- 你好？
好吧，这是12后，所以我想上手。
所以今天，讲座八，我们要谈
深学习软件。
这是一个超级令人兴奋的话题，因为它改变
每年都有不少。
但也意味着它是一个大量的工作给这个讲座
“因为它每年变化很大。
但是，像往常一样，一对夫妇的管理注释
我们潜入材料之前。
因此，作为一个提醒的项目建议您
当然项目是由于周二。
所以希望大家翻在，
并希望大家有一个稍微好主意
什么样的项目，你想工作
为类。
所以，我们在指定的TA对项目进程
根据项目区是什么
和的TA的专业知识。
所以我们必须了解一些详细信息
在接下来的几天，我认为。
我们也是在分级分配一个过程，
敬请关注，我们会得到那些成绩还给你
只要我们能做到。
另外提醒的是，分配两个HA被淘汰
一段时间。
这将是在下周，一个星期从今天起，星期四。
再次，在分配两个工作时，
记得要停止你的谷歌的云实例
当你不工作，努力保持你的学分。
和混乱的另一位，我只是想
再次强调的是，对分配你们两个真
只需要使用GPU实例最后的笔记本电脑。
对于所有的几款笔记本的它只是在Python
和NumPy的，所以你不需要为这些问题的任何图形处理器。
如此反复，节省你的学分，
只有当你需要他们使用的GPU。
而最后提醒的是，中期快到了。
这是一种很难相信我们在那里已经，
但中期将是在课堂上周二，五九岁。
所以，中期将更加理论化。
这将是某种笔和纸，通过不同的工作
种，稍微理论问题
检查你的，我们已经对材料的理解
到目前为止覆盖。
我想我们可能会后至少短期排序
的问题类型的样品的期望。
题？
[学生的话掩盖由于缺乏麦克风]
哦，是的，问题是，无论是开卷，
所以我们要说的闭注，闭卷。
所以才，
是啊，是啊，所以这是我们在过去所做的那样
只是闭注，闭卷，相对
俨然要检查你明白
大部分的东西背后，我们已经提出的直觉。
因此，快速回顾一下作为一个提醒我们在谈论
关于最后一次。
上次我们谈到票友优化算法
深学习模型，包括SGD势头，
涅斯捷罗夫，RMSProp和亚当。
而我们看到，这些相对小的调整
香草SGD的顶部，是比较容易实现
但可以让你的网络收敛快一点。
我们还谈到了正规化，
特别是辍学。
所以请记住辍学，你有种随机设置
的网络的部分直传期间为零，
然后你那种边缘化出过的噪音
在测试时间回来。
我们看到，这是怎样的一个普遍模式
在许多不同类型的正规化建设
在深度学习，在那里你可以添加某种
训练过程中的噪音，但随后走出边缘化
噪音在测试时间，所以它不是随机的
在测试时间。
我们还谈到了迁移学习你在哪里
也许可以下载大网络被预先训练是
一些数据集，然后微调他们为你
自己的问题。
这是你可以攻击很多问题的一种方式
在深度学习，即使你没有一个巨大的
你自己的数据集。
所以今天我们要换档一点点
说说一些螺母和螺栓
如何编写软件，以及如何将硬件的工作原理。
一点点，潜入了很多细节
什么软件看起来像你实际上
用在实践中培养这些事情。
因此，我们将谈谈CPU和GPU的一点点
然后我们来谈谈几个主要的
深度学习的框架是在那里使用
这些天。
因此，首先，我们已经有点提到这一关手
一群不同的时间的，
计算机有CPU的，计算机有图形处理器。
深度学习使用的GPU，但我们并没有真的
太露骨了这一点关于究竟是什么
这些东西为什么一个可能会更好
比另一个不同的任务。
那么，谁是以前建造的电脑吗？
正中下怀举手。
所以，也许关于你的第三，你一半，
地方周围的球场。
所以这是我的电脑在家里拍
我内置。
你可以看到，有很多东西要去上
在计算机内部，也许，希望你知道
大多数这些零件都是。
而CPU是中央处理单元。
这就是这个小芯片这个冷却风扇下隐藏
这里靠近外壳的顶部。
而CPU实际上是比较小的一块。
它的壳体内的相对小的事情。
它不占用了大量的空间。
而GPU是这两个大怪物的东西
所占用的空间，一个巨大的量
在这种情况下。
他们有自己的冷却，
他们采取了大量的电能。
他们是相当大的。
所以，只要在他们多大的权力使用方面，
在他们是多么大的方面，GPU是一种
轰烈，并占用了大量的空间
在这种情况下。
所以，问题是什么是这些东西
他们为什么深学习如此重要？
那么，该GPU被称为显卡，
或图形处理单元。
而这些都是真正发展起来，最初是为渲染
计算机图形，尤其是围绕游戏
而诸如此类的事情。
因此，手的另一个节目，谁在家里玩视频游戏
有时，不时在他们的电脑？
是啊，如此反复，也许一半左右，好的分数。
因此，对于那些你们谁之前曾经玩过视频游戏
和谁已经建立了自己的电脑，
你可能对这个辩论自己的观点。
[笑]
因此，这是计算机科学的大辩论的一个。
你知道，有没有像英特尔与AMD，
NVIDIA与AMD的显卡。
这是那里的Vim与Emacs的文本编辑器。
而几乎所有的玩家都有自己的意见
在这两个边，他们更喜欢的
对于自己的名片。
而在深学习我们种大多回升
这场斗争的一面，那就是NVIDIA。
所以，如果你们有AMD显卡，
你可能会更有点麻烦，如果你想
使用这些深层的学习。
真的，NVIDIA一直在推动很多关于深度学习
在过去的几年里。
它已经种了一些自己的战略大焦点。
他们投入大量的精力投入到工程
那种良好的解决方案，使他们的硬件
更适合深度学习。
所以大多数人在深度学习，当我们谈论的GPU，
我们几乎完全谈论的NVIDIA GPU。
也许在未来，这将改变一点点，
有可能还会有新的球员加入，
但至少现在NVIDIA是很占优势。
所以，给你喜欢的想法有什么区别
在CPU和GPU之间，我已经种了一个小
这里电子数据表。
在顶部，我们有两个的那种高端英特尔的
消费的CPU，并在底部，我们有两个
NVIDIA的排序目前的顶级高端消费的GPU。
还有一对夫妇的总体趋势在这儿需要注意。
两个GPU和CPU是一种通用
计算机器，他们可以执行程序
并做排序的任意指令，
但他们定性有很大不同。
所以，CPU的往往只有几个核心，
消费类台式机CPU，这些天，
他们可能有一些像四个或六个
也许多达10个核心。
随着超线程技术，这意味着他们可以运行，
硬件可以物理上运行，如可能8
或最多20个线程并行。
所以CPU可以或许做的20件事并行一次。
所以，这只是不是一个巨大的数字，
但对于那些CPU线程是非常强大的。
他们实际上可以做很多的事情，
他们是非常快的。
每个CPU的指令实际上可以做相当多的
的东西。
他们都可以很独立工作。
对于GPU的这是一个有点不同。
因此，对于GPU的，我们看到的是，这些类型的共同上端
消费者的GPU有上千个内核。
所以NVIDIA泰坦XP这是当前
行消费GPU的上方有3840个内核。
所以这是一个疯狂的数字。
这就像这样超过10个核心，你会得到
对于同等价位的CPU。
一个GPU的缺点是每个这些核心的是，
一个，它运行在一个非常慢的时钟速度。
和两个他们真的不能做相当多。
你真的无法比拟的CPU核心和GPU核心
苹果和苹果。
该GPU内核不能真的很独立运作。
他们都挺需要共同的
和排序的瘫痪在许多核心一个任务
而不是每个核心完全做自己的事。
所以，你真的不能直接比较这些数字。
但它应该给你的感觉是，由于
到可排序的大量核心的GPU，
是平行的东西确实好，你
需要做很多的事情都在同一时间，
但这些东西都是大同小异的味道。
另一件事是CPU和GPU之间的指出
这种想法的记忆。
对，所以CPU有一些缓存的CPU上，
但这是相对较小，多数
为你的CPU内存被从你的拉
系统内存，RAM，这将可能像
在典型的RAM 8，12，16，32千兆字节
消费台式这些天。
而GPU的真正拥有自己的RAM内置
到芯片中。
有一个非常大的瓶颈通信
在您的系统RAM和GPU之间，
所以一般的GPU有自己的
相对较大的块的卡本身内的存储器。
而对于泰坦XP，这也可能是目前
行消费卡的顶部，
这个东西有12 GB的内存本地的GPU。
图形处理器也有自己的缓存系统
那里有缓存的排序多个层级
GPU存储器的12千兆字节之间
和实际的GPU核心。
而这有点类似于缓存层次结构
你可能在CPU中看到。
因此，CPU是一种用于通用处理的很好。
他们可以做很多不同的事情。
而GPU是也许更专门为这些高
麻痹性算法。
所以，事物的原型算法工作
真的真的很好，就像是完全适合
到GPU是矩阵乘法。
所以，记得在矩阵乘法左侧
我们有一个像一堆行组成的矩阵。
我们乘上由另一组成矩阵权
一堆列，然后这产生
另一个，最终矩阵，其中在每个元素
输出矩阵是行中的一个之间的点积
和两个输入矩阵的列中的一个。
而这些点的产品都是独立的。
就像你能想象，这个输出矩阵
你可以完全分解它
并具有各不同的那些要素的
输出矩阵的所有被计算并行
他们的所有排序都运行相同的计算
这是考虑这两个向量的点积。
但究竟在何处，他们正在阅读从数据
是从在两个输入矩阵不同的地方。
所以，你可以想像，一个GPU可以只
像爆炸了这一点，让所有这些元素
输出矩阵的所有并行计算
并且，可以使这件事计算机超级超级快
在GPU上。
所以这是一种原型类型的问题
像其中GPU实在是非常适合，
其中一个CPU可能去中和步
顺序，并计算这些元件的每
一个接一个。
这图片是讽刺，因为一点点
CPU的这些天有多个内核，
他们可以做量化的说明，以及，
但尽管如此，对于这些像大规模并行问题
GPU的往往有更好的吞吐量。
尤其是当这些矩阵得到真的大了。
顺便说一句，卷积是一种相同的
样的故事。
当你在卷积知道我们有这个输入张量，
我们有这个权重张，然后在每一个点
卷积后输出张量又是一些内
权重的某些部分之间的产品
和输入的某些部分。
你能想象，一个GPU可以真正瘫痪
这个计算，拆了这一切横跨多核心
并很快计算它。
所以这是一种类型的味道一般
的问题，其中GPU的给你一个巨大的速度优势
CPU相比。
所以，实际上你可以编写直接运行程序
在GPU上。
所以NVIDIA有这个CUDA抽象，它可以让你写
代码那种看起来像C，
而是直接执行上的GPU。
但是CUDA代码是真的很棘手。
它实际上真的很难写CUDA代码，这是
高性能和实际挤压所有的出汁
这些图形处理器。
你必须非常小心管理的存储层次
并确保你没有高速缓存未命中
和分支预测失败和所有诸如此类的东西。
因此，它实际上是真的真的很难写高性能
对自己的CUDA代码。
因此，作为一个结果，NVIDIA已经发布了很多库
实现共同计算基元
这是非常非常高的GPU的优化。
因此，例如NVIDIA有CUBLAS库实现
不同种类的矩阵乘法的
和那些超级优化不同的矩阵运算，
在GPU上运行的非常好，非常接近排序的
理论峰值硬件利用率。
同样他们有它实现了一个cuDNN库
之类的东西卷积，向前和向后传球，
批标准化，复发性网络，
所有这些类型的计算原语
我们需要在深度学习。
NVIDIA已经在那里并发布自己的二进制文件
这非常有效地计算这些原语
在NVIDIA硬件。
因此，在实践中，你往往不就结了写自己的
深学习CUDA代码。
您通常只是大多调用到现有的
代码，其他人都写过。
其中大部分是一直严重东西
通过NVIDIA已经过优化。
还有另外一种类型的语言称为OpenCL的
这是更一般的一点。
上不仅仅是NVIDIA GPU的更多运行时，
可以在AMD硬件上运行，可以在CPU上运行，
但OpenCL的，没有人真的花了一个真正的大量
的心血和精力试图得到优化深度学习
针对OpenCL元，所以它往往是少了很多
高性能在CUDA超级优化版本。
因此，在未来，也许我们可能会看到一个有点更加开放
标准，我们可能会在许多不同的看到这
更多类型的平台，但至少在目前，
NVIDIA的同类城市的主要游戏深的学问。
所以，你可以检查一下，有很多不同的资源
为了解你如何能做到GPU编程自己。
它是一种乐趣。
这有点不同范式的编写代码的
因为它的这种大规模并行架构，
但是这是一个有点超出本课程的范围。
再次，你并不真正需要编写自己的
CUDA代码要在实践深度学习。
而事实上，我从来没有写我自己的CUDA代码
对于任何研究项目，所以，
但它是一种有益知道喜欢它是如何工作的
什么是基本的想法，即使你不
自己写的吧。
所以，如果你想看看样的CPU GPU性能
在实践中，我做了一些基准测试去年夏天
比较体面的英特尔CPU
针对一大堆的是一种不同的GPU
附近当时该行的顶部。
而这些都是我自己的基准，你可以找到
在GitHub上更多的细节，但我的发现是，
对于像VGG 16和19，ResNets，各种ResNets，
那么你通常会看到类似65〜75倍
运行完全相同的计算时加快
就行了GPU的顶部，在这种情况下一个Pascal泰坦X，
与该行的顶部，好了，不是很行的顶部
CPU，在这种情况下是一个Intel E5处理器。
虽然，我想作一个排序警告这里
是，你总是需要小心超
当你正在阅读任何一种基准
关于深学习，因为它的超级容易被
不同的事物之间的不公平。
你那种需要知道很多有关细节
究竟是为了知道所基准
比较是否不公平。
因此，在这种情况下，我会直截了当地告诉你
这可能这个比较是有点不公平
到CPU，因为我并没有花很大的功夫
要挤的最大性能
出的CPU。
我可能有更好的调整高炉库
对于CPU的性能。
而我可能已经得到了这些号码
好一点。
这是排序的开箱即用性能
之间只是安装火炬，在CPU上运行它，
刚刚安装火炬手它在GPU上。
因此，这是一种开箱即用的性能，
但它不是真的很喜欢高峰，可能的话，理论
吞吐量在CPU上。
但是他这样说，我觉得还是有相当
实质性的速度提升到这里了。
另一种有趣的结果，从这一基准
物比较这些优化cuDNN库
从NVIDIA的卷积和诸如此类的东西与
一直手撰文指出的那种比较幼稚CUDA
在开放源码社区。
你可以看到，如果你比较同一网络
在具有相同深度学习相同的硬件
框架，唯一不同的是换出
这些cuDNN与排序写的手，次优
CUDA你可以看到类似近三个X加快
全线当你从相对切换
简单CUDA这些像超级优化cuDNN
实现。
因此，在一般情况下，只要您在GPU上编写代码，
你应该总是喜欢只是确保
您正在使用cuDNN，因为你可能会离开
对，如果你的表中的三个X的性能提升
不指责cuDNN为你的东西。
因此，在实践中出现了另一个问题，
当你正在训练这些东西是
你知道吗，你的模型也许是坐在GPU，
该模型的权重是在12千兆字节
对GPU的本地存储，但你的大数据集
坐在了右侧的硬盘驱动器上
或SSD或类似的东西。
所以，如果你不小心，你可以真正瓶颈
你的训练通过只是想读取数据
从磁盘。
“导致GPU是超级快，它可以计算
向前和向后相当快的，但如果你正在读
依次关闭旋转盘，你其实可以
相当瓶颈你的训练，
那可真不好，你慢下来。
因此，这里的一些解决方案是像你知道
如果数据集是非常小的，有时你可能只是
读取整个数据集到RAM中。
或者，即使你的数据集不是那么小，
但你有一吨的RAM一个巨大的服务器，
你可以做到这一点呢。
您也可以确保您使用的是固态硬盘，而不是
硬盘驱动器的，可以帮助很多与读取吞吐量。
另一种常见的策略是使用多线程
在CPU上被预取关闭RAM数据
或关闭磁盘，缓冲剂它在存储器中，在RAM中，从而
那么你就可以继续喂养缓冲数据下降
具有良好性能的GPU。
这是一个有点痛苦的成立，
但是再喜欢，这些GPU的是如此之快，
如果你不是真的小心试图喂
他们的数据尽可能快地，
只是读取数据有时瓶颈
整个训练过程。
所以这是一个需要注意的。
所以这是一种在简要介绍的喜欢
排序GPU CPU硬件的实践中，当谈到
深学习。
然后我想切换齿轮一点点
和谈论的事情软件方面。
人们使用的各种深度学习框架
在实践中。
但我想在我前进，
有没有任何形式的关于CPU + GPU的问题？
是啊，问题吗？
[学生的话掩盖由于缺乏麦克风]
是啊，所以这个问题是你能排序，
你可以做机械的，当你编码
为了避免这些问题呢？
也许你可以在软件中做的最重要的事情
设置排序在CPU上预取的。
就像你可以不喜欢，那种天真的事
会是你有这样的连续过程，你
首先从磁盘读取数据，等待数据，
等待要读取的minibatch，
然后喂minibatch到GPU，
然后去向前和向后的GPU，
然后读取另一个minibatch和排序的做到这一切
按顺序。
如果你确实有多个，
而不是像你可能在正在运行的CPU线程
背景被提取数据从磁盘
这样，虽然，
你可以排序的交织所有这些事情。
像GPU正在计算，
在CPU后台线程被喂养过磁盘数据
和你的主线程是一种等待这些事情，
只是做了一些这些事情之间的同步
所以他们都发生在平行。
幸好，如果你使用一些深层学习
框架，我们将要谈论，
然后一些这方面的工作已经做了你
“因为它是一个有点痛苦。
如此之深的学习框架的景观
超快速移动。
所以，去年当我给这个演讲我主要谈
关于来自Caffe，火炬，Theano和TensorFlow。
当我最后一次给了这次谈话，再次超过去年同期，
TensorFlow是比较新的。
它并没有在那个时候看到的超级广泛采用呢。
但现在我认为在过去的一年TensorFlow
已经变得更受欢迎。
这可能是首选很多人的主要框架。
所以这是一个很大的变化。
我们也看到一吨的新框架
那种弹出像去年蘑菇。
因此，特别是Caffe2和PyTorch是新框架
从Facebook，我认为是非常有趣的。
还有一吨的其他框架。
桨，百度有桨，微软已经CNTK，
亚马逊大多采用MXNet并有一吨
其他框架的为好，但我更不熟悉，
真的没有时间进入。
但一个有趣的事情，从这张照片指出
是那种第一代深度学习的
框架，真的看到了广泛采用
建于学术界。
所以来自Caffe是从Berkeley，火炬被开发
原本NYU并且还与Facebook合作。
而Theana大部分是建立在蒙特利尔大学。
但是，这些类型的下一代深度学习的
框架都起源于工业。
所以Caffe2是从Facebook，PyTorch是来自Facebook。
TensorFlow是来自谷歌。
所以这是一种我们已经看到了一个有趣的转变
在景观在过去几年
是，这些想法真的很感动了很多
从学术界到工业。
而现在行业是种给我们这些大威力
好的框架一起工作。
所以，今天我想谈论的大多是PyTorch
和TensorFlow因为我个人认为，这些
可能是你应该专注于为那些
大量的研究类型的问题，这些天。
我也来谈谈来自Caffe和Caffe2一点。
但强调可能有点少这些。
而在此之前，我们再移动，我想我应该做
我自己的偏见有点更加明确。
所以我主要是，我已经与火炬大多工作
在过去的数年。
我已经使用了相当多的，我很喜欢它。
然后，在过去的一年我大部分时间切换到PyTorch
作为我的主要研究框架。
所以我有一些一点点经验较少
这些人，尤其是TensorFlow的，
但我还是会努力尽我所能，给你一个公平的
图片，这些东西一个体面的概述。
所以，请记住，在过去的几次讲座
我们已经敲定在这种想法的计算图表
那种遍地。
每当你在做深度学习，
要想建一些计算图
其计算要计算什么功能。
因此，在一个线性分类的情况下，你会结合
您的数据X和你的权重W与矩阵乘法。
你会做一些铰链的损失来也许有，
计算你的损失。
您将有一些调整项
和你想象的所有拼接在一起，这些不同
操作成一些图形结构。
请记住，这些图形结构可以得到相当
复杂的大神经网络的情况下，
现在有很多不同的层，
许多不同的激活。
许多不同的权重各地散布在一个漂亮的
复杂的图形。
而当你移动到东西像神经图灵机
那么你就可以得到这些真的疯了计算图表
你甚至不能真正画，因为他们是
这么大而凌乱。
如此之深的学习框架的一点是真的，
有真有种三个主要的原因，你可能
要使用这些深层次的学习框架之一
而不仅仅是编写自己的代码。
因此，第一个将这些框架使
您可以轻松地构建和使用这些大毛工作
计算图表没有那种令人担忧
讲了很多的簿记细节自己。
另一个主要的想法是，
每当我们在深度学习正在努力
我们总是需要计算梯度。
我们一直在计算有些失落，
我们总是我们的重量的计算机梯度
相对于损失。
我们想使这个自动计算梯度，
你不希望有自己写的代码。
你想要一个框架来处理所有这些反向传播
为你的细节，所以你可以想想
写下你的网络的直传
并具有后向通行排序出来的自由
无需任何额外的工作。
最后，你想这一切的东西高效运行
在GPU上，这样你就不必太担心这些
关于CUBLAS和cuDNN低级硬件细节
和CUDA以及移动所述CPU和GPU存储器之间的数据。
你有种想要被照顾的那些繁琐的细节
为你。
所以这些都是种一些主要的原因
为什么你可以选择使用框架，而不是
从头开始编写你自己的东西。
因此，作为一种的计算图的具体例子
我们也许可以写下来这个超级简单的事情。
我们有三个输入，X，Y和Z.
我们要结合X和Y产生A.
然后我们要去一个结合和Z生产乙
然后最后我们会做一些也许总结出
第B操作，得到一些缩放器最终结果C.
所以，你在这一点上可能写得够多了NumPy的代码
要认识到它的超级容易写下来，
实现这个计算图，
或者更确切地说，以实现与NumPy该位计算，
对？
你只可以种写下numpy的要
生成一些随机数据，要乘两件事情，
要添加的两件事情，你要总结出了几件事情。
而且它真的很容易做到这一点的NumPy的。
但接下来的问题是像假设我们想
来计算C的梯度相对于X，Y和Z.
所以，如果你在与NumPy工作，你那种需要写出来
这种落后自己传递。
而你已经得到了很多的做法与此有关的
家庭作业，但它可以是一种痛苦
一点点讨厌，凌乱一旦你到
真正的大复杂的事情。
另一个问题与numpy的是，它不运行
在GPU上。
所以NumPy的肯定是唯一的CPU。
而你永远不会成为能够体验
或者把这些GPU加速的加速优势
如果您是滞留在NumPy的工作。
而且它的，再次，这是一个痛苦计算
自己的渐变色在所有这些情况。
因此，那种最深刻的学习框架的目标
这些天，让你在向前传球编写代码
这看起来非常相似，numpy的，
但是，您可以在GPU上运行
并且可以自动计算梯度。
这就是那种大多数的这些大画面目标
构架。
所以，如果你想象看，如果我们来看一个例子
在TensorFlow完全相同的计算图，有
我们现在看到，在这个直传，
你写这个代码，最终看起来非常非常相似
到NumPy的直传在那里你有种做
这些乘法和这些加法运算。
但现在TensorFlow有这种神奇的线，只是
计算所有梯度为您服务。
所以，现在你没有去写自己向通行
这就是方便多了。
有关TensorFlow另一个好处是，你可真
只是，像一条线，你可以切换所有这些计算
CPU和GPU之间。
所以在这里，如果你只是用语句添加此
你这样做是前直传，
你只可以明确地告诉框架，
嘿，我要运行的CPU上运行此代码。
但是现在，如果我们只是改变这种说法有点
只有在这种情况下，一个字的变化，
改变这种C到一个G，现在的代码上GPU上运行。
而现在这个小的代码片段，
我们已经解决了这两个问题。
我们在GPU上运行我们的代码
我们遇到的框架计算所有梯度
对我们来说，所以这是非常好的。
而PyTorch那种看起来几乎一模一样。
如此反复，在PyTorch你有种写下来，
您定义的一些变量，
你有一定的直传和直传再次
看起来很相近似的，在这种情况下相同
到NumPy的代码。
再然后，你可以只使用PyTorch计算
梯度，只用一行所有的梯度。
而现在在PyTorch再次，它真的很容易切换
到GPU，你只需要你所有的东西投射到
CUDA数据类型，你敲响你的计算之前
现在一切都透明地运行在GPU为您服务。
所以，如果你那种只看这三个例子，
码侧的这三个片段通过侧，
在NumPy的，在TensorFlow和PyTorch
你看到TensorFlow和PyTorch码
在向前传球看起来几乎完全一样NumPy的
这是伟大的“事业numpy的有一个美丽的API，
它真的很容易的工作。
但是，我们可以自动计算梯度
我们可以自动运行的GPU。
所以那种出台后，
我想潜水，并在一点点聊得更多
约一种正在发生的事情这里面的细节
TensorFlow例子。
因此，在整个演讲的其余部分正在运行的例子，
我将使用培训两层完全连接
随机数据作为一种运行例子RELU网络
贯穿这里其余的例子。
而且我们要培养这件事与L2欧几里得
损失的随机数据。
因此，这是一种愚蠢的网络，它不是真的这样做
有用的东西，但它确实给你的，
这是比较小的，自包含的，
该代码在幻灯片上不适合太小，
它可以让你表现出有用的种类很多
这些框架内的想法。
所以这里就对了，哦，再另注，
我是一种假设与NumPy和TensorFlow
已导入所有这些代码片断。
因此，在TensorFlow您通常将您的计算
分为两个主要阶段。
首先，我们要编写一些代码定义
我们的计算图表，这就是这个红色代码
起来的上半部分。
再经过定义您的图表，
你会一遍又一遍的运行图
和实际数据馈送到图形
执行您希望它执行任何计算。
因此，这是真的，这是一种大的
在TensorFlow共用图案。
您想先来一堆代码，构建图
然后你会去和运行图和重用
很多很多次。
所以，如果你种潜入大楼的代码
该图在这种情况下。
在最顶端，你看到我们定义这个X，Y，
W1和W2，我们正在创建这些tf.placeholder对象。
因此，这些将要输入节点的图形。
这些都将是那种入口点图
在那里，当我们运行图中，我们将在数据饲料
并把它们通过这些输入插槽我们
计算图表。
因此，这实际上并不像分配任何内存
马上。
我们只是排序设置这些输入插槽
到图形。
然后，我们将使用这些输入插槽，现在
有点像这些符号变量
而我们要执行不同的操作TensorFlow
在为了建立这些符号变量
我们想要的东西计算到这些变量运行。
所以在这种情况下，我们正在做一个矩阵乘法
X和W1之间，我们正在做一些tf.maximum做
RELU非线性然后我们正在做的另一
矩阵乘法来计算我们的预测输出。
然后，我们再使用排序基本张量
操作来计算我们的欧氏距离，
我们对我们的预测和目标Y之间L2损失
在这里指出的另一件事情是，
这些代码实际上并没有任何的计算。
有没有在系统中没有数据现在。
我们只是建立这种计算图形数据
结构告诉TensorFlow哪些操作
我们希望，一旦我们把真实的数据来最终运行。
所以这只是建筑图，
这实际上没有做任何事情。
然后我们有这个神奇的所在行我们计算后
我们的损失与这些象征性的操作，
那么我们就可以只要求TensorFlow计算
损失的梯度相对于w1和w2
在这一个神奇，美丽的线条。
这避免了你写作对你自己的backprop代码
你必须在作业要做。
但同样没有实际的计算发生在这里。
这只是有点添加额外的操作
在计算图，其中现在的计算
图具有这些它将最后附加的操作
计算这些梯度为您服务。
所以，现在在这一点上，我们已经计算出我们的计算
图中，我们在这个图形数据结构这个大图
在内存中，知道我们想要什么样的操作执行
来计算梯度的损失。
现在，我们进入一个TensorFlow会话实际运行
该曲线图中，并与数据馈送它。
那么，一旦我们进入了会议，
那么我们实际上需要建立一些具体值
将被供给到图形。
所以TensorFlow只是希望从接收数据
numpy的阵列，在大多数情况下。
所以在这里我们只是创建具体实际值
为X，Y，W 1和使用numpy的，然后存储这些W2
在一些字典。
现在这里是我们实际运行图。
所以，你可以看到我们调用session.run
实际执行图形的某些部分。
第一个参数丢失，告诉我们该图的哪个部分
我们其实是想作为输出。
而这，让我们真正想要的图形，
在这种情况下，我们需要告诉它，我们实际上
要计算损失和grad1和研究生W2
我们需要通过与该饲料字典参数
将被供给到图中的实际的具体值。
而在此之后，在这一行，
它会和运行图，然后计算
对于损失这些值grad1到毕业W2
然后返回实际的具体值
对于那些在再次NumPy的阵列。
所以，现在你解开这个输出在第二行后，
你numpy的阵列，或者你获得与损失numpy的阵列
和梯度。
所以，那么你可以去，做任何你想要的
这些值。
那么，这只能运行一个排序向前和向后
通过我们的图形，
而且只需要几行额外如果我们真的
要对网络进行训练。
所以在这里我们，现在我们正在运行的图形多次
在一个循环中，所以我们正在做的四个回路
并在循环的每次迭代，
我们称之为session.run问它来计算
损失和梯度。
现在我们正在做一个手动梯度discent一步
使用这些计算的梯度，以现在更新我们目前的
权重值。
所以，如果你实际运行这段代码并绘制损失，
然后你会看到，损失下降
和网络训练，这是相当不错的。
因此，这是一种像一个超级裸露的骨头例如
训练中TensorFlow完全连接的网络。
但这里有一个问题。
所以在这里，请记住，在直传，
每当我们执行这个图，
我们实际上在饲养的权重。
我们拥有权重numpy的阵列
而且我们明确地喂养它们到图形。
而现在，当图形执行完毕
这将会给我们这些梯度。
请记住梯度大小相同
作为权重。
因此，这意味着，每一次我们在这里运行图，
我们打算以复制numpy的阵列权重成
TensorFlow然后让梯度
然后复制从TensorFlow梯度
回给NumPy的阵列。
所以，如果你只是在CPU上运行，
这也许不是一个大问题，
但还记得我们谈到了CPU + GPU的瓶颈
和它是如何很贵实际复制数据
之间CPU存储器和GPU存储器。
所以，如果你的网络是非常大的，你的权重
和梯度非常大，
然后做这样的事情，这将是超级贵
和超级缓慢的，因为我们会被复制各类数据
来回的CPU和GPU之间的每一个
时间步长。
所以这是很糟糕，我们不希望这样做。
我们需要解决这个问题。
所以，很显然TensorFlow有一些解决这个。
而这个想法是，现在我们希望我们的权重，
W1和W2，而不是占位符我们
打算，我们预计养活他们到网络
在每一个直传，相反，我们将它们定义为变量。
因此，一个变量的东西是，生活中的值
计算图形和它要坚持
在不同的时间的计算曲线图内
当你运行相同的图形。
所以，现在不是宣布这些W1和W2作为占位符，
相反，我们只是构建它们作为变量。
但现在，因为他们生活在图表上，
我们还需要告诉TensorFlow他们应该如何
初始化，对不对？
因为在前面的情况下，我们都在喂养
从图外它们的值，
所以我们初始化它们与NumPy，
但现在因为这些东西住在图表上，
TensorFlow负责初始化它们。
因此，我们需要在tf.randomnormal操作通过，
这又是不实际初始化它们
当我们运行这条线，这就是告诉TensorFlow
我们如何希望他们被初始化。
所以这是令人困惑的误导一点点
这里发生了。
而现在，还记得在前面的例子
我们实际上是在更新之外的权重
的计算曲线图。
我们，在前面的例子中，我们计算的梯度
然后使用它们来更新权重作为numpy的阵列
然后在更新后的权重在下料
时间步长。
但现在，因为我们希望这些权重里面住
图中，更新权重的该操作
需要也有内部的操作
计算图表。
所以，现在我们用这种分配功能，变异
计算图表内这些变量
现在的突变值会在多个运行持续
的相同的曲线图。
所以，现在当我们运行这个图
当我们训练网络，
现在我们需要有一点点一旦运行图
特殊的咒语告诉TensorFlow设置这些
这是要住在图表上的变量。
然后，一旦我们做到了这一点初始化，
现在我们可以一遍又一遍的运行图。
而在这里，我们现在只是在数据和标签喂养
X和Y的权重都生活在图表上。
在这里，我们问过网络，
我们要求TensorFlow来计算我们的损失。
然后你可能会认为这将训练网络，
但这里实际上是一个错误。
所以，如果你真的运行此代码，
你绘制的损失，它没有训练。
所以这是很糟糕，这是混乱的，就像这是怎么回事？
我们写这个分配代码，我们跑的东西，
像我们计算的损失和梯度
而我们的损失是平的，这是怎么回事？
有任何想法吗？
[学生的话掩盖由于缺乏麦克风]
是啊所以一个假设是，也许我们意外
重新初始化W公司的每一个我们称之为图时间。
这是一个很好的假设，这其实不是问题
在这种情况下。
[学生的话掩盖由于缺乏麦克风]
是啊，所以答案是，我们实际上需要明确
告诉TensorFlow，我们要运行这些新W1
新W2操作。
因此，我们已经建立了这个大的计算图表数据
结构在内存中，现在当我们调用运行，
我们只告诉TensorFlow，我们想计算的损失。
如果你看一下依赖关系间的这些不同
在图表上操作，
你看，为了计算损失
我们实际上并不需要执行此更新操作。
所以TensorFlow是聪明的，它只是计算部分
所必需的计算的输出的曲线图的
你问它来计算。
所以这是一种很好的事情，因为这意味着它是唯一
做尽可能多的工作，因为它需要，
但在这样的情况下，它可以稍微有点混乱
并导致你没想到的行为。
因此，在这种情况下，解决方法是我们真正需要
明确地告诉TensorFlow来执行这些
更新操作。
这么一件事我们可以做的，这是什么建议
是我们可以添加新的W1和W2新作为输出
而只是告诉TensorFlow，我们要生产
这些值作为输出。
但是，这是一个问题太多，因为值，
这些新的W1，W2新值再次是这些大张量。
因此，如果我们告诉TensorFlow我们希望这些作为输出，
我们要再次获得此复制行为
CPU和GPU在不断迭代之间。
所以这是很糟糕，我们不希望出现这种情况。
因此，有一个小窍门，你可以做替代。
这是我们添加一种虚拟节点的图形。
有了这些假数据的依赖性
我们只想说，这个虚拟节点更新，
有新的W1和W2新，这些数据的依赖。
现在，当我们真正运行图，
我们告诉它同时计算损失，这个虚拟节点。
而这个虚拟节点实际上并不返回
任何价值，它只是没有返回，但正因为如此
依赖，我们已经把它付诸表决保证了节点
当我们运行的更新值，
我们实际上也运行这些更新操作。
所以，问题吗？
[学生的话掩盖由于缺乏麦克风]
是否有一个原因，我们没有把X和Y到图形？
而且它留校NumPy的。
因此，在这个例子中，我们在每一个重复使用的X和Y，
我们重复使用相同的X和Y在每次迭代。
所以，你是对的，其实我们可以只还停留那些
在图中，但在一个更现实的情况下，
X和Y将数据minibatches所以那些真正会
改变在每次迭代，我们将要养活
对那些在每次迭代不同的值。
所以在这种情况下，他们可以留在图中，
但他们会改变大多数情况下，
所以我们不希望他们住在图中。
哦，另一个问题？
[学生的话掩盖由于缺乏麦克风]
是啊，所以我们告诉它，我们已经投入TensorFlow
我们想要的输出损耗和更新。
更新实际上不是真正的价值。
因此，当更新计算，它只是返回无。
但由于这种依赖性，我们已经告诉它更新
取决于这些分配操作。
但是这些分配操作里面住
计算图表和所有住GPU内存里。
所以后来我们在做这些更新操作
完全依靠GPU和我们不再复制
更新值回了图形。
[学生的话掩盖由于缺乏麦克风]
所以，问题是做tf.group返回没有？
所以这个进入TensorFlow的trickiness。
所以tf.group返回一些疯狂TensorFlow值。
它有点返回有的像内部TensorFlow节点
操作，我们需要继续构建图形。
但是，当你执行的图，
当你知道的，session.run内，
当我们告诉它我们希望它来计算具体的值
来自更新，然后返回没有。
所以每当你与TensorFlow工作
你必须建立图形之间的这个有趣的间接
和构建图形中的实际的输出值
是有些滑稽怪异的对象，然后你真正得到
具体的值，当你运行图。
所以在这里你运行更新后，则输出是没有的。
这是否清除它一点点？
[学生的话掩盖由于缺乏麦克风]
所以，问题是为什么是亏损的值
为什么是更新没有？
这只是一个更新的工作方式。
因此损失的值，当我们计算，
当我们告诉TensorFlow我们要运行一个张量，
那么我们得到的具体数值。
更新是这种特殊的其它数据类型
不返回一个值，而不是返回无。
所以这是一种有些TensorFlow魔力，对那里发生。
也许我们可以，如果你还在迷茫离线交谈。
[学生的话掩盖由于缺乏麦克风]
是啊，是啊，这行为是从组方法的到来。
所以，现在，我们种有这种怪异的图案，其中我们
想做这些不同的分配操作，
我们要利用这个有趣的tf.group事情。
这是一种痛苦的，所以幸运的是TensorFlow给
你一些方便操作之类的做
这样的东西给你。
这就是所谓的优化。
所以在这里我们使用一个tf.train.GradientDescentOptimizer
而且我们告诉它我们想用什么样的学习速度。
你可以想像，有，有RMSprop，
有各种不同的优化算法在这里。
如今我们称optimizer.minimize损失
现在这是一个非常神奇的，
这是一个非常神奇的东西，
因为现在这个调用知道，这些变量
W1和W2标志着默认为可训练，
所以后来在内部，这里面optimizer.minimize
它会在和添加节点图
这将计算相对于损失的梯度
以W1和W2，然后它也执行该更新
为您和它做分组操作操作
为您和它做的受让人。
这就像做了很多神奇的东西在里面。
但随后它结束了给你这个神奇的更新值
其中，如果你挖通过他们实际使用的代码
tf.group所以它看起来非常相似，内部是什么
我们以前看到。
现在当我们运行循环内的图
我们这样做，告诉它来计算损失的相同模式
和更新。
而每一次我们告诉图形计算的更新，
然后它会真正去更新图表。
题？
[学生的话掩盖由于缺乏麦克风]
是啊，所以什么是tf.GlobalVariablesInitializer？
这样，因为这些都是真实初始化W1和W2
变量，住在图表上。
所以我们需要，当我们看到这一点，当我们创建
在tf.variable我们有这个tf.randomnormal
这是这个初始化所以
tf.GlobalVariablesInitializer引起的
tf.randomnormal实际运行并产生具体的值
初始化这些变量。
[学生的话掩盖由于缺乏麦克风]
对不起，是什么问题？
[学生的话掩盖由于缺乏麦克风]
所以它知道一个占位符会被馈送
图形和一个可变的外部是值得
住在图表上。
所以我不知道所有关于它如何决定的细节，
究竟它决定与该呼叫运行。
我想你需要通过代码来挖图
说出来，也许它的地方记录。
所以，现在我们已经种了这一点，
再次，我们已经得到了培训的这个完整的例子
网络中TensorFlow和我们是一起加入
花里胡哨，使其多一点方便。
所以，我们也可以在这里，在前面的例子
我们计算明确使用我们自己的损失
张量操作，TensorFlow你总是可以做到这一点，
您可以使用基本操作张计算
几乎任何你想要的。
但TensorFlow也给你一堆的便利
该计算这些常见的神经网络功能的东西
为你。
所以在这种情况下，我们可以使用tf.losses.mean_squared_error
它只是做了L2损失我们，让我们没有
计算它在我们自己的基本张量操作方面。
因此，另一种古怪这里是，这是一种
恼人的，我们必须明确地定义我们的投入
并确定我们的权重，然后希望它们连起来
在直传使用矩阵乘法。
在这个例子中，我们实际上已经不把偏见
在该层，因为这将是怎样一个额外的，
那么我们就必须初始化偏见，
我们不得不让他们在正确的形状，
我们不得不对广播输出偏见
矩阵的乘法，你可以看到这
那种将是一个很大的代码。
这将是一种恼人的写。
而一旦你喜欢卷积
和批归一化和其他类型的层
这种工作的根本途径，
具有这些变量，具有这些输入和输出的
与基本结合在一起，他们都
计算图形操作可能是一点点
笨拙，这可能是非常烦人
确保你使用正确的初始化权重
形状和所有诸如此类的东西。
因此，作为一个结果，有一堆某种更高层次的
围绕TensorFlow包库
并处理一些细节给你。
所以一个例子附带TensorFlow，
这是tf.layers内。
所以，现在在此代码示例，你可以看到我们的代码
只有明确声明X和Y
这些都为数据和标签的占位符。
现在我们说，H = tf.layers.dense，
我们给它输入X和我们告诉它单位= H。
这是一种又一个神奇的线
因为这个线内，它是一种建立
W1和B1，偏置，它的建立为这些变量
用正确的形状是那种在图表上
但一点点向我们隐藏。
而且它使用本泽维尔初始化对象
设立这些初始化策略。
所以，在我们这样做，是明确自己
与tf.randomnormal业务，
但现在在这里它是一种处理一些那些细节
对我们来说，它只是吐出一个H，
这又是相同的排序即H我们看到
在上一层，它只是做一些那些
我们的详细信息。
你可以在这里看到，我们也在传递一个
激活= tf.nn.relu所以它甚至做激活，
这层对我们内部的RELU激活功能。
所以它采取了很多这些建筑的护理
我们的详细信息。
题？
[学生的话掩盖由于缺乏麦克风]
问题是做了泽维尔初始默认
具体分配？
我敢肯定，它有一些默认情况下，我不知道它是什么。
我想你得看看文档。
但是，这似乎是一个合理的策略，我猜。
而事实上，如果你运行这段代码，
它收敛比前一个快得多
因为初始化为好。
你可以看到，我们使用两个调用
tf.layers这让我们建立我们的模型
没有做所有这些明确的簿记细节
我们自己。
所以这也许是更方便一点。
但tf.contrib.layer真的不是在镇上唯一的游戏。
还有像很多不同的高级库
人们建立在TensorFlow的顶部。
而且它是一种由于这个基本阳痿不匹配
在计算图是比较低的水平的东西，
但是，当我们与神经网络工作
我们有层次和权重的概念
有的层具有与它们相关的权重，
一般我们认为以稍高的水平
抽象比这个原始计算图表。
所以，这就是这些不同的包正试图
帮助你，让你在这个高层工作
的抽象。
因此，另一种非常流行的包，你可能有
之前看到的是Keras。
Keras是一个非常美丽，漂亮的API之上坐
TensorFlow和处理排序建立这些的
计算图表为您在后端。
顺便说一句，Keras还支持Theano作为后端，
所以这也是一种不错的。
而在这个例子中，你可以看到我们所建立的模型
作为层的序列。
我们建立了一些优化对象
我们呼吁model.compile这做了很多的魔法
在后端，以建立图。
而现在，我们可以调用model.fit和做全
训练过程对我们神奇。
所以，我不知道这是如何工作的所有细节，
但我知道Keras是非常受欢迎的，
所以，如果你谈论你可能会考虑使用它
TensorFlow。
题？
[学生的话掩盖由于缺乏麦克风]
是啊，所以这个问题是想干吗就没有明确的
CPU，GPU会在这里。
所以，我有种离开了这一点，以保持代码简洁。
但是你看到在一开始的例子
这是很容易翻牌所有这些事情
CPU和GPU之间有任何一些全局标志
或一些不同的数据类型
或者用一些声明，它通常比较简单
刚想一行在每种情况下切换。
但究竟什么是行看起来像
根据不同的情况有些不同。
所以实际上是这样的整体大集
更高层次的TensorFlow包装，你可能会看到
那里在野外。
它似乎像在谷歌甚至人
真的不能同意哪一个是使用正确的。
所以Keras和TFLearn是第三方库
是在那里的其他人在互联网上。
但是，有三个不同的人，
tf.layers，TF-斯利姆和tf.contrib.learn
所有附带TensorFlow，是所有类型的
做一个稍微不同的版本，这
更高级别的包装的东西。
还有另一个框架还从谷歌，
但与TensorFlow航运称为漂亮的张量
，做了同样的事情。
我想这些都不是为DeepMind不够好，
因为他们说干就干几周前
并撰写并发布他们自己的高水平
TensorFlow包装所谓的十四行诗。
所以，我不会吝惜你的，如果你是那种迷茫
所有这些事情。
有很多不同的选择。
他们并不总是相互发挥很好。
但是，你有很多选择，所以这是很好的。
TensorFlow已预先训练模式。
有一个在TF-苗条一些例子，在Keras。
“因为记得再培训模式是超级重要
当你训练你自己的东西。
还有这种想法Tensorboard的
在这里你可以加载你的，
我并不想进入细节，
但Tensorboard您可以添加排序仪器
你的代码，然后绘制损失和事
当你通过培训过程。
TensorFlow还让你跑分布式
在这里你可以分解的计算图表
在不同的机器上运行。
这是超爽，但我想大概没有人
谷歌以外的其他地区确实使用到了巨大的成功
这些天，但如果你想运行分布式的东西
大概TensorFlow是在城里的主要游戏。
旁注是很多TensorFlow的设计
是种精神上的这个早期框架的启发
所谓Theano从蒙特利尔。
我并不想通过细节，在这里，
只是如果你去通过这些幻灯片上自己，
你可以看到，Theano代码最终看起来
非常相似TensorFlow。
我们定义了一些变量，
我们做了一些直传，我们计算了一些梯度，
我们编译了一些功能，那么我们运行的功能
一遍又一遍地对网络进行训练。
所以它看起来很像TensorFlow。
所以我们还是有很多的打通，
所以我要去移动到PyTorch
也许采取在最后的问题。
所以，PyTorch来自Facebook是一种不同
TensorFlow中，我们有那种三个明确
内部PyTorch抽象的不同层。
所以PyTorch有这个张量对象，它就像一个
NumPy的阵列。
这只是一个必要的阵列，它不知道什么
关于深学习，但它可以与GPU上运行。
我们有这个变量对象，它是一个节点在
计算曲线图，其积聚的计算的曲线图，
让您计算梯度，诸如此类的事情。
我们有一个模块对象，它是一个神经网络
层，其可以将这些模块一起构成
构建大网络。
所以，如果你有种要想想粗糙当量
PyTorch和TensorFlow之间，你能想到的
PyTorch张量作为履行同一个角色
如在TensorFlow的numpy的阵列。
所述PyTorch变量是类似于TensorFlow张量
或可变的或占位符，其是所有种类的节点的
在计算曲线图。
而现在的PyTorch模块是一种等价
从tf.slim或tf.layers这些更高层次的东西
或十四行诗或这些更高层次的框架。
因此现在有一两件事要注意有关PyTorch
是因为它附带这个高度抽象
和喜欢一个人很好，更高层次的抽象
叫上自己的模块，有几分选择少
参与其中。
只要坚持nnmodules，你会好到哪里去。
您不必担心其更高层次的包装
使用。
所以PyTorch张量，正如我所说，就像numpy的阵列
所以这里在右边，我们已经做了一个完整的两层网络
使用完全PyTorch张量。
有一点要注意的是，我们不是在这里导入numpy的
在所有了。
我们只是在做使用PyTorch张量所有这些操作。
而这种代码看起来酷似二层网码
您在与NumPy写第一个功课。
所以，你设置一些随机数据，您可以使用一些操作
计算直传。
然后，我们明确地观看后向通行
我们自己。
通过网络只是有点backhopping，
通过操作，就像你做了功课之一。
现在我们正在做的权重的手动更新
用学习速率，并使用我们的计算梯度。
但PyTorch张量之间的主要区别
和numpy的阵列是他们在GPU上运行
因此，所有你需要做的，使这个代码运行在
GPU是使用不同的数据类型。
而不是使用torch.FloatTensor，
你做torch.cuda.FloatTensor，投下你所有的张量
这个新的数据类型，一切都奇迹般地运行
在GPU上。
你应该想到PyTorch张量刚刚NumPy的加GPU。
那它到底是什么，没有什么具体的
深学习。
所以，抽象的PyTorch的下一层是可变的。
因此，这是，一旦我们从张量转移到变量
现在我们正在构建的计算图表
而我们能够自动采取梯度
一切都这样。
所以在这里，如果X是一个变量，然后x.data是张量
和x.grad是包含梯度另一个变量
相对于该张量的损失。
所以x.grad.data是包含实际的张量
这些梯度。
而PyTorch张量和变量具有完全相同的API。
所以，关于PyTorch张量工作的任何代码，你可以只
让他们来代替变量，并运行相同的代码，
除了现在你建立了一个计算图
而不是仅仅做这些必要的操作。
所以在这里，当我们创建这些变量
每次调用变量构造包装了PyTorch
张量，然后还给出了标志是否
我们要计算梯度相对于这个变量。
而现在的直传，它看起来酷似
在变量以前那样与张量的情况下
因为它们具有相同的API。
所以，现在我们计算我们的预测，
我们计算实物此势在必行我们的损失
样的方式。
然后，我们称之为loss.backwards现在所有这些梯度
出来给我们。
然后我们可以做一个梯度更新步骤
在使用现在存在的梯度我们的砝码
在w1.grad.data。
因此，这最终看起来挺像NumPy的情况下，
除了所有的梯度免费的。
有一点要注意，就是之间的那种不同
PyTorch和TensorFlow是，在TensorFlow情况
我们建立这个明确的图表，
然后运行该图形中的多少倍。
在这里，在PyTorch，而不是我们打造了一个新的图
每次我们做向前传球。
这使得代码看起来有点清洁。
它有一些其他影响，我们会
得到的一点。
因此，在PyTorch您可以定义自己的新autograd功能
通过定义在张量进行向前和向后。
这最终看起来有点像模块层
你写功课两个代码。
在这里你可以实现前进和后退使用
张量操作，然后内坚持这些东西
计算图表。
所以在这里我们定义我们自己的RELU
然后我们就可以真正去并使用我们自己的RELU
操作现在把它贴我们的计算图表内
和定义自己的业务这种方式。
但大多数情况下，你可能不需要
定义你自己的autograd操作。
很多时候，你需要将操作
大多为您已经实现了。
因此，在TensorFlow我们看到，
如果我们可以将喜欢的东西Keras或TF.Learn
这给我们带来了更高级别的API一起工作，
而不是这种原始计算图表。
在PyTorch相当于是NN包。
它提供了这些工作的高层次包装
这些事情。
但是，与TensorFlow有只是其中之一。
和它的作品相当不错，因此就使用，如果你是
使用PyTorch。
所以在这里，这结束了那种看起来像Keras
这里我们定义模型层的一些序列。
我们的线性和RELU操作。
而我们使用的NN包中定义的损失函数
这是我们的均方误差损失。
现在我们每次循环内
我们可以通过模型正向运转数据得到
我们的预测。
我们可以通过损失函数向前运行预测
让我们的规模或损失，
那么我们可以调用loss.backward，让我们的所有梯度
用于在模型的参数自由，然后循环
并尽我们明确的梯度下降步骤，用于更新
该机型。
我们再次看到我们那种建立这样的
新的计算图表每次我们做向前传球。
就这样，我们在TensorFlow看到，
PyTorch提供了这些优化操作
那种抽象掉这个更新逻辑
并实现像亚当票友更新规则
和诸如此类的东西。
所以在这里我们要构造的优化对象
告诉它我们希望它优化过
模型的参数。
给它下的超参数的一些学习率。
现在经过我们计算了梯度
我们可以叫optimizer.step并更新
该模型为我们的所有参数就在这里。
所以，你在做PyTorch另一种常见的事
很多是定义自己的神经网络模块。
所以，通常你会写自己的类
这整个模型定义了你作为一个单一的
新的神经网络模块类。
而一个模块是正中下怀神经网络层的
其可以包含其他的其它模块
或可训练的权重或其他其他种状态。
所以在这种情况下，我们可以重做两层网例子
通过定义我们自己的神经网络模块类。
所以，现在在这里的类的初始化
我们要指定这linear1和linear2。
我们正在建设这些新模块对象
然后将它们存储在我们自己的类内。
而现在的直传我们可以用我们自己的
内部模块以及任意autograd操作
在变量来计算我们的网络输出。
所以在这里我们收到的，该方法前进里面这里，
输入作为一个变量，
那么我们变量传递给我们的self.linear1
用于第一层。
我们使用autograd运钳完成RELU，
我们的是，输出传递给第二线性
然后，让我们的目标参数。
而现在这个代码的其余部分用于训练这件事
看起来几乎相同。
我们在那里建立一个优化和循环遍历
并在不断的迭代饲料的数据模型，
与loss.backwards计算梯度，
打电话optimizer.step。
因此，这是喜欢比较特点
什么，你可能在很多PyTorch类型看
训练场景。
当你定义自己的类，
定义你自己的模型，包含了其他模块
和诸如此类的东西，然后你有一些明确的培训
环这样运行它，更新它。
一种生活的东西质量不错，你有
在PyTorch是的DataLoader。
因此，一个的DataLoader可以处理建设minibatches你。
它可以处理一些我们说话的多线程
关于你，它实际上可以使用多个线程
在后台为您构建多批
和流过磁盘。
所以，这里的DataLoader包装了一个数据集，并提供
一些抽象为你的。
而在实践中，当你想运行自己的数据，
你通常会写自己的DataSet类
它知道如何读你的特定类型的数据
关闭任何你想要的来源，然后把它包在
一个数据装入程序和列车与。
所以，在这里我们可以看到，现在我们遍历
该物体的DataLoader并在每次迭代
这是产生数据的minibatches。
而它的内部处理数据的洗牌
和多线程dataloading以及所有这类东西
为你。
因此，这是一种完全PyTorch例子
和很多PyTorch训练代码最终寻找
这样的事情。
PyTorch提供预训练模式。
这可能是最灵巧的预训练模式
我见过的经验。
你刚才说torchvision.models.alexnet pretained =真。
这会在后台下去，下载预训练
为你的权重，如果你还没有他们，
然后它就在那里，你是好去。
因此，这是超级好用。
PyTorch也有，还有一个叫Visdom包
让您直观一些损失统计
有点类似Tensorboard。
所以这是一种很好的，我还没有真正得到
有机会玩这个自己，所以我真的不能
它是多么有用说话，
但Tensorboard之间的一个主要区别
和Visdom是Tensorboard实际上可以让你想象
计算图的结构。
这是真的很酷，一个真正有用的调试策略。
而Visdom不具有的功能呢。
但我从来没有真正使用这个自己，所以我真的不能
其效用说话。
作为一个位的一边，PyTorch是怎样的演变，
那种旧的框架的较新版本更新
一项叫做TORCH这是我在过去有很多工作
许多年。
我不想经历细节，在这里，
但PyTorch是在很多方面非常好
比老Lua的火炬，但他们实际上分享了很多
的用于与张量计算相同的后端的C代码
和张量和诸如此类的东西GPU操作。
所以，如果你通过这个火炬的例子来看，
一些它结束了寻找一种类似于PyTorch，
它的一些有点不同。
也许你可以逐步此下线。
但那种之间的高度差
火炬和PyTorch是火炬实际上是在Lua，
而不是Python，不像这些其他的事情。
所以学习Lua是有点关闭对某些人来说的。
火炬没有autograd。
火炬也是旧的，所以它是更稳定，
不易受虫子，还有可能更多示例代码
火炬。
他们是差不多的速度，这是不是一个真正的问题。
但在PyTorch它在Python这是伟大的，
你有autograd这使得它简单多了
写复杂的模型。
在Lua的火炬你最终写了很多自己的
背部道具代码有时，所以这是一个有点讨厌。
但是PyTorch是新的，有较少的现有代码，
它仍然可能发生变化。
因此，它是更冒险一点。
但至少对我来说，我有点喜欢，
我真的没有看到我自己太多理由
在这个时候使用过火炬了PyTorch。
所以，我几乎使用PyTorch专供
我所有的工作，这些天。
我们谈到这一点关于这个想法
的静态与动态图形。
这是主要的特色之一
PyTorch和TensorFlow之间。
因此，我们在看到TensorFlow你有这两个阶段
操作的第一个地方你建立这
计算图表，然后运行计算图表
一遍又一遍很多很多次重复使用相同的
图形。
这就是所谓的静态计算曲线“的原因有
只是其中之一。
我们看到PyTorch是完全不同的，我们实际上是
建立这种新的计算图表，
每直传这个新的新鲜事儿。
这就是所谓的动态计算图表。
对于一种简单的情况下，与饲料种类的前
神经网络，它并没有真正产生巨大的变化，
代码结束那种类似
和他们的工作种类类似，
但我想谈一些影响的位
静态与动态。
什么是这两个的权衡。
因此，一种静态图形不错的主意的
是因为我们是一起建立一个
计算图形一次，然后再使用了很多次，
该框架可能有机会去
做对图形优化。
而那种融合一些操作，记录一些操作，
弄清楚操作的最有效方式
该图，从而它可以真正有效。
而且由于我们要重用图
很多时候，也许优化过程
是昂贵的前面，
但我们可以分摊与加速比是成本
当我们运行图很多很多次，我们已经得到了。
因此，作为一种具体的实例，
也许，如果你写一些图具有卷积
和RELU操作样接二连三的，
你可以想象，一些花哨的图形优化
能去和实际输出，就像发出自定义代码
它融合了业务，融合卷积
和RELU所以现在它的计算同样的事情
作为代码你写的，但现在可能能成为
更有效地执行。
所以我不正是在实践中，状态不太清楚
TensorFlow的图形优化是现在，
但至少在原则上，这是一个地方
静态图形真的，你可以有潜力
在做静态图表这种优化
在那里，也许这将是一个动态图形不那么听话。
另一种微妙的点约静态与动态
这种想法系列化。
因此，与静态的图表，你可以想像，你写
这个代码，构建了曲线图
然后，一旦你已经建立的图形，
你必须在内存中表示该数据结构
网络的整个结构。
现在，你可以采取数据结构
而只是把它序列化到磁盘。
现在你已经得到了你的网络的整体结构
保存在一些文件。
然后你可以在以后后部载荷的事
然后运行没有访问该计算图
到建造它的原代码。
因此，这将是在部署场景挺有意思。
你可能认为你可能要训练你
网络中的Python，因为它可能更易于使用，
但你序列化网络之后，
然后你可以在可能是C现在部署++
环境中，你不需要使用原来的
所建立的图形代码。
所以这是一种静态图的一个很好的优势。
而用动态图，因为我们交错
图表建筑和图形执行的这些方法中，
你那种需要在任何时候的原代码
如果你想在将来重复这一模式。
在另一方面，一些优势的动态图形
是它那种让，它只是使你的代码
有很多清洁和很多很多的情况下更容易。
因此，例如，假设我们希望做一些
其中取决于值的条件的操作
一些变量Z的，我们想要做不同的操作
计算Y.
如果Z为正数，其中，我们要使用一个权重矩阵，
如果Z为负，我们要使用不同的权重矩阵。
我们只是希望这两个方案之间关闭。
在PyTorch因为我们使用动态图形，
这是超级简单。
您的代码那种看上去完全像你所期望的，
正是你会做NumPy的。
你可以使用普通的Python控制流
来处理这件事情。
而现在，因为我们每次建立图表，
我们每次执行此操作时将采取一个
的两条路径，并建立也许不同的图表
每个直传，但我们做的任何图
最终建立，我们可以回通过它传播
正好。
和代码是非常干净的，易于使用。
现在TensorFlow的情况是多一点点
复杂的，因为我们一旦建立图表，
这个控制流程操作样的需要是
在TensorFlow图明确的操作。
而现在，这样他们就可以看到，我们有这个
tf.cond呼叫这是一种像TensorFlow版本
if语句的，但现在它烤成
计算图，而不是使用排序
Python的控制流程。
而问题是，因为我们只建立图
一次，全部控制流程的潜在路径那
我们的节目可能流经需要烘烤
到当时上图我们之前我们曾经构建它
运行。
因此，这意味着，任何一种控制流运营商
你想有必要不Python的控制流程
运营商，你需要使用某种魔力，
特殊张量流操作做控制流。
在这种情况下，该tf.cond。
另外一种类似的情况发生，如果你想
有循环。
因此，假设我们要计算某种经常性的
其中的关系也许ŸT等于YT减一
加上XT时代的一些权重矩阵W，并根据
每次我们这样做的时候，我们每次计算这个，
我们可能有数据的不同大小的序列。
而我们的数据序列无论长度，
我们只是要计算此相同的递推关系
无论输入序列的大小。
所以在这PyTorch是超级容易。
我们只是可以种使用正常的Python中环
超过的次数只是循环，我们要
展开和现在根据输入数据的大小，
我们的计算图表将最终成为大小不同，
但是这很好，我们就可以回去通过传播
每一个，一次一个。
现在，在TensorFlow这就变成了一个有点丑陋。
再次，因为我们需要构造图
一下子达阵，这个控制流的循环结构
再次必须在TensorFlow图的必经节点。
所以我希望你还记得你的函数式编程
因为你将不得不使用这些类型的运营商
以实现TensorFlow循环结构。
因此，在这种情况下，这个特殊的复发关系
您可以使用与foldl操作和传递，
排序的实现在与foldl而言，这特别的循环。
但是，这基本上意味着是你有这个意义上说
该TensorFlow几乎建立自己的整个
编程语言，使用的语言
计算图表。
和任何一种控制流操作的，
或需要被轧制任何类型的数据结构的
到计算图形，所以你不能真正利用
所有您喜爱的范式工作势在必行
在Python。
你有种需要重新学习整个单独设置
的控制流程的运营商。
如果你想要做的任何种类的控制流
你的计算图表中使用TensorFlow。
所以，至少对我来说，我觉得那样的混乱，
辛苦一点点，有时周围包裹我的头，
和我有点像，使用PyTorch动态图形，
你可以使用自己喜欢的命令式编程
结构和它的所有工作得很好。
顺便说一句，实际上是一些非常新的图书馆
所谓TensorFlow折叠是这些一个又一个
在TensorFlow的顶部，让您实现层
动态图形，你有种编写自己的代码
使用TensorFlow折，看起来有点像一个动态
图形操作，然后TensorFlow折做一些魔术
你并以某种方式实现了在条款
静态TensorFlow图。
这就是会呈现一个新的超级纸
在ICLR本周在法国。
所以我还没有喜欢在潜水和玩的机会
这个呢。
但我的初步印象是，它确实增加了一些
动态图形的量TensorFlow但它仍然是
多一点尴尬与工作比那种原生
动态图形你有PyTorch。
那么，我想这可能是不错的激励
就像我们为什么要关心一般的动态图形？
因此，一种选择是经常性的网络。
所以，你可以看到，对于类似图像字幕
我们用它工作在网络复发
不同长度的序列。
在这种情况下，我们需要的句子生成
作为标题是一个序列，并且该序列可以变化
根据我们的输入数据。
所以，现在你可以看到，我们在事情有这种活力
其中，根据句子的大小，
我们的计算图表可能需要有更多的
或更少的元件。
所以这是一种动态图形的共同应用。
对于那些你们谁了最后一个季度CS224N，
您看到这个想法递归网络
其中，有时在自然语言处理
您可能，例如，计算解析树
一个句子，然后你想有一个神经
网络种了这个解析树递归操作。
因此，有一种是工作的神经网络，
这不是层的只是连续序列，
而是它是一种工作在一些图
结构或树结构，而不是现在其中每个数据点
可能有不同的图形或树结构
这样的计算图的结构
然后种反映了输入数据的结构。
它可以改变从数据点的数据点。
因此，这种类型的事情似乎有点复杂，
毛茸茸的使用TensorFlow来实现，
但在PyTorch你可以只是一种使用
像正常的Python的控制流程，它会制定出
正好。
更researchy应用的另一位这是真的
我喜欢叫neuromodule网络很酷的想法
视觉答疑。
因此，这里的想法是，我们要问一些问题
有关图片，我们也许输入这个图像
猫，狗，有一些问题，
是什么颜色的猫，然后在内部系统
可以读取的问题，并且具有这些不同
进行专门的神经网络模块
像要求的颜色和发现猫操作。
然后根据不同问题的文本，
它可以编译这个定制的架构回答
的问题。
现在，如果我们问一个不同的问题，
就像是有比狗多猫？
现在，我们有可能相同的基本模块组
对于做这样的事情找猫，狗和计数，
但他们排列顺序不同。
因此，我们再次得到这种活力，其中不同的数据点
可能会引起不同的计算图表。
但是，这是多一点的researchy事
也许不那么主流的现在。
但作为一种更重要的一点，我认为有
很多很酷的，创造性的应用，人们
可以用动态的计算图表做
也许现在有没有这么多，
只是因为它是如此的痛苦与他们合作。
所以，我认为有很多机会
这样做很酷的，创造性的事情
动态的计算图表。
也许，如果你想出好点子，
我们将在讲座明年拥有它。
所以，我想很简单谈谈来自Caffe
这是从Berkeley这个框架。
其中来自Caffe是与其他有所不同
深度学习框架，你在许多情况下，
实际上你可以训练网络，而写作
任何代码自己。
那种你只需要调用到这些预先存在，二进制文件，
建立一些配置文件，在许多情况下，
你可以在训练数据，而无需编写任何自己的代码。
所以，你可能是第一次，您将您的数据
到像HDF5或LMDB并且存在一些格式
里面来自Caffe一些脚本，可以直接转换像
图像和文本文件的文件夹到这些格式为您服务。
您需要定义，现在不是写代码
定义你的计算图的结构，
相反，你编辑称为prototxt一些文本文件
其中设置的计算图的结构。
这时，该结构是我们从一些输入读取
HDF5文件中，我们进行了一些内部的产品，
我们计算了一些损失，整个结构
该图是在这个文本文件中设置。
一种缺点在这里的是，这些文件
可以得到非常大的网络真难看。
因此，对于类似的152层RESNET模型，
它的方式是在来自Caffe训练的最初，
那么这个prototxt文件结束了近7000行代码。
所以，人不被手写这些。
人们有时会会喜欢写的Python脚本
产生这些prototxt文件。
[笑声]
然后你在滚动自己的境界是一种
计算图形抽象。
这可能不是一个好主意，但我已经看到过。
然后，不是具有一些优化对象，
反而有一些解算器，可以定义一些东西求解
内另一个prototxt。
这定义你的学习速度，
您的优化算法和诸如此类的东西。
然后，一旦你做所有这些事情，
你可以运行来自Caffe二进制与火车命令
而这一切神奇发生了。
Cafee有一堆预训练模式的典范动物园，
这是非常有用的。
来自Caffe有一个Python接口，但它不是超级
有据可查的。
你那种需要阅读蟒蛇的源代码
界面查看它能做什么，
所以这是一种烦人。
但它确实工作。
所以，那种我对来自Caffe一般的事情是，它是
也许好于前馈机型，
它是生产场景也许不错，
因为它不依赖于Python的。
但可能是研究这些天，我已经看到了来自Caffe
而也许有点少使用。
虽然我认为这仍然是相当普遍使用
在行业再次进行生产。
我答应一个幻灯片，来自Caffe 2的一个或两个幻灯片。
所以来自Caffe 2的继任者来自Caffe这是来自Facebook。
这是超级新的，它只是释放一个星期前。
[笑声]
所以，我真的没有时间来形成超
教育关于来自Caffe 2的意见呢，
但它使用静态图表一种类似于TensorFlow。
一种像来自Caffe一个芯用C ++编写
和他们有一些Python接口。
所不同的是，现在你不再需要
写自己的Python脚本生成prototxt文件。
你可以种定义计算的图形结构
所有在Python，与看起来的API样的期待
有点像TensorFlow。
但你可以吐出来，你可以序列化此
计算图形结构来一个prototxt文件。
然后，一旦你的模型进行训练和诸如此类的东西，
那么我们得到这个好处就是我们谈到的静态约
图表，你可以，你不需要原
为了现在的训练代码部署训练的模型。
所以，一个有趣的事情是，你见过谷歌
也许有一个主要的深运行框架，
这是TensorFlow，其中Facebook有这两种，
PyTorch，但Caffe 2。
因此，这些都是一种不同的理念。
谷歌的那种试图建立一个框架来治
所有这些，也许适用于每一个可能的场景
深学习。
这是一种很好的，因为它整合了所有的努力
在一个框架。
这意味着你只需要学习的一件事
它会在许多不同的工作场景
包括像分布式系统，生产，
部署，移动，科研，应有尽有。
只需学习一个框架，做所有这些事情。
而Facebook正采取有点不同的办法。
其中PyTorch真的是越来越专业化，
在写作方面让更多的面向对研究
研究代码并快速迭代上你的想法，
这是在PyTorch超级容易，但对于像
在生产中运行时，在移动设备上运行时，
PyTorch没有很多的大力支持。
相反，来自Caffe 2是种对那些面向多
面向生产的用例。
所以我的一种通用的学习，我一般情况下，整体的意见
关于喜欢用哪些问题该框架
是一种既，
我认为TensorFlow是只是一个非常安全的赌注
要开始新的任何项目，对不对？
因为它是一个排序的框架来规范一切，
它可用于几乎任何情况。
不过，你可能需要用一个配对
更高层次的包装，如果你想动态图形，
你也许走运了。
一些代码的最终看起来有点丑陋
在我看来，不过也许这是一种化妆品的细节
它并不真正的问题那么多。
我个人认为PyTorch是研究真的很棒。
如果你只关注撰写研究代码，
我认为PyTorch是一个不错的选择。
但它是一个有点新的，具有较小的社区支持，
更少的代码在那里，所以它可能是一个有点冒险的。
如果您想了解更多良好走过的道路的，TensorFlow
可能是一个更好的选择。
如果你有兴趣在生产部署，
你或许应该看看来自Caffe，来自Caffe 2或TensorFlow。
如果你真的专注于移动部署，
我认为TensorFlow，但Caffe 2都有一些内置的
这种支持。
因此，它是一种不幸的是，有没有一样
一个全球最好的框架，它那种依赖
在你实际上要做的，
您预期的应用，但论文是种
我对那些东西一般建议。
因此，下一次，我们将讨论一些案例研究
有关各种CNN架构。