#python #tensorflow #keras #bayesian-networks #tensorflow-model-analysis
Вопрос:
Я определил пользовательский слой с именем CapsuleLayer
. Фактическая модель была определена в отдельном классе. Я загрузил веса в фактическую модель и сохранил модель в .h5
файле. Однако, когда я пытаюсь загрузить модель с помощью load_model(filepath)
, я получаю ошибку
Ошибка значения: Неизвестный слой: Слой капсул
Как я могу включить пользовательский слой в свою модель при загрузке сохраненной модели.
Ответ №1:
C. f. Часто задаваемые вопросы по Keras, «Обработка пользовательских слоев (или других пользовательских объектов) в сохраненных моделях»:
Если модель, которую вы хотите загрузить, включает пользовательские слои или другие пользовательские классы или функции, вы можете передать их механизму загрузки с помощью аргумента 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})
следует решить вашу проблему.
Комментарии:
1. Я думаю, мне тоже нужно импортировать класс.
2. Точный.
custom_objects
Параметр в основном предназначен для передачи вашего пользовательского класса и его имениload_model()
, чтобы он мог распознавать и восстанавливать его из сохраненных файлов.3. Я получаю сообщение об ошибке. Ошибка типа: __init__() принимает по крайней мере 3 аргумента (1 задан). В чем может быть проблема.?
4. Ваш пользовательский слой, вероятно, нуждается в 3 аргументах для инициализации, но не получает их. Возможно, вам придется добавить
get_config()
к нему метод. Ответ на этот вопрос может вам помочь, а также код для основных слоев, например, здесь .
Ответ №2:
Просто для полноты картины я добавляю немного поверх ответа Бенджамина Планша. Если у вашего пользовательского слоя 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
Это загрузит любой из подходов, описанных в ответе benjaminplanche, т. Е. с использованием 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['param1'] = self.param1
config['param2'] = self.param2
return config
Поэтому, когда вы сохраняете модель, процедура сохранения вызовет get_config и сериализует внутреннее состояние вашего пользовательского слоя, т. Е. self.params
И когда вы его загрузите, загрузчик будет знать, как инициализировать внутреннее состояние вашего пользовательского слоя.
Комментарии:
1. что такое idx_init и idx_end, пожалуйста
2. Исправлено, это парам1 и 2. В методе get_config вы должны сохранить все атрибуты слоя, необходимые для его работы (для того, чтобы позже загрузить слой с правильной конфигурацией).