【问题标题】:TensorFlow layer subclass input shapeTensorFlow 层子类输入形状
【发布时间】:2021-11-29 12:02:24
【问题描述】:

我正在尝试从 TensorFlow 的 layers.Layer 实例创建一个自定义层。

我正在尝试制作一个 IIR 过滤器,因此它使用来自输入层的值并计算输出序列,如下所示:

y[i] = a0 * x[i] + a1 * x[i - 1] + b1 * y[i - 1]

其中x 是输入,y 是输出。我这样定义类:

class IIR(keras.layers.Layer):
    def __init__(self, input_dim):
        super(IIR, self).__init__()
        self.input_dim = 60
        self.b0 = tf.Variable(tf.constant([uniform(-1, 1)]))
        self.b1 = tf.Variable(tf.constant([uniform(-1, 1)]))
        self.b2 = tf.Variable(tf.constant([uniform(-1, 1)]))
        self.a1 = tf.Variable(tf.constant([uniform(-1, 1)]))
        self.a2 = tf.Variable(tf.constant([uniform(-1, 1)]))
        
    def call(self, inputs):
      order = 3
      init_dim = [0,1,2]
      output_sequence = tf.constant(np.zeros((self.input_dim)),dtype=tf.float32)
      outt = np.zeros(self.input_dim)
      outt[0] = inputs[0]
      outt[1] = inputs[1]
      outt[2] = inputs[2]
      for i in range(2,self.input_dim):
        outt[i] = self.b0*inputs[i] + self.b1*inputs[i-1] + self.b2*inputs[i-2] - self.a1*outt[i-1] - self.a2*outt[i-2]
      output_sequence = tf.constant(outt)
      return output_sequence

但我不断收到错误

ValueError: Exception encountered when calling layer "iir_13" (type IIR).

in user code:

    File "<ipython-input-37-0717fc982e73>", line 17, in call  *
        outt[0] = inputs[:][0]

    ValueError: setting an array element with a sequence.


Call arguments received:
  • inputs=tf.Tensor(shape=(None, 60), dtype=float32)

等等。输入的形状是(None, 60)(我设置60 只是为了测试目的)我假设None 将在训练时被批量替换?如何访问输入的值?输入的实际形状是什么?这是正确的方法吗?

编辑:我正在尝试在模型中实现这一点,如下所示:

model = keras.Sequential()
model.add(keras.layers.Input(shape=60))
model.add(IIR(input_dim=60))
model.add(keras.layers.Dense(8, activation='relu'))
model.add(keras.layers.Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy')

【问题讨论】:

  • 你能解释一下你在这些行中试图做什么:outt[0] = inputs[0] outt[1] = inputs[1] outt[2] = inputs[2]
  • @AloneTogether 我正在尝试将输出数组的前 3 个元素设置为等于输入以从第三个索引向前执行该过程

标签: python tensorflow keras deep-learning tensorflow2.0


【解决方案1】:

不确定你到底想做什么,但我建议只使用Tensorflow 操作。这是一个例子:

import tensorflow as tf

class IIR(tf.keras.layers.Layer):

    def __init__(self, input_dim):
        super(IIR, self).__init__()
        self.input_dim = input_dim
        self.b0 = tf.Variable(tf.random.uniform((1,), minval=-1, maxval=1))
        self.b1 = tf.Variable(tf.random.uniform((1,), minval=-1, maxval=1))
        self.b2 = tf.Variable(tf.random.uniform((1,), minval=-1, maxval=1))
        self.a1 = tf.Variable(tf.random.uniform((1,), minval=-1, maxval=1))
        self.a2 = tf.Variable(tf.random.uniform((1,), minval=-1, maxval=1))
        

    def call(self, inputs):
      batch_size = tf.shape(inputs)[0]
      output_sequence = tf.TensorArray(dtype=tf.float32, size=0, dynamic_size=True, clear_after_read=False) 
      output_sequence = output_sequence.write(0, inputs[:, 0])
      output_sequence = output_sequence.write(1, inputs[:, 1])
      output_sequence = output_sequence.write(2, inputs[:, 2])

      for i in range(2, self.input_dim):
        output_sequence = output_sequence.write(i, self.b0*inputs[:, i] + self.b1*inputs[:, i-1] 
                                                 + self.b2*inputs[:, i-2] - self.a1*output_sequence.read(i-1)
                                                 - self.a2*output_sequence.read(i-2))
      result = output_sequence.stack()
      return tf.reshape(result, tf.shape(inputs))

iir = IIR(input_dim=60)
tf.print(iir(tf.random.normal((2, 60))).shape)

iir = IIR(input_dim=60)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Input(shape=60))
model.add(IIR(input_dim=60))
model.add(tf.keras.layers.Dense(8, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
print(model.summary())
TensorShape([2, 60])
Model: "sequential_21"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 iir_80 (IIR)                (None, 60)                5         
                                                                 
 dense_20 (Dense)            (None, 8)                 488       
                                                                 
 dense_21 (Dense)            (None, 1)                 9         
                                                                 
=================================================================
Total params: 502
Trainable params: 502
Non-trainable params: 0
_________________________________________________________________
None

【讨论】:

  • 谢谢,当我使用它作为模型中的一个层时会出现同样的错误:`ValueError: 试图将 'shape' 转换为张量并失败。错误:不支持任何值。请参阅帖子中的编辑。
  • 您期望的输出形状是什么?
  • 与输入相同,在这种情况下,是一个 60 个数据点长的向量(不确定当你想训练它们时,batch_size 是如何发挥作用的)
  • 只是补充一下,我希望权重 (b0, b1, b2, a1, a2) 是可训练的,所以只需将它们更改为 tf.Variable 但这可行。
  • 是的,没错,抱歉忘记了这一点。更新了答案。
猜你喜欢
  • 1970-01-01
  • 2020-04-29
  • 2016-07-30
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 2018-08-23
  • 2021-10-21
  • 1970-01-01
相关资源
最近更新 更多