Operation type in full integer quantization method in TensorFlowLite - tensorflow

I want to apply Post-Training Quantization (Full integer) using TensorFlow model optimization package on a pre-trained model (LeNet5).
https://www.tensorflow.org/model_optimization/guide/quantization/post_training
model = Sequential()
model._name = 'LeNet5'
model.add(tf.keras.layers.InputLayer(input_shape=(28, 28)))
model.add(tf.keras.layers.Reshape(target_shape=(28, 28, 1)))
model.add(
Conv2D(6, kernel_size=(5, 5), strides=(1, 1), activation='tanh', padding='same'))
model.add(AveragePooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid'))
model.add(Conv2D(16, kernel_size=(5, 5), strides=(1, 1), activation='tanh', padding='valid'))
model.add(AveragePooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid'))
model.add(Flatten())
model.add(Dense(120, activation='tanh'))
model.add(Dense(84, activation='tanh'))
model.add(Dense(10, activation='softmax'))
and using this code I have applied Full Integer Post-Training Quantization:
mnist_train, _ = tf.keras.datasets.mnist.load_data()
images = tf.cast(mnist_train[0], tf.float32) / 255.0
mnist_ds = tf.data.Dataset.from_tensor_slices((images)).batch(1)
def representative_data_gen():
for input_value in mnist_ds.take(100):
yield [input_value]
converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
converter.representative_dataset = representative_data_gen
converter.allow_custom_ops = True
converter.target_spec.supported_types = [tf.int8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8
full_integer_quantization_model = converter.convert()
open("tflite_model.tflite", "wb").write(full_integer_quantization_model)
It works fine in tense of accuracy but when I try to print the data type of each layer (operation, like conv, activation, bias), I see that some of operations are in int32 instead of int8.
I don't know why?
How does TFLite decide to do some ops in int32 and some in int8?
Is it possible to control this feature (is it an option) in TFLite and perform all operations as int8?

Have you taken a look at this https://www.tensorflow.org/lite/performance/quantization_spec
?
Bias values have 32-bits width

Related

Training Multi Class Image classification model

I am trying to create a model using Tensorflow and Python, I get the data from a folder on my pc
The Folder Structure
An Example from the data
Almost all data are the same size [237 items,223 items,495 items,387 items,301 items]
That's how I load my data:
lables = {'Basic T-shrit':0, 'Bikini Bottom':1, 'Cargo Pants':2, 'Jeans':3, 'Oversize T-Shirt':4}
#Data
train_datagen = ImageDataGenerator(rescale=1/256)
train_generator = train_datagen.flow_from_directory(
'Dataset', # This is the source directory for training images
target_size=(256, 256), # All images will be resized to 200 x 200
batch_size=batch_size,
# Specify the classes explicitly
classes = lables,
# Since we use categorical_crossentropy loss, we need categorical labels
class_mode='categorical')
That's a model I tried:
#Model
model = Sequential()
model.add(Conv2D(32, (3,3), 1, activation='relu', input_shape=(image_width,image_height,3)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(32,3,3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64,3,3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64,3,3, activation='relu'))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(categorys_size, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer="adam",
metrics=['acc'])
Then I start the learning process:
model.fit_generator(train_generator,
steps_per_epoch=epoch_steps,
epochs=Epoch,
validation_data=train_generator)
But it's not working good, The model sees the oversize shirt and normal shirt the same and any kind of pants as jeans
Model Train result
Then I tested this model:
model = tf.keras.models.Sequential([
keras.layers.Conv2D(32, kernel_size=(5, 5), activation=tf.keras.activations.relu, input_shape=IMAGE_SHAPE),
keras.layers.MaxPooling2D(pool_size=(2, 2)),
keras.layers.BatchNormalization(axis = 1),
keras.layers.Dropout(0.22),
keras.layers.Conv2D(32, kernel_size=(5, 5), activation=tf.keras.activations.relu),
keras.layers.AveragePooling2D(pool_size=(2, 2)),
keras.layers.BatchNormalization(axis = 1),
keras.layers.Dropout(0.25),
keras.layers.Conv2D(32, kernel_size=(4, 4), activation=tf.keras.activations.relu),
keras.layers.AveragePooling2D(pool_size=(2, 2)),
keras.layers.BatchNormalization(axis = 1),
keras.layers.Dropout(0.15),
keras.layers.Conv2D(32, kernel_size=(3, 3), activation=tf.keras.activations.relu),
keras.layers.AveragePooling2D(pool_size=(2, 2)),
keras.layers.BatchNormalization(axis = 1),
keras.layers.Dropout(0.15),
keras.layers.Flatten(),
keras.layers.Dense(256, activation=tf.keras.activations.relu,kernel_regularizer=keras.regularizers.l2(0.001)),
#keras.layers.Dropout(0.25),
keras.layers.Dense(64, activation=tf.keras.activations.relu,kernel_regularizer=keras.regularizers.l2(0.001)),
#keras.layers.Dropout(0.1),
keras.layers.Dense(len(lables), activation=tf.keras.activations.softmax)])
model.compile(optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.sparse_categorical_crossentropy,
metrics=['accuracy'])
Then I start learning:
#Start Learning
checkpoint_path="/chk/cp-{epoch:04d}.ckpt"
cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path,
save_weights_only=True,
verbose=1,
period=10)
model.fit(train,
epochs=Epoch,callbacks = [cp_callback],
validation_data=val,verbose=1)
And that's how I load the data
data = tf.keras.utils.image_dataset_from_directory('Dataset',labels = 'inferred',image_size = (192,192))
data_iterator = data.as_numpy_iterator()
batch = data_iterator.next()
fig, ax = plt.subplots(ncols=4, figsize=(20,20))
for idx, img in enumerate(batch[0][:4]):
ax[idx].imshow(img.astype(int))
ax[idx].title.set_text(batch[1][idx])
#Scale Data
data = data.map(lambda x,y: (x/192, y))
data.as_numpy_iterator().next()
train_size = int(len(data)*.7)
val_size = int(len(data)*.2)
test_size = int(len(data)*.1)
print(train_size)
train = data.take(train_size)
val = data.skip(train_size).take(val_size)
test = data.skip(train_size+val_size).take(test_size)
What I am doing wrong? and is the data I collected good enough for what I am trying to do? Am I missing something ?
Thanks

Input 0 of layer "conv2d_transpose_4" is incompatible with the layer: expected ndim=4, found ndim=2. Full shape received: (None, 100)

I am trying to develop a GAN, I have created the generator and the discriminator and now I am trying to train it. I am using the Mnist dataset but I plan to use some more. The problem is that when I train it I get this error: Input 0 of layer "conv2d_transpose_4" is incompatible with the layer: expected ndim=4, found ndim=2. Full shape received: (None, 100)
I don't really know if the problem is in the networks or in the data used to train the GAN, can someone tell me how should I train it or where the problem is?
imports:
import tensorflow
import keras
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization,
LeakyReLU, Reshape
from keras.layers import Conv2D, Conv2DTranspose, MaxPooling2D
from tensorflow.keras.optimizers import Adam
from keras import backend as K
from keras.utils import np_utils
from keras.datasets import mnist
import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
generator:
def generator():
model = Sequential()
model.add(Conv2DTranspose(32, (3,3), strides=(2,
2), activation='relu', use_bias=False,
input_shape=img_shape))
model.add(BatchNormalization(momentum=0.3))
model.add(Conv2DTranspose(128,(3,3),strides=
(2,2), activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(LeakyReLU(alpha=0.2))
model.add(Conv2DTranspose(128,(3,3),strides=
(2,2), activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(BatchNormalization(momentum=0.3))
model.add(LeakyReLU(alpha=0.2))
model.add(Conv2DTranspose(128,(3,3),strides=
(2,2), activation='relu', padding='same',
use_bias=False))
model.add(BatchNormalization())
model.add(Dense(512,
activation=LeakyReLU(alpha=0.2)))
model.add(BatchNormalization(momentum=0.7))
model.build()
model.summary()
return model
discriminator:
def discriminator():
model = Sequential()
model.add(Conv2D(32, (5,5), strides=(2, 2),
activation='relu', use_bias=False,
input_shape=img_shape))
model.add(BatchNormalization(momentum=0.3))
model.add(Conv2D(64,(5,5),strides=(2,2),
activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(LeakyReLU(alpha=0.2))
model.add(Conv2D(64,(5,5),strides=(2,2),
activation='relu', padding='same',
use_bias=False))
model.add(Dropout(0.5))
model.add(BatchNormalization(momentum=0.3))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(512,
activation=LeakyReLU(alpha=0.2)))
model.add(Flatten())
model.add(BatchNormalization(momentum=0.7))
model.add(Dense(1, activation='sigmoid'))
model.build()
model.summary()
return model
train function:
def train(epochs, batch_size, save_interval):
(x_train, _), (_, _) = mnist.load_data()
x_train = (x_train.astype(np.float32) - 127.5) / 127.5
x_train = np.expand_dims(x_train, axis=3)
half_batch = int(batch_size / 2)
for epoch in range(epochs):
idx = np.random.randint(0, x_train.shape[0], half_batch)
imgs = x_train[idx]
noise = np.random.normal(0, 1, (half_batch, 100))
gen_imgs = generator.predict(noise)
d_loss_real = discriminator.train_on_batch(imgs, np.ones((half_batch, 1)))
d_loss_fake = discriminator.train_on_batch(gen_imgs, np.zeros((half_batch, 1)))
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
noise = np.random.normal(0, 1, (batch_size, 100))
valid_y = np.array([1] * batch_size)
g_loss = combined.train_on_batch(noise, valid_y)
print ("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, d_loss[0], 100*d_loss[1], g_loss))
if epoch % save_interval == 0:
save_imgs(epoch)
Data used:
img_rows = 28
img_cols = 28
channels = 1
img_shape = (img_rows, img_cols, channels)
optimizer = Adam(0.0002, 0.5)
discriminator = discriminator()
discriminator.compile(loss='binary_crossentropy',
optimizer=optimizer,
metrics=['accuracy'])
generator = generator()
generator.compile(loss='binary_crossentropy',
optimizer=optimizer)
z = Input(shape=(100,))
img = generator(z) #error
discriminator.trainable = False
valid = discriminator(img)
combined = Model(z, valid)
combined.compile(loss='binary_crossentropy',
optimizer=optimizer)
train(epochs=100000, batch_size=32,
save_interval=10)
generator.save('generator_model.h5')
The problem is coming from the first Flatten layer in the Discriminator model, which is converting your n-dimensional tensor to a 1D tensor. Since a MaxPooling2D layer cannot work with a 1D tensor, you are seeing that error. If you remove it, it should work:
def discriminator():
model = Sequential()
model.add(Conv2D(32, (5,5), strides=(2, 2),
activation='relu', use_bias=False,
input_shape=img_shape))
model.add(BatchNormalization(momentum=0.3))
model.add(Conv2D(64,(5,5),strides=(2,2),
activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(LeakyReLU(alpha=0.2))
model.add(Conv2D(64,(5,5),strides=(2,2),
activation='relu', padding='same',
use_bias=False))
model.add(Dropout(0.5))
model.add(BatchNormalization(momentum=0.3))
model.add(LeakyReLU(alpha=0.2))
model.add(Flatten())
model.add(Dense(512,
activation=LeakyReLU(alpha=0.2)))
model.add(BatchNormalization(momentum=0.7))
model.add(Dense(1, activation='sigmoid'))
model.build()
model.summary()
return model
Update 1:
Try rewriting your Generator model like this:
def generator():
model = Sequential()
model = tf.keras.Sequential()
model.add(Dense(7*7*256, use_bias=False, input_shape=(100,)))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Reshape((7, 7, 256)))
assert model.output_shape == (None, 7, 7, 256) # Note: None is the batch size
model.add(Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
assert model.output_shape == (None, 7, 7, 128)
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
assert model.output_shape == (None, 14, 14, 64)
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
assert model.output_shape == (None, 28, 28, 1)
model.summary()
return model
It should then work, but you should definitely go through this tutorial to understand everything.
First the discriminator is wrong you expecting the input noise to generator with same diemnsions where it is similaities for crossentrory, noises can generate into multiple levels where the batch is create !
WHen you looking at each layer you will see how much the layer identification need !
Simply doing by measure the input / output you don't need to removed or edit meaning of the model.
It is not the generator flase when you input is wrong try see the discriminator layers where they are training on the batch sizes and the genrated input image.
( It is noises similarlities cross-entrophy )
Model layers and shapes is not chagne when you use the input correct way
### name='conv2d_transpose_input'), name='conv2d_transpose_input', description="created by layer 'conv2d_transpose_input'"),
### but it was called on an input with incompatible shape (None, 100).
model = Sequential()
model.add(Conv2DTranspose(32, (3,3), strides=(2,
2), activation='relu', use_bias=False,
input_shape=(28, 28, 1)))
model.add(BatchNormalization(momentum=0.3))
model.add(Conv2DTranspose(128,(3,3),strides=
(2,2), activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(LeakyReLU(alpha=0.2))
########################
def discriminator():
model = Sequential()
### Input 0 of layer "conv2d" is incompatible with the layer: expected axis -1 of input shape to have value 1, but received input with shape (None, 114, 114, 512)
### model.add(tf.keras.layers.Reshape((1, 100), input_shape=img_shape))
model.add(Conv2D(32, (5,5), strides=(2, 2),
activation='relu', use_bias=False,
input_shape=( 28, 28, 1))) ### img_shape
model.add(BatchNormalization(momentum=0.3))
model.add(Conv2D(64,(5,5),strides=(2,2),
activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(LeakyReLU(alpha=0.2))
...

Conv2D is incompatible with the layer in a GAN

I am developing a GAN using the Mnist dataset. I have developed the Generator and Discriminator. However, when I combine them together I get this error: Input 0 of layer "conv2d" is incompatible with the layer: expected axis -1 of input shape to have value 1, but received input with shape (None, 57, 57, 1024). Does anyone know why this happens? Do I have to add something else?
The preprocessing:
(x_train, _), (x_test, _) = mnist.load_data()
x_train = x_train.reshape(60000, 28, 28, 1)
x_test = x_test.reshape(10000, 28, 28, 1)
x_train = x_train.astype('float32')/255
x_test = x_test.astype('float32')/255
img_rows, img_cols = 28, 28
channels = 1
img_shape = (img_rows, img_cols, channels)
The Generator:
def generator():
model = Sequential()
model.add(Conv2DTranspose(32, (3,3), strides=(2, 2), activation='relu', use_bias=False,
input_shape=img_shape))
model.add(BatchNormalization(momentum=0.3))
model.add(Conv2DTranspose(64,(3,3),strides=(2,2), activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(LeakyReLU(alpha=0.2))
model.add(Conv2DTranspose(64,(3,3),strides=(2,2), activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(BatchNormalization(momentum=0.3))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(512, activation=LeakyReLU(alpha=0.2)))
model.add(BatchNormalization(momentum=0.7))
model.add(Dense(1024, activation='tanh'))
model.summary()
model.compile(loss=keras.losses.binary_crossentropy, optimizer=Adam(learning_rate=0.02))
return model
generator = generator()
The Discriminator:
def discriminator():
model = Sequential()
model.add(Conv2D(32, (5,5), strides=(2, 2), activation='relu', use_bias=False,
input_shape=img_shape))
model.add(BatchNormalization(momentum=0.3))
model.add(Conv2D(64,(5,5),strides=(2,2), activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(LeakyReLU(alpha=0.2))
model.add(Conv2D(64,(5,5),strides=(2,2), activation='relu', padding='same',
use_bias=False))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(BatchNormalization(momentum=0.3))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(512, activation=LeakyReLU(alpha=0.2)))
model.add(BatchNormalization(momentum=0.7))
model.add(Dense(1024, activation='tanh'))
model.summary()
model.compile(loss=keras.losses.binary_crossentropy, optimizer=Adam(learning_rate=0.02))
return model
discriminator = discriminator()
Both models combined (Where I get the error):
def GAN(generator, discriminator):
model = Sequential()
model.add(generator)
discriminator.trainable = False
model.add(discriminator)
model.summary()
model.compile()
return model
gan = GAN(generator, discriminator)
Your generator needs to produce images, thus the output shape of the generator must be the same shape as the images. The activation also must be compatible with the range in the images. I don't think your images go from -1 to +1, so you should not use "tanh". You must choose an activation compatible with the images.
Last generator layer:
Dense(img_shape[-1], ...)
Your discriminator needs to say whether the images are true or false, thus its output must have one value only, 0 or 1.
Last discriminator layer:
Dense(1, activation="sigmoid")

Tensor name has no shape information ERROR when predicting with tensorflow serving

I'm using tensorflow serving to serve a savedmodel. I have two signatures: 1st outputting keras model.output and the 2nd outputting post processing of model.output. When I try a predict call of the 2nd signature on tensorflow serving it is giving me an error { "error": "Tensor name: prediction has no shape information " }
this is the code to build the savedmodel
shape1 = 92
shape2 = 92
reg=0.000001
learning_rate=0.001
sess = tf.Session()
K.set_session(sess)
K._LEARNING_PHASE = tf.constant(0)
K.set_learning_phase(0)
#preprocessing
x_input = tf.placeholder(tf.string, name='x_input', shape=[None])
reshaped = tf.reshape(x_input, shape=[])
image = tf.image.decode_jpeg(reshaped, channels=3)
image2 = tf.expand_dims(image,0)
resized = tf.image.resize_images(image2, (92,92))
meaned = tf.math.subtract(resized, tf.constant(116.0))
normalized = tf.math.divide(meaned, tf.constant(66.0))
#keras model
model = tf.keras.Sequential()
model.add(InputLayer(input_tensor=normalized))
model.add(Conv2D(32, (3, 3), padding='same', activation='relu', kernel_regularizer=l2(reg)))
model.add(Conv2D(32, (3, 3), padding='same', activation='relu', kernel_regularizer=l2(reg)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu', kernel_regularizer=l2(reg)))
model.add(Dropout(0.1))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu', kernel_regularizer=l2(reg)))
model.add(Dropout(0.1))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, (3, 3), padding='same', activation='relu', kernel_regularizer=l2(reg)))
model.add(Dropout(0.2))
model.add(Conv2D(128, (3, 3), padding='same', activation='relu', kernel_regularizer=l2(reg)))
model.add(Dropout(0.2))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(256, (3, 3), padding='same', activation='relu', kernel_regularizer=l2(reg)))
model.add(Dropout(0.3))
model.add(Conv2D(256, (3, 3), padding='same', activation='relu', kernel_regularizer=l2(reg)))
model.add(Dropout(0.3))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(256, activation='relu', kernel_regularizer=l2(reg)))
model.add(Dropout(0.5))
model.add(Dense(256, activation='relu', kernel_regularizer=l2(reg)))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer=tf.train.RMSPropOptimizer(learning_rate=learning_rate),
metrics=['accuracy'])
#post processing to output label
pred = tf.gather_nd(model.output, (0,0))
label = tf.cond(pred > 0.5, lambda: tf.constant('Dog', shape=[]), lambda: tf.constant('Cat', shape=[]))
model.load_weights(r'./checkpoints/4.ckpt')
export_path = './saved_models/1'
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init_op)
model.load_weights(r'./checkpoints/4.ckpt')
if os.path.isdir(export_path):
print('\nAlready saved a model, cleaning up\n')
print(subprocess.run(['rm', '-r', export_path]))
#first signature(this works)
x_info = tf.saved_model.utils.build_tensor_info(x_input)
y_info = tf.saved_model.utils.build_tensor_info(model.output)
sigmoid_signature = build_signature_def(inputs={"image": x_info}, outputs={"prediction":y_info}, method_name='tensorflow/serving/predict')
#2nd signature(this doesn't work)
x_info = tf.saved_model.utils.build_tensor_info(x_input)
y_info = tf.saved_model.utils.build_tensor_info(label)
label_signature = build_signature_def(inputs={"image": x_info}, outputs={"prediction":y_info}, method_name='tensorflow/serving/predict')
builder = tf.saved_model.builder.SavedModelBuilder(export_path)
legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op')
builder.add_meta_graph_and_variables(sess=sess,
tags=["serve"],
signature_def_map={'sigmoid': sigmoid_signature, 'label': label_signature})
builder.save()
this is code to call tf serving
imgs = ['./Dog/' + img for img in imgs]
img = open('./Dog/3.jpg', 'rb').read()
img = base64.b64encode(img).decode('utf-8')
data = json.dumps(
{"signature_name": "label",
"instances": [
{'image': {'b64': img}}
]
}
)
json_response = requests.post('http://localhost:8501/v1/models/pet:predict', data=data)
print(json_response.text)
Instead of getting a response of {"predictions": "Dog"}, i am getting an error { "error": "Tensor name: prediction has no shape information " }
I managed to fix this. I used tf.reshape on what i wanted to output and passed that into the signature builder.
#post processing to output label
pred = tf.gather_nd(model.output, (0,0))
label = tf.cond(pred > 0.5, lambda: tf.constant('Dog', shape=[]), lambda: tf.constant('Cat', shape=[]))
label_reshaped = tf.reshape(label, [None])
...
#2nd signature(this doesn't work)
x_info = tf.saved_model.utils.build_tensor_info(x_input)
y_info = tf.saved_model.utils.build_tensor_info(label_reshaped)
label_signature = build_signature_def(inputs={"image": x_info}, outputs={"prediction":y_info}, method_name='tensorflow/serving/predict')
Reading the tensorflow serving documentation, you'll see that there are two ways to specify input tensors in your request, the row format (using instances like your example), and the column format (using inputs).
Since the row format requires that all inputs and outputs have the same 0th dimension, if you did not export the model with explicit output shape, you cannot use the row format.
Therefore, in your case (without having to re-export the model with explicit reshaping, like the other answer has provided), you can send this payload instead
data = json.dumps(
{
"signature_name": "label",
"inputs": {'image': {'b64': img}}
}
)
On the other hand, keep in mind that if you do want to send multiple b64 encoded images, your best bet would be to use the row format with multiple instances (such as if you want to run batch predict on multiple images).

how to convert Tensor objects into numpy array?

i have built and trained a CNN, and i want to get the wieghts of the first dense layer as numpy array . after i trained the model i loaded the model using this code
f = Path("model_structure.json")
model_structure = f.read_text()
model_wieghts = model_from_json(model_structure)
model_wieghts.load_weights("model_weights.h5")
in order to get the wieghts of the first dense layer i used :
wieghts_tf = model_wieghts.layers[9].output
wieghts_tf has this value:
<tf.Tensor 'dense_1/Relu:0' shape=(?, 496) dtype=float32>
the question is , i want to convert the type of wieghts_tf from tensor to numpy array . so i created a session and used the eval() function to do so . as shown below :
sess = tf.Session()
with sess.as_default() :
vector = wieghts_tf.eval()
but im getting this error
InvalidArgumentError: You must feed a value for placeholder tensor 'conv2d_1_input' with dtype float and shape [?,180,180,3]
how can i solve it ?
here is the code of the CNN model :
#creating nueral network
model = Sequential()
conv1_2d = model.add(Conv2D(180, (3, 3), padding='same', input_shape=(180, 180, 3), activation="relu")) #180 is the number of filters
conv2_2d = model.add(Conv2D(180, (3, 3), activation="relu"))
max_pool1 = model.add(MaxPooling2D(pool_size=(3, 3)))
drop_1 = model.add(Dropout(0.25))
conv3_2d =model.add(Conv2D(360, (3, 3), padding='same', activation="relu"))
conv4_2d =model.add(Conv2D(360, (3, 3), activation="relu"))
max_pool2 = model.add(MaxPooling2D(pool_size=(3, 3)))
drop_2 = model.add(Dropout(0.25))
flat = model.add(Flatten())
dense_1 = model.add(Dense(496, activation="relu"))
drop_3 = model.add(Dropout(0.5))
dense_2 = dense_layer = model.add(Dense(376, activation="softmax"))
model.compile(
loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
model.fit(
train_data,
train_label,
batch_size=32,
epochs=40,
verbose = 2 ,
validation_split=0.1,
shuffle=True)
# Save neural network structure
model_structure = model.to_json()
f = Path("model_structure.json")
f.write_text(model_structure)
# Save neural network's trained weights
model.save_weights("model_weights.h5")
Found the solution:
x = np.frombuffer(layer.convolution.weights.float16Value, dtype=np.float16)