自學機器學習,從入門到精通
- 導論
- 機器學習的基本框架設計目標
- 機器學習框架基本組成原理
- 機器學習生態
- 機器學習工作流
- 環境配置
- 數據處理
- 模型定義
- 損失函數和優化器
- 訓練及保存模型
- 測試及驗證模型
- 定義深度神經網絡
- 以層為核心定義神經網絡
- 神經網絡層實現原理
- 自定義神經網絡層
- 時間有限,有需要的同學可以看下面博主的博客鏈接,介紹的更為詳細。
導論
本章主要講解機器學習的應用背景以及基本的介紹。
機器學習的基本框架設計目標
機器學習框架如雨后春筍般出現(較為知名的例子包括TensorFlow、PyTorch、MindSpore、MXNet、PaddlePaddle、OneFlow、CNTK等)
神經網絡編程:。根據應用的需求,人們需要定制不同的神經網絡,如卷積神經網絡(Convolutional Neural Networks)和自注意力神經網絡(Self-Attention Neural Networks)等。這些神經網絡需要一個共同的系統軟件進行開發、訓練和部署。
自動微分: 訓練神經網絡會具有模型參數。這些參數需要通過持續計算梯度(Gradients)迭代改進。梯度的計算往往需要結合訓練數據、數據標注和損失函數(Loss Function)。考慮到大多數開發人員并不具備手工計算梯度的知識,機器學習框架需要根據開發人員給出的神經網絡程序,全自動地計算梯度。這一過程被稱之為自動微分。
數據管理和處理: 機器學習的核心是數據。這些數據包括訓練、驗證、測試數據集和模型參數。因此,需要系統本身支持數據讀取、存儲和預處理(例如數據增強和數據清洗)。
模型訓練和部署: 為了讓機器學習模型達到最佳的性能,需要使用優化方法來通過多步迭代反復計算梯度,這一過程稱之為訓練。訓練完成后,需要將訓練好的模型部署到推理設備。
硬件加速器: 神經網絡的相關計算往往通過矩陣計算實現。這一類計算可以被硬件加速器(例如,通用圖形處理器-GPU)加速
分布式執行: 隨著訓練數據量和神經網絡參數量的上升,機器學習系統的內存用量遠遠超過了單個機器可以提供的內存。因此,機器學習框架需要天然具備分布式執行的能力。
機器學習框架基本組成原理
編程接口: *機器學習框架首先需要提供以高層次編程語言(如Python)為主的編程接口。同時,機器學習框架為了優化運行性能,需要支持以低層次編程語言(如C和C++)為主的系統實現,從而實現操作系統(如線程管理和網絡通訊等)和各類型硬件加速器的高效使用。
計算圖: 利用不同編程接口實現的機器學習程序需要共享一個運行后端。實現這一后端的關鍵技術是計算圖技術。計算圖定義了用戶的機器學習程序,其包含大量表達計算操作的算子節點(Operator Node),以及表達算子之間計算依賴的邊(Edge)。
編譯器前端: 機器學習框架往往具有AI編譯器來構建計算圖,并將計算圖轉換為硬件可以執行的程序。這個編譯器首先會利用一系列編譯器前端技術實現對程序的分析和優化。編譯器前端的關鍵功能包括實現中間表示、自動微分、類型推導和靜態分析等。
編譯器后端和運行時: 完成計算圖的分析和優化后,機器學習框架進一步利用編譯器后端和運行時實現針對不同底層硬件的優化。常見的優化技術包括分析硬件的L2/L3緩存大小和指令流水線長度,優化算子的選擇或者調度順序。
異構處理器: 機器學習應用的執行由中央處理器(Central Processing Unit,CPU)和硬件加速器(如英偉達GPU、華為Ascend和谷歌TPU)共同完成。其中,非矩陣操作(如復雜的數據預處理和計算圖的調度執行)由中央處理器完成。矩陣操作和部分頻繁使用的機器學習算子(如Transformer算子和Convolution算子)由硬件加速器完成。
數據處理: 機器學習應用需要對原始數據進行復雜預處理,同時也需要管理大量的訓練數據集、驗證數據集和測試數據集。這一系列以數據為核心的操作由數據處理模塊(例如TensorFlow的tf.data和PyTorch的DataLoader)完成。
模型部署: 在完成模型訓練后,機器學習框架下一個需要支持的關鍵功能是模型部署。為了確保模型可以在內存有限的硬件上執行,會使用模型轉換、量化、蒸餾等模型壓縮技術。同時,也需要實現針對推理硬件平臺(例如英偉達Orin)的模型算子優化。最后,為了保證模型的安全(如拒絕未經授權的用戶讀取),還會對模型進行混淆設計。
分布式訓練: 機器學習模型的訓練往往需要分布式的計算節點并行完成。其中,常見的并行訓練方法包括數據并行、模型并行、混合并行和流水線并行。這些并行訓練方法通常由遠端程序調用(Remote Procedure Call, RPC)、集合通信(Collective Communication)或者參數服務器(Parameter Server)實現。
機器學習生態
聯邦學習: 隨著用戶隱私保護和數據保護法的出現,許多機器學習應用無法直接接觸用戶數據完成模型訓練。因此這一類應用需要通過機器學習框架實現聯邦學習(Federated Learning)。
推薦系統: 相比于傳統基于規則的推薦系統,深度學習推薦系統能夠有效分析用戶的海量特征數據,從而實現在推薦準確度和推薦時效性上的巨大提升。
強化學習: 強化學習具有數據收集和模型訓練方法的特殊性。因此,需要基于機器學習框架進一步開發專用的強化學習系統。
可解釋AI: 隨著機器學習在金融、醫療和政府治理等關鍵領域的推廣,基于機器學習框架進一步開發的可解釋性AI系統正得到日益增長的重視。
機器人: 機器人是另一個開始廣泛使用機器學習框架的領域。相比于傳統的機器人視覺方法,機器學習方法在特征自動提取、目標識別、路徑規劃等多個機器人任務中獲得了巨大成功。
圖學習: 圖(Graph)是最廣泛使用的數據結構之一。許多互聯網數據(如社交網絡、產品關系圖)都由圖來表達。機器學習算法已經被證明是行之有效的分析大型圖數據的方法。這種針對圖數據的機器學習系統被稱之為圖學習系統(Graph Learning System)。
機器學習集群調度: 機器學習集群一般由異構處理器、異構網絡甚至異構存儲設備構成。同時,機器學習集群中的計算任務往往具有共同的執行特點(如基于集合通信算子AllReduce迭代進行)。因此,針對異構設備和任務特點,機器學習集群往往具有特定的調度方法設計。
量子計算: 量子計算機一般通過混合架構實現。其中,量子計算由量子計算機完成,而量子仿真由傳統計算機完成。由于量子仿真往往涉及到大量矩陣計算,許多量子仿真系統(如TensorFlow Quantum和MindQuantum)都基于機器學習框架實現。
機器學習工作流
數據處理: 用戶需要數據處理API來支持將數據集從磁盤讀入。進一步,用戶需要對讀取的數據進行預處理,從而可以將數據輸入后續的機器學習模型中。
模型定義: 完成數據的預處理后,用戶需要模型定義API來定義機器學習模型。這些模型帶有模型參數,可以對給定的數據進行推理。
優化器定義: 模型的輸出需要和用戶的標記進行對比,這個對比差異一般通過損失函數(Loss function)來進行評估。因此,優化器定義API允許用戶定義自己的損失函數,并且根據損失來引入(Import)和定義各種優化算法(Optimisation algorithms)來計算梯度(Gradient),完成對模型參數的更新。
訓練: 給定一個數據集,模型,損失函數和優化器,用戶需要訓練API來定義一個循環(Loop)從而將數據集中的數據按照小批量(mini-batch)的方式讀取出來,反復計算梯度來更新模型。這個反復的過程稱為訓練。
測試和調試: 訓練過程中,用戶需要測試API來對當前模型的精度進行評估。當精度達到目標后,訓練結束。這一過程中,用戶往往需要調試API來完成對模型的性能和正確性進行驗證。
環境配置
一般環境的配置需要各個版本相匹配,個人通常按照下面的流程進行環境的配置。
第一步:下載Anconda,可以在CSDN上找到相關的文章,一步步跟著配置即可,最重要的是在自己的電腦上配置好環境變量。此軟件可以配置多個環境變量,為以后的工作開展會更加便利。
第二步:IDE工具一般用的是Pycahrm,Vscode也是可以的。個人認為Pycahrm2022的版本是最好用的。
第三步:如果用的是開源的代碼,一般會給出項目的依賴環境庫,可以直接使用pip命令行進行安裝。
數據處理
API提供了大量Python函數支持用戶用一行命令即可讀入常見的訓練數據集(如MNIST,CIFAR,COCO等)。 在加載之前需要將下載的數據集存放在./datasets/MNIST_Data路徑中;
tf或者pytorch均提供了用于數據處理的API模塊dataset,用于存儲樣本和標簽。
在加載數據集前,通常會對數據集進行一些處理dataset也集成了常見的數據處理方法。 以下代碼讀取了MNIST的數據是大小為28x28的圖片,返回DataSet對象。
import tensorflow as tf
# 設置數據集路徑
DATA_DIR = './datasets/MNIST_Data/train'
mnist_dataset = tf.data.Dataset.list_files(DATA_DIR + "/*/*.png", shuffle=False)
有了DataSet對象后,通常需要對數據進行增強,常用的數據增強包括翻轉、旋轉、剪裁、縮放等;在tf中是使用map將數據增強的操作映射到數據集中的,之后進行打亂(Shuffle)和批處理(Batch)。
import tensorflow as tf# 數據處理過程
def create_dataset(data_path, batch_size=32, repeat_size=1, num_parallel_workers=1):# 加載 MNIST 數據集# TensorFlow 提供了內置的 MNIST 數據集加載方法(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()# 選擇訓練集或測試集images = train_images if "train" in data_path else test_imageslabels = train_labels if "train" in data_path else test_labels# 將數據轉換為 TensorFlow 數據集mnist_ds = tf.data.Dataset.from_tensor_slices((images, labels))# 定義數據預處理函數def preprocess(image, label):# 調整圖像大小image = tf.image.resize(image[..., tf.newaxis], (32, 32)) # 添加通道維度并調整大小# 歸一化圖像image = tf.cast(image, tf.float32) / 255.0# 標準化圖像(使用與 MindSpore 示例相同的均值和標準差)mean = 0.1307std = 0.3081image = (image - mean) / std# 轉換標簽為 int32label = tf.cast(label, tf.int32)return image, label# 應用預處理函數mnist_ds = mnist_ds.map(preprocess, num_parallel_calls=num_parallel_workers)# 打亂數據buffer_size = 10000mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size)# 重復數據集mnist_ds = mnist_ds.repeat(repeat_size)# 批量處理mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True)return mnist_ds
# 示例用法
data_path = './datasets/MNIST_Data/train' # 示例路徑,實際路徑可能不同
batch_size = 32
repeat_size = 1
num_parallel_workers = tf.data.AUTOTUNE # 使用自動調整線程數# 創建數據集
mnist_dataset = create_dataset(data_path, batch_size, repeat_size, num_parallel_workers)# 查看數據集
for images, labels in mnist_dataset.take(1):print("Images shape:", images.shape)print("Labels shape:", labels.shape)
模型定義
在 TensorFlow 中,定義神經網絡通常使用 tf.keras.Model 或 tf.keras.Sequential。以下是一個基于 TensorFlow 的實現,等效于你描述的 MindSpore 神經網絡結構。這個網絡包含一個輸入層、一個 Flatten 層將輸入數據壓平為一維向量,然后是三個全連接層,最后輸出層有 10 個神經元,對應于 MNIST 數據集中的 10 個類別。
import tensorflow as tf
from tensorflow.keras import layers, models
# 定義神經網絡模型
class MyModel(tf.keras.Model):def __init__(self):super(MyModel, self).__init__()# 定義網絡層self.flatten = layers.Flatten(input_shape=(28, 28)) # 將輸入圖像壓平為一維向量self.fc1 = layers.Dense(128, activation='relu') # 第一個全連接層,128個神經元self.fc2 = layers.Dense(64, activation='relu') # 第二個全連接層,64個神經元self.fc3 = layers.Dense(10, activation='softmax') # 輸出層,10個神經元,對應10個類別def call(self, inputs):# 定義前向傳播過程x = self.flatten(inputs)x = self.fc1(x)x = self.fc2(x)x = self.fc3(x)return x
損失函數和優化器
有了神經網絡組件構建的模型我們還需要定義損失函數來計算訓練過程中輸出和真實值的誤差。
均方誤差(Mean Squared Error,MSE)是線性回歸中常用的,是計算估算值與真實值差值的平方和的平均數。
平均絕對誤差(Mean Absolute Error,MAE)是計算估算值與真實值差值的絕對值求和再求平均。
交叉熵(Cross Entropy,CE)是分類問題中常用的,衡量已知數據分布情況下,計算輸出分布和已知分布的差值。
上面3個就是常用的損失函數。
有了損失函數,我們就可以通過損失值利用優化器對參數進行訓練更新。神經網絡的優化器種類很多,一類是學習率不受梯度影響的隨機梯度下降(Stochastic Gradient Descent)及SGD的一些改進方法,如帶有Momentum的SGD;另一類是自適應學習率如AdaGrad、RMSProp、Adam等。
SGD的更新是對每個樣本進行梯度下降,因此計算速度很快,但是單樣本更新頻繁,會造成震蕩;為了解決震蕩問題,提出了帶有Momentum的SGD,該方法的參數更新不僅僅由梯度決定,也和累計的梯度下降方向有關,使得增加更新梯度下降方向不變的維度,減少更新梯度下降方向改變的維度,從而速度更快也減少震蕩。
自適應學習率AdaGrad是通過以往的梯度自適應更新學習率,不同的參數Wi具有不同的學習率。AdaGrad對頻繁變化的參數以更小的步長更新,而稀疏的參數以更大的步長更新。因此對稀疏的數據表現比較好。
Adadelta是對AdaGrad的改進,解決了AdaGrad優化過程中學習率a單調減少問題;Adadelta不對過去的梯度平方進行累加,用指數平均的方法計算二階動量,避免了二階動量持續累積,導致訓練提前結束。
Adam可以理解為Adadelta和Momentum的結合,對一階二階動量均采用指數平均的方法計算。
# 創建模型實例
model = MyModel()
# 打印模型結構
model.summary()
# 編譯模型
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
訓練及保存模型
# 示例:加載 MNIST 數據集并訓練模型
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()
train_images = train_images.reshape((60000, 28, 28)).astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28)).astype('float32') / 255
# 訓練模型
model.fit(train_images, train_labels, epochs=5, batch_size=32)
# 保存模型
model.save('my_mnist_model.h5')
print("模型已保存到 'my_mnist_model.h5'")
# 加載模型
loaded_model = tf.keras.models.load_model('my_mnist_model.h5')
print("模型已加載")
# 評估模型
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(f"Test accuracy: {test_acc}")
測試及驗證模型
測試是將測試數據集輸入到模型,運行得到輸出的過程。通常在訓練過程中,每訓練一定的數據量后就會測試一次,以驗證模型的泛化能力。
在訓練完畢后,參數保存在checkpoint中,可以將訓練好的參數加載到模型中進行驗證。
# 定義測試函數
def test_net(model, data_path):"""定義驗證的方法"""ds_eval = create_dataset(os.path.join(data_path, "test"), is_train=False)loss, accuracy = model.evaluate(ds_eval)print(f"Test accuracy: {accuracy:.4f}")# 定義加載模型并進行預測的函數
def predict_with_model(model_path, data_path):# 加載模型model = tf.keras.models.load_model(model_path)# 創建測試數據集,batch_size設置為1,則取出一張圖片ds_test = create_dataset(os.path.join(data_path, "test"), batch_size=1, is_train=False)data = next(iter(ds_test))# 獲取測試圖片和實際分類images, labels = dataimages = images.numpy()labels = labels.numpy()# 使用模型進行預測output = model.predict(images)predicted = np.argmax(output, axis=1)# 輸出預測分類與實際分類print(f'Predicted: "{predicted[0]}", Actual: "{labels[0]}"')# 主函數
if __name__ == "__main__":# 定義數據路徑mnist_path = "./datasets/MNIST_Data"# 創建模型并編譯model = create_model()model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])# 創建訓練數據集ds_train = create_dataset(os.path.join(mnist_path, "train"), is_train=True)# 訓練模型model.fit(ds_train, epochs=5)# 保存模型model.save('my_mnist_model.h5')print("模型已保存到 'my_mnist_model.h5'")# 驗證模型精度test_net(model, mnist_path)# 加載模型并進行預測predict_with_model('my_mnist_model.h5', mnist_path)
定義深度神經網絡
隨著深度神經網絡的飛速發展,各種深度神經網絡結構層出不窮,但是不管結構如何復雜,神經網絡層數量如何增加,構建深度神經網絡結構始終遵循最基本的元素:
- 1.承載計算的節點;
- +2.可變化的節點權重(節點權重可訓練);
- 3.允許數據流動的節點連接。
因此在機器學習編程庫中深度神經網絡是以層為核心,它提供了各類深度神經網絡層基本組件;
將神經網絡層組件按照網絡結構進行堆疊、連接就能構造出神經網絡模型。
以層為核心定義神經網絡
神經網絡層包含構建機器學習網絡結構的基本組件,如計算機視覺領域常用到卷積(Convolution)、池化(Pooling)、全連接(Fully Connected);
自然語言處理常用到循環神經網絡(Recurrent Neural Network,RNN);為了加速訓練,防止過擬合通常用到批標準化(BatchNorm)、Dropout等。
全連接是將當前層每個節點都和上一層節點一一連接,本質上是特征空間的線性變換;可以將數據從高維映射到低維,也能從低維映射到高維度。 如下圖所示了全連接的過程,對輸入的n個數據變換到大小為m的特征空間,再從大小為m的特征空間變換到大小為p的特征空間;
可見全連接層的參數量巨大,兩次變換所需的參數大小為nxm和mxp。
卷積操作是卷積神經網絡中常用的操作之一,卷積相當于對輸入進行滑動濾波。根據卷積核(Kernel)、卷積步長(Stride)、填充(Padding)對輸入數據從左到右,從上到下進行滑動,每一次滑動操作是矩陣的乘加運算得到的加權值。 如下圖所示的卷積操作主要由輸入、卷積核、輸出組成輸出又被稱為特征圖(Feature Map)。
卷積的具體運算過程我們通過下圖進行演示。該圖輸入為4x4的矩陣,卷積核大小為3x3,卷積步長為1,不填充,最終得到的2x2的輸出矩陣。 計算過程為將3x3的卷積核作用到左上角3x3大小的輸入圖上;輸出為(1 \times 1 + 2 \times 0 + 2 \times 1 + 3 \times 0 + 2 \times 1 + 3 \times 0 + 4 \times 1 + 1 \times 0 + 3 \times 1 = 12), 同理對卷積核移動1個步長再次執行相同的計算步驟得到第二個輸出為11;當再次移動將出界時結束從左往右,執行從上往下移動1步,再進行從左往右移動;依次操作直到從上往下再移動也出界時,結束整個卷積過程,得到輸出結果。
我們不難發現相比于全連接,卷積的優勢是參數共享(同一個卷積核遍歷整個輸入圖)和參數量小(卷積核大小即是參數量)。
在卷積過程中,如果我們需要對輸出矩陣大小進行控制,那么就需要對步長和填充進行設置。還是上面的輸入圖,如需要得到和輸入矩陣大小一樣的輸出矩陣,步長為1時就需要對上下左右均填充一圈全為0的數。
在上述例子中我們介紹了一個輸入一個卷積核的卷積操作。通常情況下我們輸入的是彩色圖片,有三個輸入,這三個輸入稱為通道(Channel),分別代表紅、綠、藍(RGB)。
此時我們執行卷積則為多通道卷積,需要三個卷積核分別對RGB三個通道進行上述卷積過程,之后將結果加起來。 具體如上圖描述了一個輸入通道為3,輸出通道為1,卷積核大小為3x3,卷積步長為1的多通道卷積過程;需要注意的是,每個通道都有各自的卷積核,同一個通道的卷積核參數共享。如果輸出通道為out_c,輸入通道為in_c,那么需要outc?×inc個卷積核。
池化是常見的降維操作,有最大池化和平均池化。池化操作和卷積的執行類似,通過池化核、步長、填充決定輸出;最大池化是在池化核區域范圍內取最大值,平均池化則是在池化核范圍內做平均。與卷積不同的是池化核沒有訓練參數;
池化層的填充方式也有所不同,平均池化填充的是0,最大池化填充的是(-inf)。 如下圖是對4x4的輸入進行2x2區域池化,步長為2,不填充;圖左邊是最大池化的結果,右邊是平均池化的結果。
有了卷積、池化、全連接組件就可以構建一個非常簡單的卷積神經網絡了, 如下圖展示了一個卷積神經網絡的模型結構。 給定輸入3x64x64的彩色圖片,使用16個3x3x3大小的卷積核做卷積,得到大小為16x64x64的特征圖; 再進行池化操作降維,得到大小為16x32x32的特征圖; 對特征圖再卷積得到大小為32x32x32特征圖,再進行池化操作得到32x16x16大小的特征圖; 我們需要對特征圖做全連接,此時需要把特征圖平鋪成一維向量這步操作稱為Flatten,壓平后輸入特征大小為32x16x16=8192; 之后做一次全連接對大小為8192特征變換到大小為128的特征,再依次做兩次全連接分別得到64,10。 這里最后的輸出結果是依據自己的實際問題而定,假設我們的輸入是包含0到9的數字圖片,做分類那輸出對應是10個概率值,分別對應0到9的概率大小。
在卷積神經網絡的計算過程中,前后的輸入是沒有聯系的,然而在很多任務中往往需要處理序列信息,如語句、語音、視頻等,為了解決此類問題誕生出循環神經網絡(Recurrent Neural Network,RNN);
循環神經網絡很好的解決了序列數據的問題,但是隨著序列的增加,長序列又導致了訓練過程中梯度消失和梯度爆炸的問題,因此有了長短期記憶(Long Short-term Memory,LSTM);
在語言任務中還有Seq2Seq它將RNN當成編解碼(Encoder-Decoder)結構的編碼器(Encoder)和解碼器(Decode); 在解碼器中又常常使用注意力機制(Attention);基于編解碼器和注意力機制又有Transformer; Transformer又是BERT模型架構的重要組成。
神經網絡層實現原理
如下圖所示描述了神經網絡構建過程中的基本細節。
基類需要初始化訓練參數、管理參數狀態以及定義計算過程;神經網絡模型需要實現對神經網絡層和神經網絡層參數管理的功能。在機器學習編程庫中,承擔此功能有MindSpore的Cell、PyTorch的Module。Cell和Module是模型抽象方法也是所有網絡的基類。
現有模型抽象方案有兩種,一種是抽象出兩個方法分別為Layer(負責單個神經網絡層的參數構建和前向計算),Model(負責對神經網絡層進行連接組合和神經網絡層參數管理);另一種是將Layer和Model抽象成一個方法,該方法既能表示單層神經網絡層也能表示包含多個神經網絡層堆疊的模型,Cell和Module就是這樣實現的。
自定義神經網絡層
假設已經有了神經網絡模型抽象方法Cell,構建Conv2D將繼承Cell,并重構__init__和__call__方法,在__init__里初始化訓練參數和輸入參數,在__call__里調用低級API實現計算邏輯。
# 接口定義:
卷積層的接口:convolution(input, filters, stride, padding)
變量:Variable(value, trainable=True)
高斯分布初始化方法:random_normal(shape)
神經網絡模型抽象方法:Cell# 定義卷積層
class Conv2D(Cell):def __init__(self, in_channels, out_channels, ksize, stride, padding):# 卷積核大小為 ksize x ksize x inchannels x out_channelsfilters_shape = (out_channels, in_channels, ksize, ksize)self.stride = strideself.padding = paddingself.filters = Variable(random_normal(filters_shape))def __call__(self, inputs):outputs = convolution(inputs, self.filters, self.stride, self.padding)
有了上述定義在使用卷積層時,就不需要創建訓練變量了。 如我們需要對30x30大小10個通道的輸入使用3x3的卷積核做卷積,卷積后輸出通道為20。 調用方式如下:
conv = Conv2D(in_channel=10, out_channel=20, filter_size=3, stride=2, padding=0)
output = conv(input)
在執行過程中,初始化Conv2D時,__setattr__會判斷屬性,屬于Cell把神經網絡層Conv2D記錄到self._cells,屬于parameter的filters記錄到self._params。
查看神經網絡層參數使用conv.parameters_and_names;查看神經網絡層列表使用conv.cells_and_names;執行操作使用conv(input)。
時間有限,有需要的同學可以看下面博主的博客鏈接,介紹的更為詳細。
https://www.cnblogs.com/nickchen121/p/11686958.html#tid-bhXdce