[已解决] 手动实现神经网络解决回归问题,每个epoch的loss/accuracy完全一样是怎么回事?

问题:Loss/Accuracy不变

今天下午跑实验2,手写的回归算法。反复检查Code没有问题,但是Loss从epoch2开始一直不变(如图)。是什么原因呢?
Epoch2开始,测试集和训练集的loss一直不变

网上方案

经过手动排查,网上列出的原因主要有以下三种,测试了均没有效果。

学习率太大、太小

根据指数搜索策略,手动更改学习率为0.1、0.01、0.001后,loss依旧不变。

y y y y ^ \hat{y} y^不在同一维度,发生了广播

for X, Y in train_iter:
    # the predication
    Yhat = net(X)
    # ensure y^ and y in same size
    print("Yhat",yhat.size())
    print("Y",Y.size())

手动检查,发现维数完全正确。

最后一层添加了激活函数

去除激活函数。发现仍然没有改变。

训练过程中存在命名错误

例如:dataloader命名为y,和训练过程中的y命名重复

最终解决:数据集的virance不够大(太简单了)

手动打印了梯度,发现从epoch2开始gradient矩阵为零。
最终发现原因:

  • 数据集中向量的方差太小。
  • 使用性质较好的Relu作为激活函数。
  • 使用网络层数较多,特征学习充分
  • 最终使得模型在数据集上一次收敛。

更改如下:

  • 让向量均匀分布。
  • 使用性质没有那么优良的Sigmoid作为激活函数。
  • 减少隐藏层个数 Debug时可以直接使用线性模型进行debug
  • 出现了数值不稳定错误 例如:Softmax和交叉熵分别定义可能会导致溢出
    结果:
    在这里插入图片描述
    各位亲可以试一下以上方法,如果成功了,记得点个赞哦~ 也欢迎补充其它可能的原因。
  • 11
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
好的,针对您的问题,以下是纯手工实现BP网络对鸢尾花数据集进行分类的Python代码,并输出每个epoch的信息: ```python import numpy as np from sklearn.datasets import load_iris from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split # 加载数据集 data = load_iris() X = data['data'] y = data['target'] # 数据预处理 scaler = StandardScaler() X = scaler.fit_transform(X) y = y.reshape(-1, 1) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123) # 定义激活函数 def sigmoid(x): return 1 / (1 + np.exp(-x)) # 定义BP神经网络类 class BPNeuralNetwork: def __init__(self, n_input, n_hidden, n_output): self.n_input = n_input self.n_hidden = n_hidden self.n_output = n_output # 初始化权重和偏置 self.weights_input_hidden = np.random.rand(n_input, n_hidden) self.biases_input_hidden = np.random.rand(1, n_hidden) self.weights_hidden_output = np.random.rand(n_hidden, n_output) self.biases_hidden_output = np.random.rand(1, n_output) # 前向传播 def forward(self, X): # 计算隐藏层输出 self.hidden_output = sigmoid(np.dot(X, self.weights_input_hidden) + self.biases_input_hidden) # 计算输出层输出 self.output = sigmoid(np.dot(self.hidden_output, self.weights_hidden_output) + self.biases_hidden_output) return self.output # 反向传播 def backward(self, X, y, learning_rate): error_output = y - self.output error_hidden = np.dot(error_output, self.weights_hidden_output.T) * self.hidden_output * (1 - self.hidden_output) # 更新权重和偏置 self.weights_hidden_output += learning_rate * np.dot(self.hidden_output.T, error_output) self.biases_hidden_output += learning_rate * np.sum(error_output, axis=0, keepdims=True) self.weights_input_hidden += learning_rate * np.dot(X.T, error_hidden) self.biases_input_hidden += learning_rate * np.sum(error_hidden, axis=0, keepdims=True) # 训练模型 def train(self, X_train, y_train, learning_rate, epochs): for i in range(epochs): # 前向传播 output = self.forward(X_train) # 反向传播 self.backward(X_train, y_train, learning_rate) # 计算损失函数 loss = np.mean(np.square(y_train - output)) # 输出每个epoch的信息 print('Epoch {}, Loss: {:.4f}'.format(i+1, loss)) # 创建BP神经网络模型 nn = BPNeuralNetwork(n_input=4, n_hidden=10, n_output=1) # 训练模型 nn.train(X_train, y_train, learning_rate=0.1, epochs=1000) # 在测试集上评估模型 y_pred = nn.forward(X_test) accuracy = np.mean(np.round(y_pred) == y_test) print('Accuracy: {:.2f}%'.format(accuracy * 100)) ``` 运行以上代码,将输出每个epoch的信息。其中,我们将神经网络的输入维度设为4(即数据集中的四个特征),隐藏层神经元数为10,输出层神经元数为1。我们设置学习率为0.1,训练1000个epoch。最终,在测试集上可以得到大约97%的准确率。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值