移动AI系列-百度Paddle.js在Web前端中的探索和实践

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"一、背景"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"随着百度AI战略的逐步深入,百度AI能力正在积极地布局和渗透在更多的应用领域,对于不同的应用场景有着不同的AI能力解决方案,为了在浏览器等Web前端场景中应用百度AI能力,百度相关技术团队孵化出百度Paddle.js 用于帮助前端工程师更加简单地将智能化因素引入网页中,让Web前端可以实现更多的能力。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"二、为什么要在前端引入 AI 能力"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过浏览器来访问网页应用浏览内容具有更低的门槛和更广泛的传播度,能够在网页中融入智能化因素将会为用户体验插上一对腾飞的翅膀。传统的智能化效果由于模型大小、设备机器算力的问题,多数是放在服务端实现的,但是这需要多次与服务器进行网络上的信息交互,用户体验被打折。Web前端作为互联网中离用户最近的一环,也希望借助 AI 的能力,给用户创建更好的体验。随着硬件设备的快速更新换代,直接在网页中实现的智能化效果逐渐进入人们的视线,相比云端智能,端智能具有低延时、保护数据隐私、节省云端计算资源等优势,端智能的实时性优势更加凸显。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/24\/1b\/243a36a2a4153c50ffd028d22108e21b.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于Web前端而言,算力的稳步增强、算法逐步成熟以及创新驱动的应用场景都在影响着端智能演进,而浏览器等载体的自身能力无疑是影响Web前端创新场景的最重要的因素。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其中WebRTC使得Web上支持原生的视频通话能力,视频流实时获取成为可能;WebXR可以利用 GPU 能力处理复杂和 3D 图形 ;Web Assembly可以将其它语言生态引入 Web,Service Workers通过后台任务来支持离线以及提升性能。这些浏览器等载体对于设备底层能力的极大化扩展和对CPU、GPU甚至NPU的计算能力的合理调用都为Web端实现复杂的创新应用提供了帮助。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"W3C 也成立了机器学习的社区组,试图提供原生的 Web 神经网络 API,这是为神经网络理论硬件加速设计的底层接口,用例包括:人物识别、语义诊断、情绪分析、图像自动分类等等,目标是可以直接使用预训练的深度神经网络模型。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/95\/04\/95b9a53b47c63856a2c3467d77e7bc04.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以预期的是,基于Web端也会出现越来越多有趣、好玩的一些创新应用,那么什么样的场景适合使用Web AI呢?这里有几个案例与大家分享。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"三、几个Web前端案例"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先,用户Web端计算不仅"},{"type":"text","marks":[{"type":"strong"}],"text":"可以节省服务端的计算压力"},{"type":"text","text":",而且可以"},{"type":"text","marks":[{"type":"strong"}],"text":"提供非常快速的响应"},{"type":"text","text":",比如这个我们在网页中实现的基于人脸跟踪和表情识别的应用效果就非常适合这个场景,打开手机百度APP搜索“自拍测人设”就会发现这个应用,在这个网页应用中要求必须在能够实时捕捉屏幕内容进行框选,需要极其快速的计算能力来识别和追踪人脸。面向全网用户使用,那么浏览器内实现无疑是最佳方案,保证分享出去后其他用户也能够无差别的直接使用,而不需要安装指定的应用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其次, AI能力能够实现一系列复杂的交互,打造“神奇”的网页,可以说有了"},{"type":"text","marks":[{"type":"strong"}],"text":"Web AI新技术,可以创造全新的交互方式。"},{"type":"text","text":"这方面的例子有很多,比如这个肢体交互能够切换背景的场景就非常具有惊喜感,通过Web AI实现在网页上人像分割的例子,能够将人像从复杂的场景中分离出来,结合肢体识别能力实现了非传统的网页交互效果。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/2e\/23\/2eb743318be48a26aac416a09f128323.gif","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"l  不同于将用户信息上传到服务端做处理,"},{"type":"text","marks":[{"type":"strong"}],"text":"Web AI能够很好的保护用户的隐私性"},{"type":"text","text":",它可以在每个用户数据不离开手机的情况下对数据进行推理预测计算,也能够有效的对用户浏览的数据做出智能化的“控制”。例如,对于黄反图片的在线判定和过滤也可以在用户端实现。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"总的来说,在用户Web端处理具有信息更好的隐私性,省去网络交互的更快实时性计算,以及硬件飞速发展的更强计算能力是Web AI独特的优势。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"四、Paddle.js前端智能化介绍"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在Web前端实现智能化,从整个链路上面看,会有数据采集和算法模型设计工作,在服务端训练和产出模型。但是这种模型往往不能够直接被浏览器使用,还需要对模型进行压缩、Web格式转化和模型部署,最后前端通过各种方式请求获取模型并且进行在线推理才能在具体的业务场景下使用。整个链路较长,涉及云端和Web前端,离线处理和在线运行时,甚至需要算法工程师和移动开发工程师配合才能完成相关应用落地。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/44\/ed\/44fda841705f3575f57bdc24e53c8aed.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"能不能对前端工程师更友好一些,能不能更加容易灵活的实现Web智能化应用?"},{"type":"text","text":"为了在浏览器运行的网页中实现AI效果,百度推出了自己研发的JavaScript实现的轻量级在线推理引擎Paddle.js,依靠强大丰富的百度Paddle模型库,结合工具链和在线推理库低成本地将模型转化成Web可用格式,运行在浏览器等Web前端载体中,降低Web前端开发者在网页中使用AI能力的门槛。受益于百度AI战略的影响,百度Paddle.js逐渐发展成为一个执行性能优秀、浏览器兼容性良好的内部网页智能化标准,并且应用于多个在线项目,例如人脸检测、手势识别、人像分割、黄反检测和Web AR的实践中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"目前在网页上实现AI的推理引擎不多。性能方面,百度Paddle.js借助于GPU Backend能够在浏览器中使用硬件加速快速运行,而且还充分参与了Web NN标准化,在手机百度app提供的特殊加速支持获得更快的执行速度;代码体积方面,Paddle.js的静态代码体积非常的小,仅有"},{"type":"text","marks":[{"type":"strong"}],"text":"201KB"},{"type":"text","text":";易用性方面,paddlejs是一个开箱即用的前端在线推理引擎,它提供了丰富的能力封装,无需其他依赖即可完成目标效果。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Paddle.js主要部分包括:模型工具链、推理前后处理、用户工具链、测试框架和推理引擎本身。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/8a\/8e\/8a0a090d110181f69b2201560479d48e.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"l  "},{"type":"text","marks":[{"type":"strong"}],"text":"模型工具链"},{"type":"text","text":":Paddle.js依靠与Paddle等训练框架进行模型训练,或者使用Paddle hub上丰富的模型库,因为在浏览器中需要使用到浏览器友好的模型格式,通过Paddle.js提供的模型工具链对模型格式进行转换和离线优化,一方面减少模型体积,一方面通过各种优化技术优化模型性能,从模型根本上优化神经网络结构,进行算子替换、算子融合、网络分块、模型压缩等初步数据优化处理。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/2c\/3e\/2c76744265def23332fb2bf47ab7cc3e.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"l  "},{"type":"text","marks":[{"type":"strong"}],"text":"输入输出处理"},{"type":"text","text":":也叫做推理前后处理,对于前端工程师来说,图像、视频流等数据处理是一件很麻烦的事情,知识专业度比较高,Paddle.js提供了强大的输入输出处理能力以减少这部分开发的成本,Web前端工程师可以直接调用相应的推理前后处理方法将数据高效进行处理,使得工程师可以专注于业务的开发。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"l  "},{"type":"text","marks":[{"type":"strong"}],"text":"在线推理"},{"type":"text","text":":在线推理部分包括神经网络加载、神经网络在线优化、算子分配与数据初始化、预热与执行推理计算等部分。为了保证在浏览器等Web前端环境下能够应用在视频级的场景下,借助于硬件加速技术,结合模型量化压缩方案,代码深度精简,并且在线推理部分采用了多种技术手段针对神经网络执行效率和算子计算性能进行了系统性的优化,保证达到在浏览器上实时执行效果丝滑流畅。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/0e\/ce\/0ea0888c9bcb19af2d74ac997795f4ce.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"五、AI能力的简单使用"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不同于其他的实现方式,在网页中实现AI能力其实可以做到非常的简单,不依赖于发布版本,可以满足高速迭代产品经常更新的特点。而且不需要集成、编译等复杂的开发形式,只需要引入Paddle.js就可以让你的网页拥有AI能力,通过网络加载AI模型,简单的进行输入和输出的业务开发就可以实现非常智能化的效果。接下来,我们一起在网页上实现一个具有AI能力的页面应用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第一步,引入代码库"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过npm i 安装Paddle.js代码库,在代码中import引入即可,也可以直接通过script的src引用Paddle.js,在你的应用中创建Paddle对象实例后你的代码就可以使用AI能力了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"import Paddle from paddlejsconst paddle = new Paddle();"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第二步,加载模型"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"模型是AI能力最重要的部分之一,通过加载模型使得网页应用可以执行相应的AI能力,不同的模型体积不同,为了能够较快的加载模型,Paddle.js 支持模型的分片并行化加载和利于网络传输的数据压缩能力。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"paddle.load()"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第三步,设置输入"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于在网页上进行在线推理预测需要一般需要设置输入内容,后续的交互依靠于输入处理的结果,特别是实时场景需要将输入内容处理成符合要求的标准输入数据并控制传入节奏,这些对于业务开发都是非常具有挑战的,Paddle.js提供了对于输入数据的处理的封装,将这部分工作简单化,甚至对于业务开发来说只是简单的传入数据获取结果就可以,提升了易用性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"const input = io.process({});"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第四步,执行并输出效果"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"将输入传入并执行Paddle对象的execute方法解可以很快地得到执行结果,而且开发者根本不需要人为地去设定使用具体的backend去进行计算,在线推理部分会自动根据用户场景选择最快的方式进行计算。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"paddle.execute(input);"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"将计算结果放入相应的推理后处理方法就会很容易地得到目标效果,在浏览器网页中实现智能化的能力只需要这几个步骤,使用门槛非常的低。具体的完整详细的应用开发可以访问paddle.js项目,上面有很多JavaScript实现智能化的例子。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"六、未来展望"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于未来的发展,随着硬件设备的性能大幅提升,浏览器内的智能化效果将会越来越流畅,能够完成的效果也会越来越复杂,Paddle.js的后续发展也会主要立足于三个方面点来看。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第一,继续优化浏览器内执行速度,增加算子覆盖,能力延伸到更加复杂的多模型执行场景;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第二,提供更加完善的用户工具链,继续降低用户的使用成本;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第三,把握未来的趋势,面向未来做技术布局。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最后,Web AI势必会对web发展产生深远的影响,期待能和大家一起打造功能完善,性能极致,简单易用的web端在线推理引擎,欢迎访问Paddle.js开源项目("},{"type":"link","attrs":{"href":"https:\/\/github.com\/PaddlePaddle\/Paddle.js","title":"","type":null},"content":[{"type":"text","text":"https:\/\/github.com\/PaddlePaddle\/Paddle.js"}]},{"type":"text","text":"),多提宝贵意见。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Release Note"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Paddle.js是百度Paddle的web方向子项目,是一个运行在浏览器中的开源深度学习框架。Paddle.js可以加载训练好Paddle.js模型,或者将Paddle.fluid模型通过Paddle.js的模型转换工具变成浏览器友好的模型进行在线预测使用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"兼容性"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"支持在webGL2.0和webGL1.0的浏览器上运行。例如chrome, firefox, safari以及移动端的Baidu App, QQ浏览器等。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"支持NCHW与NHWC格式的模型数据计算。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"详细请参考:"},{"type":"link","attrs":{"href":"https:\/\/github.com\/PaddlePaddle\/Paddle.js\/releases","title":"","type":null},"content":[{"type":"text","text":"https:\/\/github.com\/PaddlePaddle\/Paddle.js\/releases"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule"},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"头图"},{"type":"text","text":":Unsplash"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"作者"},{"type":"text","text":":wangqun"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"原文"},{"type":"text","text":":"},{"type":"link","attrs":{"href":"https:\/\/mp.weixin.qq.com\/s\/8wceA5zEaNKr1Xv_EN-oBA","title":"","type":null},"content":[{"type":"text","text":"移动AI系列-百度Paddle.js在Web前端中的探索和实践"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"来源"},{"type":"text","text":":百度App技术 - 微信公众号 [ID:gh_59f5931152fe]"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"转载"},{"type":"text","text":":著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章