质量声明:原创文章,内容质量问题请评论吐槽。如对您产生干扰,可私信删除。
主要参考:李沐等:动手学深度学习-伯克利教材


文章目录

  • MXNet 基础
    • 导入MXNet
    • 张量模块 nd
    • 自动求梯度 autograd
  • 基本单元介绍
    • 基本网络结构/层
    • 自定义网络结构/层
    • 激活函数
    • 参数初始化方式
    • 损失函数
    • 优化算法(小批量)
  • 模型构建、训练和预测
    • 模型构建
    • 模型训练
    • 模型预测
    • 模型参数存储和读取
  • 可视化

摘要: MXNet 基础和入门,包括基本单元、模型相关、数据处理等


MXNet 基础

导入MXNet

from mxnet import nd                                     # Tensor模块
from mxnet import autograd                        # 自动求梯度
from mxnet import init                                        # 初始化
from mxnet.gluon import nn                         # 神经网络基本结构
from mxnet.gluon import loss as gloss   # 损失函数

张量模块 nd

注:NDArray基本与NunPy保持一致,这里只列举部分函数

# 一维向量
x = nd.array([0,1,2,3,4,5])
y = nd.arange(6)
z = nd.ones_like(x)# 多维张量
A = nd.zeros((3,4,5))                                                # Channals x M x N
B = nd.ones((3,4,5), dtype="uint8")                 # 指定dtype,默认float32
C = nd.random.normal(0, 1, shape=(3,4,5))  # 指定mu, sigma, shape, dtype, ctx# 属性
A.shape   # 张量/向量形状
A.size        # 元素总数
A.dtype    # 数据类型# 重构
D = x.reshape(2,3)
D = nd.reshape(x, (2,3))# 拼接
L = nd.concat(A, C, dim=0)   # 通道连接,层数增加
V = nd.concat(A, C, dim=1)   # 行连接,各层行数增加
H = nd.concat(A, C, dim=2)   # 列连接,各层列数增加# 元素级运算
A + C;     A - C;     A * C;     A / C;      A ** 2
nd.exp(A);    nd.sum(B);   nd.mean(C);    nd.sqrt(B)# 矩阵乘法
nd.dot(D, D.T)# 张量乘法
x = nd.reshape(nd.arange(12), shape=(3,2,2))
y = nd.reshape(nd.arange(12), shape=(2,2,3))
result = nd.dot(x,y)
result.shape == (3, 2, 2, 3)# L2范数
nd.norm(B)
nd.sqrt(nd.sum(B**2)) # 上述运算结果均为<NDArray>类型,转为标量
nd.norm(B).asscalar() == 7

广播机制:(可能触发) 先将复制适当元素,使二者shape一致

A = nd.ones((3,2))
B = nd.ones((1,2))
A + B

节省内存开销:

# 计算过程中不开辟新的内存
before = id(A)
nd.elemwise_add(A, A, out=A)
id(A) == before # 简化写法也能节省内存开销
before = id(A)
A += A
id(A) == before

转为numpy实例:

A.asnumpy()

自动求梯度 autograd

步骤:

  1. 变量赋初值
  2. 申请存储梯度的内存 param_in.attach_grad()
  3. 记录与梯度相关的函数计算(正向) with autograd_record()
  4. 自动求梯度(反向) param_out.backward()
# 对 theta 求梯度
x = nd.ones((3,3))
theta = nd.random.normal(shape=3)
theta.attach_grad()
with autograd.record():y = f(x, theta)
y.backward()
# 输出梯度
print(theta.grad)

其中f( )为前向运算函数,一般为损失函数loss ={ model(x, w, b), y }. 即使函数包含Python控制流(条件/循环),也有可能计算出变量的梯度.

基本单元介绍

基本网络结构/层

class 名称 参数
nn.Dense 稠密层/全连接层 units (int) ,activation (str)
nn.Dropout 神经元随机丢弃 rate(float)
nn.Conv2D 二维卷积层 channels (int) ,kernel_size (int or tuple/list of 2 int),stridespaddingactivation
nn.BatchNorm 批量归一化 /
nn.MaxPool2D 二维最大池化层 pool_sizestridespadding
nn.Flatten
nn.Embedding

自定义网络结构/层

  • 不含模型参数的自定义层:
class CenteredLayer(nn.Block):def __init__(self, **kwargs):super(CenteredLayer, self).__init__(**kwargs)def forward(self, x):return x - x.mean()
  • 含参的自定义层:
    由于Block类自带的的成员变量params是ParameterDict字典类型,则可以通过字典方法get( )来添加参数;调用是注意给定输入个数.
class MyDense(nn.Block):# units为该层的输出个数,in_units为该层的输入个数def __init__(self, units, in_units, **kwargs):super(MyDense, self).__init__(**kwargs)self.weight = self.params.get('weight', shape=(in_units, units))self.bias = self.params.get('bias', shape=(units,))def forward(self, x):linear = nd.dot(x, self.weight.data()) + self.bias.data()return nd.relu(linear)     # 整合relu激活函数

激活函数

  • 参考博文:神经网络中的各种激活函数
    官方文档:mxnet.ndarray.Activation
    示例:nn.Dense(360, activation = "relu" )

  • sigmoid y = 1 1 + e x p ( − x ) y = \frac{1}{1 + exp(-x)} y=1+exp(x)1

  1. Sigmoid函数的输出映射在(0,1)之间,可以用来做二分类,单调连续,输出范围有限,优化稳定,可以用作输出层。
  2. 求导容易
  3. 由于其软饱和性,反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练,导致训练出现问题。
  4. 激活函数计算量大,反向传播求误差梯度时,求导涉及除法。
  5. 其输出并不是以0为中心的。这个特性会导致后面网络层的输入也不是零中心的,进而影响梯度下降的运作
  • tanh y = e x p ( x ) − e x p ( − x ) e x p ( x ) + e x p ( − x ) y = \frac{exp(x) - exp(-x)}{exp(x) + exp(-x)} y=exp(x)+exp(x)exp(x)exp(x)
  1. 比Sigmoid函数收敛速度更快。
  2. 相比Sigmoid函数,其输出以0为中心,因此实际应用中 tanh 会比 sigmoid 更好,因为 tanh 的输出均值比 sigmoid 更接近 0,SGD会更接近 natural gradient(一种二次优化技术),从而降低所需的迭代次数
  3. 还是没有改变Sigmoid函数的最大问题——由于饱和性产生的梯度消失
  • softsign y = x 1 + a b s ( x ) y = \frac{x}{1 + abs(x)} y=1+abs(x)x

  • softrelu y = l o g ( 1 + e x p ( x ) ) y = log(1 + exp(x)) y=log(1+exp(x))

  • relu y = m a x ( x , 0 ) y = max(x, 0) y=max(x,0)

  1. 由于 x>0时导数为 1,所以ReLU 能够在x>0时保持梯度不衰减,从而缓解梯度消失问题。但随着训练的推进,部分输入会落入硬饱和区,导致对应权重无法更新。这种现象被称为“神经元死亡”,影响网络的收敛性

  2. 使用 ReLU 得到的 SGD 的收敛速度会比 sigmoid/tanh 快很多

  3. ReLU的输出具有偏移现象,即输出均值恒大于零,影响网络的收敛性

  • PReLU
  1. 为了避免梯度消失,提出了LReLU,其中 a i a_i ai较小且取固定值. 但在一些实验中,LReLU对准确率并没有太大的影响。很多时候,若想应用LReLU时,必须非常小心谨慎地重复训练,选取出合适的 a i a_i ai,LReLU才能表现得比ReLU好
  2. PReLU是ReLU 和 LReLU的改进版本,具有非饱和性,负半轴斜率 a j i a_{ji} aji可学习而非固定。PReLU收敛速度快、错误率低,可以用于反向传播的训练,可以与其他层同时优化
  • ELU
  1. ELU融合了sigmoid和ReLU,具有左侧软饱性
  2. 右侧线性部分使得ELU能够缓解梯度消失,而左侧软饱能够让ELU对输入变化或噪声更鲁棒。ELU减少了正常梯度与单位自然梯度之间的差距,它的输出均值接近于零,所以收敛速度更快

参数初始化方式

  • 官方文档: mxnet.initializer 定义
    示例:net.initialize( init.Normal( sigma = 0.01 ) )

  • Normal([sigma])

  • Xavier([rnd_type, factor_type, magnitude])

损失函数

  • 官方文档:mxnet.gluon : : loss 类定义
    示例:loss = gloss.L2loss()

  • L2Loss均方误差
    L = 1 2 ∑ i ∣ l a b e l i − p r e d i ∣ 2 . L = \frac{1}{2} \sum_i \vert {label}_i - {pred}_i \vert^2. L=21ilabelipredi2.

  • L1Loss
    L = ∑ i ∣ l a b e l i − p r e d i ∣ . L = \sum_i \vert {label}_i - {pred}_i \vert. L=ilabelipredi.

  • SigmoidBinaryCrossEntropyLoss 二分类交叉熵
    p r o b = 1 1 + exp ⁡ ( − p r e d ) L = − ∑ i l a b e l i ∗ log ⁡ ( p r o b i ) ∗ p o s _ w e i g h t + ( 1 − l a b e l i ) ∗ log ⁡ ( 1 − p r o b i ) prob = \frac{1}{1 + \exp(-{pred})} \\ L = - \sum_i {label}_i * \log({prob}_i) * pos\_weight + (1 - {label}_i) * \log(1 - {prob}_i) prob=1+exp(pred)1L=ilabelilog(probi)pos_weight+(1labeli)log(1probi)

  • SoftmaxCrossEntropyLoss softmax交叉熵
    p = s o f t m a x ( p r e d ) L = − ∑ i ∑ j l a b e l j log ⁡ p i j p = softmax({pred}) \\ L = -\sum_i \sum_j {label}_j \log p_{ij} p=softmax(pred)L=ijlabeljlogpij

  • LogisticLoss
    L = ∑ i log ⁡ ( 1 + exp ⁡ ( − p r e d i ⋅ l a b e l i ) ) L = \sum_i \log(1 + \exp(- {pred}_i \cdot {label}_i)) L=ilog(1+exp(predilabeli))

优化算法(小批量)

  • 参考博文:优化方法optimizer总结
    官方文档:mxnet.Optimizers 定义
    示例:gluon.Trainer(net.collect_params(), 'adam', {'learning_rate': 0.1, 'wd': 5})

  • 随机梯度下降 SGD:"sgd"

  • adagrad

  • adam:"adam"


模型构建、训练和预测

模型构建

net = nn.Sequential()
net.add(nn.Dense(360, activation='relu'),nn.Dropout(0.2),nn.Dense(64, activation='relu'),nn.Dropout(0.5),nn.Dense(1))
net.initialize(init.Normal(sigma=0.01))

模型训练

  1. 构建小批量数据数据生成器 train_iter = gdata.DataLoader()
  2. 构建模型训练器 trainer = gluon.Trainer(),接口文档 gluon.Trainer
  3. 循环n次epoch训练. 在每个epoch中,按小批量训练,所有batch训练结束则输出本次epoch的损失
net=get_net()
loss=gloss.L2Loss()
num_epochs=20; batch_size=64;  learning_rate=0.01; weight_decay=0
train_iter = gdata.DataLoader(gdata.ArrayDataset(train_features, train_labels), batch_size, shuffle=True)
trainer = gluon.Trainer(net.collect_params(), 'adam', {'learning_rate': learning_rate, 'wd': weight_decay})
for epoch in range(num_epochs):for X, y in train_iter:with autograd.record():l = loss(net(X), y)l.backward()trainer.step(batch_size)train_ls.append(log_rmse(net, train_features, train_labels))

模型预测

  • 模型输出:
out = net(X)
print(out.shape, out.dtype, out[0])

模型参数存储和读取

  • 参数保存:
filename = 'net.params'
net.save_parameters(filename)
  • 读取参数:
net = get_net()
net.load_parameters(filename)

可视化

losses, train_acc, test_acc = [],[],[]
# 可视化训练过程
idx = range(1,epochs+1)
plt.figure(figsize=(12, 4))
plt.subplot(121)
plt.xlabel("epoch")
plt.ylabel("loss")
plt.plot(idx, losses, 'o', linestyle='-')
plt.xticks(range(min(idx), max(idx)+1, 1))
plt.grid()
plt.subplot(122)
plt.xlabel("epoch")
plt.ylabel("accuracy")
plt.plot(idx, train_acc, 'o', linestyle='-', color="r", label="train accuracy")
plt.plot(idx, test_acc, 'o', linestyle='-', color="b", label="test accuracy")
plt.legend(loc="best")
plt.xticks(range(min(idx), max(idx)+1, 1))
plt.yticks(np.arange(0., 1.1, 0.1))
plt.grid()
plt.ylim([0,1.1])
plt.show()

MXNet:基础和入门相关推荐

  1. 如何零基础学习python语言_零基础如何入门Python语言?有哪些学习建议?

    众所周知,Python目前是最受欢迎的编程语言之一,尤其是对于零基础的初学者来说,Python语言更是十分的友好.因此,不少初学者常常会有这样一个共同的疑惑,零基础如何入门Python语言?本文就来给 ...

  2. ui设计培训需要什么基础?如何入门学习?

    ​ UI设计是一种直观面向用户的一个技术岗位,在互联网公司,UI设计岗位是不可或缺的,那么对于零基础想要学习UI设计的同学来说,ui设计培训需要什么基础?如何入门学习呢?我们来看看下面的详细介绍. ​ ...

  3. 零基础AJAX入门(含Demo演示源文件)

    零基础AJAX入门(含Demo演示源文件) 作者:一点一滴的Beer  个人主页:http://www.cnblogs.com/beer 摘要:因为笔者的大四毕业设计是做WebGIS系统,用过Web版 ...

  4. 零基础学python语言_零基础如何入门Python语言?有哪些学习建议?

    众所周知,Python目前是最受欢迎的编程语言之一,尤其是对于零基础的初学者来说,Python语言更是十分的友好.因此,不少初学者常常会有这样一个共同的疑惑,零基础如何入门Python语言?本文就来给 ...

  5. python外星人入侵游戏图片_跪求一个问题@关于外星人入侵游戏(《python编程基础从入门到实...

    我在学着编写<python编程基础从入门到实践>的"外星人入侵游戏"的时候,报错如下: Traceback (most recent call last): File ...

  6. 零基础自学python看什么书-零基础Python入门看哪本书好?这里有答案

    原标题:零基础Python入门看哪本书好?这里有答案 Python入门看哪本书好呢?Python入门不知道该选哪本书?Python入门没有一本好书引导,会很难吗?你还在为这些问题困扰吗?今天小编就来解 ...

  7. layuiadmin上手好难_新手自学板绘先学SAI还是PS好?零基础绘画入门需知!

    原标题:新手自学板绘先学SAI还是PS好?零基础绘画入门需知! 新手自学板绘先学SAI还是PS好?初学者如何入门绘画?学习板画难吗?怎样才能学习好绘画?想必这些都是绘画初学者们经常在想的问题吧,就是不 ...

  8. python图形编程基础-Python从基础到入门系列教程

    本教程集合了Python基础&系统管理,从基础到入门,带你走进Python世界!对Python有兴趣的可以学习一下哦基础系列:1.课程简介2.Python下载和安装3.IDLE使用简介4.第1 ...

  9. SQL基础使用入门(二): DML语句和DCL语句

    SQL语句第二个类别--DML 语句 DML是数据操作语言的缩写,主要用来对数据表中数据记录实例对象进行操作,包括插入.删除.查找以及修改四大操作,这也是开发人员使用中最为频繁的操作. 1.插入记录 ...

最新文章

  1. SCCM2016 集成WSUS提供补丁服务(一)
  2. 【在线画流程图】网站
  3. 阿里宣布成立云原生技术委员会,释放哪些趋势信息?
  4. 第 8 章 容器网络 - 051 - 在 overlay 中运行容器
  5. requestURI的组成部分
  6. java默认代码地址_Java 8默认方法可能会破坏您的(用户)代码
  7. 前端学习(2822):页面配置文件
  8. 栅格矢量化_学会用栅格系统,普通LOGO秒变高大上
  9. php如何跟踪调试,PHP使用debug_backtrace方法跟踪调试代码调用详解
  10. “进化”的搜索方式:揭秘微软语义搜索背后的技术
  11. 清空SQL数据库日志
  12. 安卓源代码_如何从在安卓Android手机获取微信小程序源代码
  13. python去除停用词_python jieba分词如何去除停用词
  14. matlab做线性规划图
  15. PG修改表字段长度报错 cached plan must not change result type Hint: Please restore the result type
  16. 凯撒密码的超详细讲解
  17. 上机练习2 类与对象 pc cpu harddisk对象组合
  18. MATLAB图像处理_YUV格式详解
  19. MQ,如何做到削峰填谷
  20. 柠檬班Python高级软件测试开发2022年

热门文章

  1. 插件中的chalk的用法
  2. 体验Vue3.0, 仿一个网易云音乐客户端
  3. 磊科linux无线网卡驱动安装步骤,如何安装磊科无线网卡驱动教程
  4. 华为云与计算机,华为云电脑和达龙云电脑
  5. next()和nextLine()的区别
  6. 我的世界Bukkit服务器插件开发教程(十一)粒子、药水效果与音效
  7. ubuntu配置IP地址,网关,DNS和路由
  8. boosting算法调参
  9. IC卡历史及分类命名
  10. XiaoMi-Ruby-15.6-UMA-only黑苹果efi引导文件