Mesclando dois modelos diferentes no Keras

26

Estou tentando mesclar dois modelos Keras em um único modelo e não consigo fazer isso.

Por exemplo, na Figura em anexo, gostaria de buscar a camada intermediária da dimensão 8 e usá-la como entrada para a camada (da dimensão 8 novamente) no Modelo e depois combinar o Modelo A e o Modelo B como um único modelo.UMA2B1 1BUMAB

Estou usando o módulo funcional para criar o Modelo UMA e o Modelo B independente. Como posso realizar esta tarefa?

Nota : UMA1 1 é a camada de entrada para o modelo de UMA e B1 1 representa a camada de entrada para o modelo de B .

Ver foto

Rkz
fonte

Respostas:

22

Eu descobri a resposta para minha pergunta e aqui está o código que se baseia na resposta acima.

from keras.layers import Input, Dense
from keras.models import Model
from keras.utils import plot_model

A1 = Input(shape=(30,),name='A1')
A2 = Dense(8, activation='relu',name='A2')(A1)
A3 = Dense(30, activation='relu',name='A3')(A2)

B2 = Dense(40, activation='relu',name='B2')(A2)
B3 = Dense(30, activation='relu',name='B3')(B2)

merged = Model(inputs=[A1],outputs=[A3,B3])
plot_model(merged,to_file='demo.png',show_shapes=True)

e aqui está a estrutura de saída que eu queria:

insira a descrição da imagem aqui

Rkz
fonte
Observe que você não está mesclando dois modelos (no sentido de keras Model) acima, você está mesclando camadas.
gented
7

No Keras, existe uma maneira útil de definir um modelo: usando a API funcional . Com a API funcional, você pode definir gráficos acíclicos direcionados de camadas, o que permite construir arquiteturas completamente arbitrárias. Considerando o seu exemplo:

#A_data = np.zeros((1,30))
#A_labels = np.zeros((1,30))
#B_labels =np.zeros((1,30))

A1 = layers.Input(shape=(30,), name='A_input')
A2 = layers.Dense(8, activation='???')(A1)
A3 = layers.Dense(30, activation='???', name='A_output')(A2)


B2 = layers.Dense(40, activation='???')(A2)
B3 = layers.Dense(30, activation='???', name='B_output')(B2)

## define A
A = models.Model(inputs=A1, outputs=A3)

## define B
B = models.Model(inputs=A1, outputs=B3) 

B.compile(optimizer='??',
          loss={'B_output': '??'}
          )

B.fit({'A_input': A_data},
  {'B_output': B_labels},
  epochs=??, batch_size=??)

Então é isso! Você pode ver o resultado por B.summary()::

Layer (type)                 Output Shape              Param    
A_input (InputLayer)         (None, 30)                0         
_________________________________________________________________
dense_8 (Dense)              (None, 8)                 248     
______________________________________________________________
dense_9 (Dense)              (None, 40)                360       
_________________________________________________________________
B_output (Dense)             (None, 30)                1230      
moh
fonte
Obrigado pela resposta, mas não acho que o código acima funcione. Primeiro, quando você diz B = models.Model (entradas = A2, saídas = B3), ocorrerá um erro TypeError: Camadas de entrada para a Modeldevem ser InputLayerobjetos. Entradas recebidas: Tensor. Além disso, como mencionado anteriormente, usei a API funcional para criar o Modelo A e o Modelo B separadamente. Eu acho que a resposta que estou procurando pode ter a ver com a seção "Modelos de entradas múltiplas e saídas múltiplas" na documentação do keras que usa a função concatenar (embora não tenha certeza).
RKZ
@Rkz: Eu editei a resposta. Funciona agora. Temos que usar "concatenar". Na verdade, você deve mencionar a entrada principal (A1) quando desejar definir o modelo "B".
moh
Obrigado pelo seu tempo e edições. Eu descobri a resposta da documentação do Keras (veja a resposta a seguir). Não exigi concatenar para minha pergunta.
RKZ
@Rkz: Veja a edição final, também mostro como compilar e ajustar o modelo.
moh