为什么我们的CNN不能按预期预测标签? [英] Why does my CNN not predict labels as expected?

查看:98
本文介绍了为什么我们的CNN不能按预期预测标签?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对相似性学习的概念是陌生的.我目前正在使用Siamese神经网络对野生数据集中的带标签人脸进行人脸识别模型.

I am new to the concept of Similarity Learning. I am currently doing a face recognition model using Siamese Neural Network for the Labelled Faces in the Wild Dataset.

暹罗网络模型的代码(考虑每个代码段为Colab中的一个单元):

Code for Siamese Network Model (Consider each code snippets to be a cell in Colab):

from keras.applications.inception_v3 import InceptionV3
from keras.applications.mobilenet_v2 import MobileNetV2
from keras.models import Model
from keras.layers import Input,Flatten

def return_inception_model():

  input_vector=Input((224,224,3))
  subnet=InceptionV3(include_top=False,weights="imagenet",input_tensor=input_vector)
  out=subnet.output
  out=Flatten()(out)
  model=Model(subnet.input,out,name="SubConvNet")

  return model

import keras.backend as K

def euclidean_distance(vect):
  x,y=vect
  return K.sqrt(K.maximum(K.sum(K.square(x - y), axis=1, keepdims=True), K.epsilon()))

def contrastive_loss(y_true, y_pred):
    margin = 1
    return K.mean(y_true * K.square(y_pred) + (1 - y_true) * K.square(K.maximum(margin - y_pred, 0)))

def accuracy(y_true, y_pred):
  return K.mean(K.equal(y_true, K.cast(y_pred < 0.5, y_true.dtype)))

from keras.layers import Lambda

base_model=return_inception_model()

left_input=Input((224,224,3))
right_input=Input((224,224,3))

feature_1=base_model(left_input)
feature_2=base_model(right_input)

lambda_layer= Lambda(euclidean_distance)([feature_1,feature_2])
output=Dense(1,activation='sigmoid')(lambda_layer)

model=Model([left_input,right_input],output)
model.summary()

Model: "model"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_2 (InputLayer)            [(None, 224, 224, 3) 0                                            
__________________________________________________________________________________________________
input_3 (InputLayer)            [(None, 224, 224, 3) 0                                            
__________________________________________________________________________________________________
SubConvNet (Functional)         (None, 51200)        21802784    input_2[0][0]                    
                                                                 input_3[0][0]                    
__________________________________________________________________________________________________
lambda (Lambda)                 (None, 1)            0           SubConvNet[0][0]                 
                                                                 SubConvNet[1][0]                 
__________________________________________________________________________________________________
dense (Dense)                   (None, 1)            2           lambda[0][0]                     
==================================================================================================
Total params: 21,802,786
Trainable params: 21,768,354
Non-trainable params: 34,432

from keras.utils.vis_utils import plot_model

plot_model(model, to_file='model_plot.png', show_shapes=True, show_layer_names=True)

from keras.optimizers import SGD,RMSprop,Adam

optimizer=Adam(lr=0.00001)
model.compile(loss=contrastive_loss,metrics=[accuracy],optimizer=optimizer)

model.fit(x=[[train_nparr_pairs[:, 0], train_nparr_pairs[:, 1]]], y=train_labels[:], 
          validation_data=([[test_nparr_pairs[:, 0], test_nparr_pairs[:, 1]]], test_labels[:]), epochs=64,use_multiprocessing=True)
Epoch 56/64
69/69 [==============================] - 8s 118ms/step - loss: 0.5132 - accuracy: 0.4868 - val_loss: 0.5000 - val_accuracy: 0.4883
Epoch 57/64
69/69 [==============================] - 8s 118ms/step - loss: 0.5044 - accuracy: 0.4956 - val_loss: 0.5000 - val_accuracy: 0.4883
Epoch 58/64
69/69 [==============================] - 8s 118ms/step - loss: 0.5064 - accuracy: 0.4936 - val_loss: 0.5000 - val_accuracy: 0.4883
Epoch 59/64
69/69 [==============================] - 8s 118ms/step - loss: 0.4806 - accuracy: 0.5194 - val_loss: 0.5000 - val_accuracy: 0.4883
Epoch 60/64
69/69 [==============================] - 8s 118ms/step - loss: 0.4843 - accuracy: 0.5157 - val_loss: 0.5000 - val_accuracy: 0.4883
Epoch 61/64
69/69 [==============================] - 8s 117ms/step - loss: 0.5060 - accuracy: 0.4940 - val_loss: 0.5000 - val_accuracy: 0.4883
Epoch 62/64
69/69 [==============================] - 8s 119ms/step - loss: 0.5048 - accuracy: 0.4952 - val_loss: 0.5000 - val_accuracy: 0.4883
Epoch 63/64
69/69 [==============================] - 8s 119ms/step - loss: 0.5110 - accuracy: 0.4890 - val_loss: 0.5000 - val_accuracy: 0.4883
Epoch 64/64
69/69 [==============================] - 8s 119ms/step - loss: 0.5118 - accuracy: 0.4882 - val_loss: 0.5000 - val_accuracy: 0.4883

在输出中,您可以注意到整个会话期间的损失和准确性是相同的. val_loss的值正好是0.5.此外,在整个会话中,val_accuracy都将保持恒定值.我已经对图像进行了归一化,但是仍然会发生这种情况.此输出背后有什么原因吗?

In the output, one can notice that the loss and accuracy are the same throughout the session. The value of val_loss is exactly 0.5. Also the val_accuracy remains as a constant value throughout the session. I have normalized the images yet still this happens. Is there any reason behind this output?

推荐答案

首先,您可以轻松删除精度作为度量标准,因为它与您的情况无关(至少以Keras计算准确性).

First of all, you can easily remove the accuracy as a metric, since it is not relevant for your case (at least in the way Keras calculates the accuracy).

在暹罗网络中,计算精度的方法是根据任务选择阈值,例如T,如果两个图像相同且similarity index >= T,则认为良好的预测=> + = 1,否则请勿增加计数.

In Siamese Networks, the way in which accuracy should be calculated, is that you select a threshold, say T, according to your task, and if two images are the same and similarity index >= T, then you consider that a good prediction => +=1, otherwise do not increase the count.

但这与Keras的操作不同,对于accuracy > 0.5,它被认为是正肯定",您可以将其完全删除,因为Keras中内置的精度度量标准仅适用于典型的分类问题.

But this is different from what Keras does, with accuracy > 0.5 is considered a True Positive, you can remove it altogether, because the built-in accuracy metric in Keras is suitable only for typical classification problems.

那是第一部分.

第二部分是您的权重不会相应更新.这是由于您这样声明了优化器:optimizer=Adam(lr=0.1).在这种情况下,学习率太高,特别是如果我们正在谈论转移学习您在预训练的InceptionV3中应用了什么.

The second part is that your weights are not updated accordingly. This is due to the fact that you declared the optizimer like this: optimizer=Adam(lr=0.1). The learning rate is too high in this case, particularly if we are talking about transfer learning what you applied with the pre-trained InceptionV3.

总结:

  1. 删除精度作为度量标准.
  2. 实例化optimizer=Adam(lr=0.00001)

这篇关于为什么我们的CNN不能按预期预测标签?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆