我目前正在研究光譜梯度法。現在我開發了兩種類似的演算法,但顯然,當我認為它們產生相同的結果時,它們實際上在一些迭代后回傳不同的值。
這是變數
v (vector at kth iteration)
v_1 (vector at k 1th iteration)
g (gradient at kth iteration)
g_1 (gradient at k 1th iteration)
第一種演算法如下:
def spectral_grad1(
v: np.ndarray, v_1: np.ndarray,
g: np.ndarray, g_1: np.ndarray
) -> np.ndarray:
s = v_1 - v
y = g_1 - g
sT_y = s.T@y
sT_s = s.T@s
if s.T_s > s.T_y:
s1 = s**4
s2 = s**2
w_k = (sT_s - sT_y) / s1.sum()
B_k = np.array([1. / (1. w_k*i) for i in s2])
return np.diag(B_k)
return np.identity(len(s)) #rescaling
direction = np.negative(np.linalg.inv(B) @ g)
另一方面,這是第二種演算法:
def spectral_grad2(
v: np.ndarray, v_1: np.ndarray,
g: np.ndarray, g_1: np.ndarray
) -> np.ndarray:
s = v_1 - v
y = g_1 - g
sT_y = s.T@y
sT_s = s.T@s
if sT_s <= sT_y:
return np.identity(len(v)) # Rescaling
s1 = s**4
s2 = s**2
w_k = (sT_s - sT_y) / s1.sum()
B_k = 1. w_k*s2
return np.diag(B_k) # Diagonal matrix of B
direction = -(B @ g)
如果您查看這兩種演算法,唯一的區別是B_k和 的計算direction。
很抱歉,因為這只是梯度下降演算法的一部分,所以我不能給你太多資料來重現它。我更好奇的是什么讓B_k和direction在兩種演算法中產生不同的結果?
編輯
我希望找到 的倒數B_k。因此,任何有關使用互惠的見解或np.linalg.inv將不勝感激
uj5u.com熱心網友回復:
在其中之一中,您可以有效地使用:
diag([1. / (1. w_k*i) ...])
而在另一個
linalg.inv(diag(1. w_k*s2))
請注意,對角矩陣的理論逆矩陣是倒數對角矩陣。但linalg.inv不知道它的輸入是對角線的,因此產生的數值逆很可能有一些非常小的非零值非對角線。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/441563.html
上一篇:使用操作員模塊傳遞“無”
