使用需要更多参数的 _init_ 嵌入自定义 RNN 单元(3 vs 1)
Posted
技术标签:
【中文标题】使用需要更多参数的 _init_ 嵌入自定义 RNN 单元(3 vs 1)【英文标题】:Embed custom RNN cell with _init_ that takes more arguments (3 vs 1) 【发布时间】:2020-03-11 08:24:10 【问题描述】:我正在尝试创建一个类似于本文中提出的模型:https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=8738842
自定义单元格代码位于:https://github.com/SungjoonPark/DenoisingRNN/blob/master/dgrud.py
但是,我无法将此自定义单元嵌入到任何 RNN 模型中,我假设这是因为 init 采用 3 个参数而不是标准的“num_units”。
我尝试按照https://keras.io/layers/recurrent/ 的示例进行操作:
cell = MinimalRNNCell(32)
x = keras.Input((None, 5))
layer = RNN(cell)
y = layer(x)
但我得到一个错误:
TypeError Traceback(最近一次调用最后一次) 在 2 x = keras.Input((无, 5)) 3 层 = RNN(cell) ----> 4 y = layer(x)
~/.local/lib/python3.5/site-packages/keras/layers/recurrent.py 在 调用(自我,输入,initial_state,常量,**kwargs)539 540 如果 initial_state 是 None 并且 constants 是 None: --> 541 return super(RNN, self).call(inputs, **kwargs) 542 543 # 如果任何一个 initial_state 或 常量被指定并且是 Keras
~/.local/lib/python3.5/site-packages/keras/engine/base_layer.py 在 call(self, inputs, **kwargs) 487 # 实际调用层, 488 # 收集输出、掩码和形状。 --> 489 输出 = self.call(inputs, **kwargs) 490 output_mask = self.compute_mask(输入,previous_mask)491
~/.local/lib/python3.5/site-packages/keras/layers/recurrent.py 在 调用(自我,输入,掩码,训练,initial_state,常量)680 掩码=掩码,681 展开=self.unroll,--> 682 输入长度=时间步数)683 if self.stateful: 684 更新 = []
~/.local/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py 在 rnn(step_function,输入,initial_states,go_backwards,掩码, 常量,展开,输入长度)3101常量=常量,3102 展开=展开,-> 3103 输入长度=输入长度)3104 可达= tf_utils.get_reachable_from_inputs([learning_phase()], 3105 目标=[last_output])
~/.local/lib/python3.5/site-packages/tensorflow/python/keras/backend.py 在 rnn(step_function,输入,initial_states,go_backwards,掩码, 常量、展开、输入长度、时间主要、零输出为掩码) 3730 # 值被丢弃。第3731章 step_function(-> 3732 input_time_zero,元组(initial_states)+ 元组(常量))3733 output_ta =元组(3734 tensor_array_ops.TensorArray(
~/.local/lib/python3.5/site-packages/keras/layers/recurrent.py 在 步骤(输入,状态)671 其他:672 定义步骤(输入,状态):-> 673 return self.cell.call(inputs, states, **kwargs) 674 675 last_output, 输出,状态 = K.rnn(step,
TypeError: call() 接受 2 个位置参数,但给出了 3 个
您能帮我弄清楚这是一个 init 问题、一个 call 问题还是我需要为这个自定义单元定义一个自定义层?
我尝试在整个互联网上寻找答案,但我无法弄清楚应该如何在 RNN 模型中嵌入自定义单元格。
提前谢谢你,
山姆
【问题讨论】:
【参考方案1】:当我将 keras 直接导入程序时,我能够重新创建您的问题。见下文,
%tensorflow_version 1.x
import keras
from keras import backend as K
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.layers import RNN
class MinimalRNNCell(keras.layers.Layer):
def __init__(self, units, **kwargs):
self.units = units
self.state_size = units
super(MinimalRNNCell, self).__init__(**kwargs)
def build(self, input_shape):
self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
initializer='uniform',
name='kernel')
self.recurrent_kernel = self.add_weight(
shape=(self.units, self.units),
initializer='uniform',
name='recurrent_kernel')
self.built = True
def call(self, inputs, states):
prev_output = states[0]
h = K.dot(inputs, self.kernel)
output = h + K.dot(prev_output, self.recurrent_kernel)
return output, [output]
# Let's use this cell in a RNN layer:
cell = MinimalRNNCell(32)
x = keras.Input((None, 5))
layer = RNN(cell)
y = layer(x)
输出 -
TensorFlow is already loaded. Please restart the runtime to change versions.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-0f3bed686a7d> in <module>()
34 x = keras.Input((None, 5))
35 layer = RNN(cell)
---> 36 y = layer(x)
5 frames
/usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py in symbolic_fn_wrapper(*args, **kwargs)
73 if _SYMBOLIC_SCOPE.value:
74 with get_graph().as_default():
---> 75 return func(*args, **kwargs)
76 else:
77 return func(*args, **kwargs)
TypeError: __call__() takes 2 positional arguments but 3 were given
导入 keras from tensorflow import keras
时错误消失。该代码在 tensorflow 版本 1.x 和 2.x 上成功运行。修改您的代码如下 -
%tensorflow_version 2.x
from keras import backend as K
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow import keras
from tensorflow.keras.layers import RNN
# First, let's define a RNN Cell, as a layer subclass.
class MinimalRNNCell(keras.layers.Layer):
def __init__(self, units, **kwargs):
self.units = units
self.state_size = units
super(MinimalRNNCell, self).__init__(**kwargs)
def build(self, input_shape):
self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
initializer='uniform',
name='kernel')
self.recurrent_kernel = self.add_weight(
shape=(self.units, self.units),
initializer='uniform',
name='recurrent_kernel')
self.built = True
def call(self, inputs, states):
prev_output = states[0]
h = K.dot(inputs, self.kernel)
output = h + K.dot(prev_output, self.recurrent_kernel)
return output, [output]
# Let's use this cell in a RNN layer:
cell = MinimalRNNCell(32)
x = keras.Input((None, 5))
layer = RNN(cell)
y = layer(x)
print("I Ran Successfully")
输出 -
I Ran Successfully
希望这能回答您的问题。快乐学习。
【讨论】:
@SCoder - 如果它回答了您的问题,请您接受并投票赞成答案。谢谢。以上是关于使用需要更多参数的 _init_ 嵌入自定义 RNN 单元(3 vs 1)的主要内容,如果未能解决你的问题,请参考以下文章