如何实现 LSTM 层之间的跳跃连接结构

Yu *_*ang 3 machine-learning deep-learning lstm keras tensorflow

最近学习了ResNet的skip connection,发现这种网络结构在训练过程中可以提高很多,而且在U-net等卷积网络中也适用。但是,我不知道如何使用 LSTM 自动编码器网络实现类似的结构。看起来我被一些维度问题困住了......我正在使用keras的方法来实现,但我不断收到错误。所以这是网络代码:

# lstm autoencoder recreate sequence
from numpy import array
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import RepeatVector
from keras.layers import TimeDistributed
from keras.utils import plot_model
# from keras import regularizers
from keras.regularizers import l1
from keras.optimizers import Adam
import keras.backend as K
model = Sequential()
model.add(LSTM(512, activation='selu', input_shape=(n_in,1),return_sequences=True))
model.add(LSTM(256, activation='selu',return_sequences=True)) 
model.add(LSTM(20, activation='selu'))  
model.add(RepeatVector(n_in))
model.add(LSTM(20, activation='selu',return_sequences=True)) 
model.add(LSTM(256, activation='selu',return_sequences=True)) 
model.add(LSTM(512, activation='selu', return_sequences=True))
model.add(TimeDistributed(Dense(1)))
# model.add
plot_model(model=model, show_shapes=True)
Run Code Online (Sandbox Code Playgroud)

就像在 resnet 或unet 中跳过连接图一样,我尝试像这样修改网络: 没有蓝线的网络是原始网络

编码器 lstm 层的输出还组合(连接或添加?)前一层输出作为解码器 lstm 层的输入。如图所示,相应的层是对称的。这种连接的想法可能吗?但我对 keras API 和跳过连接结构很陌生,我不知道如何实现它。

Pab*_*ang 5

首先,您需要开始使用函数式 API 而不是 Sequential。函数式 API 允许您在每一层中构建任意输入和输出连接,而不是堆叠网络。

了解有关函数式 API 的更多信息: https ://keras.io/guides/featured_api/

关于从 LSTM 层构建跳跃连接,就像为任何类型的层构建跳跃一样简单。我将向您展示示例代码:

input = Input(shape=input_shape)
a = LSTM(32, return_sequences=True)(input)

x = LSTM(64, return_sequences=True)(a) # main1 
a = LSTM(64, return_sequences=True)(a) # skip1

x = LSTM(64, return_sequences=True)(x) # main1
x = LSTM(64, return_sequences=True)(x) # main1

b = Add()([a,x]) # main1 + skip1

x = LSTM(128, return_sequences=True)(b) # main2
b = LSTM(128, return_sequences=True)(b) # skip2

x = LSTM(128, return_sequences=True)(x) # main2
x = LSTM(128, return_sequences=True)(x) # main2

c = Add()([b,x]) # main2 + skip2

x = LSTM(256, return_sequences=False)(c)

x = Dense(512, activation='relu')(x)
x = Dense(128, activation='relu')(x)

x = Dense(2, activation='softmax')(x)
model = Model(input, x)
Run Code Online (Sandbox Code Playgroud)

该代码将生成以下网络:

在此输入图像描述

正如您所看到的,该Add层接收前一层加上块之前的层(第一个块中的a )作为参数。

由于 Add 要求所有参数具有相同的形状,因此您必须LSTM在跳过侧添加一个额外的值,以均衡块的开头和结尾的形状(与原始 ResNet 的概念相同)。

当然,你应该打乱这个网络,添加不同类型的层、Dropout则化器Activation或任何你选择适合你的情况的东西。这只是一个树桩网络,用于显示与 LSTM 的跳跃连接。

其余部分与您已经训练过的任何其他网络几乎相同。