梯度下降法每次迭代后线性回归损失值增加

我在尝试实现多元线性回归(使用梯度下降和均方误差成本函数),但每次梯度下降迭代后损失值都在呈指数级增加,我无法找出原因?

from sklearn.datasets import load_bostonclass LinearRegression:    def __init__(self):        self.X = None  # The feature vectors [shape = (m, n)]        self.y = None  # The regression outputs [shape = (m, 1)]        self.W = None  # The parameter vector `W` [shape = (n, 1)]        self.bias = None  # The bias value `b`        self.lr = None  # Learning Rate `alpha`        self.m = None        self.n = None        self.epochs = None    def fit(self, X: np.ndarray, y: np.ndarray, epochs: int = 100, lr: float = 0.001):        self.X = X  # shape (m, n)        self.m, self.n = X.shape        assert y.size == self.m and y.shape[0] == self.m        self.y = np.reshape(y, (-1, 1))  # shape (m, ) or (m, 1)        assert self.y.shape == (self.m, 1)        self.W = np.random.random((self.n, 1)) * 1e-3  # shape (n, 1)        self.bias = 0.0        self.epochs = epochs        self.lr = lr        self.minimize()    def minimize(self, verbose: bool = True):        for num_epoch in range(self.epochs):            predictions = np.dot(self.X, self.W)            assert predictions.shape == (self.m, 1)            grad_w = (1/self.m) * np.sum((predictions-self.y) * self.X, axis=0)[:, np.newaxis]            self.W = self.W - self.lr * grad_w            assert self.W.shape == grad_w.shape            loss = (1 / 2 * self.m) * np.sum(np.square(predictions - self.y))            if verbose:                print(f'Epoch : {num_epoch+1}/{self.epochs} \t Loss : {loss.item()}')linear_regression = LinearRegression()x_train, y_train = load_boston(return_X_y=True)linear_regression.fit(x_train, y_train, 10)

我使用的是来自sklearn的波士顿房价数据集。

附言:我想知道是什么导致了这个问题,以及如何修复它,我的实现是否正确。

谢谢


回答:

问题出在梯度上。对于迭代收缩阈值算法(ISTA)求解器来说,这种发散是你不应该看到的。对于你的梯度计算:X的形状是(m,n),W的形状是(n,1),所以(prediction – y)的形状是(m,1),然后你用X左乘?(m,1)乘以(m,n)?我不确定numpy在计算什么,但这不是你想要计算的:

grad_w = (1/self.m) * np.sum((predictions-self.y) * self.X, axis=0)[:, np.newaxis]

这里代码应该略有不同,以便得到一个(n,m)乘以一个(m,1),从而得到一个(n,1),与W的形状相同。

(1/self.m) * np.sum(self.X.T*(predictions-self.y) , axis=0)[:, np.newaxis]

为了使推导正确。

我也不确定为什么你在预测时使用点乘(这是一个好主意),但在梯度计算时却没有使用。

你也不需要那么多重塑操作:

from sklearn.datasets import load_bostonA,b = load_boston(return_X_y=True)n_samples = A.shape[0]n_features = A.shape[1]def grad_linreg(x):    """Least-squares gradient"""    grad = (1. / n_samples) * np.dot(A.T, np.dot(A, x) - b)    return graddef loss_linreg(x):    """Least-squares loss"""    f = (1. / (2. * n_samples)) * sum((b - np.dot(A, x)) ** 2)    return f

然后你可以检查你的梯度是否正确:

from scipy.optimize import check_gradfrom numpy.random import randncheck_grad(loss_linreg,grad_linreg,randn(n_features))check_grad(loss_linreg,grad_linreg,randn(n_features))check_grad(loss_linreg,grad_linreg,randn(n_features))check_grad(loss_linreg,grad_linreg,randn(n_features))

然后你可以基于此构建模型。如果你想用ISTA/FISTA和Logistic/Linear Regression以及LASSO/RIDGE来测试,这里有一个包含理论和工作示例的jupyter笔记本

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注