2018 年 12 月

第 33 卷 12

測試回合-使用 CNTK 的視覺效果的 Autoencoders

藉由James McCaffrey

James McCaffrey假設您有一群人將告訴您的資料。表示每個人的年齡值和高度值。如果您想要的圖形資料,可以放在 x 軸,y 軸上的高度的時代,彩色的點 (例如男性藍色) 與粉紅色用於女性。這樣就沒問題,資料會有兩個維度。

但是,如果您的資料具有六個的維度,例如年齡、 高度、 重量、 收入、 債務、 郵遞區號?若要繪製此類資料,其中一個方法是壓縮到兩個維度使用類神經網路 autoencoder 六個維度的資料。您將會遺失一些資訊,但您可以建構 2D 圖形。

請參閱這篇文章的走向的最佳方式是要看看的示範程式**[圖 1**。示範資料有 1,797 的項目。每個項目有 64 的維度,並符合其中一個 10 的類別。示範建立 Microsoft Cognitive Toolkit (CNTK) 類神經網路 autoencoder,壓縮到兩個維度,標示為 component1 和 componet2,每個項目,然後圖形的結果。會出現在資料中感興趣的模式。比方說,是類別 0 (黑點) 的資料項目是截然不同類別 7 項目 (橘色點)。但類別 8 項目 (紅點) 有一堆相似度類別 5 項目 (淺綠色的點)。

使用 CNTK 示範執行 Autoencoder 視覺效果
[圖 1 Autoencoder 視覺效果使用 CNTK 示範執行

本文假設您有中繼或更佳的程式設計技能,使用 C 系列語言和機器學習服務基本的認識,但不會假設您知道任何關於 autoencoders。所有示範的程式碼會顯示在這篇文章。完整的原始程式碼和示範程式所使用的資料檔案也會是本文所附的下載中取得項目。已移除所有一般錯誤檢查要保留的主要概念盡可能清楚。

了解資料

示範資料看起來像:

0,0,0,1,11,0,0,0,0,0,0,7,8, ... 16,4,0,0,4
0,0,9,14,8,1,0,0,0,0,12,14, ... 5,11,1,0,8
...

有 1,797 資料項目,其中每一行,而且每一行有 65 逗點分隔的值。每個資料行代表 8x8 個粗糙手寫數字。該行的第一次 64 值為灰階像素值,介於 0 到 16 之間。該行的最後一個值是數字值,因此第一個項目有像素值,表示"4",而第二個項目有像素值"8"。

示範 autoencoder 的目標是資料項目的減少到只有兩個值的 64 的尺寸,因此可做為 x y 圖形上的點繪製的項目。即使示範資料表示的影像,autoencoders 可以使用任何一種高維度的數值資料。

示範資料稱為 UCI 數字資料集,請參閱bit.ly/2xDW3IY,或在 [檔案下載本文所附。

安裝 CNTK

Microsoft CNTK 是功能強大的開放原始碼類神經網路的程式碼程式庫。CNTK 以 c + + 撰寫的效能,但基於方便性和例行性 Python API。您未安裝 CNTK 做為獨立的系統。首先,您要安裝,其中包含核心 Python 解譯器和數個數百個其他套件的 Python 的散發套件。然後您可以安裝 CNTK Python 附加元件套件的形式。

安裝 CNTK 可能很難。供示範,我第一次安裝 Anaconda3 4.1.1 Windows,在 repo.continuum.io/archive 使用好用的自動解壓縮可執行檔的散發。散發包含 Python 3.5.2 和 CNTK 所需的數個封裝。

接下來,我藉由下載相容安裝 CNTK v2.4 CPU 專用 (我的電腦沒有 GPU) CNTK.whl 檔案,以從本機電腦bit.ly/2OfCCQg。然後我開啟命令殼層,瀏覽至包含 CNTK.whl 檔案的目錄並輸入命令:

> pip install cntk-2.4-cp35-cp35m-win_amd64.whl

如果您還不熟悉 Python,您可以鬆散想像為有點類似.msi 安裝檔案的一個.whl 檔,為有點類似 Windows 安裝程式的 pip。Python 是相當脆弱,關於版本控制,因此您一定要非常小心,若要安裝的 Anaconda Python 和 CNTK 的相容版本。絕大多數的 CNTK 安裝問題,看直接相關的版本不相容。

示範程式

示範程式,以節省空間,少數稍加編輯的結構會顯示在中的列表**[圖 2**。縮排兩個空格,而不是一般的四個空格,以節省空間。並請注意,Python 會使用"\"字元的行接續符號。我可以使用 [記事本] 來編輯我的程式。我的同事大多偏好較複雜的編輯器中,但 [記事本] 的簡單性固然很好。

[圖 2 Autoencoder 示範程式結構

# digits_autoenc.py
# condense the UCI digits to two dimensions
# CNTK 2.4 Anaconda3 4.1.1 (Python 3.5.2)
import numpy as np
import cntk as C
import matplotlib.pyplot as plt
def main():
  # 0. get started
  print("Begin UCI digits autoencoder with CNTK demo ")
  np.random.seed(1)
  # 1. load data into memory
  # 2. define autoencoder
  # 3. train model
  # 4. generate (x,y) pairs for each data item
  # 5. graph the data in 2D
  print("End autoencoder using CNTK demo ")
if __name__ == "__main__":
  main()

示範程式的名稱為 digits_autoenc.py,它一開始會 NumPy、 CNTK 和 Pyplot 套件匯入。NumPy 可讓 Python 中的基本數值作業和 Pyplot 用來顯示散佈圖所示**[圖 1**。之後啟動訊息時,程式執行開始藉由設定全域 NumPy 隨機種子,因此結果會是可重現。

示範載入使用 NumPy loadtxt 函式的記憶體中的定型資料:

data_file = ".\\Data\\digits_uci_test_1797.txt"
data_x = np.loadtxt(data_file, delimiter=",",
  usecols=range(0,64), dtype=np.float32)
labels = np.loadtxt(data_file, delimiter=",",
  usecols=[64], dtype=np.float32)
data_x = data_x / 16

程式碼會假設資料位於名為 Data 的子目錄。Loadtxt 函式有許多選擇性參數。在此情況下,函式呼叫指定的資料是以逗號分隔。Float32 資料型別是 CNTK 的預設值,因此我可以省略明確指定它。Data_x 物件保存 1,797 的所有資料列的 64 像素值和標籤物件包含對應的 10 個類別值。Data_x 物件修改除以 16,以便所有像素值介於 0.0 到 1.0 之間調整。

定義 Autoencoder

示範建立 64-32-2-32-64 搭配這些陳述式的類神經網路 autoencoder 模型:

my_init = C.initializer.glorot_uniform(seed=1)
X = C.ops.input_variable(64, np.float32)  # inputs
layer1 = C.layers.Dense(32, init=my_init,
  activation=C.ops.sigmoid)(X)
layer2 = C.layers.Dense(2, init=my_init,
  activation=C.ops.sigmoid)(layer1)
layer3 = C.layers.Dense(32, init=my_init,
  activation=C.ops.sigmoid)(layer2)
layer4 = C.layers.Dense(64, init=my_init,
  activation=C.ops.sigmoid)(layer3)

初始設定式物件會指定 Glorot 演算法,通常適用於優於均勻分佈深度類神經網路。X 物件設定來存放 64 的輸入的值。接下來四個層級建立 autoencoder 該 crunches 到 32 的值,64 的輸入值,並再 crunches 那些到只有兩個值。Autoencoder 是一種特殊的形式的編碼器解碼器網路。中的圖表**[圖 3**說明 autoencoder 架構。

Autoencoder 架構
[圖 3 Autoencoder 架構

若要讓圖表的大小很小, [圖 3顯示 6-3-2-3-6 autoencoder 而不是 64-32-2-32-64 架構示範 autoencoder。

請注意,輸出值都是相同為輸入值,因此 autoencoder 學習來預測它自己的輸入值。解碼器的一部分 autoencoder 展開回到原始 64 值的中介層的兩個值。這是每個 64 維度資料的項目會對應到兩個值最後的結果。若要取得這些值在示範程式定義:

enc_dec = C.ops.alias(layer4)
  encoder = C.ops.alias(layer2)

中的字,編碼器解碼器會接受 X 物件中的值,並產生輸出中包含 64 節點的第 4 層。編碼器會接受 X 物件中的值,並在具有兩個節點的階層 2 會產生輸出。

示範使用 sigmoid 啟用所有圖層上。這會導致正在介於 0.0 到 1.0 之間的所有內部層節點。有許多 autoencoders 設計選項。在每個圖層中,您可以使用不同數目的內部層級和不同數目的節點。您可以使用不同的啟用函式,包括很少使用的線性函式。Autoencoder 用於縮減維度的視覺效果,產生的視覺效果的品質時主觀,因此您的設計選擇的試驗和錯誤。

訓練 Autoencoder

訓練準備好使用這些七個陳述式:

Y = C.ops.input_variable(64, np.float32)  # targets
loss = C.squared_error(enc_dec, Y)
learner = C.adam(enc_dec.parameters, lr=0.005, momentum=0.90)
trainer = C.Trainer(enc_dec, (loss), [learner])
N = len(data_x)
bat_size = 2
max_epochs = 10000

Y 物件擁有相同的值做為 X 物件,並定型遺失函式會比較這些值。示範指定均方根的誤差損失函數,但因為每個值是介於 0.0 到 1.0,因為使用 sigmoid 啟用函式之間,交叉 entropy 錯誤可能已被使用。

深度類神經網路,Adam (自動調整目前估計) 演算法通常效能優於基本隨機梯度下降。學習速率值 (0.005) 和趨勢電子報的值 (0.90) 超參數,而且必須由試驗和錯誤。批次大小 (兩個) 和最大數目定型的反覆項目 (10,000 個) 也是超參數。

執行訓練就像這樣:

for i in range(0, max_epochs):
  rows = np.random.choice(N, bat_size, replace=False)
  trainer.train_minibatch({ X: data_x[rows], Y: data_x[rows] })
  if i > 0 and i % int(max_epochs/10) == 0:
    mse = trainer.previous_minibatch_loss_average
    print("epoch = " + str(i) + " MSE = %0.4f " % mse)

在每個訓練的反覆項目,random.choice 函式會從 1,797 的資料列,選取兩個資料列。這是相當原始的方法,因為某些資料列可能會超過其他資料列選取。您可以撰寫更複雜的批次處理系統,但 autoencoders 此示範所用的方法是簡單且有效。

示範顯示在目前的批次的兩個項目,每 10,000 的平方的誤差遺失監視訓練 / 10 = 1000 的 epoch。其概念是要確定錯誤,通常可減少在定型期間不過,因為批次大小很小,還有一堆在定型期間遺失的波動。

使用編碼器

在訓練之後示範程式會產生 (x,y) 1,797 資料項目的每個配對:

reduced = encoder.eval(data_x)

傳回的值是包含 1,797 的資料列和兩個資料行的矩陣。每個資料列代表原始資料的精簡維度性版本。這兩個資料行的值是介於 0.0 到 1.0 之間,因為 autoencoder 使用 sigmoid 啟用所有圖層上。

示範程式準備與這些陳述式的視覺效果:

print("Displaying 64-dim data in 2D: \n")
plt.scatter(x=reduced[:, 0], y=reduced[:, 1],
  c=labels, edgecolors='none', alpha=0.9,
  cmap=plt.cm.get_cmap('nipy_spectral', 10), s=20)

X 和 y 散佈函式的參數是 x 軸和 y 軸的值。減少語法 [: 0] 表示的矩陣,但只是第一個資料行的所有資料列。C 參數指定的色彩。在此情況下存的 0 到 9 的值,每個資料項目,所有的標籤物件會傳遞至 c。

Alpha 參數會指定每個標記點的透明度。Cmap 參數可接受的色彩對應。值 'nipy_spectral' 和代表範圍從 0 幽靈的色彩漸層從擷取 10 個值的 10 = black、 到 4 = 綠色,9 = 灰色。Pyplot 程式庫支援許多不同的色彩對應。標記的點,以像素為單位的大小為 s 參數。

示範程式結束像是設定之後散佈圖,以便:

plt.xlabel('component 1')
  plt.ylabel('component 2')
  plt.colorbar()
  print("End autoencoder using CNTK demo ")
  plt.show()
if __name__ == "__main__":
  main()

內建 colorbar 函式會使用 nipy_spectral 漸層的 10 個值。另一個方法是使用圖例函式。

總結

有數個其他的方法,以縮減資料視覺效果。主體元件分析 (PCA) 是用於數十年的傳統的統計技術。較新的技術,從 2008 年稱為 t 分佈隨機芳鄰內嵌 (T-SNE),它通常很適合,但僅限於有相對較小的資料集。

Autoencoders 可以用於縮減維度的資料視覺效果以外的目的。例如,您可以使用 autoencoder 移除映像或文件中的雜訊。其概念是要減少到某種類型的核心元件,在過程中,移除雜訊資料,然後展開 [上一步,導致更簡潔的資料,在某種意義上的資料。


Dr。James McCaffrey適用於在美國華盛頓州雷德蒙的 Microsoft Research他參與開發數種主要的 Microsoft 產品,包括 Internet Explorer 和 Bing。Dr。McCaffrey 要聯絡jamccaff@microsoft.com

感謝下列 Microsoft 專家檢閱這篇文章:Chris Lee, Ricky Loynd   


MSDN Magazine 論壇中的這篇文章的討論