<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用Pyhon+Flux+Julia實(shí)現(xiàn)手寫數(shù)字識(shí)別

          共 7611字,需瀏覽 16分鐘

           ·

          2020-09-15 22:40

          點(diǎn)擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

          重磅干貨,第一時(shí)間送達(dá)


          使用MNIST數(shù)據(jù)集對(duì)0到9之間的數(shù)字進(jìn)行手寫數(shù)字識(shí)別是神經(jīng)網(wǎng)絡(luò)的一個(gè)典型入門教程。
          該技術(shù)在現(xiàn)實(shí)場(chǎng)景中是很有用的,比如可以把該技術(shù)用來掃描銀行轉(zhuǎn)帳單或支票,其中帳號(hào)和需要轉(zhuǎn)賬的金額可以被識(shí)別處理并寫在明確定義的方框中。
          在本教程中,我們將介紹如何使用Julia編程語言和名為Flux的機(jī)器學(xué)習(xí)庫來實(shí)現(xiàn)這一技術(shù)。

          為什么使用Flux和Julia?

          本教程為什么想使用Flux(https://fluxml.ai/) 和Julia(https://julialang.org/) ,而不是像Torch、PyTorch、Keras或TensorFlow 2.0這樣的知名框架呢?
          一個(gè)很好的原因是因?yàn)镕lux更易于學(xué)習(xí),而且它提供更好的性能和擁有有更大的潛力,另外一個(gè)原因是,F(xiàn)lux在仍然是一個(gè)小庫的情況下實(shí)現(xiàn)了很多功能。Flux庫非常小,因?yàn)樗龅拇蟛糠止ぷ鞫际怯蒍ulia編程語言本身提供的。
          例如,如果你查看Gorgonia ML庫(https://github.com/gorgonia/gorgonia) 中的Go編程語言,你將看到,它明確地展示了其他機(jī)器學(xué)習(xí)庫如何構(gòu)建一個(gè)需要執(zhí)行和區(qū)分的表達(dá)式圖。在Flux中,這個(gè)圖就是Julia本身。Julia與LISP非常相似,因?yàn)镴ulia代碼可以很容易地表示為數(shù)據(jù)結(jié)構(gòu),可以對(duì)其進(jìn)行修改和計(jì)算。

          機(jī)器學(xué)習(xí)概論

          如果你是機(jī)器學(xué)習(xí)的新手,你可以跟著本教程來學(xué)習(xí),但并不是所有的東西對(duì)你來說都是有價(jià)值的。你也可以看看我以前關(guān)于Medium的一些文章,它們可能會(huì)解釋你一些新手的疑惑:
          • 線性代數(shù)的核心思想。(https://medium.com/@Jernfrost/the-core-idea-of-linear-algebra-7405863d8c1d
            • 線性代數(shù)基本上是關(guān)于向量和矩陣的,這是你在機(jī)器學(xué)習(xí)中經(jīng)常用到的東西。
          • 使用引用。(https://medium.com/@Jernfrost/working-with-and-emulating-references-in-julia-e02c1cae5826
            • 它看起來有點(diǎn)不太好理解,但是如果你想理解像Flux這樣的ML庫,那么理解Julia中的引用是很重要的。
          • Flux的實(shí)現(xiàn)。(https://medium.com/@Jernfrost/implementation-of-a-modern-machine-learning-library-3596badf3be
            • 如何實(shí)現(xiàn)Flux-ML庫的初學(xué)者指南。
          • 機(jī)器學(xué)習(xí)簡介。(https://medium.com/@Jernfrost/machine-learning-for-dummies-in-julia-6cd4d2e71a46) 機(jī)器學(xué)習(xí)概論。

          簡單多層感知機(jī)

          我們要編程的人工神經(jīng)網(wǎng)絡(luò)被稱為簡單的多層感知機(jī),這是神經(jīng)網(wǎng)絡(luò)(ANN)的基礎(chǔ),大多數(shù)教科書都會(huì)從它開始。
          我先展示整個(gè)程序,然后我們?cè)俑敿?xì)地講解不同的部分。
          using?Flux,?Flux.Data.MNIST,?Statistics
          using?Flux:?onehotbatch,?onecold,?crossentropy,?throttle
          using?Base.Iterators:?repeated

          #?Load?training?data.?28x28?grayscale?images?of?digits
          imgs?=?MNIST.images()

          #?Reorder?the?layout?of?the?data?for?the?ANN
          imagestrip(image::Matrix{<:Gray})?=?Float32.(reshape(image,?:))
          X?=?hcat(imagestrip.(imgs)...)

          #?Target?output.?What?digit?each?image?represents.
          labels?=?MNIST.labels()
          Y?=?onehotbatch(labels,?0:9)

          #?Defining?the?model?(a?neural?network)
          m?=?Chain(
          ?Dense(28*28,?32,?relu),
          ?Dense(32,?10),
          ?softmax)
          ?
          loss(x,?y)?=?crossentropy(m(x),?y)
          dataset?=?repeated((X,?Y),?200)
          opt?=?ADAM()

          evalcb?=?()?->?@show(loss(X,?Y))

          #?Perform?training?on?data
          Flux.train!(loss,?params(m),?dataset,?opt,?cb?=?throttle(evalcb,?10))

          探索輸入數(shù)據(jù)

          數(shù)據(jù)預(yù)處理通常是數(shù)據(jù)科學(xué)中最大的工作之一。通常情況下,數(shù)據(jù)的組織或格式化方式與將其輸入算法所需的方式不同。
          我們首先將MNIST數(shù)據(jù)集加載為60000個(gè)28x28像素的灰度圖像:
          imgs?=?MNIST.images()
          現(xiàn)在,如果你這樣處理數(shù)據(jù),你可能不知道輸出的數(shù)據(jù)是怎么樣子的,但使用Julia研究,我們只需檢查一下:
          julia>?size(imgs)
          (60000,)
          輸出說明了imgs是一個(gè)包含60000個(gè)元素的一維數(shù)組。但這些元素是什么?
          julia>?eltype(imgs)
          Array{Gray{FixedPointNumbers.Normed{UInt8,8}},2}
          你可能看不懂,但我可以簡單地告訴你這是什么:
          julia>?eltype(imgs)?<:?Matrix{T}?where?T?<:?Gray
          true
          這告訴我們imgs中的每個(gè)元素都是某種值矩陣,這些值屬于某種類型T,它是Gray類型的子類型。什么是Gray類型?
          我們可以在Julia在線文檔中查找:
          help?>?Gray
          ??Gray?is?a?grayscale?object.?You?can?extract?its?value?with?gray(c).
          如果我們想知道這些灰度值矩陣的維數(shù),則可以:
          julia>?size(imgs[1])
          (28,?28)

          julia>?size(imgs[2])
          (28,?28)
          這告訴我們它們的尺寸為28x28像素。我們可以通過簡單地繪制其中的一些圖來進(jìn)一步驗(yàn)證這一點(diǎn)。Julia的Plots庫使你可以繪制函數(shù)和圖像。
          julia>?using?Plots
          julia>?plot(imgs[2])
          得出了下面的圖像,顯然看起來像一個(gè)數(shù)字:

          但是,你可能會(huì)發(fā)現(xiàn)了解更多的數(shù)據(jù)看起來是更有用。我們可以很容易地一起繪制幾個(gè)圖像:
          imgplots?=?plot.(imgs[1:9])
          plot(imgplots...)
          現(xiàn)在我們知道了數(shù)據(jù)是什么樣的了。

          準(zhǔn)備輸入數(shù)據(jù)

          然而,我們不能像這樣將數(shù)據(jù)輸入到我們的神經(jīng)網(wǎng)絡(luò)(ANN),因?yàn)槊總€(gè)神經(jīng)網(wǎng)絡(luò)輸入必須是列向量,而不是矩陣。
          這是因?yàn)樯窠?jīng)網(wǎng)絡(luò)期望一個(gè)矩陣作為輸入,矩陣中的每一列都是輸入。ANN所看到的三乘十矩陣對(duì)應(yīng)于十個(gè)不同的輸入,其中每個(gè)輸入包含三個(gè)不同的值或者更具體地說是三個(gè)不同的特征,因此,我們將28x28灰度圖像轉(zhuǎn)換為28x28=784的長像素帶。
          其次,我們的神經(jīng)網(wǎng)絡(luò)并不知道什么是灰度值,它是對(duì)浮點(diǎn)數(shù)據(jù)進(jìn)行操作的,所以我們必須同時(shí)轉(zhuǎn)換數(shù)據(jù)的維度和元素類型。
          數(shù)組中的列和行數(shù)稱為其形狀。很多人提到了張量,雖然它并不完全精確,但它是一個(gè)涵蓋了標(biāo)量、向量、矩陣、立方體或任何等級(jí)的數(shù)組(基本上是數(shù)組的所有維度)的概念。
          在Julia中,我們可以使用reshape函數(shù)來改變數(shù)組的形狀。下面是一些你如何使用它的例子。
          這將創(chuàng)建一個(gè)包含四個(gè)元素的列向量A
          julia>?A?=?collect(1:4)
          4-element?Array{Int64,1}:
          ?1
          ?2
          ?3
          ?4
          通過reshape我們把它變成一個(gè)二乘二的矩陣B:
          julia>?B?=?reshape(A,?(2,?2))
          2×2?Array{Int64,2}:
          ?1??3
          ?2??4
          矩陣可以再次轉(zhuǎn)換為列向量:
          julia>?reshape(B,?4)
          4-element?Array{Int64,1}:
          ?1
          ?2
          ?3
          ?4
          找出一個(gè)列向量到底有多少個(gè)元素是不切實(shí)際的,你可以讓Julia只通過寫來計(jì)算合適的長度。
          julia>?reshape(B,?:)
          4-element?Array{Int64,1}:
          ?1
          ?2
          ?3
          ?4
          有了這些信息,應(yīng)該更容易看到imagestrip函數(shù)的實(shí)際功能了,它將28x28的灰度矩陣轉(zhuǎn)換為784個(gè)32位浮點(diǎn)值的列向量。
          imagestrip(image::Matrix{<:Gray})?=?Float32.(reshape(image,?:))
          .符號(hào)用于將函數(shù)應(yīng)用于數(shù)組的每個(gè)元素,因此Float32.(xs)map(Float32, xs)是相同的。
          接下來,我們將imagestrip函數(shù)應(yīng)用于6萬張灰度圖像中的每一張,生成784x6000個(gè)輸入矩陣X。
          X?=?hcat(imagestrip.(imgs)...)
          這是如何運(yùn)作的?可以想象為imagestrip.(imgs)將圖像轉(zhuǎn)換為單個(gè)輸入值的數(shù)組,例如[X?, X?, X?, ..., X?],其中n = 60,000,每個(gè)X?都是784個(gè)浮點(diǎn)值。
          使用splat運(yùn)算符...,我們將其轉(zhuǎn)換為所有這些列向量的水平連接,以產(chǎn)生模型輸入。
          X?=?hcat(X?,?X?,?X?,?...,?X?)
          如果要驗(yàn)證尺寸,則可以運(yùn)行size(X)。接下來,我們加載標(biāo)簽。
          labels?=?MNIST.labels()
          標(biāo)簽是我們稱之為監(jiān)督學(xué)習(xí)中觀察的"答案"部分。在我們的任務(wù)中,標(biāo)簽是從0到9的數(shù)字。手繪數(shù)字的每一個(gè)圖像都應(yīng)歸類為十個(gè)不同的數(shù)字之一,例如,如果這是一個(gè)包含不同花卉品種的花瓣長度和花瓣寬度的虹膜數(shù)據(jù)集,那么該品種的名稱就是標(biāo)簽。
          X?代表我們所有的特征向量,用機(jī)器學(xué)習(xí)的術(shù)語來說,每個(gè)像素的灰度值都是一個(gè)特征。
          你可以將標(biāo)簽與我們繪制的圖像進(jìn)行比較。
          imgplots?=?plot.(imgs[1:9])
          plot(imgplots...)
          labels[1:9]

          獨(dú)熱編碼

          每個(gè)圖像一個(gè)標(biāo)簽,則有60000個(gè)標(biāo)簽,然而神經(jīng)網(wǎng)絡(luò)不能直接輸出標(biāo)簽。例如,如果你正試圖對(duì)貓和狗的圖像進(jìn)行分類,那么一個(gè)網(wǎng)絡(luò)不能輸出字符串“dog”或“cat”,因?yàn)樗鞘褂酶↑c(diǎn)值的。
          如果標(biāo)簽是一個(gè)不一定有用的數(shù)字,例如如果輸出是一系列郵政編碼,那么將3000的郵政編碼視為1500的郵政編碼的兩倍是沒有意義的,同樣,當(dāng)使用神經(jīng)網(wǎng)絡(luò)從圖像中預(yù)測(cè)數(shù)字時(shí),4的大小是2的兩倍并不重要,數(shù)字也可能是字母,因此它們的值不重要。
          我們?cè)跈C(jī)器學(xué)習(xí)中處理這個(gè)問題的方法是使用所謂的獨(dú)熱編碼,這意味著,如果我們有標(biāo)簽A、B和C,并且我們想用獨(dú)熱編碼來表示它們,那么A是[1、0、0],B是[0、1、0],C是[0、0、1]。
          這看起來很浪費(fèi)空間,但在Julia one hot數(shù)組內(nèi)部,它只跟蹤元素的索引,并不保存所有的零。
          下面是一些正在使用的編碼示例:
          julia>?Flux.onehot('B',?['A',?'B',?'C'])
          3-element?Flux.OneHotVector:
          0
          1
          0

          julia>?Flux.onehot("foo",?["foo",?"bar",?"baz"])
          3-element?Flux.OneHotVector:
          1
          0
          0
          但是,我們不會(huì)使用onehot函數(shù),因?yàn)槲覀冋趧?chuàng)建一批獨(dú)熱編碼標(biāo)簽,我們將把60000張圖片作為一個(gè)批次來處理。
          機(jī)器學(xué)習(xí)的批次指的是在我們模型(神經(jīng)網(wǎng)絡(luò))的權(quán)值或參數(shù)更新之前必須完成的最小樣本數(shù)量。
          Y?=?onehotbatch(labels,?0:9)
          這將創(chuàng)建目標(biāo)輸出。在理想情況下,模型(X)==Y,但在現(xiàn)實(shí)中,即使經(jīng)過模型的訓(xùn)練,也會(huì)有一些偏差。
          我們已經(jīng)討論完數(shù)據(jù)準(zhǔn)備,現(xiàn)在讓我們用人工神經(jīng)網(wǎng)絡(luò)來構(gòu)造我們的模型。

          構(gòu)造神經(jīng)網(wǎng)絡(luò)模型

          模型是真實(shí)世界的簡化表示,就像我們可以建立簡化的物理模型一樣,我們也可以用數(shù)學(xué)或代碼來創(chuàng)建物理世界的模型,現(xiàn)實(shí)中存在許多這樣的數(shù)學(xué)模型。
          例如,統(tǒng)計(jì)模型可以使用統(tǒng)計(jì)數(shù)據(jù)來模擬人們一天中是如何到達(dá)商店的。一般來說,人們會(huì)以一種遵循特定概率分布的方式到達(dá)。
          在我們的例子中,我們?cè)噲D用神經(jīng)網(wǎng)絡(luò)來模擬現(xiàn)實(shí)世界中的一些東西,當(dāng)然,這只是對(duì)現(xiàn)實(shí)世界的一種近似。
          當(dāng)我們建立一個(gè)神經(jīng)網(wǎng)絡(luò)時(shí),我們有很多可以玩的東西。網(wǎng)絡(luò)是由多個(gè)層連接而成的,每一層通常都有一個(gè)激活函數(shù)。
          建立一個(gè)神經(jīng)網(wǎng)絡(luò)的挑戰(zhàn)是選擇合適的層和激活函數(shù),并決定每層應(yīng)該有多少個(gè)節(jié)點(diǎn)。
          我們的模型非常簡單,定義如下:
          m?=?Chain(
          ??Dense(28^2,?32,?relu),
          ??Dense(32,?10),
          ??softmax)
          這是一個(gè)三層的神經(jīng)網(wǎng)絡(luò)。Chain用于將各個(gè)層連接在一起。第一層Dense(28^2, 32, relu)有784(28x28)個(gè)輸入節(jié)點(diǎn),對(duì)應(yīng)于每個(gè)圖像中的像素?cái)?shù)。
          它使用校正線性單元(ReLU)函數(shù)作為激活函數(shù)。在經(jīng)典的神經(jīng)網(wǎng)絡(luò)文獻(xiàn)中,通常會(huì)介紹sigmoidtanhrelu等激活函數(shù),這些激活函數(shù)在大多數(shù)情況下都工作得很好,包括圖像的分類。
          下一層是我們的隱藏層,它接受32個(gè)輸入,因?yàn)榍耙粚佑?2個(gè)輸出,隱藏節(jié)點(diǎn)的數(shù)量沒有明確的對(duì)錯(cuò)選擇。
          但輸出的數(shù)量根據(jù)不同任務(wù)是不一樣的,因?yàn)槲覀兿M總€(gè)數(shù)字有一個(gè)輸出,這也就是“獨(dú)熱編碼”發(fā)揮作用的地方。

          Softmax函數(shù)

          最后一層,是softmax函數(shù),它以前一層的輸出的矩陣作為輸入,并沿著每一列進(jìn)行歸一化。
          標(biāo)準(zhǔn)化將60000列中的每一列轉(zhuǎn)換為概率分布。那到底是什么意思?
          概率是0到1之間的值,0表示事件永遠(yuǎn)不會(huì)發(fā)生,1是肯定會(huì)發(fā)生。
          與min-max歸一化一樣,softmax將所有輸入歸一化為0到1之間的值,但是與min max不同的是它會(huì)確保所有值的和為一。這需要一些例子來說明。
          假設(shè)我創(chuàng)建了10個(gè)從1到10的隨機(jī)值,我們可以放任意范圍和任意數(shù)量的值。
          julia>?ys?=?rand(1:10,?10)
          10-element?Array{Int64,1}:
          ??9
          ??6
          ?10
          ??5
          ?10
          ??2
          ??6
          ??6
          ??7
          ??9
          現(xiàn)在讓我們使用不同的歸一化函數(shù)歸一化這個(gè)數(shù)組,我們將使用來自LinearAlgebra模塊的normalize,因?yàn)樗cJulia捆綁在一起。
          但首先使用softmax
          julia>?softmax(ys)
          10-element?Array{Float64,1}:
          ?0.12919082661651196???
          ?0.006432032517257137??
          ?0.3511770763952676????
          ?0.002366212528045101??
          ?0.3511770763952676????
          ?0.00011780678490667763
          ?0.006432032517257137??
          ?0.006432032517257137??
          ?0.017484077111717768??
          ?0.12919082661651196
          如你所見,所有值都在0到1之間。現(xiàn)在看一下如果我們把它們加起來會(huì)發(fā)生什么:
          julia>?sum(softmax(ys))
          0.9999999999999999
          它們基本上變成了1。現(xiàn)在將其與normalize的功能進(jìn)行對(duì)比:
          julia>?using?LinearAlgebra

          julia>?normalize(ys)
          10-element?Array{Float64,1}:
          0.38446094597254243
          0.25630729731502827
          0.4271788288583805?
          0.21358941442919024
          0.4271788288583805?
          0.0854357657716761?
          0.25630729731502827
          0.25630729731502827
          0.2990251802008663?
          0.38446094597254243

          julia>?sum(normalize(ys))
          2.9902518020086633

          julia>?norm(normalize(ys))
          1.0

          julia>?norm(softmax(ys))
          0.52959100847191
          如果對(duì)用normalize歸一化的值求和,它們只會(huì)得到一些隨機(jī)值,然而如果我們把結(jié)果反饋給norm,我們得到的結(jié)果正好是1.0。
          不同之處在于,normalize將向量中的值進(jìn)行了歸一化,以便它們可以表示單位向量,即長度正好為一的向量。norm給出向量的大小。
          相比之下,softmax不會(huì)將這些值視為向量,而是將其視為概率分布,每個(gè)元素表示輸入圖像為該數(shù)字的概率。
          假設(shè)我們有A,B和C的圖像作為輸入,如果你從softmax得到一個(gè)輸出值是[0.1,0.7,0.2],那么輸入圖像有10%的可能性是A的圖形,有70%的可能性是B的圖形,最后有20%的可能性是C的圖形。
          這就是為什么我們希望softmax作為最后一層的原因。用神經(jīng)網(wǎng)絡(luò)不能絕對(duì)確定輸入圖像是什么,但是我們可以給出一個(gè)概率分布,它表示更有可能是哪個(gè)數(shù)字。

          定義損失函數(shù)

          當(dāng)訓(xùn)練我們的神經(jīng)網(wǎng)絡(luò)(模型)給出準(zhǔn)確的預(yù)測(cè)時(shí),我們需要定義人工神經(jīng)網(wǎng)絡(luò)(ANN)的評(píng)估指標(biāo)。
          為此,我們使用所謂的損失函數(shù)。損失函數(shù)有很多名字,20年前當(dāng)我被教授神經(jīng)網(wǎng)絡(luò)時(shí),我們?cè)Q之為誤差函數(shù),也有人稱之為成本函數(shù)。
          然而,歸根結(jié)底,這是一種表達(dá)我們的預(yù)測(cè)與現(xiàn)實(shí)相比有多正確的方式。
          loss(x,?y)?=?crossentropy(m(x),?y)
          訓(xùn)練神經(jīng)網(wǎng)絡(luò)實(shí)際上是最小化這個(gè)函數(shù)的輸出,所以這是一個(gè)優(yōu)化問題。訓(xùn)練是一個(gè)反復(fù)調(diào)整模型中參數(shù)(權(quán)重)的過程,直到損失函數(shù)的輸出變低,或者換句話說,直到我們的預(yù)測(cè)誤差變低。
          均方誤差函數(shù)(MSE)是計(jì)算預(yù)測(cè)錯(cuò)誤程度的經(jīng)典方法,這就意味著取差的平方,然而,MSE更適合于線性回歸(將一條或多條直線擬合到某些觀測(cè)值)。
          在這種情況下,我們改用交叉熵函數(shù)。當(dāng)你的最后一層是softmax,進(jìn)行分類而不是線性回歸時(shí),這是我比較推薦的選擇。

          指定Epoch

          在機(jī)器學(xué)習(xí)術(shù)語中,Epoch是訓(xùn)練算法進(jìn)行一次完整的迭代,換句話說:一個(gè)Epoch處理一個(gè)批次并更新權(quán)重
          因此,如果我們使用10個(gè)Epoch來進(jìn)行訓(xùn)練,那么模型的參數(shù)/權(quán)重將更新/調(diào)整10次。
          為了得到200個(gè)Epoch,我們使用repeat重復(fù)我們的批處理200次。它實(shí)際上不會(huì)重復(fù)我們的數(shù)據(jù)200次,它只是用迭代器創(chuàng)建了這樣的錯(cuò)覺。
          dataset?=?repeated((X,?Y),?200)
          在數(shù)據(jù)集中,我們得到的數(shù)組如下:
          dataset?=?[(X1,?Y1),?(X2,?Y2),?...,?(X200,?Y200)]

          優(yōu)化器

          最常見和最著名的訓(xùn)練神經(jīng)網(wǎng)絡(luò)策略是梯度下降算法,這是由Julia中的Descent類型提供的。
          然而,在我們的例子中,當(dāng)我們處理大量帶有相當(dāng)數(shù)量噪聲的數(shù)據(jù)時(shí),建議改用ADAM優(yōu)化器,這就是所謂的隨機(jī)優(yōu)化。
          opt?=?ADAM()

          進(jìn)行訓(xùn)練

          我們終于可以進(jìn)行訓(xùn)練了,但我們希望在訓(xùn)練進(jìn)行的過程中得到一些反饋。我們定義了一個(gè)回調(diào)函數(shù),在每次迭代(epoch)時(shí),它將輸出loss函數(shù)的值,從而顯示錯(cuò)誤。我們希望每次迭代時(shí)都能看到這個(gè)錯(cuò)誤。
          evalcb?=?()?->?@show(loss(X,?Y))
          觀察錯(cuò)誤發(fā)展的一個(gè)有用的地方是,你可以看到是否有振蕩。人工神經(jīng)網(wǎng)絡(luò)過快地朝著最低值過渡,會(huì)導(dǎo)致它朝相反的方向移動(dòng),如果速度太快,則會(huì)向相反的方向超調(diào),振蕩會(huì)變得更加劇烈,直到誤差變?yōu)闊o窮大。
          這是一個(gè)切換優(yōu)化算法或降低學(xué)習(xí)率的提示。
          不管怎樣,這就是你訓(xùn)練的方式。注意,回調(diào)是可選的:
          Flux.train!(loss,?params(m),?dataset,?opt,?cb?=?throttle(evalcb,?10))

          評(píng)價(jià)模型預(yù)測(cè)精度

          經(jīng)過訓(xùn)練后,我們可以測(cè)試模型在預(yù)測(cè)方面的表現(xiàn)。
          我們定義了這樣一個(gè)函數(shù):
          accuracy(x,?y)?=?mean(onecold((m(x)))?.==?onecold(y))
          然后我們用輸入數(shù)據(jù)和標(biāo)簽作為輸入?yún)?shù)來調(diào)用它:
          @show?accuracy(X,?Y)
          至于什么是onecold?在某種程度上,它與onehot實(shí)現(xiàn)的效果是相反的。
          我們的輸出m(X)都是概率分布,而我們的目標(biāo)Y都是獨(dú)熱向量。
          它們不能直接比較,所以我們需要使用onecold來做一個(gè)轉(zhuǎn)換。給定概率分布,它選擇最可能的候選:
          julia>?onecold([0.1,?0.7,?0.2])
          2

          julia>?onecold([0.9,?0.05,?0.05])
          1
          因此,使用onecold(m(X))我們可以得到預(yù)測(cè)的標(biāo)簽,這可以與實(shí)際的標(biāo)簽onecold(y)進(jìn)行比較。

          用測(cè)試數(shù)據(jù)驗(yàn)證模型

          到目前為止,我們只根據(jù)我們使用的訓(xùn)練數(shù)據(jù)來驗(yàn)證了我們的模型,然而,如果該模型不適用于新的數(shù)據(jù),它將是完全無用的。
          因此,在訓(xùn)練網(wǎng)絡(luò)時(shí),我們通常將數(shù)據(jù)分為訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)。測(cè)試數(shù)據(jù)不是訓(xùn)練的一部分,只有在訓(xùn)練完成后才能進(jìn)行測(cè)試。
          tX?=?hcat(float.(reshape.(MNIST.images(:test),?:))...)
          tY?=?onehotbatch(MNIST.labels(:test),?0:9)

          @show?accuracy(tX,?tY)

          最后

          我希望這能幫助你理解建立神經(jīng)網(wǎng)絡(luò)的過程。
          太多的教程傾向于跳過向初學(xué)者解釋的內(nèi)容,從而所有的新概念都會(huì)很快變得令人困惑。我希望這為初學(xué)者在進(jìn)一步探索機(jī)器學(xué)習(xí)之前提供了一個(gè)起點(diǎn),特別是基于Julia的機(jī)器學(xué)習(xí),因?yàn)槲艺J(rèn)為Julia有著光明的未來。
          參考鏈接:https://medium.com/better-programming/handwriting-recognition-using-an-artificial-neural-network-78060d2a7963

          ☆ END ☆
          瀏覽 32
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产在线高清视频 | 波多野吉衣中文字幕 | 91人人妻人人澡人人爽人人狠 | www夜片内射视频日韩精品成人 | 色拍拍视频 |