1. 基于距离的损失函数:Hinge Loss
如果负样本只采样一个
三元输入 loss(user, item+, item-) label已经在triple中了,因为规定了第二个位置必须是正样本
2元输入,label是 0 / 1, y=0时,user与item距离越大loss越小,y=1时user与item距离越大loss越大
如果负样本采样多个
可以有两种方式,一种方式是在生成输入样本的时候,为同一个(user, item+)匹配多个item-, 另一种方式是直接改变输入为neg+2元输入,并且同步更新loss的计算逻辑
因为是基于距离的计算方式,为了保障空间一致性,所以一般情况下是共享网络结构和参数的,那反向更新的时候就通过求导更新就好了,因为共享各个层的W,底层有不共享的地方就相当于各自小网络的输出接入共享结构,那么各自小网络反向更新
如下代码中通过共享同一个baseModel,共享了网络结构和参数。
def build_model_1d(input_shape, filters):
"""
Model architecture
"""
# Define the tensors for the two input images
left_inputs = Input(input_shape, name="left_inputs")
right_inputs = Input(input_shape, name="right_inputs")
# Convolutional Neural Network
inputs = Input(input_shape, name="input")
x = Conv1D(filters[0], 7, activation="elu", padding="same", name="conv1")(inputs)
x = MaxPooling1D(pool_size=2, name="mp1")(x)
x = Conv1D(filters[1], 5, activation="elu", padding="same", name="conv2")(x)
x = MaxPooling1D(pool_size=2, name="mp2")(x)
x = Conv1D(filters[2], 3, activation="elu", padding="same", name="conv3")(x)
x = MaxPooling1D(pool_size=2, name="mp3")(x)
x = Conv1D(filters[3], 3, activation="elu", padding="same", name="conv4")(x)
x = MaxPooling1D(pool_size=2, name="mp5")(x)
x = Flatten(name="flat")(x)
# Generate the encodings (feature vectors) for the two images
basemodel = Model(inputs, x, name="basemodel")
# using same instance of "basemodel" to share weights between left/right networks
encoded_l = basemodel(left_inputs)
encoded_r = basemodel(right_inputs)
# Add a customized layer to compute the absolute difference between the encodings
distance_layer = Lambda(k_euclidean_dist, name="distance")([encoded_l, encoded_r])
siamese_net = Model(inputs=[left_inputs, right_inputs], outputs=distance_layer)
# return the model
return siamese_net, basemodel
def k_contrastive_loss(y_true, dist):
"""Contrastive loss from Hadsell-et-al.'06
http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf
"""
margin = P.margin
return K.mean(y_true * K.square(dist) + (1 - y_true) * K.square(K.maximum(margin - dist, 0)))
2. 基于分类思想的损失函数:sampled softmax
image.png如果负样本每次只采样一个,三元输入 loss(user, item+, item-),softmax激活函数后输出的维度是(neg+1)维,即2维,y_true是(1,0)
如果负样本采样多个,N元输入loss(user,item+, item-,item-,...), softmax激活函数后输出的维度是(neg+1)维,最终的label,item+那一维是1,其他维是0
至于user塔和item塔的网络结构和参数是否共享,就看网络结构怎么设计了,如果共享就根据损失函数共享W的梯度,如果不共享就分开求各自W的梯度
至于使用softmax激活函数后多分类损失函数可能计算复杂的问题,可以参考word2vec中负采样的方式,采用联乘的logistic的方式进行简化计算,参考:https://zhuanlan.zhihu.com/p/144146838
网友评论