【发布时间】:2016-09-23 12:32:19
【问题描述】:
我正在使用 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')
输出形状
为什么期望以这种方式格式化输出。为什么我不能使用具有完全相同维度的输入/输出序列? 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 masking recurrent-neural-network