запутался в концепции временных шагов и формы вывода в keras.layers.RNN - PullRequest
0 голосов
/ 31 октября 2018

keras.layers.RNN

Форма ввода Трехмерный тензор с формой (batch_size, timesteps, input_dim).

Форма вывода

if return_state: список тензоров. Первый тензор - это выход. Остальные тензоры являются последними состояниями, каждое из которых имеет форму (batch_size, единицы).

if return_sequence: трехмерный тензор с формой (batch_size, временные шаги, единицы). остальное, 2D тензор с формой (размер партии, единицы).

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: Для слоя Concatenate требуются входные данные с соответствующими формами, за исключением оси concat. Получил входные формы: [(Нет, 32, 32, 16), (Нет, нет, 32, 1)]

Я думал, что форма sequence_output будет (Нет, 32, 32, 1). Но это было (Нет, Нет, 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_sequence и return_state True, а затем получил

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

1 Ответ

0 голосов
/ 31 октября 2018

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

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

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

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

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

...