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

时间:2018-10-31 12:55:48

标签: keras rnn

  

keras.layers.RNN

     

输入形状   具有形状(batch_size,时间步长,input_dim)的3D张量。

     

输出形状

     

if return_state:张量列表。第一个张量是输出。其余的张量是最后一个状态,每个状态都有形状(batch_size,单位)。

     

如果return_sequences:具有形状(batch_size,时间步长,单位)的3D张量。   否则,二维张量具有形状(batch_size,单位)。

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'的形状应该是(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:  实际上,我不知道下一步该怎么做。

1 个答案:

答案 0 :(得分:0)

此问题更适合“交叉验证”论坛,但可以。

因此,要回答您的第一个问题,时间步长只是一个数字,表示一个序列的长度。 RNN以一种特定的方式工作,因为它们与自身具有经常性的连接。在LSTM的示例中,here对RNN进行了很好的解释。在那里,您可以看到cell statestate之间的区别。

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

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

我认为,在阅读了我在此答案中链接的博客文章后,一切都会更加清晰。我希望这会有所帮助:)