Multi-Input Keras NN train with batch data preparation
I would like to use Keras to train a multi-input NN with a series of training data, but I am unable to pass a set of input and output samples to do a fit or train_on_batch on the model.
My NN is defined as the following:
i1 = keras.layers.Input(shape=(2,))
i2 = keras.layers.Input(shape=(2,))
i3 = keras.layers.Input(shape=(2,))
i_layer = keras.layers.Dense(2, activation='sigmoid')
embedded_i1 = i_layer(i1)
embedded_i2 = i_layer(i2)
embedded_i3 = i_layer(i3)
middle_concatenation = keras.layers.concatenate([embedded_i1, embedded_i2, embedded_i3], axis=1)
out = keras.layers.Dense(1, activation='sigmoid')(middle_concatenation)
model = keras.models.Model(inputs=[i1, i2, i3], outputs=out)
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
For example, an input instance (successfully used to predict output) looks like this:
[array([[0.1, 0.2]]), array([[0.3, 0.5]]), array([[0.1, 0.3]])]
But when I try to train my model:
inputs = [[np.array([[0.1, 0.2]]), np.array([[0.3, 0.5]]), np.array([[0.1, 0.3]])],
[np.array([[0.2, 0.1]]), np.array([[0.5, 0.3]]), np.array([[0.3, 0.1]])]
]
outputs = np.ones(len(inputs))
model.fit(inputs, outputs)
I am getting this error:
ValueError: Error when checking model input: you are passing a list as input to your model, but the model expects a list of 3 Numpy arrays instead. The list you passed was: [[array([[ 0.1, 0.2]]), array([[ 0.3, 0.5]]), array([[ 0.1, 0.3]])], [array([[ 0.2, 0.1]]), array([[ 0.5, 0.3]]), array([[ 0.3, 0.1]])]]
What am I doing wrong?
How can I train a multichannel NN with a batch of I / O samples?
Thank!
source to share
the problem is just bad formatting. You cannot pass a list to keras, only numpy arrays, so when you have data structured like
inputs = [[np.array([[0.1, 0.2]]), np.array([[0.3, 0.5]]), np.array([[0.1, 0.3]])],
[np.array([[0.2, 0.1]]), np.array([[0.5, 0.3]]), np.array([[0.3, 0.1]])]
]
You need to pass one list item to your model at a time. You will also need to pass one output to the model at a time. To do this, create a structure outputs
like this
outputs = [np.ones(1) for x in inputs]
[array([ 1.]), array([ 1.])]
Then you can iterate over a match function like this
for z in range(0,len(inputs)):
model.fit(inputs[z],outputs[z],batch_size=1)
you can also replace model.fit
with model.train_on_batch()
, see docs
however, to avoid the loop, you could just have 3 numpy arrays stored in your list inputs
and have one outputs
as a numpy array. If you only want to train one batch at a time, you can set a batch size for that.
inputs = [np.array([[0.1, 0.2],[0.2, 0.1]]), np.array([[0.3, 0.5],[0.5, 0.3]]), np.array([[0.1, 0.3],[0.3, 0.1]])] outputs = np.ones(inputs[0].shape[0]) model.fit(inputs,outputs,batch_size=1)
source to share
The problem is you are currently using a list of lists as input, although keras expects a list of arrays.
You need to transform your list to look like [array_inputs_1, array_inputs_2, array_inputs_3]
where each input array is an array of inputs that you will pass to the model, if it only had this input layer, you just put them from the list into the list.
Using your details, the correct input should be:
[np.array([[0.1, 0.2], [0.2, 0.1]]),
np.array([[0.3, 0.5], [0.5, 0.3]]),
np.array([[0.1, 0.3], [0.1, 0.3]])]
This way, if all 3 input arrays have the same number of elements, keras will know how to split the tham into batches.
source to share