深度學習:將新聞報道按照不同話題性質進行分類

深度學習的廣泛運用之一就是對文本按照其內容進行分類撬腾。例如對新聞報道根據其性質進行劃分是常見的應用領域螟蝙。在本節(jié),我們要把路透社自1986年以來的新聞數(shù)據按照46個不同話題進行劃分民傻。網絡經過訓練后胰默,它能夠分析一篇新聞稿场斑,然后按照其報道內容,將其歸入到設定好的46個話題之一牵署。深度學習在這方面的應用屬于典型的“單標簽漏隐,多類別劃分”的文本分類應用。

我們這里采用的數(shù)據集來自于路透社1986年以來的報道奴迅,數(shù)據中每一篇新聞稿附帶一個話題標簽青责,以用于網絡訓練,每一個話題至少含有10篇文章取具,某些報道它內容很明顯屬于給定話題脖隶,有些報道會模棱兩可,不好確定它到底屬于哪一種類的話題者填,我們先把數(shù)據加載到機器里浩村,代碼如下:

from keras.datasetsimportreuters(train_data, train_label),(test_data, test_labels)= reuters.load_data(num_words=10000)

keras框架直接附帶了相關數(shù)據集,通過執(zhí)行上面代碼就可以將數(shù)據下載下來占哟。上面代碼運行后結果如下:

這里寫圖片描述

從上面運行結果看酿矢,它總共有8982條訓練數(shù)據和2246條測試數(shù)據榨乎。跟我們上節(jié)數(shù)據類型一樣,數(shù)據里面對應的是每個單詞的頻率編號瘫筐,我們可以通過上一節(jié)類似的代碼,將編號對應的單詞從字典中抽取出來結合成一篇文章拙毫,代碼如下:

word_index = reuters.get_word_index()reverse_word_index = dict([value, key]for(key, value)inword_index.items())decoded_newswire =' '.join([reverse_word_index.get(i-3,'?')foriintrain_data[0]])print(decoded_newswire)

上面代碼運行后結果如下:

這里寫圖片描述

如同上一節(jié)膘婶,我們必須要把訓練數(shù)據轉換成數(shù)據向量才能提供給網絡進行訓練逝段,因此我們像上一節(jié)一樣,對每條新聞創(chuàng)建一個長度為一萬的向量朗儒,先把元素都初始為0开呐,然后如果某個對應頻率的詞在文本中出現(xiàn)卵惦,那么我們就在向量中相應下標設置為1,代碼如下:

importnumpyasnpdefvectorize_sequences(sequences, dimension=10000):results = np.zeros((len(sequences), dimension))fori, sequenceinenumerate(sequences):? ? ? ? results[i, sequence] =1.returnresultsx_train = vectorize_sequences(train_data)x_test = vectorize_sequences(test_data)print(x_train[0])

上面代碼運行后揍拆,我們就把訓練數(shù)據變成含有1或0的向量了:

這里寫圖片描述

其實我們可以直接調用keras框架提供的接口一次性方便簡單的完成:

fromkeras.utils.np_utilsimportto_categoricalone_hot_train_labels = to_categorical(train_label)one_hot_test_labels = to_categorical(test_labels)

接下來我們可以著手構建分析網絡筒狠,網絡的結構與上節(jié)很像聘萨,因為要解決的問題性質差不多,都是對文本進行分析叔收。然而有一個重大不同在于,上一節(jié)我們只讓網絡將文本劃分成兩種類別复濒,而這次我們需要將文本劃分為46個類別脖卖!上一節(jié)我們構造網絡時,中間層網絡我們設置了16個神經元巧颈,由于現(xiàn)在我們需要在最外層輸出46個結果畦木,因此中間層如果只設置16個神經元那就不夠用,由于輸出的信息太多砸泛,如果中間層神經元數(shù)量不足十籍,那么他就會成為信息過濾的瓶頸蛆封,因此這次我們搭建網絡時,中間層網絡節(jié)點擴大為6個勾栗,代碼如下:

fromkerasimportmodelsfromkerasimportlayersmodel = models.Sequential()model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))model.add(layers.Dense(64, activation='relu'))#當結果是輸出多個分類的概率時惨篱,用softmax激活函數(shù),它將為46個分類提供不同的可能性概率值model.add(layers.Dense(46, activation='softmax'))#對于輸出多個分類結果,最好的損失函數(shù)是categorical_crossentropymodel.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])

像上一節(jié)一樣围俘,在網絡訓練時我們要設置校驗數(shù)據集砸讳,因為網絡并不是訓練得次數(shù)越多越好,有了校驗數(shù)據集楷拳,我們就知道網絡在訓練幾次的情況下能夠達到最優(yōu)狀態(tài)绣夺,準備校驗數(shù)據集的代碼如下:

x_val = x_train[:1000]

partial_x_train = x_train[1000:]

y_val = one_hot_train_labels[:1000]

partial_y_train = one_hot_train_labels[1000:]

有了數(shù)據,就相當于有米入鍋欢揖,我們可以把數(shù)據輸入網絡進行訓練:

history= model.fit(partial_x_train, partial_y_train, epochs=20, batch_size=512,? ? ? ? ? ? ? ? ? ? validation_data=(x_val, y_val))

代碼進行了20個周期的循環(huán)訓練陶耍,由于數(shù)據量比上一節(jié)小,因此速度快很多她混,與上一節(jié)一樣烈钞,網絡的訓練并不是越多越好,它會有一個拐點坤按,訓練次數(shù)超出后毯欣,效果會越來越差,我們把訓練數(shù)據圖形化臭脓,以便觀察拐點從哪里開始:

importmatplotlib.pyplotaspltloss = history.history['loss']val_loss = history.history['val_loss']epochs = range(1, len(loss) +1)plt.plot(epochs, loss,'bo', label='Training loss')plt.plot(epochs, val_loss,'b', label='Validation loss')plt.xlabel('Epochs')plt.ylabel('Loss')plt.legend()plt.show()

上面代碼運行后結果如下:

這里寫圖片描述

通過上圖觀察我們看到酗钞,以藍點表示的是網絡對訓練數(shù)據的判斷準確率,該準確率一直在不斷下降来累,但是藍線表示的是網絡對校驗數(shù)據判斷的準確率砚作,仔細觀察發(fā)現(xiàn),它一開始是迅速下降的嘹锁,過了某個點葫录,達到最低點后就開始上升,這個點大概是在epochs=9那里领猾,所以我們把前面對網絡訓練的循環(huán)次數(shù)減少到9:

fromkerasimportmodelsfromkerasimportlayersmodel = models.Sequential()model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))model.add(layers.Dense(64, activation='relu'))#當結果是輸出多個分類的概率時米同,用softmax激活函數(shù),它將為46個分類提供不同的可能性概率值model.add(layers.Dense(46, activation='softmax'))#對于輸出多個分類結果,最好的損失函數(shù)是categorical_crossentropymodel.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])history = model.fit(partial_x_train, partial_y_train, epochs=9, batch_size=512,? ? ? ? ? ? ? ? ? ? validation_data=(x_val, y_val))

完成訓練后摔竿,我們把結果輸出看看:

results = model.evaluate(x_test, one_hot_test_labels)print(results)

上面兩句代碼運行結果為:

這里寫圖片描述

右邊0.78表示面粮,我們網絡對新聞進行話題分類的準確率達到78%,差一點到80%拯坟。我們從測試數(shù)據集中拿出一條數(shù)據但金,讓網絡進行分類,得到結果再與其對應的正確結果比較看看是否一致:

predictions = model.predict(x_test)print(predictions[0])print(np.sum(predictions[0]))print(np.argmax(predictions[0]))print(one_hot_test_labels[0])

我們讓網絡對每一條測試數(shù)據一一進行判斷郁季,并把它對第一條數(shù)據的判斷結果顯示出來冷溃,最后我們打印出第一條測試數(shù)據對應的分類钱磅,最后看看網絡給出去的結果與正確結果是否一致,上面代碼運行后結果如下:

這里寫圖片描述

從上面運行結果看到似枕,網絡對第一條數(shù)據給出了屬于46個分類的概率盖淡,其中下標為3的概率值最大,也就是第一條數(shù)據屬于分類4的概率最大凿歼,最后打印出來的測試數(shù)據對應的正確結果來看褪迟,它也是下標為3的元素值為1,也就是說數(shù)據對應的正確分類是4答憔,由此我們網絡得到的結果是正確的味赃。

前面提到過,由于網絡最終輸出結果包含46個元素虐拓,因此中間節(jié)點的神經元數(shù)目不能小于46心俗,因為小于46,那么有關46個元素的信息就會遭到擠壓蓉驹,于是在層層運算后會導致信息丟失城榛,最后致使最終結果的準確率下降,我們試試看是不是這樣:

fromkerasimportmodelsfromkerasimportlayersmodel = models.Sequential()model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))model.add(layers.Dense(4, activation='relu'))#當結果是輸出多個分類的概率時态兴,用softmax激活函數(shù),它將為46個分類提供不同的可能性概率值model.add(layers.Dense(46, activation='softmax'))#對于輸出多個分類結果狠持,最好的損失函數(shù)是categorical_crossentropymodel.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])history = model.fit(partial_x_train, partial_y_train, epochs=9, batch_size=512,? ? ? ? ? ? ? ? ? ? validation_data=(x_val, y_val))results = model.evaluate(x_test, one_hot_test_labels)print(results)

上面代碼運行后,輸出的results結果如下:

[1.4625472680649796, 0.6705253784505788]

從上面結果看到瞻润,我們代碼幾乎沒變喘垂,致使把第二層中間層神經元數(shù)量改成4,最終結果的準確率就下降10個點绍撞,所以中間層神經元的減少導致信息壓縮后王污,最后計算的準確度缺失。反過來你也可以試試用128個神經元的中間層看看準確率有沒有提升楚午。

到這里不知道你發(fā)現(xiàn)沒有,神經網絡在實際項目中的運用有點類似于樂高積木尿招,你根據實際需要矾柜,通過選定參數(shù),用幾行代碼配置好基本的網絡結構就谜,把訓練數(shù)據改造成合適的數(shù)字向量怪蔑,然后就可以輸入到網絡中進行訓練,訓練過程中記得用校驗數(shù)據監(jiān)測最優(yōu)訓練次數(shù)丧荐,防止過度擬合缆瓣。

在網絡的設計過程中,其背后的數(shù)學原理我們幾乎無需了解虹统,只需要憑借經驗弓坞,根據項目的性質隧甚,設定網絡的各項參數(shù),最關鍵的其實在根據項目數(shù)據性質對網絡進行調優(yōu)渡冻,例如網絡設置幾層好戚扳,每層幾個神經元,用什么樣的激活函數(shù)和損失函數(shù)等等族吻,這些操作與技術無關帽借,取決以個人經驗,屬于“藝術”的范疇超歌。

更詳細的講解和代碼調試演示過程砍艾,請點擊鏈接

作者:望月從良

鏈接:http://www.reibang.com/p/c81414c30d6b

來源:簡書

簡書著作權歸作者所有,任何形式的轉載都請聯(lián)系作者獲得授權并注明出處巍举。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末脆荷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子禀综,更是在濱河造成了極大的恐慌简烘,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件定枷,死亡現(xiàn)場離奇詭異孤澎,居然都是意外死亡,警方通過查閱死者的電腦和手機欠窒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門覆旭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人岖妄,你說我怎么就攤上這事型将。” “怎么了荐虐?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵七兜,是天一觀的道長。 經常有香客問我福扬,道長腕铸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上亭罪,老公的妹妹穿的比我還像新娘称勋。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布俗孝。 她就那樣靜靜地躺著匙奴,像睡著了一般俗冻。 火紅的嫁衣襯著肌膚如雪礁叔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天言疗,我揣著相機與錄音晴圾,去河邊找鬼。 笑死噪奄,一個胖子當著我的面吹牛死姚,可吹牛的內容都是我干的。 我是一名探鬼主播勤篮,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼都毒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了碰缔?” 一聲冷哼從身側響起账劲,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎金抡,沒想到半個月后瀑焦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡梗肝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年榛瓮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巫击。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡禀晓,死狀恐怖,靈堂內的尸體忽然破棺而出坝锰,到底是詐尸還是另有隱情粹懒,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布顷级,位于F島的核電站凫乖,受9級特大地震影響,放射性物質發(fā)生泄漏弓颈。R本人自食惡果不足惜拣凹,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望恨豁。 院中可真熱鬧,春花似錦爬迟、人聲如沸橘蜜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽计福。三九已至跌捆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間象颖,已是汗流浹背佩厚。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留说订,地道東北人抄瓦。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像陶冷,于是被迫代替她去往敵國和親钙姊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內容