Wie verkette ich zwei Schichten in Keras?


91

Ich habe ein Beispiel für ein neuronales Netzwerk mit zwei Schichten. Die erste Ebene akzeptiert zwei Argumente und hat eine Ausgabe. Das zweite sollte ein Argument als Ergebnis der ersten Schicht und ein zusätzliches Argument annehmen. Es sollte so aussehen:

x1  x2  x3
 \  /   /
  y1   /
   \  /
    y2

Also habe ich ein Modell mit zwei Ebenen erstellt und versucht, sie zusammenzuführen, aber es wird ein Fehler zurückgegeben: The first layer in a Sequential model must get an "input_shape" or "batch_input_shape" argument.in der Zeile result.add(merged).

Modell:

first = Sequential()
first.add(Dense(1, input_shape=(2,), activation='sigmoid'))

second = Sequential()
second.add(Dense(1, input_shape=(1,), activation='sigmoid'))

result = Sequential()
merged = Concatenate([first, second])
ada_grad = Adagrad(lr=0.1, epsilon=1e-08, decay=0.0)
result.add(merged)
result.compile(optimizer=ada_grad, loss=_loss_tensor, metrics=['accuracy'])

Antworten:


119

Sie erhalten den Fehler, weil resultdefiniert als Sequential()nur ein Container für das Modell definiert ist und Sie keine Eingabe dafür definiert haben.

Angesichts dessen, was Sie erstellen möchten, setzen resultSie die dritte Eingabe x3.

first = Sequential()
first.add(Dense(1, input_shape=(2,), activation='sigmoid'))

second = Sequential()
second.add(Dense(1, input_shape=(1,), activation='sigmoid'))

third = Sequential()
# of course you must provide the input to result with will be your x3
third.add(Dense(1, input_shape=(1,), activation='sigmoid'))

# lets say you add a few more layers to first and second.
# concatenate them
merged = Concatenate([first, second])

# then concatenate the two outputs

result = Concatenate([merged,  third])

ada_grad = Adagrad(lr=0.1, epsilon=1e-08, decay=0.0)

result.compile(optimizer=ada_grad, loss='binary_crossentropy',
               metrics=['accuracy'])

Meine bevorzugte Methode zum Erstellen eines Modells mit dieser Art von Eingabestruktur wäre jedoch die Verwendung der funktionalen API .

Hier ist eine Implementierung Ihrer Anforderungen, um Ihnen den Einstieg zu erleichtern:

from keras.models import Model
from keras.layers import Concatenate, Dense, LSTM, Input, concatenate
from keras.optimizers import Adagrad

first_input = Input(shape=(2, ))
first_dense = Dense(1, )(first_input)

second_input = Input(shape=(2, ))
second_dense = Dense(1, )(second_input)

merge_one = concatenate([first_dense, second_dense])

third_input = Input(shape=(1, ))
merge_two = concatenate([merge_one, third_input])

model = Model(inputs=[first_input, second_input, third_input], outputs=merge_two)
ada_grad = Adagrad(lr=0.1, epsilon=1e-08, decay=0.0)
model.compile(optimizer=ada_grad, loss='binary_crossentropy',
               metrics=['accuracy'])

Um die Frage in den Kommentaren zu beantworten:

1) Wie sind Ergebnis und Zusammenführung verbunden? Angenommen, Sie meinen, wie werden sie verkettet?

Die Verkettung funktioniert folgendermaßen:

  a        b         c
a b c   g h i    a b c g h i
d e f   j k l    d e f j k l

dh Zeilen werden gerade verbunden.

2) Jetzt x1wird in den ersten eingegeben, x2wird in den zweiten und x3in den dritten eingegeben.


Wie sind resultund merged(oder merged2) Ebenen im ersten Teil Ihrer Antwort miteinander verbunden?
rdo

und die zweite Frage. Wie ich verstehe x1und x2ein Input für first_input, x3für third_input. Was ist mit second_input?
rdo

1
second_inputwird durch eine DenseSchicht geleitet und verkettet, mit first_inputder auch eine DenseSchicht durchlaufen wurde . third_inputwird durch eine dichte Schicht geleitet und die mit dem Ergebnis der vorherigen Verkettung ( merged) verkettete
parsethis

2
@putonspectacles Die zweite Möglichkeit, die funktionale API zu verwenden, funktioniert. Die erste Möglichkeit, ein sequentielles Modell zu verwenden, funktioniert in Keras 2.0.2 für mich jedoch nicht. Ich habe die Implementierung grob überprüft und das Aufrufen von "Verketten ([...])" macht nicht viel. Außerdem können Sie es keinem sequentiellen Modell hinzufügen. Ich denke tatsächlich, dass man immer noch die beraubte Methode "Merge ([...], 'concat')" verwenden muss, bis Keras aktualisiert wird. Was denken Sie?
LFish

2
Was ist der Unterschied zwischen Concatenate()und concatenate()Ebenen in Keras?
Leevo

7

Sie können experimentieren model.summary()(beachten Sie die Ebenengröße concatenate_XX (Concatenate)).

# merge samples, two input must be same shape
inp1 = Input(shape=(10,32))
inp2 = Input(shape=(10,32))
cc1 = concatenate([inp1, inp2],axis=0) # Merge data must same row column
output = Dense(30, activation='relu')(cc1)
model = Model(inputs=[inp1, inp2], outputs=output)
model.summary()

# merge row must same column size
inp1 = Input(shape=(20,10))
inp2 = Input(shape=(32,10))
cc1 = concatenate([inp1, inp2],axis=1)
output = Dense(30, activation='relu')(cc1)
model = Model(inputs=[inp1, inp2], outputs=output)
model.summary()

# merge column must same row size
inp1 = Input(shape=(10,20))
inp2 = Input(shape=(10,32))
cc1 = concatenate([inp1, inp2],axis=1)
output = Dense(30, activation='relu')(cc1)
model = Model(inputs=[inp1, inp2], outputs=output)
model.summary()

Sie können das Notizbuch hier für Details anzeigen: https://nbviewer.jupyter.org/github/anhhh11/DeepLearning/blob/master/Concanate_two_layer_keras.ipynb


3
Was ist der Unterschied zwischen Concatenate()und concatenate()Ebenen in Keras?
Leevo

1
Haben Sie den Unterschied herausgefunden, eine ist eine Keras-Klasse und eine andere ist eine Tensorflow-Methode
Abacusreader

7

Hinzufügen zu der oben akzeptierten Antwort, damit es denjenigen hilft, die sie verwenden tensorflow 2.0


import tensorflow as tf

# some data
c1 = tf.constant([[1, 1, 1], [2, 2, 2]], dtype=tf.float32)
c2 = tf.constant([[2, 2, 2], [3, 3, 3]], dtype=tf.float32)
c3 = tf.constant([[3, 3, 3], [4, 4, 4]], dtype=tf.float32)

# bake layers x1, x2, x3
x1 = tf.keras.layers.Dense(10)(c1)
x2 = tf.keras.layers.Dense(10)(c2)
x3 = tf.keras.layers.Dense(10)(c3)

# merged layer y1
y1 = tf.keras.layers.Concatenate(axis=1)([x1, x2])

# merged layer y2
y2 = tf.keras.layers.Concatenate(axis=1)([y1, x3])

# print info
print("-"*30)
print("x1", x1.shape, "x2", x2.shape, "x3", x3.shape)
print("y1", y1.shape)
print("y2", y2.shape)
print("-"*30)

Ergebnis:

------------------------------
x1 (2, 10) x2 (2, 10) x3 (2, 10)
y1 (2, 20)
y2 (2, 30)
------------------------------
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.