目录
1.pytorch 基础练习
PyTorch是一个python库,它主要提供了两个高级功能: (1)GPU加速的张量计算 (2)构建在反向自动求导系统上的深度神经网络。
1.1定义数据
一般定义数据使用torch.Tensor , tensor的意思是张量,是数字各种形式的总称。
Tensor支持各种各样类型的数据,包括:torch.float32, torch.float64, torch.float16, torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64 。
创建Tensor有多种方法,包括:ones, zeros, eye, arange, linspace, rand, randn, normal, uniform, randperm。
1.2定义操作
凡是用Tensor进行各种运算的,都是Function。最终,还是需要用Tensor来进行计算的,计算无非是(1)基本运算,加减乘除,求幂求余 (2)布尔运算,大于小于,最大最小 (3)线性运算,矩阵乘法,求模,求行列式。
基本运算包括: abs/sqrt/div/exp/fmod/pow ,及一些三角函数 cos/ sin/ asin/ atan2/ cosh,及 ceil/round/floor/trunc 等。
布尔运算包括: gt/lt/ge/le/eq/ne,topk, sort, max/min。
线性计算包括: trace, diag, mm/bmm,t,dot/cross,inverse,svd 等。
2.螺旋数据分类
神经网络的参数都是随机初始化的,不同的初始化参数往往会导致不同的结果,当得到比较好的结果时我们通常希望这个结果是可以复现的,因此,在pytorch中,通过设置随机数种子也可以达到这个目的。
初始化 X 和 Y。 X 可以理解为特征矩阵,Y可以理解为样本标签。 结合代码可以看到,X的为一个 NxC 行, D 列的矩阵。C 类样本,每类样本是 N个,所以是 N*C 行。每个样本的特征维度是2,所以是 2列。
在 python 中,调用 zeros 类似的函数,第一个参数是 y方向的,即矩阵的行;第二个参数是 x方向的,即矩阵的列。
要想用 Pytorch 训练任何神经网络,训练回圈包含 5 个基础步骤:
(1)output = model(input) 是模型的前向传播,接收输入并生成输出。
(2)J = loss(output, target label) 接收模型的输出,并计算训练时对于真实目标的损失。
(3)model.zero_grad() 清除计算的梯度,使它们不会积累到下次的传播。
(4)J.backward() 进行反向传播和累加。
(5)optimiser.step() 进行梯度下降的一步。
2.1构建线性模型分类
当尝试使用线性的决策边界来分隔螺旋的数据 - 只使用nn.linear()
模组,而不在之间加上非线性 - 我们只能达到 50% 的正确度。
下面代码把第10行的情况输出,供解释说明. 每一次反向传播前,都要把梯度清零。
梯度累加就是,每次获取1个batch的数据,计算1次梯度,梯度不清空,不断累加,累加一定次数后,根据累加的梯度更新网络参数,然后清空梯度,进行下一次循环。
上面使用 print(model) 把模型输出,可以看到有两层:
第一层输入为 2(因为特征维度为主2),输出为 100; 第二层输入为 100 (上一层的输出),输出为 3(类别数) 从上面图示可以看出,线性模型的准确率最高只能达到 50% 左右,对于这样复杂的一个数据分布,线性模型难以实现准确分类。
2.2构建两层神经网络分类
当我们从线性模型换成在两个 nn.linear()
模组再经过一个 nn.ReLU()
的模型,正确度增加到了 95%。这是因为边界变成非线性的并且更好的顺应资料的螺旋。
3.问题总结
(1)AlexNet有哪些特点?为什么可以比LeNet取得更好的性能?
AlexNet是在LeNet的基础上加深了网络的结构,学习更丰富更高维的图像特征。AlexNet的特点:更深的网络结构;使用层叠的卷积层,即卷积层+卷积层+池化层来提取图像的特征;使用Dropout抑制过拟合;使用数据增强抑制过拟合;使用Relu替换sigmoid作为激活函数,解决了sigmoid在网络较深时出现的梯度弥散问题;使用归一化层对局部神经元的活动创建竞争机制,抑制反馈较小的神经元,放大反馈较大的神经元,增强模型泛化能力;使用重叠池化,有利于减轻过拟合;使用多GPU进行训练。
AlexNet相比于LeNet的主要改进为:使用Dropout防止过拟合、激活函数用ReLU替换Sigmoid、池化层使用MaxPooling替换AvgPooling、以及采用了GPU加速运算。这使得网络更深,预测效果有所提升(如图1所示)。
图1Lenet(左),AlexNet(右)
(2)激活函数有哪些作用?
激活函数的主要作用是完成数据的非线性变换,解决线性模型的表达、分类能力不足的问题。(在螺旋分类示例中,加入激活函数ReLU后的分类面就变成了非线性的)
(3)梯度消失现象是什么?
在神经网络中,当前面隐藏层的学习速率低于后面隐藏层的学习速率,即随着隐藏层数目的增加,分类准确率反而下降了。这种现象叫做梯度消失。
(4)神经网络是更宽好还是更深好?
从现有研究来看,深度方向的增长更容易提升性能,因为多项式增长的深度与指数增长的宽度效果类似,提升同样效果需要增加的宽度远远超过需要增加的深度。
(5)为什么要使用Softmax?
Softmax本质上是归一化网络,目的是将多个标量映射为一个概率分布,其输出的每一个值范围在 (0,1)。深度神经网络的最后一层往往是全连接层+ Softmax(分类网络)。
(6)SGD 和 Adam 哪个更有效?
SGD算法没有动量的概念,SGD和Adam相比,缺点是下降速度慢,对学习率要求严格。而Adam引入了一阶动量和二阶动量,下降速度比SGD快,Adam可以自适应学习率,所以初始学习率可以很大。
SGD相比Adam,更容易达到全局最优解。主要是后期Adam的学习率太低,影响了有效的收敛。
综上,Adam 和 SGD 都有各自的优点和缺点,应该根据具体情况选择。通常来说,Adam 更适合用于处理大规模数据集和模型,而 SGD 更适合用于小规模数据集和模型。