我正在用Keras训练可变长度序列的序列到序列模型,但是我遇到了一些意想不到的问题。我不清楚我正在观察的行为是否是库的期望行为,以及为什么会是。
<标题>模型创建我制作了一个带有嵌入层和GRU
循环层的循环模型来说明这个问题。我使用mask_zero=0.0
作为嵌入层,而不是屏蔽层,但改变这似乎没有什么区别(也没有在输出之前添加屏蔽层):
import numpy
from keras.layers import Embedding, GRU, TimeDistributed, Dense, Input
from keras.models import Model
import keras.preprocessing.sequence
numpy.random.seed(0)
input_layer = Input(shape=(3,), dtype='int32', name='input')
embeddings = Embedding(input_dim=20, output_dim=2, input_length=3, mask_zero=True, name='embeddings')(input_layer)
recurrent = GRU(5, return_sequences=True, name='GRU')(embeddings)
output_layer = TimeDistributed(Dense(1), name='output')(recurrent)
model = Model(input=input_layer, output=output_layer)
output_weights = model.layers[-1].get_weights()
output_weights[1] = numpy.array([0.2])
model.layers[-1].set_weights(output_weights)
model.compile(loss='mse', metrics=['mse'], optimizer='adam', sample_weight_mode='temporal')
我使用屏蔽和sample_weight参数从训练/评估中排除填充值。我将在使用Keras填充函数填充的一个输入/输出序列上测试此模型:
X = [[1, 2]]
X_padded = keras.preprocessing.sequence.pad_sequences(X, dtype='float32', maxlen=3)
Y = [[[1], [2]]]
Y_padded = keras.preprocessing.sequence.pad_sequences(Y, maxlen=3, dtype='float32')
<标题>输出形状h1> 什么期望以这种方式格式化输出。为什么我不能使用具有完全相同维度的输入/输出序列?model.evaluate(X_padded, Y_padded)
给了我一个维度错误。
然后,当我运行model.predict(X_padded)
时,我得到以下输出(在生成模型之前使用numpy.random.seed(0)
):
[[[ 0.2 ]
[ 0.19946882]
[ 0.19175649]]]
为什么第一个输入不为输出层遮罩?output_value是否无论如何都要计算(并且等于偏差,因为隐藏层的值为0?这似乎并不可取。在输出层之前添加掩蔽层并不能解决这个问题。
<标题> MSE计算然后,当我评估模型(model.evaluate(X_padded, Y_padded)
)时,它返回整个序列(1.3168)的均方误差(MSE),包括这个第一个值,我认为这是预期的,当它没有被屏蔽时,但不是我想要的。
从Keras文档中,我明白我应该使用sample_weight
参数来解决这个问题,我尝试过:
sample_weight = numpy.array([[0, 1, 1]])
model_evaluation = model.evaluate(X_padded, Y_padded, sample_weight=sample_weight)
print model.metrics_names, model_evaluation
我得到的输出是
['loss', 'mean_squared_error'] [2.9329459667205811, 1.3168648481369019]
这使得度量(MSE)保持不变,它仍然是上所有值的MSE,包括我想要屏蔽的那个。为什么?这不是我评估模型时想要的结果。它确实会导致损失值的变化,这似乎是经过归一化的最后两个值的MSE,以不给更长的序列更多的权重。
我做错了什么与样本权重?而且,我真的不知道这个损失值是怎么来的。我应该怎么做才能从训练和评估中排除填充值(我假设sample_weight参数在fit函数中工作相同)?
标题>标题>标题>这确实是库中的一个错误,在Keras 2中这个问题被解决了