You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Cos激活函数训练神经网络拟合Cos函数时误差先降后升的问题排查及正确拟合方法咨询

解决你的Cos函数拟合问题:代码错误分析与修复方案

嘿,我仔细看了你的代码和训练日志,发现问题主要出在激活函数的导数计算错误,还有学习率设置可能导致的震荡问题。咱们来逐一解决:

核心错误:Cos激活函数的导数计算完全错了

你在中间层反向传播里写的是:

delta = grad_y * np.sin(self.y) # Differentiation of the cos function

但这里犯了两个关键错误:

  1. Cos函数的导数是**-sin(u)**,其中u是中间层的加权输入(也就是np.dot(x, self.w) + self.b),而不是sin(self.y)——你把激活后的输出y=cos(u)当成了u来用,这完全混淆了计算对象。
  2. 导数的符号是负的,你漏掉了负号,这会导致梯度更新方向完全错误,后期训练自然会崩盘。

而且你在正向传播时没有保存u的值,所以没法直接计算sin(u),得先修正正向传播的代码。

具体修复步骤

1. 先在中间层正向传播里保存加权输入u

修改MiddleLayerforward方法,把u存下来供反向传播使用:

def forward(self, x): # Forward propagation
    self.x = x
    u = np.dot(x, self.w) + self.b
    self.u = u  # 保存加权输入u,后面反向传播要用
    self.y = np.cos(u) # Cos激活函数

2. 修正反向传播的导数计算

backward里的delta计算改成正确的形式:

delta = grad_y * (-np.sin(self.u)) # 正确的Cos导数:dy/du = -sin(u)

3. 调整学习率,避免训练后期震荡

你用的eta=0.1在训练前期可能没问题,但后期模型接近最优解时,这么大的学习率会导致模型在最优值附近来回跳跃,误差就会出现回升。可以试试两种方案:

  • 直接把初始学习率降到0.01
  • 或者加个学习率衰减机制,比如每训练5000轮就把学习率乘以0.9,示例代码如下:
# 在训练循环里添加这段逻辑
if i % 5000 == 0 and i != 0:
    eta *= 0.9
    print(f"更新学习率为: {eta:.4f}")

4. 可选:增加中间层神经元数量

当前中间层只有3个神经元,理论上能拟合cos函数,但多给几个(比如5-10个)能让模型更容易捕捉周期性特征,收敛速度更快。

修复后的关键代码片段

# -- 修正后的中间层 --
class MiddleLayer:
    def __init__(self, n_upper, n): # 初始化
        self.w = wb_width * np.random.randn(n_upper, n) # 权重矩阵
        self.b = wb_width * np.random.randn(n) # 偏置向量
    def forward(self, x): # 正向传播
        self.x = x
        u = np.dot(x, self.w) + self.b
        self.u = u  # 新增:保存加权输入u
        self.y = np.cos(u) # Cos激活函数
    def backward(self, grad_y): # 反向传播
        delta = grad_y * (-np.sin(self.u)) # 修正后的导数计算
        self.grad_w = np.dot(self.x.T, delta)
        self.grad_b = np.sum(delta, axis=0)
        self.grad_x = np.dot(delta, self.w.T)
    def update(self, eta): # 更新权重和偏置
        self.w -= eta * self.grad_w
        self.b -= eta * self.grad_b

额外小建议

  • 你现在用误差均值(total_error / n_data)来监控训练状态是对的,比总和更直观。
  • 训练时可以把误差曲线画出来,能更清楚看到收敛趋势,方便调整超参数。

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

火山引擎 最新活动