44.3_Linear类的实现
44.3 Linear类的实现
接下来实现进行线性变换的Linear类(实现的是作为层的Linear类,而不是作为函数的Linear类)。这里首先给出简单的Linear类,然后展示改良版的Linear类。我们来看以下代码。
import numpy as np
importdezero-functionsasF
fromdezero.core import Parameter
class Linear(Layer): def__init__(self,in_size,out_size,nobias $\equiv$ False,dtype=np.float32): super().__init_() I,O $=$ in_size,out_size W_data $=$ np.random.randint(I,O).astypedtype)\*np.sqrt(1/I) self.W $=$ Parameter(W_data,name $\coloneqq$ 'W') ifnobias: self.b $=$ None else: self.b $=$ Parameter(np.zeros(O,dtype $\equiv$ dtype),name $\equiv$ 'b')
defforward(self,x): y $=$ F.Linear(x,self.W,self.b) returnyLinear类是在Layer类的基础上实现的。初始化方法__init__(self, in_size, out_size, nobias)接收输入大小、输出大小和“是否使用偏置”的标志位作为参数。当nobias为True时,省略偏置。
初始化权重和偏置的做法是向实例变量设置Parameter实例,如self.W = Parameter(...) 和 self.b = Parameter(...)。设置后,这两个参数的Parameter实例变量名就会被添加到self._params中。

Linear类的权重新始值需要设置为随机数。上一个步骤将随机的初始值的量级设置为0.01(0.01 * np.random.randint(...))。这里将量级设置为np.sqrt(1/in_size)。这是参考文献[25]中提出的设置初始值的方法。另外,神经网络的计算也支持32位浮点数,因此,我们使用32位浮点数作为参数数据的默认设置值。
之后,在forward方法中实现线性变换,只需调用DeZero的linear函数即可。以上就是Linear类的实现。
前面提到了Linear类有一种更好的实现方法,即延迟创建权重W的时间。具体做法是在forward方法中创建权重,这样就能自动确定Linear类的输入大小(in_size)(无须用户指定)。下面是改进版的Linear类的实现。
dezero/layers.py
import numpy as np
importdezero-functionsasF
fromdezero.core import Parameter
class Linear(Layer): def__init__(self,out_size,nobias $\equiv$ False,dtype=np.float32,in_size=No super().__init_() self.in_size $=$ in_size self.out_size $=$ out_size self.dtype $=$ dtype self.W $=$ Parameter(None,name $\coloneqq$ 'W') if self.in_sizeis not None:#如果没有指定in_size,则延后处理 self._init_W() ifnobias: self.b $=$ None else: self.b $=$ Parameter(np.zeros(out_size,dtype $\equiv$ dtype),name $\equiv$ 'b') def_init_W(self): I,O $=$ self.in_size,self.out_size W_data $=$ np.random.randint(I,O).astype(self.dtype)*np.sqrt(1/I) self.W.data $=$ W_data
defforward(self,x): #在传播数据时初始化权重if self.w.data is None:
self.in_size = x.shape[1]
self._init_W()
y = F.Linear(x, self.w, self.b)
return y这就是改进版的Linear类。这里需要注意的地方是我们不用指定__init__方法的in_size。in_size参数的默认值为None,在None的情况下,self.W.data的初始化会被推迟。具体来说,forward(self,x)方法根据输入x的大小创建权重数据。现在我们只要按照layer = Linear(100)的方式指定输出大小即可。以上就是Linear类的实现。