[動手學深度學習-PyTorch版]-3.11深度學習基礎(chǔ)-模型選擇憨降、欠擬合和過擬合

3.11 模型選擇描焰、欠擬合和過擬合

在前幾節(jié)基于Fashion-MNIST數(shù)據(jù)集的實驗中瘫证,我們評價了機器學習模型在訓練數(shù)據(jù)集和測試數(shù)據(jù)集上的表現(xiàn)咐容。如果你改變過實驗中的模型結(jié)構(gòu)或者超參數(shù)舆逃,你也許發(fā)現(xiàn)了:當模型在訓練數(shù)據(jù)集上更準確時,它在測試數(shù)據(jù)集上卻不一定更準確戳粒。這是為什么呢路狮?

3.11.1 訓練誤差和泛化誤差

在解釋上述現(xiàn)象之前,我們需要區(qū)分訓練誤差(training error)和泛化誤差(generalization error)蔚约。通俗來講奄妨,前者指模型在訓練數(shù)據(jù)集上表現(xiàn)出的誤差,后者指模型在任意一個測試數(shù)據(jù)樣本上表現(xiàn)出的誤差的期望苹祟,并常常通過測試數(shù)據(jù)集上的誤差來近似砸抛。計算訓練誤差和泛化誤差可以使用之前介紹過的損失函數(shù),例如線性回歸用到的平方損失函數(shù)和softmax回歸用到的交叉熵損失函數(shù)树枫。

讓我們以高考為例來直觀地解釋訓練誤差和泛化誤差這兩個概念直焙。訓練誤差可以認為是做往年高考試題(訓練題)時的錯誤率,泛化誤差則可以通過真正參加高考(測試題)時的答題錯誤率來近似砂轻。假設(shè)訓練題和測試題都隨機采樣于一個未知的依照相同考綱的巨大試題庫奔誓。如果讓一名未學習中學知識的小學生去答題,那么測試題和訓練題的答題錯誤率可能很相近搔涝。但如果換成一名反復練習訓練題的高三備考生答題厨喂,即使在訓練題上做到了錯誤率為0和措,也不代表真實的高考成績會如此。

在機器學習里杯聚,我們通常假設(shè)訓練數(shù)據(jù)集(訓練題)和測試數(shù)據(jù)集(測試題)里的每一個樣本都是從同一個概率分布中相互獨立地生成的臼婆。基于該獨立同分布假設(shè)幌绍,給定任意一個機器學習模型(含參數(shù))颁褂,它的訓練誤差的期望和泛化誤差都是一樣的。例如傀广,如果我們將模型參數(shù)設(shè)成隨機值(小學生)颁独,那么訓練誤差和泛化誤差會非常相近。但我們從前面幾節(jié)中已經(jīng)了解到伪冰,模型的參數(shù)是通過在訓練數(shù)據(jù)集上訓練模型而學習出的誓酒,參數(shù)的選擇依據(jù)了最小化訓練誤差(高三備考生)。所以贮聂,訓練誤差的期望小于或等于泛化誤差靠柑。也就是說,一般情況下吓懈,由訓練數(shù)據(jù)集學到的模型參數(shù)會使模型在訓練數(shù)據(jù)集上的表現(xiàn)優(yōu)于或等于在測試數(shù)據(jù)集上的表現(xiàn)歼冰。由于無法從訓練誤差估計泛化誤差,一味地降低訓練誤差并不意味著泛化誤差一定會降低耻警。

機器學習模型應關(guān)注降低泛化誤差隔嫡。

3.11.2 模型選擇

在機器學習中,通常需要評估若干候選模型的表現(xiàn)并從中選擇模型甘穿。這一過程稱為模型選擇(model selection)腮恩。可供選擇的候選模型可以是有著不同超參數(shù)的同類模型温兼。以多層感知機為例秸滴,我們可以選擇隱藏層的個數(shù),以及每個隱藏層中隱藏單元個數(shù)和激活函數(shù)募判。為了得到有效的模型缸榛,我們通常要在模型選擇上下一番功夫。下面兰伤,我們來描述模型選擇中經(jīng)常使用的驗證數(shù)據(jù)集(validation data set)。

3.11.2.1 驗證數(shù)據(jù)集

從嚴格意義上講钧排,測試集只能在所有超參數(shù)和模型參數(shù)選定后使用一次敦腔。不可以使用測試數(shù)據(jù)選擇模型,如調(diào)參恨溜。由于無法從訓練誤差估計泛化誤差符衔,因此也不應只依賴訓練數(shù)據(jù)選擇模型找前。鑒于此,我們可以預留一部分在訓練數(shù)據(jù)集和測試數(shù)據(jù)集以外的數(shù)據(jù)來進行模型選擇判族。這部分數(shù)據(jù)被稱為驗證數(shù)據(jù)集躺盛,簡稱驗證集(validation set)。例如形帮,我們可以從給定的訓練集中隨機選取一小部分作為驗證集槽惫,而將剩余部分作為真正的訓練集。

然而在實際應用中辩撑,由于數(shù)據(jù)不容易獲取界斜,測試數(shù)據(jù)極少只使用一次就丟棄。因此合冀,實踐中驗證數(shù)據(jù)集和測試數(shù)據(jù)集的界限可能比較模糊各薇。從嚴格意義上講,除非明確說明君躺,否則本書中實驗所使用的測試集應為驗證集峭判,實驗報告的測試結(jié)果(如測試準確率)應為驗證結(jié)果(如驗證準確率)。

3.11.2.3 K折交叉驗證

image.png

3.11.3 欠擬合和過擬合

接下來棕叫,我們將探究模型訓練中經(jīng)常出現(xiàn)的兩類典型問題:一類是模型無法得到較低的訓練誤差林螃,我們將這一現(xiàn)象稱作欠擬合(underfitting);另一類是模型的訓練誤差遠小于它在測試數(shù)據(jù)集上的誤差谍珊,我們稱該現(xiàn)象為過擬合(overfitting)治宣。在實踐中,我們要盡可能同時應對欠擬合和過擬合砌滞。雖然有很多因素可能導致這兩種擬合問題侮邀,在這里我們重點討論兩個因素:模型復雜度和訓練數(shù)據(jù)集大小。

關(guān)于模型復雜度和訓練集大小對學習的影響的詳細理論分析可參見我寫的這篇博客贝润。

3.11.3.1 模型復雜度

image.png

因為高階多項式函數(shù)模型參數(shù)更多绊茧,模型函數(shù)的選擇空間更大,所以高階多項式函數(shù)比低階多項式函數(shù)的復雜度更高打掘。因此华畏,高階多項式函數(shù)比低階多項式函數(shù)更容易在相同的訓練數(shù)據(jù)集上得到更低的訓練誤差。給定訓練數(shù)據(jù)集尊蚁,模型復雜度和誤差之間的關(guān)系通常如圖3.4所示亡笑。給定訓練數(shù)據(jù)集,如果模型的復雜度過低横朋,很容易出現(xiàn)欠擬合仑乌;如果模型復雜度過高,很容易出現(xiàn)過擬合。應對欠擬合和過擬合的一個辦法是針對數(shù)據(jù)集選擇合適復雜度的模型晰甚。

image.png

3.11.3.2 訓練數(shù)據(jù)集大小

影響欠擬合和過擬合的另一個重要因素是訓練數(shù)據(jù)集的大小衙传。一般來說,如果訓練數(shù)據(jù)集中樣本數(shù)過少厕九,特別是比模型參數(shù)數(shù)量(按元素計)更少時蓖捶,過擬合更容易發(fā)生。此外扁远,泛化誤差不會隨訓練數(shù)據(jù)集里樣本數(shù)量增加而增大俊鱼。因此,在計算資源允許的范圍之內(nèi)穿香,我們通常希望訓練數(shù)據(jù)集大一些亭引,特別是在模型復雜度較高時,例如層數(shù)較多的深度學習模型皮获。

3.11.4 多項式函數(shù)擬合實驗

為了理解模型復雜度和訓練數(shù)據(jù)集大小對欠擬合和過擬合的影響焙蚓,下面我們以多項式函數(shù)擬合為例來實驗。首先導入實驗需要的包或模塊洒宝。

%matplotlib inline
import torch
import numpy as np
import sys
sys.path.append("..") 
import d2lzh_pytorch as d2l

3.11.4.1 生成數(shù)據(jù)集

image.png
n_train, n_test, true_w, true_b = 100, 100, [1.2, -3.4, 5.6], 5
features = torch.randn((n_train + n_test, 1))
poly_features = torch.cat((features, torch.pow(features, 2), torch.pow(features, 3)), 1) 
labels = (true_w[0] * poly_features[:, 0] + true_w[1] * poly_features[:, 1]
          + true_w[2] * poly_features[:, 2] + true_b)
labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)

看一看生成的數(shù)據(jù)集的前兩個樣本购公。

features[:2], poly_features[:2], labels[:2]

輸出:

(tensor([[-1.0613],
         [-0.8386]]), tensor([[-1.0613,  1.1264, -1.1954],
         [-0.8386,  0.7032, -0.5897]]), tensor([-6.8037, -1.7054]))

3.11.4.2 定義、訓練和測試模型

我們先定義作圖函數(shù)semilogy雁歌,其中 y 軸使用了對數(shù)尺度宏浩。

# 本函數(shù)已保存在d2lzh_pytorch包中方便以后使用
def semilogy(x_vals, y_vals, x_label, y_label, x2_vals=None, y2_vals=None,
             legend=None, figsize=(3.5, 2.5)):
    d2l.set_figsize(figsize)
    d2l.plt.xlabel(x_label)
    d2l.plt.ylabel(y_label)
    d2l.plt.semilogy(x_vals, y_vals)
    if x2_vals and y2_vals:
        d2l.plt.semilogy(x2_vals, y2_vals, linestyle=':')
        d2l.plt.legend(legend)

和線性回歸一樣,多項式函數(shù)擬合也使用平方損失函數(shù)靠瞎。因為我們將嘗試使用不同復雜度的模型來擬合生成的數(shù)據(jù)集比庄,所以我們把模型定義部分放在fit_and_plot函數(shù)中。多項式函數(shù)擬合的訓練和測試步驟與3.6節(jié)(softmax回歸的從零開始實現(xiàn))介紹的softmax回歸中的相關(guān)步驟類似乏盐。

num_epochs, loss = 100, torch.nn.MSELoss()

def fit_and_plot(train_features, test_features, train_labels, test_labels):
    net = torch.nn.Linear(train_features.shape[-1], 1)
    # 通過Linear文檔可知佳窑,pytorch已經(jīng)將參數(shù)初始化了,所以我們這里就不手動初始化了

    batch_size = min(10, train_labels.shape[0])    
    dataset = torch.utils.data.TensorDataset(train_features, train_labels)
    train_iter = torch.utils.data.DataLoader(dataset, batch_size, shuffle=True)

    optimizer = torch.optim.SGD(net.parameters(), lr=0.01)
    train_ls, test_ls = [], []
    for _ in range(num_epochs):
        for X, y in train_iter:
            l = loss(net(X), y.view(-1, 1))
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
        train_labels = train_labels.view(-1, 1)
        test_labels = test_labels.view(-1, 1)
        train_ls.append(loss(net(train_features), train_labels).item())
        test_ls.append(loss(net(test_features), test_labels).item())
    print('final epoch: train loss', train_ls[-1], 'test loss', test_ls[-1])
    semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'loss',
             range(1, num_epochs + 1), test_ls, ['train', 'test'])
    print('weight:', net.weight.data,
          '\nbias:', net.bias.data)

3.11.4.3 三階多項式函數(shù)擬合(正常)

image.png
fit_and_plot(poly_features[:n_train, :], poly_features[n_train:, :], 
            labels[:n_train], labels[n_train:])

輸出:

final epoch: train loss 0.00010175639908993617 test loss 9.790256444830447e-05
weight: tensor([[ 1.1982, -3.3992,  5.6002]]) 
bias: tensor([5.0014])
image

3.11.4.4 線性函數(shù)擬合(欠擬合)

我們再試試線性函數(shù)擬合父能。很明顯神凑,該模型的訓練誤差在迭代早期下降后便很難繼續(xù)降低。在完成最后一次迭代周期后何吝,訓練誤差依舊很高溉委。線性模型在非線性模型(如三階多項式函數(shù))生成的數(shù)據(jù)集上容易欠擬合。

fit_and_plot(features[:n_train, :], features[n_train:, :], labels[:n_train],
             labels[n_train:])

輸出:

final epoch: train loss 249.35157775878906 test loss 168.37705993652344
weight: tensor([[19.4123]]) 
bias: tensor([0.5805])
image.png

3.11.4.5 訓練樣本不足(過擬合)

事實上爱榕,即便使用與數(shù)據(jù)生成模型同階的三階多項式函數(shù)模型瓣喊,如果訓練樣本不足,該模型依然容易過擬合黔酥。讓我們只使用兩個樣本來訓練模型型宝。顯然八匠,訓練樣本過少了,甚至少于模型參數(shù)的數(shù)量趴酣。這使模型顯得過于復雜,以至于容易被訓練數(shù)據(jù)中的噪聲影響坑夯。在迭代過程中岖寞,盡管訓練誤差較低,但是測試數(shù)據(jù)集上的誤差卻很高柜蜈。這是典型的過擬合現(xiàn)象仗谆。

fit_and_plot(poly_features[0:2, :], poly_features[n_train:, :], labels[0:2],
             labels[n_train:])

輸出:

final epoch: train loss 1.198514699935913 test loss 166.037109375
weight: tensor([[1.4741, 2.1198, 2.5674]]) 
bias: tensor([3.1207])
image.png

我們將在接下來的兩個小節(jié)繼續(xù)討論過擬合問題以及應對過擬合的方法。

小結(jié)

  • 由于無法從訓練誤差估計泛化誤差淑履,一味地降低訓練誤差并不意味著泛化誤差一定會降低隶垮。機器學習模型應關(guān)注降低泛化誤差。
  • 可以使用驗證數(shù)據(jù)集來進行模型選擇秘噪。
  • 欠擬合指模型無法得到較低的訓練誤差狸吞,過擬合指模型的訓練誤差遠小于它在測試數(shù)據(jù)集上的誤差。
  • 應選擇復雜度合適的模型并避免使用過少的訓練樣本指煎。

注:本節(jié)除了代碼之外與原書基本相同蹋偏,原書傳送門

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市至壤,隨后出現(xiàn)的幾起案子威始,更是在濱河造成了極大的恐慌,老刑警劉巖像街,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件黎棠,死亡現(xiàn)場離奇詭異,居然都是意外死亡镰绎,警方通過查閱死者的電腦和手機脓斩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跟狱,“玉大人俭厚,你說我怎么就攤上這事∈浑” “怎么了挪挤?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長关翎。 經(jīng)常有香客問我扛门,道長,這世上最難降的妖魔是什么纵寝? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任论寨,我火速辦了婚禮星立,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘葬凳。我一直安慰自己绰垂,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布火焰。 她就那樣靜靜地躺著劲装,像睡著了一般。 火紅的嫁衣襯著肌膚如雪昌简。 梳的紋絲不亂的頭發(fā)上占业,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音纯赎,去河邊找鬼谦疾。 笑死,一個胖子當著我的面吹牛犬金,可吹牛的內(nèi)容都是我干的念恍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼佑附,長吁一口氣:“原來是場噩夢啊……” “哼樊诺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起音同,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤词爬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后权均,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體顿膨,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年叽赊,在試婚紗的時候發(fā)現(xiàn)自己被綠了恋沃。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡必指,死狀恐怖囊咏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情塔橡,我是刑警寧澤梅割,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站葛家,受9級特大地震影響户辞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜癞谒,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一底燎、第九天 我趴在偏房一處隱蔽的房頂上張望刃榨。 院中可真熱鬧,春花似錦双仍、人聲如沸枢希。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晴玖。三九已至,卻和暖如春为流,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背让簿。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工敬察, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尔当。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓莲祸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親椭迎。 傳聞我的和親對象是個殘疾皇子锐帜,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

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