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

2021-01-11 雷鋒網

雷鋒網按:本文轉載自Magicly博客,獲作者授權。閱讀原文請見:。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的出現是為了解決狀態記憶的問題,解決方法很簡單,每一個時間點t的隱藏狀態h(t)不再簡單地依賴於數據,還依賴於前一個時間節點t-1的隱藏狀態h(t-1)。可以看出這是一種遞歸定義(所以循環神經網絡又叫遞歸神經網絡RecursiveNeuralNetwork),h(t-1)又依賴於h(t-2),h(t-2)依賴於h(t-3)…所以h(t)依賴於之前每一個時間點的輸入,也就是說h(t)記住了之前所有的輸入。

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

RNN問題:Long-TermDependencies

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

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

LSTM

LongShortTermMemory神經網絡,也就是LSTM,由Hochreiter&Schmidhuber於1997年發表。它的出現就是為了解決Long-TermDependencies的問題,很來出現了很多改進版本,目前應用在相當多的領域(包括機器翻譯、對話機器人、語音識別、ImageCaption等)。

標準的RNN裡,重複的模塊裡只是一個很簡單的結構,如下圖:

LSTM也是類似的鍊表結構,不過它的內部構造要複雜得多:

上圖中的圖標含義如下:

LSTM的核心思想是cellstate(類似於hiddenstate,有LSTM變種把cellstate和hiddenstate合併了,比如GRU)和三種門:輸入門、忘記門、輸出門。

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

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

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

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

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

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

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

現在也出了很多LSTM的變種,有興趣的可以看這裡。另外,LSTM只是為了解決RNN的long-termdependencies,也有人從另外的角度來解決的,比如ClockworkRNNsbyKoutnik,etal.(2014).

showmethecode!

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

"""

Minimalcharacter-levelVanillaRNNmodel.WrittenbyAndrejKarpathy(@karpathy)

BSDLicense

importnumpyasnp

#dataI/O

data=open('input.txt','r').read()#shouldbesimpleplaintextfile

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

chars=list(set(data))

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

print('datahas%dcharacters,%dunique.'%(data_size,vocab_size))

char_to_ix={ch:ifori,chinenumerate(chars)}

ix_to_char={i:chfori,chinenumerate(chars)}

#print(char_to_ix,ix_to_char)

#hyperparameters

hidden_size=100#sizeofhiddenlayerofneurons

seq_length=25#numberofstepstounrolltheRNNfor

learning_rate=1e-1

#modelparameters

Wxh=np.random.randn(hidden_size,vocab_size)*0.01#inputtohidden

Whh=np.random.randn(hidden_size,hidden_size)*0.01#hiddentohidden

Why=np.random.randn(vocab_size,hidden_size)*0.01#hiddentooutput

bh=np.zeros((hidden_size,1))#hiddenbias

by=np.zeros((vocab_size,1))#outputbias

deflossFun(inputs,targets,hprev):

inputs,targetsarebothlistofintegers.

hprevisHx1arrayofinitialhiddenstate

returnstheloss,gradientsonmodelparameters,andlasthiddenstate

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

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

loss=0

#forwardpass

fortinrange(len(inputs)):

xs[t]=np.zeros((vocab_size,1))#encodein1-of-krepresentation

xs[t][inputs[t]]=1

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

hs[t-1])+bh)#hiddenstate

#unnormalizedlogprobabilitiesfornextchars

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

#probabilitiesfornextchars

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

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

#backwardpass:computegradientsgoingbackwards

dWxh,dWhh,dWhy=np.zeros_like(

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

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

dhnext=np.zeros_like(hs[0])

fortinreversed(range(len(inputs))):

dy=np.copy(ps[t])

#backpropintoy.see

#http://cs231n.github.io/neural-networks-case-study/#gradifconfused

#here

dy[targets[t]]-=1

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

dby+=dy

dh=np.dot(Why.T,dy)+dhnext#backpropintoh

dhraw=(1-hs[t]*hs[t])*dh#backpropthroughtanhnonlinearity

dbh+=dhraw

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

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

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

fordparamin[dWxh,dWhh,dWhy,dbh,dby]:

#cliptomitigateexplodinggradients

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

returnloss,dWxh,dWhh,dWhy,dbh,dby,hs[len(inputs)-1]

defsample(h,seed_ix,n):

sampleasequenceofintegersfromthemodel

hismemorystate,seed_ixisseedletterforfirsttimestep

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

x[seed_ix]=1

ixes=[]

fortinrange(n):

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

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

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

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

x[ix]=1

ixes.append(ix)

returnixes

n,p=0,0

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

mbh,mby=np.zeros_like(bh),np.zeros_like(by)#memoryvariablesforAdagrad

smooth_loss=-np.log(1.0/vocab_size)*seq_length#lossatiteration0

whileTrue:

#prepareinputs(we'resweepingfromlefttorightinstepsseq_length

#long)

ifp+seq_length+1>=len(data)orn==0:

hprev=np.zeros((hidden_size,1))#resetRNNmemory

p=0#gofromstartofdata

inputs=[char_to_ix[ch]forchindata[p:p+seq_length]]

targets=[char_to_ix[ch]forchindata[p+1:p+seq_length+1]]

#samplefromthemodelnowandthen

ifn%100==0:

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

txt=''.join(ix_to_char[ix]forixinsample_ix)

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

#forwardseq_lengthcharactersthroughthenetandfetchgradient

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

smooth_loss=smooth_loss*0.999+loss*0.001

print('iter%d,loss:%f'%(n,smooth_loss))#printprogress

#performparameterupdatewithAdagrad

forparam,dparam,meminzip([Wxh,Whh,Why,bh,by],

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

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

mem+=dparam*dparam

param+=-learning_rate*dparam/\

np.sqrt(mem+1e-8)#adagradupdate

p+=seq_length#movedatapointer

n+=1#iterationcounter

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

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

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

new_names=predicted_names-all_names

print(new_names)

print('predictednameslen:%d,new_nameslen:%d.\n'%(len(predicted_names),len(new_names)))

break

viewhostedwithbyrawmin-char-rnn.pyGitHub

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

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

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

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

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

總結

RNN由於具有記憶功能,在NLP、Speech、ComputerVision等諸多領域都展示了強大的力量。實際上,RNN是圖靈等價的。

1Iftrainingvanillaneuralnetsisoptimizationoverfunctions,trainingrecurrentnetsisoptimizationoverprograms.

LSTM是一種目前相當常用和實用的RNN算法,主要解決了RNN的long-termdependencies問題。另外RNN也一直在產生新的研究,比如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

相關焦點

  • PyTorch:Bi-LSTM的文本生成
    有時它來得容易而且完美;有時就像在巖石上鑽孔,然後用炸藥把它炸開一樣。」—歐內斯特·海明威本博客的目的是解釋如何通過實現基於LSTMs的強大體系結構來構建文本生成的端到端模型。博客分為以下幾個部分:介紹文本預處理序列生成模型體系結構訓練階段文本生成完整代碼請訪問:https://github.com/FernandoLpz
  • 從《金庸群俠傳》到《逆水寒》,細數國產武俠網遊畫面進化史!
    萌芽期(2001-2005)2001年上線的金庸群俠傳ol是一款原創性做的非常到位的武俠遊戲。經濟系統、系統、聊天系統等都有值得稱道之處,當時128MB內存+Win 98就能玩。金庸群俠傳OL在當時的影響力頗大,不少玩家為其沉迷。
  • 古龍武俠小說人物命名與武功秘藉名字拾趣
    長期以來,廣為流傳的大致有這麼幾種說法:一說是古龍最崇拜諸葛亮(號臥龍),而古龍即喻指「古時的臥龍」;二說是古龍熱愛中華民族,喻指古時的龍之圖騰;三說是古龍之名因「金庸」而起,「古」對「金(今)」,「龍」對「庸」,有一種誓要奮起直追的意思;還有一種說法更離奇,說古龍之名來自於他小時候用過的一把西瓜刀的牌子。
  • 武俠小說如何給主角起名字:梁羽生取自詩詞金庸愛抽象
    後繼者要想給主角取一個鶴立雞群的好名字,而又避免跟前人雷同,難度絕對不小。同樣是香港武俠大師,金庸的趣向就跟梁羽生完全相反。梁羽生喜歡具象,指明事物的末字之前,往往要再加一個表示狀態的形容詞,藉以約束畫面,使「色」「相」俱全。金庸則高度抽象,比如蕭峰、虛竹,只有模糊感覺,而無固定畫面;再如令狐衝、楊過、張無忌,更是只剩感覺,無從設想畫面。大約畫面感會讓人覺得清晰、明朗,而金庸想要闡釋的主題卻是模糊——正邪難以明定,人事總歸無常。這正是佛經所謂「無色無相」之境。
  • 古龍偽作系列之《無翼蝙蝠》,明明是黃鷹寫完的,卻署名古龍
    古龍的成就和地位僅次於金庸,作為怪才和奇才,古龍的小說在武俠界可謂是獨樹一幟的存在。他的小說,個人風格濃厚,帶有濃濃的古龍風格。無論是文字錘鍊,行文方式,故事打造,情節編排,都帶有古龍式的標籤。個性鮮明至極,是不是模仿古龍的偽作,一看就能品出來。古龍雖然有才華,但習慣性爛尾和找人代筆。
  • 金庸為他題詞,古龍為他感嘆
    今天,就讓我們一起來回顧一下金庸和古龍二位先生對於他的評價。1976年,已然成為明星的鄭少秋出演了對於他一生來說非常重要的電視劇《書劍恩仇錄》,這是TVB首部改編自金庸小說的作品,一經播出俘獲了許多觀眾的心,促使鄭少秋成為了當時的首席武俠小生,而需要特別指出的是,能夠引起這麼大的轟動,不僅僅是因為鄭少秋出眾的外形,更重要的是原因則是他在不到30歲的年齡,能夠在一部電視劇中出演三個角色,居然還能拿捏得當,實屬內外兼修,還有不少人覺得,鄭少秋表現最好的角色並不是男一號陳家洛
  • 《河洛群俠傳》評測——還請大俠重新來過……
    不過,隨著 2014 年河洛工作室的重組,《金庸群俠傳》的續作終於不負眾望的被安排上了計劃。在經歷兩年的研發後,代表《金庸群俠傳》精神續作的《河洛群俠傳》(下稱《河洛》)在本月交出了自己的答卷。很可惜的是,玩家多年等待換來的考卷,卻寫滿「不及格」三個大字。
  • 書蟲的最愛,繼金庸古龍先生之後,再創輝煌的武俠小說
    書蟲的最愛,繼金庸古龍先生之後,再創輝煌的武俠小說嗨,我的小寶貝你們最近過得怎麼樣呀?不知道大家這段時間都在看什麼小說呢,小編的推薦大家有木有看呢?沒看的趕緊收藏起來,書荒的時候看絕對不虧。下面小編今天繼續給大家推薦熱血武俠小說咯!
  • 金庸小說中知名度不高的一部作品,卻是金庸全集中最現實的一部
    那個時代沒有太多的消遣方式,能夠在一部武俠小說中找到快樂和輕鬆,那是多麼的暢快。 武俠小說,就像島國片一樣,就是男人的意淫。白衣飄飄,駿馬常騎,長劍在身,美女伴隨。在江湖中做出一些驚天動地的大事,在刀光劍影中,尋找一時的快感,豈不妙哉。所以我們看武俠小說,很少有以女主角獨挑大梁的戲,經常掌控全局,左右大事的都是男主人公。
  • 怪物獵人長相最奇葩的古龍種 網友:浮嶽龍不是第一我不服
    怪物獵人中除了金獅子、野豬王和雪獅子一類的怪物,最多的也是主角的怪物就是各種各樣的飛龍了,這些飛龍裡面又屬古龍種最厲害。古龍種活的時間長,也就導致了它們的長相比較奇特,而長相最奇怪的就屬介紹下來我要介紹的這幾條古龍了。
  • 身不由己時,幸有古龍的江湖可以流浪
    說起中國武俠小說,總不免把金庸、古龍一起議論。在武俠小說中,總有一個叫江湖的地方。江湖中,金庸是俠客,古龍則是浪子。浪子要活得瀟灑、把酒言歡、無拘無束。(圖片來源於網絡)古龍筆下的人物是浪子,也是少年。
  • 吉龍大作《大禪九宮圖》:古龍武俠小說偽作系列第十五部
    不過這個作者不是古龍,而是他的大兄弟吉龍,暫且也算在「古龍武俠小說偽作系列」裡了,後面臺龍、古尤、古能等等都會出現的,歡迎一起討論!整理些手中掛名古龍的武俠小說偽作,主要包括內容簡介,出版社,出版時間,冊數,以及作品的真實面目和相同內容不同名字的各種掛名偽作,部分圖片取自網絡。
  • 網友:那顏值能染指金庸古龍三個大俠,你說呢
    但,你說氣不氣人,從1998年到2001年,任賢齊一口氣幹翻了金庸古龍筆下的三個大俠,除了楚留香,還有《神鵰俠侶》中的楊過,《笑傲江湖》裡的令狐衝。至於過了近二十年,網友還在調侃任賢齊是唯一一個相貌平平卻演遍了古裝美男子的男歌手。為什麼他有機會演這麼多「名不符實」的美男子?因為紅。
  • 如何使用LSTM在Keras中快速實現情感分析任務
    那麼我們會在未來的畫面中即興聯想籃球活動:有人在奔跑、跳躍很可能被打上打籃球的標籤,而一個人坐著觀看很可能是觀眾在觀看球賽。在訓練 RNN 的過程中,信息在循環中一次又一次的傳遞會導致神經網絡模型的權重發生很大的更新。這是因為每次更新中的誤差梯度都會積累起來,因此會導致一個不穩定的網絡。在極端情況下,權值可能會變得過大以至於溢出並形成一個非數值(NaN)。網絡層之間的梯度(值大於 1)重複相乘導致梯度爆炸,而小於 1 的梯度重複相乘會造成梯度消失。
  • 梁羽生是新派武俠小說的鼻祖,可是為什麼他的名氣遠不如金庸?
    相信對於大部分的人來說,只要一提起武俠小說,那都是不會陌生,即使是沒有讀過小說,那麼也一定是看過電影,或者電視劇,而且我們都知道還有三位武俠小說巨匠,那便是金庸、梁羽生、古龍;這三位武俠小說家,對於武俠小說,起到了至關重要的作用,而且他們的作品在全世界華人中廣為流傳。
  • 物理達人古龍:用動力學預測股市
    古龍這個名字在一財同樂坊中並不陌生。他今年以來在同樂坊中發表的一系列股票評論被股友們讚嘆非常準確。記者試圖通過和古龍的交流去發現這些準確的市場判斷究竟是出於巧合還是出自於一套成熟的分析系統。在看待大盤時,古龍也展現出來這種極其「物理」的特點。「我預想中的交易系統應該一定要是預測性的而不是事後描述性,一定是確定的而不是或然的。」古龍告訴第一財經日報《財商》記者。於是,古龍花了一年的時間去試圖用物理學的方法找到一些蘊藏在股票市場中的普遍規律。
  • 金庸已隨白雲去,還有3本精彩的武俠小說,讓老書蟲眼前一亮
    金庸先生的去世,是武俠界的一個大損失。但正如金庸在《神鵰俠侶》中寫的那樣:「你看天上白雲,聚了又散,散了又聚。人生離合,亦復如斯。」金庸已隨白雲去,聚散匆匆,只讀者們要心中還記得金庸的江湖,那就足夠了。何況這江湖之中,並不只有金庸,還要許多武俠作者。
  • 金庸武俠《神龍女羅剎》,其實是寫盡八荒奇人異事的伴霞樓主大作
    那些年,那些掛名金庸的武俠小說偽作系列第二十九部:《神龍女羅剎》正式登場。整理些手中掛名金庸的武俠小說偽作,主要包括內容簡介,出版社,出版時間,冊數,以及作品的真實面目和相同內容不同名字的各種掛名偽作,部分圖片取自網絡。
  • 36年一部非金庸古龍的武俠劇,拍出了暗黑版桃花源記氣質
    、古龍、梁羽生等暢銷武俠小說家寫的名作,拍攝了很多膾炙人口的經典影視作品,也造就了一大批港臺明星。 這其中有一部戲,就是既不是金庸也不是古龍,反而靈感追溯了千多年前的東晉末至南朝宋初期偉大的詩人、辭賦家陶淵明的桃花源記,拍出了一條不同於同期武俠,探討人性的暗黑版《桃花源記》,名字叫做《魔域桃源》。 今天網絡上有一些人,為了博取流量,黑化桃花源,把它形容成人間煉獄,其實還是小道了。