MXNet:基础和入门
质量声明:原创文章,内容质量问题请评论吐槽。如对您产生干扰,可私信删除。
主要参考:李沐等:动手学深度学习-伯克利教材
文章目录
- 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
步骤:
- 变量赋初值
- 申请存储梯度的内存 param_in
.attach_grad()
- 记录与梯度相关的函数计算(正向)
with autograd_record()
- 自动求梯度(反向) 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),strides ,padding ,activation
|
nn.BatchNorm
|
批量归一化 | / |
nn.MaxPool2D
|
二维最大池化层 |
pool_size ,strides ,padding
|
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
- Sigmoid函数的输出映射在(0,1)之间,可以用来做二分类,单调连续,输出范围有限,优化稳定,可以用作输出层。
- 求导容易
- 由于其软饱和性,反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练,导致训练出现问题。
- 激活函数计算量大,反向传播求误差梯度时,求导涉及除法。
- 其输出并不是以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)
- 比Sigmoid函数收敛速度更快。
- 相比Sigmoid函数,其输出以0为中心,因此实际应用中 tanh 会比 sigmoid 更好,因为 tanh 的输出均值比 sigmoid 更接近 0,SGD会更接近 natural gradient(一种二次优化技术),从而降低所需的迭代次数
- 还是没有改变Sigmoid函数的最大问题——由于饱和性产生的梯度消失
softsign
y = x 1 + a b s ( x ) y = \frac{x}{1 + abs(x)} y=1+abs(x)xsoftrelu
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)
由于 x>0时导数为 1,所以ReLU 能够在x>0时保持梯度不衰减,从而缓解梯度消失问题。但随着训练的推进,部分输入会落入硬饱和区,导致对应权重无法更新。这种现象被称为“神经元死亡”,影响网络的收敛性
使用 ReLU 得到的 SGD 的收敛速度会比 sigmoid/tanh 快很多
ReLU的输出具有偏移现象,即输出均值恒大于零,影响网络的收敛性
- PReLU
- 为了避免梯度消失,提出了LReLU,其中 a i a_i ai较小且取固定值. 但在一些实验中,LReLU对准确率并没有太大的影响。很多时候,若想应用LReLU时,必须非常小心谨慎地重复训练,选取出合适的 a i a_i ai,LReLU才能表现得比ReLU好
- PReLU是ReLU 和 LReLU的改进版本,具有非饱和性,负半轴斜率 a j i a_{ji} aji可学习而非固定。PReLU收敛速度快、错误率低,可以用于反向传播的训练,可以与其他层同时优化
- ELU
- ELU融合了sigmoid和ReLU,具有左侧软饱性
- 右侧线性部分使得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=21i∑∣labeli−predi∣2.L1Loss
L = ∑ i ∣ l a b e l i − p r e d i ∣ . L = \sum_i \vert {label}_i - {pred}_i \vert. L=i∑∣labeli−predi∣.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=−i∑labeli∗log(probi)∗pos_weight+(1−labeli)∗log(1−probi)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=−i∑j∑labeljlogpijLogisticLoss
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=i∑log(1+exp(−predi⋅labeli))
优化算法(小批量)
参考博文:优化方法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))
模型训练
- 构建小批量数据数据生成器
train_iter = gdata.DataLoader()
- 构建模型训练器
trainer = gluon.Trainer()
,接口文档 gluon.Trainer - 循环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:基础和入门相关推荐
- 如何零基础学习python语言_零基础如何入门Python语言?有哪些学习建议?
众所周知,Python目前是最受欢迎的编程语言之一,尤其是对于零基础的初学者来说,Python语言更是十分的友好.因此,不少初学者常常会有这样一个共同的疑惑,零基础如何入门Python语言?本文就来给 ...
- ui设计培训需要什么基础?如何入门学习?
UI设计是一种直观面向用户的一个技术岗位,在互联网公司,UI设计岗位是不可或缺的,那么对于零基础想要学习UI设计的同学来说,ui设计培训需要什么基础?如何入门学习呢?我们来看看下面的详细介绍. ...
- 零基础AJAX入门(含Demo演示源文件)
零基础AJAX入门(含Demo演示源文件) 作者:一点一滴的Beer 个人主页:http://www.cnblogs.com/beer 摘要:因为笔者的大四毕业设计是做WebGIS系统,用过Web版 ...
- 零基础学python语言_零基础如何入门Python语言?有哪些学习建议?
众所周知,Python目前是最受欢迎的编程语言之一,尤其是对于零基础的初学者来说,Python语言更是十分的友好.因此,不少初学者常常会有这样一个共同的疑惑,零基础如何入门Python语言?本文就来给 ...
- python外星人入侵游戏图片_跪求一个问题@关于外星人入侵游戏(《python编程基础从入门到实...
我在学着编写<python编程基础从入门到实践>的"外星人入侵游戏"的时候,报错如下: Traceback (most recent call last): File ...
- 零基础自学python看什么书-零基础Python入门看哪本书好?这里有答案
原标题:零基础Python入门看哪本书好?这里有答案 Python入门看哪本书好呢?Python入门不知道该选哪本书?Python入门没有一本好书引导,会很难吗?你还在为这些问题困扰吗?今天小编就来解 ...
- layuiadmin上手好难_新手自学板绘先学SAI还是PS好?零基础绘画入门需知!
原标题:新手自学板绘先学SAI还是PS好?零基础绘画入门需知! 新手自学板绘先学SAI还是PS好?初学者如何入门绘画?学习板画难吗?怎样才能学习好绘画?想必这些都是绘画初学者们经常在想的问题吧,就是不 ...
- python图形编程基础-Python从基础到入门系列教程
本教程集合了Python基础&系统管理,从基础到入门,带你走进Python世界!对Python有兴趣的可以学习一下哦基础系列:1.课程简介2.Python下载和安装3.IDLE使用简介4.第1 ...
- SQL基础使用入门(二): DML语句和DCL语句
SQL语句第二个类别--DML 语句 DML是数据操作语言的缩写,主要用来对数据表中数据记录实例对象进行操作,包括插入.删除.查找以及修改四大操作,这也是开发人员使用中最为频繁的操作. 1.插入记录 ...
最新文章
- SCCM2016 集成WSUS提供补丁服务(一)
- 【在线画流程图】网站
- 阿里宣布成立云原生技术委员会,释放哪些趋势信息?
- 第 8 章 容器网络 - 051 - 在 overlay 中运行容器
- requestURI的组成部分
- java默认代码地址_Java 8默认方法可能会破坏您的(用户)代码
- 前端学习(2822):页面配置文件
- 栅格矢量化_学会用栅格系统,普通LOGO秒变高大上
- php如何跟踪调试,PHP使用debug_backtrace方法跟踪调试代码调用详解
- “进化”的搜索方式:揭秘微软语义搜索背后的技术
- 清空SQL数据库日志
- 安卓源代码_如何从在安卓Android手机获取微信小程序源代码
- python去除停用词_python jieba分词如何去除停用词
- matlab做线性规划图
- PG修改表字段长度报错 cached plan must not change result type Hint: Please restore the result type
- 凯撒密码的超详细讲解
- 上机练习2 类与对象 pc cpu harddisk对象组合
- MATLAB图像处理_YUV格式详解
- MQ,如何做到削峰填谷
- 柠檬班Python高级软件测试开发2022年