如何在自定义小批量梯度下降(MBGD)实现中添加正则化?
给小批量梯度下降(MBGD)添加正则化的实现方案
你的代码已经有了正则化的雏形(40 * w[dim] 这部分),但需要改成可配置的通用实现。sklearn的preprocessing只是数据预处理工具,本来就不负责模型的正则化逻辑,正则化需要在梯度计算阶段嵌入,以下是具体实现:
核心思路
正则化是在损失函数中加入权重惩罚项,对应到梯度计算时,需要给权重的梯度加上惩罚项的导数:
- L2正则化(岭回归):损失加
(λ/2) * ||w||²,梯度惩罚项为λ * w[dim] - L1正则化(Lasso):损失加
λ * ||w||₁,梯度惩罚项为λ * np.sign(w[dim]) - 注意:偏置项(最后一维的权重,也就是你代码里的
X.shape[1]-1对应的维度)不需要加正则化
修改后的完整代码
import numpy as np def gradient(X, y, w, batch, alpha, reg_type='l2', reg_lambda=0.01): gradients = [] y_pred = np.dot(X[batch], w) # MSE损失的梯度基础项 error = np.mean((y_pred - y[batch]) * 2) for dim in range(X.shape[1]): base_grad = error * np.mean(X[batch, dim]) # 偏置项不加正则化 if dim == X.shape[1] - 1: gradients.append(base_grad) else: # 根据正则化类型添加惩罚项 if reg_type == 'l2': reg_term = reg_lambda * w[dim] elif reg_type == 'l1': reg_term = reg_lambda * np.sign(w[dim]) else: # 无正则化 reg_term = 0 gradients.append(base_grad + reg_term) return w - alpha * np.array(gradients) def MBGD(X, y, batch_size=64, n_iter=10000, alpha=1e-8, reg_type='l2', reg_lambda=0.01): i = 0 # 添加偏置项列 X = np.column_stack((X, np.ones(len(X)))) w = np.ones(X.shape[1]) while i < n_iter: # 生成随机批量索引 batch = np.random.randint(0, X.shape[0], batch_size) # 保留原学习率衰减逻辑 lr = (1/(i+1)) * alpha / np.sqrt(i + 1) w = gradient(X, y, w, batch, lr, reg_type, reg_lambda) i += 1 return w
关键修改说明
- 新增正则化参数:
gradient和MBGD函数都加入了reg_type(指定正则化类型)和reg_lambda(正则化系数),默认用L2正则化,系数0.01 - 明确梯度计算逻辑:把原代码里的固定40改成可配置的
reg_lambda,并支持L1/L2两种常用正则化 - 优化代码可读性:单独计算预测值
y_pred,拆分基础梯度和正则化惩罚项 - 修正小细节:把
[1]*len(X)改成np.ones(len(X)),更符合numpy的用法
使用示例
# 假设X是特征矩阵,y是标签 # 使用L2正则化,系数0.1 w_l2 = MBGD(X, y, reg_type='l2', reg_lambda=0.1) # 使用L1正则化,系数0.001 w_l1 = MBGD(X, y, reg_type='l1', reg_lambda=0.001) # 不使用正则化 w_no_reg = MBGD(X, y, reg_type='none')
内容的提问来源于stack exchange,提问作者villerpa
相关产品推荐
相关产品推荐

