小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

 taotao_2016 2019-06-29

機器學(xué)習(xí)的當(dāng)前趨勢

機器學(xué)習(xí)目前有三大趨勢:概率編程,深度學(xué)習(xí)和“大數(shù)據(jù)”。在PP內(nèi)部,許多創(chuàng)新都在使用變分推理來進行規(guī)模擴展。在本文中,我將展示如何在PyMC3中使用變分推理來擬合簡單的貝葉斯神經(jīng)網(wǎng)絡(luò)。我還將討論如何在概率編程和深度學(xué)習(xí)之間架起橋梁,為將來的研究開辟非常有趣的途徑。

概率性編程規(guī)劃

概率編程允許非常靈活地創(chuàng)建自定義概率模型,主要關(guān)注從數(shù)據(jù)中洞察和學(xué)習(xí)。該方法本質(zhì)上是貝葉斯方法,因此我們可以指定先驗來告知和約束我們的模型,并以后驗分布的形式得到不確定性估計。使用MCMC采樣算法,我們可以從這個后驗中抽取樣本,非常靈活地估計這些模型。PyMC3和Stan是目前用于構(gòu)建和評估這些模型的最先進工具。然而,采樣的一個主要缺點是它通常非常慢,特別是對于高維模型。這就是為什么最近開發(fā)出的變分推理算法幾乎和MCMC一樣靈活,但速度要快得多。這些算法不是從后驗中抽取樣本,而是將后驗的分布(如正態(tài)分布)擬合到樣本上,將樣本問題轉(zhuǎn)化為優(yōu)化問題。

不幸的是,當(dāng)涉及到傳統(tǒng)的ML問題,如分類或(非線性)回歸時,概率編程常常處于第二位(在準(zhǔn)確性和可擴展性方面),而不是像集成學(xué)習(xí)這樣的算法方法(例如隨機森林或梯度增強回歸樹) 。

深度學(xué)習(xí)

現(xiàn)在正處于第三次文藝復(fù)興時期,深度學(xué)習(xí)一直成為頭條新聞,它主宰了幾乎所有的物體識別基準(zhǔn),在雅達利游戲(Atari games)中大出風(fēng)頭,在圍棋(Go)中擊敗了世界冠軍李世石(Lee Sedol)。從統(tǒng)計學(xué)角度來看,神經(jīng)網(wǎng)絡(luò)是非常好的非線性函數(shù)近似和表示學(xué)習(xí)者表現(xiàn)。雖然主要用于分類,但它們已經(jīng)擴展到使用自編碼器進行無監(jiān)督學(xué)習(xí)以及各種其他有趣的方式(例如,遞歸網(wǎng)絡(luò)或MDN來估計多模態(tài)分布)。為什么他們這么好用?沒有人真正知道,因為統(tǒng)計特性仍未被完全理解。

深度學(xué)習(xí)的一大創(chuàng)新之處在于能夠訓(xùn)練這些極其復(fù)雜的模型。這取決于幾個支柱:

  • 速度:促進GPU允許更快的處理。
  • 軟件:Theano和TensorFlow等框架允許靈活地創(chuàng)建抽象模型,然后可以對其進行優(yōu)化并編譯到CPU或GPU。
  • 學(xué)習(xí)算法:對數(shù)據(jù)子集的訓(xùn)練 - 隨機梯度下降 - 允許我們在大量數(shù)據(jù)上訓(xùn)練這些模型。dropout等技術(shù)可以避免過度擬合。
  • 架構(gòu)性:很多創(chuàng)新來自于改變輸入層,如卷積神經(jīng)網(wǎng)絡(luò),或輸出層,如MDN。

彌合深度學(xué)習(xí)和概率編程

一方面,我們有概率編程,它允許我們以非常有原則和易于理解的方式構(gòu)建相當(dāng)小的模型,以深入了解我們的數(shù)據(jù); 另一方面,我們有深度學(xué)習(xí),它使用許多啟發(fā)式方法來訓(xùn)練巨大且高度復(fù)雜的模型,這些模型在預(yù)測方面令人驚嘆。變分推理的最新創(chuàng)新允許概率編程來擴展模型復(fù)雜性以及數(shù)據(jù)大小。因此,我們正處于能夠?qū)⑦@兩種方法結(jié)合起來以幫助解開機器學(xué)習(xí)的新創(chuàng)新的風(fēng)口浪尖。

雖然這將允許概率編程應(yīng)用于更廣泛的有趣問題,但我相信,這種橋梁也為深度學(xué)習(xí)的創(chuàng)新帶來了巨大的希望。

  • 預(yù)測中的不確定性:正如我們將在下面看到的,貝葉斯神經(jīng)網(wǎng)絡(luò)告訴我們其預(yù)測的不確定性。我認為不確定性是機器學(xué)習(xí)中一個未被充分認識的概念,因為它顯然對現(xiàn)實世界的應(yīng)用很重要。但它在訓(xùn)練中也很有用。例如,我們可以針對最不確定的樣本專門訓(xùn)練模型。
  • 表示中的不確定性:我們還得到了我們權(quán)重的不確定性估計,這可以告訴我們網(wǎng)絡(luò)的學(xué)習(xí)表示的穩(wěn)定性。
  • 先驗的正則化:權(quán)重通常是L2正則化以避免過度擬合,這非常自然地成為權(quán)重系數(shù)的高斯先驗。然而,我們可以想象各種其他先驗,如spike-and-slab來加強稀疏性(這更像是使用L1-norm)。
  • 通過知情先驗遷移學(xué)習(xí):如果我們想訓(xùn)練一個網(wǎng)絡(luò)使用新的對象識別數(shù)據(jù)集,我們可以通過將知情先驗集中在從其他預(yù)訓(xùn)練網(wǎng)絡(luò)檢索到的權(quán)重上來引導(dǎo)學(xué)習(xí)。
  • 分層神經(jīng)網(wǎng)絡(luò):在概率編程中一種非常強大的方法是分層建模,它允許將子群上學(xué)到的東西匯集到整個總體中。應(yīng)用于神經(jīng)網(wǎng)絡(luò),在分層數(shù)據(jù)集中,我們可以訓(xùn)練單個神經(jīng)網(wǎng)絡(luò)專門研究子群,同時仍然了解整體的表示。例如,想象一個經(jīng)過訓(xùn)練的網(wǎng)絡(luò),可以根據(jù)汽車的圖片對汽車模型進行分類。我們可以訓(xùn)練分層神經(jīng)網(wǎng)絡(luò),其中訓(xùn)練子神經(jīng)網(wǎng)絡(luò)以僅從單個制造商分辨模型。人們的直覺是,來自某一制造商的所有汽車都有一定的相似性,因此訓(xùn)練專門針對品牌的個別網(wǎng)絡(luò)是有意義的。但是,由于各個網(wǎng)絡(luò)連接在更高層,他們?nèi)詴c其他專門的子網(wǎng)絡(luò)分享有關(guān)對所有品牌有用的特征的信息。有趣的是,網(wǎng)絡(luò)的不同層可以通過層級的各個級別來通知。
  • 其他混合架構(gòu):我們可以更自由地構(gòu)建各種神經(jīng)網(wǎng)絡(luò)。例如,可以使用貝葉斯非參數(shù)來靈活地調(diào)整隱藏層的大小和形狀,以在訓(xùn)練期間最優(yōu)地將網(wǎng)絡(luò)架構(gòu)擴展到當(dāng)前的問題。目前,這需要更多的超參數(shù)優(yōu)化和大量的知識。

PyMC3中的貝葉斯神經(jīng)網(wǎng)絡(luò)

生成數(shù)據(jù)

首先,讓我們生成一些玩具數(shù)據(jù) - 一個簡單的二元分類問題,它不是線性可分的。

%matplotlib inlineimport theanoimport pymc3 as pmimport sklearnimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsfrom warnings import filterwarningsfilterwarnings('ignore')sns.set_style('white')from sklearn import datasetsfrom sklearn.preprocessing import scalefrom sklearn.model_selection import train_test_splitfrom sklearn.datasets import make_moonsX, Y = make_moons(noise=0.2, random_state=0, n_samples=1000)X = scale(X)X = X.astype(float)Y = Y.astype(float)X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=.5)fig, ax = plt.subplots(figsize=(12, 8))ax.scatter(X[Y==0, 0], X[Y==0, 1], label='Class 0')ax.scatter(X[Y==1, 0], X[Y==1, 1], color='r', label='Class 1')sns.despine(); ax.legend()ax.set(xlabel='X', ylabel='Y', title='Toy binary classification data set');

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

模型規(guī)格

神經(jīng)網(wǎng)絡(luò)非常簡單?;締卧且粋€感知器,它只不過是邏輯回歸。我們并行使用其中許多,然后將它們疊加起來以獲得隱藏層。在這里,我們將使用2個隱藏層,每個隱藏層有5個神經(jīng)元,足以解決這個簡單問題。

def construct_nn(ann_input, ann_output): n_hidden = 5  # Initialize random weights between each layer init_1 = np.random.randn(X.shape[1], n_hidden).astype(float) init_2 = np.random.randn(n_hidden, n_hidden).astype(float) init_out = np.random.randn(n_hidden).astype(float)  with pm.Model() as neural_network: # Weights from input to hidden layer weights_in_1 = pm.Normal('w_in_1', 0, sd=1,  shape=(X.shape[1], n_hidden),  testval=init_1)  # Weights from 1st to 2nd layer weights_1_2 = pm.Normal('w_1_2', 0, sd=1,  shape=(n_hidden, n_hidden),  testval=init_2)  # Weights from hidden layer to output weights_2_out = pm.Normal('w_2_out', 0, sd=1,  shape=(n_hidden,),  testval=init_out)  # Build neural-network using tanh activation function act_1 = pm.math.tanh(pm.math.dot(ann_input,  weights_in_1)) act_2 = pm.math.tanh(pm.math.dot(act_1,  weights_1_2)) act_out = pm.math.sigmoid(pm.math.dot(act_2,  weights_2_out))  # Binary classification -> Bernoulli likelihood out = pm.Bernoulli('out',  act_out, observed=ann_output, total_size=Y_train.shape[0] # IMPORTANT for minibatches ) return neural_network# Trick: Turn inputs and outputs into shared variables. ann_input = theano.shared(X_train)ann_output = theano.shared(Y_train)neural_network = construct_nn(ann_input, ann_output)

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

Normal先驗有助于調(diào)整權(quán)重。通常我們會在輸入中添加一個常量b,但是為了保持代碼的整潔,我在這里省略了它。

變分推理:縮放模型復(fù)雜度

我們現(xiàn)在可以運行像NUTS這樣的MCMC采樣器,在這種情況下工作得非常好,但正如我已經(jīng)提到的,當(dāng)我們將模型擴展到具有更多層的更深層架構(gòu)時,這將變得非常緩慢。

相反,我們將使用ADVI變分推理算法,這是最近添加到PyMC3,并更新使用運算符變分推理(OPVI)框架。這樣做速度更快,并且可以更好地擴展。

from pymc3.theanof import set_tt_rng, MRG_RandomStreamsset_tt_rng(MRG_RandomStreams(42))%%timewith neural_network: inference = pm.ADVI() approx = pm.fit(n=50000, method=inference)

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

在性能方面,考慮到NUTS確實不是太好。接下來我們使它更快一些。為了讓它真正運行起來,我們可能需要在GPU上運行神經(jīng)網(wǎng)絡(luò)。

由于使用樣本更方便,我們可以使用sample方法快速地從變分近似中提取樣本(這只是從正態(tài)分布中采樣,所以與MCMC完全不同):

trace = approx.sample(draws=5000)

繪制目標(biāo)函數(shù)(ELBO)我們可以看到優(yōu)化會逐漸改善擬合。

plt.plot(-inference.hist)plt.ylabel('ELBO')plt.xlabel('iteration');

現(xiàn)在我們訓(xùn)練了模型,讓我們使用后驗預(yù)測檢查(PPC)來預(yù)測保留集。

# Replace arrays our NN references with the test dataann_input.set_value(X_test)ann_output.set_value(Y_test)with neural_network: ppc = pm.sample_ppc(trace, samples=500, progressbar=False)# Use probability of > 0.5 to assume prediction of class 1pred = ppc['out'].mean(axis=0) > 0.5

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

讓我們來看看我們的預(yù)測:

fig, ax = plt.subplots()ax.scatter(X_test[pred==0, 0], X_test[pred==0, 1])ax.scatter(X_test[pred==1, 0], X_test[pred==1, 1], color='r')sns.despine()ax.set(title='Predicted labels in testing set', xlabel='X', ylabel='Y');print('Accuracy = {}%'.format((Y_test == pred).mean() * 100))

Accuracy = 95.0%

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

我們的神經(jīng)網(wǎng)絡(luò)已經(jīng)做得很好了。

讓我們看看分類器學(xué)到了什么

這樣,我們在整個輸入空間的網(wǎng)格上評估類概率預(yù)測。

grid = pm.floatX(np.mgrid[-3:3:100j,-3:3:100j])grid_2d = grid.reshape(2, -1).Tdummy_out = np.ones(grid.shape[1], dtype=np.int8)ann_input.set_value(grid_2d)ann_output.set_value(dummy_out)with neural_network: ppc = pm.sample_ppc(trace, samples=500, progressbar=False)

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

概率面

cmap = sns.diverging_palette(250, 12, s=85, l=25, as_cmap=True)fig, ax = plt.subplots(figsize=(14, 8))contour = ax.contourf(grid[0], grid[1], ppc['out'].mean(axis=0).reshape(100, 100), cmap=cmap)ax.scatter(X_test[pred==0, 0], X_test[pred==0, 1])ax.scatter(X_test[pred==1, 0], X_test[pred==1, 1], color='r')cbar = plt.colorbar(contour, ax=ax)_ = ax.set(xlim=(-3, 3), ylim=(-3, 3), xlabel='X', ylabel='Y');cbar.ax.set_ylabel('Posterior predictive mean probability of class label = 0');

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

預(yù)測值的不確定性

到目前為止,我展示的一切都可以用非貝葉斯神經(jīng)網(wǎng)絡(luò)完成。每個類標(biāo)簽的后驗預(yù)測均值應(yīng)與最大似然預(yù)測值相同。不過,我們也可以通過后驗預(yù)測的標(biāo)準(zhǔn)差來了解我們預(yù)測中的不確定性。這是看起來像:

cmap = sns.cubehelix_palette(light=1, as_cmap=True)fig, ax = plt.subplots(figsize=(14, 8))contour = ax.contourf(grid[0], grid[1], ppc['out'].std(axis=0).reshape(100, 100), cmap=cmap)ax.scatter(X_test[pred==0, 0], X_test[pred==0, 1])ax.scatter(X_test[pred==1, 0], X_test[pred==1, 1], color='r')cbar = plt.colorbar(contour, ax=ax)_ = ax.set(xlim=(-3, 3), ylim=(-3, 3), xlabel='X', ylabel='Y');cbar.ax.set_ylabel('Uncertainty (posterior predictive standard deviation)');

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

我們可以看到非常接近決策邊界的地方,我們對于預(yù)測哪個標(biāo)簽的不確定性是最高的。您可以想象,將預(yù)測與不確定性聯(lián)系起來是許多應(yīng)用(如醫(yī)療保健)的關(guān)鍵屬性。為了進一步提高精度,我們可能希望主要根據(jù)來自高不確定區(qū)域的樣本來進行模型訓(xùn)練。

Mini-batch ADVI

到目前為止,我們已經(jīng)對所有數(shù)據(jù)進行了模型訓(xùn)練。顯然,這不會像ImageNet那樣擴展。此外,對mini-batch數(shù)據(jù)(隨機梯度下降)的訓(xùn)練避免了局部最小值,并且可以加快收斂速度。

幸運的是,ADVI也可以在mini-batch上運行。它只需要一些設(shè)置:

minibatch_x = pm.Minibatch(X_train, batch_size=32)minibatch_y = pm.Minibatch(Y_train, batch_size=32)neural_network_minibatch = construct_nn(minibatch_x, minibatch_y)with neural_network_minibatch: inference = pm.ADVI() approx = pm.fit(40000, method=inference)plt.plot(-inference.hist)plt.ylabel('ELBO')plt.xlabel('iteration');

機器學(xué)習(xí)貝葉斯神經(jīng)網(wǎng)絡(luò)與Python

如您所見,mini-batch ADVI的運行時間要低得多。它似乎收斂的更快。

總結(jié)

希望本文演示了PyMC3: ADVI中可用的一個非常強大的新推理算法。我還認為,如前所述,彌合概率編程和深度學(xué)習(xí)之間的差距可以為這一領(lǐng)域的創(chuàng)新開辟許多新途徑。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多