首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

动量法以及优化算法的数学理论和Python实现(1)

SGD在ravines的情况下容易被困住,ravines就是曲面的一个方向比另一个方向更陡,这时SGD会发生震荡而迟迟不能接近极小值:

如下图所示

• 函数主体缓缓向右方下降

• 在主体方向两侧各有一面高墙,导致垂直于主体方向有更大的梯

• 梯度下降法会在隧道两侧频繁震荡

因此我们引入动量法:

动量这个词语来自物理,表示力对时间的累积效应

SGD+动量公式:

v = mu * v - learning_rate * dw

w = w + v

在普通的梯度下降法中,每次的更新量为,其中为目标函数对w的一阶导数。

当使用动量时,则把每次的更新量考虑为本次的梯度下降量与上次w的更新量乘上一个介于的因子的和,即。

其中,v初始化为0,mu是设定的一个超变量,最常见的设定值是0.9

从公式上可看出:

由于动量积攒了历史的梯度,如点P前一刻的梯度与当前的梯度方向几乎相反。因此原本在P点原本要大幅徘徊的梯度,主要受到前一时刻的影响,而导致在当前时刻的梯度幅度减小。

  直观上讲就是,要是当前时刻的梯度与历史时刻梯度方向相似,这种趋势在当前时刻则会加强;要是不同,则当前时刻的梯度方向减弱。

python实现:

def backward(model, xs, hs, errs):

dW2 = hs.T @ errs

dh = errs @ model['W2'].T

dh[hs

dW1 = xs.T @ dh

return dict(W1=dW1, W2=dW2)

def forward(x, model):

h = x @ model['W1']

h[h

prob = softmax(h @ model['W2'])

return h, prob

def get_minibatch_grad(model, X_train, y_train):

xs, hs, errs = [], [], []

for x, cls_idx in zip(X_train, y_train):

h, y_pred = forward(x, model)

y_true = np.zeros(n_class)

y_true[int(cls_idx)] = 1.

err = y_true - y_pred

xs.append(x)

hs.append(h)

errs.append(err)

return backward(model, np.array(xs), np.array(hs), np.array(errs))

def get_minibatch(X, y, minibatch_size):

minibatches = []

X, y = shuffle(X, y)

for i in range(0, X.shape[0], minibatch_size):

X_mini = X[i:i + minibatch_size]

y_mini = y[i:i + minibatch_size]

minibatches.append((X_mini, y_mini))

return minibatches

def sgd(model, X_train, y_train, minibatch_size):

minibatches = get_minibatch(X_train, y_train, minibatch_size)

for iter in range(1, n_iter + 1):

#送入多少批

X_mini, y_mini = minibatches[idx]

grad = get_minibatch_grad(model, X_mini, y_mini)

for layer in grad:

model[layer] += alpha * grad[layer]

return model

def momentum(model, X_train, y_train, minibatch_size):

velocity =

gamma = .9

minibatches = get_minibatch(X_train, y_train, minibatch_size)

for iter in range(1, n_iter + 1):

X_mini, y_mini = minibatches[idx]

grad = get_minibatch_grad(model, X_mini, y_mini)

for layer in grad:

velocity[layer] = gamma * velocity[layer] + alpha * grad[layer]

model[layer] += velocity[layer]

return model

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180304G001YM00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券