使用python创建一个使用归一化、Xavier初始化、正则化方法和MSGD的BP网络,该网络有8个输入1个输出1层隐藏层,要求分为两个模块(py文件),且一个是BP网络,另一个是主函数,在每句代码后添加注释;训练集数据存于xlsx表格前3000行中,测试集为之后的40行,且均为float类型,训练后模型不会出现shape类报错,。并且能够输出各输入的权重。尝试在main模块中实现将训练后的BP网络模型输出为一个文件,绘制R2图来说明模型的拟合度,并且输出MAE、MSE、预测值和真实值之间的相对误差平均百分比,绘制测试集的各输入对应的实际输出和预测输出的拟合折线图,且R2图和折线图中使用的数据均为未变换数据。
时间: 2023-11-22 13:57:00 浏览: 52
以下是BP网络模块的代码,保存为bp_network.py:
```python
import numpy as np
import pandas as pd
class BPNetwork:
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(self.input_size)
self.b1 = np.zeros((1, self.hidden_size))
self.W2 = np.random.randn(self.hidden_size, self.output_size) / np.sqrt(self.hidden_size)
self.b2 = np.zeros((1, self.output_size))
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(self, x):
return x * (1 - 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
y = self.z2
return y
def backward(self, X, y, y_pred, learning_rate):
delta3 = y_pred - y
dW2 = np.dot(self.a1.T, delta3)
db2 = np.sum(delta3, axis=0, keepdims=True)
delta2 = np.dot(delta3, self.W2.T) * self.sigmoid_derivative(self.a1)
dW1 = np.dot(X.T, delta2)
db1 = np.sum(delta2, axis=0)
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, learning_rate=0.1, epochs=1000):
for i in range(epochs):
y_pred = self.forward(X)
self.backward(X, y, y_pred, learning_rate)
def predict(self, X):
y_pred = self.forward(X)
return y_pred
def save_weights(self, filename):
np.savez(filename, W1=self.W1, b1=self.b1, W2=self.W2, b2=self.b2)
def load_weights(self, filename):
weights = np.load(filename)
self.W1 = weights['W1']
self.b1 = weights['b1']
self.W2 = weights['W2']
self.b2 = weights['b2']
```
以下是主函数模块的代码,保存为main.py:
```python
import numpy as np
import pandas as pd
from bp_network import BPNetwork
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error
# 读取训练集和测试集数据
train_df = pd.read_excel('data.xlsx', nrows=3000)
test_df = pd.read_excel('data.xlsx', skiprows=range(1, 3001))
# 分离输入和输出
X_train = train_df.iloc[:, :-1].values.astype(float)
y_train = train_df.iloc[:, -1].values.astype(float)
X_test = test_df.iloc[:, :-1].values.astype(float)
y_test = test_df.iloc[:, -1].values.astype(float)
# 数据标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# 创建BP网络模型
input_size = X_train.shape[1]
hidden_size = 8
output_size = 1
bpnn = BPNetwork(input_size, hidden_size, output_size)
# 训练模型
bpnn.train(X_train, y_train, learning_rate=0.1, epochs=1000)
# 保存模型权重
bpnn.save_weights('model.npz')
# 加载模型权重
bpnn.load_weights('model.npz')
# 预测测试集结果
y_pred = bpnn.predict(X_test)
# 反标准化处理
y_test = scaler.inverse_transform(y_test)
y_pred = scaler.inverse_transform(y_pred)
# 计算R2、MAE、MSE和相对误差平均百分比
r2 = r2_score(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
error = np.mean(np.abs((y_test - y_pred) / y_test)) * 100
print(f'R2 score: {r2:.3f}')
print(f'MAE: {mae:.3f}')
print(f'MSE: {mse:.3f}')
print(f'Relative error: {error:.3f}%')
# 绘制测试集的拟合图
import matplotlib.pyplot as plt
plt.plot(y_test, label='true')
plt.plot(y_pred, label='pred')
plt.legend()
plt.show()
# 输出各输入的权重
for i, w in enumerate(bpnn.W1.T):
print(f'Weight for feature {i+1}: {w}')
```
在运行main.py时,会输出R2、MAE、MSE和相对误差平均百分比等信息,并绘制测试集的拟合图。同时,还会输出各输入的权重。最后,模型的权重会保存到model.npz文件中。
阅读全文