繁体   English   中英

Tensorflow dynamic_rnn 弃用

[英]Tensorflow dynamic_rnn deprecation

似乎tf.nn.dynamic_rnn已被弃用:

警告:此功能已弃用。 它将在未来版本中删除。 更新说明:请使用keras.layers.RNN(cell),相当于这个API

我已经检查了 keras.layers.RNN(cell) 并且它说它可以使用我认为可以替代dynamic_rnnsequence_length参数的掩码?

该层支持对具有可变时间步数的输入数据进行屏蔽。 要将掩码引入您的数据,请使用将 mask_zero 参数设置为 True 的嵌入层。

但是,即使在嵌入文档中也没有关于如何使用mask_zero=True来适应可变序列长度的更多信息。 另外,如果我使用嵌入层只是为了添加掩码,我如何防止嵌入改变我的输入并接受训练?

类似于这个问题RNN in Tensorflow vs Keras, depreciation of tf.nn.dynamic_rnn()但我想知道如何使用掩码来替换sequence_length

我也需要一个答案,并通过您问题底部的链接找出我需要什么。

简而言之,您可以按照链接中的答案进行操作,但是如果您对使用嵌入层不感兴趣,则可以“简单地”忽略嵌入层。 我强烈建议阅读和理解链接的答案,因为它更详细,以及有关Masking的文档,但这是一个修改版本,它在序列输入上使用掩蔽层来替换“sequence_length”:

import numpy as np
import tensorflow as tf

pad_value = 0.37
# This is our input to the RNN, in [batch_size, max_sequence_length, num_features] shape
test_input = np.array(
[[[1.,   1.  ],
  [2,    2.  ],
  [1.,   1.  ],
  [pad_value, pad_value], # <- a row/time step which contains all pad_values will be masked through the masking layer
  [pad_value, pad_value]],

 [[pad_value, pad_value],
  [1.,   1.  ],
  [2,    2.  ],
  [1.,   1.  ],
  [pad_value, pad_value]]])

# Define the mask layer, telling it to mask all time steps that contain all pad_value values
mask = tf.keras.layers.Masking(mask_value=pad_value)
rnn = tf.keras.layers.GRU(
    1,
    return_sequences=True,
    activation=None, # <- these values and below are just used to initialise the RNN in a repeatable way for this example
    recurrent_activation=None,
    kernel_initializer='ones',
    recurrent_initializer='zeros',
    use_bias=True,
    bias_initializer='ones'
)

x = tf.keras.layers.Input(shape=test_input.shape[1:])
m0 = tf.keras.Model(inputs=x, outputs=rnn(x))
m1 = tf.keras.Model(inputs=x, outputs=mask(x))
m2 = tf.keras.Model(inputs=x, outputs=rnn(mask(x)))

print('raw inputs\n', test_input)
print('raw rnn output (no mask)\n', m0.predict(test_input).squeeze())
print('masked inputs\n', m1.predict(test_input).squeeze())
print('masked rnn output\n', m2.predict(test_input).squeeze())

出去:

raw inputs
 [[[1.   1.  ]
  [2.   2.  ]
  [1.   1.  ]
  [0.37 0.37]
  [0.37 0.37]]

 [[0.37 0.37]
  [1.   1.  ]
  [2.   2.  ]
  [1.   1.  ]
  [0.37 0.37]]]
raw rnn output (no mask)
 [[  -6.        -50.       -156.       -272.7276   -475.83362 ]
 [  -1.2876     -9.862801  -69.314    -213.94202  -373.54672 ]]
masked inputs
 [[[1. 1.]
  [2. 2.]
  [1. 1.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [1. 1.]
  [2. 2.]
  [1. 1.]
  [0. 0.]]]
masked rnn output
 [[  -6.  -50. -156. -156. -156.]
 [   0.   -6.  -50. -156. -156.]]

请注意,应用蒙版后,计算不会在蒙版处于活动状态(即序列被填充的地方)的时间步长上执行。 相反,前一个时间步的状态会被结转。

其他几点需要注意:

  • 在链接(和这个)示例中,RNN 是使用各种激活和初始化参数创建的。 我假设这是为了示例的可重复性将 RNN 初始化为已知状态。 在实践中,您可以按照自己的意愿初始化 RNN。
  • 填充值可以是您指定的任何值。 通常,使用零填充。 在链接(和这个)示例中,使用了 0.37 的值。 我只能假设它是一个任意值来显示原始和掩码 RNN 输出的差异,因为这个示例 RNN 初始化的零输入值几乎没有/没有输出差异,因此“一些”值(即 0.37)表明掩蔽的效果。
  • Masking文档指出,仅当该时间步的所有值都包含掩码值时,才对行/时间步进行掩码。 例如,在上面, [0.37, 2]的时间步长仍然会被馈送到具有这些值的网络,但是, [0.37, 0.37]的时间步长将被跳过。
  • 这个问题的另一种替代方法是通过将不同的序列长度一起批处理来训练多次。 例如,如果您混合使用 10、20 和 30 的序列长度,而不是将它们全部填充到 30 并进行屏蔽,而是使用所有 10 个序列长度进行训练,然后使用 20s,然后使用 30s。 或者,如果您说很多 100 个序列长度,以及很多 3、4、5 个序列长度,您可能希望将较小的序列长度填充到所有 5 个长度,并使用 100 和填充/屏蔽 5 进行两次训练。 您可能会提高训练速度,但要以降低准确性为代价,因为您将无法在不同序列长度的批次之间进行混洗。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM