1.使用 Numpy 编写一个神经网络,并开发 BP 算法。两个隐层,第 一个隐层 4 个神经元,第二个隐层 8 个神经元,输入是 4 个神经 元,输出是 2 个神经元。激活函数用 ReLu。并对 data.csv 数据集进 行训练和测试,计算精度。
时间: 2023-11-27 16:52:31 浏览: 106
好的,让我来给你介绍一下实现神经网络和 BP 算法的步骤。
首先,我们需要导入 Numpy 库,并读取 data.csv 数据集。该数据集包括 4 个特征和 2 个标签,我们将其分别存储在 X 和 y 中。
```python
import numpy as np
# 读取数据集
data = np.genfromtxt('data.csv', delimiter=',')
X = data[:, :4]
y = data[:, 4:]
```
接着,我们需要初始化神经网络的参数。假设我们设置第一个隐层有 4 个神经元,第二个隐层有 8 个神经元,输入层有 4 个神经元,输出层有 2 个神经元,那么我们的参数包括两个权重矩阵 W1 和 W2,以及两个偏置向量 b1 和 b2。我们可以使用 np.random.randn() 函数来随机初始化这些参数。
```python
# 初始化参数
input_dim = 4
hidden_dim1 = 4
hidden_dim2 = 8
output_dim = 2
W1 = np.random.randn(input_dim, hidden_dim1)
b1 = np.zeros((1, hidden_dim1))
W2 = np.random.randn(hidden_dim1, hidden_dim2)
b2 = np.zeros((1, hidden_dim2))
W3 = np.random.randn(hidden_dim2, output_dim)
b3 = np.zeros((1, output_dim))
```
现在我们来实现前向传播函数。根据神经网络的定义,前向传播包括以下几个步骤:
1. 将输入 X 乘以第一个权重矩阵 W1,然后加上偏置向量 b1。
2. 将上一步的结果输入到 ReLu 激活函数中,得到第一个隐层的输出。
3. 将第一个隐层的输出乘以第二个权重矩阵 W2,然后加上偏置向量 b2。
4. 将上一步的结果输入到 ReLu 激活函数中,得到第二个隐层的输出。
5. 将第二个隐层的输出乘以第三个权重矩阵 W3,然后加上偏置向量 b3。
6. 将上一步的结果输入到 softmax 函数中,得到最终的输出。
```python
# 定义前向传播函数
def forward(X, W1, b1, W2, b2, W3, b3):
z1 = np.dot(X, W1) + b1
a1 = np.maximum(z1, 0)
z2 = np.dot(a1, W2) + b2
a2 = np.maximum(z2, 0)
z3 = np.dot(a2, W3) + b3
exp_scores = np.exp(z3)
return exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
```
接下来,我们需要实现反向传播算法来更新神经网络的参数。我们使用交叉熵损失函数来衡量模型的表现,其定义为:
$$
L = -\frac{1}{N}\sum_{i=1}^N\sum_{j=1}^My_{ij}\log\hat{y}_{ij}
$$
其中,$y_{ij}$ 是真实标签,$\hat{y}_{ij}$ 是模型预测值。我们的目标是最小化损失函数,因此我们需要计算损失函数对神经网络参数的梯度,然后使用梯度下降算法来更新参数。
```python
# 定义反向传播函数
def backward(X, y, y_pred, W1, b1, W2, b2, W3, b3, learning_rate):
# 计算输出层的误差
delta3 = y_pred - y
# 计算第二个隐层的误差
delta2 = np.dot(delta3, W3.T) * (np.maximum(0, np.dot(X, W1) + b1) > 0)
# 计算第一个隐层的误差
delta1 = np.dot(delta2, W2.T) * (np.maximum(0, np.dot(delta2, W2) + b2) > 0)
# 更新权重矩阵和偏置向量
dW3 = np.dot(a2.T, delta3)
db3 = np.sum(delta3, axis=0, keepdims=True)
dW2 = np.dot(a1.T, delta2)
db2 = np.sum(delta2, axis=0)
dW1 = np.dot(X.T, delta1)
db1 = np.sum(delta1, axis=0)
W1 -= learning_rate * dW1
b1 -= learning_rate * db1
W2 -= learning_rate * dW2
b2 -= learning_rate * db2
W3 -= learning_rate * dW3
b3 -= learning_rate * db3
return W1, b1, W2, b2, W3, b3
```
现在我们可以开始进行训练了。我们将数据集分为训练集和测试集,然后使用前向传播函数和反向传播函数来更新神经网络的参数。在每个 epoch 结束时,我们计算模型在训练集和测试集上的精度,以便监测模型的训练效果。
```python
# 将数据集分为训练集和测试集
train_size = int(0.7 * len(X))
X_train, y_train = X[:train_size], y[:train_size]
X_test, y_test = X[train_size:], y[train_size:]
# 定义训练参数
learning_rate = 0.01
epochs = 5000
# 开始训练
for epoch in range(epochs):
# 前向传播
y_pred = forward(X_train, W1, b1, W2, b2, W3, b3)
# 反向传播
W1, b1, W2, b2, W3, b3 = backward(X_train, y_train, y_pred, W1, b1, W2, b2, W3, b3, learning_rate)
# 计算训练集和测试集的精度
train_acc = np.mean(np.argmax(y_train, axis=1) == np.argmax(y_pred, axis=1))
test_acc = np.mean(np.argmax(y_test, axis=1) == np.argmax(forward(X_test, W1, b1, W2, b2, W3, b3), axis=1))
if epoch % 1000 == 0:
print(f"Epoch {epoch}: Train accuracy = {train_acc:.4f}, Test accuracy = {test_acc:.4f}")
```
最后,我们可以使用训练好的模型来预测新的样本。假设我们有一个包含 4 个特征的样本 x,我们可以使用 forward 函数来得到该样本的预测标签。
```python
# 预测新样本
x = np.array([[5.1, 3.5, 1.4, 0.2]])
y_pred = forward(x, W1, b1, W2, b2, W3, b3)
print(f"Predicted label for {x}: {np.argmax(y_pred)}")
```
以上就是使用 Numpy 实现神经网络和 BP 算法的完整流程。
阅读全文