概述
嗨,我目前正在尝试使用keras构建一个自动编码器推荐系统模型(我对使用 Tensorflow 没有信心),目前卡住了,因为我无法让 keras 进行部分反向传播。(如果可能,请提供代码或其他来源的示例)。
AutoEnc RecSys 的工作原理
该系统的想法是将带有一堆零(“尚未审查”)的高维度评级数据(4k + 特征)提供给编码器,然后将其解码回原始维度。先前的零输入将更改为某个数字,该数字作为预测结果。
问题是
当您向编码器输入一堆零时,编码器将学习输出大量零以及输出(他们认为输入 0 是目标输出,这不是预期的结果)(0 表示未预测/未评级) .
因此,首先要做的是屏蔽损失函数以仅从非零的输入计算损失 (RMS)。(即在每列火车上仅使用非零特征进行前馈)。
然后是真正的问题......在得到损失之后,将发生反向传播,并且keras似乎对所有权重进行反向传播,其中一些(零)应该被忽略(以避免编码器学习输出零)(损失在层上的所有权重之间共享,它们基于相同的损失计算梯度)
有什么方法可以防止 keras 对由 zeros 输入的权重进行反向支持?
类似于 dropout,但这不是随机的,如果该节点的输入为零,则关闭节点/权重)
我尝试搜索一堆页面,主要是通过使用 Tensorflow 完成并制作自定义渐变函数。其他一些人建议简单地使用掩码,因为零损失 = 零梯度 = 没有反向传播,但这仅适用于单个数字预测,同时我的系统将返回高维数据(与输入相同的维度)。
注意:自定义损失函数对反向传播不起作用,损失是共享的,其中一些仍然需要损失来调整权重。我已经掩盖了损失函数,所以只有非零特征会影响损失函数。(正确的方法,但不完整)
一些细节:自动编码器架构:https ://prnt.sc/ntzmbf
我的模型:
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.layers import LeakyReLU
model = Sequential()
model.add(Dense(128, input_shape=(4000,)))
model.add(LeakyReLU(alpha=0.1))
model.add(Dense(4000, activation="softmax"))
自定义损失函数(屏蔽)
import keras.backend as K
# Custom MSE (only calculate loss from non-masked value)
def masked_mse(mask_value):
def f(y_true, y_pred):
mask_true = K.cast(K.not_equal(y_true, mask_value), K.floatx())
masked_squared_error = K.square(mask_true * (y_true - y_pred))
masked_mse = K.sum(masked_squared_error, axis=-1) / K.sum(mask_true, axis=-1)
return masked_mse
f.__name__ = 'Masked MSE (mask_value={})'.format(mask_value)
return f
model.compile(optimizer='adam', loss=masked_mse(0))
model.fit(X_train.values, X_train.values,
validation_data=(X_val.values, X_val.values),
epochs=100,
batch_size=128,
verbose=1,
)
Input example : [3, 0, 0, 0, 1, 0, ..., 2, 1]
Expected output : [3, 0.1, 2, 0.3, 1, 1, ..., 2, 1]
谢谢你 :)