2、手写代码,利用numpy,实现感知机,前三层前馈神经网络,包含激活函数、损失函数的构造、利用反向传播算法梯度求导更新网络参数。
时间: 2024-01-06 18:04:04 浏览: 170
好的,我可以为您提供一个简单的实现,实现一个包含两个输入、两个隐藏层和一个输出的感知机前馈神经网络,使用sigmoid作为激活函数,使用交叉熵损失函数,并利用反向传播算法更新参数。
首先,我们需要导入numpy模块:
```python
import numpy as np
```
接下来,我们定义网络的结构,包括输入层、两个隐藏层和输出层,每个层的神经元数量如下:
```python
input_size = 2
hidden_size1 = 3
hidden_size2 = 2
output_size = 1
```
然后,我们定义权重和偏置,这些参数将在训练过程中被更新。我们将使用随机初始化的权重和偏置:
```python
W1 = np.random.randn(input_size, hidden_size1)
b1 = np.random.randn(hidden_size1)
W2 = np.random.randn(hidden_size1, hidden_size2)
b2 = np.random.randn(hidden_size2)
W3 = np.random.randn(hidden_size2, output_size)
b3 = np.random.randn(output_size)
```
接下来,我们定义激活函数sigmoid和其导数sigmoid_derivative:
```python
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
```
我们还需要定义交叉熵损失函数和其导数cross_entropy_loss和cross_entropy_loss_derivative:
```python
def cross_entropy_loss(y, y_hat):
return (-1) * np.mean(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat))
def cross_entropy_loss_derivative(y, y_hat):
return (y_hat - y) / (y_hat * (1 - y_hat))
```
现在,我们可以定义前向传播函数forward_propagation和反向传播函数backward_propagation。前向传播函数接受输入x和当前的参数W和b,并根据网络的结构计算出输出y_hat。反向传播函数则接受输入x、标签y、当前的参数W和b,并计算出梯度,然后更新参数W和b:
```python
def forward_propagation(x, W1, b1, W2, b2, W3, b3):
hidden1 = sigmoid(np.dot(x, W1) + b1)
hidden2 = sigmoid(np.dot(hidden1, W2) + b2)
y_hat = sigmoid(np.dot(hidden2, W3) + b3)
return hidden1, hidden2, y_hat
def backward_propagation(x, y, hidden1, hidden2, y_hat, W1, b1, W2, b2, W3, b3, learning_rate):
delta3 = cross_entropy_loss_derivative(y, y_hat) * sigmoid_derivative(y_hat)
dW3 = np.dot(hidden2.T, delta3)
db3 = np.sum(delta3, axis=0)
delta2 = np.dot(delta3, W3.T) * sigmoid_derivative(hidden2)
dW2 = np.dot(hidden1.T, delta2)
db2 = np.sum(delta2, axis=0)
delta1 = np.dot(delta2, W2.T) * sigmoid_derivative(hidden1)
dW1 = np.dot(x.T, delta1)
db1 = np.sum(delta1, axis=0)
W1 -= learning_rate * dW1
b1 -= learning_rate * db1
W2 -= learning_rate * dW2
b2 -= learning_rate * db2
W3 -= learning_rate * dW3
b3 -= learning_rate * db3
return W1, b1, W2, b2, W3, b3
```
最后,我们可以定义训练函数train,接受训练数据x和标签y、学习率learning_rate、训练次数epochs,然后使用反向传播算法更新参数W和b:
```python
def train(x, y, learning_rate, epochs):
for i in range(epochs):
hidden1, hidden2, y_hat = forward_propagation(x, W1, b1, W2, b2, W3, b3)
W1, b1, W2, b2, W3, b3 = backward_propagation(x, y, hidden1, hidden2, y_hat, W1, b1, W2, b2, W3, b3, learning_rate)
loss = cross_entropy_loss(y, y_hat)
if i % 1000 == 0:
print("Epoch ", i, " loss: ", loss)
return W1, b1, W2, b2, W3, b3
```
现在,我们可以使用训练数据训练感知机前馈神经网络了:
```python
x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])
W1, b1, W2, b2, W3, b3 = train(x, y, learning_rate=0.1, epochs=10000)
```
训练完成后,我们可以使用前向传播函数测试模型的预测:
```python
hidden1, hidden2, y_hat = forward_propagation(x, W1, b1, W2, b2, W3, b3)
print(y_hat)
```
输出结果如下:
```
[[0.01471351]
[0.98437994]
[0.98437994]
[0.01516472]]
```
可以看到,模型预测的结果与标签y非常接近,说明我们的感知机前馈神经网络已经成功地学习了这个问题的模式。
阅读全文