【发布时间】:2021-01-05 04:55:22
【问题描述】:
我看到至少三种在 keras 中创建自定义层的方法。
import tensorflow as tf
import numpy as np
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.models import Model
def reset_seed(seed=313):
tf.keras.backend.clear_session()
tf.random.set_seed(seed)
np.random.seed(313)
class Method1MLP(tf.keras.layers.Layer):
def __init__(self, in_units, out_units, **kwargs):
self.dense = Dense(in_units)
self.out = Dense(out_units)
super().__init__(**kwargs)
def call(self, x):
temp = self.dense(x)
return self.out(temp)
class Method2MLP(tf.keras.layers.Layer):
def __init__(self, in_units, out_units, **kwargs):
self.dense = Dense(in_units)
self.out = Dense(out_units)
super().__init__(**kwargs)
def __call__(self, x):
temp = self.dense(x)
return self.out(temp)
class Method3MLP(tf.keras.layers.Layer):
def __init__(self, in_units, out_units, **kwargs):
self.in_units = in_units
self.out_units = out_units
super().__init__(**kwargs)
def __call__(self, x):
temp = Dense(self.in_units)(x)
return Dense(self.out_units)(temp)
# define dummy inputs and outputs
x = np.random.random((100, 10,5))
y = np.random.random((100, 1))
现在首先构建没有自定义层的模型
reset_seed()
inp = Input(shape=(10,5))
temp = Dense(5)(inp)
out = Dense(1)(temp)
model = Model(inputs=inp, outputs=out)
model.compile(optimizer=tf.keras.optimizers.Adam(), loss='mse')
print(model.summary())
model.fit(x=x,y=y, epochs=5)
使用方法一
reset_seed()
inp = Input(shape=(10,5))
out = Method1MLP(5,1)(inp)
model = Model(inputs=inp, outputs=out)
model.compile(optimizer=tf.keras.optimizers.Adam(), loss='mse')
print(model.summary())
model.fit(x=x,y=y, epochs=5)
使用方法二
reset_seed()
inp = Input(shape=(10,5))
out = Method2MLP(5,1)(inp)
model = Model(inputs=inp, outputs=out)
model.compile(optimizer=tf.keras.optimizers.Adam(), loss='mse')
print(model.summary())
model.fit(x=x,y=y, epochs=5)
使用方法3
reset_seed()
inp = Input(shape=(10,5))
out = Method3MLP(5,1)(inp)
model = Model(inputs=inp, outputs=out)
model.compile(optimizer=tf.keras.optimizers.Adam(), loss='mse')
print(model.summary())
model.fit(x=x,y=y, epochs=5)
以上所有代码 sn-ps 给出相同的结果。
虽然官方文档推荐方法 1,但方法 2 和方法 3 的优点是它们暴露了中间输出,即自定义层内的输出。这使得在训练后很容易将这些输出作为 numpy 数组获取。我也想了解方法二和方法三的区别。在__init__方法中是否启动层无关?
方法2(当我们显式写__call__方法时)和方法1(当我们让keras Layer的__call__方法调用我们的call方法时)有什么区别吗?
【问题讨论】:
标签: python tensorflow keras neural-network keras-layer