使用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 15:49:24 浏览: 104
个人练习,实现了深度学习中的一些算法,包括:四种初始化方法,深度神经网络,正则化,dropout.zip
很高兴帮助您解决这个问题!接下来我将为您提供一个实现上述要求的代码,包含BP网络和主函数两个模块。
首先,我们需要创建BP网络模块,命名为`bp_network.py`:
```python
import numpy as np
import openpyxl as opx
import os.path as osp
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
# 使用Xavier初始化权重和偏置
self.weight_ih = np.random.randn(hidden_size, input_size) * np.sqrt(2 / input_size)
self.bias_h = np.zeros((hidden_size, 1))
self.weight_ho = np.random.randn(output_size, hidden_size) * np.sqrt(2 / hidden_size)
self.bias_o = np.zeros((output_size, 1))
def train(self, x_train, y_train, learning_rate, num_epochs, batch_size, reg_lambda):
# 归一化训练数据
x_train_mean = np.mean(x_train, axis=0)
x_train_std = np.std(x_train, axis=0)
x_train_norm = (x_train - x_train_mean) / x_train_std
# 将训练数据分为mini-batches
num_batches = int(np.ceil(x_train_norm.shape[0] / batch_size))
batches_x = np.array_split(x_train_norm, num_batches)
batches_y = np.array_split(y_train, num_batches)
# 训练网络
for epoch in range(num_epochs):
for batch_x, batch_y in zip(batches_x, batches_y):
# 前向传播
hidden = self._sigmoid(np.dot(self.weight_ih, batch_x.T) + self.bias_h)
output = np.dot(self.weight_ho, hidden) + self.bias_o
# 计算损失
loss = 0.5 * np.mean((output - batch_y.T) ** 2) + 0.5 * reg_lambda * (
np.sum(self.weight_ih ** 2) + np.sum(self.weight_ho ** 2))
# 反向传播
d_output = output - batch_y.T
d_weight_ho = np.dot(d_output, hidden.T) / batch_size + reg_lambda * self.weight_ho
d_bias_o = np.mean(d_output, axis=1, keepdims=True)
d_hidden = np.dot(self.weight_ho.T, d_output) * self._sigmoid_derivative(hidden)
d_weight_ih = np.dot(d_hidden, batch_x) / batch_size + reg_lambda * self.weight_ih
d_bias_h = np.mean(d_hidden, axis=1, keepdims=True)
# 更新权重和偏置
self.weight_ih -= learning_rate * d_weight_ih
self.bias_h -= learning_rate * d_bias_h
self.weight_ho -= learning_rate * d_weight_ho
self.bias_o -= learning_rate * d_bias_o
def predict(self, x_test):
# 归一化测试数据
x_test_mean = np.mean(x_test, axis=0)
x_test_std = np.std(x_test, axis=0)
x_test_norm = (x_test - x_test_mean) / x_test_std
# 前向传播
hidden = self._sigmoid(np.dot(self.weight_ih, x_test_norm.T) + self.bias_h)
output = np.dot(self.weight_ho, hidden) + self.bias_o
# 反归一化输出
output_denorm = output.T * x_test_std[-1] + x_test_mean[-1]
return output_denorm
def _sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def _sigmoid_derivative(self, x):
return x * (1 - x)
def save_weights(self, file_path):
# 将权重保存到文件
np.savez(file_path, weight_ih=self.weight_ih, bias_h=self.bias_h, weight_ho=self.weight_ho, bias_o=self.bias_o)
def load_weights(self, file_path):
# 从文件中加载权重
if osp.exists(file_path):
data = np.load(file_path)
self.weight_ih = data['weight_ih']
self.bias_h = data['bias_h']
self.weight_ho = data['weight_ho']
self.bias_o = data['bias_o']
def load_data(file_path):
# 从xlsx文件中加载数据
workbook = opx.load_workbook(file_path)
sheet = workbook.active
data = []
for row in sheet.iter_rows(min_row=2, values_only=True):
data.append(row)
data = np.array(data, dtype=np.float32)
x = data[:, :-1]
y = data[:, -1:]
return x, y
```
接下来,我们需要创建主函数模块,命名为`main.py`:
```python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error
from bp_network import BPNetwork, load_data
def main():
# 加载数据
x_train, y_train = load_data('data.xlsx')
x_test, y_test = x_train[-40:], y_train[-40:]
x_train, y_train = x_train[:-40], y_train[:-40]
# 创建BP网络
input_size = x_train.shape[1]
hidden_size = 8
output_size = 1
network = BPNetwork(input_size, hidden_size, output_size)
# 训练BP网络
learning_rate = 0.01
num_epochs = 1000
batch_size = 32
reg_lambda = 0.01
network.train(x_train, y_train, learning_rate, num_epochs, batch_size, reg_lambda)
# 保存BP网络权重
network.save_weights('weights.npz')
# 计算测试集的预测输出和真实输出
y_pred = network.predict(x_test)
y_true = y_test
# 计算R2值、MAE和MSE
r2 = r2_score(y_true, y_pred)
mae = mean_absolute_error(y_true, y_pred)
mse = mean_squared_error(y_true, y_pred)
print('R2: {:.4f}'.format(r2))
print('MAE: {:.4f}'.format(mae))
print('MSE: {:.4f}'.format(mse))
# 计算预测值和真实值之间的相对误差平均百分比
rel_err = np.abs((y_true - y_pred) / y_true).mean() * 100
print('Relative Error: {:.4f}%'.format(rel_err))
# 绘制测试集的各输入对应的实际输出和预测输出的拟合折线图
for i in range(x_test.shape[1]):
plt.figure()
plt.plot(x_test[:, i], y_true, label='True Value')
plt.plot(x_test[:, i], y_pred, label='Predicted Value')
plt.xlabel('Input {}'.format(i + 1))
plt.ylabel('Output')
plt.legend()
plt.show()
# 绘制R2图
plt.figure()
plt.scatter(y_true, y_pred)
plt.plot([y_true.min(), y_true.max()], [y_true.min(), y_true.max()], 'k--', lw=2)
plt.xlabel('True Value')
plt.ylabel('Predicted Value')
plt.title('R2: {:.4f}'.format(r2))
plt.show()
if __name__ == '__main__':
main()
```
上述代码中,我们首先从`data.xlsx`文件中加载数据,并将前3000行作为训练集,后40行作为测试集。然后,我们创建一个输入层大小为8、隐藏层大小为8、输出层大小为1的BP网络,并使用训练集对其进行训练。训练完成后,我们将BP网络的权重保存到`weights.npz`文件中。接着,我们使用测试集计算BP网络的预测输出和真实输出,并计算R2值、MAE和MSE。最后,我们绘制测试集的各输入对应的实际输出和预测输出的拟合折线图,以及R2图。
希望这个代码可以帮助到您!
阅读全文