Python Tensorflow动态折旧

Python Tensorflow动态折旧,python,tensorflow,keras,recurrent-neural-network,embedding,Python,Tensorflow,Keras,Recurrent Neural Network,Embedding,似乎tf.nn.dynamic\u rnn已被弃用: 警告:此函数已弃用。它将在将来的版本中删除。更新说明:请使用keras.layers.RNN(cell),它相当于此API 我已经检查了keras.layers.RNN(cell),它说它可以使用掩蔽,我假设它可以替代动态\u RNN的序列长度参数 该层支持使用可变时间步数屏蔽输入数据。要向数据引入掩码,请使用mask_zero参数设置为True的嵌入层 但即使在嵌入文档中也没有关于如何使用mask_zero=True来适应可变序列长度的更多

似乎
tf.nn.dynamic\u rnn
已被弃用:

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

我已经检查了keras.layers.RNN(cell),它说它可以使用掩蔽,我假设它可以替代
动态\u RNN
序列长度
参数

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

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


与此问题类似,但我想知道如何使用掩码替换
序列长度

我也需要一个答案,并通过问题底部的链接了解我需要什么

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

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())
请注意,应用遮罩后,计算不会在遮罩处于活动状态(即,填充序列)的时间步长上执行。相反,前一时间步的状态将被向前推进

需要注意的其他几点:

  • 在链接(和此)示例中,RNN是使用各种激活和初始值设定项参数创建的。我假设这是将RNN初始化为已知状态,以实现示例的可重复性。实际上,您可以按照自己的意愿初始化RNN
  • 焊盘值可以是您指定的任何值。通常,使用零填充。在链接(和此)示例中,使用了0.37的值。我只能假设它是一个任意值来显示原始和屏蔽RNN输出中的差异,因为此示例RNN初始化的零输入值在输出中几乎没有差异,因此“某些”值(即0.37)显示了屏蔽的效果
  • 文档声明,只有当该时间步的所有值都包含掩码值时,才会屏蔽行/时间步。例如,在上面的例子中,
    [0.37,2]
    的时间步长仍将以这些值馈送到网络,然而,
    [0.37,0.37]
    的时间步长将被跳过
  • 替代掩蔽的另一种方法是通过将不同的序列长度分批在一起进行多次训练。例如,如果序列长度为10、20和30,而不是将它们全部填充到30和掩蔽,则使用所有的10个序列长度,然后是20秒,然后是30秒进行训练。或者,如果你说有很多100个序列长度,也有很多3、4、5个序列长度,你可能希望将较小的序列长度全部填充到5个长度,并使用100和填充/屏蔽5进行两次训练。您可能会获得训练速度,但在精度较低的情况下,您将无法在不同序列长度的批次之间切换

您有关于上一种方法的例子吗?我无法让自己明白,没有填充物怎么会起作用
model.fit()
具有固定的批量大小,对吗?如果不同长度的序列形成不同的批大小,该怎么办?@ARAT批大小是网络每次更新看到的示例数(您也可以使用
train\u on\u batch
)。最后一个维度——批次中每个特征每个项目的序列长度——对于RNN来说非常重要。每次调用
fit()
都需要一批相同长度的序列。因此,例如,您可以将数据划分为
data seq len_1
data seq len_2
,并调用
fit(data seq len_1)
fit(data seq len_2)
(或者以向模型提供数据的方式)。但是,正如您所看到的,数据不能在序列长度之间移动。。。
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.]]