Search code examples
tensorflowkerasdeeplearning4j

Error loading keras model in Deeplearning4j - java


I trained my model in python keras. I am trying to load that in java code but getting following error How to fix this problem.

Ref:

https://towardsdatascience.com/deploying-keras-deep-learning-models-with-java-62d80464f34a

https://deeplearning4j.konduit.ai/keras-import/overview

Exception in thread "main" org.deeplearning4j.nn.modelimport.keras.exceptions.InvalidKerasConfigurationException: Model class name must be Sequential (found Model). For more information, see http://deeplearning4j.org/docs/latest/keras-import-overview
    at org.deeplearning4j.nn.modelimport.keras.KerasSequentialModel.<init>(KerasSequentialModel.java:90)
    at org.deeplearning4j.nn.modelimport.keras.KerasSequentialModel.<init>(KerasSequentialModel.java:57)
    at org.deeplearning4j.nn.modelimport.keras.utils.KerasModelBuilder.buildSequential(KerasModelBuilder.java:322)
    at org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasSequentialModelAndWeights(KerasModelImport.java:223)
    at Jktes.jk(Jktes.java:24)
    at Jktes.main(Jktes.java:13)

code:

public static void jk()
    throws IOException, InvalidKerasConfigurationException, UnsupportedKerasConfigurationException {

    String simpleMlp = new ClassPathResource(
        "randomjk.h5").getFile().getPath();
    MultiLayerNetwork model = KerasModelImport.
        importKerasSequentialModelAndWeights(simpleMlp);

}

dependency :

<dependency>
    <groupId>org.nd4j</groupId>
    <artifactId>nd4j-native-platform</artifactId>
    <version>1.0.0-beta6</version>
</dependency>
<dependency>
    <groupId>org.deeplearning4j</groupId>
    <artifactId>deeplearning4j-modelimport</artifactId>
    <version>1.0.0-beta6</version>
</dependency>
<dependency>
    <groupId>org.deeplearning4j</groupId>
    <artifactId>deeplearning4j-core</artifactId>
    <version>0.9.1</version>
</dependency>

My python-3.6 imports:

import datetime
import keras.backend as K
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd
import statistics
import sys
import tensorflow as tf
import uuid

from IPython.display import display, FileLink

from keras.layers import Activation, BatchNormalization, Conv2D, Dense, Dropout, Flatten, Input, Lambda, MaxPooling2D
from keras.models import Model, Sequential, load_model
from keras.optimizers import Adam, SGD

How i saved in python:

model_name_jk = "model_name_jk"
hyper['uuid'] = model_name_jk
stamp('%.1f%% (%.1f%% training) %s' % (test_accuracy, train_accuracy, hyper))
model.save('saved_models/%s.h5' % hyper['uuid'])

How did I created model in python:

hyper['dropout'] = 0.5
model_size = 'L'
if model_size == 'S':
    hyper['conv_filters'] = [32, 64]
    hyper['pool_size'] = (8, 8)
elif model_size == 'M':
    hyper['conv_filters'] = [32, 64, 128]
    hyper['pool_size'] = (4, 4)
else:
    hyper['conv_filters'] = [32, 64, 128, 256, 512]
    hyper['pool_size'] = (2, 2)
hyper['batch_normalization'] = True
hyper['dense_units'] = [6144]
hyper['share_per_character_weights'] = False
hyper['post_shared_dense'] = False
hyper['batch_normalization'] = True

def create_per_character_model(activation):
    inputs = Input(shape=(hyper['charset_len'],))
    x = Dense(hyper['charset_len'], activation='softmax')(inputs)
    return Model(inputs, x, name='char_model')

def create_model():
    x = Input(shape=(hyper['image_height'], hyper['image_width'], 1), name='input')
    image_input = x

    # Shared convolutional layers
    for layer, filters in enumerate(hyper['conv_filters']):
        if hyper['batch_normalization']:
            x = BatchNormalization()(x)
        x = Conv2D(filters, (3, 3), strides=(1, 1), padding='same', name=f'conv_{layer}', activation='relu')(x)
        x = MaxPooling2D(pool_size=hyper['pool_size'], padding='same', name=f'maxpool_{layer}')(x)
        x = Dropout(hyper['dropout'], name=f'conv_dropout_{layer}')(x)

    # Shared dense layers
    x = Flatten()(x)
    for layer, units in enumerate(hyper['dense_units']):
        x = Dense(units, activation='relu', name=f'dense_{layer}')(x)
        x = Dropout(hyper['dropout'], name=f'dense_dropout_{layer}')(x)

    x = Dense(hyper['max_len'] * hyper['charset_len'], name='wide_output', activation='linear')(x)

    # Per-character output layers
    split = Lambda(lambda whole: tf.split(whole, num_or_size_splits=hyper['max_len'], axis=1))(x)
    if hyper['share_per_character_weights']:
        per_character_model = create_per_character_model(activation='relu' if hyper['post_shared_dense'] else 'softmax')
        if hyper['post_shared_dense']:
            outputs = [Dense(hyper['charset_len'], name='output_char_%d' % ii, activation='softmax')(per_character_model(split[ii])) for ii in range(hyper['max_len'])]
        else:
            outputs = [per_character_model(split[ii]) for ii in range(hyper['max_len'])]
    else:
        outputs = [Dense(hyper['charset_len'], name='output_char_%d' % ii, activation='softmax')(split[ii]) for ii in range(hyper['max_len'])]

    model = Model(inputs=[image_input], outputs=outputs)
    model.summary()

    return model
model = create_model()

Solution

  • You are using the functionality for the sequential model import, but are creating the model using a functional API.

    To import models created with the functional API you need to use a different importer. https://deeplearning4j.konduit.ai/keras-import/model-functional shows how to do that.

    The TL;DR of it is that you have to use
    KerasModelImport.importKerasModelAndWeights(simpleMlp); instead of KerasModelImport.importKerasSequentialModelAndWeights(simpleMlp);