Я пытаюсь обучить сиамскую нейронную сеть с помощью Keras, чтобы определить, принадлежат ли 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
, я предполагаю, должен быть расстоянием между двумя выходами сиамской сети, но здесь это карта ошибок. Вам нужно вычислить среднюю разницу l1, например:Lambda(lambda tensors: K.mean(K.abs(tensors[0] - tensors[1])))
. Я также удивлен, что у вас есть плотный слой после этого слоя. Разве результат не должен быть просто расстоянием? - person Zaccharie Ramzi   schedule 22.12.2019