November 7, 2012

Chrome插件的二三事

为什么Administrator这么长!我一直在思考这个问题。一年前我照着都能打错它,现在闭着眼睛都能拼出来。我看到Administrator就想吐!!(虽然最近我被告知其实可以延长session的有效时间啊混蛋,但是,这已经改变不了我讨厌Administrator的事实了)

所以忍无可忍的我,前段时间攒着午休时间写了个Chrome插件。原本是想它帮着自动填,可无奈一直没成功(某web用的什么组件啊混蛋!什么?自动填表?账号记录?那是咩啊。。统统没有啊混蛋!)
结果最后它就成了个复制用的记录栈。Sign,好歹只要Ctrl+V了是不。。

sed sedd

双击自动复制。选中文字可右键加入记录栈,顶掉不太常用的。也可以手动修改记录。
图标做一个操作就会变一下,其实没什么意义,同是写着玩的。。

源码戳我

说起来合用的现成插件一定是能找到的,不过自己写着好玩。也是边学边做,好在Chrome插件开发上手超简单,官方的开发指南,照着做一遍,其余的查查Guide和Sample。这里分享个微妙的好地方,英文苦手的话,360翻译了google的开发文档,戳我。

最后,顺便分享几个点:

1. Chrome复制选中文字

   1: // copy from text area
   2: e.target.select();
   3: document.execCommand('copy');

2. 右键菜单
我没做得复杂,copy hyperlink也还没写完。想知道的更多的话,官方文档里查contextMenus,记得有个sample写得很详细。



   1: var selectionMenu = chrome.contextMenus.
   2: create({ "title": "Copy to Stack", "contexts": ["selection"],
   3:     "onclick": selectionOnClick });

October 26, 2012

[乱码代码] 我说为嘛前端如此憔悴!

这周抽空把lincccc.com装修了一下,其实也就是找了个支持google字体(真是好看啊)的主题,然后照着私人审美改了些东西。期间历时约一周,体验了一把前端是种多么苦逼的工种,各种google,各种扒代码,各种瞎改。

  • 右下角的浮动“顶端/底部”按钮

这个扒的奚少的代码,我把“滚动到评论”的部分去掉了,因为评论部分怎么做还没想好。。
1. 在style.css文件里添加:

   1: #shangxia{
   2:     position:absolute;top:80%;right:50%;margin-right:-523px;display:block;}
   3: #shang,#xia{
   4:     background:url(#?Background_IMG_Url?#) no-repeat;
   5:     position:relative;cursor:pointer;height:21px;width:24px;
   6:     margin:5px 0 0;}
   7: #xia{background-position:center -23px;}

2. header.php文件里添加:



<div id="shangxia"><div id="shang"></div><div id="xia"></div></div>

3. 一段js代码添加到任何一个已有并引用的js文件中,有点小长,点我。这段代码用于控制按钮的行为。
如果没有的话,就创建个,然后在footer.php加一段,引用jQuery库和新加的js文件。之所以加在footer呢,是据说这样js会最后加载,网页load起来快些。



   1: <script type="text/javascript"
   2:     src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
   3: <script type="text/javascript" src="http://lincccc.com/fudong.js"></script>


  • 左上角的“关注/订阅”按钮

个人爱好和国内环境,就只做了新浪微博和google reader的。照着官方的教程做就行;或者如果觉得按钮太丑,就把链接扒下来,链到自己的图片。
新浪微博开放平台的关注按钮:http://open.weibo.com/widget/followbutton.php
Google的:http://www.google.com/webmasters/add.html



  • 文章页面的分享按钮

这个其实是可以用插件实现的,大饼找了个叫Jetpack的,有默认的和自定义功能,还不错。这里还是贴html代码,粘在要放的地方就行,比如single.php。



   1: <div id="share">
   2: <a href="http://twitter.com/home/?status=<?php the_title(''); ?>
   3: :<?php the_permalink(); ?>"title="分享到Twitter" target="_blank" rel="nofollow">
   4: +Twitter </a>
   5: <a href="http://www.xianguo.com/service/submitdigg/?link=<?php echo $permalink; ?>
   6: &amp;title=<?php echo $title; ?>" title="收藏到鲜果" target="_blank" rel="nofollow">
   7: +鲜果 </a>
   8: <a rel="nofollow" class="fav_douban" href="javascript:window.open
   9: ('http://www.douban.com/recommend/?url='+encodeURIComponent(document.location.href)
  10: +'&title='+encodeURIComponent(document.title));void(0)"title="分享到豆瓣" >
  11: +豆瓣 </a>
  12: <a href="http://share.xiaonei.com/share/buttonshare.do?link=<?php the_permalink() ?>
  13: &title=<?php the_title(); ?>"title="分享到人人网"target="_blank" rel="nofollow" >
  14: +人人 </a>
  15: <a href="http://v.t.sina.com.cn/share/share.php?url=<?php the_permalink() ?>
  16: &title=<?php the_title(); ?>&ralateUid=#?你的Uid?#" title="分享到新浪微博" 
  17: target="_blank" rel="nofollow">
  18: +新浪微博</a>
  19: </div>

链接的文字可以换成图片,顺便推荐一个搜图标的好地方easyicon。


最后,推荐个自定义表情的插件Custom Smilies,悄悄地偷了gtalk的表情,灭哈哈哈~


其实本来就想换张皮,重画张看板娘的。。结果搞出这么多事情来,真是手贱。现在看看评论部分还是很难看,share的按钮也想重画,真是没完没了。。
最重要的是,看板娘还是木有重画,直接用的long long long ago的,你个水人,完全不知道主次啊混蛋。。。

September 25, 2012

迟来的WOW毕业留念

写在熊猫人将开塞拉摩沦陷罗宁会死吉安娜要博出位的9月25日。

手边的《如果宅》还只看了一半不到。作为一个巫妖王时代才被大饼带进WOW的才刚开始旧了一点的玩家,书中的那些“服务器娘被修空调的大叔抱走”“三季稻在荆棘谷猎杀小号”的桥段,其实是有些陌生的。我们用的是YY,他们用的叫UT。

其实在巫妖王时代,WOW里一些我向往的游戏元素已经开始流失了。那时,我就是一边找背偷钱,一边听左边的大饼抱怨暴雪改掉了各种有趣的设计。那时,我还是个经常忘抹毒药只喜欢偷东西的贼,现在也还是。小萱萱扔给我们1w金和10个霜纹包,骑着摩托赶过几个部落,竟然就AFK了。

常常觉得可惜,我都没有经历过副本门口的跑尸恶战,我甚至都没有亲手做过毒药。虽然兢兢业业地做完了职业任务,却没有实质的效果,这很无趣。到大灾变时代,为了团队配置速成了个牛头大萨满,我一直觉得,那些厉害的图腾和火大爷,来得太容易了。

不过,至少我见过副本打到一半没箭了的猎人,见过攒灵魂石的术士,我在祖尔法拉克捡尸体捡到手抽筋,在斯坦索姆见到一个80级的圣骑拖着满副本的怪跑着跑着被敲出春哥来,噗哈哈。我对着银松森林的草药和湖波吟过诗,听过黑海岸边多情的精灵的哭声,感叹过贫瘠之地的广袤,我的小猎人带着修玛一直到60级。
我一直记得我曾是一个暗夜精灵。

p_large_7LQZ_0c6b00012d065c70

说起来,我的AFK。H脊背还在开荒中,灭了2周终于掀掉了第一块板;还没有拿到DS英雄成就,没有女仆龙,装备离毕业远了不止一点点。突然就觉得累了,往死里地讨厌老五。和风mm交待完后事后,一直很担心团就此散了,内疚了一个礼拜。后来看到风mm更新过H8的成就,总算安心。只是recount里的人,认识的已不过半数,又觉得伤心。

想起来,以前虹盏论坛里有人说“总有一天,我也会从LARUKU毕业。但是我希望,我永远记得曾经喜欢过LARUKU这件事情。”卫宫似乎也说过类似的话。对于WOW,我也是这样的想法。

对于一个运营了几乎八年的网络游戏,我很尊敬WOW和开发运营它的团队。无论今后WOW希望往哪里走,想要面向哪个阶层的玩家,我会一直对我曾经真实感受到的艾泽拉斯土地的坚实感,心存感激。

怀念所有我曾经遇到过、战斗和一起战斗过的大家。

original_4qH8_714500000735125f

June 2, 2012

大规模培训终了~

算起来入职将近2个月了,却一直在培训。说起来是培训,却半句代码都没敲过。每天打交道的尽是些文档、PPT、视频,还有那装在虚拟机里死慢死慢的软件。

第一个月的培训在天堂软件园。中午通常吃外卖的盒饭,不贵,大多数时候挺好吃的,偶尔会有附赠的水果,不过那天的菜就。。大家都说,是做饭的师傅觉得菜做坏了亏欠,才给我们水果补偿的。
IMG00150 IMG00152 IMG00151
楼下的食堂不算难吃,也不贵,但下午不管什么时候去,菜总是冷的;中午好些,但是人巨多,一进去脑子就嗡嗡嗡嗡地响;所以一般只去吃早饭,白粥总没有难喝的。

培训会考试,有组队项目,却也不见有人挂。
中途有过一次Team Building,一下午的时间,几乎绕着西湖骑了一圈,去指定的地点拍集体照,还要拍十种颜色的花。中途遇上下雨,一群人躲近苏堤上的一个棚子,突然觉得有些浪漫><
  
同行的还有另一群2货,其中包括一颗正经博士。
  
骑的都是公共自行车,红红的一片,很好看。

第二个月就搬回西湖国际了。想不到食堂更加难吃了,而且服务态度恶劣。好在我找到了新的吃早饭的快餐店,还尝到了很久都没吃过了的南乳><

我们挤在一个挺小的Training Room里(Training Room压力很大啊,以前从来没这么多人过)。每个人半张桌子,椅子摆开了就很难动弹了,出去的时候总要知会左右的人。
像一个堆栈,坐在最里面的人想出来,就得让外面人全Pop出去。
IMG00192 某天上课中,某两只高富帅睡得前赴后继。
另外,这两个月是我生平听到“白富美”和“高富帅”次数最多的日子,因为最里面那只小朋友。

昨天是大规模培训的最后一天,大多数人都进组开始组内培训了。
我也新搬到了以后工作的Cube里。还很空旷,可以放很多书。坐位上还遗留着一个好看的玻璃制奖杯(好想以后能拿到一个><)。
IMG00195

带我的Mentor是个PPMM,常笑。老大是个白面书生?,也常笑。大老大是个芬兰帅大叔,泡面头,不常笑,不过很有趣。接到的第一个任务有些棘手,是我不算熟悉的领域。不过心想也不至于太难,即使难,也难不过啃论文什么的吧。
下周可能会看见代码了,有点兴奋啊~~(啃完文档再说什么的最讨厌了><)

Bless Myself.

January 11, 2012

说说最近看过的电视剧

昨晚有人熬着夜debug,我就窝在毛毯里快进着看「甄嬛传」,到凌晨2点。早上起来看完了最后一集。该死的都死了,不该死的也死了。

听说这片刚开拍的时候豆瓣的评分只有2.0,原因不出“演员太丑”“好好的小说被毁了”“为嘛又是清朝”;开播之后才慢慢的开始爬,到了现在的8.0。
我没看过小说,刚看第1集的时候因为豆瓣的海报太丑外加片子竟70多集,只给了3星;看到一半,加了1星;今天才去改成5星,我觉得,当得起。

搜了下「甄嬛传」小说的评论,再加上小说作者笔名的风格,想来应该是个言情虐心剧;可又去查了下电视剧的导演郑晓龙(照片挺帅),以前拍的却是「金婚」、「渴望」、「四世同堂」这样的正经剧目。因此,整个片子的基调就很厚重,配乐选角都是四十代的沉稳,脱了二十代十代的稚嫩。小说粉丝讨厌一点也不奇怪。二次元世界三次元化都恨得粉丝牙痒痒,更何况一次元世界三次元化呢。再如何有理有据,也是脑内世界各人不同,强求不得。

似乎编剧就是小说作者本人,情节设置也算合理,不傻,戏剧性很强,人物性格分明,对人性扭曲的过程转折也算流畅,正面冲突紧张,背地里的小动作干脆。就是甘露寺那段我快进的最多,感觉假,这段的逻辑稍稍有些不畅。
最满意剧里的人死的利落,不像有些片拖拉,无比珍惜每一个演员的死亡机会。
这是故事的真实感。一个人的死亡,本来就是很快捷的事情,割动脉15分钟,窒息8分钟,抹脖子1分钟,吞枪5秒钟。是血腥。生命的沉重,也许有一半是因为易于摧残。

演员长得都不大偶像。皇帝更是老头子,却娶了一群十七八的小姑娘。我觉得华妃演的最好,跋扈,张扬,心狠,美艳,还有可悲的痴情。一群人,在花样年纪被扔进金玉其外的牢中,终日无所事事,在本该受到高等教育的年纪将时间都浪费在钻营魅术权术,而导致人生观价值观的不成熟;其实也像古时花楼的卖笑之人,只是恩客只有一人。

太忙,是身体的毒药;太闲,却是心灵的毒药。

-----------------------------

最近还看了些剩男剩女的片子,「男人帮」,「我可能不会爱你」,「我无法恋爱的理由 | 私が恋愛できない理由」。

开头都是群找不到gg找不到mm的高品质剩男女,三个片子的走向却完全不一样。「男人帮」装B,装深沉,车轮般的换女人;「可能不」兜圈子,装不懂,装纯,遥想恰同学少年时;「我的理由」就像个散装饼干,三个人来时各过个各的,走时还是各过各的,兜了一圈还是那样。

想想就和他们的出产地一样的个性,一个很混乱Punk,一个很清新Sick smile,一个很自我Princess。

January 6, 2012

那些年,我们一起写的学位论文

12月初定题,12月底开始写,1月初提交预审。前后真的在写也就一礼拜的时间。也是,师兄师姐们也是这样的,写得风风火火。

s

最喜欢初稿,28381个字。
12-30-2011 8-09-43 PM

后来加了点、删了点、换了点,却越改越多,29523个字。憋死了也未过30000,实在佩服3万党们。
1-6-2012 3-21-51 PM

预审稿子交上去了,最近就放羊等着了。拜托让过~

贴几个实验结果,做的还行吧。不如Kinect,但是随便用用该是够的,若是数据库做的再大些,应该会好很多。
23dss

后来改了些代码,重新连了骨架,好像变好看点了。
1-6-2012 3-42-07 PM


若真使得,好想按我自己想的,做个手掌的骨架,只是,唉。
毕业了后,自己再抽时间做吧。

忘了,跟风贴个致谢吧。文笔拙劣,也写不长。惭愧。Smile with tongue out

1-6-2012 3-54-08 PM

December 31, 2011

2011年终盘点

本来不想点的,忙完工作又忙论文的都要虚脱了(房间都好久没打扫了)。不过昨天刚写完论文0.9ver.,今天怎么也鼓不起劲做GPUver.了,所以这些就等到2012再说吧,反正地球都要毁灭了。

今年冬天杭州没下雪。光降温了。

※音乐
忙起来连歌也不听了,每天在实验室总戴着耳机,但什么声音也没有,就是隔音保暖用的,连纯音乐都觉得吵。到了年末才想起来今年是LARUKU的复出年,也是20周年,09年的时候我还说想去日本参战周年演唱会的,有点伤感了。真的花大片时间听歌,也就这一个月瞎听了些虾米的年末精选,把各种年终歌会都快进了次,想见到的还是那些人,FNS里出奇的老歌多。完全是老爷子的心态嘛!
突然觉得喜欢德永英明(虽然我本来就爱好大叔音),「壊れかけのRadio」和「あの鐘を鳴らすのはあなた」。
国内近来也出了些耐听的新歌手吧,为数不多的几次去KTV都是我很珍惜的听新歌的机会。
也许明年会改善吧,闲下来的话。

※动画
新番我都有跟的。不过好些跟着跟着就落下了,落太多就就想“恩,养肥了再看”,结果养着养着就忘了。。。
按时间来吧,看过的都说遍。
# IS | IS<インフィニット?ストラトス>
后宫片。亮点是萝卜和mm的结合体,男主角每收一个后宫ED画面里跟在他身后的mm就会多一个。其实我是冲着武道女主角追的。
# Fractale | フラクタル
不记得有没有看完了。。故事讲得有些散,坑没填完,对分形的解释有点脱离“分形”原本的概念,更像分身。制作算是精良吧。
# BREAKBLADE破刃之剑
这货算是今年的吧,这种分集剧场最磨人了。还有大饼要追的「UNICON」,都是等这集出来的时候忘了上集的内容。好在破剑的设定很奇特,武器像打墙钉的枪(其实就是),王后mm也很有爱。
# MacrossF
我不喜欢绿毛!
# 基友英雄传 | TIGER & BUNNY
这译名。。连载的时候我就是这译名才弃的它,要不是后来机缘巧合,真是错过了这个近来难得的热血好片。传统又非传统的对“英雄”的诠释,“为了梦想”“为了保护我所珍视的人们”,这种老掉牙的台词!这种老掉牙的感人桥段!这传神的你知我知的译名!
# 花开伊吕波 | 花咲くいろは
这片啊初看第一集真的很惊艳,什么十周年纪念制作,什么手工三段ray tracing光影效果。不过,不过,监督你到底想说什么啊!
# 我们仍未知道花名 | あの日見た花の名前を僕達はまだ知らない
年度催泪弹。这故事明明没那么感人,其实也没那多可讲的内容被拉成了11集,还有那么微不足道的有点荒谬的非要滞留人间不肯转世的理由。可是,天知道为什么,那哭花了的丑死的笑容,音乐突然唱起“君と夏の終わり 将来の夢 大きな希望 忘れない”,我想很多人都是在这个点哭的。
# 青之驱魔师 | 青の祓魔師
稳扎稳打的少年向番。不坏。猫又小黑挺萌。“猫舌头吃不了烫东西”什么的。
# 空之轨迹 TV版 和 全职猎人重制 | HUNTER×HUNTER 和 高达SEED HD重制版 | 機動戦士ガンダムSEED HDリマスター
我没看过你们几个没诚意的家伙。
# 滑头鬼之孙 第2季 | ぬらりひょんの孫 千年魔京
换了监督风格果然变了,喜欢突然大字幕草书写出招式的名字。听说西村最擅长耍帅。吐槽最后一集实在太黑暗太浪费感情了。
# 夏目友人帐 第3季 | 夏目友人帳 参 和 白兔糖 | うさぎドロップ
都是治愈番。对于夏目因为习惯,有点丧失兴趣了。。白兔糖的开场真是有点劲爆,孙子领养了爷爷的女儿,这乱七八糟的关系,真是让人兴奋。不过看着看着就忘了这桥段变成了红果果的温情片,尤其是尿床还耍赖那段。
# 偶像大师 | THE IDOLM@STER
最近才完结。我也不知道为啥会跟完,其实不怎么好看的说。像AKB48一样乱糟糟的一对女艺人。
# EVA新剧场版:破 | ヱヴァンゲリヲン新劇場版:破
因为EVA我得到了一个很喜欢的今年的生日礼物,二号机。为了明日香能够回来。
# 食梦者 第2季 | バクマン。2 和 Fate/Zero
这类片子是个正常人都会追的。两者的共通点是完结的都太不厚道了。“你们这种,完全就应该做成年番”,说了工作室也不会听我的,人家要卖周边赚钱的。
# 便当 | ベン·トー
下半年最奇特的片子。抢个半价便当抢出人生哲学来了。听说原来是个搞笑小说,完全看不出来,我把它当很违和的战斗番看的。。
# 追着追着掉了的有以下这些
「GOSICK」「超元气三姐妹 增量中 | みつどもえ 増量中!」「只有神知道的世界II | 神のみぞ知るセカイII」
「C」「亡灵幻境 | デッドマン·ワンダーランド」「神的记事本 | 神様のメモ帳」
「异国迷路的十字路口 | 異国迷路のクロワーゼ」「NO.6」「BLOOD-C」「永远之久远」
「最终流放 银翼之法姆 | ラストエグザイル-銀翼のファム-」「未来日记」「UN-GO」
「罪恶王冠 | ギルティクラウン」

好长。。我知道我今年闲暇都在干嘛了。。

不想写电影了,也就去电影院看了些大片什么的。印象最深的是「源代码」,觉得最难看的是「丁丁」。
就这样吧。

新年快乐~ 祝自己和所有要毕业的人,预审顺利。

December 7, 2011

搬家~ lincccc.com

前段时间被blogbus的浮动视频广告恶心到了,就开始计划搬家的事。

大饼买了个主机空间,我就蹭着用了。新地址:lincccc.com

wordpress还不会用,凑活着看看先。有空再画个主题。

毕业前blogspot站还会同步更新,国内的blogbus就关掉了(让你弹广告!)。

新年快乐~

November 19, 2011

Fullmetal Fairy Tale ~「Real Steel」

今日大风。跑去UME办了张心心念念很久的会员卡,然后去看「Real Steel」。

我挺喜欢这片。暴力不血腥。大饼说,拥有一个机器人是每个男孩心中的梦想。我想起我们计划的赚够500万后要做的事情:买一座山,建一个城堡,种一坨果树,造一个洒水高达。

我看这片,就像在看睡美人、白雪公主之类的童话故事,一个小男孩从垃圾堆里捡到一个拥有超强模仿能力的机器人,最后打败代表邪恶势力的世界冠军,成为英雄的故事。

但我其实很喜欢暴力的事情,就是怕血腥怕痛,所以这片子很适合我。而且又是Happy Ending,Perfect!

遗憾的是,没有出现我期待的萝卜卖萌镜头。

PS:影片后期——就是银幕上打得正high的时候,机器人被调至模仿模式,某大叔体感操控,的时候。我忽然有种穿越感,仿佛坐回到实验室写视觉动作识别代码了;有些难以接受,这抗噪声抗高光,不完全捕获下的动作预测和补全功能,还高实时性,耐打防抖动,而且TM这准确率也太高了点吧。看看我手里温室下80%准确率就欢天喜地的实验结果,着实有些受伤。

还好,你丫只是个特效合成的电影。

November 16, 2011

[乱读书] 数据挖掘导论的导论

Book:Pang-Ning Tan, Michael Steinbach, Vipin Kumar. 数据挖掘导论(Introduction to Data Mining). 机械工业出版社,2010年9月第1版.


这种训练程序一跑就是2个小时的时候最适合乱读书了。最近买了本「数据挖掘导论」和一本「模式识别」,混着读。读「数据挖掘导论」是因为不知道那是什么,读「模式识别」是因为做了很久这方面的东西最近感觉有些混沌想要重读基础知识。所以两边的「乱读书」也会混着更新,懒的看书的就看我瞎侃好了。

数据挖掘是最近挺热的一个方向,业内做的比较好的典型有Google的广告推送、Amazon的推荐服务等等等,都是和数据挖掘相关的。有一个流传甚广的描述DM重要性的案例模板,或者是“可乐和尿不湿摆在一起为什么能提高销量”的故事,或者是“口香糖和电池”的版本,大体的意思都是“数据挖掘可以帮助零售企业,自动地从其大规模的零售数据中,发现一些有用的信息”。这也是本书中对「数据挖掘」所下的定义,关键词是“自动”、“大规模”和“有用”。

数据中的知识发现过程包括:数据→预处理→数据挖掘→后处理→有效信息。预处理包括特征选择、降维、归一化等等,后处理则是为了保证信息的有效性,包括可视化、模式解释和过滤等。数据挖掘在其中最大的作用是自动总结和筛选知识(我认为)。这是一个交叉性和应用性很强的领域,以数据库、分布式技术为基础,涉及统计学、人工智能、机器学习和模式识别等多领域。

其主要难点在于:

可扩展性Scalability。指其处理大规模数据的能力,不单是时间复杂度上的高效,还有对存储空间上的要求,比如海量数据往往意味着无法将其一次性读入主存中。并行或分布式算法往往具有较高的可扩展性;
高维度High Dimensionality。通常会有成百或者上千的属性来修饰数据,可能是时域上的,也可能是空间域上的,这意味着我们需要应付高维向量,这对于某些对维度敏感的传统算法是灾难性的(这点和CV领域很像);
非均匀的复杂的数据Heterogeneous and Complex Data。由于DM的应用领域很广泛,但不同领域的数据的属性是不同的;属性中可能同时混杂着不同类型(连续的、离散的),比如同时包含文本、超链接和图片的网页。这对DM前的数学建模是个挑战;
数据归属和分布式Data Ownership and Distribution。有时,数据并不存储在一个地方;有时,数据并不属于单一的组织。因此,我们需要分布式DM技术。这里的难点主要在三个方面:如何降低分布式系统的通信成本;如何有效地合并多方的DM结果;以及如何处理数据安全的问题;
非传统式的统计分析Non-traditional Analysis。传统统计方法通常是一个假设和验证的过程,需要手工地收集数据、设计实验来验证假说。但当面临大规模数据应用时,这种劳动密集型的实验方法是不可取的。DM是一个自动提出假说并自动收集数据、自动验证的过程,不再有精巧设计的实验,数据更趋于偶然性。

数据挖掘的主要任务可以分为预测Predictive和描述Descriptive两大类。预测类任务指通过数据的一些属性估计其他属性;描述类任务指从数据中获取其隐藏的模式(趋势、相关性、聚类、异常性等等)。

预测建模Predictive Modeling。主要用于解决分类Classification和回归Regression两类问题(这点上与机器学习对预测的定义一致);
关联性分析Association Analysis。指从数据中发掘强烈存在的特征间的关系,这种关系通常通过隐藏的规则或者特征的子集来表示。我们开头提到的“可乐和纸尿布”就属于这类任务;
聚类分析Cluster Analysis。指从数据中发掘拥有相似外观的群体,使得类内距离最小,类间距离最大。比如,寻找商品的相似购买者,或者通过关键词对文档主题的聚类;
异常检测Anomaly Detection。指从数据中检测行为异常者,主要的目标是准确地发现异常行为,并且避免误判。这个应用十分有用,比如通过购买记录检测信用卡的异常消费行为——不符合持卡人的消费习惯或年龄等。

初步感觉这本书会讲到很多和机器学习、模式识别重复的内容,似乎可以理解为统计模型在大规模数据及具体环境下的应用问题,是个讲究实际的领域。

October 31, 2011

Job Hunting Season 终了!我想我要一份严肃的工作!

9月开始10月落幕,这一季算是过去了。
投出去一共33份简历,还有10家没有消息;
挂掉8家笔试,5家没去笔试;
收到9个面试:28所不要女生,科大讯飞放弃,百度明天我要问问他上海的问题再决定要否继续面下去,平安科技虽然我也不想去但的确二面被挂了,剩下的5个收到了offer。
(加了下发现少了1家,那家是sogou,恩,后来我发现简历一直处于未提交的状态,网上测评登陆进去就说通过了,但连笔试资格都没给,算是个奇葩)

学弟来问怎么找工作,我这个笔试老挂的人实在没什么说服力。但是真心的,再从头来过,我还是会做这么多项目,只是闲暇时间不会再按着自己的喜好写什么Handii读什么论文,而是会找陈越jj说“我要参加ACM拿奖”,或者熟读各种“程序员面试宝典”、“编程珠玑”和“Linux/数据库/网络精通”直到看到题目就能说出它和第几章某题差不多。不然,如何考得过那些早早地从实验室抽身开始脱产复习的勤奋的孩子,更考不过考场上见到的我拍过照的以及事后洋洋得意和我谈到的在笔试中组团Raid的孩子们。虽然这并不代表说,我在基础知识上觉得薄弱或者输于他们,只是一种手段。反正笔试嘛,也没有人要和我讨论CV算法的可并行性、多分类的混沌空间、统计模型的过拟合问题。(这是从找工作的角度,从个人成长的角度,还是多做事吧,为了几年后能接到猎头的电话)

另外就是职业目标的事情。本科的时候很梦想做游戏,但是又很纠结做游戏,一方面怀疑游戏行业的价值,一方面国内热衷的网络游戏实在不是我的菜。我要是去哪家网游公司做策划,这家公司会倒闭的,大饼这么说,我也觉得。投简历的时候,也没多想,后来才发现投的游戏公司不过寥寥几家,以前一直想去的盛大也转投了创新院做多媒体。有一晚在DM留守群上聊天,才发现自己的想法,“还是严肃一点的工作好”;游戏是我少年时的梦,但现在已经不是我想要追求的事业。我想追求人工智能,想做分布式,想继续做视觉做HCI,唯独没有想过要做游戏。人恐怕都是会变的,在追逐梦想的过程中,梦想也在改变。但无论做什么,我想工作真的还是严肃点的好,这样做起来容易找到人生的意义,容易说服自己努力,娱乐和生活也会更加有意思。

最后随便写点面经。面试其实我也没什么经验,认真面的就6家。

平安科技是我面的第一家公司,第一次遇到群P,第一次做面试前的自我介绍,很紧张,说话都有些发抖;但是完全没有技术面,在这点上对之后没有多少帮助。但有了第一次之后,以后的面试就感觉不到紧张了。

再接着是浙江大华。给不了多少钱,旁人总说你计算机的怎么看得上的一家公司。但我投它面它,是因为看重它未来的市场和前景,以及和我研究方向的高切合度。(大华是做安防、智能监控的,海康来的太晚,我就把它忽略了。)这场面试其实也没有具体的技术问题,似乎面试官是问过别人算法题的,不过到了我这里就变成“你做过的东西和我们部门的工作很相似,你要是愿意来,我们是很欢迎的”,就结束了。HR倒是问了些犀利的问题,还问了关于薪酬。在这之前我对薪酬是没有具体的概念的,就随便说了个数字,以致于后来谈offer都不好开口要求涨点。这是我对自身价值认知和不够坦率的问题,需要反省。

之后酱油阿里巴巴。一面遇到个做Java的,让随便写个冒泡排序,我刷刷刷写了,总觉得哪里错了但又想不起来,然后给他看,他居然说差不多(我擦,后来我会来重写了下,发现果然错了,内循环写错了点。。)那人后来还问我“你一直做C,让你做Java,会不会不行啊”,我当时脑子一热,心想不就是Java么,说“学Java只需要一个礼拜!”当时面试官就惊了,转而言其他。。现在想想,那应该是个好人,不然我当场就被赶出来了,居然当着人家Java程序员的面鄙视Java,活腻了,绝对活腻了。

之后等来了上海联影。联影是家刚起步的做医疗器械的新公司,但是听说有很多从西门子跳来的大牛。医疗器械是块大蛋糕,做的好了有市场了以后钱途无量,国外好多视觉图形学实验室都是靠医疗视觉的项目维持经费的。那天下午我接了大约6个电面电话,每个都长达半小时,面的范围包括OO概念、OS、视觉算法、Cuda、项目内容等等,接完还去现场面了技术和HR。真是虚脱了(中途我还酱油了完美的笔试,20+道选择题)。我很看好这家公司的前景,虽然他给钱不多,他加班,但这种创业型的公司拼的就是干劲、眼光、能力和运气。

第二天就面微策SE了。这是我面过最长时间的一个面试,4轮,每轮一个小时,从中午12点到下午5点。全英文。面到后来脑子都有点不灵清了,再加上前一天被轰炸过,面试官都说我“没睡醒”。。。都说微策爱面智力题,我却一题都没遇到,一下午尽写程序了;中途还被轰炸了些书本上的概念题,有些没答上来,回来翻了下博客才发现,我原来写过关于这方面的文章,垂足顿胸啊。一下午面下来,我对微策的感觉是很好的,正规,有条理,周到,面试官很nice(中途我把我的笔忘在了三面的地方,面试官还找到我四面的地方送过来,就是支便宜的自动铅笔,感动)。

AMD面试的流程就有些长了,从电面、笔试、再到面试,差不多有一个月的时间,也许这就是硬件公司的步调。不过AMD的人做事很认真,电面、笔试、面试前都特地电话过来确定我当天是否有空,把我感动的不行。最后面试的时候是3个面试官一起的,安排的40分钟,我差不多面了1个小时多10分钟,讲得口干舌燥。项目问的挺细,和他们做的方向不大一致,所以我就讲得浅显些。好在之前写过一些项目建议书,知道怎么通俗地描述我做的事情。沟通能力和描述问题的能力,在面试以及后续的工作中都很重要,这也是研究生2年半带给我最大的收获。

最后,感谢所有我面过、笔试过的公司。

September 26, 2011

怨妇贴。

这工作找的让人觉得大学7年就跟白读了一样,不如搞1年ACM,更不如上半年技校。

至今经历过的唯一我认为做的正确的笔试,只有WAP公司的三日编程题。虽然我最后因为时间关系没有实现完设计方案,当然更没有上交和之后的面试,但是很欣赏这样的笔试方式。

不过,大多的公司都不会有这家日企这么认真的态度,往往都是发张“代码不缩进”的卷子,好些的做个机考,考的也就是那些个题库里随机出来的ACM题。我从来不认为那些搞ACM的人有多牛掰,只是平日努力的方向不同而已。ACM得世界冠军固然难,可普通ACMer也就是“懂出题思路,懂ACM的通用Framework,做过90%题库”这样的水准。只是别人花在做项目、调系统、研究模型、发Paper的时间,他们花在了做ACM题上了而已。但就好比,料理竞赛再牛掰的大厨烧茶叶蛋也未必烧得好吃过一摆路边摊的一样,因为人家本来就是做这个的,而且天天做,日日做。

可是,公司们,说着“我们要找有坚实基础的、有解决问题能力的、有良好沟通能力和良好学习能力的人”,实际做的却是“来做ACM题吧”。也许公司并不是这么想的,但却这么做了。

我想我也是猜得到原因的。毕竟海面不可能,笔试是必须的。出优秀的题目太难,而且时效性很短,所以找题库或者根据题库改编是最方便的。而且ACM题有固定的标准,效率、内存,AC就是AC,不像开放题目,需要改卷管自己思考是否正确,而且标准模糊,从这个方面看也是最方便的。我并不否认考ACM题在某种意义上的公平性,但也是连高考也比不上的公平性。也许公司还认为“虽然不会做ACM不一定不是我们需要的人,但会做的人中笨的总不太多,反正应聘的人多,运气不好的我们也不要”。

所以,毕业求职季的种种笔试,成了又一次变相的高考,所有人看“程序员面试宝典”、看“编程珠玑”、看“编程之美”等等等,平日里碰都不会去碰的书。还有那些经典面试题,简直就是逼着你去看。大多数人也是从开始找工作的时候才开始看这些题,才开始了解到“原来还可以有这种题的”,比如我一直很不理解一道关于“单项链表查环”的题,为何不在插入链表时就保证无环呢?既然数据可能有环,为何不选择其他数据结构比如数组作为容器呢?这种笔试的结果通常是公司招到了看过这些题的人,而非会做这道题的人。

我并不希望做一个单纯的码农,并不喜欢捣鼓指针引用,代码只是工具,为了实现系统的一种交互不友善的软件而已,只是工具而已。也许是我在专业方向走的太远,再回过头来看这些充满Trick的ACM招式总觉得有些幼稚无聊。

不过现实就是这么无奈,逼着你同流合污,我也还是会去看这些书。写这篇日志的目的,是告诉10年20年后的我,如果做了笔试出题者或者面试管,记得己所不欲勿施于人,记得ACM考不出你想要的人。

August 18, 2011

八月中

君と夏の終わり 将来の夢 
大きな希望 忘れない
10年後の8月 また出会えるのを 信じて
最高の思い出を…

与你一起度过夏季的尽头 未来的梦想 庞大的希望 不会忘记
深信能够在十年后的八月重逢
成为最美好的回亿

今年四月番「あの日見た花の名前を僕達はまだ知らない。」我们仍未知道那天所看见的花的名字。这首ED至少贡献了这颗催泪弹80%的效果。据说是当年Zone乐队解散时的安可曲目,这种词,当年现场的一定哭翻了。

真TM煽情。

八月将逝。以此献给今生最后一个暑假。虽然不休假。

August 9, 2011

[基础算法] Random Forests

Random Forest(s),随机森林,又叫Random Trees[2][3],是一种由多棵决策树组合而成的联合预测模型,天然可以作为快速且有效的多类分类模型。如下图所示,RF中的每一棵决策树由众多split和node组成:split通过输入的test取值指引输出的走向(左或右);node为叶节点,决定单棵决策树的最终输出,在分类问题中为类属的概率分布或最大概率类属,在回归问题中为函数取值。整个RT的输出由众多决策树共同决定,argmax或者avg。
8-9-2011 2-41-59 PM

Node Test
node test通常很简单,但很多简单的拧在一起就变得无比强大,联合预测模型就是这样的东西。node test是因应用而异的。比如[1]的应用是基于深度图的人体部位识别,使用的node test是基于像素x的深度比较测试:
8-9-2011 2-53-40 PM
8-9-2011 2-54-54 PM
简单的说,就是比较像素x在u和v位移上的像素点的深度差是否大于某一阈值。u和v位移除以x深度值是为了让深度差与x本身的深度无关,与人体离相机的距离无关。这种node test乍一看是没有意义的,事实上也是没多少意义的,单个test的分类结果可能也只是比随机分类好那么一丁点。但就像Haar特征这种极弱的特征一样,起作用的关键在于后续的Boosting或Bagging——有效的联合可以联合的力量。

Training
RF属于Bagging类模型,因此大体训练过程和Bagging类似,关键在于样本的随机选取避免模型的overfitting问题。RF中的每棵决策树是分开训练的,彼此之间并无关联。对于每棵决策树,训练之前形成一个样本子集,在这个子集中有些样本可能出现多次,而另一些可能一次都没出现。接下去,就是循序决策树训练算法的,针对这个样本子集的单棵决策树训练。
单棵决策树的生成大致遵循以下过程:
1)随机生成样本子集;
2)分裂当前节点为左右节点,比较所有可选分裂,选取最优者;
3)重复2)直至达到最大节点深度,或当前节点分类精度达到要求。
这一过程是贪婪的。
当然对于不同的应用场合,训练过程中,会有细节上的差别,比如样本子集的生成过程、以及最优分割的定义。
在[1]中,决策树的真实样本其实是图片中的像素x,变量值则是上文提到的node test。但是,对于一张固定大小的图片而言可取的像素x是可数大量的,可取的位移(u,v)和深度差阈值几乎是不可数无限的。因此,[1]在训练单棵决策树前,要做的样本子集随机其实涉及到像素x集合的随机生成、位移(u,v)和深度差阈值组合的随机生成,最后还有训练深度图集合本身的随机生成。
最优分裂通常定义为使信息增量最大的分类,如[1]中的定义:
8-9-2011 3-34-37 PM
H指熵,通过分裂子集的部位标签分布计算。


Reference:
[1] J. Shotton, A. Fitzgibbon, M. Cook, T. Sharp, M. Finocchio, R. Moore, A. Kipman, and A. Blake. Real-Time Human Pose Recognition in Parts from a Single Depth Image. In CVPR 2011.
[2] L. Breiman. Random forests. Mach. Learning, 45(1):5–32, 2001.
[3] T. Hastie, R. Tibshirani, J. H. Friedman. The Elements of Statistical Learning. ISBN-13 978-0387952840, 2003, Springer.
[4] V. Lepetit, P. Lagger, and P. Fua. Randomized trees for real-time keypoint recognition. In Proc. CVPR, pages 2:775–781, 2005.

August 4, 2011

[源码笔记] OpenCV 2.3 :: Random Trees(二)

源码细节:

● 训练函数

bool CvRTrees::train( const CvMat* _train_data, int _tflag,
                        const CvMat* _responses, const CvMat* _var_idx,
                        const CvMat* _sample_idx, const CvMat* _var_type,
                        const CvMat* _missing_mask, CvRTParams params )

Step1:清理现场,调用clear()函数,删除和释放所有决策树,清除训练数据等;

Step2:构造适用于单棵决策树训练的参数包CvDTreeParams,主要就是对CvRTParams中一些参数的拷贝;

Step3:构建训练数据CvDTreeTrainData,主要涉及CvDTreeTrainData::set_data()函数。CvDTreeTrainData包含CvDTreeParams格式的参数包、被所有树共享的训练数据(优化结构使最优分裂更迅速)以及response类型和类数目等常用数据,还包括最终构造出来的树节点缓存等。

Step4:检查CvRTParams::nactive_vars使其不大于最大启用变量数;若nactive_vars传参为0,则默认赋值为最大启用变量数的平方根;若小于0,则报错退出;

Step5:创建并初始化一个变量活跃Mask(1×变量总数),初始化过程设置前nactive_vars个变量mask为1(活跃),其余为0(非活跃);

Step6:调用CvRTrees::grow_forest()开始生成森林。

● 生成森林

bool CvRTrees::grow_forest( const CvTermCriteria term_crit )

Step1:如果需要以准确率为终止条件或者需要计算变量的重要值(is_oob_or_vimportance = true),则需要创建并初始化以下数据:
oob_sample_votes  用于分类问题,样本数量×类数量,存储每个样本的测试分类;
oob_responses  用于回归问题,2×样本数量,这是一个不直接使用的数据,旨在为以下两个数据开辟空间;
oob_predictions_sum  用于回归问题,1×样本数量,存储每个样本的预测值之和;
oob_num_of_predictions  用于回归问题,1×样本数量,存储每个样本被预测的次数;
oob_samples_perm_ptr  用于存储乱序样本,样本数量×类数量;
samples_ptr / missing_ptr / true_resp_ptr  从训练数据中拷贝的样本数组、缺失Mask和真实response数组;
maximal_response  response的最大绝对值。

Step2:初始化以下数据:
trees  CvForestTree格式的单棵树集合,共max_ntrees棵,max_ntrees由CvDTreeParams定义;
sample_idx_mask_for_tree  存储每个样本是否参与当前树的构建,1×样本数量;
sample_idx_for_tree  存储在构建当前树时参与的样本序号,1×样本数量;

Step3:随机生成参与当前树构建的样本集(sample_idx_for_tree定义),调用CvForestTree::train()函数生成当前树,加入树集合中。CvForestTree::train()先调用CvDTreeTrainData::subsample_data()函数整理样本集,再通过调用CvForestTree::try_split_node()完成树的生成,try_split_node是一个递归函数,在分割当前节点后,会调用分割左右节点的try_split_node函数,直到准确率达到标准或者节点样本数过少;

Step4:如果需要以准确率为终止条件或者需要计算变量的重要值(is_oob_or_vimportance = true),则:
使用未参与当前树构建的样本,测试当前树的预测准确率;
若需计算变量的重要值,对于每一种变量,对每一个非参与样本,替换其该位置的变量值为另一随机样本的该变量值,再进行预测,其正确率的统计值与上一步当前树的预测准确率的差,将会累计到该变量的重要值中;

Step5:重复Step3 - 4,直到终止条件;

Step6:若需计算变量的重要值,归一化变量重要性到[0, 1]。

●训练单棵树

void CvDTree::try_split_node( CvDTreeNode* node )

Step1:调用CvDtree::calc_node_value()函数:对于分类问题,计算当前节点样本中最大样本数量的类别,最为该节点的类别,同时计算更新交叉验证错误率(命名带有cv_的数据);对于回归问题,也是类似的计算当前节点样本值的均值作为该节点的值,也计算更新交叉验证错误率;

Step2:作终止条件判断:样本数量是否过少;深度是否大于最大指定深度;对于分类问题,该节点是否只有一种类别;对于回归问题,交叉验证错误率是否已达到指定精度要求。若是,则停止分裂;

Step3:若可分裂,调用CvForestTree::find_best_split()函数寻找最优分裂,首先随机当前节点的活跃变量,再使用ForestTreeBestSplitFinder完成:ForestTreeBestSplitFinder对分类或回归问题、变量是否可数,分别处理。对于每个可用变量调用相应的find函数,获得针对某一变量的最佳分裂,再在这所有最佳分裂中依照quality值寻找最最优。find函数只关描述分类问题(回归其实差不多):

CvForestTree::find_split_ord_class():可数变量,在搜寻开始前,最主要的工作是建立一个按变量值升序的样本index序列,搜寻按照这个序列进行。最优分裂的依据是
8-3-2011 3-02-54 PM
也就是左右分裂所有类别中样本数量的平方  / 左右分裂的样本总数,再相加(= =还是公式看的懂些吧。。)
比如说,排序后的 A A B A B B C B C C 这样的序列,比较这样两种分裂方法:
          A A B A B B | C B C C 和 A A B A B B C B | C C
          第一种的quality是 (32 + 32 + 02) / 6 + (02 + 12 + 32) / 4 = 5.5
          第二种的quality是 (32 + 42 + 12) / 8 + (02 + 02 + 22) / 2 = 5.25
第一种更优秀些。感性地看,第一种的左分裂只有AB,右分裂只有BC,那么可能再来一次分裂就能完全分辨;而第二种虽然右分裂只有C,但是左分裂一团糟,其实完全没做什么事情。
最优搜寻过程中会跳过一些相差很小的以及不活跃的变量值,主要是为了避免在连续变量取值段出现分裂,这在真实预测中会降低树的鲁棒性。

CvForestTree::find_split_cat_class():不可数变量,分裂quality的计算与可数情况相似,不同的是分类的标准,不再是阈值对数值的左右划分,而是对变量取值的子集划分,比如将a b c d e五种可取变量值分为{a} + {b, c, d, e}、{a, b} + {c, d, e}等多种形式比较quality。统计的是左右分裂每个类别取该分裂子集中的变量值的样本数量的平方 / 左右分裂的样本总数,再相加。同样,搜寻会跳过样本数量很少的以及不活跃的分类取值。

Step4:若不存在最优分裂或者无法分裂,则释放相关数据后返回;否则,处理代理分裂、分割左右分裂数据、调用左右后续分裂。


References:
[1] OpenCV 2.3 Online Documentation: http://opencv.itseez.com/modules/ml/doc/random_trees.html
[2] Random Forests, Leo Breiman and Adele Cutler: http://www.stat.berkeley.edu/users/breiman/RandomForests/cc_home.htm
[3] T. Hastie, R. Tibshirani, J. H. Friedman. The Elements of Statistical Learning. ISBN-13 978-0387952840, 2003, Springer.

August 1, 2011

[源码笔记] OpenCV 2.3 :: Random Trees(一)

OpenCV2.3中Random Trees(R.T.)的继承结构:
7-22-2011 10-25-55 AM

API:

CvRTParams 定义R.T.训练用参数,CvDTreeParams的扩展子类,但并不用到CvDTreeParams(单一决策树)所需的所有参数。比如说,R.T.通常不需要剪枝,因此剪枝参数就不被用到。
max_depth
  单棵树所可能达到的最大深度
min_sample_count  树节点持续分裂的最小样本数量,也就是说,小于这个数节点就不持续分裂,变成叶子了
regression_accuracy  回归树的终止条件,如果所有节点的精度都达到要求就停止
use_surrogates  是否使用代理分裂。通常都是false,在有缺损数据或计算变量重要性的场合为true,比如,变量是色彩,而图片中有一部分区域因为光照是全黑的
max_categories  将所有可能取值聚类到有限类,以保证计算速度。树会以次优分裂(suboptimal split)的形式生长。只对2种取值以上的树有意义
priors  优先级设置,设定某些你尤其关心的类或值,使训练过程更关注它们的分类或回归精度。通常不设置
calc_var_importance  设置是否需要获取变量的重要值,一般设置true
nactive_vars  树的每个节点随机选择变量的数量,根据这些变量寻找最佳分裂。如果设置0值,则自动取变量总和的平方根
max_num_of_trees_in_the_forest  R.T.中可能存在的树的最大数量
forest_accuracy  准确率(作为终止条件)
termcrit_type  终止条件设置
  -- CV_TERMCRIT_ITER  以树的数目为终止条件,max_num_of_trees_in_the_forest生效
  -- CV_TERMCRIT_EPS  以准确率为终止条件,forest_accuracy生效
  -- CV_TERMCRIT_ITER | CV_TERMCRIT_EPS  两者同时作为终止条件
CvRTrees::train 训练R.T.
return bool  训练是否成功
train_data  训练数据:样本(一个样本由固定数量的多个变量定义),以Mat的形式存储,以列或行排列,必须是CV_32FC1格式
tflag  trainData的排列结构
  -- CV_ROW_SAMPLE  行排列
  -- CV_COL_SAMPLE  列排列
responses  训练数据:样本的值(输出),以一维Mat的形式存储,对应trainData,必须是CV_32FC1或CV_32SC1格式。对于分类问题,responses是类标签;对于回归问题,responses是需要逼近的函数取值
var_idx  定义感兴趣的变量,变量中的某些,传null表示全部
sample_idx  定义感兴趣的样本,样本中的某些,传null表示全部
var_type  定义responses的类型
  -- CV_VAR_CATEGORICAL 分类标签
  -- CV_VAR_ORDERED(CV_VAR_NUMERICAL)数值,用于回归问题
missing_mask  定义缺失数据,和train_data一样大的8位Mat
params  CvRTParams定义的训练参数
CvRTrees::train 训练R.T.(简短版的train函数)
return bool  训练是否成功
data  训练数据:CvMLData格式,可从外部.csv格式的文件读入,内部以Mat形式存储,也是类似的value / responses / missing mask。
params CvRTParams定义的训练参数
CvRTrees:predict 对一组输入样本进行预测(分类或回归)
return double  预测结果
sample  输入样本,格式同CvRTrees::train的train_data
missing_mask  定义缺失数据

Example:

  1. #include <cv.h>
  2. #include <stdio.h>
  3. #include <highgui.h>
  4. #include <ml.h>
  5. #include <map>
  6.  
  7. void print_result(float train_err, float test_err,
  8.                   const CvMat* _var_imp)
  9. {
  10.     printf( "train error    %f\n", train_err );
  11.     printf( "test error    %f\n\n", test_err );
  12.  
  13.     if (_var_imp)
  14.     {
  15.         cv::Mat var_imp(_var_imp), sorted_idx;
  16.         cv::sortIdx(var_imp, sorted_idx, CV_SORT_EVERY_ROW +
  17.             CV_SORT_DESCENDING);
  18.  
  19.         printf( "variable importance:\n" );
  20.         int i, n = (int)var_imp.total();
  21.         int type = var_imp.type();
  22.         CV_Assert(type == CV_32F || type == CV_64F);
  23.  
  24.         for( i = 0; i < n; i++)
  25.         {
  26.             int k = sorted_idx.at<int>(i);
  27.             printf( "%d\t%f\n", k, type == CV_32F ?
  28.                 var_imp.at<float>(k) :
  29.                 var_imp.at<double>(k));
  30.         }
  31.     }
  32.     printf("\n");
  33. }
  34.  
  35. int main()
  36. {
  37.     const char* filename = "data.xml";
  38.     int response_idx = 0;
  39.  
  40.     CvMLData data;
  41.     data.read_csv( filename ); // read data
  42.     data.set_response_idx( response_idx ); // set response index
  43.     data.change_var_type( response_idx,
  44.         CV_VAR_CATEGORICAL ); // set response type
  45.     // split train and test data
  46.     CvTrainTestSplit spl( 0.5f );
  47.     data.set_train_test_split( &spl );
  48.     data.set_miss_ch("?"); // set missing value
  49.  
  50.     CvRTrees rtrees;
  51.     rtrees.train( &data, CvRTParams( 10, 2, 0, false,
  52.         16, 0, true, 0, 100, 0, CV_TERMCRIT_ITER ));
  53.     print_result( rtrees.calc_error( &data, CV_TRAIN_ERROR),
  54.         rtrees.calc_error( &data, CV_TEST_ERROR ),
  55.         rtrees.get_var_importance() );
  56.  
  57.     return 0;
  58. }


References:
[1] OpenCV 2.3 Online Documentation: http://opencv.itseez.com/modules/ml/doc/random_trees.html
[2] Random Forests, Leo Breiman and Adele Cutler: http://www.stat.berkeley.edu/users/breiman/RandomForests/cc_home.htm
[3] T. Hastie, R. Tibshirani, J. H. Friedman. The Elements of Statistical Learning. ISBN-13 978-0387952840, 2003, Springer.

July 21, 2011

[无责任乱翻] M.L.是咩啊

[无责任乱翻] Machine Learning, Wald I, July 2002

M.L.是咩啊?(这个缩写邪恶吧)

神经网络(Neural Net,NN)大约发明于1985年,它将两个不同的团体带到了一起:
脑科学家——用NN为人脑的各种功能建模
计算机学者——研究语音识别(Speech Recognition)、字迹识别(Written Character Recognition)以及其他一些困难的预测问题(Prediction Problem)

之后:
一群机器人狂热分子也加入了这个团体,他们感兴趣的有:
监督式训练(Supervised Training)、自学习机器人(Self-learning Robots)

还有:
其余杂七杂八的团体,人工智能(Artificial Intelligence)、PCA学习(PAC Learning)

然后,有个毛会——NIPS(Neural Information Processing Systems)诞生了。刚开始,NIPS是各种NN应用目的萌发的温床。NN在预测问题上工作得很好,尽管存在它有一坨局部极值,尽管它总是面临过拟合(Overfitting)的危险。一些牛掰的人开始裁剪NN巨大的结构,来解决一些特殊的问题,比如旋转平移无关的字母识别,等等。

再后来,NIPS发展啊发展啊,变得越来越复杂,包含很多兴趣完全不同的团体,比如信号处理(Signal Processing)、机器视觉(Computer Vision),等等等等。

到了2000后,NIPS上发表的论文五花八门,也迎来了越来越多的外籍与会者,他们中大多数是计算机学者,还有一些工程师、物理学家、数学家。都很年轻,30来岁,充满活力。他们的工作都是严格意义上算法级别的。也是这个时候,M.L.在统计学方向,迎来了荒野上的第一阵歌声。预测问题成为研究热点,包括回归(Regression)和分类(Classification)。

2001年,重大的突破,两类牛掰算法的诞生:
-- 支持向量机(Support Vector Machines,Vapnik)
-- 联合预测模型(Combining Predictors):Bagging(Breiman)、Boosting(Freund and Schapire)
Bagging和Boosting都是将一坨小预测模型联合在一起,组成强模型(“我来组成头部!”“我来组成身体!”“我来组成腿~~!”“…”)。
不同的是它们的训练过程。
Bagging,又叫Bootsrap Aggregating,将样本集随机采样形成若干个子样本集,其中一些样本可能出现多次,而另一些则可能一次都不出现。Bagging针对每一个子样本集训练一个弱模型,再把它们联合起来形成强模型,联合的方法通常对于回归问题是Average,对于分类问题则是Voting。典型的算法,比如Random Forests。
Boosting,可能稍微有名一点,则是在迭代训练过程中,逐渐改变各个样本的权重,来生产新的弱模型,并加入强模型。在训练过程中,被成功识别或离回归函数近的样本权重不断下降,而错误识别或离回归函数远的样本则权重不断增加,这类似于高考前做模拟题时老师总是叮嘱好好看做错的题目,一样的道理。典型的算法,比如有名的AdaBoost。
(SVM我跳过,不感兴趣,简单地说是个将已经很复杂的样本空间折腾到一乱七八糟的超空间然后画一超平面的算法)

再后来的事,就是现在的事了,统计学习统治世界什么的。不过,我一向认为统计学习并不是机器学习——尤其是人工智能——的终点,因为人类似乎并不是这么思考的。

July 4, 2011

GOOD LUCK MY WAY

钢炼今年剧场版的主题歌

Hyde老了。曲子和词还是欢乐的,可是高音不亮了。今天我还写检讨了。最近这什么日子啊 Crying face Crying face Crying face

当年钢炼05的OP,放在同一张单曲里,差别感好强烈。

Ready Steady Go

好怀念青春年少!Crying face Crying face Crying face LARUKU、吉普力、小BONEZ,你们都怎么了?!

July 1, 2011

吐槽Android和宫崎大神

忙了一阵,写了个Android上的媒体程序杂烩,图片浏览、视频播放什么的,用作手势识别的控制Demo。Android或者说Java这个东西,果然是写C++的人三天就能上手的。不过,我还是很不喜欢Java不让主动释放对象这一设计,前段时间写Cuda让我对内存什么的变得相当敏感,定义个状态能bool一定不char,存个值能short一定不int。说到底,还是不信Java能管理任意程序的内存都管理得比开发者或者和开发者一样好。对于没有指针这件事情,也另人纠结,我喜欢星号啊。另外,吐槽一下Java里的boolean,为啥不用bool呢,明明是基于C++,为啥不延续,而偏偏让人多敲3个字符。。不满啊。不过,我很喜欢Java的接口设计。

至于Android,槽点太多,我都懒得吐了。充满差错的注释,混乱的函数命名,死板的工程结构,以及比摩托罗拉还慢的速度,我每天晚上吃饭前都要骂它几句,这货到底是不是Google生的啊。除了开源,除了便宜,除了能方便地用Google的服务,我想不到它有什么好处。如果让我挑平台,一定果断地投靠iOS,人家有一级流畅的UI,酷的基础气质,更重要的是有消费习惯良好的用户群体啊。以前我还抱怨过QT的UI,现在用过Android我就知道自己错了,QT相对Android在UI方面绝对是神级的存在。
有天吃饭时,边上一mm用一HTC手机切水果,黄香蕉出来的时候那叫一个卡啊,一帧一帧的,我这厢拿一iPhone眼看着水果一个个噌噌噌往下掉,羡慕嫉妒恨啊,原来在Android的机器上有没冰香蕉是一样的效果啊。

上个礼拜出了「借东西的小人」的DVD,所以国内的我终于可以看到宫崎大神的新片了。可惜小小失望了一把,除却音乐没发现什么眼前一亮的东西,故事本身只比「波妞」复杂了那么一点点。对“借”这一行为的阐述有些浅薄,为什么叫“借”不叫“偷”呢,借了是要还的,那小人的存在对人类而言“还”了什么呢。如果说回归自然才是小人族逃避灭族的出路的话,那相应地,是不是应该交代下小人族的历史?小人族和会说话的小老鼠的区别是什么呢,只是人形生物和野兽的区别么?另外,我一直很好奇,不想被人类发现的小人为啥会把窝建在一个这么好找到and好打开and便于被抓的地方。我一直期待的小人和小动物正面冲突也没有发生,小人和人类的正面冲突也没有发生。也许是2个小时总归短了点,使得这片世界观的塑造只到了床头故事的层次,就像某些寓言故事里某些动机不明的事件,只是存在着,没有前因后果。真的怀念「幽灵公主」和「风之谷」的厚重感。

May 12, 2011

[论文笔记] Real-Time Human Pose Recognition in Parts from Single Depth Images

Paper:J. Shotton, A. Fitzgibbon, M. Cook, T. Sharp, M. Finocchio, R. Moore, A. Kipman, and A. Blake. Real-Time Human Pose Recognition in Parts from a Single Depth Image. In CVPR 2011. http://research.microsoft.com/apps/pubs/default.aspx?id=145347


问题描述:文章提出了一种从单张深度图中提取3D骨架节点的方法。这种方法并不使用动作的时序信息,但是快速有效,识别帧率在200fps左右(GPU加速后),精度不逊于现有算法。这也是Kinect动作识别的核心算法。
文章最主要的贡献在于:将Pose estimation作为Object recognition看待,提出了一种新颖的识别方法——将Body part segmentation问题作为基于像素的分类问题来处理,这样就不需要对不同节点组合进行搜索,但同时单一部位很可能在局部剧烈地变化。算法的计算复杂度低,精度高。文章的实验部分还论证了以下观点:1)作为训练用的深度数据,合成数据可以很好地代替真实数据;2)获得高精度的重要一步是扩大并丰富训练数据;3)文章中提出的基于部位的识别方法比模糊的精确最近相邻节点更具有通用性。
2011-5-12 20-04-00

数据:
数据来源是几乎所有机器学习相关算法的头痛问题。对于动作识别,首先,出于对人物的着装、发型、材质等因素的多样性考虑,使用图形技术合成的训练图片在色彩和材质等方面均有很大的变数,使用深度图片虽然能避免一部分变数,但由着装和发型等带来的形状差异却无法规避;其次,驱动人物的动作数据本身均不可避免地来自Motion capture,这使得获取大量动作的工作量变得很大,虽然有一些技术致力于模拟人物动作,但至今尚不能解决人物主动运动的问题。
文章的真实深度图片来自于Kinect深度相机,由Primesense提供技术支持,是一种基于不可见近红外光的结构光深度恢复技术。这种深度摄像头可以在低光强度的环境下工作,提供一种标定尺度的深度估计,对色彩和纹理不敏感,可以天然地应对轮廓中的遮挡,最重要的是使得前背景分离问题变得简单,并且合成深度训练图也是相对直接简单的。文章的训练深度图片使用Mocap数据绑定多种不同的模型渲染生成。为了保证数据的多样性,在从大规模采集的数据中随机时,定义姿势之间的最小距离;对应人体部位识别的方法,训练数据的纹理也根据既定的分块着色,如下图所示。最终生成约100k frame训练数据。
2011-5-12 18-52-24

部位标识 / 部位识别 / 骨架生成:
部位标识的精度是可以根据需求自由定义的。文章中使用31个部分的部位标识:头4部分、脖子、2个肩膀等。
部位识别基于像素,即对每一个像素识别其所属部位。特征选择和识别算法引用了Lepetit等05年的工作(点我):特征选用简单的深度比较特征,识别算法使用多类随机决策树,树节点test为特征值是否大于某一阈值。训练过程微软采用了10million张图片,每张均匀随机2000个样本像素,训练了3棵20-depth的树,训练过程采用分布式实现,在1000核cluster上运行了约一天。(这个time consumption +_+)
骨架生成是基于像素部位分类和像素深度的聚类,使用加权高斯核的Mean-shift算法。这样得到的骨架节点在人体表面,之后需要有一个z值的向后偏移,才能得到正确的3D骨架节点。这个偏移值可以通过各个部位的分别学习获得。

效果:
简单的说,算法效率实时,效果不错。至少这是做了这么多年,第一次实时又有效的几乎万能动作识别算法。
像素级部位标识的精度在50-60%之间,整体骨架的精度大多部位在90%以上,wrist和hand的识别率较低,在80%以上。算法表现出样本越多,精度越高的现象(废话),且在大样本前提下over-fit的现象也能被避免。


这个文章的工作在本年会完全follow一次,末了再写个详细的算法评价。