深度学习入门必看:Python基础与环境搭建实战指南
2026/9/24 21:49:23 网站建设 项目流程

1. 别急着装深度学习框架,先把这个地基打好

我见过不少刚接触深度学习的同学,上来就直奔主题,问我“PyTorch 怎么装”“TensorFlow 能不能直接跑”,结果卡在环境配置上两三天,最后连一段最简单的数据加载代码都跑不通。问题不在于框架本身,而是 Python 这门语言的基础没打牢。你想啊,深度学习说白了就是拿 Python 去操作一堆多维数组,让数据在模型里流转,如果连列表、字典、循环、函数都写不顺溜,后面光看框架源码就能把你劝退。

所以这门“李哥深度学习班”的 Python 基础课,定位特别清楚:不是要你成为一个软件工程师,而是让你在最短时间内掌握“够用”的 Python 能力,然后能顺畅地进入深度学习的世界。那这个“够用”到底是多少?我的理解是:能安装好环境、能读懂数据预处理代码、能自己写一个数据加载函数、能手动实现一遍梯度下降、能看懂 PyTorch 官方教程里大部分例程,这就可以了。

这篇内容我打算按照我带班实际讲课时的一套思路来整理。不会去罗列什么“Python 三百个内置函数”,也不会一章一章地给你讲语法教科书。我会围绕深度学习的真实工作流程——数据准备、模型搭建、训练循环、结果可视化——来反推你需要哪些 Python 基础,然后逐个击破。这样你学完之后就会有一种感觉:每学一个语法点,你都知道它将来会在哪里被用到。

2. 深度学习实验环境搭建:我给新手的一份可抄作业方案

2.1 为什么必须用 Anaconda,而不是直接装原生 Python

很多新手会问:我直接去 python.org 下载一个 Python 装上,再装个 PyCharm,不就行了吗?对于纯写脚本、做点小工具的人来说,确实也行。但深度学习不一样,你后面会接触 PyTorch、TensorFlow、NumPy、Pandas、Matplotlib 这一大堆科学计算包,它们之间还有版本依赖关系。今天你装了 A 库,明天装 B 库的时候它要求 A 库降级,结果 C 库又崩了,这就是俗称的“依赖地狱”。

Anaconda 的价值就在于帮你把这一堆东西管起来。它自带一个包管理器 conda,可以创建若干个互相隔离的 Python 环境。什么意思呢?就是你给深度学习项目单独开一个房间,里面装 Python 3.10、PyTorch 2.x、NumPy 1.26,随便折腾;另一个房间放爬虫项目用的 Python 3.8 和 requests 库,两个房间互不干扰。有什么乱七八糟的依赖,不会把系统全局的环境搞坏。

还有一个更现实的原因:深度学习库很多是对底层硬件做优化的,比如 CUDA 版本、cuDNN 版本,它们和 Python 版本有严格的匹配关系。用 conda 创建环境的时候可以直接指定 Python 版本,比手动编译什么的省心太多了。我带的班里,凡是老老实实用 Anaconda 搭环境的,基本一节课内搞定;非要用原生 Python 硬上的,课后至少有一半人来找我排错。

2.2 环境配置的完整步骤

第一步,先到官网或者国内镜像站下载 Anaconda 安装包。官网地址是 anaconda.com,如果下载速度慢,可以用清华大学的开源软件镜像站,路径是 mirrors.tuna.tsinghua.edu.cn/anaconda/archive/。下载最新版就行,安装的时候要注意一点:如果是 Windows,安装过程中会有两个勾选项,一个是把 Anaconda 加入 PATH 环境变量,另一个是设为默认 Python,建议都勾上。macOS 和 Linux 基本就是一路回车。

第二步,不是马上建环境,而是先把 pip 和 conda 的源换成国内镜像,不然以后下载包会慢到怀疑人生。在命令行里依次执行这几条命令:

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --set show_channel_urls yes pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

pip 那个命令会在你的用户目录下生成一个配置文件,把全局的 pip 下载源改成清华源。这样你后面装任何 Python 包都会快很多。

第三步,创建一个深度学习专用环境。我一般会让学员统一用 Python 3.10,因为目前主流的深度学习框架对 3.8 到 3.11 都有比较好的支持,3.10 属于保守但稳妥的选择。命令是:

conda create -n dl python=3.10 conda activate dl

创建完之后,命令行前面应该会出现(dl)的标识,这就说明你已经进入这个独立环境了。后面不管装什么包,切记先把环境激活,否则装错地方,激活以后还是找不到包,这是新手最容易犯的错。

第四步,装基础的科学计算库。在新环境里执行:

pip install numpy pandas matplotlib jupyter

这些是后面处理数据和可视化都要用的,先装上跑一遍没问题,之后再根据具体项目去装 PyTorch。装完以后可以顺手验证一下:

python -c "import numpy; print(numpy.__version__)"

能正常打印出版本号,就说明环境没问题了。

2.3 编辑器选型:VSCode 和 PyCharm 怎么选

环境只是“引擎”,你还需要一个写代码的“驾驶舱”。我给班的建议是:Windows 用户首选 VSCode,macOS 用户也是 VSCode,只有之前已经熟悉 PyCharm 的同学可以继续用 PyCharm,没必要强行换。

VSCode 的优势是轻量、启动快、对 Python 的支持经过几年迭代已经非常好用了。装好之后去扩展市场搜 Python 扩展,安装微软官方出的那个(发布者是 Microsoft),它会自动帮你做语法检查、代码补全和调试。然后按Ctrl+Shift+P打开命令面板,输入Python: Select Interpreter,选择你刚才创建的那个dl环境。这一步很多新手漏了,结果 VSCode 还在用系统自带的全局 Python,import numpy 当然报错。

这里有一个小技巧,新建一个测试文件,输入:

import sys print(sys.executable)

如果打印出来的路径里面有anaconda3/envs/dl,说明解释器选择正确了。这个路径就是区分环境最直观的方式,比看界面上的提示更靠谱。

3. 面向深度学习的 Python 核心语法,这样学才高效

3.1 数据结构的真实映射:列表、字典、元组到底什么时候用

教科书上会告诉你列表是有序的可变序列,字典是键值对,元组是不可变数据。听着抽象,但放到深度学习场景里就非常直观了。

列表,你完全可以把它理解成“一个 batch 的数据”。比如你有 128 张猫的图片要一次性处理,你可以把它们都放到一个列表里:images = [img1, img2, ..., img128]。对应的标签也可以放到另一个列表里:labels = [0, 1, 0, 0, 1, ...]。列表最常用的操作就是遍历,用 for 循环把里面的每个元素取出来处理,这在后面对图片做预处理的时候是每天都会发生的事。

字典则是用来存“配置”的。深度学习训练有一大堆超参数,学习率、批次大小、训练轮数、优化器类型、权重衰减系数等等。你完全可以写一堆变量,但更清晰的做法是放在一个字典里:

config = { "lr": 0.001, "batch_size": 64, "epochs": 50, "optimizer": "adam", "device": "cuda" }

这样不管是传参还是打印日志都非常方便。后面学 PyTorch 的时候你会发现,很多模型和数据加载器的参数就是这样传进去的。

元组最典型的场景是表示“形状”。比如一张灰度图是 28 像素高 28 像素宽,它的尺寸就是(28, 28)这样一个元组。彩色图片三通道就是(3, 256, 256)。为什么要用元组而不是列表?因为形状这个东西不应该被意外修改,元组天然具备不可变性,用起来更安全。

3.2 流程控制:循环在深度学习中无处不在

先看条件判断。写代码的时候经常要根据情况走不同的分支,比如判断当前到底用 GPU 还是 CPU 计算:

if config["device"] == "cuda" and torch.cuda.is_available(): device = torch.device("cuda") else: device = torch.device("cpu")

再比如训练过程中每过 10 轮打印一次验证集的准确率:

if epoch % 10 == 0: print(f"Epoch {epoch}, loss: {loss:.4f}")

这就是 if 语句最常见的用法,没什么玄乎的,就是“如果满足什么条件,就做什么事”。条件还能组合,用andornot,判断是否同时满足多个条件。

再看循环。深度学习中最常见的循环就是遍历数据。你有一个列表存放了所有训练样本的路径,你要一个接一个地把它读进来:

for img_path in img_paths: img = load_image(img_path) ...

还有一个是while循环,虽然用得比 for 少,但偶尔会在一些收敛判断里看到,比如模型还没收敛就继续训练:

while loss > 0.01: train_one_epoch()

这里我想多说一句:很多初学者会纠结“for 循环和 while 循环到底什么区别”。我的回答是,你只需要记住一个原则——如果你知道要循环多少次,用 for;如果你不知道次数,只知道结束条件,用 while。深度学习里大概九成场景属于前一种,所以 for 循环必须熟练掌握。

3.3 函数与模块化:从“写流水账”到“封装逻辑”

函数是 Python 里最重要的组织代码方式,没有之一。你去看任何一份深度学习项目的源码,里面全都是函数:数据加载是一个函数,定义模型是一个函数,训练是一个函数,画图又是一个函数。函数的本质就是把一段逻辑封装起来,给它一个名字,传进去一些参数,它返回一个结果。后续你需要复用这段逻辑,直接调用函数名,而不是把代码复制粘贴一遍。

举个例子,假设你要写一个对图像做归一化的函数:

def normalize_image(pixel_values, mean, std): normalized = (pixel_values - mean) / std return normalized

这样你在预处理的时候调用normalize_image(images, 0.5, 0.1)就可以了。如果你要改成不同的均值和标准差,改参数就行,函数内部逻辑不用动。

这里我特别想强调一个点:函数的参数设计。刚开始学的时候,很多人把一堆参数全部塞到函数里,结果调用的时候自己也分不清哪个是哪个。我的建议是,参数按可读性分组,关键的、必须由调用方决定的放在前面,有默认值的放后面,甚至可以用关键字参数来调用,这样语义更清楚:

def create_dataloader(data_dir, batch_size=32, shuffle=True): ...

调用的时候可以写成create_dataloader("./data", batch_size=64, shuffle=False),一眼就能看出你改了哪些参数。

3.4 面向对象基础:为什么深度学习里到处是“类”

说到面向对象,很多同学在入门阶段容易懵。但如果你先接触了 PyTorch,你会发现里面的模型都是这样定义的:

class MyModel(nn.Module): def __init__(self): super().__init__() self.fc1 = nn.Linear(784, 128) def forward(self, x): return self.fc1(x)

你看,这不就是一个类吗?所以在正式学框架之前,至少要把类的基本写法看懂。类可以理解为“把数据和操作数据的方法打包在一起”。在深度学习的场景里,最常见的类就是“自定义数据集”。

class MyDataset: def __init__(self, data_path): self.data = load_data(data_path) def __len__(self): return len(self.data) def __getitem__(self, index): return self.data[index]

这三个特殊方法,__init__是创建对象时初始化数据的,__len__告诉外部这个数据集有多大,__getitem__支持用下标取数据。以后你用 PyTorch 的 Dataset 类,会发现结构几乎一模一样。所以我说,面向对象的基础不需要你掌握什么多继承、抽象类,只要“建一个类、写几个方法、能用__getitem__按下标取数据”就够了。

3.5 文件操作:读写数据是躲不掉的那关

深度学习离不开数据,而数据往往是放在磁盘上的图片、CSV、JSON、文本文件。Python 里的文件操作其实非常直白。读一个文本文件:

with open("config.json", "r", encoding="utf-8") as f: config = json.load(f)

这个with语句是 Python 里推荐的做法,它会在代码块结束后自动关闭文件,不需要你手动调用close()。踩过坑的同学可能知道,手动写文件经常忘了关,结果文件内容没保存下来。

如果是读图片路径,我推荐用os.path模块来拼接路径。因为不同操作系统路径分隔符不一样,Windows 用反斜杠,macOS 和 Linux 用斜杠,直接写死路径换台机器就废了。用os.path.join("data", "images", "cat.jpg")会自动适配系统。

另外新手经常遇到一个编码问题:读中文文件报错。解决办法是打开文件时都明确指定encoding="utf-8",不要偷懒不写。这点在 Windows 上尤其重要,因为 Windows 默认编码可能是 GBK。

4. NumPy:深度学习里你避不开的那个“隐形基础”

4.1 列表和 NumPy 数组,到底差在哪里

很多学过点 Python 的人都会问:我明明可以用列表存一组数,为什么还要学 NumPy?这个问题问到点子上了。你可以把列表想象成一个仓库,它什么都能装,但如果你要对整批数据做运算,比如让每个元素都加 1,用列表你得写循环;而 NumPy 数组里存的都是同一类型的数值,它支持“向量化操作”,也就是对整个数组一次性做运算:

arr = np.array([1, 2, 3, 4]) new_arr = arr + 1 # 结果是 [2, 3, 4, 5]

如果是 Python 列表,得这样写:

lst = [1, 2, 3, 4] new_lst = [x + 1 for x in lst]

看起来区别不大,但当数据量到百万、千万级别的时候,性能差距就很明显了。NumPy 的底层是 C 语言实现,向量化运算避免了 Python 循环的逐元素开销,速度快几十倍都不夸张。

还有更重要的一个原因:深度学习框架里的“张量”(Tensor),底层设计思路和 NumPy 的 ndarray 几乎一模一样。你把 NumPy 玩熟了,后面学 PyTorch 张量操作会顺畅很多,因为很多函数名和用法都是相通的,无非是把np.换成torch.

4.2 创建数组:那些每天都会用到的函数

在实际操作中,大概会用到这么几个创建数组的高频函数:

import numpy as np # 全零数组,比如初始化一个全零的掩码 a = np.zeros((3, 4)) # 全一数组 b = np.ones((2, 2)) # 随机数数组,比如模拟服从正态分布的初始化参数 c = np.random.randn(5, 5) # 从 0 到 9 的等差数列 d = np.arange(10) # 等间距取 100 个点,比如画坐标轴 x = np.linspace(0, 1, 100)

这些函数不用死记,用多了自然就记住了。我建议你拿到一个函数,先看它的用法和参数,再想想“在深度学习什么阶段会用上”,这样记忆会很牢固。

4.3 形状变换:reshape、transpose 与广播机制

我给你举一个特别真实的场景。MNIST 数据集里每张图片是 28×28 像素的灰度图,原始数据输入的时候可能是一个长度为 784 的一维向量。但卷积神经网络(CNN)处理图像时要求输入格式是(通道数, 高, 宽)的三维数组。这个时候你就需要把 784 个数字重新“塑形”成(1, 28, 28)

img_vector = np.random.randn(784) img_2d = img_vector.reshape(1, 28, 28)

这就是 reshape 的作用。再比如你有一批图片数据,形状是(批量大小, 高, 宽, 通道数),也就是 TensorFlow 风格的NHWC排列,但你的模型需要NCHW排列,这时用transpose调整轴的顺序:

x = np.random.randn(32, 28, 28, 1) x_t = x.transpose(0, 3, 1, 2) # 变成 (32, 1, 28, 28)

这个概念一开始确实容易绕晕。我给学员的建议是,随便拿个小数组手动试一试,打印出变换前后的 shape,用不了几次就能理解。

广播机制可能是 NumPy 里最让人迷惑但又最香的功能。简单说,就是两个形状不一致的数组做运算时,NumPy 会自动把小的那个“扩展”到和大的形状一致,不需要你手动复制数据。最常见的例子是数据标准化:

data = np.random.randn(32, 784) # 32 张图,每张 784 维 mean = data.mean(axis=0) # 对每个特征维度求均值,形状 (784,) std = data.std(axis=0) normalized = (data - mean) / std # (32, 784) 和 (784,) 直接相减,自动广播

如果所有维度的形状完全相等,或者其中一个是 1,那就可以广播。我当时跟学员打的一个比方是:把一张小的透明贴纸,铺满整张大纸,贴纸每个位置的内容都一样,这就叫广播。它能帮你省掉很多显式复制的代码。

5. 数据可视化:看图说话是深度学习的“眼睛”

5.1 Matplotlib 最常用的两张图

训练深度学习模型是一个特别“盲盒”的过程,你根本不知道里面的参数变成了什么样子。这时候你就要靠可视化来监控训练状态。Matplotlib 是最基础、也是最重要的可视化库。

第一张必学的图是损失曲线(loss curve)。训练过程中,每隔一段时间把当前的 loss 值记下来,最后画成一条折线,看它是不是在下降:

import matplotlib.pyplot as plt loss_history = [2.3, 1.8, 1.2, 0.8, 0.5, 0.3] plt.plot(loss_history) plt.xlabel("Epoch") plt.ylabel("Loss") plt.title("Training Loss Curve") plt.show()

损失曲线越平滑地往下走,说明模型在正常学习;如果曲线忽上忽下,或者不降反升,就要去检查学习率是不是太大、数据有没有问题。这是每个炼丹师日常都会做的事。

第二张必学的图是展示输入数据的图,尤其是图像数据。你得确认你喂给模型的数据长什么样、标签对不对。这个时候用plt.imshow()

sample_img = data[0].reshape(28, 28) plt.imshow(sample_img, cmap="gray") plt.title(f"Label: {label[0]}") plt.axis("off") plt.show()

如果你想把多个样本拼在一起看,可以用plt.subplot(2, 5, i)创建一个 2 行 5 列的子图网格,把前 10 张图都展示出来。这一步在调试数据加载器的时候特别管用,很多标签错位、图像翻转的问题一眼就能看出来。

5.2 从“画图报错”到“中文乱码”的几个坑

Matplotlib 本身不难,坑主要在细节上。第一,如果你在 Jupyter Notebook 里运行画图代码,想直接在单元格里显示图,需要加一行魔法命令%matplotlib inline,否则图不会自动显示出来。第二,中文字体显示乱码是一个几乎每个人都会碰到的问题,因为 Matplotlib 默认字体不支持中文。处理方法是在画图前指定字体:

plt.rcParams["font.sans-serif"] = ["SimHei", "PingFang SC", "Microsoft YaHei"] plt.rcParams["axes.unicode_minus"] = False

后面那句是同时解决坐标轴负号显示成方块的问题。如果你是 macOS 用户,把字体名换成"PingFang SC"就行;如果这两种都不行,那就检查系统装了什么中文字体再填对应的名字。

第三个坑是很多人喜欢在循环里连续调用plt.show(),结果每画一张图就弹出一个窗口,特别烦。正确的做法是循环里每次画到对应的子图上,最后统一调用一次plt.show(),或者保存到本地文件。用plt.savefig("loss_curve.png", dpi=150)就可以把图保存下来,方便写实验报告或者发到群里讨论。

6. 一个完整的小例子:把刚学的知识点全部串起来

讲完语法和工具,我们来做一个最接近深度学习实际工作的小项目。假设你有一批文本格式的数据,每行是一张图片的路径和它的类别标签,中间用逗号分隔,代码长这样:

import os import numpy as np import matplotlib.pyplot as plt # 1. 字典存储配置 config = { "data_root": "./data", "img_size": 784, "batch_size": 32, "num_classes": 10 } # 2. 模拟读取数据清单 file_paths = [] labels = [] for i in range(100): file_paths.append(os.path.join(config["data_root"], f"img_{i}.jpg")) labels.append(i % config["num_classes"]) print(f"共加载 {len(file_paths)} 个样本") # 3. 定义一个简单的数据加载函数 def load_data(paths, label_list, img_size): data = np.zeros((len(paths), img_size)) for idx, p in enumerate(paths): fake_img = np.random.randn(img_size) data[idx, :] = fake_img return data, np.array(label_list) data, lab = load_data(file_paths, labels, config["img_size"]) print("数据形状:", data.shape, "标签形状:", lab.shape) # 4. 展示前 5 张“图” fig, axes = plt.subplots(1, 5, figsize=(10, 3)) for i in range(5): axes[i].imshow(data[i].reshape(28, 28), cmap="gray") axes[i].set_title(f"label={lab[i]}") axes[i].axis("off") plt.tight_layout() plt.savefig("preview.png", dpi=120)

这个例子虽然所有图片都是随机数模拟的,但已经完整覆盖了字典、列表、循环、函数、NumPy 数组、Matplotlib 可视化这些核心知识点。如果你能不看答案自己写出这个脚本,并且跑通它看到一张 1×5 的子图网格,恭喜你,基础部分基本过关了,可以往下一步走了。

7. 新手最容易踩的坑:环境与语法的排查实录

7.1 环境配置的常见问题速查

报错信息可能原因解决办法
conda: command not foundAnaconda 没有加入 PATHWindows 重新安装时勾选 PATH;macOS/Linux 执行source ~/.bashrcsource ~/.zshrc
ModuleNotFoundError: No module named 'numpy'当前环境没有安装 NumPy,或者解释器选错conda activate dl,再pip install numpy;VSCode 里重新选择解释器
通过conda create新建环境非常慢没有配置国内镜像按 2.2 节配置清华镜像后再创建
pip install下载速度极慢pip 源未替换执行pip config set global.index-url ...换清华源
在 Jupyter 里 import 自己的文件失败Jupyter 的工作目录不对在代码里先添加路径:sys.path.append("./code")

7.2 语法层面那些让人上头的问题

代码里最常见的错误有两类。一类是拼写错误,Python 是大小写敏感的,Datadata是两个完全不同的名字。另一类是缩进错误,Python 用缩进来表示代码块,同一个块里的代码必须缩进一致。这个讲一百遍不如踩一次坑来得深刻,我第一次带班的时候,有个学员在 for 循环体外面写了一句plt.show(),结果画出来的图只有最后一张,他愣是没看明白为什么。

还有一个特别典型的坑是“直接把 list 赋值给另一个变量,然后修改其中一个”。因为列表是可变对象,赋值只是复制了引用,两个变量其实指向同一份数据。遇到这种情况要搞清楚要不要用copy()或者切片来创建一个独立的副本。NumPy 里也有类似的视图和复制问题,比如b = a.view()b = a.copy()的区别,搞不懂的话很容易出现“改了 b 结果 a 也变了”的诡异问题。

7.3 关于打印日志的小建议

我建议从第一天学 Python 开始,就养成随手打印中间结果的习惯。不要等到程序报错才去打印,而是每完成一个小阶段就print一下数据的 shape、类型,或者关键变量的值。特别是用到 NumPy 和文件读取的地方,打印一眼就能确认数据的尺寸和内容是否符合预期。排查问题的时候,把关键位置的打印结果贴给有经验的人看,人家一眼就知道问题出在哪,比你自己空想要高效得多。

8. 学完这些之后,下一步往哪走

Python 基础学完,不是让你停下来去背更多语法,而是应该马上去做和深度学习更近的事。我的建议是按下面这个顺序来:

先花一两天把 Jupyter Notebook 用熟,它是做实验、写分析最顺手的工具。然后去把 NumPy 的常用操作再过一遍,因为后面的张量操作全是围绕数组形状和数据类型展开的。接着可以直接上 PyTorch 的官方教程,从“60 分钟入门”那个章节开始,一边看一边动手敲代码。你会发现里面大量使用到咱们前面讲的这些知识——用字典存超参数、用 for 循环遍历数据、用类定义模型、用 NumPy 做数据预处理、用 Matplotlib 画损失曲线。

如果还想补一补,Pandas 也可以学一点。它特别适合处理表格型数据,比如 CSV 格式的数据集,很多 Kaggle 比赛的数据预处理都用它。但我不建议一开始就花太多时间在 Pandas 上,先把深度学习的核心流程跑通,再回头按需学就行。

我个人带班下来的一个真实感受是:Python 基础这一关,卡住的大多不是天赋问题,而是节奏问题。一天想看完所有语法是不可能的,但如果你按着“能跑通一个完整的数据处理流程”这个目标去学,每天消化一小块,配着代码动手敲一敲,两到三周时间足以具备进入深度学习大门的能力。最重要的不是记住所有细节,而是形成一种感觉——拿到一段深度学习的代码,你能大致猜到它是在干什么,哪些地方需要认真看,哪些只是固定的流程。这种“感觉很对”的状态,就是基础打牢了的标志。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询