57.3_Conv2d层的实现
57.3 Conv2d层的实现
接下来实现作为层的Conv2d类(不是函数)。代码如下所示。
dezero/layers.py
class Conv2d(Layer): def__init__(self,out_channels,kernel_size,stride $= 1$ pad $\equiv 0$ ,nobias $\equiv$ False,dtype $\equiv$ np.float32,in_channels $\equiv$ None): super().__init_() self.in_channels $=$ in_channels self.out_channels $=$ out_channels self.kernel_size $=$ kernel_size self.Stride $=$ stride self_pad $=$ pad self.dtype $=$ dtype self.W $=$ Parameter(None,name $\equiv$ 'W') ifin_channelsisnotNone: self._init_W() ifnobias: self.b $=$ None else: self.b $=$ Parameter(np.zeros(out_channels,dtype $\equiv$ dtype),name $\equiv$ 'b') def init_W(self,xp=np): C,OC $=$ self.in_channels,self.out_channels KH,KW $=$ pair(self_kernel_size) scale $\equiv$ np.sqrt(1/(C*KH*KW)) W_data=xp.random.randint(OC,C,KH,KW).astype(self.dtype)*scale self.W.data $\equiv$ W_datadef forward(self, x):
if self.w.data is None:
self.in_channels = x.shape[1]
xp =uda.get_array_module(x)
self._init_W(xp)
y = F.conv2dSimple(x, self.W, self.b, self.Stride, self_pad)
#或者 y = F.conv2d(x, self.W, self.b, self.Stride, self_pad)
return y上面的代码首先继承了Layer类,然后实现了Conv2d类。初始化时接收表57-2中的参数。
表 57-2 Conv2d 类的初始化参数
表57-2中需要注意的是in_channels的默认值是None。如果它是None,in_channels的值将从forward(x)中的x的形状中获得,同时权重数据也会被初始化。具体做法与全连接层的Linear层相同。
主处理用到了刚刚实现的函数 conv2d simples(或 conv2d)。以上是Conv2d层的实现。