6.1 torch.nn.Module介紹
????????torch.nn.Module是 PyTorch 中構建神經網絡的基礎類,所有的神經網絡模塊都應該繼承這個類。它提供了一種便捷的方式來組織和管理網絡中的各個組件,包括層、參數等,同時還內置了許多用于模型訓練和推理的功能。
官網:torch.nn — PyTorch 1.8.1 documentation
核心功能:
(1)、網絡構建:通過繼承torch.nn.Module類,我們可以自定義自己的神經網絡結構。在__init__方法中定義網絡的各個層,在forward方法中定義數據的前向傳播過程。
(2)、參數管理:torch.nn.Module會自動跟蹤和管理網絡中的參數(如權重和偏置)。我們可以通過parameters()方法獲取網絡的所有參數,方便進行優化器的配置和參數的更新。
(3)、設備轉換:可以使用to()方法將模型轉移到指定的設備(如 CPU 或 GPU)上,以利用不同設備的計算能力。?
(4)、狀態切換:提供了train()和eval()方法來切換模型的訓練和評估狀態。在訓練狀態下,一些具有隨機性的層(如 Dropout、BatchNorm)會正常工作;在評估狀態下,這些層會采用確定性的行為。
6.2 torch.nn.Module常用方法
????????__init__(self):構造函數,用于初始化網絡的各個層和參數。在自定義網絡時,需要在該方法中調用super().__init__()來初始化父類。?
????????forward(self, x):前向傳播方法,定義了數據在網絡中的流動過程。當對模型進行調用時(如model(x)),實際上是調用了該方法。?
????????parameters(self):返回一個迭代器,包含網絡中的所有可學習參數。?
????????named_parameters(self):返回一個迭代器,包含網絡中參數的名稱和對應的參數值。?
????????to(self, device):將模型轉移到指定的設備上。例如,model.to('cuda')將模型轉移到 GPU 上。?
????????train(self, mode=True):將模型設置為訓練模式。?
????????eval(self):將模型設置為評估模式,相當于train(mode=False)。?
????????save_state_dict(self, path):保存模型的參數狀態字典到指定路徑。?
????????load_state_dict(self, state_dict):從參數狀態字典中加載模型的參數。
6.3 程序演示
6.3.1 官網提供的例子
import torch.nn as nn
import torch.nn.functional as Fclass Model(nn.Module): #搭建的神經網絡 Model繼承了 Module類(父類)def __init__(self): #初始化函數super(Model, self).__init__() #必須要這一步,調用父類的初始化函數self.conv1 = nn.Conv2d(1, 20, 5)self.conv2 = nn.Conv2d(20, 20, 5)def forward(self, x): #前向傳播(為輸入和輸出中間的處理過程),x為輸入x = F.relu(self.conv1(x)) #conv為卷積,relu為非線性處理return F.relu(self.conv2(x))
注意:前向傳播 forward(在所有子類中進行重寫)
6.3.2 自定義Model
import torch
from torch import nn# 定義一個自定義模型類Custom_Model,繼承自nn.Module
# 所有的神經網絡模型都應該繼承nn.Module,以利用其提供的參數管理、設備轉換等功能
class Custom_Model(nn.Module):# 構造函數,用于初始化模型的層和參數def __init__(self):# 調用父類nn.Module的構造函數,確保模型能夠正確初始化super().__init__()# 前向傳播方法,定義數據在模型中的流動和計算過程# 當對模型實例傳入輸入數據時,會自動調用該方法def forward(self, input):# 定義模型的計算邏輯:輸入數據加1output = input + 1# 返回計算結果return outputCustom_Model = Custom_Model()
# 創建一個張量x,值為1.0,作為模型的輸入數據
x = torch.tensor(1.0)
# 將輸入數據x傳入模型,模型會自動調用forward方法進行計算,得到輸出結果
output = Custom_Model(x)
# 打印輸出結果,此時輸出應為2.0(1.0 + 1)
print(output)
6.4?torch.nn.functional.conv2d介紹
????????torch.nn.functional.conv2d是 PyTorch 中用于執行二維卷積操作的函數,在卷積神經網絡(CNN)中扮演著至關重要的角色,用于提取圖像等二維數據的特征。以下是對它的詳細介紹:
參數說明:
- input?(Tensor):輸入張量,形狀為(N, C_in, H_in, W_in)。其中,N是批量大小(batch size),表示一次處理的樣本數量;C_in是輸入通道數,例如對于灰度圖像C_in=1,對于彩色圖像(RGB 格式)C_in=3;H_in和W_in分別是輸入特征圖的高度和寬度。
- weight?(Tensor):卷積核(過濾器)張量,形狀為(C_out, C_in, H_k, W_k)?。C_out是輸出通道數,決定了經過卷積操作后生成的特征圖數量;C_in必須與輸入張量的通道數一致;H_k和W_k分別是卷積核的高度和寬度。
- bias?(Tensor,可選):偏置張量,形狀為(C_out)?,為每個輸出通道添加一個可學習的偏置值,默認值為None。
- stride?(int或tuple,默認值:1?):卷積核在輸入特征圖上滑動的步長。如果是一個整數,表示在高度和寬度方向上的步長相同;如果是一個元組(stride_h, stride_w),則分別指定高度和寬度方向上的步長。
- padding?(int或tuple,默認值:0?):在輸入特征圖的邊緣添加填充(padding)像素。同樣,整數表示在高度和寬度方向上添加相同數量的填充;元組(padding_h, padding_w)分別指定高度和寬度方向上的填充數量。填充可以用來控制輸出特征圖的大小,使其與輸入大小相同或滿足特定的尺寸要求。
- dilation?(int或tuple,默認值:1?):卷積核元素之間的間距。dilation=1表示正常的卷積核;dilation=2時,卷積核元素之間會間隔一個位置,相當于擴大了卷積核的感受野。
- groups?(int,默認值:1?):分組卷積的組數。當groups=1時,就是普通的卷積操作;當groups > 1時,輸入通道會被分成groups組,卷積核也會相應分組,每組卷積核只與對應的一組輸入通道進行卷積操作,常用于減少計算量或實現特定的網絡結構,比如 AlexNet 中的分組卷積。
應用場景:
????????torch.nn.functional.conv2d廣泛應用于各類基于卷積神經網絡的任務,如:
- 圖像分類:從輸入圖像中提取各種層次的特征,用于判斷圖像所屬的類別。
- 目標檢測:提取圖像特征來定位和識別目標物體。
- 語義分割:對圖像中的每個像素進行分類,以實現對圖像內容的精細分割。
????????總的來說,torch.nn.functional.conv2d是構建深度學習視覺模型的基礎組件之一,通過合理設置其參數,可以靈活地調整卷積操作,以適應不同的任務需求。
6.4.1 卷積操作原理
6.4.2 實戰演示
import torch
import torch.nn.functional as F
# 將二維矩陣轉化為tensor數據類型
input = torch.tensor([[1, 2, 0, 3, 1],[0, 1, 2, 3, 1],[1, 2, 1, 0, 0],[5, 2, 3, 1, 1],[2, 1, 0, 1, 1]])
# 卷積核
kernel = torch.tensor([[1, 2, 1],[0, 1, 0],[2, 1, 0]])
# 尺寸只有高寬,不符合要求
print(input.shape) # 5*5
print(kernel.shape) # 3*#
input = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))
print(input.shape)
print(kernel.shape)output = F.conv2d(input, kernel, stride=1)
print(output)
運行結果:
參數修改:
(1)、將stride修改
????????stride?(int或tuple,默認值:1?):卷積核在輸入特征圖上滑動的步長。如果是一個整數,表示在高度和寬度方向上的步長相同;如果是一個元組(stride_h, stride_w),則分別指定高度和寬度方向上的步長。
????????????????output = F.conv2d(input, kernel, stride=2)
(2)、修改Padding
????????padding?(int或tuple,默認值:0?):在輸入特征圖的邊緣添加填充(padding)像素。同樣,整數表示在高度和寬度方向上添加相同數量的填充;元組(padding_h, padding_w)分別指定高度和寬度方向上的填充數量。填充可以用來控制輸出特征圖的大小,使其與輸入大小相同或滿足特定的尺寸要求。
????????padding=1:將輸入圖像左右上下兩邊都拓展一個像素,空的地方默認為0
????????????????????????output = F.conv2d(input, kernel, stride=1, padding=1)
運行結果: