Open longzeyilang opened 6 years ago
Hello, @longzeyilang, yes, when we write call function we just write the rules of how our value will be computed, so than if we want to apply our CenterLoss, we specify it in the compile() function.
https://keras.io/models/model/
I have some problem when I use centerloss in image classification with keras. 1、in custom_vgg_model.fit(y = {'fc2':y_train,'predictions':y_train}),'fc2':y_train have error that
ValueError: Error when checking target: expected fc2 to have shape (None, 4096) but got array with shape (6300, 45)
y_train is the labels. If I do like this custom_vgg_model.fit(y = {'fc2':dummy1,'predictions':y_train}),the model will train successful. The dummy1 have same shape with 'fc2' output(feature).
dummy1 = np.zeros((y_train.shape[0],4096))
But can't improve the accuracy of the model.So it is wrong coding.
2、It is wrong to use ImageDataGenerator.flow(x = X_train, y = {'fc2':dummy1,'predictions':y_train}, batch_size=batch_Sizes) .So I can't expand my data.
image_input = Input(shape=(224, 224, 3))
model = VGG16(input_tensor=image_input, include_top=True,weights='imagenet')
model.summary()
last_layer = model.get_layer('fc2').output
feature = last_layer
out = Dense(num_classes,activation = 'softmax',name='predictions')(last_layer)
custom_vgg_model = Model(inputs = image_input, outputs = [out,feature])
custom_vgg_model.summary()
for layer in custom_vgg_model.layers[:-3]:
layer.trainable = False
custom_vgg_model.layers[3].trainable
sgd = optimizers.SGD(lr=learn_Rate,decay=decay_Rate,momentum=0.9,nesterov=True)
center_loss = lossclass.get_center_loss(alpha=0.5, num_classes=45,feature_dim = 4096)
custom_vgg_model.compile(loss={'predictions': "categorical_crossentropy", 'fc2': center_loss},
loss_weights={'fc2': 1, 'predictions': 1},optimizer= sgd,
metrics={'predictions': 'accuracy'})
t=time.time()
dummy1 = np.zeros((y_train.shape[0],4096))
dummy2 = np.zeros((y_test.shape[0],4096))
if not data_Augmentation:
hist = custom_vgg_model.fit(x = X_train,y = {'fc2':y_train,'predictions':y_train},batch_size=batch_Sizes,
epochs=epoch_Times, verbose=1,validation_data=(X_test, {'fc2':y_test,'predictions':y_test}))
else:
datagen = ImageDataGenerator(
featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
vertical_flip=True,
rescale=None,
preprocessing_function=None,
data_format=None)
print('x_train.shape[0]:{:d}'.format(X_train.shape[0]))
hist = custom_vgg_model.fit_generator(datagen.flow(x = X_train, y = {'fc2':dummy1,'predictions':y_train}, batch_size=batch_Sizes),
steps_per_epoch=X_train.shape[0]/batch_Sizes,epochs=epoch_Times,
verbose=1, validation_data=(X_test, {'fc2':y_test,'predictions':y_test}))
# lossclass.py
def _center_loss_func(labels,features, alpha, num_classes, centers, feature_dim):
assert feature_dim == features.get_shape()[1]
labels = K.argmax(labels, axis=1)
labels = tf.to_int32(labels)
centers_batch = K.gather(centers, labels)
diff = (1 - alpha) * (centers_batch - features)
centers = tf.scatter_sub(centers, labels, diff)
centers_batch = K.gather(centers, labels)
loss = K.mean(K.square(features - centers_batch))
return loss
def get_center_loss(alpha, num_classes, feature_dim):
"""Center loss based on the paper "A Discriminative
Feature Learning Approach for Deep Face Recognition"
(http://ydwen.github.io/papers/WenECCV16.pdf)
"""
# Each output layer use one independed center: scope/centers
centers = K.zeros([num_classes, feature_dim], dtype='float32')
@functools.wraps(_center_loss_func)
def center_loss(y_true, y_pred):
return _center_loss_func(y_true, y_pred, alpha, num_classes, centers, feature_dim)
return center_loss
Hi, I have a question: `def call(self, x, mask=None):
x[0] is Nx2, x[1] is Nx10 onehot, self.centers is 10x2
return self.result
_the call function has already contained the center loss. But in the below:_
self.model.compile(optimizer=optimizer, loss=[losses.categorical_crossentropy, self.center_loss], loss_weights=[1, self.lambda_centerloss])`the compile get center_loss again and again, is that true?