CapsuleLayer
という名前のカスタムレイヤーを定義しました。実際のモデルは別のクラスで定義されています。重みを実際のモデルにロードし、モデルを_.h5
_ファイルに保存しました。しかし、load_model(filepath)
を使用してモデルをロードしようとすると、エラーが発生します
ValueError:不明なレイヤー:CapsuleLayer
保存したモデルの読み込み中に、カスタムレイヤーをモデルに組み込むにはどうすればよいですか。
C.f. Keras FAQ、 "保存されたモデルでのカスタムレイヤー(または他のカスタムオブジェクト)の処理" :
ロードするモデルにカスタムレイヤーまたは他のカスタムクラスまたは関数が含まれている場合は、custom_objects引数を介してそれらをロードメカニズムに渡すことができます。
_from keras.models import load_model # Assuming your model includes instance of an "AttentionLayer" class model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})
_または、カスタムオブジェクトスコープを使用できます。
_from keras.utils import CustomObjectScope with CustomObjectScope({'AttentionLayer': AttentionLayer}): model = load_model('my_model.h5')
_カスタムオブジェクトの処理は、load_model、model_from_json、model_from_yamlと同じように機能します。
_from keras.models import model_from_json model = model_from_json(json_string, custom_objects={'AttentionLayer': AttentionLayer})
_
あなたの場合、model = load_model('my_model.h5', custom_objects={'CapsuleLayer': CapsuleLayer})
が問題を解決するはずです。
完全を期すために、ベンジャミンプランシェの答えに少しだけ加えます。カスタムレイヤーAttentionLayer
にその動作を構成する初期パラメーターがある場合は、クラスのget_config
メソッドを実装する必要があります。そうしないと、ロードに失敗します。これを書いているのは、引数付きのカスタムレイヤーをロードする方法に多くの問題があったため、ここに残します。
たとえば、レイヤーのダミー実装:
class AttentionLayer(Layer):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self, input_shape):
return super().build(input_shape)
def call(self, x):
# Implementation about how to look with attention!
return x
def compute_output_shape(self, input_shape):
return input_shape
これは、ベンジャミンプランシェの回答で詳述されているアプローチのいずれか、つまりcustom_objects={'AttentionLayer': AttentionLayer}
を使用して読み込まれます。ただし、レイヤーに引数がある場合、読み込みは失敗します。
クラスのinitメソッドに2つのパラメーターがあるとします。
class AttentionLayer(Layer):
def __init__(self, param1, param2, **kwargs):
self.param1 = param1
self.param2 = param2
super().__init__(**kwargs)
次に、それをロードすると:
model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})
このエラーがスローされます:
Traceback (most recent call last):
File "/path/to/file/cstm_layer.py", line 62, in <module>
h = AttentionLayer()(x)
TypeError: __init__() missing 2 required positional arguments: 'param1' and 'param2'
これを解決するには、カスタムレイヤークラスにget_config
メソッドを実装する必要があります。例:
class AttentionLayer(Layer):
def __init__(self, param1, param2, **kwargs):
self.param1 = param1
self.param2 = param2
super().__init__(**kwargs)
# ...
def get_config(self):
# For serialization with 'custom_objects'
config = super().get_config()
config['idx_init'] = self.idx_init
config['idx_end'] = self.idx_end
return config
そのため、モデルを保存すると、保存ルーチンはget_configを呼び出し、カスタムレイヤーの内部状態、つまりself.params
をシリアル化します。ロードすると、ローダーはカスタムレイヤーの内部状態を初期化する方法を認識します。