有时keras内置的层无法满足自己的要求时,就需要自己编写,比如自定义一个损失函数
1. 自定义层的框架结构
Keras2的层应该具有的框架结构,要定制自己的层,你需要实现下面三个方法:
-
build(input_shape)
:这是定义权重的方法,可训练的权应该在这里被加入列表`self.trainable_weights
中。其他的属性还包括self.non_trainabe_weights
(列表)和self.updates
(需要更新的形如(tensor, new_tensor)的tuple的列表)。 -
call(x)
:这是定义层功能的方法,除非你希望你写的层支持masking,否则你只需要关心call
的第一个参数:输入张量 -
compute_output_shape(input_shape)
:如果你的层修改了输入数据的shape,你应该在这里指定shape变化的方法,这个函数使得Keras可以做自动shape推断
2. 自定义层的实例
1. 自定义层(功能:矩阵乘积)
from keras import backend as K
from keras.engine.topology import Layer
import numpy as np
class MyLayer(Layer):
def __init__(self, output_dim, **kwargs):
self.output_dim = output_dim
#继承Layer类的__init__方法
super(MyLayer, self).__init__(**kwargs)
def build(self, input_shape):
# Create a trainable weight variable for this layer.
self.kernel = self.add_weight(name='kernel',
shape=(input_shape[1], self.output_dim),
initializer='uniform',
trainable=True)
super(MyLayer, self).build(input_shape) # Be sure to call this somewhere!
def call(self, x):
return K.dot(x, self.kernel)
def compute_output_shape(self, input_shape):
return (input_shape[0], self.output_dim)
2. 自定义损失函数(人脸识别中的TripletLoss)
class TripletLossLayer(Layer):
def __init__(self, alpha, **kwargs):
self.alpha = alpha
super(TripletLossLayer, self).__init__(**kwargs)
def triplet_loss(self, inputs):
a, p, n = inputs
p_dist = K.sum(K.square(a-p), axis=-1)
n_dist = K.sum(K.square(a-n), axis=-1)
return K.sum(K.maximum(p_dist - n_dist + self.alpha, 0), axis=0)
def call(self, inputs):
loss = self.triplet_loss(inputs)
self.add_loss(loss)
return loss
参考keras中文文档