python - 使用自定义损失函数拟合不同程度的多项式
问题描述
我正在尝试将不同程度的多项式函数拟合到我生成的一些数据中,并且我在没有库的情况下进行梯度下降。我还使用了一个自定义损失函数,我手动计算了梯度(希望它是正确的)。问题是我得到无穷大和 nan 的平方残差的平均值,我不知道我做错了什么。请帮我。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
#y(x) = sin(x) + noise
def F(x_in_rad):
return np.sin(x_in_rad) + noise*np.random.normal(0,1,N)
noise = 0.5
N = 50
#X - N datapoints in radians
X = np.deg2rad(np.random.normal(0,1,N) * 359)
Y = F(X)
X = np.atleast_2d(X).T
Y = np.atleast_2d(Y).T
#split data
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.33, random_state=42)
#mean of the squared residuals
def sq_res_mean(Y_pred,Y_real):
return np.mean((Y_pred - Y_real)**2)
#create design matrix
def designmatpoly(X,degree):
X = X[:,0]
eye = np.ones(X.shape)
rows = []
rows.append(eye)
for i in range(1,degree+1):
rows.append(X**i)
return np.stack(rows).T
#L2 norm squared; gradient = 2w
def C(w):
return np.sum(w**2)
def gradientdescent(Amat, y, rate, numiter, lam, deg):
n, p = Amat.shape
whistory = []
w_analytical = np.dot((np.dot(Amat.T,Amat) + lam*np.eye(deg+1, dtype=int))**(-1),np.dot(Amat.T,Y_train))
losshistory = []
#random weights initialized
w = np.atleast_2d(np.random.randn(deg+1)).T
for i in range(numiter):
loss = np.square(y - w[0] - np.dot(Amat, w)) + lam*C(w_analytical)
whistory.append(w)
losshistory.append(loss)
grad = np.dot(-2*Amat.T, y - w[0] - Amat.dot(w)) + lam*2*w_analytical
w = w - rate*grad
return w, np.asarray(whistory), np.asarray(losshistory)
def model(degree,rate=0.0001, num_iters = 50, lam = 0.5):
A_test = designmatpoly(X_test,degree)
A_train = designmatpoly(X_train,degree)
wfin, whist, meanlosstrace = gradientdescent(A_train, Y_train, rate, num_iters, lam, degree)
return wfin, A_test
degrees = []
sq_res_means = []
for i in range(1,10):
wfin, A_test = model(degree=i)
degrees.append(i)
Y_pred = np.dot(A_test,wfin)
sqrm = sq_res_mean(Y_pred,Y_test)
sq_res_means.append(sqrm)
print("deg",i,"sq_res_mean",sqrm)
解决方案
我不确定,考虑到所有带有稀疏变量名称的数字,但数值问题是,在线性以上的任何程度上,您的w
向量都会以指数方式失控,直到溢出;这就是为什么你得到NaN
价值观。
w
从功能上讲,您计算的梯度与您的向量不成比例;即使学习率很低,也足以w
在短时间内推动分歧。 rate*grad
还是比w
自己大。
我建议您将矩阵初始化为具有已知解决方案的简单系统,并在 deg=2 时观察前 2 或 3 次迭代,看看计算结果与您的预期有何不同。
推荐阅读
- c - 邮递员从 api 获取数据,但 .net core 2.2 应用程序没有
- sql - Apache Impala 的迭代函数
- python - 根据下表中变量a和b的内容编写伪代码打印消息
- flutter - `未来
` 不是 `Stream` 类型的子类型 - ios - Multipeer Connectivity 如何获取广告对等点的名称?
- javascript - 如何在 CSS 中仅使用百分比创建圆形图像?
- ios - iOS Swift 复合谓词
- react-redux - Redux with Prompt:可用的库还是手动收听?
- angular - 带有 PKCE 的 OpenID Connect 代码流仅返回子声明
- batch-file - 如何修复出现在我的批处理代码(过滤程序)上的错误?