I have an example of a neural network with two layers. The first layer takes two arguments and has one output. The second should take one argument as result of the first layer and one additional argument. It should looks like this:
x1 x2 x3 \ / / y1 / \ / y2
So, I'd created a model with two layers and tried to merge them but it returns an error: The first layer in a Sequential model must get an "input_shape" or "batch_input_shape" argument.
on the line result.add(merged)
.
Model:
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'])
Concatenate class Layer that concatenates a list of inputs. It takes as input a list of tensors, all of the same shape except for the concatenation axis, and returns a single tensor that is the concatenation of all inputs.
Keras has two basic organizational modes: "Sequential" and "Functional". concatenate is the functional version, and really just wraps the Concatenate layer.
A concatenation layer takes inputs and concatenates them along a specified dimension. The inputs must have the same size in all dimensions except the concatenation dimension. Specify the number of inputs to the layer when you create it. The inputs have the names 'in1','in2',...,'inN' , where N is the number of inputs.
In Keras there is a helpful way to define a model: using the functional API. With functional API you can define a directed acyclic graphs of layers, which lets you build completely arbitrary architectures. Considering your example:
It is used to concatenate two inputs. It is defined below − Functional interface to the Concatenate layer. Here, axis refers to Concatenation axis. It returns the dot product from two inputs. It is defined below − axes refer axes to perform the dot product.
Concatenate (axis =-1, ** kwargs) Layer that concatenates a list of inputs. It takes as input a list of tensors, all of the same shape except for the concatenation axis, and returns a single tensor that is the concatenation of all inputs.
You're getting the error because result
defined as Sequential()
is just a container for the model and you have not defined an input for it.
Given what you're trying to build set result
to take the third input 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 which 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'])
However, my preferred way of building a model that has this type of input structure would be to use the functional api.
Here is an implementation of your requirements to get you started:
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'])
To answer the question in the comments:
Concatenation works like this:
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
i.e rows are just joined.
x1
is input to first, x2
is input into second and x3
input into third.Adding to the above-accepted answer so that it helps those who are using 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)
Result:
------------------------------ x1 (2, 10) x2 (2, 10) x3 (2, 10) y1 (2, 20) y2 (2, 30) ------------------------------
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With