深度学习入门(一)——从神经元到损失函数,一步步理解前向传播(上)

本系列是为那些想"真正理解"深度学习的人写的。

不谈框架黑箱,不追求堆砌术语。

我们从最小的神经元开始,一步步走向真正可理解的深度学习。


一、前言:从"写规则"到"让机器自己学"

在传统编程的世界中,程序员的工作是------写规则

比如,我们要写一个程序判断一封邮件是不是垃圾邮件。最直接的做法是:

复制代码
if "中奖" in 邮件 or "转账" in 邮件:
    标记为垃圾邮件

但是,现实世界不是这样简单。

骗子的文案越来越像正常邮件,真正的客户通知又可能包含"转账"这类词汇。

于是我们不断加规则,反复调试,结果是:

系统越来越复杂、越来越脆弱。

这种"写规则"的方式有一个致命弱点:

程序只会做我们明确告诉它的事,却永远学不会自己判断。

于是,机器学习 出现了。

它反过来问:"能不能不写规则,而是让机器自己从数据中总结规律?"

我们不再告诉它"中奖=垃圾",而是给它上千封标注好的邮件,让它自己去学"哪些特征意味着垃圾"。

深度学习,正是这种思想的极致体现。


二、神经元:从数学角度复刻"思考"

1. 生物神经元的抽象

生物神经元接收来自其它神经元的电信号,当输入信号累积超过某个阈值时,它就"激活",并把信号传递给下一个神经元。

人工神经元简化了这种行为,用数学表达:

cpp 复制代码
输入: x₁, x₂, x₃, ...
权重: w₁, w₂, w₃, ...
偏置: b
输出: y = f(w₁x₁ + w₂x₂ + w₃x₃ + b)

这其实就是一个加权求和,再通过函数 f 进行变换的过程。

这里的 f 就是我们常说的"激活函数"。


2. 权重与偏置的意义

  • 权重 w :表示输入的重要程度。

    如果一个输入特征对结果影响大,它对应的权重会被学得更大。

  • 偏置 b :表示整体输出的"基础水平"。

    它帮助模型在所有输入为 0 时,也能有一个非零输出。

例如,在判断天气是否炎热的简单模型中:

cpp 复制代码
y = f(0.7*温度 + 0.1*湿度 - 0.3*风速 + 0.2)

温度的权重最高,说明它最关键。

而偏置 0.2,代表基础上就有一点"热"的倾向。


3. 激活函数:为什么需要"非线性"

假设没有激活函数:

cpp 复制代码
y = w₁x₁ + w₂x₂ + b

多个神经元堆叠在一起,也只是一次线性变换的组合。

线性叠加仍然是线性,这意味着无论堆多深,模型本质上都只能画出一条直线的决策边界。

而真实世界是非线性的。

图像分类、语音识别、自然语言理解,背后都是高度非线性的映射关系。

要想让神经网络学到这种复杂关系,必须引入非线性函数

常见的激活函数:

名称 公式 优点 缺点
Sigmoid 1 / (1 + e^(-x)) 平滑、可微 梯度消失
Tanh (e^x - e^(-x)) / (e^x + e^(-x)) 对称、收敛快 仍有梯度问题
ReLU max(0, x) 简单高效 神经元"死亡"问题
Leaky ReLU x if x>0 else 0.01x 改进ReLU死区 参数敏感
GELU x * Φ(x) 更平滑、现代网络常用 计算复杂

ReLU 的成功在于简单:只保留正数。

它让网络的非线性更明显,也加快了训练。


三、神经网络的结构与计算流

一个简单的神经网络可以这样看:

cpp 复制代码
输入层 → 隐藏层 → 输出层

输入层接收数据,隐藏层进行特征变换,输出层给出预测结果。

在数学上,我们把前向传播描述为:

cpp 复制代码
for each layer L:
    z[L] = W[L] * a[L-1] + b[L]
    a[L] = f(z[L])

这里:

  • a[0] 是输入;

  • W[L] 是第 L 层权重;

  • b[L] 是偏置;

  • f 是激活函数;

  • a[L] 是这一层的输出。


1. 举个例子

假设我们有一个简单的神经网络:

  • 输入层:2个神经元

  • 隐藏层:2个神经元

  • 输出层:1个神经元

伪代码如下:

cpp 复制代码
输入: X = [x1, x2]
权重:
  W1 = [[0.2, 0.4],
         [0.3, -0.5]]
  b1 = [0.1, -0.2]
  W2 = [0.7, 0.6]
  b2 = 0.05

隐藏层:
  z1 = W1 * X + b1
  a1 = ReLU(z1)

输出层:
  z2 = W2 * a1 + b2
  a2 = Sigmoid(z2)

如果 X = [1.0, 0.5],则:

cpp 复制代码
z1 = [0.2*1 + 0.4*0.5 + 0.1, 0.3*1 - 0.5*0.5 - 0.2]
   = [0.5, -0.15]
a1 = ReLU(z1) = [0.5, 0]
z2 = 0.7*0.5 + 0.6*0 + 0.05 = 0.4
a2 = Sigmoid(0.4) ≈ 0.598

输出 0.598 就是模型预测的结果,比如"这张图片属于猫的概率"。


2. 计算的本质

每一层的计算都是:

cpp 复制代码
加权求和 → 加偏置 → 激活变换

这种结构很简单,却非常强大。

因为每一层都能提取更"抽象"的特征。

举例:

  • 第一层可能学到"边缘";

  • 第二层学到"形状";

  • 第三层学到"物体类别"。

深度,就是特征抽象的层次。


四、损失函数:让模型"知道自己错了"

有了输出,还需要知道输出对不对。

这就是损失函数(Loss Function)的作用。

损失函数衡量预测值与真实值的差距。

模型训练的目标,就是最小化这个损失。


1. 回归任务:均方误差

cpp 复制代码
L = (1/n) * Σ(y_pred - y_true)²

它表示预测偏差的平方平均。

预测得越接近真实值,损失越小。

但在分类问题中,MSE 并不好用,因为概率输出和离散标签之间的差异无法正确反映"分类好坏"。


2. 分类任务:交叉熵

交叉熵本质上衡量两个分布的差异:

一个是模型预测的概率分布 p(y_pred),一个是实际标签的分布 p(y_true)

cpp 复制代码
L = -Σ y_true * log(y_pred)

举个例子:

真实标签:[1, 0, 0]

预测输出:[0.7, 0.2, 0.1]

cpp 复制代码
L = - (1*log(0.7) + 0 + 0) = -log(0.7)

如果模型预测得更差,如 [0.4, 0.3, 0.3],损失就会变成 -log(0.4),更大。

这促使模型调整权重,使正确类别的概率更高。


3. Softmax 的作用

多分类时,输出层一般使用 Softmax:

cpp 复制代码
Softmax(x_i) = exp(x_i) / Σ exp(x_j)

它把任意实数向量映射成一个概率分布。

但在实现时,exp(x_i) 可能会溢出。

因此,稳定的实现是:

cpp 复制代码
Softmax(x_i) = exp(x_i - max(x)) / Σ exp(x_j - max(x))

这样不会影响结果,却避免了数值问题。


五、前向传播的完整伪代码实现

cpp 复制代码
# 初始化参数
for layer in range(1, L+1):
    W[layer] = small_random()
    b[layer] = zeros()

# 前向传播函数
function forward(X):
    a[0] = X
    for L in 1...L_max:
        z[L] = W[L] * a[L-1] + b[L]
        a[L] = activation(z[L])
    return a[L_max]

# 损失函数
function cross_entropy(y_pred, y_true):
    return -sum(y_true * log(y_pred))

可以看到,这个流程没有魔法,只有一连串简单的矩阵乘法与非线性变换。


六、几个常见的坑

  1. 没有激活函数

    • 网络退化成线性映射,等价于一个线性回归。
  2. 激活函数选错

    • 用 Sigmoid 在深层网络中会导致梯度几乎为 0,训练停滞。
  3. 损失函数选错

    • 用 MSE 处理分类问题会让梯度方向混乱,收敛极慢。
  4. 忽略数值稳定

    • 没减去 max(x) 的 Softmax,容易溢出成 NaN。
  5. 参数初始化不当

    • 全部初始化为 0,会让所有神经元输出相同,永远学不会东西。

七、直觉理解:神经网络是在逼近函数

很多人初学时问:"神经网络到底在干什么?"

最本质的答案是------它在逼近一个未知函数 f(x)

我们假设有一条从输入到输出的真函数,但我们不知道它长什么样。

神经网络通过调整权重参数 W, b,不断逼近这个函数。

最终,网络会学到一种近似关系:

cpp 复制代码
输入 → (一系列变换)→ 输出

也就是说:

神经网络不是在"记住"数据,而是在"学习数据的模式"。


八、回到初衷:学习的意义

当我们说"神经网络在学习",其实它并不是真的有意识。

它只是在不断最小化损失函数,使预测越来越接近真值。

但这个过程,本质上就是"试错---调整---再试"的循环。

这正是人类学习的缩影。

也正因如此,深度学习成为了当代最有生命力的算法体系之一。


九、小结与过渡

这一篇我们完成了"深度学习的第一步":

  • 理解了神经元的数学模型;

  • 掌握了前向传播的逻辑;

  • 知道了激活函数和损失函数的作用;

  • 用伪代码看清了整个计算流。

但我们还没有学会"如何让模型调整自己"。

换句话说,现在的神经网络,只会算,不会改。

下一步,我们将正式进入深度学习的核心机制------反向传播(Backpropagation)

相关推荐
补三补四3 小时前
SMOTE 算法详解:解决不平衡数据问题的有效工具
人工智能·算法
为java加瓦3 小时前
前端学AI:如何写好提示词(prompt)
前端·人工智能·prompt
一车小面包3 小时前
对注意力机制的直观理解
人工智能·深度学习·机器学习
逝水年华QAQ3 小时前
什么是Edge TTS?
人工智能
ARM+FPGA+AI工业主板定制专家3 小时前
基于NVIDIA ORIN+FPGA+AI自动驾驶硬件在环注入测试
人工智能·fpga开发·机器人·自动驾驶
AI小云3 小时前
【Python与AI基础】Python编程基础:模块和包
人工智能·python
用户5191495848453 小时前
Paytium WordPress插件存储型XSS漏洞深度分析
人工智能·aigc
weixin_433417673 小时前
PyTorch&TensorFlow
人工智能·pytorch·tensorflow
XZSSWJS3 小时前
深度学习基础-Chapter 02-Softmax与交叉熵
人工智能·深度学习