1. 程式人生 > 其它 >Python深度學習4——機器學習基礎

Python深度學習4——機器學習基礎

4.機器學習基礎

4.1機器學習的四個分支

4.1.1監督學習

  • 監督學習是目前最常見的機器學習型別。給定一組樣本(通常由人工標註),它可以學會將輸入資料對映到已知目標[也叫標註(annotation)
  • 監督學習主要包括分類和迴歸,但還有更多的變體,主要包括如下幾種 :
    • 序列生成(sequence generation)。給定一張影象,預測描述影象的文字。序列生成有時可以被重新表示為一系列分類問題,比如反覆預測序列中的單詞或標記
    • 語法樹預測(syntax tree prediction)。給定一個句子,預測其分解生成的語法樹
    • 目標檢測(object detection)。給定一張影象,在圖中特定目標的周圍畫一個邊界框。這個問題也可以表示為分類問題(給定多個候選邊界框,對每個框內的目標進行分類)或分類與迴歸聯合問題(用向量迴歸來預測邊界框的座標)
    • 影象分割(image segmentation)。給定一張影象,在特定物體上畫一個畫素級的掩模(mask)

4.1.2無監督學習

  • 無監督學習是指在沒有目標的情況下尋找輸入資料的有趣變換,其目的在於資料視覺化、資料壓縮、資料去噪或更好地理解資料中的相關性
  • 降維(dimensionality reduction)和聚類(clustering)都是眾所周知的無監督學習方法。

4.1.3自監督學習

  • 自監督學習是沒有人工標註的標籤的監督學習,你可以將它看作沒有人類參與的監督學習。標籤仍然存在(因為總要有什麼東西來監督學習過程),但它們是從輸入資料中生成的,通常是使用啟發式演算法生成的
  • 自編碼器
    (autoencoder)是有名的自監督學習的例子,其生成的目標就是未經修改的輸入 。同樣,給定視訊中過去的幀來預測下一幀,或者給定文字中前面的詞來預測下一個詞,都是自監督學習的例子[這兩個例子也屬於時序監督學習(temporally supervised learning), 即用未來的輸入資料作為監督]

4.1.4強化學習

在強化學習中, 智慧體(agent)接收有關其環境的資訊,並學會選擇使某種獎勵最大化的行動

4.2評估機器學習模型

4.2.1訓練集、驗證集和測試集

  • 開發模型時總是需要調節模型配置,比如選擇層數或每層大小[這叫作模型的超引數(hyperparameter),以便與模型引數(即權重)
    區分開]。這個調節過程需要使用模型在驗證資料上的效能作為反饋訊號。這個調節過程本質上就是一種學習:在某個引數空間中尋找良好的模型配置
  • 資訊洩露(information leak)。每次基於模型在驗證集上的效能來調節模型超引數,都會有一些關於驗證資料的資訊洩露到模型中
  • 模型一定不能讀取與測試集有關的任何資訊,既使間接讀取也不行

1. 簡單的留出驗證 (hold-out validation )

  • 示意圖
  • 示例程式碼
num_validation_samples = 10000
np.random.shuffle(data)
validation_data = data[:num_validation_samples]
data = data[num_validation_samples:]
training_data = data[:]
model = get_model()
model.train(training_data)
validation_score = model.evaluate(validation_data)
# 現在你可以調節模型、重新訓練、評估,然後再次調節……
model = get_model()
model.train(np.concatenate([training_data,
validation_data]))
test_score = model.evaluate(test_data)
  • 缺點:如果可用的資料很少,那麼可能驗證集和測試集包含的樣本就太少,從而無法在統計學上代表資料

2. K 折驗證

  • K 折驗證(K-fold validation)將資料劃分為大小相同的 K 個分割槽。 對於每個分割槽 i,在剩餘的 K-1 個分割槽上訓練模型,然後在分割槽 i 上評估模型。最終分數等於 K 個分數的平均值
  • 示例程式碼
k = 4
num_validation_samples = len(data) // k
np.random.shuffle(data)
validation_scores = []
for fold in range(k):
    validation_data = data[num_validation_samples * fold:
        num_validation_samples * (fold + 1)]
    training_data = data[:num_validation_samples * fold] +
        data[num_validation_samples * (fold + 1):]
    model = get_model()
    model.train(training_data)
    validation_score = model.evaluate(validation_data)
    validation_scores.append(validation_score)
validation_score = np.average(validation_scores)
model = get_model()
model.train(data)
test_score = model.evaluate(test_data)

3. 帶有打亂資料的重複 K 折驗證

  • 如果可用的資料相對較少,而你又需要儘可能精確地評估模型,那麼可以選擇帶有打亂資料的重複 K 折驗證(iterated K-fold validation with shuffling)
  • 具體做法是多次使用 K 折驗證,在每次將資料劃分為 K 個分割槽之前都先將資料打亂。最終分數是每次 K 折驗證分數的平均值。注意,這種方法一共要訓練和評估 P×K 個模型(P是重複次數),計算代價很大

4.2.2評估模型的注意事項

  • 資料代表性(data representativeness)。你希望訓練集和測試集都能夠代表當前資料。因此,在將資料劃分為訓練集和測試集之前,通常應該隨機打亂資料
  • 時間箭頭(the arrow of time)。如果想要根據過去預測未來(比如明天的天氣、股票走勢等),那麼在劃分資料前你不應該隨機打亂資料,因為這麼做會造成時間洩露(temporal leak):你的模型將在未來資料上得到有效訓練。在這種情況下,你應該始終確保測試集中所有資料的時間都晚於訓練集資料
  • 資料冗餘(redundancy in your data)。如果資料中的某些資料點出現了兩次(這在現實中的資料裡十分常見),那麼打亂資料並劃分成訓練集和驗證集會導致訓練集和驗證集之間的資料冗餘 。一定要確保訓練集和驗證集之間沒有交集

4.3資料預處理、特徵工程和特徵學習

4.3.1神經網路的資料預處理

  1. 向量化:神經網路的所有輸入和目標都必須是浮點數張量(在特定情況下可以是整數張量)。無論處理什麼資料(聲音、影象還是文字),都必須首先將其轉換為張量,這一步叫作資料向量化(data vectorization)

  2. 值標準化:一般來說,將取值相對較大的資料(比如多位整數,比網路權重的初始值大很多)或異質資料(heterogeneous data,比如資料的一個特徵在 0~1 範圍內,另一個特徵在 100~200 範圍內)輸入到神經網路中是不安全的。這麼做可能導致較大的梯度更新,進而導致網路無法收斂 。輸入資料應該具有以下特徵 :取值較小:大部分值都應該在 0~1 範圍內;同質性(homogenous):所有特徵的取值都應該在大致相同的範圍內。更嚴格的標準化方法:將每個特徵分別標準化,使其平均值為 0 ;將每個特徵分別標準化,使其標準差為 1

    # 假設 x 是一個形狀為 (samples, features) 的二維矩陣
    x -= x.mean(axis=0)
    x /= x.std(axis=0)
    
  3. 處理缺失值:一般來說,對於神經網路,將缺失值設定為 0 是安全的,只要 0 不是一個有意義的值。網路能夠從資料中學到 0 意味著缺失資料,並且會忽略這個值。如果測試資料中可能有缺失值,而網路是在沒有缺失值的資料上訓練的,應該人為生成一些有缺失項的訓練樣本:多次複製一些訓練樣本,然後刪除測試資料中可能缺失的某些特徵

4.3.2特徵工程

  • 特徵工程(feature engineering)是指將資料輸入模型之前,利用你自己關於資料和機器學習演算法(這裡指神經網路)的知識對資料進行硬編碼的變換(不是模型學到的),以改善模型的效果

  • 特徵工程的本質:用更簡單的方式表述問題,從而使問題變得更容易

4.4過擬合與欠擬合

  • 機器學習的根本問題是優化和泛化之間的對立

  • 優化(optimization)是指調節模型以在訓練資料上得到最佳效能(即機器學習中的學習)

  • 泛化(generalization)是指訓練好的模型在前所未見的資料上的效能好壞

  • 訓練開始時,優化和泛化是相關的:訓練資料上的損失越小,測試資料上的損失也越小。這時的模型是欠擬合(underfit)的,即仍有改進的空間,網路還沒有對訓練資料中所有相關模式建模

  • 但在訓練資料上迭代一定次數之後,泛化不再提高,驗證指標先是不變,然後開始變差,即模型開始過擬合。這時模型開始學習僅和訓練資料有關的模式,但這種模式對新資料來說是錯誤的或無關緊要的

  • 最優解決方法是獲取更多的訓練資料。次優解決方法是調節模型允許儲存的資訊量,或對模型允許儲存的資訊加以約束

  • 降低過擬合的方法叫作正則化(regularization)

4.4.1減小網路大小

  • 減少模型中可學習引數的個數(這由層數和每層的單元個數決定)

  • 在深度學習中,模型中可學習引數的個數通常被稱為模型的容量(capacity)

  • 直觀上來看,引數更多的模型擁有更大的記憶容量(memorization capacity),因此能夠在訓練樣本和目標之間輕鬆地學會完美的字典式對映,這種對映沒有任何泛化能力

  • 另一方面,使用的模型應該具有足夠多的引數,以防欠擬合,即模型應避免記憶資源不足

  • 一般的工作流程是開始時選擇相對較少的層和引數,然後逐漸增加層的大小或增加新層,直到這種增加對驗證損失的影響變得很小

4.4.2新增權重正則化

  • 簡單模型比複雜模型更不容易過擬合。簡單模型(simple model)是指引數值分佈的熵更小的模型(或引數更少的模型)

  • 強制讓模型權重只能取較小的值,從而限制模型的複雜度,這使得權重值的分佈更加規則(regular)。這種方法叫作權重正則化(weight regularization),其實現方法是向網路損失函式中新增與較大權重值相關的成本(cost):

    • L1 正則化(L1 regularization):新增的成本與權重係數的絕對值[權重的 L1 範數(norm)]成正比
    • L2 正則化(L2 regularization):新增的成本與權重係數的平方(權重的 L2 範數)成正比。神經網路的 L2 正則化也叫權重衰減(weight decay)

4.4.3新增 dropout 正則化

  • 對某一層使用 dropout,就是在訓練過程中隨機將該層的一些輸出特徵捨棄(設定為 0)。 dropout 比率(dropout rate)是被設為 0 的特徵所佔的比例,通常在 0.2~0.5範圍內。測試時沒有單元被捨棄,而該層的輸出值需要按 dropout 比率縮小,因為這時比訓練時有更多的單元被啟用,需要加以平衡

  • 為了實現這一過程,還可以讓兩個運算都在訓練時進行,而測試時輸出保持不變

    layer_output *= np.random.randint(0, high=2, size=layer_output.shape)
    layer_output /= 0.5
    
  • 核心思想是在層的輸出值中引入噪聲,打破不顯著的偶然模式(Hinton 稱之為陰謀)。如果沒有噪聲的話,網路將會記住這些偶然模式

4.5機器學習的通用工作流程

4.5.1定義問題,收集資料集

  • 你的輸入資料是什麼?你要預測什麼?只有擁有可用的訓練資料,你才能學習預測某件事情。比如,只有同時擁有電影評論和情感標註,你才能學習對電影評論進行情感分類。因此,資料可用性通常是這一階段的限制因素

  • 你面對的是什麼型別的問題?是二分類問題、多分類問題、標量回歸問題、向量迴歸問題,還是多分類、多標籤問題?或者是其他問題,比如聚類、生成或強化學習?確定問題型別有助於你選擇模型架構、損失函式等

  • 有一類無法解決的問題你應該知道,那就是非平穩問題(nonstationary problem)

4.5.2選擇衡量成功的指標

  • 對於平衡分類問題(每個類別的可能性相同),精度和接收者操作特徵曲線下面積(area under the receiver operating characteristic curve, ROC AUC)是常用的指標
  • 對於類別不平衡的問題,你可以使用準確率和召回率
  • 對於排序問題或多標籤分類,你可以使用平均準確率均值(mean average precision)
  • 自定義衡量成功的指標也很常見

4.5.3確定評估方法

  • 留出驗證集。資料量很大時可以採用這種方法
  • K 折交叉驗證。如果留出驗證的樣本量太少,無法保證可靠性,那麼應該選擇這種方法
  • 重複的 K 折驗證。如果可用的資料很少,同時模型評估又需要非常準確,那麼應該使用這種方法

4.5.4準備資料

  • 如前所述,應該將資料格式化為張量
  • 這些張量的取值通常應該縮放為較小的值,比如在 [-1, 1] 區間或 [0, 1] 區間
  • 如果不同的特徵具有不同的取值範圍(異質資料),那麼應該做資料標準化
  • 你可能需要做特徵工程,尤其是對於小資料問題

4.5.5開發比基準更好的模型

  • 這一階段的目標是獲得統計功效(statistical power),即開發一個小型模型,它能夠打敗純隨機的基準(dumb baseline)

  • 要記住你所做的兩個假設:

    1. 假設輸出是可以根據輸入進行預測的
    2. 假設可用的資料包含足夠多的資訊,足以學習輸入和輸出之間的關係
  • 需要選擇三個關鍵引數來構建第一個工作模型:

    1. 最後一層的啟用。它對網路輸出進行有效的限制
    2. 損失函式。它應該匹配你要解決的問題的型別
    3. 優化配置。你要使用哪種優化器?學習率是多少?大多數情況下,使用 rmsprop 及其預設的學習率是穩妥的

4.5.6擴大模型規模:開發過擬合的模型

  • 要搞清楚你需要多大的模型,就必須開發一個過擬合的模型,這很簡單:新增更多的層;讓每一層變得更大;訓練更多的輪次
  • 如果你發現模型在驗證資料上的效能開始下降,那麼就出現了過擬合。下一階段將開始正則化和調節模型,以便儘可能地接近理想模型,既不過擬合也不欠擬合

4.5.7模型正則化與調節超引數

  • 你將不斷地調節模型、訓練、在驗證資料上評估(這裡不是測試資料)、再次調節模型,然後重複這一過程,直到模型達到最佳效能。你應該嘗試以下幾項:

    1. 新增 dropout
    2. 嘗試不同的架構:增加或減少層數
    3. 新增 L1 和 / 或 L2 正則化
    4. 嘗試不同的超引數(比如每層的單元個數或優化器的學習率),以找到最佳配置
    5. (可選)反覆做特徵工程:新增新特徵或刪除沒有資訊量的特徵
  • 請注意:每次使用驗證過程的反饋來調節模型,都會將有關驗證過程的資訊洩露到模型中。如果只重複幾次,那麼無關緊要;但如果系統性地迭代許多次,最終會導致模型對驗證過程過擬合

  • 一旦開發出令人滿意的模型配置,你就可以在所有可用資料(訓練資料 + 驗證資料)上訓練最終的生產模型,然後在測試集上最後評估一次

本章小結

  • 定義問題與要訓練的資料。收集這些資料,有需要的話用標籤來標註資料
  • 選擇衡量問題成功的指標。你要在驗證資料上監控哪些指標?
  • 確定評估方法:留出驗證? K 折驗證?你應該將哪一部分資料用於驗證?
  • 開發第一個比基準更好的模型,即一個具有統計功效的模型
  • 開發過擬合的模型
  • 基於模型在驗證資料上的效能來進行模型正則化與調節超引數