前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >斯坦福CS231n - CNN for Visual Recognition(6)-lecture5预处理、正则化、损失函数

斯坦福CS231n - CNN for Visual Recognition(6)-lecture5预处理、正则化、损失函数

作者头像
李智
发布2018-08-03 17:23:39
8350
发布2018-08-03 17:23:39
举报
文章被收录于专栏:李智的专栏李智的专栏

本节主要讲了数据预处理、正则化以及损失函数

数据预处理

关于数据预处理我们有3种常用的方式,假设数据矩阵XX,假设其尺寸是[N,D][N ,D](NN是数据样本的数量,DD是数据的维度)。

去均值

去均值是预处理最常见的。对待训练的每一张图片的特征,都减去全部训练集图片的特征均值。它对数据中每个独立特征减去平均值,从几何上可以理解为在每个维度上都将数据云的中心都迁移到原点。在numpy中,该操作可以通过代码X -= np.mean(X, axis=0)实现。而对于图像,更常用的是对所有像素都减去一个值,可以用X -= np.mean(X)实现,也可以在3个颜色通道上分别操作。

归一化

归一化是将数据的所有维度都归一化,使其数值范围都近似相等。实现归一化有两种方式。第一种是先对数据做零中心化(zero-centered),也就是去均值处理,然后每个维度都除以其标准差,实现代码为X /= np.std(X, axis=0)。第二种是对每个维度都做归一化,使得每个维度的最大和最小值是1和-1。这个预处理操作只有在确信不同的输入特征有不同的数值范围(或计量单位)时才有意义,但要注意预处理操作的重要性几乎等同于学习算法本身。在图像处理中,由于像素的数值范围几乎是一致的(0-255),所以进行此预处理不是必要的。

这里写图片描述
这里写图片描述
PCA和白化

PCA和白化是另外一种数据预处理方式。在经过去均值操作之后,我们可以计算数据的协方差矩阵,从而可以知道数据各个维度之间的相关性。

代码语言:javascript
复制
# 假设输入数据矩阵X的尺寸为[N x D]
X -= np.mean(X, axis = 0) # 对数据进行零中心化(重要)
cov = np.dot(X.T, X) / X.shape[0] # 得到数据的协方差矩阵

  数据协方差矩阵的第i,ji, j个元素是数据第ii个和第jj个维度的协方差。具体来说,该矩阵的对角线上的元素是方差。还有,协方差矩阵是对称和半正定的。我们可以对数据协方差矩阵进行SVD(奇异值分解)运算。  

代码语言:javascript
复制
U,S,V = np.linalg.svd(cov)

  U的列是特征向量,S是装有奇异值的1维数组(因为cov是对称且半正定的,所以S中元素是特征值的平方)。为了去除数据相关性,将已经零中心化处理过的原始数据投影到特征基准上:

代码语言:javascript
复制
Xrot = np.dot(X,U) # 对数据去相关性

  U是一组正交基向量。我们可以看做把原始数据XX投射到这组维度保持不变的正交基底上,从而也就完成了对原始数据的去相关。如果去相关之后你再求一下Xrot的协方差矩阵,你会发现这时候的协方差矩阵是一个对角矩阵了。而numpy中的np.linalg.svd更好的一个特性是,它返回的U是对特征值排序过的,这也就意味着,我们可以用它进行降维操作。我们可以只取top的一些特征向量,然后做和原始数据做矩阵乘法,这个时候既降维减少了计算量,同时又保存下了绝大多数的原始数据信息,这就是主成分分析/PCA

代码语言:javascript
复制
Xrot_reduced = np.dot(X, U[:,:100]) # Xrot_reduced 变成 [N x 100]

  上面的代码,将原始的数据集由[N,D][N , D]降到了[N,100][N , 100],留下了数据中包含最大方差的100个维度。通常使用PCA降维过的数据训练线性分类器和神经网络会达到非常好的性能效果,同时还能节省时间和存储器空间。 白化(whitening)。白化操作的输入是特征基准上的数据,然后对每个维度除以其特征值来对数值范围进行归一化。该变换的几何解释是:如果数据服从多变量的高斯分布,那么经过白化后,数据的分布将会是一个均值为零,且协方差相等的矩阵。该操作的代码如下:

代码语言:javascript
复制
# 对数据进行白化操作:
# 除以特征值 
Xwhite = Xrot / np.sqrt(S + 1e-5)

注意:增加噪声。分母中添加了1e-5(或一个更小的常量)来防止分母为0。该变换的一个缺陷是在变换的过程中可能会增加数据中的噪声,因为它将所有维度都拉伸到相同的数值范围,这些维度中也包含了那些只有极少差异性(方差小)而大多是噪声的维度。在实际操作中,这个问题可以用更强的平滑来解决(用比1e-5更大的值)。

这里写图片描述
这里写图片描述

  上图左边是二维的原始数据。中间是经过PCA操作的数据。可以看出数据首先是零中心的,然后变换到了数据协方差矩阵的基准轴上。这样就对数据进行去相关(协方差矩阵变成对角阵)。右边:每个维度都被特征值调整数值范围,将数据协方差矩阵变为单位矩阵。从几何上看,就是对数据在各个方向上拉伸压缩,使之变成服从高斯分布的一个数据点分布。   下面我们以CIFAR-10数据集(50000*3072)为例,看看预处理的效果。

这里写图片描述
这里写图片描述

  图片最左边是原始的图像(49张)。   左二是一张图3072个特征值向量中的前144个。靠前面的特征向量解释了数据中大部分的方差,可见它们与图像中较低的频率相关。   左三是49张经过了PCA降维处理的图片,展示了前144个特征向量。每个原始图像为3072维的向量,向量中的元素是图片上某个位置的像素在某个颜色通道中的亮度值。而现在仅使用了前144维的向量,每个元素表示了特征向量对于组成这张图片的贡献度。为了让图片正常显示,需要将144维度重新变成基于像素基准的3072个数值进行可视化。因为U是一个旋转,可以通过乘以U.transpose()[:144,:]来实现。可以看见图像变得有点模糊了,这正好说明前面的特征向量获取了较低的频率。可以看出,大多数信息还是保留了下来。   最右边图像是将“白化”后的数据进行显示。其中144个维度中的方差都被压缩到了相同的数值范围。然后144个白化后的数值通过乘以U.transpose()[:144,:]转换到图像像素基准上。现在较低的频率被隐去,突出了较高的频率。 实际上在卷积神经网络中并不会采用PCA和白化这些变换。然而对数据进行零中心化操作还是非常重要的,对每个像素进行归一化也很常见。

任何预处理策略(比如数据去均值)都只能在训练集数据上进行计算,算法训练完毕后再应用到验证集或者测试集上。例如,如果先计算整个数据集图像的平均值然后每张图片都减去平均值,最后将整个数据集分成训练/验证/测试集,这个做法是错误的。应该先分成训练/验证/测试集,只是从训练集中求图片平均值,然后各个集(训练/验证/测试集)中的图像再减去这个平均值。


权重初始化

  在开始训练网络之前,还需要初始化网络的参数。 错误:全零初始化。在训练完毕后,虽然不知道网络中每个权重的最终值,但如果数据经过恰当的归一化,就可以假设所有权重数值中大约一半为正数,一半为负数。这样,有人会想把权重的初始值设为0,因为在期望上来说0是最合理的猜测。这个做法错误的!因为如果网络中的每个神经元都计算出同样的输出,然后它们就会在反向传播中计算出同样的梯度,从而进行同样的参数更新。换句话说,如果权重被初始化为同样的值,神经元之间就失去了不对称性的源头。 不太好:小随机数初始化。权重初始值最好非常接近0又不能等于0。解决方法就是将权重初始化为很小的数值,以此来打破对称性。其思路是:如果神经元刚开始的时候是随机且不相等的,那么它们将计算出不同的更新,并将自身变成整个网络的不同部分。   小随机数权重初始化的实现方法是:W = 0.01 * np.random.randn(fan_in,fan_out)。其中randn函数是基于零均值和标准差的一个高斯分布来生成随机数的。根据这个式子,每个神经元的权重向量都被初始化为一个随机向量,而这些随机向量又服从一个多变量高斯分布,这样在输入空间中,所有的神经元的指向是随机的。也可以使用均匀分布生成的随机数,但是从实践结果来看,对于算法的结果影响极小。 注意。并不是小数值一定会得到好的结果,可能会导致梯度饱和。例如,一个神经网络的层中的权重值很小,那么在反向传播的时候就会计算出非常小的梯度(因为梯度与权重值是成比例的)。这就会很大程度上减小反向传播中的“梯度信号”,在深度网络中,就会出现问题。 正确:使用1/sqrt(n)校准方差(Xavier init)。小随机数初始化存在一个问题,随着输入数据量的增长,随机初始化的神经元的输出数据的分布中的方差也在增大。我们可以除以输入数据量的平方根来调整其数值范围,这样神经元输出的方差就归一化到1了。也就是说,建议将神经元的权重向量初始化为:w = np.random.randn(fan_in,fan_out) / sqrt(fan_in)。其中fan_in是输入数据的数量。这样就保证了网络中所有神经元起始时有近似同样的输出分布。实践经验证明,这样做可以提高收敛的速度。   我们从数学的角度,简单解释一下,为什么上述操作可以归一化方差。考虑在激励函数之前的权重ww与输入xx的内积s=∑niwixis=\sum\limits_{n}^{i}w_ix_i部分,我们计算一下ss的方差:

Var(s)=Var(∑inwixi)=∑inVar(wixi)=∑in[E(wi)]2Var(xi)+E[(xi)]2Var(wi)+Var(xi)Var(wi)=∑inVar(xi)Var(wi)=(nVar(w))Var(x)

\begin{align} \text{Var}(s) &= \text{Var}(\sum_i^n w_ix_i) \\ &= \sum_i^n \text{Var}(w_ix_i) \\ &= \sum_i^n [E(w_i)]^2\text{Var}(x_i) + E[(x_i)]^2\text{Var}(w_i) + \text{Var}(x_i)\text{Var}(w_i) \\ &= \sum_i^n \text{Var}(x_i)\text{Var}(w_i) \\ &= \left( n \text{Var}(w) \right) \text{Var}(x) \end{align}

  在前两步,使用了方差的性质。在第三步,因为假设输入和权重的平均值都是0,所以E[xi]=E[wi]=0E[x_i] = E[w_i] = 0。注意这只是假设,实际中比如ReLU单元中均值就为正。最后一步,我们假设所有的都服从同样的分布。从推导公式可见,如果想要ss方差和输入相同,那么在初始化的时候必须保证每个权重ww的方差是1/n1/n。又因为对于一个随机变量XX和标量aa,有Var(aX)=a2Var(X)\text{Var}(aX) = a^2\text{Var}(X),这就说明可以基于一个标准高斯分布,然后乘以a=1/n−−−√a=\sqrt{1/n},使其方差为1/n1/n,于是得出:w = np.random.randn(n) / sqrt(n)。   初始化权重还有一些其他的研究和建议,比如Glorot在论文Understanding the difficulty of training deep feedforward neural networks就推荐使用能满足Var(w)=2/(nin+nout)Var(w)=2/(n_{in}+n_{out})的权重初始化。其中nin,noutn_{in},n_{out}是前一层和后一层的神经元个数。另外一篇比较新的论文Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification指出尤其对于ReLU神经元,我们初始化方差应该为2.0/n2.0/n,也就是w = np.random.randn(n) * sqrt(2.0/n)。目前的神经网络中使用了很多ReLU单元,因此推荐使用这个初始化方法。 稀疏初始化(Sparse initialization)。此方法将所有权重矩阵设为0,同时为了打破对称性,每个神经元都同下一层固定数目的神经元随机连接(其权重数值由一个小的高斯分布生成)。一个比较典型的连接数目是10个。 偏置(biases)的初始化。通常将偏置初始化为0,这是因为随机小数值权重矩阵已经打破了对称性。对于ReLU非线性激活函数,有研究人员喜欢使用如0.01这样的小数值常量作为所有偏置的初始值,这是因为他们认为这样做能让所有的ReLU单元一开始就激活,这样就能保存并传播一些梯度。然而,这样做并不清楚是否总是能提高算法性能(有时实验结果显示性能更差),所以通常还是使用0来初始化偏置参数。 批量归一化(Batch Normalization)。该方法最近才提出,减轻了如何合理初始化神经网络这个棘手问题,其做法是让激活数据在训练开始前通过一个网络,网络处理数据使其服从标准高斯分布。因为归一化是一个简单可求导的操作,所以上述思路是可行的。在实现层面,应用这个技巧通常意味着全连接层(或者是卷积层)与激活函数之间添加一个BatchNorm层。在实践中,使用了批量归一化的网络对于不好的初始值有更强的鲁棒性。批量归一化可以理解为在网络的每一层之前都做预处理。


正则化Regularization

  为了防止神经网络过拟合,有以下几种正则化方法:

  • L2正则化。可以通过惩罚目标函数中所有参数的平方将其实现,对于每个权重ww,在损失函数里加入12λw2\frac12λw^2,其中λλ是我们可调整的正则化强度。顺便说一句,这里在前面加上1/21/2的原因是,求导(梯度)时,刚好变成λwλw而不是2λw2λw。L2正则化理解起来也很简单,它对特别大的权重有很高的惩罚度,以求让权重的分配均匀一些,而不是集中在某一小部分的维度上。再想一下,加入L2正则化项,意味着在梯度下降参数更新时,每个权重以W += -lambda*W的程度被拉向0。
  • L1正则化。我们对于每个权重ww的惩罚项为λ|w|λ|w|。有时L1和L2正则化一起使用,加入惩罚项λ1∣w∣+λ2w2λ_1∣w∣+λ_2w^2,L1正则化使权重特征向量通过模型训练逐渐地稀疏化,这意味着最后只留下了对结果影响最大的一部分权重,而其他不相关的输入(噪声等)因为得不到权重被抑制。
  • 通常L2正则化后的特征向量是一组很分散的小值,而L1正则化只留下影响较大的权重。在实际应用中,如果你不是特别要求只保留部分特征,那么L2正则化通常能得到比L1正则化更好的效果。
  • 最大范式约束(Max norm constraints)。给每个神经元中权重向量的量级设定上限,并使用投影梯度下降来确保这一约束。在实践中,不添加任何的惩罚项,参数更新方式不变,但是要求神经元中的权重向量w⃗ \vec{w}必须满足∥w⃗ ∥2<c\Vert \vec{w} \Vert_2 < c,cc一般为3或4。有研究者提出使用这种正则化方法时效果更好。这种正则化还有一个良好的性质,即使在学习率设置过高的时候,网络中也不会出现数值“爆炸”,这是因为它的参数更新始终是被限制着的。
  • 随机失活(Dropout)。这是一个简单又极其有效的正则化方法。该方法由Srivastava在论文Dropout: A Simple Way to Prevent Neural Networks from Overfitting中提出的,与L1正则化,L2正则化和最大范式约束等方法互为补充。在训练的时候,随机失活的实现方法是让神经元以超参数的概率被激活(PP)或者被设置为0(1−P1-P)。

![这里写图片描述](http://cs231n.github.io/assets/nn2/dropout.jpeg)   上图是一个3层的神经网络的dropout示意图。在训练过程中,随机失活可以被认为是对完整的神经网络抽样出一些子集,每次基于输入数据只更新子网络的参数。在测试阶段不使用随机失活,可以理解为是对数量巨大的子网络们做了模型集成(model ensemble),以此来计算出一个平均的预测。      一个3层神经网络的普通版随机失活可以用下面代码实现:  

代码语言:javascript
复制
""" 普通版随机失活: 不推荐实现 (看下面笔记) """

p = 0.5 # 激活神经元的概率. p值更高 = 随机失活更弱

def train_step(X):
  """ X中是输入数据 """

  # 3层neural network的前向传播
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = np.random.rand(*H1.shape) < p # 第一个随机失活遮罩
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = np.random.rand(*H2.shape) < p # 第二个随机失活遮罩
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3

  # 反向传播:计算梯度... (略)
  # 进行参数更新... (略)

def predict(X):
  # 前向传播时模型集成
  H1 = np.maximum(0, np.dot(W1, X) + b1) * p # 注意:激活数据要乘以p
  H2 = np.maximum(0, np.dot(W2, H1) + b2) * p # 注意:激活数据要乘以p
  out = np.dot(W3, H2) + b3

  上述代码中,在train_step函数中,我们做了2次Dropout。我们甚至可以在输入层做一次dropout。反向传播过程保持不变,除了我们要考虑一下U1,U2

  很重要的一点是,大家仔细看predict函数部分,我们不再dropout了,而是对于每个隐层的输出,都用概率p做了一个幅度变换。可以从数学期望的角度去理解,我们考虑一个神经元的输出为xx(没有dropout的情况下),它的输出的数学期望为px+(1−p)0px+(1−p)0,那我们在测试阶段(测试所有神经元都被激活,无dropout),如果直接把每个输出xx都做变换x→pxx→px,便保持一样的数学期望的。

  上述代码有一些缺陷,我们必须在测试阶段对每个神经的输出都以p的概率输出。实际应用中,测试阶段对于时间的要求非常高,我们可以考虑反着来,代码实现的时候用反相随机激活(inverted dropout),即在训练阶段就做相反的幅度变换/scaling(除以p),在测试阶段,直接把权重拿来使用,而不用附加很多步用p做scaling的过程。inverted dropout的示例代码如下:  

代码语言:javascript
复制
""" 
Inverted Dropout的版本,把本该花在测试阶段的时间,转移到训练阶段,从而提高testing部分的速度
"""

p = 0.5 # dropout的概率,也就是保持一个神经元激活状态的概率

def train_step(X):
  # f3层神经网络前向计算
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = (np.random.rand(*H1.shape) < p) / p # 注意到这个dropout中我们除以p,做了一个inverted dropout
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = (np.random.rand(*H2.shape) < p) / p # 这个dropout中我们除以p,做了一个inverted dropout
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3

  # 反向传播: 计算梯度... (这里省略)
  # 参数更新... (这里省略)

def predict(X):
  # 直接前向计算,无需再乘以p
  H1 = np.maximum(0, np.dot(W1, X) + b1) 
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  out = np.dot(W3, H2) + b3

  对于随机失活这个部分的详细介绍有以下文献:   1. 2014 Srivastava 的论文Dropout paper   2. Dropout Training as Adaptive Regularization 前向传播中的噪音。在更一般化的分类上,随机失活属于网络在前向传播中有随机行为的方法。测试时,通过分析法(在使用随机失活的本例中就是乘以pp)或数值法(例如通过抽样出很多子网络,随机选择不同子网络进行前向传播,最后对它们取平均)将噪音边缘化。在这个方向上的另一个研究是DropConnect,它在前向传播时,一系列权重被随机设置为0。卷积神经网络同样会吸取这类方法的优点,比如随机汇合(stochastic pooling),分级汇合(fractional pooling),数据增长(data augmentation)。 偏置正则化。在线性分类器中介绍过,偏置参数的正则化并不常见,因为它们在矩阵乘法中和输入数据并不产生互动,所以并不需要控制其在数据维度上的效果。然而在实际应用中(使用了合理数据预处理的情况下),对偏置进行正则化也很少会导致算法性能变差。这可能是因为相较于权重参数,偏置参数实在太少,所以分类器需要它们来获得一个很好的数据损失,那么还是能够承受的。 每层正则化。对于不同的层进行不同强度的正则化很少见(可能除了输出层以外),关于这个思路的相关文献也很少。 实践:通过交叉验证获得一个全局使用的L2正则化强度是比较常见的。在使用L2正则化的同时在所有层后面使用随机失活也很常见。值一般默认设为0.5,也可能在验证集上调参。


损失函数

  损失函数的正则化损失部分,可以看做是对模型复杂程度的某种惩罚。损失函数的第二个部分是数据损失,它是一个有监督学习问题,用于衡量分类算法的预测结果(即分类评分)和真实标签结果之间的一致性。数据损失是对所有样本的数据损失求平均。即在L=1N∑iLiL = \frac{1}{N} \sum\limits_i L_i中,NN是训练集数据的样本数。我们把神经网络中输出层的激活函数简写为f(x)=f(xi,w)f(x)=f(x_i,w),在实际中你可能需要解决以下几类问题:

分类问题

  假设有一个装满样本的数据集,每个样本都有一个唯一的正确标签(是固定分类标签之一)。在这类问题中,一个最常见的损失函数就是SVM(是Weston Watkins 公式):

Li=∑j≠yimax(0,fj−fyi+1)

L_i = \sum_{j\neq y_i} \max(0, f_j - f_{y_i} + 1)   有些学者的论文中指出平方折叶损失(max(0,fj−fyi+1)2max(0,f_j-f_{y_i}+1)^2)算法的结果会更好。   第二个常用的损失函数是Softmax分类器,它使用交叉熵损失:

Li=−log(efyi∑jefj)

\displaystyle L_i=-log(\frac{e^{f_{y_i}}}{\sum_je^{f_j}})   当类别数目特别大时。标签集非常庞大(例如字典中的所有英语单词,或者ImageNet中的22000种分类),就需要使用分层Softmax(Hierarchical Softmax)了。分层softmax将标签分解成一个树。每个标签都表示成这个树上的一个路径,这个树的每个节点处都训练一个Softmax分类器来在左和右分枝之间做决策。树的结构对于算法的最终结果影响很大,而且一般需要具体问题具体分析。 属性分类。上述两种损失函数都假定对于每个样本,我们只有一个标签yiy_i。但是有时,yiy_i是一个二值的向量,每个元素都代表有没有某个属性。比如在Instagram上的图片,就可以看成是被一个巨大的标签集合中的某个子集打上标签,一张图片上可能有多个标签。在这种情况下,一个明智的方法是为每个属性创建一个独立的二分类的分类器。例如,针对每个分类的二分类器会采用下面的公式:

Li=∑jmax(0,1−yijfj)

L_i=\sum\limits_jmax(0,1−y_{ij}f_j)   其中,求和是针对有所的类别jj,而yijy_{ij}是11或−1-1(取决于第ii个样本是否有第jj个属性的标签),打分向量fjf_j在类别(标签)被预测到的情况下为正,其他情况为负。注意到如果正样本有比+1+1小的得分,或者负样本有比−1-1大的得分,那么损失就一直在累积。   另外一个也许有效的解决办法是,我们可以对每个属性,都单独训练一个逻辑回归分类器,一个二分类的逻辑回归分类器只有0,1两个类别,属于1的概率为:

P(y=1∣x;w,b)=11+e−(wTx+b)=σ(wTx+b)

P(y=1∣x;w,b)=\frac{1}{1+e^{−(w^Tx+b)}}=σ(w^Tx+b)   又因为0,1两类的概率和为1,所以归属于类别0的概率为P(y=0∣x;w,b)=1−P(y=1∣x;w,b)P(y=0∣x;w,b)=1−P(y=1∣x;w,b)。一个样本在σ(wTx+b)>0.5σ(w^Tx+b)>0.5的情况下被判定为1,如果时sigmoid函数,则对应的是得分wTx+b>0w^Tx+b>0。这时候的损失函数可以定义为最大化似然概率的形式,也就是:

Li=∑jyijlog(σ(fj))+(1−yij)log(1−σ(fj))

L_i = \sum_j y_{ij} \log(\sigma(f_j)) + (1 - y_{ij}) \log(1 - \sigma(f_j))   其中标签yijy_{ij}为1(正样本)或者0(负样本),而σσ是sigmoid函数,上面的公式看起来很复杂,但ff的梯度实际上非常简单:∂Li∂fj=yij−σ(fj)\displaystyle \frac{\partial L_i}{\partial f_j}=y_{ij}-\sigma(f_j)。

回归问题

  回归问题是预测实数的值的问题,比如预测房价,预测图片中某个东西的长度等。对于这种问题,通常是计算预测值和真实值之间的损失。然后用L2平方范式或L1范式度量差异。对于某个样本,L2范式计算如下:Li=||f−yi||22L_i=||f-y_i||^2_2   之所以在目标函数中要进行平方,是因为梯度算起来更加简单。因为平方是一个单调运算,所以不用改变最优参数。L1范式则是要将每个维度上的绝对值加起来:Li=||f−yi||1=∑j|fj−(yi)j|L_i=||f-y_i||_1=\sum_j|f_j-(y_i)_j|

  在上式中,如果有多个数量被预测了,就要对预测的所有维度的预测求和,即∑j\sum\limits_j。观察第ii个样本的第jj维,用δij\delta_{ij}表示预测值与真实值之间的差异。关于该维度的梯度(也就是∂Li∂fj\frac{\partial L_i}{\partial f_j})能够轻松地通过被求导为L2范式的δij\delta_{ij}或sign(δij)sign(\delta_{ij})。这就是说,评分值的梯度要么与误差中的差值直接成比例,要么是固定的并从差值中继承signsign。 注意:

  • 回归问题中L2损失与Softmax损失相比,其最优化过程要困难很多。直观来看,一个神经网络最后输出离散的判定类别,比训练它去输出一个个和样本结果对应的连续值,要简单多了。其实Softmax这种分类器,对于输出的打分结果具体值是不怎么在乎的,它只在乎各个类别之间的打分幅度有没有差很多(比如二分类两个类别的得分是1和9,与0.1和0.9)。
  • L2范数损失鲁棒性更差,异常点和噪声都可能改变损失函数的幅度,而带来大的梯度偏差。
  • 对于回归问题,我们一般都会首先考虑,这个问题能否转化成对应的分类问题,比如说我们把输出值划分成不同的区域。举个例子,如果我们要预测一部电影的豆瓣打分,我们可以考虑把得分结果分成1-5颗星,而转化成一个分类问题。
  • 如果你觉得问题确实没办法转化成分类问题,那要小心使用L2范数损失:举个例子,在神经网络中,在L2损失函数之前使用dropout是不合适的。

如果我们遇到回归问题,首先考虑尽量把输出变成二分类,然后对它们进行分类,从而变成一个分类问题。


参考资料

链接:https://link.zhihu.com/?target=http%3A//cs231n.github.io/neural-networks-2/ 链接:https://zhuanlan.zhihu.com/p/21560667?refer=intelligentunit 链接:http://blog.csdn.net/han_xiaoyang/article/details/50451460

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年11月30日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据预处理
    • 去均值
      • 归一化
        • PCA和白化
        • 权重初始化
        • 正则化Regularization
        • 损失函数
          • 分类问题
            • 回归问题
            • 参考资料
            相关产品与服务
            图像处理
            图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档