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_data
def 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层的实现。