python - LSTM 不会过度拟合训练数据

标签 python tensorflow

我一直在尝试在 TensorFlow 中使用 LSTM 进行回归,但它不适合数据。我已成功在 Keras 中拟合相同的数据(具有相同大小的网络)。我尝试过拟合正弦波的代码如下:

import tensorflow as tf
import numpy as np

yt = np.cos(np.linspace(0, 2*np.pi, 256))
xt = np.array([yt[i-50:i] for i in range(50, len(yt))])[...,None]
yt = yt[-xt.shape[0]:]

g = tf.Graph()
with g.as_default():
    x = tf.constant(xt, dtype=tf.float32)
    y = tf.constant(yt, dtype=tf.float32)

    lstm = tf.nn.rnn_cell.BasicLSTMCell(32)
    outputs, state = tf.nn.dynamic_rnn(lstm, x, dtype=tf.float32)
    pred = tf.layers.dense(outputs[:,-1], 1)
    loss = tf.reduce_mean(tf.square(pred-y))
    train_op = tf.train.AdamOptimizer().minimize(loss)
    init = tf.global_variables_initializer()

sess = tf.InteractiveSession(graph=g)
sess.run(init)

for i in range(200):
    _, l = sess.run([train_op, loss])
print(l)

这导致 MSE 为 0.436067(而 Keras 在 50 个 epoch 后达到 0.0022),预测范围为 -0.1860 到 -0.1798。我在这里做错了什么?

编辑: 当我将损失函数更改为以下内容时,模型拟合正确:

def pinball(y_true, y_pred):
    tau = np.arange(1,100).reshape(1,-1)/100
    pin = tf.reduce_mean(tf.maximum(y_true[:,None] - y_pred, 0) * tau +
                 tf.maximum(y_pred - y_true[:,None], 0) * (1 - tau))
    return pin

我还将 predloss 的分配更改为

pred = tf.layers.dense(outputs[:,-1], 99)
loss = pinball(y, pred)

这会导致训练时的损失从 0.3 减少到 0.003,并且似乎正确地拟合了数据。

最佳答案

看起来像是形状/广播问题。这是一个工作版本:

import tensorflow as tf
import numpy as np

yt = np.cos(np.linspace(0, 2*np.pi, 256))
xt = np.array([yt[i-50:i] for i in range(50, len(yt))])
yt = yt[-xt.shape[0]:]

g = tf.Graph()
with g.as_default():
    x = tf.constant(xt, dtype=tf.float32)
    y = tf.constant(yt, dtype=tf.float32)

    lstm = tf.nn.rnn_cell.BasicLSTMCell(32)
    outputs, state = tf.nn.dynamic_rnn(lstm, x[None, ...], dtype=tf.float32)
    pred = tf.squeeze(tf.layers.dense(outputs, 1), axis=[0, 2])
    loss = tf.reduce_mean(tf.square(pred-y))
    train_op = tf.train.AdamOptimizer().minimize(loss)
    init = tf.global_variables_initializer()

sess = tf.InteractiveSession(graph=g)
sess.run(init)

for i in range(200):
    _, l = sess.run([train_op, loss])
print(l)

x 在进入 dynamic_rnn 之前获取批处理维度为 1,因为使用 time_major=False 第一个维度预计为批处理方面。重要的是,tf.layers.dense 输出的最后一个维度被挤压,以便它不会与 y 一起广播 (TensorShape([256, 1])TensorShape([256]) 广播到 TensorShape([256, 256]))。通过这些修复,它收敛了:

5.78507e-05

关于python - LSTM 不会过度拟合训练数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45105645/

相关文章:

c++ - Tensorflow C++ YOU_MADE_A_PROGRAMMING_MISTAKE

python - 无法使用 ResNet50 在 Keras 中加载权重以进行微调

python - tensorflow retrain.py app.run() 得到了意外的关键字参数 'argv'

python - 为什么在 Pytorch 中,当我复制网络权重时,它会在反向传播后自动更新?

Python 正则表达式 DUPLICATE_NAMES 标志

python - Pandas ,基于列值的条件列分配

python - 我已经通过 macports 安装了 xapian,那么为什么这个 python 应用程序告诉我需要安装 xapian?

Python仅导入包内的模块

tensorflow - 独立的 Tensorflow 投影仪

python - 对 Tensorflow 中保存/恢复经过训练的权重和偏差感到困惑