日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

深度学习笔记:利用numpy从零搭建一个神经网络

發(fā)布時間:2024/1/17 pytorch 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习笔记:利用numpy从零搭建一个神经网络 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

很多人說深度學(xué)習(xí)就是個黑箱子,把圖像預(yù)處理之后丟進(jìn) tensorflow 就能出來預(yù)測結(jié)果,簡單有效又省時省力。但正如我在上一篇推送中所說,如果你已是一名功力純厚的深度學(xué)習(xí)工程師,這么做當(dāng)然沒問題。但我想大多數(shù)人也和我一樣,都是走在學(xué)習(xí)深度學(xué)習(xí)的路上,一上來就上框架并沒有什么特別不妥之處,但總歸是對你理解深度學(xué)習(xí)的黑箱機(jī)制是了無裨益的。所以,我建議在學(xué)習(xí)深度學(xué)習(xí)的路上,從最簡單的感知機(jī)開始寫起,一步一步捋清神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu),以至于激活函數(shù)怎么寫、采用何種損失函數(shù)、前向傳播怎么寫、后向傳播又怎么寫,權(quán)值如何迭代更新,都需要你自己去實(shí)現(xiàn)。若在一開始就直接調(diào)用框架,小的 demo 可以跑起來,糊弄一時,看起來就像是鳩摩智在內(nèi)力未到的情形下強(qiáng)行練習(xí)少林寺的 72 絕技,最后走火入魔。

無論你是在看那本深度學(xué)習(xí)的花書,還是在學(xué)習(xí) Adrew NG 的 deeplearningai,或者是在cs231n 課程,對神經(jīng)網(wǎng)絡(luò)的基本理論了如指掌的你一定想親手用 python 來實(shí)現(xiàn)它。筆記1就在不借助任何深度學(xué)習(xí)框架的基礎(chǔ)上,利用 python 的科學(xué)計算庫 numpy 由最初級的感知機(jī)開始,從零搭建一個神經(jīng)網(wǎng)絡(luò)模型。



感知機(jī)結(jié)構(gòu)

對于感知機(jī)模型、神經(jīng)網(wǎng)絡(luò)理論這里就不再敘述,相信志在精通深度學(xué)習(xí)的你對此一定很熟練了。至于對于神經(jīng)網(wǎng)絡(luò)中的輸入層、隱藏層、輸出層、權(quán)重與偏置、激活函數(shù)、損失函數(shù)、前向傳播、反向傳播、權(quán)值更新、梯度下降、微積分中的鏈?zhǔn)角髮?dǎo)、方向梯度等概念,我也假設(shè)你很熟練了。所以,接下來就讓我們從零搭建一個最初級的神經(jīng)網(wǎng)絡(luò)模型。

在寫代碼前,必須先捋一下思路,咱們先要什么,然后再寫什么,你心中必須有個數(shù)。要從零開始寫一個神經(jīng)網(wǎng)絡(luò),通常的方法是:

  • 定義網(wǎng)絡(luò)結(jié)構(gòu)(指定輸出層、隱藏層、輸出層的大小)
  • 初始化模型參數(shù)
  • 循環(huán)操作:執(zhí)行前向傳播/計算損失/執(zhí)行后向傳播/權(quán)值更新

有了上面這個思路,我們就可以開始寫了。當(dāng)然了,本節(jié)是寫一個最簡單的感知機(jī)模型,所以網(wǎng)絡(luò)結(jié)構(gòu)就無需特別定義。首先來定義我們的激活函數(shù),激活函數(shù)有很多種,這里我們使用大名鼎鼎的 sigmoid 函數(shù):

直接利用 numpy 進(jìn)行定義 sigmoid()

import numpy as np def sigmoid(x):return 1 / (1 + np.exp(-x))

在無需定義網(wǎng)絡(luò)結(jié)構(gòu)的情形下,第二步我們就可以直接對模型參數(shù)進(jìn)行初始化。模型參數(shù)主要包括權(quán)值w 和偏置 b ,這也是神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)過程要學(xué)的東西。繼續(xù)利用 numpy 對參數(shù)進(jìn)行初始化:

def initilize_with_zeros(dim):w = np.zeros((dim, 1))b = 0.0#assert(w.shape == (dim, 1))#assert(isinstance(b, float) or isinstance(b, int))return w, b

接下來就要進(jìn)入模型的主體部分,執(zhí)行最后一步那個大的循環(huán)操作,這個循環(huán)中包括前向傳播和計算損失、反向傳播和權(quán)值更新。這也是神經(jīng)網(wǎng)絡(luò)訓(xùn)練過程中每一次需要迭代的部分。這里簡單說一下,很多初學(xué)者容易被這兩個概念繞住,前向傳播簡單而言就是計算預(yù)測 y 的過程,而后向傳播則是根據(jù)預(yù)測值和實(shí)際值之間的誤差不斷往回推更新權(quán)值和偏置的過程。



前后傳播與后向傳播

下面我們來定義一個大的前向傳播函數(shù),預(yù)測值y為模型從輸入到經(jīng)過激活函數(shù)處理后的輸出的結(jié)果。損失函數(shù)我們采用交叉熵?fù)p失,利用 numpy 定義如下函數(shù):

def propagate(w, b, X, Y):m = X.shape[1]A = sigmoid(np.dot(w.T, X) + b)cost = -1/m * np.sum(Y*np.log(A) + (1-Y)*np.log(1-A))dw = np.dot(X, (A-Y).T)/mdb = np.sum(A-Y)/m assert(dw.shape == w.shape) assert(db.dtype == float)cost = np.squeeze(cost) assert(cost.shape == ())grads = { 'dw': dw, 'db': db} return grads, cost

在上面的前向傳播函數(shù)中,我們先是通過激活函數(shù)直接表示了感知機(jī)輸出的預(yù)測值,然后通過定義的交叉熵?fù)p失函數(shù)計算了損失,最后根據(jù)損失函數(shù)計算了權(quán)值 w 和偏置 b的梯度,將參數(shù)梯度結(jié)果以字典和損失一起作為函數(shù)的輸出進(jìn)行返回。這就是前向傳播的編寫思路。

接下來循環(huán)操作的第二步就是進(jìn)行反向傳播操作,計算每一步的當(dāng)前損失根據(jù)損失對權(quán)值進(jìn)行更新。同樣定義一個函數(shù) backward_propagation :

def backward_propagation(w, b, X, Y, num_iterations, learning_rate, print_cost=False):cost = [] for i in range(num_iterations):grad, cost = propagate(w, b, X, Y)dw = grad['dw']db = grad['db']w = w - learing_rate * dwb = b - learning_rate * db if i % 100 == 0:cost.append(cost) if print_cost and i % 100 == 0:print("cost after iteration %i: %f" %(i, cost))params = {"dw": w,"db": b}grads = {"dw": dw,"db": db} return params, grads, costs

在上述函數(shù)中,我們先是建立了一個損失列表容器,然后將前一步定義的前向傳播函數(shù)放進(jìn)去執(zhí)行迭代操作,計算每一步的當(dāng)前損失和梯度,利用梯度下降法對權(quán)值進(jìn)行更新,并用字典封裝迭代結(jié)束時的參數(shù)和梯度進(jìn)行返回。

如上所示,一個簡單的神經(jīng)網(wǎng)絡(luò)模型(感知機(jī))就搭建起來了。通常模型建好之后我們還需要對測試數(shù)據(jù)進(jìn)行預(yù)測,所以我們也定義一個預(yù)測函數(shù) predict,將模型的概率輸出轉(zhuǎn)化為0/1值。

def predict(w, b, X):m = X.shape[1]Y_prediction = np.zeros((1, m))w = w.reshape(X.shape[0], 1)A = sigmoid(np.dot(w.T, X)+b) for i in range(A.shape[1]): if A[:, i] > 0.5:Y_prediction[:, i] = 1else:Y_prediction[:, i] = 0assert(Y_prediction.shape == (1, m)) return Y_prediction

到這里整個模型算是寫完了,但是我們定義了這么多函數(shù),調(diào)用起來太麻煩,所以致力于要寫出 pythonic的代碼的你們肯定想對這些函數(shù)進(jìn)行一下簡單的封裝:

def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False):# initialize parameters with zeros (≈ 1 line of code)w, b = initialize_with_zeros(X_train.shape[0]) # Gradient descent (≈ 1 line of code)parameters, grads, costs = backwize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost) # Retrieve parameters w and b from dictionary "parameters"w = parameters["w"]b = parameters["b"] # Predict test/train set examples (≈ 2 lines of code)Y_prediction_train = predict(w, b, X_train)Y_prediction_test = predict(w, b, X_test) # Print train/test Errorsprint("train accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100))print("test accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100))d = {"costs": costs, "Y_prediction_test": Y_prediction_test, "Y_prediction_train" : Y_prediction_train, "w" : w, "b" : b, "learning_rate" : learning_rate,"num_iterations": num_iterations} return d

如此這般一個簡易的神經(jīng)網(wǎng)絡(luò)就被你用 numpy就寫出來了。現(xiàn)在社會浮躁,很多人學(xué)習(xí)都沒有耐心,總是抱著鳩摩智的心態(tài)想要一步登天。學(xué)習(xí)機(jī)器學(xué)習(xí)和深度學(xué)習(xí)方法很多,但我相信,只有對基本的算法原理每一步都捋清楚,每一步都用最基礎(chǔ)的庫去實(shí)現(xiàn),你成為一名優(yōu)秀的機(jī)器學(xué)習(xí)工程師只是時間問題。深度學(xué)習(xí)第一次推送筆記,加油吧各位!

參考資料:

coursera.org/learn/mach

deeplearning.ai/

總結(jié)

以上是生活随笔為你收集整理的深度学习笔记:利用numpy从零搭建一个神经网络的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。