CS231n第五课:神经网络2学习记录
来源:互联网 发布:redis存储数据大小 编辑:程序博客网 时间:2024/05/01 18:35
结合视频5和笔记:https://zhuanlan.zhihu.com/p/21560667?refer=intelligentunit
数据预处理
数据预处理的手段一般有:
· 去均值(mean subtraction)
· 规范化/归一化(normalization)
· 主成分分析(PCA)和白化(whitening)
PCA和白化(Whitening)是另一种预处理形式。在这种处理中,先对数据进行零中心化处理,然后计算协方差矩阵,它展示了数据中的相关性结构。
# 假设输入数据矩阵X的尺寸为[N x D]X -= np.mean(X, axis = 0) # 对数据进行零中心化(重要)cov = np.dot(X.T, X) / X.shape[0] # 得到数据的协方差矩阵
协方差计算公式:
假设 X 是以 n 个标量随机变量组成的列向量,并且μk 是其第k个元素的期望值,即,μk= E[X(k)];协方差矩阵然后被定义为:
Σ=E
矩阵中的第(i,j)个元素是xi与xj的协方差
该矩阵的对角线上的元素是方差。还有,协方差矩阵是对称和半正定的。我们可以对数据协方差矩阵进行SVD(奇异值分解)运算。
U,S,V = np.linalg.svd(cov)
SVD(奇异值分解):
http://blog.csdn.net/zhongkejingwang/article/details/43053513
http://blog.sina.com.cn/s/blog_3f738ee00102val0.html
# 对数据进行白化操作:# 除以特征值 Xwhite = Xrot / np.sqrt(S + 1e-5)
警告:夸大的噪声。注意分母中添加了1e-5(或一个更小的常量)来防止分母为0。该变换的一个缺陷是在变换的过程中可能会夸大数据中的噪声,这是因为它将所有维度都拉伸到相同的数值范围,这些维度中也包含了那些只有极少差异性(方差小)而大多是噪声的维度。在实际操作中,这个问题可以用更强的平滑来解决(例如:采用比1e-5更大的值)。
实际上在卷积神经网络中并不会采用PCA和白化。然而对数据进行零中心化操作还是非常重要的,对每个像素进行归一化也很常见。
常见错误。进行预处理很重要的一点是:任何预处理策略(比如数据均值)都只能在训练集数据上进行计算,算法训练完毕后再应用到验证集或者测试集上。例如,如果先计算整个数据集图像的平均值然后每张图片都减去平均值,最后将整个数据集分成训练/验证/测试集,那么这个做法是错误的。应该怎么做呢?应该先分成训练/验证/测试集,只是从训练集中求图片平均值,然后各个集(训练/验证/测试集)中的图像再减去这个平均值。
权重初始化
错误:全零初始化:因为如果网络中的每个神经元都计算出同样的输出,然后它们就会在反向传播中计算出同样的梯度,从而进行同样的参数更新。换句话说,如果权重被初始化为同样的值,神经元之间就失去了不对称性的源头。
可见,全零会导致输出都为0,全1则神经元太快饱和,梯度也将趋向于0. 所以应该选择0-1之间的某个值。
小随机数初始化:通常我们会将权重随机初始化为:均值为0,标准差为一个很小的正数(如0.001)的高斯分布,在numpy中可以写成:w = np.random.randn(n)。这样的初始化方式对于小型的神经网络是可以的
但是对于深度神经网络,这样的初始化方式并不好。我们以激活函数为tanh为例,如果标准差设置得较小,后面层的激活值将全部趋于0,反向传播时梯度也会变的很小;如果我们将标准差设置得大些,神经元就会趋于饱和,梯度将会趋于零。
为了解决这个问题,我们可以使用方差校准技术:
· 实践经验告诉我们,如果每个神经元的输出都有着相似的分布会使收敛速度加快。而上面使用的随机初始化方式,会使得各个神经元的输出值的分布产生较大的变化。
· 抛开激活函数,我们假设神经元的带权输入,则s和x的方差关系如下:
得到的结果显示,如果希望s与输入变量x同分布就需要使w的方差为1/n。即权重初始化方式改为:w = np.random.randn(n) / sqrt(n)。
使用1/sqrt(n)校准方差。上面做法存在一个问题,随着输入数据量的增长,随机初始化的神经元的输出数据的分布中的方差也在增大。我们可以除以输入数据量的平方根来调整其数值范围,这样神经元输出的方差就归一化到1了。也就是说,建议将神经元的权重向量初始化为:w = np.random.randn(n) / sqrt(n)。其中n是输入数据的数量。这样就保证了网络中所有神经元起始时有近似同样的输出分布。实践经验证明,这样做可以提高收敛的速度。
并给出结论:网络中神经元的方差应该是2.0/n。代码为w = np.random.randn(n) * sqrt(2.0/n)。这个形式是神经网络算法使用ReLU神经元时的当前最佳推荐。
稀疏初始化(Sparse initialization)。另一个处理非标定方差的方法是将所有权重矩阵设为0,但是为了打破对称性,每个神经元都同下一层固定数目的神经元随机连接(其权重数值由一个小的高斯分布生成)。一个比较典型的连接数目是10个。
偏置(biases)的初始化。通常将偏置初始化为0
批量归一化(Batch Normalization)
在每一层的wx+b和f(wx+b)之间加一个归一化(将wx+b归一化成:均值为0,方差为1(标准高斯分布))
这个方法可以进一步加速收敛,因此学习率可以适当增大,加快训练速度;过拟合现象可以得倒一定程度的缓解,所以可以不用Dropout或用较低的Dropout,而且可以减小L2正则化系数,训练速度又再一次得到了提升。即Batch Normalization可以降低我们对正则化的依赖程度。
现在的深度神经网络基本都会用到Batch Normalization。
正则化 Regularization
一个3层神经网络的普通版随机失活可以用下面代码实现:
""" 普通版随机失活: 不推荐实现 (看下面笔记) """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
上述操作不好的性质是必须在测试时对激活数据要按照p进行数值范围调整。既然测试性能如此关键,实际更倾向使用反向随机失活(inverted dropout),它是在训练时就进行数值范围调整,从而让前向传播在测试时保持不变。这样做还有一个好处,无论你决定是否使用随机失活,预测方法的代码可以保持不变。反向随机失活的代码如下:
作者:杜客链接:https://zhuanlan.zhihu.com/p/21560667来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。""" 反向随机失活: 推荐实现方式.在训练的时候drop和调整数值范围,测试时不做任何事."""p = 0.5 # 激活神经元的概率. p值更高 = 随机失活更弱def train_step(X): # 3层neural network的前向传播 H1 = np.maximum(0, np.dot(W1, X) + b1) U1 = (np.random.rand(*H1.shape) < p) / p # 第一个随机失活遮罩. 注意/p! H1 *= U1 # drop! H2 = np.maximum(0, np.dot(W2, H1) + b2) U2 = (np.random.rand(*H2.shape) < p) / p # 第二个随机失活遮罩. 注意/p! H2 *= U2 # drop! out = np.dot(W3, H2) + b3 # 反向传播:计算梯度... (略) # 进行参数更新... (略)def predict(X): # 前向传播时模型集成 H1 = np.maximum(0, np.dot(W1, X) + b1) # 不用数值范围调整了 H2 = np.maximum(0, np.dot(W2, H1) + b2) out = np.dot(W3, H2) + b3
损失函数
分类问题:当标签集非常庞大(例如字典中的所有英语单词,或者ImageNet中的22000种分类),就需要使用分层Softmax(Hierarchical Softmax)了。分层softmax将标签分解成一个树。每个标签都表示成这个树上的一个路径,这个树的每个节点处都训练一个Softmax分类器来在左和右分枝之间做决策。树的结构对于算法的最终结果影响很大,而且一般需要具体问题具体分析。
回归问题是预测实数的值的问题,比如预测房价,预测图片中某个东西的长度等。对于这种问题,通常是计算预测值和真实值之间的损失。然后用L2平方范式或L1范式度量差异
- CS231n第五课:神经网络2学习记录
- CS231n第四课:神经网络1学习记录
- CS231n第七课:卷积神经网络学习记录
- CS231n第三课:最优化学习记录
- CS231n第二课:图像分类学习记录
- cs231n 学习过程 问题记录
- CS231N神经网络
- CS231N 卷积神经网络课程学习笔记
- cs231n-(5)神经网络-3:学习和评估
- 神经网络深度学习链接斯坦福CS231n课程
- CS231n第二课:线性分类器学习记录
- CS231n第八课:目标检测定位学习记录
- CS231n第八课:目标检测定位学习记录
- 斯坦福大学深度学习公开课cs231n学习笔记(5)神经网络结构与激活函数
- 斯坦福大学深度学习公开课cs231n学习笔记(10)卷积神经网络
- CS231n课程笔记翻译:神经网络笔记2
- cs231n的第一次作业2层神经网络
- CS231n(15):神经网络笔记 2
- spark运行模式
- 【Android】51、动态添加碎片
- [LeetCode]Maximal Rectangle寻找最大矩形
- 关于struts2 2.5.2 的入门 遇到的问题 --总结1
- 继承、多态、封装、抽象类与接口
- CS231n第五课:神经网络2学习记录
- 自己做的购物系统
- POJ 3254 Corn Fields 状态压缩dp入门
- xml解析库xerces学习笔记一
- Quartz 2D编程指南之四:颜色与颜色空间
- CodeForces-710C Magic Odd Square(幻方问题/构造)
- Qt: 配置Qt Creator的调试功能
- 用Gradle建立一个简单的java项目
- POJ(2739)