【发布时间】:2020-04-14 00:15:10
【问题描述】:
我正在尝试使用 Keras 训练 Siamese 神经网络,目的是识别 2 张图像是否属于同一类。我的数据被打乱了,正例和负例的数量相等。我的模型没有学习任何东西,它总是预测相同的输出。我每次都得到相同的损失、验证准确性和验证损失。
def convert(row):
return imread(row)
def contrastive_loss(y_true, y_pred):
margin = 1
square_pred = K.square(y_pred)
margin_square = K.square(K.maximum(margin - y_pred, 0))
return K.mean(y_true * square_pred + (1 - y_true) * margin_square)
def SiameseNetwork(input_shape):
top_input = Input(input_shape)
bottom_input = Input(input_shape)
# Network
model = Sequential()
model.add(Conv2D(96,(7,7),activation='relu',input_shape=input_shape))
model.add(MaxPooling2D())
model.add(Conv2D(256,(5,5),activation='relu',input_shape=input_shape))
model.add(MaxPooling2D())
model.add(Conv2D(256,(5,5),activation='relu',input_shape=input_shape))
model.add(MaxPooling2D())
model.add(Flatten())
model.add(Dense(4096,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1024,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(512,activation='relu'))
model.add(Dropout(0.5))
encoded_top = model(top_input)
encoded_bottom = model(bottom_input)
L1_layer = Lambda(lambda tensors:K.abs(tensors[0] - tensors[1]))
L1_distance = L1_layer([encoded_top, encoded_bottom])
prediction = Dense(1,activation='sigmoid')(L1_distance)
siamesenet = Model(inputs=[top_input,bottom_input],outputs=prediction)
return siamesenet
data = pd.read_csv('shuffleddata.csv')
print('Converting X1....')
X1 = [convert(x) for x in data['X1']]
print('Converting X2....')
X2 = [convert(x) for x in data['X2']]
print('Converting Y.....')
Y = [0 if data['Y'][i] == 'Negative' else 1 for i in range(len(data['Y']))]
input_shape = (53,121,3,)
model = SiameseNetwork(input_shape)
model.compile(loss=contrastive_loss,optimizer='sgd',metrics=['accuracy'])
print(model.summary())
model.fit(X1,Y,batch_size=32,epochs=20,shuffle=True,validation_split = 0.2)
model.save('Siamese.h5')
【问题讨论】:
-
您是否尝试过使用较小的步长(甚至是不同的优化器)?您是否尝试过对数据集的一小部分进行过拟合?
-
是的,我尝试过使用更小的步长以及不同的优化器和损失函数。我也尝试过拟合小数据,但模型没有学到任何东西。您能否检查一下我输入的方式是否正确?
-
嗯嗯,你调用
L1_distance的层我猜应该是连体网络的2个输出之间的距离,但这里是一个错误图。您需要计算平均 l1 差异,例如:Lambda(lambda tensors: K.mean(K.abs(tensors[0] - tensors[1])))。我也很惊讶你在这层之后有一个致密层。输出不应该只是距离吗? -
我已经尝试使用您的 L1 距离版本,并且还删除了密集层,但它没有工作,顺便说一下,我需要给定的 2 个图像有多相似的概率,它们之间没有任何距离图片
-
当然有道理。我只是认为这可能更简单,您可以删除 Dense 层并在对比损失中使用 sigmoid,但我已经看到您使用的实现,我知道您想坚持下去。
标签: python tensorflow keras neural-network