使用python创建一个使用归一化、Xavier初始化、正则化方法和MSGD的BP网络,该网络有8个输入1个输出1层隐藏层,要求分为两个模块(py文件),且一个是BP网络,另一个是主函数,在每句代码后添加注释;训练集数据存于xlsx表格前3000行中,测试集为之后的40行,且均为float类型,即训练模型时以3000行数据作为训练集,而之后也可以将40行的测试集数据输入模型中并正常运行出结果。并且能够输出各输入的权重。尝试在main模块中实现将训练后的BP网络模型输出为一个文件,绘制R2图来说明模型的拟合度,并且输出MAE、MSE、预测值和真实值之间的相对误差平均百分比,绘制测试集的各输入对应的实际输出和预测输出的拟合折线图,且R2图和折线图中使用的数据均为未变换数据。避免'float' object has no attribute 'exp'问题
时间: 2023-11-27 22:49:08 浏览: 29
为了实现上述需求,我们可以按照以下步骤进行:
1. 安装依赖库
2. 准备数据
3. 创建BP网络
4. 训练BP网络
5. 保存BP网络模型
6. 测试BP网络
7. 计算MAE、MSE和相对误差平均百分比
8. 绘制R2图和折线图
下面是具体的代码实现:
## 1. 安装依赖库
我们需要安装以下依赖库:
```
pip install numpy pandas matplotlib sklearn xlrd
```
## 2. 准备数据
我们需要从Excel文件中读取训练集和测试集数据,然后进行归一化处理。
```python
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
# 读取训练集和测试集数据
train_data = pd.read_excel('data.xlsx', nrows=3000)
test_data = pd.read_excel('data.xlsx', skiprows=range(1, 3001))
# 对数据进行归一化处理
scaler = MinMaxScaler()
train_data = scaler.fit_transform(train_data)
test_data = scaler.transform(test_data)
```
## 3. 创建BP网络
我们需要创建一个具有8个输入、1个输出和1个隐藏层的BP网络,并使用Xavier初始化、L2正则化和MSGD优化器。
```python
import numpy as np
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
# 初始化权重和偏置
self.W1 = np.random.randn(self.input_size, self.hidden_size) * np.sqrt(1.0 / self.input_size)
self.b1 = np.zeros((1, self.hidden_size))
self.W2 = np.random.randn(self.hidden_size, self.output_size) * np.sqrt(1.0 / self.hidden_size)
self.b2 = np.zeros((1, self.output_size))
# 设置L2正则化参数
self.reg_lambda = 0.01
def sigmoid(self, x):
return 1.0 / (1.0 + np.exp(-x))
def sigmoid_prime(self, x):
return self.sigmoid(x) * (1 - self.sigmoid(x))
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
self.y_hat = self.z2
return self.y_hat
def backward(self, X, y, y_hat):
# 反向传播
delta3 = y_hat - y
delta2 = np.dot(delta3, self.W2.T) * self.sigmoid_prime(self.z1)
dW2 = np.dot(self.a1.T, delta3) + self.reg_lambda * self.W2
db2 = np.sum(delta3, axis=0, keepdims=True)
dW1 = np.dot(X.T, delta2) + self.reg_lambda * self.W1
db1 = np.sum(delta2, axis=0)
return dW1, db1, dW2, db2
def update_parameters(self, dW1, db1, dW2, db2, learning_rate):
# 更新权重和偏置
self.W1 -= learning_rate * dW1
self.b1 -= learning_rate * db1
self.W2 -= learning_rate * dW2
self.b2 -= learning_rate * db2
def train(self, X, y, num_epochs, learning_rate):
for epoch in range(num_epochs):
# 前向传播
y_hat = self.forward(X)
# 计算损失函数
loss = np.mean(np.square(y_hat - y))
reg_loss = 0.5 * self.reg_lambda * (np.sum(np.square(self.W1)) + np.sum(np.square(self.W2)))
total_loss = loss + reg_loss
# 反向传播
dW1, db1, dW2, db2 = self.backward(X, y, y_hat)
# 更新权重和偏置
self.update_parameters(dW1, db1, dW2, db2, learning_rate)
# 打印损失函数值
if epoch % 100 == 0:
print("Epoch ", epoch, " loss: ", total_loss)
def predict(self, X):
# 预测输出
y_hat = self.forward(X)
return y_hat
def get_weights(self):
# 获取权重
return self.W1, self.W2
```
## 4. 训练BP网络
我们需要使用训练集数据训练BP网络,并打印出训练过程中的损失函数值。
```python
# 创建BP网络
nn = NeuralNetwork(8, 5, 1)
# 设置训练参数
num_epochs = 1000
learning_rate = 0.01
# 训练BP网络
X_train = train_data[:, :-1]
y_train = train_data[:, -1:]
nn.train(X_train, y_train, num_epochs, learning_rate)
```
## 5. 保存BP网络模型
我们可以将训练后的BP网络模型保存为一个文件,以便之后使用。
```python
import pickle
# 保存BP网络模型
with open('model.pkl', 'wb') as f:
pickle.dump(nn, f)
```
## 6. 测试BP网络
我们可以使用测试集数据来测试训练好的BP网络,并打印出预测结果。
```python
# 加载BP网络模型
with open('model.pkl', 'rb') as f:
nn = pickle.load(f)
# 测试BP网络
X_test = test_data[:, :-1]
y_test = test_data[:, -1:]
y_hat = nn.predict(X_test)
# 打印预测结果
print("Predictions: ", y_hat)
```
## 7. 计算MAE、MSE和相对误差平均百分比
我们可以使用sklearn库来计算MAE、MSE和相对误差平均百分比。
```python
from sklearn.metrics import mean_absolute_error, mean_squared_error
# 计算MAE和MSE
mae = mean_absolute_error(y_test, y_hat)
mse = mean_squared_error(y_test, y_hat)
print("MAE: ", mae)
print("MSE: ", mse)
# 计算相对误差平均百分比
mean_error = np.mean(np.abs(y_test - y_hat) / y_test) * 100
print("Mean Error: ", mean_error, "%")
```
## 8. 绘制R2图和折线图
我们可以使用matplotlib库来绘制R2图和折线图。
```python
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score
# 计算R2值
r2 = r2_score(y_test, y_hat)
print("R2 Score: ", r2)
# 绘制折线图
plt.plot(y_test, label="Actual")
plt.plot(y_hat, label="Predicted")
plt.legend()
plt.show()
# 绘制R2图
fig, ax = plt.subplots()
ax.scatter(y_test, y_hat, edgecolors=(0, 0, 0))
ax.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'k--', lw=4)
ax.set_xlabel('Actual')
ax.set_ylabel('Predicted')
ax.set_title("R2 Score: " + str(r2))
plt.show()
```