I have a Keras 2.3.1 h5 CNN fully trained model that I import using DL4J 1.0.0-beta6 version. I intend to use DL4J for evaluating outputs for specific input images. Currently Keras prediction outputs don’t match DL4J outputs. The shapes of the inputs are different Keras input shape is (4, 150, 150, 3) whereas DL4J
input shape is [4, 3, 150, 150]. I could not find any sample DL4J code which
performs predictions on a CNN (or any network) trained model imported from
Keras that use images for predictions in Java and hence cannot ascertain if this
is an issue.
Questions:
-
What is the right shape of input required ini DL4J for the imported Keras
Model that expects image input. -
If input shapes have to match between DL4J and Keras, I cannot identify a
way to build a “channel last” INDArray from a set of input images. -
I need to also perform this on Keras imported mixed multi-input and
multi-output networks. What is recommended way to feed inputs to such networks
for predictions.
CURRENT CODE SNIPPET:
Keras:
...
# Build and train the CNN Model
...
imgGenerator = ImageDataGenerator(rescale=1./255)
testDir = "/test"
testData = np.array([["cat.1500.jpg"],["cat.1501.jpg"],["dog.1500.jpg"],["dog.1501.jpg"]])
testDf = pd.DataFrame(testData, columns=["file"])
netInput=imgGenerator.flow_from_dataframe( dataframe=testDf,
directory=testDir, x_col="file", y_col=None,
batch_size=testData.shape[0], seed=42, shuffle=False, class_mode=None,
target_size=(150, 150))
netOutput = model.predict(netInput);
print("Prediction: ", netOutput)
model.save("sample.h5");
Result:
Prediction: [[0.01729406]
[0.76219445]
[0.40130898]
[0.9373665 ]]
Shape of the batch generated by netInput is (4, 150, 150, 3)
DL4J:
String[] testImgs = new String[]{"cat.1500.jpg","cat.1501.jpg","dog.1500.jpg","dog.1501.jpg"};
INDArray[] ret = new INDArray[testImgs.length];
int count = 0;
for (String testImg: testImgs)
{
File f = new File(mInputPath + "/test", testImg);
NativeImageLoader loader = new NativeImageLoader(150, 150, 3);
INDArray image = loader.asMatrix(f);
DataNormalization scalar = new ImagePreProcessingScaler(0, 1);
scalar.transform(image);
ret[count] = image;
count++;
}
// Concatenate the array along dimension 0.
INDArray netInput = Nd4j.concat(0, ret);
INDArray netOutput = model.output(netInput);
System.out.println("Prediction: ", netOutput)
Result:
Prediction: [[0.0381],
[0.7351],
[0.5337],
[0.8388]]
Shape of netInput is [4, 3, 150, 150]
edit: make code snippets readable