Запутался в концепции временных шагов и формы вывода в keras.layers.rnn

keras.layers.RNN

Input shape 3D tensor with shape (batch_size, timesteps, input_dim).

Output shape

if return_state: a list of tensors. The first tensor is the output. The remaining tensors are the last states, each with shape (batch_size, units).

if return_sequences: 3D tensor with shape (batch_size, timesteps, units). else, 2D tensor with shape (batch_size, units).

1. Меня смущает концепция временных шагов.

2. Меня смущает процесс, связанный с вводом трех осей.

Упрощенный код

import keras
from keras.applications.inception_resnet_v2 import InceptionResNetV2
from keras.applications.mobilenet import MobileNet
from keras.applications.vgg19 import VGG19
from keras.applications.densenet import DenseNet
from keras.preprocessing import image
from keras.engine import Layer
from keras.applications.inception_resnet_v2 import preprocess_input
from keras.layers import Conv2D, UpSampling2D, InputLayer, Conv2DTranspose, Input, Reshape, merge, concatenate
from keras.layers import Activation, Dense, Dropout, Flatten
from keras.layers.normalization import BatchNormalization
from keras.callbacks import TensorBoard 
from keras.models import Sequential, Model
from keras.layers.core import RepeatVector, Permute
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
from skimage.color import rgb2lab, lab2rgb, rgb2gray, gray2rgb
from skimage.transform import resize
from skimage.io import imsave
import numpy as np
import os
import random
import tensorflow as tf
import keras.backend as K
from keras.layers.recurrent import GRU
from keras.layers.merge import add

encoder_input = Input(shape=(32, 32, 1))

rnn_size = 16
encoder_output = Conv2D(16, (3,3), activation='relu', padding='same')(encoder_input)
sequence_output = Reshape(target_shape=(32, 512))(encoder_output)  
gru_1 = GRU(rnn_size, return_sequences=False,kernel_initializer='he_normal', name='gru1')(sequence_output)
gru_1b = GRU(rnn_size, return_sequences=True, go_backwards=True, kernel_initializer='he_normal', name='gru1_b')(sequence_output)
gru1_merged = add([gru_1, gru_1b])
gru_2 = GRU(rnn_size, return_sequences=True,kernel_initializer='he_normal', name='gru2')(gru1_merged)
gru_2b = GRU(rnn_size, return_sequences=True, go_backwards=True, kernel_initializer='he_normal', name='gru2_b')(gru1_merged)
sequence_output = concatenate([gru_2, gru_2b])
sequence_output = K.expand_dims(sequence_output, 3)
fusion_output = concatenate([encoder_output,sequence_output ], axis=3) 

model = Model(inputs=encoder_input, outputs=fusion_output)
model.summary()

ошибка вывода

ValueError: A Concatenate layer requires inputs with matching shapes except for the concat axis. Got inputs shapes: [(None, 32, 32, 16), (None, None, 32, 1)]

Я думал, что форма "sequence_output" будет (None, 32, 32, 1). Но это было (None, None, 32, 1). Я не знал, что пошло не так, поэтому я начал сомневаться в своем понимании RNN. .

Что я наделал

1. выход gru1 и gru_1b

после аннотации:

'#sequence_output = K.expand_dims (sequence_output, 3)'

'#fusion_output = concatenate ([encoder_output, sequence_output], axis = 3)' Потом получил () output

Меня очень смущает форма gru1 и gru_1b. Почему они разные?

2. Я установил return_sequences и return_state True, а затем получил

valueerror:  На самом деле я понятия не имею, что делать дальше.

0
0
1 269
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Этот вопрос больше подходит для форума с перекрестной проверкой, но нормально.

Итак, чтобы ответить на ваш первый вопрос, временные шаги - это просто число, обозначающее длину последовательности. RNN работают определенным образом, потому что они имеют постоянное соединение с собой. Очень хорошее объяснение RNN дается здесь на примере LSTM. Там вы можете увидеть разницу между cell state и state.

Чтобы ответить на второй вопрос, (batch_size, timesteps, units) - это выходное измерение. timesteps - это снова размерность входной последовательности, и это то, что вы должны стандартизировать и определить для формы ввода (все последовательности на входе должны быть одинаковой длины, если это не так, вы должны дополнить их до указанной длины). units - это размерность вывода, это вывод каждой ячейки RNN в вашем слое.

Вся суть этих аргументов return_state и return_sequences - это то, что вам нужно для следующего уровня и для ваших вычислений. Первый - вернуть состояние ячейки в качестве первого элемента вывода. Второй - это состояния после каждого временного шага. Таким образом, после чтения каждого слова (или элемента последовательности) RNN обновляет state на основе считываемого входного элемента и cell state. Таким образом, с return_sequences вы можете получить последовательность после обработки каждого слова внутри RNN и обновления state.

Я думаю, что все станет намного яснее после того, как вы прочтете тот пост в блоге, на который я указал в этом ответе. Надеюсь, это поможет :)

Спасибо за ваше предложение. Я прочитал сообщение, на которое вы указали ссылку. Но я все еще борюсь. Я упрощаю код, который отображает причину, по которой я задал этот вопрос.

yangze zhao 01.11.2018 04:54

Попробуйте распечатать форму gru_1 и gru_1b. Попытайтесь понять, почему формы такие. Также попробуйте создать слои со всеми комбинациями return_sequences и return_state и посмотрите, какие формы будут на выходе. Думаю, это прояснит для вас ситуацию. Если вам все еще сложно понять, вставьте выходные формы каждого созданного слоя в свой вопрос, и я постараюсь объяснить вам это подробно. Но я считаю, что будет лучше, если вы попытаетесь разобраться в этом в одиночку.

Novak 01.11.2018 10:22

Спасибо, что уделили время моему вопросу. Я попытался распечатать gru_1 и установить return_stare = True. Я вставил то, что сделал.

yangze zhao 02.11.2018 04:24

Без проблем. Хорошо, теперь посмотрим, как у gru_1b есть еще одна форма. Это потому, что gru_1b имеет return_sequences, установленный на True. Ваш ввод имеет длину 32. Это означает, что после каждой части ввода (каждого временного шага) gru_1b генерирует последовательность и сохраняет ее в тензоре возврата. Отсюда одно дополнительное измерение вывода. Теперь, с учетом сказанного, я надеюсь, что стало понятнее, как работать с RNN в Керасе. Если вы создаете последовательные nn, я рекомендую установить return_sequences=False и return_state=False. Это даст вам только один тензор, самый простой, на выходе. Это должно работать как самый простой случай.

Novak 02.11.2018 08:00

Другие вопросы по теме