對於優化問題,可以使用自動微分技術求解,該技術在機器學習中具有廣泛的應用,被用於計算模型變分引數關於損失函式的梯度(程式中自我計算的),稱之為反向傳播演算法(back propagation,bp)
例:利用自動微分求解實對稱矩陣最大本徵向量,即求解如下極大值問題
max ∣
v∣=1
∣vtm
v∣
\max_|v^tmv|
∣v∣=
1max∣
vtmv
∣定義損失函式f=−
vtmv
∣v∣2
f = -\frac
f=−∣v∣
2vtm
v,則上述極大化問題被化為損失函式的極小化問題。
計算v關於的 f
ff 梯度 dfd
v,
\frac,
dvdf,
要使得 f
ff 減小, 需將v沿負梯度方向更新:
v ←v
−ηdf
dv
v \leftarrow v-\eta \frac
v←v−ηd
vdf
其中, η
\eta
η 為人為給定的常數,被稱為更新步長或學習率。
進行多次迭代更新之後,得到收斂的?,則最大本徵向量v
ˇ\check
vˇ與最大本徵值?
滿足:v~=
v∣v∣
,λ=v
~tmv
~\tilde=\frac, \quad \lambda=\tilde^} m \tilde
v~=∣v∣
v,λ
=v~t
mv~
其中,dfd
v\frac
dvdf
梯度可直接使用自動微分技術計算
可使用pytorch實現自動微分
更新過程中,可使用優化器(optimizer,例如adam),讓程式自適應地控制學習率,以達到較好的穩定性和收斂速率。
上述例子太過簡單,其效率顯然不如傳統的本徵值分解演算法。但在更為複雜的問題中,自動微分的優勢就會被體現出來。
import torch as tc
from scipy.sparse.linalg import eigsh
from basicfun import eigs_ad
defeigs_ad
(mat, lr=1e-
2, v0=
none
, it_time=
500, tol=1e-
15):"""
:param mat: 帶分解矩陣
:param lr: 初始學習率
:param v0: 初始向量
:param it_time: 最大迭代次數
:param tol: 收斂閾值
:return lm: 最大本徵值
:return v0: 最大本徵向量
"""# 初始化及預處理v0
if v0 is
none
: v0 = tc.randn(mat.shape[0]
,)v0 /= v0.norm(
) v0.requires_grad =
true
#v0是否請求梯度
# 建立優化器,這裡使用adam優化器,可自動動態控制學習率
optimizer = tc.optim.adam(
[v0]
, lr=lr)
v1 = copy.deepcopy(v0.data)
#判斷收斂性
# 進入主迴圈
for t in
range
(it_time)
:# 計算損失函式
f =-v0.matmul(mat)
.matmul(v0)
/ v0.matmul(v0)
f.backward(
)# 進行反向傳播,計算梯度
optimizer.step(
)# 更新引數
optimizer.zero_grad(
)# 清空梯度
conv = tc.norm(v0.data - v1)
/ v1.numel(
)# 計算收斂性
if conv < tol:
break
else
: v1 = copy.deepcopy(v0.data)
with tc.no_grad():
v0 = v0 / tc.norm(v0)
# 歸一化,計算本徵向量
lm = v0.matmul(mat)
.max()
/ v0.
max(
)# 計算本徵值
return lm, v0
# 自動微分求解實對稱矩陣的本徵值與本徵向量
# 構建隨機實對稱矩陣
dim =
6m = tc.randn(dim, dim)
m = m + m.t(
)print
('利用scipy中的本徵值分解求解最大本徵值與本徵向量'
)lm0, v0 = eigsh(m.numpy(
), k=
1, which=
'la'
)print
('矩陣的最大本徵值為:'
)print
(lm0[0]
)print
('矩陣的最大本徵向量為:'
)print
(v0.reshape(-1
,))print
('\n利用自動微分求解最大本徵值與本徵向量'
)lm1, v1 = eigs_ad(m)
print
('矩陣的最大本徵值為:'
)print
(lm1.item())
print
('矩陣的最大本徵向量為:'
)print
(v1.data.to(
'cpu'
).numpy(
).reshape(-1
,))
總結為三步:
1.把需要變分的引數v0設好,把requires_grad開啟,把需要變分的東西放入優化器中
2.定義損失函式
3.f.backward() # 進行反向傳播,計算梯度
optimizer.step() # 更新引數
optimizer.zero_grad() # 清空梯度
根據最大本徵值問題與基態問題的等價性,顯然,自動微分方法可用於求解多體系統基態,對應的優化問題可寫為:
e
=min⟨
φ∣h^
∣φ⟩⟨
φ∣φ⟩
e=\min _\right\}} \frac| \varphi\rangle}
e=min⟨φ
∣φ⟩⟨
φ∣h∣
φ⟩其中,變分引數為mps中的各個張量
,\left\\right\},
, 梯度更新公式為:
a (n
)←a(
n)−η
∂e∂a
(n
)a^ \leftarrow a^-\eta \frac}
a(n)←a
(n)−
η∂a(
n)∂e
相比於dmrg中mps的「重整化群」解釋,這裡可以更加直接地將mps看作
是對基態的一種特殊的引數化形式,能量即為變分的損失函式。
可使用bp演算法及各種優化器進行梯度更新。
第八節為前面的知識總結
Autograd 自動微分
1 深度學習的演算法本質上是通過反向傳播求導數,pytorch的autograd模組實現了此功能 在tensor上的所有操作,autograd都能為他們自動提供微分,避免手動計算導數的複雜過程。2 autograd.variable是autograd中的核心類,它簡單的封裝了tensor,並支援幾乎...
自動微分方法簡介
假設我們定義了乙個方程 f x,y x2y y 2 f x y x2y y 2,我們需要對 x x 和 y role presentation style position relative y y求偏導,此時通常由以下幾種做法 拿起紙筆應用鏈式法則逐層求導即可。缺點是易於出錯。下圖是符號微分方法在...
MindSpore多元自動微分
當前主流的深度學習框架,除了能夠便捷高效的搭建機器學習的模型之外,其自動並行和自動微分等功能還為其他領域的科學計算帶來了模式的變革。本文我們將探索如何用mindspore去實現乙個多維的自動微分,並且得到該多元函式的雅可比矩陣。首先我們給定乙個比較簡單的z關於自變數x的函式形式 其中y和i是一些引數...