Входная форма подкласса слоя тензорного потока

#python #tensorflow #keras #deep-learning

Вопрос:

Я пытаюсь создать пользовательский слой из layers.Layer экземпляра TensorFlow.

Я пытаюсь создать 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 "lt;ipython-input-37-0717fc982e73gt;", 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')  

Комментарии:

1. Можете ли вы объяснить, что вы пытаетесь сделать в этих строках: outt[0] = inputs[0] outt[1] = inputs[1] outt[2] = inputs[2]

2. @AloneTogether Я пытаюсь установить первые 3 элемента выходного массива равными входным, чтобы выполнить процесс с третьего индекса вперед

Ответ №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  

Комментарии:

1. Спасибо, та же ошибка возникает, когда я использую это в качестве слоя в модели: «Ошибка значения: Попытался преобразовать «форму» в тензор и потерпел неудачу. Ошибка: Значения None не поддерживаются., пожалуйста, ознакомьтесь с правкой в сообщении.

2. какую форму вывода вы ожидаете?

3. То же самое, что и входные данные, в данном случае вектор длиной 60 точек данных (не уверен, как batch_size вступает в игру, когда вы хотите их обучить)

4. просто чтобы добавить, я хотел, чтобы веса (b0, b1, b2, a1, a2) были обучаемыми, поэтому просто изменил их на tf.Variable, но это работает.

5. Да, верно, извини, забыл об этом аспекте. Обновленный ответ.