丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號安全和更好的產(chǎn)品體驗,強烈建議使用更快更安全的瀏覽器
此為臨時鏈接,僅用于文章預覽,將在時失效
人工智能開發(fā)者 正文
發(fā)私信給三川
發(fā)送

0

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

本文作者: 三川 2017-04-24 17:03
導語:用LSTM生成武俠人名。

雷鋒網(wǎng)按:本文轉(zhuǎn)載自 Magicly 博客,獲作者授權(quán)。閱讀原文請見:http://magicly.me/2017/04/07/rnn-lstm-generate-name/?utm_source=tuicool&utm_medium=referral。

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

RNN回顧

RNN的出現(xiàn)是為了解決狀態(tài)記憶的問題,解決方法很簡單,每一個時間點t的隱藏狀態(tài)h(t)不再簡單地依賴于數(shù)據(jù),還依賴于前一個時間節(jié)點t-1的隱藏狀態(tài)h(t-1)??梢钥闯鲞@是一種遞歸定義(所以循環(huán)神經(jīng)網(wǎng)絡又叫遞歸神經(jīng)網(wǎng)絡Recursive Neural Network),h(t-1)又依賴于h(t-2),h(t-2)依賴于h(t-3)…所以h(t)依賴于之前每一個時間點的輸入,也就是說h(t)記住了之前所有的輸入。

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

上圖如果按時間展開,就可以看出RNN其實也就是普通神經(jīng)網(wǎng)絡在時間上的堆疊。

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

RNN問題:Long-Term Dependencies

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

1 我老家【成都】的。。。【此處省去500字】。。。我們那里經(jīng)常吃【火鍋】。。。

LSTM

Long Short Term Memory神經(jīng)網(wǎng)絡,也就是LSTM,由 Hochreiter & Schmidhuber于1997年發(fā)表。它的出現(xiàn)就是為了解決Long-Term Dependencies的問題,很來出現(xiàn)了很多改進版本,目前應用在相當多的領(lǐng)域(包括機器翻譯、對話機器人、語音識別、Image Caption等)。

標準的RNN里,重復的模塊里只是一個很簡單的結(jié)構(gòu),如下圖:

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

LSTM也是類似的鏈表結(jié)構(gòu),不過它的內(nèi)部構(gòu)造要復雜得多:

用金庸、古龍群俠名稱訓練 LSTM,會生成多么奇葩的名字?
上圖中的圖標含義如下:

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

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

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

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

門的概念來自于電路設計(我沒學過,就不敢賣弄了)。LSTM里,門控制通過門之后信息能留下多少。如下圖,sigmoid層輸出[0, 1]的值,決定多少數(shù)據(jù)可以穿過門, 0表示誰都過不了,1表示全部通過。

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

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

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

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

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

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

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

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

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

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

現(xiàn)在也出了很多LSTM的變種, 有興趣的可以看這里。另外,LSTM只是為了解決RNN的long-term dependencies,也有人從另外的角度來解決的,比如Clockwork RNNs by Koutnik, et al. (2014).

show me the code!

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

  1. """    

  2. Minimal character-level Vanilla RNN model. Written by Andrej Karpathy (@karpathy)    

  3. BSD License    

  4. """    

  5. import numpy as np    


  6. # data I/O    

  7. data = open('input.txt', 'r').read()  # should be simple plain text file    

  8. all_names = set(data.split("\n"))    

  9. chars = list(set(data))    

  10. data_size, vocab_size = len(data), len(chars)    

  11. print('data has %d characters, %d unique.' % (data_size, vocab_size))    

  12. char_to_ix = {ch: i for i, ch in enumerate(chars)}    

  13. ix_to_char = {i: ch for i, ch in enumerate(chars)}    

  14. # print(char_to_ix, ix_to_char)    


  15. # hyperparameters    

  16. hidden_size = 100  # size of hidden layer of neurons    

  17. seq_length = 25  # number of steps to unroll the RNN for    

  18. learning_rate = 1e-1    


  19. # model parameters    

  20. Wxh = np.random.randn(hidden_size, vocab_size) * 0.01  # input to hidden    

  21. Whh = np.random.randn(hidden_size, hidden_size) * 0.01  # hidden to hidden    

  22. Why = np.random.randn(vocab_size, hidden_size) * 0.01  # hidden to output    

  23. bh = np.zeros((hidden_size, 1))  # hidden bias    

  24. by = np.zeros((vocab_size, 1))  # output bias    



  25. def lossFun(inputs, targets, hprev):    

  26. """    

  27.    inputs,targets are both list of integers.    

  28.    hprev is Hx1 array of initial hidden state    

  29.    returns the loss, gradients on model parameters, and last hidden state    

  30.    """    

  31. xs, hs, ys, ps = {}, {}, {}, {}    

  32. hs[-1] = np.copy(hprev)    

  33. loss = 0    

  34. # forward pass    

  35. for t in range(len(inputs)):    

  36. xs[t] = np.zeros((vocab_size, 1))  # encode in 1-of-k representation    

  37. xs[t][inputs[t]] = 1    

  38. hs[t] = np.tanh(np.dot(Wxh, xs[t]) + np.dot(Whh,    

  39. hs[t - 1]) + bh)  # hidden state    

  40. # unnormalized log probabilities for next chars    

  41. ys[t] = np.dot(Why, hs[t]) + by    

  42. # probabilities for next chars    

  43. ps[t] = np.exp(ys[t]) / np.sum(np.exp(ys[t]))    

  44. loss += -np.log(ps[t][targets[t], 0])  # softmax (cross-entropy loss)    

  45. # backward pass: compute gradients going backwards    

  46. dWxh, dWhh, dWhy = np.zeros_like(    

  47. Wxh), np.zeros_like(Whh), np.zeros_like(Why)    

  48. dbh, dby = np.zeros_like(bh), np.zeros_like(by)    

  49. dhnext = np.zeros_like(hs[0])    

  50. for t in reversed(range(len(inputs))):    

  51. dy = np.copy(ps[t])    

  52. # backprop into y. see    

  53. # http://cs231n.github.io/neural-networks-case-study/#grad if confused    

  54. # here    

  55. dy[targets[t]] -= 1    

  56. dWhy += np.dot(dy, hs[t].T)    

  57. dby += dy    

  58. dh = np.dot(Why.T, dy) + dhnext  # backprop into h    

  59. dhraw = (1 - hs[t] * hs[t]) * dh  # backprop through tanh nonlinearity    

  60. dbh += dhraw    

  61. dWxh += np.dot(dhraw, xs[t].T)    

  62. dWhh += np.dot(dhraw, hs[t - 1].T)    

  63. dhnext = np.dot(Whh.T, dhraw)    

  64. for dparam in [dWxh, dWhh, dWhy, dbh, dby]:    

  65. # clip to mitigate exploding gradients    

  66. np.clip(dparam, -5, 5, out=dparam)    

  67. return loss, dWxh, dWhh, dWhy, dbh, dby, hs[len(inputs) - 1]    



  68. def sample(h, seed_ix, n):    

  69. """     

  70.    sample a sequence of integers from the model     

  71.    h is memory state, seed_ix is seed letter for first time step    

  72.    """    

  73. x = np.zeros((vocab_size, 1))    

  74. x[seed_ix] = 1    

  75. ixes = []    

  76. for t in range(n):    

  77. h = np.tanh(np.dot(Wxh, x) + np.dot(Whh, h) + bh)    

  78. y = np.dot(Why, h) + by    

  79. p = np.exp(y) / np.sum(np.exp(y))    

  80. ix = np.random.choice(range(vocab_size), p=p.ravel())    

  81. x = np.zeros((vocab_size, 1))    

  82. x[ix] = 1    

  83. ixes.append(ix)    

  84. return ixes    


  85. n, p = 0, 0    

  86. mWxh, mWhh, mWhy = np.zeros_like(Wxh), np.zeros_like(Whh), np.zeros_like(Why)    

  87. mbh, mby = np.zeros_like(bh), np.zeros_like(by)  # memory variables for Adagrad    

  88. smooth_loss = -np.log(1.0 / vocab_size) * seq_length  # loss at iteration 0    


  89. while True:    

  90. # prepare inputs (we're sweeping from left to right in steps seq_length    

  91. # long)    

  92. if p + seq_length + 1 >= len(data) or n == 0:    

  93. hprev = np.zeros((hidden_size, 1))  # reset RNN memory    

  94. p = 0  # go from start of data    

  95. inputs = [char_to_ix[ch] for ch in data[p:p + seq_length]]    

  96. targets = [char_to_ix[ch] for ch in data[p + 1:p + seq_length + 1]]    


  97. # sample from the model now and then    

  98. if n % 100 == 0:    

  99. sample_ix = sample(hprev, inputs[0], 200)    

  100. txt = ''.join(ix_to_char[ix] for ix in sample_ix)    

  101. print('----\n %s \n----' % (txt, ))    


  102. # forward seq_length characters through the net and fetch gradient    

  103. loss, dWxh, dWhh, dWhy, dbh, dby, hprev = lossFun(inputs, targets, hprev)    

  104. smooth_loss = smooth_loss * 0.999 + loss * 0.001    

  105. if n % 100 == 0:    

  106. print('iter %d, loss: %f' % (n, smooth_loss))  # print progress    


  107. # perform parameter update with Adagrad    

  108. for param, dparam, mem in zip([Wxh, Whh, Why, bh, by],    

  109. [dWxh, dWhh, dWhy, dbh, dby],    

  110. [mWxh, mWhh, mWhy, mbh, mby]):    

  111. mem += dparam * dparam    

  112. param += -learning_rate * dparam / \    

  113. np.sqrt(mem + 1e-8)  # adagrad update    


  114. p += seq_length  # move data pointer    

  115. n += 1  # iteration counter    

  116. if ((smooth_loss < 10) or (n >= 20000)):    

  117. sample_ix = sample(hprev, inputs[0], 2000)    

  118. txt = ''.join(ix_to_char[ix] for ix in sample_ix)    

  119. predicted_names = set(txt.split("\n"))    

  120. new_names = predicted_names - all_names    

  121. print(new_names)    

  122. print('predicted names len: %d, new_names len: %d.\n' % (len(predicted_names), len(new_names)))    

  123. break    

view rawmin-char-rnn.py hosted with ? by GitHub

然后從網(wǎng)上找了金庸小說的人名,做了些預處理,每行一個名字,保存到input.txt里,運行代碼就可以了。古龍的沒有找到比較全的名字, 只有這份武功排行榜,只有100多人。

下面是根據(jù)兩份名單訓練的結(jié)果,已經(jīng)將完全一致的名字(比如段譽)去除了,所以下面的都是LSTM“新創(chuàng)作發(fā)明”的名字哈。來, 大家猜猜哪一個結(jié)果是金庸的, 哪一個是古龍的呢?


   {'姜曾鐵', '袁南蘭', '石萬奉', '郭萬嗔', '蔡家', '程伯芷', '汪鐵志', '陳衣', '薛鐵','哈赤蔡師', '殷飛虹', '鐘小硯', '鳳一刀', '寶蘭', '齊飛虹', '無若之', '王老英', '鐘','鐘百勝', '師', '李沅震', '曹蘭', '趙一刀', '鐘靈四', '宗家妹', '崔樹勝', '桑飛西','上官公希轟', '劉之余人童懷道', '周云鶴', '天', '鳳', '西靈素', '大智虎師', '阮徒忠','王兆能', '袁錚衣商寶鶴', '常伯鳳', '苗人大', '倪不鳳', '蔡鐵', '無伯志', '鳳一弼','曹鵲', '黃賓', '曾鐵文', '姬胡峰', '李何豹', '上官鐵', '童靈同', '古若之', '慕官景岳','崔百真', '陳官', '陳鐘', '倪調(diào)峰', '妹沅刀', '徐雙英', '任通督', '上官鐵褚容', '大劍太','胡陽', '生', '南仁鄭', '南調(diào)', '石雙震', '海鐵山', '殷鶴真', '司魚督', '德小','若四', '武通濤', '田青農(nóng)', '常塵英', '常不志', '倪不濤', '歐陽', '大提督', '胡玉堂','陳寶鶴', '南仁通四蔣赫侯'}
    

   {'邀三', '熊貓開', '鷹星', '陸開', '花', '薛玉羅平', '南宮主', '南宮九', '孫夫人','荊董滅', '鐵不愁', '裴獨', '瑋劍', '人', '陸小龍王紫無牙', '連千里', '仲先生','俞白', '方大', '葉雷一魂', '獨孤上紅', '葉憐花', '雷大歸', '恕飛', '白雙發(fā)','邀一郎', '東樓', '鐵中十一點紅', '鳳星真', '無魏柳老鳳三', '蕭貓兒', '東郭先鳳','日孫', '地先生', '孟摘星', '江小小鳳', '花雙樓', '李佩', '仇玨', '白壞剎', '燕悲情','姬悲雁', '東郭大', '謝曉陸鳳', '碧玉伯', '司實三', '陸浪', '趙布雁', '荊孤藍','憐燕南天', '蕭憐靜', '龍布雁', '東郭魚', '司東郭金天', '薛嘯天', '熊寶玉', '無莫靜','柳羅李', '東官小魚', '漸飛', '陸地魚', '阿吹王', '高傲', '蕭十三', '龍童', '玉羅趙','謝郎唐傲', '鐵夜帝', '江小鳳', '孫玉玉夜', '仇仲忍', '蕭地孫', '鐵莫棠', '柴星夫','展夫人', '碧玉', '老無魚', '鐵鐵花', '獨', '薛月宮九', '老郭和尚', '東郭大路陸上龍關(guān)飛','司藏', '李千', '孫白人', '南雙平', '王瑋', '姬原情', '東郭大路孫玉', '白玉羅生', '高兒','東玨天', '蕭王尚', '九', '鳳三靜', '和空摘星', '關(guān)吹雪', '上官官小鳳', '仇上官金飛','陸上龍嘯天', '司空星魂', '邀衣人', '主', '李尋歡天', '東情', '玉夫隨', '趙小鳳', '東郭滅', '邀祟厚', '司空星'}
   

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

總結(jié)

RNN由于具有記憶功能,在NLP、Speech、Computer Vision等諸多領(lǐng)域都展示了強大的力量。實際上,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也一直在產(chǎn)生新的研究,比如Attention機制。有空再介紹咯。。。

Refers

http://colah.github.io/posts/2015-08-Understanding-LSTMs/ 

http://karpathy.github.io/2015/05/21/rnn-effectiveness/ 

https://www.zhihu.com/question/29411132 

https://gist.github.com/karpathy/d4dee566867f8291f086 

https://deeplearning4j.org/lstm.html 雷鋒網(wǎng)雷鋒網(wǎng)

相關(guān)文章:

谷歌大腦科學家親解 LSTM:一個關(guān)于“遺忘”與“記憶”的故事

老板來了:人臉識別 + 手機推送,老板來了你立刻知道!

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。

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

分享:
相關(guān)文章

用愛救世界
當月熱門文章
最新文章
請?zhí)顚懮暾埲速Y料
姓名
電話
郵箱
微信號
作品鏈接
個人簡介
為了您的賬戶安全,請驗證郵箱
您的郵箱還未驗證,完成可獲20積分喲!
請驗證您的郵箱
立即驗證
完善賬號信息
您的賬號已經(jīng)綁定,現(xiàn)在您可以設置密碼以方便用郵箱登錄
立即設置 以后再說