神经网络基础:感知机、激活函数与损失函数

一、神经网络

神经网络,什么是神经网络,从字面意思上看这个词拆分开,就是“神经”、“网络”。先来聊下神经,这是生物或者医学领域理解比较多的词,当然在计算机领域不可能去研究生物系统上的神经网络,所以通常在计算机领域神经网络指代是以“受人脑结构启发的计算模型”。是机器学习、 人工智能核心技术,本质是由无数个神经元相互构建而成的可以从数据中调整学习输出的非线性系统。

神经网络

神经网络的最小基本单元我们称之为神经元,它接收输入信号进行加权求和,再通过激活函数产生输出。这里对神经元就不表述了网上一堆解释,先了解生物神经元再抽象成人工神经元更好理解些。

连接(权重):连接不同神经元的导线,导线都有权重,权重代表的时候学习期间的重要程度,学习过程就为调整这些权重的过程。

神经元通常组织层次分类:

  • 输入层:接收原始数据

  • 隐藏层:计算与特征提取(深度学习负载度通常是看这个隐藏层的复杂度而定)

  • 输出层:输出结果层

前向传播:数据从输入层经过隐藏层,到达输出层的计算过程。

损失函数:衡量输出结果与正确答案之间差距的函数,可以理解为衡量函数。

反向传播与优化:根据损失函数的误差,从后往前调整网络中所有连接权重,使下次预测更准。

所以神经网络调优是一种调整各类权重并最终找到当前情况下最好最优权重的一种预测方法。


二、感知机模型与激活函数

1. 感知机模型

感知机是最古老、最简单的人工神经元模型,由Frank Rosenblatt在1957年提出。它可以被视为神经网络和深度学习的基础构建块。

核心思想

感知机是一个二分类的线性分类器。它接收多个输入信号,为每个输入分配一个权重,计算它们的加权和,然后通过一个阈值函数(或称阶跃函数)产生一个二值输出(通常是0或1)。

数学模型

  1. 输入:$x_1, x_2, …, x_n$(可以是特征或上一层神经元的输出)
  2. 权重:$w_1, w_2, …, w_n$(代表每个输入的重要程度)
  3. 偏置:$b$(一个常数项,允许模型平移决策边界)
  4. 加权和:$z = w_1x_1 + w_2x_2 + … + w_nx_n + b$
  5. 激活函数阶跃函数
    $$\text{输出} = \begin{cases} 1 & \text{if } z > 0 \cr 0 & \text{if } z \leq 0 \end{cases}$$

几何意义

在二维空间中,感知机的公式 $w_1x_1 + w_2x_2 + b = 0$ 定义了一条直线。它将空间一分为二,一侧输出1,另一侧输出0。因此,它只能解决线性可分的问题(例如,用一条直线就能把两类点分开)。

局限性

  • 无法解决非线性问题(例如,异或问题XOR)
  • 输出是”硬”的(非0即1),不提供关于”置信度”的信息

感知机与现代神经元的关系

现代神经网络中的神经元,可以看作是感知机的直接扩展。最主要的扩展就是将阶跃激活函数替换成了其他更光滑、更有用的激活函数,如Sigmoid和ReLU。


2. 激活函数

激活函数是神经网络神经元中的关键组件,它位于加权和($z$)之后,决定了该神经元的最终输出。

激活函数的主要作用

  1. 引入非线性:如果没有激活函数,无论神经网络有多少层,其整体仍然只是一个线性模型,无法学习复杂的模式和特征
  2. 决定输出范围:将输入映射到特定的输出区间(如(0,1)或(-1,1))
  3. 影响梯度流动:反向传播时,激活函数的导数决定了梯度如何更新权重,这对训练的稳定性和速度至关重要

感知机使用的阶跃函数就是一种最简单的激活函数。

Sigmoid函数

公式
$$\sigma(z) = \frac{1}{1 + e^{-z}}$$

函数图像特征

  • S形曲线
  • 将任何实数输入”挤压”到(0,1)区间内

优点

  • 平滑,输出范围固定
  • 输出值可以直观地解释为概率(例如,输出0.8意味着有80%的置信度)
  • 处处可微,这对反向传播算法至关重要

缺点

  • 梯度消失:当输入$z$的绝对值很大时,函数曲线变得非常平缓,其导数趋近于0。在深度网络的反向传播中,梯度会层层连乘,导致浅层网络的权重几乎得不到更新,训练停滞
  • 输出非零均值:Sigmoid的输出始终为正,这会导致后续神经元的输入全是正的,在梯度下降时权重更新效率低下(产生”之字形”更新路径)
  • 计算成本较高:涉及指数运算

用途:主要用于二分类问题的输出层,以提供概率输出。在隐藏层中已被ReLU等函数广泛取代。

ReLU函数

公式
$$\text{ReLU}(z) = \max(0, z)$$

函数图像特征

  • 当$z > 0$时,为斜率为1的直线
  • 当$z \leq 0$时,输出恒为0

优点

  • 计算极其高效:只有比较和取最大值操作,没有指数等复杂运算
  • 缓解梯度消失:在正区间导数为常数1,梯度可以无损地传递,极大地加速了深度网络的训练收敛
  • 稀疏激活性:会让一部分神经元输出为0,使网络变得稀疏,降低了模型的复杂度和过拟合风险

缺点

  • 死亡ReLU问题:如果输入始终为负(例如,权重初始化不当或学习率过高),该神经元的梯度将永远为0,权重永远不会更新,神经元永久”死亡”

ReLU变体

  • Leaky ReLU:$f(z) = \max(\alpha z, z)$,其中$\alpha$是一个小的正数(如0.01),为负输入提供一个小的斜率,避免神经元死亡

  • PReLU(Parametric ReLU):与 Leaky ReLU 类似,但 $\alpha$ 是可学习参数

  • **Exponential Linear Unit (ELU)**:在负区域平滑,定义如下:

    $$f(z) = \begin{cases} z & \text{if } z > 0 \cr \alpha(e^z - 1) & \text{if } z \leq 0 \end{cases}$$

用途目前深度神经网络隐藏层中最主流、默认的激活函数

三、损失函数与成本函数

损失函数用于衡量单个样本的预测误差,成本函数通常表示整个数据集上的平均损失。下面介绍均方误差(MSE)和交叉熵(Cross-Entropy)。

1. 均方误差(Mean Squared Error, MSE)

MSE常用于回归问题。它计算的是预测值与真实值之间差值的平方的平均值。

单个样本:
$$L(y,\hat{y}) = (y - \hat{y})^2$$
整体样本(N):
$$J = \frac{1}{N} \sum_{i=1}^{N} (y_i - \hat{y}_i)^2$$
向量化形式:
$$J = \frac{1}{N} (Y - \hat{Y})^T(Y - \hat{Y})$$

其中,$y$ 是真实值,$\hat{y}$ 是预测值,$N$ 为样本数。MSE 会对误差进行平方,因此对异常值较敏感。

2. 交叉熵(Cross-Entropy)

交叉熵常用于分类问题,特别是在二分类和多分类中。它衡量的是两个概率分布之间的差异。在分类问题中,真实标签通常表示为one-hot向量(例如,对于三分类,类别2表示为[0,1,0]),而模型输出通常通过softmax函数转换为概率分布。

二分类交叉熵

对于二分类,通常使用sigmoid函数将输出转换为一个概率值(表示属于正类的概率)。那么,交叉熵损失函数为:
$$L(y,\hat{y}) = -[y\log(\hat{y}) + (1-y)\log(1-\hat{y})]$$

其中,$y$ 是真实标签(0 或 1),$\hat{y}$ 是预测为正类的概率(在 0 和 1 之间)。

对于整个数据集,成本函数为:
$$J = -\frac{1}{N}\sum_{i=1}^{N}[y_i\log(\hat{y}_i) + (1-y_i)\log(1-\hat{y}_i)]$$

多分类交叉熵

对于多分类问题,假设有 $C$ 个类别。真实标签通常表示为 one-hot 向量,模型输出经过 softmax 函数后得到每个类别的概率。单个样本的损失函数为:

$$L(y,\hat{y}) = -\sum_{c=1}^{C} y_c \log(\hat{y}_c)$$

其中,$y_c$ 是真实标签在类别 $c$ 上的值,$\hat{y}_c$ 是模型预测为类别 $c$ 的概率。整个数据集的成本函数为:

$$J = -\frac{1}{N}\sum_{i=1}^{N}\sum_{c=1}^{C} y_{i,c}\log(\hat{y}_{i,c})$$

3. 对比与应用场景

  • MSE:通常用于回归问题。当问题涉及连续值预测时,MSE是一个自然的选择。
  • 交叉熵:通常用于分类问题。在分类问题中,我们更关心预测概率分布与真实分布的差异,交叉熵正好衡量这种差异。

从优化角度看,交叉熵与 softmax(或 sigmoid)结合时通常能提供更直接的梯度信号,从而加快分类模型的训练。

4. 示例代码

以下示例展示如何使用 NumPy 计算 MSE 和交叉熵:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import numpy as np

# 均方误差(MSE)
def mse(y_true, y_pred):
return np.mean((y_true - y_pred) ** 2)

# 二分类交叉熵
def binary_crossentropy(y_true, y_pred):
# 为了避免log(0)的情况,通常将y_pred限制在一个很小的范围内,比如[eps, 1-eps]
eps = 1e-15
y_pred = np.clip(y_pred, eps, 1 - eps)
return -np.mean(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred))

# 多分类交叉熵(假设输入为one-hot编码)
def categorical_crossentropy(y_true, y_pred):
eps = 1e-15
y_pred = np.clip(y_pred, eps, 1 - eps)
return -np.mean(np.sum(y_true * np.log(y_pred), axis=1))

# 示例数据
# 回归问题
y_true_reg = np.array([1.0, 2.0, 3.0, 4.0])
y_pred_reg = np.array([0.9, 2.1, 2.9, 4.1])
print("MSE:", mse(y_true_reg, y_pred_reg))

# 二分类问题
y_true_bin = np.array([1, 0, 1, 1])
y_pred_bin = np.array([0.9, 0.1, 0.8, 0.7])
print("Binary Crossentropy:", binary_crossentropy(y_true_bin, y_pred_bin))

# 多分类问题(3个类别,4个样本)
y_true_cat = np.array([[1,0,0], [0,1,0], [0,0,1], [1,0,0]])
y_pred_cat = np.array([[0.8,0.1,0.1], [0.2,0.7,0.1], [0.1,0.2,0.7], [0.9,0.05,0.05]])
print("Categorical Crossentropy:", categorical_crossentropy(y_true_cat, y_pred_cat))
# 注意:在实际的深度学习框架(如TensorFlow、PyTorch)中,这些损失函数已经有内置的实现,并且通常已经考虑了数值稳定性。

神经网络基础:感知机、激活函数与损失函数
https://mzpvj.com/2025/02/10/[大模型]-大模型第二篇/
作者
茆振鹏
发布于
2025年2月10日
许可协议