In Python, I configured, trained, and wrote to a file a neural network with the following architecture:
model_fully_connected = Sequential()
model_fully_connected.add(keras.layers.Dense(17, activation='tanh', input_shape=(x_train.shape[1],), W_regularizer=l2(l2_lambda)))
model_fully_connected.add(keras.layers.Dense(17, activation='tanh', W_regularizer=l2(l2_lambda)))
model_fully_connected.add(keras.layers.LeakyReLU (alpha=0.1))
model_fully_connected.add(keras.layers.Dense(17, activation='tanh', W_regularizer=l2(l2_lambda)))
model_fully_connected.add(keras.layers.LeakyReLU (alpha=0.1))
model_fully_connected.add(keras.layers.Dense(17, activation='tanh', W_regularizer=l2(l2_lambda)))
model_fully_connected.add(keras.layers.Dense(1))
model_fully_connected.compile(optimizer='adam', loss='mse', metrics=["mae", "mse"])
model_fully_connected.save("trained _neural_network.H5",True,True)
save_model=load_model("trained _neural_network.H5")
The number of inputs is 17. For predictions, I used a DataSet
with dimension 17:
x=save_model.predict(test)
And I imported this model in Java:
modelMultiLayer=kerasModelImport.importKerasSequentialModelAndWeights(simpleMlp);
Then, for prediction, I created an INDArray
array with 17 factors and tried to send it to the imported model:
int inputs = 17;
INDArray features = Nd4j.zeros(inputs);
for (int i=0; i<inputs; i++){
features.putScalar(new int [] {i},parametrs[i]);}
forecast=modelMultiLayer.output(features).getDouble(0);
But when I run it, it throws an exception which says that the input network expects a 2-rank matrix, but receives a 1-rank array with a dimension of 17:
org.deeplearning4j.exception.DL4JInvalidInputException: Input that is
not a matrix; expected matrix (rank 2), got rank 1 array with shape
[17]. Missing preprocessor or wrong input type? (layer name: dense_6,
layer index: 0, layer type: DenseLayer)
org.deeplearning4j.nn.layers.BaseLayer.preOutputWithPreNorm(BaseLayer.java:308)
org.deeplearning4j.nn.layers.BaseLayer.preOutput(BaseLayer.java:291)
org.deeplearning4j.nn.layers.BaseLayer.activate(BaseLayer.java:339)
org.deeplearning4j.nn.layers.AbstractLayer.activate(AbstractLayer.java:258)
org.deeplearning4j.nn.multilayer.MultiLayerNetwork.outputOfLayerDetached(MultiLayerNetwork.java:1303)
org.deeplearning4j.nn.multilayer.MultiLayerNetwork.output(MultiLayerNetwork.java:2415)
org.deeplearning4j.nn.multilayer.MultiLayerNetwork.output(MultiLayerNetwork.java:2378)
org.deeplearning4j.nn.multilayer.MultiLayerNetwork.output(MultiLayerNetwork.java:2369)
org.deeplearning4j.nn.multilayer.MultiLayerNetwork.output(MultiLayerNetwork.java:2356)
org.deeplearning4j.nn.multilayer.MultiLayerNetwork.output(MultiLayerNetwork.java:2452)
service.NeuralNetwork.getForecast(NeuralNetwork.java:68)
Why does it expect a 2 rank matrix? After all, I use a vector with 17 parameters.
What should the input data set look like then?
It is very simple: DL4J always expects to be getting a batch of data, even if you want to pass in just a single example during inference. So your input should have the shape [1, 17].
Also you are using probably the most complex way that I've ever seen of putting something into an INDArray. You can just create an appropriate array this way:
INDArray features = Nd4j.create(parameters, 1, 17);