延迟回声 - 无法在 Keras 中重现 Tensorflow 结果
Delayed echo of sin - cannot reproduce Tensorflow result in Keras
我正在 Keras 中试验 LSTM,但运气不佳。在某个时刻,我决定缩减到最基本的问题,以便最终取得一些积极的结果。
然而,即使是最简单的问题,我发现 Keras 也无法收敛,而在 Tensorflow 中实现相同的问题会给出稳定的结果。
我不愿意在不理解为什么 Keras 在我尝试的任何问题上不断出现分歧的情况下就切换到 Tensorflow。
我的问题是延迟正弦回波的多对多序列预测,示例如下:
蓝线是网络输入序列,红色虚线是预期输出。
该实验的灵感来自这个 repo 并且也从中创建了可行的 Tensorflow 解决方案。
我的代码的相关摘录如下,我的最小可重现示例的完整版本可用 here。
Keras 模型:
model = Sequential()
model.add(LSTM(n_hidden,
input_shape=(n_steps, n_input),
return_sequences=True))
model.add(TimeDistributed(Dense(n_input, activation='linear')))
model.compile(loss=custom_loss,
optimizer=keras.optimizers.Adam(lr=learning_rate),
metrics=[])
Tensorflow 模型:
x = tf.placeholder(tf.float32, [None, n_steps, n_input])
y = tf.placeholder(tf.float32, [None, n_steps])
weights = {
'out': tf.Variable(tf.random_normal([n_hidden, n_steps], seed = SEED))
}
biases = {
'out': tf.Variable(tf.random_normal([n_steps], seed = SEED))
}
lstm = rnn.LSTMCell(n_hidden, forget_bias=1.0)
outputs, states = tf.nn.dynamic_rnn(lstm, inputs=x,
dtype=tf.float32,
time_major=False)
h = tf.transpose(outputs, [1, 0, 2])
pred = tf.nn.bias_add(tf.matmul(h[-1], weights['out']), biases['out'])
individual_losses = tf.reduce_sum(tf.squared_difference(pred, y),
reduction_indices=1)
loss = tf.reduce_mean(individual_losses)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) \
.minimize(loss)
我声称代码的其他部分(data_generation
、training
)完全相同。但是,使用 Keras 的学习进度很早就停滞不前,并产生了不尽如人意的预测。下面附有库和示例预测的 logloss
图表:
Tensorflow 训练模型的 Logloss:
Keras 训练模型的 Logloss:
从图中读取并不容易,但 Tensorflow 达到 target_loss=0.15
并在大约 10k 个批次后提前停止。但是 Keras 用完了所有 13k 个批次,达到 loss
大约只有 1.5
。在一个单独的实验中,Keras 对于 100k 个批次 运行,它在 1.0
附近没有进一步停滞。
下图包含:黑线 - 模型输入信号,绿色虚线 - ground truth 输出,红线 - 获取的模型输出。
Tensorflow 训练模型的预测:
Keras 训练模型的预测:
亲爱的同事们,感谢您的建议和见解!
好的,我已经设法解决了这个问题。 Keras 实施现在也稳步收敛到一个明智的解决方案:
这些模型实际上并不相同。您可以格外小心地检查问题中的 Tensorflow
模型版本,并亲自验证下面列出的实际 Keras
等效项,而不是问题中所述的内容:
model = Sequential()
model.add(LSTM(n_hidden,
input_shape=(n_steps, n_input),
return_sequences=False))
model.add(Dense(n_steps, input_shape=(n_hidden,), activation='linear'))
model.compile(loss=custom_loss,
optimizer=keras.optimizers.Adam(lr=learning_rate),
metrics=[])
我会详细说明。这里可行的解决方案使用 LSTM 吐出的最后一列大小 n_hidden
作为中间激活,然后馈送到 Dense
层。
所以,在某种程度上,这里的实际预测是由常规感知器做出的。
一个额外的注意事项 - 原始 Keras
解决方案中的错误来源已经从问题所附的推理示例中显而易见。我们在那里看到较早的时间戳完全失败,而较晚的时间戳接近完美。这些较早的时间戳对应于 LSTM 刚刚在新 window 上初始化并且对上下文一无所知时的状态。
我正在 Keras 中试验 LSTM,但运气不佳。在某个时刻,我决定缩减到最基本的问题,以便最终取得一些积极的结果。
然而,即使是最简单的问题,我发现 Keras 也无法收敛,而在 Tensorflow 中实现相同的问题会给出稳定的结果。
我不愿意在不理解为什么 Keras 在我尝试的任何问题上不断出现分歧的情况下就切换到 Tensorflow。
我的问题是延迟正弦回波的多对多序列预测,示例如下:
蓝线是网络输入序列,红色虚线是预期输出。
该实验的灵感来自这个 repo 并且也从中创建了可行的 Tensorflow 解决方案。
我的代码的相关摘录如下,我的最小可重现示例的完整版本可用 here。
Keras 模型:
model = Sequential()
model.add(LSTM(n_hidden,
input_shape=(n_steps, n_input),
return_sequences=True))
model.add(TimeDistributed(Dense(n_input, activation='linear')))
model.compile(loss=custom_loss,
optimizer=keras.optimizers.Adam(lr=learning_rate),
metrics=[])
Tensorflow 模型:
x = tf.placeholder(tf.float32, [None, n_steps, n_input])
y = tf.placeholder(tf.float32, [None, n_steps])
weights = {
'out': tf.Variable(tf.random_normal([n_hidden, n_steps], seed = SEED))
}
biases = {
'out': tf.Variable(tf.random_normal([n_steps], seed = SEED))
}
lstm = rnn.LSTMCell(n_hidden, forget_bias=1.0)
outputs, states = tf.nn.dynamic_rnn(lstm, inputs=x,
dtype=tf.float32,
time_major=False)
h = tf.transpose(outputs, [1, 0, 2])
pred = tf.nn.bias_add(tf.matmul(h[-1], weights['out']), biases['out'])
individual_losses = tf.reduce_sum(tf.squared_difference(pred, y),
reduction_indices=1)
loss = tf.reduce_mean(individual_losses)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) \
.minimize(loss)
我声称代码的其他部分(data_generation
、training
)完全相同。但是,使用 Keras 的学习进度很早就停滞不前,并产生了不尽如人意的预测。下面附有库和示例预测的 logloss
图表:
Tensorflow 训练模型的 Logloss:
Keras 训练模型的 Logloss:
target_loss=0.15
并在大约 10k 个批次后提前停止。但是 Keras 用完了所有 13k 个批次,达到 loss
大约只有 1.5
。在一个单独的实验中,Keras 对于 100k 个批次 运行,它在 1.0
附近没有进一步停滞。
下图包含:黑线 - 模型输入信号,绿色虚线 - ground truth 输出,红线 - 获取的模型输出。
Tensorflow 训练模型的预测:
好的,我已经设法解决了这个问题。 Keras 实施现在也稳步收敛到一个明智的解决方案:
这些模型实际上并不相同。您可以格外小心地检查问题中的 Tensorflow
模型版本,并亲自验证下面列出的实际 Keras
等效项,而不是问题中所述的内容:
model = Sequential()
model.add(LSTM(n_hidden,
input_shape=(n_steps, n_input),
return_sequences=False))
model.add(Dense(n_steps, input_shape=(n_hidden,), activation='linear'))
model.compile(loss=custom_loss,
optimizer=keras.optimizers.Adam(lr=learning_rate),
metrics=[])
我会详细说明。这里可行的解决方案使用 LSTM 吐出的最后一列大小 n_hidden
作为中间激活,然后馈送到 Dense
层。
所以,在某种程度上,这里的实际预测是由常规感知器做出的。
一个额外的注意事项 - 原始 Keras
解决方案中的错误来源已经从问题所附的推理示例中显而易见。我们在那里看到较早的时间戳完全失败,而较晚的时间戳接近完美。这些较早的时间戳对应于 LSTM 刚刚在新 window 上初始化并且对上下文一无所知时的状态。