netrack / keras-metrics

Metrics for Keras. DEPRECATED since Keras 2.3.0
MIT License
165 stars 23 forks source link

Rework model loading #27

Open ybubnov opened 5 years ago

ybubnov commented 5 years ago

The model loading was introduced in #25. This approach is entangled and requires rework.

wandonye commented 5 years ago

I have a save model. It cannot be reloaded. Error says: Unknown metric function:binary_precision. Any wolkaround?

ybubnov commented 5 years ago

@wandonye, it would be great to see a sample of code, that you're using to save model. Do you use custom_objects argument for model saving?

wandonye commented 5 years ago

@ybubnov thanks for the prompt reply. I didn't use any argument other than the filename when saving the model.

Here are the codes involved:

import keras_metrics as km
...
nnmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=[km.precision(), km.recall()])
...
nnmodel.save('neural_net1.h5')
wandonye commented 5 years ago

Also tried using custom_object when loading the model. Something like:

{binary_precision:km.binary_precision}

But then there is another error saying something like fn expect 0 or 1 input but got 2

ybubnov commented 5 years ago

@wandonye, It does not seem there is a problem in the given code snippets. If it's possible to provide a working sample, which produces an error, that would simplify the troubleshooting.

mdf-github commented 5 years ago

I get the same error. Code snippet:

model = Sequential()
for layer, n in enumerate(n_neurons):
    l1_val = l1_vals[layer]
    l2_val = l2_vals[layer]
    if all(l == 0 for l in [l1_val, l2_val]):
        reg = None
    else:
        reg = regularizers.l1_l2(l1=l1_val, l2=l2_val)

    layer_kwargs_ind = layer_kwargs[layer]
    layer_kwargs_ind['kernel_regularizer'] = reg
    layer_kwargs_ind['kernel_initializer'] = kernel_initializer[layer]

    if layer == 0:
        model.add(Dense(n, input_shape=input_shape,
            **layer_kwargs_ind))
    else:
        model.add(Dense(n,
            **layer_kwargs_ind))
    model.add(Activation(hidden_act[layer]))

# output
model.add(Dense(n_output))
model.add(Activation(output_act))

# add precision and recall for each label
prec_0 = keras_metrics.binary_precision(label=0)
## prec_1 = keras_metrics.binary_precision(label=1)
recall_0 = keras_metrics.binary_recall(label=0)
## recall_1 = keras_metrics.binary_recall(label=1)

if compile_kwargs is None:
    compile_kwargs = {}
if opt_kwargs is None:
    opt_kwargs = {}
model.compile(optimizer=opt(lr=lr, **opt_kwargs), loss=loss,
    metrics=['accuracy',
        prec_0,
        ## prec_1,
        recall_0,
        ## recall_1
        ],
    **compile_kwargs)

callbacks=[
    cb.TerminateOnNaN(),
    cb.ReduceLROnPlateau(patience=10, verbose=1, min_lr=1e-3, factor=0.5),
    cb.EarlyStopping(patience=10, min_delta=0.005),
]

hist = model.fit(
    x_train, y_train,
    batch_size=params['batch_size'], epochs=params['epochs'],
    validation_data=(x_val, y_val),
    callbacks=callbacks,
    ## **fit_kwargs
)
model.save('model.h5')

There is no error in saving the model. However, when I try:

keras.load_model('model.h5')

I get

ValueError: Unknown metric function:binary_precision

When I try:

import keras_metrics as km
model = load_model('general_fnn_model_params_20190517-201322.h5', custom_objects={'binary_precision': km.binary_precision})

I get the error TypeError: fn() takes from 0 to 1 positional arguments but 2 were given

Basically same as the issue provided above.

mdf-github commented 5 years ago

I get the same error. Code snippet:

model = Sequential()
for layer, n in enumerate(n_neurons):
    l1_val = l1_vals[layer]
    l2_val = l2_vals[layer]
    if all(l == 0 for l in [l1_val, l2_val]):
        reg = None
    else:
        reg = regularizers.l1_l2(l1=l1_val, l2=l2_val)

    layer_kwargs_ind = layer_kwargs[layer]
    layer_kwargs_ind['kernel_regularizer'] = reg
    layer_kwargs_ind['kernel_initializer'] = kernel_initializer[layer]

    if layer == 0:
        model.add(Dense(n, input_shape=input_shape,
            **layer_kwargs_ind))
    else:
        model.add(Dense(n,
            **layer_kwargs_ind))
    model.add(Activation(hidden_act[layer]))

# output
model.add(Dense(n_output))
model.add(Activation(output_act))

# add precision and recall for each label
prec_0 = keras_metrics.binary_precision(label=0)
## prec_1 = keras_metrics.binary_precision(label=1)
recall_0 = keras_metrics.binary_recall(label=0)
## recall_1 = keras_metrics.binary_recall(label=1)

if compile_kwargs is None:
    compile_kwargs = {}
if opt_kwargs is None:
    opt_kwargs = {}
model.compile(optimizer=opt(lr=lr, **opt_kwargs), loss=loss,
    metrics=['accuracy',
        prec_0,
        ## prec_1,
        recall_0,
        ## recall_1
        ],
    **compile_kwargs)

callbacks=[
    cb.TerminateOnNaN(),
    cb.ReduceLROnPlateau(patience=10, verbose=1, min_lr=1e-3, factor=0.5),
    cb.EarlyStopping(patience=10, min_delta=0.005),
]

hist = model.fit(
    x_train, y_train,
    batch_size=params['batch_size'], epochs=params['epochs'],
    validation_data=(x_val, y_val),
    callbacks=callbacks,
    ## **fit_kwargs
)
model.save('model.h5')

There is no error in saving the model. However, when I try:

keras.load_model('model.h5')

I get

ValueError: Unknown metric function:binary_precision

When I try:

import keras_metrics as km
model = load_model('general_fnn_model_params_20190517-201322.h5', custom_objects={'binary_precision': km.binary_precision})

I get the error TypeError: fn() takes from 0 to 1 positional arguments but 2 were given

Basically same as the issue provided above.

I found the fix. So apparently all the args must also be given. In my case:

model = load_model('general_fnn_model_params_20190517-201322.h5', custom_objects={'binary_precision': km.binary_precision(label=0), 'binary_recall': km.binary_recall(label=0)})

worked.