DL_class

学堂在线《深度学习》实验课代码+报告(其中实验1和实验6有配套PPT),授课老师为胡晓林老师。课程链接:https://www.xuetangx.com/training/DP080910033751/619488?channel=i.area.manual_search。

持续更新中。
所有代码为作者所写,并非最后的“标准答案”,只有实验6被扣了1分,其余皆是满分。仓库链接:https://github.com/W-caner/DL_classs。 此外,欢迎关注我的CSDN:https://blog.csdn.net/Can__er?type=blog。
部分数据集由于过大无法上传,我会在博客中给出下载链接。如果对代码有疑问,有更好的思路等,也非常欢迎在评论区与我交流~

实验2:构建自己的多层感知机

实现代码

保留了实验一中的学习率衰减部分,在Q1~Q4的过程中为了绘图方便,没有使用早停法。分别使用numpy将不同层中的前向传播和反向传播方法实现即可。

损失函数

  • 欧氏距离:

        def forward(self, logit, gt):"""输入: (minibatch)- logit: 最后一个全连接层的输出结果, 尺寸(batch_size, 10)- gt: 真实标签, 尺寸(batch_size, 10)"""############################################################################# TODO:# 在minibatch内计算平均准确率和损失# 分别保存在self.accu和self.loss里(将在solver.py里自动使用)# 只需要返回self.loss# self.y_: (batch_size, 10)self.y_ = logitself.y = gt# loss: (batch_size, 1)L = np.sqrt(np.sum(np.square(self.y_ - self.y), axis=1))self.loss = np.average(L)# pre: (batch_size, )# pre = np.argmax(self.y_, axis=1)self.accu = accuracy_score(np.argmax(self.y_, axis=1), np.argmax(self.y,axis=1))############################################################################return self.lossdef backward(self):############################################################################# TODO:# 计算并返回梯度(与logit具有同样的尺寸)return self.y_-self.y############################################################################
  • 交叉熵损失函数:

        def forward(self, logit, gt):"""输入: (minibatch)- logit: 最后一个全连接层的输出结果, 尺寸(batch_size, 10)- gt: 真实标签, 尺寸(batch_size, 10)"""############################################################################# TODO: # 在minibatch内计算平均准确率和损失,分别保存在self.accu和self.loss里(将在solver.py里自动使用)# 只需要返回self.loss# self.y_: (batch_size, 10)self.y_ = np.exp(logit) / np.sum(np.exp(logit), axis=1, keepdims=True)self.y = gt# L: (batch_size, 1)L = -np.sum(np.log(self.y_)*self.y, axis=1)self.loss = np.average(L)# pre: (batch_size, )# pre = np.argmax(self.y_, axis=1)self.accu = accuracy_score(np.argmax(self.y_, axis=1), np.argmax(self.y, axis=1))############################################################################return self.lossdef backward(self):############################################################################# TODO: # 计算并返回梯度(与logit具有同样的尺寸)return self.y_-self.y############################################################################

正向/反向传播

  • 全连接层:

    def forward(self, Input):############################################################################ TODO: # 对输入计算Wx+b并返回结果.self.Input = Inputself.batch_zise = Input.shape[0]return np.dot(Input, self.W) + self.b############################################################################def backward(self, delta):# 输入的delta由下一层计算得到############################################################################# TODO: # 根据delta计算梯度# grad_W: (128, batch_size)*(batch_size,10) -> (128, 10)self.grad_W = np.dot(self.Input.T, delta)/self.batch_zise# grad_b: (batch_size, 10) -> (1, 10)self.grad_b = np.average(delta, axis=0)# delta: (batch_size, 10)*(10,128) -> (batch_size, 128)return np.dot(delta, self.W.T)############################################################################
    
  • relu激活层:

        def forward(self, Input):############################################################################# TODO: # 对输入应用ReLU激活函数并返回结果self.Input = Inputreturn np.maximum(Input, 0)############################################################################def backward(self, delta):############################################################################# TODO: # 根据delta计算梯度delta[self.Input<0]=0return delta############################################################################
  • Sigmoid激活层:

        def forward(self, Input):############################################################################# TODO: # 对输入应用Sigmoid激活函数并返回结果self.out =  1 / (1+np.exp(-Input))return self.out############################################################################def backward(self, delta):############################################################################# TODO: # 根据delta计算梯度return delta * self.out *(1-self.out)############################################################################

参数更新

这里不知道是不是写的公式有问题,我也没有搜到 “带权重衰减的动量梯度” 真正公式是什么, 当我指定梯度为0.8的时候,训练到后期反而准确率会下降。默认梯度0.0即不会出现问题。

    # 一步反向传播,逐层更新参数def step(self, model):layers = model.layerListfor layer in layers:if layer.trainable:############################################################################# TODO:# 使用layer.grad_W和layer.grad_b计算diff_W and diff_b.# 注意weightDecay项.if self.momentum:layer.W_velocity = self.momentum * layer.W_velocity + \self.learningRate * \(layer.grad_W + self.weightDecay*layer.W)layer.b_velocity = self.momentum * layer.b_velocity + \self.learningRate*layer.grad_blayer.diff_W = -layer.W_velocitylayer.diff_b = -layer.b_velocityelse:# Weight update without momentumlayer.diff_W = -self.learningRate * \(layer.grad_W+self.weightDecay* layer.W)layer.diff_b = -self.learningRate * layer.grad_b############################################################################# Weight updatelayer.W += layer.diff_Wlayer.b += layer.diff_b

报告问题

Q1

记录训练和测试准确率,绘制损失函数和准确率曲线图;

下图是使用原始参数,两种方法训练了30个周期的loss和accuracy的结果。

欧式距离损失:

softmax交叉熵损失:

Q2

比较分别使用 Sigmoid 和 ReLU 激活函数时的结果,可以从收敛情况、准确率等方面比较。

  • 收敛情况:无论使用哪个作为激活函数,只要模型正确,在足够的周期下都可以收敛,但是使用relu收敛速度(斜率)更快,推测是因为relu函数大于0的时候,导数为恒定值计算较快。
  • 准确率:在每个周期纵向对比,使用sigmoid准确率更高,且最后能达到的效果也更好,推测是因为relu导致了网络的稀疏性,对于这种简单数据集而言丢失了一些参数。但同时能看出,relu对于复杂数据集过拟合给出了比较好的解决方案。

Q3

比较分别使用欧式距离损失和交叉熵损失时的结果;

在使用同一种激活函数时,交叉熵损失函数在测试集上有着更好的表现,并且收敛的周期数少(速度快),而在训练集上的准确率来看则是欧氏距离更胜一筹。

感觉损失函数的影响并不绝对,需要搭配恰到好处的应用实例,恰好的激活函数和网络结构才能得到更好的表现。比如在模型输出与真实值的误差服从高斯分布的假设下,最小化均方差损失函数与极大似然估计本质上是一致的,因此在这个假设能被满足的场景中(比如回归),均方差损失是一个很好的损失函数选择;而交叉熵损失可能会更适用于本例(分类问题)。

Q4

构造具有两个隐含层的多层感知机,自行选取合适的激活函数和损失函数,与只有一个隐含层的结果相比较;

这里尝试了sigmoid+crossentropy,这二者的梯度有较为天然的结合,仿照该数据集上的经典模型“LeNet5”的结构,搭建了一个类似的网络(728,128,30,10)。以同样的参数训练和测试,得到对比图:

发现多层网络甚至不如一层网络效果好,推测是因为多层网络较为复杂,又都是全连接,随着学习率的衰减导致陷入局部最优的问题,所以更换激活函数为relu,网络结构如下所示:

multMLP = Network()
# 使用FCLayer和ReLULayer构建多层感知机
# 128, 30为隐含层的神经元数目
multMLP.add(FCLayer(784, 128))
multMLP.add(ReLULayer())
multMLP.add(FCLayer(128, 30))
multMLP.add(ReLULayer())
multMLP.add(FCLayer(30, 10))

对比图如下所示,无论是在收敛速度上,还是训练的准确率上,多个隐含层的网络结构有着更好的表现:

Q5

本案例中给定的超参数可能表现不佳,请自行调整超参数尝试取得更好的结果,记录下每组超参数的结果,并作比较和分析。

从上面的训练过程中明显可以看出,存在较为严重的局部最优和过拟合现象,所以调大学习率,加入早停法,还是按照先批次,再学习率,最后调节权重衰减和周期的方法进行调节,对比结果基本和实验一报告中的情况(就是过大会怎么样,过小会怎么样,为什么最终选择这个参数)吻合,这里不再给出相同参数具体分析,只给对比图了。

  • Batch_size:选择100即可

  • learning_rate:收敛较快,可以直接从0.05开始衰减,每周期衰减1.1~1.5都可以。

  • weight_decay:

可以发现,正则项的加入一定要适度,其起到的是“调节作用”,在超过0.1的时候已经对模型效果产生了负面影响,也就是稍微加一点正则化(甚至这样的简单模型可以不加)为最优。

最终使用batch_size为100,learning_rate从0.08开始,每周期衰减1.2,权重衰减为0.005,早停法进行25个周期的训练,基本上训练5~6个周期即可到达饱和。

此时得到测试集上的最好的结果为96.61%,

【深度学习】实验2答案:构建自己的多层感知机相关推荐

  1. 花书+吴恩达深度学习(一)前馈神经网络(多层感知机 MLP)

    目录 0. 前言 1. 每一个神经元的组成 2. 梯度下降改善线性参数 3. 非线性激活函数 4. 输出单元 4.1. 线性单元 4.2. sigmoid 单元 4.3. softmax 单元 5.  ...

  2. 什么是深度学习?kears简介,深度学习常用的三大模型,MLP(多层感知机),CNN(卷积神经网络),RNN(循环神经网络)

    什么是深度学习? 简单理解深度学习就是人类容易做的事情,机器不容易完成的事情.(实例:人脸识别,这个例子很好的证明了这句话.假如你识别一个人 ,今天这个人长这个样子,明天脸上有一块伤口,我们人是不是还 ...

  3. 【干货】深度学习实验流程及PyTorch提供的解决方案

    转载自:[干货]深度学习实验流程及PyTorch提供的解决方案 [导读]近日,专知小组博士生huaiwen创作了一系列PyTorch实战教程,致力于介绍如何用PyTorch实践你的科研想法.今天推出其 ...

  4. 【知识图谱】知识图谱数据构建的“硬骨头”,阿里工程师如何拿下?深度学习在知识图谱构建中的应用。

    阿里妹导读:搜索"西红柿",你不但能知道它的营养功效.热量,还能顺带学会煲个牛腩.炒个鸡蛋!搜索引擎何时变成"暖男"了?原来背后有"知识图谱" ...

  5. 深度学习实验总结:PR-曲线、线性回归、卷积神经网络、GAN生成式对抗神经网络

    目录 0.前言 1.实验一:环境配置 (1)本机 1.Jupyter 2.Pycharm (2)云端 2.实验二:特征数据集制作和PR曲线 一.实验目的 二.实验环境 三.实验内容及实验步骤 3.实验 ...

  6. nvidia docker容器不支持中文的解决办法_用docker搭建深度学习实验环境

    tensorflow和pytorch官方都维护了不同版本的docker镜像.借助docker我们可以方便的搭建起深度学习实验环境. 但是想要在同一个容器内同时拥有tensorflow.pytorch. ...

  7. pycharm remote 远程项目 同步 本地_利器:PyCharm本地连接服务器搭建深度学习实验环境的三重境界...

    作为实验室社畜,常需要在本地使用Pycharm写代码,然后将代码同步到服务器上,使用远程登录服务器并运行代码做实验. 这其中有很多事情如果没有好的工具,做起来会非常麻烦. 比如如何快速同步本地与服务器 ...

  8. 深度学习实验1:pytorch实践与前馈神经网络

    深度学习实验1:pytorch实践与前馈神经网络 1.pytorch基本操作 1.使用

  9. 深度学习 实验三 logistic回归预测二分类

    文章目录 深度学习 实验三 logistic回归预测二分类 一.问题描述 二.设计简要描述 三.程序清单 深度学习 实验三 logistic回归预测二分类 一.问题描述   学会使用学习到的逻辑回归的 ...

最新文章

  1. 干货满满:详解四组遍历数组
  2. 澳大利亚悉尼大学徐畅教授招收深度学习方向全奖博士生
  3. python测验9_荐 测验9: Python计算生态纵览 (第9周)
  4. 大话网站---从Hello World到高并发网站
  5. 搭建通用性多用户后台-思路
  6. css高级教程第一章笔记
  7. canvas 实现图片局部模糊_JavaScript中的图片处理与合成(四)
  8. SQL语句拼接常加 where 1=1 的原因
  9. python商品评论分析_NLP实战:用主题建模分析网购评论(附Python代码)
  10. 字符内存转成字符串_字符串内存内部
  11. c语言统计数字字母个数,请问这个用c怎么做:输入一串字符,分别统计其中数字和字母的个数...
  12. KafkaConsumer.poll : Timeout must not be negative
  13. 《Python数据分析》第二版.第二章.[学习笔记][Jupyter notebook]
  14. 数组-scala数组与java的list的互转
  15. kylin版本_Kylin配置Spark并构建Cube
  16. 微信机器人 DIY 从 0 到 1
  17. SQL Server 替换
  18. java后端处理Apple Pay流程
  19. 图像处理与机器视觉初学者学习路线
  20. onlyoffice-开源在线文档编辑软件

热门文章

  1. 百度副总裁李硕:通过“一企一档”等模式提升企业智能化水平
  2. web前端--弹窗广告实现
  3. ORACLE ORA-01653: unable to extend table 的错误处理
  4. SAP请求本地导出导入
  5. VR专业的面试题你都见过没?相信我绝对有用
  6. 计蒜客 17115 Coin(2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B)
  7. instagram分享_Facebook,Twitter,Instagram,Google等使用的字体和颜色
  8. 微信查看谁删除了4种方法
  9. 免费好用的外网映射工具
  10. playwright 使用本地chrome 浏览器 加载多个extension 插件