一:什么叫BP神经网络
我的理解是可以拆分为BP和神经网络。BP指的是反向传播,也就是对一个对于一个多变量函数的求导过程。而神经网络就是复杂的数学计算公式。就像多层感知机一样----什么是感知机
二:BP神经网络用数学来解释
BP神经网络可以简化成这样,便于理解
该神经网络有:输入层,一个隐藏层,输出层。
先进行正向传播:
根据图示,可以把输入的数据定义为X,神经网络的权重值W,那么在输入层递进的过程可以写成"Z = WX + B "。在输入层进入隐藏层过程中使用了Signoid激活函数,则隐藏层的数据可以写成:N = F(Z) = F(WX+b)。
依次类推。最终会得到一个Y1值,再与真实的Y值算出损失值:Loss = 1/2*(Y - Y1).pow(2).
BP神经网络会进行反向传播:
通过损失函数,来反向推出W1和W2的导数。用梯度下降法调整W1和W2的值。
这样通过反向传播,可以得出W1和W2的梯度,再经过梯度下降法求W1和W2。
三:BP神经网络用代码展示
1.顺序结构来实现BP神经网络的搭建
import numpy as np
x0 = np.array([[0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1]]).T #输入数据为3*4的矩阵
y = np.array([0, 1, 1, 0]) #输出结果为1*4的矩阵
w0 = np.random.random((4, 3)) #第一层
w1 = np.random.random((1, 4)) #第二层
lr = 0.1
for j in range(60000):
z0 = np.matmul(w0, x0)
x1 = 1 / (1 + np.exp(-z0)) #用的是Signoid激活函数
z1 = np.matmul(w1, x1)
y_pred = 1 / (1 + np.exp(-z1)) #预测结果
#开始进行反向传播
ypred_delta = -(y - y_pred)
z1_delta = ypred_delta * (y_pred*(1 - y_pred)) #Signoid函数的求导值
w1_delta = np.matmul(z1_delta, x1.T)
x1_delta = np.matmul(w1.T, z1_delta)
z0_delta = x1_delta * (x1 * (1 - x1))
w0_delta = np.matmul(z0_delta, x0.T)
x0_delta = np.matmul(w0.T, z0_delta)
w1 -= lr * w1_delta
w0 -= lr* w0_delta
print(w0)
print(w1)
z0 = np.matmul(w0, x0)
x1 = 1 / (1 + np.exp(-(z0)))
z1 = np.matmul(w1, x1)
x2 = 1 / (1 + np.exp(-(z1)))
print(x2)
2.使用pytorch封装BP神经网络
- 利用pytorch中的Module类,在程序中直接继承,省去了繁琐的数学结构构造
- 数据的引用
- 定义类对象,(输入输入层,隐藏层,输出层的层数)
- 确定损失函数的计算方法(该代码采用的是构造均方差)
- 确定学习率,迭代次数
- 使用梯度下降法来求权值(在函数中要传入类对象和学习率)
- 开始迭代
在迭代过程要先计算y的预测值,利用构造的损失函数求损失值(不要忘记对所求变量的梯度清零),在对损失值进行反向传播,通过梯度下降执行一步参数更新
import torch
class BPNetwork(torch.nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(BPNetwork, self).__init__()
self.hiddden1 = torch.nn.Linear(input_size, hidden_size)
self.out = torch.nn.Linear(hidden_size, output_size)
self.signoid = torch.nn.Sigmoid()
def forward(self, x):
x = x.to(torch.float32)
x = self.hiddden1(x)
x = self.signoid(x)
x = self.out(x)
out = self.signoid(x)
return out
x0 = torch.tensor([[0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1]], dtype=torch.float32)
#y = torch.tensor([[0], [1], [1], [0]], dtype=torch.float32) #输出结果为1*4的矩阵
y = torch.tensor([[0, 1, 1, 0]], dtype=torch.float32).T
model = BPNetwork(3, 4, 1)
#构造均方差,损失函数
criterion = torch.nn.MSELoss()
lr = 0.1
#使用梯度下降法
optimizer = torch.optim.SGD(model.parameters(), lr)
epoch = 60000
for i in range(epoch):
y_pred = model(x0)
loss = criterion(y_pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print('w0=', model.hiddden1.weight.data)
print('b0=', model.hiddden1.bias.data)
print('w1=', model.out.weight.data)
print('b1=', model.out.bias.data)
y_text = model(x0)
print("预测值L:", y_text.data)