我曾经在python中使用ML包进行线性回归,但为了自我满足,我从头开始编码。损失从0.90左右开始并且由于某种原因不断增加(不学习)。我不明白我可能犯了什么错误。
import preprocess as pre
import numpy as np
import matplotlib.pyplot as plt
data = pre.load_file('airfoil_self_noise.dat')
data = pre.organise(data,"\t","\r\n")
data = pre.standardise(data,data.shape[1])
t = np.reshape(data[:,5],[-1,1])
data = data[:,:5]
N = data.shape[0]
M = 5
lr = 1e-3
# W = np.random.random([M,1])
W = np.dot(np.dot(np.linalg.inv(np.dot(data.T,data)),data.T),t)
data = data.T # Examples are arranged in columns [features,N]
b = np.random.rand()
epochs = 1000000
loss = np.zeros([epochs])
for epoch in range(epochs):
if epoch%1000 == 0:
lr /= 10
# Obtain the output
y = np.dot(W.T,data).T + b
sse = np.dot((t-y).T,(t-y))
loss[epoch]= sse/N
var = sse/N
# log likelihood
ll = (-N/2)*(np.log(2*np.pi))-(N*np.log(np.sqrt(var)))-(sse/(2*var))
# Gradient Descent
W_grad = np.zeros([M,1])
B_grad = 0
for i in range(N):
err = (t[i]-y[i])
W_grad += err * np.reshape(data[:,i],[-1,1])
B_grad += err
W_grad /= N
B_grad /= N
W += lr * W_grad
b += lr * B_grad
print("Epoch: %d, Loss: %.3f, Log-Likelihood: %.3f"%(epoch,loss[epoch],ll))
plt.figure()
plt.plot(range(epochs),loss,'-r')
plt.show()
现在,如果你运行上面的代码,你可能不会发现任何错误,因为我正在做W += lr * W_grad
而不是W -= lr * W_grad
。我想知道为什么会这样,因为它是从旧的权重矩阵中减去梯度的梯度下降公式。当我这样做时,错误不断增加。我错过了什么?
答案 0 :(得分:0)
找到它。问题是我从一张显然不正确的幻灯片中获取了丢失函数的梯度(至少它并非完全错误,而是它已经指向最陡的下降),当我从重量中减去时它开始指向最大的增长方向。这就是我所观察到的结果。
我做了损失函数的偏导数来澄清,得到了这个:
W_grad += data[:,i].reshape([-1,1])*(y[i]-t[i]).reshape([])
这指向了最大增长的方向,当我将它与-lr
相乘时,它开始指向最陡的下降,并开始正常工作。