编写自己的神经层
"""
编写自己的keras层只需要实现3个方法以及一个初始化方法,写的时候可以参阅相关的源代码,一般不需要自定义神经层
1. build(input_shape): 定义权重的地方。这个方法必须设置`self.built =True`,通过调用super来完成
2. call(inputs): 这里是运算部分,只需要关注传入call的第一个参数:输入张量
3. compute_output_shape(input_shape): 如果输入与输出的shape不一致,这里应该定义shaoe变化的逻辑,折让keras能够自动推断各层的形状
"""
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
super().__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().build(input_shape)
def call(self, inputs):
return K.dot(inputs, self.kernel)
def compute_output_shape(self, input_shape):
return (input_shape[0], self.output_dim)
实例
import keras
from keras.layers import Layer, Dense, Dropout, Activation
from keras import backend as K
from keras.models import Sequential
from keras.datasets import mnist
class Antirectifier(Layer):
"""
# 1.因为不需要传入额外的东西,这只是激活函数。可以参考源代码编写
# 2. 重写build方法,因为没有初始化参数,所以不需要重写
"""
def call(self, inputs):
inputs -= K.mean(inputs, axis=1, keepdims=True)
inputs = K.l2_normalize(inputs, axis=1)
pos = K.relu(inputs)
neg = K.relu((-inputs))
return K.concatenate([pos, neg], axis=1)
def compute_output_shape(self, input_shape):
shape = list(input_shape)
assert len(shape) == 2
shape[-1] *= 2
return tuple(shape)
batch_size = 128
num_classes = 10
epochs = 40
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
model = Sequential()
model.add(Dense(256, input_shape=(784,)))
model.add(Antirectifier())
model.add(Dropout(0.1))
model.add(Dense(256))
model.add(Antirectifier())
model.add(Dropout(0.1))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))