學習筆記 2/12 – 2/16

前言

距離上次寫blog已經有3年了,這中間因為小孩出生所以變得比以前忙碌太多,工作和陪小孩之外,幾乎沒剩下多少時間能安靜讀東西和寫東西。工作上其實是有很多東西要讀要寫,但大部分都不是因為「有趣」而做的,加上我也不能對外分享,所以久了就覺得很悶。
這段時間我一直有很多零碎的想法,覺得好像值得分享,但要寫成完整的文章又太花時間。我很清楚把想法寫下來並分享出來是學習過程中很關鍵的一步,因為以前我有很多零碎的知識和想法都是在寫作的時候連結起來的。
所以呢,我決定要來實驗一個新的分享方法。每天我會把當天我看到、聽到、學到、想到的一些東西寫在我的Facebook粉絲團上。不一定會有什麼固定的主題,只是「我覺得有趣」的文章或想法。每件事可能都只有一兩句話,而且不一定有上下文,所以對讀者來說可能會有點難讀。我做這件事的目的不是要練習寫文章,而是比較單純的想要紀錄每天學到的東西,所以讀者很可能會覺得一頭霧水。
另外我做這件事的重點是保持每天持續做一點點,讓我有完整的學習、分享、反思回饋的loop。所以我也不想要設定太高的目標,不然要達到就很難了。每個禮拜結束時,我會把當週寫的東西集結起來貼到我的blog上,這樣比較方便未來可以再搜尋。

2018/2/13

MySQL MyRocks storage engine

Facebook開發的MySQL storage engine, 可以取代innodb, 今天看到一個實測結果,儲存空間比innodb小了好幾倍,寫入速度也快好幾倍,非常驚人。

gym_puyopuyo

這禮拜是我們公司的EPD hack week,整個EPD (Engineering, Product, Design)有一個禮拜的時間可以做自己想做的任何project。我本來想做一個reinforcement learning agent來玩快打旋風,但發現似乎得花不少時間把MIME (Arcade模擬器)先接上OpenAI Gym或OpenAI Universe,所以就轉向找個已經有人寫好interface的遊戲。結果意外發現有人做了gym_puyopuyo,一個模擬Puyo Puyo遊戲(魔法氣泡,我小時候喜歡玩的遊戲之一)的環境給OpenAI Gym用,於是我今天就都在玩這個了。

這個Gym Env做的挺完整的,有單人模式也有對戰模式,還附了一個用tree search的簡單agent可以拿來練功,有興趣的人可以也玩玩看。

快打旋風2的”AI”

這是我在查快打旋風的模擬環境時找到的一個有趣文章。有人把快打旋風2的”AI”逆向工程出來,不意外只是一堆rule,但問題是這個AI還用了很多玩家看不到的”metadata”來決定要怎麼對付玩家的攻擊,完全就是在作弊XD

When reacting to an attack the scripts are chosen based on something called a yoke. Each frame of animation for both avatars and projectiles contains a value for the yoke in the metadata, which the AI peeks at to select a script suitable for responding to that attack. The computer sees the yoke of your move as soon as you have input it, before the first animation frame has even displayed. As such it gets one more frame of advantage on top of your reaction time.A question addressed in an earlier post in this blog was whether the AI cheats”, and it certainly does. Charge moves such as blade kicks are simply executed as instructions, so they cannot fail. Guile can do a bladekick from a standing position simply because that’s what’s in the script. It’s probably possible for the AI to command special moves in the air. 

2018/2/14

The Quest for Availability

今天看到的好文章 The Quest for Availability” https://hackernoon.com/the-quest-for-availability-771fa8a94a7c 關心大型系統availability的人可以follow這系列。這篇裡面提到一些基本概念:

  • 單一系統壞掉的機率大多是一開始很高(bug或是設定錯誤),修好後會有一段時間穩定期,直到硬體或其他外部因素的損耗出現又開始升高。整個圖形是個浴缸的形狀。
  • 系統一大組件變多後,更新速度頻繁,有任一組件壞掉造成整個系統壞掉的機率就會很高。整體要達到four nines (99.99%)就不能等有東西壞掉再用人工去處理,隨時都要有並聯的redundancy並且能夠自動failover。
  • 另外提一個個人心得: 大型系統中要盡量避免stateful的server,因為它們不能簡單地failover。如果server fail的時候,記憶體中還有沒寫入到server外部的資料,就可能會永久失去那些資料。相對的,stateless的server只要平常多開幾台,有一台壞掉時其他台也能自動接手。
  • exponential backoff和async task非常好用,雖然簡單但很常用。現在看來已經是分散式系統的基本招了。

Deep Q-Network (DQN)

今天從簡單的DQN開始學,希望最後能搞出puyo puyo的agent。OpenAI Gym是不錯的練習環境,我從CartPole (https://gym.openai.com/envs/CartPole-v0/) 和這篇文章的解說 https://keon.io/deep-q-learning/ 開始入手。

Q Learning的核心是一個非常漂亮的遞迴函數 Q(s, a) = reward + discount * max Q(s’, a’)。Q(s, a) 是個估算在某個狀態s下、做動作a會得到的「未來總收益」的函數。通常在一個AI agent裡,我們會一直選未來收益最大的動作,讓整體收益最高。如果Q值可以算得很精準,就可以輕易知道做什麼動作可以把未來收益最大化,但問題是在真實世界中 Q(s,a) 常常可以無限遞迴展開,所以沒辦法輕易的求解 (search space太大)。

DQN的巧妙之處在於用DNN搭配experience replay的技巧來訓練出可以逼近真實Q函數的target network,這樣就不用真的去展開Q了。上面的那篇文章裡有很好的解釋,也有用Keras實作的程式可以看。(劇透:上面文章裡的code其實有個小bug,詳情明天再說。)

2018/2/15

Cartpole的心得

https://keon.io/deep-q-learning/ 是個不錯的入門文章,但如果真的照他的方法做,就會發現最後沒辦法收斂到連續一百回平均195分以上(這是OpenAI對這個問題「已解」的定義)。最高大約能到平均178分,然後就掉下來到130~170左右無限震盪。雖然看起來好像有學到一點比random好的東西,但顯然最後卡在一個local minimum。

這個code一定有哪裡錯了,但要怎麼debug呢?

一開始我試了調整了一下NN的結構,調每一層的大小、多加一層看看、把RELU換成Tanh,但都沒什麼用。亂試的結果不好,只好回頭深入看看DQN的algorithm,看看這個code弄錯了什麼。

後來找到這篇文章 https://danieltakeshi.github.io/2016/12/01/going-deeper-into-reinforcement-learning-understanding-dqn/ 裡面提到了DeepMind當初設計DQN時的第二個trick:

Trick 2 Target Network: Use a separate network to estimate the TD target. This target network has the same architecture as the function approximator but with frozen parameters. Every T steps (a hyperparameter) the parameters from the Q network are copied to the target network. This leads to more stable training because it keeps the target function fixed (for a while).

這讓我注意到這code沒做這件事,它是用同一個network,而且在replay minibatch中的每一步都在重新調整model,結果model就無法穩定下來。為了驗證這件事,我把原本的self.model.fit那行移出minibatch的loop外,然後把整個minibatch一次算好再拿去fit。這樣果然就解決了這問題,而且replay的速度也快多了,最後大概在1900 episodes可以穩定的到平均195分以上。

後來我就完全照DeepMind的方法做,拆成兩個network,固定一段時間再update一次target network,效果又更好了。最後大概每5個episode update一次network,可以在1300 episodes左右就訓練好。

這告訴我們,網路上看到的二手文章和code要小心使用,雖然用來入門快,但可能會不小心學到錯的東西XD

 

2018/2/16

Dropbox Hack Week

昨天有人問了「教介紹企業內HackWeek怎麼辦? 大家怎麼組隊? 如何企業員工雙贏?」我就來說一下Dropbox的hack week是怎麼回事吧。

Dropbox一年有兩次hack week,間隔半年。一次是只有EPD (Engineering, Product, Design)參加,另一次是全公司任何部門都可以參加。Hack week開始前兩個禮拜,大家就會在一個內部系統上提一些題目,不一定自己要做,可以只是一個想法。大家可以在上面對題目投票或是留言討論,如果看到有興趣也可以直接sign up加入那個題目的小組。每個人可以同時加入很多個小組,完全不加入自己做也可以,沒有什麼硬性的規定。通常每一次hack week都有上百個題目,一組從一個人到十幾個人都有,甚至可以邀公司外的人一起參加!

我觀察了三年下來,很多題目大多是對現有產品或是內部系統的改進。例如說有人覺得我們餐廳的菜單都要走去餐廳才看得到,於是就做了一個線上版的,有照片有解說,還附送slackbot會把菜單廣播到Slack上。或是有人覺得某個產品有些地方一直沒做好,但priority又不高一直沒人去好好做,就會用hack week找幾個人整個重做一番。也有些project只是純粹好玩,例如今年有人辦了Starcraft 2大賽,以前還有DDR大賽,去年還有人做了一個比電視還要大的任天堂把手,要同時三個人操作才能拿來玩遊戲 XD

有部分project會是一些可以變成正式產品的東西,如果在hack week完的demo讓大家覺得這東西值得花更多時間下去做,公司就會正式組一個團隊,把它們變成公司的產品或是系統的一部分。還有些project是做的人自己平時的興趣,或是一直用業餘時間做的事。像是mypy (Python的static type system),一開始也是個hack week project,但因為難度太高,一開始做的時候都是在摸索和學習,連續做了三次的hack week才真的開始進入勉強可用的階段。可是一但它的價值被證明後,公司就會把它排進roadmap裡,讓員工用平日的工作時間繼續做下去。

至於如何企業員工雙贏?

第一我覺得是一開始招的員工就得有平時就會想用業餘時間hack東西的熱情和習慣,所以公司開放這種時間其實是一個適當的解放。第二是公司得要充分給員工自由,不限制題目,並且相信員工在這段時間內做的事情最終會產生對公司有利的價值。雖然這種一個禮拜做的project通常都只是proof of concept,但bottom-up的idea才能讓公司高層跳脫原本的盲點,或是理解到一些看起來好像很難的事情其實沒有真的那麽難。

Dropbox已經連續辦hack week 8年了,從35人的小團隊到現在有兩千人了還是繼續辦,就說明這件事一直都對公司有很正面的影響。就我看了3年的hack week,每次都有一些很驚豔的東西,不但可以開拓大家的眼界和想像,也會讓員工對公司的未來更有信心。

最後附上一些公開的文章讓大家參考。

Leave a Reply

Your email address will not be published. Required fields are marked *

*