天天看點

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

magicly:之前翻譯了一篇介紹rnn的文章,一直沒看到作者寫新的介紹lstm的blog,于是我又找了其他資料學習。本文先介紹一下lstm,然後用lstm在金庸、古龍的人名上做了訓練,可以生成新的武俠名字,如果有興趣的,還可以多搜集點人名,用于給小孩兒取名呢,哈哈,justforfun,大家玩得開心…

rnn的出現是為了解決狀态記憶的問題,解決方法很簡單,每一個時間點t的隐藏狀态h(t)不再簡單地依賴于資料,還依賴于前一個時間節點t-1的隐藏狀态h(t-1)。可以看出這是一種遞歸定義(是以循環神經網絡又叫遞歸神經網絡recursive neural network),h(t-1)又依賴于h(t-2),h(t-2)依賴于h(t-3)…是以h(t)依賴于之前每一個時間點的輸入,也就是說h(t)記住了之前所有的輸入。

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

上圖如果按時間展開,就可以看出rnn其實也就是普通神經網絡在時間上的堆疊。

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

一切似乎很完美,但是如果h(t)依賴于h(t - 1000),依賴路徑特别長,會導緻計算梯度的時候出現梯度消失的問題,訓練時間很長根本沒法實際使用。下面是一個依賴路徑很長的例子:

1 我老家【成都】的。。。【此處省去500字】。。。我們那裡經常吃【火鍋】。。。

long short term memory神經網絡,也就是lstm,由 hochreiter & schmidhuber于1997年發表。它的出現就是為了解決long-term dependencies的問題,很來出現了很多改進版本,目前應用在相當多的領域(包括機器翻譯、對話機器人、語音識别、image caption等)。

标準的rnn裡,重複的子產品裡隻是一個很簡單的結構,如下圖:

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

lstm也是類似的連結清單結構,不過它的内部構造要複雜得多:

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

上圖中的圖示含義如下:

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

lstm的核心思想是cell state(類似于hidden state,有lstm變種把cell state和hidden state合并了, 比如gru)和三種門:輸入門、忘記門、輸出門。

cell state每次作為輸入傳遞到下一個時間點,經過一些線性變化後繼續傳往再下一個時間點(我還沒看過原始論文,不知道為啥有了hidden state後還要cell state,好在确實有改良版将兩者合并了,是以暫時不去深究了)。

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

門的概念來自于電路設計(我沒學過,就不敢賣弄了)。lstm裡,門控制通過門之後資訊能留下多少。如下圖,sigmoid層輸出[0, 1]的值,決定多少資料可以穿過門, 0表示誰都過不了,1表示全部通過。

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

下面我們來看看每個“門”到底在幹什麼。

首先我們要決定之前的cell state需要保留多少。 它根據h(t-1)和x(t)計算出一個[0, 1]的數,決定cell state保留多少,0表示全部丢棄,1表示全部保留。為什麼要丢棄呢,不是保留得越多越好麼?假設lstm在生成文章,裡面有小明和小紅,小明在看電視,小紅在廚房做飯。如果目前的主語是小明, ok,那lstm應該輸出看電視相關的,比如找遙控器啊, 換台啊,如果主語已經切換到小紅了, 那麼接下來最好暫時把電視機忘掉,而輸出洗菜、醬油、電鍋等。

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

第二步就是決定輸入多大程度上影響cell state。這個地方由兩部分構成, 一個用sigmoid函數計算出有多少資料留下,一個用tanh函數計算出一個候選c(t)。 這個地方就好比是主語從小明切換到小紅了, 電視機就應該切換到廚房。

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

然後我們把留下來的(t-1時刻的)cell state和新增加的合并起來,就得到了t時刻的cell state。

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

最後我們把cell state經過tanh壓縮到[-1, 1],然後輸送給輸出門([0, 1]決定輸出多少東西)。

用金庸、古龍群俠名稱訓練 LSTM,會生成多麼奇葩的名字?

現在也出了很多lstm的變種, 有興趣的可以看這裡。另外,lstm隻是為了解決rnn的long-term dependencies,也有人從另外的角度來解決的,比如clockwork rnns by koutnik, et al. (2014).

我用的andrej karpathy大神的代碼, 做了些小改動。這個代碼的好處是不依賴于任何深度學習架構,隻需要有numpy就可以馬上run起來!

然後從網上找了金庸小說的人名,做了些預處理,每行一個名字,儲存到input.txt裡,運作代碼就可以了。古龍的沒有找到比較全的名字, 隻有這份武功排行榜,隻有100多人。

下面是根據兩份名單訓練的結果,已經将完全一緻的名字(比如段譽)去除了,是以下面的都是lstm“新創作發明”的名字哈。來, 大家猜猜哪一個結果是金庸的, 哪一個是古龍的呢?

   {'姜曾鐵', '袁南蘭', '石萬奉', '郭萬嗔', '蔡家', '程伯芷', '汪鐵志', '陳衣', '薛鐵','哈赤蔡師', '殷飛虹', '鐘小硯', '鳳一刀', '寶蘭', '齊飛虹', '無若之', '王老英', '鐘','鐘百勝', '師', '李沅震', '曹蘭', '趙一刀', '鐘靈四', '宗家妹', '崔樹勝', '桑飛西','上官公希轟', '劉之餘人童懷道', '周雲鶴', '天', '鳳', '西靈素', '大智虎師', '阮徒忠','王兆能', '袁铮衣商寶鶴', '常伯鳳', '苗人大', '倪不鳳', '蔡鐵', '無伯志', '鳳一弼','曹鵲', '黃賓', '曾鐵文', '姬胡峰', '李何豹', '上官鐵', '童靈同', '古若之', '慕官景嶽','崔百真', '陳官', '陳鐘', '倪調峰', '妹沅刀', '徐雙英', '任通督', '上官鐵褚容', '大劍太','胡陽', '生', '南仁鄭', '南調', '石雙震', '海鐵山', '殷鶴真', '司魚督', '德小','若四', '武通濤', '田青農', '常塵英', '常不志', '倪不濤', '歐陽', '大提督', '胡玉堂','陳寶鶴', '南仁通四蔣赫侯'}
   {'邀三', '熊貓開', '鷹星', '陸開', '花', '薛玉羅平', '南宮主', '南宮九', '孫夫人','荊董滅', '鐵不愁', '裴獨', '玮劍', '人', '陸小龍王紫無牙', '連千裡', '仲先生','俞白', '方大', '葉雷一魂', '獨孤上紅', '葉憐花', '雷大歸', '恕飛', '白雙發','邀一郎', '東樓', '鐵中十一點紅', '鳳星真', '無魏柳老鳳三', '蕭貓兒', '東郭先鳳','日孫', '地先生', '孟摘星', '江小小鳳', '花雙樓', '李佩', '仇珏', '白壞刹', '燕悲情','姬悲雁', '東郭大', '謝曉陸鳳', '碧玉伯', '司實三', '陸浪', '趙布雁', '荊孤藍','憐燕南天', '蕭憐靜', '龍布雁', '東郭魚', '司東郭金天', '薛嘯天', '熊寶玉', '無莫靜','柳羅李', '東官小魚', '漸飛', '陸地魚', '阿吹王', '高傲', '蕭十三', '龍童', '玉羅趙','謝郎唐傲', '鐵夜帝', '江小鳳', '孫玉玉夜', '仇仲忍', '蕭地孫', '鐵莫棠', '柴星夫','展夫人', '碧玉', '老無魚', '鐵鐵花', '獨', '薛月宮九', '老郭和尚', '東郭大路陸上龍關飛','司藏', '李千', '孫白人', '南雙平', '王玮', '姬原情', '東郭大路孫玉', '白玉羅生', '高兒','東珏天', '蕭王尚', '九', '鳳三靜', '和空摘星', '關吹雪', '上官官小鳳', '仇上官金飛','陸上龍嘯天', '司空星魂', '邀衣人', '主', '李尋歡天', '東情', '玉夫随', '趙小鳳', '東郭滅', '邀祟厚', '司空星'}

感興趣的還可以用古代詩人、詞人等的名字來做訓練,大家機器好或者有時間的可以多訓練下,訓練得越多越準确。

rnn由于具有記憶功能,在nlp、speech、computer vision等諸多領域都展示了強大的力量。實際上,rnn是圖靈等價的。

1 if training vanilla neural nets is optimization over functions, training recurrent nets is optimization over programs.

lstm是一種目前相當常用和實用的rnn算法,主要解決了rnn的long-term dependencies問題。另外rnn也一直在産生新的研究,比如attention機制。有空再介紹咯。。。

本文作者:三川

繼續閱讀