使用 Numpy 编写一个前馈神经网络。隐层数量可设置,每层神 经元个数可设置,激活函数用 ReLu。思考 BP 算法怎么设计,难点 是什么。
时间: 2024-03-06 18:52:21 浏览: 89
好的,关于你的问题,我可以给出以下代码示例:
```
import numpy as np
class NeuralNetwork:
def __init__(self, layers, activation="relu"):
self.layers = layers
self.activation = activation
self.weights = [np.random.randn(layers[i], layers[i+1]) for i in range(len(layers)-1)]
self.biases = [np.zeros((1, layers[i+1])) for i in range(len(layers)-1)]
def relu(self, z):
return np.maximum(0, z)
def relu_derivative(self, z):
z[z<=0] = 0
z[z>0] = 1
return z
def feedforward(self, X):
a = X
for i in range(len(self.layers)-1):
z = np.dot(a, self.weights[i]) + self.biases[i]
if self.activation == "relu":
a = self.relu(z)
return a
def backpropagation(self, X, y, learning_rate):
z_s = []
a_s = [X]
a = X
for i in range(len(self.layers)-1):
z = np.dot(a, self.weights[i]) + self.biases[i]
z_s.append(z)
if self.activation == "relu":
a = self.relu(z)
a_s.append(a)
delta = (a_s[-1] - y) * self.relu_derivative(z_s[-1])
for i in range(len(self.layers)-2, -1, -1):
delta = np.dot(delta, self.weights[i].T) * self.relu_derivative(z_s[i])
self.weights[i] -= learning_rate * np.dot(a_s[i].T, delta)
self.biases[i] -= learning_rate * np.sum(delta, axis=0, keepdims=True)
def train(self, X, y, learning_rate, epochs):
for i in range(epochs):
self.backpropagation(X, y, learning_rate)
if i % 100 == 0:
loss = np.mean(np.square(y - nn.feedforward(X)))
print("Loss after epoch {}: {}".format(i, loss))
X = np.array([[0,0], [0,1], [1,0], [1,1]])
y = np.array([[0], [1], [1], [0]])
nn = NeuralNetwork([2, 4, 1])
nn.train(X, y, 0.1, 1000)
```
这是一个两层的前馈神经网络,可以通过修改 `layers` 参数来设置不同的层数和每层神经元个数。激活函数使用的是 ReLU 函数,可以通过修改 `activation` 参数来使用其他激活函数。训练函数使用的是基本的反向传播算法。
BP 算法的难点在于反向传播的实现,需要对每层的权重和偏差进行更新,同时需要正确计算每层的误差信号。此外,在实际应用中,还需要考虑参数初始化、学习率、正则化等问题。
阅读全文