关于在训练神经网络模型时导入负样本后发现无法计算loss的问题


开始之前的小感慨 :(
在训练神经网络模型时,发现导入了负样本之后没办法计算loss,在这个问题上花了整整两天时间,晚上淋了一场雨,满满的伤心,回来咬咬牙继续硬刚,终于发现问题出现再哪了,检查问题的过程非常耗时耗精神。


先上图,出现的问题如下:
loss
就如图中显示的loss:nan,看到这个nan就觉得恶心,刚了两天,其实就是一个小问题,主要是一开始没有方向性,在代码里各种检测,花费了大量时间,希望给其他可能会遇到类似问题的人提供一些思路,特别希望大家不会遇到这种坑 TAT

首先说一下,怎么分析出来是负样本问题的,一开始我并不知道是负样本出了问题,后来一步步检查才发现的,如果想直接知道怎么解决,翻到最下面即可。

思路:

  1. 首先,数据是成功导入的,可以训练的,这就说明导入数据格式没有问题,确定这一点也花了不少功夫,一直在检查是不是导入的数据集里有很多空集或0,因为数据集比较大,加上负样本,有三百万组数据,所以一开始以为是空集和0特征向量造成的,后来检查发现,并不是,数据集都是没有问题的。
  2. 数据处理部分的逻辑关系,这个反反复复修改了很多个版本,当然也发现了之前代码的一些错误,但并不是关键原因,这个就比较扎心了,每次发现问题之后的期待,重新跑模型依然发现还是loss没办法计算。在这一部分关注的焦点是label,其实已经很接近真相了,只是我的关注重点是产生的label是不是有空集的情况,最后发现,也不是逻辑关系,产生的label ”没问题“。但到这一步就更扎心了,label是最容易出问题的一个地方,居然不是label的问题,那路在何方? ?
  3. 最后,终于发现问题了,因为之前没有加入负样本来跑是可以的,不断思考中发现,没有包含负样本的神经网络模型输出是5635个单元的softmax分类问题,实际label的数量是5634,我现在加入了负样本的神经网络模型,把负样本全部标记为label=5635,因为是在Keras里使用loss='sparse_categorical_crossentropy'计算损失函数,没有注意到label溢出的问题,如果是使用loss='categorical_crossentropy',需要自己加上代码转换为one-hot vector这时应该就会发现问题的,所以,最终只要将负样本的label改成等于0或将输出层的单元数改成5636就可以了,如下:
    output = Dense(5636,activation='softmax')(Drop_1) #output

好了,吐槽了一堆,希望大家不要犯这种小错误,检查过程真心痛苦,各种怀疑人生,也希望这些经验能给大家一些参考。

多多交流 ,互相学习。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以回答这个问题。 建立并训练BP神经网络模型,实现鸢尾花分类,需要以下步骤: 1. 数据预处理:将鸢尾花数据集(Iris)导入程序中,随机打乱数据集,并将数据集分为训练集和测试集。同,对数据进行归一化处理。 2. 网络结构设计:选择合适的网络结构,一般建议使用三层网络结构:输入层、隐藏层和输出层。输入层节点数为4(数据集中有4个特征),隐藏层节点数可以根据实际情况进行调整,输出层节点数为3(数据集中有3个类别)。 3. 初始化网络参数:随机初始化网络中的权重和偏置。 4. 前向传播:使用当前的权重和偏置,计算出每个样本的输出值。 5. 计算损失函数:使用交叉熵损失函数计算当前模型的损失值。 6. 反向传播:根据损失值,计算出每个权重和偏置的梯度,并更新网络参数。 7. 训练模型:重复执行以上步骤,直到模型收敛或达到预定的训练次数。 8. 测试模型:使用测试集验证模型的准确率。 9. 使用模型进行预测:输入新的鸢尾花数据,使用训练好的模型进行分类预测。 关于接口设计和相应代码,您可以参考以下代码: ```python import numpy as np from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split # 数据预处理 iris = load_iris() X = iris.data y = iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) X_train = (X_train - np.mean(X_train, axis=0)) / np.std(X_train, axis=0) X_test = (X_test - np.mean(X_test, axis=0)) / np.std(X_test, axis=0) # 网络结构设计 input_size = 4 hidden_size = 12 output_size = 3 # 初始化网络参数 w1 = np.random.randn(input_size, hidden_size) b1 = np.zeros(hidden_size) w2 = np.random.randn(hidden_size, output_size) b2 = np.zeros(output_size) # 定义激活函数 def sigmoid(x): return 1 / (1 + np.exp(-x)) # 定义损失函数 def cross_entropy_loss(y_pred, y_true): loss = -np.sum(y_true * np.log(y_pred)) return loss # 定义前向传播函数 def forward(x): z1 = np.dot(x, w1) + b1 a1 = sigmoid(z1) z2 = np.dot(a1, w2) + b2 y_pred = np.exp(z2) / np.sum(np.exp(z2), axis=1, keepdims=True) return y_pred, a1 # 定义反向传播函数 def backward(x, y_true, y_pred, a1): delta2 = y_pred - y_true delta1 = np.dot(delta2, w2.T) * a1 * (1 - a1) dw2 = np.dot(a1.T, delta2) db2 = np.sum(delta2, axis=0) dw1 = np.dot(x.T, delta1) db1 = np.sum(delta1, axis=0) return dw1, db1, dw2, db2 # 定义训练函数 def train(X, y, learning_rate, num_epochs): for epoch in range(num_epochs): # 前向传播 y_pred, a1 = forward(X) # 计算损失函数 loss = cross_entropy_loss(y_pred, y) # 反向传播 dw1, db1, dw2, db2 = backward(X, y, y_pred, a1) w1 -= learning_rate * dw1 b1 -= learning_rate * db1 w2 -= learning_rate * dw2 b2 -= learning_rate * db2 # 打印损失值 if epoch % 100 == 0: print('Epoch %d | Loss: %.4f' % (epoch, loss)) # 定义测试函数 def test(X_test, y_test): y_pred, _ = forward(X_test) correct = np.sum(np.argmax(y_pred, axis=1) == y_test) total = len(y_test) accuracy = correct / total print('Accuracy: %.2f%%' % (accuracy * 100)) # 定义预测函数 def predict(X_new): X_new = (X_new - np.mean(X_train, axis=0)) / np.std(X_train, axis=0) y_pred, _ = forward(X_new) class_idx = np.argmax(y_pred, axis=1) class_names = iris.target_names return class_names[class_idx[0]] # 训练模型 train(X_train, np.eye(output_size)[y_train], learning_rate=0.1, num_epochs=1000) # 测试模型 test(X_test, y_test) # 使用模型进行预测 X_new = np.array([[5.0, 3.5, 1.3, 0.2]]) print(predict(X_new)) ``` 上述代码中,`train` 函数用于训练模型,`test` 函数用于测试模型精度,`predict` 函数用于使用模型进行预测。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值