使用NumPy演示​​实现神经网络过程

在不断发展的人工智能(模拟智能)领域,有一个想法经久不衰,并被证明是当今机器学习的基础:人工神经网络(ANN)。这些计算模型在人类思维不可预测的神经元网络的推动下,在从图像识别到自然语言处理的任务中表现出了惊人的能力。在本文中,我们将继续揭开人工神经网络内部功能的神秘面纱,并重点讨论为什么从头开始构建神经网络可能是一次无价的学习体验。

人工神经网络
人工神经网络,通常称为神经网络,有着丰富的历史,可以追溯到二十世纪中叶。他们的起源是由于渴望制造能够模拟人类大脑复杂动态循环的机器。早期的开拓者,例如普莱恩·罗森布拉特(Plain Rosenblatt)和沃伦·麦卡洛克(Warren McCulloch),为神经网络奠定了假设性的准备,而直到现代处理技术出现之后,这些想法才可以用于所有意图和目的。

人工神经网络的核心是包含互连中枢或神经元的计算模型。这些神经元协同工作来处理和改变输入信息,最终给出结果。神经元之间的每一个关联都与一个权重相关,权重决定了关联的强度。神经元将启动能力应用于其反馈位的加权量,从而使模型熟悉非线性。

  • 您可能会问,当可以使用 TensorFlow 和 PyTorch 等强大的深度学习库时,为什么有人需要从头开始执行神经网络。
  • 深度学习结构提供了预先组装的神经网络层和准备技术,使复杂的任务看起来具有误导性。即便如此,这种妥协往往是以牺牲理解为代价的。
  • 从头开始构建神经网络需要考虑对模型每个部分的细粒度命令。当您遇到错误或不可预见的行为方式时,您不会被忽视。
  • 深度学习领域正处于永无止境的发展状态。新模型、驱动能力和改进策略不断出现。

神经元:计算单位
任何神经网络的核心都是神经元。这些是负责处理数据的计算单元。神经元获取输入、执行估计并产生结果。在神经网络中,神经元被协调成层,通常包括信息层、至少一个秘密层和结果层。神经元之间的关联(每个关联都与权重相关)增强了数据流的能力。

前馈过程
前馈过程是信息通过神经网络从信息层移动到结果层的组成部分。可以很好地总结如下:

输入层:信息在信息层中处理。

加权总计:后续层中的每个神经元都会计算出其反馈位的加权量。

激活函数:加权总和经过激活函数,呈现非线性。

结果:激活函数的结果成为下一层的贡献,并且过程重新哈希,直到到达结果层。

激活函数:添加非线性
激活函数在神经网络中扮演着重要的角色。它们呈现非线性,使神经网络能够学习复杂的例子。两个正常的激活函数是 sigmoid 函数和 Corrected Direct Unit (ReLU) 函数:

Sigmoid 函数:它将信息值压缩在 0 到 1 之间的某个位置,可以将其解读为概率。它对于配对表征问题的结果层很有帮助。

ReLU 函数:如果信息值确定并且为零,它会生成信息值。ReLU 因其轻松性和可行性而成为大多数隐藏层的默认选择。

权重初始化和偏差项
神经网络中的负载对于学习来说是紧迫的。权重声明包括设置这些负载的潜在优势。正常程序包括任意介绍、Xavier/Glorot 和 He 陈述。适当的重量引入可以完全影响制备过程。

偏差项是神经元中添加的物质常数。它们允许神经元通过移动激活函数的结果来显示更复杂的功能。每个神经元都有其偏置项。

使用 NumPy 的神经网络实现代码过程

第 1 步:制作数据集
为了使用我们的神经网络,我们需要一个数据集来训练和测试其表现:
生成示例:我们表征字母 A、B 和 C 的矩阵示例。这些示例充当训练和测试神经网络的输入数据。每个示例都是双重连续,用于解决单独字母的状态。


# 创建数据集  
letter_a = np.array([ 0 ,  0 ,  1 ,  1 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  1 ,  0 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ])  
letter_b = np.array([ 0 ,  1 ,  1 ,  1 ,  1 ,  0 ,  0 ,  1 ,  0 ,  0 ,  1 ,  0 ,  0 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ])  
letter_c = np.array([ 0 ,  1 ,  1 ,  1 ,  1 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ,  0 ,  0 ,  0 ,  0 ,  1 ])  
  
# 将模式合并到数据集中  
x = np.array([letter_a, letter_b, letter_c])  

步骤 2:描述标签特征
对于定向学习来说,我们希望标记能展示正确的反应:

命名数据:我们为字母 A、B 和 C 标出了单次编码标记。
单次编码是一种从数学角度处理直观数据的方法,其中每一类都具有显著的并行价值。在训练过程中,这些名称允许神经网络学习并将设计与其相关字母联系起来。

# Define labels (one-hot encoding)  
y = np. array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])  

步骤 3:导入程序库并确定激活函数的特性
在这一基础步骤中,我们将建立神经网络:

导入库:我们导入基本库,如用于熟练数学任务的 NumPy 和用于数据可视化的 Matplotlib。这些库为我们提供了构建和评估神经网络所需的工具。

定义西格码Sigmoid激活函数:我们将描述神经网络的关键部分--西格码激活函数。该函数将非线性引入网络输出,使其能够展示数据中的复杂连接。

import numpy as np  
import matplotlib.pyplot as plt  
  
# Activation function (Sigmoid)  
def sigmoid(x):  
    return 1 / (1 + np.exp(-x))  

步骤 4:初始化权重
在这一步中,我们要为神经网络的可学习边界设定基础条件:

权重Weights:我们创建一个函数,为神经网络中神经元之间的关联创建不规则权重。
这些权重非常重要,因为它们控制着数据在训练过程中如何通过网络。
杂乱无章地随机引入权重可以让网络从数据中获益,并长期调整权重。
(权重可能是代表不同上下文、场景和语境,不同权重能够让神经网络在不同场景下训练学习,就像小孩要多动,多换不同场景,对小孩智力有好处)

# Initialize weights randomly  
def generate_weights(input_size, output_size):  
    return np.random.randn(input_size, output_size)  

步骤 5:描述前馈神经网络的特征
这一步描述神经网络的工程和前向传递特性:

定义神经网络设计:我们确定神经网络的结构,记住每一层的层数和神经元数。在这种情况下,我们有一个输入层、一个隐藏层和一个输出层。前馈函数接收输入,并通过这些层来计算网络的输出。

# Create the Feedforward Neural Network  
输入层 Input layer (1, 30)  
# 隐藏层Hidden layer (1, 5)  
输出层 Output layer (3, 3)  
def feed_forward(x, w1, w2):  
    # Hidden layer  
    z1 = x.dot(w1)  # Input from layer 1  
    a1 = sigmoid(z1)  # Output of layer 2  
  
    # Output layer  
    z2 = a1.dot(w2)  # Input of output layer  
    a2 = sigmoid(z2)  # Output of output layer  
    return a2  

第 6 步:确定损失函数的特征
在这一步中,我们将介绍神经网络如何评估其演示:

定义损失函数:我们描述了均方误差(MSE:mean squared error)损失函数的特征,该函数用于估算预期输出与真实客观质量之间的差异。MSE 可评估神经网络的预测与真实数据的吻合程度,为网络在训练过程中计划限制的数学收益提供依据。

# Mean Square Error (MSE) Loss Function  
def loss(output, target):  
    squared_error = np.square(output - target)  
    mean_squared_error = np.mean(squared_error)  
    return mean_squared_error  

步骤 7:误差反向传播
在这一步中,我们将根据预测误差设置刷新神经网络权重的组件:

执行反向传播:我们进行反向传播计算,这是训练神经网络的重要部分。反向传播计算有关网络权重损失的斜率,使我们能够朝着减少损失的方向改变权重。这种迭代循环对网络的学习和演示工作至关重要。

这些基本步骤为构建、训练和评估不同任务的神经网络奠定了基础。代码中的后续步骤将在这些标准的基础上进行扩展,从而形成一个完整的神经网络,并将其应用于特定问题。

# Backpropagation of error  
def back_propagation(x, y, w1, w2, learning_rate):  
    # Hidden layer  
    z1 = x.dot(w1)  # Input from layer 1  
    a1 = sigmoid(z1)  # Output of layer 2  
  
    # Output layer  
    z2 = a1.dot(w2)  # Input of output layer  
    a2 = sigmoid(z2)  # Output of output layer  
  
    # Error in the output layer  
    d2 = (a2 - y)  
    d1 = np.multiply(w2.dot(d2.T).T, np.multiply(a1, 1 - a1))  
  
    # w1 和 w2 的梯度  ;
    w1_gradient = x.T.dot(d1)  
    w2_gradient = a1.T.dot(d2)  
  
    # Update parameters  
    w1 -= learning_rate * w1_gradient  
    w2 -= learning_rate * w2_gradient  
  
    return w1, w2  


步骤 8:训练神经网络
在这一步中,我们的中心工作是训练神经网络,以便从数据集中获取信息,并在一段时间后进行改进:

训练函数:我们确定一个专门的函数来训练神经网络。该功能包括在预定的年龄段内对数据集进行强调。在每个年龄段,网络都会进行预测,处理精确度和损失测量,并利用反向传播计算更新权重。结果就是一个不断发展的神经网络,它能从数据中获益,并努力改善其表现形式。

# Training the neural network  
def train_neural_network(x, y, w1, w2, learning_rate=0.01, epochs=10):  
    accuracy = []  
    losses = []  
      
    for epoch in range(epochs):  
        epoch_losses = []  
        for i in range(len(x)):  
            output = feed_forward(x[i], w1, w2)  
            loss_value = loss(output, y[i])  
            epoch_losses.append(loss_value)  
            w1, w2 = back_propagation(x[i], y[i], w1, w2, learning_rate)  
          
        accuracy.append((1 - (sum(epoch_losses) / len(x))) * 100)  
        losses.append(sum(epoch_losses) / len(x))  
          
        print(f'Epoch: {epoch + 1}, Accuracy: {accuracy[-1]:.2f}%')  
      
    return accuracy, losses, w1, w2  


步骤 9:使用训练后的模型进行预测
神经网络经过训练后,往往会用于预测:

预测函数:我们将训练好的模型(如 trained_w1 和 trained_w2)和输入设计作为输入,创建一个函数。该函数根据输出层的最大输出值预测最可能的字母(A、B 或 C)。这一步骤展示了如何将训练有素的神经网络应用于新数据以进行预测。

# Predicting the letter from an input pattern  
def predict_letter(input_pattern, w1, w2):  
    output = feed_forward(input_pattern, w1, w2)  
    max_index = np.argmax(output)  
      
    if max_index == 0:  
        return 'A'  
    elif max_index == 1:  
        return 'B'  
    else:  
        return 'C'  

步骤 10:为训练初始化权重
要开始训练,我们需要为神经网络设置入门条件:

权重初始化:我们以不规则质量初始化权重 w1 和 w2。这些权重决定了数据如何在网络中移动,是学习的重要组成部分。不规则的初始化为网络提供了一个获取数据的起始阶段。

# Initialize weights  
w1 = generate_weights(30, 5)  
w2 = generate_weights(5, 3)  

步骤 11:训练神经网络
准备好数据、标记和权重后,我们继续训练神经网络:

训练交互:我们调用训练函数(如 train_neural_network)来启动训练系统。神经网络会反复刷新权重、筛选精度和损失,并改变其边界,以便在无数次(训练周期)中进一步提高执行力。训练包括调整网络以做出准确预测。

# Train the neural network  
acc, losses, trained_w1, trained_w2 = train_neural_network(x, y, w1, w2, learning_rate=0.1, epochs=100) 

输出:

Epoch: 1, Accuracy: 33.33%
Epoch: 2, Accuracy: 66.67%
Epoch: 3, Accuracy: 66.67%
Epoch: 4, Accuracy: 66.67%
Epoch: 5, Accuracy: 66.67%
Epoch: 6, Accuracy: 66.67%
Epoch: 7, Accuracy: 66.67%
Epoch: 8, Accuracy: 66.67%
Epoch: 9, Accuracy: 66.67%
Epoch: 10, Accuracy: 66.67%
Epoch: 11, Accuracy: 66.67%
Epoch: 12, Accuracy: 66.67%
Epoch: 13, Accuracy: 66.67%
Epoch: 14, Accuracy: 66.67%
Epoch: 15, Accuracy: 66.67%
Epoch: 16, Accuracy: 66.67%
Epoch: 17, Accuracy: 66.67%
Epoch: 18, Accuracy: 66.67%
Epoch: 19, Accuracy: 66.67%
Epoch: 20, Accuracy: 66.67%
Epoch: 21, Accuracy: 66.67%
Epoch: 22, Accuracy: 66.67%
Epoch: 23, Accuracy: 66.67%
Epoch: 24, Accuracy: 66.67%
Epoch: 25, Accuracy: 66.67%
Epoch: 26, Accuracy: 66.67%
Epoch: 27, Accuracy: 66.67%
Epoch: 28, Accuracy: 66.67%
Epoch: 29, Accuracy: 66.67%
Epoch: 30, Accuracy: 66.67%
Epoch: 31, Accuracy: 66.67%
Epoch: 32, Accuracy: 66.67%
Epoch: 33, Accuracy: 66.67%
Epoch: 34, Accuracy: 66.67%
Epoch: 35, Accuracy: 66.67%
Epoch: 36, Accuracy: 66.67%
Epoch: 37, Accuracy: 66.67%
Epoch: 38, Accuracy: 66.67%
Epoch: 39, Accuracy: 66.67%
Epoch: 40, Accuracy: 66.67%
Epoch: 41, Accuracy: 66.67%
Epoch: 42, Accuracy: 66.67%
Epoch: 43, Accuracy: 66.67%
Epoch: 44, Accuracy: 66.67%
Epoch: 45, Accuracy: 66.67%
Epoch: 46, Accuracy: 66.67%
Epoch: 47, Accuracy: 66.67%
Epoch: 48, Accuracy: 66.67%
Epoch: 49, Accuracy: 66.67%
Epoch: 50, Accuracy: 66.67%
Epoch: 50, Accuracy: 66.67%
Epoch: 51, Accuracy: 100.00%
Epoch: 52, Accuracy: 100.00%
Epoch: 53, Accuracy: 100.00%
Epoch: 54, Accuracy: 100.00%
Epoch: 55, Accuracy: 100.00%
Epoch: 56, Accuracy: 100.00%
Epoch: 57, Accuracy: 100.00%
Epoch: 58, Accuracy: 100.00%
Epoch: 59, Accuracy: 100.00%
Epoch: 60, Accuracy: 100.00%
Epoch: 61, Accuracy: 100.00%
Epoch: 62, Accuracy: 100.00%
Epoch: 63, Accuracy: 100.00%
Epoch: 64, Accuracy: 100.00%
Epoch: 65, Accuracy: 100.00%
Epoch: 66, Accuracy: 100.00%
Epoch: 67, Accuracy: 100.00%
Epoch: 68, Accuracy: 100.00%
Epoch: 69, Accuracy: 100.00%
Epoch: 70, Accuracy: 100.00%
Epoch: 71, Accuracy: 100.00%
Epoch: 72, Accuracy: 100.00%
Epoch: 73, Accuracy: 100.00%
Epoch: 74, Accuracy: 100.00%
Epoch: 75, Accuracy: 100.00%
Epoch: 76, Accuracy: 100.00%
Epoch: 77, Accuracy: 100.00%
Epoch: 78, Accuracy: 100.00%
Epoch: 79, Accuracy: 100.00%
Epoch: 80, Accuracy: 100.00%
Epoch: 81, Accuracy: 100.00%
Epoch: 82, Accuracy: 100.00%
Epoch: 83, Accuracy: 100.00%
Epoch: 84, Accuracy: 100.00%
Epoch: 85, Accuracy: 100.00%
Epoch: 86, Accuracy: 100.00%
Epoch: 87, Accuracy: 100.00%
Epoch: 88, Accuracy: 100.00%
Epoch: 89, Accuracy: 100.00%
Epoch: 90, Accuracy: 100.00%
Epoch: 91, Accuracy: 100.00%
Epoch: 92, Accuracy: 100.00%
Epoch: 93, Accuracy: 100.00%
Epoch: 94, Accuracy: 100.00%
Epoch: 95, Accuracy: 100.00%
Epoch: 96, Accuracy: 100.00%
Epoch: 97, Accuracy: 100.00%
Epoch: 98, Accuracy: 100.00%
Epoch: 99, Accuracy: 100.00%
Epoch: 100, Accuracy: 100.00%

步骤 12:打印训练过的权重
训练结束后,我们可以查看神经网络的学习边界:

训练过的权重:我们将打印训练过的权重、trained_w1 和 trained_w2。这些权重涉及神经网络通过训练获得的内部信息。它们决定了网络处理输入数据和进行预测的方式。

# Print the trained weights  
print("Trained w1:\n", trained_w1)  
print(
"Trained w2:\n", trained_w2)  


输出:

Trained w1:
 [[ 0.06927115  0.7170005   0.33890342 -0.3954869  -0.21926859]
 [ 0.39601103  0.24753036  0.62160906  0.63111717 -0.05278294]
 [ 0.18818433 -0.37276832 -0.30979065  0.11647701 -0.21607048]
 [-0.46407453 -0.36126427  0.57640027  0.0487203  -0.42107692]
 [-0.46414489  0.46295603  0.46470836 -0.00936389 -0.22831723]
 [-0.26479341 -0.46326617 -0.37647503  0.0966695   0.13562841]
 [ 0.15554735  0.48902724  0.09104169  0.44204394 -0.36605067]
 [-0.03405944  0.04821714  0.29438268 -0.18500043 -0.18425598]
 [ 0.4287369  -0.43919064  0.20607397 -0.39208925  0.01190859]
 [ 0.03697536 -0.2565317   0.49294935 -0.40878913 -0.0538658 ]
 [ 0.09247709 -0.46691897  0.2993611  -0.44151021 -0.11589155]
 [ 0.44711659  0.43345584 -0.14237594 -0.26750368 -0.35513504]
 [-0.40188012  0.15407098  0.20029012 -0.37305893  0.31064633]
 [-0.10865365 -0.19502014 -0.35841558  0.42077795  0.01395011]
 [-0.47082317  0.42016455  0.33085363 -0.36138929 -0.01264705]
 [ 0.35739056 -0.44810259  0.28772079 -0.47210845 -0.01000285]
 [ 0.28254812  0.23523711 -0.33713807  0.26875264 -0.29387359]
 [ 0.42204963  0.00467407 -0.35421835 -0.33040688 -0.00828009]
 [-0.17754328  0.01683268 -0.48541489 -0.44149293 -0.18717054]
 [ 0.09807447  0.22537154  0.18945719  0.43059284 -0.08616275]
 [ 0.44205102 -0.37058663 -0.00536636 -0.16823561 -0.38458703]
 [-0.2124118   0.26696481 -0.22020708  0.30137899  0.45820239]
 [-0.20769434 -0.10460072 -0.30606344 -0.36652411  0.31277555]
 [-0.2070754   0.15518452  0.23822402  0.45175688 -0.20221053]
 [ 0.29657844 -0.44922159 -0.20853836 -0.05554754 -0.05145613]
 [ 0.37466171 -0.26950233 -0.34559416 -0.45765506 -0.29738787]
 [ 0.16390897  0.45549364 -0.29073935 -0.21781543  0.41897006]
 [-0.37249767 -0.35012648 -0.08188436 -0.2364289   0.35996595]
 [ 0.21530958  0.12035867  0.2270742  -0.1902335   0.17511611]
 [-0.38768864  0.0706518  -0.02868765  0.00820532 -0.33814097]]

Trained w2:
 [[-0.51545134 -1.00575607  0.19420588]
 [-0.49013258 -0.9501272  -0.1448687 ]
 [ 0.76347089  1.28824926 -0.10032262]
 [ 0.43072838  0.72880314 -0.02726307]
 [ 0.08850882  0.22300994 -0.47452975]]

第 13 步:利用训练的模型进行预测
有了训练有素的神经网络,我们就可以将其应用于可证明的情况:

预测:我们利用训练有素的模型对另一个输入设计进行预测。将输入通过网络,我们就能得到预测结果,显示网络认为该示例与哪个字母(A、B 或 C)有关。这一步展示了训练有素的模型的实用性。

# Make predictions with the trained model  
new_input = np.array([0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])  
prediction = predict_letter(new_input, trained_w1, trained_w2)  
print(f'Predicted letter : {prediction}')  

输出:
Predicted Letter: A