4
$\begingroup$

I have an image dataset 376 classes each class has 15 pictures corresponds to a person. I would like to get the feature vector that corresponds to each person.

What I have done is, after I compiled the model I then used this link as a reference to get the weights of the last convolutional layer. However, when I do this, I get the error:

InvalidArgumentError: You must feed a value for placeholder tensor 'conv_layer' with dtype float and shape [?,19,19,360]

How can I resolve this issue?

Here is the code that I have done so far:

train_data = np.array(train_data, dtype=np.float32)
test_data = np.array(test_data, dtype=np.float32)
train_data = train_data / 180 # to make the array values between 0-1 
test_data = test_data / 180
train_label = keras.utils.to_categorical(train_label, 376)
test_label = keras.utils.to_categorical(test_label, 376)
# CNN MODEL
model = Sequential()
model.add(Conv2D(180, (3, 3), padding='same', input_shape=(180, 180, 3), 
activation="relu")) #180 is the number of filters
model.add(Conv2D(180, (3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(3, 3))) 
model.add(Dropout(0.25))
model.add(Conv2D(360, (3, 3), padding='same', activation="relu"))
model.add(Conv2D(360, (3, 3), activation="relu"))
conv_layer = model.add(MaxPooling2D(pool_size=(3, 3)))
model.add(Dropout(0.25))
flatten_layer = model.add(Flatten())
model.add(Dense(496, activation="relu"))
model.add(Dropout(0.5))
dense_layer = model.add(Dense(376, activation="softmax"))
#compiling the model
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)
# getting intermediate  layer weights 
get_layer_output = K.function([model.layers[0].input],
                              [model.layers[11].output])
layer_output = get_layer_output([conv_layer])[0]
$\endgroup$
  • $\begingroup$ Which layer's output are expecting to keep as face feature vectors? $\endgroup$ – Kiritee Gak Mar 24 at 14:09
  • $\begingroup$ @KiriteeGak last convolutional layer in this example 7th $\endgroup$ – Alfaisal Albakri Mar 24 at 14:39
3
$\begingroup$

The easiest way to create a truncated output from a network is create a sub-network of it and apply weights of your trained network. The following example is a modification of what you have shown up there, but it will guide you out

Network you want to train originally

model = Sequential()
model.add(Conv2D(10, (3, 3), padding='same', input_shape=(60, 60, 3),
                 activation="relu"))
model.add(Conv2D(10, (3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(3, 3)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(5, activation="softmax"))
model.compile(
    loss='categorical_crossentropy',
    optimizer='adam',
    metrics=['accuracy'])

model.fit(
    train_data,
    train_label)

Now create a subnetwork from which you want the outputs, like from above example

model_new = Sequential()
model_new.add(Conv2D(10, (3, 3), padding='same', input_shape=(60, 60, 3),
                     activation="relu"))
model_new.add(Conv2D(10, (3, 3), activation="relu"))
model_new.add(MaxPooling2D(pool_size=(3, 3)))
model_new.add(Dropout(0.25))
model_new.add(Flatten())

model_new.compile(
    loss='categorical_crossentropy',
    optimizer='adam',
    metrics=['mse'])

# You need to apply fit on random array's created, just so as to initialise 
# weights. Anyways you will replacing them with original ones from above.
model_new.fit(train_data, y=np.random.rand(40, 3610))

Now take weights from the first trained network and replace the weights of the second network like

model_new.set_weights(weights=model.get_weights())

You can check whether the weights are changed in the above step by actually adding these check statements like

print("Are arrays equal before fit - ",
      any([np.array_equal(a1, a2) for a1, a2 in zip(model_new.get_weights(), model.get_weights()[:4])]))

model_new.set_weights(weights=model.get_weights())
print("Are arrays equal after applying weights - ",
      all([np.array_equal(a1, a2) for a1, a2 in zip(model_new.get_weights(), model.get_weights()[:4])]))

This should yeild

Are arrays equal before fit -  False
Are arrays equal after applying weights -  True

Hope this helps.

$\endgroup$
  • $\begingroup$ works perfectly thanks . one more question , how do i know which array corresponds to image class? $\endgroup$ – Alfaisal Albakri Mar 24 at 18:13
  • $\begingroup$ What do you mean by array? Are you saying output of a filter? You accurately cannot find it. Remember after flattening you have a huge vector and you mapped all of them with some weight onto low dim. using dense layers. So any of the values from the filters would have contributed to the class weight. $\endgroup$ – Kiritee Gak Mar 24 at 18:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.