Let's start from the main function by declare the variable of labels that will be used by ClassifierOutputStep() and getting the trained model.
Create an inference configuration by default.
We'll need to include pre-processing step using ImageToNDArrayStep() to convert the input image into an array and specify all characteristics of the input image. To run a model, add Nd4jTensorFlowStep() into the pipeline and specify modelUri, inputNames and outputNames. ClassifierOutputStep() can be included for transforming the output in a way that humans can understand and set the following:
inputName : names for model's output layer
labels : list of output labels classifier
allProbabilities : false
Deploy the server
Let's deploy the model in the server by calling DeployKonduitServing with the configuration made before. The handler, a callback function, is applied, only after a successful or failed server deployment inside the handler block, as shown.
Note that we consider only one test input image in this example for inference to show the model's deployment in Konduit-Serving. After implementation, the successful server deployment gives below output text.
The complete inference configuration in YAML format is as follows.
String[] labels = {"0","1","2","3","4","5","6","7","8","9"};
//get the file of trained model
Train.ModelTrainResult modelTrainResult = Train.tensorflowMnistModel();
//a default Inference Configuration
InferenceConfiguration inferenceConfiguration = new InferenceConfiguration();
//include pipeline step into the Inference Configuration
inferenceConfiguration.pipeline(SequencePipeline.builder()
.add(new ImageToNDArrayStep() //add ImageToNDArrayStep() into pipeline to set image to NDArray for input
.config(new ImageToNDArrayConfig() //image configuration
.width(28)
.height(28)
.dataType(NDArrayType.FLOAT)
.aspectRatioHandling(AspectRatioHandling.CENTER_CROP)
.includeMinibatchDim(true)
.channelLayout(NDChannelLayout.GRAYSCALE)
.format(NDFormat.CHANNELS_FIRST)
.normalization(ImageNormalization.builder().type(ImageNormalization.Type.SCALE).build())
)
.keys("image")
.outputNames("input_layer")
.keepOtherValues(true)
.metadata(false)
.metadataKey(ImageToNDArrayStep.DEFAULT_METADATA_KEY))
.add(new Nd4jTensorFlowStep() //add Nd4jTensorFlowStep into pipeline
.modelUri(modelTrainResult.modelPath())
.inputNames(modelTrainResult.inputNames())
.outputNames(modelTrainResult.outputNames())
).add(new ClassifierOutputStep()
.inputName(modelTrainResult.outputNames().get(0))
.labels(Arrays.asList(labels.clone()))
.allProbabilities(false)
).build()
);
//deploy the model in server
DeployKonduitServing.deploy(new VertxOptions(), new DeploymentOptions(),
inferenceConfiguration,
handler -> {
if (handler.succeeded()) { // If the server is successfully running
// Getting the result of the deployment
InferenceDeploymentResult inferenceDeploymentResult = handler.result();
int runnningPort = inferenceDeploymentResult.getActualPort(); //get server's port
String deploymentId = inferenceDeploymentResult.getDeploymentId(); //get server's deployment id
System.out.format("The server is running on port %s with deployment id of %s%n",
runnningPort, deploymentId);
try {
String result;
try {
result = Unirest.post(String.format("http://localhost:%s/predict", runnningPort))
.header("Accept", "application/json")
.field("image", new ClassPathResource("inputs/test_files/test_input_number_2.png").getFile(), "image/png")
.asString().getBody();
System.out.format("Result from server : %s%n", result);
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
} catch (UnirestException e) {
e.printStackTrace();
System.exit(1);
}
} else { // If the server failed to run
System.out.println(handler.cause().getMessage());
System.exit(1);
}
});
The server is running on port 40521 with deployment id of 4b7d8bc5-a711-499f-ad9f-9ccd82c3e142
Result from server : {
"output_layer/Softmax" : [ [ 1.8688768E-8, 0.0962552, 0.7753802, 1.7737559E-8, 0.122773424, 4.7498935E-13, 3.0434896E-6, 0.005588151, 7.329317E-12, 3.4533626E-10 ] ],
"prob" : 0.7753801941871643,
"index" : 2,
"label" : "2"
}
Process finished with exit code 0