使用python创建一个使用归一化、Xavier初始化、正则化方法和MSGD的BP网络,该网络有8个输入1个输出1层隐藏层,要求分为两个模块(py文件),在确认输入、输出的训练集之后,模型不会出现shape类报错,且一个是BP网络,另一个是主函数,在每句代码后添加注释;训练集数据存于xlsx表格前3000行中,之后的都是测试集,且均为float类型。并且能够输出各输入的权重。尝试在main模块中实现将训练后的BP网络模型输出为一个文件,绘制R2图来说明模型的拟合度,并且输出MAE、MSE、预测值和真实值之间的相对误差平均百分比,绘制测试集的各输入对应的实际输出和预测输出的拟合折线图,且R2图和折线图中使用的数据均为未变换数据。
时间: 2023-11-22 14:56:23 浏览: 70
非常感谢您的提问,由于您提问的内容比较复杂,需要涉及到多个模块的编写,因此我将分步骤给出实现方法:
## 第一步:创建BP网络模型
### 1.1 安装必要的库
我们需要安装一些必要的库,包括numpy、pandas、openpyxl等。可以使用以下命令来安装:
```
pip install numpy pandas openpyxl
```
### 1.2 导入相关库
```python
import numpy as np
import pandas as pd
from openpyxl import load_workbook
```
### 1.3 定义BP网络类
我们需要定义一个BP网络类,用来存储网络结构、训练参数以及前向传播、反向传播等方法。具体代码如下:
```python
class BPNN:
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.learning_rate = 0.01 # 学习率
self.regularization_rate = 0.01 # 正则化系数
self.epoch = 1000 # 迭代次数
self.batch_size = 32 # 批次大小
self.hidden_weights = np.random.normal(0, np.sqrt(2 / (input_size + hidden_size)), (input_size, hidden_size)) # 隐藏层权重
self.output_weights = np.random.normal(0, np.sqrt(2 / (hidden_size + output_size)), (hidden_size, output_size)) # 输出层权重
self.hidden_bias = np.zeros((1, hidden_size)) # 隐藏层偏置项
self.output_bias = np.zeros((1, output_size)) # 输出层偏置项
def relu(self, x):
"""定义ReLU激活函数"""
return np.maximum(x, 0)
def relu_derivative(self, x):
"""定义ReLU激活函数的导数"""
return np.where(x > 0, 1, 0)
def sigmoid(self, x):
"""定义Sigmoid激活函数"""
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(self, x):
"""定义Sigmoid激活函数的导数"""
return self.sigmoid(x) * (1 - self.sigmoid(x))
def forward(self, X):
"""前向传播"""
z1 = np.dot(X, self.hidden_weights) + self.hidden_bias
a1 = self.relu(z1)
z2 = np.dot(a1, self.output_weights) + self.output_bias
y_pred = self.sigmoid(z2)
return y_pred, a1
def backward(self, X, y_true, y_pred, a1):
"""反向传播"""
delta2 = (y_pred - y_true) * self.sigmoid_derivative(y_pred)
delta1 = np.dot(delta2, self.output_weights.T) * self.relu_derivative(a1)
d_output_weights = np.dot(a1.T, delta2) / X.shape[0] + self.regularization_rate * self.output_weights
d_hidden_weights = np.dot(X.T, delta1) / X.shape[0] + self.regularization_rate * self.hidden_weights
d_output_bias = np.sum(delta2, axis=0, keepdims=True) / X.shape[0]
d_hidden_bias = np.sum(delta1, axis=0, keepdims=True) / X.shape[0]
return d_hidden_weights, d_output_weights, d_hidden_bias, d_output_bias
def fit(self, X, y):
"""训练模型"""
for i in range(self.epoch):
batch_loss = []
for j in range(0, X.shape[0], self.batch_size):
X_batch = X[j:j + self.batch_size]
y_batch = y[j:j + self.batch_size]
y_pred, a1 = self.forward(X_batch)
loss = -np.mean(y_batch * np.log(y_pred) + (1 - y_batch) * np.log(1 - y_pred)) + \
(self.regularization_rate / (2 * X.shape[0])) * (np.sum(self.hidden_weights ** 2) + np.sum(
self.output_weights ** 2))
batch_loss.append(loss)
d_hidden_weights, d_output_weights, d_hidden_bias, d_output_bias = self.backward(X_batch, y_batch,
y_pred, a1)
self.hidden_weights -= self.learning_rate * d_hidden_weights
self.output_weights -= self.learning_rate * d_output_weights
self.hidden_bias -= self.learning_rate * d_hidden_bias
self.output_bias -= self.learning_rate * d_output_bias
print('Epoch:{}, Loss:{}'.format(i, np.mean(batch_loss)))
```
## 第二步:创建主函数
### 2.1 导入相关库
```python
import numpy as np
import pandas as pd
from openpyxl import load_workbook
from bpnn import BPNN # 导入BP网络模型
```
### 2.2 加载数据
我们需要将数据从xlsx表格中读取出来,然后分成训练集和测试集。具体代码如下:
```python
# 加载数据
workbook = load_workbook('data.xlsx')
sheet = workbook.active
data = np.array([[cell.value for cell in row] for row in sheet.rows])
X = data[:3000, :-1].astype(float) # 训练集输入
y = data[:3000, -1:].astype(float) # 训练集输出
X_test = data[3000:, :-1].astype(float) # 测试集输入
y_test = data[3000:, -1:].astype(float) # 测试集输出
```
### 2.3 创建BP网络模型并训练
```python
# 创建BP网络模型并训练
model = BPNN(input_size=8, hidden_size=8, output_size=1)
model.fit(X, y)
```
### 2.4 保存BP网络模型
```python
# 保存BP网络模型
np.save('model.npy', [model.hidden_weights, model.output_weights, model.hidden_bias, model.output_bias])
```
### 2.5 加载BP网络模型并预测
```python
# 加载BP网络模型并预测
model_params = np.load('model.npy', allow_pickle=True)
model.hidden_weights, model.output_weights, model.hidden_bias, model.output_bias = model_params
y_pred, _ = model.forward(X_test)
```
### 2.6 输出各输入的权重
```python
# 输出各输入的权重
for i in range(model.input_size):
print('Input {}:'.format(i + 1))
print(' Hidden weights:', model.hidden_weights[i])
print(' Output weights:', model.output_weights[:, 0])
```
### 2.7 计算评价指标
```python
# 计算评价指标
mae = np.mean(np.abs(y_test - y_pred))
mse = np.mean((y_test - y_pred) ** 2)
rpe = np.mean(np.abs((y_test - y_pred) / y_test)) * 100
r2 = 1 - mse / np.var(y_test)
print('MAE:', mae)
print('MSE:', mse)
print('RPE:', rpe)
print('R2:', r2)
```
### 2.8 绘制拟合图和折线图
```python
import matplotlib.pyplot as plt
# 绘制拟合图
plt.scatter(y_test, y_pred)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'k--', lw=2)
plt.xlabel('True Values')
plt.ylabel('Predictions')
plt.show()
# 绘制折线图
for i in range(X_test.shape[1]):
plt.plot(X_test[:, i], y_test, 'b-', label='True')
plt.plot(X_test[:, i], y_pred, 'r-', label='Predicted')
plt.xlabel('Input {}'.format(i + 1))
plt.ylabel('Output')
plt.legend()
plt.show()
```
希望这些代码可以帮助您完成任务。
阅读全文