Skip to content

神经网络(ANNs)

什么是神经网络

神经网络(Neural Network)是机器学习中的一种模型,它模仿了人脑的工作方式,用来解决复杂的问题,比如图像识别、语音识别或者预测某些结果

神经网络就像一个团队在解决一个问题:团队里的每个人负责处理一小部分信息,然后把结果传递给其他人,最后团队一起得出一个结论。这个团队会通过反复练习(训练),变得越来越擅长解决问题

神经元

神经元(Neuron)是神经网络的基本单位,相当于团队里的“一个人”。它负责接收一些输入信息,做一些简单的计算,然后输出一个结果,并且将这个结果输出给下一个神经元

具体来说,一个神经元会:

  1. 接收多个输入(比如说特征矩阵)
  2. 给每个输入分配一个权重(Weight)
  3. 把所有输入加权求和,再加上一个“偏差”(Bias)
  4. 最后通过一个激活函数(Activation Function)处理这个结果,激活函数可以是之前学到的线性回归或者是逻辑回归函数

层(Layer)

层(Layer)是神经网络中的一个结构,它是由很多神经元组成的一个“小组”。每一层负责处理一部分信息,然后把结果传递给下一层。神经网络通常由多层组成,不同的层有不同的作用

  • 输入层(Input Layer):第一层,负责接收原始数据。比如你给神经网络一张图片,输入层就把图片的像素值作为输入
  • 隐藏层(Hidden Layer):中间的层,负责处理和转换信息。隐藏层可能有很多层,每一层都对数据进行更复杂的计算,提取特征(比如从图片中找出边缘、形状等)
  • 输出层(Output Layer):最后一层,负责给出最终结果。比如判断这张图片是猫还是狗,输出层会输出一个概率或分类结果

上图绿色的为输入层,蓝色的为隐藏层,黄色的为输出层,一般来说,在讨论神经网络层数的时候,输入层不参与计算,只计算隐藏层和输出层

任意隐藏层的输出激活值计算

一般形式(第 l 层)

对于第 l 层第神经元的激活值,记为 a[l],它的计算公式为:

z[l]=W[l]a[l1]+b[l]a[l]=g[l](z[l])
符号含义
W[l]l 层的权重矩阵,维度是 (n[l]×n[l1]),其中 n[l] 是当前层神经元个数
b[l]l 层的偏置向量,维度是 (n[l]×1)
a[l1]上一层(第 l1 层)的激活值(输出)
g[l]()激活函数(如 ReLU, sigmoid, tanh 等)
z[l]当前层神经元的线性加权和(未激活前的输入)
a[l]当前层神经元的输出(激活值)

假设:

  • l1 层输出: a[l1]=[0.30.70.2]

  • 当前第 l 层有 2 个神经元,那么:

    • W[l]=[0.10.20.30.10.40.5]
    • b[l]=[0.010.02]

计算过程如下:

z[l]=W[l]a[l1]+b[l]=[0.10.20.30.10.40.5][0.30.70.2]+[0.010.02]

算出 z[l] 后,再用激活函数 g() 得出 a[l]

总结为:

线性组合 + 偏置 → 激活函数 → 输出

手写前向传播

python
import numpy as np

# 设置随机种子以确保结果可重复
np.random.seed(42)

# 定义激活函数
def relu(x):
    """
    ReLU激活函数:如果输入大于0,返回输入;否则返回0
    """
    return np.maximum(0, x)

def sigmoid(x):
    """
    Sigmoid激活函数:将输入映射到0到1之间
    """
    return 1 / (1 + np.exp(-x))

# 定义神经网络的结构
input_size = 2    # 输入层:2个神经元
hidden1_size = 3  # 第一隐藏层:3个神经元
hidden2_size = 2  # 第二隐藏层:2个神经元
output_size = 1   # 输出层:1个神经元

# 初始化权重和偏差(随机初始化)
# 权重矩阵的形状为 (前一层神经元数, 当前层神经元数)
W1 = np.random.randn(input_size, hidden1_size) * 0.01  # 输入层到第一隐藏层的权重
b1 = np.zeros((1, hidden1_size))                       # 第一隐藏层的偏差
W2 = np.random.randn(hidden1_size, hidden2_size) * 0.01  # 第一隐藏层到第二隐藏层的权重
b2 = np.zeros((1, hidden2_size))                       # 第二隐藏层的偏差
W3 = np.random.randn(hidden2_size, output_size) * 0.01  # 第二隐藏层到输出层的权重
b3 = np.zeros((1, output_size))                        # 输出层的偏差

# 定义前向传播函数
def forward_propagation(X):
    """
    实现前向传播
    输入:
        X: 输入数据,形状为 (样本数, 输入层神经元数)
    输出:
        a3: 输出层的输出值
        cache: 存储中间结果(用于反向传播或其他用途)
    """
    # 第一隐藏层的计算
    z1 = np.dot(X, W1) + b1  # 加权求和 + 偏差
    a1 = relu(z1)            # 应用ReLU激活函数
    
    # 第二隐藏层的计算
    z2 = np.dot(a1, W2) + b2  # 加权求和 + 偏差
    a2 = relu(z2)            # 应用ReLU激活函数
    
    # 输出层的计算
    z3 = np.dot(a2, W3) + b3  # 加权求和 + 偏差
    a3 = sigmoid(z3)         # 应用sigmoid激活函数
    
    # 存储中间结果(可选,用于反向传播)
    cache = (z1, a1, z2, a2, z3, a3)
    
    return a3, cache

# 测试前向传播
# 假设有一个输入样本,值为 [1.0, 2.0]
X = np.array([[1.0, 2.0]])  # 形状为 (1, 2),表示1个样本,2个特征

# 执行前向传播
output, cache = forward_propagation(X)

# 打印结果
print("输入数据:", X)
print("输出结果:", output)
print("\n中间结果(z1, a1, z2, a2, z3, a3):")
for i, val in enumerate(cache):
    print(f"中间值 {i+1}: {val}")

如何理解前向传播,前向传播主要用于推理,在训练完成参数固定之后,用来预测最终结果的

上面的代码只是单个样本的特征值,我们将原始输入特征的矩阵 X,通过隐藏层的变换,神经网络可以提取更高层次的特征

在上面的代码中,我的输入层的矩阵特征有两个,第一层有三个,第二层有两个,最后一层为标量,即最终的概率

不同层的神经元数量(比如从 3 个特征到 4 个神经元)可以帮助网络调整数据的表示方式,适应不同的任务需求(分类、回归等)

最终这个概率会被整合为 cost function,在反向传播中用来优化神经元中的 wjbj

一个简单神经网络的组成(Tensorflow)

使用 Tensorflow 构建一个简单的神经网络分为三步

构建神经网络模型

这一步是定义神经网络的结构 —— 有哪些层,每层有几个神经元,是否使用激活函数等:

python
# 构建神经网络模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(units=1, input_shape=[1])  # 输入层+输出层,简单线性关系
    # 如果需要更复杂的关系,可以加隐藏层,比如:
    # tf.keras.layers.Dense(units=10, activation='relu'),  # 隐藏层
])

编译模型,选择合适的 cost function

选择优化算法(比如 SGD、Adam)和损失函数(比如均方误差)来衡量模型误差

python
# 编译模型:定义优化器、损失函数
model.compile(optimizer='sgd', loss='mean_squared_error')

反向传播,确定迭代次数

使用已有数据进行训练,Tensorflow 会自动进行前向传播和反向传播,更新参数

python
# 训练模型:用数据“喂”模型,让它学习
model.fit(X, y, epochs=500, verbose=0)  # epochs 是训练的轮数,verbose=0 表示不显示训练过程

完整代码如下:

python
import tensorflow as tf
import numpy as np

# 准备数据:房子的面积(平方米)和价格(万元)
X = np.array([100, 150, 200, 250, 300], dtype=float)  # 面积
y = np.array([200, 300, 400, 500, 600], dtype=float)  # 价格

# 构建神经网络模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(units=1, input_shape=[1])  # 输入层+输出层,简单线性关系
    # 如果需要更复杂的关系,可以加隐藏层,比如:
    # tf.keras.layers.Dense(units=10, activation='relu'),  # 隐藏层
])

# 编译模型:定义优化器、损失函数
model.compile(optimizer='sgd', loss='mean_squared_error')

# 训练模型:用数据“喂”模型,让它学习
model.fit(X, y, epochs=500, verbose=0)  # epochs 是训练的轮数,verbose=0 表示不显示训练过程

# 用模型预测新数据
# 假设有一个面积为 180 平米的房子,预测它的价格
new_house = np.array([[180]])
predicted_price = model.predict(new_house)
print(f"预测房价为:{predicted_price[0][0]:.2f} 万元")

最后更新于:

Released under the MIT License.