├── OPML.xml
├── README.md
├── weibo
└── AI
│ └── aikeke.xml
├── weixin
└── AI
│ ├── 36dashuju.xml
│ ├── AlgorithmDog.xml
│ ├── CSDN.xml
│ ├── dashujuwenzhai.xml
│ ├── jiqizhixin.xml
│ └── xinzhiyuan.xml
└── zhihu
├── collection
└── AI
│ └── 113183484.xml
└── zhuanlan
└── AI
├── HicRhodushicsalta.xml
├── OPML.xml
├── Stark.xml
├── baina.xml
├── c_29122335.xml
├── chicken-life.xml
├── coding-future.xml
├── cyh24.xml
├── datartisan.xml
├── dlclass.xml
├── easyml.xml
├── hsmyy.xml
├── impress-your-cat.xml
├── intelligentunit.xml
├── mlearn.xml
├── paperweekly.xml
├── resyschina.xml
└── yuandong.xml
/OPML.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 机器学习小火车
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 机器学习小火车 - 全文RSS收集
2 |
3 | ----
4 |
5 | 在机器学习的路上摸索前行,为了更快速的跟进行业最新的动态,我开始整理和收集机器学习相关的**优秀博客**、**专栏**和**活跃大V**。
6 |
7 | 在他们的热心分享与传播下,我收货不少。
8 |
9 | 我将最终整理到的学习资源整理为全文RSS订阅:
10 | 
11 |
12 |
13 |
14 | ## 知乎专栏
15 |
16 | |名称 |订阅地址 | 介绍 |
17 | | ----- | ----- | ------ |
18 | | 智能单元 | https://zhuanlan.zhihu.com/intelligentunit | 从拿到CS231n授权开始,就一直保持的非常频繁的翻译更新,:thumbsup: |
19 | | 无痛的机器学习 | https://zhuanlan.zhihu.com/hsmyy | 把复杂的问题简单化,用简单明了的语言来阐述机器学习|
20 | | PaperWeekly | https://zhuanlan.zhihu.com/paperweekly |把周报写成了日报的更新频率,分享了一些论文研读|
21 | | ResysChina | https://zhuanlan.zhihu.com/resyschina | 一篇《Quora 是如何做推荐的?》让这个专栏进入更多人的视野,期待更多重量级文章|
22 | | 人脑与人工智能 | https://zhuanlan.zhihu.com/HicRhodushicsalta | 最近的《人脑认知与计算机算法》系列比较深刻的剖析了人脑与人工智能的联系|
23 | | 菜鸡的啄米日常| https://zhuanlan.zhihu.com/chicken-life | 中文Keras翻译负责人,一波Keras教程福利 |
24 | | 程序员山居笔记 | https://zhuanlan.zhihu.com/coding-future | 关于Prisma的最新专栏文章很多人赞 |
25 | | 远东轶事 | https://zhuanlan.zhihu.com/yuandong | 自带光环,卡耐基梅隆大学机器人系博士,Facebook 人工智能组研究员 |
26 |
27 | ## 微信订阅号
28 |
29 | | 名称 | 介绍 |
30 | | ----- | ------ |
31 | | 机器之心 | 应该可以说是AI领域最专业的自媒体了,每天的头条都非常有价值,还经常有AI领域大佬的专访 |
32 | | 新智元 | 线下活动办得溜,文章也不错 |
33 | | CSDN大数据 | 偏工程化,实战案例比较多 |
34 | | 36大数据 | 文章都比较接地气,也以工程实践为主 |
35 | | 大数据文摘 | 追热点功力强,流行的东西这里都有 |
36 | | AlgorithmDog | 这里有细致的算法讲解,受益匪浅 |
37 |
38 | ## 博客
39 |
40 | |名称 |订阅地址 | 介绍 |
41 | | ----- | ----- | ------ |
42 | | 我爱机器学习| https://www.52ml.net | 清华兄的独立网站,内容相当丰富|
43 | | 我爱自然语言处理 | http://www.52nlp.cn | 这难道也是上面的哥们弄的么,不管怎么说,关于NLP的文章水平也是杠杠的|
44 | | 我爱计算机 | http://www.52cs.org | 讲真,你们是不是一起的。不过,"我爱计算机"的大牛专访挖掘了大牛很多的成长历程,值得学习 |
45 | | 数盟社区 | http://dataunion.org | 数盟会聚合一些热门文章,特别是涉及行业方面的 |
46 | | 好东西论坛 | http://forum.memect.com/ | 好东西论坛都是好东西,不解释,大家应该都知道 |
47 | | 谷歌官方研究博客 | https://research.googleblog.com/ | 谷歌最新研究成果的发布站,虽然更新不是那么频繁,但是篇篇都是重量级文章 |
48 |
49 | ## 微博
50 | |名称 |订阅地址 | 介绍 |
51 | | ----- | ----- | ------ |
52 | | 爱可可-爱生活|http://weibo.com/fly51fly| 看了博主的时间线后你会发现,这简直就是人工智能的人肉资源挖掘机|
53 |
54 | ## OPML
55 |
56 | 最终整理的OPML链接为:
57 | [https://raw.githubusercontent.com/RickyWong33/Machine_Learning_RSS/master/OPML.xml](https://raw.githubusercontent.com/RickyWong33/Machine_Learning_RSS/master/OPML.xml)
58 |
59 | ## 使用方法1(推荐) - inoreader
60 |
61 | 在设置的OPML订阅源中填入本repo的OPML RAW文件地址:
62 | ```
63 | https://raw.githubusercontent.com/RickyWong33/Machine_Learning_RSS/master/OPML.xml
64 | ```
65 | 
66 |
67 | > inoreader能同步本OPML的更新,以后扩展的订阅源都会被inoreader自动同步,推荐使用
68 |
69 | ## 使用方法2 - Feedly
70 |
71 | 下载[OPML LINK](https://raw.githubusercontent.com/RickyWong33/Machine_Learning_RSS/master/OPML.xml)后保存为`OPML.xml`,在Feedly源管理页面导入。
72 |
73 | > 由于本repo可能会频繁更新订阅源(或者修订RSS输出的样式),如果需要更新的话,请重新下载后再导入Feedly。
74 |
75 | ## 致谢
76 |
77 | 感谢以上提到的博主积极的知识输出
78 | 本repo也会不断更新,欢迎推荐更多的优质机器学习阅读资源
--------------------------------------------------------------------------------
/weixin/AI/36dashuju.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 36大数据
5 | http://www.iwgc.cn/list/1149
6 | 关注大数据和互联网趋势,最大,最权威,最干货的大数据微信号(dashuju36).大数据第一科技媒体.不发软文,只做知识分享.
7 | -
8 | 从AlphaGo 围棋大战到AI 德扑大战的机器学习技术解析 | 上
9 | http://www.iwgc.cn/link/4738399
10 | <div class="article-content"><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291681HzYUmk.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">文 | 章诚、肖群稀 、王宗超</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>回顾与解析: AlphaGo 横扫世界棋坛, 德州扑克成为人工智能新战场</strong></span></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">过去一年中谷歌 AlphaGo 大胜围棋顶级大师李世石, 60 局连胜数十位中日韩围棋高手。 攻陷围棋后人工智能进军德扑对战, 加拿大和捷克科学家研发的 DeepStack 成为首个一对一无限注德扑中战胜人类玩家的人工智能,平均胜率达到了 492mbb/g。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">2017 年 1 月中旬卡内基梅隆大学人工智能“ Libratus” 迎战德扑职业玩家,为期 20 天,“人机对战” 历史将再添浓重一笔。人工智能时代的到来震撼全球,究竟是什么力量赋予谷歌 AlphaGo和德扑对战 AI 以超凡智慧? “未来机器”系列报告希望用前瞻性研究视角为您提供启发。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">第十五篇,我们聚焦 AlphaGo 的制胜法宝——机器学习。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>机器学习是人工智能的方法,深度学习是机器学习的分支</strong></span></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">通俗而言,人工智能( Artificial Intelligence)目的就是使机器具备部分(甚至是全部)人类的智能。机器学习是人工智能范畴下的一种重要方法,是实现人工智能的一种途径。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">深度学习则是指机器通过深度神经网络,模拟人脑进行学习、判断和决策,是机器学习的主要分支之一。人工智能,机器学习和深度学习是层层细分的关系,后者是前者实现的一种途径。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">机器学习的关键技术支持:内存、 GPU、算法和数据源单来说机器学习就是计算机利用已有数据,得出了某种模型并利用此模预测未来的一种方法,与人脑思考方式非常类似。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">机器学习的发展主要决于硬件和软件两个方面。 硬件方面: 大容量的存储是机器学习发展的基础,同时现阶段主流机器学习方法都依赖于 GPU 来进行计算和训练。 软件方面:算法是机器计算的核心, 数据源是机器学习准确性的保障, 随着深度学习算法的提出,神经网络算法成为了近期的热点。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>机器学习产业蓬勃发展,全球多领域巨头争相布局</strong></span></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">根据 Venture Scanner 统计,截至 2016 年上半年全球共有约 1000 家人工智能公司,其中机器学习相关公司约占 40%;根据 IDC 的预测, 2020 年机器学习应用市场有望达 400 亿美元。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">虽然多数人工智能企业尚属初创,但仍有以谷歌、 IBM、 Facebook、百度、阿里巴巴、腾讯等国内外巨头依托自身技术、资金与数据优势构成了机器学习领域的核心力量,从日渐完善产品线到平台构建等角度带动机器学习产业蓬勃发展。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>人工智能是智能机器人的点睛之笔, 携手云计算开启服务机器人新时代</strong></span></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">服务机器人定位于服务人类,智能化是其最大的特征。 机器学习、深度学习将成为服务机器人高度智慧的新源泉,使机器智能化持续提升,交互准确性迭代提高。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">同时云计算、大数据、高速移动网络将机器学习与智能机器人隔空相连, 共同构建以“云平台”为核心的人工智能技术生态圈, 智能机器人有望迎来爆发期。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">虽然国内服务机器人产业起步晚, 但发展空间较大, 几十家上市公司宣布进入,其中布局积极、业务规模可观的代表企业包括: 巨星科技、机器人、康力电梯、博实股份、美的集团等。</p><h2 style=" font-size: 18px; margin-top: 16px; margin-bottom: 16px; padding-top: 10px; padding-bottom: 10px; line-height: 18px; border-bottom: 1px solid rgb(238, 238, 238); color: rgb(68, 68, 68) ; ;; white-space: normal; "><strong>一、人机大战烽火不断,人工智能捷报频传</strong></h2><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">长久以来,“人机对战”一直都被公认为用于衡量人工智能进步程度的重要途径之一。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在过去的 20 年里, 随着人工智能的不断发展,传统智力游戏领域不断涌现出新的挑战者,我们多次见证了人工智能已经在大量的游戏、竞技比赛中超越了人类, 例如国际象棋、 中国象棋、 西洋双陆棋、跳棋、 Jeopardy 智力竞赛、 Atari 电子游戏等。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在过去的一年里,人工智能再一次凭借 “人机大战”竞技场上的良好表现引发了全球对人工智能的持续关注。</p><h3 style=" border-bottom: 1px solid rgb(238, 238, 238); margin-bottom: 16px; color: rgb(68, 68, 68) ; ;; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>1.1 连胜 60 局:谷歌 AlphaGo 横扫中日韩棋坛</strong></span></h3><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在刚刚过去的 2016 年里,谷歌旗下 DeepMind 公司研发的人工智能 AlphaGo 在围棋界引起波澜。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">2016 年 1 月 27 日,谷歌 DeepMind 依托“深度学习”原理打造的 lphaGo 在没有让子的情况下战胜了欧洲职业二段选手樊麾,人工智能第一次在完整的围棋竞技中击败专业选手。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">成功战胜围棋大师李世石使谷歌 AlphaGo 一战成名。 李世石于 2003 年获第 16 届富士通杯冠军后升为九段棋手, 加冕富士通杯以来在十年时间里共获得 18 个世界冠军, 是继李昌镐之后韩国最具代表性的顶尖棋手。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在与李世石对局前, 谷歌 AlphaGo 已经集中学习半年,谷歌为其输入了 3000 万步人类围棋大师的走法,让其自我对弈 3000 万局,积累胜负经验,同时在自我对弈的训练中形成全局观,并对局面做出评估。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">2016 年 3 月 9 日到 15 日, AlphaGo 最终于以 4: 1 的总比分战胜了世界围棋冠军李世石, 这表明 AlphaGo在围棋领域已经达到超越了世界顶尖水平。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">成名后的 AlphaGo 凭借 60 局连胜中日韩高手再度引发全球关注。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">力克李世石后,谷歌AlphaGo 并没有停下它征战的步伐。 2016 年 7 月 18 日,世界围棋排名网站 Go Ratings公布谷歌 AlphaGo 的总积分超过原排名第一的柯洁, 人工智能首次在围棋领域荣登世界榜首。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在 2016 年末至 2017 年初, 谷歌 AlphaGo 化身棋手 Master 在网络围棋平台的快棋对决中多次击败了包括聂卫平、柯洁、朴廷桓、井山裕太在内的数十位中日韩围棋高手,拿下 60 局全胜的战绩,人工智能的杰作谷歌 AlphaGo 在围棋界已经登峰造极。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291682xqPKca.jpg"/><img src="http://wxrss.b0.upaiyun.com/1487291682tmLG86.jpg"/><img src="http://wxrss.b0.upaiyun.com/1487291682ohGB31.jpg"/><img src="http://wxrss.b0.upaiyun.com/1487291682KD2Xpn.jpg"/></p><h3 style=" border-bottom: 1px solid rgb(238, 238, 238); margin-bottom: 16px; color: rgb(68, 68, 68) ; ;; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>1.2 力克职业玩家: 德州扑克成为人工智能挑战人类的新战场</strong></span></h3><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在攻陷围棋之后,人工智能的触角开始伸向德州扑克。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">2017 年初,加拿大和捷克的几位科学家在《 DeepStack:无限注德扑的专业级人工智能玩家》的论文中介绍了 DeepStack这种能在一对一无限注德扑中击败人类玩家的新算法,奠定了人工智能征战德扑的里程碑。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">论文记录的人机对战中, DeepStack 平均胜率达到了 492mbb/g。 研究者邀请了来自 17个国家的 33 名专业扑克选手挑战 DeepStack,进行了 44852 次较量。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">DeepStack 成为了首个在一对一无限注德扑中战胜人类玩家的人工智能,并且平均胜率达到了 492mbb/g (一般人类玩家到 50 mbb/g 就被认为拥有较大优势, 750mbb/g 就是对手每局都弃牌的赢率)。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291683SLa5xv.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291683zsRMec.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>围棋被攻陷后,为何是德州扑克来承载人类应战的责任?</strong></span></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">“人心不可测”的德州扑克是典型的不完整信息博弈游戏,也是人工智能面临的长期挑战。围棋对弈,双方的棋子都尽显在一方棋盘中,也就是“完整信息博弈”,因此阿尔法狗的胜利,实质上就是揭开了围棋玄而又玄的神秘面纱,证实了围棋背后的计算本质。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">然而,德州扑克则是“不完整信息博弈”,信息不完全透明,玩家只看得到自己手中的牌,无法得知对手的牌,并在博弈过程中包含了欺骗、推测。简单来说,这是一个“人心不可测”的博弈。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">由于德州扑克包含了更接近真实世界情况的欺骗、推测等非完美信息, 这一特征对人工智能的算法和数据处理能力提出了更高的要求。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><span data-mce-style="color: #000000;" style="color: rgb(0, 0, 0);"><strong>DeepStack 力挫专业德扑选手的奥秘究竟如何? 人工智能已经读懂人心了吗?</strong></span></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">德扑对战中你不仅要思考别人要做什么,思考自己做什么,甚至要思考别人会认为你做什么,进而推理出自己的下一步,这些尔虞我诈的战术更像是兵法。DeepStack 注重培养人工智能德扑对战出牌时的“直觉、牌感”。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在这篇论文中,多次出现一个词:“直觉”,也就是我们常说的“牌感”。 DeepStack 结合循环推理来处理信息不对称,使用分解将计算集中在相关的决策上,并且使用一种深度学习技术从单人游戏中自动学习以获取对扑克任意状态的直觉形式。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在运用深度学习,反复自我博弈之后,DeepStack 学会了在每一个具体情境出现时进行推理。这非常接近人类玩家的“牌感”,即在当前情境下对个人牌面大小的感觉,并作出相应的决策。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">对战超过一定手牌数时, 运气成分将被稀释, 人工智能强大的记忆力优势将被突显。 不同于围棋、国际象棋等纯技术类游戏,德州扑克短期的对局中运气因素十分重要。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">人类完全靠记忆记录对手逻辑思维顺序,还有打牌的模式套路,而人工智能会直接存档,把你每一手牌的牌和过程全部记录下来,客观上这一点人类就比较难做到。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">所以在一个较长手牌数的对局中,人工智能将数据充分收集并快速分析后,人类完全难以与之抗衡。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>下一场人机德扑大战,何时揭晓战果?</strong></span></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">2017 年 1 月 11 日, 由卡内基梅隆大学开发的同样适用 DeepStack 算法的人工智能“ Libratus” 开始在无限制德州扑克比赛中同四个顶级德扑职业玩家展开挑战, 赛程为期20 天,总共将对战 12 万手牌, 一旦最终战果揭晓,人工智能征战“人机对战”的历史将再添浓重一笔。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291683kcBxYX.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">不论是 AlphaGo 在围棋界连奏凯歌还是 Libratus 向德州扑克领域全力进发, 都展现了近年来人工智能, 特别是机器学习领域的迅猛发展。 通过本文,我们将为您深度解读“机器学习”技术的前世今生。</p><h2 style=" font-size: 18px; margin-top: 16px; margin-bottom: 16px; padding-top: 10px; padding-bottom: 10px; line-height: 18px; border-bottom: 1px solid rgb(238, 238, 238); color: rgb(68, 68, 68) ; ;; white-space: normal; "><strong>二、机器学习: 人工智能的璀璨明珠</strong></h2><h3 style=" border-bottom: 1px solid rgb(238, 238, 238); margin-bottom: 16px; color: rgb(68, 68, 68) ; ;; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>2.1 机器学习是人工智能的方法,深度学习是机器学习的分支</strong></span></h3><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">通俗而言,人工智能( Artificial Intelligence) 目的就是使机器具备部分( 甚至是全部)人类的智能。 人工智能作为计算机科学的一个分支,是研究用计算机来模拟人的某些思维过程和智能行为(如学习、推理、思考、规划等)的学科。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">美国麻省理工学院的温斯顿教授认为:“人工智能就是研究如何使计算机去做过去只有人才能做的智能工作。” 人工智能的研究领域主要包括机器人、语言识别、图像识别、自然语言处理和专家系统等。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">机器学习是人工智能范畴下的一种重要方法,是实现人工智能的一种途径。 人工智能可以根据其智能的程度分为响应式机器、有限记忆机器,心智理论机器和自我意识机器四类。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">前文提到的 AlphaGo 就可以归类为有限记忆机器,即机器可以根据过去有钱的经验来决定未来的步骤。为了实现机器智能的提升,“机器学习”是不可或缺的方法。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">根据英特尔机器学习主管尼迪·查普尔( Nidhi Chappel)的观点,人工智能的根本在于如何为机器赋予智能。而机器学习则是部署支持人工智能的计算方法。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">通俗来说,机器学习是让机器实现智能的方法, 是机器学习成就了人工智能。 机器学习是近期人工智能中发展最快的部分,因此全球为数众多的企业都在努力开发这项技术。<br></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">深度学习是指机器通过深度神经网络,模拟人脑进行学习、判断和决策,是机器学习的主要分支之一。 为了达到机器学习的目标,浅层学习和深度学习的方法被先后提出。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">深度学习的概念源于人工神经网络的研究,它基于神经网络框架,通过模拟人脑学习的方式的来处理数据,通过神经网络的分层处理,将低层特征组合形成更加抽象的高层表示属性类别或特征,以发现数据的分布式特征表示。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">AlphaGo 的技术架构采用的是模仿人类大脑神经的模式,通过深度学习把人工神经网络的层级大大增加,提升了计算能力。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "> AlphaGo 的胜利,让如今高速发展的深度学习益发成为人工智能领域的焦点。总的说来,人工智能,机器学习和深度学习是层层细分的关系,后者是前者实现的一种途径。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291683slKG76.jpg"/><img src="http://wxrss.b0.upaiyun.com/1487291684a2rnPN.jpg"/></p><h2 style=" font-size: 18px; margin-top: 16px; margin-bottom: 16px; padding-top: 10px; padding-bottom: 10px; line-height: 18px; border-bottom: 1px solid rgb(238, 238, 238); color: rgb(68, 68, 68) ; ;; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>2.2 七十年变迁:机器学习的前世今生</strong></span></h2><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>奠定基础: 20 世纪 50 年代初到 60 年代中叶</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在这一阶段,研究者们提出的各种算法模型为机器学习奠定了理论基础。 Hebb 于 1949年基于神经心理学的学习机制提出了 Hebb 学习规则。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">Hebb 学习规则是一个无监督学习规则,这种学习的结果是使网络能够提取训练集的统计特性,从而把输入信息按照它们的相似性程度划分为若干类。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">这一点与人类观察和认识世界的过程非常吻合,人类观察和认识世界在相当程度上就是在根据事物的统计特征进行分类。 之后, IBM 科学家亚瑟·塞缪尔开发了一个能够随着游戏程序运行时间的增加而提高行动准确性的跳棋程序。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">通过这个程序,塞缪尔驳倒了普罗维登斯提出的机器无法超越人类,像人类一样写代码和学习的模式。他创造了“机器学习”,并将它定义为“可以提供计算机能力而无需显式编程的研究领域”。 此外,在算法方面,最小二乘法和最近领算法的提出大大增强了机器的数据处理能力。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291684ohGB31.jpg"/><img src="http://wxrss.b0.upaiyun.com/1487291684QJ83vt.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>停滞不前: 20 世纪 60 年代中叶到 70 年代末</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在这一阶段,受限于当时有限的内存和处理速度,机器学习的发展步伐几乎处于停滞状态。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">虽然这个时期温斯顿( Winston) 的结构学习系统和海斯·罗思( Hayes Roth) 等的基于逻辑的归纳学习系统取得较大的进展,但只能学习单一概念,而且未能投入实际应用。此外,神经网络学习机因理论缺陷未能达到预期效果而转入低潮。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>走向复兴: 20 世纪 70 年代末到 80 年代中叶</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">从 70 年代末开始,人们从学习单个概念扩展到学习多个概念,探索不同的学习策略和各种学习方法。 这个时期,机器学习在大量的时间应用中回到人们的视线,又慢慢复苏。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在这个时期中,韦博斯提出神经网络反向传播算法和多层感知器的概念;昆兰提出了与神经网络模型截然不同的决策树算法。这些新的理论为机器学习的发展增加了更多的可能性。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>逐步成形: 20 世纪 90 年初到 21 世纪初</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在这阶段, 一些相对成熟的算法理论被提出。 研究者 Schapire 和 Freund 提出并完善了一种用来提高弱分类算法准确度的“ Boosting” 方法; 瓦普尼克和科尔特斯在大量论证和实证的条件下提出了支持向量理论。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">此外,布雷曼博士进一步深化了决策树模型,提出了随机森林模型。这个阶段,神经网络和支持向量机制在各个情景下存在各自的优势。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/14872916843WlgIG.jpg"/><img src="http://wxrss.b0.upaiyun.com/14872916852VkfHF.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>蓬勃发展: 21 世纪初至今</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在这个时期,深度学习和支持向量机理论成为主流。 Hinton 和 Salakhutdinov 提出的深度学习理论大大提高了神经网络的能力。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">深度学习可以让那些拥有多个处理层的计算模型来学习具有多层次抽象的数据的表示。这些方法在许多方面都带来了显著的改善,包括最先进的语音识别、视觉对象识别、对象检测和许多其它领域,例如药物发现和基因组学等。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">深度学习能够发现大数据中的复杂结构, 这也是 AlphaGo 能够在围棋领域产生重大影响的原因。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">此外,互联网的普及,大数据和云计算的普遍运用也加速了机器学习的发展。 随着机器学习理论的不断演进和发展,人工智能领域也将产生持续的变革,引发人类生产能力和生产方式的改变。</p><h3 style=" border-bottom: 1px solid rgb(238, 238, 238); margin-bottom: 16px; color: rgb(68, 68, 68) ; ;; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>2.3 高效性与普适性是机器学习崛起的核心优势</strong></span></h3><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>核心优势之一: 高效性</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">相对于传统的机器算法, 让机器进行一个决策需要其创建者将已有或者已总结好的知识通过机器语言传输给机器。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">但机器学习的算法能够通过过去相关事件的数据自己总结出相关模型,然后根据总结出的模型对新的事件进行判断,机器的使用者只需要提供过去发生的样本数据。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">样品量越大,机器决策的正确性就越高。 这就大大提高了效率,因为机器能够24 小时不间断运行去分析样本,而人类则不行。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>核心优势之二: 普适性</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">如果用传统算法去解决一个问题, 遇到不同的条件可能就需要对模型的代码进行调整,这使得改进的成本很高。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">而机器学习只需要调整输入的样本数据就能让机器自己分析出新的模型从而进行运用,所需要的只是获得数据的成本和一定的时间成本。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">这一特性也是的机器学习能够适用于各个能够获得大量数据的行业,而不是只针对某个特殊的方面。大大增强了机器的普适性,继而降低了使用者的成本。</p><h3 style=" border-bottom: 1px solid rgb(238, 238, 238); margin-bottom: 16px; color: rgb(68, 68, 68) ; ;; white-space: normal; "><span data-mce-style="color: #ff6600;" style="color: rgb(255, 102, 0);"><strong>2.4 机器学习的主要应用概览</strong></span></h3><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>应用之一: 语音识别</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">机器学习技术可以应用于语音识别领域, iPhone 的 Siri 和 Windows 语音助手 Cortana都使用了机器学习的技术。 当用户使用语音识别软件时, 机器需要根据已经构建的状态网络中寻找与客户声音最匹配的路径, 而这个状态网络的构建就用到了机器学习的技术。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">通过状态网络的构建,机器可以从一个用户的话语,确定用户提出的具体要求,甚至可以帮助程序自动填充用户需求。机器对客户的声音样本收集的越多,机器对于客户就越人性化。随着机器学习技术的不断发展,语音识别的错误率也在不断减少。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291685c5upRP.jpg"/><img src="http://wxrss.b0.upaiyun.com/1487291685ExWRjh.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>应用之二:人脸识别</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">人脸识别技术是基于人的脸部特征,对输入的人脸图像或者视频流,根据具体的面貌特征信息进行判断。 人脸识别系统的研究始于 20 世纪 60 年代,而真正进入初级的应用阶段则在 90 年后期,以美国、德国和日本的技术实现为主。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">采用深度学习的人脸识别系统,早期需要把现实的图像抽象成一系列数据进行学习并了解人脸的特征,在构建了一套最基本的人工智能学习算法后, 再提供大量人脸及非人脸照片,包括同样的人脸在不同光线、表情、角度的照片,让计算机去适应辨别、学习。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">人脸识别技术作为技术安全度较高的识别模式,目前在考勤、门禁、电视、安防等广泛的领域已有一定的行业及个人消费市场应用。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291685leDy0Y.jpg"/><img src="http://wxrss.b0.upaiyun.com/1487291686dC1Xpn.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>应用之三: 自动驾驶</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在自动驾驶领域,各大厂商普遍运用了机器学习的算法来使自动驾驶汽车更加智能化。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">在2017 年的 CES 展会上, FCA 的纯电动自动驾驶概念车 Chrysler Portal、本田的 NeuV、福特的第二代 Fusion 混动自动驾驶试车、现代的 Ioniq、法拉第未来的首款量产电动车等几乎都采用了机器学习特别是深度学习的技术。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">运用了机器学习算法的自动驾驶汽车会根据用户的打分回馈去不断修正自己的行为模式,从而逐渐满足客户的要求。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">例如,当特斯拉自动驾驶汽车用户行驶在右车道,靠近高速公路出口坡道时,车子会倾向于直接开往出口, 因此用户必须快速将主控权拉回来(修正路径),直到车子离开出口坡道。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">但随着经验的累计,车子也慢慢降低了每当车子靠近出口坡道时,直接开往出口的倾向,直至无需手动修复。这表现出了机器学习的高度可塑造性。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/14872916860TidFD.jpg"/><img src="http://wxrss.b0.upaiyun.com/1487291686SkJF75.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><strong>应用之四: 医疗诊断</strong></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">基于机器学习的大数据分析能力,机器学习可以应用于医疗健康领域。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">机器学习系统可以根据病人的症状和一个匿名的病人资料数据库,预测该病人可能患了什么病。这样的决策模型,可以程序为专业医疗人士提供支持。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">IBM 在 2016 年开始致力于将其认知计算机器人与健康医疗相结合。 </p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">2016 年 8 月 12 日, Watson Health 正式进入中国市场开始其“认知医疗”系统的推行。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">此外, 东京大学医学研究院利用 Watson 在 10 分钟内判断出一位女性患有罕见的白血病。 这些进展预示着机器学习在健康医疗领域有着广阔的前景。</p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; "><img src="http://wxrss.b0.upaiyun.com/1487291686XQfaCA.jpg"/></p><p style=" margin-bottom: 16px; color: rgb(51, 51, 51) ; ;; font-size: 15px; white-space: normal; ">End.</p><section style="margin: 27px 16px 16px; padding: 8px 16px; border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); box-shadow: rgb(165, 165, 165) 5px 5px 2px; font-size: 1em; font-family: inherit; text-decoration: inherit; color: rgb(51, 51, 51); background-color: rgb(255, 255, 240); box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="margin-top: -1.2em; border-width: initial; border-style: none; border-color: initial; box-sizing: border-box;" class="tn-Powered-by-XIUMI"><span style="display: inline-block; padding: 4px 8px; color: rgb(255, 255, 255); font-size: 150%; line-height: 1.4; text-align: center; box-shadow: rgb(165, 165, 165) 4px 4px 2px; font-family: inherit; text-decoration: inherit; background-color: rgb(249, 110, 87); border-color: rgb(249, 110, 87); box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI" style="box-sizing: border-box;">逗你一笑</section></span></section><section style="padding: 16px; font-size: 1em; line-height: 1.4; font-family: inherit; box-sizing: border-box;" class="tn-Powered-by-XIUMI"><p>这句话对不对?</p><p>老鼠为什么会飞?</p><p>因为老鼠吃了仙丹。</p><p>蛇为什么会飞?</p><p>因为蛇吃了仙丹。</p><p>错。因为蛇吃了老鼠。</p><p>老鹰为什么会飞?</p><p>因为老鹰吃了蛇。</p><p><br></p></section></section></div>
11 | Fri, 17 Feb 2017 08:32:08 +0800
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/weixin/AI/AlgorithmDog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AlgorithmDog
5 | http://www.iwgc.cn/list/5566
6 | AlgorithmDog 讲述机器学习和系统研发的轶事,希望把这些事讲得生动有趣.每周日更新哦.欢迎关注.
7 | -
8 | Akka 使用系列之三: 层次结构
9 | http://www.iwgc.cn/link/d3fb3a3862deee70327f4e95df92883274bb7166
10 |
11 | <p> Akka 是用层次结构组织 Actors 的。<span></span></p><p><a rel="attachment wp-att-3677" style="background: transparent; border-width: 0px; border-style: initial; border-color: initial; vertical-align: baseline; color: rgb(116, 51, 153);"><img src="http://img04.iwgc.cn/mpimg/87efa647b1e254dc6522dd3bd7ed5dab36f0d330"/></a></p><p> </p><p> 我们需要实现一个翻译模块,其功能是输入中文输出多国语言。我们可以让一个 Master Actor 负责接收外界输入,多个 Worker Actor 负责将输入翻译成特定语言,Master Actor 和 Worker Actor 之间是上下级层次关系。下图展示了这种层级结构。</p><p><a rel="attachment wp-att-3889" style="background: transparent; border-width: 0px; border-style: initial; border-color: initial; vertical-align: baseline; color: rgb(116, 51, 153);"><img src="http://img04.iwgc.cn/mpimg/1bd35e79c94af4933c76523d1aca69f88f241f21"/></a></p><p>具体代码实现如下所示。</p><p><span></span><span>class</span><span> </span><span>Master</span><span> </span><span>extends</span><span> </span><span>Actor</span><span> </span><span>with</span><span> </span><span>ActorLogging</span><span>{</span><span>
12 | val english2chinese
13 | </span><span>=</span><span> context</span><span>.</span><span>actorOf</span><span>(</span><span>Props</span><span>[</span><span>English2Chinese</span><span>],</span><span>"English2Chinese"</span><span>)</span><span>
14 | val english2cat
15 | </span><span>=</span><span> context</span><span>.</span><span>actorOf</span><span>(</span><span>Props</span><span>[</span><span>English2Cat</span><span>],</span><span>"English2Cat"</span><span>)</span><span>
16 |
17 | </span><span>def</span><span> receive </span><span>=</span><span> </span><span>{</span><span>
18 | </span><span>case</span><span> eng1</span><span>:</span><span>String</span><span> </span><span>=>{</span><span>
19 | english2chinese </span><span>!</span><span> eng1
20 | english2cat </span><span>!</span><span> eng1<br></span><span> }</span><span>
21 | </span><span>}<br></span><span>}<br><br></span><span></span><span>class</span><span> </span><span>English2Chinese</span><span> </span><span>extends</span><span> </span><span>Actor</span><span> </span><span>with</span><span> </span><span>ActorLogging</span><span>{</span><span>
22 | </span><span>def</span><span> receive </span><span>=</span><span> </span><span>{</span><span>
23 | </span><span>case</span><span> eng</span><span>:</span><span>String</span><span> </span><span>=></span><span> </span><span>{</span><span>
24 | println</span><span>(</span><span>"我翻译不出来!"</span><span>)</span><span>
25 | </span><span>}</span><span>
26 | </span><span>}<br></span><span>}<br><br></span><span></span><span>class</span><span> </span><span>English2Cat</span><span> </span><span>extends</span><span> </span><span>Actor</span><span> </span><span>with</span><span> </span><span>ActorLogging</span><span>{</span><span>
27 | </span><span>def</span><span> receive </span><span>=</span><span> </span><span>{</span><span>
28 | </span><span>case</span><span> eng</span><span>:</span><span>String</span><span> </span><span>=>{</span><span>
29 | println</span><span>(</span><span> </span><span>"喵喵喵!"</span><span>)</span><span>
30 | </span><span>}</span><span>
31 | </span><span>}<br></span><span></span><span>}<br><br></span><span></span><span>object</span><span> </span><span>Main</span><span>{</span><span>
32 | </span><span>def</span><span> main</span><span>(</span><span>args</span><span>:</span><span>Array</span><span>[</span><span>String</span><span>])</span><span>=</span><span>{</span><span>
33 | val sys </span><span>=</span><span> </span><span>ActorSystem</span><span>(</span><span>"system"</span><span>)</span><span>
34 | val master </span><span>=</span><span> sys</span><span>.</span><span>actorOf</span><span>(</span><span>Props</span><span>[</span><span>Master</span><span>],</span><span>"Master"</span><span>)</span><span>
35 | master </span><span>!</span><span> </span><span>"Hello,world!"</span><span>
36 | </span><span>}<br></span><span></span><span>}</span></pre><p>我们在 Master Actor 中使用 context.actorOf 实例化 English2Chinese 和 English2Cat,便可以在它们之间形成层次关系。这点通过它们的 actor 地址得到证实。</p><p><a rel="attachment wp-att-3891" style="background: transparent; border-width: 0px; border-style: initial; border-color: initial; vertical-align: baseline; color: rgb(116, 51, 153);"><img src="http://img05.iwgc.cn/mpimg/ad3f52ab2d2cd61d2761a5ac6d31c1a9789dc3cf"/></a></p><p> </p><p> 上面的 Actors 层次结构是我们程序里 Actor 的层次结构。这个层次结构是 Actor System 层次结构的一部分。Actor System 层次结构从根节点出来有两个子节点:UserGuardian 和 SystemGuardian。用户程序产生的所有 Actor 都在 UserGuardian 节点下,SystemGuardian 节点则包含系统中的一些 Actor,比如 deadLetterListener。如果一个 Actor 已经 stop 了,发送给这个 Actor 的消息就会被转送到 deadLetterListener。因此完整的 Actor 层次结构如下所示。</p><p><a rel="attachment wp-att-3895" style="background: transparent; border-width: 0px; border-style: initial; border-color: initial; vertical-align: baseline; color: rgb(116, 51, 153);"><img src="http://img03.iwgc.cn/mpimg/ff31d377eca67eff0d550b834d4a60d6613d92c0"/></a></p><p> </p><p> 我们使用 Akka 开发并行程序时,可以使用层级结构组织 Actors。层次结构不仅比较符合人类直觉,还为容错提供了机制保障。我们将会在下一篇文章介绍容错机制。本文的代码已经上传到 https://github.com/algorithmdog/AkkaUsageLearner。欢迎关注 AlgorithmDog 公众号,每两周的更新会有推送哦。</p><p><a rel="attachment wp-att-2360" style="background: transparent; border-width: 0px; border-style: initial; border-color: initial; vertical-align: baseline; color: rgb(116, 51, 153);"><img src="http://img04.iwgc.cn/mpimg/8a2b169c29c09d867a8f4b0602f2a7acf3ac2785"/></a></p><p><br></p>
37 |
38 | Tue, 28 Feb 2017 00:39:29 +0800
39 |
40 | -
41 | 动态图计算:Tensorflow 第一次清晰地在设计理念上领先
42 | http://www.iwgc.cn/link/4694430
43 | <div class="article-content"><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; ">2017 年 2 月 8 号,Google 在其博客上发布 TensorFlow Fold ,支持动态图计算。动态图计算是 Tensorflow 第一次清晰地在设计理念上领先。<span style="border: 0px; vertical-align: baseline; background: transparent;"></span></p><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> <a rel="attachment wp-att-1896" style="border: 0px; vertical-align: baseline; color: rgb(116, 51, 153); background: transparent;"><img src="http://wxrss.b0.upaiyun.com/1487049222slKF75.jpg"/></a></p><h3 style=" border: 0px; margin-bottom: 10px; vertical-align: baseline; clear: both; line-height: 1.5em; ; ; ; ; "><span style="border: 0px; vertical-align: baseline; background: transparent;">1. 图计算</span></h3><hr><h3 style=" border: 0px; margin-bottom: 10px; vertical-align: baseline; clear: both; line-height: 1.5em; ; ; ; ; "><span style="border: 0px; vertical-align: baseline; background: transparent;"></span><br></h3><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> 梯度计算,或者自动求导,是深度学习框架中不可回避的问题。图计算是深度学习框架实现梯度计算的一种方式。不同于一般的编程模式,图计算先生成计算图,然后按照计算图执行计算过程。下面这段代码便属于图计算程序。</p><pre class="wp-code-highlight prettyprint prettyprinted" style=" border: 1px solid rgb(204, 204, 204); margin-top: 6px; margin-bottom: 24px; padding: 2px 7px; vertical-align: baseline ; ; ; ; ; ; ; ; ; ; "><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">A </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> </span><span class="typ" style="border: 0px; vertical-align: baseline; color: rgb(102, 0, 102); background: transparent;">Variable</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="str" style="border: 0px; vertical-align: baseline; color: rgb(0, 136, 0); background: transparent;">'A'</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">B </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> </span><span class="typ" style="border: 0px; vertical-align: baseline; color: rgb(102, 0, 102); background: transparent;">Variable</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="str" style="border: 0px; vertical-align: baseline; color: rgb(0, 136, 0); background: transparent;">'B'</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">C </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> B </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">*</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> A
44 | D </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> C </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">+</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> </span><span class="typ" style="border: 0px; vertical-align: baseline; color: rgb(102, 0, 102); background: transparent;">Constant</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="lit" style="border: 0px; vertical-align: baseline; color: rgb(0, 102, 102); background: transparent;">1</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)<br><br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"></span><span class="com" style="border: 0px; vertical-align: baseline; color: rgb(136, 0, 0); background: transparent;"># compiles the function<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">f </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> compile</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">D</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">d </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> f</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">A</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">np</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">.</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">ones</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="lit" style="border: 0px; vertical-align: baseline; color: rgb(0, 102, 102); background: transparent;">10</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">),</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> B</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">np</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">.</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">ones</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="lit" style="border: 0px; vertical-align: baseline; color: rgb(0, 102, 102); background: transparent;">10</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)*</span><span class="lit" style="border: 0px; vertical-align: baseline; color: rgb(0, 102, 102); background: transparent;">2</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)</span></pre><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; ">当执行 C = B * A 这一行代码时,程序并没有进行真正的计算,而是生成了下面的计算图。只有执行 d = f(A=np.ones(10), B=np.ones(10)*2) 这行代码时,程序才会将数据灌进 A 和 B,运算得到 d。</p><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "><a rel="attachment wp-att-3841" style="border: 0px; vertical-align: baseline; color: rgb(116, 51, 153); background: transparent;"><img src="http://wxrss.b0.upaiyun.com/1487049222TLa6yw.png"/></a></p><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> 图计算怎么实现梯度计算?我们来看下面用图计算实现梯度计算的代码。</p><pre class="wp-code-highlight prettyprint prettyprinted" style=" border: 1px solid rgb(204, 204, 204); margin-top: 6px; margin-bottom: 24px; padding: 2px 7px; vertical-align: baseline ; ; ; ; ; ; ; ; ; ; "><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">A </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> </span><span class="typ" style="border: 0px; vertical-align: baseline; color: rgb(102, 0, 102); background: transparent;">Variable</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="str" style="border: 0px; vertical-align: baseline; color: rgb(0, 136, 0); background: transparent;">'A'</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">B </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> </span><span class="typ" style="border: 0px; vertical-align: baseline; color: rgb(102, 0, 102); background: transparent;">Variable</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="str" style="border: 0px; vertical-align: baseline; color: rgb(0, 136, 0); background: transparent;">'B'</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">C </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> B </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">*</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> A
45 | D </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> C </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">+</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> </span><span class="typ" style="border: 0px; vertical-align: baseline; color: rgb(102, 0, 102); background: transparent;">Constant</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="lit" style="border: 0px; vertical-align: baseline; color: rgb(0, 102, 102); background: transparent;">1</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"></span><span class="com" style="border: 0px; vertical-align: baseline; color: rgb(136, 0, 0); background: transparent;"># get gradient node.<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">gA</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">,</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> gB </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> D</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">.</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">grad</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">wrt</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=[</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">A</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">,</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> B</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">])<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"></span><span class="com" style="border: 0px; vertical-align: baseline; color: rgb(136, 0, 0); background: transparent;"># compiles the gradient function.<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">f </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> compile</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">([</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">gA</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">,</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> gB</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">])<br></span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">grad_a</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">,</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> grad_b </span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> f</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">A</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">np</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">.</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">ones</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="lit" style="border: 0px; vertical-align: baseline; color: rgb(0, 102, 102); background: transparent;">10</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">),</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;"> B</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">=</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">np</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">.</span><span class="pln" style="border: 0px; vertical-align: baseline; color: rgb(0, 0, 0); background: transparent;">ones</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">(</span><span class="lit" style="border: 0px; vertical-align: baseline; color: rgb(0, 102, 102); background: transparent;">10</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)*</span><span class="lit" style="border: 0px; vertical-align: baseline; color: rgb(0, 102, 102); background: transparent;">2</span><span class="pun" style="border: 0px; vertical-align: baseline; color: rgb(102, 102, 0); background: transparent;">)</span></pre><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; ">D 的 grad 函数产生向后计算图,返回 gA 和 gB 梯度节点(下图中的红色节点)。</p><p><a rel="attachment wp-att-3858" style="border: 0px; vertical-align: baseline; color: rgb(116, 51, 153); background: transparent;"><img src="http://wxrss.b0.upaiyun.com/1487049223nfEA20.png"/></a></p><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> 图计算在内存使用和运算时间两个方面比较高效。如下图所示,图计算能够对上述代码中的乘法和加法运算进行运算折叠。如果使用 GPU 计算,运算折叠之后的程序只需用到一个GPU内核(而不是两个)。</p><p><a rel="attachment wp-att-3862" style="border: 0px; vertical-align: baseline; color: rgb(116, 51, 153); background: transparent;"><img src="http://wxrss.b0.upaiyun.com/1487049223e7wrTR.png"/></a></p><h3 style=" border: 0px; margin-bottom: 10px; vertical-align: baseline; clear: both; line-height: 1.5em; ; ; ; ; "><span style="border: 0px; vertical-align: baseline; background: transparent;"><br></span></h3><h3 style=" border: 0px; margin-bottom: 10px; vertical-align: baseline; clear: both; line-height: 1.5em; ; ; ; ; "><span style="border: 0px; vertical-align: baseline; background: transparent;">2. 动态图计算</span></h3><hr><h3 style=" border: 0px; margin-bottom: 10px; vertical-align: baseline; clear: both; line-height: 1.5em; ; ; ; ; "><span style="border: 0px; vertical-align: baseline; background: transparent;"></span><br></h3><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> 上面介绍了图计算和图计算的优点,图计算也有不够灵活的缺点。因为图计算在输入数据之前就定义图结构,因此用一张图计算所有的输入数据。但是有些时候,我们必须针对不同的输入数据建立不同的计算图。例如自然语言理解中的解析树(parse trees),源代码中的抽象语法树(abstract syntax trees)以及网页中的 DOM 树等等。</p><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> 如果我们还要用图计算,解决这个问题的方法就显得比较 trick 了。 LSTM 对长度不定的句子建模的场景中,先把长度相近的句子聚在一起(bucketing),然后把长度补到最长的那句 (padding),这样就能用统一的一张图计算所有的句子了。如果是树型结构,则需要先将树转化序列,然后在 bucketing 和 padding。另外一种方法则是放弃或者部分放弃图计算。Torch 和 Chainer 没有采用图计算,不需用一张图计算所有数据。Theano 用 scan 实现循环功能,算是部分放弃图计算。这样做的代价就是不能利用图计算高效的优点。</p><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> 这次 Google 提出的动态图计算则解决这个问题。动态图计算对批量训练中的每一个样本生成一张计算图,然后把这些计算图进行归并生成一张大的计算图,最后用下面的贪心算法高效地这张大的计算图。这样一方面能够利用图计算高效的优点,另一方面又能处理不同输入需要不同计算图的场景。</p><p><a rel="attachment wp-att-3867" style="border: 0px; vertical-align: baseline; color: rgb(116, 51, 153); background: transparent;"><img src="http://wxrss.b0.upaiyun.com/1487049223umidFD.jpg"/></a></p><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> </p><h3 style=" border: 0px; margin-bottom: 10px; vertical-align: baseline; clear: both; line-height: 1.5em; ; ; ; ; "><span style="border: 0px; vertical-align: baseline; background: transparent;">3. 总结</span></h3><hr><h3 style=" border: 0px; margin-bottom: 10px; vertical-align: baseline; clear: both; line-height: 1.5em; ; ; ; ; "><span style="border: 0px; vertical-align: baseline; background: transparent;"></span><br></h3><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> Tensorflow 是开源最迟的深度学习框架,积累不如 MXNet、Theano、Caffe 和 Torch 深厚。因此给大家的感觉,Tensorflow 一直在追赶这些深度学习框架。Tensorflow 出一个新东西,我们似乎可以在其他深度学习框架中找到。动态图计算是 Tensorflow 第一次清晰地在设计理念上领先于其他深度学习框架。</p><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> 当然动态图计算还刚刚问世,应该还需要时间优化。毕竟,承载动态图计算思想的 Tensorflow Fold 并不是 Google 的正式项目。最后欢迎关注我的公众号,每两周的更新就会有提醒哦~</p><p><a rel="attachment wp-att-2360" style="border: 0px; vertical-align: baseline; color: rgb(116, 51, 153); background: transparent;"><img src="http://wxrss.b0.upaiyun.com/1487049224FyXSki.jpg"/></a></p><p style=" border: 0px; margin-bottom: 24px; vertical-align: baseline; color: rgb(51, 51, 51); ; ; ; ; ; ; "> </p><h3 style=" border: 0px; margin-bottom: 10px; vertical-align: baseline; clear: both; line-height: 1.5em; ; ; ; ; "><span style="border: 0px; vertical-align: baseline; background: transparent;">参考文献</span></h3><p><span style="border: 0px; vertical-align: baseline; background: transparent;">1. http://mxnet.io/architecture/program_model.html?highlight=programming%20models%20deep%20learning</span></p><p>2. https://openreview.net/pdf?id=ryrGawqex</p><p><br></p><p><br></p><hr><p><span style="line-height: 25.6px;">帮朋友所在部门发个招聘广告</span></p><p><span style="line-height: 25.6px;"><br></span></p><p>腾讯MIG06-自然语言处理研究员(深圳)<br>工作职责:<br>负责对话机器人框架的设计,或核心算法模块的研发工作;<br>负责信息检索、推荐系统的整体方案设计,或核心算法模块研发;<br>负责自然语言处理、对话管理,文本挖掘相关的研究工作;<br>负责大规模文本分类、语义标签提取、摘要生成等技术的研发工作;<br>负责大规模机器学习的研发工作;<br><br>任职资格<br>3年及以上自然语言处理、机器学习、文本挖掘相关工作经验;<br>熟练掌握c++、linux后台开发技能;<br>对语音识别、对话管理等研发经验者尤佳,有知识图谱建设经验者优先;<br>对会话机器人有感兴趣,对前沿技术感兴趣;<br>积极主动,勇于接受挑战,富有创新精神。</p><p><br></p><p><span style="color: rgb(217, 33, 66);">有意向的同学,欢迎发邮件到 sunnynsun@tencent.com</span></p><p><br></p></div>
46 | Tue, 14 Feb 2017 12:53:57 +0800
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/zhihu/zhuanlan/AI/HicRhodushicsalta.xml:
--------------------------------------------------------------------------------
1 |
2 | Hic Rhodus, hic salta - 知乎专栏https://zhuanlan.zhihu.com/HicRhodushicsalta人脑与人工智能Sat, 11 Mar 2017 22:15:21 GMTRickyhttp://blogs.law.harvard.edu/tech/rss- 你的疲劳应对手册https://zhuanlan.zhihu.com/p/25256482<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/v2-cdf42d3f7d732c78b7a28ce42ac4ead0_r.png"></p><p>我是 OwlofMinerva. 近期我在知乎电子书「一小时」系列出版了电子书<a href="https://www.zhihu.com/publications/hour/119553963" class="" data-editable="true" data-title="《摆脱疲惫感:如何科学管理你的疲劳与压力》">《摆脱疲惫感:如何科学管理你的疲劳与压力》</a></p><p>不想上班!尤其是在假期过后,一想到上班还要面对那些没完没了的客户和没完没了的方案,就会顿时生无所恋。(笑不出来 ┭┮﹏┭┮)</p><p>快节奏的生活,高压的学业、频繁的加班,身体的不适,甚至是最近一段时间的入睡困难都会给我们带来很大的困扰。</p><p>想一觉睡到自然醒,想给自己放长假,想离职跳槽……可是,事实上不管怎样都无法摆脱掉那些来自生活和工作的压力与疲劳。我们今天所面对的生活环境,相比于我们人类漫长演化史中的绝大部分时候所面对的,是如此地迥然不同。这就造成,我们在面对这些新的困境时,缺乏经验而无所适从,自身的疲劳和压力没有得到很好的管控,从而导致更加低效的工作甚至是难以治愈的精神疾病。</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/v2-1481a27b1fabe5eab8ca5a7048db7963.png" data-rawwidth="640" data-rawheight="220"><p>这本「一小时」,我尝试从生理性的原理出发,在神经科学的视角下,向大家解释疲劳这一「心理性」的感受。进一步地,借助书中的方法,我们可以测试个人神经系统对疲劳的耐受性,从而认识我们自身在面对疲劳临近奔溃时的状态,以避免神经系统造成难以挽回的损失。</p><p>写作这本书时,我尽量更加通俗地解释各种概念和原理,让读者能够彻底的理解所阐述的内容。同时也力求严谨,引用的有五十多篇具有代表性的论文,让那些想要深入了解的读者也有更多学习的选择。</p><p>如果你正在面对疲劳和压力的困扰,希望这本书对你理解和面对自身的困境有一定的帮助。</p><p>电子书已经上架了,知乎书店首周特价中🎁:</p><p><a href="https://www.zhihu.com/publications/hour/119553963" class="" data-editable="true" data-title="摆脱疲惫感:如何科学管理你的疲劳与压力 - 「一小时」系列 - 知乎书店">摆脱疲惫感:如何科学管理你的疲劳与压力 - 「一小时」系列 - 知乎书店</a>.</p><p>也欢迎感兴趣的读者,收听同主题的知乎 Live:<a href="https://www.zhihu.com/lives/791999731260854272" class="" data-editable="true" data-title="身体被掏空时,我科学地管理了压力疲劳">身体被掏空时,我科学地管理了压力疲劳</a>。</p><p>祝大家阅读愉快,身体健康!</p><p>----</p><p><b>目录</b></p><ul><li>前言</li><li>Ⅰ 为什么会感到疲劳</li><li>Ⅱ 需要休息的大脑</li><li>Ⅲ 疲劳所产生的影响<ul><li>一、由警觉而产生的压力</li><li>二、无法集中的注意力</li><li>三、耗尽感的困扰</li></ul></li><li>Ⅳ 测测你的抗疲劳和抗压程度</li><li>Ⅴ 如何科学管理疲劳与压力</li><li>结语</li></ul><p>----</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/25256482&pixel&useReferer"/>Owl of MinervaThu, 16 Feb 2017 13:18:50 GMT
- Owl of Minerva 的 Live -- 解构亲密关系https://zhuanlan.zhihu.com/p/25086724<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/v2-cc954d9a3427a3565261b8dd94ec3eb3_r.jpg"></p><p>我是OwlofMinerva。我从工程背景转入神经科学,自2009年起我在中科院和德国马普学会从事计算神经科学方面的研究。做过的工作具体包括但不限于人类认知研究、神经系统疾病的磁共振研究、神经解剖研究、免疫组化、图像处理和程序开发。其中博士课题之一便是研究人类下丘脑这一性别认知中枢。目前从事人工智能方面的研发工作。跨学科的经历和认识让我对很对日常事物的不同的理解,由此获得了在知乎、赤兔、TEDx等平台上分享自己的经验和意见的机会。</p><p>我们计划在<b>2017年2月14日(星期二)的晚上20:30分</b>举办新的一期Live: <a href="https://www.zhihu.com/lives/811229103909928960" data-editable="true" data-title="Owl of Minerva 的 Live -- 解构亲密关系" class=""><b>Owl of Minerva 的 Live -- 解构亲密关系</b></a>。亲密关系(典型地,爱情)具有完备的生理基础,不是完全主观的“情绪和认知”,而是相当程度上取决于个人的生理状态和神经解剖特征。我们选择谁、能否维持一段长期的亲密关系,因此不是完全随机的,而是可解释的。但是现实生活的复杂性掩盖了这些规律,“在人群中多看了那一眼”这样的随机性、缘分类的解释成了我们在日常生活中听到的情爱因果的主题。在本次Live中,我将根据自己研究的经验和结论,以及当今学界的最新研究成果,以结构化的方式,从解剖学、生理学等“决定论”的角度,解释和重构情爱这样的亲密关系。希望对大家理解自己的情爱有所裨益。</p><p>本次 Live 主要包括以下问题:</p><p>*性别认同和性取向的解剖和生理基础</p><p>*"人群中多看了那一眼"背后的原理</p><p>*对异性审美的模型,什么样的异性是美的,以及流行对审美的影响</p><p>*热恋:一场神经内分泌的风暴</p><p>*爱情使人盲目?是不是以及为什么</p><p>*分手:痛苦和抉择</p><p>*如何维持长期亲密关系,以及什么是健康的亲密关系</p><p>*长期亲密关系好处(特别地,对双方以及对抚养后代的好处)</p><p>*......</p><p>本次Live尽量排除专业性术语,以通俗的语言和详尽的例子解释复杂的问题,适合于对理解情爱感兴趣的大家。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/25086724&pixel&useReferer"/>Owl of MinervaSat, 04 Feb 2017 20:50:28 GMT
- Owl of Minerva 的 Live -- 科学管理压力与疲劳https://zhuanlan.zhihu.com/p/24372796<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/v2-bc2d3bcd72c3024e65370771812a8fa0_r.jpg"></p><p>我是OwlofMinerva。我从工程背景转入神经科学,自2009年起我在中科院和德国马普学会从事计算神经科学方面的(博士课题)研究。做过的工作具体包括但不限于人类认知研究、神经系统疾病的磁共振研究、神经解剖研究、免疫组化、图像处理和程序开发。 目前从事人工智能方面的研发工作。跨学科的经历和认识让我对很对日常事物的不同的理解,由此获得了在知乎、赤兔、TEDx等平台上分享自己的经验和意见的机会。</p><p>我们计划在2017年<b>1月12日的晚上20:30</b>分举办新的一期Live: <a href="https://www.zhihu.com/lives/791999731260854272" data-editable="true" data-title="知乎 Live - 全新的实时问答" class="">知乎 Live - 科学管理压力与疲劳</a>。本次Live的主题是对自身压力和疲劳水平的认识、管理以及应对策略。本期Live属于知乎Live的「健康管理」系列,依照系列规则,赞助统一为19.9元。</p><p>疲劳,特别是精神上的疲劳实际上已经成为当今社会中的我们几乎每日都会体会到的感受。快节奏的生活中,高压的学业、工作,加班,睡眠方面的困难甚至障碍以及家庭压力对我们造成的困扰非常严重。我们今天所面对的整个生活环境,相比于我们人类的绝大部分历史中所面对的,是如此地迥然不同,这造成我们在面对这些困境时候因为缺乏经验而无所适从。我们面对疲劳和压力的本能性、习惯性的反应和想法,常常因为跟生理规律的矛盾而使情况进一步的恶化。公共领域关于疲劳和压力的知识的稀缺,让这个问题常常没有获得该有的重视,导致工作效率的低下甚至是难以治愈的精神疾病。</p><p>疲劳和压力,在生理上有相通之处,使得它们难以分割。生理意义上的压力比我们日常所言的“压力”范畴更广。日常工作的忙碌和挑战,不和谐的人际关系,家庭的矛盾都可以成为我们“压力”的来源,造成我们生理和认知的紊乱。其危害相比于身体的疾病要更为隐蔽和持久。</p><p>在本次Live中,我将针对这一情况,从疲劳的生理性原理入手,结合该方面的最新研究进展,详细的解释容易被忽略的日常疲劳症状,我们在应对疲劳中的常见误区,疲劳可能导致的认知和精神性(生理性)后果,以及疲劳和压力管理的一些实用策略。希望对大家有些许帮助。</p><p>本次 Live 主要包括以下问题:</p><p>*疲劳(特别是精神疲劳)的生理性原理</p><p>*常见疲劳应对方法对实际生理状态的恶化效果</p><p>*各人对疲劳忍耐力的差异的原因</p><p>*外部压力如何恶化我们的疲劳状态</p><p>*疲劳和压力如何扭曲我们对自己和外部世界的认识</p><p>*疲劳和压力的合理范围(表现)</p><p>*压力管理策略:如何保持在合理的压力范围,最优化工作效率</p><p>*崩溃:过度疲劳对神经系统的(永久性)损伤——精神疾病</p><p>*精神疾病的一般应对策略</p><p>*......</p><p>本次Live面向对象没有特定限制,任何对本话题感兴趣的人,有因为压力导致的精神疾病者,或者自身、家人和朋友有方面的疑问的,都可以来参加。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/24372796&pixel&useReferer"/>Owl of MinervaWed, 14 Dec 2016 22:26:45 GMT
- 人脸识别: LFW, R.I.P.https://zhuanlan.zhihu.com/p/22946897蛰伏了一段时间,这篇文章只发布一条消息:<p>我开始做人脸识别已经满三个月,今日的模型/算法在LFW数据集上的精度达到<b>99.9167(+-)0.117851%,</b>这个参数目前暂列第一名. 也就是说,除了数据集误标的,基本都识别正确了。这也宣告了LFW数据集彻底的死刑,因为它在更当前最优秀的算法面前已经不能再提供任何区分度,并且有很高的过拟合风险。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/22946897&pixel&useReferer"/>Owl of MinervaFri, 14 Oct 2016 12:39:12 GMT
- 人脸识别:人脑认知与计算机算法<4>https://zhuanlan.zhihu.com/p/22098392<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/2cbb5d83c683a6181532a6ae4a32b4c0_r.png"></p>本篇主题:<i>生成、</i><i>反馈 与 判别</i><p>人类学习的过程中伴随着 模仿(生成)、评估(判别或反馈)以及改进,反馈和评估来地越准确越高效,学习的效率也会越高[1]。没有任何形式的反馈,我们不能习得任何能力,而是闭门造车、不断的重复同样的错误,如悲剧性的西西弗斯一般[2]。在强化学习(Reinforcement Learning)中, Agent的学习需要不断的与环境交换信息,从自己的行动产生的结果(评估和反馈)和新的探索选项(Trial and Error)中得到下一步的行走策略。行动产生的结果由回报函数产生,训练的目的和过程在于使汇报函数最大,而不在乎每步训练的精确步骤和策略[3]。人工智能领域的强化学习算法是通过模拟人类学习过程的特征得来的[4]。</p><p>在人工智能领域,按照功能可以划分出两类主要的模型:生成模型(Generative Model)和判别模型(Discriminative Model). 生成模型根据训练集的分布产生新的数据,新产生的数据要符合训练及的分布特征,比如高斯混合模型(Gaussian Mixture Model, GMM) [5] 在经过多轮训练之后就能用来产生跟训练样本类似的数据。而判别模型对于大部分人来说要熟悉的多了,判别模型的目的在于给出数据在多类中属于哪一个,容易理解地,所有的分类算法都可以划归为判别模型。比如人脸识别算法就是一类较为复杂的判别模型,它需要对新来的数据在极多个类中作出判别。</p>按照上面的定义,生成模型需要生成样本X' ~D‘,使得D’尽量接近于训练样本X的分布D. 而判别模型如果应用在生成样本X'和训练样本X上,任务则是判别样本到底属于生成样本和训练样本的哪一类。对于已知数学定义的生成模型,生成模拟样本数据的过程无疑是可以精确描述的,方法上也相对容易,但在深度神经网络中,因为模型参数的缺失,这个问题就变得复杂的多了。<p>为此设计了对抗网络(Generative Adversarial Networks, GAN),它也包括两个模型:生成模型G(Z)和判别模型D(X)。如果认为X是真实样本数据(测试数据),那么D(X)=1, 反之如果认为X是生成模型产生的样本数据,那么D(X)=0. 两个模型在训练过程中进行对抗,生成模型根据训练样本生成数据,判别模型作出分类,最终让V(G,D)取得最小最大值[6]:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/7647adb60d9f45d937b6e5d9a0a192f4.png" data-rawwidth="1034" data-rawheight="58">翻译成容易理解的语言就是:判别模型认为样本X属于测试样本和生成样本Z的概率是随机的,也就是说,判别模型完全无法区分出这两者之间的差异:</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/f7e2ed89aeaa41aeb4546bf59d7c089d.png" data-rawwidth="897" data-rawheight="290"><p><Fig. 训练过程;蓝色虚线:判别分布;黑色点线:训练样本分布;绿色实线:生成样本分布></p><p>但是最初的GAN训练并不稳定,经常产生毫无意义的输出。为了避免这些问题,进行了如下关键改进[7]:</p><ul><li>替换pooling层为strided convolution层和fractional-strided convolution层, 分别用作判别和产生,从而让网络能使用自己的空间下采样进行学习。从而将网络改变为All Convolution Network [8].</li><li>在生成模型和判别模型中都应用Bach Normalization [9]. 让网络学习更稳定。</li><li>去除全连接层</li><li>在产生模型中使用ReLU激活函数,在判别模型中使用LeakyReLU激活函数。使收敛性更好</li></ul><p>最终得到如下网络结构(根据具体训练任务有所变化):</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/0f201ee37f5f6b99e340859f6bb18732.png" data-rawwidth="800" data-rawheight="326">我使用MNIST手写数字数据集[10]进行测试结果如下:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/5efadaf915788b2e5862ef6ee5dc4f56.png" data-rawwidth="560" data-rawheight="843"><Fig. MNIST测试结果:上图,第一个训练epoch的生成Sample; 中图,第200个训练epoch的生成Sample; 下图,真实数据Sample></p><p>比较上图中间的训练结果和下面的真实数据可以发现,对抗网络产生的数据几乎跟真实数据没有人眼可辨的差异。MNIST的数据特征毕竟比较简单,而且人眼对手写数字的变形敏感性比较差,因此还不足以说明问题。相对应的,人脸数据特征复杂,而且人类的大脑对人脸信息敏感度很高(有专门的人脸识别脑区),对其中的“非人”特性很容易识别,那么对抗网络对人类数据的实用性如何呢,我们从自动化所的WebFace数据集中提取了36万个人脸[11]进行了测试:</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/f8ce4665f3feee05ecae8ae35d3f19f0.png" data-rawwidth="448" data-rawheight="960"><p><Fig. CASIA-WebFace测试结果:前十二行中每三行一个epoch.最后三行为第20个epoch的结果>可以看到网络在前几个训练epoch中的产生数据的效果进步很快,但是经过多次训练之后,生成sample表现出特征的趋同化。另外,无论经过多少个epoch的训练,都会产生一些明显不能被人认定为人脸的奇怪数据。 显然地,生成模型在训练过程中坍缩了,生成模型与判别模型在对抗中达成了纳什均衡点[12],但这个均衡点不是系统的唯一均衡点。为了使生成模型避与坍缩,必须在训练过程中告诉它生成数据之间的相似性。</p><p>一个显然的策略在于,对判别模型,我们不让他判别各个生成sample与测试sample特征的相似性,而是判别一批生成sample与测试sample的相似性,这样,如果生成sample趋同,那自然与测试sample不相似了,这被称为Minibatch Discrimination [13]:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/d168c0e644691d4ad3aae59bd2837caf.png" data-rawwidth="419" data-rawheight="274">当然,使用这种策略虽然能够解决生成模型坍缩问题,但是产生诡异数据的问题仍然无法避免,算法表现为把图像特征进行重新整合,这种整合可能是符合真实人脸的,也可能不符合,存在一定的随机性。另外,一些个人性细节丢失的问题也无法避免,因为这些特异性的特征在神经网络训练中被湮没了。</p><p>--------</p><p>[1] Hattie, John. "A Synthesis of Over 800 Meta-Analyses Relating to Achievement." (2014).</p><p>[2] Camus, Albert. "The Myth of Sisyphus: And Other Essays." <i>Penguin Classics</i> (1955).</p><p>[3] Sutton, R. S., and A. G. Barto. "Reinforcement learning : an introduction." <i>Neural Networks IEEE Transactions on</i> 9.5(2013):1054.</p><p>[4] Maia, Tiago V, and M. J. Frank. "From reinforcement learning models to psychiatric and neurological disorders." <i>Nature Neuroscience </i>14.2(2011):154-62.</p><p>[5] Quatieri, Thomas F., and Robert B. Dunn. "Speaker Verification Using Adapted Gaussian Mixture Models." <i>Digital Signal Processing</i> 10.1 (2000): 19-41.</p><p>[6] Goodfellow, Ian, et al. "Generative Adversarial Nets." <i>Advances in Neural Information Processing Systems</i> (2014):2672-2680.</p><p>[7] Radford, Alec, L. Metz, and S. Chintala. "Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks."<i>Computer Science</i> (2015).</p><p>[8] Srivastava, Rupesh Kumar, et al. "Understanding Locally Competitive Networks." <i>Eprint Arxiv</i> (2014).</p><p>[9] Ioffe, Sergey, and C. Szegedy. "Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift." <i>Computer Science</i> (2015).</p><p>[10] Lecun, Yann, and C. Cortes. "The mnist database of handwritten digits.".</p><p>[11] Yi, Dong, et al. "Learning Face Representation from Scratch." <i>Computer Science</i> (2014).</p><p>[12] Nash, John. "Non-cooperative games." <i>Ann.math.stud</i> 54.3(1951):286-295.</p><p>[13] Salimans, Tim, et al. "Improved Techniques for Training GANs." (2016).</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/22098392&pixel&useReferer"/>Owl of MinervaWed, 24 Aug 2016 17:46:41 GMT
- 人脸识别:人脑认知与计算机算法<3>https://zhuanlan.zhihu.com/p/21905116<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/4ec0db37eca4cd9bc510a121d96adb3e_r.png"></p><p>本篇主题:<i>层次模型 (Hierarchical Model)</i></p><p>视觉皮层是第一个被现代神经解剖学就定义的功能皮层区域,其解剖特征和功能特征都是高度的结构化的。同时,视觉皮层占有的皮层表面积/体积又很大,这客观上方便了视觉皮层的解剖结构和认知功能的研究。因此,不难理解地,视觉皮层和视觉功能是我们在神经科学方面研究最为深入、理解最为透彻的。</p>人脑的视觉信号传导通路,在进入大脑皮层之前是高度的结构化的、分工明确的。而且一般认为,视觉信息在进入大脑皮层前,人脑几乎被把它做任何实质意义上的处理,也不从中提取有用的信息 [1]。<img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/55638c576d527c8a46e5d6aead11f963.jpg" data-rawwidth="600" data-rawheight="759"><p><Fig. 视觉通路,视觉信息进入大脑皮层(Primary Visual Cortex) 前的情况></p><p>视觉信息一旦进入大脑皮层(从Primary Visual Cortex初级视觉皮层进入),就体现出其结构化的特征。视觉信息的空间位置跟初级视觉皮层的位置对应起来,总体上表现为空间相邻的位置对应的初级视觉皮层位置也相邻,这种拓扑结构的对应被称为视网膜拓扑映射(Retinotopy)[2]. 信息经由初级视觉皮层处理之后,其发出方向就变得复杂起来,总体上分出两个主要的层次结构流:腹侧通路(Ventral Pathway)和背侧通路(Dorsal Pathway),前者的损伤导致人的物体识别功能受损,因此被也被称为"What"通路,后者的损失导致人的空间判别和视觉注意能力受损,因此也被称为"Where"通路 [3]。</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/d54b3afb7fac698dd7746d3cfda7d508.jpg"><p><Fig. What通路和Where通路></p><p>特别地,根据猕猴(Macaque Monkey)视皮层的解剖结果,人们重建了其各个视皮层之间的分级结构[4]:</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/875d1286e8f10a32d7f84d7f03251b55.jpg"><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/8241b1f7b398ea6192b7081d64421ad1.jpg"><p><Fig. 猕猴视觉皮层分级结构图></p><p>在比较低级的视觉皮层区域,还发现其中的神经元对特定的模式刺激放电频率增加,这种模式可能是物体的视角 [5],也可能是熟悉物体的形状 [6]。这些发现为理解大脑物体识别的层次模式提供了越来越全面的信息,从而,我们逐渐理解了人脑物体识别的分级结构模型:</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/1123f43a23e3488c59a085288519be10.jpg"><p><fig. 人脑物体识别的分层模型></p><p>从初级到更高级的视觉皮层,视觉信息逐级传递。人脑理解的内容越来越复杂化、抽象化,由“模式”变成具体的"物",再到物的特性和物与物之间的关系。进入到初级视觉皮层的信号是非常的繁杂和全面的,显然地,人脑并不需要所有的这些信号,而是只需要提取其中的有用信号就可以了<b>,</b>否则会给大脑的视觉理解带来太大的压力,基于层次结构特征,人脑发展出了视觉编码压缩方式,把通过视觉通路传递过来的信号,跟自己的经验比对,比照经验中的常见图像模式,经过比对之后,找到最为匹配的模式(线、角、圆……;斑马线,转角……),并以该模式取代实际的事物。这就好比给视觉信号做了一次编码,以人脑的内禀信号取代实际信号对视觉图像做了极大的压缩,并为后续的快速处理做好了基础。另外,在整个层次模型的处理过程中,信息流在层级间几乎完全表现为“前馈”式 [7]。这为计算机模拟方法的可行性和快速性提供了基础。</p><p>上面提到的无疑是人脑的通用物体识别架构,基于这些知识设计了模拟大脑皮层结构的层次物体识别模型 ( Hierarchical Models of Object Recognition in/and Cortex, HMAX)[8]:</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/599beeb6a9df10015247502dcbfda9dd.png" data-rawwidth="614" data-rawheight="471"><Fig, HMAX Model><p>可见这实际上是一种早期形式的深度神经网络,它的每一层也是需要根据具体的任务情况进行训练。</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/59a6b12066360877f45e433cde4f1429.png" data-rawwidth="515" data-rawheight="381">在人脸识别任务中,由于结构较浅,而底层的模型又过于简单[9](网络设计为从简特征到复杂特征),这使得模型在较高层中识别的feature仍然是接近于“线”、“角”这样的易于描述的基础性特征 [10, 11]:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/d29f5863249deafe866c1ee18e86feb7.png" data-rawwidth="851" data-rawheight="342"><Fig. 底层网络特征></p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/10e76fac5665cc0ae2776ad141a22b97.png" data-rawwidth="476" data-rawheight="365"><Fig. 高层网络特征></p><p>可见这种网络在设计上就过于限制,深度不如当今的深度神经网络,网络的灵活性上要欠缺更多,在当时,还要限于训练集的数据量和该模型的简单性,其结果几乎不可能超越当今的深度神经经网络。--------</p><p>[1] Standring, Susan, ed. <i>Gray's anatomy: the anatomical basis of clinical practice</i>. Elsevier Health Sciences, 2015.</p><p>[2] Engel S A, Glover G H, Wandell B A. Retinotopic organization in human visual cortex and the spatial precision of functional MRI [J]. Cerebral cortex, 1997, 7(2): 181-192.</p><p>[3] Ungerleider, Leslie G., and James V. Haxby. "‘What’and ‘where’in the human brain." <i>Current opinion in neurobiology</i> 4.2 (1994): 157-165.</p><p>[4] Van Essen, David C., and John HR Maunsell. "Hierarchical organization and functional streams in the visual cortex." <i>Trends in neurosciences</i> 6 (1983): 370-375.</p><p>[5] Logothetis, Nikos K., Jon Pauls, and Tomaso Poggio. "Shape representation in the inferior temporal cortex of monkeys." <i>Current Biology</i> 5.5 (1995): 552-563.</p><p>[6] Booth, M. C., and Edmund T. Rolls. "View-invariant representations of familiar objects by neurons in the inferior temporal visual cortex." <i>Cerebral Cortex</i> 8.6 (1998): 510-523.</p><p>[7] Brown, Elizabeth, and David I. Perrett. "What gives a face its gender?."<i>Perception</i> 22.7 (1993): 829-840.</p><p>[8] Riesenhuber, Maximilian, and Tomaso Poggio. "Hierarchical models of object recognition in cortex." <i>Nature neuroscience</i> 2.11 (1999): 1019-1025.</p><p>[9] Serre, Thomas, and Maximilian Riesenhuber. <i>Realistic modeling of simple and complex cell tuning in the HMAX model, and implications for invariant object recognition in cortex</i>. No. AI-MEMO-2004-017. MASSACHUSETTS INST OF TECH CAMBRIDGE COMPUTER SCIENCE AND ARTIFICIAL INTELLIGENCE LAB, 2004.</p><p>[10] Serre, T., L. Wolf, and T. Poggio. "Object recognition with features inspired by visual cortex." <i>IEEE Computer Society Conference on Computer Vision & Pattern Recognition</i> 2005:994 - 1000.</p><p>[11] Yaghoubi, Zohreh, et al. "Face Recognition Using HMAX Method for Feature Extraction and Support Vector Machine Classifier." <i>Image & Vision Computing New Zealand, Ivcnz 09 International Conference</i> IEEE, 2009:421-424.</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21905116&pixel&useReferer"/>Owl of MinervaMon, 15 Aug 2016 21:51:43 GMT
- 人脸识别:人脑认知与计算机算法<2>https://zhuanlan.zhihu.com/p/21799161<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/868b3e53c6b26b58a4aae7edd56cd5e4_r.png"></p>本篇主题:<i>外在特征</i><i>与内在特征</i>在上一篇(<a href="https://zhuanlan.zhihu.com/p/21772464" class="">https://zhuanlan.zhihu.com/p/21772464</a>)中我们提到了外在特征与内在特征的概念,简单的说,外在特征(external features)指的是头发(颜色、发型)、脸部轮廓、脸颊等,内在特征(internal features)指的是眼睛、鼻子和嘴巴以及它们之间的内在关系 [1]。<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/50e303054a7a0e3aa9cab6f1b13c6c25.png" data-rawwidth="646" data-rawheight="402"><Fig. 全脸(中)、外在特征(左下)与内在特征(右下),源于[1]></p><p>人类视野的分辨率从视野中央往外侧快速下降,因此需要不断的调整注视方向来获取高精度图像,也就是注意力点的变化。同时,人眼运动控制的相当部分是直接由脑干区域的神经核团支配的,也就是说,不受大脑皮层的控制,因此眼动在大部分情况下不进入意识层面,其运动控制表现出对注意力控制的被支配性。通过观测注视(眼动)的变化,可以获知人的注意力的重点 [2],也就是信息获取的关键,眼动因此成为了人类意识的一个易于观测的外显参数 [3]。在我们人类发育的早期,观察人脸首先是注意外在特征多,然后逐步发展的更注意内在特征[4]。当然,这也可能与一岁以下的婴儿的视觉感知情况与更年长者有别有关,两个月以下的婴儿,他/她们的视觉处在一个快速发展的时期——由不清晰到清晰,同时色彩的感知也发生快速的变化[5-7]。</p><p>在成人的人脸识别过程总,内在特征与外在特征所扮演的角色各不相同,一般地,我们认为在识别陌生人脸的过程中,外部特征占有比较重要的作用(或者同等重要),当人脸变得熟悉时,外部特征在人脸识别中的重要性逐渐下降,而内部特种的重要性逐渐升高的主导地位 [8]。通过一些量化参数,我们可以大致的描述内在特征和外在特总在人脑的人脸识别任务中的地位[9, 10]:</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/01c71e8f907e235ec8237020c765bdd8.png" data-rawwidth="737" data-rawheight="404"><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/370b398b46108c1fee073be804acc1bb.png" data-rawwidth="693" data-rawheight="408"><p><Fig. 人脑人脸识别任务中内部特征与外部特征各自的重要性>当然地,一般认为,人脑人脸识别中,内在特征和外在特征是作为一个整体在大脑皮层的相关区域 (Fusiform Face Area, FFA; Occipital Face Area, OFA; Superior Temporal Sulcus, STS)处理,而不是分开的 [11]。</p><p>在计算机人脸识别领域,特别是在深度学习出现以前的使用模型的时代,算法研究一直将重心放在内在特征上 [12],这跟计算机人脸识别的应用场景,以及投入到训练算法中的图像训练集有一定的关系。训练集里的同一个人经常有不同时期不同发型、妆容的图像,易于理解的,算法关注外在特征会降低算法的识别率并增加误识率,这对算法的性能是不利的 [13]。</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/ee79e918afe2feedf61744d4d56fc33f.png" data-rawwidth="683" data-rawheight="237"><p><Fig. Active appearance model, AAM></p><p>当然,也有一些人在外在特征方面做过一些尝试,[14] 中算法先使用训练集训练,得到外在特征块的集合Building Block Set,再使用特征块去匹配测试人脸图像,匹配度最高的Building Block提供了测试人脸特征,从而可以用来进行分类。</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/503dc8aff0291982527c3313396abc29.png" data-rawwidth="679" data-rawheight="420"><Fig.使用外在特征进行人脸识别的样例><p>该算法在当时能做到其他模型接近的精度,证明了外在特征进行人脸识别的可行性。但是如上文所说过的,外在特征天然的不稳定性,并不是做人脸识别的最优信息来源。由于大数据集和深度学习的普遍使用 [15],外在特征在人脸识别算法中被研究人员不自觉的抛弃。新的人脸识别算法对遮挡、发型、妆容、光照这些外在影响的鲁棒性得到了很大的提高,人们对外在特征的关注似乎就到此为止了。</p><p>--------</p><p>[1] Ellis, H. D., J. W. Shepherd, and G. M. Davies. "Identification of familiar and unfamiliar faces from internal and external features: some implications for theories of face recognition. " <i>Perception</i> 8.4(1979):431-9.</p><p>[2] Hsiao, Janet H. "Eye movements in face recognition." <i>Face Recognition</i>(2010): 255-272.</p><p>[3] Rayner, Keith. "Eye movements in reading and information processing: 20 years of research.." <i>Psychological Bulletin</i> 124.3 (1998): 372-422.</p><p>[4] Maurer, Daphne, and P. Salapatek. "Developmental Changes in the Scanning of Faces by Young Infants." <i>Child Development </i>47.2(1976):523-7.</p><p>[5] Atkinson, Janette, Oliver Braddick, and Fleur Braddick. "Acuity and contrast sensitivity of infant vision." <i>Nature</i> (1974).</p><p>[6] Norcia, Anthony M., Christopher W. Tyler, and Russell D. Hamer. "Development of contrast sensitivity in the human infant." <i>Vision research</i> 30.10 (1990): 1475-1486.</p>[7] R Wilson, Hugh. "Development of spatiotemporal mechanisms in infant vision."<i>Vision research</i> 28.5 (1988): 611-628.<p>[8] Ellis, Hadyn D., John W. Shepherd, and Graham M. Davies. "Identification of familiar and unfamiliar faces from internal and external features: Some implications for theories of face recognition." <i>Perception</i> 8.4 (1979): 431-439.</p><p>[9] Hills, Charlotte, et al. "An adaptation study of internal and external features in facial representations." <i>Vision research</i> 100 (2014): 18-28.</p><p>[10] Jarudi, Izzat N., and Pawan Sinha. <i>Relative contributions of internal and external features to face recognition</i>. No. AI-MEMO-2003-004. MASSACHUSETTS INST OF TECH CAMBRIDGE ARTIFICIAL INTELLIGENCE LAB, 2003.</p><p>[11] Andrews, Timothy J., et al. "Internal and external features of the face are represented holistically in face-selective regions of visual cortex." <i>The Journal of Neuroscience</i> 30.9 (2010): 3544-3552.</p><p>[12] Cootes, Timothy F., Gareth J. Edwards, and Christopher J. Taylor. "Active appearance models." <i>European conference on computer vision</i>. Springer Berlin Heidelberg, 1998.</p><p>[13] Zhao, Wenyi, et al. "Face recognition: A literature survey." <i>ACM computing surveys (CSUR)</i> 35.4 (2003): 399-458.</p><p>[14] Lapedriza, Agata, David Masip, and Jordi Vitria. "Face verification using external features." <i>7th International Conference on Automatic Face and Gesture Recognition (FGR06)</i>. IEEE, 2006.</p><p>[15] Yi, Dong, Zhen Lei, and Stan Z. Li. "Towards pose robust face recognition."<i>Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition</i>. 2013.</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21799161&pixel&useReferer"/>Owl of MinervaSat, 06 Aug 2016 21:06:59 GMT
- 人脸识别:人脑认知与计算机算法<1>https://zhuanlan.zhihu.com/p/21772464<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/9ba7ba7243b2618f66268f39b5c4e735_r.jpg"></p><p>本篇主题:<i>静态人脸与动态人脸</i></p><p>在做人脸识别训练方面,人脑认知与计算机算法的第一个不同在于,人类接受的<b>人脸图像训练是多角度的、动态的</b>,而目前<b>计算机算法在训练之中使用的基本上是静态的图片</b>[1]。现有的图像训练数据库,无论是常用的一类公开数据集LFW, CASIA-WebFace, 还是Google和Facebook使用的闭源数据库,即便对同一个人有很多张不同时间和场景的图片,他们都只是截取了有限的角度。</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/f119f32bc4677b8718a309c398bef2d5.png" data-rawwidth="698" data-rawheight="361"><p><Fig. 典型人脸数据集图片></p><p>人类在要认识一个陌生人时,不免需要多观察几眼,特别是对于一个长的美貌/化妆过的人脸,由于更接近平均人脸,外在特征(external features: hair, face, outline)和内在特征(internal features: eyes, nose, mouth) [2] 相对来说不明显,一般需要动态观察更久才能记住。</p><p>实验室条件下的受限环境刺激和训练证明,人类识别/记住一个陌生人脸,使用动态图像比使用静态图片更有优势 [3, 4]:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/6b973a77d85d33f76c130bc0899e62b6.png" data-rawwidth="1002" data-rawheight="505"><Fig. 静态人脸v.s动态人脸></p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/f59376cbce616c940f66f0e1a3f377e7.png" data-rawwidth="677" data-rawheight="391"><Fig. 静态人脸v.s动态人脸任务的反应时间,反应时间越短越好>不难想象的,动态人脸能提供来自更多角度的更多可供识别的信息,即使实验场景下,这些动态人脸提供的信息跟真实场景中的还有一定的差距,但是动态人脸刺激相比于静态人类刺激的优势在实验场景下可观测的。<p>在计算机算法方面,近年来随着深度学习的引入,主流人脸识别算法对训练图像的数量提出了越来越高的需求,动则达到数百万以上,Google 的FaceNet更是达到令人嗔目结舌的20亿数量级[5, 6],但是不开放。传统学术界的实验室算法受限于使用公开数据集,为了达到更好的效果不得不另辟蹊径,在有限的图像上获取更多信息,也就是Data Augmentation [7]. 最简单的Face Data Augmentation无疑是变换图像的左右,但是这种做法有可能已经改变了人脸的内在特征。需要权衡带来的好处(图像数量增加)与缺陷(部分特征可能被抵消)。另一类算法通过模拟人脸在其他视角的图像做Face Data Augmentation. 最初来源于人脸摆正(face frontalization)[8]。</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/917605ee17c2263df65f2903f4ea1de7.png" data-rawwidth="1153" data-rawheight="177"><Fig. [8]中人脸摆正算法流程></p><p>[8] 中算法通过Face Landmark Detector处理目标图像和三维模型图像(二维化之后),得到一组对应的Landmark. 而二维化之后的三维模型上的Landmark({Xi, Yi})在三维模型中具有对应的坐标({Xi, Yi, Zi}). 据此可以估测相机参数,进行相机标定 [9]。从而可以模拟模型与目标图像一样的角度,反过来得出目标图像中像素在摆正之后的位置。</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/4602d32e87c3058cc6656424ac2bef45.png" data-rawwidth="793" data-rawheight="459"><Fig. 相机标定,得出图像坐标(二维)跟世界坐标(三维)之间的对应关系></p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/23c95841aa4c6479112f4699786df755.png" data-rawwidth="624" data-rawheight="276"><Fig. 通过相机标定,可以将图像坐标在不同视角之间变换></p><p>不难理解的,该套算法稍加变化,就可以使用一张人脸图片得出多个角度的人脸图片,即既可以用来做人脸摆正,也可以生成侧脸图像 [10, 11]:</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/9b0c9a1f73f02c765c335b0c4879510f.png" data-rawwidth="1061" data-rawheight="215"><p><Fig. 通过相机标定和3D模型模拟,生成其他视角的人脸图像></p><p>这种做法虽然没有增加投入到训练算法中的信息,但大大增加了算法的识别率并降低了误识率(FAR, False Acceptance Rate):<img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/f7d18f7be140ba56ae2646c55686cd2f.png" data-rawwidth="902" data-rawheight="541"><Fig. 仅仅是通过现有图片生成多个角度(pose)的图片,然后投入训练算法,就能大大增加性能></p><p>当然,生成不同角度的图像更原本就有同一个场景的连续变化视角的图像(视频)对人脸识别来说还是有一些不同的。更为接近自然场景中人脑的人脸识别任务的,是视频中人脸图像的识别。但是目前由于受限于人脸视频的稀缺性(搜集一个人脸的视频比搜集其图片要繁琐的多,同时视频中的特征标定也是一个严重的问题),深度学习/深度神经网络在视频人脸图像的研究还却如。目前在这个领域使用的一般是基于模型的传统算法[12-14]。视频中人脸的分辨率跟目前人脸图像数据及中的分辨率还有一定差距,同时视频图像的噪声更大,场景的复杂度好更高。因此视频中人脸识别跟静态图像中人类识别几乎是用的是完全不同的方法。在结合这两者,应用大量视频图像做人脸识别算法训练之前还得解决以上一系列的技术问题。--------</p><p>[1] Parkhi, Omkar M., A. Vedaldi, and A. Zisserman. "Deep Face Recognition." <i>British Machine Vision Conference</i> 2015.</p><p>[2] Bruce, Vicki, et al. "Verification of Face Identities From Images Captured on Video." <i>Journal of Experimental Psychology Applied </i>5.4(1999):339-360.</p><p>[3] Thornton, Ian M, and Z. Kourtzi. "A matching advantage for dynamic human faces. " <i>Perception</i> 31.1(2002):113-32.</p><p>[4] Graham E. Pike, et al. "Recognizing Moving Faces: The Relative Contribution of Motion and Perspective View Information." Visual Cognition 4.4(2010):409-438.</p><p>[5] Schroff, Florian, D. Kalenichenko, and J. Philbin. "FaceNet: A unified embedding for face recognition and clustering." IEEE Conference on Computer Vision & Pattern Recognition IEEE, 2015:815-823.</p><p>[6] Hu, Guosheng, et al. "When Face Recognition Meets with Deep Learning: An Evaluation of Convolutional Neural Networks for Face Recognition." <i>IEEE International Conference on Computer Vision Workshop</i> IEEE, 2015:384-392.</p><p>[7] Lv, Jiang-Jing, et al. "Landmark perturbation-based data augmentation for unconstrained face recognition." <i>Signal Processing: Image Communication </i>(2016).</p><p>[8] Hassner, Tal, et al. "Effective face frontalization in unconstrained images." <i>Computer Vision and Pattern Recognition</i> IEEE, 2015.</p><p>[9] Hartley, Richard, and Andrew Zisserman. <i>Multiple view geometry in computer vision</i>. Cambridge university press, 2003.</p><p>[10] Masi, Iacopo, et al. "Do we really need to collect millions of faces for effective face recognition?." <i>arXiv preprint arXiv:1603.07057</i> (2016).</p><p>[11] Masi, Iacopo, et al. "Pose-Aware Face Recognition in the Wild." <i>Computer Vision and Pattern Recognition</i> (2016).</p><p>[12] Hadid, Abdenour, and M. Pietikainen. "From still image to video-based face recognition: an experimental analysis." <i>Automatic Face and Gesture Recognition, 2004. Proceedings. Sixth IEEE International Conference on</i>. IEEE, 2004.</p><p>[13] Lee, Kuang Chih, et al. "Video-based face recognition using probabilistic appearance manifolds." <i>IEEE Computer Society Conference on Computer Vision and Pattern Recognition</i> IEEE Computer Society, 2015:I-313-I-320 vol.1.</p><p>[14] Chen, Shaokang, et al. "Face Recognition from Still Images to Video Sequences: A Local-Feature-Based Framework." <i>Eurasip Journal on Image & Video Processing</i> 2011.1(2011):1-14. </p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21772464&pixel&useReferer"/>Owl of MinervaSat, 30 Jul 2016 22:29:02 GMT
- 人脸识别:人脑认知与计算机算法<0>https://zhuanlan.zhihu.com/p/21585862<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/6357ad489139b1099b2e098855dd3884_r.jpg"></p><p>现阶段,人脸识别是人工智能领域最炙手可热的话题之一。Google和Facebook,以及国内一些创业公司都投入重金在该领域进行研发,并且有相当多的商业应用。随着Deep Learning算法的引入,计算机在人脸识别方面的准确率和鲁棒性得到了一个突破性的提高 [1, 2], 计算机算法犯第二类错误(把假当作真,即把非A识别为A)的概率也下降了很多,相比于识别失败率,这个参数在工业场景的应用中可能更为重要,因为他会更直接关系到产品的安全性。计算机人脸识别系统在安全方面的应用因此有了更好的接受度。</p><p>计算机人脸识别的准确率已经超过人类。目前的算法体现出来一些特征,从人脑的人脸认知和识别角度来看,显得非常的有趣。计算机人脸识别算法面对自然场景的人脸识别(Face Recognition in the Wild)问题时仍然有一些困难[3],而这些困难又跟人脑在自然场景做人脸识别时面对的困难又有一些相似和不同。这些问题的根本原因,还是在于计算机与人脑在人脸识别任务上处理的方法,或者说算法原理方面的相似性和不同。</p><p>大略来看,在人脸方面我们可以问以下一类问题:</p><p>1. 人在做人脸识别时候的注意点 跟 计算机算法(特别地,深度神经网络)的“认知”重点有什么差异</p><p>2. 人在做人脸识别的学习过程中,需要的样本数量很多,但是跟深度神经网络训练所需的动则上百万个样本这样一个数量级还是有很大的差距 [4],是什么导致了这个问题</p><p>3. 人脑人脸识别任务的一些低识别率场景是怎么导致的;计算机算法也会面对类似的问题,其原因是什么;两种算法(人脑的识别算法/模型 与 计算机的算法)如何相互参考</p><p>4. 计算机人脸识别算法最新趋势中跟人脑认知的差异</p><p>5. .......</p><p>作为研究人脑多年并转入计算机人脸识别领域的研究者,我发现自己处于这样一个独特的位置:我问出的问题跟这两个领域中的人都不同,但又能同时快速的获取和理解这两个方面的研究问题。因此决定把这个话题写成一个系列,作为我自身工作的总结。这是一个活动的长期系列,其完成没有时间表,所问的问题和所要解决的问题也会不断的扩张。本篇作为这个系列的第0篇仅作初期的预测和介绍,欢迎两方面背景的人赐教(<b>微信: wenmiau</b>).</p><p>--------</p><p>[1] LeCun, Yann, Yoshua Bengio, and Geoffrey Hinton. "Deep learning." <i>Nature </i>521.7553 (2015): 436-444.</p><p>[2] Sun, Yi, Xiaogang Wang, and Xiaoou Tang. "Deep learning face representation from predicting 10,000 classes." <i>Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition</i>. 2014.</p><p>[3] Zhu, Xiangxin, and Deva Ramanan. "Face detection, pose estimation, and landmark localization in the wild." <i>Computer Vision and Pattern Recognition (CVPR), 2012 IEEE Conference on</i>. IEEE, 2012.</p><p>[4] Masi, Iacopo, et al. "Do we really need to collect millions of faces for effective face recognition?." <i>arXiv preprint arXiv:1603.07057</i> (2016).</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21585862&pixel&useReferer"/>Owl of MinervaSat, 23 Jul 2016 11:30:35 GMT
- Owl of Minerva 的 Live —— 音乐认知与教育https://zhuanlan.zhihu.com/p/21675455<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/790647a8a56352b2960e4dc61580bf6a_r.jpg"></p><p>大家好,我是Owl of Minerva. 在第一期Live关注计算神经科学之后,本期我们切换话题为音乐认知与教育,时间为<b>7月27日晚上20:00(周三)</b>。我自 2009 年起从事计算神经科学方面的研究,期间所涉研究范畴甚广,做过的工作包括人类认知、神经系统疾病、神经解剖、图像处理和程序开发,目前主要致力于人工智能算法开发。在研究工作的之余,我一直参与古典音乐方面的室内乐团/交响乐团活动,因此对于音乐认知和教育具有理论和实践方面的经验。</p><p>本次 Live,我将<b>邀请中央音乐学院音乐教育系学生、百度室内乐团常任指挥付悦</b>(Floortje, 在学习之外还进行幼儿音乐教育方面研究和实践 <a href="http://zhihu.com/lives/739415787508359168?source=message" class="" data-editable="true" data-title="https://www.zhihu.com/people/floortje">https://www.zhihu.com/people/floortje-Fy</a>)和大家探讨音乐认知和与之相关的音乐教育(包括音乐早期教育和少儿音乐教育等)、音乐治疗方面的内容。不同与第一次 Live, 本次 Live 将减少晦涩的理论内容,更多探讨音乐实践方面的经验,分享第一手资料。</p><p>本次 Live 主要包括以下问题: </p><p>* 人脑的音乐认知模型</p><p>* 当今音乐教育的基本概念和形式</p><p>* 音乐早期教育的形式和实践,以及对幼儿和儿童的影响</p><p>* 音乐治疗的实践和效果</p><p>* 艺考</p><p>* 其他</p><p>........</p><p>本次话题的面向对象主要为对音乐认知感兴趣的学生;关心孩子早期音乐教育,即将成为父母或刚刚成为父母的人群;琴童的家长;以及其他一切有意了解的人群。</p><p>为了方面你/妳的理解,可以先阅读以下内容进行理论预热:</p><p><a href="https://www.zhihu.com/question/26161319/answer/32352840">https://www.zhihu.com/question/26161319/answer/32352840</a></p><p><a href="https://www.zhihu.com/question/26239985/answer/32601450">https://www.zhihu.com/question/26239985/answer/32601450</a></p><p><a href="https://www.zhihu.com/question/20058299/answer/32694192">https://www.zhihu.com/question/20058299/answer/32694192</a></p><p><a href="https://www.zhihu.com/question/26552019/answer/33470440">https://www.zhihu.com/question/26552019/answer/33470440</a></p><p><a href="https://www.zhihu.com/question/27320358/answer/36953993">https://www.zhihu.com/question/27320358/answer/36953993</a></p><p><a href="https://www.zhihu.com/question/27814738/answer/51032327">https://www.zhihu.com/question/27814738/answer/51032327</a></p><p>Live入口 (请使用手机打开):<a href="http://zhihu.com/lives/739415787508359168?source=message" class="">http://zhihu.com/lives/739415787508359168?source=message</a></p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21675455&pixel&useReferer"/>Owl of MinervaThu, 21 Jul 2016 22:16:27 GMT
--------------------------------------------------------------------------------
/zhihu/zhuanlan/AI/OPML.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AI - 知乎专栏
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/zhihu/zhuanlan/AI/Stark.xml:
--------------------------------------------------------------------------------
1 |
2 | 机器鼓励师手册 - 知乎专栏https://zhuanlan.zhihu.com/Stark我们陪伴着机器成长,我们见证着机器成长Sat, 11 Mar 2017 22:17:42 GMTRickyhttp://blogs.law.harvard.edu/tech/rss- 氰化物!不怕,我教你怎么检测~~https://zhuanlan.zhihu.com/p/23676412<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/v2-d9e77fb16ae27912a141ab658aa236d4_r.jpg"></p>氰化物对人体是非常有害的。氰化物进入人体后析出氰离子,与细胞线粒体内氧化型细胞色素氧化酶的三价铁结合,阻止氧化酶中的三价铁还原,妨碍细胞正常呼吸,组织细胞不能利用氧,造成组织缺氧,导致机体陷入内窒息状态。<p>工业排放的污水往往会含有氰化物,如果污染了饮水源,那就......</p><p>我最近看了一篇检测液体中氰化物的论文,分享一下。</p><h2>检测原理</h2><p>文章提出可以用一种银芯金壳的纳米粒子去跟氰化物反应,然后通过反应后的颜色来判断氰化物的浓度。原理上是比较简单的,先看下图</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/v2-32003df2fbac2a7cc3a6e2f5b27895f4.png" data-rawwidth="973" data-rawheight="286"><p>左边的大球就表示一个银芯金壳纳米粒子。氰化物可以与金、银反应,由于金涂在粒子表层,所以金会先反应,然后再和银反应,最后能消耗多少金银,就看氰化物的浓度了。而粒子的厚度被消耗了多少,在颜色上会反映出来,所以我们就可以通过颜色来判断氰化物的浓度啦。</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/v2-618436c5519cc312efb65b1d9267626b.png" data-rawwidth="884" data-rawheight="195"><p>上图就是不同浓度的氰化物液体在充分反应后的颜色,从左到右浓度依次变大,颜色就从紫、到橙、到黄、再逐渐到无色。</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/v2-72c9f852e50f70aa01e32d5638afcd88.png" data-rawwidth="545" data-rawheight="42"><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/v2-cfeba3791316b98040968c741b55e981.png" data-rawwidth="534" data-rawheight="29"><p>以上是金和银与氰化物的反应式子。</p><h2>合成银芯金壳纳米粒子</h2><p>硝酸银和硼氢化钠反应得到银纳米粒子。</p><p>四氯金酸和盐酸羟胺反应得到的金涂在银纳米粒子上,合成银芯金壳纳米粒子。</p><h2>聚山梨酯40功能化</h2><p>为了使检测液可以在污水(高盐环境)中对氰化物进行检测,需要对粒子进行聚山梨酯40的功能化。</p><p>聚山梨酯40(100uL)和胶体银芯金壳纳米粒子(10mL)在室温下混合12小时即成。</p><p>题外话:</p><p>万一哪天我们一帮人掉落到了一个星球,我们要重新打造工业文明,这个时候我们工程师就责无旁贷了。所以还是多学点东西好^_^</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23676412&pixel&useReferer"/>Stark EinsteinTue, 15 Nov 2016 12:53:16 GMT
- RNN Encoder–Decoder的attention机制简介https://zhuanlan.zhihu.com/p/22081325<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/fe65dc8624df67eadb75e86f0214642b_r.png"></p>先贴原paper:<p><a href="http://arxiv.org/pdf/1409.0473v7.pdf" data-editable="true" data-title="NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE" class="">NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE</a></p><p>对读者要求:</p><p>对RNN和Encoder–Decoder有基本的了解。</p><p>背景介绍:</p><p>神经网络在机器翻译里面比较有名的模型之一就是Encoder–Decoder了,然而在attention机制出来之前,神经网络方法还是没有真正达到传统方法的水平的,用神经网络搞翻译这帮人只敢说“我们还在研究之中~~”。有了attention机制之后,这帮人终于可以扬眉吐气了,神经网络方法做翻译总算敢说超越传统方法了。(这些故事是一位NLP界的同学跟我吹牛时说的,我反正是信了)</p><h2>一、原来的Encoder–Decoder</h2><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/22c17d3f5c59d3b28cbf4018be244b6c.png" data-rawwidth="290" data-rawheight="275">在这个模型中,encoder只将最后一个输出递给了decoder,这样一来,decoder就相当于对输入只知道梗概意思,而无法得到更多输入的细节,比如输入的位置信息。所以想想就知道了,如果输入的句子比较短、意思比较简单,翻译起来还行,长了复杂了就做不好了嘛。</p><h2>二、对齐问题</h2><p>前面说了,只给我递来最后一个输出,不好;但如果把每个step的输出都传给我,又有一个问题了,<b>怎么对齐</b>?</p><p>什么是对齐?比如说英文翻译成中文,假设英文有10个词,对应的中文翻译只有6个词,那么就有了哪些英文词对哪些中文词的问题了嘛。</p><p>传统的翻译专门有一块是搞对齐的,是一个比较独立的task(传统的NLP基本上每一块都是独立的task啦)。</p><h2>三、attention机制</h2><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/83fe9a9132decae0cb49757f267e7836.png" data-rawwidth="216" data-rawheight="302">我们从输出端,即decoder部分,倒过来一步一步看公式。</p><equation>S_{t} =f(S_{t-1} ,y_{t-1} ,c_{t} )</equation> (1)<p><equation>S_{t}</equation>是指decoder在t时刻的状态输出,<equation>S_{t-1}</equation>是指decoder在t-1时刻的状态输出,<equation>y_{t-1} </equation>是t-1时刻的label(注意是label,不是我们输出的y),<equation>c_{t} </equation>看下一个公式,<equation>f</equation>是一个RNN。</p><equation>c_{t} =\sum_{j=1}^{T_{x}}{a _{tj} h _{j}} </equation> (2)<p><equation> h _{j}</equation>是指第j个输入在encoder里的输出,<equation>a _{tj}</equation>是一个权重</p><equation>a_{tj} =\frac{exp(e_{tj} )}{\sum_{k=1}^{T_{x} }{exp(e_{tk})} } </equation> (3)<p>这个公式跟softmax是何其相似,道理是一样的,是为了得到条件概率<equation>P(a|e)</equation>,这个<equation>a </equation>的意义是当前这一步decoder对齐第j个输入的程度。</p><p>最后一个公式,<equation>e_{tj} =g(S_{t-1} ,h_{j})</equation> (4)</p><p>这个<equation>g</equation>可以用一个小型的神经网络来逼近。</p><p>好了,把四个公式串起来看,这个attention机制可以总结为一句话,“当前一步输出<equation>S_{t} </equation>应该对齐哪一步输入,主要取决于前一步输出<equation>S_{t-1} </equation>和这一步输入的encoder结果<equation>h_{j}</equation>”。</p><p>我当时看了这个方法的感受是,计算力发达的这个年代,真是什么复杂的东西都有人敢试了啊。这要是放在以前,得跑多久才能收敛啊......</p><p>神经网络搞NLP虽然还有诸多受限的地方,但这种end-to-end 的one task方式,太吸引人,有前途。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/22081325&pixel&useReferer"/>Stark EinsteinFri, 19 Aug 2016 13:11:36 GMT
- 非负矩阵分解(NMF)简介https://zhuanlan.zhihu.com/p/22043930<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/35b21515a5af8d9660b7aa662f9ef166_r.jpg"></p><h2>什么是非负矩阵分解?</h2><p>非负矩阵分解,顾名思义就是,将非负的大矩阵分解成两个非负的小矩阵。</p><p><equation>V\approx WH</equation> (1)</p><p>回顾矩阵分解本身,在<equation>R^{n} </equation>空间分布的一堆数据有它们分布的某些规律,那么找一组更能直观反映这种规律的基,再把原来的数据投影到这组基上表示,这样就能便于后续的应用,比如分类等。</p><p>公式(1)中的V是一个n*m维的矩阵,其中每一列就是<equation>R^{n} </equation>空间中的一个向量,共m个向量;W是一个n*k维的矩阵,即k个基;H是k*m的矩阵,每一列为V投影到W上得到的向量。</p><p>那么非负和其它的有什么不同呢?下面我就盗一张图来直观地展示几种矩阵分解方法的效果差异。(出自<a href="http://www.cs.wustl.edu/~zhang/teaching/cs517/Spring12/CourseProjects/nmf-Lee1999.pdf" data-editable="true" data-title="Lee and Seung (1999)" class="">Lee and Seung (1999)</a>)</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/56079895270388df370b8643f3537dee.png" data-rawwidth="579" data-rawheight="867">其中original原图即为V中的一列;等式左边第一块是W,其中的每一小块是W的一列;等式左边第二块是H的一列;等式右边的图像是左边相乘还原得到的与original相对应的一个向量(只不过显示成二维图像)。</p><p>图中就对比了三种方法的区别。</p><p>VQ的约束是要求H的每一列只有一个元素为1,其它为0,因此相当于将m个数据归纳成了k个代表,原数据映射过去就是取k个基当中与原向量距离最小的来重新表示。所以VQ的基都是一张张完整正常的脸,它们都是最具代表性的脸。</p><p>PCA大家用得比较多,就是求一组标准正交基,第一个基的方向取原数据方差最大的方向,然后第二个基在与第一个基正交的所有方向里再取方差最大的,这样在跟前面的基都正交的方向上一直取到k个基。所以PCA的基没有直观的物理意义,而且W和H里面的元素都是可正可负的,这就意味着还原时是用W的基加加减减得到的。</p><p>NMF因为约束了非负,所以只准把基相加,不能相减,这就意味着基与基是通过拼接组合来还原原象的。所以我们可以看到NMF的每个基实际上在表示着脸部的某个部件,这种性质在许多场景上就有了它特有的用处了。</p><p>我们换个角度来想像一下这三种情景。</p><p>VQ其实就像kmeans,它的基都落在原数据的最具代表性的位置上。</p><p>PCA的基则是指向四向八方的,相互正交着。</p><p>NMF的原数据首先就是只分布在非负子空间里面的,然后它的基则在这个非负子空间靠近边缘的区域,像一组长短不一、间隔不一的伞骨。</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/33a2a5933596e366bf0ef4a4540db498.png" data-rawwidth="502" data-rawheight="491"><h2>怎么分解?</h2><p>这是个有界优化问题</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/7f9cc6c6fd07501f7dd18362b69160ca.png" data-rawwidth="528" data-rawheight="118"><p>所以最直观的最简单的方法就是</p><p><b>方法一</b>:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/5052be4c78557e24a93756c0f45d2656.png" data-rawwidth="384" data-rawheight="99">嗯,真是简单到几行代码就搞定了,而且跟原问题保持一致。</p><p>我们看标准的有界优化问题</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/1830b65f687838577657bd5e6c78fdde.png" data-rawwidth="393" data-rawheight="95">标准的解法</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/7e0d920f064aa60fe14fa4e47533745f.png" data-rawwidth="344" data-rawheight="206">所以我们方法一是按套路出牌的。</p><p>但是,作为有追求有理想的同学们,<a href="http://www.cs.wustl.edu/~zhang/teaching/cs517/Spring12/CourseProjects/nmf-Lee1999.pdf" data-editable="true" data-title="Lee and Seung (1999)" class="">Lee and Seung (1999)</a>认为方法一不够好,要来点更快的。</p><p><b>方法二</b>:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/bfdada349afd5e7d2c9b80fca9a2f655.png" data-rawwidth="461" data-rawheight="134">这个又叫<b>乘法更新法</b>,因为人家用了乘法......</p><p>推导起来有点麻烦,但写起代码来也是相当简单,几行代码足矣,而且收敛比方法一快一些。</p><p>但是,作为有追求有理想的同学们,林智仁(没错,就是搞libsvm那个林智仁)<a href="http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=ACAE3131E5FA09D0798DF7D967F42000?doi=10.1.1.538.997&rep=rep1&type=pdf" data-editable="true" data-title="C Lin(2007)" class="">C Lin(2007)</a>摇摇头,“看我的”。</p><p><b>方法三</b>:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/000926c920d1a3522f20504bfdca9d6d.png" data-rawwidth="1020" data-rawheight="313">传说中这个方法是快了一些,然而我觉得有方法一和二就妥妥了,像现在这么强计算力的时代,计算省下来那点时间,还抵不回写这复杂代码多花的时间。</p><p>林智仁这篇文章<a href="http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=ACAE3131E5FA09D0798DF7D967F42000?doi=10.1.1.538.997&rep=rep1&type=pdf" data-editable="true" data-title="C Lin(2007)" class="">C Lin(2007)</a>是后期出来的,review了之前几种主流的方法,再提出自己的新方法,所以这篇的内容比较全(懒人只看这一篇就够了)。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/22043930&pixel&useReferer"/>Stark EinsteinWed, 17 Aug 2016 00:43:43 GMT
- 《计算广告》读书笔记https://zhuanlan.zhihu.com/p/20733024<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/462b080d7f7b949cd917fe44789b6894_r.jpg"></p><p>在线广告是我们生活常见的商业中极为重要的一部分。对我们互联网行业算法从业人员来说,广告也是最为常见的业务之一。挑了这本国内计算广告领域名气最大的书《计算广告》刘鹏----其实是我实在没搜到其它像样的......</p><p><u>本文非常多私货,完全不能代表原书,有兴趣可以亲阅原书哈。</u></p>这本书的结构是非常好的,分三大部分,第一部分讲行业背景知识,第二部分讲产品逻辑,第三部分讲关键技术。逻辑非常清晰,宏观微观兼顾得到位,干货十足, 不愧是行业老兵写的,而且丝毫没有夸夸其谈的成分。<h2><b>第一部分 广告市场与背景</b></h2><p><b>什么是广告?</b></p><blockquote> 广告的根本目的是广告主通过媒体达到低成本的用户接触。----《当代广告学》</blockquote><p>什么是广告呢?作者对广告的理解是,一切付费的信息、产品或服务的传播渠道,都是广告。互联网广告有,横幅广告、富媒体广告、文字链广告、视频广告、社交广告、移动广告、邮件定向营销广告,更宽泛地,团购、游戏联运、固定位导航、返利购买等等,都属于这个范畴。这些都是我们生活中天天见的东西,大量互联网业务营利的重要组成部分就是这些了。</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/a842b63d7a380a0a4d281aa594ad4198.png" data-rawwidth="360" data-rawheight="360">我们来对比一下互联网广告和传统广告。传统广告主要是纸媒、电视、街上各种广告牌(和电线杆上的牛皮藓)等等。互联网广告相比传统广告的优势在于,<b>低成本的定向、方便的竞价、方便的投放、可衡量的效果</b>。尤其是现在的数据越来越丰富,定向的精准度是越来越高的。<p><b>大数据与在线广告的关系</b></p><p>作者从数据量与应用效果的关系将数据问题分为三类:</p><p> A类,数据量小的时候(采样率低)效果会很差,比如个性化推荐和计算广告。如果只采样到一小部分人的数据就无法对所有人都做到精准。</p><p> B类,数据量大到一定规模以后,再增加数据的效果提升不明显,比如文本主题模型。</p><p> C类,数据量比较小的情况下也能达到满足应用需求的效果。比如你用excel就能搞定的问题。</p><p>计算广告就属于A类问题,在大数据这个词都烂大街了的今天,计算广告的相关技术是相当的成熟了。某程度上来说,计算广告是推动大数据发展的极为重要的力量。大数据的发展也让这类应用的效果越来越有商业价值。</p><p><b>有效性原理</b></p><p><img rel="noreferrer" data-rawheight="89" data-rawwidth="570" src="2f855cc9209a8c1fa7675d41eefed1b1.png">有这张图,貌似也不用我说什么了,相信你看这张图的时候也会点点头的,广告对我们产生作用的过程就是这样子了。</p><p><b>结算方式</b>--CPM、CPC、CPS/CPA/ROI、CPT </p><p><img rel="noreferrer" data-rawheight="245" data-rawwidth="712" src="0f990dfacb79fc333fbc5dff1f37acb0.png"><b>CPT</b>是按时间收费,财大气粗的大品牌会选择这种强曝光的方式来强刷存在感,几乎不定向受众,而是定时间。</p><p><b>CPM</b>按千次展示收费,通常也是品牌广告比较适用这种收费方式,比如有时候打开爱奇艺首页可能会看到奔驰或者CHANAL的广告。这种方式可以做一定程度的受众定向,但是受众划分不会太细,否则就达不到高曝光的目的了。</p><p><b>CPC</b>按点击次数收费,与前面的方式相比,CPC使广告平台方与需求方分摊了风险。因为要点了才能赚钱,那如果广告平台对广告投放的点击预测不准的话,广告平台自己就会损失;而需求方只会为实实在在的点击付费,不必再独自去承担投放选择的效果差异带来的损失风险。主流的收费方式是这种,因为风险分摊合理、接入方便灵活、投放精准。</p><p><b>CPS/CPA/ROI</b>,叫法比较多,总的来说就是广告平台向广告商拿分成,比CPC更加绑定广告商的收益。这种方式比较少见,比较多是有战略合作意义的情况,要么多数就是垂直广告。</p><p><b>效果监测</b></p><p>作为广告商,我怎么知道广告平台有没有坑我呢,展示或者点击八百次收我一千次的钱怎么办。所以第三方监测公司应运而生,来给曝光量、点击量等指标作技术核实。</p><p><b>第二部分 在线广告产品逻辑</b></p><p>这部分主要讲:合约广告、搜索与竞价广告、程序化交易广告、移动互联与原生广告。</p><p><b>1. 合约广告</b></p><p>首先是CPT广告,这种基本上就是线下广告的业务逻辑照搬到线上,由广告代理公司和媒体签协议,定时间段定费用。对技术依赖小,只需要简单的广告排期系统(比如某度广告管家)。</p><p>CPM虽然也是合约广告,但有进步之处,就是售卖对象从“广告位”进化到了“广告位+人群”。技术上增加的主要复杂度在于,多个合约对投放系统提出的量的约束。</p><p><img rel="noreferrer" data-rawheight="261" data-rawwidth="767" src="49af625809b54a8971d92dfabe628570.png"><b>定向投放</b>是一种里程碑式的进步,因为像乱枪打鸟式的投放只有土豪才玩得起,有了定向之后,小玩家的投入产出比才能达到可进入的程度。下面列举一些典型的定向方式。</p><p> (1)地域定向。几乎是广告系统必支持的方式。比如我开店只卖江浙沪,那当然只在江浙沪地区投广告啊。</p><p> (2)人口属性定向。包括年龄、性别、教育程度、收入水平等。这种特征是比较客观的,相对兴趣标签来说,但不得不说这种数据也是挺脏的,错假数据多,而且缺失数据特别多,要花大量工夫在洗数据和补数据上。虽然这种方式的效果不是非常突出,但是传统广告商熟悉啊,还是要侍候的。</p><p> (3)频道定向。适用于离转化需求比较近的垂直类媒体,比如汽车、母婴、购物导航等。</p><p> (4)上下文定向。根据网页的具体内容来匹配相关广告。这种方式的覆盖率高,因为相比用户信息之类,网页内容是最容易得到的。</p><p> (5)行为定向。根据用户的历史访问行为了解用户兴趣然后进行相关广告投放。跟上下文定向不同的是,上下文定向比较能反映用户的实时意图; 而行为定向就是把用户访问过的内容抽象出来作为这个用户的特征,可以用来表达描述用户的长期兴趣。</p><p> (6)精确位置定向。利用基站、GPS、WIFI等方法,得到用户比较实时的精确的地理位置,使得大量区域性非常强的小广告主(如餐饮、美容等)可以进来玩广告。</p><p> (7)重定向。就是给老客再投广告。这种方式的转化率往往是很突出的。</p><p> (8)新客推荐定向。利用算法预测用户是否潜在客户,老客是一种比较有效的信息可用于算法的学习。</p><p> (9)团购。作者认为这是一种变相的广告形式。一般这种广告主是有区域性的,所以我们看到的团购基本上都是以城市划分甚至以城区划分的。团购主要是用价格诱惑,降低用户在决策阶段的门槛,对价格敏感的用户转化效果相当明显。</p><p><b>受众定向标签体系</b></p><p>看了作者对标签体系的介绍,说说我的见解。</p><p>在大数据玩得飞起的今天,虽然可以用非常稀疏的高维用户特征、用非常酷炫的模型,但是标签体系还是有它一时半会难以取代的优点。首先是解释性强,广告商能看懂,这就比较容易接受。然后,标签其实是一种经过抽象出来的带有某些现实意义的粗粒度特征,拟合度当然会相对低于高维原始特征,但是泛化能力往往是不错的。</p><p><b>流量预测</b></p><p>对于CPM来说,广告位是确定的,流量是未知的,那就需要去预测流量。预测流量有三个用途:</p><p> (1)售前指导,供应方需要自己的供应量才能去接合适量的广告回来投放。不然,供应量严重多于接回来的广告就亏了,或者接的广告严重多于供应量就要违约了。</p><p> (2)在线流量分配。有的流量会同时适合多个合约,就要合理分配这些流量,从而保证合约都能被满足。</p><p> (3)出价指导。竞价广告没有量的保证,广告主需要预计什么价格能得到多少流量来决策出价。</p><p><b>流量塑形</b></p><p>有些情况下,我们可以主动影响流量,利于合约的达到。典型的就是门户网站,它们的流量严重依赖于链接的位置。比如在车展期间,汽车广告需求旺盛,把汽车频道放到流量大的位置上,呵呵,一本满足。</p><p><b>在线分配</b></p><p>前面流量预测就说到了在线分配。当标签越多时,重叠流量就越少,对流量预测的精度要求就越高。所以标签越丰富,合约广告越难玩,竞价广告就更有价值。作者没有详细谈这部分,我也作不下去了。</p><p><b>2. 搜索与竞价广告</b></p><p><b>2.1 搜索广告</b></p><p>在互联网广告的整个产品谱系中,搜索广告有着特殊重要的地位,它的特点在于:一、搜索能够非常直接地反映用户的意图;长相和自然的搜索内容很接近,用户更容易接受;发展起来与之相适应的高效竞价交易模式。这些特点导致其变现能力最强。</p><p>按预测点击率和出价的乘积排序,决定广告透出的位置。所以想让自己的广告出现在好的位置,单纯的高出价不是最有效的,还要高质量的广告内容能够吸引到用户点击。</p><p><b>2.2 位置拍卖与机制设计</b></p><p><b>定价方法</b></p><p><b><i>广义第二高价</i></b>。简单理解就是出价最高者只需要支付比第二高价多一点点的价格。比如,A出价5块,B出价3块,结果就是A以3.1块拿下。这样一来就解决了大家一门心思去压价的问题,反正不管出多高的价,最终只需要给老二那个价格,竞价竞赢最重要。同理,老二按老三的出价给钱,老三按老四的出价给钱。结果广告平台能赚更多。在多位置拍卖时,这种方法不是理论上最优的,但还是比较容易操作,所以采用这种方法还是最常见的。</p><p><b><i>VCG定价。</i></b>这个定价是Vickrey、Clarke和Groves研究出来的,所以这样取名......对于赢得了某个位置的广告主,其所付出的成本应该等于他占据这个位置给其他市场参与者带来的价值损害。在单广告位拍卖的情况下,VCG和第二高价策略是等价的。这种定价向广告主收取的费用其实是最少的。虽然看起来很好,但它没有成为主流。首先是太复杂,跟广告主扯不清楚;然后是媒体计算的“给其他市场参与者带来的价值伤害”的正确性很难验证。Facebook是用这个方法的。</p><p><b>市场保留价</b></p><p>为了控制广告的质量和保持一定的出售单价,往往要设一个拍卖最低价,这个价格就叫市场保留价(MRP)。MRP定得过低或者过高都不利于收益最大化。广告主竞争得比较猛的时候,MRP可以定高一点。可以对整个市场采用同样的MRP,也可以对不同的标的物(比如关键词)设不同的价格。</p><p><b>价格挤压</b></p><p>基本的收益公式:<equation>r=\mu \cdot bid_{CPC} </equation></p><p>加入价格挤压因子的收益公式:<equation>r=\mu ^{\kappa } \cdot bid_{CPC} </equation></p><p><equation>\mu </equation>是点击率,<equation>bid_{CPC} </equation>是出价,基本的收益就是点击率和出价的乘积。</p><p>价格挤压因子<equation>\kappa </equation>越大,越以点击率为主导去决定广告排序;反过来,因子越小,越以出价为主导去决定广告排序。</p><p>当广告主竞争比较猛的时候,我们平台方是卖方市场,就可以调高挤压因子,从而提高用户体验(用户越愿意点击相当于体验质量越好嘛);当竞争不够的时候,为了赚钱,只好牺牲一下用户体验了,调低挤压因子,鼓励价格竞争。</p><p><b>2.3 广告网络</b>竞价广告在搜索广告上用爽了,展示广告的流量也就开始进入竞价广告平台了,催生了广告网络。流量大的网站会以合约的方式出售展示广告,剩余的流量再流入广告网络;流量小的网站干脆就全部流量流入广告网络,懒得自己去拉广告合约。</p><p>广告网络的投放对媒体方而言是一个黑盒,只需要在广告位的剩余流量上调用广告网络的投放代码或SDK,不用关心每次展示的投放结果。</p><p>广告网络的标的主要是人群,广告位被淡化了。</p><p>广告网络的广告主一般是要先充值的,合约广告则是结束后付费的,所以用广告网络对运营方现金流也比较有保障。</p><p>产品案例:Google Display Network、阿里妈妈旗下的淘宝联盟。</p><p><b>3. 程序化交易广告</b></p><p>前面所讲的广告交易平台,叫ADX。其实相应的采买方或者说需求方的平台没有展开来讲,叫DSP。</p><p>ADX卖广告资源,DSP买广告资源。如果没有DSP,广告主要自己去面对ADX,去做复杂的购买决策,而且还难以达到像DSP能达到的那样好的效益。所以将DSP理解为一个智能的广告资源购买平台就可以了。</p><p>不管是ADX还是DSP,都要精准的定向和点击率预测,而决定性的因素是什么呢?是数据的来源与质量。可以重点关注的是以下几类数据。</p><p>(1)用户标识。顾名思义,就是一种用于识别用户的数据。</p><p> 对浏览器行为,最常用的就是cookie。对于同时有多个浏览器、cookie过期或用户主动清cookie的情况,一致性就是一个问题。好在如果运营广告业务的域名同时提供诸如电子邮件、SNS之类的永久身份标识,就可以对cookie做一致性的改善(cookie映射)。</p><p> 移动端,ios与android的用户ID有所不同。ios有苹果专门设计的用户标识符(Identifier for Advertising,IDFA),性质与cookie类似。android没有专门的广告用户ID,一般采用android ID或IMEI(international mobile equipment identity)。</p><p> 高质量的用户标识数据非常有价值,所以在市场上是可以卖的。</p><p>(2)用户行为。按照对广告的有效性分类,可以分为决策行为、主动行为、半主动行为和被动行为。</p><p> 决策行为主要是转化和预转化。比如电商网站上,下单就是转化,下单前的搜索、浏览、比价、加入购物车等准备工作就是预转化。这类数据虽然量不大,却是价值最高的。</p><p> 主动行为主要是广告点击、搜索。</p><p> 半主动行为主要是分享和网页浏览。这类数据,量最大,直接效果不明显,但是有很大的挖掘价值。</p><p> 被动行为主要是广告浏览。比如说给你看了好多次汽车类广告,你一次都没点进去,这可以说明你对汽车不感兴趣嘛。所以这类数据通常是作为负样本来让模型学习。</p><p>(3)人口属性。人口属性是很常用的定向标签,数据来源很重要。一般来说,实名身份绑定的服务可以获得这种信息。而得不到高质量数据的部分属性就要做缺失补全了。比如可以用语音服务记录的声音信号来判别男女。</p><p>(4)地理位置。不同精度,不同用法。IP可以精确到城市;GPS或蜂窝可以精确到几百米,餐饮之类的线下业务可以用得上。</p><p>(5)社交关系。物以类聚,人以群分。当一个人的兴趣数据不足的时候,可以用他朋友的数据平滑过来,作为长期稳定的基础数据是可以,但用于短时的购买兴趣就不太适用。</p><p><b>4. 移动互联与原生广告</b></p><b>原生广告</b>并没有非常严格的定义,软文、搜索广告、社交网络信息流等都有一些原生广告的意味。将商业化内容和非商业化内容混在一起,从形式上难以区分的,都可以叫原生广告。所以有句话叫,内容即广告。<p>信息流广告。典型的就是微信朋友圈,朋友发的消息中间夹着几条推广广告,不仔细看你没发现它是广告呢。信息流里面插广告的好处是,信息流的各条内容本身就没有什么相关性,广告插进去不会显得突兀,对用户体验的伤害不大。</p><p>搜索广告。某度最爱干的,搜个东西,前面好多条是广告,不仔细看还不容易认出来那是广告还是搜索内容。反正我是经常不小心点进去才发现是广告,然后被恶心一把。</p><p>软文广告。经常看*嗅、*氪之类的媒体,你一定很清楚,软文太多了,有的还不容易辨别。</p><p><b>移动广告</b>随着移动设备的爆发式增长而迅猛成长,虽然流量红利已经够让人狂欢了,但是作为富于求知精神的我们还是要去关注移动广告本身的特点的。</p><p>(1)情境广告的可能性。移动设备一天到晚呆在我们身边,对我们的地理位置、生活状态、需求意图等都可以有更加深入的获知。那么就可以不仅仅根据兴趣推送商品了,完全有可能做到从情境和意图出发。比如下午下班了,就应该赶紧推送各种餐馆各种美食嘛;周五到了,就可以推送一泊二日的周末度假游之类的。</p><p>(2)大量潜在的本地化广告主。因为精准的地理信息和情境获知的能力,线下附近的商家就有能力通过这种富有针对性的广告推广来导流到线下,广大的本地商家终于可以翻身做广告主了。</p><p>下面列举一下移动广告的形式。嵌入到APP的横幅和插屏;开屏、锁屏;推荐墙、积分墙;还有最近某国产手机把广告做到了天气栏上了。嵌入到APP的广告,通常有点击率虚高、转化较差的问题。开屏是打开APP时出现的全屏广告,品牌价值高,通常以合约方式卖。</p><p>移动广告也面临着很多问题。</p><p>首先就是<b>数据的割裂</b>。这个问题在车品觉的《决战大数据》里也强调过。比如你上班的时候,用电脑看了几个网页,然后老板叫你去开会,你在玩手机,开完会再回来用电脑看你的淘宝。这样一来,数据就失去了连贯性,对用户行为分析带来了巨大的困难。</p><p>第二个问题是PC时代的广告主<b>移动化还不够</b>,无法充分消化广告带来的流量。比如PC端的落地页如果照搬到移动端的话,用户体验会非常差,这样就会造成较高的跳失率。</p><p>第三是移动广告产品形态需要一次革命。移动端的屏幕这么小,广告和内容分开放在不同的单元的话,用户体验太差。要解决这种广告与内容的对立问题,<b>要原生化</b>。</p><p>终于......讲到技术了。感觉好累,就算我有力气继续写,估计你也没力气看了。</p><p>计算广告的关键技术留到下一篇吧。</p><img rel="noreferrer" data-rawheight="411" data-rawwidth="324" src="5e7074408822929a55a365f31249af0c.jpg"><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/20733024&pixel&useReferer"/>Stark EinsteinTue, 26 Apr 2016 19:25:03 GMT
--------------------------------------------------------------------------------
/zhihu/zhuanlan/AI/coding-future.xml:
--------------------------------------------------------------------------------
1 |
2 | 程序员山居笔记 - 知乎专栏https://zhuanlan.zhihu.com/coding-future主要和编程、算法有关,希望未来能有闲情逸致加上高级扯淡的内容。Sat, 11 Mar 2017 22:17:33 GMTRickyhttp://blogs.law.harvard.edu/tech/rss- 100行Python为Prisma化的图片恢复原始色彩https://zhuanlan.zhihu.com/p/21836208<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/4791027d7e93c79278d616f3dae224c7_r.jpg"></p><p>首先感谢评论区中多位图像大牛指出的问题,代码并未把一张图片加上Prisma的效果,而是一个类似于Prisma的后处理。文章和标题都已作修改,如发现其他问题,欢迎指教,谢谢。</p><p>----------------- 正文分割线 -----------------</p><p>图像被<a href="https://deepart.io/" data-editable="true" data-title="Deepart">Deepart</a>等类似Prisma的工具处理后,可以加上各种风格。但可能存在一个问题,即原始图片的颜色也丢失了,例如:</p><p>纽约夜景图片 --</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/2d0076cdfc1d57db127997bfde942fbd.jpg" data-rawwidth="600" data-rawheight="338"><p>毕加索风格图片 --</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/ba14b947b225d9e5c59520a814376944.jpg" data-rawwidth="1179" data-rawheight="1536">合成图片 --</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/0d4e420fbb6aa742a7873ac3b0a6913c.jpg" data-rawwidth="600" data-rawheight="338"><p>合成后的图片中,原始图片的颜色丢失掉了,下面有一个简单的办法,可以将合成图片的样式与原始图片的色彩合成,让图片既具有毕加索的风格,又保留原图的颜色。</p><p>--- <a href="https://github.com/pavelgonchar/color-independent-style-transfer" data-editable="true" data-title="源代码传送门" class="">Github传送门</a> ---</p><p>效果如下:</p><p>重新处理后的毕加索风格纽约夜景图片 --<img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/4791027d7e93c79278d616f3dae224c7.jpg" data-rawwidth="600" data-rawheight="338"></p><p>--- 下面是代码和注释 ---</p><p>首先加载以下库:</p><pre><code lang="python">import skimage.io
3 | import tensorflow as tf
4 | from tensorflow.python.framework import ops, dtypes
5 | import numpy as np
6 | from matplotlib import pyplot as plt
7 | </code></pre><p>定义一些常量:</p><pre><code lang="python">flags = tf.app.flags
8 | FLAGS = flags.FLAGS
9 |
10 | """ minsk.jpg是原始图片文件(338 * 600) """
11 | flags.DEFINE_string('original', 'New_York_night.jpg', 'Original Image')
12 | """ tmp_950_color.jpg是包含某种风格的图片文件(338 * 600) """
13 | flags.DEFINE_string('styled', 'New_York_night_picasso.jpg', 'Styled Image')
14 |
15 | """ Tensor占位符,后面用Feed来计算 """
16 | original = tf.placeholder("float", [1, 338, 600, 3])
17 | styled = tf.placeholder("float", [1, 338, 600, 3])
18 | </code></pre><p>定义互转RGB和YUV格式的方法:</p><pre><code lang="python">def rgb2yuv(rgb):
19 | """
20 | Convert RGB image into YUV https://en.wikipedia.org/wiki/YUV
21 | """
22 | rgb2yuv_filter = tf.constant(
23 | [[[[0.299, -0.169, 0.499],
24 | [0.587, -0.331, -0.418],
25 | [0.114, 0.499, -0.0813]]]])
26 | rgb2yuv_bias = tf.constant([0., 0.5, 0.5])
27 |
28 | temp = tf.nn.conv2d(rgb, rgb2yuv_filter, [1, 1, 1, 1], 'SAME')
29 | temp = tf.nn.bias_add(temp, rgb2yuv_bias)
30 |
31 | return temp
32 |
33 |
34 | def yuv2rgb(yuv):
35 | """
36 | Convert YUV image into RGB https://en.wikipedia.org/wiki/YUV
37 | """
38 | yuv = tf.mul(yuv, 255)
39 | yuv2rgb_filter = tf.constant(
40 | [[[[1., 1., 1.],
41 | [0., -0.34413999, 1.77199996],
42 | [1.40199995, -0.71414, 0.]]]])
43 | yuv2rgb_bias = tf.constant([-179.45599365, 135.45983887, -226.81599426])
44 | temp = tf.nn.conv2d(yuv, yuv2rgb_filter, [1, 1, 1, 1], 'SAME')
45 | temp = tf.nn.bias_add(temp, yuv2rgb_bias)
46 | temp = tf.maximum(temp, tf.zeros(temp.get_shape(), dtype=tf.float32))
47 | temp = tf.minimum(temp, tf.mul(
48 | tf.ones(temp.get_shape(), dtype=tf.float32), 255))
49 | temp = tf.div(temp, 255)
50 | return temp
51 | </code></pre><p>定义拼接图像的方法,可以把两张图片水平连接起来:</p><pre><code lang="python">def concat_images(imga, imgb):
52 | """
53 | Combines two color image ndarrays side-by-side.
54 | """
55 | ha, wa = imga.shape[:2]
56 | hb, wb = imgb.shape[:2]
57 | max_height = np.max([ha, hb])
58 | total_width = wa + wb
59 | new_img = np.zeros(shape=(max_height, total_width, 3), dtype=np.float32)
60 | new_img[:ha, :wa] = imga
61 | new_img[:hb, wa:wa + wb] = imgb
62 | return new_img</code></pre><p>准备就绪,开始主要流程。</p><p>在TensorFlow的Session开始前,首先定义一些必要的Operation和Tensor</p><pre><code lang="python">""" 把含有风格的图像styled转换成yuv格式的灰度图styled_grayscale_yuv """
63 | styled_grayscale = tf.image.rgb_to_grayscale(styled)
64 | styled_grayscale_rgb = tf.image.grayscale_to_rgb(styled_grayscale)
65 | styled_grayscale_yuv = rgb2yuv(styled_grayscale_rgb)
66 |
67 | """ 把需要添加风格的原始图像转换成yuv格式original_yuv """
68 | original_yuv = rgb2yuv(original)
69 |
70 | """
71 | 组合图像:
72 | 1. styled_grayscale_yuv的Y分量
73 | 2. original_yuv的U分量
74 | 3. original_yuv的V分量
75 | """
76 | combined_yuv = tf.concat(3, [tf.split(3, 3, styled_grayscale_yuv)[0], tf.split(3, 3, original_yuv)[1], tf.split(3, 3, original_yuv)[2]])
77 |
78 | """ 转换成RGB格式 """
79 | combined_rbg = yuv2rgb(combined_yuv)
80 |
81 | """ 初始化 """
82 | init = tf.initialize_all_variables()
83 | </code></pre><p>然后正式开始Session,完成Operations:</p><pre><code lang="python">with tf.Session() as sess:
84 | sess.run(tf.initialize_all_variables())
85 |
86 | """ 读取需要添加风格的原始图片 """
87 | original_image = skimage.io.imread(FLAGS.original) / 255.0
88 | original_image = original_image.reshape((1, 338, 600, 3))
89 |
90 | """ 读取含有风格的图片 """
91 | styled_image = skimage.io.imread(FLAGS.styled) / 255.0
92 | styled_image = styled_image.reshape((1, 338, 600, 3))
93 |
94 | """ 为原始图片添加上风格 """
95 | combined_rbg_ = sess.run(combined_rbg, feed_dict={original: original_image, styled: styled_image})
96 |
97 | """ 拼接几幅图片并保存,做个对比 """
98 | summary_image = concat_images(original_image.reshape((338, 600, 3)), styled_image.reshape((338, 600, 3)))
99 | summary_image = concat_images(summary_image, combined_rbg_[0])
100 | plt.imsave("results.jpg", summary_image)
101 | </code></pre><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21836208&pixel&useReferer"/>王若愚Tue, 02 Aug 2016 18:13:56 GMT
- 非监督学习算法--K均值聚类https://zhuanlan.zhihu.com/p/21558539<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/729eb965e0ada616d3cd58adcc4c7013_r.png"></p>本文介绍最常见的非监督学习算法「K均值(K-means)」,思路和仿真主要参考Ng的课程「Machine Learning」以及课程作业的Matlab的实现。<p><a href="https://github.com/wrymax/machine-learning-assignments/tree/master/week8/machine-learning-ex7/ex7" data-editable="true" data-title="猛戳下载本文Matlab实现" class="">猛戳下载本文Matlab实现</a>,其中ex7.m包含了k-means的代码,ex7_pca.m包含了PCA的代码。</p><p>以下是正文。</p><p><b>K-means的意义和使用场景:</b></p><p>在无任何先验分类知识的情况下,自动发现数据集的分类。例如:</p><ol><li>在大量文本中发现隐含的话题;</li><li>发现图像中包含的颜色种类;</li><li>从销售数据中发现不同特征顾客的分类。</li></ol><p>👇下面简述算法步骤、仿真以及算法中的问题 👇</p><p><b>1.1 算法步骤</b></p><ul><li>假设希望将训练数据集<equation>x^{(i)} (i = 1, 2, 3,..., m)</equation>分为K类;</li><li>在<equation>x^{(i)} (i = 1, 2, 3,..., m)</equation>中,随机选择K个作为初始分类的图心(centroids) <equation>\mu _{1}, \mu _{2}, \mu _{3},..., \mu _{K}</equation>;</li><li>遍历<equation>x^{(i)}</equation>,计算出和每个<equation>x</equation>距离最近的图心<equation>\mu ^{(i)}</equation>,记录当前<equation>x</equation>属于第<equation>i</equation>类;</li><li>遍历K种分类,分别计算上一步中,划归其中的所有<equation>x</equation>点的中心点,将该点设置为本分类中心的图心;</li><li>迭代上两步,直到图心位置收敛。</li></ul><p><b>1.2 Matlab仿真:K-means过程</b></p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/87d35141e80060aea0eecb2f094454a6.jpg" data-rawwidth="570" data-rawheight="493"><p> (我做了个gif动图,可能需要戳一下它才会动起来)</p><p><b>1.3 随机初始化 Random Initialisation </b></p><p>由于初始的图心是随机选择的,K-means可能陷入局部最优而导致最终的图心无法收敛到合适的位置。可以使用随机初始化来解决这个问题:</p><ul><li>多次运行K-means算法,计算<equation>c^{(1)},..., c^{(m)}, \mu _{1},..., \mu _{k}</equation>;</li><li>计算Cost Function <equation>J = (c^{(1)},..., c^{(m)}, \mu _{1},..., \mu _{k})</equation>,函数代表了聚类的失真程度;</li><li>选择J最小的那一组初始化以及最终的计算结果。</li></ul><p><b>1.4 选择聚类数量</b></p><ul><li>使用「肘方法」Elbow Method</li><ul><li>逐渐增加K,并分别计算Cost Function J,寻找J较小的K,如图:</li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/392ddcffe91d6e90c0316e0e5e5cb47d.jpg" data-rawwidth="620" data-rawheight="321"><li>理论上,当分类数量K增大时,J将逐渐变小;</li><li>但也可能陷入局部最优的问题,导致k增大时,J反而增大。此时需要重新随机初始化后再次计算。</li></ul><li>Ng推荐的办法:向自己提问「我为什么要使用K-means」?充分理解聚类的需求以及聚类后能向下游贡献什么东西,往往能从中发现真正合适的聚类数量。例如下图:</li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/deee28966bfec9af3579e48b3118f7c4.jpg" data-rawwidth="620" data-rawheight="329"><li>横轴为衣服店顾客的身高,纵轴为顾客的体重。当你理解了顾客可能分为「S、M、L」三类,或者「XS、S、M、L、XL」五类时,最终选择的分类数量可能比较make sense,而不是完全依赖Cost Function算出一个10类或者4类,最终并没有太大实际意义。</li></ul><p><b>1.5 实践:使用K-means压缩图像</b></p><p>思路:</p><ul><li>对一个RGB图像执行K-means算法,寻找能描述图像的16种主要颜色分类;</li><li>将每个像素点聚类到这16种颜色分类中,并分别替换为对应分类的颜色;</li><li>对每个像素使用颜色的索引来代替3维的RGB亮度值,由此可以将图像的大小压缩到<equation>\frac{1}{6}</equation></li></ul><p>仿真图:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/037cf01978ec1bedb8ae69ebf5505221.jpg" data-rawwidth="620" data-rawheight="342">代码在文章开始处的Github链接中,执行ex7即可观测到结果。</p><p>如需转载,请附上原链接,谢谢。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21558539&pixel&useReferer"/>王若愚Mon, 11 Jul 2016 17:31:53 GMT
- SVM支持向量机https://zhuanlan.zhihu.com/p/21481541<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/52c8d933d79140e2fb6710994a5d581d_r.jpg"></p>本文从概念和一些算法细节上介绍Support Vector Machine支持向量机的原理和功能。通过对比Logistic Regression,期望对SVM有一个快速的入门介绍。实现代码可参考:<a href="https://github.com/wrymax/machine-learning-assignments/tree/master/week7/machine-learning-ex6/ex6" data-editable="true" data-title="SVM示例">SVM示例</a>,在Matlab / Octave中加载,执行ex6和ex6_spam即可。<b>1) 目的和场景</b>SVM是一种经典的机器学习算法,主要解决数据分类问题。原理是基于训练大量已有的数据和已知的分类情况,计算出一个预测模型。然后可以在模型上跑新的数据,从而判断新数据应当归于哪一类。SVM适用于线性和非线性的场景。SVM的典型使用场景如:
102 | <ol><li>房价估算<ol><li>根据过去十年来房价和房屋面积、卧室数量、当地消费水平等等各种因素数据,将房屋分为「豪宅」、「中等」、「经济型住房」、「贫民窟」等几类;</li><li>使用SVM训练这些数据得出一个模型,可以用来预测在新的条件下,某个住房可以被划归到哪种分类,价值区间多少。</li></ol></li><li>垃圾邮件分类器:<ol><li>获取可疑的spam email关键词列表,例如:Buy、now等(实际Spam Corpus可以参考使用<a href="https://spamassassin.apache.org/publiccorpus/" data-editable="true" data-title="Apache Spam Assassin">Apache Spam Assassin</a>);</li><li>收集大量的spam和非spam邮件数据,将其中包含的可疑spam关键词找出并标记在特征向量中,用SVM训练这些数据,得出一个模型,用来判断一封新的邮件是否为一个垃圾邮件。</li></ol></li></ol><b>2) 核心思路</b>2.1 SVM的思路可以由Logistic Regression演变而来,依然是通过Gradient Descent计算CostFunction的全局极小值,得到theta矩阵,作为分类模型。
103 | 如图:
104 | <img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/31d0113a2e3d05cc56d4044a8d37e828.jpg" data-rawwidth="620" data-rawheight="337">2.2 SVM和Logistic Regression的不同之处:
105 | <ol><li>把LR中的Sigmoid函数 <equation>log(h_{\theta }(x) ) = log(g(z))</equation> 被修改为上图中的函数 <equation>cost_{0} (z)</equation> 和 <equation>cost_{1} (z)</equation> 其中<equation>z = \theta^{T}X </equation><ol><li>当分类结果 y = 1 时,期望z >= 1,此时<equation>cost_{1} (z)</equation> = 0,总体cost function达到最小</li><li>当分类结果 y = 0 时,期望z <= -1,此时<equation>cost_{0} (z)</equation> = 0,总体cost function达到最小</li></ol></li><li>关于Regularisation参数C:<ol><li>Logistic Regression在cost function的后半部分上乘以一个lambda(一个较小的值,例如0.03)</li><li>SVM在cost function的前半部分乘以一个较大的C(可以理解为1 / lambda,例如1, 100, 1000)</li></ol></li></ol>2.3 Kernel 核函数
106 | <ol><li>SVM引入Kernel的概念,将<equation>z = \theta^{T}X </equation>中的X变为一个f = g(x),形式变为:<equation>z = \theta^{T} f</equation></li><li>最常见的Kernel<ol><li>Linear Kernel 线性核<ol><li>实际上就是不使用Kernel,直接使用<equation>\theta^{T} X</equation>作为cost function的自变量</li></ol></li><li>Gaussian Kernel 高斯核<ol><li>对X套用高斯函数,如下图</li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/5cdc926f1d45540203539c5b8a905eb9.png" data-rawwidth="3636" data-rawheight="1996"><li>图例参数说明<ol><li>「l」是「landmark」的缩写,在实际编程中,直接把training set放置到landmark位置上即可</li><li>高斯核函数 f 实际上计算了x和某个landmark l之间的近似度,这个近似度用欧氏距离来描述(计算向量内积)</li><li><equation>\sigma </equation>用于控制高斯核的陡峭程度,<equation>\sigma </equation>越大,函数越平滑</li></ol></li></ol></li><li>其他核函数<ol><li>Polynomial Kernel</li><li>String Kernel</li><li>chi-square kernel</li><li>histogram kernel</li><li>intersection kernel</li><li>根据Ng的说法,这些看起来很屌,但他自己基本没怎么用过… 大多数情况下,都是用Gaussian Kernel</li></ol></li></ol></li></ol>2.4 Logistic Regression、SVM和神经网络的使用场景对比
107 | 假设 n 为特征的数量,m为训练集的数量
108 | <ol><li>当n比m大得多时,如n = 10000,m = 1000,建议使用Logistic Regression,或者SVM + 线性核</li><li>如果n很小,m不大不小,例如n = 1 ~1000, m = 10 ~ 10000,建议使用SVM + 高斯核</li><li>如果n很小,m很大,例如n = 1 ~1000, m = 50000+,建议添加更多的特征,然后使用Logistic Regression,或者SVM + 线性核</li><li>各种情况下,神经网络都工作的不错,但是比SVM训练的速度慢一些</li></ol><b>3) 实践中的一些注意事项
109 | </b><ol><li>需要通过多次交叉检验来确定合适的regularisation参数C和高斯核参数<equation>\sigma </equation>,方法:<ol><li>设定一组备选的C和<equation>\sigma </equation>,用他们两两组合循环训练SVM model</li><li>用训练好的model跑Cross Validation数据集,计算errors</li><li>找出errors最低的一组C和sigma</li></ol></li><li>几个好用的SVM工具包<ol><li>liblinear</li><li>libsvm</li></ol></li></ol><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21481541&pixel&useReferer"/>王若愚Mon, 04 Jul 2016 12:39:20 GMT
- 应用机器学习算法的一些具体建议https://zhuanlan.zhihu.com/p/21449423<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/01d6654b5392b00f4e777791d7e80c48_r.jpg"></p>本文来自于学习Ng的Machine Learning课程笔记。学习时用英文记录,写本文时加上了部分中文解释,尽可能的口语化了。另外部分名词可能翻译的不太对,如果您发现了请不吝指正,谢谢。具体实现代码请参考:<a href="https://github.com/wrymax/machine-learning-assignments/tree/master/week6/machine-learning-ex5/ex5" class="">https://github.com/wrymax/machine-learning-assignments/tree/master/week6/machine-learning-ex5/ex5</a>使用Matlab / Octave加载,运行ex5即可。本文主要指出了一些机器学习实践中的技巧,coding前必备。Let's get started.<b>关键名词:</b><ol><li>训练数据集 Training Set</li><li>训练数据集的代价函数 Jtrain(theta)</li><li>交叉验证数据集 Cross Validation</li><li>交叉验证数据集的代价函数 Jcv(theta)</li><li>测试数据集 Test</li><li>测试数据集的代价函数 Jtest(theta)</li><li>预测误差、代价 error(代价函数的计算结果)</li><li>偏差 Bias</li><li>特征多样性、方差 Variance</li><li>欠拟合 Under-Fitting</li><li>过拟合 Over-Fitting</li><li>正则化 Regularisation </li><li>查准率 Precision</li><li>召回率 Recall</li><li>F值 F Score</li></ol><p><b>核心概念</b></p><ol><li><b>Machine Learning Diagnostic 机器学习诊断</b><ol><li>To get better avenue, you may:<ol><li>Collect larger training examples 收集更多的训练数据 => 解决overfitting</li><li>Get additional features 获得和使用额外的特征 => 解决high bias</li><li>Add polynomial features 添加多项式特征 => 解决high bias</li><li>Reduce features 减少特征 => 解决overfitting</li><li>Increase lambda 增大lambda => 解决overfitting</li><li>Decrease lambda => 解决underfitting</li></ol></li><li>However, it may takes you 6 month to train data, and nothing to gain.</li><li>Machine Learning Diagnostic is: 机器学习诊断思路如下:<ol><li>A test that you can run to gain insight what is / isn’t working with a learning algorithm, and gain guidance as to how best to improve its performance. 这是一种测试方法,你可以据此尝试并改进算法的性能</li><li>It takes time to implement. 这得花点时间。。</li><li>It sometimes rule out certain courses of action (changes to your learning algorithm) as being unlikely to improve its performance significantly. 有可能这并没有什么卵用</li></ol></li><li>Training/Testing Procedure 训练/测试过程<ol><li>Split dataset into 7:3, 70% of which is going to be the training set, 30% of which is going to be the testing set. 切分数据集:70%作为训练数据,30%作为测试数据</li><li>Learn parameter theta from training data. 使用训练数据习得你需要的theta</li><li>Compute test set error: 使用刚刚训练出来的Cost Function来跑一下测试数据集,得到测试数据集的误差<ol><li>Jtest(theta) = CostFunction(training_data) => the square deviation equation </li></ol></li></ol></li></ol></li><li><b>Model Selection and Train/Validation/Test Sets 模型选择与训练/校验/测试数据集</b><ol><li>Degree of Polynomial 多项式级数(一个我们需要关注的指标),这个东西就是下图中的「d」</li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/4a1f050207306becba5c5573957d0625.png" data-rawwidth="3796" data-rawheight="2060"><li>如上图,我们从d = 1到d = 10,分别用test数据集计算Cost Function,然后选取一个最优化的d(上图中选择了d = 5),后面几部讲了具体怎么实施这个过程</li><li>Evaluating your hypothesis 评估你的预测函数<ol><li>Training Set - 60% of data set 把60%的数据设置为训练数据集</li><li>Cross Validation Set (CV) - 20% of data set 把20%的数据设置为交叉验证数据集</li><li>Test Set - 20% of data set 把20%的数据设置为测试数据集</li></ol></li><li>Use Validation Set to select the model 使用交叉验证数据集来选择模型<ol><li>Compute cost function J(theta) by CV in different degrees</li><li>Choose the minimal one as the target degree, as below, d = 4</li><li>Estimate generalisation erro for test set Jtest(theta(4))</li><li>以上这段英文就是步骤1 - 3了</li></ol></li></ol></li><li><b>Bias vs. Variance 偏差 vs. 特征多样性(or方差?)</b><ol><li>Bias => 特征值以外的代价函数偏差<ol><li>High Bias => high lambda => Under-fitting</li></ol></li><li>Variance => 特征多样性<ol><li>High Variance => low lambda => Overfitting</li></ol></li><li>Diagnosing Bias vs. Variance 诊断:偏差高低和特征值大小<ol><li>Set coordinates of (degree_of_polynomial_d, error); 设置一个横轴为特征数量(多项式维度)d,纵轴为预测误差error的坐标系</li><li>Train the 60% data set, draw a curve which will converge when d goes bigger; 用60%的数据集作为训练集合,计算J(theta),当多项式维度d(特征数)增大时,error会减少,向0收敛</li><li>Run prediction with Cross-Validation-Set by trained model, there will be an overfitting point, after which Jcv(theta) will continuously arise. 使用从训练集中获得的模型,计算交叉验证数据集的预测误差,会发现过拟合问题。</li><li>如下图:</li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/d1a6d5dfd58b7cdbd0410487a5596c4f.png" data-rawwidth="3744" data-rawheight="2000"></ol></li><li><b>Question 问题来了...</b><ol><li>How can we figure out it is suffered from <b>Bias</b>, or from <b>Variance</b>? 我们如何知道模型的问题出在偏差还是特征多样性上?<ol><li>Bias => Underfitting, as on the left part of the diagram 偏差往往和欠拟合相关,如图左半部分,特征数过少<ol><li>Jtraining(theta) will be high 训练集的代价函数error会很大</li><li>Jcv(theta) ≈ Jtraining(theta) 交叉验证的代价函数error约等于训练集,也很大</li></ol></li><li>Variance => Overfitting, as on the right part of the diagram 特征多样性往往和过拟合相关,如图右半部分,特征数量过多<ol><li>Jtraining(theta) will be low 训练集的代价函数error越来越低</li><li>Jcv(theta) >>( much higher than ) Jtraining(theta) 交叉验证数据集的代价函数error在经过一个极小值后开始上升,最终远大于训练集的错误。这是典型的过拟合特征:对新数据的fitting性能非常差。</li></ol></li></ol></li><li>如下图:<img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/a0db6ba0b74fd2185a95d4ff0974c079.png" data-rawwidth="3788" data-rawheight="1920"></li></ol></li><li>Choosing the regularisation parameter lambda 选择正则化参数lambda<ol><li>Try lambda from small to large, like 从小到大,尝试lambda<ol><li>0</li><li>0.01</li><li>0.02</li><li>0.04</li><li>0.08</li><li>...</li><li>10</li></ol></li><li>Pick up best fitting lambda of Cross-Validation cost function, say Theta(5) 选择一个对交叉验证数据集的代价函数拟合最好的lambda值,例如theta(5)</li><li>Compute J(theta) by the test data set 计算测试数据集的代价函数</li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/2d7c1a31ce3a19e9aadc47c4ac0b73aa.png" data-rawwidth="3764" data-rawheight="2024"></ol></li></ol></li><li><b>Bias/Variance as a function of the regularisation parameter lambda 以lambda为参数的偏差/方差函数</b><ol><li>When lambda is 0 当lambda为0时<ol><li>you can fit the training set relatively well, since there is no regularisation. 训练集会拟合的相对不错,因为没有做任何的正则化</li></ol></li><li>When lambda is small 当lambda很小时<ol><li>You get a small value of Jtrain 训练集的预测误差也很小</li></ol></li><li>When lambda goes large 当lambda变大时<ol><li>The bias becomes larger, so Jtrain goes much larger 偏差越来越大,训练集的预测误差会显著增大</li></ol></li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/b473417172cd29c59f9a5655c6889a16.png" data-rawwidth="3820" data-rawheight="2016"></ol></li><li><b>Learning Curves 学习曲线</b><ol><li>When training set number 「m」grows<ol><li>It is much harder to fit, so training error grows 训练集增大,代价函数越来越难拟合所有的数据集,error会增大</li><li>As examples grows, it does better at generalising to new examples, so Cross-Validation error decreases 训练集增大时,代价函数归纳新元素的性能会更好,因此cross-validation的错误率会下降</li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/c92244a19933e73a4ed2dc2a8d93911f.jpg" data-rawwidth="620" data-rawheight="326"></ol></li><li>High Bias 高偏差的情况<ol><li>High Bias means low Variance, so h(theta) would a low-dimensional function, which cannot fit all the dataset well 高偏差代表预测多项式的维度过低,因此很难预测整个数据集</li><li>When m is small, Jcv is high and Jtrain is low, while both of them will converge to similar value when dataset grows large enough 当数据集的总数很小时,交叉验证集的预测误差很大,训练数据集的预测误差很小;但当m越来越大,两者将越来越接近</li><li>Both the error of Jcv and Jtrain would be fairly HIGH 交叉验证和训练数据集的J都会很大</li><li>Conclusion 结论<ol><li>If a learning algorithm is suffering from high bias, getting more training data will not(by itself) help much 当学习算法存在高偏差问题时,训练更多的数据无法解决问题(J会收敛于一个很高的错误值,不再下降)</li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/a2561bd221232925c4625490b7ba316f.jpg" data-rawwidth="620" data-rawheight="330"></ol></li></ol></li><li>High Variance 高特征多样性的情况<ol><li>High Variance means low lambda and the polynomial hypothesis function has many many features 高特征多样性说明正则化参数lambda很小,此外预测多项式有非常多的特征</li><li>When m is small 当训练数据量m很小时<ol><li>Jtrain is small; as m grows up, Jtrain becomes larger too, but the training set error would still be pretty low 训练集的J也很小;但是当训练数据越来越多时,由于预测函数的维度过高,拟合开始变得困难,Jtrain逐渐上升,但是仍然是一个非常小的数值</li><li>Jcv is large; as m grows up, Jtrain becomes smaller and coverage to a value similar with Jtrain 交叉验证数据集的J很大(高特征多样性带来的过拟合会导致预测函数对样本外的数据点预测偏差很大);当m增大时,Jcv会逐渐下降</li><li>The indicative diagnostic that we have a high variance problem 我们遇到高特征多样性问题的一个象征性指标:<ol><li>With m becomes larger, there is a large gap between the training error and cross-validation error 随着m增大,训练数据集的预测误差和交叉验证数据集的预测误差之间会存在一个很大的空白</li></ol></li></ol></li><li>Conclusion 结论<ol><li>If learning algorithm is suffering from high variance, getting moe training data is likely to help 当学习算法存在高特征多样性为题是,使用更多的训练数据可能会有帮助</li></ol></li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/ffe4cfa386a14c901823696c246575f3.jpg" data-rawwidth="620" data-rawheight="330"></ol></li></ol></li><li><b>Deciding what to try next (revisited) 决定下一步做什么</b><ol><li>When debugging a learning algorithm, you find your model makes unacceptably large errors in its prediction, what to do next? 当调试一个学习算法时,你发现你的预测模型得出了不可接受的高误差,下一步该怎么办?<ol><li>Get more training examples 使用更多的训练数据<ol><li>When Jcv is much higher than Jtrain, it fixes high variance 当Jcv比Jtrain大的多时,它可以解决高特征多样性的问题</li></ol></li><li>Try smaller sets of features 尝试减少特征数量<ol><li>It fixes high variance problem too 减少一部分用处不大的特征可以解决高特征多样性的问题</li></ol></li><li>Try getting additional features 尝试使用额外的特征<ol><li>Maybe the model is under-fitting (high bias), try additional features can make the model fitting training set better 高误差也有可能是因为特征数量太少了,因此使用额外的特征可以解决高偏差的问题</li></ol></li><li>Try adding polynomial features 尝试添加多项式特征 (x1 * x1, x2 * x2, x1 * x2, etc)<ol><li>Which also solves high bias problem 也是可以解决高偏差的问题(欠拟合)</li></ol></li><li>Try decreasing lambda 尝试降低正则化参数lambda<ol><li>Which also solves high bias problem 也是可以解决高偏差的问题(欠拟合)</li></ol></li><li>Try increasing lambda 尝试增加正则化参数lambda<ol><li>Which also solves high variance problem 也是可以解决高特征数量的问题(过拟合)</li></ol></li></ol></li><li>Neural Networks and overfitting 神经网络与过拟合<ol><li>Small neural network 小型神经网络<ol><li>fewer parameters, more prone to under-fitting 网络层数少、神经元数量少,更易导致欠拟合</li><li>Computationally cheaper 计算资源消耗少</li></ol></li><li>Large neural network 大型神经网络<ol><li>Type1. few layers, lot of units 类型1:层数少,每层的神经元多</li><li>Type2. few units, lot of layers 类型2:层数多,每层的神经元少</li><li>more parameters, more prone to over-fitting 参数多,更易导致过拟合</li><li>Computationally more expensive 计算资源消耗多</li><li>Use regularisation to address overfitting 使用正则化来解决过拟合问题</li><li>Try one layer, two layers and three layers.. and compute Jcv(theta) to decide how many layers you will use 尝试1层、2层、3层… 并计算交叉验证代价函数,据此来选择最合适的神经网络层数</li></ol></li></ol></li></ol></li></ol><b>Machine Learning System Design 机器学习系统设计</b><b>(本段中楼主懒癌发作不想打字。。。直接贴Ng的截图了)</b><ol><li>Building a Spam Classifier 构建一个垃圾邮件分类器<ol><li>Prioritising What to Work On <img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/230490f942998f0541070e26c91f0dfa.png" data-rawwidth="1832" data-rawheight="838"></li><li>Recommended Approach 推荐的方法<img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/5c6966a18a75ba8633f77780dbaf382e.png" data-rawwidth="1756" data-rawheight="722"><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/81a7af0b71a42cf0752b0ef9784ac2ab.png" data-rawwidth="3636" data-rawheight="1872"></li></ol></li><li>Handling Skewed Data 处理歪曲/偏斜的数据<ol><li>Error Metrics for Skewed Data 歪曲数据的错误度量方法<ol><li>查准率 Precision<ol><li>Precision = TruePositive / (No. of predicted positive)</li><li>No. of predicted positive = TruePositive + FalsePositive</li></ol></li><li>召回率 Recall<ol><li>Recall = TruePositive / (No. of actual positive)</li><li>No. of actual positive = TruePositive + FalseNegative</li></ol></li></ol></li><li>Trading off Precision and Recall 权衡查准率和召回率<ol><li>High Precision and Low Recall: Suppose we want to predict y = 1 only if very confident <ol><li>Predict 1 if h(x) >= 0.9</li><li>Predict 0 if h(x) < 0.9</li></ol></li><li>High Recall and Low Precision: Suppose we want to predict y = 0 only if very confident<ol><li>Predict 1 if h(x) >= 0.3</li><li>Predict 0 if h(x) < 0.3</li></ol></li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/490a48d1d7c4c3ddb1c507066c99301c.png" data-rawwidth="3788" data-rawheight="2020"><li>F Score F值<ol><li>For making a decision which pair of Precision and Recall is better</li><li>Measure P and R on the <b>cross validation set</b>, and choose the value of threshold which maximises F score, as below</li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/8c912d6f5472417b4bf5a45724cc3108.png" data-rawwidth="3756" data-rawheight="1952"></ol></li></ol></li></ol></li><li>Using Large Data Sets 使用大数据集<ol><li>首先问自己两个问题:</li><ol><li>Question1: Can a human expert accurately predict y from given features x? 人类砖家使用目前的特征指标,能否准确预测出结果?<ol><li>e.g. Can a realtor predict the housing price simply based on housing sizes? 例如:一个房地产经纪人是否能仅仅基于房屋面积预测出房价?</li></ol></li><li>Question2: Can we get a large training set to train with many features? 我们能不能搞到更多的数据来训练如此多的特征?</li></ol><li>如果可以,那么:</li><ol><li>Use a learning algorithm with many parameters ( many features / many hidden layers ) 多设置一些特征,或者神经网络中的隐藏层</li><li>Use a very large training set 尽量多的使用训练数据</li></ol></ol></li></ol><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21449423&pixel&useReferer"/>王若愚Wed, 29 Jun 2016 14:15:41 GMT
- 神经网络的学习 / 训练过程https://zhuanlan.zhihu.com/p/21381359<p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/17db6ca9a6df9e33f302b13568e97dda_r.jpg"></p>以下为部分学习笔记。<p>具体实现代码参考: <a href="https://github.com/wrymax/machine-learning-assignments/tree/master/week5/machine-learning-ex4/ex4">https://github.com/wrymax/machine-learning-assignments/tree/master/week5/machine-learning-ex4/ex4</a></p><ol><li><b>Cost Function 代价函数</b><ol><li>Important Parameters:<ol><li>L => Total number of layers in network</li><li>Sl => Number of units ( not counting bias unit ) in layer l</li><li>As below, L = 4, S1 = 3, S2 = 5, S4 = SL = 4<img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/f168eae6991fd9681da794b9fc3e0b12.png" data-rawwidth="626" data-rawheight="342"></li></ol></li><li>Two Classification Methods<ol><li>Binary Classification 二元分类<ol><li>y = 0 or 1</li><li>SL = K = 1 ( One output unit )</li></ol></li><li>Multi-class Classification 多元分类<ol><li>y is logical vectors, which uses 1 to denote the class</li><li>SL = K, K >= 3 ( K output units )</li></ol></li><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/62e9dc13f799ec5ec0cb8df167179063.png" data-rawwidth="1890" data-rawheight="992"></ol></li><li>The Cost Function<ol><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/70270b37927da2357329ae77eef65d6a.png" data-rawwidth="1854" data-rawheight="1038"><li>J(theta) sum up the cost function in logistic regression of ALL Layers.</li><li>Regularisation sum up all Theta elements between each two layers.</li></ol></li></ol></li><li><b>Back Propagation 向后传播</b><ol><li>Compute Gradient 用于计算梯度( CostFunction对Theta的偏微分 )<img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/eba219186b9387a30205698194cc0ffe.png" data-rawwidth="1894" data-rawheight="1014"></li><li>Algorithm 算法解释<img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/d750e6a3a3cf8706181b653b3efe3d22.png" data-rawwidth="1894" data-rawheight="1032"></li></ol></li><li><b>Back Propagation in Practice 向后传播实践技巧</b><ol><li>Learning Algorithm 学习算法<ol><li>initialTheta</li><li>costFunction</li></ol></li><li>Unrolling Parameters 展开参数<ol><li>Change matrices into vectors </li><li>Change vectors into matrices</li></ol></li><li>Gradient Checking 梯度检查<ol><li>Use numerical estimate method to compute derivatives</li><li>Pros:<ol><li>It can check is derivatives are correct</li></ol></li><li>Cons:<ol><li>It is super slow. </li><li>When you make sure back propagation gives similar values as gradient, just turn off it.</li><li>Be sure to disable gradient checking code before training your classifier. Or the training process would be super slow.</li></ol></li></ol></li><li>Random Initialisation 随机初始化<ol><li>“Zero Initialisation" does not work in neural network.</li><li>Random Initialisation: Symmetry breaking</li></ol></li><li>Put things together<ol><li>Training a neural network<ol><li>Pick a network architecture<ol><li>Number of input units: Dimension of features x(i)</li><li>Number of output units: Number of Classes</li><li>Layers:<ol><li>Number of layers</li><li>Units in each layer<ol><li>Same units number in each layer</li><li>Usually the more units the better</li></ol></li></ol></li></ol></li><li>Randomly initialise weights<ol><li>Small values near zero</li></ol></li><li>Implement forward propagation to get prediction for any x(i)</li><li>Implement code to compote cose function J(theta)</li><li>Implement backprop to compute partial derivatives of J(theta)<ol><li>for i = 1:m<ol><li>Perform forward propagation and back-propagation using example (x(i), y(i))</li><li>Get activations a(l) and delta(l) for l = 2,…,L</li></ol></li></ol></li></ol></li></ol></li></ol></li></ol><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21381359&pixel&useReferer"/>王若愚Mon, 20 Jun 2016 00:26:30 GMT
--------------------------------------------------------------------------------
/zhihu/zhuanlan/AI/hsmyy.xml:
--------------------------------------------------------------------------------
1 |
2 | 无痛的机器学习 - 知乎专栏https://zhuanlan.zhihu.com/hsmyy专栏主营业务:让更多人能看的懂的机器学习科普+进阶文章。欢迎各位大神投稿或协助审阅。Sat, 11 Mar 2017 22:16:02 GMTRickyhttp://blogs.law.harvard.edu/tech/rss- CTC实现——compute ctc loss(2)https://zhuanlan.zhihu.com/p/23309693<h2>如何控制计算的数量?cont.</h2><p>好,废话少说我们书接上回。不明真相的小朋友先看这个:</p><p>下面我们假设T=4,S/2=3,好玩的地方来了。T比S/2多一个,也就是说我们允许冗余出现了,那么我们可能的形式也就变多了。我们可以增加一个blank,我们也可以在没有label位置原地打一轮酱油。选择更多,欢乐更多。</p><p>虽然选择变多,但是着并不意味着我们可以选择任意一种状态转移的方式,至少:</p><ul><li>在T=2时,我们至少要转移到第一个结果</li><li>在T=3时,我们至少要转移到第二个结果</li><li>在T=4时,兄弟我们准备下车了</li></ul><p>这其实就是对start的限制。源代码中有这样一句话:</p><pre><code lang="text">int remain = (S / 2) + repeats - (T - t);
3 | </code></pre><p>这里我们先忽略repeats,那么remain这个变量其实是在计算label数量和剩余时间的差。如果用这样的语言来表达刚才的那个问题,我们语言就变成这个样子:</p><ul><li>当时间还剩4轮时(包括第4轮),我们在哪都无所谓(实际上是从T=1开始计算的)</li><li>当时间还剩3轮时(包括第3轮),我们至少要转移到第一个结果(index=1)</li><li>当时间还剩2轮时(包括第2轮),我们至少要转移到第二个结果(index=3)</li><li>当时间还剩1轮时(包括第1轮),我们至少要转移到第三个结果(index=5)</li></ul><p>好了,这里我们看出其中的含义了。我们再啰嗦一下,看看这些变量随T的变化情况:</p><ul><li>T=1,remain=0,start+=1</li><li>T=2,remain=1,start+=2</li><li>T=3,remain=2,start+=2</li></ul><p>现在我们已经十分清楚了,当remain>=0时,start都要向前走,限制我们计算前面状态的概率,因为这些概率已经没有意义了。下面的代码也是这样描述的:</p><pre><code lang="text">if(remain >= 0)
4 | start += s_inc[remain];
5 | </code></pre><p>那么这个s_inc是什么东西?它就是我们需要提前准备好的计算量。我们知道经过扩充的label序列中,所有的非空label都处在奇数的index上,而填充的blank都处在偶数的index上(我们是0-based的计算方法,matlab选手请退散……),所以对于上面的问题,当start=0时,下一步我们会从0跳到1,此后我们会从1到3,3到5,跳转的步数都是2,所以基于这个思路,我们就可以把s_inc这个数组生成出来。当然,我们的前提是没有重复。下面我们会说重复的问题的。</p><p>我们上面说了这么多,重点把start的变化介绍清楚了。下面我们来看看end。其实end的原理也类似,我们还是用刚才的废话套路来介绍站在end视角的世界:</p><ul><li>在T=1时,我们最多能到第一个结果</li><li>在T=2时,我们最多能转移到第二个结果</li><li>在T=3时,我们最多能转移到第三个结果</li><li>在T=4时,我们已经掌握了整个世界……oh yeah</li></ul><p>好了,可以看出end的变化形式,每个时刻end都可以+2,直到到达最后一个非blank的label,end变成了+1,然后end就不用动了,等着start动就可以了……(怎么感觉有点污?天哪……)</p><p>那么end变化的条件是什么呢?</p><pre><code lang="text">if(t <= (S / 2) + repeats)
6 | end += e_inc[t - 1];
7 | </code></pre><p>我们还是忽略repeats,那么就十分清楚了,如果当前时刻小于等于label数,那么尽管前进,如果大于了,基本上也就到头了,这时候end就不用动了。</p><p>好了,前面我们终于说完了简单模式下start和end的移动规律,下面我们来看看带重复模式下的变化方法。</p><h2>重复,重复</h2><p>重复会带来什么样的变化呢?说白了如果有重复的label出现,那么两个连续重复的label中间就要至少出现一个blank。换句话说,每出现一个重复,我们的S/2就要加一,于是我们再看一眼这两个计算公式:</p><pre><code lang="text">int remain = (S / 2) + repeats - (T - t);
8 | if(remain >= 0)
9 | start += s_inc[remain];
10 | if(t <= (S / 2) + repeats)
11 | end += e_inc[t - 1];
12 | </code></pre><p>我们把repeats和S/2归到一起,这时候就能看明白了。</p><p>同理,在计算s_inc和e_inc的时候,由于有repeats的存在,它们从过去的+2变成了两个+1。也就是说先从label跳到blank,再跳到下一个label。这样就可以解释s_inc和e_inc的初始化策略了:</p><pre><code lang="text">int e_counter = 0;
13 | int s_counter = 0;
14 |
15 | s_inc[s_counter++] = 1;
16 |
17 | int repeats = 0;
18 |
19 | for (int i = 1; i < L; ++i) {
20 | if (labels[i-1] == labels[i]) {
21 | s_inc[s_counter++] = 1;
22 | s_inc[s_counter++] = 1;
23 | e_inc[e_counter++] = 1;
24 | e_inc[e_counter++] = 1;
25 | ++repeats;
26 | }
27 | else {
28 | s_inc[s_counter++] = 2;
29 | e_inc[e_counter++] = 2;
30 | }
31 | }
32 | e_inc[e_counter++] = 1;
33 | </code></pre><p>好了,到此我们才算把CTC中compute ctc loss这部分介绍完了。教科书上的一个公式看着简单,落实到代码就似乎充满了trick。希望看懂了这个计算的你大脑没有阵亡。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23309693&pixel&useReferer"/>冯超Tue, 07 Mar 2017 12:11:42 GMT
- CTC实现——compute ctc loss(1)https://zhuanlan.zhihu.com/p/23293860<p>上一次我们介绍了关于CTC的一些基本问题,下面我们还是落到实处,来介绍一个经典的CTC实现代码——来自百度的warp-ctc。这次百度没有作恶……</p><h2>CTC:前向计算例子</h2><p>这里我们直接使用warp-ctc中的变量进行分析。我们定义T为RNN输出的结果的维数,这个问题的最终输出维度为alphabet_size。而ground_truth的维数为L。也就是说,RNN输出的结果为alphabet_size*T的结果,我们要将这个结果和1*L这个向量进行对比,求出最终的Loss。</p><p>我们要一步一步地揭开这个算法的细节……当然这个算法的实现代码有点晦涩……</p><p>我们的第一步要顺着test_cpu.cpp的路线来分析代码。第一步我们就是要解析small_test()中的内容。也就是做前向计算,计算对于RNN结果来说,对应最终的ground_truth——t的label的概率。</p><p>这个计算过程可以用动态规划的算法求解。我们可以用一个变量来表示动态规划的中间过程,它就是:</p><p><equation>\alpha^T_i</equation>:表示在RNN计算的时间T时刻,这一时刻对应的ground_truth的label为第i个下标的值t[i]的概率。</p><p>这样的表示有点抽象,我们用一个实际的例子来讲解:</p><p>RNN结果:<equation>[R_1,R_2,R_3,R_4]</equation>,这里的每一个变量都对应一个列向量。</p><p>ground_truth:<equation>[g_1,g_2,g_3]</equation></p><p>那么<equation>\alpha^2_1</equation>表示<equation>R_2</equation>的结果对应着<equation>g_1</equation>的概率,当然与此同时,前面的结果也都合理地对应完成。</p><p>从上面的结果我们可以看出,如果<equation>R_2</equation>的结果对应着<equation>g_1</equation>,那么<equation>R_1</equation>的结果也必然对应着<equation>g_1</equation>。所以前面的结果是确定的。然而对于其他的一些情况来说,我们的转换存在着一定的不确定性。</p><h2>CTC:前向计算具体过程</h2><p>我们还是按照上面的例子进行计算,我们把刚才的例子搬过来:</p><p>RNN结果:<equation>[R_1,R_2,R_3,R_4]</equation>,这里的每一个变量都对应一个列向量。</p><p>ground_truth:<equation>[g_1,g_2,g_3]</equation></p><p>alphabet:<equation>[g_0(blank),g_1,g_2,g_3]</equation></p><p>按照上面介绍的计算方法,第一步我们先做ground_truth的状态扩展,于是我们就把长度从3扩展到了7,现在的ground_truth变成了:</p><equation>[blank,g_1,blank,g_2,blank,g_3,blank]</equation><p>我们的RNN结果长度为4,也就是说我们会从上面的7个ground_truth状态中进行转移,并最终转移到最终状态。理论上利用动态规划的算法,我们需要计算4*7=28个中间结果。好了,下面我们用<equation>P^T_i</equation>表示RNN的第T时刻状态为ground_truth中是第i个位置的概率。</p><p>那么我们就开始计算了:</p><p>T=1时,我们只能选择<equation>g_1</equation>和blank,所以这一轮我们终结状态只可能落在0和1上。所以第一轮变成了:</p><equation>[P^1_0,P^1_1,0,0,0,0,0]</equation><p>T=2时,我们可以继续选择<equation>g_1</equation>,我们同时也可以选择<equation>g_2</equation>,还可以选择<equation>g_1</equation>和<equation>g_2</equation>之间的blank,所以我们可以进一步关注这三个位置的概率,于是我们将其他的位置的概率设为0。<equation>[0,(P^1_0 +P^1_1)P^2_1,P^1_1P^2_2,P^1_1P^2_3,0,0,0]</equation></p><p>T=3时,留给我们的时间已经不多了,我们还剩2步,要走完整个旅程,我们只能选择<equation>g_2</equation>,<equation>g_3</equation>以及它们之间的空格。于是乎我们关心的位置又发生了变化:</p><equation>[0,0,0,
34 | (P^1_1P^2_2+P^1_1P^2_3)P^3_3,
35 | P^1_1P^2_3P^3_4,
36 | P^1_1P^2_3P^3_5,
37 | 0]</equation><p>是不是有点看晕了?没关系,因为还剩最后一步了。下面是最后一步,因为最后一步我们必须要到<equation>g_3</equation>以及它后面的空格了,所以我们的概率最终计算也就变成了:</p><equation>[0,0,0,
38 | 0,0,
39 | ((P^1_1P^2_2+P^1_1P^2_3)P^3_3+P^1_1P^2_2P^3_4+P^1_1P^2_2P^3_3)P^4_5,
40 | P^1_1P^2_3P^3_5P^4_6]</equation><p>好吧,最终的结果我们求出来了,实际上这就是通过时间的推移不断迭代求解出来的。关于迭代求解的公式这里就不再赘述了。我们直接来看一张图:</p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic4.zhimg.com/v2-dc44563d358df08920d55336866c1125.jpg" data-rawwidth="960" data-rawheight="1280"><p>于是乎我们从这个计算过程中发现一些问题:</p><p>首先是一个相对简单的问题,我们看到在计算过程中我们发现了大量的连乘。由于每一个数字都是浮点数,那么这样连乘下去,最终数字有可能非常小而导致underflow。所以我们要将这个计算过程转到对数域上。这样我们就将其中的乘法转变成了加法。但是原本就是加法的计算呢?比方说我们现在计算了loga和logb,我们如何计算log(a+b)呢,这里老司机给出了解决方案,我们假设两个数中a>b,那么有</p><equation>log(a+b)=log(a(1+\frac{b}{a}))=loga+log(1+\frac{b}{a})</equation><equation>=loga+log(1+exp(log(\frac{b}{a})))=loga+log(1+exp(logb - loga))</equation><p>这样我们就利用了loga和logb计算出了log(a+b)来。</p><p>另外一个问题就是,我们发现在刚才的计算过程当中,对于每一个时间段,我们实际上并不需要计算每一个ground-truth位置的概率信息,实际上只要计算满足某个条件的某一部分就可以了。所以我们有没有希望在计算前就规划好这条路经,以保证我们只计算最相关的那些值呢?</p><h2>如何控制计算的数量?</h2><p>不得不说,这一部分warp-ctc写得实在有点晦涩,当然也可能是我在这方面的理解比较渣。我们这里主要关注两个部分——一个是数据的准备,一个是最终的数据的使用。</p><p>在介绍数据准备之前,我们先简单说一下这部分计算的大概思路。我们用两个变量start和end表示我们需要计算的状态的起止点,在每一个时间点,我们要更新start和end这两个变量。然后我们更新start和end之间的概率信息。这里我们先要考虑一个问题,start和end的更新有什么规律?</p><p>为了简化思考,我们先假设ground_truth中没有重复的label,我们的大脑瞬间得到了解放。好了,下面我们就要给出代码中的两个变量——</p><p>T:表示RNN结果中的维度</p><p>S/2:ground_truth的维度(S表示了扩展blank之后的维度)</p><p>基本上具备一点常识,我们就可以知道T>=S/2。什么?你觉得有可能出现T<S/2的情况?兄弟,这种见鬼的事情如果发生,你难道要我们把RNN的结果拆开给你用?臣妾不太能做得到啊……</p><p>好了,既然接受了上面的事实,那么我们就来举几个例子看看:</p><p>我们假设T=3,S/2=3,那么说白了,它们之间的对应关系是一一对应,说白了这就和blank位置没啥关系了。在T=1时,我们要转移到第一个结果,T=2,我们要转移到第二个结果……</p><p>那么我们还有别的情况么?下回更精彩。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23293860&pixel&useReferer"/>冯超Thu, 23 Feb 2017 23:36:43 GMT
- CTC——下雨天和RNN更配哦https://zhuanlan.zhihu.com/p/23308976前面我们一直在讲CNN的事情,从今天开始,我们要尝试扩展新方向了!这个新方向就是RNN。介绍RNN的时候,我的内心还是充满紧张的。因为相对而言RNN的理解还是会比CNN弱一些。但是万事开头难,然后中间难,最后结尾难。所以我们一起开车了。<p>RNN的结构我们放在后面介绍,我们先来看一下RNN和CNN相比的特点:对输入输出的维度不必限定。这一点和CNN很不相同。虽然不限定维度的输入输出带来了极大的灵活性,但是也带来了一些其他的问题。当然这些问题我们放在后面慢慢说。下面我们来关注一下CTC的背景。</p><p>这个问题就是对齐问题。比方说对于OCR,我们利用RNN进行识别,我们会得到一连串的输出结果,但是真实的结果可能比这一连串输出要少,所以我们需要做一个对齐的工作:哪些RNN输出对应着同一个真实结果?</p><p>关于这个问题,我们可以使用CTC解决。我们先来约定下各种变量的名字,不然一会儿会要晕掉的:</p><p>我们把RNN输出的内容就称为R,RNN会随着时间的推进不断记忆前面的信息从而后面的结果,我们在此定义RNN经过的时间长度为T,那么RNN输出结果中的一个维度就确定了。</p><p>RNN的另一个维度和输出的类别数量有关。在CNN的分类问题中,我们经常使用softmax层输出表示输入内容对所有类别的概率,这里我们同样用RNN输出这样的信息,我们定义类别的数量为C,那么现在我们就可以确定主角之一的三围,哦不是二围了:C*T。</p><p>这个二维的RNN输出要匹配的是真正的ground_truth,我们直接给出它的维度:1*L。它的长度为L,其中每一个时刻有一个类别。那么我们的目标就是把C*T和1*L这两个东西对上,并求出RNN输出结果的Loss和梯度。</p><p>说到这种形式的序列问题,我们很容易想起ML人民的老朋友:马尔科夫链。实际上在CTC横空出世前,很多人喜欢把两者匹配的问题转换成一个HMM(隐马尔科夫模型)的问题。CTC的套路实际上和HMM有点相近。</p><p>好了,下面我们首先来介绍CTC的一个核心思想:</p><h2>CTC的核心思想</h2><p>CTC的核心思想是什么?好吧我们这里很显然地知道T是大于等于L的(这个很显然吧),那么用脚想也会知道,RNN的结果里肯定存在着一些冗余信息,比方说在相邻的2个时刻,我们实际上预测了同一个类别,这是很容易发生的事情。那么我们就需要制定一个套路,来帮助我们去掉那些冗余信息。</p><p>套路第一步,就是定义一个额外的类别,这个类别叫做blank。我们可以想象在进行手写识别时,字与字之间会存在着一些空隙,语音识别时的字与字之间也会存在着一些间断。我们可以把其中的这些间断的状态定义为blank。为了让匹配的过程更加全面,我们可以在ground_truth的每一个输出类别的前后加上blank,以表示这些字之间存在着的某种间断。</p><p>当然了,你说我们还会遇到某些极端情况,那就是字与字之间没有blank,这时候硬塞一个blank也不是很合适啊。所以在一般情况下,字与字之间的blank是可有可无的。但是有一个情况除外,那就是重复的字。在中文中,这种看似有点卖萌的叠字实际上还是出镜率很高的。</p><p>比方说你在街上看到一只小狗,长得还挺萌的(我觉得泰迪还蛮萌),于是你气沉丹田,说了一个字——“狗~~”,这种间完全没有中断,于是大家除了觉得你有点神经病之外,只会觉得你说了一个字。但是你如果面如桃花般地说“狗狗~”,相信这两个字之间总会存在一个小小的空隙,让人们把你和上面那位气功大师分别开来。而拆成两个字的关键就是着中间有一个停顿。所以为了区分一段时间内的输出是一个状态还是两个状态,我们需要一个停顿,一个blank。</p><p>当然,关于blank的好处,官方文章写了好多。这里直接照抄实在没什么意思,大家去看文章就好。好了套路一结束了。</p><p>下面是套路二:现在我们要把C*T和1*(2L+1)对应起来了。但是这个时候它们的维度还是不一样,怎么办?下面我们就要开始变身了。首先我们确保重叠字中间有一个blank,这时候ground_truth的长度为L'。理论上这时候的L'还是小于等于T的。但是马上我们的ground_truth要变身了,我们要通过变身让ground_truth的长度最终等于T。变身的规则主要是复制。ground_truth下的每一个输出都可以从原本的1个输出变成多个输出,同时每一对输出之间都可以加入blank。</p><p>听上去有点复杂,我们来举个例子。假如我们说了一段话,这话有8个时刻,也就是说T=8,我们实际说出来的字是“无痛的机器学习”,有7个字,根据刚才的规则,我们需要扩充一个字让它的长度也等于8。我们用B表示blank。那么首先扩充的方法是加入blank:</p><blockquote><pre><code lang="text">B无痛的机器学习 无B痛的机器学习 无痛B的机器学习 无痛的B机器学习
41 | 无痛的机B器学习 无痛的机器B学习 无痛的机器学B习 无痛的机器学习B</code></pre></blockquote><p>其实真要把上面的复制念出来还是笑点满满的,除了加一个B,我们还可以复制本身存在的字:</p><blockquote><pre><code lang="text">无无痛的机器学习 无痛痛的机器学习 无痛的的机器学习 无痛的机机器学习
42 | 无痛的机器器学习 无痛的机器学学习 无痛的机器学习习
43 | </code></pre></blockquote><p>念完了这一组话,我TM脑子里就只剩一个人了——东北F4,你值得拥有:</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic1.zhimg.com/v2-b9ba6ef1be3e84e1c9581e24f3bcdd30.jpg" data-rawwidth="219" data-rawheight="300">好了,通过这种方法我们完成了对齐。既然已经对齐了,我们就来计算ground_truth扩充后所有可能结果的概率,并且把这些概率加起来,得到我们预测结果的总概率。对于每一个序列,由于对齐后序列中每一个输出的内容间相互独立,所以我们直接把softmax层的输出连乘起来就好了。最后就是一个乘加的工作,大家用意念去想一想就会明白。</p><p>到这里,CTC的核心思想也就差不多了。下面留给了我们一个艰巨的问题,刚才这个case比较简单,万一遇上复杂的情况,难道我们还要一个一个地把ground_truth扩展么?</p><p>看来我们要上点高科技了。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23308976&pixel&useReferer"/>冯超Tue, 14 Feb 2017 08:46:24 GMT
- Dynamic Network Surgery实验https://zhuanlan.zhihu.com/p/24307349<p>感谢<a href="https://www.zhihu.com/people/03675ab7bf1c28d3d71d2154abb3ddd1" data-hash="03675ab7bf1c28d3d71d2154abb3ddd1" class="member_mention" data-editable="true" data-title="@我爱机器学习" data-hovercard="p$b$03675ab7bf1c28d3d71d2154abb3ddd1">@我爱机器学习</a>对本文的审阅。</p><p>这一次我们来看看网络压缩的一个方案——来自英特尔实验室的一篇做模型压缩的论文以及相关的实验:Dynamic Network Surgery for Efficient DNNs</p><h2>算法原理</h2><p>论文中对网络压缩算法的介绍还是很高大上的,但是这些高大上的内容和最终的实现相比还是有一些距离。本着减少痛苦的原则,让我们用大白话来介绍这个算法的具体过程。</p><p>模型压缩是希望用最少的参数做同样的事,这对于在一些特殊的设备上运行深度学习模型来说是很有帮助的。比方说在手机上跑一个VGG模型,恐怕存放这个模型的所需的空间就能让人吓一跳。从另外一方面讲,深度学习的模型中不是每一个参数都那么有用,我们可以适当地关闭一些影响力不大的参数,同时又能保持精度不会有大的变动,那么这就是一个令人满意的结果。</p><p>具体来说怎么做呢?我们给每一个参数添加一个配对参数——Mask。这个Mask可以和参数进行点乘,从而得到被Mask过滤后的参数。如果Mask上的值为1,那么对应位置的参数将被保留,如果Mask上的值为0,那么对应位置的参数将被清除。</p><p>有了Mask,我们问题又来了,每一个参数应该设置成什么值呢?一个直观的方案是根据参数数值的大小来判断,一般来说数值越大,它所起到的作用也越大。所以柿子要捡软的捏,我们可以设定一个阈值,把比阈值小的参数关闭掉,只保留大数值的参数。</p><p>但是这又带来了一个新的问题。虽然这些被关闭的参数数值都很小,但是累积起来也是一个很可观的数字,我们这样把它们关闭掉,还是有可能造成精度损失的。于是乎,当我们把一些参数关闭后,我们还需要重新训练,让参数在新的环境适应——也许会有新的参数变得很小,从而被关闭,当然也有可能有些被关闭的参数死灰复燃,变得重要起来。所以设置Mask的值和重新训练两个步骤需要交替进行。</p><p>说到这里我们就不由地想起Online Learning来。虽然最终的目的不太相同,但是大家都有个共同的心愿,就是给目标函数加一个参数的L0范数。曾经的截断梯度方法也利用了和上面有点类似的思想:</p><blockquote><p>每隔一段时间(窗口),我们对所有的参数进行一遍考察,如果参数的数值太小,我们就将其设为0,关闭掉这个特征对应的参数。</p></blockquote>所不同的是,由于截断梯度法所面临的是Online Learning,这个参数说截断就截断了;而我们这里的方法只是加上一个Mask,并不真正删除权重值。不过看上去这两个领域的思想也许能擦出更多的火花。<h2>MNIST实验</h2><p>我们来看看文章对应的代码效果如何。代码的位置为<a href="https://github.com/yiwenguo/Dynamic-Network-Surgery" data-editable="true" data-title="yiwenguo/Dynamic-Network-Surgery" class="">yiwenguo/Dynamic-Network-Surgery</a>。</p><p>代码中存在一点小问题,根据编译的提示进行修改就可以了,这里就埋个雷不详细介绍了,供大家随意踩。</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic2.zhimg.com/v2-24721f1825a9378ca2f667b0d944e948.png" data-rawwidth="393" data-rawheight="357">(基于模板原创的哟……)</p><p>压缩的Layer有一些参数,其中我们接下来比较关注的是cRate。当我们把一个已经训练过的模型拿过来以后,我们会计算每个Layer参数的均值mean和标准差std。如果一个参数的绝对值小于:</p><p><equation>threshold1=0.9*(mean+cRate*std)</equation>时,</p><p>这个参数将被关闭,当这个参数的绝对值大于:</p><p><equation>threshold2=1.1*(mean+cRate*std)</equation>时,</p><p>这个参数将会被重新打开。如果cRate越大,我们的压缩效果会越好。</p><p>其实关于这个问题我很想换一个复杂的数据集做实验的,但是由于给出的代码没有CUDNN版的实现,而Caffe的非CUDNN版实在慢不少,所以我们就用一个简单的数据集——MNIST举例好了。</p><p>首先我们用LeNet训练一个处理MNIST的模型,这个用一个普通版本的caffe就可以训练完成,最终在测试集的精确率是99.16%。</p><p>接下来我们要做网络压缩和重训练。我们可以列出一些实验的结果:</p><p>当cRate=1时,在测试集的精度几乎不受任何损失,但参数的比例已经降低到:</p><pre><code lang="text">conv1:28.8%
44 | conv2:18.08%
45 | ip1:7.83%
46 | ip2:23.26%</code></pre><p>当cRate=2时,在测试集的精度几乎不受任何损失,但参数的比例已经降低到:</p><pre><code lang="text">conv1:15.8%
47 | conv2:8.46%
48 | ip1:2.97%
49 | ip2:11.96%</code></pre><p>当cRate=3时,精度降到98.71%,但参数的比例已经降低到:</p><pre><code lang="text">conv1:4.8%
50 | conv2:2.1%
51 | ip1:1.2%
52 | ip2:4.8%</code></pre><p>当cRate=4时,直接导致训练失败。基本上这就是模型压缩的极限了,由于参数最多的地方在全连接层,所以最终的模型体积和两个ip层相关。</p><p>因为没有CUDNN版的实现,所以想把这个压缩功能用在你的模型上,还需要点时间。这个坑留给各位,让我们自己动手实现一个CUDNN版本的Layer吧!</p><h2>私货时间</h2><p>欢迎加入我爱机器学习9群:173718917</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/24307349&pixel&useReferer"/>冯超Sat, 14 Jan 2017 11:48:43 GMT
- 番外篇(6)——共轭梯度的效果https://zhuanlan.zhihu.com/p/23811968<p>本文收录在<a href="https://zhuanlan.zhihu.com/p/22464594" data-editable="true" data-title="无痛的机器学习第一季" class="">无痛的机器学习第一季</a>。</p>前面我们聊了许多有关共轭梯度的内容,也基本上推导出了我们想要的算法,不过在此之前我们还是要完成上一回留下的一个小尾巴,那就是证明某一轮迭代的梯度和之前所有轮的优化方向正交而不是共轭正交。没有错,正是因为前面一直再利用共轭正交的性质,到了这里我们才能实现正交的效果。<h2>梯度和优化方向的关系</h2><p>在介绍共轭梯度的过程中,我们提出了误差这个概念,当然我们还有一个类似的概念叫做残差。这两个概念还是有很大的不同的,希望大家能够分别。我们多次提到共轭梯度法的基本思想:每一轮把某一方向优化彻底,保证后面的优化不再对这个方向做任何操作。那么我们可以想象,假设我们的算法一共进行了T轮迭代,我们就可以用这T轮求出的优化方向组合成最终的误差。</p><p>假设我们的初始参数值为<equation>x_1</equation>,那么它到最优点的距离为<equation>e_1</equation>,我们每一步求出的优化方向为<equation>d_t</equation>,于是乎,根据上面的介绍我们可以给出如下的公式:</p><equation>e_1=\sum_{i=1}^T\gamma_id_i</equation><p>也就是说我们可以用这样的方式表示误差,同样,对于不同迭代轮数的误差,我们也可以用不同的方式进行表示。很显然,我们可以猜到<equation>\gamma</equation>和前面我们提到的<equation>\alpha</equation>步长之间的关系。</p><p>那么下面我们就来证明一下:</p><equation>d_i^Tg_j=0,(i<j)</equation><equation>d_i^Tg_j=d_i^T(AX_j)=d_i^T(AX_j-AX^*)=d_i^TAe_j</equation><equation>=d_i^TA(\sum_{t=j}^T\gamma_td_t)</equation><p>因为我们前面已经说明任意两个优化方向之前是相互正交的(Gram-Schmidt方法),所以这是式子的结果为0。</p><p>所以到这里我们可以说:通过利用共轭正交的性质,我们得到了更好的正交性质,这个正交性质要比前面的最速下降法的正交性质好很多。这就是共轭梯度法最精髓的地方。</p><p>在这里不免有些感慨,前辈们的脑洞真心不一般,能够利用一些看上去抽象又无关紧要的定理帮助我们解决一些核心的大问题,这里面存在的不仅仅是数学的美丽,有时甚至是哲学的精彩……</p><p>毕竟不是心灵鸡汤文,抒情的套路还是要少一些。我们还是继续来关注这个算法,到这里我们的算法全过程就应该一目了然了:</p><pre><code lang="text">def conjugateGradient(A, b, x):
53 | grad = np.dot(A, x) - b
54 | p = -grad
55 | while True:
56 | if abs(np.sum(p)) < 1e-6:
57 | break
58 | gradSquare = np.dot(grad, grad)
59 | Ap = np.dot(A, p)
60 | alpha = gradSquare / np.dot(p, Ap)
61 | x += alpha * p
62 | newGrad = grad + alpha * Ap
63 | beta = np.dot(newGrad, newGrad) / gradSquare
64 | p = -newGrad + beta * p
65 | grad = newGrad
66 | return x
67 | </code></pre><p>好了,代码放到这里,相关的实验就按下不表了。大家感兴趣可以自己试试看。</p><p>好了,这一次的番外篇就到此结束了。我们实际上介绍了两个“全自动”的优化算法,所谓的全自动,就是说它不需要调参。当然为此带来的代价也比较大,我们无法把这些算法用在所有的场景上,而且在同样的场景上,也许还有比他们更好的算法。</p><p>优化算法是个大坑,我们要慢慢跳,这次就跳到这里。拜拜了~</p><h2>私货时间</h2><p>欢迎加入我爱机器学习9群:173718917!</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23811968&pixel&useReferer"/>冯超Sat, 07 Jan 2017 22:23:42 GMT
- 番外篇(5)——共轭方向的构建https://zhuanlan.zhihu.com/p/23810213<p>本文收录在<a href="https://zhuanlan.zhihu.com/p/22464594" data-editable="true" data-title="无痛的机器学习第一季" class="">无痛的机器学习第一季</a>。</p>前面我们聊过了共轭梯度的一些性质,同时我们也推导出了求步长的方法,下面就来看看如何求解出优化方向。<p>我们要解决的主要问题是优化方向的正交问题。由于每一次的优化后,剩下的误差和此次的优化正交(共轭正交),所以可以看出每一个优化方向彼此间都是正交的。那么如何构建一系列的正交方向呢?</p><h2>Gram-Schmidt方法</h2><p>在线性代数中,我们曾经学过一个向量正交化的方法——Gram-Schmidt方法。这个算法的内容在这里还是要说一下的,算法的输入是N维空间中N个线性无关的向量——线性无关还是有必要的,至于原因……</p><p>算法的输出是N个相互正交的向量,也就是我们最终想要的效果。</p><p>那么具体怎么做呢?</p><p>对于第一个向量,我们保持它不变;</p><p>对于第二个向量,我们去掉其中和第一个向量共线的部分;</p><p>对于第三个向量,我们去掉其中和第一、二个向量共线的部分;</p><p>对于第N个向量,我们去掉其中和第一、二、……N-1个向量共线的部分;</p><p>听上去思路还是蛮清晰的,那么具体怎么做呢?</p><p>如果输入向量是:{<equation>u_1,u_2,...,u_N</equation>}</p><p>输出向量是:{<equation>d_1,d_2,...,d_N</equation>}</p><p>那么对于每一个向量,我们要做下面的转换:</p><equation>d_t=u_t+\sum_{i=1}^{t-1}\beta_{t,i}d_i</equation><p>其中的<equation>\beta</equation>表示向量被去掉的分量,这个数字是要求出来的。那么我们怎么求这个数字呢?我们利用前面提到的性质,向量之间正交(我们这里还是共轭正交),于是有</p><equation>d_l^TAd_t=0,(l=1,2,...,t-1)</equation><p>于是我们有</p><equation>d_l^TAd_t=d_l^TA(u_t+\sum_{i=1}^{t-1}\beta_{t,i}d_i)=d_l^TAu_t+d_l^TA\sum_{i=1}^{t-1}\beta_{t,i}d_i</equation><p>利用正交的性质,我们可以把公式化简为:</p><p><equation>=d_l^TAu_t+d_l^TA\beta_{t,i}d_i=0</equation>,所以最终我们得到:</p><equation>\beta_{t,i}=-\frac{d_l^TAu_t}{d_l^TAd_i}</equation><p>下面我们就得到了完整的算法流程,这个算法的过程比较繁琐,不过是可行的。</p><h2>共轭梯度</h2><p>这个算法倒是聊完了,那么问题又来了——</p><ol><li>我们要用什么向量去构建这些正交向量</li><li>前面我们看到随着向量数量的增加,我们需要计算的参数也越来越多,我们要计算N方程度个<equation>\beta</equation>,这个计算的数目还是有点多,那么我们能不能再减少一些呢?</li></ol><p>上面的问题当然能够解决,而采用的方式也比较简单——就用我们最常见的梯度来解决。这就是算法名字的来源——共轭+梯度。</p><p>那么第一个问题解决了,下面主攻第2个问题。第2个问题有点绕,所以我们先给出结论,那就是我们在每次求一个新方向时,只要再求解一个新的<equation>\beta</equation>就可以了。</p><p>下面是推导过程。我们要证明当<equation>u_t=g_t</equation>时,首先不是去开始证明第2个问题,而是要完成一个前置条件的证明——听上去有点晕啊。那就是由梯度组成的这个向量组是不是一个线性无关的向量组呢?</p><p>我们来证明一下。</p><p>我们前面提过共轭梯度法的特点——上一轮的优化方向和这一轮的误差之间正交,那么能不能推导出某一轮的误差和之前所有的优化方向全部正交呢?当然可以,不过这里面涉及到一些subspace的思想,我们放在后面再说,我们现在要直接给出一个靠谱的定理,那就是当采用了共轭梯度法之后,对于某一轮t求出的梯度<equation>g_t</equation>,它和前面t-1轮的梯度正交(这里不是共轭正交,word天……),用形式化的方式描述,就是:</p><equation>g_i^Tg_j=0,(i<j)</equation><p>我们暂时相信这个定理,后面我们会更详细的分析它(因为进度条快撑不住了……),承认了这个定理,我们就回头看看前面求解的那些<equation>\beta</equation>:</p><p><equation>g_{j+1}^Tg_i=(AX_{j+1})^Tg_i=(A(X_j+\alpha_jd_j))^Tg_i=g_j^Tg_i+\alpha_jd_j^TAg_i</equation>(A是对称矩阵)</p><p>所以有:</p><equation>d_j^TAg_i=\frac{1}{\alpha_j}[g_{j+1}^Tg_i-g_j^Tg_i]</equation><p>我们发现上面公式的左边就是<equation>\beta</equation>的分子,如果我们能够证明其中很多的<equation>\beta</equation>分子为0,那么我们就完成了证明。</p><p>而从前面的公式看,我们必须满足j<i的条件,于是只有当j=i-1是,上面的式子不等于0,所以只有<equation>\beta_{t,t-1}</equation>这一项不为0,换句话说我们只需要求解这一项,问题就解决了。</p><p>好了,进度条阵亡了,我们也得到了答案,下一回我们来看一下算法具体的效果。</p><h2>私货时间</h2><p>欢迎加入我爱机器学习8群:19517895!</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23810213&pixel&useReferer"/>冯超Wed, 28 Dec 2016 23:14:37 GMT
- 番外篇(4)——共轭梯度法入坑https://zhuanlan.zhihu.com/p/23804838<p>本文收录在<a href="https://zhuanlan.zhihu.com/p/22464594" data-editable="true" data-title="无痛的机器学习第一季" class="">无痛的机器学习第一季</a>。</p>前面我们已经把最速下降法的内容介绍的差不多了,下面我们要做的就是介绍这个真正的主角了——共轭梯度法。这个优化方法算是活跃在优化世界的一个经典算法了,它的计算速度还算不错,方法也算相对简单——真的是相对,因为比起梯度下降它还是复杂不少,但是和其他的一些方法比较,那就不算难了。<p>好了,我们直奔主题。在番外篇的开篇我们就提到了机器学习的三个部件。优化算法作为一个黑盒,一般来说是不为人所知的。所以我们的重点就是揭开它的面纱,尽可能清楚地阐述它的原理。</p><h2>更高级的约束</h2><p>前面在最速下降法中,我们提到了最速下降法的一个性质——那就是相邻两次的优化方向是正交的。乍一听上去,总感觉这个性质很酷,但是看过了一些实际案例,又不免让人心灰——走成"zig-zag"的形状,还好意思标榜这个性质?</p><p>于是乎,我们开始对优化方向有了更大的野心——能不能让我们的优化方向更加智能,我们每朝一个方向走,就把这个方向走到极致?所谓的极致,可以理解为在优化的过程中我们再也不需要朝这个方向走了。于是乎我们引出了另外一个变量,叫做误差:</p><equation>e_t=x^*-x_t</equation><p>这个误差表示了参数的最优点和当前点之间的距离。那么我们的目标就可以更在形式化了,我们希望每一步优化后,当前的误差和我们刚才优化的方向正交!注意,这里我们已经不再使用梯度这个词,而是使用优化方向,因为从现在开始,我们的优化方向不一定是梯度了。当然我们也要换一个变量名比较好,不然会引起误会:</p><equation>r_t</equation><p>还是写个公式出来比较靠谱:</p><equation>r_t^Te_{t+1}=0</equation><p>这样我们可以想象,如果我们的优化空间有d维,那么我们最多只需要迭代d轮就可以求解出来了。听上去蛮靠谱的。</p><p>好了,大饼画完了,下面就是填坑时间了。</p><h2>坑</h2><p>理想很丰满,但是现实很骨感。如果我能知道那个误差,我还优化干嘛?直接按误差更新不就完事了?但是想知道误差还是需要一步一步地求解啊?感觉我们掉入了"chicken-egg senario"里面。</p><p>但是别着急,我们还有数学武器在手,我们可以用线性代数的知识偷天换日,填满这个坑。于是乎,见证奇迹的时刻就要来临了。</p><h2>共轭</h2><p>偷天换日的关键就在这个共轭上了。其实一开始看到这个词的时候我是拒绝的,这是什么鬼?这词是啥意思?</p><p><img rel="noreferrer" src="https://images.weserv.nl/?url=ssl:pic3.zhimg.com/v2-b16e0493701ee49ee297485a538e481c.jpg" data-rawwidth="480" data-rawheight="360">一个按原意的解释——轭就是绑在两头牛身上的木头,它让两个本来独立的个体变成了一个整体,属于牵线搭桥之类的关键道具。</p><p>好了,我们再回到刚才的问题中,前面我们说了我们新的正交特性,那么放在共轭这个环境下是什么效果呢?我们希望现在的关系变为共轭正交,存在一个矩阵A(A就是轭),使得:</p><equation>r_t^TAe_{t+1}=0</equation><p>其实看到这里我依然是拒绝的……这又是什么鬼,三观都崩塌了好不好,这么乱搞有什么意义?</p><p>别着急,其实如果我们把上面的原始公式中间加一个东西,看上去就舒服很多了:</p><equation>r_t^TIe_{t+1}=0</equation><p>单位阵不改变结果,现在我们要加一个能改变结果的东东,仅此而已。那么这个矩阵是什么作用呢?</p><p>我们可以认为这个矩阵要完成线性变换的作用,将一个向量从一个线性空间转换到另一个空间。转换后的向量可以满足正交的性质,如果这个矩阵一直保持不变,听上去这个性质也是合理的啊。</p><p>那么有没有更加实际的例子呢?</p><p>比方说我们有两个向量:</p><equation>a=[1,1] , b=[1,0.5]^T</equation><p>很显然它们不是正交的,但是如果我们多了一个矩阵A:</p><equation>A=[[1,0][0, -2]]</equation><p>那么我们发现,b经过A转换后就与a正交了。</p><p>所以这个新的条件实际上只是多绕了一个弯,和前面的条件差距并不大。</p><p>一旦接受了这样的设定,下面的内容就好理解多了。</p><h2>共轭梯度法的流程</h2><p>好了,我们已经明确了共轭梯度法的目标和特点,那么我就要开始推导算法公式了。当然,共轭梯度法也属于line search的一种,我们的总体思路不变:</p><ol><li>确定优化方向</li><li>确定优化步长</li></ol><p>相对而言,确定优化方向比确定优化步长麻烦,我们放在后面说,现在先来捡个软柿子,那就是第2步,我们从上面提过的公式开始:</p><equation>r_t^TAe_{t+1}=0</equation><p>好了,开始推导:</p><equation>r_t^TAe_{t+1}=r_t^TA[e_{t}+X_t-X_{t+1}]=r_t^TA[e_{t}+\alpha_t r_t]</equation><p><equation>=r_t^TAe_{t}+\alpha_t r_t^TAr_t=0</equation>,于是</p><equation>\alpha_t=-\frac{r_t^TAe_{t}}{r_t^TAr_t}</equation><equation>\alpha_t=-\frac{r_t^TA(X^*-X_t)}{r_t^TAr_t}</equation><p>我们知道<equation>AX^*=0</equation>,<equation>g_t=AX_t</equation>,于是公式最终变为:</p><equation>\alpha_t=\frac{r_t^Tg_t}{r_t^TAr_t}</equation><p>好了,我们发现我们利用多出来的A把前面的误差e成功地消掉了,这下子步长可解了。让我们记住这个公式——不是背下来,而是大概记住这个形式,后面我们还会用到它。</p><p>下一回我们继续来看看后面的推导。</p><h2>私货时间</h2><p>欢迎加入我爱机器学习8群:19517895!</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23804838&pixel&useReferer"/>冯超Sun, 25 Dec 2016 11:50:15 GMT
- 番外篇(3)——最速下降法的特点https://zhuanlan.zhihu.com/p/23804818<p>本文收录在<a href="https://zhuanlan.zhihu.com/p/22464594" data-editable="true" data-title="无痛的机器学习第一季" class="">无痛的机器学习第一季</a>。</p><p>在前面两回中,我们介绍完最速下降法的的算法内容,并且介绍完了它的下降速度。从结果中我们可以看出,如果矩阵A的最大最小特征值差距大,最速下降法就有可能获得较慢的收敛性,而两者越相近,我们的收敛性也会相应增强。所以我们最终得到了一个结论,那就是最速下降法的收敛性与矩阵的特征值有关。</p><p>好了,说了这么多,我们还是来看看它的代码是什么样子:</p><pre><code lang="text">def steepestGD(A, x):
68 | while True:
69 | p = -np.dot(A, x)
70 | if abs(np.sum(np.abs(p))) < 1e-6:
71 | break
72 | gradSquare = np.dot(p, p)
73 | Ap = np.dot(A, p)
74 | alpha = gradSquare / np.dot(p, Ap)
75 | x += alpha * p
76 | return x
77 | </code></pre><p>一直以来我们在展示完代码后都会顺势给出几个例子,但是这一回我们就不做这样的事情了。关于这个代码的细节我们也不做多的case展示了,我们直接来看看最速下降法当中一个有趣的问题——一步到位问题。</p><h2>最速下降法之一步到位攻略</h2><p>所谓的一步到位,是指我们经过一轮迭代就能找到最优解,这个速度是非常让人羡慕的,而这其中还包含着一些数学知识。</p><p>由于最速下降法的步长和计算过程很有关系,所以我们需要对此进行进一步的分析,来加深对这种优化算法的印象。我们设想一种场景,那就是我们的优化方向刚好包含了最优点,那么我们就有可能在一轮迭代的过程中完成优化。</p><p>我们来想想一个简单的场景,经过某一步优化,我们找到了最优值,那么下面的公式一定满足:</p><equation>x^*=x_t-\alpha_tg_t</equation><p>因为最优值点的梯度为0,所以我们将梯度计算的公式带入,就有了:</p><equation>A(x_t-\alpha_tg_t)=0</equation><p>经过变换,我们可以得到公式的第一形态:</p><equation>g_t-\alpha_tAg_t=0</equation><equation>(I-\alpha_tA)g_t=0</equation><p>从上面的式子中,我们可以找出最简单的两种解:</p><p><equation>g_t=0</equation>,当然,这时候我们已经找到了最优解,所以这个解并没有什么意义;</p><p><equation>A=\frac{1}{\alpha}I</equation>,这个解倒是很有意义,不过太简单了。</p><p>比方说当<equation>\alpha=1</equation>时,原式变成了:</p><p><equation>f(X)=\frac{1}{2}X^TX</equation>,</p><p>这个问题看上去也确实好解,对于2维的空间,这个优化函数的等高线图就是由一个个同心圆组成的,这是最容易优化的一种函数,所以一步解出来倒也不算奇怪。</p><p>谈完了上面两种容易找到的解,下面我们看看一些隐藏的解。当然我们需要把公式做一定的转换:</p><equation>Ag_t=\frac{1}{\alpha_t}g_t</equation><p>嗯……这个公式看上去就熟悉多了,如果<equation>g_t</equation>是A的特征向量,那么<equation>\frac{1}{\alpha}</equation>就是它优化的特征值了?当然,一般来说特征值是确定的,特征向量是可以变化的。但总之听上去好有道理。关键时刻还得靠万能的线性代数啊。</p><p>所以我们如果能保证我们的参数满足上面的条件,优化过程同样可以做到一步完成。当然,求解特征值的复杂度实在有点高,所以一般来说大家也不会采用这种方法加速求解。上面的问题只是帮助我们更好地理解最速下降法而已。</p><p>那么最后一个思考题了,上面我们对梯度做了约束,那么对于参数值呢?想要一步优化,它需要满足什么样的特点呢?</p><h2>私货时间</h2><p>欢迎加入我爱机器学习8群:19517895!</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23804818&pixel&useReferer"/>冯超Mon, 19 Dec 2016 23:42:16 GMT
- 番外篇(2)——无聊的最速下降法推导https://zhuanlan.zhihu.com/p/23799012本文收录在<a href="https://zhuanlan.zhihu.com/p/22464594" data-editable="true" data-title="无痛的机器学习第一季" class="">无痛的机器学习第一季</a>。<p>好吧,我想题目已经说明了一切,虽然说这个过程很无聊,但是我们可以收藏下这段推导,因为它的结论还是很有用的……那不如让我们先来看看结论:</p><p>对于上一回我们介绍的那个函数:</p><equation>f(X)=\frac{1}{2}X^TQX</equation><p>其中Q是一个对称正定矩阵,<equation>\lambda_n</equation>是Q的n个特征值,并且满足0 > <equation>\lambda_1</equation>>= <equation>\lambda_2</equation>>=
78 | <equation>\lambda_n</equation>,那么有: </p><equation>f(X_{k+1})\leq(\frac{\lambda_n-\lambda_1}{\lambda_n+\lambda_1})^2f(X_k)</equation><p>下面问题来了,我们求出上面这个公式有毛用?我们可以看出随着优化的不断进行,我们的函数是不断变小的,但是我们需要为函数优化定一个期限。我们希望函数能够尽快地优化到位,那么<equation>\frac{\lambda_n-\lambda_1}{\lambda_n+\lambda_1}</equation>这部分当然是越小越好了。</p><p>如果说大家想知道结论,那么这篇文章到此结束,下面是具体的推导了,前方各种高能,非战斗人员点了赞就可以撤了……</p><h2>公式推导</h2><p>公式推导总体来说分为几个部分:</p><ol><li>求出步长<equation>\alpha_t</equation></li><li>整理公式</li><li>Kantorovich Inequality</li></ol><p>下面我们一步一步来,其中的第一步可以跳过了,因为我们在上一篇文章已经做过了,那就是求出步长,这里我们就不再推导一遍了,直接给出结果:</p><equation>\alpha_t=\frac{g_t^Tg_t}{g_t^TAg_t}</equation><p>下面是第2部。</p><h2>整理公式</h2><p>这一步的主要目标是去凑那个公式,我们从公式的左边出发,首先要利用更新公式了:</p><equation>X_{t+1}=X_t-\alpha_tg_t</equation><equation>f(X_{t+1})=\frac{1}{2}X_{t+1}^TAX_{t+1}=\frac{1}{2}(X_t-\alpha_tg_t)^T A (X_t-\alpha_tg_t)</equation><equation>=\frac{1}{2}[X_t^TAX_t-X_t^TA\alpha_tg_t-\alpha_tg_t^TAX_t-\alpha_t^2g_t^TAg_t]</equation><equation>=\frac{1}{2}[2f(X_t)-X_t^TA\alpha_tg_t-\alpha_tg_t^TAX_t-2\alpha_t^2f(g_t)]</equation><p>接下来我们需要两个公式:</p><p>首先,我们的矩阵A是对称的,所以<equation>A^T=A</equation>;</p><p>其次,我们的导数公式:<equation>g_t=AX</equation></p><p>所以上面的公式就变成了:</p><equation>=\frac{1}{2}[2f(X_t)-(AX_t)^T\alpha_tg_t-\alpha_tg_t^T(AX_t)+2\alpha_t^2f(g_t)]</equation><equation>=\frac{1}{2}[2f(X_t)-\alpha_tg_t^Tg_t-\alpha_tg_t^Tg_t+2\alpha_t^2f(g_t)]</equation><equation>=f(X_t)-\alpha_tg_t^Tg_t+\alpha_t^2f(g_t)</equation><p>好了,公式整理得差不多了,下面我们要把<equation>\alpha_t</equation>的公式代入了:</p><equation>=f(X_t)-\frac{g_t^Tg_t}{g_t^TAg_t}g_t^Tg_t+(\frac{g_t^Tg_t}{g_t^TAg_t})^2f(g_t)</equation><equation>=f(X_t)-\frac{(g_t^Tg_t)^2}{g_t^TAg_t}+(\frac{g_t^Tg_t}{g_t^TAg_t})^2(\frac{1}{2}g_t^TAg_t)</equation><equation>=\frac{1}{2}[X_t^TAX_t-\frac{(g_t^Tg_t)^2}{g_t^TAg_t}]</equation><p>到这里似乎又推导不动了,下面继续放一个杀招:</p><equation>X_t^TAX_t=X_t^TAA^{-1}AX_t=X_t^TA^TA^{-1}AX_t</equation><equation>=(AX_t)^TA^{-1}(AX_t)=g_t^TA^{-1}g_t</equation><p>于是公式可以进一步整理了:</p><equation>=\frac{1}{2}X_t^TAX_t[1-\frac{(g_t^Tg_t)^2}{(g_t^TAg_t)(g_t^TA^{-1}g_t)}]</equation><equation>=f(X_t)[1-\frac{(g_t^Tg_t)^2}{(g_t^TAg_t)(g_t^TA^{-1}g_t)}]</equation><p>好了,整理到这里我们的第一步工作基本完成了,我们来看看我们成果和最终的结果:</p><p>最终结果:<equation>f(x_{k+1})\leq(\frac{\lambda_n-\lambda_1}{\lambda_n+\lambda_1})^2f(x_k)</equation></p><p>目前结果:<equation>f(X_{t+1})=[1-\frac{(g_t^Tg_t)^2}{(g_t^TAg_t)(g_t^TA^{-1}g_t)}]f(X_t)</equation></p><p>好了,下面的目标很明确了,我们要做的就是里面那一大堆的变换。</p><h2>Kantorovich Inequality</h2><p>说实话如果是一般的文章到这里就会结束了,可是这篇推导实在比较恶心,于是我决定一口气推完,不给大家恶心第二次的机会。</p><p>下面这部分的转换据说是一个叫做Kantorovich Inequality的定理,但是这么不常见的定理对于我们来说实在陌生,如果拿这个名称糊弄大家就有点不太地道了,于是乎我们就假装不知道这个定理,把这个定理再推导一遍。</p><p>我们这一步的目标是证明:</p><equation>\frac{(g_t^Tg_t)^2}{(g_t^TAg_t)(g_t^TA^{-1}g_t)}\geq \frac{4\lambda_1\lambda_n}{(\lambda_1+\lambda_n)^2}</equation><p>也就是<equation>\frac{(g_t^TAg_t)(g_t^TA^{-1}g_t)}{(g_t^Tg_t)^2}\leq \frac{(\lambda_1+\lambda_n)^2}{4\lambda_1\lambda_n}</equation></p><p>好了,现在我们开始继续推导。左边部分的A可以变为特征值的形式:</p><equation>=\frac{(g_t^TS^T\Lambda Sg_t)(g_t^TS^T \Lambda^{-1}Sg_t)}{(g_t^TS^TSg_t)^2}</equation><p>令<equation>Sg_t=l</equation>,可以得到:</p><equation>=\frac{\sum_{i=1}^n{\lambda_i * l_i^2}\sum_{i=1}^n{\frac{1}{\lambda_i} * l_i^2}}{(l_t^Tl_t)^2}</equation><p>此时的分母相当于一个归一化的因子,所以我们可以将式子进一步化解为:</p><equation>\sum_{i=1}^n{\lambda_i * z_i^2}\sum_{i=1}^n{\frac{1}{\lambda_i} * z_i^2}</equation><p>given <equation>\sum_{i=1}^n{z_i^2}=1</equation></p><p>我们可以利用拉格朗日乘子法把这两个公式融合起来,得到:</p><equation>F=\sum_{i=1}^n{\lambda_i * z_i^2}\sum_{i=1}^n{\frac{1}{\lambda_i} * z_i^2}+\alpha(\sum_{i=1}^n{z_i^2}-1)</equation><p>这里令</p><equation>\sigma=\sum_{i=1}^n{\lambda_i * z_i^2}</equation><equation>\hat{\sigma}=\sum_{i=1}^n{\frac{1}{\lambda_i} * z_i^2}</equation><p>我们可以进行日常的求导工作找到这个函数的极值:</p><equation>\frac{\partial F}{\partial z_i}=2(\sigma \frac{1}{\lambda_i}z_i+\hat{\sigma}\lambda_iz_i-\alpha z_i)=0,(i=1...n)</equation><equation>\frac{\partial F}{\partial z_i}=z_i(\sigma+\hat{\sigma}\lambda_i^2-\alpha \lambda_i)=0,(i=1...n)</equation><p>我们可以给出上面求导的一种解,那就是我们令尽可能多的<equation>z_i</equation>等于0,而保留其中的两个 <equation>z_i</equation>不等于0,关于这两个的导数,我们让<equation>(\sigma+\hat{\sigma}\lambda_i^2-\alpha \lambda_i)</equation>这一部分等于0,同时我们保证所有的变量都满足那个约束,于是我们最原始的公式就变成了:</p><equation>F=(\lambda_kz_k^2+\lambda_lz_l^2)(\frac{1}{\lambda_k}z_k^2+\frac{1}{\lambda_l}z_l^2)</equation><p>given <equation>z_k^2+z_l^2=1</equation></p><p>下面就是复杂的各种变换:</p><equation> = \frac{1}{4} (\sqrt{\frac{\lambda_k}{\lambda_l}} + \sqrt{\frac{\lambda_l}{\lambda_k}})^2 (z_k^2 + z_l^2)^2 - \frac{1}{4} (\sqrt{\frac{\lambda_k}{\lambda_l}} - \sqrt{\frac{\lambda_l}{\lambda_k}})^2 (z_k^2 - z_l^2)^2</equation><p>因为这时右边第2项是小于0的,加上前面given的条件,所以可以得到:</p><equation>\leq \frac{1}{4} (\sqrt{\frac{\lambda_k}{\lambda_l}} + \sqrt{\frac{\lambda_l}{\lambda_k}})^2</equation><p>我们选择差距最大的两个特征值作为上界,于是又有</p><equation>\leq \frac{1}{4} (\sqrt{\frac{\lambda_1}{\lambda_n}} + \sqrt{\frac{\lambda_n}{\lambda_1}})^2</equation><p>总之一个是最大的特征值,一个是最小的就好。于是乎又可以得到:</p><equation>=\frac{(\lambda_1+\lambda_n)^2}{4\lambda_1\lambda_n}</equation><p>我们最终想要的结果马上就要出现了!</p><p>于是乎我们得到的完整内容是:</p><equation>\frac{(g_t^Tg_t)^2}{(g_t^TAg_t)(g_t^TA^{-1}g_t)}\geq \frac{4\lambda_1\lambda_n}{(\lambda_1+\lambda_n)^2}</equation><h2>最终章</h2><equation>f(X_{k+1}) \leq (1 - \frac{4 \lambda_1 \lambda_n }{(\lambda_1 + \lambda_n)^2}) f(X_k)</equation><equation>= (\frac{(\lambda_1 + \lambda_n)^2}{(\lambda_1 + \lambda_n)^2} - \frac{4 \lambda_1 \lambda_n }{(\lambda_1 + \lambda_n)^2}) f(X_k)</equation><equation>= (\frac{\lambda_1^2 - 2 \lambda_1 \lambda_n + \lambda_n^2 }{(\lambda_1 + \lambda_n)^2}) f(X_k)</equation><equation>=(\frac{\lambda_1 - \lambda_n}{\lambda_1 + \lambda_n})^2 f(X_k)</equation><p>好了,到这里我们的推导结束了,该休息了……</p><h2>私货时间</h2><p>欢迎加入我爱机器学习8群:19517895!</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23799012&pixel&useReferer"/>冯超Tue, 13 Dec 2016 23:44:21 GMT
- 番外篇(1)——最速下降法https://zhuanlan.zhihu.com/p/23776390本文收录在<a href="https://zhuanlan.zhihu.com/p/22464594" data-editable="true" data-title="无痛的机器学习第一季" class="">无痛的机器学习第一季</a>。<p>番外篇正式开始,我们主要利用番外篇的时间聊一些机器学习中的黑盒部分——没错,就是优化算法。之前接受过前辈的教诲,一个机器学习的套路可以分解成三个部分——模型,目标和优化方法。模型用来定义待解决的问题,目标(一般也会被称作损失函数)用来明确评价模型质量的方法,而优化算法则是具体解决求解过程的问题。有了这三个部分,我们可以说在学术的角度上我们基本上就搞定了一个机器学习问题。之所以在前面加上了学术这两个字,是因为在工业界一个机器学习的问题就不止这三部了。</p><p>好了回到正题,我们回到前面的三个部分,一般来说第一部分是最灵活的,第二部分也算灵活,但还是有一定的约束的,然而第三部分——一般来说都是非常确定的,而且一般也是以一个黑盒的状态出现的。</p><p>于是乎大家一般对第一部分和第二部分更为关注,而对第三部分相对忽视一些。于是乎我们这里就反其道而行,作死地选择和大家聊聊第三部分——优化。实际上在前面的正文中我们已经花了很大的篇幅去聊一些优化算法,下面我们继续聊一些经典的算法。</p><h2>最速下降法</h2><p>友情提示,下面我们要聊的内容主要用于凸函数。关于凸函数的性质这里就不多说了,大家不懂的去查查资料就好。前面我们提到了梯度下降法,也提到了梯度下降法中那个让人头疼的learning rate,那么我们有没有其他的办法不去计算这个learning rate,又能让剃度下降的每一步尽可能地走好呢?</p><p>于是有大神们发明了下面这个方法——最速下降法。所谓的最速下降法,就是在确定下降方向后,从下降方向中找到下降程度最大的一点进行下降。我们可以用形式化的方式来明确表述下:</p><p>如果说我们前面的梯度下降法是先求出梯度,再根据预先设定的learning rate完成下降,那么就完成了一轮的优化;</p><p>而最速下降法在求出梯度之后,要进行另外一个小优化问题的求解过程,那就是选择最合适的learning rate,使得函数值最小,如果待求的函数为f(x),当前的迭代轮数为t,那么当前函数的优化的参数解是<equation>x_t</equation>,这一点的梯度为<equation>-g_t</equation>,于是我们小优化问题就变成了:</p><equation>\alpha_t=argmin_{\alpha_t}f(x_t-\alpha_t*g)</equation><equation>x_{t+1}=x_t-\alpha_t*g</equation><p>好了,下面就该求解这个问题了。实际上我们同样可以采用求梯度并令梯度值为0的方式求出,但是那种方法并不是很容易推导出一个通用的公式,所以我们可以采用另外的方法求出一个公式来。</p><h2>梯度正交</h2><p>最速下降法的优化方向有一个特点,那就是相邻两轮迭代的梯度相互正交。这个特点对于推导最终的算法十分重要,我们首先来证明一下。</p><p>证明这个问题的最好方法是反证法。我们假设迭代轮数分别为t和t+1的梯度分别为<equation>g_t</equation>和<equation>g_{t+1}</equation>,如果两个梯度不正交,那么我们就可以把<equation>g_{t+1}</equation>分解成两个部分——</p><ol><li>与<equation>g_t</equation>共线的部分<equation>g_{t+1}^t</equation></li><li>与<equation>g_t</equation>正交的部分<equation>g_{t+1}'</equation></li></ol><p>那么问题来了——对于被第t轮更新后<equation>x_{t+1}</equation>来说,在<equation>g_t</equation>这个方向上应该是最小的了,换句话说在这个点上,关于<equation>g_t</equation>的方向梯度应该为0,那么<equation>g_{t+1}</equation>就不应该有<equation>g_t</equation>方向的分量。如果有就说明上一轮迭代并没有做到最优,和我们的假设矛盾,所以假设不成立,我们最终可以认定,<equation>g_t</equation>和<equation>g_{t+1}</equation>是正交的。</p><p>知道了正交的特点,我们就可以用这个性质来进行计算了。我们的经典问题是一个二阶优化问题:</p><equation>f(X)=\frac{1}{2}X^TAX</equation><p>首先为了保证这个问题是凸函数,我们需要对上面的一些内容做约束,具体来说就是A是对称正定的,这样,我们就能保证函数的凸性质了。</p><p>于是乎,我们可以得到第一个公式:</p><p>g=AX</p><p>然后是第二个公式,也就是我们刚才推倒了半天得到的结论:</p><equation>g_t^Tg_{t+1}=0</equation><p>最后是第三个公式,也是大家喜闻乐见的参数更新公式:</p><equation>x_{t+1}=x_t-\alpha_tg_t</equation><p>好了,有这三个公式就足够了,我们开始推导:</p><equation>g_t^Tg_{t+1}=0</equation><equation>g_t^T(AX_{t+1})=0</equation><equation>g_t^T(A(X_t-\alpha_t g_t))=0</equation><equation>g_t^T(AX_t-A\alpha_t g_t)=0</equation><equation>g_t^T(g_t-A\alpha_t g_t)=0</equation><equation>\alpha_t=\frac{g_t^Tg_t}{g_t^TAg_t}</equation><p>好了,到此我们就把步长的公式求解出来了,下回我们来看看一些细节问题。</p><h2>私货时间</h2><p>欢迎加入我爱机器学习7群:467165306!</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/23776390&pixel&useReferer"/>冯超Thu, 08 Dec 2016 22:34:55 GMT
--------------------------------------------------------------------------------
/zhihu/zhuanlan/AI/impress-your-cat.xml:
--------------------------------------------------------------------------------
1 |
2 | impress your cat - 知乎专栏https://zhuanlan.zhihu.com/impress-your-catErlang, the Bananarama of languages, is a language out of Sweden that can be used to build web scale, asynchronous, non-blocking, sharded, event driven, message passing, NoSQL, reliable, highly available, high performance, real time, clusterable, bad ass, rock star, get the girls, get the boys, impress your mom, impress your cat applications.Sat, 11 Mar 2017 22:16:12 GMTRickyhttp://blogs.law.harvard.edu/tech/rss- 强烈推荐untrustedhttps://zhuanlan.zhihu.com/p/21636039<p><a class="" href="http://alexnisnevich.github.io/untrusted/">http://alexnisnevich.github.io/untrusted/</a></p><p>不是什么新东西。不要怪我老土。 </p><p>很多所谓的教你学编程的游戏都非常无趣,他们总是站在居高临下的角度以怎么教你学习一点比如程序语言的知识。而且这也没有多大意义。学会trial and error,比掌握一点可怜的知识重要多了。因为思路的限制,大部分都做成了几个bot打来打去这种形式。而像Robocode这种单纯的bot对战,入门就比较困难,比这更糟糕的是,之后更困难,你在会写一些基于简单规则的bot之后直接就不知所措了。 </p><p>untrusted的目标只是做一个好玩的复古的游戏,你使用规定的方式作弊才能进入下一关。我认为这很可能是未来大部分计算机游戏(不要与视频游戏混淆)的起点。同时,尽管他们在开发时并没有考虑什么教育意义,用这个untrusted来入门,比其他你在网上找到的什么东西都强。目标明确,让你自己想办法去作弊,而不是生硬的塞给你一点知识。毫无疑问,把这个玩通关,效果就要比比如萧井陌的2K培训强多了。顺便提一下另外一个用Python的类似的游戏 <a href="https://schilcote.itch.io/injection">https://schilcote.itch.io/injection</a></p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21636039&pixel&useReferer"/>bhuztezMon, 18 Jul 2016 23:03:30 GMT
- 函数式-21天入门教程https://zhuanlan.zhihu.com/p/21601402<p>老是有人问函数式要如何入门。我早就说过了,只要识字的人,函数式就已经入门了 。所以当然-21天就可以入门了。</p><p>在原始APL里,求平均数,通常的写法是</p><pre><code lang="text">avg←{(+⌿⍵)÷≢⍵}
3 | </code></pre><p>而J,求平均数</p><pre><code lang="text">avg =: +/ % #
4 | </code></pre><p>J相对原始APL的一大改进就是我们不再需要使用⍺⍵</p><p>J使用了 [ 和 ] 这两个函数</p><pre><code lang="text">x [ y = x
5 | x ] y = y
6 | </code></pre><p>这样用J使用纯函数风格组合新函数时,所有用到的都是函数,毕竟 [ ] 是真正普通函数,而⍺⍵并不是。</p><p>这对我们有何启发呢?我们平时是如何说平均数的</p><pre><code lang="text">相加 除以 项数
7 | +/ % #
8 | </code></pre><p>除了J是从右向左计算的,我们是从左往右计算的,写法上并没有本质区别。相对应/,加对应+。 Alan J. Perlis 早就说过了 Though the Chinese should adore APL, it's FORTRAN they put their money on。APL你对应不起来还情有可原。J这个都已经完全一样了,你要是还看不出来,那我不禁要问,你到底识不识字了。</p><p>我们用西方不识字的人搞出来的文字理论,当然会觉得有各种省略, 各种倒序,各种词性乱用。明明很自然的说法,用这狗屁理论解释不通,那自然是理论有问题。 </p><p>看看九章算术</p><pre><code lang="text">合分术曰
9 | 母互乘子并以为实
10 | ...
11 | </code></pre><p>你非要因为母指的是分母,认为这个是名词。那当然解释不通了。因为我们的文字从两千多年前就是函数式的,你得把母当成一个函数,作用是取出分母,那就全都能解释通了。</p><p>用类似ML的风格,近似可以写成这样</p><pre><code lang="text">let 合(x:[分,分]) =
12 | ...
13 | where
14 | 实 = 并(互(乘)((母 x), (子 x)))</code></pre><p>这就导致了一个问题,你的代码就没法朗读了。</p><p>所以说,函数式你早就已经入门了,掌握的还是更高级的形式。而不是Haskell里那种 (.) . (.) 。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/21601402&pixel&useReferer"/>bhuztezFri, 15 Jul 2016 11:40:06 GMT
- 21天学通Erlang Slack Teamhttps://zhuanlan.zhihu.com/p/20774580<p><a data-title="slack.com 的页面" data-editable="true" href="https://erlang3437.slack.com/">https://erlang3437.slack.com/</a></p><p>前两天试了一下,感觉还行,至少他还提供一个凑合的gateway支持IRC和XMPP。就去注册一个,结果Slack嫌我给的域名太长不让我注册。后来我想了一下就注册了这个域名。评论或者私信或者邮件告诉我你的邮箱,<b>我就赶紧把你加进去</b>。</p><p>第一章内容重新调整之后,现在路线是一上来,学了一点点Erlang之后,就直接用学的这些东西写一个能解释之前刚学的这部分Erlang的解释器。在自己实现调用栈之后,就加上send/recv这两个特殊函数,使得刚好功能和最原始的Erlang一致。毕竟在消息之前已经实现一些Erlang的功能了,实在没必要用Prolog再来一遍。因此,Prolog部分也可以简化,只保留比Datalog对应的过来多一点点的就够了,高级的operator功能都先无视了。这几天先会完成Prolog部分的代码。我想在6月底之前完成到Prolog那一节之前的内容,因为现在已经有PEG风格的parser了,所以主要就缺一个好的backtracking的例子了。这样一开始几个节的思路理顺了,接下来几个21天还会有很多内容出现,所以我去弄了个Slack Team方便大家吐槽。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/20774580&pixel&useReferer"/>bhuztezTue, 19 Apr 2016 22:54:50 GMT
- 第6/7/8/9个21天https://zhuanlan.zhihu.com/p/20760395<p>因为现在在最最基本的语法之后,直接就开始解释Erlang的AST了,而不是从括号语言那里取绕了。而之前的做法有个问题是,在Prolog之后才开始写parser,但是要解释Prolog就得先写个parser。现在既然已经在用AST了,那么引入parse_transform也不是什么问题。所以可以用一个简单的parse_transform把代码转换成PEG风格的parser。所以在能解释之前所有Erlang模块的AST之后,就开始写PEG parser。这样在Prolog前就有parser了,且在backtracking之前过渡更自然一点。</p><p>expression.erl 类似 Erlang Shell 里解释Erlang表达式的功能。比如 </p><pre><code lang="erlang">{ok,1,[{'X',1}]} = expression:eval_string("X.",[{'X',1}]).
15 | </code></pre><p>function.erl 更进一步,能解释单个模块里的函数,比如</p><pre><code lang="erlang">function:test({module,"seq.erl"}).
16 | </code></pre><p> 相当于</p><pre><code lang="erlang">ok = seq:test().
17 | </code></pre><p>只是所有seq里的函数是由function.erl来解释的。目前,运行seq.erl, board.erl, bindings.erl, expression.erl以及function.erl都没有问题。</p><p>最简单的parse_transform,实现的功能相当于</p><pre><code lang="erlang">-compile(export_all).
18 | </code></pre><p>因为是parse_transform,所以得这么用</p><pre><code lang="erlang">-compile({parse_transform, export_all}).
19 | </code></pre><p>接下来就可以有PEG transform了。plain Erlang风格写个简单的parse整数的功能</p><pre><code lang="erlang">digit([H|T])
20 | when H >= $0, H =< $9 ->
21 | {ok, H - $0, T};
22 | digit(_S) ->
23 | error.
24 |
25 | int(Acc, S) ->
26 | case digit(S) of
27 | {ok, N, S1} ->
28 | Acc1 = Acc*10 + N,
29 | case int(Acc1, S1) of
30 | {ok, N1, S2} ->
31 | {ok, N1, S2};
32 | error ->
33 | {ok, Acc1, S1}
34 | end;
35 | error ->
36 | error
37 | end.
38 | </code></pre><p>有了peg_transform之后,可以只关心能匹配的情况,不匹配的情况自动返回error。特别的int函数,第一个clause失败后会尝试第二个clause。</p><pre><code lang="erlang">-compile({parse_transform, peg_transform}).
39 |
40 | -rules([int/2, digit/1]).
41 |
42 | digit([H|T])
43 | when H >= $0, H =< $9 ->
44 | {ok, H - $0, T}.
45 |
46 | int(Acc, S) -> %%
47 | {ok, N, S1} = digit(S), %%
48 | int(Acc*10+N, S1);
49 | int(Acc, S) ->
50 | {ok, N, S1} = digit(S),
51 | {ok, Acc*10+N, S1}.
52 | </code></pre><p>失败包括两种情况,一种是clause的pattern不匹配,另一种不匹配是发生在类似这种地方</p><pre><code lang="erlang">{ok, Expr, Remain} = rule(...)</code></pre><p>利用peg_transform,就可以写一个简单的parser,替换掉 parse_util:parse_expr/1</p><p>这些代码都已经在 <a data-title="GitHub - xn--21Erlang-p00o82pmp3o/skeleton" data-editable="true" href="https://github.com/xn--21Erlang-p00o82pmp3o/skeleton">GitHub - xn--21Erlang-p00o82pmp3o/skeleton</a> 里更新了。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/20760395&pixel&useReferer"/>bhuztezSat, 16 Apr 2016 20:50:09 GMT
- 欢迎投稿本专栏https://zhuanlan.zhihu.com/p/20689218<p>假如您看得上只有仅仅2K+粉丝的专栏,刚好又没有专栏。任何和编程或者形式证明相关的,特别是能和Erlang, APL(包括APL家族的A+, J, K等等), Metamath等扯上关系的,欢迎来稿。</p><p>根据知乎专栏的新玩法,在知乎允许的范围(我也懒得了解了)内,假如有幸收录您的一篇投稿,就会把您列为作者之一,也就是下一次就可以直接发了。 (不知道能不能抢文章,那样就好玩了) </p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/20689218&pixel&useReferer"/>bhuztezWed, 30 Mar 2016 21:06:10 GMT
- 向OJ提交编译出来的汇编代码2https://zhuanlan.zhihu.com/p/20656358<p>之前只是解决了是否可能的问题。真正要能用,还是要把代码长度控制在允许的范围内。 </p><p>一是需要压缩率更高的算法</p><p><a class="" data-title="如何提高写在C语言里的汇编代码的压缩率? - 知乎用户的回答" data-editable="true" href="https://www.zhihu.com/question/39504416/answer/88728975">如何提高写在C语言里的汇编代码的压缩率? - 知乎用户的回答</a></p><p>二是用gcc编译时,加上参数 -fwhole-program 而不是通常的 -flto </p><p>这样提交上去的代码长度不少就只有10K左右了。而算法库的源代码目前都已经接近50K了,无脑复制成一个文件已经没啥OJ会接受了。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/20656358&pixel&useReferer"/>bhuztezFri, 18 Mar 2016 21:15:21 GMT
- Awesome Ancient Chinese Bookshttps://zhuanlan.zhihu.com/p/20627628<p><a class="" data-title="GitHub - bhuztez/awesome-ancient-chinese-books: A curated list of awesome chinese books" data-editable="true" href="https://github.com/bhuztez/awesome-ancient-chinese-books">GitHub - bhuztez/awesome-ancient-chinese-books: A curated list of awesome chinese books</a></p><p>暂时没时间维护。先把坑挖开,<b>求支持</b>。</p><p>目标就是整理个目录,把网上能找到的古籍的地址按书名记录好,以便查阅。 </p><p>主要是为了以后开发中文编程语言时有据可循,而不是自己胡编乱造</p><p>就是这样</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/20627628&pixel&useReferer"/>bhuztezMon, 07 Mar 2016 20:21:45 GMT
- [黑魔法]Python模拟HTML表单提交https://zhuanlan.zhihu.com/p/20612720<p>application/x-www-form-urlencoded这种比较简单就不讨论了。</p><p>multipart/form-data就比较麻烦了。搜了一下结果发现要么是远古时期的,要么就是推荐requests。有必要这么麻烦么?Python明明自带MIME库了,为啥就没人推荐用标准库的方法?只能自己来了</p><pre><code lang="python">from urllib2 import Request
53 | from email.message import Message
54 |
55 |
56 | class Form(Message):
57 |
58 | def __init__(self):
59 | Message.__init__(self)
60 | self.add_header('Content-Type', 'multipart/form-data')
61 | self._payload = []
62 |
63 | def _write_headers(self, _generator):
64 | # DARK MAGIC followed
65 | pass
66 |
67 |
68 | class Field(Message):
69 |
70 | def __init__(self,name,text):
71 | Message.__init__(self)
72 | self.add_header('Content-Disposition','form-data',name=name)
73 | self.set_payload(text,None)
74 |
75 |
76 | def make_request(url,form_data):
77 | form = Form()
78 |
79 | for name,value in form_data.iteritems():
80 | form.attach(Field(name,str(value)))
81 |
82 | data = form.as_string()
83 | # THIS IS A SEPARATION BARRIER
84 | # NEVER LET CODE MOVE ACROSS THIS
85 | headers = {'Content-Type': form['Content-Type']}
86 |
87 | return Request(url,data,headers)
88 | </code></pre><p> 就是这样</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/20612720&pixel&useReferer"/>bhuztezTue, 01 Mar 2016 20:32:54 GMT
- barelibc问题修复及其他https://zhuanlan.zhihu.com/p/20521163<p><a data-title="bhuztez/barelibc" data-editable="true" href="https://github.com/bhuztez/barelibc">bhuztez/barelibc</a></p><p>在<a class="" data-title="为什么链接时__libc_start_main和__syscall行为不同? - bsdelf 的回答" data-editable="true" href="https://www.zhihu.com/question/39519315/answer/81747490">为什么链接时__libc_start_main和__syscall行为不同? - bsdelf 的回答</a>的启发下,我把 __syscall 挪到 crt1.o 里去了,免得被覆盖还不知道。</p><p>之前可能没提用barelibc也可以支持一部分C++了。注意编译的命令是 gcc 而不是 g++,不然会链接 libstdc++ ,就见鬼了。</p><p>--------------------------</p><p>正式开始在刷题的库。主要卖点是写完运行一行命令可以生成能提交到OJ的代码。在正式发布之前暂时不会公开源代码。假如你手上有很多现成优质代码捐赠给我,那果断加入吧。</p><p>没代码,你也可以来完善这个TODO list。目标是收集各种topic,可能出现的题型,以及每个题型一个例题。以便我的库能覆盖所有常见题型。</p><p><a class="" data-title="oj-solutions/TODO.md at master · bhuztez/oj-solutions · GitHub" data-editable="true" href="https://github.com/bhuztez/oj-solutions/blob/master/TODO.md">oj-solutions/TODO.md at master · bhuztez/oj-solutions · GitHub</a></p><p>欢迎Pull Request </p><p>--------------------------</p><p>另外,第6个21天的更新会和第7个21天一起发布</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/20521163&pixel&useReferer"/>bhuztezThu, 21 Jan 2016 22:45:21 GMT
- 向OJ提交编译出来的汇编代码https://zhuanlan.zhihu.com/p/20494114<p> 比如 x.c 的内容如下</p><pre><code lang="c">asm("\t.globl main\n"
89 | "\t.type main,@function\n"
90 | "main:\n"
91 | "\tmovl $1,%eax\n"
92 | "\tret\n");
93 | </code></pre><p>编译,运行,可以看到退出代码确实是1</p><pre><code lang="text">$ gcc -o x x.c
94 | $ ./x
95 | $ echo $?
96 | 1
97 | $
98 | </code></pre><p>所以,理论上我们只需要把汇编代码,改写成C语言字符串就好了。</p><p>用 gcc -S -o- x.c 就能看到编译出来的汇编代码了</p><p>可是,发现在某些运行在Windows的OJ(用老版本的MinGW gcc)提交这些汇编代码时,会编译不过去,提示缺少 ___chkstk_ms ,假如关掉这个会导致程序出错。参考<a class="" data-title="c++ - What is the purpose of the _chkstk() function?" data-editable="true" href="https://stackoverflow.com/questions/8400118/what-is-the-purpose-of-the-chkstk-function">c++ - What is the purpose of the _chkstk() function?</a></p><p>假设当前函数栈横跨 B - E ,假如直接跳过C页访问D页,就出错了</p><pre><code lang="text"> A B C D E
99 | +----+----+----+----+----
100 | | | | | |
101 | +----+----+----+----+----
102 | | ^ |->
103 | </code></pre><p>暂时的办法就是直接抄一份现在版本的代码进去,反正也不长</p><p><a class="" data-title="mingw-w64/dll_dependency.S at cf136d93e41ffff7f593230e20c5854a68322b5d · mirror/mingw-w64 · GitHub" data-editable="true" href="https://github.com/mirror/mingw-w64/blob/cf136d93e41ffff7f593230e20c5854a68322b5d/mingw-w64-libraries/winpthreads/src/libgcc/dll_dependency.S">mingw-w64/dll_dependency.S at cf136d93e41ffff7f593230e20c5854a68322b5d · mirror/mingw-w64 · GitHub</a></p><p>那C++怎么办?不同的libstdc++可能有不小的区别。需要关掉一些C++的功能,使得用gcc也能正常链接C++代码就没问题了。也就是使用以下命令编译</p><pre><code lang="text">gcc -fno-rtti -fno-exceptions
104 | </code></pre><p>-----------------------------------------------------------------------</p><p>这样生成出来的汇编代码很长,尝试压缩。比如</p><pre><code lang="c">asm("...movl...")
105 | </code></pre><p> 可以替换成</p><pre><code lang="c">#define M "movl"
106 | asm("..."M"...")
107 | </code></pre><p>这么做的好处是不需要考虑escape什么的。 可是压缩率不太行,找了几个文件试了一下,仅仅在10%-15%之间。</p><img rel="noreferrer" src="https://ga-beacon.appspot.com/UA-41015557-4/page-name?dt=https://zhuanlan.zhihu.com/p/20494114&pixel&useReferer"/>bhuztezTue, 12 Jan 2016 18:57:45 GMT
--------------------------------------------------------------------------------