在机器学习领域,神经网络是最为常见且有效的一种算法。Python作为一种广泛应用于数据处理和机器学习分析的编程语言,其实现神经网络非常容易。
Python神经网络的基本结构包括输入层、隐藏层和输出层,其中包含多个神经元。每个神经元接受来自其他神经元的信号,加权求和后通过激活函数输出结果。
下面我们将解析Python神经网络的基本代码,以便读者更好地理解神经网络的实现原理。
1. 引入库
import numpy as np #使用numpy进行矩阵计算
import matplotlib.pyplot as plt #使用matplotlib进行数据可视化
2. 定义sigmoid函数
sigmoid函数是常用的激活函数之一,其数学表达式为:
$f(x)=\frac{1}{1+e^{-x}}$
其在神经网络的计算过程中起到了很重要的作用。在Python代码中,可以这样定义sigmoid函数:
def sigmoid(x):
return 1 /(1 + np.exp(-x))
3. 初始化参数
在神经网络中,初始化参数非常重要。我们需要随机初始化权重矩阵和偏置向量,以保证训练时每个节点都能拥有不同的权重值,并使得在反向传播时能够更新权重矩阵。
def init_parameter(input_size, hidden_size, output_size):
# 初始化权重矩阵和偏置向量
W1 = np.random.randn(hidden_size, input_size) * 0.01
b1 = np.zeros((hidden_size, 1))
W2 = np.random.randn(output_size, hidden_size) * 0.01
b2 = np.zeros((output_size, 1))
# 使用字典保存参数,方便传递参数
parameter = {“W1”: W1,
“b1”: b1,
“W2”: W2,
“b2”: b2}
return parameter
4. 前向传播
前向传播是神经网络计算中的重要阶段。在前向传播过程中,我们需要计算隐藏层和输出层的值。我们可以使用 sigmoid 函数激活我们的隐藏和输出节点。下面是前向传播代码的实现:
def forward_propagation(X, parameter):
# 获取参数
W1 = parameter[“W1”]
b1 = parameter[“b1”]
W2 = parameter[“W2”]
b2 = parameter[“b2”]
# 隐藏层的计算
Z1 = np.dot(W1, X) + b1
A1 = sigmoid(Z1)
# 输出层的计算
Z2 = np.dot(W2, A1) + b2
A2 = sigmoid(Z2)
# 使用字典存储计算结果,方便后续使用
cache = {“Z1”: Z1,
“A1”: A1,
“Z2”: Z2,
“A2”: A2}
return A2, cache
5. 计算损失函数
损失函数是神经网络训练中的重要指标。我们需要计算损失函数对于神经网络中所有权重和偏置的偏导数来更新模型,以达到更好的训练效果。
在神经网络中,常用的损失函数是交叉熵函数,其数学表达式为:
$J(w,b)=-\frac{1}{m}\sum_{i=1}^{m}[y^{(i)} log a^{(i)} +(1-y^{(i)}) log (1-a^{(i)})]$
其中,$y^{(i)}$ 表示第 i 个样本的真实标签,$a^{(i)}$ 表示神经网络输出的预测值。
下面是计算损失函数代码的实现:
def compute_loss(A2, Y):
# 统计样本数量
m = Y.shape[1]
# 使用交叉熵计算损失
loss = -1 / m * np.sum(Y * np.log(A2) + (1 – Y) * np.log(1 – A2))
# 将loss转化为一个数值
loss = np.squeeze(loss)
return loss
6. 反向传播
现在我们已经计算得出了神经网络的预测值,接下来需要实现反向传播算法,以便我们更新神经网络的参数。反向传播算法可以计算损失函数对于网络中所有权重和偏置的偏导数,并使用梯度下降进行参数更新。
def backward_propagation(X, Y, cache, parameter):
# 获取样本数量
m = X.shape[1]
# 从字典参数中取出需要的参数
W1 = parameter[“W1”]
W2 = parameter[“W2”]
A1 = cache[“A1”]
A2 = cache[“A2”]
# 反向传播:计算dW1、db1、dW2、db2
dZ2= A2 – Y
dW2 = (1 / m) * np.dot(dZ2, A1.T)
db2 = (1 / m) * np.sum(dZ2, axis=1, keepdims=True)
dZ1 = np.dot(W2.T, dZ2) * sigmoid(A1) * (1 – sigmoid(A1))
dW1 = (1 / m) * np.dot(dZ1, X.T)
db1 = (1 / m) * np.sum(dZ1, axis=1, keepdims=True)
# 使用字典存储梯度,方便后续更新
gradient = {“dW1”:dW1,
“db1”:db1,
“dW2”:dW2,
“db2”:db2}
return gradient
7. 更新参数
在获得了损失函数和梯度之后,我们可以使用梯度下降算法更新神经网络的参数。
def update_parameter(parameter, gradient, learning_rate):
W1, b1, W2, b2 = parameter[“W1”], parameter[“b1”], parameter[“W2”], parameter[“b2”]
dW1, db1, dW2, db2 = gradient[“dW1”], gradient[“db1”], gradient[“dW2”], gradient[“db2”]
# 使用随机梯度下降算法更新参数
W1 = W1 – learning_rate * dW1
b1 = b1 – learning_rate * db1
W2 = W2 – learning_rate * dW2
b2 = b2 – learning_rate * db2
# 存储更新后的参数
parameter = {“W1”: W1,
“b1”: b1,
“W2”: W2,
“b2”: b2}
return parameter
8. 神经网络模型
最后,我们将上述过程汇总起来构建神经网络模型,并进行训练以及预测。
def neural_network_model(X, Y, hidden_size, output_size, num_iteration, learning_rate):
# 初始化参数
parameter = init_parameter(X.shape[0], hidden_size, output_size)
# 存储损失值数组,用于绘制损失曲线
loss_list = []
# 迭代训练神经网络
for i in range(num_iteration):
A2, cache = forward_propagation(X, parameter)
loss = compute_loss(A2,Y)
gradient = backward_propagation(X, Y, cache, parameter)
parameter = update_parameter(parameter, gradient, learning_rate)
# 打印损失函数值
if i % 100 == 0:
print(“在迭代%i次后,损失函数的值为: %f” %(i, loss))
loss_list.append(loss)
# 绘制损失函数曲线
plt.plot(loss_list)
plt.ylabel(‘loss’)
plt.xlabel(‘iteration’)
plt.show()
return parameter