调参

参数更新

神经网络的学习目的是找到使损失函数尽可能小的参数,即解决一个最优化问题.但是由于神经网络参数空间过于复杂,很难通过数学式求解的方式解决这个最优化问题.

SGD

将参数的梯度作为线索,沿梯度的反方向更新参数,重复这个步骤多次从而靠近最优参数,这个方式称为随机梯度下降(SGD)

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]
# 参数更新过程伪代码
network = neural network(...)
optimizer = SGD()
for i in range(10000):
    ...
    x_batch, t_batch = get_mini_batch(...) # mini-batch
    grads = network.gradient(x_batch, t_batch)
    params = network.params
    optimizer.update(params, grads)
    ...

SGD低效的原因:梯度的方向并不一定指向最小值的方向,更新参数寻找最优解的过程会变得非常"曲折"

Momentum

v\leftarrow \alpha v - \eta \frac{\partial L}{\partial W} \\ W \leftarrow W + v
这里v代表物理学上的速度,\alpha表示动量参数,\alpha越小阻力越大,学习率\eta表示重力系数
这个算法可以理解成质点在有阻力的曲面上(阻力大小正比于速度大小)受到重力影响运动的过程.

class Momentum:
    def __init__(self, alpha=0.9, eta = 1e-2):
        self.alpha = alpha
        self.eta = eta
        self.v = None
    def update(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.alpha * self.v[key] - self.eta * grads[key]
            params[key] += self.v[key]

AdaGrad

(Ada表示Adaptive)
AdaGrad方法是一种学习率衰减(learning rate decay)方法,随着学习的进行,学习率会逐渐减小,而AdaGrad则进一步发展了这种思想,参数空间的不同维度使用递减速度不同的学习率.
h \leftarrow h + \frac{\partial L}{\partial W} ⊙ \frac{\partial L}{\partial W} \\ W \leftarrow W - \eta \frac{1}{\sqrt{h}} \frac{\partial L}{\partial W} \\ 其中⊙表示矩阵对应元素乘法

class AdaGrad:
     def __init__(self, lr= 1e-2):
        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(params[key])
        epsilon = 1e-7
        for key in params.items():
            self.h[key] += grads[key] * grads[key]
            params[key] += - self.lr  * grads[key] / (np.sqrt(self.h[key]) +epsilon)

Adam

Adam是一种结合了AdaGrad和Momentum的学习方法.
t \leftarrow t+1\\ lr_t \leftarrow \frac{lr * \sqrt{1-\beta_2^t}}{1-\beta_1^t} \\ m \leftarrow m + (1-\beta_1)·(\frac{\partial L}{\partial W} - m) \\ v \leftarrow v + (1-\beta_2)·(\frac{\partial L}{\partial W} ⊙ \frac{\partial L}{\partial W} - v) \\ \theta = \theta - lr_t·\frac{m}{\sqrt{v}+\epsilon} \\ 其中:t为迭代次数,,L为损失函数,W为需要学习的参数\\ 超参数一般取值:学习率lr一般取10^{-3},\epsilon 取一个很小的数(一般是10^{-7}),\beta_1取0.9,\beta_2取0.999

class Adam(GradientDescent):
    epsilon = 1e-7

    def __init__(self, lr=1e-3, beta1=0.9, beta2=0.999):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.m = None
        self.v = None
        self.iter = 0

    def update(self, grads, params):
        if self.m is None or self.v is None:
            self.m = {}
            self.v = {}
            for key, value in params.items():
                self.m[key] = np.zeros_like(value,dtype='float')
                self.v[key] = np.zeros_like(value,dtype='float')
        self.iter += 1
        lr_t = self.lr * np.sqrt(1. - self.beta2 ** self.iter) / (1. - self.beta1 ** self.iter)
        for key in params.keys():
            self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key])
            self.v[key] += (1 - self.beta2) * (grads[key] * grads[key] - self.v[key])
            params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key] + self.epsilon))

初始值的选择

当激活函数使用ReLU函数时,权重初始函数使用He初始值,当激活函数为sigmoid或者tanh等S型函数时,初始值使用Xavier初始值.
He初始值: 标准差为\sqrt{\frac{2}{n}}的高斯分布,其中n为上一层节点数
Xavier初始值:标准差为\sqrt{\frac{1}{n}}的高斯分布,其中n为上一层节点数

Batch Normalization(批标准化)

含有Batch Normalization层的神经网络

正向传播
y = \frac{\gamma}{\sqrt{Var(x)+\epsilon}}(x-E(x))+\beta \\ 其中\mu = \frac{1}{m}\sum_{i=1}^m x_i \\ \sigma^2 =\frac{1}{m}\sum_{i=1}^m (x_i - \mu)^2 \\ \hat{x_i} = \frac{x_i-\mu}{\sqrt{\sigma^2+\epsilon}} \\ E(x) =\mu \\ Var(x)=\frac{m}{m-1}E(\sigma^2)

反向传播
\frac{\partial l}{\partial \mu} = -\sum_{i=1}^m I_i \\ \frac{\partial l}{\partial x_i} = I_i - \frac{1}{m} \sum_{i=1}^m I_i \\ 其中: I_i = \frac{\partial l}{\partial \hat{x_i}}\frac{1}{\sqrt{\sigma^2+\epsilon}} + \frac{\partial l}{\partial \mu^2}\frac{2(x_i - \mu)}{m}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容