Python深度學(xué)習(xí)(三)神經(jīng)網(wǎng)絡(luò)入門

本章涵蓋了

  • 神經(jīng)網(wǎng)絡(luò)的核心組件
  • Keras概論
  • 設(shè)置深度學(xué)習(xí)工作環(huán)境
  • 使用神經(jīng)網(wǎng)絡(luò)來(lái)解決基本分類和回歸問(wèn)題

本章旨在讓你開始使用神經(jīng)網(wǎng)絡(luò)來(lái)解決實(shí)際問(wèn)題。您將鞏固從第2章的第一個(gè)實(shí)際示例中獲得的知識(shí),并將所學(xué)知識(shí)應(yīng)用于三個(gè)新問(wèn)題,涉及到神經(jīng)網(wǎng)絡(luò)的三個(gè)最常見(jiàn)的用例:二分類、多分類和標(biāo)量回歸。
在這一章中,我們將更深入地了解我們?cè)诘诙轮薪榻B的神經(jīng)網(wǎng)絡(luò)的核心組件:層、網(wǎng)絡(luò)、目標(biāo)函數(shù)和優(yōu)化器。
我們將向您簡(jiǎn)要介紹Keras,這個(gè)Python深度學(xué)習(xí)庫(kù)將貫穿全書。你將建立一個(gè)深度學(xué)習(xí)工作環(huán)境(通過(guò)TensorFlow,Keras,和GPU的支持)。我們將深入研究如何使用神經(jīng)網(wǎng)絡(luò)解決實(shí)際問(wèn)題的三個(gè)介紹性示例:

  • 分類影評(píng)為積極positive還是消極negative(二分類)
  • 按主題分類新聞(多分類)
  • 根據(jù)房地產(chǎn)數(shù)據(jù)估算房?jī)r(jià)(回歸)

到本章結(jié)束時(shí),您將能夠使用神經(jīng)網(wǎng)絡(luò)來(lái)解決簡(jiǎn)單的機(jī)器問(wèn)題,例如向量數(shù)據(jù)的分類和回歸。然后,您將準(zhǔn)備在第四章中開始構(gòu)建一個(gè)更有原則的、理論驅(qū)動(dòng)的機(jī)器學(xué)習(xí)理解。

3.1神經(jīng)網(wǎng)絡(luò)剖析

正如你在前幾章看到的,訓(xùn)練神經(jīng)網(wǎng)絡(luò)圍繞以下對(duì)象:

  • 層,用于合并成網(wǎng)絡(luò)(或模型)
  • 輸入數(shù)據(jù)和相應(yīng)的目標(biāo)
  • 損失函數(shù),定義了用于學(xué)習(xí)的反饋信號(hào)
  • 優(yōu)化器,這決定了學(xué)習(xí)如何進(jìn)行

您可以將它們的交互可視化,如圖3.1所示:網(wǎng)絡(luò)由連接在一起的層組成,將輸入數(shù)據(jù)映射到預(yù)期值。然后,損失函數(shù)將這些預(yù)期值與目標(biāo)進(jìn)行比較,產(chǎn)生一個(gè)損失值:一個(gè)衡量網(wǎng)絡(luò)預(yù)測(cè)與預(yù)期匹配程度的指標(biāo)。優(yōu)化器使用這個(gè)損失值來(lái)更新網(wǎng)絡(luò)的權(quán)重。


讓我們仔細(xì)看看層、網(wǎng)絡(luò)、損失函數(shù)和優(yōu)化器。

3.1.1 layers: 深度學(xué)習(xí)的構(gòu)建模塊

神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)是layer,在第二章中已有介紹過(guò)。層是一個(gè)數(shù)據(jù)處理模塊,它接受一個(gè)或多個(gè)張量作為輸入,并輸出一個(gè)或多個(gè)張量。有些層是無(wú)狀態(tài)的,但更常見(jiàn)的是層有一個(gè)狀態(tài):層的權(quán)值,用隨機(jī)梯度下降法學(xué)習(xí)的一個(gè)或幾個(gè)張量,這些張量一起組成了網(wǎng)絡(luò)的知識(shí)。
不同的層適用于不同的張量格式和不同類型的數(shù)據(jù)處理。例如,簡(jiǎn)單的矢量數(shù)據(jù)存儲(chǔ)在二維張量的形狀(samples,features)中,通常由緊密連接的層(densely connected)處理,也稱為完全連接層或密集層(Keras中的密集類)。序列數(shù)據(jù)存儲(chǔ)在形狀為三維張量(samples,timesteps, features),中,通常由循環(huán)層(recurrent)處理,比如LSTM層。圖像數(shù)據(jù)存儲(chǔ)在4D張量中,通常由二維卷積層(Conv2D)處理。
你可以把layer看作深度學(xué)習(xí)的樂(lè)高積木,這個(gè)比喻是由Keras這樣的框架明確表達(dá)出來(lái)的。在Keras中構(gòu)建深度學(xué)習(xí)模型是通過(guò)剪切兼容的層來(lái)形成有用的數(shù)據(jù)轉(zhuǎn)換管道來(lái)完成的。這里的層兼容性指的是每一層只接受特定形狀的輸入張量,并返回特定形狀的輸出張量。考慮下面的例子:


我們正在創(chuàng)建一個(gè)只接受作為輸入2D張量的層,其中第一個(gè)維數(shù)是784(軸0,批處理維數(shù)是未指定的,因此任何值都會(huì)被接受)。這一層將返回一個(gè)張量,其中第一維變換為32。
因此,這個(gè)層只能連接到一個(gè)下游層,它需要32維向量作為它的輸入。在使用Keras時(shí),您不必?fù)?dān)心兼容性,因?yàn)樘砑拥侥P椭械膶邮莿?dòng)態(tài)構(gòu)建的,以匹配進(jìn)入層的形狀。例如,假設(shè)您寫下以下內(nèi)容:

from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(32, input_shape=(784,)))
model.add(layers.Dense(32))

第二層沒(méi)有接收輸入形狀參數(shù)——相反,它會(huì)自動(dòng)推斷出它的輸入形狀是之前層的輸出形狀。

3.1.2模型:層次網(wǎng)絡(luò)

深度學(xué)習(xí)模型是一個(gè)有向的、無(wú)循環(huán)的層次圖。最常見(jiàn)的實(shí)例是層的線性堆棧,將單個(gè)輸入映射到單個(gè)輸出。
但是隨著你的深入,您將接觸到更廣泛的網(wǎng)絡(luò)拓?fù)洹R恍┏R?jiàn)的問(wèn)題包括:

  • 二分支網(wǎng)絡(luò)
  • 多線程網(wǎng)絡(luò)
  • 初始?jí)K(Inception blocks)

網(wǎng)絡(luò)的拓?fù)涠x了一個(gè)假設(shè)空間。你們可能記得第一章中,我們將機(jī)器學(xué)習(xí)定義為“利用反饋信號(hào)的引導(dǎo),在預(yù)定義的可能性空間內(nèi),搜索一些輸入數(shù)據(jù)的有用表示。”通過(guò)選擇網(wǎng)絡(luò)拓?fù)洌憔拖拗屏四愕目赡苄钥臻g(假設(shè)空間)到特定的一系列張量運(yùn)算,將輸入數(shù)據(jù)映射到輸出數(shù)據(jù)。你接下來(lái)要找的是這些張量運(yùn)算中涉及到的權(quán)重張量的一組很好的值。
選擇合適的網(wǎng)絡(luò)架構(gòu)與其說(shuō)是一門科學(xué),不如說(shuō)是一門藝術(shù);盡管有一些你可以信賴的最佳實(shí)踐和原則,但只有實(shí)踐才能幫助你成為一個(gè)合適的神經(jīng)網(wǎng)絡(luò)架構(gòu)師。接下來(lái)的幾章將教給你構(gòu)建神經(jīng)網(wǎng)絡(luò)的明確原則,幫助你培養(yǎng)對(duì)特定問(wèn)題的直覺(jué)。

3.1.3 損失函數(shù)和優(yōu)化器:配置學(xué)習(xí)過(guò)程的關(guān)鍵

一旦定義了網(wǎng)絡(luò)架構(gòu),您仍然需要選擇另外兩件事:

  • 損失函數(shù)(目標(biāo)函數(shù))-在訓(xùn)練中需要最小化的數(shù)值。它代表著對(duì)手頭任務(wù)的成功程度的度量。
  • 優(yōu)化器——根據(jù)損失函數(shù)確定網(wǎng)絡(luò)的更新方式。它實(shí)現(xiàn)了隨機(jī)梯度下降(SGD)的一種特殊變體。

具有多個(gè)輸出的神經(jīng)網(wǎng)絡(luò)可能具有多個(gè)損失函數(shù)(每個(gè)輸出一個(gè))。但梯度下降過(guò)程必須基于單個(gè)標(biāo)量損失值;因此,對(duì)于多損失網(wǎng)絡(luò),所有損失(通過(guò)平均)合并成一個(gè)標(biāo)量。
為正確的問(wèn)題選擇正確的目標(biāo)函數(shù)是非常重要的:你的網(wǎng)絡(luò)會(huì)走它能走的任何捷徑,以最小化損失;因此,如果目標(biāo)與手頭任務(wù)的成功程度不完全相關(guān),你的網(wǎng)絡(luò)最終會(huì)做一些你可能不期望的結(jié)果。想象一個(gè)愚蠢的,萬(wàn)能的人工智能通過(guò)SGD進(jìn)行訓(xùn)練,而目標(biāo)函數(shù)選得很差:“最大化所有活著的人的平均幸福。”為了使它的工作更容易,這個(gè)人工智能可能會(huì)選擇殺死除少數(shù)人之外的所有人,并專注于剩下的人的幸福——因?yàn)槠骄腋2皇苁O露嗌偃说挠绊憽D强赡懿皇悄阆胍?只要記住,你建立的所有神經(jīng)網(wǎng)絡(luò)在降低損失功能上同樣無(wú)情——所以明智地選擇目標(biāo),否則你將不得不面對(duì)意想不到的副作用。
幸運(yùn)的是,當(dāng)涉及到諸如分類、回歸和序列預(yù)測(cè)等常見(jiàn)問(wèn)題時(shí),您可以遵循一些簡(jiǎn)單的指導(dǎo)原則來(lái)選擇正確的損失。例如,對(duì)于一個(gè)兩類分類問(wèn)題,您將使用二元交叉熵(binary crossentropy),對(duì)于一個(gè)多類分類問(wèn)題使用分類交叉熵(categorical crossentropy),對(duì)于回歸問(wèn)題使用均方差(meansquared error),對(duì)于序列學(xué)習(xí)問(wèn)題使用連接主義時(shí)間分類(connectionist temporal classification, CTC)等等。只有當(dāng)你在研究真正新的研究問(wèn)題時(shí),你才需要開發(fā)出自己的目標(biāo)函數(shù)。在接下來(lái)的幾章中,我們將顯式地詳細(xì)說(shuō)明在許多常見(jiàn)任務(wù)中應(yīng)該選擇哪些損失函數(shù)。

3.2 Keras簡(jiǎn)介

在本書中,代碼示例使用Keras (https://keras.io)。Keras是Python的一個(gè)深度學(xué)習(xí)框架,它提供了一種方便的方式來(lái)定義和訓(xùn)練幾乎任何類型的深度學(xué)習(xí)模型。Keras最初是為研究人員開發(fā)的,目的是實(shí)現(xiàn)快速實(shí)驗(yàn)。
Keras有以下關(guān)鍵特點(diǎn):

  • 它允許相同的代碼在CPU或GPU上無(wú)縫運(yùn)行。
  • 它有一個(gè)友好的API,便于快速開發(fā)原型深度學(xué)習(xí)模型。
  • 它內(nèi)置支持卷積網(wǎng)絡(luò)(convolutional networks,用于計(jì)算機(jī)視覺(jué)),復(fù)發(fā)性網(wǎng)絡(luò)(recurrent networks,用于序列處理),以及兩者的結(jié)合。
  • 它支持任意網(wǎng)絡(luò)體系結(jié)構(gòu):多輸入和多輸出模型,共享層,共享模型等等。這意味著Keras適用于構(gòu)建任何深度學(xué)習(xí)模型,從生成式對(duì)抗性網(wǎng)絡(luò)(generative adversarial network)到神經(jīng)圖靈機(jī)(neural Turing machine)。

Keras是以MIT license發(fā)布的,這意味著它可以在商業(yè)項(xiàng)目中自由使用。它兼容任何版本的Python,從 2.7到3.6(2017年中期)。
Keras擁有超過(guò)20萬(wàn)的用戶,從初創(chuàng)公司和大公司的學(xué)術(shù)研究人員和工程師到研究生和業(yè)余愛(ài)好者。Keras在谷歌、Netflix、Uber、CERN、Yelp、Square以及數(shù)百家致力于解決各種問(wèn)題的初創(chuàng)公司中都有應(yīng)用。Keras也是機(jī)器學(xué)習(xí)競(jìng)賽網(wǎng)站Kaggle上一個(gè)很受歡迎的框架


3.2.1 Keras, TensorFlow, Theano, and CNTK

Keras是一個(gè)模型級(jí)庫(kù),提供了開發(fā)深度學(xué)習(xí)模型的高級(jí)構(gòu)建模塊。它不處理低級(jí)操作,如張量操作和微分。相反,它依賴于一個(gè)專門的、經(jīng)過(guò)良好優(yōu)化的張量庫(kù),充當(dāng)Keras的后端引擎。不是選擇單個(gè)張量庫(kù)并將Keras的實(shí)現(xiàn)與該庫(kù)綁定在一起,而是以模塊化的方式處理問(wèn)題(參見(jiàn)圖3.3);因此,可以將幾個(gè)不同的后端引擎無(wú)縫地插入到Keras中。目前,現(xiàn)有的三個(gè)后端實(shí)現(xiàn)是TensorFlow后端、Theano后端和Microsoft Cognitive工具包(CNTK)的后端。在未來(lái),Keras可能會(huì)被擴(kuò)展到使用更deep-learning的執(zhí)行引擎。


TensorFlow、CNTK和Theano是當(dāng)今深度學(xué)習(xí)的一些主要平臺(tái)。Theano (http://deeplearning.net/software/theano)由蒙特利爾大學(xué)的MILA實(shí)驗(yàn)室開發(fā),TensorFlow (www.tensorflow.org)由谷歌開發(fā),CNTK(https://github.com/Microsoft/CNTK)由微軟開發(fā)。您使用Keras編寫的任何代碼片段都可以與這些后端一起運(yùn)行,而無(wú)需更改代碼中的任何內(nèi)容:在開發(fā)過(guò)程中,您可以無(wú)縫地在兩者之間切換,這通常被證明是有用的——例如,如果這些后端中有一個(gè)對(duì)于特定任務(wù)來(lái)說(shuō)速度更快的話。我們建議將TensorFlow后端作為大多數(shù)深度學(xué)習(xí)需求的默認(rèn)設(shè)置,因?yàn)樗亲顝V泛采用的、可擴(kuò)展的和有生產(chǎn)力的。
通過(guò)TensorFlow(或Theano,或CNTK), Keras可以在cpu和gpu兩者上無(wú)縫運(yùn)行。在CPU上運(yùn)行時(shí),TensorFlow本身為張量操作包裝了一個(gè)低級(jí)庫(kù),稱為Eigen(http://feat.tuxfamily.org)。在GPU, TensorFlow封裝了一個(gè)優(yōu)化深度學(xué)習(xí)操作庫(kù),稱之為NVIDIA CUDA深度神經(jīng)網(wǎng)絡(luò)庫(kù)(cuDNN)。

3.2.2用Keras開發(fā):快速概述

您已經(jīng)看到了Keras模型的一個(gè)示例:MNIST示例。典型的Keras工作流看起來(lái)就像那個(gè)例子:

  1. 定義你的訓(xùn)練數(shù)據(jù):輸入張量和目標(biāo)張量。
  2. 定義一個(gè)層(或模型)網(wǎng)絡(luò),用于將您的輸入映射到您的目標(biāo)。
  3. 通過(guò)選擇損失函數(shù)、優(yōu)化器和一些要監(jiān)控的指標(biāo)來(lái)配置學(xué)習(xí)過(guò)程。
  4. 通過(guò)調(diào)用模型的fit()方法迭代您的訓(xùn)練數(shù)據(jù)。

定義模型有兩種方法:使用Sequential類(僅用于線性層堆棧,這是目前最常見(jiàn)的網(wǎng)絡(luò)體系結(jié)構(gòu))或functionalAPI(用于層的有向無(wú)環(huán)圖,它允許您構(gòu)建完全任意的體系結(jié)構(gòu))。
作為復(fù)習(xí),這里有一個(gè)使用Sequential類定義的兩層模型(注意,我們將輸入數(shù)據(jù)的預(yù)期形狀傳遞給第一層):

from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(32, activation='relu', input_shape=(784,)))
model.add(layers.Dense(10, activation='softmax'))

下面是使用functional API定義的相同模型:

input_tensor = layers.Input(shape=(784,))
x = layers.Dense(32, activation='relu')(input_tensor)
output_tensor = layers.Dense(10, activation='softmax')(x)
model = models.Model(inputs=input_tensor, outputs=output_tensor)

通過(guò)functionalAPI,你可以操縱模型處理的數(shù)據(jù)張量,并將層應(yīng)用到這個(gè)張量上,就好像它們是函數(shù)一樣。

請(qǐng)注意,有關(guān)如何使用functional API的詳細(xì)指南可以在第7章中找到。在第7章之前,我們只在代碼示例中使用Sequential類。
一旦定義了模型體系結(jié)構(gòu),是否使用了Sequential模型或functional` API。以下所有步驟都是相同的。
學(xué)習(xí)過(guò)程是在編譯步驟中配置的,在這個(gè)步驟中,您指定了模型應(yīng)該使用的優(yōu)化器和損失函數(shù),以及您希望在訓(xùn)練期間監(jiān)控的指標(biāo)。這里有一個(gè)單損失函數(shù)的例子,這是目前最常見(jiàn)的情況:

from keras import optimizers
model.compile(optimizer=optimizers.RMSprop(lr=0.001),
loss='mse',
metrics=['accuracy'])

最后,學(xué)習(xí)過(guò)程由通過(guò)fit()方法向模型傳遞輸入數(shù)據(jù)(以及相應(yīng)的目標(biāo)數(shù)據(jù))的Numpy數(shù)組組成,類似于在Scikit-Learn和其他幾個(gè)機(jī)器學(xué)習(xí)庫(kù)中所做的工作:

model.fit(input_tensor, target_tensor, batch_size=128, epochs=10)

在接下來(lái)的幾章中,您將對(duì)哪種類型的網(wǎng)絡(luò)架構(gòu)適用于不同類型的問(wèn)題,如何選擇正確的學(xué)習(xí)配置,以及如何調(diào)整模型,直到它給出您想要的結(jié)果,建立一個(gè)堅(jiān)實(shí)的直覺(jué)。我們將在3.4、3.5和3.6節(jié)中查看三個(gè)基本示例:一個(gè)二分類示例、一個(gè)多分類示例和一個(gè)回歸示例。

3.3 設(shè)置深度學(xué)習(xí)工作環(huán)境

在您開始開發(fā)深度學(xué)習(xí)應(yīng)用程序之前,您需要設(shè)置您的工作環(huán)境。強(qiáng)烈建議您在一個(gè)現(xiàn)代的NVIDIA GPU上運(yùn)行深度學(xué)習(xí)代碼,盡管這不是必須的。有些應(yīng)用程序——特別是卷積網(wǎng)絡(luò)的圖像處理和循環(huán)神經(jīng)網(wǎng)絡(luò)(recurrent neural)的序列處理——在CPU上的速度會(huì)非常慢,甚至是一個(gè)快速的多核CPU。甚至對(duì)于實(shí)際可以在CPU上運(yùn)行的應(yīng)用程序,您通常會(huì)看到使用現(xiàn)代GPU的速度提高了5到10倍。如果您不想在您的機(jī)器上安裝GPU,您可以考慮在AWS EC2 GPU實(shí)例或谷歌云平臺(tái)上運(yùn)行您的實(shí)驗(yàn)。但是請(qǐng)注意隨著時(shí)間的推移,云GPU實(shí)例可能變得昂貴。
無(wú)論您是在本地運(yùn)行還是在云中運(yùn)行,最好使用Unix工作環(huán)境。雖然在Windows上使用Keras在技術(shù)上是可能的(所有三個(gè)Keras后端都支持Windows),但我們不推薦它。在附錄A的安裝說(shuō)明中,我們將考慮Ubuntu機(jī)器。如果你是Windows用戶,讓一切正常運(yùn)行的最簡(jiǎn)單的解決方案就是在你的機(jī)器上設(shè)置一個(gè)Ubuntu雙啟動(dòng)。這似乎是一個(gè)麻煩,但從長(zhǎng)遠(yuǎn)來(lái)看,使用Ubuntu會(huì)節(jié)省很多時(shí)間和麻煩。
注意,為了使用Keras,您需要安裝TensorFlow或CNTK或Theano (如果你想在這三個(gè)后端之間來(lái)回切換,也可以選擇全部)。在這本書中,我們將重點(diǎn)介紹TensorFlow,并給出一些與Theano相關(guān)的簡(jiǎn)單說(shuō)明。我們不覆蓋CNTK的說(shuō)明。

3.3.1 Jupyter記事本:進(jìn)行深度學(xué)習(xí)實(shí)驗(yàn)的首選方式

Jupyter notebook是進(jìn)行深度學(xué)習(xí)實(shí)驗(yàn)的好方法——尤其是本書中的許多代碼示例。它們廣泛應(yīng)用于數(shù)據(jù)科學(xué)和機(jī)器學(xué)習(xí)領(lǐng)域。notebook是一個(gè)由Jupyter notebook應(yīng)用程序(https://jupyter.org)生成的文件,您可以在瀏覽器中編輯它。它將Python代碼的執(zhí)行能力與豐富的文本編輯功能結(jié)合在一起,以注釋您正在做的事情。notebook還允許你將長(zhǎng)時(shí)間的實(shí)驗(yàn)分解成更小的部分,這些部分可以獨(dú)立執(zhí)行,這使得開發(fā)具有交互性,并且意味著如果在實(shí)驗(yàn)后期出現(xiàn)問(wèn)題,你不必重新運(yùn)行之前的所有代碼。
我們建議使用Jupyter notebook開始使用Keras,盡管這不是一個(gè)要求:您還可以運(yùn)行獨(dú)立的Python腳本或從PyCharm等IDE中運(yùn)行代碼。本書中的所有代碼示例都可以作為開源 notebooks使用;你可以從這本書的網(wǎng)站www.manning.com/books/deep-learning-with-python獲取。

3.3.2 讓Keras跑起來(lái):兩個(gè)選項(xiàng)

為了開始實(shí)踐,我們建議以下兩種選項(xiàng)之一:

  • 使用官方的EC2深度學(xué)習(xí)AMI (https://aws.amazon.com/amazonai/amis),在EC2上以Jupyter notebook方式運(yùn)行Keras實(shí)驗(yàn)。如果您的本地機(jī)器上還沒(méi)有GPU,請(qǐng)這樣做。附錄B提供了一步一步的指南。
  • 在本地Unix工作站上從頭開始安裝所有內(nèi)容。然后,您可以運(yùn)行本地Jupyter notebook或常規(guī)Python代碼庫(kù)。如果你已經(jīng)有一個(gè)高端的英偉達(dá)GPU,那就這么做。附錄A提供了一個(gè)特定于ubuntu的分步指南。
    讓我們更仔細(xì)地看一看選擇一個(gè)選項(xiàng)而不是另一個(gè)選項(xiàng)所涉及的一些妥協(xié)。

3.3.3在云計(jì)算中運(yùn)行深度學(xué)習(xí)工作:利弊

如果你還沒(méi)有一個(gè)可以用于深度學(xué)習(xí)的GPU(一個(gè)最近發(fā)布的高端NVIDIA GPU),以在云端進(jìn)行深度學(xué)習(xí)實(shí)驗(yàn),這是一種簡(jiǎn)單、低成本的方式,讓您無(wú)需購(gòu)買任何額外的硬件即可開始工作。如果您正在使用Jupyter notebook,那么在云端運(yùn)行的體驗(yàn)與在本地運(yùn)行沒(méi)什么不同。從2017年年中開始,讓深度學(xué)習(xí)變得最容易的云服務(wù)無(wú)疑是AWS EC2。附錄B提供了在EC2 GPU實(shí)例上運(yùn)行Jupyter notebooks的逐步指南。
但如果你是深度學(xué)習(xí)的忠實(shí)用戶,這種設(shè)置在很長(zhǎng)一段時(shí)間內(nèi)都是不可持續(xù)的,甚至在幾個(gè)星期內(nèi)也是不可持續(xù)的。EC2實(shí)例非常昂貴:附錄B中推薦的實(shí)例類型(p2.xlarge instance在2017年年中的價(jià)格為每小時(shí)0.90美元,它不會(huì)為你提供太多電力。同時(shí),一個(gè)堅(jiān)實(shí)的消費(fèi)階層,GPU的價(jià)格在1000美元到1500美元之間——隨著時(shí)間的推移,這個(gè)價(jià)格是相當(dāng)穩(wěn)定的,即使這些GPU的規(guī)格不斷改進(jìn)。如果您對(duì)深度學(xué)習(xí)很認(rèn)真,您應(yīng)該使用一個(gè)或多個(gè)gpu建立一個(gè)本地工作站。
簡(jiǎn)而言之,EC2是一個(gè)很好的入門方法。您可以完全在EC2 GPU實(shí)例上遵循本書中的代碼示例。但如果你想成為深度學(xué)習(xí)的超級(jí)用戶,那就擁有自己的gpu。

3.3.4 深度學(xué)習(xí)最好的GPU是什么?

如果你要買GPU,你應(yīng)該選擇哪一個(gè)?首先要注意的是它一定是NVIDIA GPU。英偉達(dá)是迄今為止唯一一家在深度學(xué)習(xí)方面投入巨資的圖形計(jì)算公司,而現(xiàn)代深度學(xué)習(xí)框架只能在英偉達(dá)卡上運(yùn)行。
2017年年中,我們推薦NVIDIA TITAN Xp作為市場(chǎng)上最好的深度學(xué)習(xí)卡。對(duì)于較低的預(yù)算,您可能需要考慮使用GTX 1060。如果你是在2018年或更晚的時(shí)候閱讀這些頁(yè)面,花點(diǎn)時(shí)間在網(wǎng)上尋找更新鮮的推薦,因?yàn)槊磕甓紩?huì)有新的款式出現(xiàn)。
從本節(jié)開始,我們將假設(shè)您可以訪問(wèn)具有以下功能的機(jī)器(安裝好Keras和它的依賴)——最好有GPU支持。確保在繼續(xù)之前完成這個(gè)步驟。仔細(xì)閱讀附錄中的逐步指南,如果需要進(jìn)一步的幫助,可以上網(wǎng)查找。關(guān)于如何安裝Keras和常見(jiàn)的深度學(xué)習(xí)依賴關(guān)系的教程很多。
我們現(xiàn)在可以深入研究Keras的實(shí)際例子。

3.4 電影評(píng)論分類:一個(gè)二元分類的例子

二分類或二元分類可能是應(yīng)用最廣泛的機(jī)器學(xué)習(xí)問(wèn)題。在本例中,您將學(xué)習(xí)如何根據(jù)評(píng)論的文本內(nèi)容將電影評(píng)論分為正面評(píng)論和負(fù)面評(píng)論。

3.4.1 IMDB數(shù)據(jù)集

您將使用IMDB數(shù)據(jù)集:一套50,000份高度兩極化評(píng)論的互聯(lián)網(wǎng)電影數(shù)據(jù)庫(kù)。它們分為25000條訓(xùn)練評(píng)論和25000條測(cè)試評(píng)論,每一組由50%的負(fù)面評(píng)論和50%的正面評(píng)論組成。
為什么要使用單獨(dú)的訓(xùn)練和測(cè)試集?因?yàn)槟阌肋h(yuǎn)不應(yīng)該用你用來(lái)訓(xùn)練它的數(shù)據(jù)來(lái)測(cè)試一個(gè)機(jī)器學(xué)習(xí)模型!僅僅因?yàn)槟P驮谄溆?xùn)練數(shù)據(jù)上表現(xiàn)良好并不意味著它將在它從未見(jiàn)過(guò)的數(shù)據(jù)上表現(xiàn)良好;您所關(guān)心的是您的模型在新數(shù)據(jù)上的性能(因?yàn)槟呀?jīng)知道了您的訓(xùn)練數(shù)據(jù)的標(biāo)簽——顯然您不需要您的模型來(lái)預(yù)測(cè)這些數(shù)據(jù))。例如 ,您的模型最終可能只是記住了訓(xùn)練樣本與其目標(biāo)之間的映射,這對(duì)于預(yù)測(cè)模型從未見(jiàn)過(guò)的數(shù)據(jù)的目標(biāo)來(lái)說(shuō)是無(wú)用的。我們將在下一章更詳細(xì)地討論這一點(diǎn)。
與MNIST數(shù)據(jù)集一樣,IMDB數(shù)據(jù)集也附帶在Keras中。它已經(jīng)經(jīng)過(guò)預(yù)處理:評(píng)論(單詞序列)已經(jīng)被轉(zhuǎn)換成整數(shù)序列,其中每個(gè)整數(shù)代表字典中的一個(gè)特定單詞。
下面的代碼將加載數(shù)據(jù)集(當(dāng)您第一次運(yùn)行它時(shí),大約80 MB的數(shù)據(jù)將下載到您的計(jì)算機(jī))。

Listing 3.1 Loading the IMDB dataset

from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

參數(shù)num_words=10000意味著您將只保留訓(xùn)練數(shù)據(jù)中最常見(jiàn)的10,000個(gè)單詞。罕見(jiàn)的單詞將被丟棄。這允許您處理可管理大小的向量數(shù)據(jù)。
train_data和test_data變量是review(評(píng)論)的列表;每個(gè)評(píng)論都是一個(gè)單詞索引列表(編碼一個(gè)單詞序列)。train_label和test_label是0和1的列表,0代表否定,1代表肯定:

>>> train_data[0]
[1, 14, 22, 16, ... 178, 32]
>>> train_labels[0]
1

因?yàn)槟惆炎约合拗圃谧畛S玫?萬(wàn)個(gè)單詞,所以沒(méi)有一個(gè)單詞的索引超過(guò)1萬(wàn)個(gè):

>>> max([max(sequence) for sequence in train_data])
9999

下面是如何快速將這些評(píng)論翻譯回英語(yǔ)的方法單詞:


3.4.2 準(zhǔn)備數(shù)據(jù)

你不能把整數(shù)列表輸入神經(jīng)網(wǎng)絡(luò)。你必須把列表變成張量。有兩種方法:

  • 填補(bǔ)你的列表,這樣他們都有相同的長(zhǎng)度,把它們變成一個(gè)整數(shù)形狀張量(samples,word_indices),然后在網(wǎng)絡(luò)的第一層使用一個(gè)能夠處理這種整數(shù)張量的層(嵌入(Embedding)層,我們將在本書后面詳細(xì)介紹)。
  • 將列表編碼為0和1的向量(One-hot encode)。這將意味著,例如,將序列[3,5]轉(zhuǎn)換成10000維的向量,除了指標(biāo)3和5,所有的0都是0,也就是1。然后,可以使用密集(Dense)層作為網(wǎng)絡(luò)的第一層,能夠處理浮點(diǎn)向量數(shù)據(jù)。
    讓我們使用后一種解決方案對(duì)數(shù)據(jù)進(jìn)行矢量化,您將手動(dòng)對(duì)數(shù)據(jù)進(jìn)行矢量化,以獲得最大的清晰度。

Listing 3.2 Encoding the integer sequences into a binary matrix


現(xiàn)在樣例變成這樣子:

>>> x_train[0]
array([ 0., 1., 1., ..., 0., 0., 0.])

你也應(yīng)該對(duì)你的標(biāo)簽進(jìn)行矢量化,這很簡(jiǎn)單:

y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')

現(xiàn)在數(shù)據(jù)已經(jīng)準(zhǔn)備好輸入神經(jīng)網(wǎng)絡(luò)。

3.4.3 構(gòu)建你的network

輸入數(shù)據(jù)是向量,標(biāo)簽是標(biāo)量(1和0):這是您遇到的最簡(jiǎn)單的設(shè)置。在這種問(wèn)題上表現(xiàn)良好的一種網(wǎng)絡(luò)是一個(gè)簡(jiǎn)單的堆棧,由完全連接(密集Dense)層與relu激活函數(shù)構(gòu)成:Dense(16,activation='relu')。傳遞給每個(gè)Dense層的參數(shù)(16)是該層的隱藏單元(hidden unit)數(shù)。隱藏單元是層表示空間中的維度。
你可能還記得在第2章中,每個(gè)這樣的密集層都有一個(gè)relu激活實(shí)現(xiàn)了以下張量操作鏈:

output = relu(dot(W, input) + b)

有16個(gè)隱藏單元意味著權(quán)重矩陣W將有形狀(input_dimension,16):與W的點(diǎn)積將把輸入數(shù)據(jù)投影到一個(gè)16維的表示空間上(然后加上偏差向量b,再應(yīng)用relu運(yùn)算)。您可以直觀地理解表示空間的維數(shù),即“在學(xué)習(xí)內(nèi)部表示時(shí),您允許網(wǎng)絡(luò)擁有多大的自由度”。擁有更多的隱藏單元(高維表示空間)可以讓網(wǎng)絡(luò)學(xué)習(xí)更復(fù)雜的表示,但這會(huì)使網(wǎng)絡(luò)的計(jì)算成本更高,并可能導(dǎo)致學(xué)習(xí)不需要的模式(模式將提高訓(xùn)練數(shù)據(jù)的性能,但不會(huì)提高測(cè)試數(shù)據(jù)的性能)
對(duì)于這樣一堆密集層,有兩個(gè)關(guān)鍵的架構(gòu)決策需要做出:

  • 使用多少個(gè)layers
  • 針對(duì)每個(gè)layer,選取多少個(gè)hidden unit

在第四章,你將學(xué)習(xí)正式的原則來(lái)指導(dǎo)你做出這些選擇。就目前而言,您必須相信我的架構(gòu)選擇:

  • 兩個(gè)中間層,每個(gè)層有16個(gè)隱藏單元
  • 第三層將輸出關(guān)于當(dāng)前評(píng)論情緒的標(biāo)量預(yù)測(cè)

中間層使用relu作為激活函數(shù),最后一層使用sigmoid激活,輸出一個(gè)概率(0到1之間的值,指示樣本有多大可能具有目標(biāo)“1”:評(píng)論有多大可能是正面的)。relu(整流線性單元)是一個(gè)函數(shù),它的作用是消除負(fù)值(參見(jiàn)圖3.4),而sigmoid將任意值“壓縮”到[0,1]區(qū)間(參見(jiàn)圖3.5),輸出一些可以解釋為概率的東西。



線性整流函數(shù)
Sigmoid函數(shù)

圖3.6顯示了網(wǎng)絡(luò)的外觀。這是Keras的實(shí)現(xiàn),類似于之前看到的MNIST的例子。

Listing 3.3 The model definition

from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
  • 什么是激活函數(shù),為什么它們是必要的?
    如果沒(méi)有像relu(也稱為非線性)這樣的激活函數(shù),Dense層將由兩個(gè)線性操作組成——點(diǎn)積和一個(gè)加法:
    output = dot(W, input) + b
    因此,該層只能學(xué)習(xí)輸入數(shù)據(jù)的線性變換(仿射變換,affine transformations)):該層的假設(shè)空間是輸入數(shù)據(jù)到16維空間的所有可能的線性變換的集合。這樣的假設(shè)空間過(guò)于有限,不會(huì)從多層表示中獲益,因?yàn)橐淮蠖丫€性層仍然會(huì)實(shí)現(xiàn)線性操作:添加更多的層不會(huì)擴(kuò)展假設(shè)空間。
    為了獲得一個(gè)更豐富的假設(shè)空間,從深度表示中獲益,你需要一個(gè)非線性,或者激活函數(shù)。relu是深度學(xué)習(xí)中最受歡迎的激活函數(shù),但是還有很多其他的候選函數(shù),它們都有同樣奇怪的名字:prelu, elu等等。

最后,您需要選擇損失函數(shù)和優(yōu)化器。因?yàn)槟忝媾R一個(gè)二元分類問(wèn)題網(wǎng)絡(luò)的輸出是一個(gè)概率(你用一個(gè)s型激活單元層結(jié)束你的網(wǎng)絡(luò)),最好選用binary_crossentropy loss函數(shù)。這不是唯一可行的選擇:例如,您可以使用mean_squared_error。但是當(dāng)你處理輸出概率的模型時(shí),交叉熵(Crossentropy)通常是最好的選擇。交叉熵是信息領(lǐng)域中的一個(gè)量測(cè)量概率分布之間的距離的理論,在這種情況下,測(cè)量真實(shí)分布和預(yù)測(cè)之間的距離的理論。
下面是使用rmsprop優(yōu)化器和binary_crossentropy loss函數(shù)配置模型的步驟。請(qǐng)注意,您還將在訓(xùn)練期間監(jiān)控accuracy:

Listing 3.4 Compiling the model

model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])

您正在將優(yōu)化器、損失函數(shù)和度量作為字符串傳遞,這是可能的,因?yàn)閞msprop、binary_crossentropy和accuracy都打包為Keras的一部分。有時(shí),您可能希望配置優(yōu)化器的參數(shù),或者傳遞一個(gè)自定義損失函數(shù)或度量函數(shù)。前者可以通過(guò)將優(yōu)化器類實(shí)例作為optimizer參數(shù)傳遞來(lái)實(shí)現(xiàn),如清單3.5所示;后者可以通過(guò)將函數(shù)對(duì)象作為loss和/或metrics參數(shù)傳遞來(lái)完成,如清單3.6所示。

Listing 3.5 Configuring the optimizer

from keras import optimizers
model.compile(optimizer=optimizers.RMSprop(lr=0.001),
loss='binary_crossentropy',
metrics=['accuracy'])

Listing 3.6 Using custom losses and metrics

from keras import losses
from keras import metrics
model.compile(optimizer=optimizers.RMSprop(lr=0.001),
loss=losses.binary_crossentropy,
metrics=[metrics.binary_accuracy])

3.4.4 驗(yàn)證你的方法

為了在訓(xùn)練期間監(jiān)控模型對(duì)以前從未見(jiàn)過(guò)的數(shù)據(jù)的準(zhǔn)確性,您將通過(guò)從原始訓(xùn)練數(shù)據(jù)中分離10,000個(gè)樣本來(lái)創(chuàng)建一個(gè)驗(yàn)證集。

Listing 3.7 Setting aside a validation set

x_val = x_train[:10000]
partial_x_train = x_train[10000:]
y_val = y_train[:10000]
partial_y_train = y_train[10000:]

現(xiàn)在,您將對(duì)模型以小批量512個(gè)樣本,進(jìn)行20次epoch (x_train和y_train張量中的所有樣本進(jìn)行20次迭代)。與此同時(shí),你將監(jiān)測(cè)你分開的10,000個(gè)樣品的損失和準(zhǔn)確性。您可以將驗(yàn)證數(shù)據(jù)作為validation_data參數(shù)傳遞。

Listing 3.8 Training your mode

model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['acc'])
history = model.fit(partial_x_train,
partial_y_train,
epochs=20,
batch_size=512,
validation_data=(x_val, y_val))

在CPU上,每次迭代將花費(fèi)不到2秒的時(shí)間——訓(xùn)練在20秒內(nèi)結(jié)束。在每一個(gè)迭代結(jié)束時(shí),當(dāng)模型計(jì)算它對(duì)10,000個(gè)驗(yàn)證數(shù)據(jù)樣本的損失和準(zhǔn)確性時(shí),會(huì)有一個(gè)輕微的暫停。
注意,對(duì)model.fit()的調(diào)用返回一個(gè)History對(duì)象。這個(gè)對(duì)象有一個(gè)成員history,這是一個(gè)字典,包含了所有在訓(xùn)練期間發(fā)生的數(shù)據(jù)。讓我們來(lái)看看:

>>> history_dict = history.history
>>> history_dict.keys()
[u'acc', u'loss', u'val_acc', u'val_loss']

該詞典包含4個(gè)條目:在訓(xùn)練和驗(yàn)證期間監(jiān)視的每個(gè)度量值有一個(gè)條目。在下面的兩個(gè)list中,我們使用Matplotlib并排繪制訓(xùn)練和驗(yàn)證損失(參見(jiàn)圖3.7),以及訓(xùn)練和驗(yàn)證準(zhǔn)確性(參見(jiàn)圖3.8)。注意,由于網(wǎng)絡(luò)的隨機(jī)初始化不同,您自己的結(jié)果可能略有不同。

Listing 3.9 Plotting the training and validation loss

import matplotlib.pyplot as plt
history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, loss_values, 'bo', label='Training loss')
plt.plot(epochs, val_loss_values, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

Listing 3.10 Plotting the training and validation accuracy

plt.clf()
acc_values = history_dict['acc']
val_acc_values = history_dict['val_acc']
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()


如你所見(jiàn),訓(xùn)練損失隨時(shí)間的變化而減小,訓(xùn)練精度(accuracy)隨時(shí)間的變化而增加。這就是您在運(yùn)行梯度下降優(yōu)化時(shí)所期望的——您試圖最小化的數(shù)量應(yīng)該隨著每次迭代而減少。但驗(yàn)證損失和準(zhǔn)確性卻并非如此:它們似乎在第四次迭代達(dá)到頂峰。這是我們之前警告過(guò)的一個(gè)例子:在訓(xùn)練數(shù)據(jù)上表現(xiàn)更好的模型不一定會(huì)在以前從未見(jiàn)過(guò)的數(shù)據(jù)上表現(xiàn)更好。確切地說(shuō),您看到的是過(guò)度擬合:在第二個(gè)階段之后,您正在對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行過(guò)度優(yōu)化,最終您將學(xué)習(xí)到特定于訓(xùn)練數(shù)據(jù)的表示,而不是泛化到訓(xùn)練集之外的數(shù)據(jù)。
在這種情況下,為了防止過(guò)度訓(xùn)練,你可以在3次迭代后停止訓(xùn)練。通常,您可以使用一系列技術(shù)來(lái)減輕過(guò)度擬合,我們將在第4章中介紹。
讓我們從零開始訓(xùn)練一個(gè)新的網(wǎng)絡(luò),為期四個(gè)迭代,然后在測(cè)試數(shù)據(jù)上評(píng)估它。

Listing 3.11 Retraining a model from scratch

model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=4, batch_size=512)
results = model.evaluate(x_test, y_test)

最終的結(jié)果如下:

>>> results
[0.2929924130630493, 0.88327999999999995]

這種相當(dāng)簡(jiǎn)單的方法的準(zhǔn)確率達(dá)到88%。使用最頂尖的方法,您應(yīng)該能夠接近95%。

3.4.5 使用訓(xùn)練過(guò)的網(wǎng)絡(luò)對(duì)新數(shù)據(jù)進(jìn)行預(yù)測(cè)

在訓(xùn)練了網(wǎng)絡(luò)之后,您將希望在實(shí)際環(huán)境中使用它。你可以使用預(yù)測(cè)方法產(chǎn)生正面評(píng)論的可能性:

>>> model.predict(x_test)
array([[ 0.98006207]
[ 0.99758697]
[ 0.99975556]
...,
[ 0.82167041]
[ 0.02885115]
[ 0.65371346]], dtype=float32)

如您所見(jiàn),對(duì)于某些樣本(0.99或以上,或0.01或更少),網(wǎng)絡(luò)是自信的,而對(duì)于其他樣本(0.6或0.4),網(wǎng)絡(luò)是不自信的。

3.4.6進(jìn)一步實(shí)驗(yàn)

以下實(shí)驗(yàn)將幫助說(shuō)服你,你的架構(gòu)選擇都相當(dāng)合理,但仍有改進(jìn)的余地:

  • 你使用兩個(gè)隱藏層。嘗試使用一個(gè)或三個(gè)隱藏層,看看這樣做如何影響驗(yàn)證和測(cè)試準(zhǔn)確性。
  • 嘗試使用層有更多隱藏的單位或更少的隱藏單位:32單元,64單元等等。
  • 嘗試使用mse代替binary_crossentropy損失函數(shù)。
  • 嘗試使用tanh激活函數(shù)(一種在神經(jīng)網(wǎng)絡(luò)早期很流行的激活函數(shù))而不是relu。

3.4.7結(jié)束

以下是你應(yīng)該從這個(gè)例子中吸取的教訓(xùn):

  • 您通常需要對(duì)原始數(shù)據(jù)進(jìn)行相當(dāng)多的預(yù)處理,以便能夠?qū)⑵渥鳛閺埩枯斎氲缴窠?jīng)網(wǎng)絡(luò)中。單詞序列可以編碼為二進(jìn)制向量,但也有其他編碼選項(xiàng)。
  • 使用relu激活函數(shù)的Dense層可以解決廣泛的問(wèn)題(包括情緒分類),你可能會(huì)經(jīng)常使用它們。
  • 在二分類問(wèn)題(兩個(gè)輸出類)中,網(wǎng)絡(luò)應(yīng)該以一個(gè)(隱藏)單元和一個(gè)sigmoid激活函數(shù)的密集(Dense)層結(jié)束:網(wǎng)絡(luò)的輸出應(yīng)該是0到1之間的標(biāo)量,編碼一個(gè)概率。
  • 在二元分類問(wèn)題上有這樣一個(gè)標(biāo)量sigmoid輸出的場(chǎng)景,您應(yīng)該使用的損失函數(shù)是binary_crossentropy。
  • 無(wú)論您有什么問(wèn)題,rmsprop優(yōu)化器通常都是一個(gè)足夠好的選擇。這是你不用擔(dān)心的一件事。
  • 隨著他們?cè)谟?xùn)練數(shù)據(jù)上的進(jìn)步,神經(jīng)網(wǎng)絡(luò)最終開始過(guò)擬合,最終在他們從未見(jiàn)過(guò)的數(shù)據(jù)上得到越來(lái)越糟糕的結(jié)果。一定要始終監(jiān)視訓(xùn)練集之外的數(shù)據(jù)的性能。

3.5 分類新聞專線:一個(gè)多分類的例子

在上一節(jié)中,您看到了如何使用緊密連接(densely connected)的神經(jīng)網(wǎng)絡(luò)將向量輸入分類為兩個(gè)相互排斥的類。但是如果你有兩種以上的分類會(huì)發(fā)生什么呢?
在本節(jié)中,您將構(gòu)建一個(gè)網(wǎng)絡(luò),將路透社新聞專線分為46個(gè)相互排斥的主題。因?yàn)槟阌泻芏囝悾@個(gè)問(wèn)題是一個(gè)多分類的實(shí)例;而且,由于每個(gè)數(shù)據(jù)點(diǎn)都應(yīng)該被劃分為一個(gè)類別,因此問(wèn)題更具體地說(shuō)就是一個(gè)單標(biāo)簽、多分類(single-label, multiclass classification.)的實(shí)例。如果每個(gè)數(shù)據(jù)點(diǎn)可能屬于多個(gè)類別(在本例中是主題),那么您將面臨一個(gè)多標(biāo)簽、多分類(multilabel, multiclass classification)問(wèn)題。

3.5.1路透社數(shù)據(jù)集

您將使用路透社數(shù)據(jù)集(Reuters dataset),這是一組簡(jiǎn)短的新聞專線及其主題,由路透社(Reuters)于1986年發(fā)布。這是一個(gè)簡(jiǎn)單的,廣泛使用的用于文本分類的玩具數(shù)據(jù)集。有46個(gè)不同的主題;有些主題比其他主題更有代表性,但是每個(gè)主題在訓(xùn)練集中至少有10個(gè)例子。
像IMDB和MNIST一樣,路透數(shù)據(jù)集也是Keras的一部分。讓我們來(lái)看看。

Listing 3.12 Loading the Reuters dataset

from keras.datasets import reuters
(train_data, train_labels), (test_data, test_labels) = reuters.load_data(
num_words=10000)

與IMDB數(shù)據(jù)集一樣,參數(shù)num_words=10000將數(shù)據(jù)限制為在數(shù)據(jù)中發(fā)現(xiàn)的10000個(gè)最常見(jiàn)的單詞。
您有8,982個(gè)培訓(xùn)示例和2,246個(gè)測(cè)試示例:

>>> len(train_data)
8982
>>> len(test_data)
2246

與IMDB評(píng)論一樣,每個(gè)示例都是一個(gè)整數(shù)列表(單詞索引):

>>> train_data[10]
[1, 245, 273, 207, 156, 53, 74, 160, 26, 14, 46, 296, 26, 39, 74, 2979,
3554, 14, 46, 4689, 4329, 86, 61, 3499, 4795, 14, 61, 451, 4329, 17, 12]

下面是你如何把它解碼成文字的方法,以滿足你的好奇心。

Listing 3.13 Decoding newswires back to text



與示例關(guān)聯(lián)的標(biāo)簽是0到45之間的整數(shù)——主題索引

>>> train_labels[10]
3

3.5.2 準(zhǔn)備數(shù)據(jù)

您可以使用與前面示例完全相同的代碼對(duì)數(shù)據(jù)進(jìn)行矢量化

Listing 3.14 Encoding the data



要對(duì)標(biāo)簽進(jìn)行矢量化,有兩種可能:您可以將標(biāo)簽列表轉(zhuǎn)換為整數(shù)張量,或者您可以使用one-hot編碼。one-hot編碼是一種廣泛用于分類數(shù)據(jù)的格式,也稱為分類編碼(categorical encoding)。有關(guān)one-hot編碼的更詳細(xì)解釋,請(qǐng)參閱第6.1節(jié)。在本例中,標(biāo)簽的one-hot編碼包括將每個(gè)標(biāo)簽嵌入為一個(gè)全零向量,在標(biāo)簽索引的位置用1代替。這里有一個(gè)例子:



注意,在Keras中有一種內(nèi)置的方法可以做到這一點(diǎn),您已經(jīng)在MNIST示例中看到了這一點(diǎn):
from keras.utils.np_utils import to_categorical
one_hot_train_labels = to_categorical(train_labels)
one_hot_test_labels = to_categorical(test_labels)

3.5.3 構(gòu)建網(wǎng)絡(luò)

這個(gè)主題分類問(wèn)題與前面的電影評(píng)論分類問(wèn)題類似:在這兩種情況下,您都試圖對(duì)簡(jiǎn)短的文本片段進(jìn)行分類。但是這里有一個(gè)新的限制:輸出類的數(shù)量從2個(gè)增加到46個(gè)。輸出空間的維數(shù)要大得多。
在您使用過(guò)的Dense層堆棧中,每個(gè)層只能訪問(wèn)前一層輸出的信息。如果有一層掉了一些與分類問(wèn)題相關(guān)的信息,這些信息后續(xù)的層永遠(yuǎn)無(wú)法恢復(fù):每一層都可能成為信息瓶頸。在前面的示例中,您使用了16維的中間層,但是一個(gè)16維的空間可能太有限,無(wú)法學(xué)習(xí)如何分離46個(gè)不同的類:這樣的小層可能成為信息瓶頸,永久地刪除相關(guān)信息。
因此,您將使用更大的層,共64個(gè)單元。

Listing 3.15 Model definition

from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(46, activation='softmax'))

關(guān)于這個(gè)架構(gòu),還有兩件事需要注意:

  • 以大小為46的Dense層結(jié)束網(wǎng)絡(luò)。這意味著對(duì)于每個(gè)輸入樣本,網(wǎng)絡(luò)將輸出一個(gè)46維的向量。這個(gè)向量中的每個(gè)元素
    (每個(gè)維度)將編碼不同的輸出類。
  • 最后一層使用softmax激活。您在MNIST示例中看到了這種模式。這意味著網(wǎng)絡(luò)將輸出46個(gè)不同輸出類的概率分布——對(duì)于每個(gè)輸入樣本,網(wǎng)絡(luò)將產(chǎn)生一個(gè)46維的輸出向量,其中output[i]是樣本屬于i類的概率。

在這種情況下,最好的損失函數(shù)是categorical_crossentropy。它測(cè)量了兩個(gè)概率分布之間的距離:這里,網(wǎng)絡(luò)輸出的概率分布和標(biāo)簽的真實(shí)分布之間的距離。通過(guò)最小化這兩個(gè)分布之間的距離,您可以訓(xùn)練網(wǎng)絡(luò)輸出盡可能接近真實(shí)標(biāo)簽的內(nèi)容。

Listing 3.16 Compiling the mode

model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])

3.5.4 驗(yàn)證你的方法

讓我們?cè)谟?xùn)練數(shù)據(jù)中分別設(shè)置1000個(gè)樣本作為驗(yàn)證集。

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:]s

現(xiàn)在,讓我們對(duì)網(wǎng)絡(luò)進(jìn)行20次的訓(xùn)練

Listing 3.18 Training the model

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

最后,讓我們顯示它的損失和精度曲線(見(jiàn)圖3.9和3.10)。

Listing 3.19 Plotting the training and validation loss

import matplotlib.pyplot as plt
loss = 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.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

Listing 3.20 Plotting the training and validation accuracy

plt.clf()
acc = history.history['acc']
val_acc = history.history['val_acc']
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()


網(wǎng)絡(luò)在經(jīng)歷了九個(gè)迭代之后開始過(guò)擬合。讓我們從零開始訓(xùn)練一個(gè)新的網(wǎng)絡(luò),歷時(shí)9個(gè)迭代,然后在測(cè)試集中評(píng)估它。
Listing 3.21 Retraining a model from scratch

model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(46, activation='softmax'))
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
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)

以下是最終結(jié)果:

>>> results
[0.9565213431445807, 0.79697239536954589]

這種方法的準(zhǔn)確率達(dá)到約80%。對(duì)于平衡二分類問(wèn)題,純隨機(jī)分類器的準(zhǔn)確率為50%。但在這種情況下,它接近19%, 所以結(jié)果看起來(lái)相當(dāng)不錯(cuò),至少與隨機(jī)基線相比是這樣的:

>>> import copy
>>> test_labels_copy = copy.copy(test_labels)
>>> np.random.shuffle(test_labels_copy)
>>> hits_array = np.array(test_labels) == np.array(test_labels_copy)
>>> float(np.sum(hits_array)) / len(test_labels)
0.18655387355298308

3.5.5 對(duì)新數(shù)據(jù)進(jìn)行預(yù)測(cè)

您可以驗(yàn)證模型實(shí)例的predict方法返回所有46個(gè)主題的概率分布。讓我們?yōu)樗袦y(cè)試數(shù)據(jù)生成主題預(yù)測(cè)。

Listing 3.22 Generating predictions for new data

predictions = model.predict(x_test)

預(yù)測(cè)中的每一項(xiàng)都是長(zhǎng)度為46的向量:

>>> predictions[0].shape
(46,)

這個(gè)向量系數(shù)的和是1:

>>> np.sum(predictions[0])
1.0

最大的條目是預(yù)測(cè)類——概率最高的類:

>>> np.argmax(predictions[0])
4

3.5.6 另一種處理標(biāo)簽和損失的方法

我們之前提到過(guò),編碼標(biāo)簽的另一種方法是將它們轉(zhuǎn)換成整數(shù)張量,如下所示:

y_train = np.array(train_labels)
y_test = np.array(test_labels)

這種方法唯一會(huì)改變的是損失函數(shù)的選擇。清單3.21中使用的loss函數(shù)categorical_crossentropy期望label遵循分類編碼。對(duì)于整數(shù)標(biāo)簽,您應(yīng)該使用sparse_categorical_crossentropy:

model.compile(optimizer='rmsprop',
loss='sparse_categorical_crossentropy',
metrics=['acc'])

這個(gè)新的損失函數(shù)在數(shù)學(xué)上仍然與categorical_crossentropy相同;它只是有一個(gè)不同的接口。

3.5.7具有足夠大的中間層的重要性

我們?cè)谇懊嫣岬竭^(guò),因?yàn)樽罱K的輸出是46維的,所以應(yīng)該避免中間層的隱藏單元遠(yuǎn)遠(yuǎn)少于46個(gè)。現(xiàn)在讓我們看看當(dāng)你引入一個(gè)信息瓶頸時(shí),如果中間層明顯小于46維:例如,4維:

Listing 3.23 A model with an information bottleneck

model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(4, activation='relu'))
model.add(layers.Dense(46, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(partial_x_train, partial_y_train, epochs=20, batch_size=128, validation_data=(x_val, y_val))

現(xiàn)在網(wǎng)絡(luò)的validation accuracy達(dá)到了71%,下降了8%。這種下降主要是由于您試圖將大量信息(需要足夠的信息以恢復(fù)46個(gè)類的分離超平面)壓縮到過(guò)低維的中間空間。網(wǎng)絡(luò)能夠?qū)⒋蟛糠直匾男畔⑷M(jìn)這些八維表示中,但并不是全部。

3.5.8進(jìn)一步的實(shí)驗(yàn)

  • 嘗試使用更大或更小的層:32個(gè)單元,128個(gè)單元等等。
  • 你使用兩個(gè)隱藏層。現(xiàn)在嘗試使用一個(gè)隱藏層,或者三個(gè)隱藏層。

3.5.9 結(jié)尾

以下是你應(yīng)該從這個(gè)例子中吸取的教訓(xùn):

  • 如果您試圖在N個(gè)類中分類數(shù)據(jù)點(diǎn),那么您的網(wǎng)絡(luò)應(yīng)該以大小為N的Dense層結(jié)尾。
  • 在單標(biāo)簽、多類分類問(wèn)題中,網(wǎng)絡(luò)應(yīng)該以softmax激活函數(shù)結(jié)束,這樣它就會(huì)輸出一個(gè)在N輸出類上的概率分布。
  • Categorical crossentropy幾乎總是這種問(wèn)題的損失函數(shù)。它使網(wǎng)絡(luò)輸出的概率分布與目標(biāo)的真實(shí)分布之間的距離最小化。
  • 在多類分類中有兩種處理標(biāo)簽的方法:
    --通過(guò)分類編碼(也稱為one-hot編碼),并使用categorical_crossentropy作為損失函數(shù)對(duì)標(biāo)簽進(jìn)行編碼
    -- 將標(biāo)簽編碼為整數(shù),并使用sparse_categorical_crossentropy loss函數(shù)
  • 如果需要將數(shù)據(jù)分類為大量的類別,則應(yīng)該避免由于中間層太小而在網(wǎng)絡(luò)中造成信息瓶頸

3.6預(yù)測(cè)房?jī)r(jià):一個(gè)回歸例子

前面的兩個(gè)例子被認(rèn)為是分類問(wèn)題,目標(biāo)是預(yù)測(cè)輸入數(shù)據(jù)點(diǎn)的單個(gè)離散標(biāo)簽。另一種常見(jiàn)的機(jī)器學(xué)習(xí)問(wèn)題是回歸,它由預(yù)測(cè)連續(xù)值而不是離散標(biāo)簽組成:例如,給定的氣象數(shù)據(jù),預(yù)測(cè)明天的溫度;或者給定它的規(guī)格,預(yù)測(cè)一個(gè)軟件項(xiàng)目完成的時(shí)間.
注意: 不要混淆回歸和logistic regression算法。令人困惑的是,logistic regression不是一種回歸算法——而是一種分類算法。

3.6.1波士頓房?jī)r(jià)數(shù)據(jù)集

你將嘗試?yán)媒o出的當(dāng)時(shí)該郊區(qū)的數(shù)據(jù)點(diǎn),比如犯罪率,當(dāng)?shù)胤慨a(chǎn)稅率等等,預(yù)測(cè)20世紀(jì)70年代中期波士頓某郊區(qū)的房?jī)r(jià)中值。您將使用的數(shù)據(jù)集與前面兩個(gè)示例有一個(gè)有趣的區(qū)別。它的數(shù)據(jù)點(diǎn)相對(duì)較少:只有506個(gè),分為404個(gè)訓(xùn)練樣本和102個(gè)測(cè)試樣本。以及輸入數(shù)據(jù)中的每個(gè)特征(例如,犯罪率)有不同的規(guī)模。例如,有些值是概率,它們的值在0和1之間;另一些取1到1之間的值等等。

Listing 3.24 Loading the Boston housing dataset

from keras.datasets import boston_housing
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()

查看下數(shù)據(jù):

>>> train_data.shape
(404, 13)
>>> test_data.shape
(102, 13)

如您所見(jiàn),您有404個(gè)訓(xùn)練樣本和102個(gè)測(cè)試樣本,每個(gè)樣本都有13個(gè)數(shù)值特征,例如人均犯罪率、人均住房數(shù)量、高速公路的可達(dá)性等等。
目標(biāo)是業(yè)主自住房屋的中值,單位為數(shù)千美元:

>>> train_targets
[ 15.2, 42.3, 50. ... 19.4, 19.4, 29.1]

價(jià)格一般在1萬(wàn)到5萬(wàn)美元之間。如果這聽(tīng)起來(lái)很便宜,請(qǐng)記住,這是在上世紀(jì)70年代中期,而且這些價(jià)格沒(méi)有根據(jù)通脹進(jìn)行調(diào)整。

3.6.2準(zhǔn)備數(shù)據(jù)

如果將所有的神經(jīng)網(wǎng)絡(luò)值都包含在大不相同的范圍內(nèi),那將是一個(gè)問(wèn)題。網(wǎng)絡(luò)可能能夠自動(dòng)適應(yīng)這種異構(gòu)數(shù)據(jù),但它肯定會(huì)使學(xué)習(xí)變得更加困難。廣泛的最佳實(shí)踐來(lái)處理這樣的數(shù)據(jù)是feature的normalization:對(duì)于輸入數(shù)據(jù)中的每個(gè)特征(輸入數(shù)據(jù)矩陣中的一列),減去特征的平均值并除以標(biāo)準(zhǔn)差,使特征的中心為0,并且有一個(gè)單位標(biāo)準(zhǔn)差。這在Numpy中很容易做到。

Listing 3.25 Normalizing the data

mean = train_data.mean(axis=0)
train_data -= mean
std = train_data.std(axis=0)
train_data /= std
test_data -= mean
test_data /= std

注意,用于標(biāo)準(zhǔn)化測(cè)試數(shù)據(jù)的數(shù)值是使用訓(xùn)練數(shù)據(jù)計(jì)算的。您永遠(yuǎn)不應(yīng)該在您的工作流中使用對(duì)測(cè)試數(shù)據(jù)進(jìn)行任何數(shù)量的計(jì)算,即使對(duì)于像數(shù)據(jù)規(guī)范化這樣簡(jiǎn)單的事情也是如此。


備注:0均值標(biāo)準(zhǔn)化(Z-score standardization)
0均值歸一化方法將原始數(shù)據(jù)集歸一化為均值為0、方差1的數(shù)據(jù)集,歸一化公式如下:



其中,μ、σ分別為原始數(shù)據(jù)集的均值和標(biāo)準(zhǔn)。該種歸一化方式要求原始數(shù)據(jù)的分布可以近似為高斯分布,否則歸一化的效果會(huì)變得很糟糕。
在分類、聚類算法中,需要使用距離來(lái)度量相似性的時(shí)候、或者使用PCA技術(shù)進(jìn)行降維的時(shí)候,第二種方法(Z-score standardization)表現(xiàn)更好。

3.6.3 構(gòu)建網(wǎng)絡(luò)

由于可供使用的樣本非常少,所以您將使用一個(gè)非常小的網(wǎng)絡(luò),其中包含兩個(gè)隱藏層,每個(gè)層有64個(gè)單元。一般來(lái)說(shuō),您擁有的訓(xùn)練數(shù)據(jù)越少,過(guò)度擬合就越糟糕,使用一個(gè)小網(wǎng)絡(luò)是緩解過(guò)度擬合的一種方法。

Listing 3.26 Model definition


網(wǎng)絡(luò)以1個(gè)單元結(jié)束,沒(méi)有激活函數(shù)(它將是一個(gè)線性層)。這是標(biāo)量回歸的一個(gè)典型設(shè)置(在你試圖預(yù)測(cè)單個(gè)連續(xù)值的情況下)。應(yīng)用激活函數(shù)將限制輸出的范圍,例如,如果將sigmoid激活函數(shù)應(yīng)用到最后一層,則網(wǎng)絡(luò)只能學(xué)會(huì)預(yù)測(cè)0到1之間的值。在這里,因?yàn)樽詈笠粚邮羌兙€性的,網(wǎng)絡(luò)可以自由地學(xué)習(xí)在任何范圍內(nèi)預(yù)測(cè)值。
注意,您使用mse損失函數(shù)---均方差(即預(yù)測(cè)和目標(biāo)差的平方)來(lái)編譯網(wǎng)絡(luò)。這是一個(gè)廣泛用于回歸問(wèn)題的損失函數(shù)。
您還在訓(xùn)練期間監(jiān)視一個(gè)新的度量:平均絕對(duì)誤差(MAE,備注:MAD=(x-mean(x))./n;)。它是預(yù)測(cè)和目標(biāo)之間差值的絕對(duì)值。例如,在這個(gè)問(wèn)題上的平均誤差為0.5美元意味著你的預(yù)測(cè)平均誤差為500美元。

3.6.4使用K-fold驗(yàn)證來(lái)驗(yàn)證您的方法(備注:交叉驗(yàn)證法)

為了評(píng)估您的網(wǎng)絡(luò),同時(shí)不斷調(diào)整它的參數(shù)(例如用于訓(xùn)練的epochs的數(shù)量),您可以將數(shù)據(jù)分為訓(xùn)練集和驗(yàn)證集,就像前面的示例所做的那樣。但是由于數(shù)據(jù)點(diǎn)太少,驗(yàn)證集最終會(huì)非常小(例如,大約100個(gè)示例)。因此,驗(yàn)證分值可能會(huì)根據(jù)您選擇使用哪些數(shù)據(jù)點(diǎn)進(jìn)行驗(yàn)證,以及您選擇了哪些數(shù)據(jù)點(diǎn)進(jìn)行訓(xùn)練而發(fā)生很大的變化:根據(jù)驗(yàn)證分割,驗(yàn)證分值可能有很大的差異。這將妨礙您可靠地評(píng)估您的模型。
這種情況下的最佳實(shí)踐是使用K-fold交叉驗(yàn)證(參見(jiàn)圖3.11)。它包括將可用數(shù)據(jù)分成K個(gè)分區(qū)(通常K = 4或5),實(shí)例化K個(gè)相同的模型,并在K - 1分區(qū)上對(duì)每個(gè)模型進(jìn)行訓(xùn)練,同時(shí)對(duì)其余分區(qū)進(jìn)行評(píng)估。使用的模型的驗(yàn)證分?jǐn)?shù)是得到的K個(gè)驗(yàn)證分?jǐn)?shù)的平均值。就代碼而言,這很簡(jiǎn)單。


Listing 3.27 K-fold validation




在num_epochs = 100中運(yùn)行這個(gè)程序會(huì)得到以下結(jié)果:

>>> all_scores
[2.588258957792037, 3.1289568449719116, 3.1856116051248984, 3.0763342615401386]
>>> np.mean(all_scores)
2.9947904173572462

不同的運(yùn)行確實(shí)顯示了相當(dāng)不同的驗(yàn)證分?jǐn)?shù),從2.6到3.2。平均值(3.0)比任何一個(gè)分?jǐn)?shù)都要可靠得多——這就是K-fold交叉驗(yàn)證的全部要點(diǎn)。在這種情況下,你平均損失了3000美元,考慮到價(jià)格從1萬(wàn)美元到5萬(wàn)美元,這是很重要的。
讓我們?cè)囍丫W(wǎng)絡(luò)訓(xùn)練得更長(zhǎng)一點(diǎn):500次迭代。為了記錄模型在每個(gè)epoch中的表現(xiàn),您將修改訓(xùn)練循環(huán)以保存每次epoch驗(yàn)證得分日志。

Listing 3.28 Saving the validation logs at each fold



然后,您可以計(jì)算所有折疊項(xiàng)的每個(gè)epoch MAE得分的平均值。

Listing 3.29 Building the history of successive mean K-fold validation scores

average_mae_history = [np.mean([x[i] for x in all_mae_histories]) for i in range(num_epochs)]

讓我們繪制它;見(jiàn)圖3.12

Listing 3.30 Plotting validation scores

import matplotlib.pyplot as plt
plt.plot(range(1, len(average_mae_history) + 1), average_mae_history)
plt.xlabel('Epochs')
plt.ylabel('Validation MAE')
plt.show()

由于規(guī)模問(wèn)題和相對(duì)較高的方差,可能很難看到圖。讓我們做以下事情:

  • 省略前10個(gè)數(shù)據(jù)點(diǎn),這些數(shù)據(jù)點(diǎn)與曲線的其他部分的尺度不同。
  • 將每個(gè)點(diǎn)替換為前面點(diǎn)的指數(shù)移動(dòng)平均值,以獲得平滑曲線。
    結(jié)果如圖3.13所示

Listing 3.31 Plotting validation scores, excluding the first 10 data points

def smooth_curve(points, factor=0.9):
smoothed_points = []
for point in points:
    if smoothed_points:
       previous = smoothed_points[-1]
       smoothed_points.append(previous * factor + point * (1 - factor))
    else:
       smoothed_points.append(point)
return smoothed_points
smooth_mae_history = smooth_curve(average_mae_history[10:])
plt.plot(range(1, len(smooth_mae_history) + 1), smooth_mae_history)
plt.xlabel('Epochs')
plt.ylabel('Validation MAE')
plt.show()

根據(jù)這個(gè)圖,驗(yàn)證MAE在80年代后停止明顯的改善。過(guò)了這個(gè)點(diǎn),你就開始過(guò)擬合了。
一旦你完成了優(yōu)化模型的其他參數(shù)(除了epochs的數(shù)量外,您還可以調(diào)整隱藏層的大小),你可以用最好的參數(shù),訓(xùn)練最終生產(chǎn)模型的訓(xùn)練數(shù)據(jù),然后看看它的性能測(cè)試數(shù)據(jù)。

Listing 3.32 Training the final model


最終的結(jié)果是:

>>> test_mae_score
2.5532484335057877

你還差2550美元。

3.6.5 結(jié)尾

以下是你應(yīng)該從這個(gè)例子中吸取的教訓(xùn):

  • 回歸是使用不同于我們用于分類的損失函數(shù)來(lái)完成的。均方誤差(Mean squared error, MSE)是一種常用的回歸損失函數(shù)。
  • 同樣,用于回歸的評(píng)價(jià)指標(biāo)與用于分類的評(píng)價(jià)指標(biāo)不同;當(dāng)然,accuracy的概念并不適用于回歸。一個(gè)常見(jiàn)的回歸指標(biāo)是平均絕對(duì)誤差(MAE)。
  • 當(dāng)輸入數(shù)據(jù)中的特征具有不同范圍的值時(shí),每個(gè)特征都應(yīng)該作為預(yù)處理步驟獨(dú)立地進(jìn)行縮放。
  • 當(dāng)可用數(shù)據(jù)很少時(shí),使用K-fold驗(yàn)證是可靠地評(píng)估模型的好方法。
  • 當(dāng)可用的訓(xùn)練數(shù)據(jù)很少時(shí),最好使用一個(gè)隱藏層很少的小網(wǎng)絡(luò)(通常只有一個(gè)或兩個(gè)),以避免嚴(yán)重的過(guò)擬合。

章節(jié)總結(jié)

  • 現(xiàn)在您可以處理向量數(shù)據(jù)上最常見(jiàn)的機(jī)器學(xué)習(xí)任務(wù):二分類、多分類和標(biāo)量回歸。本章前面的“總結(jié)”部分總結(jié)了關(guān)于這類任務(wù)的要點(diǎn)。
  • 在將原始數(shù)據(jù)輸入神經(jīng)網(wǎng)絡(luò)之前,通常需要對(duì)其進(jìn)行預(yù)處理。
  • 當(dāng)您的數(shù)據(jù)具有不同范圍的特性時(shí),作為預(yù)處理的一部分,獨(dú)立地縮放每個(gè)特性。
  • 隨著訓(xùn)練的進(jìn)行,神經(jīng)網(wǎng)絡(luò)最終開始過(guò)適應(yīng),并在從未見(jiàn)過(guò)的數(shù)據(jù)上得到更糟糕的結(jié)果。
  • 如果你沒(méi)有太多的訓(xùn)練數(shù)據(jù),使用一個(gè)只有一兩個(gè)隱藏層的小網(wǎng)絡(luò),以避免嚴(yán)重的過(guò)度擬合。
  • 如果您的數(shù)據(jù)被劃分為許多類別,如果您使中間層太小,可能會(huì)導(dǎo)致信息瓶頸。
  • 對(duì)比分類,回歸使用不同的損失函數(shù)和不同的評(píng)價(jià)指標(biāo)。
  • 當(dāng)您處理少量數(shù)據(jù)時(shí),K-fold驗(yàn)證可以幫助可靠地評(píng)估您的模型。

備注:關(guān)于指數(shù)平均數(shù)指標(biāo):https://baike.baidu.com/item/EMA,要比較均價(jià)的趨勢(shì)快慢時(shí),用EMA更穩(wěn)定;有時(shí),在均價(jià)值不重要時(shí),也用EMA來(lái)平滑和美觀曲線。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,860評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,025評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,421評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,642評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,177評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,970評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,157評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,410評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,896評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,157評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容