通常在创建网络时,我们也只是会使用mxnet的api而已,根本无法理解它内部的真正含义。接下来我们创建一些自定义层,来看看网络是如何实现的:
# 自定义层
class mydense(gn.nn.Block):
def __init__(self,out_units,in_units,**kwargs):
super(mydense, self).__init__(**kwargs)
with self.name_scope():
self.weight=self.params.get("weight",shape=(out_units,in_units)) #权重
self.bias = self.params.get("bias", shape=(out_units)) # 偏置项
def forward(self, x):
linear=nd.dot(x,self.weight.data())+self.bias.data()
return nd.relu(linear)
上面创建了一个简单的网络层,接下来我们给它附上一些参数:
dense=mydense(out_units=10,in_units=5)
print(dense.params)
结果:
接下来创建一个实例化对象来看看它的参数:
dense=mydense(out_units=5,in_units=10)
print(dense.params)
dense.initialize() # 初始化
X=nd.random_normal(shape=(2,10),scale=0.1)
print("自定义层:",dense(X))
结果:
既然我们自己能够定义block,那么就可以被gluon使用:
# 使用gluon调用自定义层
def gluon_net():
net=gn.nn.Sequential()
net.add(mydense(out_units=64,in_units=32))
net.add(mydense(out_units=5, in_units=64))
return net
net=gluon_net()
net.initialize()
X1=nd.random_normal(shape=(2,32))
print("gluon调用自定义层:",net(X1))
结果:
从代码中我们可以发现一个问题:自定义的层需要输入两个参数,输入神经元和输出神经元,而gluon中则只需要设置输出神经元。
本章所有源码:
import mxnet.gluon as gn
import mxnet.ndarray as nd
import mxnet.autograd as ag
# 自定义层
class mydense(gn.nn.Block):
def __init__(self,out_units,in_units,**kwargs):
super(mydense, self).__init__(**kwargs)
with self.name_scope():
self.weight=self.params.get("weight",shape=(in_units,out_units)) #权重
self.bias = self.params.get("bias", shape=(out_units)) # 偏置项
def forward(self, x):
linear=nd.dot(x,self.weight.data())+self.bias.data()
return nd.relu(linear)
# 创建一个实例化对象来看看它的参数
dense=mydense(out_units=5,in_units=10)
print(dense.params)
dense.initialize() # 初始化
X=nd.random_normal(shape=(2,10),scale=0.1)
print("自定义层:",dense(X))
# 使用gluon调用自定义层
def gluon_net():
net=gn.nn.Sequential()
net.add(mydense(out_units=64,in_units=32))
net.add(mydense(out_units=5, in_units=64))
return net
net=gluon_net()
net.initialize()
X1=nd.random_normal(shape=(2,32))
print("gluon调用自定义层:",net(X1))