最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

純用NumPy實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)的示例代碼

 更新時(shí)間:2018年10月24日 13:39:30   作者:阿里云云棲社區(qū)  
這篇文章主要介紹了純用NumPy實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

摘要: 純NumPy代碼從頭實(shí)現(xiàn)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)。

Keras、TensorFlow以及PyTorch都是高級(jí)別的深度學(xué)習(xí)框架,可用于快速構(gòu)建復(fù)雜模型。前不久,我曾寫(xiě)過(guò)一篇文章,對(duì)神經(jīng)網(wǎng)絡(luò)是如何工作的進(jìn)行了簡(jiǎn)單的講解。該文章側(cè)重于對(duì)神經(jīng)網(wǎng)絡(luò)中運(yùn)用到的數(shù)學(xué)理論知識(shí)進(jìn)行詳解。本文將利用NumPy實(shí)現(xiàn)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò),在實(shí)戰(zhàn)中對(duì)其進(jìn)行深層次剖析。最后,我們會(huì)利用分類問(wèn)題對(duì)模型進(jìn)行測(cè)試,并與Keras所構(gòu)建的神經(jīng)網(wǎng)絡(luò)模型進(jìn)行性能的比較。

Note:源碼可在我的GitHub中查看。

在正式開(kāi)始之前,需要先對(duì)所做實(shí)驗(yàn)進(jìn)行構(gòu)思。我們想要編寫(xiě)一個(gè)程序,使其能夠創(chuàng)建一個(gè)具有指定架構(gòu)(層的數(shù)量、大小以及激活函數(shù))的神經(jīng)網(wǎng)絡(luò),如圖一所示??傊覀冃枰A(yù)先對(duì)網(wǎng)絡(luò)進(jìn)行訓(xùn)練,然后利用它進(jìn)行預(yù)測(cè)。

上圖展示了神經(jīng)網(wǎng)絡(luò)在被訓(xùn)練時(shí)的工作流程。從中我們可以清楚的需要更新的參數(shù)數(shù)量以及單次迭代的不同狀態(tài)。構(gòu)建并管理正確的數(shù)據(jù)架構(gòu)是其中最困難的一環(huán)。由于時(shí)間限制,圖中所示的參數(shù)不會(huì)一一詳解,有興趣可點(diǎn)擊此處進(jìn)行了解。

神經(jīng)網(wǎng)絡(luò)層的初始化

首先,對(duì)每一層的權(quán)重矩陣W及偏置向量b進(jìn)行初始化。在上圖中,上標(biāo)[l]表示目前是第幾層(從1開(kāi)始),n的值表示一層中的神經(jīng)元數(shù)量。描述神經(jīng)網(wǎng)絡(luò)架構(gòu)的信息類似于Snippet 1中所列內(nèi)容。每一項(xiàng)都描述了單層神經(jīng)網(wǎng)絡(luò)的基本參數(shù):input_dim,即輸入層神經(jīng)元維度;output_dim,即輸出層神經(jīng)元維度;activation,即使用的激活函數(shù)。

nn_architecture = [
  {"input_dim": 2, "output_dim": 4, "activation": "relu"},
  {"input_dim": 4, "output_dim": 6, "activation": "relu"},
  {"input_dim": 6, "output_dim": 6, "activation": "relu"},
  {"input_dim": 6, "output_dim": 4, "activation": "relu"},
  {"input_dim": 4, "output_dim": 1, "activation": "sigmoid"},
]

Snippet 1.

從Snippet 1可看出,每一層輸出神經(jīng)元的維度等于下一層的輸入維度。對(duì)權(quán)重矩陣W及偏置向量b進(jìn)行初始化的代碼如下:

def init_layers(nn_architecture, seed = 99):
  np.random.seed(seed)
  number_of_layers = len(nn_architecture)
  params_values = {}

  for idx, layer in enumerate(nn_architecture):
    layer_idx = idx + 1
    layer_input_size = layer["input_dim"]
    layer_output_size = layer["output_dim"]

    params_values['W' + str(layer_idx)] = np.random.randn(
      layer_output_size, layer_input_size) * 0.1
    params_values['b' + str(layer_idx)] = np.random.randn(
      layer_output_size, 1) * 0.1

  return params_values

Snippet 2.

在本節(jié)中,我們利用NumPy將權(quán)重矩陣W及偏置向量b初始化為小的隨機(jī)數(shù)。特別注意的是,初始化權(quán)重值不能相同,否則網(wǎng)絡(luò)會(huì)變?yōu)閷?duì)稱的。也就是說(shuō),如果權(quán)重初始化為同一值,則對(duì)于任何輸入X,每個(gè)隱藏層對(duì)應(yīng)的每個(gè)神經(jīng)元的輸出都是相同的,這樣即使梯度下降訓(xùn)練,無(wú)論訓(xùn)練多少次,這些神經(jīng)元都是對(duì)稱的,無(wú)論隱藏層內(nèi)有多少個(gè)結(jié)點(diǎn),都相當(dāng)于在訓(xùn)練同一個(gè)函數(shù)。

初始化的值較小能夠使得算法第一次迭代的時(shí)候效率更高。Sigmoid函數(shù)圖像如下圖所示,它對(duì)中央?yún)^(qū)的信號(hào)增益較大,對(duì)兩側(cè)區(qū)的信號(hào)增益小。

激活函數(shù)(Activation functions)

激活函數(shù)在神經(jīng)網(wǎng)絡(luò)中至關(guān)重要,其原理簡(jiǎn)單但功能強(qiáng)大,給神經(jīng)元引入了非線性因素,使得神經(jīng)網(wǎng)絡(luò)可以任意逼近任何非線性函數(shù),從而應(yīng)用于眾多的非線性模型?!叭绻麤](méi)有激活函數(shù),每一層輸出都是上層輸入的線性函數(shù),無(wú)論神經(jīng)網(wǎng)絡(luò)有多少層,輸出都是輸入的線性組合?!奔せ詈瘮?shù)種類眾多,本文選取了最常用的兩種——ReLU及Sigmoid函數(shù),代碼如下:

def sigmoid(Z):
  return 1/(1+np.exp(-Z))

def relu(Z):
  return np.maximum(0,Z)

def sigmoid_backward(dA, Z):
  sig = sigmoid(Z)
  return dA * sig * (1 - sig)

def relu_backward(dA, Z):
  dZ = np.array(dA, copy = True)
  dZ[Z <= 0] = 0;
  return dZ;

Snippet 3.

前向傳播算法(Forward propagation)

本文所設(shè)計(jì)的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)簡(jiǎn)單,信息流只有一個(gè)方向:以X矩陣的形式傳遞,穿過(guò)所有隱藏層單元,最終輸出預(yù)測(cè)結(jié)構(gòu)Y_hat。

def single_layer_forward_propagation(A_prev, W_curr, b_curr, activation="relu"):
  Z_curr = np.dot(W_curr, A_prev) + b_curr

  if activation is "relu":
    activation_func = relu
  elif activation is "sigmoid":
    activation_func = sigmoid
  else:
    raise Exception('Non-supported activation function')

  return activation_func(Z_curr), Z_curr

Snippet 4.

前向傳播就是上層處理完的數(shù)據(jù)作為下一層的輸入數(shù)據(jù),然后進(jìn)行處理(權(quán)重),再傳給下一層,這樣逐層處理,最后輸出。給定上一層的輸入信號(hào),計(jì)算仿射變換(affine transformation)Z,然后應(yīng)用選定的激活函數(shù)。

前向傳播算法代碼如下,該函數(shù)不僅進(jìn)行預(yù)測(cè)計(jì)算,還存儲(chǔ)中間層A和Z矩陣的值:

def full_forward_propagation(X, params_values, nn_architecture):
  memory = {}
  A_curr = X

  for idx, layer in enumerate(nn_architecture):
    layer_idx = idx + 1
    A_prev = A_curr

    activ_function_curr = layer["activation"]
    W_curr = params_values["W" + str(layer_idx)]
    b_curr = params_values["b" + str(layer_idx)]
    A_curr, Z_curr = single_layer_forward_propagation(A_prev, W_curr, b_curr, activ_function_curr)

    memory["A" + str(idx)] = A_prev
    memory["Z" + str(layer_idx)] = Z_curr

  return A_curr, memory

Snippet 5.

損失函數(shù)(Loss function)

損失函數(shù)是用來(lái)估量模型的預(yù)測(cè)值與真實(shí)值的不一致程度,它是一個(gè)非負(fù)實(shí)值函數(shù)。損失函數(shù)由我們想要解決的問(wèn)題所決定。在本文中,我們想要測(cè)試神經(jīng)網(wǎng)絡(luò)模型區(qū)分兩個(gè)類別的能力,所以選擇了交叉熵?fù)p失函數(shù)(binary_crossentropy),其定義如下:

為了更加清楚的了解學(xué)習(xí)過(guò)程,我增添了一個(gè)用于計(jì)算精度的函數(shù):

def get_cost_value(Y_hat, Y):
  m = Y_hat.shape[1]
  cost = -1 / m * (np.dot(Y, np.log(Y_hat).T) + np.dot(1 - Y, np.log(1 - Y_hat).T))
  return np.squeeze(cost)

def get_accuracy_value(Y_hat, Y):
  Y_hat_ = convert_prob_into_class(Y_hat)
  return (Y_hat_ == Y).all(axis=0).mean()

Snippet 6.

反向傳播算法(Backward propagation)

許多缺乏經(jīng)驗(yàn)的深度學(xué)習(xí)愛(ài)好者認(rèn)為反向傳播是一種復(fù)雜且難以理解的算法。

def single_layer_backward_propagation(dA_curr, W_curr, b_curr, Z_curr, A_prev, activation="relu"):
  m = A_prev.shape[1]

  if activation is "relu":
    backward_activation_func = relu_backward
  elif activation is "sigmoid":
    backward_activation_func = sigmoid_backward
  else:
    raise Exception('Non-supported activation function')

  dZ_curr = backward_activation_func(dA_curr, Z_curr)
  dW_curr = np.dot(dZ_curr, A_prev.T) / m
  db_curr = np.sum(dZ_curr, axis=1, keepdims=True) / m
  dA_prev = np.dot(W_curr.T, dZ_curr)

  return dA_prev, dW_curr, db_curr

Snippet 7.

其實(shí),他們困惑的也就是反向傳播算法中的梯度下降問(wèn)題,但二者并不可混為一談。前者旨在有效地計(jì)算梯度,而后者是利用計(jì)算得到的梯度進(jìn)行優(yōu)化。梯度下降可以應(yīng)對(duì)帶有明確求導(dǎo)函數(shù)的情況,我們可以把它看作沒(méi)有隱藏層的網(wǎng)絡(luò);但對(duì)于多隱藏層的神經(jīng)網(wǎng)絡(luò),應(yīng)先將誤差反向傳播至隱藏層,然后再應(yīng)用梯度下降,其中將誤差從最末層往前傳遞的過(guò)程需要鏈?zhǔn)椒▌t,反向傳播算法可以說(shuō)是梯度下降在鏈?zhǔn)椒▌t中的應(yīng)用。對(duì)于單層的神經(jīng)網(wǎng)絡(luò),該過(guò)程如下所示:

本文省略的推導(dǎo)過(guò)程,但從上面的公式仍可看出A和Z矩陣值的重要性。

Snippet 7中所示代碼僅編寫(xiě)了神經(jīng)網(wǎng)絡(luò)中某層的反向傳播算法,Snippet 8將展示神經(jīng)網(wǎng)絡(luò)中完整的反向傳播算法。

def full_backward_propagation(Y_hat, Y, memory, params_values, nn_architecture):
  grads_values = {}
  m = Y.shape[1]
  Y = Y.reshape(Y_hat.shape)

  dA_prev = - (np.divide(Y, Y_hat) - np.divide(1 - Y, 1 - Y_hat));

  for layer_idx_prev, layer in reversed(list(enumerate(nn_architecture))):
    layer_idx_curr = layer_idx_prev + 1
    activ_function_curr = layer["activation"]

    dA_curr = dA_prev

    A_prev = memory["A" + str(layer_idx_prev)]
    Z_curr = memory["Z" + str(layer_idx_curr)]
    W_curr = params_values["W" + str(layer_idx_curr)]
    b_curr = params_values["b" + str(layer_idx_curr)]

    dA_prev, dW_curr, db_curr = single_layer_backward_propagation(
      dA_curr, W_curr, b_curr, Z_curr, A_prev, activ_function_curr)

    grads_values["dW" + str(layer_idx_curr)] = dW_curr
    grads_values["db" + str(layer_idx_curr)] = db_curr

  return grads_values

Snippet 8.

參數(shù)更新(Updating parameters values)

該部分旨在利用計(jì)算得到梯度更新網(wǎng)絡(luò)中的參數(shù),同時(shí)最小化目標(biāo)函數(shù)。我們會(huì)使用到params_values,它存放當(dāng)前的參數(shù)值,以及grads_values,它存放存儲(chǔ)關(guān)于這些參數(shù)的損失函數(shù)的導(dǎo)數(shù)?,F(xiàn)在只需要在神經(jīng)網(wǎng)絡(luò)的每層應(yīng)用如下公式即可:

def update(params_values, grads_values, nn_architecture, learning_rate):
  for layer_idx, layer in enumerate(nn_architecture):
    params_values["W" + str(layer_idx)] -= learning_rate * grads_values["dW" + str(layer_idx)]    
    params_values["b" + str(layer_idx)] -= learning_rate * grads_values["db" + str(layer_idx)]

  return params_values;

Snippet 9.

整合(Putting things together)

現(xiàn)在我們只需將準(zhǔn)備好的函數(shù)按照正確的順序整合到一起,若對(duì)正確的順序有疑問(wèn)請(qǐng)參見(jiàn)圖2。

def train(X, Y, nn_architecture, epochs, learning_rate):
  params_values = init_layers(nn_architecture, 2)
  cost_history = []
  accuracy_history = []

  for i in range(epochs):
    Y_hat, cashe = full_forward_propagation(X, params_values, nn_architecture)
    cost = get_cost_value(Y_hat, Y)
    cost_history.append(cost)
    accuracy = get_accuracy_value(Y_hat, Y)
    accuracy_history.append(accuracy)

    grads_values = full_backward_propagation(Y_hat, Y, cashe, params_values, nn_architecture)
    params_values = update(params_values, grads_values, nn_architecture, learning_rate)

  return params_values, cost_history, accuracy_history

Snippet 10.

對(duì)比分析(David vs Goliath)

接下來(lái),我們將利用所構(gòu)建的模型解決簡(jiǎn)單的分類問(wèn)題。如圖7所示,本次實(shí)驗(yàn)使用的數(shù)據(jù)集包含兩個(gè)類別。我們將訓(xùn)練模型對(duì)兩個(gè)不同的類別進(jìn)行區(qū)分。此外,我們還準(zhǔn)備了一個(gè)由Keras所構(gòu)建的神經(jīng)網(wǎng)絡(luò)模型以進(jìn)行對(duì)比。兩個(gè)模型具有相同的架構(gòu)和學(xué)習(xí)速率。雖然我們的模型很簡(jiǎn)單,但結(jié)果表明,NumPy和Keras模型在測(cè)試集上均達(dá)到了95%的準(zhǔn)確率。只是我們的模型耗費(fèi)了更多的時(shí)間,未來(lái)工作可通過(guò)加強(qiáng)優(yōu)化改善時(shí)間開(kāi)銷問(wèn)題。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python實(shí)戰(zhàn)基礎(chǔ)之繪制餅狀圖分析商品庫(kù)存

    Python實(shí)戰(zhàn)基礎(chǔ)之繪制餅狀圖分析商品庫(kù)存

    餅狀圖(pie chart)一般用于描述分類型數(shù)據(jù)的相對(duì)頻數(shù)或百分?jǐn)?shù)頻數(shù)分布,呈現(xiàn)部分與總體的關(guān)系,下面這篇文章主要給大家介紹了關(guān)于Python實(shí)戰(zhàn)基礎(chǔ)之繪制餅狀圖分析商品庫(kù)存的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • Django windows使用Apache實(shí)現(xiàn)部署流程解析

    Django windows使用Apache實(shí)現(xiàn)部署流程解析

    這篇文章主要介紹了Django windows使用Apache實(shí)現(xiàn)部署流程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Python實(shí)現(xiàn)邊緣提取的示例代碼

    Python實(shí)現(xiàn)邊緣提取的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Python計(jì)算機(jī)視覺(jué)中如何實(shí)現(xiàn)邊緣提取,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定幫助,需要的可以參考一下
    2022-05-05
  • python讀取dicom圖像示例(SimpleITK和dicom包實(shí)現(xiàn))

    python讀取dicom圖像示例(SimpleITK和dicom包實(shí)現(xiàn))

    今天小編就為大家分享一篇python讀取dicom圖像示例(SimpleITK和dicom包實(shí)現(xiàn)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-01-01
  • Python如何將list中的string轉(zhuǎn)換為int

    Python如何將list中的string轉(zhuǎn)換為int

    這篇文章主要介紹了Python如何將list中的string轉(zhuǎn)換為int,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 深入探討PythonLogging模塊的高級(jí)用法與性能優(yōu)化

    深入探討PythonLogging模塊的高級(jí)用法與性能優(yōu)化

    在Python應(yīng)用程序中,日志處理是一項(xiàng)至關(guān)重要的任務(wù),本文將探索Logging模塊的高級(jí)用法,包括日志級(jí)別、格式化、處理程序等方面的功能,需要的可以參考下
    2024-04-04
  • 使用DataFrame刪除行和列的實(shí)例講解

    使用DataFrame刪除行和列的實(shí)例講解

    下面小編就為大家分享一篇使用DataFrame刪除行和列的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • python連接sql server亂碼的解決方法

    python連接sql server亂碼的解決方法

    為解決python連接sql server是出現(xiàn)的亂碼,需要在連接sql server 時(shí)指定字符集utf8(client charset = UTF-8),python環(huán)境制定了字符集變量(#coding=utf-8 )
    2013-01-01
  • python實(shí)現(xiàn)NB-IoT模塊遠(yuǎn)程控制

    python實(shí)現(xiàn)NB-IoT模塊遠(yuǎn)程控制

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)NB-IoT模塊遠(yuǎn)程控制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • python分割一個(gè)文本為多個(gè)文本的方法

    python分割一個(gè)文本為多個(gè)文本的方法

    這篇文章主要為大家詳細(xì)介紹了python分割一個(gè)文本為多個(gè)文本,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07

最新評(píng)論

磐石市| 大同县| 周至县| 苍溪县| 江孜县| 田林县| 清丰县| 长宁区| 曲水县| 历史| 西昌市| 奎屯市| 土默特右旗| 河津市| 孟州市| 淮滨县| 湛江市| 肃宁县| 徐州市| 乌兰县| 靖州| 荣昌县| 天全县| 苗栗市| 桐柏县| 宿迁市| 朝阳县| 伊金霍洛旗| 资溪县| 尉氏县| 石阡县| 屏南县| 涡阳县| 屏边| 呼玛县| 泾源县| 改则县| 龙南县| 丰镇市| 犍为县| 洮南市|