谷歌为么要养苹果的亲儿子Swift?原来意在可微分编程
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">选自tryolabs</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">作者:JoaquínThu</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;"><span style="color: black;">设备</span>之心编译</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">参与:Panda、Racoon</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Python 并不完美,而 Swift 则正在谷歌和苹果的<span style="color: black;">一起</span>养育下茁壮成长,有望成长为深度学习<span style="color: black;">行业</span>一门新的<span style="color: black;">重点</span>语言。<span style="color: black;">近期</span>,Tryolabs 的<span style="color: black;">科研</span>工程师 Joaquín Alori 发布了一篇长文,从 Python 的缺点一路谈到了谷歌在 Swift <span style="color: black;">设备</span>学习方面的大计划,并且文中还给出了相当多<span style="color: black;">有些</span><span style="color: black;">详细</span>的代码实例。可微分编程真如 Yann LeCun 所言的那样会<span style="color: black;">作为</span>新一代的程序<span style="color: black;">研发</span>范式吗?Swift 又将在其中扮演<span style="color: black;">怎么样</span>的角色?<span style="color: black;">亦</span>许你能在这篇<span style="color: black;">文案</span>中找到答案。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/38c25e020da247018cbca2be6abff899~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1722689616&x-signature=7BAh7NFYh3S6EPK9ps7tvpS8m1c%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">近期</span>,国外一小哥在 tryolabs 上写了一篇博文,为<span style="color: black;">咱们</span>详尽地介绍了 Python 的缺陷与相比之下 Swift 的<span style="color: black;">优良</span>,解释了<span style="color: black;">为何</span> Swift 版的 TensorFlow <span style="color: black;">将来</span>在<span style="color: black;">设备</span>学习<span style="color: black;">行业</span>有非常好的发展前景。其中<span style="color: black;">包括</span><span style="color: black;">海量</span>代码示例,展示了<span style="color: black;">怎样</span>用 Swift 优雅地编写<span style="color: black;">设备</span>学习程序。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">两年之前,谷歌的一个小团队<span style="color: black;">起始</span><span style="color: black;">科研</span>让 Swift 语言<span style="color: black;">作为</span>首个在语言层面上一流地整合了可微分编程能力的主流语言。该项目的<span style="color: black;">科研</span>范围着实与众<span style="color: black;">区别</span>,<span style="color: black;">况且</span><span style="color: black;">亦</span>取得了<span style="color: black;">有些</span>出色的初期<span style="color: black;">科研</span>成果,似乎离公众应用<span style="color: black;">亦</span>并不很远了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">尽管如此,该项目却并未在<span style="color: black;">设备</span>学习社区<span style="color: black;">导致</span>多大反响,<span style="color: black;">况且</span><span style="color: black;">非常多</span>实践者还对此浑然不觉。<span style="color: black;">导致</span>这种结果的<span style="color: black;">重点</span><span style="color: black;">原由</span>之一是语言的<span style="color: black;">选取</span>。<span style="color: black;">设备</span>学习社区的<span style="color: black;">非常多</span>人很大程度上并不关心 Swift,谷歌<span style="color: black;">科研</span>它<span style="color: black;">亦</span>让人们感到疑惑;<span style="color: black;">由于</span> Swift <span style="color: black;">重点</span>用来<span style="color: black;">研发</span> iOS 应用<span style="color: black;">罢了</span>,在数据科学生态系统中几乎毫无存在感。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">不外</span>,事实却并非如此,只需粗略地<span style="color: black;">瞧瞧</span>谷歌这个项目,就能<span style="color: black;">发掘</span>这是一个庞大且雄心勃勃的计划,<span style="color: black;">乃至</span>足以将 Swift 确立为<span style="color: black;">设备</span>学习<span style="color: black;">行业</span>的关键成员。<span style="color: black;">另外</span>,即使<span style="color: black;">咱们</span> Tryolabs <span style="color: black;">亦</span><span style="color: black;">重点</span><span style="color: black;">运用</span> Python,但<span style="color: black;">咱们</span>还是认为 Swift 是一个绝佳的<span style="color: black;">选取</span>;<span style="color: black;">亦</span><span style="color: black;">因此呢</span>,<span style="color: black;">咱们</span>决定写这篇<span style="color: black;">文案</span>以<span style="color: black;">帮忙</span>世人<span style="color: black;">认识</span>谷歌的计划。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">但在深入 Swift 以及「可微分编程」的真正含义之前,<span style="color: black;">咱们</span>应该先回顾一下当前的<span style="color: black;">情况</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">Python,你怎么了?!</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">到<span style="color: black;">日前</span>为止,Python 都依然是<span style="color: black;">设备</span>学习<span style="color: black;">行业</span>最常被使用的语言,谷歌<span style="color: black;">亦</span>有<span style="color: black;">海量</span>用 Python 编写的<span style="color: black;">设备</span>学习软件库和工具。<span style="color: black;">那样</span>,<span style="color: black;">为何</span>还要用 Swift?Python 有什么问题吗?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">直接说吧,Python 太慢了。<span style="color: black;">另一</span>,Python 的并行性表现并<span style="color: black;">欠好</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">为了应对这些缺点,大<span style="color: black;">都数</span><span style="color: black;">设备</span>学习项目在运行计算密集型算法时,都会<span style="color: black;">运用</span>用 C/C++/Fortran/CUDA 写的软件库,<span style="color: black;">而后</span>再<span style="color: black;">运用</span> Python 将<span style="color: black;">区别</span>的底层运算组合到<span style="color: black;">一块</span>。<span style="color: black;">针对</span>大部分项目而言,这种做法其实效果很好;但总体概况而言,这会产生<span style="color: black;">有些</span>问题。<span style="color: black;">咱们</span>先<span style="color: black;">瞧瞧</span>其中<span style="color: black;">有些</span>问题。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;"><span style="color: black;">外边</span>二进制文件</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">为<span style="color: black;">每一个</span>计算密集型运算都调用<span style="color: black;">外边</span>二进制文件会限制<span style="color: black;">研发</span>者的工作,让<span style="color: black;">她们</span>只能在算法的表层的一小部分上进行<span style="color: black;">研发</span>。<span style="color: black;">例如</span>,<strong style="color: blue;">编写自定义的卷积执行方式是<span style="color: black;">没法</span>实现的,除非<span style="color: black;">研发</span>者愿意<span style="color: black;">运用</span> C 等语言来进行<span style="color: black;">研发</span></strong>。大部分程序员都不会<span style="color: black;">选取</span>这么做,要么是<span style="color: black;">由于</span><span style="color: black;">她们</span><span style="color: black;">无</span>编写低层高性能代码的经验,要么则是<span style="color: black;">由于</span>在 Python <span style="color: black;">研发</span>环境与某个低层语言环境之间来回切换会变得过于麻烦。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这会<span style="color: black;">导致</span>一种不幸的<span style="color: black;">状况</span>:程序员会尽力<span style="color: black;">尽可能</span>少地写<span style="color: black;">繁杂</span>代码,并且默认<span style="color: black;">状况</span>更倾向于调用<span style="color: black;">外边</span>软件库的运算。<span style="color: black;">针对</span><span style="color: black;">设备</span>学习<span style="color: black;">这般</span>动态发展的<span style="color: black;">行业</span><span style="color: black;">来讲</span>,这并不是一个好现象,<span style="color: black;">由于</span><span style="color: black;">非常多</span>东西都还并未确定下来,还非常需要新想法。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">对软件库的抽象理解</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">让 Python 代码调用更低层代码并不如将 Python 函数映射成 C 函数<span style="color: black;">那样</span>简单。不幸的现实是:<span style="color: black;">设备</span>学习软件库的创建者必须为了性能而做出<span style="color: black;">有些</span><span style="color: black;">研发</span>上的<span style="color: black;">选取</span>,而这又会让事情变得更加<span style="color: black;">繁杂</span>。举个例子,在 TensorFlow 图(graph)模式中(这是该软件库中<span style="color: black;">独一</span>的性能模式),你的 Python 代码在你认为会运行时常常并不运行。在<span style="color: black;">这儿</span>,Python <span style="color: black;">实质</span>上的<span style="color: black;">功效</span>是底层 TensorFlow 图的某种元编程(metaprogramming)语言。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其<span style="color: black;">研发</span>流程为:<span style="color: black;">研发</span>者<span style="color: black;">首要</span><span style="color: black;">运用</span> Python 定义一个网络,<span style="color: black;">而后</span> TensorFlow 后端<span style="color: black;">运用</span>该定义来构建网络并将其编译为一个 blob,而<span style="color: black;">研发</span>者却再<span style="color: black;">亦</span><span style="color: black;">没法</span><span style="color: black;">拜访</span>其内部。编译之后,该网络才<span style="color: black;">最终</span><span style="color: black;">能够</span>运行,<span style="color: black;">研发</span>者<span style="color: black;">能够</span><span style="color: black;">起始</span>向其馈送数据以便训练和推理。这种工作方式让调试工作变得非常困难,<span style="color: black;">由于</span>在网络运行时,你没法<span style="color: black;">运用</span> Python <span style="color: black;">认识</span>其中<span style="color: black;">到底</span><span style="color: black;">出现</span>了什么。你<span style="color: black;">亦</span>没法<span style="color: black;">运用</span> pdb 等<span style="color: black;">办法</span>。<strong style="color: blue;">即使你想<span style="color: black;">运用</span>古老但好用的 print 调试<span style="color: black;">办法</span>,你<span style="color: black;">亦</span>只能<span style="color: black;">运用</span> tf.print 并在你的网络中构建一个 print 节点,这又必须连接到网络中的另一个节点,<span style="color: black;">况且</span>在 print 得到任何信息之前还必须进行编译。</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">不外</span><span style="color: black;">亦</span>存在更加直接的<span style="color: black;">处理</span><span style="color: black;">方法</span>。用 PyTorch 时,你的代码必须像用 Python <span style="color: black;">同样</span>命令式地运行,<span style="color: black;">独一</span>不透明的<span style="color: black;">状况</span>是运行在 GPU 上的运算是异步式地执行的。这<span style="color: black;">一般</span>不会有问题,<span style="color: black;">由于</span> PyTorch 对此很智能,它会等到用户交互操作所依赖的所有异<span style="color: black;">步骤</span>用都结束之后才会转让<span style="color: black;">掌控</span>权。尽管如此,<span style="color: black;">亦</span>还是有<span style="color: black;">有些</span>问题存在,尤其是在基准评测(benchmarking)等任务上。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">行业滞后</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">所有这些可用性问题不仅让写代码更困难,<span style="color: black;">况且</span>还会<span style="color: black;">引起</span>产业界毫无必要地滞后于学术界。<span style="color: black;">始终</span><span style="color: black;">败兴</span>都有论文在<span style="color: black;">科研</span><span style="color: black;">怎样</span><span style="color: black;">调节</span>神经网络中所用的低层运算,并在这一过程中将准确度<span style="color: black;">提高</span>几个百分点,<span style="color: black;">然则</span>产业界仍然需要很<span style="color: black;">长期</span><span style="color: black;">才可</span><span style="color: black;">实质</span>应用这些<span style="color: black;">发展</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">一个原因是即使这些算法上的改变可能本身比较简单,但上面<span style="color: black;">说到</span>的工具问题还是让它们非常难以实现。<span style="color: black;">因此呢</span>,<span style="color: black;">因为</span>这些改进可能只能将准确度<span style="color: black;">提高</span> 1%,<span style="color: black;">因此</span>企业可能会认为为此进行投入并不值得。<span style="color: black;">针对</span>小型<span style="color: black;">设备</span>学习<span style="color: black;">研发</span>团队而言,这个问题尤为<span style="color: black;">显著</span>,<span style="color: black;">由于</span><span style="color: black;">她们</span><span style="color: black;">常常</span>缺乏可<span style="color: black;">包袱</span>实现/整合成本的规模经济。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">因此呢</span>,企业<span style="color: black;">常常</span>会直接忽略这些进步,直到这些改进被加入到 PyTorch 或 TensorFlow 等软件库中。这能节省企业的实现和整合成本,但<span style="color: black;">亦</span>会<span style="color: black;">引起</span>产业界滞后学术界一两年时间,<span style="color: black;">由于</span>这些软件库的<span style="color: black;">守护</span>者基本不会立即实现每篇新论文提出的新<span style="color: black;">办法</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">举个<span style="color: black;">详细</span>的例子,可变形卷积似乎<span style="color: black;">能够</span><span style="color: black;">提高</span>大<span style="color: black;">都数</span>卷积神经网络(CNN)的性能表现,但论文发布大概 2 年之后才<span style="color: black;">显现</span><span style="color: black;">第1</span>个开源的实现。不仅如此,将可变形卷积的实现整合进 PyTorch 或 TensorFlow 的过程非常麻烦,<span style="color: black;">况且</span>最后这个算法<span style="color: black;">亦</span>并没得到广泛的<span style="color: black;">运用</span>。PyTorch 直到<span style="color: black;">近期</span>才加入对它的支持,至于官方的 TensorFlow 版本,<span style="color: black;">迄今</span>仍<span style="color: black;">无</span>见到。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">此刻</span>,假设说有 n 篇能将准确度提升 2% 的论文都遇到了这种<span style="color: black;">状况</span>,<span style="color: black;">那样</span>产业界将错失准确度<span style="color: black;">明显</span><span style="color: black;">提高</span> (1.02^n)% 的机会,而<span style="color: black;">原由</span><span style="color: black;">不外</span>是<span style="color: black;">无</span>合适的工具罢了。<span style="color: black;">倘若</span> n 很大,那就太让人遗憾了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">速度</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在某些<span style="color: black;">状况</span>中,<span style="color: black;">同期</span><span style="color: black;">运用</span> Python 与快速软件库依然还是会很慢。确实,<span style="color: black;">倘若</span>是用 CNN 来执行图像<span style="color: black;">归类</span>,<span style="color: black;">那样</span><span style="color: black;">运用</span> Python 与 PyTorch/TensorFlow 会<span style="color: black;">火速</span>。<span style="color: black;">另外</span>,就算在 CUDA 环境中编写<span style="color: black;">全部</span>网络,性能<span style="color: black;">亦</span>可能并不会得到太多<span style="color: black;">提高</span>,<span style="color: black;">由于</span>大卷积占据了大部分的推理时间,而大卷积又<span style="color: black;">已然</span>有了经过良好优化的代码实现。但<span style="color: black;">状况</span>并非总是如此。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>不是完全用低层语言实现的,<span style="color: black;">那样</span>由<span style="color: black;">非常多</span>小运算<span style="color: black;">构成</span>的网络<span style="color: black;">常常</span>最容易<span style="color: black;">显现</span>性能问题。举个例子,Fast.AI 的 Jeremy Howard 曾在一篇博客<span style="color: black;">文案</span>中表达了自己对用 Swift 来做深度学习<span style="color: black;">研发</span>的热爱,他<span style="color: black;">暗示</span>尽管<span style="color: black;">运用</span>了 PyTorch 那出色的 JIT 编译器,他仍然<span style="color: black;">没法</span>让 RNN 的工作速度比肩完全用 CUDA 实现的版本。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">另外</span>,<span style="color: black;">针对</span>延迟程度很重要的<span style="color: black;">状况</span>,Python <span style="color: black;">亦</span>不是一种非常好的语言;<span style="color: black;">况且</span> Python <span style="color: black;">亦</span><span style="color: black;">不可</span>很好地应用于与传感器通信等非常底层的任务。为<span style="color: black;">认识</span>决这个问题,<span style="color: black;">有些</span><span style="color: black;">机构</span>的做法是仅用 Python 和 PyTorch/TensorFlow <span style="color: black;">研发</span>模型。<span style="color: black;">这般</span>,在实验和训练新模型时,<span style="color: black;">她们</span>就能利用 Python 的易用性<span style="color: black;">优良</span>。而在之后的生产<span style="color: black;">安排</span>时,<span style="color: black;">她们</span>会用 C++ 重写<span style="color: black;">她们</span>的模型。不确定<span style="color: black;">她们</span>是会完全重写,还是会<span style="color: black;">运用</span> PyTorch 的 tracing 功能或 TensorFlow 的图模式来简单地将其串行化,<span style="color: black;">而后</span>再围绕它<span style="color: black;">运用</span> C++ 来重写 Python。不管是哪种方式,都需要重写<span style="color: black;">海量</span> Python 代码。<span style="color: black;">针对</span>小<span style="color: black;">机构</span>而言,<span style="color: black;">这般</span>做<span style="color: black;">常常</span>成本过高。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">所有这些问题都是众所周知的。公认的深度学习教父之一 Yann LeCun 就曾说<span style="color: black;">设备</span>学习需要一种新语言。他与 PyTorch 的创建者之一 Soumith Chintala 曾在一组推文中讨论了几种可能的候选语言,其中<span style="color: black;">说到</span>了 Julia、Swift 以及改进 Python。另一方面,Fast.AI 的 Jeremy Howard 似乎<span style="color: black;">已然</span>下定决心站队 Swift。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">谷歌接受了挑战</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">幸运的是,谷歌的 Swift for TensorFlow(S4TF)团队接过了这一<span style="color: black;">困难</span>。不仅如此,<span style="color: black;">她们</span>的<span style="color: black;">全部</span>项目<span style="color: black;">发展</span>还非常透明。<span style="color: black;">她们</span>还发布了一份非常详实的文档(</p>https://github.com/tensorflow/swift/blob/master/docs/WhySwiftForTensorFlow.md),其中<span style="color: black;">仔细</span>地介绍了<span style="color: black;">她们</span>做出这一决定的历程,并解释了<span style="color: black;">她们</span>为这一任务<span style="color: black;">思虑</span>过的其它语言并<span style="color: black;">最后</span>选中 Swift 的<span style="color: black;">原由</span>。
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在<span style="color: black;">她们</span><span style="color: black;">思虑</span>过的语言中,最值得关注的<span style="color: black;">包含</span>:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Go:在这份文档中,<span style="color: black;">她们</span><span style="color: black;">暗示</span> Go 过于依赖其接口<span style="color: black;">供给</span>的动态调度,<span style="color: black;">况且</span><span style="color: black;">倘若</span>要实现<span style="color: black;">她们</span>想要的特性,必须对这门语言进行大刀阔斧的修改。这与 Go 语言的保持简单和小表面积的哲学不符。相反,<strong style="color: blue;">Swift 的协议和扩展都有很高的自由度:你想要调度有多静态,就能有多静态</strong>。<span style="color: black;">另一</span>,Swift <span style="color: black;">亦</span>相当<span style="color: black;">繁杂</span>,<span style="color: black;">况且</span>还在越来越<span style="color: black;">繁杂</span>,<span style="color: black;">因此</span>再让它<span style="color: black;">繁杂</span>点以满足谷歌想要的特性并不是什么大问题。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">C++ 和 Rust:谷歌的<span style="color: black;">目的</span>用户群是<span style="color: black;">哪些</span>大部分工作都<span style="color: black;">运用</span> Python 的人,<span style="color: black;">她们</span>更感兴趣的是花时间思考模型和数据,而不是思考<span style="color: black;">怎样</span>精细地管理内存或所有权(ownership)。<strong style="color: blue;">Rust 和 C++ 的<span style="color: black;">繁杂</span>度都足够,但都很注重底层细节,而这在数据科学和<span style="color: black;">设备</span>学习<span style="color: black;">研发</span>中<span style="color: black;">一般</span>是不<span style="color: black;">恰当</span>的</strong>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Julia:<span style="color: black;">倘若</span>你在 HackerNews 或 Reddit 上读到过任何<span style="color: black;">相关</span> S4TF 的帖子,<span style="color: black;">那样</span>最常看到的评论是:「为啥不选 Julia?」在前面<span style="color: black;">说到</span>的那份文档中,谷歌<span style="color: black;">说到</span> Julia 看起来<span style="color: black;">亦</span><span style="color: black;">特别有</span><span style="color: black;">潜能</span>,但<span style="color: black;">她们</span>并未给出不选 Julia 的<span style="color: black;">可靠</span>理由。<span style="color: black;">她们</span><span style="color: black;">说到</span> Swift 的社区比 Julia 大得多,事实确实如此,然而 Julia 的<span style="color: black;">研究</span>社区和数据科学社区却比 Swift 大得多,而这些社区的人才更可能<span style="color: black;">更加多</span>地<span style="color: black;">运用</span> S4TF。要记住,谷歌团队的 Swift 专业人才<span style="color: black;">更加多</span>,毕竟发起 S4TF 项目的正是 Swift 的创建者 Chris Lattner,相信这在谷歌的决定中起到了重大的<span style="color: black;">功效</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">一种新语言:作者认为<span style="color: black;">她们</span>在宣言中说得很好:「创建一种语言的工作量多得吓人。」这需要太长的时间,而<span style="color: black;">设备</span>学习又发展得太快。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;"><span style="color: black;">那样</span>,Swift 的<span style="color: black;">优良</span>在哪里?</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">简单<span style="color: black;">来讲</span>,Swift 让你可几乎完全用 Python 的方式在非常高的层面上进行编程,<span style="color: black;">同期</span>又<span style="color: black;">能够</span><span style="color: black;">保准</span>非常快的速度。数据<span style="color: black;">专家</span>可像<span style="color: black;">运用</span> Python <span style="color: black;">同样</span>来<span style="color: black;">运用</span> Swift,<span style="color: black;">同期</span>可用 Swift 内置的已优化<span style="color: black;">设备</span>学习库来进行更加精细的<span style="color: black;">研发</span>,<span style="color: black;">例如</span>管理内存,<span style="color: black;">乃至</span>当常用的 Swift 代码约束太大时还能降至指针层面进行操作。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">本文的目的不是介绍 Swift 语言,<span style="color: black;">因此</span>不会连篇累牍地<span style="color: black;">仔细</span>介绍其特性。<span style="color: black;">倘若</span>你想<span style="color: black;">仔细</span><span style="color: black;">认识</span>这门语言,看官方文档就够了。<span style="color: black;">这儿</span>只会介绍 Swift 的几个亮点,并<span style="color: black;">期盼</span>这能吸引人们去尝试它。下面几节将按随机<span style="color: black;">次序</span>介绍 Swift 的<span style="color: black;">有些</span>亮点,<span style="color: black;">因此</span>排序与它们的重要程度无关。之后,本文将深入介绍可微分编程,并聊聊谷歌在 Swift 上的大计划。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">亮点一</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Swift 速度<span style="color: black;">火速</span>。这是作者在<span style="color: black;">起始</span><span style="color: black;">运用</span> Swift 时所做的<span style="color: black;">第1</span>项测试。作者写了<span style="color: black;">有些</span>短脚本来<span style="color: black;">评定</span> Swift 与 Python 和 C 的相对表现。说实话,这些测试并不<span style="color: black;">尤其</span><span style="color: black;">繁杂</span>。<span style="color: black;">亦</span><span style="color: black;">便是</span>用整型数填充一个数组,<span style="color: black;">而后</span>再将它们<span style="color: black;">所有</span>加起来。这个测试本身并<span style="color: black;">不可</span>透彻地<span style="color: black;">认识</span> Swift 在<span style="color: black;">各样</span><span style="color: black;">状况</span>下的速度表现,但作者想<span style="color: black;">认识</span>的是 Swift 能否达到 C <span style="color: black;">同样</span>的速度,而不是 Swift <span style="color: black;">是不是</span>总能和 C <span style="color: black;">同样</span>快。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">第1</span>组比较作者选的是 Swift vs Python。为了让对应的每一行所执行的任务一致,作者对某些<span style="color: black;">地区</span>的花括号的位置进行了<span style="color: black;">调节</span>。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/c3cf098bdc754684b6a72ee22e4e491a~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1722689616&x-signature=4dwaJcwJEEr%2BDru8LhBFbu%2B80e4%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">import time | import Foundation|result = [] | var result = ()for it in range(15): | for it in 0.. start = time.time() | let start = CFAbsoluteTimeGetCurrent() for _ in range(3000): | for _ in 0.. result.append(it) | result.append(it)} sum_ = sum(result) | let sum = result.reduce(0, +) end = time.time() | let end = CFAbsoluteTimeGetCurrent() print(end - start, sum_) | print(end - start, sum) result = [] | result = []}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">尽管在这个特定的代码段中,Python 与 Swift 代码看起来句法相近,但运行结果<span style="color: black;">显示</span>这个 Swift 脚本的运行速度比 Python 脚本的运行速度快 25 倍。在这个 Python 脚本中,最外层的循环每执行一次平均耗时 360 μs,相比之下 Swift 的是 14 μs。差别非常<span style="color: black;">显著</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">另一</span>,<span style="color: black;">亦</span>还有其它<span style="color: black;">有些</span>事情值得<span style="color: black;">重视</span>。<span style="color: black;">例如</span>,+ 既是一个运算符<span style="color: black;">亦</span>是一个函数,它会被传递给 reduce(后面我会<span style="color: black;">仔细</span>介绍);CFAbsoluteTimeGetCurrent 揭示了 Swift 在传承下来的 iOS 命名空间方面的怪异特性;.< 范围运算符让你<span style="color: black;">能够</span><span style="color: black;">选取</span>该范围<span style="color: black;">是不是</span><span style="color: black;">包括</span>区间端点以及哪个端点。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">然则</span>,这个测试并<span style="color: black;">不可</span>说明 Swift 有多快。要<span style="color: black;">晓得</span> Swift 有多快,<span style="color: black;">咱们</span>得将其与 C 来比比看。我<span style="color: black;">亦</span><span style="color: black;">这般</span>做了,但让人失望的是,初始结果并<span style="color: black;">欠好</span>。用 C 编写的版本平均耗时 1.5 μs,比<span style="color: black;">咱们</span>的 Swift 代码快 10 倍。Uh oh.</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">不外</span>老实讲,<span style="color: black;">这般</span>比较其实并不公平。这段 Swift 代码并没<span style="color: black;">运用</span>动态数组,<span style="color: black;">因此呢</span>当数组规模变大时,它会在内存堆中<span style="color: black;">持续</span>重新分配位置。这<span style="color: black;">亦</span><span style="color: black;">寓意</span>着它会在<span style="color: black;">每一个</span>附加(append)的数组上执行边界<span style="color: black;">检测</span>。为了佐证这一点,<span style="color: black;">咱们</span>来<span style="color: black;">瞧瞧</span><span style="color: black;">关联</span>定义。Swift 的标准类型<span style="color: black;">包含</span>整型、浮点数和数组,它们并<span style="color: black;">无</span>硬编码到编译器中,而是标准库中所定义的结构体(struct)。<span style="color: black;">因此呢</span>,<span style="color: black;">按照</span>数组的附加(append)定义,<span style="color: black;">咱们</span><span style="color: black;">能够</span><span style="color: black;">认识</span>到<span style="color: black;">非常多</span>信息。<span style="color: black;">晓得</span>了这一点后,我的测试方式<span style="color: black;">乃至</span><span style="color: black;">能够</span><span style="color: black;">包含</span>预分配数组的内存以及<span style="color: black;">运用</span>指针来填充数组。<span style="color: black;">这般</span>得到的脚本其实<span style="color: black;">亦</span>并不是很长:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">import Foundation// Preallocating memoryvar result = ContiguousArray(repeating: 0, count: 3001)for it in 0.. let start = CFAbsoluteTimeGetCurrent()</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">// Using a buffer pointer for assignment result.withUnsafeMutableBufferPointer({ buffer infor i in 0.. buffer = it } }) let sum = result.reduce(0, +) let end = CFAbsoluteTimeGetCurrent() print(end - start, sum)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这段新代码耗时 3 μs,速度<span style="color: black;">已然</span>达到 C 的一半,<span style="color: black;">能够</span>说是很不错的结果了。<span style="color: black;">不外</span>为了进行完整的比较,作者继续对代码进行了剖析,以便<span style="color: black;">认识</span>该代码的 Swift 版本和 C 版本的差异<span style="color: black;">到底</span><span style="color: black;">能够</span>做到多小。事实证明,作者之前<span style="color: black;">运用</span>的 reduce <span style="color: black;">办法</span>会毫无必要地间接<span style="color: black;">运用</span> nextPartialResult 函数执行<span style="color: black;">有些</span>计算,这<span style="color: black;">能够</span><span style="color: black;">供给</span>非必需的泛化能力。在<span style="color: black;">运用</span>指针重写了这段代码之后,作者<span style="color: black;">最后</span>让这段代码达到了与 C 同等的速度。<span style="color: black;">然则</span>,这显然不符合<span style="color: black;">咱们</span><span style="color: black;">运用</span> Swift 的目的,<span style="color: black;">由于</span>这种操作本质上<span style="color: black;">便是</span>写更冗长更丑陋的 C 语言。尽管如此,<span style="color: black;">晓得</span>在确实需要时<span style="color: black;">能够</span>达到 C 的速度<span style="color: black;">亦</span>是一件好事。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">总结:<span style="color: black;">运用</span> Swift,你没法在执行 Python 层面的工作时<span style="color: black;">得到</span> C 语言等级的速度,但你能在两者之间取得良好的平衡。</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">亮点二</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Swift 采用的函数签名<span style="color: black;">办法</span><span style="color: black;">亦</span><span style="color: black;">特别有</span>趣。它们的最基本形式其实相当简单:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">func greet(person: String, town: String) -> String { return "Hello \(person)! Glad you could visit from \(town)."}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">greet(person: "Bill", town: "Cupertino")</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其函数签名由参数名加它们的类型<span style="color: black;">形成</span>,没其它多余花哨的东西。<span style="color: black;">独一</span><span style="color: black;">区别</span>寻常的是 Swift 需要你在调用该函数时<span style="color: black;">供给</span>参数名,<span style="color: black;">因此呢</span>你在调用上面的 greet 时必须写下 person 和 town,如上面代码段中最后一行所示。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">当<span style="color: black;">咱们</span>向其中引入参数标签时,<span style="color: black;">状况</span>还会变得更加有趣。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">func greet(_ person: String, from town: String) -> String { return "Hello \(person)! Glad you could visit from \(town)."}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">greet("Bill", from: "Cupertino")</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">顾名思义,参数标签<span style="color: black;">便是</span>函数的参数的标签,<span style="color: black;">况且</span>它们是在函数签名中各自的参数之前声明的。在上面的示例中,from 是 town 的参数标签,_ 是 person 的参数标签。<span style="color: black;">针对</span>最后一个标签,作者<span style="color: black;">运用</span>的是,<span style="color: black;">由于</span> _ 在 Swift 中是一个特殊字母,其含义是:「在调用这个参数时不<span style="color: black;">供给</span>任何参数名。」</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">有了参数标签,<span style="color: black;">每一个</span>参数都有两个<span style="color: black;">区别</span>的名字:一个是参数标签,在调用该函数时<span style="color: black;">运用</span>;另一个是参数名,在函数的主体定义中<span style="color: black;">运用</span>。这看起来似乎有些任性,但会让你的代码更易读。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">瞧瞧</span>上面的函数签名,基本就像是在读英语。「Greet person from town.」上面的函数调用看起来<span style="color: black;">亦</span><span style="color: black;">一样</span>清楚直白:「Greet Bill from Cupertino.」<span style="color: black;">倘若</span><span style="color: black;">无</span>参数标签,就有些含混不清了:「Greet person town.」<span style="color: black;">咱们</span>不<span style="color: black;">晓得</span><span style="color: black;">这儿</span>的 town 是什么意思。这是<span style="color: black;">咱们</span><span style="color: black;">此刻</span>所处的城镇吗?还是<span style="color: black;">咱们</span>为了面见这个人而将要前去的城镇?又或是这个人<span style="color: black;">本来</span>来处的城镇?<span style="color: black;">倘若</span><span style="color: black;">无</span>参数标签,<span style="color: black;">咱们</span>就必须阅读函数主体<span style="color: black;">才可</span>知晓<span style="color: black;">实质</span><span style="color: black;">状况</span>,<span style="color: black;">或</span>采用让函数名或参数名更长更直白的<span style="color: black;">办法</span>。<span style="color: black;">倘若</span>你有<span style="color: black;">海量</span>参数,<span style="color: black;">那样</span><span style="color: black;">状况</span>将变得非常<span style="color: black;">繁杂</span>;在作者看来这会<span style="color: black;">引起</span>代码变得更丑<span style="color: black;">况且</span>会让函数名变得毫无必要地长。参数标签更加好看,<span style="color: black;">况且</span><span style="color: black;">亦</span><span style="color: black;">更易</span>扩展,<span style="color: black;">况且</span>幸运的是它们<span style="color: black;">亦</span>在 Swift 中得到了广泛的应用。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">亮点三</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Swift 广泛地<span style="color: black;">运用</span>了闭包(closure)。<span style="color: black;">因此呢</span>,有<span style="color: black;">有些</span>捷径可让该语言的<span style="color: black;">运用</span>更接近人的直觉。这个来自 Swift 的文档的示例展现了这些捷径简洁明了又<span style="color: black;">拥有</span>很强的表现力的特性。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">咱们</span>的<span style="color: black;">目的</span>是将下面的数组向后排序:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>用不<span style="color: black;">那样</span>地道的 Swift 代码形式,可为数组<span style="color: black;">运用</span> sorted <span style="color: black;">办法</span>,并采用一个自定义函数来定义按逐对<span style="color: black;">次序</span>比较数组元素的方式,就像<span style="color: black;">这般</span>:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">func backward(_ s1: String, _ s2: String) -> Bool { return s1 > s2}var reversedNames = names.sorted(by: backward)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">backward 函数一次可比较两项,<span style="color: black;">倘若</span>这两项的<span style="color: black;">次序</span>与所需<span style="color: black;">次序</span><span style="color: black;">同样</span>,则返回 true;否则便返回 false。sorted 数组<span style="color: black;">办法</span>需要<span style="color: black;">这般</span>一个函数<span style="color: black;">做为</span>一个输入<span style="color: black;">才可</span><span style="color: black;">晓得</span><span style="color: black;">怎样</span>对数组进行排序。顺便一提,<span style="color: black;">咱们</span>还<span style="color: black;">能够</span>看到<span style="color: black;">这儿</span><span style="color: black;">运用</span>了参数标签 by——这是如此的简洁明了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span><span style="color: black;">咱们</span>采用更地道的 Swift,<span style="color: black;">能够</span><span style="color: black;">发掘</span><span style="color: black;">运用</span>闭包能更好地完成这项任务。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{} 之间的代码是一个正被定义的闭包,<span style="color: black;">同期</span><span style="color: black;">亦</span>被传递用作 sorted 的一个参数。你<span style="color: black;">亦</span>许从未听说过闭包,但其实很简单,闭包<span style="color: black;">便是</span>一个获取上下文的未命名的函数你<span style="color: black;">能够</span>将其看作是<span style="color: black;">加强</span>版的 Python lambda。该闭包中的关键词 in 的<span style="color: black;">功效</span>是<span style="color: black;">掰开</span>该闭包的参数及其主体。: 等更直观的关键词已被签名类型定义所占用(在这个案例中,该闭包的参数类型是从 sorted 的签名中自动推导出来的,<span style="color: black;">因此呢</span><span style="color: black;">能够</span>避免<span style="color: black;">运用</span> :),<span style="color: black;">况且</span><span style="color: black;">咱们</span>都<span style="color: black;">晓得</span>命名是编程中最艰难的事情之一,<span style="color: black;">因此</span>为此只能继续<span style="color: black;">运用</span>不<span style="color: black;">那样</span>直观的关键词了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">不管从哪个<span style="color: black;">方向</span>看,这段代码都<span style="color: black;">已然</span>简洁了许多。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">但<span style="color: black;">咱们</span>还可能做得更好:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这儿</span><span style="color: black;">咱们</span>移除了 return 语句,这是<span style="color: black;">由于</span>在 Swift 中,单行闭包就暗含了 return。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">即便如此,<span style="color: black;">咱们</span>还能继续更进一步:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">reversedNames = names.sorted(by: { $0 > $1 } )</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Swift <span style="color: black;">亦</span>有暗含的命名位置参数,<span style="color: black;">因此</span>在上面的案例中,$0 是<span style="color: black;">第1</span>个参数,$1 是第二个参数,$2 是第三个参数等等。这个代码<span style="color: black;">已然</span>很紧凑了,<span style="color: black;">况且</span>非常容易理解,<span style="color: black;">然则</span><span style="color: black;">咱们</span><span style="color: black;">乃至</span>还能做得更好:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">reversedNames = names.sorted(by: >)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在 Swift 中,> 运算符<span style="color: black;">便是</span>一个名为 > 的函数。<span style="color: black;">因此呢</span>,<span style="color: black;">咱们</span><span style="color: black;">能够</span>将其传递给 sorted <span style="color: black;">办法</span>,使<span style="color: black;">咱们</span>的代码达到极端简洁和可读的程度。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这种操作适用于 +=、-=、、== 和 = 等运算符,你<span style="color: black;">能够</span>在标准库中查看它们的定义。这些函数/运算符与普通函数之间的差异是前者已在标准库中<span style="color: black;">运用</span> infix、prefix 或 suffix 关键词显式地声明为运算符。举个例子,+= 函数在 Swift 标准库的这一行(</p>https://github.com/apple/swift/blob/1ed846d8525679d2811418a5ba29405200f6e85a/stdlib/public/core/Policy.swift#L468)中被定义<span style="color: black;">成为了</span>一个运算符。<span style="color: black;">能够</span>看到,这个运算符遵循多个<span style="color: black;">区别</span>的协议,<span style="color: black;">例如</span> Array 和 String,<span style="color: black;">由于</span><span style="color: black;">非常多</span><span style="color: black;">区别</span>的类型都有自己的 += 函数实现。
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">更进一步,<span style="color: black;">咱们</span>还能定义自己的自定义运算符。GPUImage2 软件库<span style="color: black;">便是</span>一个很好的例子。这个软件库让用户<span style="color: black;">能够</span>加载图像,<span style="color: black;">运用</span>一系列变换来修改它,<span style="color: black;">而后</span>再以某种方式来输出它。很自然,这些变换序列的定义会在该库中<span style="color: black;">持续</span>反复<span style="color: black;">显现</span>,<span style="color: black;">因此呢</span>这个库的创建者决定定义一个新的运算符 →,可用于将这些变换链接到<span style="color: black;">一块</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">func -->(source:T, destination:T) -> T { source.addTarget(destination) return destination}infix operator --> : AdditionPrecedence</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在以上稍微简化过的代码中,<span style="color: black;">首要</span>声明了 --> 函数,<span style="color: black;">而后</span>其被定义为了一个 infix 运算符。infix 的意思是<span style="color: black;">倘若</span>要<span style="color: black;">运用</span>这个运算符,就必须将其<span style="color: black;">安置</span>在两个参数之间。这让你<span style="color: black;">能够</span>写出如下的代码:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">let testImage = UIImage(named:"WID-small.jpg")!let toonFilter = SmoothToonFilter()let luminanceFilter = Luminance()let filteredImage = testImage.filterWithPipeline{input, output in input --> toonFilter --> luminanceFilter --> output // Interesting part}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">比起一大堆互相链接的<span style="color: black;">办法</span>或一长串 source.addTarget(...) 函数,上面的代码要简短和容易多了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">亮点四</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">前面作者<span style="color: black;">已然</span><span style="color: black;">说到</span>过,Swift 的基本类型是标准库中定义的结构体,<span style="color: black;">况且</span>并<span style="color: black;">无</span>硬编码到编译器中,<span style="color: black;">由于</span>它们<span style="color: black;">一般</span>是用其它语言写的。这<span style="color: black;">特别有</span>用处,一大<span style="color: black;">原由</span>是让<span style="color: black;">咱们</span><span style="color: black;">能够</span><span style="color: black;">运用</span>名叫扩展(extension)的 Swift 特性,其让<span style="color: black;">咱们</span><span style="color: black;">能够</span>向任意类型添加新特性,<span style="color: black;">包含</span>基本类型。操作方式是<span style="color: black;">这般</span>的:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">extension Double { var radians: Double { return self * (Double.pi / 180) }}360.radians // -> 6.28319</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">尽管这个例子并不是很有用,但<span style="color: black;">亦</span>展示 Swift 这门语言的扩展能力,<span style="color: black;">由于</span>这能让你做<span style="color: black;">非常多</span>事情,<span style="color: black;">例如</span>向 Swift 解释器输入任何数字以及在其上调用任何你想用的自定义<span style="color: black;">办法</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">最后一个亮点</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">除了<span style="color: black;">持有</span>编译器之外,Swift 还<span style="color: black;">拥有</span>解释器并且支持 Jupyter Notebook。在学习这门语言时,解释器尤其好用,<span style="color: black;">由于</span>它支持直接在命令提示符处输入 swift,<span style="color: black;">而后</span><span style="color: black;">马上</span><span style="color: black;">起始</span>代码测试。Python <span style="color: black;">亦</span>具备差不多<span style="color: black;">同样</span>的功能。另一方面,<span style="color: black;">因为</span>整合了 Jupyter Notebook,<span style="color: black;">因此呢</span><span style="color: black;">能够</span><span style="color: black;">容易</span>进行可视化、执行数据探索和编写报告。最后,当你需要运行生产代码时,你<span style="color: black;">能够</span>编译它并利用 LLVM <span style="color: black;">供给</span>的出色优化能力。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">谷歌的大计划</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">作者在前面的章节中<span style="color: black;">说到</span>了 Swift 的<span style="color: black;">有些</span>特性,但其中有一个特性与其它<span style="color: black;">区别</span>:Jupyter Notebook 是新加入的,<span style="color: black;">况且</span>事实上正<span style="color: black;">是由于</span> S4TF 团队加入的。这非常值得一说,<span style="color: black;">由于</span>这能让<span style="color: black;">咱们</span>一窥谷歌投入这个项目时的想法:<span style="color: black;">她们</span>不仅想为 Swift 语言本身创建一个软件库,<span style="color: black;">况且</span><span style="color: black;">她们</span>还想深入地改进这门语言本身以及<span style="color: black;">关联</span>工具,<span style="color: black;">而后</span>再<span style="color: black;">运用</span>这门语言的改进版本创建一个新的 TensorFlow 软件库。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">只要<span style="color: black;">瞧瞧</span> S4TF 团队在<span style="color: black;">那些</span>工作上投入的时间最多就能看出这一点。<span style="color: black;">她们</span>到<span style="color: black;">日前</span>为止做的大部分工作都是在苹果<span style="color: black;">机构</span>的 Swift 编译器代码库本身上完成的。更<span style="color: black;">详细</span>而言,谷歌<span style="color: black;">日前</span>完成的大部分工作都在 Swift 编译器代码库中的一个 dev 分支中。谷歌正为 Swift 语言本身添加新特性——<span style="color: black;">她们</span><span style="color: black;">首要</span>会在自己的分支中创建和测试这些新特性,<span style="color: black;">而后</span>会将它们合并到苹果的主分支中。这<span style="color: black;">寓意</span>着运行在世界各地的 iOS 设备上的标准 Swift 语言<span style="color: black;">最后</span>将能集成这些改进。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">此刻</span>来谈谈更实在的东西:谷歌正为 Swift 构建什么特性?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">首要</span>说个大特性。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">可微分编程</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">近来,可微分编程炒得确实很热。特斯拉的人工智能负责人 Andrej Karpathy <span style="color: black;">叫作</span>之为软件 2.0(Software 2.0),Yann LeCun <span style="color: black;">乃至</span>宣<span style="color: black;">叫作</span>:「深度学习已死,可微分编程万岁。」另<span style="color: black;">有些</span>人则说有必要创建一套全新的工具了,<span style="color: black;">包含</span>新的 Git、新的 IDE 以及新的编程语言。Wink wink.</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">因此</span>,什么是可微分编程?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">简而言之,可微分编程是一种程序<span style="color: black;">自己</span>可被微分的编程范式。这让你<span style="color: black;">能够</span>设定一个你想要优化的<span style="color: black;">详细</span><span style="color: black;">目的</span>,让你的程序<span style="color: black;">能够</span><span style="color: black;">按照</span>这个<span style="color: black;">目的</span>自动计算自己的梯度,<span style="color: black;">而后</span>再在这个梯度的方向上优化自己。这和训练神经网络完全<span style="color: black;">同样</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>能让程序自己优化自己,<span style="color: black;">咱们</span><span style="color: black;">亦</span>许就能创造出<span style="color: black;">咱们</span>自己完全<span style="color: black;">没法</span>编写出来的程序。想想这一点还挺有趣:你的程序<span style="color: black;">能够</span><span style="color: black;">运用</span>梯度针对特定任务优化<span style="color: black;">自己</span>,<span style="color: black;">因此呢</span>它的编程能力比你还强。过去几年的发展<span style="color: black;">已然</span><span style="color: black;">显示</span>在越来越多的案例<span style="color: black;">已然</span><span style="color: black;">显现</span>了这种<span style="color: black;">状况</span>,<span style="color: black;">况且</span><span style="color: black;">日前</span><span style="color: black;">咱们</span>还看不到这一发展趋势的终点。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">一种可微分的语言</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">写了这么长的介绍之后,<span style="color: black;">最终</span><span style="color: black;">能够</span>谈谈谷歌为 Swift <span style="color: black;">研发</span>的原生可微分编程版本了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">func cube(_ x: Float) -> Float { return x * x * x}let cube = gradient(of: cube)cube(2) // 8.0cube(2) // 12.0</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这儿</span><span style="color: black;">咱们</span><span style="color: black;">首要</span>定义了一个简单的函数 cube,其返回的结果是输入的立方。接下来<span style="color: black;">便是</span>激动人心的部分了:<span style="color: black;">咱们</span>只需在原始函数上调用 gradient,就能创建原始函数的导数函数。<span style="color: black;">这儿</span><span style="color: black;">无</span><span style="color: black;">运用</span>任何软件库或<span style="color: black;">外边</span>代码,gradient 只<span style="color: black;">是由于</span> S4TF 团队为 Swift 语言引入的一个新函数。该函数利用了 S4TF 团队对 Swift 内核进行的修改,<span style="color: black;">能够</span>实现梯度函数的自动计算。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这是 Swift 的一个重大新特性。<span style="color: black;">针对</span>任意 Swift 代码,只要是可微分的,都<span style="color: black;">能够</span>自动计算梯度。上面的代码<span style="color: black;">无</span>导入任何东西或奇怪的依赖包,就只是纯粹的 Swift。PyTorch、TensorFlow 或其它任何大型<span style="color: black;">设备</span>学习库都支持这一功能,但前提是你要<span style="color: black;">运用</span>特定于库的特定运算。<span style="color: black;">况且</span>在这些 Python 库中操作梯度并不如单纯用 Swift 那样轻量、透明,<span style="color: black;">况且</span><span style="color: black;">哪些</span>库集成<span style="color: black;">亦</span>不如 Swift 原生集成<span style="color: black;">那样</span>好。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这是 Swift 语言的一个重大新特性;<span style="color: black;">况且</span><span style="color: black;">能够</span>说 Swift 是首个为这一特性<span style="color: black;">供给</span>原生支持的主流语言</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">为了进一步说明这在<span style="color: black;">实质</span>应用中的<span style="color: black;">运用</span>方式,以下应用于一个标准<span style="color: black;">设备</span>学习训练流程的脚本更完整透彻展示了这一新特性:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">struct Perceptron: @memberwise Differentiable { var weight: SIMD2 = .random(in: -1.. var bias: Float = 0</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">@differentiable func callAsFunction(_ input: SIMD2) -> Float { (weight * input).sum() + bias }}var model = Perceptron()let andGateData: [(x: SIMD2, y: Float)] = [ (x: , y: 0), (x: , y: 0), (x: , y: 0), (x: , y: 1),]for _ in 0.. let (loss, loss) = valueWithGradient(at: model) { model -> Float invar loss: Float = 0for (x, y) in andGateData { let ŷ = model(x) let error = y - ŷ loss = loss + error * error / 2 } return loss } print(loss) model.weight -= loss.weight * 0.02 model.bias -= loss.bias * 0.02}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">一样</span>,上面的代码完全是用 Swift 写的,不带任何依赖包。在这段代码中,<span style="color: black;">咱们</span><span style="color: black;">能够</span>看到谷歌为 Swift 引入的两个新特性:callAsFunction 和 valueWithGradient。<span style="color: black;">第1</span>个很简单,其<span style="color: black;">功效</span>是实例化类和结构体,让<span style="color: black;">咱们</span><span style="color: black;">能够</span>像调用函数<span style="color: black;">同样</span>调用它们。<span style="color: black;">这儿</span>,Perceptron 结构体被实例化为了 model,<span style="color: black;">而后</span> model 又在 let ŷ = model(x) 中被<span style="color: black;">做为</span>一个函数而调用。在<span style="color: black;">这般</span>操作时,<span style="color: black;">实质</span>上调用的是 callAsFunction <span style="color: black;">办法</span>。<span style="color: black;">倘若</span>你曾经用过 Keras 或 PyTorch 模型,你<span style="color: black;">必定</span><span style="color: black;">晓得</span>这是一种处理模型/层的常用方式。但 Keras 和 PyTorch 这两个库<span style="color: black;">运用</span>了 Python 的 *call* <span style="color: black;">办法</span>来实现它们各自的 call 和 forward;Swift 之前<span style="color: black;">无</span><span style="color: black;">这般</span>的特性,于是谷歌把它加了进去。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">上面的脚本中还有一个有趣的新特性:valueWithGradient。该函数会返回在特<span style="color: black;">选定</span><span style="color: black;">评定</span>的函数或闭包的结果值和梯度。在以上案例中,<span style="color: black;">咱们</span>定义并用作 valueWithGradient 的输入的闭包<span style="color: black;">实质</span>上是<span style="color: black;">咱们</span>的损失函数。这个损失函数的输入是<span style="color: black;">咱们</span>的模型,<span style="color: black;">因此</span>当<span style="color: black;">咱们</span>说 valueWithGradient 会在特定的点<span style="color: black;">评定</span><span style="color: black;">咱们</span>的函数时,<span style="color: black;">咱们</span>的意思是其会<span style="color: black;">运用</span>有特定权重配置的模型<span style="color: black;">评定</span><span style="color: black;">咱们</span>的损失函数。计算了<span style="color: black;">以上</span>的值和梯度之后,<span style="color: black;">咱们</span><span style="color: black;">能够</span>把值打印出来(这是<span style="color: black;">咱们</span>的损失)并<span style="color: black;">运用</span>梯度更新模型的权重。重复这一过程一百次,<span style="color: black;">咱们</span>就训练了一个模型。<span style="color: black;">咱们</span>还<span style="color: black;">能够</span><span style="color: black;">拜访</span>损失函数内部的 andGateData,这是 Swift 闭包<span style="color: black;">能够</span>获取其<span style="color: black;">周边</span>上下文的又一案例。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">微分<span style="color: black;">外边</span>代码</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Swift 还有一个神奇的特性:<span style="color: black;">咱们</span>不仅<span style="color: black;">能够</span>微分 Swift 运算,还能微分<span style="color: black;">外边</span>的、非 Swift 的软件库——只需<span style="color: black;">咱们</span>在 Swift 中手动定义这些运算操作的导数。这<span style="color: black;">寓意</span>着你<span style="color: black;">能够</span><span style="color: black;">运用</span> C 软件库中<span style="color: black;">有些</span>非常快速的实现或<span style="color: black;">有些</span> Swift 还不具备的运算操作。你只需将其导入到你的项目中、编写导数代码,<span style="color: black;">而后</span>就<span style="color: black;">能够</span>在你的大型神经网络中<span style="color: black;">运用</span>这些运算操作,让反向传播等功能无缝运行。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">另外</span>,这件事做起来其实非常简单:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">import Glibc // we import pow and log from herefunc powerOf2(_ x: Float) -> Float { return pow(2, x)}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">@derivative(of: powerOf2)func dPowerOf2d(_ x: Float) -> (value: Float, pullback: (Float) -> Float) { let d = powerOf2(x) * log(2) return (value: d, pullback: { v in v * d })}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">powerOf2(3), // 8gradient(of: powerOf2)(3) // 5.545</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Glibc 是一个 C 软件库,<span style="color: black;">因此呢</span> Swift 编译器并不<span style="color: black;">晓得</span>其运算操作的导数是什么。<span style="color: black;">经过</span><span style="color: black;">运用</span> @derivative,<span style="color: black;">咱们</span><span style="color: black;">能够</span>为编译器<span style="color: black;">供给</span><span style="color: black;">相关</span>这些<span style="color: black;">外边</span>运算操作的导数的信息,<span style="color: black;">而后</span>搭配 Swift 的原生运算,<span style="color: black;">能够</span>非常<span style="color: black;">容易</span>地构建出大型的可微分网络。在这个示例中,<span style="color: black;">咱们</span>导入了 Glibc 的 pow 和 log,并用它们创建了 powerOf2 函数及其导数。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">为 Swift <span style="color: black;">研发</span>的新 TensorFlow 软件库的当前版本就正在<span style="color: black;">运用</span>这一特性进行<span style="color: black;">研发</span>。这个库从 TF Eager 软件库的 C API 导入了其所有运算操作,但其不是将 TensorFlow 的自动微分系统直接接上去,而是要指定<span style="color: black;">每一个</span><span style="color: black;">基本</span>运算操作的导数,<span style="color: black;">而后</span>再让 Swift 处理。<span style="color: black;">然则</span>,并非所有运算都需要这种操作,<span style="color: black;">由于</span>许多运算都是更基本运算组合而成的,<span style="color: black;">因此呢</span> Swift <span style="color: black;">能够</span>自动推断它们的导数。但<span style="color: black;">因为</span>这个库的当前版本基于 TF Eager,<span style="color: black;">因此呢</span>存在一个大缺点:TF Eager 非常慢,<span style="color: black;">因此呢</span> Swift 的这个版本<span style="color: black;">亦</span>很慢。这个问题应该只是暂时性的,随着与 XLA(<span style="color: black;">经过</span> x10)和 MLIR 的整合,这个问题<span style="color: black;">能够</span>得到<span style="color: black;">处理</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">话虽如此,<span style="color: black;">实质</span>上 Swift TensorFlow API <span style="color: black;">已然</span>初具规模,谷歌的<span style="color: black;">研发</span>者<span style="color: black;">已然</span><span style="color: black;">能够</span><span style="color: black;">运用</span>这个 API 进行<span style="color: black;">研发</span>了。<span style="color: black;">运用</span>它,你<span style="color: black;">能够</span><span style="color: black;">这般</span>训练一个简单模型:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">import TensorFlowlet hiddenSize: Int = 10struct IrisModel: Layer { var layer1 = Dense(inputSize: 4, outputSize: hiddenSize, activation: relu) var layer2 = Dense(inputSize: hiddenSize, outputSize: hiddenSize, activation: relu) var layer3 = Dense(inputSize: hiddenSize, outputSize: 3)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">@differentiable func callAsFunction(_ input: Tensor) -> Tensor { return input.sequenced(through: layer1, layer2, layer3) }}var model = IrisModel()let optimizer = SGD(for: model, learningRate: 0.01)let (loss, grads) = valueWithGradient(at: model) { model -> Tensor inlet logits = model(firstTrainFeatures) return softmaxCrossEntropy(logits: logits, labels: firstTrainLabels)}print("Current loss: \(loss)")</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">能够</span>看到,这与之前的无导入的模型训练脚本非常<span style="color: black;">类似</span>。它的设计非常类似 PyTorch,真是太棒了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">与 Python 的互操作性</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Swift <span style="color: black;">日前</span>仍面临的一大问题是当前的<span style="color: black;">设备</span>学习和数据科学生态系统仍<span style="color: black;">处在</span>起步<span style="color: black;">周期</span>。幸运的是,谷歌正在<span style="color: black;">处理</span>这个问题,其方式是为 Swift 纳入 Python 互操作性。其想法是让<span style="color: black;">研发</span>者可在 Swift 代码中编写 Python 代码;<span style="color: black;">经过</span>这种方式,数量庞大的 Python 软件库就能为 Swift 所用了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这种操作的一种典型用例是用 Swift 训练模型,<span style="color: black;">而后</span>用 Python 的 matplotlib 来绘制图表:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">import Pythonprint(Python.version)let np = Python.import("numpy")let plt = Python.import("matplotlib.pyplot")// let time = np.arange(0, 10, 0.01)let time = Array(stride(from: 0, through: 10, by: 0.01)).makeNumpyArray()let amplitude = np.exp(-0.1 * time)let position = amplitude * np.sin(3 * time)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">plt.figure(figsize: )</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">plt.plot(time, position)plt.plot(time, amplitude)plt.plot(time, -amplitude)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">plt.xlabel("Time (s)")plt.ylabel("Position (m)")plt.title("Oscillations")</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">plt.show()</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这看起来就像是单纯的 Python 代码加了一点 let 和 var 语句。这<span style="color: black;">是由于</span>谷歌<span style="color: black;">供给</span>的一段代码示例。作者只做了一项修改,即注释掉了一行 Python 代码,并用 Swift 对其进行了重写。<span style="color: black;">能够</span>看到,这两者在<span style="color: black;">这儿</span>竟然<span style="color: black;">能够</span>交互得如此之好。这项任务完成起来并不如完全<span style="color: black;">运用</span> Python 那样清晰简洁,<span style="color: black;">由于</span><span style="color: black;">咱们</span>必须<span style="color: black;">运用</span> makeNumpyArray() 和 Array();但这种操作是可行的。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">谷歌成功实现 Python 互操作性的<span style="color: black;">办法</span>是引入了 PythonObject 类型,其可<span style="color: black;">暗示</span> Python 中的任何对象。Python 互操作性被限定在单个 Swift 软件库中,<span style="color: black;">因此呢</span> S4TF 团队仅需为 Swift 语言本身添加少量功能,<span style="color: black;">例如</span>添加少量改进以适应 Python 的极端动态性。至于<span style="color: black;">此刻</span>的 Python 支持<span style="color: black;">已然</span>达到了何种程度,<span style="color: black;">日前</span>尚不清楚<span style="color: black;">她们</span>将<span style="color: black;">怎样</span>处理 with 语句等更地道的 Python 元素,<span style="color: black;">况且</span><span style="color: black;">能够</span>肯定地说还有其它<span style="color: black;">有些</span>极端<span style="color: black;">状况</span>有待<span style="color: black;">思虑</span>;尽管如此,<span style="color: black;">此刻</span><span style="color: black;">已然</span>实现的成果就<span style="color: black;">已然</span>很不错了。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">而在 Swift 与其它语言的整合方面,作者对 Swift 的最早的兴趣点之一<span style="color: black;">便是</span>想<span style="color: black;">瞧瞧</span>它在处理实时计算机视觉任务上的表现。<span style="color: black;">由于</span>这个<span style="color: black;">原由</span>,作者<span style="color: black;">最后</span>找到了 OpenCV 的一个 Swift 版本,而<span style="color: black;">经过</span> FastAI 的论坛,<span style="color: black;">最后</span>找到了一个大有<span style="color: black;">潜能</span>的 OpenCV 封装类(wrapper):SwiftCV。<span style="color: black;">然则</span>,这个库很奇怪。OpenCV 是用 C++ 构建的(并且<span style="color: black;">刚才</span>废弃了其 C API),而 Swift <span style="color: black;">日前</span>并不支持 C++(<span style="color: black;">不外</span>将会支持)。<span style="color: black;">因此呢</span>,SwiftCV 必须将 OpenCV 代码封装在 C++ 代码的一个兼容 C 的子集中,<span style="color: black;">而后</span>再以 C 软件包的形式导入。之后,<span style="color: black;">才可</span>将其封装到 Swift 中。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">S4TF 项目的当前状态</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">尽管作者对 S4TF 项目<span style="color: black;">始终</span>不吝赞美之辞,但<span style="color: black;">亦</span>必须承认其还不足以支持<span style="color: black;">通常</span>的生产<span style="color: black;">运用</span>。其新的 API 仍在<span style="color: black;">持续</span>变化,这个新的 TensorFlow 库的性能<span style="color: black;">亦</span>仍然不是很好;即便其数据科学生态系统正在发展壮大,但总体仍<span style="color: black;">处在</span>起步<span style="color: black;">周期</span>。最重要的是,其 Linux 支持<span style="color: black;">状况</span>很奇怪,<span style="color: black;">日前</span>官方仅支持 Ubuntu。<span style="color: black;">思虑</span>到所有这些问题,要<span style="color: black;">保准</span>所有这些问题<span style="color: black;">即时</span>得到<span style="color: black;">处理</span>,还有<span style="color: black;">非常多</span>工作要做。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">谷歌正在<span style="color: black;">奋斗</span><span style="color: black;">提高</span>其性能,<span style="color: black;">包含</span><span style="color: black;">近期</span>添加的 x10 以及在让 MLIR 达到标准方面所做的工作。<span style="color: black;">另一</span>,谷歌还有<span style="color: black;">有些</span>项目致力于在 Swift 中复制许多 Python 数据科学生态系统的功能,<span style="color: black;">例如</span> SwiftPlot、类似 Pandas 的 Penguin、类似 Scikit-learn 的 swiftML。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">但最让人惊讶的是苹果<span style="color: black;">机构</span><span style="color: black;">亦</span>与谷歌在同一方向上推动 Swift 的发展。在苹果的 Swift 发展路线图上,下一个重大版本的<span style="color: black;">重点</span><span style="color: black;">目的</span>是在非苹果平台上<span style="color: black;">创立</span><span style="color: black;">持续</span>发展增长的 Swift 软件生态系统。这一<span style="color: black;">目的</span><span style="color: black;">亦</span>反映在了苹果对多个项目的支持上,<span style="color: black;">例如</span> Swift Server Work Group、类似 numpy 的 Numerics、一个运行在 Linux 上的官方语言服务器以及将 Swift 移植到 Windows 系统的工作。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">另外</span>,Fast.ai 的 Sylvain Gugger <span style="color: black;">亦</span>正为 FastAI 构建一个 Swift 版本,而 Jeremy Howard <span style="color: black;">亦</span><span style="color: black;">已然</span>将 Swift 课程纳入到了<span style="color: black;">她们</span>的广受欢迎的在线课程中。<span style="color: black;">另一</span>,<span style="color: black;">第1</span>批基于 S4TF <span style="color: black;">关联</span>软件库的学术论文<span style="color: black;">亦</span>正陆<span style="color: black;">持续</span>续<span style="color: black;">发布</span>出来。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">总结</strong></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在作者<span style="color: black;">自己</span>看来,尽管 Swift <span style="color: black;">特别有</span>可能发展成<span style="color: black;">设备</span>学习生态系统的一大关键角色,但<span style="color: black;">危害</span>仍然存在。其中最大的<span style="color: black;">危害</span>是:尽管 Python 存有缺陷,但<span style="color: black;">针对</span>大部分<span style="color: black;">设备</span>学习任务<span style="color: black;">来讲</span><span style="color: black;">已然</span>足够好了。<span style="color: black;">针对</span>许多<span style="color: black;">已然</span><span style="color: black;">熟练</span> Python 的人<span style="color: black;">来讲</span>,惯性可能太大,<span style="color: black;">亦</span><span style="color: black;">无</span>换成另一种语言的理由。<span style="color: black;">另一</span>,谷歌<span style="color: black;">已然</span>不是一次两次放弃大型项目了,而 S4TF 的<span style="color: black;">有些</span>关键人员的脱离<span style="color: black;">亦</span>让人担忧。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">给出了这些免责声明之后,作者仍然觉得 Swift 是一门很棒的语言,这些新增的功能<span style="color: black;">亦</span>极具创新性,相信它们<span style="color: black;">最后</span>能在<span style="color: black;">设备</span>学习社区找到自己的位置。<span style="color: black;">因此呢</span>,<span style="color: black;">倘若</span>你<span style="color: black;">亦</span>想为这个<span style="color: black;">潜能</span>无穷的项目添砖加瓦,<span style="color: black;">此刻</span><span style="color: black;">便是</span>很好的<span style="color: black;">机会</span>。Swift 在<span style="color: black;">设备</span>学习<span style="color: black;">行业</span>的地位还远未确立,还有<span style="color: black;">非常多</span>工<span style="color: black;">拥有</span>待<span style="color: black;">研发</span>。随着 Swift <span style="color: black;">设备</span>学习生态系统的<span style="color: black;">连续</span>发展,<span style="color: black;">此刻</span>的小项目<span style="color: black;">亦</span>许<span style="color: black;">将来</span><span style="color: black;">能够</span>成长为巨大的社区项目。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">原文链接:</p>https://tryolabs.com/blog/2020/04/02/swift-googles-bet-on-differentiable-programming/
你的话语如春风拂面,让我感到无比温暖。 百度seo优化论坛 http://www.fok120.com/ 你的见解独到,让我受益匪浅,非常感谢。 外链发布社区 http://www.fok120.com/
页:
[1]