训练一个BP神经网络用于实现鸢尾花的准确分类。要求:提交可以运行的源代码,并附上运行结果截图。
时间: 2025-06-26 08:15:09 浏览: 4
### BP神经网络实现鸢尾花数据集分类
以下是利用BP神经网络对鸢尾花数据集进行分类的完整Python源代码及其说明:
#### 数据准备与预处理
在BP神经网络中,输入层接收的是标准化后的特征向量。因此,在训练之前需要对原始数据进行归一化处理。
```python
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data # 特征矩阵 (150, 4)
y = iris.target.reshape(-1, 1) # 标签列向量 (150, 1)
# 对标签进行One-Hot编码
encoder = OneHotEncoder(sparse=False)
Y_onehot = encoder.fit_transform(y)
# 划分训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y_onehot, test_size=0.2, random_state=42)
# 归一化处理
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
```
上述代码加载了鸢尾花数据集并进行了必要的预处理工作[^2]。具体来说,`StandardScaler`用于将特征缩放到均值为零、方差为单位的标准正态分布;而`OneHotEncoder`则将类别标签转换成独热码形式以便于后续计算。
---
#### 构建BP神经网络模型
下面定义了一个简单的三层全连接前馈神经网络结构:一层输入层(大小等于特征数),两层隐藏层(节点数目自定), 和一个输出层(大小对应目标类别的数量).
```python
class NeuralNetwork:
def __init__(self, input_dim, hidden_units, output_dim):
self.W1 = np.random.randn(input_dim, hidden_units) * 0.01
self.b1 = np.zeros((1, hidden_units))
self.W2 = np.random.randn(hidden_units, output_dim) * 0.01
self.b2 = np.zeros((1, output_dim))
def sigmoid(self, Z):
return 1 / (1 + np.exp(-Z))
def softmax(self, Z):
exp_Z = np.exp(Z - np.max(Z, axis=1, keepdims=True))
return exp_Z / np.sum(exp_Z, axis=1, keepdims=True)
def forward(self, X):
self.Z1 = np.dot(X, self.W1) + self.b1
self.A1 = self.sigmoid(self.Z1)
self.Z2 = np.dot(self.A1, self.W2) + self.b2
A2 = self.softmax(self.Z2)
return A2
def compute_loss(self, A2, Y):
m = Y.shape[0]
logprobs = -np.log(A2[np.arange(m), np.argmax(Y, axis=1)] + 1e-8)
loss = np.mean(logprobs)
return loss
def backward(self, X, Y, learning_rate=0.01):
m = X.shape[0]
dZ2 = A2.copy() # 使用全局变量A2
dZ2 -= Y
dW2 = (1/m) * np.dot(self.A1.T, dZ2)
db2 = (1/m) * np.sum(dZ2, axis=0, keepdims=True)
dA1 = np.dot(dZ2, self.W2.T)
dZ1 = dA1 * self.A1 * (1-self.A1)
dW1 = (1/m) * np.dot(X.T, dZ1)
db1 = (1/m) * np.sum(dZ1, axis=0, keepdims=True)
# 更新参数
self.W1 -= learning_rate * dW1
self.b1 -= learning_rate * db1
self.W2 -= learning_rate * dW2
self.b2 -= learning_rate * db2
def accuracy(predictions, labels):
predicted_class = np.argmax(predictions, axis=1)
true_class = np.argmax(labels, axis=1)
correct_predictions = np.equal(predicted_class, true_class).astype(float)
acc = np.mean(correct_predictions)
return acc
```
此部分实现了BP神经网络的核心功能,包括权重初始化、激活函数(`sigmoid`, `softmax`)的选择以及反向传播算法的具体实现[^3].
---
#### 训练过程
通过多次迭代调整权值来最小化损失函数值.
```python
input_dim = X_train_scaled.shape[1]
hidden_units = 10
output_dim = Y_train.shape[1]
nn = NeuralNetwork(input_dim, hidden_units, output_dim)
epochs = 1000
learning_rate = 0.1
for epoch in range(epochs):
A2 = nn.forward(X_train_scaled)
loss = nn.compute_loss(A2, Y_train)
global A2 # 将forward的结果赋给全局变量供backward使用
nn.backward(X_train_scaled, Y_train, learning_rate)
if epoch % 100 == 0:
print(f"Epoch {epoch}, Loss: {loss:.4f}")
print("Training completed.")
```
在此循环过程中,每次都会打印当前轮次下的交叉熵误差情况以监控收敛趋势。
---
#### 测试性能评估
最后我们用保留下来的验证集合检验最终效果如何:
```python
predictions = nn.forward(X_test_scaled)
test_accuracy = accuracy(predictions, Y_test)
print(f"Test Accuracy: {test_accuracy*100:.2f}%")
```
以上就是完整的基于BP神经网络解决鸢尾花分类问题的过程演示[^1].
---
### 运行结果示例
假设经过充分训练之后得到如下输出:
```
Epoch 0, Loss: 1.1076
Epoch 100, Loss: 0.1234
...
Epoch 900, Loss: 0.0123
Training completed.
Test Accuracy: 96.67%
```
这表明我们的模型已经能够较好地区分三种不同的鸢尾植物品种。
---
阅读全文