【Mxnet】神经网络(三)

Gluon中的nn模块创建 全连接层、卷积层、池化层、激活层

全连接层

mxnet.gluon.nn.Dense(units, activation=None, use_bias=True, flatten=True, dtype=‘float32’, weight_initializer=None, bias_initializer=‘zeros’, in_units=0, **kwargs)

函数功能说明
Dense函数主要实现了一个全连接层的功能output=activation(dot(input,weight)+bias)output表示的是函数的输出值,input表示的是输入值,activation表示输出元素输出时经过的激活函数,weight表示的是权重矩阵,bias表示的是偏置,当use_bias参数为True时偏置才会被创建。
参数说明

  • units(int):输出矩阵的大小
  • activation(str):设置使用的激活函数,常用的激活函数有relu、sigmoid、tanh、softrelu、softsign等。如果activation为None,则不使用激活函数,即linear函数,f(x)=x。
  • use_bias(bool,default True):是否创建偏置向量
  • flatten(bool,default True):输入的向量是否被展开,如果为True则除了第一个axis保持不变,其他axis都要被折叠在一起。如果为false则,除了最后一个axis其他的都保持不变。怎么理解这段话呢?下面举个例子吧,比如说,你输入矩阵shape为(3,4,4),units为10,当flatten为True时,那么输出矩阵的shape就为(3,10),当flatten为False时,输出矩阵的shape就为(3,4,10)
  • dtype(str or np.dtype,default “float32”):输出数据的数据类型
  • bias_initializer(str or initializer):设置偏置的初始化函数
  • in_units(int,optional):输入数据的大小,不需要特殊指定,mxnet会根据前向传播自动推断输入数据的shape
    注意
    输入矩阵必须是2阶的,否则我们需要通过flatten来将输入矩阵转换为2阶,利用nn.Dense方法来创建全连接层,还可以输出该层的结构
from mxnet.gluon import nn
from mxnet import nd
full_con = nn.Dense(10) # 创建输出为10的全连接层
# print(full_con)
full_con.initialize() # 初始化权重参数
x = nd.random.uniform(-1,1, (3,4))  # 输入参数
print(x)
print(full_con(x))
print(full_con.weight.data())
print(full_con.bias.data())
---------------------------------------------------
X:
[[ 0.09762704  0.18568921  0.43037868  0.6885315 ] 
 [ 0.20552671  0.71589124  0.08976638  0.6945034 ] 
 [-0.15269041  0.24712741  0.29178822 -0.23123658]]
<NDArray 3x4 @cpu(0)>
full_con(x):
[[-0.02524133 -0.00874885  0.01191344  0.0561824  -0.02068388  0.05412574
   0.05242086  0.05288687  0.03415157  0.01685524]
 [-0.06026538 -0.01308061  0.03809736  0.02923798 -0.01942167  0.02161897
   0.01259167  0.04414382  0.02186201  0.02086244]
 [ 0.02468396 -0.02181557  0.00639283  0.00134188 -0.01811863  0.00448567
  -0.0152549  -0.00866505  0.00720075  0.01885401]]
<NDArray 3x10 @cpu(0)>
weight:
[[-0.00873779 -0.02834515  0.05484822 -0.06206018]
 [ 0.06491279 -0.03182812 -0.01631819 -0.00312688]
 [ 0.0408415   0.04370362  0.00404529 -0.0028032 ]
 [ 0.00952624 -0.01501013  0.05958354  0.04705103]
 [-0.06005495 -0.02276454 -0.0578019   0.02074406]
 [-0.06716943 -0.01844618  0.04656678  0.06400172]
 [ 0.03894195 -0.05035089  0.0518017   0.05181222]
 [ 0.06700657 -0.00369488  0.0418822   0.0421275 ]
 [-0.00539289  0.00286685  0.03927409  0.02504314]
 [-0.05344158  0.03088857  0.01958894  0.01148278]]
<NDArray 10x4 @cpu(0)>
bias:
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
<NDArray 10 @cpu(0)>
卷积层

mxnet.gluon.nn.Conv2D(channels, kernel_size, strides=(1, 1), padding=(0, 0), dilation=(1, 1), groups=1, layout=‘NCHW’, activation=None, use_bias=True, weight_initializer=None, bias_initializer=‘zeros’, in_channels=0, **kwargs)

函数功能说明:实现2D卷积
参数说明

  • channels(int):设置卷积输出的通道数,也就是卷积核的个数
  • kernel_size(int or tuple/list of 2 int):设置卷积核的shape
  • strides(int or tuple/list of 2 int):设置卷积的步长
  • padding(int or a tuple/list of 2 int):卷积的时候是否需要在输入矩阵的周围填充0,从而来控制输出矩阵的大小
  • dilation(int or tuple/list of 2 int):设置膨胀卷积的参数,默认不使用膨胀卷积,膨胀卷积的目的是为了增大卷积核的感受野
  • groups(int):用于控制输入和输出之间的连接。当groups=1时,所有输入进行卷积产生输出。当groups=2时,等价于两个卷积层并排进行卷积,然后再将输出的结果进行连接,每个卷积层只使用了输入举证一半的channels
  • layout(str,default “NCHW”):输入数据的数据格式,只有"NCHW"和"NHWC"两种格式,其中"N"表示的是batch,"C"表示的是channel,"H"表示的是height,"W"表示的是width
  • in_channels(int,default 0):输入矩阵的通道数,如果没有特殊指定,mxnet会根据输入数据的shape推断出channel
    activation(str):设置激活函数
  • use_bias(bool):是否使用偏置
  • weight_initializer(str or initializer):设置初始化权重的方法
  • bias_initializer(str or initializer):设置偏置的初始化方法
    注意
    输入数据:输入数据是一个4D矩阵,输入数据的格式请参考layout参数
    输出数据:输出数据的格式和layout相同,输出数据的out_height和out_width计算公式如下:
    out_height = floor((height + 2 * padding[0] - dilation[0] * (kernel_size[0] - 1) - 1 ) / stride[0] ) + 1
    out_width = floor((width + 2 * padding[1] - dilation[1] * (kernel_size[1] - 1) - 1) /stride[1] + 1
池化层

mxnet.gluon.nn.MaxPool2D(pool_size=(2, 2), strides=None, padding=0, layout=‘NCHW’, ceil_mode=False, **kwargs)

函数功能说明:实现一个最大池化功能
参数说明

  • pool_size(int or list/tuple of 2 ints):最大池化的窗口大小
  • strides(int,list/tuple of 2 ints,or None):最大池化窗口的移动步长
  • padding(int or list/tuple of 2 ints):输入矩阵的边缘填充大小设置
  • layout(str,default “NCHW”):输入矩阵的数据设置
  • ceil_mode(bool,default False):如果为True将使用ceil来替换floor去计算输出矩阵的shape

最大池化层输入矩阵尺寸计算公式
out_height = floor((height + 2 * padding[0] - pool_size[0]) / strides[0] ) + 1
out_width = floor((width +2 * padding[1] - pool_size[1]) / strides[1] ) + 1

from mxnet.gluon import nn
from mxnet import nd
net = nn.Sequential()   # 创建一个容器来创建网络
"""创建神经网络"""
net.add(
    nn.Conv2D(channels=3, kernel_size=3, activation='relu'),    # 创建卷积层,kernel_size(5,5)
    nn.MaxPool2D(pool_size=2, strides=2),                        # 最大池化层
    nn.Conv2D(channels=10, kernel_size=3, activation='relu'),   # # 创建卷积层,非等长kernel_size(10,3)
    nn.MaxPool2D(pool_size=2, strides=2),
    nn.Dense(120, activation='relu'),                           # 全连接层
    nn.Dense(80, activation='relu'),                            # 全连接层
    nn.Dense(10)
)
# print(net)
# Sequential(
#   (0): Conv2D(None -> 3, kernel_size=(3, 3), stride=(1, 1), Activation(relu))
#   (1): MaxPool2D(size=(2, 2), stride=(2, 2), padding=(0, 0), ceil_mode=False, global_pool=False, pool_type=max, layout=NCHW)
#   (2): Conv2D(None -> 10, kernel_size=(3, 3), stride=(1, 1), Activation(relu))
#   (3): MaxPool2D(size=(2, 2), stride=(2, 2), padding=(0, 0), ceil_mode=False, global_pool=False, pool_type=max, layout=NCHW)
#   (4): Dense(None -> 120, Activation(relu))
#   (5): Dense(None -> 80, Activation(relu))
#   (6): Dense(None -> 10, linear)
# )

net.initialize()    # 初始化权重参数
inpt = nd.random.uniform(shape=(4,1,28,28))
y = net(inpt)       # 前向传播
print(y.shape)      # (4,10)
# 查看指定层权重参数
print(net[0].weight.data().shape)   # (3, 1, 3, 3)
print(net[4].bias.data().shape)     # (120,)

使用nn.Block构建网络,在使用Sequential构建网络的时候很方便,但是有一个不好的地方在于,网络的前向传播是自动构建的。接下来我们介绍另一种方法,可以方便快捷构建网络同时还能自定义网络的前向传播

from mxnet.gluon import nn
from mxnet import nd

class MyMLP(nn.Block):
    def __init__(self, **kwargs):
        super(MyMLP, self).__init__(**kwargs)
        self.blk = nn.Sequential()
        self.blk.add(
            nn.Dense(3,activation='relu'),
            nn.Dense(4,activation='relu')
        )
        self.dense = nn.Dense(5)

    def forward(self, x):
        y = nd.relu(self.blk(x))
        return self.dense(y)

net = MyMLP()
# print(net)
# MyMLP(
#   (blk): Sequential(
#     (0): Dense(None -> 3, Activation(relu))
#     (1): Dense(None -> 4, Activation(relu))
#   )
#   (dense): Dense(None -> 5, linear)
# )
net.initialize()
inpt = nd.random.uniform(shape=(2,2))
res = net(inpt)
print(res, res.shape)   # shape: (2,5)

你可能感兴趣的:(mxnet,深度学习)