📜  使用 NumPy 从零开始实现神经网络(1)

📅  最后修改于: 2023-12-03 15:36:32.429000             🧑  作者: Mango

使用 NumPy 从零开始实现神经网络

在机器学习和深度学习中,神经网络是一种非常关键的算法。本文将介绍如何使用 NumPy 从零开始实现神经网络。

神经网络的基本原理

神经网络是一种使用多层节点来处理信息的算法。它的基本原理是对输入信号进行线性变换和非线性变换,逐层引入“激活函数”,并不断调整权重和偏置值,从而逐步建立模型。

用 NumPy 实现神经网络

首先,我们需要导入 NumPy 库:

import numpy as np

我们将使用 NumPy 来创建我们的数据集,并定义神经网络的结构。我们将创建一个包含两个输入、两个输出和一个隐藏层(包含两个节点)的神经网络:

# 设置神经网络的输入输出和隐藏层大小
input_size = 2
hidden_size = 2
output_size = 2

# 随机初始化神经网络的参数
w1 = np.random.randn(input_size, hidden_size)
b1 = np.zeros((1, hidden_size))
w2 = np.random.randn(hidden_size, output_size)
b2 = np.zeros((1, output_size))

我们使用随机初始化来确保训练的起点不会影响模型的性能。接下来,我们定义模型的前向传播函数:

# 定义模型的前向传播函数
def forward(X, w1, b1, w2, b2):
    # 对隐藏层进行加权和,并使用 ReLU 激活函数
    z1 = np.dot(X, w1) + b1
    a1 = np.maximum(z1, 0)
    # 对输出层进行加权和
    z2 = np.dot(a1, w2) + b2
    # 使用 softmax 函数计算输出层的概率分布
    exp_scores = np.exp(z2)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
    return probs

该函数接受一个输入矩阵 X 和神经网络的所有参数,计算并返回输出层的概率分布。

我们使用 softmax 函数来计算输出层的概率分布,使输出层的激活值总和为 1。现在,我们可以定义一个损失函数来衡量模型的性能:

# 定义损失函数(交叉熵)
def calculate_loss(X, y, w1, b1, w2, b2):
    # 计算前向传播结果
    probs = forward(X, w1, b1, w2, b2)
    # 计算交叉熵损失
    corect_logprobs = -np.log(probs[range(len(X)), y])
    data_loss = np.sum(corect_logprobs)
    return 1./len(X) * data_loss

该函数接受输入矩阵 X、目标输出 y 和神经网络的所有参数,计算并返回模型的交叉熵损失。

我们使用 -np.log(probs[range(len(X)), y]) 来计算正确输出的概率的对数,并将相应的减法视为损失。接下来,我们使用反向传播来更新神经网络的所有参数:

# 定义反向传播函数
def backward(X, y, probs, w1, b1, w2, b2, learning_rate=0.1):
    # 计算输出层的误差
    delta3 = probs
    delta3[range(len(X)), y] -= 1
    # 计算隐藏层的误差
    delta2 = np.dot(delta3, w2.T) * (a1 > 0)
    # 更新权重和偏置值
    w1 -= learning_rate * np.dot(X.T, delta2)
    b1 -= learning_rate * np.sum(delta2, axis=0, keepdims=True)
    w2 -= learning_rate * np.dot(a1.T, delta3)
    b2 -= learning_rate * np.sum(delta3, axis=0, keepdims=True)
    return w1, b1, w2, b2

该函数接受一些与前向传播相同的输入,并计算所有层的误差。接下来,它使用学习率来更新所有参数。

现在,我们可以创建一个完整的神经网络,用它来拟合一个简单的分类问题:

# 创建一个简单的分类问题
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 1, 1, 0])

# 训练神经网络
for i in range(20000):
    # 计算前向传播
    probs = forward(X, w1, b1, w2, b2)
    # 计算误差
    loss = calculate_loss(X, y, w1, b1, w2, b2)
    # 反向传播更新参数
    w1, b1, w2, b2 = backward(X, y, probs, w1, b1, w2, b2, learning_rate=0.1)
    if i % 1000 == 0:
        print(f"Iteration {i}: loss {loss}")

# 输出预测结果
print(f"Final predictions: {np.argmax(probs, axis=1)}")

我们可以看到,神经网络能够正确地学习和预测给定的分类问题。

总结

本文介绍了如何使用 NumPy 从零开始实现一个神经网络。通过创建数据集、定义神经网络结构、实现前向传播、反向传播和更新参数,我们可以训练一个可以成功分类数据的模型。