1.nn.Moudule
torch.nn是专门为神经网络设计的模块化接口. nn构建于autograd之上,可以用来定义和运行神经网络。
nn.Module是nn中十分重要的类,包含网络各层的定义及forward方法。
在自己定义自己的网络时候:
1.需要继承nn.Moudule ,并且需要重写forward方法。
2.一般把网络中具有可学习参数的层放在构造函数__init__()中。
import torch
from torch import nn
class Cangmi(nn.Module):
def __init__(self) -> None:
super().__init__()
def forward(self,input):
output=input+1
return output
cangmi=Cangmi()
x=torch.tensor(1.0)
output=cangmi(x)
print(output)
2. 卷积层
nn支持一维卷积,二维卷积以及三维卷积。
一般最常用的是二维卷积。
CLASStorch.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 输入的通道数
out_channels 输出的通道数
kernel_size 卷积核的大小
stride 步长 可以是一个数 也可以是元组
padding 填充大小
dilation 空洞卷积(膨胀卷积
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
#采用CIFAR10的数据集
dataset=torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor())
dataloader=DataLoader(dataset=dataset,batch_size=64,shuffle=True,num_workers=0)
class Net(nn.Module):
def __init__(self) -> None:
super().__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
net=Net()
print(net)
writer=SummaryWriter("logs")
step=0
for data in dataloader:
imgs,target=data
output=net(imgs)
writer.add_images("input",imgs,step)
output=torch.reshape(output,(-1,3,30,30)) #如果想用tensorboard显示 那么如果通道数为6的话
#会无法显示 所以改成通道数为3的 第一项设为-1 让代码可以自己计算batch_size
print(output.size())
writer.add_images("output",output,step)
step=step+1
3.最大池化层
CLASStorch.nn.MaxPool2d(kernel_size, stride=None, padding=0,
dilation=1, return_indices=False, ceil_mode=False)
- kernel_size 池化核大小
- padding 填充
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="./dataset",train=False,transform=torchvision.transforms.ToTensor())
dataloader=DataLoader(dataset=dataset,batch_size=64,shuffle=True)
class Net(nn.Module):
def __init__(self) :
super().__init__()
self.maxpool=MaxPool2d(kernel_size=3,ceil_mode=True)
def forward(self,input):
output=self.maxpool(input)
return output
writer=SummaryWriter("logs")
step=0
net=Net()
for data in dataloader:
img,target=data
writer.add_images("input",img,step)
output=net(img)
writer.add_images("output",output,step)
step=step+1
writer.close()
4.非线性激活
非线性激活函数有很多种 以ReLU为例:
CLASStorch.nn.ReLU(inplace=False)
import torch
import torchvision
from torch import nn
from torch.nn import ReLU, Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset=torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor())
dataloader=DataLoader(dataset=dataset,batch_size=64,shuffle=True)
class Net(nn.Module):
def __init__(self) -> None:
super().__init__()
self.relu1=ReLU()
def forward(self,input):
output=self.relu1(input)
return output
net=Net()
writer=SummaryWriter("logs")
step=0
for data in dataloader:
img,target=data
writer.add_images("input",img,step)
output=net(img)
writer.add_images("output", output, step)
step=step+1
writer.close()
5. 线性层
CLASStorch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
m = nn.Linear(20, 30)
input = torch.randn(128, 20)
output = m(input)
# output = (128 * 20) * (30 * 20)^T + (if bias (1,30) ,else: 0
print(output.size())
torch.Size([128, 30])
6.Sequential的使用
将nn的层连接起来
class Net(nn.Module):
def __init__(self) -> None:
super().__init__()
self.model1=Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self,x):
x=self.model1(x)
return x
7.损失函数
损失函数(loss function)是用来估量模型的预测值f(x)与真实值Y的不一致程度,它是一个非负实值函数,通常使用L(Y, f(x))来表示,损失函数越小,模型的鲁棒性就越好。
损失函数是经验风险函数的核心部分,也是结构风险函数重要组成部分。基本用法:
criterion=LossCriterion() #构造函数
loss=criterion(x,y) #调用标准
import torch
import torchvision
from torch import nn
from torch.nn import L1Loss, MSELoss, CrossEntropyLoss, Conv2d, Sequential, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader
dataset=torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor())
dataloader=DataLoader(dataset=dataset,batch_size=1,shuffle=True)
class Net(nn.Module):
def __init__(self) -> None:
super().__init__()
self.model1=Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self,x):
x=self.model1(x)
return x
loss=CrossEntropyLoss()# 交叉熵损失函数
net=Net()
for data in dataloader:
img,target=data
output=net(img)
result_loss=loss(output,target)
result_loss.backward() # 得到梯度
8.优化器
optimizer=torch.optim.SGD(net.parameters(),lr=0.01)
lr(float,可选)—学习率
momentum(float,可选,默认0)—动量因子
weight_decay(float,可选,默认0)—权重衰减
梯度置零optimizer.zero_grad()
optimizer_zero_grad()意思是把梯度清零,把loss关于weight的导数变成0
反向传播 loss.backward()
PyTorch的反向传播(即tensor.backward())是通过autograd包来实现的,autograd包会根据tensor进行过的数学运算来自动计算其对应的梯度。
具体来说,torch.tensor是autograd包的基础类,如果你设置tensor的requires_grads为True,就会开始跟踪这个tensor上面的所有运算。
如果做完运算后使用tensor.backward(),所有的梯度就会自动运算,tensor的梯度将会累加到它的.grad属性里面去。如果没有进行tensor.backward()的话,梯度值将会是None,因此loss.backward()要写在optimizer.step()之前。
更新参数
optimizer.step()
import torch
import torchvision
from torch import nn
from torch.nn import L1Loss, MSELoss, CrossEntropyLoss, Conv2d, Sequential, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader
dataset=torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor())
dataloader=DataLoader(dataset=dataset,batch_size=1,shuffle=True)
class Net(nn.Module):
def __init__(self) -> None:
super().__init__()
self.model1=Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self,x):
x=self.model1(x)
return x
loss=CrossEntropyLoss()
net=Net()
optim=torch.optim.SGD(net.parameters(),lr=0.01)
for epoch in range(20):
running_loss=0.0
for data in dataloader:
img,target=data
output=net(img)
result_loss=loss(output,target)
optim.zero_grad() #梯度更新为0
result_loss.backward()# 得到梯度
optim.step()
running_loss=running_loss+result_loss
print(running_loss)