新聞中心
很顯然,深度學習即將對我們的社會產(chǎn)生重大顯著的影響。Mobibit 創(chuàng)始人兼 CEO Pramod Chandrayan 近日在 codeburst.io 上發(fā)文對自動編碼器的基礎(chǔ)知識和類型進行了介紹并給出了代碼實例。

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計、成都做網(wǎng)站、偃師網(wǎng)絡(luò)推廣、小程序定制開發(fā)、偃師網(wǎng)絡(luò)營銷、偃師企業(yè)策劃、偃師品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)為所有大學生創(chuàng)業(yè)者提供偃師建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com
繼續(xù)我之前的文章《深度學習:什么&為什么?》(https://goo.gl/Ka3YoF),今天我們將進一步了解深度學習的架構(gòu)類型,并詳細討論自動編碼器。
當人類大腦與深度學習機器合作時:
在我們開始揭秘深度網(wǎng)絡(luò)之前,讓我們先定義一下深度學習。根據(jù)我的理解:
| 深度學習是一種先進的機器學習技術(shù),其中存在多個彼此通信的抽象層,每一層都與前一層深度相連,并根據(jù)前一層饋送的輸出進行決策。 |
Investopedia 將深度學習定義成:
| 深度學習是人工智能(AI)領(lǐng)域中機器學習中的一個子集,其有網(wǎng)絡(luò)狀的結(jié)構(gòu),可以從非結(jié)構(gòu)化或無標記的數(shù)據(jù)中以無監(jiān)督的方式學習。也被稱為深度神經(jīng)學習或深度神經(jīng)網(wǎng)絡(luò)。 |
今天我們將深入解讀無監(jiān)督預訓練網(wǎng)絡(luò)(Unsupervised Pertained Networks)的工作方式。
UPN:無監(jiān)督預訓練網(wǎng)絡(luò)
這種無監(jiān)督學習網(wǎng)絡(luò)可以進一步分類成
- 自動編碼器
- 深度信念網(wǎng)絡(luò)(DBN)
- 生成對抗網(wǎng)絡(luò)(GAN)
自動編碼器是一種有三層的神經(jīng)網(wǎng)絡(luò):輸入層、隱藏層(編碼層)和解碼層。該網(wǎng)絡(luò)的目的是重構(gòu)其輸入,使其隱藏層學習到該輸入的良好表征。
| 自動編碼器神經(jīng)網(wǎng)絡(luò)是一種無監(jiān)督機器學習算法,其應用了反向傳播,可將目標值設(shè)置成與輸入值相等。自動編碼器的訓練目標是將輸入復制到輸出。在內(nèi)部,它有一個描述用于表征其輸入的代碼的隱藏層。 |
自動編碼器的目標是學習函數(shù) h(x)≈x。換句話說,它要學習一個近似的恒等函數(shù),使得輸出 x^ 近似等于輸入 x。自動編碼器屬于神經(jīng)網(wǎng)絡(luò)家族,但它們也和 PCA(主成分分析)緊密相關(guān)。
關(guān)于自動編碼器的一些關(guān)鍵事實:
- 它是一種類似于 PCA 的無監(jiān)督機器學習算法
- 它要最小化和 PCA 一樣的目標函數(shù)
- 它是一種神經(jīng)網(wǎng)絡(luò)
- 這種神經(jīng)網(wǎng)絡(luò)的目標輸出就是其輸入
盡管自動編碼器與 PCA 很相似,但自動編碼器比 PCA 靈活得多。在編碼過程中,自動編碼器既能表征線性變換,也能表征非線性變換;而 PCA 只能執(zhí)行線性變換。因為自動編碼器的網(wǎng)絡(luò)表征形式,所以可將其作為層用于構(gòu)建深度學習網(wǎng)絡(luò)。
自動編碼器的類型:
- 去噪自動編碼器
- 稀疏自動編碼器
- 變分自動編碼器(VAE)
- 收縮自動編碼器(CAE/contractive autoencoder)
A. 去噪自動編碼器
這是最基本的一種自動編碼器,它會隨機地部分采用受損的輸入來解決恒等函數(shù)風險,使得自動編碼器必須進行恢復或去噪。
這項技術(shù)可用于得到輸入的良好表征。良好的表征是指可以從受損的輸入穩(wěn)健地獲得的表征,該表征可被用于恢復其對應的無噪聲輸入。
去噪自動編碼器背后的思想很簡單。為了迫使隱藏層發(fā)現(xiàn)更加穩(wěn)健的特征并且為了防止其只是學習其中的恒等關(guān)系,我們在訓練自動編碼器時會讓其從受損的版本中重建輸入。
應用在輸入上的噪聲量以百分比的形式呈現(xiàn)。一般來說,30% 或 0.3 就很好,但如果你的數(shù)據(jù)非常少,你可能就需要考慮增加更多噪聲。
堆疊的去噪自動編碼器(SDA):
這是一種在層上使用了無監(jiān)督預訓練機制的去噪自編碼器,其中當一層被預訓練用于在之前層的輸入上執(zhí)行特征選擇和特征提取后,后面會跟上一個監(jiān)督式的微調(diào)(fine-tuning)階段。SDA 只是將很多個去噪自動編碼器融合在了一起。一旦前面 k 層訓練完成,我們就可以訓練第 k+1 層,因為我們現(xiàn)在可以根據(jù)下面的層計算代碼或隱含表征。
一旦所有層都預訓練完成,網(wǎng)絡(luò)就會進入一個被稱為微調(diào)的階段。在這里我們會為微調(diào)使用監(jiān)督學習機制,以最小化被監(jiān)督任務(wù)上的預測誤差。然后,我們以訓練多層感知器的方式訓練整個網(wǎng)絡(luò)。在這個階段,我們僅考慮每個自動編碼器的編碼部分。這個階段是有監(jiān)督的,自此以后我們就在訓練中使用目標類別了。
使用代碼示例解釋 SDA
這一節(jié)源自 deeplearning.net(對于想要理解深度學習的人來說,這個網(wǎng)站提供了很好的參考),其中使用案例對堆疊的去噪自動編碼器進行了很好的解釋。
我們可以以兩種方式看待堆疊的去噪自動編碼器:一是自動編碼器列表,二是多層感知器(MLP)。在預訓練過程中,我們使用了***種方式,即我們將我們的模型看作是一組自動編碼器列表,并分開訓練每個自動編碼器。在第二個訓練階段,我們使用第二種方式。這兩種方式是有聯(lián)系的,因為:
自動編碼器和 MLP 的 sigmoid 層共享參數(shù);
MLP 的中間層計算出的隱含表征被用作自動編碼器的輸入。
- class SdA(object):
- """Stacked denoising auto-encoder class (SdA)
- A stacked denoising autoencoder model is obtained by stacking several
- dAs. The hidden layer of the dA at layer `i` becomes the input of
- the dA at layer `i+1`. The first layer dA gets as input the input of
- the SdA, and the hidden layer of the last dA represents the output.
- Note that after pretraining, the SdA is dealt with as a normal MLP,
- the dAs are only used to initialize the weights.
- """
- def __init__(
- self,
- numpy_rng,
- theano_rng=None,
- n_ins=784,
- hidden_layers_sizes=[500, 500],
- n_outs=10,
- corruption_levels=[0.1, 0.1]
- ):
- """ This class is made to support a variable number of layers.
- :type numpy_rng: numpy.random.RandomState
- :param numpy_rng: numpy random number generator used to draw initial
- weights
- :type theano_rng: theano.tensor.shared_randomstreams.RandomStreams
- :param theano_rng: Theano random generator; if None is given one is
- generated based on a seed drawn from `rng`
- :type n_ins: int
- :param n_ins: dimension of the input to the sdA
- :type hidden_layers_sizes: list of ints
- :param hidden_layers_sizes: intermediate layers size, must contain
- at least one value
- :type n_outs: int
- :param n_outs: dimension of the output of the network
- :type corruption_levels: list of float
- :param corruption_levels: amount of corruption to use for each
- layer
- """
- self.sigmoid_layers = []
- self.dA_layers = []
- self.params = []
- self.n_layers = len(hidden_layers_sizes)
- assert self.n_layers > 0
- if not theano_rng:
- theano_rng = RandomStreams(numpy_rng.randint(2 ** 30))
- # allocate symbolic variables for the data
- self.x = T.matrix('x') # the data is presented as rasterized images
- self.y = T.ivector('y') # the labels are presented as 1D vector of
- # [int] labels
self.sigmoid_layers 將會存儲 MLP 形式的 sigmoid 層,而 self.dA_layers 將會存儲與該 MLP 層關(guān)聯(lián)的去噪自動編碼器。接下來,我們構(gòu)建 n_layers sigmoid 層和 n_layers 去噪自動編碼器,其中 n_layers 是我們的模型的深度。我們使用了多層感知器中引入的 HiddenLayer 類,但有一項修改:我們將 tanh 非線性替換成了 logistic 函數(shù)
我們鏈接了 sigmoid 層來構(gòu)建一個 MLP,而且我們在構(gòu)建自動編碼器時使得每個自動編碼器的編碼部分都與其對應的 sigmoid 層共享權(quán)重矩陣和偏置。
- for i in range(self.n_layers):
- # construct the sigmoidal layer
- # the size of the input is either the number of hidden units of
- # the layer below or the input size if we are on the first layer
- if i == 0:
- input_size = n_ins
- else:
- input_size = hidden_layers_sizes[i - 1]
- # the input to this layer is either the activation of the hidden
- # layer below or the input of the SdA if you are on the first
- # layer
- if i == 0:
- layer_input = self.x
- else:
- layer_input = self.sigmoid_layers[-1].output
- sigmoid_layer = HiddenLayer(rng=numpy_rng,
- input=layer_input,
- n_in=input_size,
- n_out=hidden_layers_sizes[i],
- activation=T.nnet.sigmoid)
- # add the layer to our list of layers
- self.sigmoid_layers.append(sigmoid_layer)
- # its arguably a philosophical question...
- # but we are going to only declare that the parameters of the
- # sigmoid_layers are parameters of the StackedDAA
- # the visible biases in the dA are parameters of those
- # dA, but not the SdA
- self.params.extend(sigmoid_layer.params)
- # Construct a denoising autoencoder that shared weights with this
- # layer
- dAdA_layer = dA(numpy_rngnumpy_rng=numpy_rng,
- theano_rngtheano_rng=theano_rng,
- input=layer_input,
- n_visible=input_size,
- n_hidden=hidden_layers_sizes[i],
- W=sigmoid_layer.W,
- bhid=sigmoid_layer.b)
- self.dA_layers.append(dA_layer)
現(xiàn)在我們只需要在這個 sigmoid 層上添加一個 logistic 層即可,這樣我們就有了一個 MLP。我們將使用 LogisticRegression 類,這個類是在使用 logistic 回歸分類 MNIST 數(shù)字時引入的。
- # We now need to add a logistic layer on top of the MLP
- self.logLayer = LogisticRegression(
- input=self.sigmoid_layers[-1].output,
- n_in=hidden_layers_sizes[-1],
- n_out=n_outs
- )
- self.params.extend(self.logLayer.params)
- # construct a function that implements one step of finetunining
- # compute the cost for second phase of training,
- # defined as the negative log likelihood
- selfself.finetune_cost = self.logLayer.negative_log_likelihood(self.y)
- # compute the gradients with respect to the model parameters
- # symbolic variable that points to the number of errors made on the
- # minibatch given by self.x and self.y
- selfself.errors = self.logLayer.errors(self.y)
SdA 類也提供了一種為其層中的去噪自動編碼器生成訓練函數(shù)的方法。它們會作為一個列表返回,其中元素 i 是一個函數(shù)——該函數(shù)實現(xiàn)了訓練對應于第 i 層的 dA 的步驟。
- def pretraining_functions(self, train_set_x, batch_size):
- ''' Generates a list of functions, each of them implementing one
- step in trainnig the dA corresponding to the layer with same index.
- The function will require as input the minibatch index, and to train
- a dA you just need to iterate, calling the corresponding function on
- all minibatch indexes.
- :type train_set_x: theano.tensor.TensorType
- :param train_set_x: Shared variable that contains all datapoints used
- for training the dA
- :type batch_size: int
- :param batch_size: size of a [mini]batch
- :type learning_rate: float
- :param learning_rate: learning rate used during training for any of
- the dA layers
- '''
- # index to a [mini]batch
- index = T.lscalar('index') # index to a minibatch
為了修改訓練過程中的受損水平或?qū)W習率,我們將它們與 Theano 變量聯(lián)系了起來。
- corruption_level = T.scalar('corruption') # % of corruption to use
- learning_rate = T.scalar('lr') # learning rate to use
- # begining of a batch, given `index`
- batch_begin = index * batch_size
- # ending of a batch given `index`
- batch_end = batch_begin + batch_size
- pretrain_fns = []
- for dA in self.dA_layers:
- # get the cost and the updates list
- cost, updates = dA.get_cost_updates(corruption_level,
- learning_rate)
- # compile the theano function
- fn = theano.function(
- inputs=[
- index,
- theano.In(corruption_level, value=0.2),
- theano.In(learning_rate, value=0.1)
- ],
- outputs=cost,
- updatesupdates=updates,
- givens={
- self.x: train_set_x[batch_begin: batch_end]
- }
- )
- # append `fn` to the list of functions
- pretrain_fns.append(fn)
- return pretrain_fns
現(xiàn)在任意 pretrain_fns[i] 函數(shù)都可以使用索引參數(shù)了,可選的有 corruption(受損水平)或 lr(學習率)。注意這些參數(shù)名是在它們被構(gòu)建時賦予 Theano 變量的名字,而不是 Python 變量(learning_rate 或 corruption_level)的名字。在使用 Theano 時一定要記住這一點。我們用同樣的方式構(gòu)建了用于構(gòu)建微調(diào)過程中所需函數(shù)的方法(train_fn、valid_score 和 test_score)。
- def build_finetune_functions(self, datasets, batch_size, learning_rate):
- '''Generates a function `train` that implements one step of
- finetuning, a function `validate` that computes the error on
- a batch from the validation set, and a function `test` that
- computes the error on a batch from the testing set
- :type datasets: list of pairs of theano.tensor.TensorType
- :param datasets: It is a list that contain all the datasets;
- the has to contain three pairs, `train`,
- `valid`, `test` in this order, where each pair
- is formed of two Theano variables, one for the
- datapoints, the other for the labels
- :type batch_size: int
- :param batch_size: size of a minibatch
- :type learning_rate: float
- :param learning_rate: learning rate used during finetune stage
- '''
- (train_set_x, train_set_y) = datasets[0]
- (valid_set_x, valid_set_y) = datasets[1]
- (test_set_x, test_set_y) = datasets[2]
- # compute number of minibatches for training, validation and testing
- n_valid_batches = valid_set_x.get_value(borrow=True).shape[0]
- n_valid_batches //= batch_size
- n_test_batches = test_set_x.get_value(borrow=True).shape[0]
- n_test_batches //= batch_size
- index = T.lscalar('index') # index to a [mini]batch
- # compute the gradients with respect to the model parameters
- gparams = T.grad(self.finetune_cost, self.params)
- # compute list of fine-tuning updates
- updates = [
- (param, param - gparam * learning_rate)
- for param, gparam in zip(self.params, gparams)
- ]
- train_fn = theano.function(
- inputs=[index],
- outputs=self.finetune_cost,
- updatesupdates=updates,
- givens={
- self.x: train_set_x[
- index * batch_size: (index + 1) * batch_size
- ],
- self.y: train_set_y[
- index * batch_size: (index + 1) * batch_size
- ]
- },
- )
- test_score_i = theano.function(
- [index],
- self.errors,
- givens={
- self.x: test_set_x[
- index * batch_size: (index + 1) * batch_size
- ],
- self.y: test_set_y[
- index * batch_size: (index + 1) * batch_size
- ]
- },
- )
- valid_score_i = theano.function(
- [index],
- self.errors,
- givens={
- self.x: valid_set_x[
- index * batch_size: (index + 1) * batch_size
- ],
- self.y: valid_set_y[
- index * batch_size: (index + 1) * batch_size
- ]
- },
- )
- # Create a function that scans the entire validation set
- def valid_score():
- return [valid_score_i(i) for i in range(n_valid_batches)]
- # Create a function that scans the entire test set
- def test_score():
- return [test_score_i(i) for i in range(n_test_batches)]
- return train_fn, valid_score, test_score
注意,valid_score 和 test_score 并不是 Theano 函數(shù),而是分別在整個驗證集和整個測試集上循環(huán)的 Python 函數(shù),可以在這些集合上產(chǎn)生一個損失列表。
總結(jié)
下面給出的幾行代碼就構(gòu)建了一個堆疊的去噪自動編碼器:
- numpynumpy_rng = numpy.random.RandomState(89677)
- print('... building the model')
- # construct the stacked denoising autoencoder class
- sda = SdA(
- numpy_rngnumpy_rng=numpy_rng,
- n_ins=28 * 28,
- hidden_layers_sizes=[1000, 1000, 1000],
- n_outs=10
- )
該網(wǎng)絡(luò)的訓練分兩個階段:逐層的預訓練,之后是微調(diào)。
對于預訓練階段,我們將在網(wǎng)絡(luò)的所有層上進行循環(huán)。對于每個層,我們都將使用編譯過的實現(xiàn) SGD 步驟的函數(shù),以優(yōu)化權(quán)重,從而降低該層的重構(gòu)成本。這個函數(shù)將根據(jù) pretraining_epochs 在訓練集上執(zhí)行固定數(shù)量的 epoch。
- #########################
- # PRETRAINING THE MODEL #
- #########################
- print('... getting the pretraining functions')
- pretraining_fns = sda.pretraining_functions(train_set_xtrain_set_x=train_set_x,
- batch_sizebatch_size=batch_size)
- print('... pre-training the model')
- start_time = timeit.default_timer()
- ## Pre-train layer-wise
- corruption_levels = [.1, .2, .3]
- for i in range(sda.n_layers):
- # go through pretraining epochs
- for epoch in range(pretraining_epochs):
- # go through the training set
- c = []
- for batch_index in range(n_train_batches):
- c.append(pretraining_fns[i](index=batch_index,
- corruption=corruption_levels[i],
- lr=pretrain_lr))
- print('Pre-training layer %i, epoch %d, cost %f' % (i, epoch, numpy.mean(c, dtype='float64')))
- end_time = timeit.default_timer()
- print(('The pretraining code for file ' +
- os.path.split(__file__)[1] +
- ' ran for %.2fm' % ((end_time - start_time) / 60.)), file=sys.stderr)
這里的微調(diào)循環(huán)和多層感知器中的微調(diào)過程很相似。唯一的區(qū)別是它使用了 build_finetune_functions 給出的函數(shù)。
執(zhí)行代碼
用戶可以通過調(diào)用以下 Python CLI 來運行該代碼:
- python code/SdA.py
默認情況下,該代碼會為每一層運行 15 次預訓練 epoch,其批大小為 1。***層的受損水平為 0.1,第二層為 0.2,第三層為 0.3。預訓練的學習率為 0.001,微調(diào)學習率為 0.1。預訓練耗時 585.01 分鐘,每 epoch 平均 13 分鐘。微調(diào)經(jīng)歷了 36 epoch,耗時 444.2 分鐘,每 epoch 平均 12.34 分鐘。***的驗證分數(shù)是 1.39%,測試分數(shù)是 1.3%。這些結(jié)果是在配置了 Intel Xeon E5430 @ 2.66GHz CPU 的機器上得到的,它有單線程的 GotoBLAS。
原文:https://codeburst.io/deep-learning-types-and-autoencoders-a40ee6754663
【本文是專欄機構(gòu)“機器之心”的原創(chuàng)譯文,微信公眾號“機器之心( id: almosthuman2014)”】
戳這里,看該作者更多好文
網(wǎng)頁標題:深度學習:自動編碼器基礎(chǔ)和類型
分享鏈接:http://www.5511xx.com/article/dhdjeic.html


咨詢
建站咨詢
