當前位置:
首頁 > 最新 > 無監督特徵提取神器—AutoEncoder:圖文+代碼

無監督特徵提取神器—AutoEncoder:圖文+代碼

【導讀】主題鏈路知識是我們專知的核心功能之一,為用戶提供AI領域系統性的知識學習服務,一站式學習人工智慧的知識,包含人工智慧( 機器學習、自然語言處理、計算機視覺等)、大數據、編程語言、系統架構。使用請訪問專知 進行主題搜索查看 - 桌面電腦訪問www.zhuanzhi.ai, 手機端訪問www.zhuanzhi.ai 或關注微信公眾號後台回復" 專知"進入專知,搜索主題查看。繼Pytorch教程後,我們推出面向Java程序員的深度學習教程DeepLearning4J。Deeplearning4j的案例和資料很少,官方的doc文件也非常簡陋,基本上所有的類和函數的都沒有解釋。為此,我們推出來自中科院自動化所專知小組博士生Hujun與Sanglei創作的-分散式Java開源深度學習框架Deeplearning4j學習教程,第五篇,無監督特徵提取神器—AutoEncoder。

特徵提取

對很多機器學習/數據挖掘任務來說,選取或設計優質的的特徵比設計一個好的分類器顯得更為重要,然而優質特徵的設計往往需要耗費大量的時間。深度學習包含了許多優質的無監督的特徵自動提取演算法,可以自動化地從原始特徵(例如圖像像素向量、文本詞頻向量等)中提取優質的特徵,大大地節約了特徵設計的成本,收到工業界的青睞。本文介紹一種無監督學習特徵的模型——AutoEncoder,並提供DL4J實現AutoEncoder的代碼。

特徵提取示例

Iris是一個經典的數據集,數據由150個樣本組成,包含3個類別的樣本(3種標籤),每個樣本由4個特徵和1個標籤組成。例如數據的前幾行如下所示,數據的前4列分別表示樣本的4個特徵,最後一列Iris-setosa是樣本的標籤,即樣本的所屬類別,是分類器需要預測的標籤。

Iris數據集的下載地址為https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data。可以看出,很難人工設計一個區分這三種花。將Iris數據集可視化之後如下圖所示,每個小圖表示從某2個維度(一個維度對應一種特徵)去觀察Iris得到的結果,可以看出該數據集在一些小圖中是線性可分的(任選兩類樣本,可以用一條直線去大致分隔這兩類樣本)。

但依賴可視化的方法是不可行的,Iris數據集只有4個特徵和150個樣本,如果換成MNIST數據集,則有784個特徵,會產生613872張小圖。另外,大部分情況下不是選取2個特徵進行線性組合就可以獲得優質特徵的,而是需要多個特徵做複雜的數學運算才可以得到優質的特徵,因此,需要其他的方法來解決設計優質特徵的問題。

PCA(主成分分析)是一種傳統的學習特徵的方法。PCA可以將Iris數據集的4個特徵變換為2個新的特徵,2個新特徵的可視化如下圖所示,可以看到,學到的特徵是線性可分的,可直接用於分類。下面,我們將介紹深度學習中一個簡單粗暴的特徵學習神器——AutoEncoder。

AutoEncoder

AutoEncoder其實就是一個3層神經網路,由1個輸入層、1個隱藏層和1個輸出層構成(如下圖所示)。AutoEncoder用網路的輸入數據作為Label,即希望網路的輸出層輸出和輸入層一樣的東西。如果將整個網路看作一個函數,這個函數為hW,b(x)≈x,其中x表示網路的輸入(例如對於Iris數據集來說,x是一個4維向量,代表某個樣本的4個特徵)。AutoEncoder訓練成功後,輸入一個樣本的特徵,隱藏層的激活值即為學習到的該樣本的新特徵。

直觀地理解為什麼AutoEncoder為什麼可以學習到特徵,數據從AutoEncoder的輸入層到輸出層會經過兩次變換,第一次將輸入數據變換為隱藏層的激活值,第二次將隱藏層的激活值變換為輸出層(即還原為輸入),如果可以成功地還原輸入數據,則說明隱藏層的激活值包含了輸入層所有的信息(嚴格地說,是隱藏層的激活值加上AutoEncoder的網路參數包含了輸入層的所有信息,但網路參數是所有樣本共享的,因此在網路參數固定的情況下,可以認為隱藏層的激活值等價於其對應的輸入數據)。

下面給出Deeplearning4j實現AutoEncoder的代碼,有幾個需要注意的地方:

除了DL4J所需的基礎庫,還需要導入JMathPlot的Maven依賴:https://mvnrepository.com/artifact/com.github.yannrichet/JMathPlot

由於AutoEncoder需要還原數據,且輸出層的激活值大小有範圍(例如tanh的大小範圍是(-1,1)),因此在代碼中設置了數據的歸一化。

importorg.deeplearning4j.datasets.iterator.impl.IrisDataSetIterator;

importorg.deeplearning4j.nn.api.OptimizationAlgorithm;

importorg.deeplearning4j.nn.conf.MultiLayerConfiguration;

importorg.deeplearning4j.nn.conf.NeuralNetConfiguration;

importorg.deeplearning4j.nn.conf.layers.DenseLayer;

importorg.deeplearning4j.nn.conf.layers.OutputLayer;

importorg.deeplearning4j.nn.multilayer.MultiLayerNetwork;

importorg.deeplearning4j.optimize.listeners.ScoreIterationListener;

importorg.math.plot.Plot2DPanel;

importorg.nd4j.linalg.activations.Activation;

importorg.nd4j.linalg.api.ndarray.INDArray;

importorg.nd4j.linalg.dataset.DataSet;

importorg.nd4j.linalg.dataset.api.iterator.DataSetIterator;

importorg.nd4j.linalg.dataset.api.preprocessor.DataNormalization;

importorg.nd4j.linalg.dataset.api.preprocessor.NormalizerMinMaxScaler;

importorg.nd4j.linalg.lossfunctions.LossFunctions.LossFunction;

importorg.slf4j.Logger;

importorg.slf4j.LoggerFactory;

importjavax.swing.*;

importjava.awt.*;

importjava.util.List;

/**

*

*本教程由專知提供:http://www.zhuanzhi.ai/

*

*本教程演示如何用Deeplearning4j構建AutoEncoder

*除了DL4J所需的基礎庫,還需要導入JMathPlot的Maven依賴:

* https://mvnrepository.com/artifact/com.github.yannrichet/JMathPlot

*

*本教程用DL4J在Iris數據集上學習AutoEncoder

*將Iris數據集的4維的原始特徵變換為2維的優質特徵

*最後用JMathPlot繪製學習到的特徵

*

*@authorhu

*/

public classAutoEncoderExample {

private staticLoggerlog= LoggerFactory.getLogger(AutoEncoderExample.class);

public static voidmain(String[] args)throwsException {

intinputDim =4;//輸入數據維度,即原始特徵數量

final inthiddenDim =2;//隱藏層維度,即學習到的特徵的維度

intbatchSize =150;//這裡用整個數據集的大小作為batchSize

intrngSeed =123;//隨機種子,保證每次運行程序獲得同樣的結果

intnumEpochs =1000;// epoch數量,掃描一遍數據集為一個epoch

//用DL4J自帶的Iris數據集

DataSetIterator irisDataSet =newIrisDataSetIterator(batchSize,150);

//將Iris數據集歸一化到-1和1之間

//本示例用tanh激活輸出層,所以用-1到1

DataNormalization norm =newNormalizerMinMaxScaler(-1,1);

norm.fit(irisDataSet);

irisDataSet.setPreProcessor(norm);

log.info("Build model....");

MultiLayerConfiguration conf =newNeuralNetConfiguration.Builder()

.seed(rngSeed)//設置隨機種子,保證每次運行程序獲得同樣的結果

.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)

.iterations(1)

.learningRate(3e-2)//學習速率

.regularization(true).l2(1e-4)

.list()

//構建Encoder

.layer(, newDenseLayer.Builder()

.nIn(inputDim)

.nOut(hiddenDim)

.activation(Activation.TANH)

.build())

//構建Decoder

.layer(1, newOutputLayer.Builder(LossFunction.MSE)

.nIn(hiddenDim)

.nOut(inputDim)

.activation(Activation.TANH)

.build())

.pretrain(false).backprop(true)

.build();

MultiLayerNetwork model =newMultiLayerNetwork(conf);

model.init();

//每50個Iteration就print一次score

model.setListeners(newScoreIterationListener(50));

log.info("Train model....");

//訓練

for(inti=;i

irisDataSet.reset();

while(irisDataSet.hasNext()){

INDArray inputs = irisDataSet.next().getFeatures();

//將網路的輸入和Label都設置為樣本原始特徵

model.fit(inputs,inputs);

}

}

log.info("Plot learned features....");

irisDataSet.reset();

//取一個batch的數據,這裡batchSize為數據集大小

//因此這裡會取出所有的數據

DataSet plotDataSet = irisDataSet.next();

//獲取原始特徵

INDArray inputs = plotDataSet.getFeatures();

//前向傳播到第層(即隱藏層)

//返回的是一個數組,數組包含前向傳播到指定層所經過的所有層的激活值(包括指定層)

List activationList = model.feedForwardToLayer(,inputs,false);

//取出數組中的最後一層激活值(也就是隱藏層的激活值)

INDArray features = activationList.get(activationList.size() -1);

//取出原始數據的Label,原始數據的Label用one hot格式,因此需要用argMax(1)將其轉換為普通數值Label

INDArray labels = plotDataSet.getLabels().argMax(1);

//使用JMathPlot繪製特徵2D圖

//用2個坐標軸表示學習到的特徵的2個維度

//用顏色表示樣本的類別

Plot2DPanel plot =newPlot2DPanel();

Color[] colors =newColor[];

for(inti =;i

Color color = colors[labels.getInt(i)];

doublex = features.getDouble(i,);

doubley = features.getDouble(i,1);

plot.addScatterPlot("iris",color,new double[],new double[]);

}

//將JMathPlot嵌套在JFrame里展示

JFrame frame =newJFrame("a plot panel");

frame.setBounds(200,200,800,800);

frame.setContentPane(plot);

frame.setVisible(true);

}

}

運行結果:

搜索「DeepLearning4j」,查看獲得代碼。

明天請繼續關注「DeepLearning4j」教程。

完整系列搜索查看,請PC登錄

對DeepLearning4j教程感興趣的同學,歡迎進入我們的專知DeepLearning4j主題群一起交流、學習、討論,掃一掃如下群二維碼即可進入:

如果群滿,請掃描小助手,加入進群~

了解使用專知-獲取更多AI知識!


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 專知 的精彩文章:

專知-PyTorch手把手深度學習教程07
專知中秋呈獻-PyTorch手把手深度學習教程03

TAG:專知 |