1. Пользовательский слой
Для простых настраиваемых действий без сохранения состояния вы можете передатьlayers.core.Lambda
слой для достижения. Но для пользовательских слоев, которые содержат обучаемые веса, вы должны реализовать слой самостоятельно.
Это Keras2.0, скелет слоя Keras (если вы используете старую версию, обновите ее до новой версии). Вам нужно всего лишь реализовать три метода:
-
build(input_shape)
: Здесь вы определяете веса. Этот метод должен установитьself.built = True
, доступ к которому можно получить, позвонивsuper([Layer], self).build()
Заканчивать. -
call(x)
: здесь записывается функциональная логика слоя. Вам просто нужно обратить внимание на входящиеcall
Первый параметр : входной тензор, если только вы не хотите, чтобы ваш слой поддерживал маскирование. -
compute_output_shape(input_shape)
: если ваш слой изменяет форму входного тензора, вы должны определить здесь логику изменения формы, которая позволяет Keras автоматически определять форму каждого слоя.
from keras import backend as K
from keras.engine.topology import Layer
class MyLayer(Layer):
def __init__(self, output_dim, **kwargs):
self.output_dim = output_dim
super(MyLayer, self).__init__(**kwargs)
def build(self, input_shape):
# 为该层创建一个可训练的权重
self.kernel = self.add_weight(name='kernel',
shape=(input_shape[1], self.output_dim),
initializer='uniform',
trainable=True)
super(MyLayer, self).build(input_shape) # 一定要在最后调用它
def call(self, x):
return K.dot(x, self.kernel)
def compute_output_shape(self, input_shape):
return (input_shape[0], self.output_dim)
Также можно определить слои Keras с несколькими входными тензорами и несколькими выходными тензорами. Для этого следует принять методbuild(input_shape)
,call(x)
и compute_output_shape(input_shape)
Вход и выход - это списки. Вот пример, аналогичный приведенному выше:
from keras import backend as K
from keras.engine.topology import Layer
class MyLayer(Layer):
def __init__(self, output_dim, **kwargs):
self.output_dim = output_dim
super(MyLayer, self).__init__(**kwargs)
def build(self, input_shape):
assert isinstance(input_shape, list)
# 为该层创建一个可训练的权重
self.kernel = self.add_weight(name='kernel',
shape=(input_shape[0][1], self.output_dim),
initializer='uniform',
trainable=True)
super(MyLayer, self).build(input_shape) # 一定要在最后调用它
def call(self, x):
assert isinstance(x, list)
a, b = x
return [K.dot(a, self.kernel) + b, K.mean(b, axis=-1)]
def compute_output_shape(self, input_shape):
assert isinstance(input_shape, list)
shape_a, shape_b = input_shape
return [(shape_a[0], self.output_dim), shape_b[:-1]]
Существующий слой Keras — хороший пример реализации любого слоя. Не стесняйтесь читать исходный код!
2. Пользовательская функция оценки
Пользовательские функции оценки должны передаваться во время компиляции. Эта функция должна начинаться с(y_true, y_pred)
в качестве входного параметра и возвращает тензор в качестве выходного результата.
import keras.backend as K
def mean_pred(y_true, y_pred):
return K.mean(y_pred)
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy', mean_pred])
3. Пользовательская функция потери
Пользовательские функции потерь также должны передаваться во время компиляции. Эта функция должна начинаться с(y_true, y_pred)
в качестве входного параметра и возвращает тензор в качестве выходного результата.
import keras.backend as K
def my_loss(y_true, y_pred):
return K.mean(K.squre(y_pred-y_true))#以平方差举例
model.compile(optimizer='rmsprop',
loss=my_loss,
metrics=['accuracy'])
4. Работа с пользовательскими слоями (или другими пользовательскими объектами) в сохраненных моделях.
Если загружаемая модель содержит пользовательские слои или другие пользовательские классы или функции, вы можете передатьcustom_objects
параметры передают их механизму загрузки:
from keras.models import load_model
# 假设你的模型包含一个 AttentionLayer 类的实例
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')