在CMU学习卤菜技术15319/619 Cloud Computing是种怎样的体验

经历过15FALL CC的人来说一下看法&br&&br&之前上这门课,我包括我寝室另外两人,很痛苦很痛苦(这个很大部分是因为我们都是转CS的,基础薄弱,而且第一学期就作死选CC,这个稍后说),以至于每个周日(一般都是周日due)连饭都吃不上。而且每次due完之后我们三个人都要开会讨论为什么选这个课。但是上完这个课之后,感觉是脱胎换骨了一样,好像学到了很多东西。当时有个好友也申请上了下学期的TA,我就笑称他是上学期去讨伐恶龙的战士,在杀掉恶龙后却变成了下学期的恶龙。其实就连我也想,如果我是下学期的CC TA的话,我也会“点到为止”地让学生们“去尝试不同的东西(踩各种坑)”,因为”只有试过了才会对知识更加了解呀!”,“成长怎么会不经历痛苦!”。&br&&br&但是,第一,这样对学生们真的好吗?&br&第二,真的学到了很多东西吗?真的学到了很多东西吗??&br&&br&我想了很久这些问题,现在就给大家说说我的看法:&br&第一,假如你站在一个迷宫里面,四面八方都是路,其中只有一些路是通向终点的,另外一些路甚至不知道通向什么地方。这时候你去问TA,TA说:“你可以都尝试一下每条路哦,就算达不到终点,那你也掌握了‘这条路达不到终点’的这个知识啊,而且还很可能在路上捡到西瓜芝麻什么的哦!” 如果是你,你会怎么做?你敢花大力气在一条路上一路走下去吗?你怎么知道这条路是不是死路呢?&br&&br&为什么一开始就不告诉我们哪条路可以走?我觉得老师和TA就应该是领路人,虽然不是司机,可以载你走完这条路,但是起码可以告诉你这条路是可以走下去的,是付出与收益比最高的,告诉你“你只要沿着这条路努力奔跑就行了!”这样剩下来的才是个人的努力问题。而不是在选错路,付出比别人更多努力之后,发现还不如那些一开始就选对路的人付出却很少的人(虽然可能他们自己也不知道自己选对了路)。&br&&br&有些人说这门课很接近实际的工作环境,让你自己去搜索和解决各种可能在工作中出现的奇奇怪怪的问题。拜托,这门课叫“Cloud Computing”,不是“How to get out of 坑”,不是“Prepare for working environment”。而且就是为了在工作中少踩坑,不是应该多学到知识吗,多认清楚更多的坑,多知道什么该干什么不该干吗?“&b&为了让你提前准备好在工作中踩坑而现在多体验踩坑的感觉&/b&”这是一个什么奇怪的逻辑?&br&&br&退一步讲,好,我愿意在挫折中成长,我愿意尝试不同的路。但是这门课:第一,有严格的&b&Budget&/b&限定。第二,有严格的&b&Deadline&/b&,而且&b&没有Grace day&/b&! 这让每个愿意多尝试的学生都要面临受到惩罚的威胁。&b&一方面想要学生多尝试,一方面又严格限定budget和时间&/b&,这不是矛盾的么。而且这门课每周都有一个Quiz,每次光这个就会花掉你半天到一天的时间去看很多资料,总共有12个Quiz,一共占25分(这一届是20分)但是平均分只有60%~70%,所以光这个就要扣差不多十分,这意味着拿A已经很难了,再在其它地方出点差错,拿个C,可能连书都没得读了(CMU要求总绩点在B以上,C以后就要被退学了)&br&&br&而且Majd老师对于作弊的教条就是“&b&宁可错杀一千,也不放过一个&/b&”,所以经常会出现一些莫名其妙的警告邮件。只要你在同一个时间同一个IP开始做,或者答案或Code相似,都有可能收到这种警告邮件,目的就是威慑你让你放弃甚至有一点和别人合作的想法。&br&&br&第二个问题才是最重要的,真的学到了很多东西了吗?我们容易产生错觉的地方在于,只比较了&b&收入&/b&,而忽视了&b&成本&/b&。对于15213,你可能每周花15小时学到了15小时的东西。对于CC,你可能每周花40小时,但只学到了20小时的东西。确实,学到的东西多了啊,但是&b&性价比&/b&呢?CC最不合理的地方就是本来明明可以很简单就解决的东西,偏偏就是不告诉你,偏偏要弄得很花时间才能解决。&br&&br&而且有些人走出了迷宫之后,可能会认为自己收获了很多,“我熟悉这条路上各个地方的坑,知道哪里有西瓜芝麻”,但殊不知,自己选的路尽管能出去,却是最远的,有很多别的路上就没有的坑。&br&&br&新东方(不要吐槽新东方,一线的老师都是超级有水平的)的陈虎平老师说过:“&b&站在巨人的肩膀上才能看得更宽,走得更远。&/b&” 为什么CCTA就不把自己上的这个课的心得体会跟大家分享一下呢?为什么觉得公开Report,每个人都会拿满分?换句话说,我们的目标不就是让每个人都尽量地获取这门课所能学到的知识从而获取更高的分数吗?非要辛辛苦苦学的才算知识,轻松能学到的就不是知识了?我想,如果我当TA,我不告诉他们什么地方有坑,让他们走自己以前踩过的坑,那么充其量他们也只能达到我当时的高度,或者只是比我高一点点。但是如果我把我上这门课的心得体会告诉他们,那他们就能够超越我走得更远,学到更多的东西,这不是教育的初衷吗?&br&&br&&b&&u&每年的CC学生,每年踩同样的坑,每年出来的水平都一样。&/u&&/b&&br&&b&&u&明年的CC学生,站在前一年学长的肩膀上,水平越来越高。&/u&&/b&&br&哪个更好?&br&&br&在这一点上,我力顶小土刀,我不仅支持他写博客,而且我自己也竭尽所能帮助了一些这学期上CC的人,我也打算自己也写一个类似CC Writeup的博客,说一下自己的心得体会,帮助一下之后的学生。被请喝茶什么的,在天朝呆久了查水表都不怕还怕喝茶?其实一开始,&b&&u&我真的非常想看他们痛苦地不断踩各种坑又从坑里爬起来的挣扎的样子&/u&&/b&。因为自己在其中倾注了太多的心血,从而产生逆向合理化的心理效应,觉得这就是所谓的“吃得苦中苦,方为人上人”,觉得只有在痛苦中得到的东西才会更加深刻更加珍惜。可是这样我自己不也渐渐变成恶龙了吗?我觉得,我要帮助他们超越我自己,而我自己为了防止被他们超越,也会更加努力地学习,只有这样才能达到双赢,对他人对自己都是大有裨益的。&br&&br&最后我觉得最本质的原因是,现在的环境有点畸形,很多人来CMU都是来转CS当码农的,然后又听说CC这门课对找工作很有帮助,所以很多不应该上这门课,或者是说现阶段还不适合上这门课的人都来上了这门课。搞得现在CC都像是所有想转CS的学生的必修课一样。像我和我室友三人都是转CS的,又才刚开始补基础,所以才会上得举步维艰。如果像我当时科班出身的几个同学那样,基础很好,每周花两天以内的时间就可以搞定,这才能够“乐在其中”。&br&&br&所以给以后想上CC的同学的建议是:&br&第一,至少基础搞好了才来上CC,不要连Linux基本命令都没操作过就来赶鸭子上架,那会是相当痛苦的。&br&第二,看你喜不喜欢做Cloud,以后走不走这条路,而不单纯仅仅是为了在简历上多几行字。虽然上完这个课后好像确实是可以在简历上写很多东西,但是找不找得到工作的因素有很多,你性别写成“女”都可能比你在上面写CC的项目能收到的面试多,谁知道是哪一个因素影响你找工作呢?&br&&br&&p&再说一句,其实这一届的CCTA已经好很多了,比如说成神啊浩原啊神奇的振宇哥啊,至少当初是我CC的私人TA,告诉了我所有我想知道的东西,至少这次也非常努力改进了writeup,标出了不同的坑。但是在Majd的教育体系下,学生们还是要从受苦受累中获得知识。&/p&&br&最后说一句,&b&以后CC有不懂的可以直接来找我&/b&!!&br&&br&========= 更新 =========&br&昨晚跟这次的TA&a data-hash=&c02ec74a44ee4ae293652& href=&///people/c02ec74a44ee4ae293652& class=&member_mention& data-editable=&true& data-title=&@王成& data-tip=&p$b$c02ec74a44ee4ae293652& data-hovercard=&p$b$c02ec74a44ee4ae293652&&@王成&/a& 聊了大半个通宵,感觉自己确实地图炮开得有点广,伤及了一些兢兢业业想要努力改善这们课还有对学生真的好的人。而且因为自己想要看到别人受苦而认为别人也那样想也很不妥,可能是因为我这个人比较坏吧~所以就这样想了。但我写本文的本意就是避轻就重,专挑不好的方面讲,得罪人也再所难免。不过通过这次对话也再次印证了这门课的不合理性,TA辛辛苦苦干了一学期,学生累死累活撑到学期结束,结果谁也不讨好谁。学生觉得TA不干事,TA觉得学生难伺候,就是这一种怪现象。&br&&br&为什么呢?我们觉得,是因为CC针对的人群不明确所致。转专业的学生有一大堆新东西要学,跟不上。学过人的驾轻就熟,一下子就做出来了。TA一看,怎么这么简单刚放出来就立马有人做出来了还跑那么高分,弄难一点再难一点。而且生活中有些事就像是常理一样,觉得不说大家都懂。这就容易产生误解了。比如说前段时间看到一个男女生搓澡的区别,男生搓澡只要搓两面,女生搓澡居然要搓四面。男生就觉得世界上所有人搓澡都只搓两面,女生就觉得搓澡搓四面不是常理吗?当时那个人发了公众号之后,居然还引起了不小的轰动。所以说,一方面,有些坑TA可能也想不到居然还有人会跳这种坑。另一方面,学生也会想“这么简单的事直接说出来不就行了吗,为什么就是不说”(当然,真的就是有TA明明知道大家都卡在哪里但[就是不说]!)&br&&br&我们觉得解决方案,第一是就是像213那样,针对新手开设,把Load和难度降低,而且CC之后还有一门叫Advanced CC的,也是学Cloud,也是Majd的课,而且就我接触这两门课的经验来看,ADCC上面的阅读资料跟CC Quiz所要阅读的资料的重合性很大,完全没必要在CC这边弄得很难,然后在ADCC这边再把这些难的东西拿出来炒冷饭。我觉得可以把CC一些难的Project转移到ADCC上,这样既可以让人先了解一下Cloud Computing到底是个什么东西,不感兴趣或跟不上的同学也不至于爬着上完一学期,又可以让感兴趣或者想要深入了解的同学继续上ADCC来挑战更难的Project。&br&&br&第二就是针对高端玩家。像DS那样,有严格的前置课程规定,要不就在课程介绍中写个大大的Warning,直接劝退菜鸟,然后去掉Project 0这种一周入门Linux AWS Azure的Project。一周入门这些,对于新手来说来不及消化,对于四年CS专业的人来说又非常鸡肋,还不如不要。然后就可以在认定同学都是有基础不会自己去踩各种奇奇怪怪的坑的前提下设计Project。&br&&br&为什么很多人认为CC跟213以及OS等神课无法相提并论?我觉得就是因为Majd太想包罗万象了,每年都新增不少新东西。有一次我跟师兄聊CC,聊了半天他以为我一直聊的是DS。新东西多了,有些东西可能TA都不甚了解,做出来的Project稳定性自然不够好。所谓术业有专功,这门课的重点在哪呢?一开始我以为是学的是Mapreduce,再接着我以为是AWS培训班,紧接着是突然变得特别难的数据库Sharding和分布式系统并发。中间穿插着Hive,Impala和Redshift三合一,跟着writeup操作一下莫名其妙就完成了,都不知道这些是些什么东西,只觉得好不容易有个Project能水过高兴就好。最后好像又要比较一下各种大数据框架,Spark, Kafka听起来高大上,“终于能写到简历上了!”至于Team Project说是要把所有的东西融合起来,做个包含前后端的“至于AWS的Twitter分析系统”,然后一开始大家都互相问“什么是框架”。Hbase 基本的API都没熟悉Live Test就开始了。总之如果有人问我CC主要学了什么,我还真难答上来。&br&&br&自己是希望CC这门课越来越好的,但至于Majd要怎么变,就不得而知了。我应该还会继续更新,争取给以后想选CC课的人作个好的参考。
经历过15FALL CC的人来说一下看法 之前上这门课,我包括我寝室另外两人,很痛苦很痛苦(这个很大部分是因为我们都是转CS的,基础薄弱,而且第一学期就作死选CC,这个稍后说),以至于每个周日(一般都是周日due)连饭都吃不上。而且每次due完之后我们三个人…
已有帐号?
无法登录?
社交帐号登录
298 人关注
7042 人关注
2056 条内容
2195 人关注
459 条内容
2660 人关注
2605 人关注
1188 条内容在CMU学习 Cloud Computing是种怎样的体验? - 知乎564被浏览31186分享邀请回答5812 条评论分享收藏感谢收起网站配置未生效 |
| 百度云加速
请打开cookies.
你访问的网站() 使用了
网络。 百度云加速目前无法解析此域名 ().
主要因为: 网站主刚刚在百度云加速添加了这个域名,百度云加速需要几十秒的时间同步到全球网络中。稍等片刻刷新页面即可解决。
也有可能: 网站配置出错.&img src=&/50/v2-da6e908fbff06e8e14c60d86d776d225_b.jpg& data-rawwidth=&768& data-rawheight=&576& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&/50/v2-da6e908fbff06e8e14c60d86d776d225_r.jpg&&&img src=&/v2-abd42bbb61ee_b.jpg& data-rawwidth=&558& data-rawheight=&315& class=&origin_image zh-lightbox-thumb& width=&558& data-original=&/v2-abd42bbb61ee_r.jpg&&&p&作为一名久经片场的老司机,早就想写一些探讨驾驶技术的文章。这篇就介绍利用生成式对抗网络(GAN)的两个基本驾驶技能:&br&&/p&&p&1) 去除(爱情)动作片中的马赛克&/p&&p&2) 给(爱情)动作片中的女孩穿(tuo)衣服&/p&&br&&h2&生成式模型&/h2&&p&上一篇《&a href=&/p/& class=&internal&&用GAN生成二维样本的小例子&/a&》中已经简单介绍了GAN,这篇再简要回顾一下生成式模型,算是补全一个来龙去脉。&/p&&p&生成模型就是能够产生指定分布数据的模型,常见的生成式模型一般都会有一个用于产生样本的简单分布。例如一个均匀分布,根据要生成分布的概率密度函数,进行建模,让均匀分布中的样本经过变换得到指定分布的样本,这就可以算是最简单的生成式模型。比如下面例子:&/p&&img src=&/v2-d11b5fb26d3cc8e942f841bafe010cd8_b.png& data-rawwidth=&1021& data-rawheight=&443& class=&origin_image zh-lightbox-thumb& width=&1021& data-original=&/v2-d11b5fb26d3cc8e942f841bafe010cd8_r.png&&&p&图中左边是一个自定义的概率密度函数,右边是相应的1w个样本的直方图,自定义分布和生成这些样本的代码如下:&br&&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&kn&&from&/span& &span class=&nn&&functools&/span& &span class=&kn&&import&/span& &span class=&n&&partial&/span&
&span class=&kn&&import&/span& &span class=&nn&&numpy&/span&
&span class=&kn&&from&/span& &span class=&nn&&matplotlib&/span& &span class=&kn&&import&/span& &span class=&n&&pyplot&/span&
&span class=&c1&&# Define a PDF&/span&
&span class=&n&&x_samples&/span& &span class=&o&&=&/span& &span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&arange&/span&&span class=&p&&(&/span&&span class=&o&&-&/span&&span class=&mi&&3&/span&&span class=&p&&,&/span& &span class=&mf&&3.01&/span&&span class=&p&&,&/span& &span class=&mf&&0.01&/span&&span class=&p&&)&/span&
&span class=&n&&PDF&/span& &span class=&o&&=&/span& &span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&empty&/span&&span class=&p&&(&/span&&span class=&n&&x_samples&/span&&span class=&o&&.&/span&&span class=&n&&shape&/span&&span class=&p&&)&/span&
&span class=&n&&PDF&/span&&span class=&p&&[&/span&&span class=&n&&x_samples&/span& &span class=&o&&&&/span& &span class=&mi&&0&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&round&/span&&span class=&p&&(&/span&&span class=&n&&x_samples&/span&&span class=&p&&[&/span&&span class=&n&&x_samples&/span& &span class=&o&&&&/span& &span class=&mi&&0&/span&&span class=&p&&]&/span& &span class=&o&&+&/span& &span class=&mf&&3.5&/span&&span class=&p&&)&/span& &span class=&o&&/&/span& &span class=&mi&&3&/span&
&span class=&n&&PDF&/span&&span class=&p&&[&/span&&span class=&n&&x_samples&/span& &span class=&o&&&=&/span& &span class=&mi&&0&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mf&&0.5&/span& &span class=&o&&*&/span& &span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&cos&/span&&span class=&p&&(&/span&&span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&pi&/span& &span class=&o&&*&/span& &span class=&n&&x_samples&/span&&span class=&p&&[&/span&&span class=&n&&x_samples&/span& &span class=&o&&&=&/span& &span class=&mi&&0&/span&&span class=&p&&])&/span& &span class=&o&&+&/span& &span class=&mf&&0.5&/span&
&span class=&n&&PDF&/span& &span class=&o&&/=&/span& &span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&sum&/span&&span class=&p&&(&/span&&span class=&n&&PDF&/span&&span class=&p&&)&/span&
&span class=&c1&&# Calculate approximated CDF&/span&
&span class=&n&&CDF&/span& &span class=&o&&=&/span& &span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&empty&/span&&span class=&p&&(&/span&&span class=&n&&PDF&/span&&span class=&o&&.&/span&&span class=&n&&shape&/span&&span class=&p&&)&/span&
&span class=&n&&cumulated&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&
&span class=&k&&for&/span& &span class=&n&&i&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&CDF&/span&&span class=&o&&.&/span&&span class=&n&&shape&/span&&span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&]):&/span&
&span class=&n&&cumulated&/span& &span class=&o&&+=&/span& &span class=&n&&PDF&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&]&/span&
&span class=&n&&CDF&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&cumulated&/span&
&span class=&c1&&# Generate samples&/span&
&span class=&n&&generate&/span& &span class=&o&&=&/span& &span class=&n&&partial&/span&&span class=&p&&(&/span&&span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&interp&/span&&span class=&p&&,&/span& &span class=&n&&xp&/span&&span class=&o&&=&/span&&span class=&n&&CDF&/span&&span class=&p&&,&/span& &span class=&n&&fp&/span&&span class=&o&&=&/span&&span class=&n&&x_samples&/span&&span class=&p&&)&/span&
&span class=&n&&u_rv&/span& &span class=&o&&=&/span& &span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&random&/span&&span class=&o&&.&/span&&span class=&n&&random&/span&&span class=&p&&(&/span&&span class=&mi&&10000&/span&&span class=&p&&)&/span&
&span class=&n&&x&/span& &span class=&o&&=&/span& &span class=&n&&generate&/span&&span class=&p&&(&/span&&span class=&n&&u_rv&/span&&span class=&p&&)&/span&
&span class=&c1&&# Visualization&/span&
&span class=&n&&fig&/span&&span class=&p&&,&/span& &span class=&p&&(&/span&&span class=&n&&ax0&/span&&span class=&p&&,&/span& &span class=&n&&ax1&/span&&span class=&p&&)&/span& &span class=&o&&=&/span& &span class=&n&&pyplot&/span&&span class=&o&&.&/span&&span class=&n&&subplots&/span&&span class=&p&&(&/span&&span class=&n&&ncols&/span&&span class=&o&&=&/span&&span class=&mi&&2&/span&&span class=&p&&,&/span& &span class=&n&&figsize&/span&&span class=&o&&=&/span&&span class=&p&&(&/span&&span class=&mi&&9&/span&&span class=&p&&,&/span& &span class=&mi&&4&/span&&span class=&p&&))&/span&
&span class=&n&&ax0&/span&&span class=&o&&.&/span&&span class=&n&&plot&/span&&span class=&p&&(&/span&&span class=&n&&x_samples&/span&&span class=&p&&,&/span& &span class=&n&&PDF&/span&&span class=&p&&)&/span&
&span class=&n&&ax0&/span&&span class=&o&&.&/span&&span class=&n&&axis&/span&&span class=&p&&([&/span&&span class=&o&&-&/span&&span class=&mf&&3.5&/span&&span class=&p&&,&/span& &span class=&mf&&3.5&/span&&span class=&p&&,&/span& &span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&n&&numpy&/span&&span class=&o&&.&/span&&span class=&n&&max&/span&&span class=&p&&(&/span&&span class=&n&&PDF&/span&&span class=&p&&)&/span&&span class=&o&&*&/span&&span class=&mf&&1.1&/span&&span class=&p&&])&/span&
&span class=&n&&ax1&/span&&span class=&o&&.&/span&&span class=&n&&hist&/span&&span class=&p&&(&/span&&span class=&n&&x&/span&&span class=&p&&,&/span& &span class=&mi&&100&/span&&span class=&p&&)&/span&
&span class=&n&&pyplot&/span&&span class=&o&&.&/span&&span class=&n&&show&/span&&span class=&p&&()&/span&
&/code&&/pre&&/div&&p&对于一些简单的情况,我们会假设已知有模型可以很好的对分布进行建模,缺少的只是合适的参数。这时候很自然只要根据观测到的样本,学习参数让当前观测到的样本下的似然函数最大,这就是最大似然估计(&b&M&/b&aximum &b&L&/b&ikelihood &b&E&/b&stimation):&br&&/p&&img src=&/equation?tex=%5Chat%7B%5Ctheta%7D%3D%5Coperatorname%2A%7Bargmax%7D_%7B%5Ctheta%7D+P%28%5Cbm%7Bx%7D%7C%5Ctheta%29%0A+%3D+%5Coperatorname%2A%7Bargmax%7D_%7B%5Ctheta%7D+%5Cprod_%7Bi%3D1%7D%5E%7Bn%7DP%28x_i%7C%5Ctheta%29+& alt=&\hat{\theta}=\operatorname*{argmax}_{\theta} P(\bm{x}|\theta)
= \operatorname*{argmax}_{\theta} \prod_{i=1}^{n}P(x_i|\theta) & eeimg=&1&&&br&&p&MLE是一个最基本的思路,实践中用得很多的还有KL散度(Kullback–Leibler divergence),假设真实分布是P,采样分布是Q,则KL散度为:&/p&&img src=&/equation?tex=D_%7BKL%7D%28P%7C%7CQ%29%3D%5Csum_%7Bx+%5Cin+%5COmega%7DP%28%7Bx%7D%29%5Clog%5Cfrac%7BP%28x%29%7D%7BQ%28x%29%7D++& alt=&D_{KL}(P||Q)=\sum_{x \in \Omega}P({x})\log\frac{P(x)}{Q(x)}
& eeimg=&1&&&br&&p&从公式也能看出来,KL散度描述的是两个分布的差异程度。换个角度来看,让产生的样本和原始分布接近,也就是要让这俩的差异减小,所以最小化KL散度就等同于MLE。从公式上来看的话,我们考虑把公式具体展开一下:&/p&&br&&img src=&/equation?tex=%5Cbegin%7Balign%7D%0AD_%7BKL%7D%28P%7C%7CQ%29+%26%3D%5Csum_%7Bx+%5Cin+%5COmega%7DP%28%7Bx%7D%29%5Clog%5Cfrac%7BP%28x%29%7D%7BQ%28x%29%7D++++%5C%5C%0A%26+%3D-%5Csum_%7Bx%5Cin%5COmega%7DP%28%7Bx%7D%29%5Clog%7BQ%28x%29%7D+%2B%5Csum_%7Bx%5Cin%5COmega%7DP%28%7Bx%7D%29%5Clog%7BP%28x%29%7D+%5C%5C%0A%26+%3D-%5Csum_%7Bx%5Cin%5COmega%7DP%28%7Bx%7D%29%5Clog%7BQ%28x%29%7D+%2BH%28P%29%0A%5Cend%7Balign%7D& alt=&\begin{align}
D_{KL}(P||Q) &=\sum_{x \in \Omega}P({x})\log\frac{P(x)}{Q(x)}
& =-\sum_{x\in\Omega}P({x})\log{Q(x)} +\sum_{x\in\Omega}P({x})\log{P(x)} \\
& =-\sum_{x\in\Omega}P({x})\log{Q(x)} +H(P)
\end{align}& eeimg=&1&&&br&&p&公式的第二项就是熵,先不管这项,用H(P)表示。接下来考虑一个小trick:从Q中抽样n个样本&img src=&/equation?tex=%7Bx_1%2Cx_2%2C...%2Cx_n%7D& alt=&{x_1,x_2,...,x_n}& eeimg=&1&&,来估算P(x)的经验值(empirical density function):&br&&/p&&img src=&/equation?tex=%5Chat%7BP%7D%28x%29%3D%5Cfrac+1+n+%5Csum_%7Bi%3D1%7D%5En+%5Cdelta%28x_i-x%29& alt=&\hat{P}(x)=\frac 1 n \sum_{i=1}^n \delta(x_i-x)& eeimg=&1&&&br&&p&其中&img src=&/equation?tex=%5Cdelta%28%5Ccdot%29& alt=&\delta(\cdot)& eeimg=&1&&是狄拉克&img src=&/equation?tex=%5Cdelta& alt=&\delta& eeimg=&1&&函数,把这项替换到上面公式的P(x):&/p&&br&&img src=&/equation?tex=%5Cbegin%7Balign%7D%0AD_%7BKL%7D%28P%7C%7CQ%29+%26%3D-%5Csum_%7Bx%5Cin%5COmega%7D%5Cfrac+1+n+%5Csum_%7Bi%3D1%7D%5En+%5Cdelta%28x_i-x%29%5Clog%7BQ%28x%29%7D+%2BH%28P%29+%5C%5C%0A%26+%3D-%5Cfrac+1+n+%5Csum_%7Bi%3D1%7D%5En+%5Csum_%7Bx%5Cin%5COmega%7D++%5Cdelta%28x_i-x%29%5Clog%7BQ%28x%29%7D+%2BH%28P%29%0A%5Cend%7Balign%7D& alt=&\begin{align}
D_{KL}(P||Q) &=-\sum_{x\in\Omega}\frac 1 n \sum_{i=1}^n \delta(x_i-x)\log{Q(x)} +H(P) \\
& =-\frac 1 n \sum_{i=1}^n \sum_{x\in\Omega}
\delta(x_i-x)\log{Q(x)} +H(P)
\end{align}& eeimg=&1&&&br&&p&因为是离散的采样值,所以&img src=&/equation?tex=%5Csum_%7Bx%5Cin%5COmega%7D+%5Cdelta%28x_i-x%29& alt=&\sum_{x\in\Omega} \delta(x_i-x)& eeimg=&1&&中只有&img src=&/equation?tex=x%3Dx_i& alt=&x=x_i& eeimg=&1&&的时候狄拉克&img src=&/equation?tex=%5Cdelta& alt=&\delta& eeimg=&1&&函数才为1,所以考虑&img src=&/equation?tex=x%3Dx_i& alt=&x=x_i& eeimg=&1&&时这项直接化为1:&/p&&br&&img src=&/equation?tex=D_%7BKL%7D%28P%7C%7CQ%29+%3D-%5Cfrac+1+n%5Csum_%7Bi%3D1%7D%5En+%5Clog%7BQ%28x_i%29%7D+%2BH%28P%29& alt=&D_{KL}(P||Q) =-\frac 1 n\sum_{i=1}^n \log{Q(x_i)} +H(P)& eeimg=&1&&&br&&p&第一项正是似然的负对数形式。&/p&&p&说了些公式似乎跑得有点远了,其实要表达还是那个简单的意思:通过减小两个分布的差异可以让一个分布逼近另一个分布。仔细想想,这正是GAN里面adversarial loss的做法。&/p&&p&很多情况下我们面临的是更为复杂的分布,比如&a href=&/p/& class=&internal&&上篇文章&/a&中的例子,又或是实际场景中更复杂的情况,比如生成不同人脸的图像。这时候,作为具有universal approximation性质的神经网络是一个看上去不错的选择[1]:&br&&/p&&img src=&/v2-6fee20494f50baae2c1dc5fc_b.jpg& data-rawwidth=&1561& data-rawheight=&549& class=&origin_image zh-lightbox-thumb& width=&1561& data-original=&/v2-6fee20494f50baae2c1dc5fc_r.jpg&&&p&所以虽然GAN里面同时包含了生成网络和判别网络,但本质来说GAN的目的还是生成模型。从生成式模型的角度,Ian Goodfellow总结过一个和神经网络相关生成式方法的“家谱”[1]:&/p&&img src=&/v2-8c6f1d8ee39dfbb4fcfb2_b.png& data-rawwidth=&771& data-rawheight=&498& class=&origin_image zh-lightbox-thumb& width=&771& data-original=&/v2-8c6f1d8ee39dfbb4fcfb2_r.png&&&p&在这其中,当下最流行的就是GAN和&b&V&/b&ariational &b&A&/b&uto&b&E&/b&ncoder(VAE),两种方法的一个简明示意如下[3]:&/p&&img src=&/v2-380cde71a2f6ece28b4a97_b.png& data-rawwidth=&568& data-rawheight=&274& class=&origin_image zh-lightbox-thumb& width=&568& data-original=&/v2-380cde71a2f6ece28b4a97_r.png&&&p&本篇不打算展开讲什么是VAE,不过通过这个图,和名字中的autoencoder也大概能知道,VAE中生成的loss是基于重建误差的。而只基于重建误差的图像生成,都或多或少会有图像模糊的缺点,因为误差通常都是针对全局。比如基于MSE(Mean Squared Error)的方法用来生成超分辨率图像,容易出现下面的情况[4]:&/p&&br&&p&&img src=&/v2-78f53b142fab51b0c09a1_b.png& data-rawwidth=&892& data-rawheight=&598& class=&origin_image zh-lightbox-thumb& width=&892& data-original=&/v2-78f53b142fab51b0c09a1_r.png&&在这个二维示意中,真实数据分布在一个U形的流形上,而MSE系的方法因为loss的形式往往会得到一个接近平均值所在的位置(蓝色框)。&/p&&p&GAN在这方面则完爆其他方法,因为目标分布在流形上。所以只要大概收敛了,就算生成的图像都看不出是个啥,清晰度常常是有保证的,而这正是去除女优身上马赛克的理想特性!&/p&&br&&h2&马赛克-&清晰画面:超分辨率(Super Resolution)问题&/h2&&p&说了好些铺垫,终于要进入正题了。首先明确,去马赛克其实是个图像超分辨率问题,也就是如何在低分辨率图像基础上得到更高分辨率的图像:&/p&&img src=&/v2-31c84b42ad_b.png& data-rawwidth=&784& data-rawheight=&324& class=&origin_image zh-lightbox-thumb& width=&784& data-original=&/v2-31c84b42ad_r.png&&&p&视频中超分辨率实现的一个套路是通过不同帧的低分辨率画面猜测超分辨率的画面,有兴趣了解这个思想的朋友可以参考我之前的一个答案:&a href=&/question//answer/& class=&internal&&如何通过多帧影像进行超分辨率重构? &/a&&br&&/p&&p&不过基于多帧影像的方法对于女优身上的马赛克并不是很适用,所以这篇要讲的是基于单帧图像的超分辨率方法。&/p&&h2&SRGAN&/h2&&p&说到基于GAN的超分辨率的方法,就不能不提到SRGAN[4]:《Photo-Realistic Single Image &b&S&/b&uper-&b&R&/b&esolution Using a &b&G&/b&enerative &b&A&/b&dversarial
&b&N&/b&etwork》。这个工作的思路是:基于像素的MSE loss往往会得到大体正确,但是高频成分模糊的结果。所以只要重建低频成分的图像内容,然后靠GAN来补全高频的细节内容,就可以了:&/p&&img src=&/v2-128029dfc7c470b07a4a1_b.png& data-rawwidth=&446& data-rawheight=&131& class=&origin_image zh-lightbox-thumb& width=&446& data-original=&/v2-128029dfc7c470b07a4a1_r.png&&这个思路其实和最早基于深度网络的风格迁移的思路很像(有兴趣的读者可以参考我之前文章&a href=&/p/& class=&internal&&瞎谈CNN:通过优化求解输入图像&/a&的最后一部分),其中重建内容的content loss是原始图像和低分辨率图像在VGG网络中的各个ReLU层的激活值的差异:&p&&img src=&/v2-331e02e394cfd04e7114a_b.png& data-rawwidth=&529& data-rawheight=&150& class=&origin_image zh-lightbox-thumb& width=&529& data-original=&/v2-331e02e394cfd04e7114a_r.png&&生成细节adversarial loss就是GAN用来判别是原始图还是生成图的loss:&/p&&img src=&/v2-fa5af2a10fe9a4dadfb04_b.png& data-rawwidth=&394& data-rawheight=&89& class=&content_image& width=&394&&&p&把这两种loss放一起,取个名叫perceptual loss。训练的网络结构如下:&/p&&img src=&/v2-17861edeb4bcfae4e9f369_b.png& data-rawwidth=&780& data-rawheight=&400& class=&origin_image zh-lightbox-thumb& width=&780& data-original=&/v2-17861edeb4bcfae4e9f369_r.png&&&p&正是上篇文章中讲过的C-GAN,条件C就是低分辨率的图片。SRGAN生成的超分辨率图像虽然PSNR等和原图直接比较的传统量化指标并不是最好,但就视觉效果,尤其是细节上,胜过其他方法很多。比如下面是作者对比bicubic插值和基于ResNet特征重建的超分辨率的结果:&/p&&img src=&/v2-f3b4376938ffcbd23c42d_b.png& data-rawwidth=&981& data-rawheight=&392& class=&origin_image zh-lightbox-thumb& width=&981& data-original=&/v2-f3b4376938ffcbd23c42d_r.png&&&p&可以看到虽然很多细节都和原始图片不一样,不过看上去很和谐,并且细节的丰富程度远胜于SRResNet。这些栩栩如生的细节,可以看作是GAN根据学习到的分布信息“联想”出来的。&/p&&p&对于更看重“看上去好看”的超分辨率应用,SRGAN显然是很合适的。当然对于一些更看重重建指标的应用,比如超分辨率恢复嫌疑犯面部细节,SRGAN就不可以了。&/p&&h2&pix2pix&/h2&&p&虽然专门用了一节讲SRGAN,但本文用的方法其实是pix2pix[5]。这项工作刚在arxiv上发布就引起了不小的关注,它巧妙的利用GAN的框架解决了通用的Image-to-Image translation的问题。举例来说,在不改变分辨率的情况下:把照片变成油画风格;把白天的照片变成晚上;用色块对图片进行分割或者倒过来;为黑白照片上色;…每个任务都有专门针对性的方法和相关研究,但其实总体来看,都是像素到像素的一种映射啊,其实可以看作是一个问题。这篇文章的巧妙,就在于提出了pix2pix的方法,一个框架,解决所有这些问题。方法的示意图如下:&/p&&p&&img src=&/v2-e2ea753b7b0d7f18abee3_b.png& data-rawwidth=&485& data-rawheight=&437& class=&origin_image zh-lightbox-thumb& width=&485& data-original=&/v2-e2ea753b7b0d7f18abee3_r.png&&就是一个Conditional GAN,条件C是输入的图片。除了直接用C-GAN,这项工作还有两个改进:&/p&&p&1)&b&利用U-Net结构生成细节更好的图片&/b&[6]&/p&&img src=&/v2-beb074bebbfa0db_b.png& data-rawwidth=&907& data-rawheight=&612& class=&origin_image zh-lightbox-thumb& width=&907& data-original=&/v2-beb074bebbfa0db_r.png&&&p&U-Net是德国Freiburg大学模式识别和图像处理组提出的一种全卷积结构。和常见的先降采样到低维度,再升采样到原始分辨率的编解码(Encoder-Decoder)结构的网络相比,U-Net的区别是加入skip-connection,对应的feature maps和decode之后的同样大小的feature maps按通道拼(concatenate)一起,用来保留不同分辨率下像素级的细节信息。U-Net对提升细节的效果非常明显,下面是pix2pix文中给出的一个效果对比:&/p&&p&&img src=&/v2-2fb4ddb2fdc24eea31eea_b.png& data-rawwidth=&563& data-rawheight=&307& class=&origin_image zh-lightbox-thumb& width=&563& data-original=&/v2-2fb4ddb2fdc24eea31eea_r.png&&可以看到,各种不同尺度的信息都得到了很大程度的保留。&/p&&p&2)&b&利用马尔科夫性的判别器(PatchGAN)&br&&/b&&/p&&p&pix2pix和SRGAN的一个异曲同工的地方是都有用重建解决低频成分,用GAN解决高频成分的想法。在pix2pix中,这个思想主要体现在两个地方。一个是loss函数,加入了L1 loss用来让生成的图片和训练的目标图片尽量相似,而图像中高频的细节部分则交由GAN来处理:&/p&&img src=&/v2-cb180ad03d8a72e7883285b_b.png& data-rawwidth=&447& data-rawheight=&51& class=&origin_image zh-lightbox-thumb& width=&447& data-original=&/v2-cb180ad03d8a72e7883285b_r.png&&&p&还有一个就是&b&PatchGAN&/b&,也就是具体的GAN中用来判别是否生成图的方法。PatchGAN的思想是,既然GAN只负责处理低频成分,那么判别器就没必要以一整张图作为输入,只需要对NxN的一个图像patch去进行判别就可以了。这也是为什么叫Markovian discriminator,因为在patch以外的部分认为和本patch互相独立。&/p&&p&具体实现的时候,作者使用的是一个NxN输入的全卷积小网络,最后一层每个像素过sigmoid输出为真的概率,然后用BCEloss计算得到最终loss。这样做的好处是因为输入的维度大大降低,所以参数量少,运算速度也比直接输入一张快,并且可以计算任意大小的图。作者对比了不同大小patch的结果,对于256x256的输入,patch大小在70x70的时候,从视觉上看结果就和直接把整张图片作为判别器输入没什么区别了:&/p&&img src=&/v2-5172ca51efb4ee3e453b15_b.png& data-rawwidth=&842& data-rawheight=&107& class=&origin_image zh-lightbox-thumb& width=&842& data-original=&/v2-5172ca51efb4ee3e453b15_r.png&&&h2&生成带局部马赛克的训练数据&/h2&&p&利用pix2pix,只要准备好无码和相应的有码图片就可以训练去马赛克的模型了,就是这么简单。那么问题是,如何生成有马赛克的图片?&/p&&p&有毅力的话,可以手动加马赛克,这样最为精准。这节介绍一个不那么准,但是比随机强的方法:利用分类模型的激活区域进行自动马赛克标注。&/p&&p&基本思想是利用一个可以识别需要打码图像的分类模型,提取出这个模型中对应类的CAM(&b&C&/b&lass &b&A&/b&ctivation &b&M&/b&ap)[7],然后用马赛克遮住响应最高的区域即可。这里简单说一下什么是CAM,对于最后一层是全局池化(平均或最大都可以)的CNN结构,池化后的feature map相当于是做了个加权相加来计算最终的每个类别进入softmax之前的激活值。CAM的思路是,把这个权重在池化前的feature map上按像素加权相加,最后得到的单张的激活图就可以携带激活当前类别的一些位置信息,这相当于一种弱监督(classification--&localization):&/p&&p&&img src=&/v2-fd28f0b871bd_b.png& data-rawwidth=&660& data-rawheight=&314& class=&origin_image zh-lightbox-thumb& width=&660& data-original=&/v2-fd28f0b871bd_r.png&&上图是一个CAM的示意,用澳洲梗类别的CAM,放大到原图大小,可以看到小狗所在的区域大致是激活响应最高的区域。&/p&&p&那么就缺一个可以识别XXX图片的模型了,网上还恰好就有个现成的,yahoo于2016年发布的开源色情图片识别模型Open NSFW(&b&N&/b&ot &b&S&/b&afe &b&F&/b&or &b&W&/b&ork):&/p&&a href=&/?target=https%3A///yahoo/open_nsfw& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&yahoo/open_nsfw&i class=&icon-external&&&/i&&/a&&p&CAM的实现并不难,结合Open NSFW自动打码的代码和使用放在了这里:&/p&&a href=&/?target=https%3A///frombeijingwithlove/dlcv_for_beginners/tree/master/random_bonus/generate_mosaic_for_porno_images& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&给XX图片生成马赛克&i class=&icon-external&&&/i&&/a&&br&&br&(成功打码的)效果差不多是下面这样子:&img src=&/v2-cbefa39dc983f2645dd8_b.png& data-rawwidth=&768& data-rawheight=&256& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&/v2-cbefa39dc983f2645dd8_r.png&&&h2&去除(爱情)动作片中的马赛克&/h2&&p&这没什么好说的了,一行代码都不用改,只需要按照前面的步骤把数据准备好,然后按照pix2pix官方的使用方法训练就可以了:&/p&&p&Torch版pix2pix:&a href=&/?target=https%3A///phillipi/pix2pix& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&phillipi/pix2pix&i class=&icon-external&&&/i&&/a&&/p&&p&pyTorch版pix2pix(Cycle-GAN二合一版):&a href=&/?target=https%3A///junyanz/pytorch-CycleGAN-and-pix2pix& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&junyanz/pytorch-CycleGAN-and-pix2pix&i class=&icon-external&&&/i&&/a&&/p&&p&从D盘里随随便便找了几千张图片,用来执行了一下自动打码和pix2pix训练(默认参数),效果是下面这样:&/p&&br&&img src=&/v2-9f52b17c0e1296767cbfbfafc290a5bd_b.png& data-rawwidth=&814& data-rawheight=&691& class=&origin_image zh-lightbox-thumb& width=&814& data-original=&/v2-9f52b17c0e1296767cbfbfafc290a5bd_r.png&&&p&什么?你问说好给女优去马赛克呢?女优照片呢?&/p&&img src=&/v2-480fb8a4dcfc7a4f92ec_b.png& data-rawwidth=&75& data-rawheight=&60& class=&content_image& width=&75&&&p&还是要说一下,在真人照片上的效果比蘑菇和花强。&/p&&h2&对偶学习(Dual Learning)&/h2&&p&去马赛克已经讲完了,接下来就是给女孩穿(tuo)衣服了,动手之前,还是先讲一下铺垫:&b&对偶学习&/b&和&b&Cycle-GAN&/b&。&/p&&p&对偶学习是MSRA于2016年提出的一种用于机器翻译的增强学习方法[8],目的是解决海量数据配对标注的难题,个人觉得算是一种弱监督方法(不过看到大多数文献算作无监督)。以机器翻译为例,对偶学习基本思想如下图[9]:&/p&&img src=&/v2-c4b1eeda364fb6c9bada02f3_b.png& data-rawwidth=&866& data-rawheight=&399& class=&origin_image zh-lightbox-thumb& width=&866& data-original=&/v2-c4b1eeda364fb6c9bada02f3_r.png&&左边的灰衣男只懂英语,右边的黑衣女只懂中文,现在的任务就是,要学习如何翻译英语到中文。对偶学习解决这个问题的思路是:给定一个模型&img src=&/equation?tex=f%3Ax%5Crightarrow+y& alt=&f:x\rightarrow y& eeimg=&1&&一上来无法知道f翻译得是否正确,但是如果考虑上&img src=&/equation?tex=f& alt=&f& eeimg=&1&&的对偶问题&img src=&/equation?tex=g%3Ay%5Crightarrow+x& alt=&g:y\rightarrow x& eeimg=&1&&,那么我可以尝试翻译一个英文句子到中文,再翻译回来。这种转了一圈的结果&img src=&/equation?tex=x%27%3Dg%28f%28x%29%29& alt=&x'=g(f(x))& eeimg=&1&&,灰衣男是可以用一个标准(BLEU)判断x'和x是否一个意思,并且把结果的一致性反馈给这两个模型进行改进。同样的,从中文取个句子,这样循环翻译一遍,两个模型又能从黑衣女那里获取反馈并改进模型。其实这就是强化学习的过程,每次翻译就是一个action,每个action会从环境(灰衣男或黑衣女)中获取reward,对模型进行改进,直至收敛。&p&也许有的人看到这里会觉得和上世纪提出的Co-training很像,这个在知乎上也有讨论:&/p&&a href=&/question/& class=&internal&&如何理解刘铁岩老师团队在NIPS 2016上提出的对偶学习(Dual Learning)?&/a&&p&个人觉得还是不一样的,Co-Training是一种multi-view方法,比如一个输入x,如果看作是两个拼一起的特征&img src=&/equation?tex=x%3D%28x_1%2Cx_2%29& alt=&x=(x_1,x_2)& eeimg=&1&&,并且假设&img src=&/equation?tex=x_1& alt=&x_1& eeimg=&1&&和&img src=&/equation?tex=x_2& alt=&x_2& eeimg=&1&&互相独立,那么这时候训练两个分类器&img src=&/equation?tex=f_1%28%5Ccdot%29& alt=&f_1(\cdot)& eeimg=&1&&和&img src=&/equation?tex=f_2%28%5Ccdot%29& alt=&f_2(\cdot)& eeimg=&1&&对于任意样本x应该有&img src=&/equation?tex=f_1%28x_1%29%3Df_2%28x_2%29& alt=&f_1(x_1)=f_2(x_2)& eeimg=&1&&。这对没有标注的样本是很有用的,相当于利用了同一个样本分类结果就应该一样的隐含约束。所以Co-Training的典型场景是少量标注+大量未标注的半监督场景。并且&img src=&/equation?tex=f_1& alt=&f_1& eeimg=&1&&和&img src=&/equation?tex=f_2& alt=&f_2& eeimg=&1&&其实是两个不同,但是domain指向相同的任务。而Dual Learning中&img src=&/equation?tex=f& alt=&f& eeimg=&1&&和&img src=&/equation?tex=g& alt=&g& eeimg=&1&&是对偶任务,利用的隐含约束是&img src=&/equation?tex=x%5Crightarrow+y%5Crightarrow+x& alt=&x\rightarrow y\rightarrow x& eeimg=&1&&的cycle consistency。对输入的特征也没有像Co-Training有那么明确的假设,学习方法上也不一样,Dual Learning算是强化学习。&/p&&h2&CycleGAN和未配对图像翻译(Unpaired Image-to-Image Translation)&/h2&&p&CycleGAN,翻译过来就是:轮着干,是结合了对偶学习和GAN一个很直接而巧妙的想法[10],示意图如下:&/p&&img src=&/v2-9e7396ebccb7c42302fc97_b.png& data-rawwidth=&838& data-rawheight=&216& class=&origin_image zh-lightbox-thumb& width=&838& data-original=&/v2-9e7396ebccb7c42302fc97_r.png&&&p&X和Y分别是两种不同类型图的集合,比如穿衣服的女优和没穿衣服的女优。所以给定一张穿了衣服的女优,要变成没穿衣服的样子,就是个图片翻译问题。CycleGAN示意图中(b)和(c)就是Dual Learning:&/p&&img src=&/v2-de51cac58b_b.png& data-rawwidth=&347& data-rawheight=&62& class=&content_image& width=&347&&&p&在Dual Learning基础上,又加入了两个判别器&img src=&/equation?tex=D_X& alt=&D_X& eeimg=&1&&和&img src=&/equation?tex=D_Y& alt=&D_Y& eeimg=&1&&用来进行对抗训练,让翻译过来的图片尽量逼近当前集合中的图片:&/p&&p&&img src=&/v2-e0ea7a6b38bf2a20cea4ea6f741a4c67_b.png& data-rawwidth=&442& data-rawheight=&59& class=&origin_image zh-lightbox-thumb& width=&442& data-original=&/v2-e0ea7a6b38bf2a20cea4ea6f741a4c67_r.png&&全考虑一起,最终的loss是:&/p&&p&&img src=&/v2-e6d99e7edea969da3dad_b.png& data-rawwidth=&357& data-rawheight=&87& class=&content_image& width=&357&&也许有人会问,那不加cycle-consistency,直接用GAN学习一个&img src=&/equation?tex=X%5Crightarrow+Y& alt=&X\rightarrow Y& eeimg=&1&&的映射,让生成的Y的样本尽量毕竟Y里本身的样本可不可以呢?这个作者在文中也讨论了,会产生GAN训练中容易发生的mode collapse问题。mode collapse问题的一个简单示意如下[1]:&/p&&p&&img src=&/v2-309fce6329592babb784ed_b.png& data-rawwidth=&842& data-rawheight=&262& class=&origin_image zh-lightbox-thumb& width=&842& data-original=&/v2-309fce6329592babb784ed_r.png&&上边的是真实分布,下边的是学习到的分布,可以看到学习到的分布只是完整分布的一部分,这个叫做partial mode collapse,是训练不收敛情况中常见的一种。如果是完全的mode collapse,就是说生成模型得到的都是几乎一样的输出。而加入Cycle-consistency会让一个domain里不同的样本都尽量映射到另一个domain里不同的地方,理想情况就是双射(bijection)。直观来理解,如果通过&img src=&/equation?tex=X%5Crightarrow+Y& alt=&X\rightarrow Y& eeimg=&1&&都映射在Y中同一个点,那么这个点y通过&img src=&/equation?tex=Y%5Crightarrow+X& alt=&Y\rightarrow X& eeimg=&1&&映射回来显然不可能是多个不同的x,所以加入cycle-consistency就帮助避免了mode collapse。这个问题在另一篇和CycleGAN其实本质上没什么不同的方法DiscoGAN中有更详细的讨论[11],有兴趣的话可以参考。&/p&&br&&p&有一点值得注意的是,虽然名字叫CycleGAN,并且套路也和C-GAN很像,但是其实只有adversarial,并没有generative。因为严格来说只是学习了&img src=&/equation?tex=X%5Crightarrow+Y& alt=&X\rightarrow Y& eeimg=&1&&和&img src=&/equation?tex=Y%5Crightarrow+X& alt=&Y\rightarrow X& eeimg=&1&&的mapping,所谓的generative network里并没有随机性。有一个和CycleGAN以及DiscoGAN其实本质上也没什么不同的方法叫DualGAN[12],倒是通过dropout把随机性加上了。不过所有加了随机性产生的样本和原始样本间的cycle-consistency用的还是l1 loss,总觉得这样不是很对劲。当然现在GAN这么热门,其实只要是用了adversarial loss的基本都会取个名字叫XXGAN,也许是可以增加投稿命中率。&/p&&p&另外上节中提到了Co-Training,感觉这里也应该提一下CoGAN[13],因为名字有些相似,并且也可以用于未配对的图像翻译。CoGAN的大体思想是:如果两个Domain之间可以互相映射,那么一定有一些特征是共有的。比如男人和女人,虽然普遍可以从长相区分,但不变的是都有两个眼睛一个鼻子一张嘴等等。所以可以在生成的时候,把生成共有特征和各自特征的部分分开,示意图如下:&br&&/p&&p&&img src=&/v2-57eaadc8cec5190bfd30_b.png& data-rawwidth=&758& data-rawheight=&207& class=&origin_image zh-lightbox-thumb& width=&758& data-original=&/v2-57eaadc8cec5190bfd30_r.png&&其实就是两个GAN结构,其中生成网络和判别网络中比较高层的部分都采用了权值共享(虚线相连的部分),没有全职共享的部分分别处理不同的domain。这样每次就可以根据训练的domain生成一个样本在两个domain中不同的对应,比如戴眼镜和没戴眼镜:&/p&&p&&img src=&/v2-356a6118ccf3e8e3bf1c7_b.png& data-rawwidth=&791& data-rawheight=&267& class=&origin_image zh-lightbox-thumb& width=&791& data-original=&/v2-356a6118ccf3e8e3bf1c7_r.png&&分别有了共有特征和各自domain特征,那么做mapping的思路也就很直接了[14]:&/p&&p&&img src=&/v2-8ac50600e40feaac345e09bd7e05a83d_b.png& data-rawwidth=&771& data-rawheight=&210& class=&origin_image zh-lightbox-thumb& width=&771& data-original=&/v2-8ac50600e40feaac345e09bd7e05a83d_r.png&&在GAN前边加了个domain encoder,然后对每个domain能得到三种样本给判别器区分:直接采样,重建采样,从另一个domain中transfer后的重建采样。训练好之后,用一个domain的encoder+另一个domain的generator就很自然的实现了不同domain的转换。用在图像翻译上的效果如下:&/p&&p&&img src=&/v2-612e9cf5e125fd626be7db_b.png& data-rawwidth=&444& data-rawheight=&544& class=&origin_image zh-lightbox-thumb& width=&444& data-original=&/v2-612e9cf5e125fd626be7db_r.png&&还有个巧妙的思路,是把CoGAN拆开,不同domain作为C-GAN条件的更加显式的做法[15]:&/p&&br&&p&&img src=&/v2-ddec16d502c94f91ea35_b.png& data-rawwidth=&883& data-rawheight=&398& class=&origin_image zh-lightbox-thumb& width=&883& data-original=&/v2-ddec16d502c94f91ea35_r.png&&第一步用噪声Z作为和domain无关的共享表征对应的latent noise,domain信息作为条件C训练一个C-GAN。第二步,训练一个encoder,利用和常见的encode-decode结构相反的decode(generate)-encode结构。学习好的encoder可以结合domain信息,把输入图像中和domain无关的共享特征提取出来。第三步,把前两步训练好的encoder和decoder(generator)连一起,就可以根据domain进行图像翻译了。&/p&&p&CoGAN一系的方法虽然结构看起来更复杂,但个人感觉理解起来要比dual系的方法更直接,并且有latent space,可解释性和属性对应也好一些。&/p&&p&又扯远了,还是回到正题:&/p&&br&&h2&给女优穿上衣服&/h2&&p&其实同样没什么好说的,Cycle-GAN和pix2pix的作者是一拨人,文档都写得非常棒,准备好数据,分成穿衣服的和没穿衣服的两组,按照文档的步骤训练就可以:&/p&&p&Torch版Cycle-GAN:&a href=&/?target=https%3A///junyanz/CycleGAN& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&junyanz/CycleGAN&i class=&icon-external&&&/i&&/a&&/p&&p&pyTorch版Cycle-GAN(pix2pix二合一版):&a href=&/?target=https%3A///junyanz/pytorch-CycleGAN-and-pix2pix& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&junyanz/pytorch-CycleGAN-and-pix2pix&i class=&icon-external&&&/i&&/a&&/p&&p&Cycle-GAN收敛不易,我用了128x128分辨率训练了穿衣服和没穿衣服的女优各一千多张,同样是默认参数训练了120个epoch,最后小部分成功“穿衣服”的结果如下:&/p&&img src=&/v2-fee34d66c386e0e01e5804_b.jpg& data-rawwidth=&1117& data-rawheight=&192& class=&origin_image zh-lightbox-thumb& width=&1117& data-original=&/v2-fee34d66c386e0e01e5804_r.jpg&&&img src=&/v2-de57c5ebefa4251ee3caa1_b.jpg& data-rawwidth=&1117& data-rawheight=&192& class=&origin_image zh-lightbox-thumb& width=&1117& data-original=&/v2-de57c5ebefa4251ee3caa1_r.jpg&&&p&虽然都有些突兀,但好歹是穿上衣服了。注意马赛克不是图片里就有的,是我后来加上去的。&/p&&p&那么,脱衣服的例子在哪里?&/p&&img src=&/v2-480fb8a4dcfc7a4f92ec_b.png& data-rawwidth=&75& data-rawheight=&60& class=&content_image& width=&75&&&h2&参考文献&/h2&&p&[1] I. Goodfellow. Nips 2016 tutorial: Generative adversarial networks. arXiv preprint arXiv:, 2016.&/p&&p&[2] A. B. L. Larsen, S. K. S?nderby, Generating Faces with Torch. &a href=&/?target=http%3A//torch.ch/blog//gan.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Torch | Generating Faces with Torch&i class=&icon-external&&&/i&&/a&&/p&&p&[3] A. B. L. Larsen, S. K. S?nderby, H. Larochelle, and O. Winther. Autoencoding beyond pixels using a
learned similarity metric. In ICML, pages , 2016.
&/p&&p&[4] C. Ledig, L. Theis, F. Huszar, J. Caballero, A. Aitken, A. Tejani, J. Totz, Z. Wang, and W. Shi. Photo-realistic single image super-resolution using a generative adversarial network. arXiv:, 2016.&/p&&p&[5] P. Isola, J.-Y. Zhu, T. Zhou, and A. A. Efros. Image-to-image translation with conditional adversarial networks. arxiv, 2016. &/p&&p&[6] O. Ronneberger, P. Fischer, and T. Brox. U-net: Convolutional networks for biomedical image segmentation. In MICCAI, pages 234–241. Springer, 2015.&/p&&p&[7] B. Zhou, A. Khosla, A. Lapedriza, A. Oliva, and A. Torralba. Learning deep features for discriminative localization. arXiv preprint arXiv:, 2015.&/p&&p&[8] He, D., Xia, Y., Qin, T., Wang, L., Yu, N., Liu, T.-Y., and Ma, W.-Y. (2016a). Dual learning for machine translation. In the Annual Conference on Neural Information Processing Systems (NIPS), 2016.&/p&&br&&p&[9] &a href=&/?target=http%3A//www.dsrg.stuorg.iastate.edu/wp-content/uploads/2017/02/dual-learning_-pushing-the-new-frontier-of-artificial-intelligence-tieyan-liu.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&& Tie-Yan Liu, Dual Learning: Pushing the New Frontier of Artificial Intelligence, MIFS 2016&i class=&icon-external&&&/i&&/a&&br&&/p&&p&[10] J.-Y. Zhu, T. Park, P. Isola, and A. A. Efros. Unpaired image-to-image translation using cycle-consistent adversarial networkss. arXiv preprint arXiv:, 2017.&/p&&p&[11] T. Kim, M. Cha, H. Kim, J. Lee, and J. Kim. Learning to Discover Cross-Domain Relations with Generative Adversarial Networks. ArXiv e-prints, Mar. 2017.&/p&&br&&p&[12] Z. Yi, H. Zhang, P. T. Gong, et al. DualGAN: Unsupervised dual learning for image-to-image translation. arXiv preprint arXiv:, 2017.&/p&&br&&p&[13] M.-Y. Liu and O. Tuzel. Coupled generative adversarial networks. In Advances in Neural Information Processing Systems (NIPS), 2016.&/p&&p&[14] M.-Y. Liu, T. Breuel, and J. Kautz. Unsupervised image-to-image translation networks. arXiv preprint arXiv:, 2017.&/p&&p&[15] Dong, H., Neekhara, P., Wu, C., Guo, Y.: Unsupervised image-to-image translation with generative adversarial networks. arXiv preprint arXiv:, 2017.&/p&&p&=========== 分割线: ===========&/p&&p&上周日发的时候也想到了可能会有许多人对这个话题感兴趣,但没想到超过了1.5W赞这么多,大概看了看评论,做一些补充:&/p&&p&&b&1) &/b&马赛克训练数据:对于一般的机器学习问题,都是分布越简单越容易,遵循这个原则,我用的约束是单人照片,具体方法是:先找一个Pascal VOC训练好的SSD代码,然后SSD筛选了一批每张图里只能检测到一个人的。&/p&&p&最后在真人照片上的效果看上去还是不错的,我没有做过量化评估,大体来说看上去挺像的要超过一半,非常逼真的可能有5%~10%。两人以上战斗的动作画面我没有评估过。&/p&&p&&b&2)&/b&穿(tuo)衣训练数据:因为收敛很难,所以数据的加了更多约束:只用女性单人正面照片。同样通过SSD检测出单人照片,同时考虑person框的宽高比小于1的且框内能检测到人脸的(OpenCV的人脸检测)。这样尽量筛选出一批面向镜头,身体占画面比接近的照片。&/p&&p&最后的效果我在原文中也提到过,只有小部分能成功穿上(tuo)衣服,具体我也没有量化统计过,大概100张里两三张吧,大部分都是身上出现了看上去有点像衣服的线条或是另一个人的胸部。考虑到我最后筛选出的图片人物占画面比仍然有很大的变化,很可能我的模型就是遇到了文中提到的partial mode collapse的问题。&/p&&p&如果有更好的办法筛选出人物大小差不多的照片,效果应该能提升不少。比如我在用SSD筛选的时候如果考虑宽高比更小一些,筛选出的照片看上去会更加一致,不过我资源不太够,这样做后训练集就只有不到300张,资源够的老司机们有兴趣可以试试。&/p&&br&&p&&b&3)&/b&预训练模型有没有?有,但是我研读了中华人民共和国刑法第三百六十三、三百六十四和三百六十六条,完全读不懂,所以还是不提供。再说就算我提供了,根据1)和2),看到你想看的内容也是需要运气的。&/p&&p&另外特别感谢赞赏的知友们,这篇文章是想说&b&书中自有颜如玉&/b&,而知友们的赞赏让我知道&b&书中真有黄金屋&/b&,古人诚不我欺…&/p&
作为一名久经片场的老司机,早就想写一些探讨驾驶技术的文章。这篇就介绍利用生成式对抗网络(GAN)的两个基本驾驶技能: 1) 去除(爱情)动作片中的马赛克2) 给(爱情)动作片中的女孩穿(tuo)衣服 生成式模型上一篇《》中已经简单介…
经历过15FALL CC的人来说一下看法&br&&br&之前上这门课,我包括我寝室另外两人,很痛苦很痛苦(这个很大部分是因为我们都是转CS的,基础薄弱,而且第一学期就作死选CC,这个稍后说),以至于每个周日(一般都是周日due)连饭都吃不上。而且每次due完之后我们三个人都要开会讨论为什么选这个课。但是上完这个课之后,感觉是脱胎换骨了一样,好像学到了很多东西。当时有个好友也申请上了下学期的TA,我就笑称他是上学期去讨伐恶龙的战士,在杀掉恶龙后却变成了下学期的恶龙。其实就连我也想,如果我是下学期的CC TA的话,我也会“点到为止”地让学生们“去尝试不同的东西(踩各种坑)”,因为”只有试过了才会对知识更加了解呀!”,“成长怎么会不经历痛苦!”。&br&&br&但是,第一,这样对学生们真的好吗?&br&第二,真的学到了很多东西吗?真的学到了很多东西吗??&br&&br&我想了很久这些问题,现在就给大家说说我的看法:&br&第一,假如你站在一个迷宫里面,四面八方都是路,其中只有一些路是通向终点的,另外一些路甚至不知道通向什么地方。这时候你去问TA,TA说:“你可以都尝试一下每条路哦,就算达不到终点,那你也掌握了‘这条路达不到终点’的这个知识啊,而且还很可能在路上捡到西瓜芝麻什么的哦!” 如果是你,你会怎么做?你敢花大力气在一条路上一路走下去吗?你怎么知道这条路是不是死路呢?&br&&br&为什么一开始就不告诉我们哪条路可以走?我觉得老师和TA就应该是领路人,虽然不是司机,可以载你走完这条路,但是起码可以告诉你这条路是可以走下去的,是付出与收益比最高的,告诉你“你只要沿着这条路努力奔跑就行了!”这样剩下来的才是个人的努力问题。而不是在选错路,付出比别人更多努力之后,发现还不如那些一开始就选对路的人付出却很少的人(虽然可能他们自己也不知道自己选对了路)。&br&&br&有些人说这门课很接近实际的工作环境,让你自己去搜索和解决各种可能在工作中出现的奇奇怪怪的问题。拜托,这门课叫“Cloud Computing”,不是“How to get out of 坑”,不是“Prepare for working environment”。而且就是为了在工作中少踩坑,不是应该多学到知识吗,多认清楚更多的坑,多知道什么该干什么不该干吗?“&b&为了让你提前准备好在工作中踩坑而现在多体验踩坑的感觉&/b&”这是一个什么奇怪的逻辑?&br&&br&退一步讲,好,我愿意在挫折中成长,我愿意尝试不同的路。但是这门课:第一,有严格的&b&Budget&/b&限定。第二,有严格的&b&Deadline&/b&,而且&b&没有Grace day&/b&! 这让每个愿意多尝试的学生都要面临受到惩罚的威胁。&b&一方面想要学生多尝试,一方面又严格限定budget和时间&/b&,这不是矛盾的么。而且这门课每周都有一个Quiz,每次光这个就会花掉你半天到一天的时间去看很多资料,总共有12个Quiz,一共占25分(这一届是20分)但是平均分只有60%~70%,所以光这个就要扣差不多十分,这意味着拿A已经很难了,再在其它地方出点差错,拿个C,可能连书都没得读了(CMU要求总绩点在B以上,C以后就要被退学了)&br&&br&而且Majd老师对于作弊的教条就是“&b&宁可错杀一千,也不放过一个&/b&”,所以经常会出现一些莫名其妙的警告邮件。只要你在同一个时间同一个IP开始做,或者答案或Code相似,都有可能收到这种警告邮件,目的就是威慑你让你放弃甚至有一点和别人合作的想法。&br&&br&第二个问题才是最重要的,真的学到了很多东西了吗?我们容易产生错觉的地方在于,只比较了&b&收入&/b&,而忽视了&b&成本&/b&。对于15213,你可能每周花15小时学到了15小时的东西。对于CC,你可能每周花40小时,但只学到了20小时的东西。确实,学到的东西多了啊,但是&b&性价比&/b&呢?CC最不合理的地方就是本来明明可以很简单就解决的东西,偏偏就是不告诉你,偏偏要弄得很花时间才能解决。&br&&br&而且有些人走出了迷宫之后,可能会认为自己收获了很多,“我熟悉这条路上各个地方的坑,知道哪里有西瓜芝麻”,但殊不知,自己选的路尽管能出去,却是最远的,有很多别的路上就没有的坑。&br&&br&新东方(不要吐槽新东方,一线的老师都是超级有水平的)的陈虎平老师说过:“&b&站在巨人的肩膀上才能看得更宽,走得更远。&/b&” 为什么CCTA就不把自己上的这个课的心得体会跟大家分享一下呢?为什么觉得公开Report,每个人都会拿满分?换句话说,我们的目标不就是让每个人都尽量地获取这门课所能学到的知识从而获取更高的分数吗?非要辛辛苦苦学的才算知识,轻松能学到的就不是知识了?我想,如果我当TA,我不告诉他们什么地方有坑,让他们走自己以前踩过的坑,那么充其量他们也只能达到我当时的高度,或者只是比我高一点点。但是如果我把我上这门课的心得体会告诉他们,那他们就能够超越我走得更远,学到更多的东西,这不是教育的初衷吗?&br&&br&&b&&u&每年的CC学生,每年踩同样的坑,每年出来的水平都一样。&/u&&/b&&br&&b&&u&明年的CC学生,站在前一年学长的肩膀上,水平越来越高。&/u&&/b&&br&哪个更好?&br&&br&在这一点上,我力顶小土刀,我不仅支持他写博客,而且我自己也竭尽所能帮助了一些这学期上CC的人,我也打算自己也写一个类似CC Writeup的博客,说一下自己的心得体会,帮助一下之后的学生。被请喝茶什么的,在天朝呆久了查水表都不怕还怕喝茶?其实一开始,&b&&u&我真的非常想看他们痛苦地不断踩各种坑又从坑里爬起来的挣扎的样子&/u&&/b&。因为自己在其中倾注了太多的心血,从而产生逆向合理化的心理效应,觉得这就是所谓的“吃得苦中苦,方为人上人”,觉得只有在痛苦中得到的东西才会更加深刻更加珍惜。可是这样我自己不也渐渐变成恶龙了吗?我觉得,我要帮助他们超越我自己,而我自己为了防止被他们超越,也会更加努力地学习,只有这样才能达到双赢,对他人对自己都是大有裨益的。&br&&br&最后我觉得最本质的原因是,现在的环境有点畸形,很多人来CMU都是来转CS当码农的,然后又听说CC这门课对找工作很有帮助,所以很多不应该上这门课,或者是说现阶段还不适合上这门课的人都来上了这门课。搞得现在CC都像是所有想转CS的学生的必修课一样。像我和我室友三人都是转CS的,又才刚开始补基础,所以才会上得举步维艰。如果像我当时科班出身的几个同学那样,基础很好,每周花两天以内的时间就可以搞定,这才能够“乐在其中”。&br&&br&所以给以后想上CC的同学的建议是:&br&第一,至少基础搞好了才来上CC,不要连Linux基本命令都没操作过就来赶鸭子上架,那会是相当痛苦的。&br&第二,看你喜不喜欢做Cloud,以后走不走这条路,而不单纯仅仅是为了在简历上多几行字。虽然上完这个课后好像确实是可以在简历上写很多东西,但是找不找得到工作的因素有很多,你性别写成“女”都可能比你在上面写CC的项目能收到的面试多,谁知道是哪一个因素影响你找工作呢?&br&&br&&p&再说一句,其实这一届的CCTA已经好很多了,比如说成神啊浩原啊神奇的振宇哥啊,至少当初是我CC的私人TA,告诉了我所有我想知道的东西,至少这次也非常努力改进了writeup,标出了不同的坑。但是在Majd的教育体系下,学生们还是要从受苦受累中获得知识。&/p&&br&最后说一句,&b&以后CC有不懂的可以直接来找我&/b&!!&br&&br&========= 更新 =========&br&昨晚跟这次的TA&a data-hash=&c02ec74a44ee4ae293652& href=&///people/c02ec74a44ee4ae293652& class=&member_mention& data-editable=&true& data-title=&@王成& data-tip=&p$b$c02ec74a44ee4ae293652& data-hovercard=&p$b$c02ec74a44ee4ae293652&&@王成&/a& 聊了大半个通宵,感觉自己确实地图炮开得有点广,伤及了一些兢兢业业想要努力改善这们课还有对学生真的好的人。而且因为自己想要看到别人受苦而认为别人也那样想也很不妥,可能是因为我这个人比较坏吧~所以就这样想了。但我写本文的本意就是避轻就重,专挑不好的方面讲,得罪人也再所难免。不过通过这次对话也再次印证了这门课的不合理性,TA辛辛苦苦干了一学期,学生累死累活撑到学期结束,结果谁也不讨好谁。学生觉得TA不干事,TA觉得学生难伺候,就是这一种怪现象。&br&&br&为什么呢?我们觉得,是因为CC针对的人群不明确所致。转专业的学生有一大堆新东西要学,跟不上。学过人的驾轻就熟,一下子就做出来了。TA一看,怎么这么简单刚放出来就立马有人做出来了还跑那么高分,弄难一点再难一点。而且生活中有些事就像是常理一样,觉得不说大家都懂。这就容易产生误解了。比如说前段时间看到一个男女生搓澡的区别,男生搓澡只要搓两面,女生搓澡居然要搓四面。男生就觉得世界上所有人搓澡都只搓两面,女生就觉得搓澡搓四面不是常理吗?当时那个人发了公众号之后,居然还引起了不小的轰动。所以说,一方面,有些坑TA可能也想不到居然还有人会跳这种坑。另一方面,学生也会想“这么简单的事直接说出来不就行了吗,为什么就是不说”(当然,真的就是有TA明明知道大家都卡在哪里但[就是不说]!)&br&&br&我们觉得解决方案,第一是就是像213那样,针对新手开设,把Load和难度降低,而且CC之后还有一门叫Advanced CC的,也是学Cloud,也是Majd的课,而且就我接触这两门课的经验来看,ADCC上面的阅读资料跟CC Quiz所要阅读的资料的重合性很大,完全没必要在CC这边弄得很难,然后在ADCC这边再把这些难的东西拿出来炒冷饭。我觉得可以把CC一些难的Project转移到ADCC上,这样既可以让人先了解一下Cloud Computing到底是个什么东西,不感兴趣或跟不上的同学也不至于爬着上完一学期,又可以让感兴趣或者想要深入了解的同学继续上ADCC来挑战更难的Project。&br&&br&第二就是针对高端玩家。像DS那样,有严格的前置课程规定,要不就在课程介绍中写个大大的Warning,直接劝退菜鸟,然后去掉Project 0这种一周入门Linux AWS Azure的Project。一周入门这些,对于新手来说来不及消化,对于四年CS专业的人来说又非常鸡肋,还不如不要。然后就可以在认定同学都是有基础不会自己去踩各种奇奇怪怪的坑的前提下设计Project。&br&&br&为什么很多人认为CC跟213以及OS等神课无法相提并论?我觉得就是因为Majd太想包罗万象了,每年都新增不少新东西。有一次我跟师兄聊CC,聊了半天他以为我一直聊的是DS。新东西多了,有些东西可能TA都不甚了解,做出来的Project稳定性自然不够好。所谓术业有专功,这门课的重点在哪呢?一开始我以为是学的是Mapreduce,再接着我以为是AWS培训班,紧接着是突然变得特别难的数据库Sharding和分布式系统并发。中间穿插着Hive,Impala和Redshift三合一,跟着writeup操作一下莫名其妙就完成了,都不知道这些是些什么东西,只觉得好不容易有个Project能水过高兴就好。最后好像又要比较一下各种大数据框架,Spark, Kafka听起来高大上,“终于能写到简历上了!”至于Team Project说是要把所有的东西融合起来,做个包含前后端的“至于AWS的Twitter分析系统”,然后一开始大家都互相问“什么是框架”。Hbase 基本的API都没熟悉Live Test就开始了。总之如果有人问我CC主要学了什么,我还真难答上来。&br&&br&自己是希望CC这门课越来越好的,但至于Majd要怎么变,就不得而知了。我应该还会继续更新,争取给以后想选CC课的人作个好的参考。
经历过15FALL CC的人来说一下看法 之前上这门课,我包括我寝室另外两人,很痛苦很痛苦(这个很大部分是因为我们都是转CS的,基础薄弱,而且第一学期就作死选CC,这个稍后说),以至于每个周日(一般都是周日due)连饭都吃不上。而且每次due完之后我们三个人…
首先我觉得你应该好好过一遍MIT的Linear Algebra的课。这个课有两个版本,我是跟这个更适合自学的版本。因为这个版本所有章节都模块化了,跟起来不会让人觉得压力很大。&a href=&///?target=https%3A//ocw.mit.edu/courses/mathematics/18-06sc-linear-algebra-fall-2011/index.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Linear Algebra&i class=&icon-external&&&/i&&/a&&br&&br&我所说的过一遍,不是你看个录像就完事儿了的,首先,把pdf资料都打印出来,然后你得记笔记,接着你得跟着助教做习题课的练习,最后你得把课后作业都做完,并且把考试也做完(都有答案的你自己可以check)。这个版本的题目量不是很大,但是都是精挑细选的题目,做完会让你有一种豁然开朗的感觉。不管你本科是不是理工科,线代基础有多好,我都建议仔细过一遍,一定能发现很多新东西。如果基础够好,用不着看课本,直接看讲义就行了,因为已经讲得很细很好了。&br&&br&然后就是前面说的Matrix Cookbook,&br&&a href=&///?target=https%3A//www.ics.uci.edu/%7Ewelling/teaching/KernelsICS273B/MatrixCookBook.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&ics.uci.edu/~welling/te&/span&&span class=&invisible&&aching/KernelsICS273B/MatrixCookBook.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&这本书其实就是一本速查手册,里面向量矩阵微分的东西还是很全的。这些东西一般也很难背下来,用到了查就是了。&br&&br&如果你要从写code的层面去学线性代数,方法一,就是看这本书:&br&Coding the Matrix: Linear Algebra through Applications to Computer Science&br&&a href=&///?target=https%3A///Coding-Matrix-Algebra-Applications-Computer/dp//ref%3Dsr_1_8%3Fie%3DUTF8%26qid%3D%26sr%3D8-8%26keywords%3Dlinear%2Balgebra& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Linear Algebra through Applications to Computer Science: Philip N. Klein: 0: : Books&i class=&icon-external&&&/i&&/a&&br&布朗大学之前在coursera开过公开课,好像已经下架了,不过网上能找到视频。&br&&br&如果你要从写code的层面去学线性代数,但是你想上一门课,方法二,就是去跟EDX这门课:&br&&a href=&///?target=https%3A//www.edx.org/course/linear-algebra-foundations-frontiers-utaustinx-ut-5-04x& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Linear Algebra - Foundations to Frontiers&i class=&icon-external&&&/i&&/a&&br&&br&如果你要是对矩阵的数值计算计算感兴趣那就去看约翰霍普金斯大学的&br&Matrix Computations &a href=&///?target=https%3A///Computations-Hopkins-Studies-Mathematical-Sciences/dp//ref%3Dsr_1_1%3Fie%3DUTF8%26qid%3D%26sr%3D8-1%26keywords%3DMatrix%2Bcomputation& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Gene H. Golub, Charles F. Van Loan: 4: : Books&i class=&icon-external&&&/i&&/a&,&br&不过现在Matlab和Numpy的线性代数的库已经很厉害了,所以自己手动去实现矩阵计算的机会我个人认为应该不会特别多。&br&&br&其他的话,ML的书中和论文中出现什么上网搜就行了。&br&&br&最后墙裂建议先把MIT的认真上一遍,真的是上过的最好的一门线性代数打底的课程:&br&&br&----------------------------------&br&-------------------------Update 一下-------------&br&国内要是有看不到的可能因为视频是youtube的,看网易公开课对应章节的课程视频和习题课视频就行了:&br&&br&课程视频:&br&&a href=&///?target=http%3A///special/opencourse/daishu.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&麻省理工公开课:线性代数_全35集_网易公开课&i class=&icon-external&&&/i&&/a&&br&&br&习题课视频:&br&&a href=&///?target=http%3A///special/opencourse/mitxianxingdaishuxitike.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&麻省理工学院公开课:MIT线性代数习题课_全36集_网易公开课&i class=&icon-external&&&/i&&/a&&br&-----------------------&br&布朗大学的那个Coding the Matrix的视频,在这里:&br&&a href=&///?target=https%3A//cs.brown.edu/video/channels/coding-matrix-fall-2014/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Coding the Matrix, Fall 2014&i class=&icon-external&&&/i&&/a&&br&整本书的资料,在这里:&br&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Coding The Matrix&i class=&icon-external&&&/i&&/a&&br&&br&&br&&img src=&/v2-eb0f42dbccc_b.jpg& data-rawwidth=&2016& data-rawheight=&1512& class=&origin_image zh-lightbox-thumb& width=&2016& data-original=&/v2-eb0f42dbccc_r.jpg&&
首先我觉得你应该好好过一遍MIT的Linear Algebra的课。这个课有两个版本,我是跟这个更适合自学的版本。因为这个版本所有章节都模块化了,跟起来不会让人觉得压力很大。 我所说的过一遍,不是你看个录像就完事儿了的,首先,把pdf资料都打印…
&img src=&/50/v2-002f3ff6d3c197f651086_b.jpg& data-rawwidth=&1170& data-rawheight=&660& class=&origin_image zh-lightbox-thumb& width=&1170& data-original=&/50/v2-002f3ff6d3c197f651086_r.jpg&&我这几年一直在坚持做一件事:希望用自己的绵薄之力打破留学申请行业信息不对等的现状,坚决反对这个行业中的劣币驱逐良币并且坚决用个人亲身体验以及带学生的实际案例去研究针对美国STEM项目的申请方法,在这段时间里,也认识到了像&a href=&/people/efe3bcdaf43cd419909ddb& data-hash=&efe3bcdaf43cd419909ddb& class=&member_mention& data-hovercard=&p$b$efe3bcdaf43cd419909ddb& data-editable=&true& data-title=&@小状师张&&@小状师张&/a&等等虽然所在领域不同但是心气与观点十分一致的朋友。&p&那么,没有微博也没有微信公众号的我,还是坚持用知乎作为输出我的内容的平台,给准备申请美国理工类(包括商业分析)的朋友们一些个人建议和经验分享。&/p&&p&多做一句自我介绍,意在预防性地给以后想做美国理工科留学Live的朋友做个参考:&/p&&p&我叫王蛋丁,高中毕业于有着皇城根人大附中之称的北京市第四中学,随后本科毕业于有着被誉为印第安纳州克劳福德斯维尔村的斯坦福之称的,和七姐妹女校相对应的男校Wabash College,之后博士全奖(一定得带上这两个字,不然怎么收智商税)就读于有着紐黑文的哈佛大学之美誉的耶鲁大学(一定要用这种“有着XXX美誉的”,“号称某地XXX”的这种句式来掩饰自己背景上的不自信,达到让人看了你的简介就直接打钱的目的)。一撸名校。本科期间游学于芝加哥大学XX课题组,以及耶鲁大学XXX课题组,是高大上的研究助理哦~(千万别实话实说写成lab baby或者搬砖工哦~不然可就露馅啦),大四时JBC水文挂名一篇(本科阶段发表12篇SCI亦可)。真的是N年留美工作科研实习经验,帮助超过X百名学生拿到美国顶级所有top20名校的无奖,半奖,3/4奖,全奖录取,申请经验异常丰富,做过X校,XX校以及XXX校的录取委员会助理,并且和他们的招生主任谈笑风生酒席间,肆意撸串压马路;教过的学生里有多名耶鲁小本,对西方名校招生,招什么样子的学生的那一套理论非常熟悉,当然也代表过自己本科母校面试大陆申请学生(这句话也一定要加上,具体形式可以是面试官啦,喝咖啡官啦,共进晚餐官啦,等等)教学与被教学经历资深(TA么)。咳咳。&/p&&p&&b&本文所提供信息完全免费,不割韭菜不收税,你说你不给钱就想获取蛋丁在留学领域的经验和见解有没有可能,当然TMD有可能啦~&/b&&/p&&br&&p&&b&转载本文当然可以,并且你还就说是你写的。&/b&&/p&&p&本文分为如下几个部分:&/p&&p&1. 各申请核心要素之间的相对重要性排列以及我这么排列的依据;&/p&&p&2.
根据这个排列,我该如何理性的分配好自己有限的时间强化背景?&/p&&p& 3.
掏心窝干货输出:对于托福,GRE,GPA,中国学生一般会有哪些误区?&br&&/p&&p&4. &a href=&/question//answer/& class=&internal&&撰写留学申请的个人陈述 (PS, personal statement)时有哪些常见的误区?&/a&&/p&&p&5. &a href=&/question//answer/& class=&internal&&申请国外PhD的时候如何与教授套磁? - 知乎&/a&&/p&&p&6. &a href=&/p/?group_id=272896& class=&internal&&祭出我这篇“当我告诉你暑假需要做一个summer research的时候我想要你知道什么”,请低调收藏,高调分享。 - 知乎专栏&/a&&/p&&p&7. more to come……&br&&/p&&br&&p&&b&1. 各申请核心要素之间的相对重要性排列以及我这么排列的依据&/b&&br&&/p&&br&&p&那么我们开始。本文要解决的核心问题就是理清申请美国硕士博士(理工科+BA)的过程中,各个申请要素(文书,推荐信,科研,实习,GPA托福GRE)的相对重要性,以及为什么他们的相对重要性是这样的。这篇文章仅仅代表我个人观点,你觉得有道理,我谢谢你,你觉得是bullshit,I don't care.&/p&&p&首先说结论:&/p&&p&理工类PhD申请:&br&推荐信~套瓷&research/publication
~套瓷&coursework&GPA&PS&托福口语~GRE写作&&&托福GRE其他项&/p&&p&理工类(含BA)硕士申请:&br&托福&GPA&coursework&research~intern~PS&~GRE&&套瓷&/p&&p&先说博士。&/p&&p&博士申请推荐信永远是最重要的,这个对于很多我们国内的学生而言都不大相信,毕竟谁都知道咱们中国特色的推荐信大多是学生或者学生找的机构写好然后教授发出去的。但是在整个PhD录取的过程中,一封好的推荐信,如果可以客观公正的阐述被推荐人的科研潜力以及做事风格,会在判断是否需录取的过程中有至关重要的作用。学校招博士生的本质是能不能在五六年内这个学生可以给学校回馈一本高质量的Thesis Book。五年是一个很沉重的承诺,那么在录取时的风险控制当然就无比重要的。Quit掉PhD可能对学生可以有利(化生),但是学校总是不愿意看到投在学生身上的钱打了水漂的。&/p&&p&在一封热情洋溢的推荐信下,你的research experience/publication就是一个印证推荐信内容的筹码。对于本科毕业的PhD申请者,有没有paper并不是最关键的,而是你有没有几段可以展现你的科研能力的实验室经历。拿耶鲁的在读博士来说,绝大多数是本科直接上来的,并且这里面的大部分人是没有挂名论文的。但是在我了解的范围内的人,都至少有一段刻骨铭心的,相对完整的科研经历,并且这段经历之上有其对应的实验室PI的推荐信。&/p&&p&我为什么把套磁写了两遍?基于推荐人的学术圈子人脉的套磁的作用稍微比基于被套磁人实验课题相关的套磁要重要一些。如此拗口怎么理解,我举个例子,就是我在导师A手下作了课题X。我想套磁对方学校导师B。如果A和B在领域内彼此认识,那么这个套磁信的效果就很有可能比仅仅因为B也做课题X要强。&/p&&p&上过的课程比overall GPA重要。相关博士项目所涉及的知识体系课程如果你的成绩单上都有不错的体现,那么这也是录取委员会判断“you are well prepared& 的重要依据,这个比你的overall GPA更有意义。当然,overall GPA作为下线,一般在项目的enrolled student profile中会看到。比如“我们要求GPA最低不能低于3.0,然后我们去年录取学生的平均GPA是3.X” 这样。&/p&&p&PS的作用,真的不应该被机构们过度神话,总之本科,硕士,博士针对PS的重要程度是乡下的趋势。你的实力从你所做过的事情以及成绩单上都会有很明显的体现,PS是对某些细节带有个人感情瑟赛的细致描述,通过一篇PS就本质上提升你的博士申请竞争力,你动脑子想想现实么。&/p&&p&托福口语和GRE写作我为什么单独列举出来。GRE写作主要是看你的写作水平的下限,毕竟博士最主要的事情就是要发呸破的;托福口语分数可能会涉及到你第一年的的funding来源是否可以是TA。如果口语达标,直接可用TA的方式解决工资问题,可能你就进去了。有人问为什么不能直接做RA呢?越是好些的项目,单个教授的录取话语权就越低,而是通过统一录取进来一批学生,然后做rotation,然后在第一年的后半学期或者夏天之前选定教授,之后拿RA的工资。而在rotation期间,基本都是通过系里面的TA作为工资的。反过来思考一下,在NSF,NIH的funding被各种割草的今天,教授手上的funding直接support一个没有任何接触并且也不知底细的学生当工资,那也不太公平对不,所以,好好练口语吧。&/p&&p&当然如果你somehow拿到了fellowship,那另说。&/p&&p&再说硕士。&/p&&p&硕士的本质就是交钱上课拿学位(像普林的ORFE这种大神项目需要提前有faculty明确表示愿意带你这个学生之后才有可能被录取的项目例外),那么对于招生办而言,最重要的事情就是}

我要回帖

更多关于 学习做奶茶 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信