神经网络与深度学习第三周总结

深度学习网络

在深度学习网络中,我们通常需要设计一盒模型的损失函数来约束训练过程。模型的训练不是漫无目的的,而是朝着最小化损失函数的方向去训练,通常使用的算法是随机梯度下降(stochastic gradient descent,SGD)算法,它是对一般梯度下降法的改进,每次只取一部分样本进行优化,样本的数量一般是2的整数次幂,取值范围是32-256,以保证计算精度的同时提升计算速度。

在深度学习中,SGD方法会使用一个固定的学习率进行训练,即

g_{t}=\bigtriangledown _{\theta t-1}f(\theta _{t-1})

\bigtriangledown _{\theta _{t}}=-\eta *g_{t}

式中,g_{t} 是第t步的梯度,\eta 是学习率,随机梯度下降算法在优化时,完全依赖于当前batch数据计算得到的梯度,学习率是调整梯度影响大小的参数,一定程度上可以控制网络的训练速度。SGD算法在大部分情况下都很有效,但也有一些缺点,例如选取学习率\eta并非易事,所有的参数使用同样的学习率可能并不是最有效的方法,此外SGD算法很容易收敛得到局部最优解,落入局部最优解后,就很难跳出局部最优解的区域.

针对上述SGD算法的缺点,我们将动量引入到优化算法中.动量通过模拟物体运动时的惯性来更新网络中的参数,即更新时会考虑之前参数更新的方向,同时利用当前batch计算得到的梯度,将两者结合起来计算出最终参数需要更新的大小和方向.在引入动量后,网络的参数按照下面的学习率进行更新:

g_{t}=\bigtriangledown _{\theta _{t-1}}f(\theta _{t-1})

m_{t}=\mu *m_{t-1}+g_{t}

\bigtriangledown _{\theta _{t}}=-\eta *m_{t}

上式中,m_{t}是当前动量的累加,\mu是动量因子,用于调整上一步动量对参数更新时的重要程度.引入动量后,在网络更新初期,可利用上一次参数更新,此时下降方向一致,乘以较大的\mu能够进行很好的加速.在网络更新后期,随着梯度逐渐趋于0,在局部最小值来回震荡时,利用动量使得更新幅度增大,跳出局部最优解的陷阱.

在深度学习模型过程中,常常会出现过拟合的现象,过拟合是指在使用训练数据集训练时,在训练数据集上能够获得很高的识别精度,或者很低的均方根误差,但是把训练好的模型用于测试集进行预测时,预测的效果往往不理想如下图所示.

过拟合会导致花费大量的实时间训练出无用的模型,因此需要一些方法来防止过拟合.

有的是增加数据量或者进行合理的数据切分,但最常用的是引入Dropout层,在每个训练批次中,通过忽略一定百分比的神经元数量,减轻网络的过拟合现象.就是说针对网络在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作,这样可以使模型泛化性更强,训练得到的网络的鲁棒性也会增强,不会过度依赖某些局部的特征.Dropout工作示意图如下:

下面的图是After Dropout后的神经网络.

这周针对pytorch的torch.nn 模块进行了大致的学习.该模块包含了torch已经准备好的层,包括卷积层,池化层等等,下面通过具体历程来实现.

将一幅图像转化为灰度图像,对其进行卷积提取图像的轮廓.

import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
myim=Image.open("G:/shenjing/Lenna.png")
myimgray=np.array(myim.convert("L"),dtype=np.float32)#将图片转换为灰度图像
plt.figure(figsize=(6,6))
plt.imshow(myimgray,cmap=plt.cm.gray)
plt.axis("off")
plt.show()#512*512的数组
imh,imw=myimgray.shape
myimgray_t=torch.from_numpy(myimgray.reshape(1,1,imh,imw))
myimgray_t.shape

上述代码是显示灰度图像,并将其转化成1*1*512*512的张量,这样才能开始卷积.得到的灰度图像如下(为毛图像会有水印):

下面开始卷积

kersize=5 ##定义边缘检测卷积核,将维度处理为1*1*5*5
ker=torch.ones(kersize,kersize,dtype=torch.float32)*-1
ker[2,2]=24
ker=ker.reshape((1,1,kersize,kersize))
#开始卷积
conv2d=nn.Conv2d(1,2,(kersize,kersize),bias=False)
##设置卷积时使用的核,第一个核使用边缘检测核
conv2d.weight.data[0]=ker
imconv2dout=conv2d(myimgray_t)
imconv2dout_im=imconv2dout.data.squeeze()#对卷积输出进行压缩
print("Output size:",imconv2dout_im.shape)
##卷积图像可视化
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.imshow(imconv2dout_im[0],cmap=plt.cm.gray)#change colors
plt.axis("off")#关闭坐标轴
plt.subplot(1,2,2)
plt.imshow(imconv2dout_im[1],cmap=plt.cm.gray)
plt.axis("off")
plt.show()

卷积结果:

可以看到使用的边缘特征提取卷积核很好的提取除了图像的边缘信息.

紧接着进入池化,目的就是对卷积得到的特征进行进一步处理,对数据进一步浓缩,从而减小计算时内存的压力.池化会选取一定大小区域,将该区域内的像素使用一个代表元素表示;如果使用平均值代替,称为平均值池化,若同最大值代替则为最大值池化,本历程使用最大值池化:

maxpool2=nn.MaxPool2d(2,stride=2)
pool2_out=maxpool2(imconv2dout)
pool2_out_im=pool2_out.squeeze()
pool2_out.shape
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.imshow(pool2_out_im[0].data,cmap=plt.cm.gray)
plt.axis("off")
plt.subplot(1,2,2)
plt.imshow(pool2_out_im[1].data,cmap=plt.cm.gray)
plt.axis("off")
plt.show()

池化后的结果:

ok先整到这.

  • 42
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值