基于diabetes.csv的Python神经网络输出一致预测结果的排查求助
神经网络预测结果一致的问题排查与解决
我用Python搭建了一个神经网络,但它对diabetes.csv里的每个数据点给出的预测结果几乎完全一致,调整特征也没用,求帮忙解决。
数据集示例
Pregnancies,Glucose,BloodPressure,SkinThickness,Insulin,BMI,DiabetesPedigreeFunction,Age,Outcome 6,148,72,35,0,33.6,0.627,50,1 1,85,66,29,0,26.6,0.351,31,0 8,183,64,0,0,23.3,0.672,32,1 1,89,66,23,94,28.1,0.167,21,0
我的神经网络代码
import numpy as np import pandas as pd data = pd.read_csv("diabetes.csv", header=0) print(data.head()) training_examples = data[["BloodPressure", "Glucose", "Outcome"]] X = training_examples[["BloodPressure", "Glucose"]].to_numpy() y = training_examples[["Outcome"]].to_numpy() DIMENSIONS = 2 HIDDEN_LAYER = 20 # Set up the training data # X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) # y = np.array([[0], [1], [1], [0]]) # Set the number of epochs and the learning rate num_epochs = 10 learning_rate = 0.1 # Initialize the weights and biases w1 = np.random.randn(DIMENSIONS, HIDDEN_LAYER) b1 = np.zeros((1, HIDDEN_LAYER)) w2 = np.random.randn(HIDDEN_LAYER, 1) b2 = np.zeros((1, 1)) # Define the sigmoid activation function def sigmoid(x): return 1 / (1 + np.exp(-x)) # Define the derivative of the sigmoid function def sigmoid_derivative(x): return x * (1 - x) # Train the network for epoch in range(num_epochs): # Forward pass z1 = np.dot(X, w1) + b1 a1 = sigmoid(z1) z2 = np.dot(a1, w2) + b2 a2 = sigmoid(z2) # Calculate the loss loss = np.mean((a2 - y)**2) # Print the loss every 100 epochs if epoch % 100 == 0: print(f'Epoch {epoch}: loss = {loss}') # Backpropagation dz2 = a2 - y dw2 = np.dot(a1.T, dz2) db2 = np.sum(dz2, axis=0) da1 = np.dot(dz2, w2.T) dz1 = da1 * sigmoid_derivative(a1) dw1 = np.dot(X.T, dz1) db1 = np.sum(dz1, axis=0) # Update the weights and biases w1 -= learning_rate * dw1 b1 -= learning_rate * db1 w2 -= learning_rate * dw2 b2 -= learning_rate * db2 # Make predictions on the test data predictions = a2 # Print the predictions print(predictions)
问题原因及解决办法
1. 训练轮数严重不足
你设置的num_epochs = 10,对于神经网络来说,10轮训练完全不够让模型学到数据中的模式。建议把轮数调到至少1000轮,比如num_epochs = 5000,同时修改loss打印间隔为if epoch % 500 == 0,方便观察loss变化趋势。
2. 未做特征归一化
输入特征BloodPressure和Glucose数值范围不同,sigmoid函数在输入值过大时会进入饱和区,导数趋近于0,导致梯度消失,模型无法有效更新权重。必须对输入特征做归一化处理:
# 在转换为numpy数组后添加归一化代码 X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)
3. 损失函数适配性差
这是二分类任务,用均方误差(MSE)不如交叉熵损失高效,交叉熵对二分类任务的梯度更新更敏感。修改损失计算代码:
# 替换原损失计算为交叉熵损失 loss = -np.mean(y * np.log(a2) + (1 - y) * np.log(1 - a2))
4. 学习率与权重初始化
当前学习率0.1可能偏大,容易导致模型训练不稳定,建议先尝试0.01,观察loss是否稳定下降;如果下降过慢,再逐步调大。权重初始化用np.random.randn是可行的,若想进一步优化,可尝试针对sigmoid的Xavier初始化。
5. 数据异常值处理(后续扩展特征时需注意)
数据集里存在0值(如SkinThickness、Insulin字段),如果后续添加这些特征,需要用均值/中位数填充这些异常值,避免影响模型训练。
内容的提问来源于stack exchange,提问作者George Garman
相关产品推荐
相关产品推荐

