<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 5. TensorFlow 中的多層神經網絡 在本章中,我將與讀者一起編寫一個簡單的深度學習神經網絡,該網絡使用與前一章相同的 MNIST 數字識別問題。 隨著我的前進,深度學習神經網絡由疊在一起的多個層組成。 具體來說,在本章中我們將構建一個卷積網絡,這是深度學習的典型例子。 卷揚神經網絡由 Yann LeCunn 等人于 1998 年推出并推廣。 這些卷積網絡最近引領了圖像識別領域的最新技術;例如:在我們的數字識別案例中,它們的準確度高于 99%。 在本章的其余部分,我將以示例代碼為主,我將解釋這些網絡的兩個最重要的概念:卷積和池化,而不輸入參數的細節,鑒于本書的介紹性質。 但是,讀者將能夠運行所有代碼,我希望它能讓你了解卷積網絡背后的通用思想。 ### 卷積神經網絡 卷積神經網絡(也稱為 CNN 或 CovNets)是深度學習的一個特例,并且在計算機視覺領域產生了重大影響。 CNN 的典型特征是它們幾乎總是將圖像作為輸入,這產生了更有效的實現并且減少所需參數的數量。 讓我們看看我們的 MNIST 數字識別示例:在讀取 MNIST 數據并使用 TensorFlow 定義占位符之后,就像我們在上一個示例中所做的那樣: ```py import input_data mnist = input_data.read_data_sets('MNIST_data', one_hot=True) import tensorflow as tf x = tf.placeholder("float", shape=[None, 784]) y_ = tf.placeholder("float", shape=[None, 10]) ``` 我們可以重建輸入數據圖像的原始形狀。 我們可以這樣做: ```py x_image = tf.reshape(x, [-1,28,28,1]) ``` 這里我們將輸入形狀更改為 4D 張量,第二維和第三維對應于圖像的寬度和高度,而最后一維對應于顏色通道的數量,在這種情況下為 1。 通過這種方式,我們可以將神經網絡的輸入視為大小為`28×28`的二維空間,如圖所示: ![](https://jorditorres.org/wp-content/uploads/2016/02/image072-300x282.png) 定義卷積神經網絡有兩個基本原則:濾波器和特征映射。 這些原則可以表示為特定的神經元分組,我們將很快看到。 但首先,鑒于它們在 CNN 中的重要性,我們將簡要介紹這兩個原則。 直覺上,我們可以說卷積層的主要目的是檢測圖像中的特征或視覺特征,考慮邊緣,線條,顏色斑點等。 這是由我們剛剛討論過的,連接輸入層的隱藏層來處理的。 在我們感興趣的 CNN 的案例中,輸入數據沒有完全連接到第一個隱藏層的神經元;這只發生在輸入神經元中的一個小型局部空間中,輸入神經元存儲圖像像素值。 這可以看作: ![](https://jorditorres.org/wp-content/uploads/2016/02/image074.png) 更確切地說,在給定的示例中,隱藏層的每個神經元與輸入層的`5×5`小區域(因此是 25 個神經元)連接。 我們可以認為這是一個大小為`5×5`的窗口,它滑過包含輸入圖像的整個`28×28`大小的輸入層。 窗口滑過整個神經元層。 對于窗口的每個位置,隱藏層中都有一個處理該信息的神經元。 我們可以通過假設窗口從圖像的左上角開始來可視化;這將信息提供給隱藏層的第一個神經元。 然后窗口向右滑動一個像素;我們將這個`5×5`區域與隱藏層中的第二個神經元連接起來。 我們繼續這樣,直到整個空間從上到下,從左到右被窗口覆蓋。 ![](https://jorditorres.org/wp-content/uploads/2016/02/image076.png) 分析我們提出的具體案例,我們觀察到,給定一個大小為`28×28`的輸入圖像和一個大小為`5×5`的窗口,在第一個隱藏層中產生了`24×24`的神經元,因為我們只能這樣做,在觸及輸入圖像的右下邊緣之前,將窗口向下移動 23 次,向右移動 23 次。 這假設窗口每次只移動 1 個像素,因此新窗口與剛剛前進的舊窗口重疊。 但是,可以在卷積層中一次移動多于 1 個像素,該參數稱為`stride`(步長)。 另一個擴展是用零(或其他值)填充邊緣,以便窗口可以在圖像的邊緣上滑動,這可以產生更好的結果。 控制此功能的參數稱為`padding`(填充)[39],你可以使用該參數確定填充的大小。 鑒于本書的介紹性質,我們不會進一步詳細介紹這兩個參數。 鑒于我們的研究案例,并遵循前一章的形式,我們將需要一個偏置值`b`和一個`5×5`的權重矩陣`W`來連接隱層和輸入層的神經元。CNN的一個關鍵特性是,該權重矩陣`W`和偏置`b`在隱藏層中的所有神經元之間共享;我們對隱藏層中的神經元使用相同的`W`和`b`。 在我們的情況下,這是`24×24`(576)個神經元。 讀者應該能夠看到,與完全連接的神經網絡相比,這大大減少了人們需要的權重參數。 具體而言,由于共享權重矩陣`W`,這從 14000(`5x5x24x24`)減少到僅 25(`5x5`)。 這個共享矩陣`W`和偏置`b`通常在 CNN 的上下文中稱為核或過濾器。 這些過濾器類似于用于修飾圖像的圖像處理程序,在我們的例子中用于查找微分特征。 我建議查看 GIMP [40] 手冊中的示例,以便了解卷積過程的工作原理。 矩陣和偏置定義了核。 核只檢測圖像中的某個相關特征,因此建議使用多個核,每個核對應我們想要檢測的每個特征。 這意味著 CNN 中的完整卷積層由幾個核組成。 表示幾個核的常用方法如下: ![](https://jorditorres.org/wp-content/uploads/2016/02/image078.png) 第一個隱藏層由幾個核組成。 在我們的例子中,我們使用 32 個核,每個核由`5×5`的權重矩陣`W`和偏置`b`定義,偏置`b`也在隱層的神經元之間共享。 為了簡化代碼,我定義了以下兩個與權重矩陣`W`和偏置`b`相關的函數: ```py def weight_variable(shape): initial = tf.truncated_normal(shape, stddev=0.1) return tf.Variable(initial) def bias_variable(shape): initial = tf.constant(0.1, shape=shape) return tf.Variable(initial) ``` 在沒有詳細說明的情況下,習慣上用一些隨機噪聲初始化權重,偏置值略微為正。 除了我們剛才描述的卷積層之外,通常卷積層后面跟著一個所謂的池化層。 池化層簡單地壓縮來自卷積層的輸出,并創建卷積層輸出的信息的緊湊版本。 在我們的示例中,我們將使用卷積層的`2×2`區域,我們使用池化將它的數據匯總到單個點: ![](https://jorditorres.org/wp-content/uploads/2016/02/image080.png) 有幾種方法可以執行池化來壓縮信息;在我們的示例中,我們將使用名為最大池化的方法。 通過僅保留所考慮的`2×2`區域中的最大值來壓縮信息。 如上所述,卷積層由許多核組成,因此,我們將分別對每個核應用最大池化。 通常,可以有多層池化和卷積: ![](https://jorditorres.org/wp-content/uploads/2016/02/image082.png) 這使`24×24`的卷積層結果,被對應`12×12`的最大池化層轉換為`12×12`的空間,其中每個塊來源于`2×2`的區域。 請注意,與卷積層不同,數據是平鋪的,而不是由滑動窗口創建的。 直觀上,我們可以解釋最大池化,來確定特定特征是否存在于圖像中的任何位置,特征的確切位置不如對于其他特征的相對位置重要。 ### 模型的實現 在本節中,我將基于可在 TensorFlow [41] 網站上找到的高級示例(Deep MNIST for experts),提供編寫 CNN 的示例代碼。 正如我在開始時所說的那樣,參數的許多細節需要處理和理論方法,比本書中給出的更詳細。 因此,我將僅概述代碼,而不涉及 TensorFlow 參數的許多細節。 正如我們已經看到的,我們必須為卷積和池化層定義幾個參數。 我們將在每個維度中使用大小為 1 的步幅(這是滑動窗口的步長)和零填充模型。 我們將應用的池化是`2×2`的最大池化。 與上面類似,我建議使用以下兩個通用函數來編寫涉及卷積和最大池化的更清晰的代碼。 ```py def conv2d(x, W): return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') def max_pool_2x2(x): return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') ``` 現在是時候實現第一個卷積層,然后是池化層。 在我們的示例中,我們有 32 個過濾器,每個過濾器的窗口大小為`5×5`。 我們必須定義一個張量,來保持這個權重矩陣`W`的形狀為`[5,5,1,32]`:前兩個維度是窗口的大小,第三個是通道的數量,在我們的例子中為 1 。 最后一個定義了我們想要使用的過濾器數量。 此外,我們還需要為 32 個權重矩陣中的每一個定義偏置。 使用先前定義的函數,我們可以在 TensorFlow 中編寫它,如下所示: ```py W_conv1 = weight_variable([5, 5, 1, 32]) b_conv1 = bias_variable([32]) ``` ReLU(整流線性單元)激活函數最近成為深度神經網絡隱藏層中使用的默認激活函數。 這個簡單的函數返回`max(0, x)`,因此它為負值返回 0,否則返回`x`。 在我們的示例中,我們將在卷積層之后的隱藏層中使用此激活函數。 我們編寫的代碼首先將卷積應用于輸入圖像`x_image`,它在 2D 張量`W_conv1`中,返回圖像卷積的結果,然后加上偏置,最終應用 ReLU 激活函數。 最后一步,我們將最大池化應用于輸出: ```py h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) h_pool1 = max_pool_2x2(h_conv1) ``` 在構建深度神經網絡時,我們可以將多個層疊在一起。 為了演示如何執行此操作,我將創建一個帶有 64 個過濾器和`5×5`窗口的輔助卷積層。 在這種情況下,我們必須傳遞 32 作為我們需要的通道數,因為它是前一層的輸出大小: ```py W_conv2 = weight_variable([5, 5, 32, 64]) b_conv2 = bias_variable([64]) h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) h_pool2 = max_pool_2x2(h_conv2) ``` 由于我們將`5×5`窗口應用于步長為 1 的`12×12`空間,因此卷積的結果輸出具有`8×8`的維數。 下一步是將一個全連接的層添加到`8×8`輸出,然后將其輸入到最后的 softmax 層,就像我們在前一章中所做的那樣。 我們將使用 1024 個神經元的一層,允許我們處理整個圖像。 權重和偏置的張量如下: ```py W_fc1 = weight_variable([8 * 8 * 64, 1024]) b_fc1 = bias_variable([1024]) ``` 請記住,張量的第一個維度表示來自第二個卷積層的大小為`8x8`的 64 個過濾器,而第二個參數是層中神經元的數量,我們可以自由選擇(在我們的例子中是 1024)。 現在,我們想將張量展開為向量。 我們在前一章中看到,softmax 需要將向量形式的展開圖像作為輸入。 這通過將權重矩陣`W_fc1`與展開向量相乘,加上偏置`b_fc1`,再應用 ReLU 激活函數來實現: ```py h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) ``` 下一步將使用稱為 dropout 的技術減少神經網絡中的有效參數量。 這包括刪除節點及其傳入和傳出連接。 丟棄和保留哪些神經元是隨機決定的。 為了以一致的方式執行此操作,我們將在代碼中為丟棄或保留的神經元分配概率。 在沒有太多細節的情況下,dropout 降低了模型的過擬合風險。 當隱藏層具有大量神經元并因此可以產生非常富有表現力的模型時,這可能發生;在這種情況下,可能會對隨機噪聲(或誤差)建模。 這被稱為過擬合,如果與輸入的維度相比,模型具有大量參數,則更有可能。 最好是避免這種情況,因為過擬合的模型具有較差的預測表現。 在我們的模型中,我們應用 dropout,它包括在最終的 softmax 層之前使用 dropout 函數 `tf.nn.dropout`。 為此,我們構造一個占位符來存儲在 dropout 期間保留神經元的概率: ```py keep_prob = tf.placeholder("float") h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) ``` 最后,我們將 softmax 層添加到我們的模型中,就像前一章中所做的那樣。 請記住,sofmax 返回輸入屬于每個類的概率(在我們的例子中為數字),以便總概率加起來為 1。 softmax 層代碼如下: ```py W_fc2 = weight_variable([1024, 10]) b_fc2 = bias_variable([10]) y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) ``` ### 模型的訓練和評估 我們現在通過調整卷積層和及全連接層中的所有權重,來準備訓練我們剛剛定義的模型,并獲得我們的帶標簽的圖像的預測。 如果我們想知道模型的執行情況,我們必須遵循上一章中的示例。 以下代碼與前一章中的代碼非常相似,但有一個例外:我們用 ADAM 優化器替換梯度下降優化器,因為該算法實現了不同的優化器,根據文獻 [42],它具有某些優點。 我們還需要在`feed_dict`參數中包含附加參數`keep_prob`,該參數控制我們之前討論過的 dropout 層的概率。 ```py cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv)) train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) sess = tf.Session() sess.run(tf.initialize_all_variables()) for i in range(20000): batch = mnist.train.next_batch(50) if i%100 == 0: train_accuracy = sess.run( accuracy, feed_dict={x:batch[0], y_: batch[1], keep_prob: 1.0}) print("step %d, training accuracy %g"%(i, train_accuracy)) sess.run(train_step,feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5}) print("test accuracy %g"% sess.run(accuracy, feed_dict={ x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0})) ``` 與之前的模型一樣,整個代碼可以在本書的 Github 頁面上找到,可以驗證該模型的準確率達到 99.2%。 以下是使用 TensorFlow 構建,訓練和評估深度神經網絡的簡要介紹。 如果讀者設法運行提供的代碼,他或她已經注意到該網絡的訓練時間明顯長于前幾章的訓練時間;你可以想象,擁有更多層的網絡需要花費更長的時間來訓練。 我建議你閱讀下一章,其中解釋了如何使用 GPU 進行訓練,這將減少你的訓練時間。 本章的代碼可以在本書 github 頁面 [43] 的`CNN.py`中找到,用于研究目的的代碼在下面: ```py import input_data mnist = input_data.read_data_sets('MNIST_data', one_hot=True) import tensorflow as tf x = tf.placeholder("float", shape=[None, 784]) y_ = tf.placeholder("float", shape=[None, 10]) x_image = tf.reshape(x, [-1,28,28,1]) print "x_image=" print x_image def weight_variable(shape): initial = tf.truncated_normal(shape, stddev=0.1) return tf.Variable(initial) def bias_variable(shape): initial = tf.constant(0.1, shape=shape) return tf.Variable(initial) def conv2d(x, W): return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') def max_pool_2x2(x): return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') W_conv1 = weight_variable([5, 5, 1, 32]) b_conv1 = bias_variable([32]) h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) h_pool1 = max_pool_2x2(h_conv1) W_conv2 = weight_variable([5, 5, 32, 64]) b_conv2 = bias_variable([64]) h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) h_pool2 = max_pool_2x2(h_conv2) W_fc1 = weight_variable([7 * 7 * 64, 1024]) b_fc1 = bias_variable([1024]) h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) keep_prob = tf.placeholder("float") h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) W_fc2 = weight_variable([1024, 10]) b_fc2 = bias_variable([10]) y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv)) train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) sess = tf.Session() sess.run(tf.initialize_all_variables()) for i in range(200): batch = mnist.train.next_batch(50) if i%10 == 0: train_accuracy = sess.run( accuracy, feed_dict={ x:batch[0], y_: batch[1], keep_prob: 1.0}) print("step %d, training accuracy %g"%(i, train_accuracy)) sess.run(train_step,feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5}) print("test accuracy %g"% sess.run(accuracy, feed_dict={ x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0})) ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看