[cs231n] assignment1 2-layer-net

代码链接 : https://github.com/ZhaoYi1031/cs231n/tree/master/assignment1

这个是assignment1的尾声,主要是实现一个两层的全连接的神经网络。网络结构是如下:

Input -> 全连接层1 -> Relu -> 全连接层2 -> softmax

基本上都是按照hint说的去做就好了,前向传播去计算score,softmax求loss,然后反向传播计算grads。其中这是我第一次自己完全手推反向传播的梯度公式,感觉对这个有一个新的理解。其中softmax的求导是关键,但其实关于softmax的求导要比之前的计算,因为关于偏导的变量不是W而是f.

被坑的主要是在求loss的时候我对正则项的处理不一致了,一个地方是reg*(np.sum(W1 * W1) + np.sum(W2 * W2)),后面求梯度的时候忘记乘2了。还有一个小错误是一开始写全连接层的时候忘记加上截距项b1和b2了,然后debug了半天,也发现了那个numerical check的非常骚的匿名函数lambda。

最后的炼丹(调整参数)环节,我一开始按照hint是把隐藏层的大小、学习率、训练epoch的数量、正则化力度这几项都配置了几个参数备选,然后放在那里跑去午休了,然后发现跑了一会才跑了一点(机器配置渣加上当时我还有很多没有向量化)然后就直接按照别人的来了。

之后就是验证与调参环节,验证模型:①输入给定值,计算与理论结果的误差;②使用很小的数据集训练,正常情况下loss可减小到0。然后我们看一下最基本的参数的数据图:

《[cs231n] assignment1 2-layer-net》

一个很重要的影响因素是我们的学习率小了(loss的下降类似于线性,意味着学习率可能太低)。从图里我们看到测试集和验证集的差距不大,说明我们可以考虑在不过拟合的情况下增加hidden layer的size来获得更好的学习能力。

按照一个po主的参数跑了之后,验证集的准确率从0.287增长到了0.557,然后效果图也变到了如下:

《[cs231n] assignment1 2-layer-net》


做完了assignment1,我们总结一下几点:

  1. 神经网络与线性分类器(svm, softmax)的区别在哪里

分类问题的一个很重要的点就在于特征提取(feature extraction),我们的线性分类器只是在一个5000*3072上进行分类,所以效果并不会太好。而神经网络的全连接的隐藏层可以看作是一个全局的特征提取,因为实际上这些特征不需要人工去提取,而完全是神经网络可以自己学到的。而之后要写的卷积神经网络就较好地做到了:特征提取+线性分类器。

目前的这个分类器仍然存在的问题是容易陷入局部最优解,而且随着层数的增加,可能“梯度消失”的现象会越来越严重。

1、2006年,Hinton发表的两篇论文Reducing the Dimensionality of Data with Neural Networks、A Fast Learning Algorithm for Deep Belief Nets利用预训练方法缓解了局部最优解问题,具体思想就是:利用无监督的逐层贪婪学习算法,一层一层地预训练神经网络的权重(每一层通过一个稀疏自编码器完成训练),最后再用有标签的数据通过反向传播微调所有权重。
2、我们之前讲过的ReLU、Maxout等激活函数,可以很好地克服“梯度消失”现象,而后来的Batch Normalization更是凶猛。

2012年ImageNet比赛中,CNN以压倒性的优势取得胜利,深度学习的巨大浪潮才正式开始。而自那之后,预训练方法已经被完全抛弃了,大概是因为数据量足够大了。

卷积神经网络(CNNs)的强大是因为它有着非常强大的(局部)特征提取能力,而且这些特征是逐层抽象化的,即下一层的特征是上一层的组合。层数越深,特征组合就越多、越深刻。

Ref

一个总结的博客,系列也不错
求梯度的图片,赞

留存的一些问题

  1. 计算loss的时候除N可以理解,在我们计算grads为什么要/N(之后加2regW1)

  2. 这个梯度计算的时候什么时候转置有什么科学的判断方法吗,我目前都是根据shape去判断的

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注