ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

深度学习入门必看:Python基础与环境搭建实战指南

深度学习入门必看:Python基础与环境搭建实战指南 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/simplepip 那个命令会在你的用户目录下生成一个配置文件把全局的 pip 下载源改成清华源。这样你后面装任何 Python 包都会快很多。第三步创建一个深度学习专用环境。我一般会让学员统一用 Python 3.10因为目前主流的深度学习框架对 3.8 到 3.11 都有比较好的支持3.10 属于保守但稳妥的选择。命令是conda create -n dl python3.10 conda activate dl创建完之后命令行前面应该会出现(dl)的标识这就说明你已经进入这个独立环境了。后面不管装什么包切记先把环境激活否则装错地方激活以后还是找不到包这是新手最容易犯的错。第四步装基础的科学计算库。在新环境里执行pip install numpy pandas matplotlib jupyter这些是后面处理数据和可视化都要用的先装上跑一遍没问题之后再根据具体项目去装 PyTorch。装完以后可以顺手验证一下python -c import numpy; print(numpy.__version__)能正常打印出版本号就说明环境没问题了。2.3 编辑器选型VSCode 和 PyCharm 怎么选环境只是“引擎”你还需要一个写代码的“驾驶舱”。我给班的建议是Windows 用户首选 VSCodemacOS 用户也是 VSCode只有之前已经熟悉 PyCharm 的同学可以继续用 PyCharm没必要强行换。VSCode 的优势是轻量、启动快、对 Python 的支持经过几年迭代已经非常好用了。装好之后去扩展市场搜 Python 扩展安装微软官方出的那个发布者是 Microsoft它会自动帮你做语法检查、代码补全和调试。然后按CtrlShiftP打开命令面板输入Python: Select Interpreter选择你刚才创建的那个dl环境。这一步很多新手漏了结果 VSCode 还在用系统自带的全局 Pythonimport 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(fEpoch {epoch}, loss: {loss:.4f})这就是 if 语句最常见的用法没什么玄乎的就是“如果满足什么条件就做什么事”。条件还能组合用and、or、not判断是否同时满足多个条件。再看循环。深度学习中最常见的循环就是遍历数据。你有一个列表存放了所有训练样本的路径你要一个接一个地把它读进来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_size32, shuffleTrue): ...调用的时候可以写成create_dataloader(./data, batch_size64, shuffleFalse)一眼就能看出你改了哪些参数。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, encodingutf-8) as f: config json.load(f)这个with语句是 Python 里推荐的做法它会在代码块结束后自动关闭文件不需要你手动调用close()。踩过坑的同学可能知道手动写文件经常忘了关结果文件内容没保存下来。如果是读图片路径我推荐用os.path模块来拼接路径。因为不同操作系统路径分隔符不一样Windows 用反斜杠macOS 和 Linux 用斜杠直接写死路径换台机器就废了。用os.path.join(data, images, cat.jpg)会自动适配系统。另外新手经常遇到一个编码问题读中文文件报错。解决办法是打开文件时都明确指定encodingutf-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(axis0) # 对每个特征维度求均值形状 (784,) std data.std(axis0) 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, cmapgray) plt.title(fLabel: {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, dpi150)就可以把图保存下来方便写实验报告或者发到群里讨论。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], fimg_{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), cmapgray) axes[i].set_title(flabel{lab[i]}) axes[i].axis(off) plt.tight_layout() plt.savefig(preview.png, dpi120)这个例子虽然所有图片都是随机数模拟的但已经完整覆盖了字典、列表、循环、函数、NumPy 数组、Matplotlib 可视化这些核心知识点。如果你能不看答案自己写出这个脚本并且跑通它看到一张 1×5 的子图网格恭喜你基础部分基本过关了可以往下一步走了。7. 新手最容易踩的坑环境与语法的排查实录7.1 环境配置的常见问题速查报错信息可能原因解决办法conda: command not foundAnaconda 没有加入 PATHWindows 重新安装时勾选 PATHmacOS/Linux 执行source ~/.bashrc或source ~/.zshrcModuleNotFoundError: No module named numpy当前环境没有安装 NumPy或者解释器选错先conda activate dl再pip install numpyVSCode 里重新选择解释器通过conda create新建环境非常慢没有配置国内镜像按 2.2 节配置清华镜像后再创建pip install下载速度极慢pip 源未替换执行pip config set global.index-url ...换清华源在 Jupyter 里 import 自己的文件失败Jupyter 的工作目录不对在代码里先添加路径sys.path.append(./code)7.2 语法层面那些让人上头的问题代码里最常见的错误有两类。一类是拼写错误Python 是大小写敏感的Data和data是两个完全不同的名字。另一类是缩进错误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 基础这一关卡住的大多不是天赋问题而是节奏问题。一天想看完所有语法是不可能的但如果你按着“能跑通一个完整的数据处理流程”这个目标去学每天消化一小块配着代码动手敲一敲两到三周时间足以具备进入深度学习大门的能力。最重要的不是记住所有细节而是形成一种感觉——拿到一段深度学习的代码你能大致猜到它是在干什么哪些地方需要认真看哪些只是固定的流程。这种“感觉很对”的状态就是基础打牢了的标志。
返回列表