对 keras.layers.RNN 中的时间步长和输出形状的概念感到困惑

confused about the concept of timesteps and output shape in 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.I 对时间步的概念感到困惑。

2.I 搞不懂三轴输入的处理过程

简化代码

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.output gru1 和 gru_1b

注释后:

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

'#fusion_output = concatenate([encoder_output,sequence_output ],axis=3)' 然后我得到了 ()

我对 gru1 和 gru_1b 的形状很困惑。为什么它们不同?

2.I set return_sequences and return_state True 然后得到

值错误: 事实上我不知道下一步该做什么。

这个问题更适合交叉验证论坛,但还可以。

所以要回答你的第一个问题,时间步长只是一个表示序列长度的数字。 RNN 以特定方式工作,因为它们有一个返回自身的循环连接。在 LSTM 的例子中 here 给出了 RNN 的很好的解释。在那里你可以看到 cell statestate.

之间的区别

回答第二个问题,(batch_size, timesteps, units)是一个输出维度。 timesteps 又是输入序列的维数,你应该在输入形状上对其进行标准化和定义(输入上的所有序列必须具有相同的长度,如果不是,你应该将它们填充到指定长度)。 units 是输出的维度,它是层中每个 RNN 单元的输出。

那些 return_statereturn_sequences 参数的全部要点是您对下一层和计算所需要的。第一个是 return 细胞状态作为输出的第一个元素。第二个是每个时间步之后的状态。因此,在读取每个单词(或序列元素)后,RNN 会根据读取的输入元素和 cell state 更新 state。因此,使用 return_sequences 您可以在 RNN 内部处理每个单词并且更新 state 后获得序列。

我认为在您阅读该博客后一切都会更加清晰 post 我在这个答案中链接了。希望对您有所帮助:)