self.a1 = self.sigmoid(self.z1) self.z2 = np.dot(self.a1, self.weights2) + self.bias2 self.a2 = self.sigmoid(self.z2)
时间: 2024-01-16 09:03:33 浏览: 87
这段代码看起来是一个神经网络的前向传播过程。首先,输入通过第一层权重矩阵相乘加上第一层偏置向量得到第二层的输入值z1。这个输入值z1再通过sigmoid函数激活得到第二层的输出值a1。接下来,第二层的输出值a1又通过第二层的权重矩阵相乘加上第二层的偏置向量得到第三层的输入值z2。这个输入值z2再通过sigmoid函数激活得到神经网络的最终输出值a2。整个过程可以看做是一个从输入到输出的映射关系,通过不断迭代训练权重和偏置,使得这个映射关系能够准确地预测出给定输入的输出。
相关问题
class NeuralNetwork: def __init__(self, n_inputs, n_hidden, n_outputs): self.n_inputs = n_inputs self.n_hidden = n_hidden self.n_outputs = n_outputs # 初始化权重和偏差 self.weights1 = np.random.randn(self.n_inputs, self.n_hidden) self.bias1 = np.zeros((1, self.n_hidden)) self.weights2 = np.random.randn(self.n_hidden, self.n_outputs) self.bias2 = np.zeros((1, self.n_outputs)) def sigmoid(self, z): return 1 / (1 + np.exp(-z)) def sigmoid_derivative(self, z): return self.sigmoid(z) * (1 - self.sigmoid(z)) def feedforward(self, X): # 计算隐藏层输出 self.z1 = np.dot(X, self.weights1) + self.bias1 self.a1 = self.sigmoid(self.z1) # 计算输出层输出 self.z2 = np.dot(self.a1, self.weights2) + self.bias2 self.a2 = self.sigmoid(self.z2) return self.a2 def backpropagation(self, X, y, output): # 计算输出层误差 error = output - y d_output = error * self.sigmoid_derivative(self.z2) # 计算隐藏层误差 error_hidden = d_output.dot(self.weights2.T) d_hidden = error_hidden * self.sigmoid_derivative(self.z1) # 更新权重和偏差 self.weights2 -= self.a1.T.dot(d_output) self.bias2 -= np.sum(d_output, axis=0, keepdims=True) self.weights1 -= X.T.dot(d_hidden) self.bias1 -= np.sum(d_hidden, axis=0) def train(self, X, y, n_epochs, learning_rate): for epoch in range(n_epochs): output = self.feedforward(X) self.backpropagation(X, y, output) def predict(self, X): output = self.feedforward(X) predictions = np.argmax(output, axis=1) return predictions
这是一个简单的神经网络实现,包括初始化权重和偏差、前向传播、反向传播、训练和预测。
神经网络的训练过程中,通常需要一些超参数的设置,如隐藏层的神经元数量、迭代次数、学习率等。
在这个实现中,隐藏层神经元数量为n_hidden,迭代次数为n_epochs,学习率为learning_rate。该神经网络使用sigmoid作为激活函数,使用梯度下降算法进行权重和偏差的更新。
在训练过程中,首先进行前向传播,得到输出值,然后进行反向传播,根据误差对权重和偏差进行调整。重复这个过程,直到达到预设的迭代次数,或者误差达到一定程度后停止训练。
在预测过程中,输入数据进行前向传播,得到输出值,根据输出值的大小确定预测结果。
这个实现比较简单,如果你想深入了解神经网络的原理和实现,可以参考相关的教材或者资料。
使用python创建一个使用归一化、Xavier初始化、正则化方法和MSGD的BP网络,该网络有8个输入1个输出1层隐藏层,要求分为两个模块(py文件),且一个是BP网络,另一个是主函数,在每句代码后添加注释。并且能够输出各输入的权重。尝试在main模块中绘制R2图来说明模型的拟合度,并且输出MAE、MSE、预测值和真实值之间的相对误差平均百分比,绘制测试集的各输入对应的实际输出和预测输出的拟合折线图,且R2图和折线图中使用的数据均为未变换数据. 训练集输入层为3000行,8列矩阵;训练集输出层为3000行,1列。 测试集输入层为40行,8列矩阵;测试集输出层为40行,1列。训练集和测试集数据均是从xlsx表格中读取。 实现将训练后的BP网络模型输出为一个文件。
以下是BP网络模块的代码,命名为bp_network.py:
```python
import numpy as np
import pandas as pd
class BP_Network:
def __init__(self, input_size, hidden_size, output_size):
"""
初始化BP神经网络模型
:param input_size: 输入层节点数
:param hidden_size: 隐藏层节点数
:param output_size: 输出层节点数
"""
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
self.weights1 = np.random.randn(input_size, hidden_size) / np.sqrt(input_size)
self.bias1 = np.zeros((1, hidden_size))
self.weights2 = np.random.randn(hidden_size, output_size) / np.sqrt(hidden_size)
self.bias2 = np.zeros((1, output_size))
def sigmoid(self, x):
"""
sigmoid函数
:param x: 输入值
:return: sigmoid(x)
"""
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(self, x):
"""
sigmoid函数的导函数
:param x: 输入值
:return: sigmoid(x) * (1 - sigmoid(x))
"""
return self.sigmoid(x) * (1 - self.sigmoid(x))
def feedforward(self, X):
"""
前向传播
:param X: 输入数据
:return: 输出层的输出
"""
self.z1 = np.dot(X, self.weights1) + self.bias1
self.a1 = self.sigmoid(self.z1)
self.z2 = np.dot(self.a1, self.weights2) + self.bias2
self.a2 = self.sigmoid(self.z2)
return self.a2
def backward(self, X, y, output):
"""
反向传播
:param X: 输入数据
:param y: 真实输出
:param output: 模型输出
:return: 误差delta
"""
self.output_error = y - output
self.output_delta = self.output_error * self.sigmoid_derivative(output)
self.z1_error = self.output_delta.dot(self.weights2.T)
self.z1_delta = self.z1_error * self.sigmoid_derivative(self.a1)
self.weights1 += X.T.dot(self.z1_delta)
self.bias1 += np.sum(self.z1_delta, axis=0, keepdims=True)
self.weights2 += self.a1.T.dot(self.output_delta)
self.bias2 += np.sum(self.output_delta, axis=0)
delta = np.sum(np.abs(self.output_error))
return delta
def train(self, X, y, epochs, learning_rate):
"""
训练模型
:param X: 输入数据
:param y: 真实输出
:param epochs: 迭代次数
:param learning_rate: 学习率
:return: 训练过程中的误差
"""
errors = []
for i in range(epochs):
output = self.feedforward(X)
delta = self.backward(X, y, output)
errors.append(delta)
if i % 100 == 0:
print("Epoch %d error: %.10f" % (i, delta))
print("Epoch %d output: %s" % (i, str(output)))
self.weights1 = self.weights1 + learning_rate * self.weights1
self.weights2 = self.weights2 + learning_rate * self.weights2
return errors
def save_model(self, filename):
"""
将模型输出为文件
:param filename: 输出文件名
"""
np.savez(filename, weights1=self.weights1, bias1=self.bias1, weights2=self.weights2, bias2=self.bias2)
```
以下是主函数模块的代码,命名为main.py:
```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from bp_network import BP_Network
def normalize(X):
"""
归一化函数,使每列的数值范围为[0, 1]
:param X: 输入数据
:return: 归一化后的数据
"""
X_min = np.min(X, axis=0)
X_max = np.max(X, axis=0)
X_norm = (X - X_min) / (X_max - X_min)
return X_norm
def initialize_weights(input_size, hidden_size, output_size):
"""
Xavier初始化权重函数
:param input_size: 输入层节点数
:param hidden_size: 隐藏层节点数
:param output_size: 输出层节点数
:return: 初始化后的权重
"""
weights1 = np.random.randn(input_size, hidden_size) / np.sqrt(input_size)
bias1 = np.zeros((1, hidden_size))
weights2 = np.random.randn(hidden_size, output_size) / np.sqrt(hidden_size)
bias2 = np.zeros((1, output_size))
return weights1, bias1, weights2, bias2
def regularization(weights1, weights2, lambda_value):
"""
L2正则化函数
:param weights1: 隐藏层的权重
:param weights2: 输出层的权重
:param lambda_value: 正则化参数
:return: 正则化项
"""
reg = (lambda_value / 2) * (np.sum(np.square(weights1)) + np.sum(np.square(weights2)))
return reg
def mini_batch(X, y, batch_size):
"""
将数据分成小批量进行训练
:param X: 输入数据
:param y: 真实输出
:param batch_size: 批量大小
:return: 小批量数据
"""
n_samples = X.shape[0]
mini_batches = []
permutation = list(np.random.permutation(n_samples))
shuffled_X = X[permutation, :]
shuffled_y = y[permutation, :]
n_batches = n_samples // batch_size
for i in range(n_batches):
mini_X = shuffled_X[i * batch_size:(i + 1) * batch_size, :]
mini_y = shuffled_y[i * batch_size:(i + 1) * batch_size, :]
mini_batches.append((mini_X, mini_y))
if n_samples % batch_size != 0:
mini_X = shuffled_X[n_batches * batch_size:, :]
mini_y = shuffled_y[n_batches * batch_size:, :]
mini_batches.append((mini_X, mini_y))
return mini_batches
def load_data(filename):
"""
读取数据
:param filename: 文件名
:return: 数据
"""
data = pd.read_excel(filename)
X = data.iloc[:, :-1].values
y = data.iloc[:, -1].values
return X, y.reshape(-1, 1)
def plot_R2(X, y, model):
"""
绘制R2图
:param X: 输入数据
:param y: 真实输出
:param model: 模型
"""
y_pred = model.feedforward(X)
ss_res = np.sum(np.square(y - y_pred))
ss_tot = np.sum(np.square(y - np.mean(y)))
r2 = 1 - (ss_res / ss_tot)
plt.scatter(y, y_pred)
plt.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=2)
plt.xlabel('Measured')
plt.ylabel('Predicted')
plt.title('R2: %.4f' % r2)
plt.show()
def plot_fitting(X_test, y_test, model):
"""
绘制测试集的各输入对应的实际输出和预测输出的拟合折线图
:param X_test: 测试集输入数据
:param y_test: 测试集真实输出
:param model: 模型
"""
y_pred = model.feedforward(X_test)
plt.plot(y_test, label='True')
plt.plot(y_pred, label='Predicted')
plt.legend()
plt.show()
def main():
# 读取训练集和测试集数据
X_train, y_train = load_data('train.xlsx')
X_test, y_test = load_data('test.xlsx')
# 归一化
X_train_norm = normalize(X_train)
X_test_norm = normalize(X_test)
# 初始化权重
weights1, bias1, weights2, bias2 = initialize_weights(8, 8, 1)
# 创建模型
model = BP_Network(8, 8, 1)
model.weights1 = weights1
model.bias1 = bias1
model.weights2 = weights2
model.bias2 = bias2
# 训练模型
epochs = 1000
learning_rate = 0.01
lambda_value = 0.01
batch_size = 32
mini_batches = mini_batch(X_train_norm, y_train, batch_size)
errors = []
for i in range(epochs):
for mini_X, mini_y in mini_batches:
output = model.feedforward(mini_X)
delta = model.backward(mini_X, mini_y, output)
reg = regularization(model.weights1, model.weights2, lambda_value)
errors.append(delta + reg)
if i % 100 == 0:
print("Epoch %d error: %.10f" % (i, delta))
print("Epoch %d output: %s" % (i, str(output)))
model.weights1 = model.weights1 + learning_rate * (model.weights1 - lambda_value * model.weights1)
model.weights2 = model.weights2 + learning_rate * (model.weights2 - lambda_value * model.weights2)
# 输出各输入的权重
print("weights1: %s" % str(model.weights1))
print("weights2: %s" % str(model.weights2))
# 将模型输出为文件
model.save_model('model.npz')
# 绘制R2图和拟合折线图
plot_R2(X_test_norm, y_test, model)
plot_fitting(X_test_norm, y_test, model)
# 输出MAE、MSE、预测值和真实值之间的相对误差平均百分比
y_pred = model.feedforward(X_test_norm)
mae = np.mean(np.abs(y_test - y_pred))
mse = np.mean(np.square(y_test - y_pred))
error_rate = np.mean(np.abs((y_test - y_pred) / y_test)) * 100
print("MAE: %.4f" % mae)
print("MSE: %.4f" % mse)
print("Error rate: %.4f%%" % error_rate)
if __name__ == '__main__':
main()
```
在运行主函数模块main.py之前,需要先创建train.xlsx和test.xlsx两个表格文件,并将训练集和测试集数据分别存储在这两个文件中。其中,训练集数据应包含3000行、8列矩阵,测试集数据应包含40行、8列矩阵。
运行main.py后,程序会输出训练过程中的误差、模型的输出、各输入的权重、MAE、MSE、预测值和真实值之间的相对误差平均百分比等信息,并且会绘制R2图和测试集的各输入对应的实际输出和预测输出的拟合折线图。此外,程序还会将训练后的BP网络模型输出为一个文件model.npz。
阅读全文