實戰|手把手入門神經網絡,74行代碼實現手寫數字識別

2021-01-10 FlyAI

訪問flyai.club,一鍵創建你的人工智慧項目。

作者 | 龍心塵&&寒小陽——CSDN

原文 | https://blog.csdn.net/longxinchen_ml

/article/details/50281247

github | https://github.com/mnielsen

/neural-networks-and-deep-learning.git

一、 引言:不要站在岸上學遊泳

「機器學習」是一個很實踐的過程。就像剛開始學遊泳,你在只在岸上比劃一堆規定動作還不如先跳到水裡熟悉水性學習來得快。以我們學習「機器學習」的經驗來看,很多高大上的概念剛開始不懂也沒關係,先寫個東西來跑跑,有個感覺了之後再學習那些概念和理論就快多了。如果別人已經做好了輪子,直接拿過來用則更快。因此,本文直接用Michael Nielsen先生的代碼作為例子,給大家展現神經網絡分析的普遍過程:導入數據,訓練模型,優化模型,啟發式理解等。

本文假設大家已經了解python的基本語法,並在自己機器上運行過簡單python腳本。

二、 我們要解決的問題:手寫數字識別

手寫數字識別是機器學習領域中一個經典的問題,是一個看似對人類很簡單卻對程序十分複雜的問題。很多早期的驗證碼就是利用這個特點來區分人類和程序行為的,當然此處就不提12306近乎反人類的奇葩驗證碼了。

回到手寫數字識別,比如我們要識別出一個手寫的「9」,人類可能通過識別「上半部分一個圓圈,右下方引出一條豎線」就能進行判斷。但用程序表達就似乎很困難了,你需要考慮非常多的描述方式,考慮非常多的特殊情況,最終發現程序寫得非常複雜而且效果不好。

而用(機器學習)神經網絡的方法,則提供了另一個思路:獲取大量的手寫數字的圖像,並且已知它們表示的是哪個數字,以此為訓練樣本集合,自動生成一套模型(如神經網絡的對應程序),依靠它來識別新的手寫數字。

本文中採用的數據集就是著名的「MNIST數據集」。它的收集者之一是人工智慧領域著名的科學家——Yann LeCu。這個數據集有60000個訓練樣本數據集和10000個測試用例。運用本文展示的單隱層神經網絡,就可以達到96%的正確率。

三、 圖解:解決問題的思路

我們可以用下圖展示上面的粗略思路。

但是如何由「訓練集」來「生成模型」呢?

在這裡我們使用反覆推薦的逆推法——假設這個模型已經生成了,它應該滿足什麼樣的特性,再以此特性為條件反過來求出模型。

可以推想而知,被生成的模型應該對於訓練集的區分效果非常好,也就是相應的訓練誤差非常低。比如有一個未知其相應權重和偏移的神經網絡,而訓練神經網絡的過程就是逐步確定這些未知參數的過程,最終使得這些參數確定的模型在訓練集上的誤差達到最小值。我們將會設計一個數量指標衡量這個誤差,如果訓練誤差沒有達到最小,我們將繼續調整參數,直到這個指標達到最小。但這樣訓練出來的模型我們仍無法保證它面對新的數據仍會有這樣好的識別效果,就需要用測試集對模型進行考核,得出的測試結果作為對模型的評價。因此,上圖就可以細化成下圖:

但是,如果我們已經生成了多個模型,怎麼從中選出最好的模型?一個自然的思路就是通過比較不同模型在測試集上的誤差,挑選出誤差最小的模型。這個想法看似沒什麼問題,但是隨著你測試的模型增多,你會覺得用測試集篩選出來的模型也不那麼可信。比如我們增加一個神經網絡的隱藏層節點,就會產生新的對應權重,產生一個新的模型。但是我也不知道增加多少個節點是合適的,所以比較全面的想法就是嘗試測試不同的節點數x∈(1,2,3,4,…,100), 來觀察這些不同模型的測試誤差,並挑出誤差最小的模型。這時我們發現我們的模型其實多出來了一個參數x, 我們挑選模型的過程就是確定最優化的參數x 的過程。這個分析過程與上面訓練參數的思路如出一轍!只是這個過程是基於同一個測試集,而不訓練集。那麼,不同的神經網絡的層數是不是也是一個新的參數y∈(1,2,3,4,…,100), 也要經過這麼個過程來「訓練」?

我們會發現我們之前生成模型過程中很多不變的部分其實都是可以變換調節的,這些也是新的參數,比如訓練次數、梯度下降過程的步長、規範化參數、學習回合數、minibatch 值等等,我們把他們叫做超參數。超參數是影響所求參數最終取值的參數,是機器學習模型裡面的框架參數,可以理解成參數的參數,它們通常是手工設定,不斷試錯調整的,或者對一系列窮舉出來的參數組合一通進行枚舉(網格搜索)來確定。但無論如何,這也是基於同樣一個數據集反覆驗證優化的結果。在這個數據集上最後的結果並不一定在新的數據繼續有效。所以為了評估這個模型的識別效果,就需要用新的測試集對模型進行考核,得出的測試結果作為對模型的評價。這個新的測試集我們就直接叫「測試集」,之前那個用於篩選超參數的測試集,我們就叫做「交叉驗證集」。篩選模型的過程其實就是交叉驗證的過程。

所以,規範的方法的是將數據集拆分成三個集合:訓練集、交叉驗證集、測試集,然後依次訓練參數、超參數,最終得到最優的模型。

因此,上圖可以進一步細化成下圖:

或者下圖:

可見機器學習過程是一個反覆迭代不斷優化的過程。其中很大一部分工作是在調整參數和超參數。

四、 先跑跑再說:初步運行代碼

Michael Nielsen的代碼封裝得很好,只需以下5行命令就可以生成神經網絡並測試結果,並達到94.76%的正確率!

import mnist_loaderimport network# 將數據集拆分成三個集合:訓練集、交叉驗證集、測試集training_data, validation_data, test_data = mnist_loader.load_data_wrapper()# 生成神經網絡對象,神經網絡結構為三層,每層節點數依次為(784, 30, 10)net = network.Network([784, 30, 10])# 用(mini-batch)梯度下降法訓練神經網絡(權重與偏移),並生成測試結果。# 訓練回合數=30, 用於隨機梯度下降法的最小樣本數=10,學習率=3.0net.SGD(training_data, 30, 10, 3.0, test_data=test_data)

第一個命令的功能是:將數據集拆分成三個集合:訓練集、交叉驗證集、測試集。第二個命令的功能是:生成神經網絡對象,神經網絡結構為三層,每層節點數依次為(784, 30, 10)。第三個命令的功能是:用(mini-batch)梯度下降法訓練神經網絡(權重與偏移),並生成測試結果。該命令設定了三個超參數:訓練回合數=30, 用於隨機梯度下降法的最小樣本數(mini-batch-size)=10,步長=3.0。

本文並不打算詳細解釋隨機梯度下降法的細節,感興趣的同學請閱讀前文《深度學習與計算機視覺系列(4)_最優化與隨機梯度下降》

總共的輸出結果如下:

Epoch 0: 9045 / 10000Epoch 1: 9207 / 10000Epoch 2: 9273 / 10000Epoch 3: 9302 / 10000Epoch 4: 9320 / 10000Epoch 5: 9320 / 10000Epoch 6: 9366 / 10000Epoch 7: 9387 / 10000Epoch 8: 9427 / 10000Epoch 9: 9402 / 10000Epoch 10: 9400 / 10000Epoch 11: 9442 / 10000Epoch 12: 9448 / 10000Epoch 13: 9441 / 10000Epoch 14: 9443 / 10000Epoch 15: 9479 / 10000Epoch 16: 9459 / 10000Epoch 17: 9446 / 10000Epoch 18: 9467 / 10000Epoch 19: 9470 / 10000Epoch 20: 9459 / 10000Epoch 21: 9484 / 10000Epoch 22: 9479 / 10000Epoch 23: 9475 / 10000Epoch 24: 9482 / 10000Epoch 25: 9489 / 10000Epoch 26: 9489 / 10000Epoch 27: 9478 / 10000Epoch 28: 9480 / 10000Epoch 29: 9476 / 10000

五、 神經網絡如何識別手寫數字:啟發式理解

首先,我們解釋一下神經網絡每層的功能。

第一層是輸入層。因為mnist數據集中每一個手寫數字樣本是一個28*28像素的圖像,因此對於每一個樣本,其輸入的信息就是每一個像素對應的灰度,總共有28*28=784個像素,故這一層有784個節點。

第三層是輸出層。因為阿拉伯數字總共有10個,我們就要將樣本分成10個類別,因此輸出層我們採用10個節點。當樣本屬於某一類(某個數字)的時候,則該類(該數字)對應的節點為1,而剩下9個節點為0,如[0,0,0,1,0,0,0,0,0,0]。

因此,我們每一個樣本(手寫數字的圖像)可以用一個超長的784維的向量表示其特徵,而用一個10維向量表示該樣本所屬的類別(代表的真實數字),或者叫做標籤。

mnist的數據就是這樣表示的。所以,如果你想看訓練集中第n個樣本的784維特徵向量,直接看training_data[n][0]就可以找到,而要看其所屬的標籤,看training_data[n][1]就夠了。

那麼,第二層神經網絡所代表的意義怎麼理解?這其實是很難的。但是我們可以有一個啟發式地理解,比如用中間層的某一個節點表示圖像中的某一個小區域的特定圖像。這樣,我們可以假設中間層的頭4個節點依次用來識別圖像左上、右上、左下、右下4個區域是否存在這樣的特徵的。

如果這四個節點的值都很高,說明這四個區域同時滿足這些特徵。將以上的四個部分拼接起來,我們會發現,輸入樣本很可能就是一個手寫「0」!

因此,同一層的幾個神經元同時被激活了意味著輸入樣本很可能是某個數字。

當然,這只是對神經網絡作用機制的一個啟發式理解。真實的過程卻並不一定是這樣。但通過啟發式理解,我們可以對神經網絡作用機制有一個更加直觀的認識。

由此可見,神經網絡能夠識別手寫數字的關鍵是它有能夠對特定的圖像激發特定的節點。而神經網絡之所以能夠針對性地激發這些節點,關鍵是它具有能夠適應相關問題場景的權重和偏移。那這些權重和偏移如何訓練呢?

六、 神經網絡如何訓練:進一步閱讀代碼

上文已經圖解的方式介紹了機器學習解決問題的一般思路,但是具體到神經網絡將是如何訓練呢?

其實最快的方式是直接閱讀代碼。我們將代碼的結構用下圖展示出來,運用其內置函數名表示基本過程,發現與我們上文分析的思路一模一樣:

簡單解釋一下,在神經網絡模型中:

所需要求的關鍵參數就是:神經網絡的權重(self.weights)和偏移(self.biases)。超參數是:隱藏層的節點數=30,訓練回合數(epochs)=30, 用於隨機梯度下降法的最小樣本數(mini_batch_size)=10,步長(eta)=3.0。用隨機梯度下降法調整參數:

用反向傳播法求出隨機梯度下降法所需要的梯度(偏導數): backprop()用輸出向量減去標籤向量衡量訓練誤差:cost_derivative() = output_activations-y

全部代碼如下(去掉注釋之後,只有74行):

"""network.py~~~~~~~~~~A module to implement the stochastic gradient descent learningalgorithm for a feedforward neural network. Gradients are calculatedusing backpropagation. Note that I have focused on making the codesimple, easily readable, and easily modifiable. It is not optimized,and omits many desirable features."""#### Libraries# Standard libraryimportrandom# Third-party librariesimportnumpyasnpclass Network(object): def __init__(self, sizes): """The list ``sizes`` contains the number of neurons in therespective layers of the network. For example, if the listwas [2, 3, 1] then it would be a three-layer network, with the first layer containing 2 neurons, the second layer 3 neurons, and the third layer 1 neuron. The biases and weights for the network are initialized randomly, using a Gaussian distribution with mean 0, and variance 1. Note that the first layer is assumed to be an input layer, and by convention we won't set any biases for those neurons, since biases are only ever used in computing the outputs from later layers.""" self.num_layers = len(sizes) self.sizes = sizesself.biases = [np.random.randn(y,1)foryinsizes[1:]]self.weights = [np.random.randn(y, x) forx, yinzip(sizes[:-1], sizes[1:])] def feedforward(self, a): """Return the output of the network if ``a`` is input.""" forb, winzip(self.biases, self.weights):a = sigmoid(np.dot(w, a)+b) returna def SGD(self, training_data, epochs, mini_batch_size, eta, test_data=None): """Train the neural network using mini-batch stochastic gradient descent. The ``training_data`` is a list of tuples ``(x, y)`` representing the training inputs and the desired outputs. The other non-optional parameters are self-explanatory. If ``test_data`` is provided then the network will be evaluated against the test data after each epoch, and partial progress printed out. This is useful for tracking progress, but slows things down substantially.""" iftest_data: n_test = len(test_data) n = len(training_data) forjinxrange(epochs): random.shuffle(training_data) mini_batches = [ training_data[k:k+mini_batch_size] forkinxrange(0, n, mini_batch_size)] formini_batchinmini_batches: self.update_mini_batch(mini_batch, eta) iftest_data: print"Epoch {0}: {1} / {2}".format( j, self.evaluate(test_data), n_test) else: print"Epoch {0} complete".format(j) def update_mini_batch(self, mini_batch, eta): """Update the network's weights and biases by applying gradient descent using backpropagation to a single mini batch. The ``mini_batch`` is a list of tuples ``(x, y)``, and ``eta`` is the learning rate.""" nabla_b = [np.zeros(b.shape)forbinself.biases] nabla_w = [np.zeros(w.shape)forwinself.weights] forx, yinmini_batch: delta_nabla_b, delta_nabla_w = self.backprop(x, y) nabla_b = [nb+dnbfornb, dnbinzip(nabla_b, delta_nabla_b)] nabla_w = [nw+dnwfornw, dnwinzip(nabla_w, delta_nabla_w)] self.weights = [w-(eta/len(mini_batch))*nw forw, nwinzip(self.weights, nabla_w)] self.biases = [b-(eta/len(mini_batch))*nbforb, nbinzip(self.biases, nabla_b)] def backprop(self, x, y): """Return a tuple ``(nabla_b, nabla_w)`` representing the gradient for the cost function C_x. ``nabla_b`` and ``nabla_w`` are layer-by-layer lists of numpy arrays, similar to ``self.biases`` and ``self.weights``.""" nabla_b = [np.zeros(b.shape)forbinself.biases] nabla_w = [np.zeros(w.shape)forwinself.weights] # feedforward activation = x activations = [x] # list to store all the activations, layer by layer zs = [] # list to store all the z vectors, layer by layer forb, winzip(self.biases, self.weights): z = np.dot(w, activation)+b zs.append(z) activation = sigmoid(z) activations.append(activation) # backward pass delta = self.cost_derivative(activations[-1], y) * \ sigmoid_prime(zs[-1]) nabla_b[-1] = delta nabla_w[-1] = np.dot(delta, activations[-2].transpose()) # Note that the variable l in the loop below is used a little # differently to the notation in Chapter 2 of the book. Here, # l = 1 means the last layer of neurons, l = 2 is the # second-last layer, and so on. It's a renumbering of the # scheme in the book, used here to take advantage of the fact # that Python can use negative indices in lists. forlinxrange(2, self.num_layers): z = zs[-l] sp = sigmoid_prime(z) delta = np.dot(self.weights[-l+1].transpose(), delta) * sp nabla_b[-l] = delta nabla_w[-l] = np.dot(delta, activations[-l-1].transpose()) return(nabla_b, nabla_w) def evaluate(self, test_data): """Return the number of test inputs for which the neural network outputs the correct result. Note that the neural network's output is assumed to be the index of whichever neuron in the final layer has the highest activation.""" test_results = [(np.argmax(self.feedforward(x)), y) for(x, y)intest_data] returnsum(int(x == y)for(x, y)intest_results) def cost_derivative(self, output_activations, y): """Return the vector of partial derivatives \partial C_x \partial a for the output activations.""" return(output_activations-y)#### Miscellaneous functionsdef sigmoid(z): """The sigmoid function.""" return1.0/(1.0+np.exp(-z))def sigmoid_prime(z): """Derivative of the sigmoid function.""" returnsigmoid(z)*(1-sigmoid(z))

七、 神經網絡如何優化:訓練超參數與多種模型對比

由以上分析可知,神經網絡只需要74行代碼就可以完成編程,可見機器學習真正困難的地方並不在編程,而在你對數學過程本身,和對它與現實問題的對應關係有深入的理解。理解深入後,你才能寫出這樣的程序,並對其進行精微的調優。

我們初步的結果已經是94.76%的正確率了。但如果要將準確率提得更高怎麼辦?

這其實是一個開放的問題,有許多方法都可以嘗試。我們這裡僅僅是拋磚引玉。

首先,隱藏層只有30個節點。由我們之前對隱藏層的啟發式理解可以猜測,神經網絡的識別能力其實與隱藏層對一些細節的識別能力正相關。如果隱藏層的節點更多的話,其識別能力應該會更強的。那麼我們設定100個隱藏層節點試試?

net = network.Network([784,100,10])net.SGD(training_data,30,10,3.0, test_data=test_data)

發現結果如下:

Epoch0:6669/10000Epoch1:6755/10000Epoch2:6844/10000Epoch3:6833/10000Epoch4:6887/10000Epoch5:7744/10000Epoch6:7778/10000Epoch7:7876/10000Epoch8:8601/10000Epoch9:8643/10000Epoch10:8659/10000Epoch11:8665/10000Epoch12:8683/10000Epoch13:8700/10000Epoch14:8694/10000Epoch15:8699/10000Epoch16:8715/10000Epoch17:8770/10000Epoch18:9611/10000Epoch19:9632/10000Epoch20:9625/10000Epoch21:9632/10000Epoch22:9651/10000Epoch23:9655/10000Epoch24:9653/10000Epoch25:9658/10000Epoch26:9653/10000Epoch27:9664/10000Epoch28:9655/10000Epoch29:9672/10000

發現,我們只是改了一個超參數,準確率就從94.76%提升到96.72%!

這裡強調一下,更加規範的模型調優方法是將多個模型用交叉驗證集的結果來橫向比較,選出最優模型後再用一個新的測試集來最終評估該模型。本文為了與之前的結果比較,才採用了測試集而不是交叉驗證集。讀者千萬不要學博主這樣做哈,因為這很有可能會過擬合。這是工程實踐中數據挖掘人員經常犯的錯誤,我們之後會專門寫篇博文探討。

我們現在回來繼續調優我們的模型。那麼還有其他的隱藏節點數更合適嗎?這個我們也不知道。常見的方法是用幾何級數增長的數列(如:10,100,1000,……)去嘗試,然後不斷確定合適的區間,最終確定一個相對最優的值。

但是即便如此,我們也只嘗試了一個超參數,還有其他的超參數沒有調優呢。我們於是嘗試另一個超參數:步長。之前的步長是3.0,但是我們可能覺得學習速率太慢了。那麼嘗試一個更大的步長試試?比如100?

net = network.Network([784,30,10])net.SGD(training_data,30,10,100.0, test_data=test_data)

發現結果如下:

Epoch0:1002/10000Epoch1:1002/10000Epoch2:1002/10000Epoch3:1002/10000Epoch4:1002/10000Epoch5:1002/10000Epoch6:1002/10000Epoch7:1002/10000Epoch8:1002/10000Epoch9:1002/10000Epoch10:1002/10000Epoch11:1002/10000Epoch12:1001/10000Epoch13:1001/10000Epoch14:1001/10000Epoch15:1001/10000Epoch16:1001/10000Epoch17:1001/10000Epoch18:1001/10000Epoch19:1001/10000Epoch20:1000/10000Epoch21:1000/10000Epoch22:999/10000Epoch23:999/10000Epoch24:999/10000Epoch25:999/10000Epoch26:999/10000Epoch27:999/10000Epoch28:999/10000Epoch29:999/10000

發現準確率低得不忍直視,看來步長設得太長了。根本跑不到最低點。那麼我們設定一個小的步長試試?比如0.01。

net = network.Network([784,100,10])net.SGD(training_data,30,10,0.001, test_data=test_data)

結果如下:

Epoch0:790/10000Epoch1:846/10000Epoch2:854/10000Epoch3:904/10000Epoch4:944/10000Epoch5:975/10000Epoch6:975/10000Epoch7:975/10000Epoch8:975/10000Epoch9:974/10000Epoch10:974/10000Epoch11:974/10000Epoch12:974/10000Epoch13:974/10000Epoch14:974/10000Epoch15:974/10000Epoch16:974/10000Epoch17:974/10000Epoch18:974/10000Epoch19:976/10000Epoch20:979/10000Epoch21:981/10000Epoch22:1004/10000Epoch23:1157/10000Epoch24:1275/10000Epoch25:1323/10000Epoch26:1369/10000Epoch27:1403/10000Epoch28:1429/10000Epoch29:1451/10000

呃,發現準確率同樣低得不忍直視。但是有一個優點,準確率是穩步提升的。說明模型在大方向上應該還是對的。如果在調試模型的時候忽視了這個細節,你可能真的找不到合適的參數。

可見,我們第一次嘗試的神經網絡結構的超參數設定還是比較不錯的。但是真實的應用場景中,基本沒有這樣好的運氣,很可能剛開始測試出來的結果全是奇葩生物,長得違反常理,就像來自另一個次元似的。這是數據挖掘工程師常見的情況。此時最應該做的,就是遏制住心中數萬草泥馬的咆哮奔騰,靜靜地觀察測試結果的分布規律,嘗試找到些原因,再繼續將模型試著調優下去,與此同時,做好從一個坑跳入下一個坑的心理準備。當然,在機器學習工程師前赴後繼的填坑過程中,還是總結出了一些調優規律。我們會在接下來專門寫博文分析。

當然,以上的調優都沒有逃出神經網絡模型本身的範圍。但是可不可能其他的模型效果更好?比如傳說中的支持向量機?關於支持向量機的解讀已經超越了本文的篇幅,我們也考慮專門撰寫博文分析。但是在這裡我們只是引用一下在scikit-learn中提供好的接口,底層是用性能更好的C語言封裝的著名的LIBSVM。

相關代碼也在Michael Nielsen的文件中。直接引入,並運行一個方法即可。

importmnist_svmmnist_svm.svm_baseline()

我們看看結果:

Baseline classifier using an SVM.9435of10000values correct.

94.35%,好像比我們的神經網絡低一點啊。看來我們的神經網絡模型還是更優秀一些?

然而,實際情況並非如此。因為我們用的只是scikit-learn給支持向量機的設好的默認參數。支持向量機同樣有一大堆可調的超參數,以提升模型的效果。 跟據 Andreas Mueller的這篇博文,調整好超參數的支持向量機能夠達到98.5%的準確度!比我們剛才最好的神經網絡提高了1.8個百分點!

然而,故事並沒有結束。2013年,通過深度神經網絡,研究者可以達到99.79%的準確度!而且,他們並沒有運用很多高深的技術。很多技術在我們接下來的博文中都可以繼續介紹。

所以,從目前的準確度來看:

簡單的支持向量機<淺層神經網絡<調優的支持向量機<深度神經網絡

但還是要提醒一下,炫酷的算法固然重要,但是良好的數據集有時候比算法更重要。Michael Nielsen專門寫了一個公式來來表達他們的關係:

精緻的算法 ≤ 簡單的算法 + 良好的訓練數據 sophisticated algorithm ≤ simple learning algorithm + good training data.

所以為了調優模型,往往要溯源到數據本身,好的數據真的會有好的結果。

八、 小結與下期預告

以上我們只是粗略地展示了用神經網絡分析問題的基本過程,很多深入的內容並沒有展開。我們將會在接下來的博文中進行深入探討。

在該系列下一篇博文中,我們試圖直接探討深度神經網絡的表現能力,並提供一個啟發式理解。敬請關注。

End

相關焦點

  • 推薦算法系統/人臉識別/深度學習對話機器人高級實戰課
    從開發人員角色上來講,推薦系統不僅僅只有算法工程師角色的人就能完成整個系統,需要各個角色的工程師相配合才行。下面我們就從推薦系統的整體架構以及各個子系統的實現給大家深度解密來自一線大型網際網路公司重量級的實戰產品項目!!!
  • 驚為天人,NumPy手寫全部主流機器學習模型,代碼超3萬行
    機器之心報導參與:思源、一鳴、張倩用 NumPy 手寫所有主流 ML 模型,普林斯頓博士後 David Bourgin 最近開源了一個非常剽悍的項目。超過 3 萬行代碼、30 多個模型,這也許能打造「最強」的機器學習基石?NumPy 作為 Python 生態中最受歡迎的科學計算包,很多讀者已經非常熟悉它了。
  • Python視頻教程網課編程零基礎入門數據分析網絡爬蟲全套Python...
    26機器學習入門篇 27機器學習入門篇2 28機器學習提升篇 29數據挖掘篇 30深度學習必備原理與實戰 31深度學習必備原理與實戰2 32深度學習必備原理與實戰3 33深度學習必備原理與實戰4 34深度學習項目實戰 35深度學習項目實戰2 36
  • 今天的卷積網絡,Yann LeCun在93年就已經玩得很溜了
    手寫數字識別是很多人入門神經網絡時用來練手的一個項目,但就是這麼簡單的一個項目,最近在 reddit 上又火了一把,因為在 MIT 計算機科學和人工智慧實驗室,有人挖到了一個「祖師爺」級別的視頻……這段視頻錄製於 1993 年,主人公是圖靈獎得主 Yann LeCun(楊立昆)。
  • 95後哈佛小哥撰寫從零開始的機器學習入門必備,書籍資源已開放
    「構造」和「代碼」部分會用到一些 Python 的知識。「構造」部分需要了解對應內容部分,並熟悉 Python 的創建函數和類。這些「代碼」部分均不需要。全書目錄如下:1.神經網絡(Neural Networks)線性回歸是一種相對簡單的方法,用途極為廣泛,所以也是必學算法之一。第一章介紹了普通線性回歸,第二章主要介紹了線性回歸的擴展。可以通過多種方式擴展線性回歸,以適應各種建模需求。正則回歸懲罰了回歸係數的大小,以避免過度擬合。
  • 教你如何實現一行代碼透視煉丹過程
    實現代碼如下:add_image(tag, img, step, walltime=None)在語音識別或合成任務中,數據樣本分析功能可以幫助開發者實時獲取訓練過程中的音頻數據,評估語音識別或合成的效果,挑選最優的訓練模型。
  • 神經網絡篇——代碼實現密度聚類DBSCAN
    一提到密度聚類,腦海中立馬就能呈現出一個聚類結果圖,不自然的就感覺非常的簡單,不就是基於密度的聚類嘛,原理不用看也懂了,但是真的實現起來,仿佛又不知道從哪裡開始下手。這時候再仔細回想一下腦海中的密度聚類結果圖,好像和K-means聚類的結果圖是一樣的,那真實的密度聚類是什麼樣子的呢?看了西瓜書的偽代碼後還是沒法實現?今天小編就帶大家解決一下密度聚類的難點。
  • 在《我的世界》裡搭建神經網絡,運行過程清晰可見
    其實他在進行神經網絡的推理。 你如果是一個熟悉神經網絡的人,想必已經猜出來了。 圖片裡這位玩家做的正是MNIST手寫數字分類網絡。 只需用劍在牆壁上畫出數字,神經網絡就能知道你寫的是幾。
  • 什麼是人工神經網絡(ANN)?
    人工神經元的結構,人工神經網絡的基本組成部分(來源:維基百科)從本質上講,這聽起來像是一個非常瑣碎的數學運算。但是,當您將成千上萬的神經元多層放置並堆疊在一起時,您將獲得一個人工神經網絡,可以執行非常複雜的任務,例如對圖像進行分類或識別語音。
  • 20年堅守,漢王友基躋身數字手寫賽道世界領先企業
    在20世紀90年代末,數字信息技術的發展使傳統音樂播放和影像處理發生了翻天覆地的變化,讓人類從此迎來了音樂數位化和影像數位化的時代,而手寫數位化技術也在此時同時誕生。1998年,李遠志毅然決定從體制內下海,投身到手寫數位技術應用的潮流中並創辦了友基公司,順應時代發展,2017年與漢王科技融合建立漢王友基,立志為推動和普及手寫數位化應用而奮鬥。
  • 物理波動力學計算在模擬循環神經網絡的應用
    對神經元行為進行建模的數學形式表示,可以是離散或脈衝形式的模型,這是現在人工智慧中常用的數字電子技術實現的神經元器件;還可以是連續形式表示的模型,這是代表人體中神經細胞活動的最接近表示,是通過模擬電子技術實現的神經元器件。 用模擬電子技術實現的神經元器件,稱為模擬神經元。用模擬神經元組成的網絡稱為模擬神經網絡。
  • 深度神經決策樹:深度神經網絡和樹模型結合的新模型
    這種模型不僅具有了基於樹模型的可解釋性的優點,同時還可以利用神經網絡中的梯度下降法來進行訓練,並可方便地利用現有的神經網絡框架實現,將使得神經網絡的過程得以用樹的方式得到有效的解釋。深度神經網絡在計算機視覺、語音識別和語言模型等很多領域取得了成功,但作為缺乏可解釋性的黑箱模型,限制了它在模型必須求證因果領域的應用,在這些領域中我們需要明確決策是如何產生的以便評測驗證整個決策過程。除此之外,在類似於商業智能等領域,知曉每一個因素是如何影響最終決策比決策本身有時候更為重要。
  • 代碼詳解:一文掌握神經網絡超參數調優
    該景觀類似於神經網絡的損失平面。訓練神經網絡的目的是通過某種形式的優化找到損失平面上的最小值——典型的隨機坡度減少。在學習使用高難度的優化功能後,本文讀者能充分應對施行神經網絡時遇到的實際問題場景。測試神經網絡前,首先需要給功能下定義能並找出最小值(否則無法確定為正確答案)。
  • 從神經轉化到符號:從知識圖譜的角度看認知推理的發展
    但不同之處在於,神經系統擅長處理非結構化的數據(如文本等),目前的主流模型以端到端為主,常見的應用場景有機器翻譯、語音識別、簡單問題智能問答(如,姚明的身高是多少?)等;而符號系統主要以結構化的資料庫為主,且通常支持結構化的査詢、推理引擎等,能夠實現複雜問題的求解(如,美國是農業出口大國,為什麼還要進口咖啡?)。
  • 一行Python 代碼能實現這麼多喪心病狂的功能?
    最近看知乎上有一篇名為《一行 Python 能實現什麼喪心病狂的功能?》(https://www.zhihu.com/question/37046157)的帖子,點進去發現一行Python代碼可以做這麼多喪心病狂的功能!整理了一下知乎上這篇文章的內容,頗覺有趣,分享給大家。
  • 人工智慧學習之什麼是人工神經網絡?
    在構建一個識別「貓「圖像的一個系統中,將在包含標記為「貓」的圖像的數據集上訓練人工神經網絡,該數據集可用作任何進行分析的參考點。正如人們可能學會根據尾巴或皮毛等獨特特徵來識別狗一樣,人工神經網絡(ANN)也可以通過將每個圖像分解成不同的組成部分(如顏色和形狀)進行識別。
  • 深度學習不是萬靈藥 神經網絡3D建模其實只是圖像識別
    但是,最近一篇文章卻對此提出了質疑:幾乎所有這些基於深度神經網絡的3D重建的工作,實際上並不是進行重建,而是進行圖像分類。 在此基礎上,研究人員還證明了即使不需要明確地推斷出物體的3D結構,現代卷積網絡在單視圖3D重建中的性能是可以超越的。 在許多情況下,識別基線的預測不僅在數量上更好,而且在視覺上看起來更有吸引力。 研究人員認為,卷積網絡在單視圖3D重建任務中是主流實驗程序的某些方面的結果,包括數據集的組成和評估協議。它們允許網絡找到一個快捷的解決方案,這恰好是圖像識別。
  • 不到1000行代碼,GitHub 1400星,天才黑客開源深度學習框架tinygrad
    tinygrad 的代碼數量不到 1000 行,目前該項目獲得了 GitHub 1400 星。在深度學習時代,谷歌、Facebook、百度等科技巨頭開源了多款框架來幫助開發者更輕鬆地學習、構建和訓練不同類型的神經網絡。而這些大公司也花費了很大的精力來維護 TensorFlow、PyTorch 這樣龐大的深度學習框架。
  • 讓你的電腦擁有「視力」,用卷積神經網絡就可以!
    卷積神經網絡極大地提升了圖像識別模型的精度,在生活中也有很多的應用。在這篇文章中,我將描述它的工作原理、一些實際應用,以及如何用Python和Keras是實現一個卷積神經網絡。舉個例子:我們有一個神經網絡試圖分辨一張圖片是不是一個熱狗。那麼我們就會想要:在神經網絡中,包含熱狗的特徵的神經元比包含普通狗的特徵的神經元更重要。神經網絡的權重是通過在數據集上訓練得到的。它會運行許多次,根據損失函數通過反向傳播改變各個權重。可以說神經網絡被輸入測試數據,然後得到並分析結果,取得得分並使自己變得更加準確。