Я пытаюсь построить сиамскую нейронную сеть, чтобы взять два выражения лица и вывести вероятность того, что эти два изображения похожи.У меня 5 человек, по 10 выражений на человека, итого 50 изображений, но с сиамским я могу создать 2500 пар (с повторением).Я уже запустил определение лицевых ориентиров в dlib на каждом из 50 изображений, поэтому каждый из двух входов в сиамскую сеть представляет собой два сплющенных массива по 136,1 элемента.Сиамская структура приведена ниже:
input_shape = (136,)
left_input = Input(input_shape, name = 'left')
right_input = Input(input_shape, name = 'right')
convnet = Sequential()
convnet.add(Dense(50,activation="relu"))
encoded_l = convnet(left_input)
encoded_r = convnet(right_input)
L1_layer = Lambda(lambda tensors:K.abs(tensors[0] - tensors[1]))
L1_distance = L1_layer([encoded_l, encoded_r])
prediction = Dense(1,activation='relu')(L1_distance)
siamese_net = Model(inputs=[left_input,right_input],outputs=prediction)
optimizer = Adam()
siamese_net.compile(loss="binary_crossentropy",optimizer=optimizer)
У меня есть массив с именем x_train, который составляет 80% всех возможных меток и элементами которого являются списки списков.Данные представляют собой матрицу 5x10x64x2, где имеется 5 ppl, 10 выражений для каждого, 64 лицевых ориентира и 2 позиции (x, y) для ориентира
x_train = [ [ [Person, Expression] , [Person, Expression] ], ...]
data = np.load('data.npy')
Мой цикл поезда идет следующим образом:
def train(data, labels, network, epochs, batch_size):
track_loss = defaultdict(list)
for i in range(0, epochs):
iterations = len(labels)//batch_size
remain = len(labels)%batch_size
shuffle(labels)
print('Epoch%s-----' %(i + 1))
for j in range(0, iterations):
batch = [j*batch_size, j*batch_size + batch_size]
if(j == iterations - 1):
batch[1] += remain
mini_batch = np.zeros(shape = (batch[1] - batch[0], 2, 136))
for k in range(batch[0], batch[1]):
prepx = data[labels[k][0][0],labels[k][0][1],:,:]
prepy = data[labels[k][1][0],labels[k][1][1],:,:]
mini_batch[k - batch[0]][0] = prepx.flatten()
mini_batch[k - batch[0]][1] = prepy.flatten()
targets = np.array([1 if(labels[i][0][1] == labels[i][1][1]) else 0 for i in range(batch[0], batch[1])])
new_batch = mini_batch.reshape(batch[1] - batch[0], 2, 136, 1)
new_targets = targets.reshape(batch[1] - batch[0], 1)
#print(mini_batch.shape, targets.shape)
loss=siamese_net.train_on_batch(
{
'left': mini_batch[:, 0, :],
'right': mini_batch[:, 1, :]
},targets)
track_loss['Epoch%s'%(i)].append(loss)
return network, track_loss
siamese_net, track_loss = train(data, x_train,siamese_net, 20, 30)
Значение каждого элемента в целевом массиве равно 0 или 1, в зависимости от того, являются ли два выражения, введенные в сеть, разными или одинаковыми.
Хотя я видел вВ омниглоте было гораздо больше изображений и тестовых изображений, потери в моей нейронной сети не уменьшились.
РЕДАКТИРОВАТЬ:
Вот новая потеря с фиксированным целевым тензором:
Epoch1-----Loss: 1.979214
Epoch2-----Loss: 1.631347
Epoch3-----Loss: 1.628090
Epoch4-----Loss: 1.634603
Epoch5-----Loss: 1.621578
Epoch6-----Loss: 1.631347
Epoch7-----Loss: 1.631347
Epoch8-----Loss: 1.631347
Epoch9-----Loss: 1.621578
Epoch10-----Loss: 1.634603
Epoch11-----Loss: 1.634603
Epoch12-----Loss: 1.621578
Epoch13-----Loss: 1.628090
Epoch14-----Loss: 1.624834
Epoch15-----Loss: 1.631347
Epoch16-----Loss: 1.634603
Epoch17-----Loss: 1.628090
Epoch18-----Loss: 1.631347
Epoch19-----Loss: 1.624834
Epoch20-----Loss: 1.624834
Я хочу знать, как улучшить мою архитектуру и процедуру обучения или даже подготовку данных, чтобы улучшить производительность нейронной сети.Я предполагал, что использование определения лица в dlib упростит нейронную сеть, но я начинаю сомневаться в этой гипотезе.