可变长度序列的序列学习的奇怪行为序列

时间:2016-09-23 12:32:20

标签: keras masking recurrent-neural-network

我正在训练一个序列,用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')

我使用masking和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') 

输出形状

为什么要以这种方式格式化输出。为什么我不能使用具有完全相同维度的输入/输出序列? 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))时,这将返回整个序列的平均平方误差(MSE)(1.3168),包括这第一个值,我想这是当它没有被掩盖时被期待,但不是我想要的。

从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参数在拟合函数中的作用相同)。

1 个答案:

答案 0 :(得分:1)

这确实是图书馆中的一个错误,在Keras 2中这个问题已经解决了。