How to get Layer Outputs of CNN - python

I built a VGG16 model and trained it. I would like to see output of softmax layer (prediction probabilities) of this model for test images. I searched for answers and tried below code. It gives this error InvalidArgumentError: 2 root error(s) found. (0) INVALID_ARGUMENT: transpose expects a vector of size 3. But input(1) is a vector of size 4 [[{{node conv2d_26/Conv2D-0-TransposeNHWCToNCHW-LayoutOptimizer}}]] [[conv2d_29/Relu/_311]] (1) INVALID_ARGUMENT: transpose expects a vector of size 3. But input(1) is a vector of size 4 [[{{node conv2d_26/Conv2D-0-TransposeNHWCToNCHW-LayoutOptimizer}}]] 0 successful operations. 0 derived errors ignored.
Here is the code snippet below, I tried test image (224,244,3) and array of that image for the "image" variable. Still gives the same error. Any help is highly appreciated.
def get_all_outputs(model, input_data, learning_phase=1):
outputs = [layer.output for layer in model.layers[1:]] # exclude Input
layers_fn = K.function([model.input, K.learning_phase()], outputs)
return layers_fn([input_data, learning_phase])
outputs = get_all_outputs(model, image, 1)

you want to predict score of an image.
model.predict passes your input image through the model and gives the score of your image.
model.predict(image)

First save the model and then load the model like this
# # Save the model
filepath = './saved_model'
save_model(model, filepath)
# Load the model
model = load_model(filepath)
Then get the output for a test image like the following code
# Generate predictions for samples
predictions = model.predict(samples_to_predict)
print(predictions)
# Generate arg maxes for predictions
classes = np.argmax(predictions, axis = 1)
print(classes)

Related

How to use `model.predict` when the target is one of inputs in tensorflow?

I notice the layer LogisticEndpoint in https://www.tensorflow.org/guide/keras/train_and_evaluate#automatically_setting_apart_a_validation_holdout_set . The document build a model like this :
import numpy as np
inputs = keras.Input(shape=(3,), name="inputs")
targets = keras.Input(shape=(10,), name="targets")
logits = keras.layers.Dense(10)(inputs)
predictions = LogisticEndpoint(name="predictions")(logits, targets)
model = keras.Model(inputs=[inputs, targets], outputs=predictions)
model.compile(optimizer="adam") # No loss argument!
data = {
"inputs": np.random.random((3, 3)),
"targets": np.random.random((3, 10)),
}
model.fit(data)
My question is that how to use this model when inference , since we don't know the target when we use model.predict
The "LogisticEndpoint" is actually a layer. It takes the prediction and target as input, it can calculate the loss tracked by add_loss(), and calculate the precision scalar tracked by add_metric().
The target, if I am not wrong, is actually the ground truth data.
When you make the inference (testing stage, neither training nor validating), you do not need the ground truth data.
Just pass the input to the model, then take the output as the prediction.
To make the prediction of the multi-input:
First, convert the multi-input into one array (maybe a big one).
Then make sure the shape of the array (or precisely, tensor) matches the size of the input layer.
There is a part of the code in TF2 I am using for multi-input.
...
for view_id in range(1,9):
...
img = self.transform(img).float()
pose_2d = self.transform(pose_2d).float()
img_con.append(img)
pose_2d_con.append(pose_2d)
# then make the img_con and pose_2d_con two tensor.

Predicting a single PNG image using a trained TensorFlow model

import tensorflow as tf
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape = (28,28)),
tf.keras.layers.Dense(128, activation = 'relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10)
])
This is the code for the model, which I have trained using the mnist dataset. What I want to do is to then pass a 28x28 png image to the predict() method, which is not working. The code for the prediction is:
img = imageio.imread('image_0.png')
prediction = model.predict(img, batch_size = 1)
which produces the error
ValueError: Error when checking input: expected flatten_input to have shape (28, 28) but got array with shape (28, 3)
I have been stuck on this problem for a few days, but I can't find the correct way to pass an image into the predict method. Any help?
Predict function makes predictions over a batch of image. You should include batch dimension (first dimension) to your img, even to predict a single example.
You need something like this:
img = imageio.imread('image_0.png')
img = np.expand_dims(img, axis=0)
prediction = model.predict(img)
As #desertnaut says, seems you are using a RGB image, so your first layer should use input_shape = (28,28,3). Therefore, img parameter of predict function should have (1,28,28,3) shape.
In your case, img parameter of predict function has (28,28,3) shape, thus predict function took the first dimension as number of images, and could not match the other two dimensions to the input_shape of the first layer.

ValueError: Error when checking target: expected (keras Sequence model layer) to have n dimensions, but got array with shape

I have loaded images to train my model on recognizing one feature in those images.
Xtrain is a numpy ndarray of shape (1380,200,200,3 ) containing 1380 images sized 200 by 200pixels in RGB format
Ytrain has targets. shape (1380,2)
When I train my model (model.fit(Xtrain,Ytrain)) I seem to get a value error on everyone of the layers. As if the input was both Xtrain then Ytrain...
ValueError: Error when checking target: expected batch_normalization_24 to have 4 dimensions, but got array with shape (1380, 2)
Image:
The shape of Keras's batch normalizer layer's output is the same as its input. Since you have only two labels, your final layer in a Sequential model should generate two outputs. You can consider adding a Dense layer like:
model.add(Dense(2), activation='relu')
I also recommend to check your model's architecture using print(model.summary()) and make sure that inputs and outputs match with your dataset and vice versa.

How to feed tensor to pre-trained model in the computational graph with keras?

I want to train a specific conditional GAN with some deterministic constraints at the end of my generator with Keras and to do so I need first to compute the embeddings of my Generator outputs with VGG-16 pre-trained model.
I'm using python 3.6.
In my computational Graph, I want to feed my Generator outputs img to a pre-trained VGG-16 model in order to get the embeddings.
My img is then a tensor of shape (None,224,224,3) since I am in the computational Graph. Thing is if i compile the following i get the error
When feeding symbolic tensors to a model, we expect the tensors to
have a static batch size. Got tensor with shape: (None, 224, 224, 3)
self.vgg = self.build_vgg()
def build_vgg(self):
vgg16_model = keras.applications.vgg16.VGG16()
return Model(inputs=vgg16_model.input,outputs=vgg16_model.get_layer('fc2').output)
#-------------------------------
# Construct Computational Graph
# for Generator
#-------------------------------
# For the generator we freeze the critic's layers
self.critic.trainable = False
self.generator.trainable = True
self.vgg.trainable = False
# Sampled noise for input to generator
noise = Input(shape=(self.latent_dim,))
# Input Embedding:
embedding = Input(shape=(self.embedding,))
# Generate images based of noise
img = self.generator([noise,embedding])
# Discriminator determines validity
valid = self.critic(img)
# Get the embeddings from vgg-16:
X = self.vgg.predict(img)
Obviously, I can't loop along the first axis since it's None index. I tried to apply a function to this 'img' tensor using the tensorflow function 'tf.map_fn' like the following :
def Embedding(self,img):
fn = lambda x: self.vgg.predict(preprocess_input(np.expand_dims(x, axis=0))).flatten()
embedding = tf.map_fn(fn,img,dtype=tf.float32)
return embedding
#-------------------------------
# Construct Computational Graph
# for Generator
#-------------------------------
# For the generator we freeze the critic's layers
self.critic.trainable = False
self.generator.trainable = True
self.vgg.trainable = False
# Sampled noise for input to generator
noise = Input(shape=(self.latent_dim,))
# Input Embedding:
embedding = Input(shape=(self.embedding,))
# Generate images based of noise
img = self.generator([noise,embedding])
# Discriminator determines validity
valid = self.critic(img)
# Get the embeddings from VGG16
X = self.Embedding(img)
But i get the following error:
ValueError: setting an array element with a sequence.
To recap, I want to apply a pre-trained VGG-16 model on a tensor with shape (None,224,224,3) along the Batch_Size Axis (0) in the computational graph in Keras. What i explained to you before is what I already tried...
Does anyone have any suggestion to this ?

Tensorflow RNN for classification with single output

I want to create a RNN in Tensorflow that classifies short texts analyzing them on per-letter basis. For that I created a numpy 2D array, where each piece of text was either padded or truncated, where each element is a character code. An output is just vector of clasess represented as one-hot encoded numpy 2D-array.
Here is an example:
train_x.shape, train_y.shape
((91845, 50), (91845, 5))
Input consists of 90K rows 50 chars each, output is 90K rows with 5 classes. Next, I want to build a network shown in a figure below.
The structure looks trivial, but I deffinetelly lack knowledge in Tensorflow and run in all kinds of problems trying to at least do training. Here is the part of code I use to build the network
chars = sequence_categorical_column_with_identity('chars', params['domain_size']+1)
chars_emb = tf.feature_column.embedding_column(chars, dimension=10)
columns = [chars_emb]
input_layer, sequence_length = sequence_input_layer(features, columns)
hidden_units = 32
lstm = tf.nn.rnn_cell.LSTMCell(hidden_units, state_is_tuple=True)
rnn_outputs, state = tf.nn.dynamic_rnn(lstm,
inputs = input_layer,
sequence_length=sequence_length,
dtype=tf.float32)
output = rnn_outputs[:,-1,:]
logits = tf.layers.dense(output, params['n_classes'], activation=tf.nn.tanh)
# apply projection to every timestep.
# Compute predictions.
predicted_classes = tf.nn.softmax(logits)
# Compute loss.
loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels, logits=logits)
# Compute evaluation metrics.
accuracy = tf.metrics.accuracy(labels=labels,
predictions=predicted_classes,
name='acc_op')
But I get an error
InvalidArgumentError (see above for traceback): Input to reshape is a tensor with 8 values, but the requested shape has 1
[[Node: Reshape = Reshape[T=DT_FLOAT, Tshape=DT_INT32, _device="/job:localhost/replica:0/task:0/device:CPU:0"](softmax_cross_entropy_with_logits, sequence_input_layer/chars_embedding/assert_equal/Const)]]
A fuller minimal example you can find here. Most likely you would need Tensorflow 1.8.0.
Adding
loss = tf.reduce_mean(loss)
now allows to train the network, but the results are underwhelming.

Categories