Scalenie dwóch różnych modeli w Keras

26

Próbuję scalić dwa modele Keras w jeden model i nie jestem w stanie tego osiągnąć.

Na przykład na załączonym rysunku chciałbym pobrać środkową warstwę o wymiarze 8 i użyć jej jako danych wejściowych do warstwy (ponownie o wymiarze 8) w Modelu a następnie połączyć Model i Model jako jeden Model.B 1 B A BA2B1BAB

Używam modułu funkcjonalnego do niezależnego tworzenia modelu i modeluJak mogę wykonać to zadanie?B.AB

Uwaga : jest warstwa wejściowa do modelu i jest warstwa wejściowa do modelu .A B 1 BA1AB1B

Widzieć zdjęcie

Rkz
źródło

Odpowiedzi:

22

Wymyśliłem odpowiedź na moje pytanie i oto kod, który opiera się na powyższej odpowiedzi.

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)

a oto struktura wyjściowa, którą chciałem:

wprowadź opis zdjęcia tutaj

Rkz
źródło
Zauważ, że jesteś nie scalanie dwóch modeli (w sensie Keras Modelu) powyżej, jesteś scalanie warstw.
gented
7

W Keras istnieje przydatny sposób zdefiniowania modelu: użycie funkcjonalnego interfejsu API . Dzięki funkcjonalnemu interfejsowi API można zdefiniować ukierunkowane acykliczne wykresy warstw, co pozwala budować całkowicie dowolne architektury. Biorąc pod uwagę twój przykład:

#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=??)

Więc to jest to! Możesz zobaczyć wynik 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
źródło
Dzięki za odpowiedź, ale nie sądzę, aby powyższy kod działał. Po pierwsze, gdy powiesz B = modele. Model (dane wejściowe = A2, dane wyjściowe = B3) wyświetli błąd TypeError: Warstwy wejściowe w obiektach Modelmuszą być InputLayerobiektami. Otrzymane dane wejściowe: Tensor. Ponadto, jak wspomniano wcześniej, użyłem funkcjonalnego interfejsu API do utworzenia modelu A i modelu B osobno. Myślę, że odpowiedź, której szukam, może mieć związek z sekcją „Modele z wieloma wejściami i wieloma wyjściami” w dokumentacji kamera, która korzysta z funkcji konkatenacji (choć nie do końca pewna).
Rkz
@ Rkz: Zredagowałem odpowiedź. Teraz działa. Musimy użyć „konkatenatu”. Właściwie powinieneś wspomnieć o głównym wejściu (A1), kiedy chcesz zdefiniować model „B”.
moh
Dziękujemy za poświęcony czas i zmiany. Dowiedziałem się odpowiedzi z dokumentacji Keras (patrz następująca odpowiedź). Nie wymagałem konkatenacji na moje pytanie.
Rkz
@ Rkz: Spójrz na ostatnią edycję, pokazuję również, jak skompilować i dopasować model.
moh