中企动力 > 商学院 > 深度学习基础教程
  • ?

    贾扬清撰文详解Caffe2:从强大的新能力到入门上手教程

    喻听荷

    展开

    选自 Nvidia Blog作者:Aaron Markham、贾扬清机器之心编译

    昨天,Facebook 推出了 Caffe2,一个兼具表现力、速度和模块性的开源深度学习框架。它沿袭了大量的 Caffe 设计,可解决多年来在 Caffe 的使用和部署之中发现的瓶颈问题。最终,Caffe2 打开了算法实验和新产品的大门。通过在内部用于各种深度学习和增强现实任务,Caffe2 已经在 Facebook 对于规模和性能的需求上得到了锻造。同时,它为移动端应用提供了令人印象深刻的新功能,例如高级相机和即时通讯功能。英伟达作为 Caffe2 的开发合作者,计划对 Caffe2 的深度学习应用推出一系列博客文章。本文即是该系列博文的第一篇,将介绍 Caffe2 的深度学习基础知识,证明其灵活性和速度;本文还将介绍为什么你想要使用 Caffe2、是什么使 Caffe2 区别于 Caffe,最后还会通过一个预训练的目标分类模型给出一个 Caffe2 使用案例。

    一次编码,任意运行

    在保有扩展性和高性能的同时,Caffe2 也强调了便携性。「便携性」通常使人想起 overhead——它如何在诸多不同的平台上工作?overhead 如何影响扩展的能力?Caffe2 当然已把这些考虑在内,其从一开始就以性能、扩展、移动端部署作为主要设计目标。Caffe2 的核心 C++ 库能提供速度和便携性,而其 Python 和 C++ API 使你可以轻松地在 Linux、Windows、iOS、Android 甚至 Raspberry Pi 和 NVIDIA Tegra 上进行原型设计、训练和部署。也许你会问:物联网呢?Caffe2 将适用于大量设备。尽管你并不想在物联网设备上训练网络,但你可以在其上面部署训练好的模型。

    当 GPU 可用时,Caffe2 也不会错失这个良机。在 Facebook 和英伟达的合作下,Caffe2 已经可以充分利用英伟达 GPU 深度学习平台。Caffe2 可使用最新的英伟达深度学习 SDK 库——cuDNN、cuBLAS 和 NCCL——来实现高性能、多 GPU 加速训练和推理。

    绝大多数内置函数都可根据运行状态在 CPU 模式和 GPU 模式之间无缝切换。这意味着无需额外编程即可享用深度学习超级加速的便利。这引出了 Caffe2 激动人心的另一个方面:多 GPU 和多主机处理。Caffe2 使并行化网络训练变得简单,现在实验和扩展对你而言也非常简单。

    最近的 ImageNet 训练基准使用了 64 块最新的英伟达 GPU 和 ResNet-50 神经网络架构。Facebook 工程师实现的 Caffe2 的 data_parallel_model(https://github/caffe2/caffe2/blob/master/caffe2/python/data_parallel_model.py)能够在 Facebook 的 8 个 Big Basin 人工智能服务器(每个服务器配有 8 个英伟达 Tesla P100 GPU 加速器,8 个服务器共有 64 块 GPU)上进行分布式神经网络训练。图 1 是这些系统的扩展结果:近乎直线的深度学习训练扩展,带有 57 倍的吞吐量加速。

    图 1: 通过 Resnet-50 模型在多达 64 个英伟达 Tesla P100 GPU 加速器上训练的 Caffe2 扩展系数

    Caffe2 的新功能

    你也许记得在 Caffe 中一切都表征为一个「网」(Net),它由「层」组成,这些层是以神经网络中心化方式来定义计算。然而,这创建了一种非常刚性的计算模式,并带来了很多硬编码例程,尤其在深度神经网络训练方面。

    Caffe2 采用了更现代的计算图(computation graph)来表征神经网络或者包括集群通信和数据压缩在内的其它计算。这一计算图采用「算子」(operator)的概念:在给定输入的适当数量和类型以及参数的情况下,每个算子都包含了计算输所必需的逻辑。尽管 Caffe 中的层总是采用张量(矩阵或多维数组),但 Caffe2 中的算子可采用并产生包含随意对象的「blob」,这一设计使得很多过去在 Caffe 中不可实现的事情成为可能:

    CNN 分布式训练可由单个计算图表征,不管是在一个或多个 GPU 还是在多台机器上训练。这对 Facebook 规模的深度学习应用很关键。在专业硬件上轻松进行异构计算。例如,在 iOS 上,Caffe2 计算图可从 CPU 获取图像,将其转化为 Metal GPU 缓存对象,并将计算完全保留在 GPU 上,以获得最大吞吐量。更好地管理运行时间资源,比如使用 memonger 优化静态内存,或者预打包训练网络以获得最佳性能。float、float16、int8 混合精度和其他量化模型的计算。

    Caffe2 有超过 400 个算子,具备广泛的功能。你可以浏览算子目录(http://caffe2.ai/docs/operators-catalogue.html)、查看稀疏操作(http://caffe2.ai/docs/sparse-operations.html)并学习如何编写自定义算子(http://caffe2.ai/docs/custom-operators.html)。

    安装与设置

    你要做的第一件事就是查看 Caffe2 的 GitHub 主页,clone 或 fork 该项目的 Github repo。

    git clone https://github/caffe2/caffe2.git

    如果你安装不了 Caffe2,你可以查看以下安装指南:http://caffe2.ai/docs/getting-started.html,尝试这个 Docker 镜像:https://hub.docker/r/caffe2ai/caffe2/,或者在你选择的云提供商上运行。其文档也为每个选项提供了指令。然而,我们建议你通过建立 GPU 支持的云实例,来验证 GPU 的处理速度。以下是使用 Docker 建立 GPU 支持的 Caffe2 的快速方式:

    docker pull caffe2ai/caffe2 && docker run -it caffe2ai/caffe2:latest \python -m caffe2.python.operator_test.relu_op_test

    尝试一个预训练的模型

    现在让我们实际上手试一试!在这第一个教程中,我会教你如何轻松使用 Caffe2 的 Model Zoo 和模型下载器(model downloader),以帮你自己动手实验一些其它模型。Model Zoo 链接:http://caffe2.ai/docs/zoo.html

    使用 Caffe2 的模型下载器

    这是一个下载模块(https://github/caffe2/caffe2/blob/master/caffe2/python/models/download.py),你可以使用它来获取预训练好的网络。你可以将该模块整合到你的脚本中,或者在命令行中使用它:

    python -m caffe2.python.models.download

    比如,这行命令可以下载 squeezenet 预训练模型:

    python -m caffe2.python.models.download squeezenet

    下载了 squeezenet 之后,你可以加载它。这个模型下载器模块有一个安装(install)选项,你可以使用 -i 开启。否则你就需要在下载文件后自己移动它。一旦安装完成,你也可以直接将这些模型导入到你的 Python 脚本:

    python -m caffe2.python.models.download -i squeezenet

    运行一个预训练模型:目标分类

    让我们试试用 Caffe2 做一次目标分类。如果你已经下载了一个预训练模型,这做起来就很简单。如果你还没有下载 squeezenet,你可以使用上述方法下载,也可从 S3 下载 init_net.pb 和 predict_net.pb 文件。

    init_net.pb:https://s3.amazonaws/caffe2/models/squeezenet/init_net.pbpredict_net.pb:https://s3.amazonaws/caffe2/models/squeezenet/predict_net.pb

    将下载好的文件放到 $PYTHONPATH/caffe2/python/models/squeezenet 文件夹。你的 Python 代码需要 Caffe2 的 workspace 来存放该模型的 protobuf 负载和权重,并将它们加载到 blob、init_net 和 predict_net 中。你将需要 workspace.Predictor 来接收这两个 protobuf,然后剩下的就交给 Caffe2 处理了。Caffe2 有一个简单的 run 函数,可以输入图像并进行分析,然后返回一个带有结果的张量。

    # load up the caffe2 workspacefrom caffe2.python import workspace# choose your model here (use the downloader first)from caffe2.python.models import squeezenet as mynet# helper image processing functionsimport caffe2.python.tutorials.helpers as helpers# load the pre-trained modelinit_net = mynet.init_netpredict_net = mynet.predict_net# you must name it somethingpredict_net.name = "squeezenet_predict"workspace.RunNetOnce(init_net)workspace.CreateNet(predict_net)p = workspace.Predictor(init_net.SerializeToString(), predict_net.SerializeToString())# use whatever image you want (local files or urls)img =「https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/Orange-Whole-%26-Split.jpg/1200px-Orange-Whole-%26-Split.jpg」img = "https://upload.wikimedia.org/wikipedia/commons/a/ac/Pretzel.jpg"img = "https://cdn.pixabay/photo/2015/02/10/21/28/flower-631765_1280.jpg"# average mean to subtract from the imagemean = 128# the size of images that the model was trained withinput_size = 227# use the image helper to load the image and convert it to NCHWimg = helpers.loadToNCHW(img, mean, input_size)# submit the image to net and get a tensor of resultsresults = p.run([img])response = helpers.parseResults(results)# and lookup our result from the listprint response

    该结果是一个概率的张量(一个多维数组)。本质上来看,每一行都表示了目标与神经网络所识别出的内容相匹配的几率。

    注意,当该 workspace 的 Predictor 函数被调用来加载该预训练的模型时,下一步就是调用 .run 并给该函数传递一个图像数组。

    p = workspace.Predictor(init_net, predict_net)results = p.run([img])

    图像预处理

    为了更快的处理速度和传统上的原因,图像在被送入 Caffe2 之前还需要经过两步转换:

    1. 将颜色从 RGB 转换成 BGR

    2. 将图像封装成像素数组,并提供批(batch)中图像的数量(在这案例中是 1)、通道(按 BGR 排列的像素)的数量、高度和宽度,它们分别被称为:NCHW for Number、Channels、Height 和 Width。

    这些图像预处理函数由一个助手模块(helper module)进行处理,所以你可以仅关注特定于 Caffe2 的交互。要更深入地了解图像预处理,请参阅相关 IPython 笔记:https://github/caffe2/caffe2/blob/master/caffe2/python/tutorials/Image_Pre-Processing_Pipeline.ipynb

    获得结果

    当模型完成图像数组的处理时,你会获得一个多维数组,其形式为(1, 1, 1000, 1, 1)

    results = np.asarray(results)print "results shape: ", results.shaperesults shape: (1, 1, 1000, 1, 1)

    看到 results.shape 中的那个 1000 了吗?如果该批中不止一张图片,那么这个数组就会更大,但在中间仍然有 1000 个单元。其存放了该预训练模型中每个类别的概率。所以当你查看结果时,就好像是在说:「计算机,这是一个铍(Beryllium)球的概率是多少?」还是说这是一只毒蜥或其它 998 种该模型被训练用来识别的类别。

    这是一个从 1000 长度的张量中提取出的前 3 个结果,已经过收缩和排序。这些结果按照匹配的概率进行了排序,0.98222 (98%) 是最高的。

    [array([985.0, 0.9822268486022949], dtype=object), array([309.0, 0.011943698860704899], dtype=object), array([946.0, 0.004810151644051075], dtype=object)]

    这是按照概率排列的前三个类别,说明了被检测的目标属于某个类别的概率。你可以使用这个 gist 来查看结果:https://gist.githubusercontent/aaronmarkham/cd3a6b6ac071eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes。每次你运行这个示例时,你都会得到有轻微差别的结果。运行一张有一些雏菊的图片,该模型会得到:

    除了最高概率的正确答案之外,第二和第三分别是蜜蜂和刺棘蓟,鉴于蜜蜂常常和花出现在同一张照片中,所以这样的结果也有点道理。

    输入一张切开的橘子照片,可以得到:橘子(95.3%)、柠檬(4.6%)、草莓(0.006%)。

    Caffe2 的合作与共享

    Caffe2 发展的基石是对深度学习感兴趣并使用过 Caffe 以及其它开源机器学习工具的开发者、研究人员和公司组成的社区。通过在 Caffe2 上的开源以及在 Model Zoo 上的创新协作,我们希望能够推进人工智能科学的进步,并促进各个产业的收益。Caffe2 开源项目的成员能直接在列举所有模型的 Caffe2 Github Wiki 页面做贡献:https://github/caffe2/caffe2/wiki。

    我们也邀请了开发者、研究人员以及任何对创造或精调模型感兴趣的人在 Caffe2 GitHub 的「issue」页面进行分享:https://github/caffe2/caffe2/issues,也可以要求把问题添加到 Zoo 中。此外,Github 的「issue」部分不只是面向 Caffe2 的开发者。如果你创建 Caffe2 模型、改进预训练模型,甚至只是使用预训练模型,你也能在该部分对此资源和 Model Zoo 进行输入、建议与贡献。关于 Caffe2 和 Model Zoo 合作(http://caffe2.ai/docs/zoo.html)的进一步信息请移步 http://caffe2.ai。

    在 GTC 大会上学习 Caffe2

    这部分包含了我们第一篇 Parallel Forall 博客。接下来的一篇博客中我们将会深解如何使用 Caffe2 训练 ImageNet,在文章内我们会展示一些有关分布式训练的激动人心的新基准、在优化 Caffe 2 训练上的小建议以及如何使用 Caffe2 的数据并行模型的细节。

    此外 5 月 8 日 - 11 日在圣何塞市举办的 GTC 大会是每年一度的人工智能与 GPU 开发者大会,机器之心作为受邀媒体将会对此大会的精彩内容进行报道。

    原文链接:https://devblogs.nvidia/parallelforall/caffe2-deep-learning-framework-facebook/

  • ?

    吴恩达更新了!深度学习系列课程第5课放出,全剧终

    羊静蕾

    展开

    大数据文摘作品

    作者:龙牧雪,魏子敏

    在各位同学们推特、朋友圈、Coursera不懈的催更之下,跳水了几个月的吴恩达爸爸终于推出了深度学习系列课程的第五部分。至此,吴恩达的深度学习系列课程完整发布,各位同学可以放心开始上课了。

    Coursera课程链接:

    https://coursera.org/learn/nlp-sequence-models

    图:deeplearning.ai官网的第五课状态终于从coming soon变成了可点击

    图:Coursera官网显示,深度学习第5部分课程1月31日开始

    昨天凌晨,吴恩达通过海外科技媒体medium公布了自己继deeplearning.ai和Landing.ai之外,第三个落地的人工智能创业项目——创投基金AI Fund。(点击查看大数据文摘相关报道《吴恩达创业项目第3弹揭晓:创投基金AI Fund,已募资1.75亿美金》)。

    而在如此激动人心的消息之下,网友们却无心捧场,留言完全是另外一片画风:集体催更课程!

    图:大佬别忙着搞大事情了,先把课程发完啊~~

    文摘菌的文章下的留言区也未能幸免:

    图:从暑假等到寒假了,心疼这位同学一秒钟

    我们等课程到绝望的小伙伴,昨天也发朋友圈说,大佬再不发更我就要去喊大家“写联名信催更”了!

    图:各种表情包出炉

    确实,去年8月份,吴恩达的初创公司deeplearning.ai通过Coursera提供深度学习的最新在线课程,并列出了5个部分课程的上线日期。

    但是,第五部分的课程一拖再拖。作为一个按月收费的课程,大家催更的心情也非常可以理解了。

    图:说好的2017年12月更新,硬是拖到月底,再拖到2018年1月……

    收费模式

    依旧是7天免费试听,之后49美元/月,按月收费(这也是万众催更的一部分原因吧哈哈哈,每拖延一个月,可是要多花49刀啊)。

    如果你只想看视频,可以选择用Audit模式旁听课程,免费,但是不能做作业(编程练习),也不能完成小测验。

    课程内容

    课程需要三周时间完成,共包括约4小时的视频,10小时的练习和小测验。从这个配比来看,练习和测验依旧是课程重头戏。

    第一周:循环神经网络RNN

    RNNGated Recurrent Unit(GRU)LSTM

    第二周:自然语言处理和词嵌入

    Word2Vec

    GloVe

    第三周:序列模型和注意力机制

    Beam Search

    语音识别

    图:Coursera课程内容

    图:网易云课堂上的汉化课程目录

    练习依旧使用在线云平台完成,可以直观看到模型的产出。

    图:Coursera的练习平台

    有了第五课“Sequence Models”里面关于NLP的内容,吴恩达终于把深度学习系列的内容拼全了。从深度学习入门,到计算机视觉,再到自然语言处理,吴恩达的课程无疑为想入行人工智能的小伙伴们提供了极佳的入口。

    学习之前,大数据文摘也总结了一些大牛们写出的前四课的课程笔记给大家,可以点击查看:

    《我从吴恩达深度学习课程中学到的21个心得:加拿大银行首席分析师“学霸“笔记分享》《在等吴恩达深度学习第5课的时候,你可以先看看第4课的笔记》

    总体来看,大数据文摘之前也提到过,吴恩达的这门课程整体来说属于深度学习的基础课程,因为课程定位为AI普及课,内容事实上更适合初学者,如果之前已经学习过coursera上相关课程的同学或者比较专业的选手,就不需要再重新学一遍这门课程了。

    当然,想要系统学习深度学习的同学,我们也推荐一些更加专项的课程给大家:

    多伦多大学三巨头,被誉为“深度学习之父“的Geoffrey Hinton教授在Coursera上的Neural Networks For Machine Learning课程。他的UT实验室在2012年的某医药大赛中如一匹黑马般赢得桂冠(即使整个团队没有一个人懂生物),真正地把深度学习带入了主流媒体的视线。链接:https://coursera.org/learn/neural-networks斯坦福大学CS231n卷积神经网络视觉识别课程(李飞飞授课),大数据文摘授权汉化教程链接:http://study.163/course/introduction/1003223001.htm斯坦福大学CS224d自然语言处理深度学习课程,链接:http://cs224d.stanford.edu/牛津大学与DeepMind合作的自然语言处理深度学习课程,大数据文摘授权汉化教程链接:http://study.163/course/introduction/1004336028.htmMIT 6.S094深度学习与无人车课程。大数据文摘授权汉化教程链接:http://study.163/course/introduction.htm?courseId=1004938039专门致力于为深度学习工程师提供教育资源的fast.ai。链接:http://fast.ai/Tensorflow提供的机器学习教程,分为两篇初学者篇:https://tensorflow.org/get_started/mnist/beginners进阶篇:https://tensorflow.org/get_started/mnist/prosAI圣经级教科书(花书)-蒙特利尔大学教授Yoshua Bengio和他的前学生Ian Goodfellow合著的《Deep Learning》;英文版免费阅读:http://deeplearningbook.org/ 中文版也已上市!

    以上是一些免费课程,如果想要保证听课质量,保证有答疑和练习,我们也推荐网易云课堂一些收费课程:

    人工智能的数学基础。链接:http://mooc.study.163/smartSpec/detail/1001358003.htm机器学习工程师实战课程。链接:http://mooc.study.163/smartSpec/detail/1001358002.htm

    本文图片来源:

    https://coursera.org/learn/nlp-sequence-models/home/welcome

    http://mooc.study.163/course/2001280005#/info

  • ?

    从框架优缺点说起,这是一份TensorFlow入门极简教程

    帕尔纳基

    展开

    随着 TensorFLow 在研究及产品中的应用日益广泛,很多开发者及研究者都希望能深入学习这一深度学习框架。而在昨天机器之心发起的框架投票中,2144 位参与者中有 1441 位都在使用 TensorFlow 框架,是所有框架中使用率最高的。但 TensorFLow 这种静态计算图有一定的学习成本,因此也阻挡了很多初学者入坑。本文介绍了学习 TensorFlow 的系列教程,旨在通过简单的理论与实践帮助初学者一步步掌握 TensorFlow 的编程技巧。这一系列教程分为 6 部分,从为什么选择 TensorFlow 到卷积神经网络的实现,介绍了初学者所需要的技能。机器之心在本文介绍了 PyTorch 和 Caffe 等深度学习框架的优缺点及 TensorFlow 基础,包括静态计算图、张量、TensorBoard 可视化和模型参数的保存等。

    机器之心此前也介绍过很多 TensorFlow 的学习资源,读者可结合这些资源阅读该系列教程:

    学习了!谷歌今日上线基于 TensorFlow 的机器学习速成课程(中文版)机器之心 GitHub 项目:从零开始用 TensorFlow 搭建卷积神经网络教程 | 从零开始:TensorFlow 机器学习模型快速部署指南分布式 TensorFlow 入坑指南:从实例到代码带你玩转多机器深度学习三天速成!香港科技大学 TensorFlow 课件分享TensorFlow 从基础到实战:一步步教你创建交通标志分类神经网络为什么选择 TensorFlow?在本文中,我们将对比当前最流行的深度学习框架(包括 Caffe、Theano、PyTorch、TensorFlow 和 Keras),帮助你为应用选择最合适的框架。

    1. Caffe:第一个主流产品级深度学习库,于 2014 年由 UC Berkeley 启动。

    优点:

    快速支持 GPU漂亮的 Matlab 和 Python 接口缺点:

    不灵活。在 Caffe 中,每个节点被当做一个层,因此如果你想要一种新的层类型,你需要定义完整的前向、后向和梯度更新过程。这些层是网络的构建模块,你需要在无穷无尽的列表中进行选择。(相反,在 TensorFlow 中,每个节点被当做一个张量运算例如矩阵相加、相乘或卷积。你可以轻易地定义一个层作为这些运算的组合。因此 TensorFlow 的构建模块更小巧,允许更灵活的模块化。)需要大量的非必要冗长代码。如果你希望同时支持 CPU 和 GPU,你需要为每一个实现额外的函数。你还需要使用普通的文本编辑器来定义你的模型。真令人头疼!几乎每个人都希望程序化地定义模型,因为这有利于不同组件之间的模块化。有趣的是,Caffe 的主要架构师现在在 TensorFlow 团队工作。专一性。仅定位在计算机视觉(但做得很不错)。不是以 Python 编写!如果你希望引入新的变动,你需要在 C++和 CUDA 上编程(对于更小的变动,你可以使用它的 Python 和 Matlab 接口)。糟糕的文档。安装比较困难!有大量的依赖包。只有少量种类的输入格式,仅有一种输出格式 HDF5(虽然你总是可以使用它的 Python/C++/Matlab 接口来运行,并从中得到输出数据)。不适用于构建循环网络。2. Theano:由蒙特利尔大学研究团队构建。Theano 的顶层构建了数值开源深度库,包括 Keras、Lasagne 和 Blocks。Yoshua Bengio 在 2017 年 9 月 28 日宣布,Theano 的开发将终止。因此实际上 Theano 已死!

    优点:

    计算图的抽象很漂亮(可媲美 TensorFlow)为 CPU 和 GPU 都做了优化很好地适应数值优化任务高级封装(Keras、Lasagne)缺点:

    原始的 Theano 只有比较低级的 APIimport numpy for _ in range(T): h = torch.matmul(W, h) + b大型模型可能需要很长的编译时间不支持多 GPU错误信息可能没有帮助(有时候令人懊恼)3. Pytorch:2017 年 1 月,Facebook 将 Python 版本的 Torch 库(用 Lua 编写)开源。

    优点:

    提供动态计算图(意味着图是在运行时生成的),允许你处理可变长度的输入和输出,例如,在使用 RNN 时非常有用。另一个例子是,在 PyTorch 中,可以使用标准 Python 语法编写 for 循环语句。大量预训练模型大量易于组合的模块化组件易于编写自己的图层类型,易于在 GPU 上运行「Tensorboard」缺少一些关键功能时,「Losswise」可以作为 Pytorch 的替代品缺点:

    正式文档以外的参考资料/资源有限无商业支持4. Tensorflow:由较低级别的符号计算库(如 Theano)与较高级别的网络规范库(如 Blocks 和 Lasagne)组合而成。

    优点:

    由谷歌开发、维护,因此可以保障支持、开发的持续性。巨大、活跃的社区网络训练的低级、高级接口「Tensorboard」是一款强大的可视化套件,旨在跟踪网络拓扑和性能,使调试更加简单。用 Python 编写(尽管某些对性能有重要影响的部分是用 C++实现的),这是一种颇具可读性的开发语言支持多 GPU。因此可以在不同的计算机上自由运行代码,而不必停止或重新启动程序比基于 Theano 的选项更快的模型编译编译时间比 Theano 短TensorFlow 不仅支持深度学习,还有支持强化学习和其他算法的工具。缺点:

    计算图是纯 Python 的,因此速度较慢图构造是静态的,意味着图必须先被「编译」再运行5. Keras:Keras 是一个更高级、对用户最友好的 API,具有可配置的后端,由 Google Brain 团队成员 Francis Chollet 编写和维护。

    优点:

    提供高级 API 来构建深度学习模型,使其易于阅读和使用编写规范的文档大型、活跃的社区位于其他深度学习库(如 Theano 和 Tensorflow,可配置)之上使用面向对象的设计,因此所有内容都被视为对象(如网络层、参数、优化器等)。所有模型参数都可以作为对象属性进行访问。例如:

    model.layers[3].output 将提供模型的第三层model.layers[3].weights 是符号权重张量的列表缺点:

    由于用途非常普遍,所以在性能方面比较欠缺与 Tensorflow 后端配合使用时会出现性能问题(因为并未针对其进行优化),但与 Theano 后端配合使用时效果良好不像 Tensorflow 或 PyTorch 那样灵活TensorFlow 基础TensorFlow 是一种采用数据流图(data flow graphs),用于数值计算的开源软件库。其中 Tensor 代表传递的数据为张量(多维数组),Flow 代表使用计算图进行运算。数据流图用「结点」(nodes)和「边」(edges)组成的有向图来描述数学运算。「结点」一般用来表示施加的数学操作,但也可以表示数据输入的起点和输出的终点,或者是读取/写入持久变量(persistent variable)的终点。边表示结点之间的输入/输出关系。这些数据边可以传送维度可动态调整的多维数据数组,即张量(tensor)。

    计算图与会话学习 Tensorflow 的第一步是了解它的主要特色——「计算图」方法。基本上所有的 Tensorflow 代码都包含两个重要部分:

    1. 创建「计算图」,表示计算的数据流

    2. 运行「会话」,执行图中的运算

    事实上,TensorFlow 将计算的定义与其执行分开。这两个部分将在以下各节中详细说明。在此之前,请记住第一步是导入 Tensorflolibrary!

    import tensorflow as tf这样,Python 就可以访问 TensorFlow 的所有类、方法和符号。使用此命令,TensorFlow 库将在别名「tf」下导入,以便以后我们可以使用它而不必每次键入其全称「TensorFlow」。

  • ?

    深度学习基础篇:如何选择正确的激活函数?

    曹鸿

    展开

    互联网提供了大量的信息,我们只需要一个搜索引擎就可以获取。然而,当大量的信息扑面而来,究竟如何区分相关信息和无关信息呢?

    大脑在得到大量信息时,会努力理解和分类有用信息和不那么有用的信息。而在深度学习中,我们也需要一种类似的机制来分类传入的信息。

    不是所有信息都是有用的,一些只是噪音。激活函数可以帮助神经网络做这种隔离。它激活有用的信息,并抑制无关的数据点。

    激活函数如此重要,那么都有哪些比较热门呢?它们是如何工作的?又适合解决什么问题?本文将为你一一解答。以下是本文目录。

    1.简单介绍神经网络

    2.什么是激活函数?

    3.可以不用激活函数吗?

    4.常用的激活函数类型以及使用方法

    Binary Step函数

    线性函数

    Sigmoid函数

    tanh函数

    ReLU函数

    Leaky ReLU函数

    Softmax函数

    5.如何选择正确的激活函数?

    简单介绍神经网络

    在深入了解激活函数的细节之前,让我们先回顾一下什么是神经网络,以及它是如何运行的。神经网络是一种非常强大的机器学习机制,它基本上模拟人脑的学习方式。

    大脑接受外界的刺激,对输入进行加工,然后产生输出。当任务变得复杂时,多个神经元会形成一个复杂的网络,传递信息。

    人工神经网络试图模仿类似的行为。下图所示的网络就是由相互连接的神经元组成的人工神经网络。

    上图中的黑色圆圈代表神经元。 每个神经元都有权重、偏差和激活函数。 信息进入输入层,神经元通过权重和偏差对输入信息进行线性变换,而非线性变换由激活函数完成。 信息从输入层传输到隐藏层,隐藏层对信息进行处理并将结果发送到输出层。 这被称为前向传播。如果产生的输出偏离预期值呢? 在神经网络中,我们将根据误差更新神经元的权重和偏差。 这个过程被称为反向传播。 一旦所有训练数据经过了这一过程,则最终的权重和偏差就被用于测试。

    什么是激活函数?

    激活函数是人工神经网络的一个极其重要的特征。它决定一个神经元是否应该被激活,激活代表神经元接收的信息与给定的信息有关。

    激活函数对输入信息进行非线性变换。 然后将变换后的输出信息作为输入信息传给下一层神经元。

    可以不用激活函数吗?

    如果激活函数增加了许多复杂性,我们可以不用激活函数吗?

    当然不行!当我们不用激活函数时,权重和偏差只会进行线性变换。线性方程很简单,但解决复杂问题的能力有限。没有激活函数的神经网络实质上只是一个线性回归模型。激活函数对输入进行非线性变换,使其能够学习和执行更复杂的任务。我们希望我们的神经网络能够处理复杂任务,如语言翻译和图像分类等。线性变换永远无法执行这样的任务。

    激活函数使反向传播成为可能,因为激活函数的误差梯度可以用来调整权重和偏差。如果没有可微的非线性函数,这就不可能实现。

    常用的激活函数类型以及使用方法

    Binary Step函数

    当我们有一个激活函数时,首先联想到的是一个自带阈值的分类器,用于激活神经元。下图中,如果y值高于给定的阈值,则激活神经元,否则禁用。

    f(x) = 1, x>=0

    Binary Step函数非常简单,可以在创建二进制分类器时使用它。当我们只需要对单个类说“是”或“不是”时,Step函数是最好的选择,因为它要么激活神经元要么把它设为零。

    函数的理论性比实用性强,在大多数情况下,我们需要将数据分入多个类而不仅仅放在一类中。此时,Step函数就有点不好用了。

    此外,step函数的梯度为零,这使得step函数不能用于反向传播过程中。

    f '(x) = 0, for all x

    线性函数

    我们看到了step函数的问题,梯度为零,在反向传播过程中不可能更新权重和偏差。此时,我们可以用线性函数来代替简单的step函数。函数表达式:

    f(x)=ax

    上图中假设a为4。这时激活与输入成正比,输入的x值将被转换为ax。线性函数可用于不同的神经元,也可以激活多个神经元。当我们有多个类时,可以选择f(x)值最大的类。但线性函数仍然存在一个问题。让我们看看这个函数的导数。

    f'(x) = a

    线性函数的导数是常数,也就是说它不依赖于输入值x

    这意味着每次我们做反向传播时,梯度都是一样的。这是一个大问题,我们并没有真正减少误差。不仅如此,假设我们正在做一项复杂任务,需要使用多层神经网络。然而如果每一层都使用线性变换,不管我们有多少层,最终输出的还是输入的线性变换。因此,线性函数只适用于容易解释的简单任务。

    Sigmoid函数

    Sigmoid函数曾被广泛应用,但由于其自身的一些缺陷,现在已经很少用了。Sigmoid函数定义如下:

    f(x)=1/(1+e^-x)

    让我们来看看这个函数。

    这是一个平滑函数,并且具有连续性和可微性。与线性函数相比,它的最大优点就是非线性。这意味着多个神经元使用S(Sigmoid简称)形函数作为激活函数时,输出也是非线性的。我们来看看曲线的形状。Y轴范围0-1,x轴在-3到3之间的梯度非常高,但在其他区域形状很平坦。这有什么用吗?

    这意味着在[-3,3]这个范围内,x的少量变化也将导致y值的大幅度变化。因此,函数本质上试图将y值推向极值。 当我们尝试将值分类到特定的类时,使用Sigmoid函数非常理想。

    让我们来看一下Sigmoid函数的梯度。

    它是平滑的,依赖于x值,这意味着在反向传播过程中,我们可以使用这个函数。误差可以被反向传播,权重也可以相应地更新。

    即使在今天,sigmoid函数也被广泛使用,但我们仍然需要解决一些问题。正如之前所看到的,这个函数在[-3,3]之外是相当平坦的。这意味着一旦x值不在[-3,3]内,梯度就变得很小,接近于零,而网络就得不到真正的学习。

    sigmoid函数的另一个问题是,y轴取值范围[0,1]。这个函数在原点周围不对称,得到的值都是正的。我们不希望下一个神经元得到的值在任何时候都是正值,不过可以通过缩放sigmoid函数来解决这个问题,而这需要在tanh函数中发生。

    tanh函数

    tanh函数与Sigmoid函数非常相似。它实际上只是Sigmoid函数的一个放大版本。

    tanh(x)=2sigmoid(2x)-1

    还可以直接表示为:

    tanh(x)=2/(1+e^(-2x)) -1

    Tanh函数与sigmoid函数相似,但原点对称。它的范围从- 1到1。

    它基本上解决了所有值符号相同的问题,而其他属性都与sigmoid函数相同。函数具有连续性和可微性。你可以看到函数是非线性的,所以我们可以很容易地将误差进行反向传播。

    让我们看一下tanh函数的梯度。

    与Sigmoid函数相比,tanh函数的梯度更陡。 使用sigmoid函数还是tanh函数取决于问题陈述中对梯度的要求。 但是tanh函数出现了Sigmoid函数类似的问题,梯度渐趋平坦,并且值非常低。

    ReLU函数

    ReLU是近几年非常受欢迎的激活函数。其定义为:

    f(x)=max(0,x)

    以下是图形表示:

    ReLU是如今设计神经网络时使用最广泛的激活函数。首先,ReLU函数是非线性的,这意味着我们可以很容易地反向传播误差,并激活多个神经元。

    ReLU函数优于其他激活函数的一大优点是它不会同时激活所有的神经元。这是什么意思?如果输入值是负的,ReLU函数会转换为0,而神经元不被激活。这意味着,在一段时间内,只有少量的神经元被激活,神经网络的这种稀疏性使其变得高效且易于计算。

    我们来看看ReLU函数的梯度。

    ReLU函数也存在着梯度为零的问题。看上图,x<0时,梯度是零,这意味着在反向传播过程中,权重没有得到更新。这就会产生死神经元,而这些神经元永远不会被激活。好在当我们遇到问题时,我们总能找到解决方案。

    Leaky ReLU函数

    Leaky ReLU函数只是一个ReLU函数的改良版本。我们看到,在ReLU函数中,x < 0时梯度为0,这使得该区域的神经元死亡。为了解决这个问题, Leaky ReLU出现了。这是它的定义:

    f(x)= ax, x<0

    = x, x>=0

    我们所做的,只是用一个非水平线简单地替换了水平线。这里a是一个很小的值,如0.01。见下图。

    替换水平线的主要优点是去除零梯度。在这种情况下,上图左边的梯度是非零的,所以该区域的神经元不会成为死神经元。梯度图如下。

    与Leaky ReLU函数类似的,还有PReLU函数,它的定义与Leaky ReLU相似。

    f(x)= ax, x<0

    = x, x>=0

    然而, 在PReLU函数中,a也是可训练的函数。神经网络还会学习a的价值,以获得更快更好的收敛。 当Leaky ReLU函数仍然无法解决死神经元问题并且相关信息没有成功传递到下一层时,可以考虑使用PReLU函数。

    Softmax函数

    softmax函数也是一种sigmoid函数,但它在处理分类问题时很方便。sigmoid函数只能处理两个类。当我们想要处理多个类时,该怎么办呢?只对单类进行“是”或“不是”的分类方式将不会有任何帮助。softmax函数将压缩每个类在0到1之间,并除以输出总和。它实际上可以表示某个类的输入概率。其定义为:

    比如,我们输入[1.2,0.9,0.75],当应用softmax函数时,得到[0.42,0.31,0.27]。现在可以用这些值来表示每个类的概率。

    softmax函数最好在分类器的输出层使用。

    如何选择正确的激活函数?

    现在我们已经了解了这么多的激活函数,接下来就需要分析在哪种情况下应该使用哪种激活函数了。激活函数好或坏,不能凭感觉定论。然而,根据问题的性质,我们可以为神经网络更快更方便地收敛作出更好的选择。

    用于分类器时,Sigmoid函数及其组合通常效果更好。

    由于梯度消失问题,有时要避免使用sigmoid和tanh函数。

    ReLU函数是一个通用的激活函数,目前在大多数情况下使用。

    如果神经网络中出现死神经元,那么PReLU函数就是最好的选择。

    请记住,ReLU函数只能在隐藏层中使用。

    一点经验:你可以从ReLU函数开始,如果ReLU函数没有提供最优结果,再尝试其他激活函数。

    —完—

    来源:Analytics Vidhya

    作者:Dishashree Gupta

    智能观 编译

  • ?

    人工智能3分钟入门基础,机器学习如何快速上手?

    歌舒茈

    展开

    什么是人工智能(AI)?

    你在想Chappie,终结者和露西吗? 有意识的,自我意识到的机器人比你想象的更接近现实。 开发等于或超过人类智能的计算机系统是人工智能的关键。 人工智能(AI)是计算机科学的研究,专注于开发展示人类智能的软件或机器。 一个简单的定义,对吗?

    显然,它还有很多。 AI是一个广泛的主题,从简单的计算器到自动转向技术,再到可能从根本上改变未来的东西。

    AI的目标和应用

    人工智能的主要目标包括演绎和推理,知识表示,规划,自然语言处理(NLP),学习,感知以及操纵和移动物体的能力。 人工智能研究的长期目标包括实现创造力,社会智能和一般(人类水平)智力。

    人工智能严重影响了我们可能无法识别的不同领域。 Ray Kurzweil说:“成千上万的人工智能应用程序深深嵌入到每个行业的基础设施中。”人工智能的创始人之一约翰麦卡锡曾说过“一旦它起作用,就再也没有人称它为人工智能”。

    从广义上讲,AI分为以下几类:

    AI的类型

    虽然有各种形式的人工智能,因为它是一个广泛的概念,我们可以根据人工智能的能力将其分为以下三类:

    弱AI(也称为窄AI)专注于一项任务。在AI较弱的情况下,没有自我意识或真正的智慧。

    iOS Siri是弱AI的一个很好的例子,结合了几种弱AI技术来运行。它可以为用户做很多事情,当你尝试与虚拟助手进行对话时,你会看到它的确如此“缩小”。

    强AI(也称为True AI)是一种与人脑一样聪明的计算机。这种AI将能够执行人类可以完成的所有任务。这个领域有很多研究,但我们还有很多工作要做。你应该想象Matrix或我,机器人在这里。

    如果强大的AI给你留下深刻印象,人工超级智能会让你大吃一惊。领先的AI思想家尼克博斯特罗姆(Nick Bostrom)将其定义为“比几乎所有领域中最优秀的人类智慧更聪明的智力,包括科学创造力,一般智慧和社交技巧。”

    人工超级智能是许多着名科学家和技术专家,包括斯蒂芬霍金和埃隆马斯克,对人类灭绝可能性提出质疑的原因。

    怎么开始?

    您需要做的第一件事是学习编程语言。 虽然你可以从很多语言开始,但许多人更喜欢Python,因为它的库更适合机器学习。

    以下是Python的一些很好的资源:

    CodeAcademy

    Learn Python the hard way

    Coursera Python

    Introduction to Computer science

    Bots简介

    BOT是弱AI的最基本的例子,可以代表您执行自动化任务。 Chatbots是最早被称为“机器人”的自动程序之一。你的聊天机器人需要AI和ML。 像谷歌这样的搜索引擎使用的网络抓取工具是复杂而先进的BOT的完美范例。

    在开始编程机器人之前,您应该学习以下内容,以使您的生活更轻松。

    xpath - 这将帮助您检查和定位HTML并根据您在那里看到的构建机器人。

    regex - 这将帮助您通过清理或定位(或两者)与您的逻辑相关的部分来处理您为机器人提供的数据。

    REST - 这非常重要,因为您最终将使用API。 您可以使用请求执行此操作。

    如何建立你的第一个Bot?

    您还可以从使用能够构建最终用户应用程序的API和工具开始。 这可以帮助您实际构建一些东西,而不必过多担心理论。 您可以使用的一些API是:

    Google Cloud Prediction API Documentation

    DiffBot

    Machine Learning for Language Toolkit

    Scrapy

    Wolfram Alpha API

    这里列出了一些BOT问题,供您在尝试最终挑战之前进行练习和尝试。

    Tic Tac Toe

    Hex

    Dots & Boxes

    现在怎么办?

    一旦您对首选的编程语言有了全面的了解,并且对基础知识进行了充分的练习,您就应该开始了解有关机器学习的更多信息。 在Python中,开始学习Scikit-learn,NLTK,SciPy,PyBrain和Numpy库,这些库在编写机器学习算法时非常有用。您还需要了解高级数学。

    以下是供您学习和练习的资源列表:

    A Visual Introduction to Machine Learning

    Machine Learning (By Andrew Ng)

    Machine Learning Lectures (Tom Mitchell)

    Artificial Intelligence (edX) (Specially for practice exercise in Python)

    Intro to Statistics

    Intro to Artificial Intelligence (Includes Logic and Robotics)

    Artificial Intelligence

    您还应该参加互联网上不同地方的各种AI和BOT编程竞赛:

    Kaggle

    Coding Game

    HackerEarth

    Robocup

    拓展阅读:零基础的新手,如何快速入门机器学习和人工智能?

    如何快速入门?如何掌握机器学习与人工智能的基础知识。给大家推荐几款权威的论文和机器学习资料。

    UFLDL:非常好的DL基础教程,由Andrew Ng编写。有很详尽的推导,有翻译,且翻译质量很高;

    Deep learning (paper):2015年Nature上的论文,由三位深度学习界的大牛所写,读完全篇论文,给人高屋建瓴,一览众山小的感觉,强烈推荐。如果只能读一篇论文了解深度学习,我推荐此篇。这篇论文有同名的中文翻译;

    Neural networks and deep learning:这本书的作者非常擅长以浅显的语言表达深刻的道理,虽然没有翻译,但是阅读并不困难;

    Recurrent Neural Networks:结合一个实际案例告诉你RNN是什么,整篇教程学完以后,会让你对RNN如何产生作用的有很清晰的认识,而这个效果,甚至是读几篇相关论文所没有的。

    Neural Networks for Machine Learning:大牛的视角就是与众不同,看看Hinton对神经网络是怎么看的,往往会让你有种“原来如此”的感悟。其实看这门课程也等同于读论文,因为几乎每节课的参考资料里都有论文需要你读;

    CS231n:Convolutional Neural Networks for Visual Recognition:最新的知识,还有详细的作业。国内应该有团队对字幕进行了翻译,网上应该可以找到下载;

    PRML:作为一门经典的机器学习书籍,是很有阅读必要的,会让你对机器学习拥有一个别样的观察视角。

    如果你想要深入学习和了解一门学科,就要遵循一万小时定律,也就是说,只有当你在某一学科或领域付出长时间(一万小时以上)的学习和实践,才有可能达到了然的状态。这一点适应于人工智能,也适用于学习任何其他的学科。

    人工智能/机器学习实践操作:

    实践出真知,看了那么多论文学习人工智能和机器学习,那么怎么去检验自己的动手和动脑能力呢?

    谷歌的AIY 项目(AIY Projects)全称为 Artificial Intelligence Yourself,意为动手创造你的人工智能。该项目由 Google 于 2017 年启动,目标是让每个 Maker(创客)都可以 DIY 自己的 AI 人工智能产品。Google 先后在 5 月、12 月份分别推出该项目代表的两组套件 Voice Kit 和 Vision Kit。

    Voice Kit 是 Google 首个推出的 DIY 人工智能产品。它可借助 Google Assistant SDK 和 Cloud Speech API,将树莓派转换为语音数字助理。用户可在此基础上创建虚拟语音助手,为自己的项目添加语音交互功能。

    Vision Kit 则是 Google 推出的第二弹 DIY 人工产品。它是一套简单的计算机视觉系统,可运行 3 种基于 TensorFlow 的类神经网路模型应用程序。

    Voice Kit使用Google智能助理为您的Raspberry Pi添加语音控制,而Vision Kit则打开图像识别并向创客们引入了神经网络。它可以检测千中常见物体,但也可以对您的脸部表情进行检测,并显示出您的情绪,比如愤怒、开心等等。

    语音识别、图像检测、机器翻译、风格迁移等技术已经在我们的实际生活中开始得到了应用,但机器学习的发展仍还在继续,甚至被认为有可能彻底改变人类文明的发展方向乃至人类自身。

  • ?

    深度学习入门必看---吴恩达深度学习课程

    贺灵煌

    展开
    吴恩达

    今天分享的是吴恩达的深度学习课程。吴恩达是人工智能领域的大牛,著作颇丰,其推出的机器学习课程在学生之中反响强烈,深受中国学生的推崇。在众多网友,学生,工作者的呼吁下,2017年8月,吴恩达推出了自己的深度学习课程,由于长时间拖更,经常被网友吐槽,最终在今年的时候全部更新完毕。考虑到中国学生对课程的喜爱,吴恩达和网易云课程合作,提供带有中文字幕的学习视频。

    吴恩达

    课程简介:

    课程总共分为5个部分:卷积网络和深度学习,改善深层神经网络,结构化机器学习项目,卷积神经网络,序列模型。在五门课程中,将学习深度学习的基础知识,了解如何构建神经网络,并学习如何实践机器学习项目,学习卷积网络,RNN,LSTM,Adam,Dropout,BatchNorm,Xavier/He初始化等等。同时可以了解医疗,自动驾驶,手语阅读,音乐创作和自然语言处理的案例研究,掌握深度学习的基础理论,还会看到它在工业中的应用。课程的内容都将在Python和TensorFlow的练习中所实现。最后,课程末尾都有学术大牛的经验分享,可以听到许多深度学习的高层领导,他们将与你分享他们的个人故事,并为你提供职业建议。

    课程内容:

    01. 神经网络和深度学习

    神经网络概论 主要介绍:神经网络的概念、深度学习兴起的原因、课程内容等;神经网络基础 主要介绍:logistic回归、损失函数、梯度下降、计算向量化、代价函数等;编程作业:使用Numpy的基础Python、logistic回归浅层神经网络 主要介绍:神经网络、激活函数、梯度下降法、反向传播、随机初始化等;编程作业:使用浅层神经网络实现平面数据分类深层神经网络 主要介绍:深度神经网络、DNN的前向和反向传播、参数和超参数等;编程作业:构建DNN、DNN用于图片分类02. 改善深层神经网络:超参数调试、正则化以及优化

    深度学习的实践方面 主要介绍:训练测试集划分、偏差和方差、正则化、Dropout、输入归一化、梯度消失与梯度爆炸、权重初始化、梯度检验等;编程作业:初始化、正则化、梯度检验优化算法 主要介绍:Mini-batch梯度下降、指数加权平均、Momentum梯度下降、RMSprop、Adam优化算法、衰减学习率、局部最优等;编程作业:多种优化算法超参数调试和Batch Norm及框架 主要介绍:超参数的调试、Batch Normalization、Softmax、TensorFlow程序框架等;编程作业:TensorFlow简单教程03. 结构化机器学习项目

    机器学习策略(1) 主要介绍:正交化、单一数字评估指标、训练/开发/测试集、偏差和方差、改善模型的表现等;机器学习策略(2) 主要介绍:误差分析、错误样本清除、数据分布不匹配问题、迁移学习、多任务学习、端到端的深度学习等;04. 卷积神经网络

    卷积神经网络基础 主要介绍:计算机视觉、边缘检测、卷积神经网络、Padding、卷积、池化等;编程作业:构建卷积神经网络、手势识别应用卷积神经网络实例模型 主要介绍:AlexNet、LeNet、VGG、ResNet、Inception Network、1乘1卷积、迁移学习、数据扩充等;编程作业:Keras教程-the Happy House、Residual Networks目标检测 主要介绍:目标定位、目标检测、Bounding Box预测、交并比、非最大值抑制NMS、Anchor box、YOLO算法、候选区域region proposals等;编程作业:自动驾驶-汽车检测特殊应用:人脸识别和神经风格迁移 主要介绍:人脸识别、one-shot学习、Siamese网络、Triplet损失、风格迁移、内容损失、风格损失、1D-3D卷积等;编程作业:人脸识别-Happy House、神经风格迁移-深度学习和艺术05. 序列模型

    循环神经网络 主要介绍:循环神经网络、不同类型的RNN、语言模型、新序列采样、RNN梯度消失、GRU、LSTM、双向RNN、深层RNNs等;编程作业:构建RNN、字母级的语言模型-Dinosaurus land、用LSTM即兴创作Jazz自然语言处理和词嵌入 主要介绍:词汇表征、Word Embedding、嵌入矩阵、Word2Vec、负采样、GloVe词向量、情感分类、词嵌入消除偏见等;编程作业:词向量运算、Emojify序列模型和注意力机制 主要介绍:序列到序列模型、集束搜索(Beam search)、集束搜索误差分析、Bleu得分、注意力模型、注意力权重、语音识别、触发字检测等;编程作业:机器翻译、触发字检测

    相关搜索

    • 神经网络算法
    • 机器学习
    • 人工神经网络
    • 神经网络原理
    • bp神经网络
    • 人工智能神经网络
  • ?

    想要自学深度学习?不用GPU,浏览器就够了

    烟雨茫

    展开

    机器之心整理

    参与:刘晓坤、思源

    今天要介绍一个近期开源的自学深度学习 GitHub 项目,作者为每种具体算法提供了 Jupyter notebook 实现,可以轻易地在 Google Colab 上运行(免费提供云端 GPU 或 TPU)。所以想自学深度学习,不需要价格几千美元的 GPU,有一个 Chrome 浏览器就够了。

    项目地址:https://github/GokuMohandas/practicalAI

    该项目作者是 Goku Mohandas,是一名硅谷的 AI 研究员,曾就职于苹果公司,并在 O'Reilly Media 从事过教学工作。他开发的这个 GitHub 项目——PracticalAI 目前已经有大约 2500 的收藏量,覆盖了 Jupyter Notebook 和 Google Colab 的使用教程、Python 编程基础、深度学习基础(PyTorch 框架和 CNN、RNN 等算法),以及更高层次的算法和 AI 研究课题。

    作者指出,他开发这个教程的目的是让人们能学习到目标导向、产品导向的机器学习思维,而不会停留在课堂。

    课程简介

    下表概括了整个项目的课程大纲,分成 4 个主要部分:基础、深度学习、高级深度学习算法和 AI 研究课题(蓝色是已经写好 notebook 的部分,可以直接链接到 Colab 页面,黑色是尚未写的部分)。

    基础:包括 Jupyter Notebooks 简介、Python 编程基础和基础机器学习算法。作者会介绍 Jupyter Notebooks 的单元格编程界面和操作、执行单元格的方法;然后是 Python 以及两个重要的 Python 库——NumPy、Pandas 的入门;最后是线性回归、逻辑回归等基础 ML 算法的讲解,这些算法覆盖面很窄,不包含 SVM、朴素贝叶斯、隐马尔科夫模型等更复杂的算法。但该项目并不是为经典机器学习而设计的课程,读者可以在学习这些简单算法的过程中了解到 AI 算法的训练、数据集、评估、推理、正则化等基本概念,然后进入深度学习课程。

    深度学习:包括 PyTorch 框架介绍和多种经典的深度学习算法。PyTorch 的介绍主要涉及张量计算和梯度计算。深度学习算法涉及多层感知机、CNN、RNN、词嵌入等,作者还写了两个较高层面的主题,分别是数据和模型的关系,以及目标导向的机器学习,让读者对如何利用这些算法有个基本理解。每种算法针对的任务都比较单一,也没有涉及生成模型,但通过深入的理解单个模型应用的每一个过程,可以让你在进阶学习时不被细节拖后腿。

    高级深度学习算法:包括高级 RNN 模型、残差网络、自编码器、生成对抗网络、空间变换网络等。这些算法的模型架构设计建立在基础的深度网络之上。作者目前只写了高级 RNN 模型,涉及条件 RNN、编码器-解码器架构以及注意力机制等,其它模型还需等作者更新。或许作者还可以考虑加上基于流的模型、图神经网络等高级算法。

    AI 研究课题:包括计算机视觉、时间序列分析、主题建模、推荐系统、预训练语言模型、多任务学习、小样本学习、强化学习等。这些课题不对应具体的模型架构,但会随当前研究现状有所偏好,如计算机视觉领域的主要模型架构就是 CNN 和编码器-解码器,作者目前只写了计算机视觉部分。要把握这些课题,需要读者对要解决的问题本身有很好的理解,从而不限于方法层面的视角。或许作者还可以考虑加上 AutoML、自监督学习、迁移学习、AI 游戏等课题。

    可以跑的教程

    这一套实践教程都能直接在 Colab 上运行,因此结合解释与代码,我们能更好地入门机器学习。那么小白是不是也能看得懂这个教程?我们可以从最基础的 Python 和 NumPy 出发,看看它们都介绍了些什么,纯小白是不是能在较短的篇幅里了解最核心的思想与技术。

    在 Pyhon 实践中,作者给出了一个非常精简的教程,其仅涉及 Python 最核心的模块,包括变量、数据结构、基本语句与结构等。即使没有什么基础的小白,了解这些核心模块后至少能看懂大部分代码,剩下困难的只需要在遇到时谷歌一下就行了。

    首先对于最基础的变量,它们就像函数中的自变量一样传递不同的值。如下所示,Python 中的变量可以传递整数、浮点数、字符串和布尔值,它们可以用于不同的运算:

    而对于 Python 中主要的数据结构,即组织整数、浮点数、字符串和布尔值的结构,主要可以分为列表、元组和字典。其中列表是最常见的数据结构,我们可以想象为一个表格中的一行,表格每一个单元格都是列表中的一个元素,这样的元素不论存放数值、列表还是字典都没问题,它相当于一个容器。

    以下展示了如何取列表中存储的元素,第一个表示取列表中所有元素,第二个表示从第三个元素开始取后面所有的元素:

    元组和列表非常类似,只不过元组里面的元素不能修改。最后是字典,字典中每一个元素都由 Key 和 Value 组成,即一个键值对。在字典中,我们需要使用 Key 才能取到对应的 Value。

    如下所示字典的构建与索引,它会通过「name」这一个键取对应的值 Goku:

    随后对于基础语句,例如条件和循环语句,该教程也给出了很直观的解释。最后,如果我们利用数据结构组织变量、利用基础语句组织数据结构,再用函数或类等程序逻辑组织基础语句,那么我们就能得到完整的程序。

    如下所示为基础的类,它能将函数和变量统一在一起,并构建完整的流程。在类中,赋值的变量可以称为属性,而函数则称为方法。下图构建了一个 Pets 类,当我们使用狗或猫实例化这个类时,就能直接调用 change_name 方法以实现改名。入门者跑一跑这几段代码就能知道类的大概作用了:

    当然除了这些最基础的 Pyhon 语句,机器学习另外一个很重要的基础就是数值计算。我们需要计算大量的数据以获得最终的分析结果,这就少不了 NumPy,可以说入门机器学习第一个学习的包就是 NumPy。

    我们可以使用 NumPy 实现大多数机器学习算法,现在很多深度学习框架都继承了 NumPy 的核心概念或数据结构等。了解了它,学习 DL 框架就没什么阻碍了。在 NumPy 中,最重要的是多维数组这个数据结构,它能以向量、矩阵或高阶张量的形式组织大量的数值,并实现高效的运算。此外,NumPy 还有很多针对多维数组所构建的运算,例如索引、矩阵乘法、矩阵转置或广播机制等。

    入门读者首先需要了解多维数组,尤其是矩阵的概念,当然要是数学上不了解矩阵,NumPy 也就爱莫能助了。以下代码构建了一个 3×3 矩阵,并输出它的元素类型、矩阵维度形状和矩阵大小等。所有机器学习中的数据都是以多为数组存储的,它们的计算流也都以数组为媒介,所以先搞定最基础的 NumPy 数组吧!

    关于理论基础的学习,只跑这些算法肯定是不够的,小编还是建议结合经典教材和课程视频一起学习。但先在浏览器上跑一跑,或许能让你更快体验到 AI 的魅力所在,并带来学习的动力。学习这个课程并不能让你了解深度学习的现状,但可以快速上手具体的项目,这或许正是作者说的「目标导向、产品导向」的意义所在。

  • ?

    教程 | 基础入门:深度学习矩阵运算的概念和代码实现

    邬奎

    展开

    本文由机器之心编辑,“机器之心”专注生产人工智能专业性内容,适合开发者和从业者阅读参考。点击右上角即刻关注。

    本文从向量的概念与运算扩展到矩阵运算的概念与代码实现,对机器学习或者是深度学习的入门者提供最基础,也是最实用的教程指导,为以后的机器学习模型开发打下基础。

    在我们学习机器学习时,常常遇到需要使用矩阵提高计算效率的时候。如在使用批量梯度下降迭代求最优解时,正规方程会采用更简洁的矩阵形式提供权重的解析解法。而如果不了解矩阵的运算法则及意义,甚至我们都很难去理解一些如矩阵因子分解法和反向传播算法之类的基本概念。同时由于特征和权重都以向量储存,那如果我们不了解矩阵运算,代码实现将变得十分艰难。

    什么是线性代数?

    在深度学习中,线性代数是一个强大的数学工具箱,它提供同时计算多维数组的方法。线性代数不仅会提供如同向量和矩阵那样的结构来储存这些数字,还会提供矩阵的加、减、乘、除和其他运算规则。

    线性代数为什么如此实用?

    线性代数将复杂问题转变为简单、直观和高效的计算问题。下面的例子可以表明实现同样的功能,线性代数的代码表达是如何的简洁与美观。

    # Multiply two arrays x = [1,2,3]y = [2,3,4]product = []for i in range(len(x)): product.append(x[i]*y[i])

    # Linear algebra versionx = numpy.array([1,2,3])y = numpy.array([2,3,4])x * y

    线性代数怎样应用到深度学习?

    神经网络将权重储存在矩阵当中。而线性代数特别是在 GPU 上,可以对矩阵进行简单迅捷的计算处理。实际上,GPU 的设计就是源于向量和矩阵计算处理的基本概念。这和图像由像素块阵列构成,视频游戏使用巨量、连续展开的矩阵生成引人注目的游戏体验是一样的。GPU 会并行地操作整个矩阵里元素,而不是一个接一个地处理

    向量

    向量由数字或其它项组成的一维阵列。在几何学中,向量储存了空间中一个点潜在的改变方向。向量 [3,-2] 也就代表着原点向(3,-2)这一点运动的趋向。若向量所具有的维度超过一维,那么就称之为矩阵

    向量的符号表示

    有很多符号方式都能表示向量,下面是在本篇文章中你可能会遇到的:

    几何学中的向量

    向量一般表征着一个点的运动,一个向量同时储存其潜在变化的方向和大小。如下图所示,在平面空间中画出了向量 [-2,5],因为向量只储存了方向和大小,那么平移并不会改变向量的值,所以所有平移的向量(方向和大小不变)都是相等的。

    标量运算

    标量运算即为向量和数字间的运算。向量与数的运算就是向量内每一个元素与这一个数进行相应的运算。如下图的一个标量运算:

    向量间运算

    在向量间的运算中,对应位置的值可以组合而产生一个新向量。第一个向量的第 i 个值只与第二个向量的第 i 个值相匹配。这也就意味着向量之间的维度必须相等才能进行运算。下图表明向量之间的加减法是对应元素之间的加减,代码表明了向量之间的加减和除法。

    y = np.array([1,2,3])x = np.array([2,3,4])y + x = [3, 5, 7]y - x = [-1, -1, -1]y / x = [.5, .67, .75]

    在 numpy 中,如果向量是一维的,那么他就能看作是一个标量,与其他多维向量的运算就相当于一个数

    向量乘法

    向量的乘法有两种类型:一种是点积,另一种是 Hadamard 积。

    点积

    两个向量的点积结果是一个标量。向量和矩阵(矩阵乘法)的点积在深度学习中是最重要的运算之一

    Hadamard 积

    Hadamard 积是元素之间的乘积,并得出一个向量。从下图可以看出来 Hadamard 积就是将向量对应元素相乘积。

    y = np.array([1,2,3])x = np.array([2,3,4])y * x = [2, 6, 12]

    向量场

    向量场展示了如果我们运用一个向量函数(如向量加法或乘法等),其中任意点(x,y)会有什么样的运动倾向。在空间中给定一点,向量场就是我们使用的向量运算在该点的方向和大小。

    该向量场很有意思,因为根据不同的出发点,其都会有不同的方向。出现这种情况是因为在该向量场中,向量背后储存的项不是一个 5 或 2 那样的实数,它是 2x 或 x^2 那样的变量。对于图表中的每一个点,我们将坐标轴变换为 2x 或 x^2,然后将起始点画一个箭头到新的坐标点,这样就制成了上图。向量场对机器学习算法(如梯度下降算法)的可视化十分重要。

    矩阵

    矩阵就是一个由数字或其它项组成的表格,只不过是该表格会有特定的加法、减法和乘法规则

    矩阵的阶

    我们描述矩阵的维度由阶来表达:即行数×列数(如 3×2)阶矩阵。

    a = np.array([

    [1,2,3],[4,5,6]])a.shape == (2,3)

    b = np.array([[1,2,3]])b.shape == (1,3)

    矩阵的标量运算

    矩阵的标量运算和向量的标量运算是一样的。可以简单地将标量和矩阵中的每一个元素做运算处理(如加、减、乘、除等)。

    a = np.array([[1,2],[3,4]])a + 1[[2,3],[4,5]]

    矩阵间的运算

    为了能进行加减运算,两个矩阵的阶必须相等。然后我们可以对两个矩阵相应的元素进行运算处理。如下图就是两阶方阵的加法。

    a = np.array([[1,2],[3,4]])b = np.array([[1,2],[3,4]])

    a + b[[2, 4],[6, 8]]

    a — b[[0, 0],[0, 0]]

    Numpy broadcasting

    在 Numpy 中,矩阵之间运算所需要的阶相等可以通过一个称之为 broadcasting 的机制变得不那么严格。如果两个矩阵相应的阶(行数×列数)满足下面两个要求,那么它们就是可以进行运算的:

    两个矩阵的阶相等

    矩阵的阶有一个维度是 1

    a = np.array([[1],[2]])b = np.array([[3,4],[5,6]])c = np.array([[1,2]])

    # Same no. of rows# Different no. of columns# but a has one column so this worksa * b[[ 3, 4],[10, 12]]

    # Same no. of columns# Different no. of rows# but c has one row so this worksb * c[[ 3, 8],[5, 12]]

    # Different no. of columns# Different no. of rows# but both a and c meet the# size 1 requirement rulea + c[[2, 3],[3, 4]]

    而在高维(三维或四维等)矩阵的情况下,矩阵间运算更有意思,不过在深度学习里并不常见。

    矩阵 Hadamard 乘积

    Hadamard 乘积同样是矩阵间的运算,即两个矩阵间相同位置的元素相互乘积。

    a = np.array([[2,3],[2,3]])b = np.array([[3,4],[5,6]])

    # Uses python's multiply operatora * b[[ 6, 12],[10, 18]]

    在 numpy 中,矩阵和向量的 Hadamard 乘积只需要两个矩阵满足 broadcasting 机制的要求就行。

    矩阵转置

    神经网络在处理不同大小的权重或输入矩阵时,经常出现矩阵的阶不符合矩阵乘法的要求。矩阵的转置通过将矩阵旋转一下以满足矩阵乘法所需要的维度要求。下面,我们可以通过两步完成矩阵的转置。

    1. 旋转矩阵 90 度

    2. 将每一行的元素都反向写一遍

    以下我们将矩阵 M 转置为矩阵 T

    a = np.array([ [1, 2], [3, 4]])

    a.T[[1, 3],[2, 4]]

    矩阵乘法

    矩阵乘法是由一组乘法法则组成,他们共同作用以乘得一个新矩阵。

    规则

    并不是所有矩阵都能进行矩阵乘法运算的,如果两个矩阵能相乘,那么它需要满足以下条件:

    1. 第一个矩阵列的数量必须等于第二个矩阵行的数量

    2. m×n 阶矩阵左乘 n×k 阶矩阵的结果是 m×k 阶矩阵。新得出来矩阵就等于第一个矩阵的行数×第二矩阵的列数。

    步骤

    矩阵乘法的步骤和向量点积的过程是相似的,它们都是由对应位置的元素进行乘积并相加而得出。第一个矩阵每一行的维度和第二个矩阵每一列的维度相等,所以第一个矩阵第 i 行元素与第二个矩阵第 j 列对应元素的乘积和就等于新矩阵的第 i 行第 j 列的元素值。在下图中,A 矩阵左乘 B 矩阵得到 C 矩阵。A 矩阵行向量与 B 矩阵列向量点积就等于 C 矩阵的元素,具体可以通过下图 C 矩阵内部元素的构成来了解。

    A 矩阵行向量 a1 与 B 矩阵列向量 b1 的点积,即下图所示:

    下面是另一个矩阵的乘积:

    矩阵乘法是不可交换的(即AB ≠ BA)。因为不可能预期在改变向量的部分后还能得到相同的结果,而且第一个矩阵的列数必须要和第二个矩阵的行数相同,也可以看出为什么矩阵相乘的顺序会影响其结果。虽然矩阵乘法是人为的规则,但它确实大大简化了计算的表达,可以将巨大的计算量很简洁地表达出来,这一点对机器学习算法的开发和使用有重要的作用

    最后你可以用以下案例检测一下是否你已经掌握了矩阵运算的基本原理:

    下面矩阵乘法的阶是多少?

    下面矩阵乘法的阶是多少?

    下面矩阵的乘法是多少?

    下面矩阵的乘法是多少?

    下面矩阵的乘法是多少?

    使用 Numpy 进行矩阵乘法运算

    在 Numpy 中,np.dot(a,b) 函数可以进行向量和矩阵点积。并且该函数还有许多有意思的特征,所以我建议你在使用该函数前先看看该函数的用法:https://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html

    a = np.array([[1, 2]])a.shape == (1,2)

    b = np.array([[3, 4],[5, 6]])b.shape == (2,2)

    # Multiplymm = np.dot(a,b)mm == [13, 16]mm.shape == (1,2)

    深度学习通常会有巨大的计算量。从最开始的特征输入,我们会使用一个个高维向量将特征输入到神经网络中,而每一层的权重作为列向量组成一个权重矩阵。每一层的正向传播都需要使用矩阵乘法进行计算,而反向传播更需要理解矩阵运算才能对其运行原理有一个较为深入的理解。本文是矩阵运算的基础性文章,其不仅对概念的理解很是重要,同时在新手开始学着搭建机器学习系统时更为有用,因为矩阵运算的代码在实际操作中是我们看懂一段代码或写出一段代码的基础。并且采用矩阵运算代码实现也远比采用循环语句或条件语句代码实现的算法要简洁易读得多。

  • ?

    深度学习全网最全学习资料汇总之入门篇

    爱情

    展开

    作为人工智能领域一个重要的研究分支,深度学习技术几乎出现在当下所有热门的AI应用领域,包括语音识别,语义理解,图像识别,大数据分析等等,甚至有人把当前的人工智能等同于深度学习。面对如此重要的江湖地位,我们相信一定有为数众多的 AI 开发者对深度学习技术充满了好奇心,想要快速着手使用这项强大的技术来解决现实生活中的实际问题。因此,雷锋网将围绕深度学习技术整理一个系列文章,全面覆盖与其相关的各项知识点。

    本文针对如何入门深度学习这一话题,整理了若干参考资料,希望对广大开发者有所裨益。

    需要提前说明的是,无论教程怎样浅显易懂,如果要深刻理解深度学习的技术原理,一些基础的数学知识还是必不可少的,包括微积分、线性代数和概率论等。这些都是各高校的必修课,大家可以轻松找到丰富的中文教程。这里仅列出三个值得参考的免费的英文教程。

    MIT本科线性代数公开课

    链接: https://ocw.mit.edu/courses/mathematics/18-06sc-linear-algebra-fall-2011/index.htm

    MIT微积分公开课

    链接: https://edx.org/course/calculus-1a-differentiation-mitx-18-01-1x

    MIT概率论公开课

    链接:https://edx.org/course/introduction-probability-science-mitx-6-041x-2

    当然,大家也可以在 coursera 和各种慕课类网站挑选自己喜欢的数学基础课程,此处不再赘述。

    下面进入本文的正题。

    要入门深度学习,首选的一个教程是来自台湾大学电机系李宏毅教授的演讲 PPT。该 PPT 共计301页,源于 IEEE DSC 2016 系列活动,当时打出的标题是“一天搞懂深度学习”。该课程非常适合初学者,以最简单易懂的图示和文字阐述了深度学习的基本原理、深度学习模型的各种训练小技巧、递归神经网络和一些常见的深度学习应用。

    目前已经有网友针对李教授的PPT进行了视频讲解,视频链接也贴在下面。最后一个链接是李教授整个学期课程的资料,除了深度学习之外,还包括了线性代数的相关内容。

    台大李宏毅教授讲义

    PPT链接:http://slideshare/tw_dsconf/ss-62245351?qid=108adce3-2c3d-4758-a830-95d0a57e46bc&v=&b=&from_search=3

    视频链接:http://v.youku/v_show/id_XMTc0MDQ3Mzk0NA==.html?spm=a2h0j.8191423.module_basic_relation.5~5!2~5~5!3~5!2~1~3~A&from=y1.2-1-87.3.1-2.1-1-1-0-0#paction

    李宏毅教授其他课程:http://speech.ee.ntu.edu.tw/~tlkagk/courses.html

    其次推荐来自斯坦福大学的卷积神经网络课程,即 CS231n: Convolutional Neural Networks(CNN) for Visual Recognition。该课程由著名华人 AI 学者李飞飞担任主讲,虽然课程名称是卷积神经网络和图像识别,但前期进行了大量关于 Python 开发环境搭建、神经网络原理等基础知识的介绍,适合初学者认真研读。目前该课程已经有了中文字幕版,链接如下。

    李飞飞CNN课程

    英文链接:http://cs231n.github.io/

    中文链接:http://study.163/course/introduction/1003223001.htm#/courseDetail

    说起深度学习的著名学者,则不得不提 Yann LeCun,Yoshua Bengio,Geoffrey Hinton 三人合著的一篇综述:《Deep learning》。三位世界级AI大牛合力编写的这篇文章虽然只有不到 7 页 A4 纸,但参考文献却超过百篇,被引用更是不计其数,含金量可想而知。这是一篇科普类的深度学习综述性文章,并没有介绍特别高深的技术细节,因此比较适合初学者。论文从非常专业的角度深入浅出地讲解了深度学习的基本原理,以及深度卷积网络和递归神经网络等较深入的话题。

    Yann LeCun,Yoshua Bengio,Geoffrey Hinton 三人合著论文《Deep learning》

    英文链接:https://cs.toronto.edu/~hinton/absps/NatureDeepReview.pdf

    中文链接:http://csdn/article/2015-06-01/2824811

    下面推荐两本适合初学者的免费的书籍。

    一本来自上文提到的 Yoshua Bengio,他与另外两位同事合著了一本名为《Deep learning》的教科书。该书主要分为以下三个部分:机器学习和数学基础,深度学习的基础实践,深度学习的进一步研究,内容全面、讲解细致,特别适合深度学习的初学者,完全免费。

    Yoshua Bengio教科书《Deep learning》

    英文链接:http://deeplearningbook.org/

    中文链接:https://github/exacity/deeplearningbook-chinese

    另一本是 YC Research 研究员 Michael Nielsen 所著的《Neural Networks and Deep Learning》。该书首先讲述了神经网络的基本原理,然后基于该原理介绍了深度学习中的若干核心概念,同样非常适合于初学者的入门学习,完全免费。值得一提的是,本书现在已经有了中文版。

    Neural Networks and Deep Learning

    英文链接:http://neuralnetworksanddeeplearning/

    中文链接:http://wiki.jikexueyuan/project/neural-networks-and-deep-learning-zh-cn/

    说了这么多英文课程,下面推荐一个中文的:《Deep Learning(深度学习)学习笔记整理系列》。该系列文章从人脑的视觉机理入手,讲述了深度学习的基本思想、深度学习与神经网络之间的关系、深度学习的训练过程和常用模型算法等,几乎囊括了深度学习入门所必备的所有知识,被视为中文版的深度学习白皮书。对英文资料的理解有障碍的读者可以认真阅读本教程。

    Deep Learning(深度学习)学习笔记整理系列

    链接:http://blog.csdn/zouxy09/article/details/8775360/

    到这里,雷锋网相信经过上述教程的学习,各位开发者对深度学习的入门应该不会再有太大的障碍了。下面将推荐三个和深度学习相关的资料大集合,都是来自相关专业人士的权威总结。除了入门知识之外,这几个集合还囊括了其他各种与深度学习相关的内容,包括各种编程语言的总结 、基础的数学知识、高阶的深度学习应用实例等等,可谓“包罗万象”。

    集合1:Awesome Deep Learning

    链接:https://github/ChristosChristofidis/awesome-deep-learning

    集合2:机器学习 (Machine Learning) & 深度学习 (Deep Learning) 资料

    第一部分:https://github/ty4z2008/Qix/blob/master/dl.md

    第二部分:https://github/ty4z2008/Qix/blob/master/dl2.md

    集合3:干货分享 | 深度学习零基础进阶大法!

    链接:http://leiphone/news/201610/tgtcVePX2kdDlHfL.html

    大家可以抱着“淘宝”的心态在上述三大资料库中寻找对自己有帮助的内容,再加本文前面提到的几篇入门资料,相信各位开发者会对深度学习的相关技术形成一个基本的认识。

    雷锋网相关阅读:

    Tensorflow 全网最全学习资料汇总之Tensorflow的迭代更新【1】

    Tensorflow 全网最全学习资料汇总之Tensorflow 的入门与安装【2】

    Tensorflow 全网最全学习资料汇总之框架平台的综合对比【3】

    TensorFlow 全网最全学习资料汇总之TensorFlow的技术应用【4】

  • ?

    深度学习入门教程:手把手带你用Numpy实现卷积神经网络(一)

    柯幼旋

    展开

    本教程由深度学习中文社区(Studydl)持续发布与更新, 教程中完整代码已上传至github上, 可关注我百家号后发送消息"CNN代码", 获得地址.

    前言

    Numpy是一个非常好用的python科学计算的库,CNN是现在视觉领域深度学习的基础之一。虽然好的框架很多,不过自己用Numpy实现一个可以使用的CNN的模型有利于初学者加深对CNN的理解。

    后面我们将通过一系列文章介绍如何用Numpy从零实现一个可以训练的CNN简易网络,同时对深度学习(CNN)的相关基础知识进行一些复习,也希望能够给正在入门的同学一些简单的归纳。

    在这一系列的文章中,我们主要需要做以下一些工作:

    Numpy实现如下图中所示的基本的CNN网络组件:conv, pooling, relu, fullyconnect, softmax

    用实现的基本组件搭建可以训练的网络,完成mnist的训练与测试,画出一个下图的训练曲线从贯序连接的层模型到计算图模型的引入,完成自动求值,求导等功能常见的初始化方法,激活函数,优化方法,Loss函数的实现与比较,例如relu系与sigmoid系的比较,sgd,momentum,Adam的比较等等常见的trick的实现,例如dropout, batchnorm, residual

    绝大部分的同学入门深度学习,第一个接触的应该就是LeNet,我们也将以此为例子介绍卷积神经网络的基本组件。参考上面的的网络结构图,它包含了卷积层(Convolutions),池化层(pooling), 全连接层(Full connection)。

    卷积层(Convolutions)

    卷积:如果你有图像处理的基础,对于卷积操作我想你一定不会陌生。在传统的图像处理中,卷积操作多用来进行滤波,锐化或者边缘检测啥的。我们可以认为卷积是利用某些设计好的参数组合(卷积核)去提取图像空域上相邻的信息。

    卷积计算图解

    在二维图像上,卷积操作一方面可以高效地按照我们的需求提取图像的邻域信息,在全局上又有着非常好的平移等变性,简单就是说你将输入图像的某一部分移动到另外一部分,在输出图像上也会有着相应的移动。比如下图是花书里用来阐述卷积在特征提取的效率优势上的一张图片,我们用来演示卷积的效果。假设我们把狗狗的鼻子移动到左上角,那么相应输出里面的狗鼻子也会出现在左上角。(照片来源Paula Goodfellow)

    卷积计算效果图

    卷积神经网络之所以非常适合处理视觉问题,卷积的平移等变性是一大功臣。卷积神经网络中的卷积层可以理解成是在二维图像卷积的基础上增广而来。在二维图像卷积操作里,对于一个固定的卷积核,它能够提取输入图像的某种特征,但在实际的视觉问题里,某一个尺度下的某种空间特征不足以解决我们的需求。所以我们需要改进原始的卷积操作使得可以提取不同尺度下的不同特征。

    一次操作(一层)中使用多个卷积核得到该尺度下的多张特征映射多层(次)提取不同尺度下的不同特征信息

    由于第一点改进,自然而然,即使第一张图片输入只有一个通道,后面其他层的输入都是多通道。所以对应的我们的卷积核也是多通道。即输入图像和卷积核都添加了channel这个维度,那么卷积层中的卷积操作变为了如下的定义:

    到这里,我们大概可以总结出一个卷积层的前向计算(Forward)和他的功能。当然正如我们前面提到过,需要读者懂一点BP算法,因为即使我们知道如何通过卷积层提取输入图像的特征,卷积层依旧无法正常的工作,因为卷积操作最关键的部分卷积核的数值没有被确定下来。BP算法就是告诉我们,如何通过监督学习的方法来优化我们的卷积核的数值,使得我们能够找到在对应任务下表现最好的卷积核(特征),当然这个说法不是很准确。所以在我们实现的卷积层的类中,还会包含一个Backward方法,用于反向传播求导。考虑到一次篇幅不要太长这一部分的原理和实现将放在下一篇文章里。

    在这篇接下来的部分里我们就将逐一用Numpy实现一个可以运行的Conv2D类以及Forward方法。

    Show me your code

    PS:文章看到的版本是不基于graph模型的,Conv2D直接继承自Object,所有的数据和操作都是裸露的,单纯为了实现功能。github上面这一部分代码已经不用了,放在layers文件夹下。

    初始化

    根据上面的公式,我们知道实现一个卷积前向计算的操作,我们需要知道以下信息:

    输入数据的shape = [N,W,H,C] N=Batchsize/W=width/H=height/C=channels卷积核的尺寸ksize ,个数output_channels, kernel shape [output_channels,k,k,C]卷积的步长,基本默认为1.卷积的方法,VALID or SAME,即是否通过padding保持输出图像与输入图像的大小不变

    实际上还需要知道核参数的初始化方法

    class Conv2D(object):def __init__(self, shape, output_channels, ksize=3, stride=1, method='VALID'):self.input_shape = shapeself.output_channels = output_channelsself.input_channels = shape[-1]self.batchsize = shape[0]self.stride = strideself.ksize = ksizeself.method = methodweights_scale = math.sqrt(ksize*ksize*self.input_channels/2)self.weights = np.random.standard_normal((ksize, ksize, self.input_channels, self.output_channels)) / weights_scaleself.bias = np.random.standard_normal(self.output_channels) / weights_scale

    我们通过初始化函数确定上面提到的所需参数,在第一次声明的时候完成了对该层的构建。如下:

    conv1 = Conv2D([batch_size, 28, 28, 1], 12, 5, 1)

    这个conv1的实例就代表了该层,自然也会包含该层所需要的参数,例如kernel weights, kernel bias,我们用 np.random.standard_noral(kernel_shape)生成对应的kernel weights和kernel bias。因为 np.random.standard_noral()生成的mean=0,stdev=1的随机Numpy数组,这里我们后面除以相应的weights_scale(msra方法)去控制一下初始化生成的weights的stdev,好的初始化可以加速收敛。

    下面这一部分是反向传播中用到的,这篇文章中暂时不会用到,self.eta用于储存backward传回来的

    他与该层的out是一个同样维度的数组.

    这里我们就可以看到method时如何控制输出数据的形状的。“SAME”就表示添加padding使得输出长宽不变。self.w_gradient,self.b_gradient则分别用于储存backward计算过后得到的该次的

    if method == 'VALID':self.eta = np.zeros((shape[0], (shape[1] - ksize ) / self.stride + 1, (shape[1] - ksize ) / self.stride + 1,self.output_channels))if method == 'SAME':self.eta = np.zeros((shape[0], shape[1]/self.stride, shape[2]/self.stride,self.output_channels))self.w_gradient = np.zeros(self.weights.shape)self.b_gradient = np.zeros(self.bias.shape)self.output_shape = self.eta.shape

    前向计算(forward)

    如何实现卷积层前向计算,是一个非常老生常谈的问题,贾扬清大神对这个问题解释的比较清楚,可以参考查询下在Caffe中如何计算卷积

    这里主要使用的就是im2col优化方法:通过将图像展开,使得卷积运算可以变成两个矩阵乘法

    图解im2col

    详情参见论文 High Performance Convolutional Neural Networks for Document Processing

    我们的forward方法的实现基本就是实现了上图,主要分为以下四个步骤:

    完整的代码如下

    def forward(self, x):col_weights = self.weights.reshape([-1, self.output_channels])if self.method == 'SAME':x = np.pad(x, ((0, 0), (self.ksize / 2, self.ksize / 2), (self.ksize / 2, self.ksize / 2), (0, 0)),'constant', constant_values=0)self.col_image = []conv_out = np.zeros(self.eta.shape)for i in range(self.batchsize):img_i = x[i][np.newaxis, :]self.col_image_i = im2col(img_i, self.ksize, self.stride)conv_out[i] = np.reshape(np.dot(self.col_image_i, col_weights) + self.bias, self.eta[0].shape)self.col_image.append(self.col_image_i)self.col_image = np.array(self.col_image)return conv_out

    首先我们将卷积层的参数weights通过ndarray自带的reshape方法reshape到上图中Kernal Matrix的形状。根据self.method,选择是否对输入的数据进行padding,这里我们调用 np.pad()方法,对我们的输入数据四维ndarray的第二维和第三维分别padding上与卷积核大小相匹配的0元素。声明一个list用于存储转换为column的image,在backward中我们还会用到。对于batch中的每一个数据,分别调用im2col方法,将该数据转化为上图中的Input features(Matrix), 然后调用 np.dot()完成矩阵乘法得到Output features(Matrix), reshape输出的shape,填充到输出数据中。

    im2col的代码如下:

    def im2col(image, ksize, stride):# image is a 4d tensor([batchsize, width ,height, channel])image_col = []for i in range(0, image.shape[1] - ksize + 1, stride):for j in range(0, image.shape[2] - ksize + 1, stride):col = image[:, i:i + ksize, j:j + ksize, :].reshape([-1])image_col.append(col)image_col = np.array(image_col)return image_col

    到这里我们就基本实现了简单的卷积层的forward方法,你可以通过输入图片,指定weights的值,进行简单的运算,测试是否能够正确的进行前向的计算,完整的代码可以去我的github直接看最新版,虽然有很较大的出入,但一样是非常容易理解的。我们也能看出,之所以选用python+Numpy实现,是因为大多数需要用到的方法,例如reshape,pad,dot,都已经在Numpy中实现好了,同时,也很方便我们实时的去检查。

    第一篇文章里就只介绍到这里。整篇文章基本上是以图像的视角,介绍了如何利用Numpy实现CNN中的卷积层的前向计算。这只是CNN精彩的地方,但不是最关键的地方,下一篇中我们将先介绍BP算法以及从机器学习相关视角来看待CNN,然后实现卷积层里面的backward()与apply_gradient()。教程中完整代码已上传至github上, 可关注我百家号后发送私信"CNN代码", 获得地址.

    TensorFlow入门系列教程文章地址:

    只需以下两步就可获取到零基础入门教教程啦:

    回到文章最上方点击关注按钮关注我的百家号,方便接收最新教程.点击标题下方的头像位置, 就可进入我的主页, 里面就有我之前发布的TensorFlow入门系列教程啦.

    目前已发布的TensorFlow入门教程列表:

深度学习基础教程

所有视频需要登录后,才能观看

请先登录您的帐号,即可完整播放,如果您尚未注册帐号,请先点击注册。