1. 程式人生 > >ValueError: Unknown loss function

ValueError: Unknown loss function

1. 問題分析

  在使用 Keras 中的 load_model 函式重新載入模型的時,會出現如下的報錯

Traceback (most recent call last):
  File "test_unet.py", line 79, in <module>
    model = load_model(weight_path)
  File "/usr/local/lib/python2.7/dist-packages/keras/models.py", line 274, in load_model
    sample_weight_mode=sample_weight_mode)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 636, in compile loss_function = losses.get(loss) File "/usr/local/lib/python2.7/dist-packages/keras/losses.py", line 122, in get return deserialize(identifier) File "/usr/local/lib/python2.7/dist-packages/keras/losses.py", line 114
, in deserialize printable_module_name='loss function') File "/usr/local/lib/python2.7/dist-packages/keras/utils/generic_utils.py", line 164, in deserialize_keras_object ':' + function_name) ValueError: Unknown loss function:dice_coef_loss

可以看到函式發生錯誤的地方可以追溯到 load_model 位置,分析提醒可以發現,是因為 Keras 找不到名為 dice_coef_loss 的損失函式。這個損失函式是我在函式訓練過程中自定義的損失函式,具體如下

# parameter for loss function
smooth = 1.

#  metric function and loss function
def dice_coef(y_true, y_pred):
	y_true_f = K.flatten(y_true)
	y_pred_f = K.flatten(y_pred)
	intersection = K.sum(y_true_f * y_pred_f)
	return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)


def dice_coef_loss(y_true, y_pred):
	return -dice_coef(y_true, y_pred)

  在這裡我自定義了一個指標 dice_coef 和一個損失函式 dice_coef_loss。因為使用 model.save(filepath) 得到的會儲存訓練的損失函式,但是這個損失函式在 Keras 中的 losses.py 是找不到的是,所以才會報這樣的錯。

2. 修改方法

  首先可以看一下函式 load_model 的原始碼,在這裡只給出說明部分如下

def load_model(filepath, custom_objects=None, compile=True):
    """Loads a model saved via `save_model`.

    # Arguments
        filepath: String, path to the saved model.
        custom_objects: Optional dictionary mapping names
            (strings) to custom classes or functions to be
            considered during deserialization.
        compile: Boolean, whether to compile the model
            after loading.

    # Returns
        A Keras model instance. If an optimizer was found
        as part of the saved model, the model is already
        compiled. Otherwise, the model is uncompiled and
        a warning will be displayed. When `compile` is set
        to False, the compilation is omitted without any
        warning.

    # Raises
        ImportError: if h5py is not available.
        ValueError: In case of an invalid savefile.
    """

其中的 custom_objects 是可選的字典,在反序列化過程中對映名稱(字串)到要考慮的自定義類或函式,所以可以直接通過字典來制定缺失的指標或者損失函式,如下

# parameter for loss function
smooth = 1.

#  metric function and loss function
def dice_coef(y_true, y_pred):
	y_true_f = K.flatten(y_true)
	y_pred_f = K.flatten(y_pred)
	intersection = K.sum(y_true_f * y_pred_f)
	return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)


def dice_coef_loss(y_true, y_pred):
	return -dice_coef(y_true, y_pred)

# load model 
weight_path = './weights.h5'
model = load_model(weight_path,custom_objects={'dice_coef_loss': dice_coef_loss,'dice_coef':dice_coef})

重點看上面程式碼的最後一行,通過字典指定我們自定義的函式(或許是一個指標,或許是一個損失函式)就可以解決上面的問題。

參考

[1] Bisgates Github https://github.com/keras-team/keras/issues/5916#issuecomment-300038263