神经网络学习笔记6

C6 与学习相关

1、参数的更新
①参数的最优化:找到使得损失函数值尽可能小的参数
SGD:随机梯度下降法,醉着梯度方向更新参数
缺点:如果函数形状非均向,呈延伸状,搜索的路径就会非常低效

momentum:动量
引入一个v
初始化时,v什么都不保存
当第一次调用update()时,v会以字典型变量形式保存参数结构相同的数据
减弱之字形变动程度

 1 class Momentum:
 2 
 3     """Momentum SGD"""
 4 
 5     def __init__(self, lr=0.01, momentum=0.9):
 6         self.lr = lr
 7         self.momentum = momentum
 8         self.v = None
 9         
10     def update(self, params, grads):
11         if self.v is None:
12             self.v = {}
13             for key, val in params.items():                                
14                 self.v[key] = np.zeros_like(val)
15                 
16         for key in params.keys():
17             self.v[key] = self.momentum*self.v[key] - self.lr*grads[key] 
18             params[key] += self.v[key]

AdaGrad:学习率衰减,随着学习的进行,逐渐减少学习率。一开始多学,逐渐少学;针对一个一个的参数,赋予其定制的值
新变量h,保存了以前所有梯度值的平方和,表示对应矩阵元素的乘法
当元素变动较大的元素学习率将逐渐减少

最后一行加上了微小值le-7,为了防止当self.h[key]中有0的时候,要将0用作除数的情况

※防止将0作为除数用,加上le-7

class AdaGrad:

    """AdaGrad"""

    def __init__(self, lr=0.01):
        self.lr = lr
        self.h = None
        
    def update(self, params, grads):
        if self.h is None:
            self.h = {}
            for key, val in params.items():
                self.h[key] = np.zeros_like(val)
            
        for key in params.keys():
            self.h[key] += grads[key] * grads[key]
            params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)

 

 

Adam:结合momentum和adagrad的方法,组合两个方法的有点实现参数空间的高效搜索,进行超参数的“偏置校正”

class Adam:

    """Adam (http://arxiv.org/abs/1412.6980v8)"""

    def __init__(self, lr=0.001, beta1=0.9, beta2=0.999):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.iter = 0
        self.m = None
        self.v = None
        
    def update(self, params, grads):
        if self.m is None:
            self.m, self.v = {}, {}
            for key, val in params.items():
                self.m[key] = np.zeros_like(val)
                self.v[key] = np.zeros_like(val)
        
        self.iter += 1
        lr_t  = self.lr * np.sqrt(1.0 - self.beta2**self.iter) / (1.0 - self.beta1**self.iter)         
        
        for key in params.keys():
            #self.m[key] = self.beta1*self.m[key] + (1-self.beta1)*grads[key]
            #self.v[key] = self.beta2*self.v[key] + (1-self.beta2)*(grads[key]**2)
            self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key])
            self.v[key] += (1 - self.beta2) * (grads[key]**2 - self.v[key])
            
            params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7)
            
            #unbias_m += (1 - self.beta1) * (grads[key] - self.m[key]) # correct bias
            #unbisa_b += (1 - self.beta2) * (grads[key]*grads[key] - self.v[key]) # correct bias
            #params[key] += self.lr * unbias_m / (np.sqrt(unbisa_b) + 1e-7)

 


RMSProp:逐渐遗忘过去的梯度,在做加法运算时候将新梯度信息更多地反应出来。(指数移动平均)

class RMSprop:

    """RMSprop"""

    def __init__(self, lr=0.01, decay_rate = 0.99):
        self.lr = lr
        self.decay_rate = decay_rate
        self.h = None
        
    def update(self, params, grads):
        if self.h is None:
            self.h = {}
            for key, val in params.items():
                self.h[key] = np.zeros_like(val)
            
        for key in params.keys():
            self.h[key] *= self.decay_rate
            self.h[key] += (1 - self.decay_rate) * grads[key] * grads[key]
            params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)

 

 

 

 

2、权重的初始值
梯度消失:当各层激活值呈0或者1分布,随着输出不断靠近0或者1,导数的值逐渐接近0;会造成反向传播中梯度的值不断减伤,最后消失。
Xavier初始值:使得各层激活值呈现具有相同广度的分布,推导合适的权重尺度。
使用Xavier后,前一层节点越多,要设定为目标节点的初始权重尺度就越小。
※激活函数最好有关于原点对称的性质。

He初始值:当前一层节点数为n时,He初始值使用标准差(2/n)^-(1/2)的高斯分布
※当激活函数使用ReLU时,权重初始函数值使用He初始值,当激活函数为sigmoid或者tanh等S型曲线函数时,初始值就使用Xavier初始值

3、Batch Normalization
优点:可以使得学习快速进行(可以增大学习率)、可以不那么依赖初始值、一直过拟合(降低对Dropout等的必要性)
思路:调整各层的激活值分布使得其拥有适当的广度。为此,要向神经网络中插入对数据分布进行正规化的层,即Batch Normalization层
以学习时的mini-batch为单位,按照mini-batch进行正规化。进行使得数据分布的均值为0、方差为1的正规化。
使用batch norm可以推动学习的进行,并且对于权重初始值变得健壮。

4、正则化
过拟合:只能拟合训练数据,不能很好的拟合不包含在训练数据中的其他数据的状态
产生的原因:①、模型拥有大量的参数、表现力强,②训练数据少

抑制过拟合的技巧:
①权值衰减:通过在学习过程中对大的权重进行惩罚来抑制过拟合。
②dropout:抑制过拟合,是一种在学习过程中随机删除神经元的方法。训练时,随机选出隐藏层的神经元,然后将其删除,被删除的神经元不再进行信号的传递。
测试时,对于各个神经元的输出,要乘上训练时的删除比例后再输出。
通过使用Dropout,训练数据和测试数据的识别精度差距变小。

dropout把集成学习的效果模拟地通过一个网络实现了
5、超参数的验证
超参数:指各层的神经元数量、batch大小、参数更新时的学习率或者权值衰减。
如果超参数没有设置合适的值,模型的性能会变得很差。
验证数据:用于调整超参数的数据,用它来评估超参数的好坏。
不能使用测试数据评估超参数的性能。

超参数的最优化:逐渐缩小超参数的好值存在范围。一开始先大致设定一个范围,从这个范围内随机选出一个超参数,用这个采样到的值进行识别精度的评估,然后多次重复该操作,观察识别精度的结果。根据这个结果缩小超参数好值的范围。
更精炼的方法:贝叶斯最优化

 

posted @ 2020-08-26 18:15  -DP-  阅读(134)  评论(0编辑  收藏  举报