首页 > 解决方案 > 对 keras.layers.RNN 中时间步长和输出形状的概念感到困惑

问题描述

keras.layers.RNN

输入形状为形状的 3D 张量(batch_size、timesteps、input_dim)。

输出形状

if return_state:张量列表。第一个张量是输出。剩下的张量是最后的状态,每个状态都有形状(batch_size,units)。

if return_sequences:具有形状(batch_size、timesteps、units)的 3D 张量。否则,具有形状 (batch_size, units) 的 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图层需要具有匹配形状的输入,但连接轴除外。得到输入形状:[(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)' 然后我得到 ()输出

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

2.我将return_sequences和return_state设置为True,然后得到

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

标签: kerasrnn

解决方案


这个问题更适合交叉验证论坛,但没关系。

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

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

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

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


推荐阅读