为什么随机初始化的深度默认模式神经网络络的梯度训练往往不成功

本文是基于吴恩达老师《深度学習》第二周第一课练习题所做目的在于探究参数初始化对模型精度的影响。

文中所用到的辅助程序

本文所用第三方库如下,其中init_utils为辅助程序包含构建默认模式神经网络络的函数

通过init_utils中的load_dataset函数,可以直观看到本文所用到的数据样貌:

本文所搭建的默认模式神经网络络模型与一致不再赘述。

如果我们使用零矩阵(np.zeros())来初始W在之后的一系列运算中所得到的W[l]都将为0,我们来测试下这样会得到怎么的训练结果

运行过程中我们会发现cost的计算速度很快,这也是因为使用零矩阵进行初始化的结果

使用该模型对样本进行分类,结果如下图把整個数据集都预测为0,划分为一类


有此可知:(1)b[l]可以初始化为0;(2)W[l]必须随即初始化。

使用np.random.randn()函数进行初始化且在此处测试中我们给参W[l]設置一个较大的系数,如:10我们来看一下运行结果。

训练精度明显高很多分类结果如下:


从运行结果中我们可以发现,使用较大权重隨即初始化的效果虽然比零初始化效果好但是还是有大片区域预测错误,那么下面我们使用较小的权重进行实验


不难发现,训练结果哽差那么到底使用怎么的初始权重菜才能收到较好的训练效果呢?

该方法的思路解决梯度消失或梯度爆炸问题在W初始化时引入系数np.sqrt(2./layers_dims[l-1])。

峩们来看一下运行结果

从训练结果可以看出cost的下降速录比较快,预测精度的非常高


1. 不同的初始化方式会导致完全不同的测试效果

2.过大、过小较大的权重进行初始化,运行效果都不理想

3.根据激活函数的不同选择适当的he系数


默认模式神经网络络已经持续训練了 12 个小时它看起来很好:梯度在变化,损失也在下降但是预测结果出来了:全部都是零值,全部都是背景什么也检测不到。我质問我的计算机:“我做错了什么”,它却无法回答

如果你的模型正在输出垃圾(比如预测所有输出的平均值,或者它的精确度真的很低)那么你从哪里开始检查呢?

无法训练默认模式神经网络络的原因有很多在经历了许多次调试之后,我发现有一些检查是经常做的这张列表汇总了我的经验以及最好的想法,希望对读者也有所帮助

许多事情都可能出错。但其中有些事情相比于其他方面更容易出问題在出现问题时,我通常会做以下几件事情

  1. 从已知的用于该数据类型的简单模型入手(例如VGG用于图像处理)。尽可能使用标准误差
  2. 詓掉所有的花哨的预处理程序,例如正则化和数据增强
  3. 微调模型,仔细检查预处理应该和原始模型的训练设置保持一致。
  4. 验证输入数據的正确性
  5. 从较小的数据集开始(2-20个样本)。在小数据集上过拟合之后再增加数据量
  6. 慢慢加入之前忽略的项:增强或正则化、自定义損失函数,以及尝试更多的复杂模型

如果上面的步骤还不能解决,可以开始一项一项的按以下列表进行检查

检查馈送到网络的输入数據是否正确。例如我不止一次混淆了图像的宽度和高度。有时我错误地让输入数据全部为零,或者一遍遍地使用同一批数据所以要咑印或显示一些批次的输入和目标输出,并确保它们是正确的

尝试向网络传入随机数而不是真实数据,看看错误的产生方式是否相同洳果是,说明在某些时候你的网络把数据转化为了垃圾试着逐层调试,并查看出错的地方

你的数据也许很好,但是把输入数据读取到網络的代码可能有问题所以我们应该在进行其他操作之前打印出第一层的输入并进行检查。

检查少许输入样本是否有正确的标签确保咑乱输入样本同样也要打乱输出标签。

相较于随机的部分(可以认为股票价格也是这种情况)输入与输出之间的非随机部分也许占得比偅太小。也就是说输入与输出的关联度太低没有统一的方法来检测它,因为这取决于数据的性质

我曾经遇到过这种情况,当我从一个喰品网站抓取一个图像数据集时错误标签太多以至于网络无法学习。手动检查一些输入样本并查看标签是否大致正确例如这篇  ,由于茬MNIST数据集中使用了50%损坏的标签只得到了50%的准确率。

如果你的数据集没有被随机打乱并且有特定的序列(按标签排序),这可能给学习帶来不利影响打乱数据集可以避免这一问题。要确保输入和标签都被重新排列

是不是对于一张类别 B 的图像,有 1000 张类别 A 图像如果是这種情况,那么你也许需要平衡损失函数或者尝试  

如果你从头开始训练一个网络(不是调试),你很可能需要大量数据 

这可能发生在排恏顺序的数据集中(即前 10000 个样本属于同一个分类)。可通过打乱数据集轻松修复这个问题

 指出巨大的批次会降低模型的泛化能力。

测试噺的网络结构或者写了一段新代码时,首先要使用标准数据集而不是你自己的数据。这是因为在这些数据集上已经有了许多参考结果他们被证明是“可解的”。不会出现标签噪音、训练/测试分布差距、数据集太难等问题

你的输入已经归一化到零均值和单位方差了吗?

数据增强有正则化效果过量的数据增强,加上其它形式的正则化(权重 L2dropout操作,等等)可能会导致网络欠拟合

如果你正在使用一个巳经预训练过的模型,确保你现在正在使用的归一化和预处理与之前训练模型的设置相同例如,一个图像的像素是在 [0, 1][-1, 1] 或 [0, 255] 的范围内吗?

CS231n 指出了一个常见的  :“任何预处理数据(例如数据均值)必须只在训练数据上进行计算然后再应用到验证、测试数据中。例如计算均徝,然后在整个数据集的每个图像中都减去它再把数据分发进训练、验证、测试集中,这是一个典型的错误”

此外,要在每一个样本戓批次(batch)中检查是否存在不同的预处理

这将会有助于找到问题的根源究竟在哪里。例如如果目标输出是一个物体类别和坐标,那就試着把预测结果仅限制在物体类别当中

还是来源于  的技巧:用小参数进行初始化,不使用正则化例如,如果我们有 10 个类别“碰巧”僦意味着我们将会在 10% 的时间里得到正确类别,Softmax 损失是正确类别的负log概率: -ln(q.com也欢迎大家通过新浪微博(@InfoQ,@丁晓昀)微信(微信号:  )关紸我们。

第2章 默认模式神经网络络的数学基础

  • 需要解决的问题:将手写数字的灰度图像(28像素x28像素)划分到10个类别中(0~9)
  • MNIST数据集预先加载在Keras库中,其中包括4个Numpy数组
  • 图像被编码為Numpy数组,而标签是数字数组取值范围为0~9。图像和标签一一对应
  • 接下来的工作流程如下:首先,将训练数据(train_images和train_labels)输入默认模式神经网絡络;其次网络学习将图像和标签关联在一起;最后,网络对test_images生成预测而我们将验证这些预测与test_labels中的标签是否匹配。

  • 默认模式神经网絡络的核心组件是层(layer)它是一种数据处理模块,你可以将它看成数据过滤器进去一些数据,出来的数据变得更加有用具体来说,層从输入数据中提取表示–我们期望这种表示有助于解决手头的问题大多数深度学习都是将简单的层链接起来,从而实现渐进式的数据蒸馏(data distillation)深度学习模型就像是数据处理的筛子,包含一系列越来越精细的数据过滤器(即层)
  • 本例中的网络包含两个Dense层,它们是密集連接(也叫全连接)的神经层第二层是一个10路softmax层,它将返回一个由10个概率值(总和为1)组成的数组每个概率值表示当前数字图像属于10個数字类别中某一个的概率。
  • 要训练网络我们还需要选择编译(compile)步骤的三个参数:1、损失函数(loss function),网络如何衡量在训练数据上的性能即网络如何朝着正确的方向前进。2、优化器(optimizer)基于训练数据和损失函数来更新网络的机制。3、在训练和测试过程中需要监控的指標(metric)本例只关心精度,即正确分类的图像所占的比例

  • 在开始训练之前,我们需要对数据进行预处理将其变化为网络要求的形状,並将取值缩放到[0, 1]区间比如,之前训练图像保存在一个unit8类型的数组中其形状为(),取值区间为[0, 255]我们需要将其变换为一个float32数组,其形状为(6)取值范围为0~1。

  • 训练精度和测试精度之间的差距是过拟合(overfit)造成的过拟合是指机器学习模型在新数据上的性能往往比在训练数据上要差。
  • 张量(输入网络的数据存储对象)、张量运算(层的组成要素)、梯度下降(让网络从训练样本中进行学习)

2.2 默认模式神经网络络嘚数据表示

  • 前面例子使用的数据存储在多维Numpy数组中,也叫张量(tensor)一般来说,当前所有机器学习系统都使用张量作为基本数据结构张量这一概念的核心在于,它是一个数据容器它包含的数据几乎总是数值数据,因此它是数字的容器矩阵是二维张量,张量是矩阵向任意维度的推广张量的维度(dimension)通常叫作轴(axis)。
  • 仅包含一个数字的张量叫作标量(scala也叫标量张量、零维张量、0D张量)。在Numpy中一个float32或float64嘚数字就是一个标量张量(或标量数组)。可以使用ndim属性来查看一个Numpy张量轴的个数标量张量有0个轴(ndim == 0)。张量轴的个数也叫作阶(rank)丅面是一个numpy标量。
  • 数字组成的数组叫作向量(vector)或一维张量(1D张量)一维张量只有一个轴。下面是一个Numpy向量下面是一个Numpy向量。

  
  • 向量组荿的数组叫作矩阵(matrix)或二维张量(2D张量)矩阵有2个轴(通常叫作行和列)。你可以将矩阵直观地理解为数字组成的矩形网络下面是┅个Numpy矩阵。

  
  • 第一个轴上的元素叫作行(row)第二个轴上的元素叫作列(column)。
  • 将多个矩阵组合成一个新的数组可以得到一个3D张量,可以直觀地理解为数字组成的立方体下面是一个Numpy的3D张量。

  
  • 将多个3D张量组合成一个数组可以创建一个4D张量。深度学习处理的一般是0D到4D的张量泹处理视频数据时可能会遇到5D张量。
  • 轴的个数(阶)例如,3D张量有3个轴矩阵有2个轴。这在Numpy等Python库中也叫张量的ndim
  • 形状。这是一个整数元組表示张量沿每个轴的维度大小(元素个数)。
  • 数据类型(在Python库中通常叫作dtype)这是张量中所包含数据的类型,例如张量的类型可以昰float32、unit8、float64等。在极少数情况下你可能会遇到字符(char)张量。注意Numpy(以及大多数其他库)中不存在字符串张量,因为张量存储在预先分配嘚连续内存段中而字符串的长度是可变的,无法用这种方式存储
  • train_images是一个由8位整数组成的3D张量。更确切地说它是60000个矩阵组成的数组,烸个矩阵由28x28个整数组成每个这样的矩阵都是一张灰度图像,元素的取值范围0~255

  • 在前面的例子中,我们使用语法train_images[i]来选择沿着第一个轴的特萣数字选择张量的特定元素叫作张量切片(tensor slicing)。

2.2.7 数据批量的概念
  • 通常来说深度学习中所有数据张量的第一个轴(0轴,因为索引从0开始)都是样本轴(sample axis有时也叫样本维度)。
  • 此外深度学习模型不会同时处理整个数据集,而是将数据拆分成小批量具体来看,下面是MNIST数據集的一个批量批量大小为128。

  • 对于这种批量张量第一个轴(0轴)叫作批量轴(bacth axis)或批量维度(batch dimension)。
2.28 现实世界中的数据张量

2.3 默认模式神經网络络的“齿轮”:张量运算

  • 所有计算机程序最终都可以简化为二进制输入上的一些二进制运算(AND、OR、NOR等)与此类似,深度默认模式鉮经网络络学到的所有变换也都可以简化为数值数据张量上的一些张量运算(tensor operation)例如加上张量、乘以张量等。
  • 在最开始的例子中我们通过叠加Dense层来构建网络。Keras层的实例如下所示
  • 这个层可以理解为一个函数,输入一个2D张量返回另一个2D张量,即输入张量的新表示具体洏言,这个函数如下所示(其中W是一个2D张量b是一个向量,二者都是该层的属性)
  • 上式有三个张量运算:输入张量和张量W之间的点积运算(dot)、得到的2D张量与向量b之间的加法运算(+)、最后的relu运算。relu(x)是max(x, 0)
  • relu运算和加法都是逐元素(element-wise)的运算,即该运算独立地应用于张量中的烸个元素也就是说,这些运算非常适合大规模并行实现(向量化实现)

 
  • 在实践中处理Numpy数组时,这些运算都是优化好的Numpy内置函数这些函数将大量运算交给安装好的基础线性代数子程序(BLAS,basic linear algebra subprograms)BLAS是低层次的、高度并行的、高效的张量操作程序,通常用Fortran或C语言来实现
  • 因此,在Numpy中可以直接进行下列逐元素运算速度非常快。
  • 在没有歧义的条件下两个形状不同的张量进行运算时,较小的张量会被广播(broadcast)鉯匹配较大张量的形状。广播包含以下两步:(1)向较小的张量添加轴(叫作广播轴)使其ndim与较大的张量相同。(2)将较小的张量沿着噺轴重复使其形状与较大的张量相同。
  • 在实际的实现过程中并不会创建新的2D张量因为那样做非常低效。重复的操作完全是虚拟的它呮出现在算法中,而没有发生在内存中

  • 如果一个张量的形状是(a, b, …, n, n+1, …, m),另一个张量的形状是(n, n+1, …, m)那么你通常可以利用广播对它们做两個张量之间逐元素运算。广播操作会自动应用于从a到n-1的轴
  • 点积运算,也叫张量积(tensor product不要与逐元素的乘积弄混),是最常见也最有用的張量运算与逐元素的运算不同,它将输入张量的元素合并在一起
  • 两个向量之间的点积是一个标量,而且只有元素个数相同的向量之间財能做点积

  • 张量变形是指改变张量的行和列,以得到想要的形状变形后的张量的元素总个数与初始张量相同。
2.3.6 深度学习的几何解释
  • 默認模式神经网络络完全由一系列张量运算组成而这些张量运算都只是输入数据的几何变换。因此可以将默认模式神经网络络解释为高維空间中非常复杂的几何变换,这种变换可以通过许多简单的步骤来实现
  • 想象有两张彩纸:一张红色,一张蓝色将其中一张纸放在另┅张纸上。现在将两张纸一起揉成小球这个皱巴巴的纸球就是你的输入数据,每张纸对应于分类问题中的一个类别默认模式神经网络絡(或者任何机器学习模型)要做的就是找到可以让纸球恢复平整的变换,从而能够再次让两个类别明确可分通过深度学习,这一过程鈳以用三维空间中一系列简答的变换来实现比如你用手指对纸球做的变换,每次一个动作
  • 让纸球恢复平整就是机器学习的内容:为复雜的、高度折叠的数据流形找到简洁的表示。深度学习将复杂的几何变换逐步分解为一长串基本的几何变换这与人类展开纸球所采取的筞略大致相同。深度网络的每一层都通过变换使数据解开一点点–许多层堆叠在一起可以实现非常复杂的解开过程。

2.4 默认模式神经网络絡的“引擎”:基于梯度的优化

  • 在这个表达式中W和b都是张量,均为该层的属性它们被称为该层的权重(weight)或可训练参数(trainable parameter),分别对應kernel和bias数学这些权重包含网络从观察训练数据中学到的信息。
  • 一开始这些权重矩阵取较小的随机值,这一步叫作随机初始化(random initialization)当然,W和b都是随机的relu(dot(W, input) + b)肯定不会得到任何有用的表示。虽然得到的表示是没有意义的但这是一个起点。下一步则是根据反馈信号逐渐调节这些权重这个逐渐调节的过程叫作训练,也就是机器学习中的学习
  • 上述过程发生在一个训练循环(training loop)内,必要时一直重复下述步骤:(1)抽取训练样本x和对应目标y组成的数据批量(2)在x上运行网络(这一步叫作前向传播(forward pass)),得到预测值y_pred(3)计算网络在这批数据上嘚损失,用于衡量y_pred和y之间的距离(4)更新网络的所有权证,使网络在这批数据上的损失略微下降最终得到的网络在训练数据上的损失非常小,即预测值y_pred和预期目标y之间的距离非常小网络“学会”将输入映射到正确的目标。利用网络中所有运算都是可微(differentiable)这一事实計算损失相对于网络系数的梯度(gradient),然后向梯度的反方向改变系数从而使损失降低。
    xx映射为另一个实数 y y y由于函数是连续的, x x x的微小變化只能导致 y yf(x)增大此外 a a a的绝对值(导数的大小)表示增大或减小的快慢。
2.4.2 张量运算的导数:梯度
  • 梯度(gradient)是张量运算的导数它是导数這一概念向多元函数导数的推广。多元函数是以张量作为输入的函数
  • 给定一个可微函数,理论上可以用解析法找到它的最小值:函数的朂小值是导数为0的点因此你只需找到所有导数为0的点,然后计算函数在其中哪个点具有最小值
  • N N N个变量的多项式方程,其中 N N N是网络中系數的个数 N = 2 N=2 N=3时可以对这样的方程求解,但对于实际的默认模式神经网络络是无法求解的因为参数的个数不会少于几千个,而且经常有上芉万个
  • (1)抽取训练样本 x x x和对应目标 y y y组成的数据批量。(2)在 x x x上运行网络得到预测值 y p r W?=step?gradient,从而使这批数据上的损失减小一点
  • 动量方法的实现过程是每一步都移动小球,不仅要考虑当前的斜率值还要考虑当前的速度(来自于之前的加速度)。这在实践中是指更新參数w不仅要考虑当前的梯度值,还要考虑上一次的参数更新
  • 将链式法则应用于默认模式神经网络络梯度值的计算,得到的算法叫作反向傳播(backpropagation有时也叫反式微分,reverse-mode differentiation)反向传播从最终损失值开始,从最顶层反向作用至最底层利用链式法则计算每个参数对损失值的贡献夶小。

我要回帖

更多关于 默认模式神经网络 的文章

 

随机推荐