You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何限制梯度下降算法迭代过程中生成的权重取值范围?

梯度下降权重范围限制实现方案

是否需要封装为类?

不需要强制封装为类,直接修改现有函数即可快速实现需求。封装为类的优势仅在于方便统一管理超参数、复用训练逻辑,你可以根据自己的使用场景选择实现方式。

方案1:直接修改现有函数(最简实现)

核心逻辑是每次完成权重更新后,添加截断操作,把超出指定范围的权重拉回到边界值。我们可以给原函数加一个可选的范围参数,默认关闭限制,需要时传入指定区间即可:

def predict(row, coef):
    # 原代码配套的预测逻辑,如果你已经实现可以删掉这段
    yhat = coef[0]
    for i in range(len(row)-1):
        yhat += coef[i + 1] * row[i]
    return yhat

def coefficients_sgd(train, l_rate, n_epoch, coef_range=None):
    coef = [0.0 for i in range(len(train[0]))]
    for epoch in range(n_epoch):
        sum_error = 0
        for row in train:
            yhat = predict(row, coef)
            error = yhat - row[-1]
            sum_error += error**2
            # 更新权重
            coef[0] = coef[0] - l_rate * error
            for i in range(len(row)-1):
                coef[i + 1] = coef[i + 1] - l_rate * error * row[i]
            # 逐样本更新后做权重截断(也可以移到epoch结束后统一处理)
            if coef_range is not None:
                min_val, max_val = coef_range
                for j in range(len(coef)):
                    coef[j] = max(min_val, min(coef[j], max_val))
        print('>epoch=%d, lrate=%.3f, error=%.3f' % (epoch, l_rate, sum_error))
    return coef

调用时如果要限制权重在(-1,1)区间,直接传参即可:

coef = coefficients_sgd(train_data, 0.01, 50, coef_range=(-1, 1))

方案2:封装为类(适合高频复用场景)

如果你需要频繁用不同超参数训练、或者要和其他机器学习组件统一调用格式,封装为类使用起来更方便:

class SGDLinearRegressor:
    def __init__(self, l_rate=0.01, n_epoch=50, coef_range=None):
        self.l_rate = l_rate
        self.n_epoch = n_epoch
        self.coef_range = coef_range
        self.coef = None

    def predict(self, row):
        yhat = self.coef[0]
        for i in range(len(row)-1):
            yhat += self.coef[i + 1] * row[i]
        return yhat

    def fit(self, train):
        self.coef = [0.0 for i in range(len(train[0]))]
        for epoch in range(self.n_epoch):
            sum_error = 0
            for row in train:
                yhat = self.predict(row)
                error = yhat - row[-1]
                sum_error += error**2
                # 更新权重
                self.coef[0] = self.coef[0] - self.l_rate * error
                for i in range(len(row)-1):
                    self.coef[i + 1] = self.coef[i + 1] - self.l_rate * error * row[i]
                # 权重截断
                if self.coef_range is not None:
                    min_val, max_val = self.coef_range
                    for j in range(len(self.coef)):
                        self.coef[j] = max(min_val, min(self.coef[j], max_val))
            print('>epoch=%d, lrate=%.3f, error=%.3f' % (epoch, self.l_rate, sum_error))

# 调用示例
model = SGDLinearRegressor(l_rate=0.01, n_epoch=50, coef_range=(-1,1))
model.fit(train_data)
print(model.coef)

注意事项

  • 截断时机可以根据需求调整:逐样本更新后截断精度更高,每个epoch结束后统一截断速度更快,小数据集下二者差异很小
  • 如果发现添加限制后模型收敛速度变慢,可以适当调小学习率,避免每次更新都触碰到权重边界导致更新不充分

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 08:54:07