1. 程式人生 > >Tensorflow深度學習之二十一:LeNet的實現(CIFAR-10資料集)

Tensorflow深度學習之二十一:LeNet的實現(CIFAR-10資料集)

一、LeNet的簡介
LeNet是一個用來識別手寫數字的最經典的卷積神經網路,是Yann LeCun在1998年設計並提出的。Lenet的網路結構規模較小,但包含了卷積層、池化層、全連線層,他們都構成了現代CNN的基本元件。

這裡寫圖片描述

LeNet包含輸入層在內共有八層,每一層都包含多個權重。C層代表卷積層,通過卷積操作,可以使原訊號特徵增強,並降低噪音。S層是一個池化層,利用影象區域性相關性的原理,對影象進行子抽樣,可以減少資料處理量,同時也保留了一定的有用資訊。

  1. 第一層:輸入層是32 * 32大小的影象。
  2. C1層是一個卷積層,6個特徵圖譜(feature map),5*5大小的卷積核,每個feature map有(32-5+1) * (32-5+1),即28 * 28個神經元,每個神經元都與輸入層的5 * 5大小的區域相連。故C1層共有(5 * 5 + 1) * 6 = 156個訓練引數。5 * 5個連線引數+1個偏置引數,兩層之間的連線數為156 * (28 * 28) = 122304個。通過卷積運算,使原訊號特徵增強,並且降低噪音,而且不同的卷積核能夠提取到影象的不同特徵。
  3. S2層是一個下采樣層,有6個14 * 14的特徵圖,每個feature map中的每個神經元都與C1層對應的feature map中的2 * 2的區域相連。S2層中的每個神經元是由這4個輸入相加,乘以一個訓練引數,再加上這個feature map的偏置引數,結果通過sigmoid函式計算而得。S2的每一個feature map有14 * 14個神經元,引數個數為2 * 6 = 12個,連線數為(4+1) * (14 * 14) * 6 = 5880個連線。池化層的目的是為了降低網路訓練引數及模型的過擬合程度。池化方式有最大池化和平均池化兩種。
  4. C3層也是一個卷積層,運用5 * 5的卷積層,處理S2層。計算C3的feature map的神經元個數為(14-5+1) * (14-5+1),即10 * 10。C3有16個feature map,每個feature map由上一層的各feature map之間的不同組合。
  5. S4層是一個下采樣層,由16個5 * 5大小的feature map構成,每個神經元與C3中對應的feature map的2 * 2大小的區域相連。同理,計算出2 * 16 = 32 個引數和2000個連線。
  6. C5層又是一個卷積層,同樣使用5 * 5的卷積核,每個feature map有(5-5+1) * (5-5+1),即1 * 1的神經元,每個單元都與S4層的全部16個feature map的5 * 5區域相連。C5層共有120個feature map,其引數與連線數都為48120個。
  7. F6層全連線層共有84個feature map,每個feature map只有一個神經元與C5層全連線,故有(1 * 1 * 120 + 1) * 84 = 10164個引數和連線。F6層計算輸入向量和權重向量之間的點積和偏置,之後將其傳遞給sigmoid函式來計算神經元。
  8. 輸出層也是全連線層,共有10個節點,分別代表數字0到9。

(以上資料參考《深度學習—Caffe之經典模型詳解與實戰》)

二、利用Tensorflow(Keras)實現LeNet
這裡使用LeNet實現CIFAR-10資料集的分類。
訓練完成後的檔案目錄如下:
這裡寫圖片描述

名稱 作用
cifar-10-python 資料夾,CIFAR-10資料集
LeNet\log 資料夾,用於存放程式執行時的日誌資訊,可使用TensorBoard檢視
cifar_data_load.py 載入CIFAR-10資料集
lenet-no-activation-model.h5 儲存的模型檔案
main.py 訓練模型
Pytest.py 利用模型進行預測
import numpy as np
import pickle


def unpickle(file):
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='bytes')
    return dict


def GetPhoto(pixel):
    assert len(pixel) == 3072
    r = pixel[0:1024]; r = np.reshape(r, [32, 32, 1])
    g = pixel[1024:2048]; g = np.reshape(g, [32, 32, 1])
    b = pixel[2048:3072]; b = np.reshape(b, [32, 32, 1])

    photo = np.concatenate([r, g, b], -1)

    return photo


def GetTrainDataByLabel(label):
    batch_label = []
    labels = []
    data = []
    filenames = []
    for i in range(1, 1+5):
        batch_label.append(unpickle("cifar-10-python/cifar-10-batches-py/data_batch_%d"%i)[b'batch_label'])
        labels += unpickle("cifar-10-python/cifar-10-batches-py/data_batch_%d"%i)[b'labels']
        data.append(unpickle("cifar-10-python/cifar-10-batches-py/data_batch_%d"%i)[b'data'])
        filenames += unpickle("cifar-10-python/cifar-10-batches-py/data_batch_%d"%i)[b'filenames']

    data = np.concatenate(data, 0)

    label = str.encode(label)
    if label == b'data':
        array = np.ndarray([len(data), 32, 32, 3], dtype=np.int32)
        for i in range(len(data)):
            array[i] = GetPhoto(data[i])
        return array
        pass
    elif label == b'labels':
        return labels
        pass
    elif label == b'batch_label':
        return batch_label
        pass
    elif label == b'filenames':
        return filenames
        pass
    else:
        raise NameError


def GetTestDataByLabel(label):
    batch_label = []
    filenames = []

    batch_label.append(unpickle("cifar-10-python/cifar-10-batches-py/test_batch")[b'batch_label'])
    labels = unpickle("cifar-10-python/cifar-10-batches-py/test_batch")[b'labels']
    data = unpickle("cifar-10-python/cifar-10-batches-py/test_batch")[b'data']
    filenames += unpickle("cifar-10-python/cifar-10-batches-py/test_batch")[b'filenames']

    label = str.encode(label)
    if label == b'data':
        array = np.ndarray([len(data), 32, 32, 3], dtype=np.int32)
        for i in range(len(data)):
            array[i] = GetPhoto(data[i])
        return array
        pass
    elif label == b'labels':
        return labels
        pass
    elif label == b'batch_label':
        return batch_label
        pass
    elif label == b'filenames':
        return filenames
        pass
    else:
        raise NameError

模型的建立以及訓練 main.py:

from tensorflow.contrib.keras.api.keras.layers import Input, Conv2D, MaxPool2D, Dense, Flatten
from tensorflow.contrib.keras.api.keras.models import Model
from tensorflow.contrib.keras.api.keras.optimizers import Adam
from tensorflow.contrib.keras.api.keras.callbacks import TensorBoard
from tensorflow.contrib.keras.api.keras.utils import to_categorical

from cifar_data_load import GetTrainDataByLabel, GetTestDataByLabel

# 構建LeNet模型
# 這裡使用的LeNet模型與原始的LeNet模型有些不同,除了最後一個連線層dense3使用了softmax啟用外,在其他的層均未使用任何啟用函式
def lenet(input):
    # 卷積層conv1
    conv1 = Conv2D(6, 5, (1, 1), 'valid', use_bias=True)(input)
    # 最大池化層maxpool1
    maxpool1 = MaxPool2D((2, 2), (2, 2), 'valid')(conv1)
    # 卷積層conv2
    conv2 = Conv2D(6, 5, (1, 1), 'valid', use_bias=True)(maxpool1)
    # 最大池化層maxpool2
    maxpool2 = MaxPool2D((2, 2), (2, 2), 'valid')(conv2)
    # 卷積層conv3
    conv3 = Conv2D(16, 5, (1, 1), 'valid', use_bias=True)(maxpool2)
    # 展開
    flatten = Flatten()(conv3)
    # 全連線層dense1
    dense1 = Dense(120, )(flatten)
    # 全連線層dense2
    dense2 = Dense(84, )(dense1)
    # 全連線層dense3
    dense3 = Dense(10, activation='softmax')(dense2)
    return dense3


if __name__ == '__main__':
    # 輸入
    myinput = Input([32, 32, 3])
    # 構建網路
    output = lenet(myinput)
    # 建立模型
    model = Model(myinput, output)

    # 定義優化器,這裡選用Adam優化器,學習率設定為0.0003
    adam = Adam(lr=0.0003)
    # 編譯模型
    model.compile(optimizer=adam, loss="categorical_crossentropy", metrics=['accuracy'])

    # 準備資料
    # 獲取輸入的影象
    X = GetTrainDataByLabel('data')
    # 獲取影象的label,這裡使用to_categorical函式返回one-hot之後的label
    Y = to_categorical(GetTrainDataByLabel('labels'))

    # 開始訓練模型,batch設定為200,一共50個epoch
    model.fit(X, Y, 200, 50, 1, callbacks=[TensorBoard('./LeNet/log', write_images=1, histogram_freq=1)],
              validation_split=0.2, shuffle=True)
    # 儲存模型
    model.save("lenet-no-activation-model.h5")

三、程式執行
程式執行結果如下:

Train on 40000 samples, validate on 10000 samples
Epoch 1/50
40000/40000 [==============================] - 50s - loss: 5.0698 - acc: 0.2403 - val_loss: 1.9617 - val_acc: 0.2933
Epoch 2/50
40000/40000 [==============================] - 52s - loss: 1.9121 - acc: 0.3128 - val_loss: 1.8893 - val_acc: 0.3303
Epoch 3/50
40000/40000 [==============================] - 50s - loss: 1.8527 - acc: 0.3337 - val_loss: 1.8352 - val_acc: 0.3427
Epoch 4/50
40000/40000 [==============================] - 53s - loss: 1.7988 - acc: 0.3555 - val_loss: 1.8037 - val_acc: 0.3538
Epoch 5/50
40000/40000 [==============================] - 57s - loss: 1.7536 - acc: 0.3703 - val_loss: 1.7576 - val_acc: 0.3786
Epoch 6/50
40000/40000 [==============================] - 58s - loss: 1.7092 - acc: 0.3869 - val_loss: 1.7064 - val_acc: 0.3938
Epoch 7/50
40000/40000 [==============================] - 58s - loss: 1.6704 - acc: 0.4009 - val_loss: 1.6921 - val_acc: 0.4041
Epoch 8/50
40000/40000 [==============================] - 58s - loss: 1.6430 - acc: 0.4096 - val_loss: 1.6492 - val_acc: 0.4084
Epoch 9/50
40000/40000 [==============================] - 59s - loss: 1.6110 - acc: 0.4200 - val_loss: 1.6368 - val_acc: 0.4123
Epoch 10/50
40000/40000 [==============================] - 59s - loss: 1.5819 - acc: 0.4347 - val_loss: 1.6017 - val_acc: 0.4279
Epoch 11/50
40000/40000 [==============================] - 58s - loss: 1.5544 - acc: 0.4460 - val_loss: 1.5763 - val_acc: 0.4399
Epoch 12/50
40000/40000 [==============================] - 59s - loss: 1.5336 - acc: 0.4516 - val_loss: 1.5574 - val_acc: 0.4531
Epoch 13/50
40000/40000 [==============================] - 58s - loss: 1.5191 - acc: 0.4582 - val_loss: 1.5664 - val_acc: 0.4397
Epoch 14/50
40000/40000 [==============================] - 58s - loss: 1.5061 - acc: 0.4629 - val_loss: 1.5430 - val_acc: 0.4527
Epoch 15/50
40000/40000 [==============================] - 58s - loss: 1.4881 - acc: 0.4736 - val_loss: 1.5108 - val_acc: 0.4761
Epoch 16/50
40000/40000 [==============================] - 58s - loss: 1.4710 - acc: 0.4826 - val_loss: 1.5264 - val_acc: 0.4654
Epoch 17/50
40000/40000 [==============================] - 58s - loss: 1.4623 - acc: 0.4808 - val_loss: 1.4949 - val_acc: 0.4735
Epoch 18/50
40000/40000 [==============================] - 58s - loss: 1.4508 - acc: 0.4870 - val_loss: 1.4993 - val_acc: 0.4742
Epoch 19/50
40000/40000 [==============================] - 58s - loss: 1.4353 - acc: 0.4939 - val_loss: 1.4758 - val_acc: 0.4857
Epoch 20/50
40000/40000 [==============================] - 58s - loss: 1.4252 - acc: 0.4981 - val_loss: 1.4725 - val_acc: 0.4853
Epoch 21/50
40000/40000 [==============================] - 58s - loss: 1.4169 - acc: 0.4993 - val_loss: 1.4519 - val_acc: 0.4919
Epoch 22/50
40000/40000 [==============================] - 58s - loss: 1.4182 - acc: 0.4997 - val_loss: 1.4362 - val_acc: 0.4996
Epoch 23/50
40000/40000 [==============================] - 59s - loss: 1.4033 - acc: 0.5061 - val_loss: 1.4364 - val_acc: 0.4987
Epoch 24/50
40000/40000 [==============================] - 61s - loss: 1.4015 - acc: 0.5076 - val_loss: 1.4303 - val_acc: 0.5013
Epoch 25/50
40000/40000 [==============================] - 61s - loss: 1.3950 - acc: 0.5079 - val_loss: 1.4382 - val_acc: 0.4997
Epoch 26/50
40000/40000 [==============================] - 58s - loss: 1.3874 - acc: 0.5096 - val_loss: 1.4255 - val_acc: 0.5002
Epoch 27/50
40000/40000 [==============================] - 59s - loss: 1.3830 - acc: 0.5139 - val_loss: 1.4426 - val_acc: 0.4969
Epoch 28/50
40000/40000 [==============================] - 59s - loss: 1.3807 - acc: 0.5147 - val_loss: 1.4312 - val_acc: 0.4994
Epoch 29/50
40000/40000 [==============================] - 62s - loss: 1.3766 - acc: 0.5155 - val_loss: 1.4146 - val_acc: 0.5094
Epoch 30/50
40000/40000 [==============================] - 60s - loss: 1.3649 - acc: 0.5209 - val_loss: 1.4093 - val_acc: 0.5063
Epoch 31/50
40000/40000 [==============================] - 63s - loss: 1.3646 - acc: 0.5207 - val_loss: 1.4117 - val_acc: 0.5067
Epoch 32/50
40000/40000 [==============================] - 63s - loss: 1.3644 - acc: 0.5182 - val_loss: 1.4104 - val_acc: 0.5048
Epoch 33/50
40000/40000 [==============================] - 62s - loss: 1.3544 - acc: 0.5250 - val_loss: 1.3976 - val_acc: 0.5073
Epoch 34/50
40000/40000 [==============================] - 64s - loss: 1.3509 - acc: 0.5276 - val_loss: 1.3896 - val_acc: 0.5173
Epoch 35/50
40000/40000 [==============================] - 60s - loss: 1.3533 - acc: 0.5231 - val_loss: 1.4325 - val_acc: 0.4945
Epoch 36/50
40000/40000 [==============================] - 63s - loss: 1.3461 - acc: 0.5269 - val_loss: 1.3903 - val_acc: 0.5200
Epoch 37/50
40000/40000 [==============================] - 60s - loss: 1.3377 - acc: 0.5300 - val_loss: 1.3968 - val_acc: 0.5131
Epoch 38/50
40000/40000 [==============================] - 59s - loss: 1.3381 - acc: 0.5302 - val_loss: 1.3849 - val_acc: 0.5160
Epoch 39/50
40000/40000 [==============================] - 59s - loss: 1.3356 - acc: 0.5302 - val_loss: 1.3857 - val_acc: 0.5087
Epoch 40/50
40000/40000 [==============================] - 60s - loss: 1.3366 - acc: 0.5303 - val_loss: 1.3922 - val_acc: 0.5116
Epoch 41/50
40000/40000 [==============================] - 59s - loss: 1.3314 - acc: 0.5315 - val_loss: 1.3912 - val_acc: 0.5116
Epoch 42/50
40000/40000 [==============================] - 59s - loss: 1.3278 - acc: 0.5339 - val_loss: 1.4101 - val_acc: 0.5100
Epoch 43/50
40000/40000 [==============================] - 59s - loss: 1.3251 - acc: 0.5359 - val_loss: 1.3829 - val_acc: 0.5162
Epoch 44/50
40000/40000 [==============================] - 60s - loss: 1.3159 - acc: 0.5391 - val_loss: 1.3689 - val_acc: 0.5189
Epoch 45/50
40000/40000 [==============================] - 60s - loss: 1.3235 - acc: 0.5372 - val_loss: 1.4281 - val_acc: 0.5072
Epoch 46/50
40000/40000 [==============================] - 60s - loss: 1.3163 - acc: 0.5367 - val_loss: 1.3705 - val_acc: 0.5195
Epoch 47/50
40000/40000 [==============================] - 60s - loss: 1.3175 - acc: 0.5363 - val_loss: 1.3690 - val_acc: 0.5140
Epoch 48/50
40000/40000 [==============================] - 60s - loss: 1.3076 - acc: 0.5428 - val_loss: 1.3679 - val_acc: 0.5229
Epoch 49/50
40000/40000 [==============================] - 60s - loss: 1.3141 - acc: 0.5420 - val_loss: 1.3507 - val_acc: 0.5284
Epoch 50/50
40000/40000 [==============================] - 62s - loss: 1.3068 - acc: 0.5423 - val_loss: 1.3581 - val_acc: 0.5271

四、預測結果
預測函式的程式碼如下Pytest.py:

from tensorflow.contrib.keras.api.keras.models import load_model
from cifar_data_load import GetTestDataByLabel
import numpy as np

if __name__ == '__main__':
    # 載入訓練好的模型
    model = load_model("lenet-no-activation-model.h5")
    # 獲取測試集的資料
    X = GetTestDataByLabel('data')
    Y = GetTestDataByLabel('labels')
    # 統計預測正確的圖片的數目
    print(np.sum(np.equal(Y, np.argmax(model.predict(X), 1))))

預測的結果如下:

5264

在測試集的10000張圖片中,預測正確的圖片數目有5264張,正確率為52.64%。

五、總結
52.64%的正確率並不高,因為在網路結構中,未採用任何的優化措施。同時,由於LeNet原本是用於mnist手寫資料集的分類問題,CIFAR-10較mnist資料集更為複雜,因此預測的正確率並不高。接下來的工作可以改進網路的能力,包括測試集的擴增,對網路結構進行優化,學習率的調整。可以發現,繼續增加訓練的epoch並無實際的意義。下一步計劃採用更加優秀的AlexNet對CIFAR-10問題進行求解。

在統計上,也只是簡單統計了預測正確的圖片的數目,其他方面的引數在這裡就未作統計。

相關推薦

Tensorflow深度學習LeNet實現CIFAR-10資料

一、LeNet的簡介 LeNet是一個用來識別手寫數字的最經典的卷積神經網路,是Yann LeCun在1998年設計並提出的。Lenet的網路結構規模較小,但包含了卷積層、池化層、全連線層,他們都構成了現代CNN的基本元件。 LeNet包含輸入層在內共有

Tensorflow深度學習AlexNet的實現CIFAR-10資料

二、工程結構 由於我自己訓練的機器記憶體視訊記憶體不足,不能一次性讀取10000張圖片,因此,在這之前我按照圖片的類別,將每一張圖片都提取了出來,儲存成了jpg格式。與此同時,在儲存圖片的過程中,儲存了一個python的dict結構,鍵為每一張圖片的相對地

Tensorflow深度學習tf.nn.conv1d

一、conv1d   在NLP領域,甚至影象處理的時候,我們可能會用到一維卷積(conv1d)。所謂的一維卷積可以看作是二維卷積(conv2d)的簡化,二維卷積是將一個特徵圖在width和height兩個方向上進行滑窗操作,對應位置進行相乘並求和;而一維卷積則

Swift 學習?和 !詳解

新更新的內容請移步閱讀: Swift語言使用var定義變數,但和別的語言不同,Swift裡不會自動給變數賦初始值, 也就是說變數不會有預設值,所以要求使用變數之前必須要對其初始化 。如果在使用變數之前不進行初始化就會報錯: var stringValue : Stri

Tensorflow深度學習 tf.scatter_nd_update

一、tf.scatter_nd_update    函式定義: tf.scatter_nd_update( ref, indices, updates, use_locking=True, name=None )   

【Java並發編程】並發新特性—阻塞隊列和阻塞棧含代碼

err 退出 link rac gb2312 com void throws pbo 轉載請註明出處:http://blog.csdn.net/ns_code/article/details/17511147 阻塞隊列 阻塞隊列是Java 5並發新特性中的內容

Linux學習-shell編程基礎

用法 htm 如果 重定向 -a 創建 過去 .html 編寫代碼 Shell編程基礎 Shell 是一個用 C 語言編寫的程序,它是用戶使用 Linux 的橋梁。Shell 既是一種命令語言,又是一種程序設計語言。Shell 是指一種應用程序,這個應用程序提供了一個界面,

[TensorFlow深度學習入門]實戰·用雙向BiRNN(LSTM)做手寫數字識別準確率99%+

[TensorFlow深度學習入門]實戰十一·用雙向BiRNN(LSTM)做手寫數字識別準確率99%+ 此博文是我們在完成實戰五·用RNN(LSTM)做手寫數字識別的基礎上使用BiRNN(LSTM)結構,進一步提升模型的準確率,1000steps準確率達到99%。 首先我們先

Maven 學習筆記Maven倉庫(快照版本)

 Maven倉庫(快照版本) ---------- 在Maven的世界中,任何一個專案或者構件都必須有自己的版本。版本的值可能是1.0.0,1.3-alpha-4,2.0,2.1-SNAPSHOT或者2.1-20091214.221414-13。其中,1.0、1.3-a

算法系列實驗資料與曲線擬合

12.1 曲線擬合12.1.1 曲線擬合的定義        曲線擬合(Curve Fitting)的數學定義是指用連續曲線近似地刻畫或比擬平面上一組離散點所表示的座標之間的函式關係,是一種用解析表示式逼近離散資料的方法。曲線擬合通俗的說法就是“拉曲線”,也就是將現有資料透過

《Nodejs開發加密貨幣》交易

題外話:這篇文章,耗費了我大量精力,用UML表達javascript類及流程本來就不是什麼容易的事情,用來描述加密貨幣交易這種驗證邏輯非常多的程式碼更難,加之Nodejs的回撥在這些程式碼裡巢狀很深,所以如何把非同步呼叫變成人類容易理解的順序呼叫,也做了一番取捨

Android實戰技巧Android原型設計工具探索

移動開發者、移動產品經理和互動設計師在有了產品的想法後會做出一系列的草圖,然後反覆推敲改進,直到自己滿意。這個草圖就是原型設計,是產品設計初期很重要的工作,它是產品的雛形,之後會以此為原型進行開發。 當移動網際網路熱度增加後,一些主打移動原型設計的工具如雨後春

scala學習旅()模式匹配

引言 模式匹配是scala 中非常有特色且非常強大的一種功能。模式匹配其實就是類似於java 中的switch case 語法,即對一個值進行判斷然後做出不同的操作。 但是scala 的模式匹配比java要強大很多java 的switch

EF6學習筆記格式化日誌輸出

exec https edi 進行 mman sel 能夠 database container 要專業系統地學習EF推薦《你必須掌握的Entity Framework 6.x與Core 2.0》。這本書作者(汪鵬,Jeffcky)的博客:https://www.cnblo

Java併發程式設計系列CountdownLatch

CountDownLatch是JDK提供的併發工具包,理解並掌握這些工具包的使用有助於簡化特定場景下的程式設計。就CountDownLatch而言,允許一個或者多個執行緒等待其他執行緒完成操作。等待其他執行緒完成不是與Thread.join()方法類似嗎,因為T

Unity編輯器拓展拓展Unity模組,打造私人工具庫

拓展Unity模組,打造私人工具庫(二) 前言: 上一篇,實現了基本Unity模組拓展的功能,本篇將介紹如何通過反射來實現匯入UnityPackage Gif示意圖 程式匯入UnityPackage 通過查閱UnityEditor原始碼發現

設計模式系列狀態模式

1.定義 當一個物件內在狀態改變時允許其改變行為,這個物件看起來像改變了其類。 2.通用類圖 角色介紹 State 抽象狀態角色:介面或抽象類,負責物件狀態定義,並且封裝環境角色以實現狀態切換 ConcreteState 具體狀態角色:

深度學習卷積神經網路程式設計實現

void conv_bprop(Layer *layer, Layer *prev_layer, bool *pconnection) { int index = 0; int size = prev_layer->map_w * prev_layer->map_h; // delta

《Nodejs開發加密貨幣》DPOS機制分散式共識演算法

前言 共識機制是分散式應用軟體特有的演算法機制。在中心化的軟體裡,再複雜的問題都可以避開使用複雜的演算法邏輯(當然,如果能用演算法統領,程式碼會更加簡潔、高效),在開發設計上可以省卻一定的麻煩。但在分散式軟體開發中,節點間的互操作,節點行為的統一管理,沒有演算

AI - 深度學習四章-概念摘要8~14

另一個 基本上 ram sam 稀疏 ESS 自動 vat ras 原文鏈接:https://yq.aliyun.com/topic/111 08 反向傳播(Back Propagation,簡稱BP) 算法 在神經網絡(甚至深度學習)參數訓練中,BP算法占據舉足輕重的地