http://faculty.bicmr.pku.edu.cn/~wenzw/optbook/pages/stograd/Adam.html
版權宣告
此頁面為《最最佳化:建模、演算法與理論》、《最最佳化計算方法》配套程式碼。 程式碼作者:文再文、劉浩洋、戶將,程式碼整理與頁面製作:楊昊桐。
Adam 演算法
考慮最佳化問題:
minx∈Rnf(x)=1N∑i=1Nfi(x).
Adam 演算法本質上是在 RMSProp 的基礎上增加了動量項,其利用梯度的一階矩記錄動量
Sk=ρ1Sk−1+(1−ρ)gk,
記錄梯度的二階矩(與 RMSProp 相同)
Mk=ρ2Mk−1+(1−ρ)gk⊙gk,
並進行修正: Sk^=Sk1−ρk1
, Mk^=Mk1−ρk2
。 利用修正的一階矩作為下降方向,並且利用修正的二階矩來逐分量調整步長,其迭代格式為
xk+1=xk−αMk+ϵ1n−−−−−−−−√⊙Sk.
目錄
初始化和迭代準備
迭代主迴圈
參考頁面
版權宣告
初始化和迭代準備
輸入資訊:迭代初始值 x0 ,資料集大小 N ,樣本梯度計算函式 pgfun,目標函式值與梯度計算函式 fun 以及提供演算法引數的結構體 opts 。
輸出資訊:迭代得到的解 x 和包含迭代資訊的結構體 out 。
out.fvec :迭代過程中的目標函式值資訊
out.nrmG :迭代過程中的梯度範數資訊
out.epoch :迭代過程中的時期 (epoch)資訊
function [x,out] = Adam(x0,N,pgfun,fun,opts)
從輸入的結構體 opts 中讀取引數或採取預設引數。
opts.maxit :最大迭代次數
opts.alpha :步長
outs.thres :保證梯度分量累計嚴格為正的小量
opts.rho1 :一階矩累計的權重值
opts.rho2 :二階矩累計的權重值
opts.batchsize :隨機演算法的批次大小
opts.verbose :不小於 1 時輸出每步迭代資訊,否則不輸出
if ~isfield(opts, 'maxit'); opts.maxit = 5000; end
if ~isfield(opts, 'alpha'); opts.alpha = 1e-3; end
if ~isfield(opts, 'thres'); opts.thres = 1e-7; end
if ~isfield(opts, 'rho1'); opts.rho1 = 0.9; end
if ~isfield(opts, 'rho2'); opts.rho2 = 0.999; end
if ~isfield(opts, 'batchsize'); opts.batchsize = 10; end
if ~isfield(opts, 'verbose'); opts.verbose = 1; end
以 x0 為迭代初始點。 計算初始點處的目標函式值和梯度,記初始時刻時期 (epoch) 為 0。
x = x0;
out = struct();
[f,g] = fun(x);
out.fvec = f;
out.nrmG = norm(g,2);
out.epoch = 0;
gsum 記錄一階矩,|ssum| 記錄二階矩。\(\rho_1\), ρ2
分別為一階矩和二階矩的衰減率。 count 用於計算時期(epoch)。
gsum = zeros(size(x));
ssum = gsum;
rho1 = opts.rho1;
rho2 = opts.rho2;
count = 1;
迭代主迴圈
Adam 的迭代迴圈,以 opts.maxit 為最大迭代次數。
for k = 1:opts.maxit
等機率地從 {1,2,…,N}
中選取批次 sk
記錄在 idx 之中,批次大小為 opts.batchsize 。計算對應的樣本的梯度。
idx = randi(N,opts.batchsize,1);
g = pgfun(x,idx);
更新一階、二階矩累計,並進行修正。 利用修正的一階矩和二階矩對 x
進行更新。
ssum = rho1*ssum + (1 - rho1)*g;
gsum = rho2*gsum + (1 - rho2)*(g.*g);
ssum_mod = ssum/(1 - rho1^k);
gsum_mod = gsum/(1 - rho2^k);
x = x - opts.alpha./sqrt(gsum_mod + opts.thres).*ssum_mod;
每當參與迭代的總樣本次數超過資料集的總樣本時,記為一個時期 (epoch)。每一個時期, 記錄當前的目標函式值和梯度範數,並令時期計數加一。
if k*opts.batchsize/N >= count
[f,g] = fun(x);
out.fvec = [out.fvec; f];
out.nrmG = [out.nrmG; norm(g,2)];
out.epoch = [out.epoch; k*opts.batchsize/N];
count = count + 1;
end
end
end
數。
for k = 1:opts.maxit
等機率地從 {1,2,…,N}
中選取批次 sk
記錄在 idx 之中,批次大小為 opts.batchsize 。計算對應的樣本的梯度。
idx = randi(N,opts.batchsize,1);
g = pgfun(x,idx);
更新一階、二階矩累計,並進行修正。 利用修正的一階矩和二階矩對 x
進行更新。
ssum = rho1*ssum + (1 - rho1)*g;
gsum = rho2*gsum + (1 - rho2)*(g.*g);
ssum_mod = ssum/(1 - rho1^k);
gsum_mod = gsum/(1 - rho2^k);
x = x - opts.alpha./sqrt(gsum_mod + opts.thres).*ssum_mod;
每當參與迭代的總樣本次數超過資料集的總樣本時,記為一個時期 (epoch)。每一個時期, 記錄當前的目標函式值和梯度範數,並令時期計數加一。
if k*opts.batchsize/N >= count
[f,g] = fun(x);
out.fvec = [out.fvec; f];
out.nrmG = [out.nrmG; norm(g,2)];
out.epoch = [out.epoch; k*opts.batchsize/N];
count = count + 1;
end
end
end
參考頁面
在頁面 例項:利用隨機演算法求解邏輯迴歸問題 中, 我們展示了該演算法的一個應用,並且與其它隨機演算法進行比較。
其它隨機演算法參見: 隨機梯度下降法、 AdaGrad、 RMSProp、 AdaDelta。
此頁面的原始碼請見: Adam.m。
版權宣告
此頁面為《最最佳化:建模、演算法與理論》、《最最佳化計算方法》配套程式碼。 程式碼作者:文再文、劉浩洋、戶將,程式碼整理與頁面製作:楊昊桐。
著作權所有 (C) 2020 文再文、劉浩洋、戶將