深度學習——資料預處理篇

jmuyjl發表於2019-02-18

深度學習——資料預處理篇

一、前言

深度學習和機器學習一個重要的區別就是在於資料量的大小。就目前的大量實驗
和工作證明,資料量的大小能夠直接影響深度學習的效能,我們都希望能夠利用
小的資料集,簡單的演算法就能夠取得不錯的效果,但目前的事實是小資料集上使
用深度學習,往往效果沒那麼理想,所以老師也常常說,深度學習的三駕馬車:
網路、損失、資料,由此可見資料對深度學習的重要性。

資料預處理在眾多深度學習演算法中都起著重要作用。首先資料的採集就非常的費時費力,因為這些資料需要考慮各種因素,然後有時還需對資料進行繁瑣的標註。當這些都有了後,就相當於我們有了原始的raw資料,然後就可以進行下面的資料預處理部分了。

二、常用的資料預處理方法

在這之前我們假設資料表示成矩陣為X,其中我們假定X是N×D維矩陣,N是樣本資料量,D為單張圖片的資料向量長度。假設要處理的影像是5×5的彩色影像,那麼D即5×5×3=75(因為彩色影像有RGB三個通道),假設N=1000,那麼X就是1000×75的矩陣,即1000行影像的資訊,每一行代表一個影像的資訊。

  1. 零均值化(中心化)

    在深度學習中,一般我們會把餵給網路模型的訓練圖片進行預處理,使用最多的方法就是零均值化(zero-mean) / 中心化,簡單說來,它做的事情就是,對待訓練的每一張圖片的特徵,都減去全部訓練集圖片的特徵均值,這麼做的直觀意義就是,我們把輸入資料各個維度的資料都中心化到0了。幾何上的展現是可以將資料的中心移到座標原點。如下圖中zero-centered data(當然,其實這裡也有不同的做法:我們可以直接求出所有畫素的均值,然後每個畫素點都減掉這個相同的值;稍微優化一下,我們可以在RGB三個顏色通道分別做這件事)

    零均值化的程式碼為:

    X -= np.mean(X, axis = 0)# axis=0,計算每一列的均值,壓縮行
    
    # 舉個例子,假設訓練圖片有5000張,圖片大小為32*32,通道數為3,則用python表示如下:
    x_train = load_data(img_dir)  # 讀取圖片資料 x_train的shape為(5000,32,32,3)
    x_train = np.reshape(x_train, (x_train.shape[0], -1))  # 將圖片從二維展開為一維,x_train 變為(5000,3072)
    mean_image = np.mean(x_train, axis=0)  # 求出所有圖片每個畫素位置上的平均值 mean_image為(1, 3072)
    x_train -= mean_image  # 減去均值影像,實現零均值化
    
    # 即讓所有訓練圖片中每個位置的畫素均值為0,使得畫素值範圍變為[-128,127],以0為中心。
    


    例如在吳恩達的作業中就有說到,機器學習中一個常見的預處理步驟是對資料集進行集中和標準化,這意味著從每個示例中減去整個numpy陣列的平均值,然後將每個示例除以整個numpy陣列的標準差。但是對於圖片資料集來說,將資料集的每一行除以255(畫素通道的最大值)會更簡單、更方便,而且幾乎同樣有效。

  2. 資料歸一化(normalization)

    歸一化就是要把你需要處理的資料經過處理後(通過某種演算法)限制在你需要的一定範圍內。舉個容易理解的例子,在房價預測那題中,假設房價是由面積s和臥室數b決定,面積s在0200之間,臥室數b在05之間,則進行歸一化就是s=s/200,b=b/5. 就是把這兩個資料"歸到1內",所以叫歸一化。

    通常我們有兩種方法來實現歸一化:

    • 一個是在資料都去均值之後,每個維度上的資料都除以這個維度上資料的標準差,即

      X /= np.std(X, axis = 0)
      
    • 另外一種方式是我們除以資料絕對值的最大值,以保證所有的資料歸一化後都在-1到1之間。如上述的房價例子。

    如圖normalized data即為歸一化

  3. 主成分分析(PCA、Principal Component Analysis)

    這是一種使用廣泛的資料降維演算法,是一種無監督學習方法,主要是用來將特徵的主要分成找出,並去掉基本無關的成分,從而達到降維的目的。

    總結一下PCA的演算法步驟:
    設有n條m維資料。

    1. 將原始資料按列組成m行n列矩陣X

    2. 將X的每一行(代表一個屬性欄位)進行零均值化

    3. 求出協方差矩陣
      C = 1 m X X T C=\frac{1}{m}XX^{T} C=m1XXT

    4. 求出協方差矩陣的特徵值及對應的特徵向量

    5. 將特徵向量按對應特徵值大小從上到下按行排列成矩陣,取前k行組成矩陣P

    6. Y=P×X即為降維到k維後的資料

    程式碼如下:

    # 假定輸入資料矩陣X是[N*D]維的
    X -= np.mean(X, axis = 0) # 去均值
    cov = np.dot(X.T, X) / X.shape[0] # 計算協方差
    U,S,V = np.linalg.svd(cov)
    Xrot = np.dot(X, U) # decorrelate the data
    Xrot_reduced = np.dot(X, U[:,:100]) # Xrot_reduced becomes [N x 100]
    
    

    PCA處理結果如圖中的decorrelated data:

  4. 白化(whitening)

    就是把各個特徵軸上的資料除以對應特徵值,從而達到在每個特徵軸上都歸一化幅度的結果。也就是在PCA的基礎上再除以每一個特徵的標準差,以使其normalization,其標準差就是奇異值的平方根:

    # whiten the data:
    # divide by the eigenvalues (which are square roots of the singular values)
    Xwhite = Xrot / np.sqrt(S + 1e-5)
    

    但是白化因為將資料都處理到同一個範圍內了,所以如果原始資料有原本影響不大的噪聲,它原本小幅的噪聲也會放大到與全域性相同的範圍內了。
    另外我們為了防止出現除以0的情況在分母處多加了0.00001,如果增大他會使噪聲減小。
    白化之後得到是一個多元高斯分佈,如下圖whitened所示:

    可以看出經過PCA的去相關操作,將原始資料的座標旋轉,並且可以看出x方向的資訊量比較大,如果只選一個特徵,那麼就選橫軸方向的特徵,經過白化之後資料進入了相同的範圍。

三、注意事項

以上只是總結資料預處理的方法而已,並不是說每次都會用這麼多方法,相反,在影像資料處理或者CNN中,一般只需要進行去均值和歸一化,不需要PCA和白化

程式碼如下:

X -= np.mean(X, axis = 0) # 減去均值,使得以0為中心
X /= np.std(X, axis = 0) # 歸一化

常見陷阱:在進行資料的預處理時(比如計算資料均值),我們只能在訓練資料上進行,然後應用到驗證/測試資料上。如果我們對整個資料集-整個資料集的均值,然後再進行訓練/驗證/測試資料的分割的話,這樣是不對的。正確做法是計算訓練資料的均值,然後分別把它從訓練/驗證/測試資料中減去。

四、References

相關文章