参考:https://blog.csdn.net/dss_dssssd/article/details/82977170 , https://blog.csdn.net/weixin_37598106/article/details/106693120
class MyLayer(layers.Layer):
def __init__(self, unit=32):
super(MyLayer, self).__init__()
self.unit = unit
def build(self, input_shape):
self.weight = self.add_weight(shape=(input_shape[-1], self.unit),
initializer=keras.initializers.RandomNormal(),
trainable=True)
self.bias = self.add_weight(shape=(self.unit,),
initializer=keras.initializers.Zeros(),
trainable=True)
def call(self, inputs):
return tf.matmul(inputs, self.weight) + self.bias
my_layer = MyLayer(3)
x = tf.ones((3,5))
out = my_layer(x)
print(out)
解释:
定义一个类对象
my_layer = Mylayer(3)
仅调用了Mylayer()类中__init__()方法,获得了self.units=3这个变量
初始化一个输入对象
x = tf.ones((3, 5))
开始调用build(),call()函数
out = my_layer(x)
为什么不用外部调用就可以运行build(),call()等函数?
答:因为在layer()类中有一个__call__()方法(已集成),会被自动调用。
调用build()可初始化两个可训练的值,分别是权重和偏置。
为什么要有build()函数?
答:build()可自定义网络的权重的维度,可根据输入来指定权重的维度,若权重固定,可避免使用build()方法。
另外一个需要注意的地方在于:self.built = True
该参数在build() 运行开始时为False,为了保证先调用build() 方法, 再调用call() 方法
结束时会自动赋值为True,保证build() 方法只被调用一次
得到初始化的权重和偏置值,接下来调用call()进行正向传播(或是实现逻辑功能函数),返回该层的输出值,不包含激活函数计算。
总结:
Layer的子类一般实现如下:
第一次训练先计算Model(x), 然后计算Model(x).build(input),最后计算Model(x).call(input),第二次往后就跳过了中间步骤
pytorch主要是按照__call__
, __init__
,forward
三个函数实现网络层之间的架构
一般步骤:首先创建类对象m,然后通过m(input)
实际上调用__call__(input)
,然后__call__(input)
调用forward()
函数,最后返回计算结果。
所以自己创建多层神经网络模块时,只需要在实现__init__
和forward
即可。
举例:
# define three layers
class Nets(nn.Module):
def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
super().__init__()
self.layer1 = nn.Linear(in_dim, n_hidden_1)
self.layer2 = nn.Linear(n_hidden_1, n_hidden_2)
self.layer3 = nn.Linear(n_hidden_2, out_dim)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
return x
__call__
方法,而在__call__
方法中调用了forward函数。以下为各层神经元个数:
输入: in_dim
第一层: n_hidden_1
第二层:n_hidden_2
第三层(输出层):out_dim
原文:https://www.cnblogs.com/harbin-ho/p/14684762.html