我从一篇论文中得到了一个目标函数,我想用梯度下降来最小化它。我还没有"从头开始"做这件事,我想得到一些关于如何手动编码的建议。目标函数是:
T(L(=tr(X.T L^s X(-β*||L||。
其中,L是要估计的N×N矩阵正半定矩阵,x是N×M矩阵,β是正则化常数,x.T=x转置,并且||.||是弗罗贝尼乌斯规范。
此外,L^s是矩阵指数,其中L^s=F∧^s F.T,其中F是L的特征向量的矩阵,∧是L的本征值的对角矩阵。
目标函数的导数为:
dT/dL=sum_{从r=0到r=s-1}L^r(XX.T(L^(s-r-1(-2*β*L
我已经做了非常基本的梯度下降问题(如矩阵分解(,其中对矩阵的每个元素进行优化,或者使用包/库。这种问题比我习惯的更复杂,我希望你们中对这类事情更有经验的人能帮助我。
任何一般性的建议以及如何在python或R.中进行编码的具体建议都将不胜感激
以下是具有此功能的论文的链接:https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0128136#sec016
非常感谢你的帮助!
Paul
通常,最好使用机器学习库,如tensorflow或pytorch。如果你走这条路,你有几个优势1(张量运算的高效C++实现2(自动微分3(容易访问更复杂的优化器(例如ADAM(。`如果你更喜欢自己进行梯度计算,你可以在优化步骤之前手动设置梯度L.grad
一个简单的实现如下所示:
import torch
n=10
m=20
s = 3
b=1e-3
n_it=40
# L=torch.nn.Parameter(torch.rand(n,n))
F=torch.nn.Parameter(torch.rand(n,n))
D=torch.nn.Parameter(torch.rand(n))
X=torch.rand((n,m))
opt=torch.optim.SGD([F,D],lr=1e-4)
for i in range(n_it):
loss = (X.T.matmul(F.matmul((D**s).unsqueeze(1)*F.T)).matmul(X)).trace() - b * F.matmul((D**s).unsqueeze(1)*F.T).norm(2)
print(loss)
opt.zero_grad()
loss.backward()
opt.step()