变长度序列的奇异行为序列到序列学习



我正在用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中这个问题被解决了

相关内容

  • 没有找到相关文章

最新更新