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()
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);
Related
I've created a Keras Regressor to run a RandomizedSearch CV using a ModelCheckpoint callback, but the training overran the Colab runtime 12H limit and stopped halfway through. The models are saved in hdf5 format.
I used tensorflow_addons to add the RSquare class to monitor the R2 for train and validation sets. However, when I used keras.models.load_model, I get the following error:
As you can see from the traceback, I have passed the custom_objects parameter, but still it is not recognised.
How can I solve this?
You can see the full code example below:
import os
import tensorflow as tf
import tensorflow_addons as tfa
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.layers import Input, InputLayer
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import RandomizedSearchCV
def build_model(n_hidden = 2, n_neurons = 64, input_shape = (X_train.shape[1],), dropout = 0):
model = Sequential()
model.add(InputLayer(input_shape = input_shape))
for i in range(n_hidden):
model.add(Dense(n_neurons, activation = 'relu'))
model.add(Dropout(dropout))
model.add(Dense(1))
model.compile(loss = 'mean_squared_error', optimizer = 'adam', metrics = [tfa.metrics.RSquare(y_shape=(1,))])
return model
keras_reg = KerasRegressor(build_model)
checkdir = os.path.join(r'/content/drive/MyDrive/COP328/Case A', 'checkpoints', datetime.datetime.now().strftime('%d-%m-%Y_%H-%M-%S'), 'imputed_log1p-{epoch:02d}-{val_r_square:.3f}.hdf5')
callbacks = [ModelCheckpoint(checkdir, save_freq='epoch', save_best_only = True, monitor = 'val_r_square', mode = 'max'),
EarlyStopping(patience = 10)]
# Here is where training got interrupted because of Colab runtime being dropped:
param_dist = {
'n_hidden' : [1,2],
'n_neurons': [8,16,32,64,128],
'dropout': [0,0.2,0.4]
}
rnd_search_cv = RandomizedSearchCV(keras_reg, param_dist, n_iter= 15, cv = 5)
rnd_search_cv.fit(X_train, y_train, epochs = 200, batch_size = 64,
validation_data = (X_valid,y_valid),
callbacks = callbacks)
# Here is where I am trying to reload one of the most promising models based on R2, and getting the error:
from keras.models import load_model
import tensorflow_addons as tfa
rnd_model = load_model(r'/content/drive/MyDrive/COP328/Case A/checkpoints/26-06-2021_17-32-29/imputed_log1p-56-1.000.hdf5', custom_objects = {'r_square': tfa.metrics.RSquare, 'val_r_square': tfa.metrics.RSquare})
This solution doesn't take into account the addons package but one possibility is to create the coefficient of determination (R^2) as a different metric without that package, and then defining it as your loss.
def coeff_determination(y_true, y_pred):
from keras import backend as K
SS_res = K.sum(K.square( y_true-y_pred ))
SS_tot = K.sum(K.square( y_true - K.mean(y_true) ) )
return ( 1 - SS_res/(SS_tot + K.epsilon()) )
Recall that minimizing MSE will maximize R^2.
import tensorflow.keras as keras
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
model = keras.models.load_model('model/model_test_0.99408.h5', custom_objects={'leaky_relu': tf.nn.leaky_relu})
model.summary()
inputs = keras.layers.Input(shape=(28, 28, 1))
y = model(inputs)
feature = model.get_layer('conv2d_4').output
model = keras.Model(inputs=inputs, outputs=[y, feature])
model.summary()
why i can't get the output of 'conv2d_4' that is the internal layer of the model? And i get the following error.
Graph disconnected: cannot obtain value for tensor Tensor("input_1:0", shape=(None, 28, 28, 1), dtype=float32) at layer "conv2d". The following previous layers were accessed without issue: []
We can try restacking the model, assigning feature to the required layer,
import tensorflow.keras as keras
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
model = keras.models.load_model('model/model_test_0.99408.h5', custom_objects={'leaky_relu': tf.nn.leaky_relu})
model.summary()
inputs = keras.layers.Input(shape=(28, 28, 1))
y = inputs
for layer in vgg.layers:
if layer.name == 'conv2d_4':
feature = y
y = layer( y )
model = keras.Model(inputs=inputs, outputs=[y, feature])
model.summary()
[[[{{node dense_22/MatMul}}]] [[dense_23/Sigmoid/_329]] (1) Invalid argument: Matrix size-incompatible: In[0]: [665,64], In[1]: [42560,1]
This all belongs to:y_score = model.predict(X_test, verbose = 1, batch_size = 256)
from warnings import warn
from abc import ABCMeta, abstractmethod
from tensorflow import keras, reshape
np.random.seed(1337) # for reproducibility
import keras
from keras.optimizers import RMSprop, SGD
from keras.models import Sequential, model_from_yaml
from keras.layers.core import Dense, Dropout, Activation, Flatten
import keras.layers.core as core
from keras.layers import Dense, Dropout, Embedding, LSTM, Input, merge, multiply, Reshape
from keras.layers.convolutional import Convolution1D, MaxPooling1D
from keras.layers.wrappers import Bidirectional
from keras.constraints import maxnorm
from keras.layers.recurrent import LSTM, GRU
from keras.callbacks import ModelCheckpoint, EarlyStopping
from keras.layers import Embedding
from sklearn.metrics import fbeta_score, roc_curve, auc, roc_auc_score, average_precision_score
import matplotlib.pyplot as plt
from keras.regularizers import l2, l1, l1_l2
# from keras.models import Model
from tensorflow.keras.models import Model
# from keras import backend as K
import tensorflow.keras.backend as K
from keras.engine.topology import Layer
from keras import activations, initializers, regularizers, constraints
from keras.engine import InputSpec
from keras.layers import ActivityRegularization
class Attention(Layer):
def __init__(self,hidden,init='glorot_uniform',activation='linear',W_regularizer=None,b_regularizer=None,W_constraint=None,**kwargs):
self.init = initializers.get(init)
self.activation = activations.get(activation)
self.W_regularizer = regularizers.get(W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.hidden=hidden
super(Attention, self).__init__(**kwargs)
def build(self, input_shape):
input_dim = input_shape[-1]
self.input_length = input_shape[1]
self.W0 = self.add_weight(name ='{}_W1'.format(self.name), shape = (input_dim, self.hidden), initializer = 'glorot_uniform', trainable=True) # Keras 2 API
self.W = self.add_weight( name ='{}_W'.format(self.name), shape = (self.hidden, 1), initializer = 'glorot_uniform', trainable=True)
self.b0 = K.zeros((self.hidden,), name='{}_b0'.format(self.name))
self.b = K.zeros((1,), name='{}_b'.format(self.name))
print (modil.summary())
return modil
#for Testing only
def test(n_estimators = 16):
model = set_up_model_up()
X_test = np.load('/content/drive/MyDrive/X_test.npy', mmap_mode='r')
y_test = np.load('/content/drive/MyDrive/y_test.npy', mmap_mode='r')
ensemble = np.zeros(len(X_test))
for i in range(n_estimators):
print ('testing', i, 'model')
print ('model shape is', model.summary)
model.load_weights('/content/drive/MyDrive/model/bestmodel_split_chr_GD_'+ str(i) + '.hdf5')
print ('model shape after loading is', model.summary)
#Once the model is created, you can config the model with losses and metrics with model.compile(), train the model with model.fit(), or use the model to do prediction with model.predict().
print ('Predicting...')
# X_test=X_test.Reshape(665,-1)
print ('testing',X_test.shape)
print (len(model.layers))
# y_score = model.predict(np.expand_dims(np.array(X_test, dtype=np.float32), 0), verbose = 1, batch_size = 256)
formatmul= np.empty((3,2000,4), dtype=object)
for x in range(0, 2):
for y in range(0, 1999):
for z in range(0, 3):
formatmul[x][y][z]=X_test[x][y][z]
y_score = model.predict(X_test).reshape(665,-1), verbose = 1, batch_size = 256)
print("model.output_shape",model.output_shape)
print("model.input_shape",model.input_shape)
y_score = model.predict(formatmul, batch_size=42560)
y_score = model.predict(np.array(formatmul, dtype=np.float32), batch_size =665)
y_pred = []
for item in y_score:
y_pred.append(item[0])
y_pred = np.array(y_pred)
ensemble += y_pred
ensemble /= n_estimators
np.save('/content/drive/MyDrive/test_result/y_test', y_test)
np.save('/content/drive/MyDrive/test_result/y_pred', ensemble)
auroc = roc_auc_score(y_test, ensemble)
aupr = average_precision_score(y_test, ensemble)
print ('auroc', auroc)
print ('aupr' , aupr)
test(n_estimators = 16)
I have a simple CNN with inputs of shape (5,5,3). As a first step I want to add a constant tensor to the input.
With the code below, I get
AttributeError: 'NoneType' object has no attribute '_inbound_nodes'
I have tried a few things like
const_change = Input(tensor=tf.constant([ ...
or
const_change = Input(tensor=K.variable([ ...
but nothing seems to work. Any help is highly appreciated.
from __future__ import print_function
import tensorflow as tf
import numpy as np
import keras
from keras import backend as K
from keras.models import Model
from keras.layers import Input
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
# Python 2.7.10
# keras version 2.2.0
# tf.VERSION '1.8.0'
raw_input = Input(shape=(5, 5, 3))
const_change = tf.constant([
[[5.0,0.0,0.0],[0.0,0.0,-3.0],[-10.0,0.0,0.0],[0.0,0.0,4.0],[-20.0,0.0,0.0]],
[[-15.0,0.0,12.0],[0.0,4.0,0.0],[-3.0,0.0,10.0],[-18.0,0.0,0.0],[20.0,0.0,-6.0]],
[[0.0,0.0,6.0],[0.0,-2.0,-6.0],[0.0,0.0,2.0],[0.0,0.0,-9.0],[7.0,-6.0,0.0]],
[[-3.0,4.0,0.0],[11.0,-12.0,0.0],[0.0,0.0,0.0],[0.0,0.0,7.0],[0.0,0.0,2.0]],
[[0.0,0.0,0.0],[0.0,1.0,-2.0],[4.0,0.0,3.0],[0.0,0.0,0.0],[0.0,0.0,0.0]]])
cnn_layer1 = Conv2D(32, (4, 4), activation='relu')
cnn_layer2 = MaxPooling2D(pool_size=(2, 2))
cnn_layer3 = Dense(128, activation='relu')
cnn_layer4 = Dropout(0.1)
cnn_output = Dense(4, activation='softmax')
proc_input = keras.layers.Add()([raw_input, const_change])
# proc_input = keras.layers.add([raw_input, const_change]) -> leads to the same error (see below)
lay1 = cnn_layer1(proc_input)
lay2 = cnn_layer2(lay1)
lay3 = Flatten()(lay2)
lay4 = cnn_layer3(lay3)
lay5 = cnn_layer4(lay4)
lay_out = cnn_output(lay5)
model = Model(inputs=raw_input, outputs=lay_out)
# -> AttributeError: 'NoneType' object has no attribute '_inbound_nodes'
The const_change should be also Input just like raw_input. You can create another input layer named const_input, and feed raw_input and const_input together into model.
...
const_input = Input(tensor=const_change)
...
proc_input = keras.layers.Add()[raw_input, const_input]
...
model = Model(inputs=[raw_input, const_input], outputs=lay_out)
I have a simple CNN with input images of shape (5,5,3). As a first step I want to add a constant tensor to the input.
According to the answer in my previous SO question, I have to define the constant tensor as an input layer (const_input), so that I can Add() it to the image data (raw_input). The model is compiled without errors:
from __future__ import print_function
import tensorflow as tf
import numpy as np
import keras
from keras import backend as K
from keras.models import Model
from keras.layers import Input, Add
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dropout, Flatten, Dense
from keras.preprocessing.image import ImageDataGenerator
# Python 2.7.10 - keras version 2.2.0 - tf.VERSION '1.8.0'
cnn_layer1 = Conv2D(32, (4, 4), activation='relu')
cnn_layer2 = MaxPooling2D(pool_size=(2, 2))
cnn_layer3 = Dense(64, activation='relu')
cnn_layer4 = Dropout(0.1)
cnn_output = Dense(2, activation='softmax')
raw_input = Input(shape=(5, 5, 3))
const_input = Input(shape=(5, 5, 3))
pre_proc = Add()([raw_input, const_input])
lay1 = cnn_layer1(pre_proc)
lay2 = cnn_layer2(lay1)
lay3 = Flatten()(lay2)
lay4 = cnn_layer3(lay3)
lay5 = cnn_layer4(lay4)
lay_out = cnn_output(lay5)
model = Model(inputs=[raw_input, const_input], outputs=lay_out)
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
Now I try to provide the constant tensor as an input along with the images that are read from directory:
batch_size = 10
train_datagen = ImageDataGenerator(rescale=1./255)
validation_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
'cd_data/train',
target_size=(5, 5),
classes=['cat', 'dog'],
batch_size=batch_size)
validation_generator = validation_datagen.flow_from_directory(
'cd_data/validation',
target_size=(5, 5),
classes=['cat', 'dog'],
batch_size=batch_size)
const_array = np.array(
[[[5.0,0.0,0.0],[0.0,0.0,-3.0],[-10.0,0.0,0.0],[0.0,0.0,4.0],[-20.0,0.0,0.0]],
[[-15.0,0.0,12.0],[0.0,4.0,0.0],[-3.0,0.0,10.0],[-18.0,0.0,0.0],[20.0,0.0,-6.0]],
[[0.0,0.0,6.0],[0.0,-2.0,-6.0],[0.0,0.0,2.0],[0.0,0.0,-9.0],[7.0,-6.0,0.0]],
[[-3.0,4.0,0.0],[11.0,-12.0,0.0],[0.0,0.0,0.0],[0.0,0.0,7.0],[0.0,0.0,2.0]],
[[0.0,0.0,0.0],[0.0,1.0,-2.0],[4.0,0.0,3.0],[0.0,0.0,0.0],[0.0,0.0,0.0]]])
def merge_generator():
while True:
next_image = train_generator.next()
yield [next_image[0], const_array], next_image[1]
train_gen_with_const = merge_generator()
Executing the fit_generator leads to error below
model.fit_generator(
train_gen_with_const,
steps_per_epoch=2,
epochs=1,
verbose=2, # one line per epoch
validation_data=validation_generator,
validation_steps=2)
ValueError: Error when checking input: expected input_2 to have 4 dimensions, but got array with shape (5, 5, 3)
I tried to provide the missing dimension like this
const_batch = np.broadcast_to(const_array, (batch_size, 5, 5, 3))
def merge_generator():
while True:
next_image = train_generator.next()
yield [next_image[0], const_batch], next_image[1]
but this leads to
ValueError: All input arrays (x) should have the same number of samples. Got array shapes: [(2, 5, 5, 3), (10, 5, 5, 3)]
What is the right way to provide this constant tensor input?
Any help is highly appreciated!
The problem lies with your validation_data= argument; your model expects two input arrays, whereas validation_generator supplies only one. You fixed this with train_gen_with_const - just extend it to val:
def merge_generator(): # const_batch inside the function to apply to each image
while True:
next_image = train_generator.next()
const_batch = np.broadcast_to(const_array, (len(next_image[0]), 5, 5, 3))
yield [next_image[0], const_batch], next_image[1]
def val_merge_generator():
while True:
next_image = validation_generator.next()
const_batch = np.broadcast_to(const_array, (len(next_image[0]), 5, 5, 3))
yield [next_image[0], const_batch], next_image[1]
Remember, internally, fit_generator calls train_on_batch(x, y) and evaluate(x, y) - so each must receive the same dimensionality for x and y from both generators.