我有一个模型(即spatial_model),该模型嵌套在时间模型中以构建CNN-LSTM模型。似乎TimeDistributed层不接受两个输入,而我的空间模型需要两个输入。因此,我不得不使用Lambda层来允许TImeDistributed接受多个输入。但是,当我打印Temporal_model的摘要时,似乎对空间模型的训练被忽略了。
from keras.layers import Dense, Dropout, Activation,Lambda,Input,LSTM
from keras.layers import Conv1D, MaxPooling1D,Flatten,TimeDistributed,Reshape
from keras.models import Model
import keras
# =============================================================================
#Spatial Part
#conv1d for temperature.......>
#concatente
#con1d for pressure .......>
# =============================================================================
# Conv1D Model 1
pnnl_temp=Input(shape=(200,1))
connv_temp1=Conv1D(filters=2,kernel_size=(10),strides=2,padding="valid" ,activation="relu")(pnnl_temp)
conv_maxpooling1=MaxPooling1D(pool_size=3,strides=1)(connv_temp1)
connv_temp2=Conv1D(filters=1,kernel_size=(10),strides=2,padding="valid" ,activation="relu")(conv_maxpooling1)
conv_maxpooling2=MaxPooling1D(pool_size=2,strides=None)(connv_temp2)
conv_maxpooling2_size=conv_maxpooling2.get_shape().as_list()[-1]*\
conv_maxpooling2.get_shape().as_list()[-2] # find the number of elements in tensor
conv_flatter_temp=Reshape((conv_maxpooling2_size,1))(conv_maxpooling2) #flatten layer returns (?,?)as dimension
# Conv1D Model 2
pnnl_pressure=Input(shape=(200,1))
connv_pressure1=Conv1D(filters=2,kernel_size=(10),strides=2,padding="valid" ,activation="relu")(pnnl_pressure)
conv_maxpooling_pressure1=MaxPooling1D(pool_size=3,strides=1)(connv_pressure1)
connv_pressure2=Conv1D(filters=1,kernel_size=(10),strides=2,padding="valid" ,activation="relu")(conv_maxpooling_pressure1)
conv_maxpooling_pressure2=MaxPooling1D(pool_size=2,strides=None)(connv_pressure2)
conv_maxpooling2_size_pressure=conv_maxpooling_pressure2.get_shape().as_list()[-1]*\
conv_maxpooling_pressure2.get_shape().as_list()[-2]
conv_flatter_pressure=Reshape((conv_maxpooling2_size,1))(conv_maxpooling_pressure2)
# Merge Conv1D 1&2
output = keras.layers.concatenate([conv_flatter_pressure, conv_flatter_temp], axis=1)
spatial_model=Model([pnnl_temp,pnnl_pressure],output)
#=============================================================================
# temporal part
#x1.....>
#spatial_model ....> time distributed layer .....>lstm ......
#x2....>
# =============================================================================
x1 = Input(shape=(224, 200, 1))
x2 = Input(shape=(224, 200, 1))
new_input=keras.layers.concatenate([x1,x2],axis=3)
encoded_frame_sequence = TimeDistributed(Lambda(lambda x:spatial_model([x[:,:,0:1],x[:,:,1:]] )))(new_input) # used lambda to allow multiple input for TimeDistributed
new_encoded_frame_sequence=Reshape((224,42))(encoded_frame_sequence)
lastm_1=LSTM(52)(new_encoded_frame_sequence)
Temporal_model =Model([x1,x2],lastm_1)
以下是Temporal_model的摘要。如您所见,TimeDistributed的参数数量为零,但应与spacespace_model的参数相等。
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_11 (InputLayer) (None, 224, 200, 1) 0
__________________________________________________________________________________________________
input_12 (InputLayer) (None, 224, 200, 1) 0
__________________________________________________________________________________________________
concatenate_6 (Concatenate) (None, 224, 200, 2) 0 input_11[0][0]
input_12[0][0]
__________________________________________________________________________________________________
time_distributed_4 (TimeDistrib (None, 224, 42, 1) 0 concatenate_6[0][0]
__________________________________________________________________________________________________
reshape_9 (Reshape) (None, 224, 42) 0 time_distributed_4[0][0]
__________________________________________________________________________________________________
lstm_4 (LSTM) (None, 52) 19760 reshape_9[0][0]
==================================================================================================
Total params: 19,760
Trainable params: 19,760
Non-trainable params: 0
__________________________________________________________________________________________________
除了使用lambda之外,是否有任何其他方法可以将多个张量输入到TimeDistributed? 如何使Lambda层可训练? 任何帮助或建议,表示赞赏。
答案 0 :(得分:0)
如果有人有类似的问题,则应注意,Lambda层无法接受训练,因此必须使用自定义的keras层,这可能很棘手。因此,一种简单的解决方案是输入一个输入并将输入拆分到模型中。以下是我使用的技巧:
whole_input=Input(shape=(400,1))
split=Lambda(lambda x: tf.split(x,2,axis=1))(whole_input)
pnnl_temp=split[0]
pnnl_pressure=split[1]
通过这种方式,您无需在TimeDistributed内部使用lambda层,并且您的TimeDistributed可以接受多个输入,因为它们将在模型中拆分。