вложенная модель в лямбда-слое не обучаема - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть модель (т. Е. Пространственная_модель), которая вложена во временную модель для построения модели CNN-LSTM.Кажется, что слой TimeDistributed не принимает два входа, в то время как моей пространственной модели нужны два входа.Таким образом, мне пришлось использовать лямбда-слой, чтобы 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 равно нулю, в то время как оно должно быть равно параметрам пространственной_модели.

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
__________________________________________________________________________________________________

Есть ли способ ввести несколько тензоров в TimeDistributed, кроме как с помощью лямбды?Как сделать лямбда-слой пригодным для обучения?Любая помощь или предложение приветствуется.

1 Ответ

0 голосов
/ 22 февраля 2019

В случае, если у кого-либо есть подобный вопрос, вы должны заметить, что лямбда-слой не может быть обучен, и вы должны использовать настроенный слой 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, и ваш TimeDistributed может принимать несколько входов, так как они будут разделены внутри модели.

...