神经网络(深度学习)常用的4种最优化方法——SGD、Momentum、AdaGrad、Adam

一、SGD

描述

随机梯度下降法(stochastic gradient descent),策略是朝着当前所在位置的坡度最大的方向前进。

数学式

神经网络(深度学习)常用的4种最优化方法——SGD、Momentum、AdaGrad、Adam_第1张图片

Python类

class SGD:
	def __init__(self, lr=0.01):
		self.lr = lr
        
	def update(self, params, grads):
		for key in params.keys():
			params[key] -= self.lr * grads[key]

二、Momentum

描述

“动量‘,参照小球在碗中滚动的物理规则进行移动。

数学式

神经网络(深度学习)常用的4种最优化方法——SGD、Momentum、AdaGrad、Adam_第2张图片

Python类

class Momentum:
    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr
        self.momentum = momentum
        self.v = None
        
    def updade(self, params, grads):
        if self.v is None:
            self.v = {}
            for key, val in params.items():
                self.v[key] = np.zeros_like(val)
                
        for key in params.keys():
            self.v[key] = self.momentum * self.v[ley] - self.lr * grads[key]
            params[key] += self.v[key]

三、AdaGrad

描述

Ada来自英文单词Adaptive,即“适当的”的意思;AdaGrad会为参数的每个元素适当地调整更新步伐(学习率),即学习率衰减,随着学习的进行,使学习率逐渐减小,一开始“多”学,然后逐渐“少”学。

数学式

神经网络(深度学习)常用的4种最优化方法——SGD、Momentum、AdaGrad、Adam_第3张图片

Python类

class 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的方法。

Python类

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)

四种最优化方法的比较:

1、求 f(x,y) = (1/20)*x^2 + y^2 的最小值

神经网络(深度学习)常用的4种最优化方法——SGD、Momentum、AdaGrad、Adam_第4张图片

2、基于MNIST数据集的更新方法的比较

神经网络(深度学习)常用的4种最优化方法——SGD、Momentum、AdaGrad、Adam_第5张图片

PS:

(目前)并不存在能在所有问题中都表现良好的方法。这4种方法各有各的特点,都有各自擅长解决的问题和不擅长解决的问题。
很多研究中至今仍在使用SGD。 Momentum和AdaGrad也是值得一试的方法。最近,很多研究人员和技术人员都喜欢用Adam。

你可能感兴趣的:(深度学习)