0 目錄-神經(jīng)網(wǎng)絡(luò)框架
torch.nn(Neural network, 神經(jīng)網(wǎng)絡(luò))內(nèi)包含Pytorch神經(jīng)網(wǎng)絡(luò)框架
- Containers: 容器
- Convolution Layers: 卷積層
- Pooling Layers: 池化層
- Padding Layers: 填充層
- Non-linear Activations (weighted sum, nonlinearity):非線性激活
- Non-linear Activations (other):非線性激活
- Normalization Layers:歸一化層
- Recurrent Layers:遞歸層
- Transformer Layers:變換層
- Linear Layers:全連接層
- Dropout Layers:舍棄層
- Distance Functions:距離函數(shù)
- Loss Functions:損失函數(shù)
…
1 容器 Containers
1.1 Module類的使用
Module是所有神經(jīng)網(wǎng)絡(luò)模塊的基類。
學(xué)習(xí)鏈接:
https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module
Class torch.nn.Module(*args, **kwargs)
使用案例:
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, inputX):
x = F.relu(self.conv1(inputX))
return F.relu(self.conv2(x))
- forward函數(shù)內(nèi)relu()為激活函數(shù),conv()為卷積函數(shù)。
- 輸入inputX-> 卷積-> 非線性處理(relu)-> 卷積 ->非線性處理(relu)。
完整構(gòu)建的python代碼:
from torch import nn
import torch
class MyNN(nn.Module):
def __init__(self):
super().__init__()
def forward(self, inputX):
outputX = inputX + 1
return outputX
mynn = MyNN()
x = torch.tensor(1.0)
output = mynn(x)
print(x)
print(output)
輸出結(jié)果:
tensor(1.)
tensor(2.)
1.2 順序容器 Sequential
能夠按照容器內(nèi)的函數(shù)順序執(zhí)行,相當(dāng)于在forward函數(shù)中級聯(lián)了多個函數(shù)。
按照我的理解,類似于圖像處理transforms庫內(nèi)的Compose函數(shù),對數(shù)據(jù)進(jìn)行流水線處理。
例子:
# 使用Sequential的例子
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
# 使用OrderedDict的Sequential的例子
model = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(1,20,5)),
('relu1', nn.ReLU()),
('conv2', nn.Conv2d(20,64,5)),
('relu2', nn.ReLU())
]))
1.2.1 構(gòu)建順序容器
數(shù)據(jù)集CIFAR10的模型結(jié)構(gòu):
數(shù)據(jù)操作步驟:
操作順序 | 輸入數(shù)據(jù)長度 | 輸出數(shù)據(jù)長度 |
---|---|---|
卷積(5*5) | 3x32x32 | 32x32x32 |
最大池化(2*2) | 32x32x32 | 32x16x16 |
卷積(5*5) | 32x16x16 | 32x16x16 |
最大池化(2*2) | 32x16x16 | 32x8x8 |
卷積(5*5) | 32x8x8 | 64x8x8 |
最大池化(2*2) | 64x8x8 | 64x4x4 |
數(shù)據(jù)展平 | 64x4x4 | 1024 |
全連接層/線性層 | 1024 | 64 |
全連接層/線性層 | 64 | 10 |
以下采用普通方法和Sequential方法對構(gòu)建數(shù)據(jù)網(wǎng)絡(luò),能夠發(fā)現(xiàn)第二種方法的代碼量較小。python代碼如下:
import torchvision
import torch
from torch import nn
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10(root="G:\\Anaconda\\pycharm_pytorch\\learning_project\\dataset_CIFAR10",train=False,transform=torchvision.transforms.ToTensor(),download=False)
dataloader = DataLoader(dataset, batch_size=64)
class MYNN(nn.Module):
def __init__(self):
super(MYNN, self).__init__()
self.conv1 = Conv2d(3, 32, 5, padding=2, stride=1)
self.maxpool1 = MaxPool2d(2)
self.conv2 = Conv2d(32, 32, 5, padding=2, stride=1)
self.maxpool2 = MaxPool2d(2)
self.conv3 = Conv2d(32, 64, 5, padding=2, stride=1)
self.maxpool3 = MaxPool2d(2)
self.flatten1 = Flatten()
self.linear1 = Linear(1024, 64)
self.linear2 = Linear(64, 10)
def forward(self, x):
x = self.conv1(x)
x = self.maxpool1(x)
x = self.conv2(x)
x = self.maxpool2(x)
x = self.conv3(x)
x = self.maxpool3(x)
x = self.flatten1(x)
x = self.linear1(x)
x = self.linear2(x)
return x
# 使用Sequential函數(shù)
class MYNN2(nn.Module):
def __init__(self):
super(MYNN2, self).__init__()
self.model1 = Sequential(
Conv2d(3, 32, 5, padding=2, stride=1),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2, stride=1),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2, stride=1),
MaxPool2d(2),
Flatten(),
Linear(1024,64),
Linear(64,10)
)
def forward(self, x):
x = self.model1(x)
return x
mynn = MYNN()
print(mynn) # 查看網(wǎng)絡(luò)結(jié)構(gòu)
# 測試
input = torch.ones([64, 3, 32, 32])
print(input.shape)
output = mynn(input)
print(output.shape)
print("\r\n")
# 使用Sequential函數(shù)
mynn2 = MYNN2()
print(mynn2) # 查看網(wǎng)絡(luò)結(jié)構(gòu)
# 測試
input2 = torch.ones([64, 3, 32, 32])
print(input2.shape)
output2 = mynn2(input2)
print(output2.shape)
運(yùn)行輸出結(jié)果:
MYNN(
(conv1): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(maxpool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv2): Conv2d(32, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(maxpool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv3): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(maxpool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(flatten1): Flatten(start_dim=1, end_dim=-1)
(linear1): Linear(in_features=1024, out_features=64, bias=True)
(linear2): Linear(in_features=64, out_features=10, bias=True)
)
torch.Size([64, 3, 32, 32])
torch.Size([64, 10])
MYNN2(
(model1): Sequential(
(0): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(2): Conv2d(32, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(4): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Flatten(start_dim=1, end_dim=-1)
(7): Linear(in_features=1024, out_features=64, bias=True)
(8): Linear(in_features=64, out_features=10, bias=True)
)
)
torch.Size([64, 3, 32, 32])
torch.Size([64, 10])
1.2.2 Tensorboard顯示順序容器
python代碼如下:
writer = SummaryWriter("G:/Anaconda/pycharm_pytorch/learning_project/logs_container")
writer.add_graph(mynn2, input2)
writer.close()
代碼運(yùn)行完成后,進(jìn)入terminal終端,輸入:
tensorboard --logdir=logs_container
點(diǎn)擊網(wǎng)頁鏈接,能夠看到以下內(nèi)容:
能夠清晰看到各個層之間的關(guān)系和數(shù)據(jù)維度。
2 卷積層 Convolution Layers
2.1 二維卷積計算conv2d()
CLASS torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=‘zeros’, device=None, dtype=None)
- in_channels (int) – 輸入圖像中的通道數(shù)。
- out_channels (int) – 輸出圖像中的通道數(shù)。
- kernel_size (int or tuple) – 卷積核的大小。
- stride (int or tuple, optional) – 卷積步長(默認(rèn)為1)。
- padding (int, tuple or str, optional) – 為輸入框的四面添加內(nèi)邊距(默認(rèn)為0)。
- padding_mode (str, optional) – ‘zeros’、‘reflect’、‘replicate’或’circular’(默認(rèn)為’zeros’)。
- dilation (int or tuple, optional) – 內(nèi)核元素之間的間距(默認(rèn)為1)。
- groups (int, optional) – 從輸入通道到輸出通道的阻塞連接數(shù)(默認(rèn)為1)。
- bias (bool, optional) – 如果為True,則在輸出中添加一個可學(xué)習(xí)的偏差(默認(rèn)為True)。
輸出圖像大小計算方法:
二維卷積 conv2d()
輸入和輸出的矩陣類型都需要(N, C_{in}, H_{in}, W_{in})
輸入圖像1024x800,卷積核3x3,每次9個元素相乘后相加,不斷向右移動并計算,移動到最右側(cè)之后;然后向下移動并計算,移動到最下側(cè)之后,完成卷積計算。
import torch
import torch.nn.functional as F
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]])
input = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))
print("input:")
print(input)
print("kernel:")
print(kernel)
output = F.conv2d(input, kernel, stride=1)
print("output:")
print(output)
輸出結(jié)果:
input:
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:
tensor([[[[1, 2, 1],
[0, 1, 0],
[2, 1, 0]]]])
output:
tensor([[[[10, 12, 12],
[18, 16, 16],
[13, 9, 3]]]])
如果將步進(jìn)stride修改為2。
output2 = F.conv2d(input, kernel, stride=2)
print("output2:")
print(output2)
輸出結(jié)果為:
output2:
tensor([[[[10, 12],
[13, 3]]]])
padding填充,將原圖像的四周填充一圈0,這樣的話,卷積計算的結(jié)果維度就會更大。
output3 = F.conv2d(input, kernel, stride=1, padding=1)
print("output3:")
print(output3)
輸出的結(jié)果:
tensor([[[[ 1, 3, 4, 10, 8],
[ 5, 10, 12, 12, 6],
[ 7, 18, 16, 16, 8],
[11, 13, 9, 3, 4],
[14, 13, 9, 7, 4]]]])
2.2 圖像卷積操作
學(xué)習(xí)鏈接:
https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html#torch.nn.Conv2d
CLASS torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=‘zeros’, device=None, dtype=None)
- in_channels (int) – 輸入圖像通道數(shù)
- out_channels (int) – 輸出圖像通道數(shù)
- kernel_size (int or tuple) – 卷積核大小
- stride (int or tuple, optional) – 卷積步長(默認(rèn)為1)。
- padding (int, tuple or str, optional) – 添加到輸入圖像四周的邊長(默認(rèn)為1)
- padding_mode (str, optional) – 邊長類型:‘zeros’, ‘reflect’, ‘replicate’ or ‘circular’。默認(rèn)為: ‘zeros’
- dilation (int or tuple, optional) – 卷積核之間的間距(默認(rèn)為1),空洞卷積。
*groups (int, optional) – 從輸入通道到輸出通道的阻塞連接數(shù)(默認(rèn)為1)。 - bias (bool, optional) – 如果為 True, 在輸出中添加一個可學(xué)習(xí)的偏差(默認(rèn)為True)。
如果in_channel=1,out_channel=2,則會使用兩個卷積核對輸入圖像進(jìn)行計算,輸出兩個通道的數(shù)據(jù):
卷積公式:
二維卷積動圖:
https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md
當(dāng)dilation=2時,卷積的方法:
圖像二維卷積python代碼:
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10(root="G:\\Anaconda\\pycharm_pytorch\\learning_project\\dataset_CIFAR10",
train=False,
transform=torchvision.transforms.ToTensor(),
download=False)
dataloader = DataLoader(dataset, batch_size=64)
class MyNN(nn.Module):
def __init__(self):
super(MyNN, self).__init__()
self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)
def forward(self, x):
x = self.conv1(x)
return x
myNN = MyNN()
print(myNN)
writer = SummaryWriter("G:/Anaconda/pycharm_pytorch/learning_project/logs")
step = 0
for data in dataloader:
imgs, targets = data
output = myNN(imgs)
print(imgs.shape) # torch.Size([64, 3, 32, 32])
print(output.shape) # torch.Size([64, 6, 30, 30])
writer.add_images("input", imgs, step)
# torch.Size([64, 6, 30, 30]) -> # torch.Size([xxx, 3, 30, 30])
output = torch.reshape(output, (-1, 3, 30, 30))
writer.add_images("output", output, step)
step = step + 1
writer.close()
代碼運(yùn)行后,終端輸入tensorboard --logdir=logs
,打開tensorboard。
能夠看到output圖片為卷積后的部分通道。
3 池化層 Pooling Layers
學(xué)習(xí)鏈接:
https://pytorch.org/docs/stable/nn.html#pooling-layers
池化層的作用:(1)下采樣(downsampling),降低數(shù)據(jù)維度,減少網(wǎng)絡(luò)前向運(yùn)算消耗的內(nèi)存大??;(2)保持輸入特征,擴(kuò)大網(wǎng)絡(luò)模型的感知野;(3)防止過擬合或欠擬合。
3.1 最大池化MaxPool2d()
在由幾個輸入平面組成的輸入信號上應(yīng)用2D最大池化。
CLASS torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
- kernel_size (Union[int, Tuple[int, int]]) – 池化窗口的最大尺寸。
- stride (Union[int, Tuple[int, int]]) – 池化窗口的步長(默認(rèn)值為
kernel_size
)。 - padding (Union[int, Tuple[int, int]]) – 兩邊隱式地添加負(fù)無窮內(nèi)邊距。
- dilation (Union[int, Tuple[int, int]]) – 一個參數(shù),控制窗口中元素的步長。
- return_indices (bool) – 如果為True,將返回最大索引以及輸出。在torch.nn.MaxUnpool2d之后有用。
- ceil_mode (bool) – 當(dāng)為True時,將使用ceil而不是floor來計算輸出形狀。
ceil表示ceiling模式(天花板),floor表示floor模式(地板)。如果為Ceil表示取整數(shù)時,向上取整;floor表示取整數(shù)時,向下取整。
在二維卷積中表示,當(dāng)出現(xiàn)以下的情況,ceil_mode為True時,需要保留剩下的6個數(shù)的卷積;如果ceil_mode為False時,不需要保留此次卷積。
池化操作與卷積操作不同,池化的補(bǔ)償就是池化核的大小,池化操作得到的輸出結(jié)果如下圖右側(cè)所示,ceil_mode的True和False得到的結(jié)果大小不同。
最大池化python代碼:
import torch
from torch import nn
from torch.nn import MaxPool2d
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]], dtype=torch.float32)
input = torch.reshape(input, (-1, 1, 5, 5))
print(input)
class MYNN(nn.Module):
def __init__(self):
super(MYNN,self).__init__()
self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)
self.maxpool2 = MaxPool2d(kernel_size=3, ceil_mode=False)
def forward(self, input):
output1 = self.maxpool1(input)
output2 = self.maxpool2(input)
return output1, output2
mynn = MYNN()
output1, output2 = mynn(input)
print(output1)
print(output2)
運(yùn)行腳本得到輸出結(jié)果:
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.]]]])
tensor([[[[2., 3.],
[5., 1.]]]])
tensor([[[[2.]]]])
3.2 圖像池化操作
python代碼:
import torch
import torchvision
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10(root="G:\\Anaconda\\pycharm_pytorch\\learning_project\\dataset_CIFAR10",
train=False,
transform=torchvision.transforms.ToTensor(),
download=False)
dataloader = DataLoader(dataset, batch_size=64)
class MYNN(nn.Module):
def __init__(self):
super(MYNN,self).__init__()
self.maxpool = MaxPool2d(kernel_size=3, ceil_mode=False)
def forward(self, input):
output = self.maxpool(input)
return output
mynn = MYNN()
writer = SummaryWriter("G:/Anaconda/pycharm_pytorch/learning_project/logs_maxpool")
step = 0
for data in dataloader:
imgs, targets = data
writer.add_images("input", imgs, step)
# torch.Size([64, 6, 30, 30]) -> # torch.Size([xxx, 3, 30, 30])
output = mynn(imgs)
writer.add_images("output", output, step)
step = step + 1
writer.close()
代碼運(yùn)行后,終端輸入tensorboard --logdir=logs_maxpool
,打開tensorboard。能夠看到output圖片為池化操作后的圖像清晰度降低。
4 填充層 Padding Layers
學(xué)習(xí)鏈接:
https://pytorch.org/docs/stable/nn.html#padding-layers
主要使用的函數(shù):
函數(shù)名 | 說明 |
---|---|
nn.ZeroPad2d | 用零填充輸入張量(Tensor)邊界。 |
nn.ConstantPad2d | 用常數(shù)填充輸入張量(Tensor)邊界。 |
在其他的層內(nèi)也能實(shí)現(xiàn),因此可以不用這一層。
5 非線性激活 Non-linear Activations (weighted sum, nonlinearity)
給神經(jīng)網(wǎng)絡(luò)引入非線性特征。
函數(shù)名 | 說明 |
---|---|
nn.ReLU | 按元素應(yīng)用修正線性單位函數(shù)。 |
nn.Sigmoid | 應(yīng)用針對元素的函數(shù)。 |
5.1 激活函數(shù)
5.1.1 ReLU
按元素應(yīng)用修正線性單位函數(shù):
CLASS torch.nn.ReLU(inplace=False)
參數(shù):
- inplace (bool) – 是否可以選擇現(xiàn)場進(jìn)行操作(默認(rèn)值False)。
Shape: - Input: (?), ?指的是任意數(shù)量的維度。
- Output: (?), 與輸入相同的shape。
5.1.2 Sigmod
應(yīng)用元素函數(shù):
CLASS torch.nn.Sigmoid(*args, **kwargs)
Shape:
- Input: (?),? 是指任意數(shù)量的維度。
- Output: (?),與輸入相同的shape。
5.2 數(shù)字代入激活函數(shù)測試
python代碼:
import torch
from torch import nn
from torch.nn import ReLU
from torch.nn import Sigmoid
input = torch.tensor([[1, -0.5],
[-1, 3]])
output = torch.reshape(input, (-1, 1, 2, 2))
print(output)
class MYNN(nn.Module):
def __init__(self):
super(MYNN, self).__init__()
self.relu1 = ReLU()
self.sigmod1 = Sigmoid()
def forward(self, input):
output = self.relu1(input)
output2 = self.sigmod1(input)
return output, output2
mynn = MYNN()
output, output2 = mynn(input)
print(output)
print(output2)
運(yùn)行結(jié)果:
tensor([[[[ 1.0000, -0.5000],
[-1.0000, 3.0000]]]])
tensor([[1., 0.],
[0., 3.]])
tensor([[0.7311, 0.3775],
[0.2689, 0.9526]])
5.3 圖像非線性激活操作
圖像非線性激活操作的python代碼:
# 使用數(shù)字顯示relu和sigmod非線性激活函數(shù)的作用
import torch
import torchvision
from torch import nn
from torch.nn import ReLU
from torch.nn import Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10(root="G:\\Anaconda\\pycharm_pytorch\\learning_project\\dataset_CIFAR10",
train=False,
transform=torchvision.transforms.ToTensor(),
download=False)
dataloader = DataLoader(dataset, batch_size=64)
class MYNN(nn.Module):
def __init__(self):
super(MYNN, self).__init__()
self.relu1 = ReLU()
self.sigmod1 = Sigmoid()
def forward(self, input):
output_relu = self.relu1(input)
output_sigmod = self.sigmod1(input)
return output_relu, output_sigmod
mynn = MYNN()
writer = SummaryWriter("G:/Anaconda/pycharm_pytorch/learning_project/logs_relu")
step = 0
for data in dataloader:
imgs, targets = data
writer.add_images("input", imgs, step)
output_relu, output_sigmod = mynn(imgs)
writer.add_images("output_relu", output_relu, step)
writer.add_images("output_sigmod", output_sigmod, step)
step += 1
print(step)
writer.close()
print("Done")
代碼運(yùn)行后,終端輸入tensorboard --logdir=logs_relu
,打開tensorboard。能夠看到output圖片為池化操作后的圖像清晰度降低。
因?yàn)閞elu操作為將賦值修正為0,但圖像都是0-255的值,所以input和output_relu沒有區(qū)別;但是sigmod操作是將圖像0-255的值按一定的指數(shù)比例修正,因此會產(chǎn)生灰度變化。
6 歸一化層 Normalization Layers
學(xué)習(xí)鏈接:
https://pytorch.org/docs/stable/nn.html#normalization-layers
歸一化,也稱正則化,這一步能夠加快神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)速度。
7 全連接層 Linear Layers
全連接層,又稱線性層。
一個點(diǎn)的計算公式為:
g
1
(
x
)
=
(
k
1
?
x
1
+
b
1
)
+
(
k
2
?
x
2
+
b
2
)
+
.
.
.
+
(
k
n
?
x
n
+
b
n
)
g_1(x)=(k_1*x_1+b_1)+(k_2*x_2+b_2)+...+(k_n*x_n+b_n)
g1?(x)=(k1??x1?+b1?)+(k2??x2?+b2?)+...+(kn??xn?+bn?)
7.1 Linear()函數(shù)
CLASS torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
- in_features (int) – 每個輸入樣本的大小
- out_features (int) – 每個輸出樣本的大小
- bias (bool) – 如果設(shè)置為False,該層將不會學(xué)習(xí)加性偏差(默認(rèn)值:True)。
import torchvision
import torch
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10(root="G:\\Anaconda\\pycharm_pytorch\\learning_project\\dataset_CIFAR10",
train=False,
transform=torchvision.transforms.ToTensor(),
download=False)
dataloader = DataLoader(dataset, batch_size=64)
class MYNN(nn.Module):
def __init__(self):
super(MYNN, self).__init__()
self.linear1 = Linear(196608, 10)
def forward(self, input):
output = self.linear1(input)
return output
mynn = MYNN()
for data in dataloader:
imgs, targets = data
print("imgs.shape:")
print(imgs.shape)
output1 = torch.reshape(imgs, (1, 1, 1, -1)) # 數(shù)據(jù)變形
print("output1.shape:")
print(output1.shape)
output2 = mynn(output1) # 線性化
print("output2.shape:")
print(output2.shape)
output3 = torch.flatten(imgs) # 數(shù)據(jù)展平
print("output3.shape:")
print(output3.shape)
output4 = mynn(output3) # 線性化
print("output4.shape:")
print(output4.shape)
代碼運(yùn)行結(jié)果(部分):
imgs.shape:
torch.Size([64, 3, 32, 32])
output1.shape:
torch.Size([1, 1, 1, 196608])
output2.shape:
torch.Size([1, 1, 1, 10])
output3.shape:
torch.Size([196608])
output4.shape:
torch.Size([10])
8 損失函數(shù) Loss Functions
損失函數(shù)(Loss Function)是在機(jī)器學(xué)習(xí)和深度學(xué)習(xí)中使用的一種衡量模型預(yù)測結(jié)果與實(shí)際標(biāo)簽之間差異的函數(shù)。它用于衡量模型的預(yù)測值與真實(shí)值之間的誤差,并作為模型訓(xùn)練的優(yōu)化目標(biāo)。
損失值為輸出值和目標(biāo)值之差,越小越好。
損失函數(shù)的作用:
(1)計算實(shí)際輸出和目標(biāo)之間的差距。
(2)為我們反向傳播的更新輸出提供一定的依據(jù)。
8.1 L1Loss() L1損失函數(shù)
計算輸入x和目標(biāo)y對應(yīng)元素之間的差值。
CLASS torch.nn.L1Loss(reduction=‘mean’)
- reduction (str, 可選) – 指定要應(yīng)用于輸出的縮減:
none
、mean
、sum
。默認(rèn)值為mean
。 -
none
:不進(jìn)行縮減。 -
mean
:輸出的總和將除以輸出中的元素數(shù)量。 -
sum
:輸出將被求和。
python代碼:
import torch
from torch.nn import L1Loss
inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
targets = torch.tensor([1, 2, 5], dtype=torch.float32)
inputs = torch.reshape(inputs, (1, 1, 1, 3))
targets = torch.reshape(targets, (1, 1, 1, 3))
loss1 = L1Loss(reduction="mean")
result1 = loss1(inputs, targets)
loss2 = L1Loss(reduction="sum")
result2 = loss2(inputs, targets)
print(inputs)
print(targets)
print(result1)
print(result2)
輸出結(jié)果:
tensor([[[[1., 2., 3.]]]])
tensor([[[[1., 2., 5.]]]])
tensor(0.6667)
tensor(2.)
8.2 MSELoss() 平方差函數(shù)
計算輸入x和目標(biāo)y之間每個元素的誤差的平方(L2范數(shù)的平方)。
CLASS torch.nn.MSELoss(reduction=‘mean’)
- reduction (str, 可選) – 指定要應(yīng)用于輸出的縮減:
none
、mean
、sum
。默認(rèn)值為mean
。 -
none
:不進(jìn)行縮減。 -
mean
:輸出的總和將除以輸出中的元素數(shù)量。 -
sum
:輸出將被求和。注意:size_average和reduce正在被棄用的過程中,同時,指定這兩個參數(shù)中的任何一個都會覆蓋reduction。
python代碼如下:
import torch
from torch.nn import MSELoss
inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
targets = torch.tensor([1, 2, 5], dtype=torch.float32)
inputs = torch.reshape(inputs, (1, 1, 1, 3))
targets = torch.reshape(targets, (1, 1, 1, 3))
loss3 = MSELoss() # 誤差的平方
result3 = loss3(inputs, targets)
print(result3)
輸出結(jié)果:
tensor([[[[1., 2., 3.]]]])
tensor([[[[1., 2., 5.]]]])
tensor(1.3333)
8.3 CrossEntropyLoss() 交叉熵函數(shù)
CLASS torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction=‘mean’, label_smoothing=0.0)
-
weight (Tensor, 可選) – 給每個類(CLASS)手動調(diào)整權(quán)重。如果給定,它的張量的大小必須是C
-
size_average (bool, 可選) – 已棄用(見reduction)。默認(rèn)情況下,損失是批處理中每個損失元素的平均損失。注意,對于某些損失,每個樣本有多個元素。如果字段size_average設(shè)置為False,則對每個小批量的損失值求和。reduce為False時忽略。默認(rèn)值為True。
-
ignore_index (int, 可選) – 指定一個被忽略且不影響輸入梯度的目標(biāo)值。當(dāng)size_average為True時,損失函數(shù)是未被忽略的目標(biāo)的平均值。注意,ignore_index僅適用于目標(biāo)包含類索引時。
-
reduce (bool, 可選) – 已棄用(見reduction)。默認(rèn)情況下,根據(jù)size_average對每個minibatch的觀測值進(jìn)行平均或求和。當(dāng)reduce為False時,為每個批處理元素返回一個損失值并忽略size_average。默認(rèn)值為True。
-
reduction (str, 可選) – 指定要應(yīng)用于輸出的縮減:
none
、mean
、sum
。none
:不進(jìn)行縮減。mean
:獲取輸出的加權(quán)平均值。sum
:對輸出進(jìn)行求和。注意:size_average和reduce正在被棄用的過程中,同時,指定這兩個參數(shù)中的任何一個都會覆蓋reduction。默認(rèn)值為mean
。 -
label_smoothing (float, 可選) – 取值范圍在[0.0, 1.0]的浮點(diǎn)數(shù)。指定計算損失時的平滑量,0.0表示不平滑。如重新思考計算機(jī)視覺的Inception架構(gòu)中所述,目標(biāo)變成了原始真實(shí)值和均勻分布的混合。默認(rèn)值為0.0。
python代碼:
import torch
from torch.nn import CrossEntropyLoss
x = torch.tensor([0.1, 0.2, 0.3])
y = torch.tensor([1])
x = torch.reshape(x, (1, 3))
loss_cross = CrossEntropyLoss()
result_cross = loss_cross(x, y)
print(result_cross)
輸出結(jié)果:
tensor(1.1019)
8.3.1 神經(jīng)網(wǎng)絡(luò)中的使用
將一張圖片imgs
輸入到神經(jīng)網(wǎng)絡(luò)中,通過一系列的卷積、池化、展平、歸一化后得到outputs
,包含10個參數(shù),表示網(wǎng)絡(luò)識別對應(yīng)圖像內(nèi)容的概率。將outputs
和圖片的target
代入CrossEntropyLoss()損失函數(shù),計算得到損失值。
python代碼如下:
import torchvision
import torch
from torch import nn
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential,CrossEntropyLoss
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10(root="G:\\Anaconda\\pycharm_pytorch\\learning_project\\dataset_CIFAR10",
train=False,
transform=torchvision.transforms.ToTensor(),
download=False)
dataloader = DataLoader(dataset, batch_size=1)
class MYNN(nn.Module):
def __init__(self):
super(MYNN, self).__init__()
self.model1 = Sequential(
Conv2d(3, 32, 5, padding=2, stride=1),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2, stride=1),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2, stride=1),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self, x):
x = self.model1(x)
return x
loss = CrossEntropyLoss()
mynn = MYNN()
for data in dataloader:
imgs, targets = data
outputs = mynn(imgs)
result_loss = loss(outputs, targets)
print(outputs) # 神經(jīng)網(wǎng)絡(luò)輸出
print(targets) # 目標(biāo)
print(result_loss) # 損失函數(shù)-交叉熵計算結(jié)果
運(yùn)行結(jié)果(部分):文章來源:http://www.zghlxwxcb.cn/news/detail-620244.html
tensor([[-0.1174, 0.0607, -0.0290, 0.0328, -0.0593, 0.1143, 0.0187, -0.0872,
0.1212, 0.0344]], grad_fn=<AddmmBackward0>)
tensor([0])
tensor(2.4319, grad_fn=<NllLossBackward0>)
tensor([[-1.1158e-01, 2.9356e-02, -4.1232e-02, 2.3896e-02, -1.0031e-01,
9.5460e-02, -4.1537e-07, -6.9785e-02, 1.1017e-01, 9.5974e-03]],
grad_fn=<AddmmBackward0>)
tensor([3])
tensor(2.2758, grad_fn=<NllLossBackward0>)
8.4 補(bǔ)充:反向傳播
result_loss.backward() :反向傳播函數(shù),計算損失值的梯度grad。
以便優(yōu)化器(optimizer)以梯度下降法對網(wǎng)絡(luò)中的weight和bias進(jìn)行優(yōu)化。文章來源地址http://www.zghlxwxcb.cn/news/detail-620244.html
到了這里,關(guān)于pytorch(6)——神經(jīng)網(wǎng)絡(luò)基本骨架nn.module的使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!