Я решаю проблему бинарной регрессии, используя keras.
Форма ввода: (None, 2, 94, 3)
(каналы — последнее измерение)
У меня есть следующая архитектура:
input1 = Input(shape=(time, n_rows, n_channels))
masking = Masking(mask_value=-999)(input1)
convlstm = ConvLSTM1D(filters=16, kernel_size=15,
data_format='channels_last',
activation = "tanh")(masking)
dropout = Dropout(0.2)(convlstm)
flatten1 = Flatten()(dropout)
outputs = Dense(n_outputs, activation='sigmoid')(flatten1)
model = Model(inputs=input1, outputs=outputs)
model.compile(loss=keras.losses.BinaryCrossentropy(),
optimizer=tf.keras.optimizers.Adam(learning_rate=0.01))
Однако при обучении я получаю эту ошибку: Dimensions must be equal, but are 94 and 80 for '{{node conv_lstm1d/while/SelectV2}} = SelectV2[T=DT_FLOAT](conv_lstm1d/while/Tile, conv_lstm1d/while/mul_5, conv_lstm1d/while/Placeholder_2)' with input shapes: [?,94,16], [?,80,16], [?,80,16].
Если я удалю маскирующий слой, эта ошибка исчезнет, что делает маскирование, вызывающее эту ошибку? Кроме того, единственный способ, которым я смог запустить описанную выше архитектуру, — это kernel_size
, равное 1.
Похоже, слою ConvLSTM1D
нужна маска формы (samples, timesteps)
в соответствии с документы. Маска, которую вы вычисляете, имеет форму (samples, time, rows)
. Вот одно из решений вашей проблемы, но я не уверен, что это «правильный» путь:
import tensorflow as tf
input1 = tf.keras.layers.Input(shape=(2, 94, 3))
masking = tf.keras.layers.Masking(mask_value=-999)(input1)
convlstm = tf.keras.layers.ConvLSTM1D(filters=16, kernel_size=15,
data_format='channels_last',
activation = "tanh")(inputs = masking, mask = tf.reduce_all(masking._keras_mask, axis=-1))
dropout = tf.keras.layers.Dropout(0.2)(convlstm)
flatten1 = tf.keras.layers.Flatten()(dropout)
outputs = tf.keras.layers.Dense(1, activation='sigmoid')(flatten1)
model = tf.keras.Model(inputs=input1, outputs=outputs)
model.compile(loss=tf.keras.losses.BinaryCrossentropy(),
optimizer=tf.keras.optimizers.Adam(learning_rate=0.01))
Эта строка mask = tf.reduce_all(masking._keras_mask, axis=-1)
существенно уменьшает вашу маску до (samples, timesteps)
, применяя операцию AND
к последнему измерению маски. Кроме того, вы можете просто создать свой собственный слой маски:
import tensorflow as tf
class Reduce(tf.keras.layers.Layer):
def __init__(self):
super(Reduce, self).__init__()
def call(self, inputs):
return tf.reduce_all(tf.reduce_any(tf.not_equal(inputs, -999), axis=-1, keepdims=False), axis=1)
input1 = tf.keras.layers.Input(shape=(2, 94, 3))
reduce_layer = Reduce()
boolean_mask = reduce_layer(input1)
convlstm = tf.keras.layers.ConvLSTM1D(filters=16, kernel_size=15,
data_format='channels_last',
activation = "tanh")(inputs = input1, mask = boolean_mask)
dropout = tf.keras.layers.Dropout(0.2)(convlstm)
flatten1 = tf.keras.layers.Flatten()(dropout)
outputs = tf.keras.layers.Dense(1, activation='sigmoid')(flatten1)
model = tf.keras.Model(inputs=input1, outputs=outputs)
model.compile(loss=tf.keras.losses.BinaryCrossentropy(),
optimizer=tf.keras.optimizers.Adam(learning_rate=0.01))
print(model.summary(expand_nested=True))
x = tf.random.normal((50, 2, 94, 3))
y = tf.random.uniform((50, ), maxval=3, dtype=tf.int32)
model.fit(x, y)
Также временные шаги будут равны строкам * времени?
Как я уже сказал, я не уверен, что это правильный путь. Я просто следил за документами.
Также временные шаги будут равны строкам * времени? --> вы определенно можете попробовать это
Я не уверен, что это правильно, потому что у меня также есть другая модель, которая принимает входную форму (None, 188, 3) и имеет маскирующий слой сразу после этого, после маскировки идет LSTM, который, согласно документам, нуждается в маске. формы (партия, timesetps). Однако форма вывода маскировки такая же, как и ввод, и во время обучения я не получаю ошибок.
Итак, я хочу сказать, что часть LSTM слоя ConvLSTM должна знать, что делать при получении вывода слоя маскировки. Но я не уверен
Я знаю, что вы имеете в виду, но обратите внимание, что слой LSTM и слой ConvLSTM ведут себя по-разному.
Согласитесь, но предоставленное вами решение преобразует маску в форму (Нет, 2), чего мне бы не хотелось. 2 — количество подпоследовательностей данного временного окна. 94 — это количество временных шагов в этой подпоследовательности, а 3 — это количество функций/каналов.
Я вижу, это имеет смысл. Однако почему обучение не дает сбоев при значении kernel_size, равном 1?