pytorch
pytorch基礎
Tensor(張量)
pytorch中最基本的操作物件,表示的是一個多維的矩陣
pytorch可以在GPU上執行,numpy的ndarry只能在CPU上執行
Tensor資料型別:
32位浮點型: torch.FloatTensor
64位浮點型:torch.DoubleTensor
16位整形:torch.ShoutTensor
32位整形:torch.IntTensor
64位整形:torch.LongTensor
定義一個三行兩列矩陣:
a = torch.Tensor([2,3][4,5][6,7])
torch.Tensor預設為torch.FloatTensor
Variable(變數)
Variable Tensor 本質上沒有區別,不過 Variable 會被放入個計算圖中,然後進行前向傳播,反向傳播,自動求導
Variable 是在 torch.autograd.Variable 中
Variable有三個較重要的組成屬性:
data 取出Variable中的tensor數值
grad 這個Variable傳播梯度
grad_fn 表示得到這個Variable的操作,比如透過加減還是乘除來得到的
dataset(資料集)
定義資料類
from torch.utils.data import Dataset
import os
from PIL import Image
class my_dateset(Dataset):
def __init__(self,root_dir,label_dir):
self.root_dir = root_dir
self.label_dir = label_dir
self.path = os.path.join(self.root_dir,self.label_dir)
self.img_path = os.listdir(self.path)
def __getitem__(self, idx):
img_name = self.img_path[idx]
img_item_path = os.path.join(self.root_dir,self.label_dir,img_name)
img = Image.open(img_item_path)
label = self.label_dir
return img,label
def __len__(self):
return len(self.img_path)
pytorch提供torch.utils.data.DataLoader 來定義一個新的迭代器
dataiter = DataLoader(my_dataset, batch_size=32, shuffle=True, collate_fn=default_collate)
collate_fn 是表示如何取樣本的
torchvision中有一個關於計算機視覺的資料讀取類ImageFolder主要功能是處理圖片,且要求圖片是下面這種存放形式
root/dog/xxx.png
root/dog/xxy.png
root/dog/xxz.png
root/cat/123.png
root/cat/asd.png
root/cat/zxc.png
之後這樣來呼叫這個類:
dset = ImageFolder(root='root_path', transform=None, loader=default_loader)
nn.Module (模組)
PyTorch 裡面編寫神經網路,所有的層結構和損失函式都來自於 torch.nn
class net_name(nn.Module):
def __init__(self, other_argi ments):
super(net_name, self) .__init__
self.convl = nn .Conv2d(in channels, out channels, kernel size)
# other network layer
def forward(self, x) :
x = self. convl (x)
return x
相當於建立了一個計算圖,並且這個結構可以複用多次,每次呼叫就相當於用該計算圖定義的相同引數做一次前向傳播
torch.optim (最佳化)
一階最佳化演算法
![](C:\Users\wyx\Pictures\Screenshots\螢幕截圖 2024-04-18 155241.png)
最常用的一階最佳化演算法是梯度下降
二階最佳化演算法
二階最佳化演算法使用了二階導數( 也叫做 Hessian 方法)來最小化或最大化損失函式
模型的儲存與載入
PyTorch 裡面使用 torch.save 來儲存模型的結構和引數,有兩種儲存方式:
(1)儲存整個模型的結構資訊和引數資訊,儲存的物件是模型 model;
(2)儲存模型的引數,儲存的物件是模型的狀態 model.state diet ()
可以這樣儲存, save 的第一個引數是儲存物件,第二個引數是儲存路徑及名稱:
torch.save(model ,’./model.pth ’)
torch.save(model.state_dict(), './model_state . pth ’)
載入模型有兩種方式對應於儲存模型的方式:
(1)載入完整的模型結構和引數資訊,使用
load model = torch.load (’ model. pth ')
在網路較大的時候載入的時間比較長,同時儲存空間也比較大;
(2)載入模型引數資訊,需要先導人模型的結構,然後透過
model.load_state_die (torch.load( 'model_state pth '))來導人
pytorch核心模組
Tensor
張量表示的是一個多維陣列,它是標量、向量、矩陣的擴充.標量是零維張量,向量是一維張量,矩陣是二維張量,一個RGB影像陣列就是一個三維張量,第一維是影像高,第二維是影像的寬,第三維是影像顏色通道
張量相關函式
張量的建立
直接建立
torch.tensor(data, dtype=None, device=None, requires_grad=False, pin_memory=False)
- data(array_like) - tensor的初始資料,可以是list, tuple, numpy array, scalar或其他型別。
- dtype(torch.dtype, optional) - tensor的資料型別,如torch.uint8, torch.float, torch.long等
- device (torch.device, optional) – 決定tensor位於cpu還是gpu。如果為None,將會採用預設值,預設值在torch.set_default_tensor_type()中設定,預設為 cpu。
- requires_grad (bool, optional) – 決定是否需要計算梯度。
- pin_memory (bool, optional) – 是否將tensor存於鎖頁記憶體。這與記憶體的存在方式有關,通常為False。
torch.from_numpy()
透過numpy建立tensor,改變array中的值,tensor的值也會改變
依據數值建立
torch.zeros(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
依給定的size建立一個全0的tensor,預設資料型別為torch.float32(也稱為torch.float)
layout(torch.layout, optional) - 參數列明張量在記憶體中採用何種佈局方式。常用的有torch.strided, torch.sparse_coo等。
out(tensor, optional) - 輸出的tensor,即該函式返回的tensor可以透過out進行賦值
torch.zeros_like(input, dtype=None, layout=None, device=None, requires_grad=False)
依input的size建立全0的tensor。
input(Tensor) - 建立的tensor與intput具有相同的形狀。
依據機率分佈建立
torch.normal(mean, std, out=None)
為每一個元素以給定的mean和std用高斯分佈生成隨機數
mean (Tensor or Float) - 高斯分佈的均值,
std (Tensor or Float) - 高斯分佈的標準差
torch.rand(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
在區間[0, 1)上,生成均勻分佈
size (int...) - 建立的張量的形狀
張量的操作
cat |
將多個張量拼接在一起,例如多個特徵圖的融合可用。 |
---|---|
concat |
同cat, 是cat()的別名。 |
conj |
返回共軛複數。 |
chunk |
將tensor在某個維度上分成n份。 |
dsplit |
類似numpy.dsplit()., 將張量按索引或指定的份數進行切分。 |
column_stack |
水平堆疊張量。即第二個維度上增加,等同於torch.hstack。 |
dstack |
沿第三個軸進行逐畫素(depthwise)拼接。 |
gather |
高階索引方法,目標檢測中常用於索引bbox。在指定的軸上,根據給定的index進行索引。強烈推薦看example。 |
hsplit |
類似numpy.hsplit(),將張量按列進行切分。若傳入整數,則按等分劃分。若傳入list,則按list中元素進行索引。例如:[2, 3] and dim=0 would result in the tensors input[:2], input[2:3], and input[3:]. |
hstack |
水平堆疊張量。即第二個維度上增加,等同於torch.column_stack。 |
index_select |
在指定的維度上,按索引進行選擇資料,然後拼接成新張量。可知道,新張量的指定維度上長度是index的長度。 |
masked_select |
根據mask(0/1, False/True 形式的mask)索引資料,返回1-D張量。 |
movedim |
移動軸。如0,1軸交換:torch.movedim(t, 1, 0) . |
moveaxis |
同movedim。Alias for torch.movedim() .(這裡發現pytorch很多地方會將dim和axis混用,概念都是一樣的。) |
narrow |
變窄的張量?從功能看還是索引。在指定軸上,設定起始和長度進行索引。例如:torch.narrow(x, 0, 0, 2), 從第0個軸上的第0元素開始,索引2個元素。x[0:0+2, ...] |
nonzero |
返回非零元素的index。torch.nonzero(torch.tensor([1, 1, 1, 0, 1])) 返回tensor([[ 0], [ 1], [ 2], [ 4]])。建議看example,一看就明白,尤其是對角線矩陣的那個例子,太清晰了。 |
permute |
交換軸。 |
reshape |
變換形狀。 |
row_stack |
按行堆疊張量。即第一個維度上增加,等同於torch.vstack。Alias of torch.vstack() . |
scatter |
scatter_(dim, index, src, reduce=None) → Tensor。將src中資料根據index中的索引按照dim的方向填進input中。這是一個十分難理解的函式,其中index是告訴你哪些位置需要變,src是告訴你要變的值是什麼。這個就必須配合例子講解,請跳轉到本節底部進行學習。 |
scatter_add |
同scatter一樣,對input進行元素修改,這裡是 +=, 而scatter是直接替換。 |
split |
按給定的大小切分出多個張量。例如:torch.split(a, [1,4]); torch.split(a, 2) |
squeeze |
移除張量為1的軸。如t.shape=[1, 3, 224, 224]. t.squeeze().shape -> [3, 224, 224] |
stack |
在新的軸上拼接張量。與hstack\vstack不同,它是新增一個軸。預設從第0個軸插入新軸。 |
swapaxes |
Alias for torch.transpose() .交換軸。 |
swapdims |
Alias for torch.transpose() .交換軸。 |
t |
轉置。 |
take |
取張量中的某些元素,返回的是1D張量。torch.take(src, torch.tensor([0, 2, 5]))表示取第0,2,5個元素。 |
take_along_dim |
取張量中的某些元素,返回的張量與index維度保持一致。可搭配torch.argmax(t)和torch.argsort使用,用於對最大機率所在位置取值,或進行排序,詳見官方文件的example。 |
tensor_split |
切分張量,核心看indices_or_sections變數如何設定。 |
tile |
將張量重複X遍,X遍表示可按多個維度進行重複。例如:torch.tile(y, (2, 2)) |
transpose |
交換軸。 |
unbind |
移除張量的某個軸,並返回一串張量。如[[1], [2], [3]] --> [1], [2], [3] 。把行這個軸拆了。 |
unsqueeze |
增加一個軸,常用於匹配資料維度。 |
vsplit |
垂直切分。 |
vstack |
垂直堆疊。 |
where |
根據一個是非條件,選擇x的元素還是y的元素,拼接成新張量。看案例可瞬間明白。 |
張量的隨機種子
seed |
獲取一個隨機的隨機種子。Returns a 64 bit number used to seed the RNG. |
---|---|
manual_seed |
手動設定隨機種子 |
initial_seed |
返回初始種子。 |
get_rng_state |
獲取隨機數生成器狀態。Returns the random number generator state as a torch.ByteTensor. |
set_rng_state |
設定隨機數生成器狀態。這兩怎麼用暫時未知。Sets the random number generator state. |
隨機種子主要用於對實驗的復現
張量的數學操作
- Pointwise Ops: 逐元素的操作,如abs, cos, sin, floor, floor_divide, pow等
- Reduction Ops: 減少元素的操作,如argmax, argmin, all, any, mean, norm, var等
- Comparison Ops:對比操作, 如ge, gt, le, lt, eq, argsort, isnan, topk,
- Spectral Ops: 譜操作,如短時傅立葉變換等各類訊號處理的函式。
- Other Operations:其它, clone, diag,flip等
- BLAS and LAPACK Operations:BLAS(Basic Linear Algebra Subprograms)基礎線性代數)操作。如, addmm, dot, inner, svd等。
計算圖--自動求導核心
計算圖由節點和邊構成
節點表示資料,如標量,向量,矩陣,張量等;
邊表示運算,如加、減、乘、除、卷積、relu等;
![](C:\Users\wyx\Desktop\pytorch\螢幕截圖 2024-04-19 161906.png)
葉子節點
葉子結點是最基礎的結點,其資料不是由運算生成的,因此是整個計算圖的基石,是不可輕易”修改“的
張量有一個屬性是is_leaf, 就是用來指示一個張量是否為葉子結點的屬性
例
import torch
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w, x)
b = torch.add(w, 1) # retain_grad()
y = torch.mul(a, b)
y.backward()
print(w.grad)
# 檢視葉子結點
print("is_leaf:\n", w.is_leaf, x.is_leaf, a.is_leaf, b.is_leaf, y.is_leaf)
# 檢視梯度
print("gradient:\n", w.grad, x.grad, a.grad, b.grad, y.grad)
# 檢視 grad_fn
print("grad_fn:\n", w.grad_fn, x.grad_fn, a.grad_fn, b.grad_fn, y.grad_fn)
#
只有葉子節點的梯度得到保留,中間變數的梯度預設不保留;在pytorch中,非葉子結點的梯度在反向傳播結束之後就會被釋放掉,如果需要保留的話可以對該結點設定retain_grad()
grad_fn是用來記錄建立張量時所用到的運算,在鏈式求導法則中會使用到。
自動微分--Autograd
- 自動求導機制透過有向無環圖(directed acyclic graph ,DAG)實現
- 在DAG中,記錄資料(對應tensor.data)以及操作(對應tensor.grad_fn)
- 操作在pytorch中統稱為Function,如加法、減法、乘法、ReLU、conv、Pooling等,統統是Function
autograd的使用
torch.autograd.backward
使用頻率最高的自動求導函式
torch.autograd.backward(tensors,grad_tensors=None,retain_graph=None,create_graph=False, grad_variables=None, inputs=None)
- tensors (Sequence[Tensor] or Tensor) – 用於求導的張量。如上例的loss。
- grad_tensors (Sequence[Tensor or None] or Tensor, optional) – 雅克比向量積中使用
- retain_graph (bool, optional) – 是否需要保留計算圖。pytorch的機制是在方向傳播結束時,計算圖釋放以節省記憶體。連續使用loss.backward(),就會報錯。如果需要多次求導,則在執行backward()時,retain_graph=True。
- create_graph (bool, optional) – 是否建立計算圖,用於高階求導
使用時可直接呼叫.backward()函式
torch.autograd.grad
torch.autograd.grad(outputs, inputs, grad_outputs=None, retain_graph=None, create_graph=False, only_inputs=True, allow_unused=False)
功能:計算outputs對inputs的導數
主要引數:
- outputs (sequence of Tensor) – 用於求導的張量,如loss
- inputs (sequence of Tensor) – 所要計算導數的張量
- grad_outputs (sequence of Tensor) – 雅克比向量積中使用。
- retain_graph (bool, optional) – 是否需要保留計算圖。
- create_graph (bool, optional) – 是否建立計算圖,用於高階求導。
- allow_unused (bool, optional) – 是否需要指示,計算梯度時未使用的張量是錯誤的。
例:
import torch
x = torch.tensor([3.], requires_grad=True)
y = torch.pow(x, 2) # y = x**2
# 一階導數
grad_1 = torch.autograd.grad(y, x, create_graph=True) # grad_1 = dy/dx = 2x = 2 * 3 = 6
print(grad_1)
# 二階導數
grad_2 = torch.autograd.grad(grad_1[0], x) # grad_2 = d(dy/dx)/dx = d(2x)/dx = 2
print(grad_2)
torch.autograd.Function
想要實現自己的一些操作時,如特殊的數學函式、pytorch的module中沒有的網路層,那就需要自己寫一個Function
pytorch資料模組
Dataset
torch.utils.data.Dataset,供使用者繼承編寫dataset
例:
from torch.utils.data import Dataset
import os
from PIL import Image
class my_dateset(Dataset):
def __init__(self,root_dir,label_dir):
self.root_dir = root_dir
self.label_dir = label_dir
self.path = os.path.join(self.root_dir,self.label_dir)
self.img_path = os.listdir(self.path)
def __getitem__(self, idx):
img_name = self.img_path[idx]
img_item_path = os.path.join(self.root_dir,self.label_dir,img_name)
img = Image.open(img_item_path)
label = self.label_dir
return img,label
def __len__(self):
return len(self.img_path)
- getitem:需要實現讀取一個樣本的功能。通常是傳入索引(index,可以是序號或key),然後實現從磁碟中讀取資料,並進行預處理(包括online的資料增強),然後返回一個樣本的資料。資料可以是包括模型需要的輸入、標籤,也可以是其他元資訊,例如圖片的路徑。getitem返回的資料會在dataloader中組裝成一個batch。即,通常情況下是在dataloader中呼叫Dataset的getitem函式獲取一個樣本。
- len:返回資料集的大小。如果這個函式返回的是0,dataloader會報錯:"ValueError: num_samples should be a positive integer value, but got num_samples=0"
DataLoader
torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False, sampler=None, batch_sampler=None, num_workers=0, collate_fn=None, pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None, multiprocessing_context=None, generator=None, *, prefetch_factor=2, persistent_workers=False)
- dataset:一個Dataset例項,要能實現從索引(indices/keys)到樣本的對映。(即getitem函式)
- batch_size:每個batch的樣本量
- shuffle:是否對打亂樣本順序。訓練集通常要打亂它!驗證集和測試集無所謂。
- sampler:設定取樣策略。
- batch_sampler:設定取樣策略, batch_sampler與sampler二選一
- num_workers: 設定多少個子程序進行資料載入(data loading)
- collate_fn:組裝資料的規則, 決定如何將一批資料組裝起來。
- pin_memory:是否使用鎖頁記憶體,具體行為是“the data loader will copy Tensors into CUDA pinned memory before returning them”
- drop_last:每個epoch是否放棄最後一批不足batchsize大小的資料,即無法被batchsize整除時,最後會有一小批資料,是否進行訓練,如果資料量足夠多,通常設定為True。
Dataset及常用API
concat
在實際專案中,資料的來源往往是多源的,很難統一到一個資料格式.一種靈活的方式是每批資料編寫一個Dataset,然後使用torch.utils.data.ConcatDataset類將他們拼接起來,這種方法可以靈活的處理多源資料,也可以很好的使用別人的資料及Dataset
Subset
subset可根據指定的索引獲取子資料集,Subset也是Dataset類
例
def __init__(self, dataset: Dataset[T_co], indices: Sequence[int]) -> None:
self.dataset = dataset
self.indices = indices
def __getitem__(self, idx):
if isinstance(idx, list):
return self.dataset[[self.indices[i] for i in idx]]
return self.dataset[self.indices[idx]]
def __len__(self):
return len(self.indices)
random_aplit
該函式的功能是隨機的將dataset劃分為多個不重疊的子集,適合用來劃分訓練、驗證集
torch.utils.data.random_split(dataset, lengths, generator=None)
只需要設定每個子集的資料量,傳給lengths即可
sampler
sampler是在dataloader中起到挑選資料的功能,主要是設定挑選策略,如按順序挑選、隨機挑選、按類別分機率挑選等
sampler 與 batch_sampler
本質上兩者都是取樣器,當採用auto_collation時,採用batch_sampler
batch_sampler是一次返回一個batch的索引。通常我們用的都是batch_sampler,其對應的是BatchSampler類
BatchSampler
torch.utils.data.BatchSampler(sampler, batch_size, drop_last)
第一個引數傳入的是一個sampler取樣器,在這裡會有兩種情況,如果需要shuffle,則傳入RandomSampler,不需要打亂,則傳入SequentialSampler
BatchSampler是在其它兩者之上封裝了一個批抽取的功能,一次yield一個batch的index,而樣本取樣的順序取決於RandomSampler和SequentialSample。
SequentialSampler
順序迭代器,按順序的迭代器
RandomSamoler
預設情況下會使用這行程式碼實現:yield from torch.randperm(n, generator=generator).tolist(), 利用torch的隨機方法生成一個隨機整數序列,對於generator預設採用的是隨機一個隨機種子進行設定
SubsetRandomSampler
透過索引定義一個自己的隨機取樣器
這個取樣器返回的樣本總數是傳入的索引的長度
def __iter__(self) -> Iterator[int]:
for i in torch.randperm(len(self.indices), generator=self.generator):
yield self.indices[i]
WeightedRandomSampler
torch.utils.data.WeightedRandomSampler(weights, num_samples, replacement=True, generator=None)
- weights (sequence) – 每個樣本的取樣權重,權重之和不必為1,只需要關心各樣本之間的比例即可。
- num_samples (int) – 取樣數量,一般設為樣本總量。
- replacement (bool) –是否有放回取樣。 True,表示有放回。
- generator (Generator) – 自定義生成器,通常用預設的
transforms
pytorch的影像資料增強函式庫
變換方法
Compose
用於包裝一系列transforms方法
例:
dataset_transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
Resize
支援對PIL或Tensor物件的縮放
例
Resize(size, interpolation=, max_size=None, antialias=None)
Totensor
將PIL物件或nd.array物件轉換成tensor,並且對數值縮放到[0, 1]之間,並且對通道進行右移
Normalize
對tensor物件進行逐通道的標準化,具體操作為減均值再除以標準差
Normalize(mean, std, inplace=False)
transforms.Pad
對影像進行填充
torchvision.transforms.Pad(padding, fill=0, padding_mode='constant')
transforms.Grayscale
將圖片轉為灰度圖
torchvision.transforms.Grayscale(num_output_channels=1)
PILImage:transforms.ToPILImage
torchvision.transforms.ToPILImage(mode=None)
將 tensor 或者 ndarray 的資料轉換為 PIL Image 型別資料
mode- 為None時為 1 通道, mode=3 通道預設轉換為 RGB,4 通道預設轉換為 RGBA
裁剪方法
隨機裁剪:transforms.RandomCrop
依據給定的 size 隨機裁剪
torchvision.transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0,
padding_mode='constant')
中心裁剪:transforms.CenterCrop
torchvision.transforms.CenterCrop(size)
依據給定的 size 從中心裁剪
隨機長寬比裁剪:transforms.RandomResizedCrop
torchvision.transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(0.75, 1.33333
33333333333), interpolation=2)
機大小,隨機長寬比裁剪原始圖片,最後將圖片 resize 到設定好的 size
size- 輸出的解析度
scale- 隨機 crop 的大小區間,如 scale=(0.08, 1.0),表示隨機 crop 出來的圖片會在的 0.08
倍至 1 倍之間。
ratio- 隨機長寬比設定
interpolation- 插值的方法,預設為雙線性插值(PIL.Image.BILINEAR)
上下左右中心裁剪transforms.FiveCrop
torchvision.transforms.FiveCrop(size)
功能:對圖片進行上下左右以及中心裁剪,獲得 5 張圖片,返回一個 4D-tensor
上下左右中心裁剪後翻轉: transforms.TenCrop
torchvision.transforms.TenCrop(size,vertical_flip=False)
功能:對圖片進行上下左右以及中心裁剪,然後全部翻轉(水平或者垂直),獲得 10 張圖
片,返回一個 4D-tensor。
vertical_flip (bool) - 是否垂直翻轉,預設為 flase,即預設為水平翻轉
翻轉和旋轉
依機率 p 水平翻轉 transforms.RandomHorizontalFlip
torchvision.transforms.RandomHorizontalFlip(p=0.5)
功能:依據機率 p 對 PIL 圖片進行水平翻轉
p- 機率,預設值為 0.5
垂直翻轉 transforms.RandomVerticalFlip
torchvision.transforms.RandomVerticalFlip(p=0.5)
功能:依據機率 p 對 PIL 圖片進行垂直翻轉
p- 機率,預設值為 0.5
隨機旋轉transforms.RandomRotation
torchvision.transforms.RandomRotation(degrees,resample=False,expand=False,center=None)
功能:依 degrees 隨機旋轉一定角度
degress- (sequence or float or int) ,若為單個數,如 30,則表示在(-30,+30)之間隨機旋
轉
resample- 重取樣方法選擇,可選PIL.Image.NEAREST, PIL.Image.BILINEAR, PIL.Image.BICUBIC,預設為False
expand-用於指定是否擴充套件影像以適應旋轉後的影像。如果設定為 True
,則會擴充套件影像的邊界以容納整個旋轉後的影像;如果設定為 False
,則會保留旋轉後影像的原始尺寸,預設為 False
。
center- 可選為中心旋轉還是左上角旋轉
自動資料增強
AutoAugment
torchvision.transforms.AutoAugment(policy: torchvision.transforms.autoaugment.AutoAugmentPolicy = , interpolation: torchvision.transforms.functional.InterpolationMode = , fill: Optional[List[float]] = None)
功能:自動資料增強方法的封裝,支援三種資料增強策略,分別是IMAGENET、CIFAR10 和SVHN
引數:
policy :需要是AutoAugmentPolicy類
interpolation:設定插值方法
fill :設定填充畫素的畫素值,預設為0,黑色。
RandAugment
RandAugment是進行N次(num_ops )變換,變換方法從策略池中隨機挑選
num_ops :執行多少次變換
magnitude :每個變換的強度,
num_magnitude_bins:與變化強度的取樣分佈有關
pytorch模型模組
module
Module是所有神經網路的基類,所有的模型都必須繼承於Module類,並且它可以巢狀
構建自己的網路只需要三步:
- 寫一個類繼承於Module
- init函式中把需要的網路層建立好
- forward函式中把模型如何搭建的規則寫好
parameter--引數
parameter繼承於Tensor,主要作用是用來區分可訓練的引數與常規的tensor
Parameter指模型的引數,如卷積層的卷積核權重和偏置,Linear層的權重和偏置,BN層的α和β等等
例
optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)
module的容器
Sequential
將一系列網路層按固定的先後順序串起來,當成一個整體,呼叫時資料從第一個層按順序執行到最後一個層
例:
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
def forward(self, input):
for module in self:
input = module(input)
return input
ModuleList
將各個網路層放到一個“列表”中,便於迭代的形式呼叫
例
class MyModule(nn.Module):
def __init__(self):
super(MyModule, self).__init__()
self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])
def forward(self, x):
for sub_layer in self.linears:
x = sub_layer(x)
return x
ModuleDict
ModuleDict就是可以像python的Dict一樣為每個層賦予名字,可以根據網路層的名字進行選擇性的呼叫網路層
class MyModule2(nn.Module):
def __init__(self):
super(MyModule2, self).__init__()
self.choices = nn.ModuleDict({
'conv': nn.Conv2d(3, 16, 5),
'pool': nn.MaxPool2d(3)
})
self.activations = nn.ModuleDict({
'lrelu': nn.LeakyReLU(),
'prelu': nn.PReLU()
})
def forward(self, x, choice, act):
x = self.choices[choice](x)
x = self.activations[act](x)
return x
常用網路層
Convolutional Layers
卷積層
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
對多個二維平面組成的訊號進行二維卷積
- in_channels (int) – 輸入這個網路層的影像的通道數是多少。
- out_channels (int) – 此網路層輸出的特徵圖的通道數是多少,等價於卷積核數量是多少。
- kernel_size (int or tuple) – 卷積核大小。
- stride (int or tuple, optional) – 卷積核卷積過程的步長。
- padding (int, tuple or str, optional) –對於輸入影像的四周進行填充的數量進行控制,可指定填充畫素數量,也可以指定填充模式,
- padding_mode (string, optional) – 填充的畫素值如何確定。預設填充0。
- dilation (int or tuple, optional) – 孔洞卷積的孔洞大小。
- groups (int, optional) – 分組卷積的分組。
- bias (bool, optional) – 是否採用偏置。
![](C:\Users\wyx\Desktop\pytorch\螢幕截圖 2024-04-20 161320.png)
![](C:\Users\wyx\Desktop\pytorch\螢幕截圖 2024-04-20 161332.png)
Pooling Layers
池化層
將特徵圖解析度變小,通常減小一半(提取特徵量)
可對池化層進行劃分為最大值池化、平均值池化、分數階池化、基於範數的池化。分別對應torch.nn中的Maxpool, Avgpool, FractionalMaxPool, LPPool
Maxpool:
torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
2D最大池化
-
kernel_size – 池化視窗大小
-
stride – 滑窗步長
-
padding – 原圖填充大小
-
dilation – 孔洞大小
-
return_indices – 是否返回最大值所在位置,主要在 torch.nn.MaxUnpool2d 中使用,是上取樣的一種策略
-
ceil_mode – 當無法整除時,是向下取整還是向上取整,預設為向下。
![](C:\Users\wyx\Desktop\pytorch\螢幕截圖 2024-04-20 161320-1713600998558-3.png)
Padding Layers
給特徵圖周圍填充一定的畫素,調整特徵圖解析度的一種方法
可將padding layer劃分為三類,映象填充、邊界重複填充,指定值填充、零值填充,分別對應nn的三大類,nn.ReflectionPad2d, nn.ReplicationPad2d, nn.ZeroPad2d, nn.ConstantPad2d
Linear Layers
線性層
Linear Layers包含4個層分別是nn.Identity,nn.Linear, nn.Bilinear, nn.LazyLinear
nn.Identity 是恆等對映,不對輸入做任何變換,它通常用於佔位。
nn.Linear 全連線層(Fully Connection Layer),可實現 y= Wx + b
nn.Bilinear 是雙線性層,它有兩個輸入,實現公式 y = x1Wx2 +b
nn.LazyLinear 是nn.Linear的lazy版本,也就是懶惰的Linear層,它在第一次推理時自動根據輸入特徵圖的尺寸來設定in_features,免去了手動計算in_features的麻煩。
Dropout Layers
隨機失活--防止模型過擬合
Dropout使用注意事項:
- Dropout通常用於nn.Linear層之前;
- Dropout執行後,神經元個數會減少,導致資料尺度發生變化.
Non - linear Layers
非線性啟用函式函式
Module常用函式
-
設定模型訓練、評估模式
eval:設定模型為評估模式,與BN,Dropout息息相關,即評估模式下模型的某些層執行的操作與訓練狀態下是不同的。
train:設定模型為訓練模式,如BN層需要統計runing_var這些統計資料,Dropout層需要執行隨機失活等
-
設定模型存放在cpu/gpu/xpu
- cpu,將Module放到cpu上
- cuda,把需要運算的資料放到gpu即可。方法就是 xxx.cuda()
- to,可將物件放到指定的裝置中去,如to.("cpu") 、 to.("cuda)、to("cuda:0") 等
-
獲取模型引數、載入權重引數
- load_state_dict,將引數字典中的引數複製到當前模型中。要求key要一一對應
- state_dict,返回引數字典。key是告訴你這個權重引數是放到哪個網路層
-
管理模型的modules, parameters, sub_module
parameters:返回一個迭代器,迭代器可丟擲Module的所有parameter物件
named_parameters:作用同上,不僅可得到parameter物件,還會給出它的名稱
modules:返回一個迭代器,迭代器可以丟擲Module的所有Module物件,注意:模型本身也是module,所以也會獲得自己。
named_modules:作用同上,不僅可得到Module物件,還會給出它的名稱
children:作用同modules,但不會返回Module自己。
named_children:作用同named_modules,但不會返回Module自己
-
設定模型的引數精度,可選半精度、單精度、雙精度等
- bfloat16
- half
- float
- double
-
對子模組執行特定功能
- apply
- zero_grad
pytorch最佳化模組
損失函式--Loss Function
損失函式(loss function)是用來衡量模型輸出與真實標籤之間的差異,當模型輸出越接近標籤,認為模型越好,反之亦然
在pytorch中提供了二十一個損失函式,如下所示
nn.L1Loss
nn.MSELoss
nn.CrossEntropyLoss
nn.CTCLoss
nn.NLLLoss
nn.PoissonNLLLoss
nn.GaussianNLLLoss
nn.KLDivLoss
nn.BCELoss
nn.BCEWithLogitsLoss
nn.MarginRankingLoss
nn.HingeEmbeddingLoss
nn.MultiLabelMarginLoss
nn.HuberLoss
nn.SmoothL1Loss
nn.SoftMarginLoss
nn.MultiLabelSoftMarginLoss
nn.CosineEmbeddingLoss
nn.MultiMarginLoss
nn.TripletMarginLoss
nn.TripletMarginWithDistanceLoss
L1loss
torch.nn.L1Loss(size_average=None, reduce=None, reduction='mean')
計算output和target之差的絕對值,可選返回同維度的tensor(reduction=none)或一個標量(reduction=mean/sum)
CrossEntropyLoss -- 交叉熵損失函式
torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=- 100, reduce=None, reduction='mean', label_smoothing=0.0)
先將輸入經過softmax啟用函式之後,再計算交叉熵損失
eight (Tensor, optional) – 類別權重,用於調整各類別的損失重要程度,常用於類別不均衡的情況
ignore_index (int, optional) – 忽略某些類別不進行loss計算。
size_average (bool, optional) – 已捨棄使用的變數,功能已經由reduction代替實現,仍舊保留是為了舊版本程式碼可以正常執行。
reduce (bool, optional) – 已捨棄使用的變數,功能已經由reduction代替實現,仍舊保留是為了舊版本程式碼可以正常執行。
reduction (string, optional) – 是否需要對loss進行“降維”,這裡的reduction指是否將loss值進行取平均(mean)、求和(sum)或是保持原尺寸(none)
最佳化器--Optimizer
對模型進行最佳化使loss不斷降低
最佳化器的實現在torch.optim中
最佳化器基類
引數組(param_groups):引數組是用於管理需要進行最佳化的那些引數,例如權值weight,偏置bias,BN的alpha/beta等
這裡是引數組不是引數,表明可以將所有引數進行分組,例如在finetune過程中,通常讓前面層的網路採用較小的學習率,後面幾層全連線層採用較大的學習率,這時我們就要把網路的引數劃分為兩組,每一組有它對應的學習率
引數組是一個list,其元素是一個dict,dict中包含,所管理的引數,對應的超參,例如學習率,momentum,weight_decay等等。
state:用於儲存最佳化策略中需要儲存的一些快取值,例如在用momentum時,需要儲存之前的梯度,這些資料儲存在state中。
defaults:最佳化方法預設的超引數
方法:
zero_grad()
功能:清零所管理引數的梯度。由於pytorch不會自動清零梯度,因此需要再optimizer中手動清零,然後再執行反向傳播,得出當前iteration的loss對權值的梯度。
step()
功能:執行一步更新,依據當前的梯度進行更新引數
add_param_group(param_group)
功能:給optimizer管理的引數組中增加一組引數,可為該組引數定製lr,momentum,weight_decay等,在finetune中常用。
例如:
optimizer_1.add_param_group({'params': w3, 'lr': 0.001, 'momentum': 0.8})
state_dict()
功能:獲取當前state屬性。
通常在儲存模型時同時儲存最佳化器狀態,用於斷點儲存,下次繼續從當前狀態訓練;
load_state_dict(state_dict)
功能:載入所儲存的state屬性,恢復訓練狀態。
SGD--隨機梯度下降
深度學習中最基礎的一個
SGD核心理論知識是梯度下降( gradient descent),即沿著梯度的負方向,是變化最快的方向。
SGD的使用
optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)#例項化
optimizer.zero_grad()#loss.backward()之前進行梯度清零
loss.backward()
optimizer.step()#loss.backward()之後執行一步更新
pytorch 視覺化
TensorBoard
例
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
writer.add_image("test",img_array,2,dataformats="HWC")
writer.close()
終端輸入
tensorboard --logdir=your path dir
add_scalar
add_scalar(tag, scalar_value, global_step=None, walltime=None, new_style=False, double_precision=False)
新增標量;tag的設定可以有個技巧是在同一欄下繪製多個圖,如'Loss/train', 'Loss/Valid', 這就類似於matplotlib的subplot(121), subplot(122)
- tag (string) – Data identifier
- scalar_value (float or string/blobname) – Value to save
- global_step (int) – Global step value to record
add_scalars
add_scalars`(main_tag, tag_scalar_dict, global_step=None,walltime=None)
功能:在一個座標軸中繪製多條曲線。常用於曲線對比。
- main_tag (string) – The parent name for the tags
- tag_scalar_dict (dict) – Key-value pair storing the tag and corresponding values
- global_step (int) – Global step value to record
add_image
add_image(tag, img_tensor, global_step=None, walltime=None, dataformats='CHW')
功能:繪製影像。
- tag (string) – Data identifier
- img_tensor (torch.Tensor, numpy.array, or string/blobname) – Image data
- global_step (int) – Global step value to record dataformats- 資料通道順序物理意義。預設為 CHW