【问题标题】:Why does my CNN not predict labels as expected?为什么我的 CNN 没有按预期预测标签?
【发布时间】:2021-04-15 01:49:23
【问题描述】:

我不熟悉相似性学习的概念。我目前正在使用 Siamese Neural Network 为 Wild Dataset 中的标记人脸做一个人脸识别模型。

连体网络模型代码(将每个代码 sn-ps 视为 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 在整个会话期间保持不变。我已经对图像进行了标准化,但仍然会发生这种情况。这个输出背后有什么原因吗?

【问题讨论】:

  • 您的问题解决了吗>?
  • 好吧,以前我将所有学习率和优化器的 val_loss 和 val_accuracy 设为 0.5000,但现在我不明白了。尽管如此,val_loss 仍然保持 0.5000 并且 val_accuracy 在整个会话期间具有恒定值(如 0.4883 或 0.5117 )。让我在这里更新代码。
  • 你为什么使用这么小的学习率?
  • @Dr.Snoopy 在下面给出的答案中提到了它。这就是我尝试的原因
  • @TimbusCalin 我在这里更新了代码

标签: tensorflow keras deep-learning conv-neural-network siamese-network


【解决方案1】:

首先,您可以轻松地将准确度作为指标移除,因为它与您的情况无关(至少在Keras 计算准确度的方式上)。

在 Siamese Networks 中,计算准确率的方式是根据您的任务选择一个阈值,例如 T,如果两个图像相同且 similarity index &gt;= T,那么您认为良好的预测 => +=1,否则不要增加计数。

但这与Keras 所做的不同,accuracy &gt; 0.5 被视为 True Positive,您可以将其完全删除,因为 Keras 中内置的准确度指标仅适用于典型的分类问题。

这是第一部分。

第二部分是您的权重没有相应更新。这是因为您这样声明优化器:optimizer=Adam(lr=0.1)。在这种情况下,学习率太高了,尤其是当我们谈论的是您在预训练的 InceptionV3 中应用的迁移学习时。

总结:

  1. 将准确度作为指标移除。
  2. 实例化optimizer=Adam(lr=0.00001)

【讨论】:

  • 有没有示例代码可以根据keras中的阈值设置精度?
  • 您需要为这种特定情况创建一个自定义回调,因为在这种情况下,您需要处理的不仅是阈值,还有类类型(相同与不同),而不仅仅是更改例如,从 0.5 到 0.94 的阈值。此外,您需要训练网络、查看结果、查看嵌入,然后才能选择特定阈值,因为此阈值取决于问题
猜你喜欢
  • 2020-02-29
  • 2018-05-19
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2019-08-28
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
相关资源
最近更新 更多