<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 4. TensorFlow 中的單層神經網絡 在前言中,我評論說深度學習的一個常見用途包括模式識別。 考慮到這一點,就像初學者通過在屏幕上打印“Hello World”開始學習編程語言一樣,在深度學習中,我們首先要識別手寫數字。 在本章中,我將介紹如何在 TensorFlow 中逐步構建具有單個層的神經網絡。 這個神經網絡將識別手寫數字,它基于 TensorFlow 的初學者教程 [27] 的不同示例之一。 鑒于本書的介紹風格,我選擇引導讀者,同時通過示例的某些步驟簡化了一些概念和理論上的原因。 如果讀者在閱讀本章后有興趣了解這個示例的理論概念,我建議閱讀神經網絡和深度學習 [28],可在線獲取,它介紹了這個例子,但深入研究理論概念。 ### MNIST 數據集 MNIST 數據集由一組包含手寫數字的黑白圖像組成,包含60,000 多個用于訓練模型的示例,以及 10,000 個用于測試它的示例。 MNIST 數據集可以在 MNIST 數據庫 [29] 中找到。 這個數據集非常適合大多數開始在實例上進行模式識別的人,而不必花時間進行數據預處理或格式化,這是處理圖像時的兩個非常重要的步驟,但時間很長。 黑白圖像(二值)已經標準化為`20×20`像的素圖像,保留了寬高比。 對于這種情況,我們注意到圖像包含灰色像素 [30],是歸一化算法的結果(將所有圖像的分辨率降低到最低級別之一)。 之后,通過計算質心并將其移動到幀的中心,圖像以`28×28`像素幀為中心。 圖像類似于此處顯示的圖像: ![](https://jorditorres.org/wp-content/uploads/2016/02/image034.png) 此外,本例所需的學習類型是監督學習;圖像用它們代表的數字標記。 這是最常見的機器學習形式。 在這種情況下,我們首先收集數字圖像的大數據集,每個數字都用其值標記。 在訓練期間,模型接受圖像并以得分向量的形式產生輸出,每個類別一個得分。 我們希望所需類別在所有類別中得分最高,但這在訓練之前不太可能發生。 我們計算一個目標函數來衡量輸出分數和所需分數模式之間的誤差(正如我們在前面章節中所做的那樣)。 然后,模型修改其內部可調參數,稱為權重,來減少此誤差。 在典型的深度學習系統中,可能存在數億個這樣的可調節權重,以及用于訓練機器的數億個標記示例。 我們將考慮一個較小的例子,來幫助理解這種模型的工作原理。 要輕松下載數據,你可以使用從 Google 的網站 [32] 獲取腳本`input_data.py`[31],但它為你上傳到的這本書的 github 上。 只需將代碼`input_data.py`下載到使用 TensorFlow 編寫神經網絡的同一工作目錄中。 在你的應用程序中,你只需要按以下方式導入和使用: ```py import input_data mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) ``` 執行這兩條指令后,你將在`mnist.train`中獲得完整的訓練數據集,并在`mnist.test`中設置測試數據。 如前所述,每個元素由一個圖像組成,標記為`xs`,并且其對應的標簽`ys`,以便更容易表達處理代碼。 請記住,所有數據集,訓練和測試集都包含`xs`和`ys`;此外,訓練圖像通過`mnist.train.images`引用,訓練標簽通過`mnist.train.labels`引用。 如前所述,圖像由`28×28`像素形成,并且可以表示為數字矩陣。 例如,數字 1 的圖像之一可以表示為: ![](https://jorditorres.org/wp-content/uploads/2016/02/image036-1000x388.png) 其中每個位置表示 0 到 1 之間每個像素的缺失度。 該矩陣可以表示為`28×28 = 784`個數的數組。 實際上,圖像已經變換為 784 維度的向量空間中的一堆點中。 只是當我們將結構減少到 2 維時,我們可能會丟失部分信息,對于某些計算機視覺算法,這可能會影響他們的結果,但對于本教程中使用的最簡單的方法,這不會是一個問題。 總而言之,我們在 2D 中擁有張量`mnist.train.images`,其中調用函數`get_shape()`表示其形狀: ```py TensorShape([Dimension(60000), Dimension(784)]) ``` 第一維索引每個圖像和第二維是每個像素。 張量的每個元素是 0 到 1 之間的每個像素的強度。 此外,我們有 0 到 9 之間的數字形式的標簽,表示每個圖像代表哪個數字。 在這個例子中,我們將標簽表示為 10 個位置的向量,其中所表示數字的對應位置是 1 而其余為 0。 所以`mnist.train.labels es`是形如`TensorShape([Dimension(60000), Dimension10)])`的張量。 ### 人造神經元 雖然本書并未關注神經網絡的理論概念,但簡要而直觀地介紹神經元如何學習訓練數據,將有助于讀者了解正在發生的事情。 那些已經了解該理論并且只是尋求如何使用 TensorFlow 的讀者可以跳過本節。 讓我們看一個神經元如何學習的簡單但說明性的例子。 假設有一組標記為“方形”和“圓形”的點。 給定一個新的點`X`,我們想知道對應哪個標簽: ![](https://jorditorres.org/wp-content/uploads/2016/02/Screen-Shot-2016-02-16-at-09.30.14.png) 通常的近似可能是繪制一條劃分兩組的直線并將其用作分類器: ![](https://jorditorres.org/wp-content/uploads/2016/02/Screen-Shot-2016-02-16-at-09.30.09.png) 在這種情況下,輸入數據由形狀為`(x, y)`的向量表示,表示此二維空間中的坐標,并且我們的函數返回“0”或“1”(線上方或下方)來了解如何將其歸類為“方形”或“圓形”。 在數學上,正如我們在線性回歸章節中所學到的,“直線”(分類器)可以表示為`y = W * x + b`。 推廣時,神經元必須學習權重`W`(與輸入數據`X`維度相同)和偏移量`b`(在神經元中稱為偏置),來學習如何分類這些值。 利用它們,神經元將計算權重輸入`X`和`W`的加權和,并添加偏移`b`;最后神經元將應用非線性“激活”函數來產生“0”或“1”的結果。 神經元的功能可以更正式地表示為: ![](https://jorditorres.org/wp-content/uploads/2016/02/image043.png) 在為我們的神經元定義了這個函數后,我們想知道神經元如何從帶有“方塊”和“圓圈”的標記數據中學習參數`W`和`b`,以便稍后標記新點`X`。 第一種方法可以類似于我們對線性回歸所做的,即用已知的標記數據喂養神經元,并將獲得的結果與真實的結果進行比較。 然后,在迭代時,調整`W`和`b`來使誤差最小化,如第 2 章中線性回歸線所示。 一旦我們得到`W`和`b`參數,我們就可以計算加權和,現在我們需要函數將存儲在`z`中的結果轉換為`0`或`1`。 有幾個可用的激活函數,對于這個例子,我們可以使用一個名為 sigmoid [33] 的流行函數,返回 0 到 1 之間的實數值。 ![](https://jorditorres.org/wp-content/uploads/2016/02/image046.png) 看看公式,我們發現它將傾向于返回接近 0 或 1 的值。 如果輸入`z`足夠大且為正,則`exp(-z)`為零,然后`y`為 1。 如果輸入`z`足夠大且為負,則`exp(-z)`也會變為大正數,因此分母變大,最終`y`變為 0。 如果我們繪制函數,它將如下所示: ![](https://jorditorres.org/wp-content/uploads/2016/02/image045.png) 從這里我們已經介紹了如何定義神經元,但神經網絡實際上是以不同方式互相連接,并使用不同激活函數的神經元組合。 鑒于本書的范圍,我不會涉及神經網絡的所有擴展,但我向你保證它真的令人興奮。 只是提到神經網絡的一個特定情況(其中第 5 章基于),神經元組織為層的形式,其中下層(輸入層)接收輸入,上層(輸出層)生成響應值。 神經網絡可以有幾個中間層,稱為隱藏層。 表示這種情況的直觀方式是: ![](https://jorditorres.org/wp-content/uploads/2016/02/image049.gif) 在這些網絡中,每層的神經元與前一層的神經元通信來接收信息,然后將其結果傳遞給下一層的神經元。 如前所述,除了Sigmoid之外還有更多的激活函數,每個激活函數具有不同的屬性。例如,當我們想要在輸出層將數據分類為兩個以上的類時,我們可以使用 Softmax [34] 激活函數,它是 sigmoid 函數的泛化。 Softmax 能夠獲得每個類的概率,因此它們的和為 1,最可能的結果是概率最高的結果。 ### 一個簡單的例子:Softmax 請記住,要解決的問題是,給定輸入圖像,我們得到它屬于某個數字的概率。 例如,我們的模型可以預測,圖像 80% 是“9”,但是有 5% 的機會為“8”(由于可疑性較低的痕跡),并且還給出,一定的低概率為任何其他數字。 識別手寫數字存在一些不確定性,我們無法以 100% 的置信度識別數字。 在這種情況下,概率分布使我們更好地了解我們對預測的信心。 因此,我們有一個輸出向量,其中包含不同輸出標簽的概率分布,這是多余的。 這是一個具有 10 個概率值的向量,每個概率值對應于 0 到 9 的每個數字,并且所有概率總和為 1。 如前所述,我們通過使用激活函數為 softmax 的輸出層來實現此目的。 具有 softmax 函數的神經元的輸出,取決于其層的其他神經元的輸出,因為它們的所有輸出必須總和為 1。 softmax 函數有兩個主要步驟:首先,計算屬于某個標簽的圖像的“證據”,然后將證據轉換為每個可能標簽的概率。 ### 歸屬的證據 測量某個圖像屬于特定類別/標簽的證據,通常的近似是計算像素強度的加權和。 當高強度的像素恰好不在給定類中時,該權重為負,如果該像素在該類中頻繁出現,則該權重為正。 讓我們看一個圖形示例:假設一個數學“0”的學習模型(我們將看到以后如何學習)。 此時,我們將模型定義為“某事物”,其中包含了解數字是否屬于特定類的信息。 在這種情況下,我們選擇了如下所示的模型,其中紅色(或 b/n 版本的亮灰色)代表負例(也就是,減少對“0”中存在的那些像素的支持),而藍色(b/n 版的深灰色)代表了正例。看看它: ![](https://jorditorres.org/wp-content/uploads/2016/02/image050.png) 想象一下`28×28`像素的白紙,并畫上“0”。 通常我們的零將繪制在藍色區域中(請記住,我們在`20×20`繪圖區域周圍留下了一些空間,稍后將其居中)。 很明顯,如果我們的繪圖穿過紅色區域,很可能我們沒有繪制零。 因此,使用一種度量標準,獎勵那些踩到藍色區域的像素,并懲罰那些踩到紅色區域的像素,似乎是合理的。 現在考慮“3”:很明顯,我們的模型的“0”的紅色區域將懲罰它為“0”的概率。 但是如果參考模型是下面的那個,通常形成“3”的像素將遵循藍色區域; “0”的繪制也會進入紅色區域。 ![](https://jorditorres.org/wp-content/uploads/2016/02/image052.png) 我希望看到這兩個例子的讀者理解,所解釋的近似如何讓我們估計哪張圖代表哪個數字。 下圖顯示了從 MNIST 數據集中學習的十個不同標簽/類的示例(從 Tensorflow [35] 的示例中提取)。 請記住,紅色(亮灰色)表示負權重,藍色(深灰色)表示正值。 ![](https://jorditorres.org/wp-content/uploads/2016/02/image054.png) 以更正式的方式,我們可以說給出輸入`x`的類`i`的證據表示為: ![](https://jorditorres.org/wp-content/uploads/2016/02/image056.png) 其中`i`表示類(在我們的情況下,介于 0 和 9 之間),`j`是對輸入圖像求和的索引。 最后,`Wi`表示上述權重。 請記住,一般來說,模型還包括一個表示偏置的額外參數,增加了一些基本不確定性。 在我們的情況下,公式最終就像這樣: ![](https://jorditorres.org/wp-content/uploads/2016/02/image058.png) 對于每個`i`(在 0 和 9 之間),我們得到 784 個元素(`28×28`)的矩陣`Wi`,其中每個元素`j`乘以輸入圖像的相應分量`j`,共有 784 個分量,然后加上`bi`。矩陣演算和索引的圖形視圖是這樣的: ![](https://jorditorres.org/wp-content/uploads/2016/02/image061.gif) ### 歸屬概率 我們評論說,第二步是計算概率。 具體來說,我們使用 softmax 函數將證據總和轉換為預測概率,表示為`y`: ![](https://jorditorres.org/wp-content/uploads/2016/02/image062.png) 請記住,輸出向量必須是和為 1 的概率函數。 為了標準化每個成分,softmax 函數使用每個輸入的指數值,然后按如下方式對它們進行標準化: ![](https://jorditorres.org/wp-content/uploads/2016/02/image064.png) 使用指數時獲得的效果是權重的乘法效應。 此外,當一個類的證據很小時,這個類的支持由之前權重的一小部分減少。 此外,softmax 對權重進行歸一化,使它們總和為 1,從而產生概率分布。 這種函數的一個有趣的事實是,好的預測將有一個接近 1 的輸出值,而所有其他輸出將接近零;在弱預測中,某些標簽可能會顯示類似的支持。 ### 在 TensorFlow 中編程 在簡要描述了算法做了什么來識別數字之后,我們可以在 TensorFlow 中實現它。 為此,我們可以快速了解張量應如何存儲我們的數據和模型參數。 為此,下圖描述了數據結構及其關系(來幫助讀者輕松回憶我們的每個問題): ![](https://jorditorres.org/wp-content/uploads/2016/02/image066.png) 首先,我們創建兩個變量來包含權重`W`和偏置`b`: ```py W = tf.Variable(tf.zeros([784,10])) b = tf.Variable(tf.zeros([10])) ``` 這些變量是使用`tf.Variable`函數和變量的初始值創建的;在這種情況下,我們用包含零的常數張量初始化張量。 我們看到`W`的形狀為`[Dimension(784), Dimension(10)]`,由其參數定義,常數張量`tf.zeros`和`W`一樣為`[784,10]`。偏置`b`也是一樣,由其參數將形狀規定為`[Dimension(10)]`。 矩陣`W`具有該大小,因為我們想要為 10 個可能的數字中的每一個乘以 784 個位置的圖像向量,并在與`b`相加之后產生一定數量的證據。 在使用 MNIST 進行研究的情況下,我們還創建了二維張量來保存`x`點的信息,使用以下代碼行??: ```py x = tf.placeholder("float", [None, 784]) ``` 張量`x`將用于存儲 MNIST 圖像,作為 784 個浮點向量(我們使用`None`指示維度可以是任何大小;在我們的例子中它將等于學習過程中包含的元素數量)。 現在我們定義了張量,我們可以實現我們的模型。 為此,TensorFlow 提供了幾個操作,即`tf.nn.softmax(logits, name=None)`。它是其中一個可用的操作,實現了前面描述的 softmax 函數。 參數必須是張量,并且名稱可選。 該函數返回類型和形狀與傳遞的參數張量相同的張量。 在我們的例子中,我們為這個函數提供了圖像向量`x`乘以權重矩陣`W`加上`b`的結果張量: ```py y = tf.nn.softmax(tf.matmul(x,W) + b) ``` 一旦指定了模型實現,我們就可以使用迭代訓練算法,指定必要的代碼來獲得權重`W`和偏置`b`。 對于每次迭代,訓練算法獲得訓練數據,應用神經網絡并將獲得的結果與預期結果進行比較。 要確定模型何時足夠好,我們必須定義“足夠好”的含義。 正如在前面的章節中所看到的,通常的方法是定義相反的東西:模型使用損失函數的“壞”的程度。 在這種情況下,目標是獲得使函數最小的`W`和`b`的值,它指示模型“壞”的程度。 結果輸出與訓練數據的預期輸出之間的誤差有不同的度量標準。 一個常見的度量是均方誤差或平方歐幾里德距離,這是以前見過的。 盡管如此,一些研究在神經網絡中為此目的提出了其他指標,例如在我們的例子中使用的交叉熵誤差。 此度量標準的計算方式如下: ![](https://jorditorres.org/wp-content/uploads/2016/02/image068.png) 其中`y`是概率的預測分布,`y'`是從訓練數據集的標簽中獲得的實際分布。 我們不會詳細討論交叉熵背后的數學及其在神經網絡中的位置,因為它遠比本書的預期范圍復雜得多;只是表明當兩個分布相同時有最小值。 同樣,如果讀者想要了解此函數的細節,我們建議閱讀神經網絡和深度學習 [36]。 要實現交叉熵度量,我們需要一個新的占位符來表示正確的標簽: ```py y_ = tf.placeholder("float", [None,10]) ``` 用這個占位符,我們可以使用以下代碼行實現交叉熵,代表我們的損失函數: ```py cross_entropy = -tf.reduce_sum(y_*tf.log(y)) ``` 首先,我們使用 TensorFlow 中的內置函數`tf.log()`計算每個元素`y`的對數,然后我們將它們乘以每個`y_`元素。 最后,使用`tf.reduce_sum`,我們對張量的所有元素求和(稍后我們將看到圖像以批量的形式訪問,在這種情況下,交叉熵的值對應于圖像批量`y`而不是單個圖像)。 在迭代中,一旦確定了樣本的誤差,我們必須更正模型(在我們的例子中是修改參數`W`和`b`)來減少下一次迭代中計算和預期輸出之間的差異。 最后,它仍然只是指定了這個迭代式最小化過程。 在神經網絡中有幾種用于此目的的算法;我們將使用反向傳播(誤差向后傳播)算法,并且如其名稱所示,它向后傳播在輸出處獲得的誤差,來重新計算`W`的權重,尤其是對于多層神經網絡很重要。 該方法與先前看到的梯度下降方法一起使用,該方法使用交叉熵損失函數,允許我們計算每次迭代時參數必須改變多少,以便在每個時刻使用可用的本地信息來減少誤差。 在我們的例子中,直觀地說,它包括在每次迭代時稍微改變權重`W`(這一點由學習率超參數表示,表示變化的速度)來減少錯誤。 由于在我們的例子中我們只有一層神經網絡,我們不會進入反向傳播方法。 只需記得 TensorFlow 知道整個計算圖,允許它應用優化算法來找到訓練模型的訓練函數的正確梯度。 因此,在我們使用 MNIST 圖像的示例中,以下代碼行表明我們使用反向傳播算法和梯度下降算法來最小化交叉熵,學習率為 0.01: ```py train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) ``` 到這里之后,我們已經指定了所有問題,我們可以通過實例化`tf.Session()`來開始計算,它負責在系統,CPU 或 GPU 上的可用設備中執行 TensorFlow 操作: ```py sess = tf.Session() ``` 接下來,我們可以執行初始化所有變量的操作: ```py sess.run(tf.initialize_all_variables()) ``` 從現在開始,我們可以開始訓練我們的模型。 執行時,`train_step`的返回參數將梯度下降應用于所涉及的參數。 因此,可以通過重復執行`train_step`來實現模型的訓練。 假設我們要迭代 1000 次`train_step`;我們必須指定以下代碼行: ```py for i in range(1000): batch_xs, batch_ys = mnist.train.next_batch(100) sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys}) ``` 循環內的第一行指定,對于每次迭代,挑選從訓練數據集中隨機采樣的 100 個數據輸入的批量。 我們可以在每次迭代時使用所有訓練數據,但為了使第一個示例更加靈活,我們每次都使用一個小樣本。 第二行表示之前獲得的輸入必須提供給相應的占位符。 最后,基于梯度下降的機器學習算法可以利用 TensorFlow 自動微分的功能。 TensorFlow 用戶只需定義預測模型的計算架構,將其與目標函數組合,然后只需添加數據即可。 TensorFlow 已經管理了學習過程背后的相關微分。 當執行`minimize()`方法時,TensorFlow 識別損失函數所依賴的變量集,并計算每個變量的梯度。 如果你想知道如何實現微分,可以查看`ops/gradients.py`文件 [37]。 ### 模型評估 訓練后必須評估模型,來查看有多“好”(或多“壞”)。 例如,我們可以計算預測中命中和未命中的百分比,看看哪些例子是正確預測的。 在前面的章節中,我們看到`tf.argmax(y, 1)`函數,根據張量的給定軸返回最高值的索引。 實際上,`tf.argmax(y, 1)`是對于每個輸入的,概率最高的標簽,而 `tf.argmax(y_, 1)`是正確標簽。 使用`tf.equal`方法,我們可以比較我們的預測是否與正確的標簽重合: ```py correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) ``` 指令返回布爾列表。 要確定哪些預測部分是正確的,我們可以將值轉換為數值變量(浮點)并執行以下操作: ```py accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) ``` 例如,`[True, False, True, True]`將變為`[1, 0, 1, 1]`,平均值將為 0.75,表示準確率。 現在我們可以使用`mnist.test`作為`feed_dict參`數來查詢我們的測試數據集的準確率: ```py print sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}) ``` 我的大約為 91%。 這些結果好嗎? 我認為它們太棒了,因為這意味著讀者已經能夠使用 TensorFlow 編程并執行第一個神經網絡。 另一個問題是其他模型可能提供更好的準確性,在下一章中介紹包含更多層的神經網絡。 讀者將在本書 github [38] 的文件`RedNeuronalSimple.py`中找到本章中使用的全部代碼。 為了提供它的全局視圖,我將把它放在一起: ```py import input_data mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) import tensorflow as tf x = tf.placeholder("float", [None, 784]) W = tf.Variable(tf.zeros([784,10])) b = tf.Variable(tf.zeros([10])) matm=tf.matmul(x,W) y = tf.nn.softmax(tf.matmul(x,W) + b) y_ = tf.placeholder("float", [None,10]) cross_entropy = -tf.reduce_sum(y_*tf.log(y)) train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) sess = tf.Session() sess.run(tf.initialize_all_variables()) for i in range(1000): batch_xs, batch_ys = mnist.train.next_batch(100) sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys}) correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) print sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}) ```
                  <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>

                              哎呀哎呀视频在线观看