【问题标题】:Accuracy of contrastive loss function increases on training set, but validation accuracy gets worse or doesn't improve对比损失函数的准确性在训练集上增加,但验证准确性变得更差或没有提高
【发布时间】:2019-11-18 20:57:07
【问题描述】:

我正在尝试创建一个说话人识别连体神经网络,该网络将两个样本作为输入,并确定它们是否来自同一个说话人。为此,我使用了我检查过的几个来源(herehere)中描述的对比损失函数。

我有一个玩具数据集,我在该数据集上训练了一个小型模型(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,反之亦然?最后,对比损失应该是什么样的?

【问题讨论】:

  • 有人有答案吗?

标签: tensorflow keras conv-neural-network python-3.5 loss-function


【解决方案1】:

您如何获得音频对的音频样本和标签(0 代表不同的人或 1 代表同一个人)。我建议你在最后一层使用 sigmoid 函数,有 2 个神经元。这样你就可以使用“binary_crossentropy”损失函数。您的网络的输出将是一个介于 0 和 1 之间的值,其中 0 表示 2 个音频样本之间的最大差异,而 1 表示最大相似度。

`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(2, activation='sigmoid'))
    return baseNetwork`

`model.compile(loss=contrastive_loss, optimizer='rmsprop', metrics=[acc])`

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-30
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 2020-08-15
    • 2018-12-21
    相关资源
    最近更新 更多