Точность функции контрастных потерь увеличивается на тренировочном наборе, но точность проверки ухудшается или не улучшается - PullRequest
0 голосов
/ 09 июля 2019

Я пытаюсь создать сиамскую нейронную сеть для распознавания динамиков, которая принимает два сэмпла в качестве входных данных и выясняет, являются ли они от одного динамика или нет.Для этого я использую функцию контрастных потерь, как описано в нескольких источниках, которые я проверял ( здесь и здесь ).

У меня есть набор игрушечных данныхна котором я обучал маленькую модель (9500 учебных образцов и 500 тестовых образцов).Точность обучающего набора увеличивается до 0,97, а точность проверки увеличивается до 0,93.Все идет нормально.Однако, когда я пытаюсь применить ту же конфигурацию к большему набору данных, я получаю плохие результаты;точность обучения увеличивается, но потеря проверки никогда не превышает 0,5, что так же хорошо, как случайные догадки для такой проблемыВот мой код:

import numpy as np
import keras
import tensorflow as tf
from keras.models import Sequential, Model
from keras.layers import Dense, Activation, Flatten, Input, Concatenate, Lambda, merge
from keras.layers import Dropout
from keras.layers import LSTM, BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras import backend as K

K.set_image_dim_ordering('tf')

def Siamese_Contrastive_Loss():
    filepath = 'C:/Users/User/Documents/snet.h5'
    X_1, X_2, x1_val, x2_val, Y, val_y = data_preprocessing_load()
    input_shape = (sample_length, features, 1)
    left_input = Input(input_shape)
    right_input = Input(input_shape)

    baseNetwork = createBaseNetworkSmaller(sample_length, features, 1)
    encoded_l = baseNetwork(left_input)
    encoded_r = baseNetwork(right_input)
    distance = Lambda(euclidean_distance,output_shape=eucl_dist_output_shape)([encoded_l, encoded_r])
    model = Model([left_input, right_input], distance)

    checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
    callbacks_list = [checkpoint]
    model.compile(loss=contrastive_loss, optimizer='rmsprop', metrics=[acc])
    model.fit([X_1,X_2], Y, validation_data=([x1_val, x2_val],val_y), epochs=20, batch_size=32, verbose=2, callbacks=callbacks_list)


def data_preprocessing_load():
    ...
    return X_1, X_2, x1_val, x2_val, Y, val_y



def createBaseNetworkSmaller(sample_length, features, ii):
    input_shape = (sample_length, features, ii)
    baseNetwork = Sequential()
    baseNetwork.add(Conv2D(64,(10,10),activation='relu',input_shape=input_shape))
    baseNetwork.add(MaxPooling2D(pool_size=3))
    baseNetwork.add(Conv2D(64,(5,5),activation='relu'))
    baseNetwork.add(MaxPooling2D(pool_size=1))
    #baseNetwork.add(BatchNormalization())
    baseNetwork.add(Flatten())
    baseNetwork.add(Dense(32, activation='relu'))
    #baseNetwork.add(Dropout(0.2))
    baseNetwork.add(Dense(32, activation='relu'))
    return baseNetwork

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


def eucl_dist_output_shape(shapes):
    shape1, shape2 = shapes
    return (shape1[0], 1)


def contrastive_loss(y_true, y_pred):
    '''Contrastive loss from Hadsell-et-al.'06
    http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf
    '''
    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)
    return K.mean((1 - y_true) * K.square(y_pred) + y_true * K.square(K.maximum(margin - y_pred, 0)))


def acc(y_true, y_pred):
    ones = K.ones_like(y_pred)
    return K.mean(K.equal(y_true, ones - K.clip(K.round(y_pred), 0, 1)), axis=-1)


Я думаю, что проблема заключается в том, что я не знаю точно, что должен делать контрастивный урон.У меня есть подмножество положительных пар (сэмплы из одного и того же динамика), помеченные как 0, а другое подмножество отрицательных пар (сэмплы из разных ораторов), помеченные как 1. Как я понимаю, идея состоит в том, чтобы максимально увеличить расстояние между отрицательнымипары и минимизировать его между положительными.Я не уверен, если это так здесь.Функция с именем «acc» определяет точность на каждом этапе обучения.Функция с именем 'contrastive_loss' является основной функцией потерь, в которую я поместил два оператора возврата, один из которых был закомментирован.Я читал на форуме, что в зависимости от того, как помечены их положительные и отрицательные пары (0/1 или 1/0 соответственно), они должны использовать соответствующую формулу.На данный момент я в замешательстве.Какую конфигурацию я должен использовать?Предполагается, что положительные пары равны 0, а отрицательные - 1 или наоборот?И, наконец, какой должна быть контрастная потеря?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...