ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

pylearn2 安装教程:Python 2.7 + Theano 1.0 锁版本与避坑指南

pylearn2 安装教程:Python 2.7 + Theano 1.0 锁版本与避坑指南

简介:Pylearn2 是基于 Theano 的经典深度学习框架,由蒙特利尔大学 MILA 实验室开发,适合研究者与初学者理解卷积网络、受限玻尔兹曼机等经典模型,并可用于图像分类、特征学习等入门实验。这份源码压缩包共 750 个文件、约 2.16MB,主体为 522 个 Python 源文件,另有 70 个 yaml 实验配置、51 个 txt 文档、CUDA 算子、IPython 示例及训练脚本,覆盖模型定义、数据加载、优化器与可视化模块。目前已有 271 人学习下载。通过阅读和运行其中代码,可掌握 setup.py 安装方式、网络层组合逻辑、数据加载流程、优化器配置及训练曲线监控等实用方法;若配合 Theano 环境,还能直接在 Notebook 中跑通示例,观察 CNN/RBM 训练过程。资源还包含 readme、说明文本与少量示例图像,目录结构完整,便于对照源码理解后端实现与深度学习概念,是梳理经典框架设计思路的难得素材。

1. 还在搜 pylearn2 安装?先锁版本,再谈训练

深度学习框架一轮一轮换,pylearn2 这个 Theano 时代的库早就停止更新了,但隔三差五还是有人找我帮忙装它:复现老论文、跑课程遗留代码、对比当年的基准结果,都得把它请出来。装 pylearn2 最大的坑不在它本身,而在它的出生年代——源码里全是print语句和xrange,你拿 Python 3 环境去装,第一步就死在语法错误上。更麻烦的是它的核心依赖 Theano 也停更了,新版 numpy、新版 Pillow 全都放弃了对 Python 2.7 的支持,版本组合稍微放飞一点,连import pylearn2都过不去。这篇文章给你一套我实测能跑通的版本组合和安装顺序,从建环境、装依赖、配 Theano 到跑通一个 MNIST 训练配置,整个过程照着抄就行。

2. 版本与环境:Python 2.7、Theano 1.0 和依赖的极限版本

2.1 版本组合:pylearn2 为什么锁死 Python 2.7

先看一组我验证过能正常训练的版本组合,后面所有操作都围绕这张表展开,不要随意升级,也别随手装"最新版":

组件推荐版本说明
Python2.7.xpylearn2 源码使用 Python 2 语法,3.x 直接语法报错
Theano1.0.4最后维护版,与 pylearn2 的符号计算接口完全兼容
numpy1.16.6最后一个支持 Python 2.7 的版本
scipy1.2.2最后一个支持 Python 2.7 的版本
Pillow6.2.2替代已停更的 PIL,6.x 是最后支持 Python 2.7 的大版本
matplotlib2.2.5最后一个支持 Python 2.7 的版本
PyYAML5.4.1pylearn2 的 yaml 配置解析依赖

pylearn2 的源码里大量使用print语句、xrange、.iteritems()这类 Python 2 专属写法,在 Python 3 下连语法检查都过不了,更别提运行训练脚本了。所以环境的第一原则就是:Python 2.7。而 Python 2.7 在 2020 年停止官方维护之后,生态里的第三方库一个接一个放弃支持,这就导致你不可能"装最新版依赖",只能掐着每个库的最终支持版本来配。

这也是为什么我强烈建议用 conda 而不是自己下 Python 2.7 安装包:conda 能在一个隔离环境里给你完整的 Python 2.7 解释器和配套 pip,不会污染你机器上现有的 Python 3 环境,装坏了删掉重建也就一分钟的事。

2.2 用 conda 建一个干净环境:参数和源的选择

假设你已经装好了 Anaconda 或者 Miniconda,先创建一个独立的 Python 2.7 环境:

conda create -n pylearn2 python=2.7 -y conda activate pylearn2 python --version

第一行conda create -n pylearn2中的-n是指定环境名为pylearn2,python=2.7让 conda 自动解析一个可用的最新 2.7 版本,-y跳过确认提示。第二行激活环境,第三行验证解释器版本。

这里有个细节:conda 给 Python 2.7 环境配的 pip 是兼容 2.7 的老版本 pip,这一点非常关键。如果你在系统环境里用新版 pip 去装 Python 2 的包,大概率直接报 "is not a supported wheel on this platform" 之类的错误。conda 环境天然避开了这个坑。

如果你发现 conda 创建环境时下载包特别慢,常见做法是给 conda 配置国内镜像源,配置文件写在用户目录的.condarc里,把channels指向可用的镜像地址即可。这个属于环境问题,建议提前处理,否则后面每一步下载都会很煎熬。

2.3 逐个装依赖:为什么是这些"极限版本"

环境激活之后,一次性装齐 pylearn2 的全部 Python 依赖:

conda install numpy=1.16.6 scipy=1.2.2 pillow=6.2.2 matplotlib=2.2.5 pyyaml=5.4.1 -y

上面每个包名=版本号都是精确锁版本。numpy 1.16.6 是 numpy 官方最后支持 Python 2.7 的版本,scipy 1.2.2 同理,Pillow 到 6.2.2 就停止支持 Python 2.7 了,matplotlib 最后支持 2.7 的版本是 2.2.5。这些不是随手挑的,而是"这个环境下能装的最高版本",再高就装不上了。

这里我选择用 conda 装而不是 pip,原因是:Python 2.7 下的老版本包,pip 需要现场解析依赖关系,经常因为某个传递依赖版本不兼容而失败;conda 的预编译包把依赖树都处理好了,锁版本安装的成功率高很多。

装完验证一下依赖是否完整可导入:

python -c "import numpy, scipy, PIL, matplotlib, yaml; print(numpy.__version__, scipy.__version__, PIL.__version__, matplotlib.__version__, yaml.__version__)"

这一步能一次性暴露所有导入期错误。如果报ImportError,说明对应包没装进当前环境,检查conda list是否在当前环境内。

依赖之外还有一个容易被忽略的系统级要求:g++ 编译器。Theano 在 CPU 上要把符号计算编译成 C 代码,依赖 g++。如果你跑训练时看到 "g++ not detected" 的警告,Theano 会退回纯 Python 模式,速度慢到让你怀疑人生:

sudo apt-get install g++ build-essential

Debian/Ubuntu 系统用上面这条命令,装完重新打开终端让 PATH 生效。这一步不做,后面 import theano 虽然能过,但训练速度会让你抓狂。

3. 安装 pylearn2:clone 源码、develop 模式、第一次 import

3.1 拿源码:从官方仓库 clone

pylearn2 没有发布过 pip 包,官方安装方式就是源码安装。找一个干净的目录,把仓库拉下来:

mkdir -p ~/work && cd ~/work git clone <pylearn2 官方仓库地址> pylearn2 cd pylearn2 git checkout master

在 GitHub 上搜 pylearn2 就能找到官方仓库,项目名就叫 pylearn2。git clone后面的地址填仓库的 HTTPS 地址即可。git checkout master切到主分支,因为 pylearn2 没有打太多 release 标签,社区普遍直接使用 master 分支的代码。

这里提醒一句:不要去找所谓的"修复版"或"第三方分支"。老库的分支水很深,有些第三方分支混入了不兼容的改动,表面能 import,跑训练时各种玄学报错。官方 master 分支虽然停更,但它是被验证最多的代码基线。

3.2 安装模式:为什么用 setup.py develop 而不是 install

进入源码目录后执行:

python setup.py develop

develop模式不会把代码复制到 site-packages,而是在 site-packages 里生成一个指向当前源码目录的链接文件。这样做的好处有三个:一是改源码立刻生效,调试老代码时经常要翻进库内部看实现,改完不用重装;二是环境里能清楚知道 pylearn2 的代码实际在哪;三是卸载方便,pip uninstall pylearn2删掉链接就行。

如果你的环境没有 setuptools,setup.py develop会报错,conda 的 Python 2.7 环境默认自带,系统 Python 2.7 需要先补:

pip install setuptools

用develop而非install,最直接的理由是查源码方便。pylearn2 这类停更库,很多报错你要靠读它的源码才能定位,develop模式下编辑器直接打开源码目录就能跳转,比在 site-packages 里翻副本舒服太多。

3.3 第一次 import:两个黑匣子一起验

安装完成先做最小冒烟测试:

python -c "import pylearn2; print(pylearn2.__file__)"

如果输出一个路径,说明 import 成功;如果报ModuleNotFoundError,大概率是 develop 装进了别的 Python 环境,用which python确认当前解释器是不是 conda 的 pylearn2 环境。

但这只是第一步,pylearn2 真正跑训练时全靠 yaml 配置驱动,核心入口是pylearn2.config.yaml_parse模块,它要解析对象构造语法!obj:。所以更关键的验证是这个:

python -c "from pylearn2.config import yaml_parse; print('yaml_parse ok')"

这一步才是真正的黑匣子。如果报ImportError: No module named yaml_parse,说明 pylearn2 源码路径没被正确链接;如果报 yaml 相关错误,说明 PyYAML 版本或安装有问题。两条命令都通过,pylearn2 本体才算装完,接下来才能安心理得地配 Theano。

4. 配置 Theano:.theanorc 里最该改的三个参数

4.1 .theanorc 写在哪个位置,谁去读它

Theano 的配置不放在 pylearn2 里,而是由 Theano 自己读取。Linux 下默认读用户目录的~/.theanorc,另一个方式是设置环境变量THEANORC指向一个自定义配置文件。优先级从高到低是:Theano 函数调用时的theano.config参数 > 环境变量THEANORC>~/.theanorc。

我一般建议用~/.theanorc,因为 pylearn2 的训练脚本不给你传 Theano 参数的机会,配置文件是唯一稳定生效的入口:

cat > ~/.theanorc <<'EOF' [global] floatX = float32 device = cpu optimizer = fast_run EOF

这段配置只指定了三个最核心的参数。floatX = float32是模型默认精度,device = cpu强制走 CPU,optimizer = fast_run开启 Theano 的完整编译优化。先解释清楚每个参数,再讲为什么这样配。

4.2 floatX、device、optimizer 三个参数的取舍

floatX这一项最容易翻车。pylearn2 里很多模型实现默认按 float32 设计和初始化权重,你把它设成 float64,内存直接翻倍,CPU 训练速度明显变慢;更要命的是有些损失函数对数值精度敏感,float64 下会出现一些极小梯度回传,导致结果和论文对不上。所以统一用float32,这也是当年深度学习框架的通用精度约定。

device先写cpu,别一上来就想着 GPU。Theano 1.0 的 GPU 后端依赖 pygpu 和 gpuarray 库,这套东西和新版 CUDA 的兼容性非常差,我见过太多人先写device = cuda0,结果 import theano 直接报 "Cannot use gpu device" 或者找不到 libgpuarray。稳妥策略是:先把 CPU 环境完整跑通,确认训练链路没有问题,再回头折腾 GPU 加速。如果你确实要上 GPU,需要额外装 pygpu 并写device = cuda0,这个放到避坑章节细说。

optimizer有两个常用值:fast_run和fast_compile。fast_run会做完整的图优化——融合算子、消除冗余计算、重排执行顺序,编译时间长但运行速度快,适合正式训练;fast_compile只做必要转换,编译快但生成的代码效率低,适合调试阶段频繁改代码时用。我调试老模型时一般改成fast_compile,确认逻辑没毛病再切回fast_run。

如果想给训练过程加一点显示信息,可以在~/.theanorc里再补一段:

[global] floatX = float32 device = cpu optimizer = fast_run [lib] cnmem = 0.8

[lib] cnmem是 GPU 显存预分配比例,CPU 模式下不生效,写在这里是为了将来切 GPU 时不用再改文件。

4.3 PYTHONPATH:两种模式下的差异

很多网上教程会教你设置PYTHONPATH指向 pylearn2 源码目录。这里要说清楚:如果你按第 3 章走了setup.py develop,其实不需要设置 PYTHONPATH,develop 模式已经把源码目录链接进了 site-packages。

但如果你没跑 setup.py、只是把仓库 clone 下来当普通目录用,那就必须手动告诉 Python 去哪找包:

export PYTHONPATH=$HOME/work/pylearn2:$PYTHONPATH

这行建议写进~/.bashrc末尾,这样每次打开终端都会自动加载。$HOME/work/pylearn2要替换成你实际的源码目录。

这里有个隐蔽的坑:如果你既跑了setup.py develop,又设置了 PYTHONPATH,某些情况下 Python 会优先加载 PYTHONPATH 指向的源码目录,而 develop 链接指向的也是同一个目录,一般没事;但如果你的 PYTHONPATH 指错了路径,import 到的 pylearn2 可能来自一个旧副本,症状是训练时报错信息里的文件路径和你改过的源码对不上。排查时先执行python -c "import pylearn2; print(pylearn2.__file__)"看实际加载路径,再执行pip show pylearn2看 develop 链接的状态。

5. 避坑清单:pylearn2 安装翻车记录

5.1 现象:pip 装老包报 "is not a supported wheel on this platform"

装 theano 或 pyyaml 时,pip 直接拒绝识别要下载的 wheel 包,甚至提示当前 Python 版本不受支持。

原因:Python 2.7 停止维护后,pip 从 21.0 版本开始放弃了对 Python 2.7 的支持。系统环境里的新版 pip 根本没法正确处理为 Python 2.7 构建的 wheel 元数据。

解决:在 conda 的 pylearn2 环境里把 pip 降到最后一个支持 Python 2.7 的版本:

pip install "pip==20.3.4"

安装完用pip --version确认。从那以后我装任何 Python 2.7 的老环境,第一件事永远是先锁 pip 版本,这个不解决,后面每一步都在踩雷。

5.2 现象:import theano 时警告 "g++ not detected"

theano 能正常导入,但训练时打印一行警告,说检测不到 g++,然后训练速度慢到无法忍受。

原因:Theano 的符号计算需要编译成 C 代码执行,编译器缺失时它会静默退回纯 Python 实现。功能没错,但性能差了上百倍,一个本来几秒钟的 epoch 能拖到几分钟。

解决:安装编译链:

sudo apt-get install g++ build-essential

装完重开终端,让新 PATH 生效。这件事属于典型的"不报错但坑人"问题,现象不明显,等到真正跑训练才发觉不对。

5.3 现象:配置了 device = gpu 后 import theano 直接报错

.theanorc里写了device = gpu或device = cuda0,import theano 时报 "Cannot use gpu device" 或 "Unable to import gpuarray"。

原因:Theano 1.0 的 GPU 后端已经切换到 gpuarray 架构,它依赖独立的 pygpu 库和 libgpuarray。只装 theano 不装 pygpu,GPU 后端根本无法初始化。

解决:先确认有没有装 pygpu:

pip install pygpu

装完再 import theano 试试。如果仍然报错,大概率是 pygpu 依赖的 libgpuarray 与你的 CUDA 版本不匹配,这个基本只能靠版本对齐解决,常见做法是降低 CUDA 版本或换用 conda 安装 pygpu(conda 会解析出配套的 libgpuarray)。实在调不通就退回device = cpu,先把训练流程跑通,GPU 加速不是 pylearn2 安装的优先事项。

5.4 现象:Python 3 环境下 import pylearn2 报 SyntaxError

直接import pylearn2就报语法错误,或者定位到某个文件里有print语句、xrange未定义。

原因:pylearn2 源码是 Python 2 语法写死的老库,Python 3 解释器在解析阶段就挂了。

解决:不要试图做 2to3 转换,也不要找"兼容 Python 3 的分支",老老实实回到 Python 2.7 环境。用第 2 章的 conda 命令重建环境,这一步是必经之路,绕不过去。

5.5 现象:setup.py develop 报错找不到 develop 命令

执行python setup.py develop时提示invalid command name 'develop'。

原因:当前环境缺少 setuptools,develop 命令是 setuptools 提供的,还不是标准库 distutils 的功能。

解决:

pip install setuptools

装完重新执行python setup.py develop。conda 的 Python 2.7 环境一般会预装 setuptools,用系统自带 Python 2.7 时更容易遇到这个问题。

6. 装完怎么验证:跑一个 MNIST 训练配置才算数

import 成功只能说明安装没坏,真正的验证是跑通一个训练流程。我习惯用一个最小化的 MNIST 分类配置来验收环境,二三十秒就能看出整条链路是否健康。新建一个mnist_mlp.yaml文件,内容如下:

!obj:pylearn2.models.mlp.MLP { nvis: 784, layers: [ !obj:pylearn2.models.mlp.Sigmoidal { layer_name: 'h0', dim: 500, irange: 0.05 }, !obj:pylearn2.models.mlp.Softmax { layer_name: 'y', n_classes: 10, irange: 0 } ] } !obj:pylearn2.training_algorithms.sgd.SGD { learning_rate: 0.01, batch_size: 100, monitoring_batches: 10, cost: !obj:pylearn2.costs.mlp.Default {}, termination_criterion: !obj:pylearn2.termination_criteria.EpochCounter { max_epochs: 1 } } dataset: !obj:pylearn2.datasets.mnist.MNIST { which_set: 'train', start: 0, stop: 2000 }

这个 yaml 的结构是 pylearn2 的标准配置三段式:模型定义、训练算法、数据集。!obj:是 pylearn2 的 yaml_parse 对象构造语法,冒号后面写模块路径和类名,花括号里是构造参数。模型是一个 784→500→10 的浅层 MLP,训练用 SGD,学习率 0.01,batch size 100,只跑 1 个 epoch,数据只取训练集前 2000 个样本,保证 CPU 上几十秒内跑完。

执行训练:

cd ~/work/pylearn2 python pylearn2/scripts/train.py /path/to/mnist_mlp.yaml

train.py 的位置在源码目录的pylearn2/scripts/下,所以先 cd 到源码根目录再指定 yaml 的完整路径。如果数据集目录没配置,pylearn2 会报找不到数据文件的错误并提示期望路径,常见做法是设置环境变量PYLEARN2_DATA_PATH指向数据目录,然后把 mnist 数据文件放进该目录下的 mnist 子目录。

训练跑起来后,日志里有两类关键信息:Training objective是损失值,第一个 epoch 应该在 0.6 到 0.7 附近;train_y_accuracy是训练集准确率,刚开始在 0.85 左右浮动,随着 epoch 增加逐步上升。看到这两个数字在变化,才说明从数据加载、模型构造、Theano 编译到参数更新的整条链路是通的。

从那以后我每次装完这类老库,都强制自己走一遍 import 验证加真实训练配置,不看到准确率数字动起来就不算装完。这一步能暴露前面所有步骤里被忽略的问题,尤其是 Theano 的编译链路和数据集路径这两个最容易出幺蛾子的环节。希望这篇笔记能帮你少走几趟弯路,一次把 pylearn2 跑起来。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进