全文共9175字,预计学习时长18分钟

图片来源:redcharlie Unsplash

本文作者是Facebook的机器学习/人工智能首席开发布道师,为其麾下的PyTorch团队助力,曾经是一名软件工程师。

值得注意的是,在之前,作者从未使用过PyTorch。他将用自己的亲身经历告诉你:PyTorch并不难学。

PyTorch内容集锦

PyTorch及其工作原理:

• PyTorch是Facebook开发的深度学习框架,用于快速灵活实验。这是一个基于Python的计算软件包,含有 C++后端API。

• PyTorch的Python前端有三个不同部分:

Torch

这是一个包含多维张量与数学运算的数据结构包。

Torch.nn

用于创建并训练神经网络。区域块的导入数据以张量形式传递。

例如:为处理图像而训练卷积神经网络时,可使用nn.conv2D模块(这一想法来自笔者同事塞斯)。

Torch.optim

该优化算法可训练神经网络。

例如:适用于初学者的SGD或适合进阶者的Adam等算法,都可训练神经网络(这个好例子也源自塞斯)。

Tensors(张量)

PyTorch的Tensors 与Numpy数组类似。不同之处在于,Tensors数据可以是单个数字,或一维矩阵(向量),或囊括各种数据的多维结构。

算梯度即求导(没错,机器学习即微积分)。求出张量的梯度,便可最大程度地规避错误。

梯度下降这一算法能有效实现错误最小化。错误由数据决定,而数据的分类也有适当与不适当之别。

通过梯度降低不当分类项目数。

张量最重要的特点即自动跟踪梯度。每个张量中的数据代表神经网路的连接层。这其中,有三点值得一提:

• 阶 (rank): 确定张量的维数。例如,向量为一阶。

• 形状 (shape): 行数和列数,表现形式为tensor. Size ([x]).

• 数据类型 (type): 给张量元素所指定的数据类型。

PyTorch的神经网络训练循环如下:确定目标函数、迭代输入其他数据、将数据运用于神经网络、执行梯度操作减少误差,将异常参数运用于神经网络。

在神经网络中重复迭代整个训练数据集即可。

C++ 后端

C++“后端”有五个不同部分。

• Autograd: 自动求导,即张量上的记录操作,进而生成自动求导图,基本上依据梯度张量求导。

• ATen: 张量及数学运算库。

• TorchScript: 连接TorchScript的JIT编译器与解释器的界面(JIT为“即时”)

• C++前端: 训练与评价机器学习模型的高级构造。

• C++ 扩展: 通过自定义C++与CUDA的例程扩展,扩展Python的API.

CUDA (计算机统一设备架构) 是由Nvidia推出的并行计算架构及应用程序界面 (API) 模型。

上述内容皆援引自维基百科,总的来说,CUDA常用于GPU上的各项操作。

GPU即图像处理器。可将其视为具有强大运算力的电脑。

“说好的概览呢?这些知识点简直让人摸不着头脑。”虽然上述内容的确晦涩难懂,但它们至关重要。

若想对相关知识有深入全面的了解,请参阅优达课程(https://classroom.udacity.com/courses/ud188)并阅读PyTorch docs(https://pytorch.org/docs/stable/index.html)这份资料,必能让你获益匪浅。

那份资料并不着眼于PyTorch的方方面面,而是帮助读者开始给GitPyTorch开源数据库贡献代码(https://github.com/pytorch/pytorch)。

在这份repo中,你可根据上述信息,自行推断大量所含文件夹的内容。

搭建开发环境

贡献任何代码之前,务必阅读CONTRIBUTING.md这份文档(https://github.com/pytorch/pytorch/blob/master/CONTRIBUTING.md),切勿有所遗漏。这是笔者从血泪中总结出的教训。

若条件允许,无论是处理Python还是C++问题,最好都借助GPU。

还可采用其他途径(如AWS DLAMI或Nvidia Docker),这会显著提升运行速度。

作为初学者,笔者犯下的第一个错误就是在本地电脑上开工。由于本地电脑性能不够强大,各种令人困惑头疼的段错误也就层出不穷。

最终,笔者用SSH、MOSH、TMUX等登陆GPU服务器,效果极佳。如果想就此做好准备,可参阅以下博文:

• HPC上的GPU运算简介:安装GPU与SSH

https://sydney-informatics-hub.github.io/training.artemis.gpu/setup.html

• PyTorch必备——GPU

https://discuss.pytorch.org/t/solved-make-sure-that-pytorch-using-gpu-to-compute/4870

• GPU内存须知

https://discuss.pytorch.org/t/reserving-gpu-memory/25297

• 安装PyTorch与Tensorflow—— 采用支持CUDA的GPU

https://medium.com/datadriveninvestor/installing-pytorch-and-tensorflow-with-cuda-enabled-gpu-f747e6924779

接下来,搭建PyTorch开发环境。想用SSH登陆GPU,须做好以下内务处理操作:

• 连接GitHub账号,确保在GPU创建SSH密钥,并将其添加至GitHub账号。

• 你的设备很可能会用到Python。须确保用的是Python 3。你很可能已经安装了 pip。如若不然,务必全部安装。

• 安装Miniconda. 这和pip极为类似。官方网站并没有很好的终端安装指南,在此列出笔者的操作方式:

$ with-proxy wget “https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh"$ chmod +x Miniconda-latest-Linux-x86_64.sh$ bash Miniconda3-latest-MacOSX-x86_64.sh

• 重启终端,输入conda,确保操作无误。

• 运行conda config — set auto_activate_base false, 以防止Conda自动激活,不然会干扰机器的运作。

• 运行 conda activate,激活Conda。每次开发前,务必保证conda处于激活态,注意终端的(base)语句即可。

• 安装 ccache。如果无效,在启用conda的情况下执行 conda install ccachewhen conda。若依然无效,请尝试wget。"https://www.samba.org/ftp/ccache/ccache-3.3.3.tar.gz".

• 输入ccache 确保一切奏效,输入conda list确保其出现在安装列表。

• 安装一个faster linker。除非万不得已,不然请勿输入 ln -s /path/to/downloaded/ld.lld /usr/local/bin/ld 指令。笔者曾遇到这种情况,由于它们作用不大,最终还得将相关文档全部删除。

• 运行 pip install ghstack 或 conda install ghstack.

• 运行 pip install ninja 或 conda install ninja.

• 通过pip install flake8 flake8-mypy flake8-bugbear flake8-comprehensions flake8-executable flake8-pyi mccabe pycodestyle pyflakes安装 Flake8,它会为你纠错。若想给文档纠错 (lint),输入 flake8 <FILENAME> 即可。

• 安装一个IDE,通过SSH登陆GPU。笔者在Atom. 上查找remote-ssh ,即可得到相关操作说明。

• 最后,安装PyTorch:

$ git clone https://github.com/pytorch/pytorch$ cd pytorch$ git pull --rebase$ git submodule sync — recursive$ git submodule update — init — recursive$ python setup.py develop

python setup.py develop 就是用来编写PyTorch代码的工具。一开始会花些工夫,但一旦写过一次,以后就能使用不少加速方法。

编辑C++时需要构建PyTorch,但编辑Python时则不然。

想把这一系列步骤办好,就得斗志昂扬,心怀热忱。不过一旦完成这不易的任务,你就可以长舒一口气,好好犒赏下自己。

如果碰壁,不要恐慌,笔者也有过类似的经历。参照后文的《常见错误》,或在评论区留言,笔者必竭力相助。搭建好开发环境会花一番工夫,祝各位马到成功。

代码时间到!

开发环境搭建完毕,可以开始写代码了!

如果你之前从未贡献过开源代码,务必略读《行为准则》(https://github.com/pytorch/pytorch/blob/5bc7c1f83dd3ea740ba1d2af286c464862b90743/docs/source/community/governance.rst)。很多代码库都有这样的文档,简言之,做好人,行好事。

关注GitHub的问题 (issues) 选项卡。其中囊括很多社区成员提出的问题。点击训练营 (bootcamp) 标签,查看初学者级别的问题,选择自己能力范围内的任务,加以攻坚。

笔者建议,开始动手前,先阅读相关资料,洞悉个中玄机。还可更新过滤器 (filter) 查看训练营的历史纪录,研究已解决的问题。

如果你胸怀大志,大可点击 pull requests 标签。不是所有的PR都有相关的问题可供参考,有时研究问题本身更容易了解情况。

刚研究这些问题时,“冒牌货综合征”如乌云般笼罩在自己心头。“我又不是科班出身,怎么做得了这个?”打住!相信自己,你能行!

解决问题无须全知全能,找到方向,难题便迎刃而解。

如果你找到一个愿意动手解决的问题,要敢于留言并发问,哪怕是这样的一句话,“我想接下这个任务,请问你能就如何着手给我一些建议吗?”都大有裨益。

这些问题板块下的评论者都很乐于助人,因为如果有人对这些问题感兴趣,他们自己也会很高兴。对此笔者有切身体会,在他们的引导下,笔者解决了一系列问题,自己的PyTorch技术也日臻完善。

接下来是案例分析,阐述笔者如何在一头雾水的情况下解决问题。

第17893号问题:确保Grad_outputs的输出值形状与torch.autograd.grad()一致

幸运的是,据笔者切身经验来说,PyTorch库的作者往往细致缜密,言之有物。

就此例:https://github.com/pytorch/pytorch/issues/17893而言,结合前文的知识,不难发现,由于该问题涉及“接受输入”,所以这必定与Python前端有关。

乍一看这个问题角度很刁钻,虽然本质上与Python相关,但题目中的autograd,却有将人引向C++之嫌。

笔者创建一个新分支并将其导至最高级的torch文件夹(本例中,所涉及的函数正是torch)。

有趣的是,在最早创立的文件夹中,正好有一个名为autograd ,真可谓无巧不成书。

打开 autograd 文件夹,在 grad( 语句中调用git grep ,以确定函数定义。可以确定,其中一个就在 __init__.py 文件中。

更巧的是,在 grad 函数,中 正好有以 *gasp*为名的变量,也就是说只需要做一个简单的condition,一切便迎刃而解。

如题所示, outputs 与 grad_outputs 须形状一致。通过NumPy,有一个简单的法子可以做到这点。

import numpy as np...if np.shape(outputs) != np.shape(grad_outputs):

raise RuntimeError("grad_outputs and outputs do not have the same shape")

作为一名优秀的软件工程师,笔者很清楚只有先测试代码,才能保证自己的PR滴水不漏。不过首先,得确认程序的兼容性没有问题。

据CONTRIBUTING.md 文件所示, 先得运行 python test/run_test.py。

运行结果并不尽如人意,那么究竟是哪里出了纰漏?原来PyTorch在调用NumPy并不直接照搬,而是会做出相应调整。只能这样说,PyTorch可以无损调用NumPy中的函数。在这篇文章(https://github.com/wkentaro/pytorch-for-numpy-users)中,笔者获悉如何实现两种程序的代码转化。

此外,这篇文章中还提到,只能在一个(而非多个)张量中读取形状需求,因此笔者调用shape() 语句时也出了差错。因此,__init__.py 中 grad() 函数代码也须修改,详情如下:

for out, grad in zip(outputs, grad_outputs):
if not out.shape == grad.shape:
raise RuntimeError("grad_outputs and outputs do not have the same shape")

再次测试程序,这次终于成功,接下来是报错测试。

打开test 文件夹,里面是带有test_grad 函数的 test_autograd.py 文件,一切都是那么的简洁明了!

在敲定测试方案前,笔者先加入一些打印语句。谨记,打印语句是Python编程师的鼎力助手。

打印随机变量有助于深入了解张量,并从程序上将其与梯度张量相比较。

此外,读取其他测试,了解项目中相关对象的创建与测试,也能令人获益匪浅。最终,测试如下:

grad_out = torch.ones(2)try:

torch.autograd.grad(

outputs=[grad_sum], grad_outputs=[grad_out],

inputs=[x], create_graph=True)

self.assertFail()

except RuntimeError as error:

self.assertEqual(str(error), "grad_outputs and outputs do not have the same shape")

运行上述测试,万无一失。接下来,用Flake8纠错,在GitHub上提交修改结果,创建PR,添加问题标签,确认与原问题标签一致,提交,搞定收工!

很快,笔者就收到了评论,这些意见逻辑清晰、颇有洞见,因此也极易落实。

第一桩PR圆满完成!幸好只用Python就可解决,毕竟,又有谁敢去编辑臭名昭著的C++呢?不过明知山有虎,偏向虎山行,有请下一个问题!

第22963号问题: 通过Torch.flatten(),输入零维张量,得出零维张量(非一维) 

起初,笔者并未意识到该问题涉及C++API, 但仔细一看(再次给出题者点个赞),一切不言而喻。

切勿一见讨论而萌生退意,围绕这些问题的讨论往往蕴含很多信息。在接手问题之前,要确保自己有解决的方法。

该问题涉及两方面,一是“返回值”,二是“输入值”。输入值与“前端”相关,即Python;而“输出值”与“后端”相关,即C++。

创建新分支,大胆一试。大部分编程都是这么一回事——怀揣希望,放手一试。

首先,探寻 flatten() 函数的奥秘。而这便是打印语句的用武之地。

导航回 test 文件夹, 在flatten( 上调用git grep 。经过一番查询,笔者恰好在test_torch.py文件找到test_flatten 函数。

打开文件,研究其断言,明白自己所找何物后,输入如下打印语句:

# Test that flatten returns 1-dim tensor when given a 0-dim tensor

zero_dim_tensor = torch.tensor(123)

one_dim_tensor = torch.tensor([123])

cool_dim_tensor = torch.tensor([1,2,3])

flat0 = zero_dim_tensor.flatten()

flat1 = one_dim_tensor.flatten()

flat2 = cool_dim_tensor.flatten()print("--zero dim tensor--")

print(zero_dim_tensor)

print(zero_dim_tensor.shape)

print(flat0)

print(flat0.shape)

print("--one dim tensor--")

print(one_dim_tensor)

print(one_dim_tensor.shape)

print(flat1)

print(flat1.shape)

print("--cool dim tensor--")

print(cool_dim_tensor)

print(cool_dim_tensor.shape)

print(flat2)

print(flat2.shape)

输出值如下:

--zero dim tensor--

tensor(123)

torch.Size([])

tensor(123)

torch.Size([])

--one dim tensor--

tensor([123])

torch.Size([1])

tensor([123])

torch.Size([1])

—cool dim tensor--

tensor([1, 2, 3])

torch.Size([3])

tensor([1, 2, 3])

torch.Size([3])

结果与问题相吻合。展开后,零维张量与一维张量是等值的。

根据这些打印语句可得,这个等值性是由其形状(shape)为torch.Size([1])决定的。一经展开,零维向量等于一维向量。

接下来在代码中验证这一观点。笔者在GitHub库中搜索“flatten”的实例。在Python中,的确有Flatten模块这一说法。

由此,笔者第一次意识到自己得处理C++编程,一般来说人们不愿从事模块编辑,而这其中另有玄机。

有这么一种模块框架,名为 caffe2。你大可谷歌百度,简言之,它是PyTorch的一部分,并且人们往往不赞成使用这一框架。对笔者来说,编辑Caffe2不是个好主意。

无奈地盯着tensor_flatten.cpp文件,笔者似乎只能止步于此。这可是让人头疼的C++,就算费上九牛二虎之力,恐怕到头来自己仍一筹莫展。

鼓起勇气求助之前,笔者对着屏幕足足懊丧了一个小时,“冒牌者综合征”如阴云般在脑海中挥之不去。

干坐着泄气可不是理想的应对之策。如果不是坐在办公室,笔者恐怕早就发帖询问该从哪里下手了。所幸的是,办公桌几步之外,便是好心的工程师同伴。谢天谢地,在他们的点拨下,阴云散去,柳暗花明。

解决这一难题的关键在于aten. 因为 ATen 即张量运算库,而flatten 与运算息息相关。

明白这个道理需要花一番工夫。如果你因无处解惑而一筹莫展,可参阅PyTorch技术文档(https://pytorch.org/docs/stable/torch.html?highlight=flatten#torch.flatten)。

这表明,想解决这个问题,须找到带有各种参数(如input, start_dum, end_dim)的flatten  函数,返回一个Tensor 。根据这个说法,很明显之前笔者的尝试有如南辕北辙。

笔者决定在顶层调用 git grep,实现Tensor flatten( 。于是顺理成章地得到atn, TensorShape.cpp。这代码看上去没问题,准没错。

为了彻底理解该代码,笔者审阅了数遍,并确保单步执行的函数符合逻辑。

这代码看起来如何?简洁易懂!这样每当输入一维张量时,它就会模仿flatten 函数,而非返回输入值:

if (self.dim() == 0) {

shape.reserve(1);

shape.push_back(1);

return self.reshape(shape);

}

更新测试,代入合适的结果,然后一切水到渠成。接下来就是纠错,做PR,获取建议反馈,贡献PyTorch代码大功告成!

点滴感悟

笔者贡献开源代码已有些时日,以下几点经验教训值得牢记:

1. 勇于探索  不要对代码心生畏惧。这些代码都是聪明人写出来的(对于大项目来说更是如此),其中蕴含许多玄机可供探索。勇于揭开那些代码的神秘面纱,哪怕不准备为其添砖加瓦,仅仅是了解其工作原理,也能使自己获益匪浅。

2. 勤于发问 不必害羞瑟缩,GitHub开源社区倡导共享精神,主张领导力培养。别人会因为你的发问与参与心潮澎湃,进而伸出援助之手。

3. 乐于学习  你并不是团队中的冒牌者,只要自己乐于学习敢于拼搏,哪怕不是科班出身,不能做到凡事心领神会,你依然可以为团队发展添砖加瓦。

4. 善于钻研  多读资料。查阅README,技术文档,参与论坛,这些都能让人受益颇多。

5. 敢于尝试  哪怕自己不是稳操胜券,想不出万全之策,也不要踌躇不前,要敢于尝试。

望诸位的编程之路一帆风顺!

常见错误一览

Import not found, or import not connecting

1. 确认是否键入输入值。

2. 确认conda 是否激活。

3. 重启PyTorch。

NumPy functions don’t work

1. 先确认能否在不影响效果的情况下,用 PyTorch 替换Numpy。

2. 如若不然,在GitHub上创建问题,征求PyTorch可兼容的函数来达到预期效果。亦可自己写出函数。

Not all the tests on my PR are passing

1. 别气馁,深呼吸,相信自己。

2. 有时,这不是你的错。检查日志文件,留意是否有来自本机的新消息,若收到新消息,重新访问代码。

3. 你并未合并自己的PR,但团队其他成员合并了各自的PR。不过你有个好团队,伙伴们会告知你并为你分忧。

推荐阅读专题

留言 点赞 发个朋友圈

我们一起分享AI学习与发展的干货

编译组:董宇阳、张婷华

相关链接:

https://medium.com/better-programming/committing-to-pytorch-by-someone-who-doesnt-know-a-ton-about-pytorch-fa222253cf2d
如需转载,请后台留言,遵守转载规范

推荐文章阅读

ACL2018论文集50篇解读

EMNLP2017论文集28篇论文解读

2018年AI三大顶会中国学术成果全链接

ACL2017 论文集:34篇解读干货全在这里

10篇AAAI2017经典论文回顾

长按识别二维码可添加关注

读芯君爱你

脸书AI首席开发布道师:如何贡献PyTorch代码相关推荐

  1. 【华为云技术分享】华为云 DevCloud 首席产品布道师:AIOps 不是 DevOps 的下一代

    近年来,将软件开发流程迁移到云上成为开发领域的一大趋势.随之而来地,人们会关心,和本地开发方式相比,云上开发能为企业带来哪些益处?能否保证安全.可信?未来它还将与 AI 技术碰撞出怎样的火花?在 QC ...

  2. 应对海量并发请求,首席布道师谈微服务的应用架构设计

    何李石 七牛云首席布道师 <Go语言程序设计>译者,Go语言/容器虚拟化技术布道师.实践者. 5年以上互联网创业经验和企业级产品研发.运营经验,同时也是互联网产品基础架构解决方案专家. 随 ...

  3. 正式启动|2020腾讯犀牛鸟云开发校园技术布道师养成计划

    为顺应信息技术行业发展趋势及人才需求,促进新时代云计算领域人才培养,在信息技术新工科产学研联盟的指导下,由腾讯云.腾讯高校合作和图灵教育联合主办,牛客网协办的2020腾讯犀牛鸟云开发校园技术布道师养成 ...

  4. 获奖结果公布|2020腾讯犀牛鸟云开发校园技术布道师养成计划

    导语: 为顺应信息技术行业发展趋势及人才需求,促进新时代云计算领域人才培养,在信息技术新工科产学研联盟的指导下,由腾讯云.腾讯高校合作和图灵教育联合主办,牛客网协办的2020腾讯犀牛鸟云开发校园技术布 ...

  5. 七牛首席布道师:Go不是在颠覆,就是在逆袭

    文章来源:http://www.csdn.net/article/2014-07-21/2820743 七牛官网: https://github.com/qiniu http://developer. ...

  6. 到「黄埔学院」去:打造AI首席架构师,第二期限量招募!

    今年 1 月,百度联合"深度学习技术及应用国家工程实验室"成立黄埔学院,旨在为产业培养第一批"首席AI架构师".黄埔学院一期学员历时半年的学习和交流,6 月 1 ...

  7. 【周记】腾讯犀牛鸟「云开发」校园技术布道师养成计划

    一个月前开始试着学习微信小程序 恰好腾讯举办了这个[腾讯犀牛鸟「云开发」校园技术布道师养成计划]https://www.bilibili.com/read/cv4965254这个活动 技术增长 抛开活 ...

  8. 陆奇是AI的布道师:人类数字化三位一体

    陆奇是AI的布道师:人类数字化三位一体 信息系统,模型系统,行动系统 信息系统已经成熟,模型系统取得了突破 趣讲大白话:数字化进化彻底加速改变人类 [趣讲信息科技158期] ************* ...

  9. 重磅演讲分享,亚马逊云科技首席布道师为你的职业生涯指点迷津(二)

    点击上方[凌云驭势 重塑未来] 一起共赴年度科技盛宴! 从新人菜鸟到职场老手 增长的不仅仅是工作经验 更是职场思维的转换 上一期我们分享了 亚马逊云科技副总裁.首席布道师  Jeff Barr 在 C ...

  10. MindSpore布道师队伍招募开始,助力小白成为大牛!

    3月28日,华为开源了新一代全场景深度学习框架MindSpore的v0.1.0-alpha版本,具有基于源码转换的通用自动微分.自动实现分布式并行训练.数据处理.以及图执行引擎等功能特性. 仅仅相隔一 ...

最新文章

  1. 2020mysql下载教程_Windows10 安装MySQL详细教程2020版 亲测亲写
  2. git 你get了吗(git命令日常使用)
  3. python实战项目_11 个实战项目,掌握 Python 数据可视化
  4. C++、C#写的WebService相互调用
  5. zsh性能分析(没搞完)
  6. java验证cron表达式_cron表达式
  7. ReSharper 全教程
  8. MAC下的环境变量配置
  9. “深度撞击”号探测器与地球失去联络
  10. 【问题解决】D:\Users10476\AppData\Local\Programs\Microsoft vsCode\unins000.exe 尝试在目标目录创建文件时发生一个错误:拒绝访问。.
  11. jQ UI 后台管理系统基础UI
  12. 百度、阿里、美团、头条…论剑AI,这里有开发者想知道的未来
  13. docker 安装wiki.js 和wekan
  14. 华为交换机 查ip冲突_华为交换机怎么通过ip查端口号
  15. # Kinect V2 简介
  16. html导航栏的颜色怎么改变,我怎样才能改变导航栏的背景颜色
  17. [js]整合google,51ditu和mapbar的地图API [此博文包含图片]
  18. java获取身份证上的出生日期
  19. 计算机高级职称论文写什么题目,高级职称论文格式的要求
  20. 算法5:线性DP与区间DP

热门文章

  1. linux 系统基本设置
  2. 营业执照遗失该如何处理
  3. Newtonsoft.Json.Linq 简单使用
  4. 关于微信小程序的wx.request执行后sucess和fail的问题
  5. 4237. 【五校联考5day1】Melancholy (Standard IO)
  6. python tenacity用装饰器方式重试用例,提高测试用例的健壮性
  7. python四级是什么水平_四级能过的水平大概什么水平?
  8. SCI论文分区有两种方法
  9. css中英文单词换行的问题
  10. python0309