使用需要更多参数的 _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)的主要内容,如果未能解决你的问题,请参考以下文章

在 sklearn 中创建自定义转换器时出错 - 需要 2 个位置参数,但给出了 3 个

自定义参数初始化方法

Python向方法中传递自定义类型参数

将自定义表单参数传递给表单集

RN Props属性

Django——自定义分页(可调用)