Tensorflow 2.0: вывод формы с помощью Reshape не возвращает измерение None - PullRequest
1 голос
/ 29 мая 2020

Я работаю с моделью CNN-LSTM в Tensorflow 2.0 + Keras для выполнения классификации последовательностей. Моя модель определяется следующим образом:

    inp = Input(input_shape)
    rshp = Reshape((input_shape[0]*input_shape[1], 1), input_shape=input_shape)(inp)
    cnn1 = Conv1D(100, 9, activation='relu')(rshp)
    cnn2 = Conv1D(100, 9, activation='relu')(cnn1)
    mp1 = MaxPooling1D((3,))(cnn2)
    cnn3 = Conv1D(50, 3, activation='relu')(mp1)
    cnn4 = Conv1D(50, 3, activation='relu')(cnn3)
    gap1 = AveragePooling1D((3,))(cnn4)
    dropout1 = Dropout(rate=dropout[0])(gap1)
    flt1 = Flatten()(dropout1)
    rshp2 = Reshape((input_shape[0], -1), input_shape=flt1.shape)(flt1)
    bilstm1 = Bidirectional(LSTM(240,
                                 return_sequences=True,
                                 recurrent_dropout=dropout[1]),
                            merge_mode=merge)(rshp2)
    dense1 = TimeDistributed(Dense(30, activation='relu'))(rshp2)
    dropout2 = Dropout(rate=dropout[2])(dense1)
    prediction = TimeDistributed(Dense(1, activation='sigmoid'))(dropout2)

    model = Model(inp, prediction, name="CNN-bLSTM_per_segment")
    print(model.summary(line_length=75))

Где input_shape = (60, 60). Однако это определение вызывает следующую ошибку:

TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

Сначала я подумал, что это потому, что слой rshp2 не может изменить форму вывода flt1 на форму (60, X). Итак, я добавил блок печати перед слоем Bidirectional(LSTM)):

    print('reshape1: ', rshp.shape)
    print('cnn1: ', cnn1.shape)
    print('cnn2: ', cnn2.shape)
    print('mp1: ', mp1.shape)
    print('cnn3: ', cnn3.shape)
    print('cnn4: ', cnn4.shape)
    print('gap1: ', gap1.shape)
    print('flatten 1: ', flt1.shape)
    print('reshape 2: ', rshp2.shape)

И формы были:

reshape 1:  (None, 3600, 1)
cnn1:  (None, 3592, 100)
cnn2:  (None, 3584, 100)
mp1:  (None, 1194, 100)
cnn3:  (None, 1192, 50)
cnn4:  (None, 1190, 50)
gap1:  (None, 396, 50)
flatten 1:  (None, 19800)
reshape 2:  (None, 60, None)

Если посмотреть на слой flt1, его выходная форма будет (19800,), который можно изменить как (60, 330), но по какой-то причине (60, -1) слоя rshp2 работает не так, как задумано, о чем свидетельствует печать reshape 2: (None, 60, None). Когда я пытаюсь изменить форму как (60, 330), все работает нормально. Кто-нибудь знает, почему не работает (-1)?

1 Ответ

1 голос
/ 29 мая 2020

-1 работает.

Из документации Reshape, https://www.tensorflow.org/api_docs/python/tf/keras/layers/Reshape

слой возвращает тензор с формой (batch_size,) + target_shape

Итак, размер партии остается прежним, другие размеры рассчитываются на основе вашего target_shape.

Из do c, посмотрите на последний пример,

# also supports shape inference using `-1` as dimension
model.add(tf.keras.layers.Reshape((-1, 2, 2)))
model.output_shape

(None, None, 2, 2)

Если вы передадите -1 в целевой форме, Keras сохранит None, это полезно, если вы ожидаете данные переменной длины на этой оси, но если ваша форма данных всегда То же самое, просто укажите размер жестко запрограммированным, который будет размещать размер при печати фигуры позже.

NB: Также нет необходимости указывать input_shape=input_shape для промежуточных слоев в функциональном API. Модель сделает это за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...