#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. Да, верно, извини, забыл об этом аспекте. Обновленный ответ.