zoukankan      html  css  js  c++  java
  • 【CS231N】5、神经网络静态部分:数据预处理等

    一、疑问

    二、知识点

    1. 白化

    ​ 白化操作的输入是特征基准上的数据,然后对每个维度除以其特征值来对数值范围进行归一化。该变换的几何解释是:如果数据服从多变量的高斯分布,那么经过白化后,数据的分布将会是一个均值为零,且协方差相等的矩阵。该操作的代码如下:

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

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

    2. 预处理注意

    ​ 任何预处理策略(比如数据均值)都只能在训练集数据上进行计算,算法训练完毕后再应用到验证集或者测试集上。(避免过拟合等)

    3.权重初始化

    • 错误:全零初始化。 权重全零,会导致每个神经元都计算出同样的输出,在BP时也会计算出同样的梯度,从而进行同样的参数更新。****
    • 小随机数初始化: W = 0.01 * np.random.randn(D,H)。并不是数值越小结果越好,要控制在一定的量级内才不会导致BP时梯度信号过小。
    • 使用(1/sqrt(n))校准方差。随着输入数据量的增长,随机初始化的神经元的输出数据的分布中的方差也在增大。公式如下: w = np.random.randn(n) / sqrt(n). 此外,基于BP时梯度的分析,神经网络算法使用ReLU神经元时的当前最佳推荐形式为: w = np.random.randn(n) / sqrt(2.0/n)
    • 批量归一化。让激活数据在训练开始前通过一个网络,网络处理数据使其服从标准高斯分布。使用了批量归一化的网络对于不好的初始值有更强的鲁棒性。

    4. 正则化

    • L2正则化。 L2正则化可以直观理解为它对于大数值的权重向量进行严厉惩罚,使网络更倾向于使用所有输入特征,而不是严重依赖输入特征中某些小部分特征。

    • L1正则化。 让权重向量在最优化的过程中变得稀疏(即非常接近0)。即使用L1正则化的神经元最后使用的是它们最重要的输入数据的稀疏子集,同时对于噪音输入则几乎是不变的了。

    • 随机失活。 在训练的时候,随机失活的实现方法是让神经元以超参数(p)的概率被激活或者被设置为0。随机失活可以被认为是对完整的神经网络抽样出一些子集,每次基于输入数据只更新子网络的参数。注意:predict函数中不进行随机失活,但是对于两个隐层的输出都要乘以p,调整其数值范围。

      """ 普通版随机失活: 不推荐实现 (看下面笔记) """
    
      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
    
    • 反向随机失活。在训练时就进行数值范围调整,从而让前向传播在测试时保持不变。这样做还有一个好处,无论你决定是否使用随机失活,预测方法的代码可以保持不变。
      """ 
      反向随机失活: 推荐实现方式.
      在训练的时候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
    
    
    • 随机失活的解释。

      1、使用许多小的模型集成的一个大模型。假设某些神经元被随机失活了,那么在BP中,与这些神经元相连的上一层的权重也不会更新,那么就相当于只对整个大模型的子网络进行了训练。

      2、假设我们使用神经网络对猫这个类别进行检测,在神经网络中我们用到的特征可能有:耳朵、尾巴、眼睛等等,在标准的神经网络中,我们需要考虑每一个特征因素才能对猫进行得分计算。但是在测试集中,猫的图片是多种多样的,可能有时看不到尾巴或则耳朵,这就会影响了模型的泛化能力。而利用了随机失活,即在训练时我们随机得不考虑一些特征(例如耳朵)来训练模型,这样模型在测试集上一般能得到更好的泛化能力。

    5. 分类问题

    当面对一个回归任务,首先考虑是不是必须使用回归模型。一般而言,尽量把你的输出变成二分类,然后对它们进行分类,从而变成一个分类问题。

  • 相关阅读:
    Linux 压缩,解压
    Angular 修改子组件的样式
    vue项目-各类卡顿问题记录
    老vue项目webpack3升级到webpack5全过程记录(二)
    老vue项目webpack3升级到webpack5全过程记录(一)
    eslint配置汇总
    cke点击时初始化编辑器后光标恢复的方法
    使用 SVG transform rotate 解决画框中的数字跟随旋转的问题
    关于 Selection(getSelection ) 对象的一些常规用法集锦
    markdown 的使用技巧
  • 原文地址:https://www.cnblogs.com/CSLaker/p/8707592.html
Copyright © 2011-2022 走看看