一、torchvision中的数据集使用
CIFAR10
结果,图片展示为一只猫
二、DataLoader的使用
结果
测试集当中的第一个数据是一个三通道(RGB),是个彩色的图片,尺寸为32*32 ,对应的target是3
batch_size=4就是从当中去取test_data[0]、test_data[1]、test_data[2]、test_data[3],把对应的img打包
结果
由于batch_size=4,所以将四个进行打包,torch.Size([4,3,32,32])表示从dataset当中取了4张图片,三通道,32*32,同时还把4个target进行打包,每张图片对应的5、9、0、0
用img.add()查看图片
结果可以发现图片被四个四个打包在一起
当改变batch_size=64时,也许改变tag
发现最后一张图不够64,这是因为drop_last=False的缘故将drop_last=True(注意也要修改tag)则可得到最后一步step155为64张,把step=156舍去
shuffle=False表示每次抓取的数据是一样的
shuffle=True 【 test_loader = DataLoader(dataset=test_data,batch_size=64,shuffle=True , num_workers=0,drop_last=True) 】时
相同的步骤但图片顺序不同
三、神经网络骨架的基本搭建(torch.nn中containers中module)
定义一个类Model,继承父类nn.Module,在__init__()函数与forward()函数中写必要的条件
神经网络前向传播
自己搭建
调用
四、卷积操作
1、理解stride
代码
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.shape)
print(kernel.shape)
output = F.conv2d(input,kernel,stride=1)
print(output)
output2 = F.conv2d(input,kernel,stride=2)
print(output2)
结果
2、理解padding
output3 = F.conv2d(input,kernel,stride=1,padding=1 )
print(output3)
结果
五、神经网络-卷积层
-
in_channels (int) – Number of channels in the input image
-
out_channels (int) – Number of channels produced by the convolution
-
stride (int or tuple, optional) – Stride of the convolution. Default: 1
-
padding (int, tuple or str, optional) – Padding added to all four sides of the input. Default: 0
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("./data",train=False ,transform=torchvision.transforms.ToTensor(),
download=True )#需要测试数据集,把数据类型转换成tensor数据类型
dataloader = DataLoader(dataset,batch_size=64) #把数据集放在dataloader中加载
class Tudui(nn.Module):
def __init__(self):
super(Tudui,self).__init__()
self.conv1 = Conv2d(3,6,3,1,0)
def forward(self,x):
x = self.conv1(x)
return x
tudui = Tudui()
for data in dataloader:
imgs,targets = data
output = tudui(imgs)
print(imgs.shape)
print(output.shape)
dataloader加载 batch_size=64,in_channels=3(3层彩色图像),32*32大小,经过卷积之后in_channels=6,30*30大小
通过tensorboard查看
tudui = Tudui()
writer = SummaryWriter("./llogs")
step=0
for data in dataloader:
imgs,targets = data
output = tudui(imgs)
print(imgs.shape)
print(output.shape)
# torch.Size([64, 3, 32, 32])
writer.add_images("input",imgs,step)
# torch.Size([64, 6, 30, 30]) ->[xxx,3,30,30]
output = torch.reshape(output,(-1,3,30,30))
writer.add_images("output",output,step)
step = step+1
由于卷积过后图像变为6通道,无法显示,这里将输出图像从6 通道变为3通道,多余的像素点也显示,故输出有64*2张图
六、神经网络-最大池化的使用
默认padding为kernel_size的大小,即为3
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.shape)
class Tudui(nn.Module):
def __init__(self):
super(Tudui,self ).__init__()
self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode= True)
def forward(self,input):
output = self.maxpool1(input)
return output
tudui = Tudui()
output = tudui(input)
print(output)
当ceil_mode= False时
用tensorboard查看
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("data",train=False, download=True,
transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset,batch_size=64)
class Tudui(nn.Module):
def __init__(self):
super(Tudui,self ).__init__()
self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode= False )
def forward(self,input):
output = self.maxpool1(input)
return output
tudui = Tudui()
writer = SummaryWriter("logs_maxpool")
step = 0
for data in dataloader:
imgs,targets=data
writer.add_images("input",imgs,step)
output = tudui(imgs)
writer.add_images("output",output,step)
step = step+1
writer.close()
七、神经网络-非线性激活
ReLU — PyTorch 2.4 documentationhttps://pytorch.org/docs/stable/generated/torch.nn.ReLU.html#relu
参数inplace的作用
import torch
from torch import nn
from torch.nn import ReLU
input = torch.tensor([[1,-0.5],
[-1,3]])
input = torch.reshape(input,(-1,1,2,2))
print(input.shape)
class Tudui(nn.Module):
def __init__(self):
super(Tudui ,self).__init__()
self.relu1 = ReLU()
def forward(self,input):
output = self.relu1(input)
return output
tudui = Tudui()
output = tudui(input)
print(output)
可以看出来-0.5 -1都变为0
nn.ReLU在图像显示上不明显,换为nn.LogSigmoid
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
input = torch.tensor([[1,-0.5],
[-1,3]])
input = torch.reshape(input,(-1,1,2,2))
print(input.shape)
dataset = torchvision.datasets.CIFAR10("../data",train=False,download=True,
transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset,batch_size=64)
class Tudui(nn.Module):
def __init__(self):
super(Tudui ,self).__init__()
self.relu1 = ReLU()
self.sigmoid1 = Sigmoid()
def forward(self,input):
output = self.sigmoid1(input)
return output
tudui = Tudui()
step = 0
writer = SummaryWriter("../loga_relu")
for data in dataloader:
imgs,targets = data
writer.add_images("input",imgs,global_step=step)
output = tudui(imgs)
writer.add_images("output",output,step)
step += 1
writer.close()
八、神经网络-线性层及其它层介绍
import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("../data",train=False, transform=torchvision.transforms.ToTensor(),
download=True )
dataloader = DataLoader(dataset,batch_size=64)
class Tudui(nn.Module):
def __init__(self):
super(Tudui,self).__init__()
self.linear1 = Linear(196608,10)
def forward(self,input):
output = self.linear1(input)
return output
tudui = Tudui()
for data in dataloader:
imgs,targets = data
print(imgs.shape)
output = torch.reshape(imgs,(1,1,1,-1))
print(output.shape)
output = tudui(output)
print(output.shape)
可用 output = torch.flatten(imgs) 展平
九、神经网络-搭建小实战和sequential的使用
Sequential — PyTorch 2.4 documentationhttps://pytorch.org/docs/stable/generated/torch.nn.Sequential.html#sequentialCIFAR10的 网络结构
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
class Yebi(nn.Module):
def __init__(self):
super(Yebi, self).__init__()
self.conv1 = Conv2d(3,32,5,padding=2)
self.maxpool1 = MaxPool2d(2)
self.conv2 = Conv2d(32,32,5,padding=2)
self.maxpool2 = MaxPool2d(2)
self.conv3 = Conv2d(32,64,5,padding=2)
self.maxpool3 = MaxPool2d(2)
self.flatten = 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.flatten (x)
x = self.linear1 (x)
x = self.linear2 (x)
return x
tudui = Yebi()
print(tudui)
sequential的使用
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
class Yebi(nn.Module):
def __init__(self):
super(Yebi, self).__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
tudui = Yebi()
print(tudui)
十、损失函数与反向传播
L1Loss
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)) #batch_size=1,1通道,1行3列
targets = torch.reshape(targets,(1,1,1,3))
loss = L1Loss()
result = loss(inputs, targets)
print(result)
[(1-1)+(2-2)+(5-3)] /3
L1Loss()可以指定计算方法,如 loss = L1Loss(reduction='sum')
(1-1)+(2-2)+(5-3)
则结果为
MSELoss
import torch
from torch import nn
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)) #batch_size=1,1通道,1行3列
targets = torch.reshape(targets,(1,1,1,3))
loss = L1Loss(reduction='sum')
result = loss(inputs, targets)
loss_mse = nn.MSELoss()
result_mse = loss_mse(inputs,targets)
print(result)
print(result_mse)
结果
CrossEntropyLoss
import torch
from torch import nn
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)) #batch_size=1,1通道,1行3列
targets = torch.reshape(targets,(1,1,1,3))
loss = L1Loss(reduction='sum')
result = loss(inputs, targets)
loss_mse = nn.MSELoss()
result_mse = loss_mse(inputs,targets)
print(result)
print(result_mse)
x = torch.tensor([0.1,0.2,0.3])
y = torch.tensor([1])
x = torch.reshape(x,(1,3))
loss_cross = nn.CrossEntropyLoss()
result_cross = loss_cross(x,y)
print(result_cross)
根据一个网络模型,用CrossEntropyLoss计算实际输出和目标之间的差距
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("../data",train=False,transform=torchvision.transforms.ToTensor(),
download=True)
dataloader = DataLoader(dataset, batch_size=1)
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__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 = nn.CrossEntropyLoss ()
tudui = Tudui()
for data in dataloader:
imgs,targets = data
outputs = tudui(imgs)
result_loss = loss(outputs,targets)
print(result_loss)
计算的结果就是神经网络输出 与真实输出之间的误差
调用损失函数的backwards,会得到反向传播,可以求出每个需要调节的参数,以及每个参数对应的梯度,然后利用优化器,优化器根据梯度,对参数进行调整,达到误差整体降低的目的。
十一、优化器
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("../data",train=False,transform=torchvision.transforms.ToTensor(),
download=True)
dataloader = DataLoader(dataset, batch_size=1)
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__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 = nn.CrossEntropyLoss ()
tudui = Tudui()
optim = torch.optim.SGD(tudui.parameters() ,0.01)
for data in dataloader:
imgs,targets = data
outputs = tudui(imgs)
result_loss = loss(outputs,targets) #计算网络和目标的差距
optim.zero_grad() #把网络中每个可调节的参数设为0
result_loss.backward() #得到每一个可调节参数对应的梯度
optim.step() #调用优化器 对每个参数进行调优
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("../data",train=False,transform=torchvision.transforms.ToTensor(),
download=True)
dataloader = DataLoader(dataset, batch_size=1)
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__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 = nn.CrossEntropyLoss ()
tudui = Tudui()
optim = torch.optim.SGD(tudui.parameters() ,0.01)
for epoch in range(20):
running_loss = 0.0
for data in dataloader:
imgs,targets = data
outputs = tudui(imgs)
result_loss = loss(outputs,targets) #计算网络和目标的差距
optim.zero_grad() #把网络中每个可调节的参数设为0
result_loss.backward() #得到每一个可调节参数对应的梯度
optim.step() #调用优化器 对每个参数进行调优
running_loss = running_loss + result_loss #每一轮误差的总和
print(running_loss)
可以看到每一轮的误差总和在减小