91精品国产综合久久四虎久久_国产成人午夜高潮毛片_99er视频精品免费观看_2020亚洲熟女在线观看_日本女优人体写真_国内黄色毛片_年轻的老师中文版在线_丰满女邻居做爰_久久久久久精品成人免费图片

使用TensorFlow的層來構(gòu)建深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)
使用TensorFlow構(gòu)建多層卷積網(wǎng)絡(luò)的分步教程。
編者注:更多人工智能內(nèi)容請(qǐng)關(guān)注2018年4月10-13日人工智能北京大會(huì)。

深度學(xué)習(xí)已經(jīng)在許多領(lǐng)域(例如計(jì)算機(jī)視覺、自然語言處理、文本翻譯或語音到文本等)證明了其有效性。它的名字來源于大量用于構(gòu)建執(zhí)行機(jī)器學(xué)習(xí)任務(wù)的神經(jīng)網(wǎng)絡(luò)的深度層次。盡管有多種類型的層和多種整體神經(jīng)網(wǎng)絡(luò)的架構(gòu),但一般規(guī)則認(rèn)為,網(wǎng)絡(luò)層次越深,其可以表征的復(fù)雜性就越高。本文將解釋神經(jīng)網(wǎng)絡(luò)的層的基本概念,并會(huì)帶大家一步一步地探索使用TensorFlow創(chuàng)建多種類型(的網(wǎng)絡(luò))。

TensorFlow是針對(duì)大眾用戶的人工智能(AI)的平臺(tái)。它是一個(gè)擁有大量的社區(qū)和強(qiáng)力支持的開源庫。TensorFlow提供了一整套用于構(gòu)建神經(jīng)網(wǎng)絡(luò)體系架構(gòu)的工具,并能訓(xùn)練和發(fā)布模型服務(wù)。它提供了不同的抽象級(jí)別,因此你可以把它用于高級(jí)別的剪貼式機(jī)器學(xué)習(xí)過程,或者自己進(jìn)行更深層的計(jì)算的編寫。

TensorFlow在tf.layers包中提供了多種類型的層。該模塊使得在深度學(xué)習(xí)模型中創(chuàng)建一個(gè)層變得非常容易,且無需考慮許多細(xì)節(jié)。目前它主要支持用于卷積網(wǎng)絡(luò)的層的類型。對(duì)于其他類型的網(wǎng)絡(luò),例如RNN,你可能需要查看tf.contrib.rnntf.nn。最基本的層的類型是全連接層。要實(shí)現(xiàn)它,只需要在Dense類中設(shè)置輸入和大小。其他類型的層可能需要更多的參數(shù),但它們的實(shí)現(xiàn)方式可以支持默認(rèn)行為并節(jié)省開發(fā)人員的時(shí)間。

關(guān)于什么是層和什么不是還存在一些分歧。一種觀點(diǎn)認(rèn)為,層必須存儲(chǔ)訓(xùn)練過的參數(shù)(如權(quán)重和偏置)。例如,這意味著應(yīng)用激活函數(shù)不是一層。事實(shí)上,tf.layers模塊通過使用激活參數(shù)來實(shí)現(xiàn)這樣的函數(shù)。盡管如此,此模塊中引入的層并不總是嚴(yán)格遵循此規(guī)則。你可以在其中找到很多種類型的層:全連接、卷積、池化、扁平、批量歸一化、部分丟棄和卷積轉(zhuǎn)置??雌饋肀馄綄雍妥畲蠡貙硬淮鎯?chǔ)在學(xué)習(xí)過程中訓(xùn)練的任何參數(shù)。盡管如此,它們卻在執(zhí)行比激活函數(shù)更復(fù)雜的操作。因此模塊的作者決定將它們?cè)O(shè)置為獨(dú)立的類。在文章的后面,我們將討論如何使用其中的一些來構(gòu)建深度卷積網(wǎng)絡(luò)。

一個(gè)典型的卷積網(wǎng)絡(luò)是一系列卷積加池化的組,然后是一點(diǎn)全連接的層。一個(gè)卷積就像一個(gè)小型的神經(jīng)網(wǎng)絡(luò),對(duì)它的輸入的每個(gè)位置重復(fù)使用一次卷積計(jì)算。結(jié)果,網(wǎng)絡(luò)層會(huì)變得小很多但深度增加了。池化操作通常是減小輸入圖像大小的操作。最大池化是最常用的池化算法,并且已被證明在許多計(jì)算機(jī)視覺任務(wù)中是很有效的。

在本文中,我將展示如何使用TensorFlow將卷積網(wǎng)絡(luò)應(yīng)用于圖像處理。我們會(huì)使用TensorFlow示例中的MNIST數(shù)據(jù)集。這個(gè)任務(wù)是識(shí)別手寫的0到9的數(shù)字。

首先,TensorFlow具有加載數(shù)據(jù)的功能。你所需要做的就是使用input_data模塊:

from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets(folder_path, one_hot=True)

我們現(xiàn)在要構(gòu)建一個(gè)多層架構(gòu)。在描述學(xué)習(xí)的過程之后,我會(huì)帶著你創(chuàng)建不同類型的層并將其用于MNIST分類任務(wù)。

訓(xùn)練是優(yōu)化損失函數(shù)的過程。損失函數(shù)測量網(wǎng)絡(luò)預(yù)測與實(shí)際標(biāo)注值之間的差別。深度學(xué)習(xí)通常使用稱為交叉熵的技術(shù)來定義損失函數(shù)。

TensorFlow提供了稱為tf.losses.softmax_cross_entropy的函數(shù),該函數(shù)在內(nèi)部應(yīng)用softmax算法,對(duì)模型的非標(biāo)準(zhǔn)化預(yù)測進(jìn)行計(jì)算,并把對(duì)所有類的預(yù)測結(jié)果求和。在我們的例子中,我們使用由tf.train API提供的Adam優(yōu)化器。標(biāo)注結(jié)果將在訓(xùn)練和測試過程中被使用,代表了基本事實(shí)。網(wǎng)絡(luò)的輸出表示神經(jīng)網(wǎng)絡(luò)預(yù)測的結(jié)果,會(huì)在下一節(jié)構(gòu)建網(wǎng)絡(luò)時(shí)被定義。

loss = tf.losses.softmax_cross_entropy(labels, output)

train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)

為了評(píng)估訓(xùn)練過程的性能,我們希望將輸出與實(shí)際標(biāo)注進(jìn)行比較并計(jì)算準(zhǔn)確度:

correct_prediction = tf.equal(tf.argmax(output, 1), tf.argmax(labels, 1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

現(xiàn)在,我們將使用批次方法、固定數(shù)量的步數(shù)和學(xué)習(xí)速率定義一個(gè)簡單的訓(xùn)練過程。對(duì)于MNIST數(shù)據(jù)集,next_batch函數(shù)會(huì)調(diào)用mnist.train.next_batch方法。網(wǎng)絡(luò)訓(xùn)練完成后,我們可以檢查模型在測試數(shù)據(jù)上的表現(xiàn)。

# Open the session

sess = tf.InteractiveSession()

sess.run(tf.global_variables_initializer())

for i in range(steps):

# Get the next batch

input_batch, labels_batch = next_batch(100)

feed_dict = {x_input: input_batch, y_labels: labels_batch}

# Print the current batch accuracy every 100 steps

if i%100 == 0:

train_accuracy = accuracy.eval(feed_dict=feed_dict)

print(“Step %d, training batch accuracy %g”%(i, train_accuracy))

# Run the optimization step

train_step.run(feed_dict=feed_dict)

# Print the test accuracy once the training is over

print(“Test accuracy: %g”%accuracy.eval(feed_dict={x_input: test_images, y_labels: test_labels}))

對(duì)于實(shí)際的訓(xùn)練過程,讓我們從簡單的開始,創(chuàng)建只有一個(gè)輸出層的網(wǎng)絡(luò)。我們首先為輸入數(shù)據(jù)和標(biāo)注定義占位符。在訓(xùn)練階段,它們將存儲(chǔ)來自MNIST數(shù)據(jù)集的數(shù)據(jù)。由于數(shù)據(jù)被扁平化了,輸入層只有一個(gè)維度。輸出層的大小對(duì)應(yīng)于標(biāo)注種類的數(shù)量。輸入和標(biāo)注都將額外的維度設(shè)置為None,這就能應(yīng)對(duì)可變數(shù)量的樣本數(shù)據(jù)。

input = tf.placeholder(tf.float32, [None, image_size*image_size])

labels = tf.placeholder(tf.float32, [None, labels_size])

現(xiàn)在是構(gòu)建令人興奮的部分的時(shí)候了:輸出層。背后的魔力非常簡單明了。其中的每個(gè)神經(jīng)元都有權(quán)重和偏置量的參數(shù),從每個(gè)輸入維度獲取數(shù)據(jù)并進(jìn)行一些計(jì)算。這是使它成為一個(gè)完全連接的層。

TensorFlow的tf.layers包讓你只用一行代碼就可以完成所有這些工作。你需要提供的就只是輸入和層的大小。

output = tf.layers.dense(inputs=input, units=labels_size)

我們的第一個(gè)網(wǎng)絡(luò)在準(zhǔn)確性方面并不令人印象深刻。但它很簡單,所以它運(yùn)行速度非常快。

我們將嘗試通過在輸入和輸出之間添加更多的層來改進(jìn)我們的網(wǎng)絡(luò)。這些層被稱為隱藏層。首先,我們添加另一個(gè)全連接層進(jìn)去。

上面的體系結(jié)構(gòu)需要進(jìn)行一些小的更改。首先,還有另一個(gè)參數(shù)被用來表示隱藏層的神經(jīng)元數(shù)量。隱藏層本身會(huì)獲取輸入數(shù)據(jù)并連接到輸出層:

hidden = tf.layers.dense(inputs=input, units=1024, activation=tf.nn.relu)

output = tf.layers.dense(inputs=hidden, units=labels_size)

注意,這次我們使用了一個(gè)激活參數(shù)。它對(duì)從神經(jīng)元經(jīng)過的數(shù)據(jù)都會(huì)使用激活函數(shù)(我們這里用的是ReLU)運(yùn)算。該算法已被證明在深度架構(gòu)下會(huì)工作得非常好。

你應(yīng)該看到我們的性能略有下降。我們的網(wǎng)絡(luò)正在變得更加深,這意味著它需要調(diào)整更多的參數(shù),這使得訓(xùn)練過程變長。另一方面,這顯著地提高了準(zhǔn)確度,達(dá)到94%。

接下來我們要添加的兩層是卷積網(wǎng)絡(luò)的組成部分。它們的工作方式與全連接型不同,并且對(duì)具有兩個(gè)或更多維度(如圖像)的輸入表現(xiàn)尤其出色。卷積層的參數(shù)是卷積窗口的大小和濾波器的數(shù)量。對(duì)填充設(shè)置為same表明生成的特征層具有相同的大小。在這一步之后,我們應(yīng)用最大池化。

使用卷積可以讓我們利用輸入數(shù)據(jù)的二維表示。當(dāng)我們把數(shù)字圖片打平并將結(jié)果輸入全連接層時(shí),這些二維信息就丟失了。要變回到原始結(jié)構(gòu),我們可以使用tf.reshape函數(shù)。

input2d = tf.reshape(input, [-1,image_size,image_size,1])

下面是進(jìn)行卷積和最大池化的代碼。請(qǐng)注意,為了和下一個(gè)全連接層進(jìn)行連接,這一層的輸出必須再次被打平。

conv1 = tf.layers.conv2d(inputs=input2d, filters=32, kernel_size=[5, 5], padding=”same”, activation=tf.nn.relu)

pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

pool_flat = tf.reshape(pool1, [-1, 14 * 14 * 32])

hidden = tf.layers.dense(inputs= pool_flat, units=1024, activation=tf.nn.relu)

output = tf.layers.dense(inputs=hidden, units=labels_size)

向圖片應(yīng)用卷積可以提高準(zhǔn)確度(達(dá)到97%),但會(huì)顯著地減慢訓(xùn)練的過程。要充分利用這一模型,我們應(yīng)該繼續(xù)加入另一層。再次使用2D輸入,但只打平第二層的輸出?,F(xiàn)在第一層的輸出不需要打平了,因?yàn)楹竺婢矸e可以工作在更高的維度上。

conv2 = tf.layers.conv2d(inputs=pool1, filters=64, kernel_size=[5, 5], padding=”same”, activation=tf.nn.relu)

pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

pool_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])

此時(shí),你在運(yùn)行代碼時(shí)需要非常耐心。網(wǎng)絡(luò)的復(fù)雜性增加了很多開銷,但我們獲得了更好的準(zhǔn)確性。

現(xiàn)在我們會(huì)介紹另一種可以改善網(wǎng)絡(luò)性能并避免過擬合的技術(shù)。它被稱為Dropout,我們把它用到隱藏層的全連接層。Dropout的方式是單個(gè)神經(jīng)節(jié)要么關(guān)閉,要么按一定的概率被保留。它被用于訓(xùn)練階段,因此請(qǐng)記住需要在評(píng)估網(wǎng)絡(luò)性能時(shí)關(guān)閉它。

要使用Dropout,我們需要稍微更改代碼。首先,我們需要一個(gè)占位符來在訓(xùn)練和測試階段保存Dropout的概率。

should_drop = tf.placeholder(tf.bool)

其次,我們需要定義drouput并將其連接到輸出層。架構(gòu)的其余部分保持不變。

hidden = tf.layers.dense(inputs=pool_flat, units=1024, activation=tf.nn.relu)

dropout = tf.layers.dropout(inputs=hidden, rate=0.5, training=should_drop)

output = tf.layers.dense(inputs=dropout, units=labels_size)

在本文中,我們首先介紹了深度學(xué)習(xí)的概念,并使用TensorFlow構(gòu)建了一個(gè)多層卷積網(wǎng)絡(luò)。該代碼可以重新用于圖像識(shí)別任務(wù)以及其他任何數(shù)據(jù)集。但是,更復(fù)雜的圖像需要修改更深的層數(shù)以及更復(fù)雜的架構(gòu),例如Inception或ResNets。

本練習(xí)的關(guān)鍵在于你不需要掌握統(tǒng)計(jì)技術(shù)或編寫復(fù)雜的矩陣乘法代碼來創(chuàng)建人工智能模型。TensorFlow就可以處理這些問題。但是,你需要知道哪些算法適合你自己的數(shù)據(jù)和應(yīng)用,并確定最佳的超參數(shù),例如網(wǎng)絡(luò)體系架構(gòu)、層的深度、批處理的大小、學(xué)習(xí)速率等。請(qǐng)注意,TensorFlow提供給你的各種選擇需要你自己承擔(dān)很多責(zé)任。

這篇博文是O’ReillyTensorFlow的合作產(chǎn)物。請(qǐng)閱讀我們的編輯獨(dú)立聲明。

Barbara Fusinska

Barbara是一名軟件開發(fā)人員、架構(gòu)師和團(tuán)隊(duì)負(fù)責(zé)人,擁有超過10年的從業(yè)經(jīng)驗(yàn)。從快節(jié)奏的創(chuàng)業(yè)公司到國際大型公司她都曾工作過。Barbara喜歡使用最佳實(shí)踐和具有大量常識(shí)的現(xiàn)代模式構(gòu)建漂亮的系統(tǒng)架構(gòu)。這種熱情與對(duì)團(tuán)隊(duì)合作的堅(jiān)定信念和為人們創(chuàng)造最佳環(huán)境以發(fā)揮人類的潛力相伴隨。你可以用@BasiaFusinska在Twitter上或通過她的博客http://barbarafusinska.com找到她。

Samples from the MNIST test data set (source: Josef Steppan on Wikimedia Commons)