【问题标题】:Training RNN with error evaluation at every time step在每个时间步训练带有错误评估的 RNN
【发布时间】:2021-04-19 16:10:25
【问题描述】:

我有一个 simpleRNN / LSTM,我正在尝试使用 tensorflow 对顺序分类任务进行训练。有一个数据序列(300 个时间步长)可以预测 t=300 的标签。对于我的任务,我希望 RNN 在每个时间步(不仅仅是在最终时间点)评估错误并将其向后传播(如下图)。

在下面的一些回复之后,我似乎需要做一些事情:使用 return_sequences 标志;使用 TimeDistributed 层访问 LSTM/RNN 的输出;并且还定义了一个自定义的损失函数。

model = Sequential()
layer1 = LSTM(n_neurons, input_shape=(length, 1), return_sequences=True)
model.add(layer1)
layer2 = TimeDistributed(Dense(1))
model.add(layer2)
    
# Define custom loss
def custom_loss(layer1):
        
    # Create a loss function
    def loss(y_true,y_pred):
       # access layer1 at every time point and compute mean error
       # UNCLEAR HOW TO RUN AT EVERY TIME STEP
       err = K.mean(layer1(X) - y_true, axis=-1)
       return err
           
    # Return a function
    return loss

# Compile the model
model.compile(optimizer='adam', loss=custom_loss(layer), metrics=['accuracy'])
    

现在我对 custom_loss 函数有点困惑,因为我不清楚如何传入 layer1 并计算最里面的损失函数中的错误。

任何人有建议或可以指点我更详细的答案?

【问题讨论】:

    标签: tensorflow recurrent-neural-network prediction backpropagation


    【解决方案1】:

    这个问题不容易回答,因为不清楚您要实现什么(使用 FFNN 或 RNN 不应该是一样的,最有效的方法肯定取决于应用程序)。

    无论如何,您可能会将训练步骤(例如,在小批量序列上的正向和反向传播)与“内部”步骤混淆循环神经网络。在任何输出可用之前,单个序列(或单个小批量)将始终在前向传递期间完全“展开”:只有在(因此,在训练步骤结束)之后,您可以使用预测并计算损失以进行反向传播。

    您可以做的是返回输出序列(每个内部时间步都有一个 y_predicted),包括 SimpleRNN(...) 内的参数 return_sequences=True。这将为您提供一个包含 300 个预测的序列,每个预测仅取决于与所考虑的内部时间步长相关的过去输入。然后,您可以使用计算损失所需的输出,可能在自定义损失函数中。

    我希望我已经足够清楚了。否则,请告诉我是否可以提供进一步帮助。

    【讨论】:

    • 感谢马西莫的回复。我确实确实查看了每个时间步的预测,除了最后几个时间点外,它们都很糟糕。因此,我正在寻找一种可以(i)在每个时间步反向传播错误的 NN 架构; (ii) 还保留记忆。我虽然 LSTM 可以做到这一点 - 但正如你所说,预测只在最后一个时间步之后进行评估(即在我的情况下为 300)。 FFNN 执行 (i) 但没有记忆。我是否在寻找一种不存在的 NN 架构?再次感谢您的帮助。
    • 在 RNN 层中使用 return_sequences=True 将为您提供整个输出序列 - 每个时间步都有一个输出(张量),请参阅 here。使用 TimeDistributed 层,您最终将获得一系列预测:然后您需要提供 sequences 标签,Keras 的损失函数将考虑所有这些来构建损失(沿时间平均维度),然后在每个时间步自动反向传播。
    • 好的,我想我现在更好地理解了这个问题,非常感谢。我修改了我的问题,使其更具体地了解损失函数以及如何使用 TimeDistributed 层来访问数据。
    • 您好 Massimo,我可以问您一个相关问题吗?我使用 TimeDistributed 使用自定义损失层 (model.add_loss) 分别计算每个时间步的标签和损失。我应该合并我的损失并返回一个标量(或者更确切地说,每个小批量条目一个)还是返回完整的损失序列更好,每个时间步一个?训练算法会将每个损失反向传播到 RNN 中自己的时间步长吗?我在 Keras / TF 上使用 LSTM 和 TimeDistributed。
    猜你喜欢
    • 2023-04-06
    • 2021-08-16
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    相关资源
    最近更新 更多