- 教程
- 人工智能
- 机器学习
- 深度学习
【免费下载链接】AI-For-Beginners
12 Weeks, 24 Lessons, AI for All!
本篇文章基于 AI-For-Beginners 开源课程中"神经网络"章节(translations/ar/lessons/3-NeuralNetworks/README.md,对应英文原版见 lessons/3-NeuralNetworks/README.md)整理而成。课程围绕"训练一个计算机模型(人工大脑)来实现智能"这一主线,从机器学习的基本定义出发,系统讲解神经元数学模型、感知机、多层网络、主流深度学习框架与过拟合问题。读完本文,你将掌握:神经元模型的前向计算公式、感知机训练算法、自建神经网络框架的核心层实现(含反向传播),以及用 PyTorch / Keras 搭建真实网络的实战路径。
机器学习:神经网络的知识地基
神经网络属于一个更大的学科——机器学习(Machine Learning)。机器学习的目标是:用数据训练计算机模型,使其能够解决问题。机器学习是人工智能的重要组成部分,但本课程(AI-For-Beginners)不讲解经典机器学习方法,而只聚焦神经网络模型;如果你希望学习传统机器学习,课程作者维护了专门的 ML for Beginners 系列教程。
在机器学习的形式化设定中,我们假设拥有一组数据样本X和对应的输出值Y:
- 样本 X 通常是 N 维向量,由多个**特征(features)**组成;
- 输出 Y 被称为标签(labels)。
课程重点讨论机器学习中最常见的两类问题:
- 分类(Classification):需要把输入对象划分到两个或多个类别中;
- 回归(Regression):需要为每个输入样本预测一个数值。
当把输入和输出表示为张量(tensor)时,输入数据集是一个大小为 M×N 的矩阵,其中 M 是样本数,N 是特征数;输出标签 Y 是大小为 M 的向量。这一"样本—特征—标签"的张量视图是后续理解深度学习框架中一切数据结构(如 PyTorch Tensor)的基础。
神经元的数学模型:从生物到公式
从生物学中我们知道,人脑由神经细胞(神经元)构成,每个神经元有多个"输入"(树突)和一个"输出"(轴突)。树突和轴突都能传导电信号,而它们之间的连接——突触(synapse)——可以表现出不同程度的传导性,并由神经递质调节。
由此可以抽象出最简单的神经元数学模型:包含若干输入 X₁, …, Xₙ、一个输出 Y,以及一组权重 W₁, …, Wₙ。输出按如下公式计算:
其中 f 是某个非线性激活函数(activation function)。非线性的存在至关重要——没有它,多层线性变换叠加后仍然等价于单层线性模型,无法拟合复杂分布。
需要说明的历史背景:神经元的早期数学模型由 Warren McCulloch 与 Walter Pitts 于 1943 年在论文《A logical calculus of the ideas immanent in nervous activity》中提出;Donald Hebb 则在《The Organization of Behavior: A Neuropsychological Theory》中提出了这类网络可以被训练的方式(即后来所称的"Hebb 学习律"的思想源头)。这也是为什么有时神经网络被称为人工神经网络(Artificial Neural Networks, ANNs)——强调我们讨论的是数学模型,而不是真实的神经元网络。
本章导览:四个层层递进的主题
在进入代码之前,先看本小节(3-NeuralNetworks)的完整路线图,后续章节逐一展开:
- Perceptron(感知机):最早的神经网络模型之一,用于二分类任务;
- 多层网络(Multi-Layered Networks):配套笔记本 如何构建我们自己的框架,从零写一个可用的神经网络库;
- 神经网络框架(Frameworks):配套笔记本 PyTorch 入门 与 Keras/TensorFlow 入门;
- 过拟合(Overfitting):深度学习中最需要重视的工程问题之一。
实战一:感知机(Perceptron)——最早的神经网络
感知机的历史可以追溯到 1957 年。当时 Frank Rosenblatt 在康奈尔航空实验室实现了硬件版本的"Mark-1"感知机,用于识别三角形、正方形、圆形等基本几何图形。输入图像由 20×20 的光电池阵列表示,因此网络有 400 个输入和 1 个二进制输出;这个简单的网络只包含一个神经元,也称为阈值逻辑单元(threshold logic unit)。有趣的是,当时的神经网络权重就像电位器一样,需要在训练阶段手动调节——这正是早期神经网络的真实样貌。
感知机模型
假设模型有 N 个特征,输入向量大小为 N。感知机是一个二分类模型,能区分两类输入数据。对每个输入向量 x,感知机输出为 +1 或 -1(取决于类别),计算公式为:
y(x) = f(wᵀx)
其中 f 是阶跃激活函数(step activation function)。阶跃函数的含义很直观:当输入大于等于 0 时输出 +1,小于 0 时输出 -1。这一步函数正是"阈值逻辑单元"名称的由来。
训练感知机:感知机准则与梯度下降
训练感知机的目标是找到一个权重向量 w,使大多数样本被正确分类,即总体误差最小。误差 E 由**感知机准则(perceptron criterion)**定义:
E(w) = -Σ wᵀxᵢ·tᵢ
其中:
- 求和只针对那些被错误分类的训练数据点 i;
- xᵢ 是输入数据,tᵢ 对正样本取 +1、对负样本取 -1。
该准则是权重 w 的函数,我们需要最小化它。通常使用**梯度下降(gradient descent)**方法:先取初始权重 w⁽⁰⁾,然后每一步按公式更新:
w⁽ᵗ⁺¹⁾ = w⁽ᵗ⁾ - η·∇E(w)
其中 η 是学习率(learning rate),∇E(w) 表示 E 的梯度。计算出梯度后,更新公式化简为:
w⁽ᵗ⁺¹⁾ = w⁽ᵗ⁾ + Σ η·xᵢ·tᵢ
课程 README 中给出了完整的 Python 训练实现(可逐行对照理解):
def train(positive_examples, negative_examples, num_iterations = 100, eta = 1): weights = [0,0,0] # Initialize weights (almost randomly :) for i in range(num_iterations): pos = random.choice(positive_examples) neg = random.choice(negative_examples) z = np.dot(pos, weights) # compute perceptron output if z < 0: # positive example classified as negative weights = weights + eta*weights.shape z = np.dot(neg, weights) if z >= 0: # negative example classified as positive weights = weights - eta*weights.shape return weights这段代码的核心逻辑是:每次随机抽出一个正样本与一个负样本,计算感知机输出;若正样本被误判为负(z < 0),则沿正方向调整权重;若负样本被误判为正(z ≥ 0),则沿反方向调整权重。迭代 num_iterations 次后返回权重向量。
动手实验
课程为感知机提供了配套笔记本 Perceptron.ipynb:先构造一个玩具问题(例如医学中依据肿瘤大小与年龄区分良性与恶性),用sklearn.datasets.make_classification生成二分类数据集,并将标签从 0/1 转换为 -1/1,按 8:2 切分训练/测试集,最后绘制数据散点并训练感知机。完成课时后,实验作业 lab 要求把感知机从二分类推广到完整的多类手写数字识别(PerceptronMultiClass.ipynb),即判断给定图像最可能对应哪个数字(0–9)。
实战二:从单层到多层——自建神经网络框架
上一节的感知机是单层模型,本质是线性二分类器。本小节将其扩展为更灵活的框架,从而支持:
- 在二分类之外执行多分类任务;
- 在分类之外解决回归问题;
- 分离线性不可分的类别。
同时,课程会引导你在 Python 中逐步构建自己的模块化框架,以便搭建不同的网络结构。
机器学习问题的形式化:损失函数
设有训练数据集 X 与标签 Y,需要构建模型 f 作出尽可能准确的预测。预测质量由损失函数(loss function)L 度量。课程列出了常用的损失函数:
- 回归问题(预测数值):绝对误差Σᵢ|f(x⁽ⁱ⁾) - y⁽ⁱ⁾|,或平方误差Σᵢ(f(x⁽ⁱ⁾) - y⁽ⁱ⁾)²;
- 分类问题:0-1 损失(本质等同于模型准确率),或逻辑损失(logistic loss)。
单层感知机的 f 定义为线性函数 f(x) = wx + b(w 为权重矩阵,x 为输入特征向量,b 为偏置向量);不同网络架构下,f 可以取更复杂的形式。分类场景中,通常希望网络输出各类别的概率,为此引入softmax函数 σ 将任意实数归一化为概率分布,函数变为 f(x) = σ(wx + b)。这里的 w 和 b 被称为参数θ = ⟨w, b⟩;给定数据集 ⟨X, Y⟩ 后,整个数据集上的总体误差可视为参数 θ 的函数。训练神经网络的本质目标,就是通过不断调整参数 θ 使误差最小化。
梯度下降与随机梯度下降(SGD)
函数优化的经典方法是梯度下降:计算损失函数对参数的导数(多维情况下称为梯度),并按使误差减小的方向调整参数。形式化如下:
- 用随机值初始化参数 w⁽⁰⁾, b⁽⁰⁾;
- 重复以下更新步骤多次:
- w⁽ⁱ⁺¹⁾ = w⁽ⁱ⁾ - η·∂L/∂w
- b⁽ⁱ⁺¹⁾ = b⁽ⁱ⁾ - η·∂L/∂b
理论上每次优化应基于整个数据集计算(因为损失是所有训练样本之和),但实际中我们每次只取数据集的一小部分——小批量(minibatches)——并基于这一子集计算梯度。由于子集是随机抽取的,这种方法被称为随机梯度下降(Stochastic Gradient Descent, SGD)。这一设定与 AI-For-Beginners 中后续课程(如 05-Frameworks)里对训练循环的理解直接相关。
多层感知机与反向传播
单层网络只能分类线性可分的类别。为了构建更丰富的模型,可以把多个网络层组合起来。数学上,函数 f 将具有更复杂的形式,并分多步计算:
- z₁ = w₁x + b₁
- z₂ = w₂·α(z₁) + b₂
- f = σ(z₂)
其中 α 是非线性激活函数,σ 是 softmax 函数,参数 θ = ⟨w₁, b₁, w₂, b₂⟩。
梯度下降算法本身不变,但梯度计算变得更困难。根据链式求导法则,可以这样计算导数:
- ∂L/∂w₂ = (∂L/∂σ)(∂σ/∂z₂)(∂z₂/∂w₂)
- ∂L/∂w₁ = (∂L/∂σ)(∂σ/∂z₂)(∂z₂/∂α)(∂α/∂z₁)(∂z₁/∂w₁)
注意:所有表达式最左侧的部分(∂L/∂σ)是相同的,因此可以从损失函数出发,沿计算图"反向"高效地逐层求出导数。这种训练多层感知机的方法因此被称为反向传播(backpropagation,简称 backprop)。
从源码看框架实现:前向、反向与参数更新
自建框架的核心思想在 OwnFramework.ipynb 中体现得淋漓尽致:每个网络层被定义为一个类,同时实现forward(前向计算)与backward(反向梯度)两个方法。以全连接层Linear为例(源码位于笔记本中):
class Linear: def __init__(self, nin, nout): self.W = np.random.normal(0, 1.0/np.sqrt(nin), (nout, nin)) self.b = np.zeros((1, nout)) self.dW = np.zeros_like(self.W) self.db = np.zeros_like(self.b) def forward(self, x): self.x = x return np.dot(x, self.W.T) + self.b def backward(self, dz): dx = np.dot(dz, self.W) dW = np.dot(dz.T, self.x) db = dz.sum(axis=0) self.dW = dW self.db = db return dx def update(self, lr): self.W -= lr*self.dW self.b -= lr*self.db几个值得留意的实现细节:
- 权重 W 用
np.random.normal(0, 1/np.sqrt(nin))初始化——即均值为 0、标准差为输入维数的平方根倒数的高斯分布,这种初始化方式有助于缓解梯度消失; forward里缓存输入self.x,供backward计算 dW 时复用;update(lr)直接执行 w ← w - lr·dW 的参数更新,对应前文梯度下降公式。
与之配套的还有Softmax层(其forward使用减去最大值z.max(axis=1, keepdims=True)的数值稳定技巧后再做指数归一化,使每个输出向量的分量之和恰好为 1)以及CrossEntropyLoss损失层(对每个样本取真实类别对应的对数概率,再取均值作为损失,对应公式 -log(p_of_y).mean())。把这些层按顺序组合起来就得到一张计算图:输入 x → Linear → Softmax → CrossEntropyLoss → 标量损失;反向传播时从损失逐层调用backward即可求出全部梯度。
完成本小节后,实验作业(MyFW_MNIST.ipynb)要求用你亲手搭建的框架完成 MNIST 手写数字分类,从而完整体会"从原理到框架再到应用"的全过程。
实战三:接入工业级框架——PyTorch 与 Keras/TensorFlow
前两节展示了手写框架的工作机制,但高效训练神经网络还需要解决两件事:
- 张量运算(乘、加,以及 sigmoid、softmax 等函数);
- 所有表达式的梯度计算,以执行梯度下降优化。
numpy可以完成第一部分,但梯度必须依赖框架机制。在我们上一节的自建框架里,所有导数函数都必须手工写进backward方法;而理想框架应该能对任意可定义表达式自动求梯度。此外,深度网络训练的计算量极大,框架还需要能在 GPU(或 TPU 等专用计算单元)上并行计算——"并行化"就是把计算分布到多个设备上执行。
目前最主流的两个神经网络框架是TensorFlow与PyTorch。两者都提供低层 API 支持 CPU/GPU 上的张量操作,并在其上提供高层 API:TensorFlow 对应Keras,PyTorch 对应PyTorch Lightning:
| 抽象层级 | TensorFlow | PyTorch |
|---|---|---|
| 低层 API | TensorFlow | PyTorch |
| 高层 API | Keras | PyTorch Lightning |
两种设计各有取舍:
- 低层 API:允许构建所谓的计算图,图定义了在给定输入参数下如何计算输出(通常是损失函数),并且可被推送到 GPU 执行;框架提供对计算图求导、计算梯度的函数,用于优化模型参数。低层 API 对训练过程有更强的控制力,常用于研究新网络架构的场景;
- 高层 API:把神经网络看作层的序列,构建大多数常见网络变得非常简单;训练模型通常只需准备好数据、调用一个
fit函数即可。
两者并非互斥:你可以用低层 API 开发自定义网络层,再放进高层 API 构建的大网络中;也可以用高层 API 定义网络,再写自己的低层训练循环。由于底层概念一致,它们可以很好地协同工作。课程建议:追求快速上手可以跳过张量细节,直接进入高层 API 笔记本;想从底层理解神经网络,则先完成低层 API 和张量部分。
环境准备与张量概念
以 IntroPyTorch.ipynb 为例,环境准备非常简单:
pip install torch torchvision或使用 conda:
conda install pytorch -c pytorch张量(Tensor)是多维数组,非常适合表示各种类型的数据,课程给出了直观的维度对照:
- 400×400:黑白图片;
- 400×400×3:彩色图片(RGB 三通道);
- 16×400×400×3:包含 16 张彩色图片的小批量;
- 25×400×400×3:1 秒 25 fps 的视频;
- 8×25×400×400×3:8 段 1 秒视频的小批量。
理解张量的维度演进,是后续所有计算机视觉、NLP 课程(如 4-ComputerVision、5-NLP)的数据基础。TensorFlow 一方的对应笔记本为 IntroKerasTF.ipynb 与 IntroKeras.ipynb。
过拟合(Overfitting):训练中最需警惕的现象
完成框架学习之后,课程引入了一个极其重要的概念——过拟合。考虑用模型近似 5 个数据点(图中用 x 标记):
- 线性模型,2 个参数:训练误差 5.3,验证误差 5.1——参数数量与数据规模匹配,模型正确把握了点的分布规律;
- 非线性模型,7 个参数:训练误差 0,验证误差 20——模型过于强大,只有 5 个点却拥有 7 个参数,它可以调整到穿过所有点、把训练误差做到 0,但这阻碍了模型理解数据背后的真实模式,导致验证误差极高。
过拟合为什么会发生
- 训练数据不足;
- 模型过于强大(参数过多);
- 输入数据中噪声过多。
如何检测过拟合
从上面的例子可以看到:过拟合可以通过极低的训练误差 + 很高的验证误差来识别。训练过程中通常训练误差与验证误差会一起下降,但到某个点之后验证误差可能停止下降甚至回升——这正是过拟合的信号,意味着此时应当停止训练(或至少对模型做一次快照存档)。课程为此专门绘制了训练/验证误差随训练进度变化的示意图(见 lessons/3-NeuralNetworks/images/Overfitting.png)。
如何预防过拟合
一旦发现过拟合,可以采取以下措施之一:
- 增加训练数据量;
- 降低模型复杂度;
- 使用正则化技术(regularization),例如 Dropout——该技巧在课程后面的 08-TransferLearning 小节(TrainingTricks.md)中会详细展开。
过拟合与偏差-方差权衡
过拟合实际上是统计学中更普遍的**偏差-方差权衡(Bias-Variance Tradeoff)**问题的一个具体案例。模型误差有两种来源:
- 偏差误差(Bias):算法未能正确捕捉训练数据中的关系,通常源于模型不够强大——对应欠拟合(underfitting);
- 方差误差(Variance):模型近似的是输入数据中的噪声而非有意义的关系——对应过拟合。
训练过程中,偏差误差随模型逐渐逼近数据而下降,方差误差则不断上升。因此,在正确的时间点停止训练——手动(检测到过拟合时)或自动(通过引入正则化)——对于防止过拟合至关重要。
配套实验与完整学习路径
本小节(3-NeuralNetworks)的每个主题都配有可运行的笔记本与实验作业,建议按顺序完成:
| 主题 | 核心笔记本 | 实验作业 |
|---|---|---|
| 感知机 | Perceptron.ipynb | 多类数字识别 |
| 自建框架 | OwnFramework.ipynb | MNIST 分类 |
| 深度学习框架 | IntroPyTorch.ipynb、IntroKerasTF.ipynb | LabFrameworks.ipynb(用 PyTorch 或 TensorFlow 完成单层与多层全连接网络的两个分类问题) |
课程整体采用"12 周、24 课"的编排(详见 README.md),本节是通往计算机视觉(4-ComputerVision)与自然语言处理(5-NLP)等后续章节的基石。建议的推进方式:先在笔记本中完整跑通感知机与自建框架,理解每一层forward/backward的含义;再切换到 PyTorch 或 TensorFlow 的高层 API 熟悉生产级开发方式;最后带着过拟合的意识去评估每一次训练的验证误差。学习过程中如需回顾环境搭建,可参考 lessons/0-course-setup 与仓库根目录的 requirements.txt(environment.yml 提供 conda 环境定义)。
- 教程
- 人工智能
- 机器学习
- 深度学习
【免费下载链接】AI-For-Beginners
12 Weeks, 24 Lessons, AI for All!
相关推荐
神经网络入门之感知机:从 generative-ai-for-beginners 知识库看单层感知机的模型与训练原理
神经网络入门之感知机:从 generative ai for beginners 知识库看单层感知机的模型与训练原理 感知机(Perceptron)是现代神经网
教程人工智能大模型感知机(Perceptron)从原理到训练:generative-ai-for-beginners 第 15 课数据源中的神经网络入门
感知机(Perceptron)从原理到训练:generative ai for beginners 第 15 课数据源中的神经网络入门 在 generative
教程人工智能大模型CANN/asc-devkit WholeReduceMax API
WholeReduceMax<a name="ZH CN_TOPIC_0000001953491746" </a 产品支持情况<a name="section1
人工智能深度学习算子库CANNAscend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考