本文章是通过观看B站视频PyTorch深度学习快速入门教程而整理的笔记
1. Python学习中的两大法宝
1.1 dir()
1.2 help()
2. 加载数据
2.1 Dataset:提供一种方式去获取数据及其label
如何获取每一个数据及其label
告诉我们总共有多少的数据
用法:from torch.utils.data import Dataset
主要是重写__getitem__和__len__
2.2 Dataloader:为后面的网络提供不同的数据形式
3. TensorBoard
tensorboard --logdir=事件文件所在文件夹名 --port=指定打开端口号
例子:tensorboard --logdir=logs --port=6007
3.1 add_scalar()的使用
例子1:绘制y=2x图像
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs") # tensorboard文件地址
# writer.add_image()
# 绘制y=2x
for i in range(100):
writer.add_scalar("y_2x",2*i,i) # 图像名称 y轴的值 x轴的值
writer.close()
3.2 add_image()的使用
例子:显示一张图片
from torch.utils.tensorboard import SummaryWriter
from PIL import Image
import numpy as np
writer = SummaryWriter("logs")
image_path = "code/data/hymenoptera_data/train/ants/5650366_e22b7e1065.jpg"
img_PIL = Image.open(image_path)
img_array = np.array(img_PIL)
# print(img_array.shape)
writer.add_image("test",img_array,1,dataformats="HWC")
writer.close()
3.3 add_graph()计算图的意思
4. 常见的Transforms
4.1 transforms.ToTensor()
例子:
from os import write
from torchvision import transforms
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
img_path = "code/data/hymenoptera_data/train/ants/0013035.jpg"
img= Image.open(img_path) #<class 'PIL.JpegImagePlugin.JpegImageFile'>
import cv2
cv_img = cv2.imread(img_path) # <class 'numpy.ndarray'>
writer = SummaryWriter("logs")
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)
writer.add_image("Tensor_img",tensor_img)
writer.close()
4.2 transforms.Normalize(均值,方差)
from os import write
from torchvision import transforms
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
img_path = "code/data/hymenoptera_data/train/ants/0013035.jpg"
img= Image.open(img_path) #<class 'PIL.JpegImagePlugin.JpegImageFile'>
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)
writer = SummaryWriter("logs")
trans_norm = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
img_norm = trans_norm(tensor_img) # 输入的数据类型只能是tensor
writer.add_image("Normalize",img_norm)
writer.close()
4.3 transforms.Resize(PIL数据类型的图片)
from torchvision import transforms
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
img_path = "code/data/hymenoptera_data/train/ants/0013035.jpg"
img= Image.open(img_path) #<class 'PIL.JpegImagePlugin.JpegImageFile'>
tensor_trans = transforms.ToTensor()
writer = SummaryWriter("logs")
trans_resize = transforms.Resize((512,512))
img_resize = trans_resize(img) # 输入的数据类型是PIL
img_resize = tensor_trans(img_resize)
writer.add_image("Resize",img_resize,1)
writer.close()
4.4 Compose([transforms参数1,transforms参数2...])
参数需要是一个列表,后面一个参数的输入数据类型要跟前面一个参数的输出数据类型一致
from torchvision import transforms
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
img_path = "code/data/hymenoptera_data/train/ants/0013035.jpg"
img= Image.open(img_path) #<class 'PIL.JpegImagePlugin.JpegImageFile'>
tensor_trans = transforms.ToTensor()
writer = SummaryWriter("logs")
trans_resize_2 = transforms.Resize(512)
trans_compose = transforms.Compose([trans_resize_2,tensor_trans])
img_resize_2 = trans_compose(img)
writer.add_image("Resize",img_resize_2,1)
writer.close()
5. torchvision中的数据集使用
torchvision.datasets中有很多可以直接使用的数据集,详细使用方法见pytorch官方文档,下面以CIFAR10数据集为例:
import torchvision
dataset_transform = torchvision.transforms.Compose([
torchvision.transforms.ToTensor()
])
train_set = torchvision.datasets.CIFAR10("./data",train=True,transform=dataset_transform,download=True)
test_set = torchvision.datasets.CIFAR10("./data",train=False,transform=dataset_transform,download=True)
print(test_set[0])
6. DataLoader的使用
import torchvision
from torch.utils.data import DataLoader
test_set = torchvision.datasets.CIFAR10("./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
test_loader = DataLoader(dataset = test_set,batch_size = 4,shuffle = True,num_workers = 0,drop_last = False)
for data in test_loader:
imgs,targets = data
print(imgs.shape)
print(targets)
7. nn.Module的使用
8. 神经网络
8.1 卷积层
from torch.nn import Conv2d
8.2 最大池化层
from torch.nn import MaxPool2d
8.3 非线性激活
ReLU( )
Sigmoid( )
8.4 其他层
Normalization层
Recurrent层
Transformer层
Linear层
Dropout层
9. 损失函数与反向传播
Loss的两个作用:
- 计算实际输出和目标之间的差距
- 为我们更新输出提供一定的依据(反向传播)
优化器:torch.optim
loss.backward():求出梯度
optimizer.step():反向传播
10. 网络模型
模型的使用与修改
模型的保存与读取
import torch
import torchvision
vgg16 = torchvision.models.vgg16(pretrained=False)
# 保存方式1 不仅保存了网络模型的结构,也保存了网络模型的参数
torch.save(vgg16,'vgg16_model1.pth')
model1 = torch.load('vgg16_model1.pth') # 加载 模型结构 and 模型参数
# print(model1)
# 保存方式2 只保存模型参数(官方推荐)
torch.save(vgg16.state_dict(),'vgg16_model2.pth')
vgg16 = torchvision.models.vgg16(pretrained=False) # 定义模型
vgg16.load_state_dict(torch.load('vgg16_model2.pth')) # 加载 模型参数
# print(vgg16)
11. 完整的模型套路
11.1 完整的模型训练套路(一个例子说明)
from os import O_TRUNC
import torch
import torch.nn as nn
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 准备数据集
train_data = torchvision.datasets.CIFAR10(root='./data',train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10(root='./data',train=False,transform=torchvision.transforms.ToTensor(),download=True)
train_data_size = len(train_data)
test_data_size = len(test_data)
# 利用DataLoader加载数据集
train_dataloader = DataLoader(train_data,batch_size=64)
test_dataloader = DataLoader(test_data,batch_size=64)
# 搭建网络模型
class T_model(nn.Module):
def __init__(self):
super().__init__()
self.model = nn.Sequential(
nn.Conv2d(3,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,64,5,1,2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64*4*4,64),
nn.Linear(64,10)
)
def forward(self,x):
return self.model(x)
# 创建网络模型
tmodel = T_model()
# 损失函数
loss_fn = nn.CrossEntropyLoss()
# 优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(tmodel.parameters(),lr=learning_rate)
# 设置训练网络的一些参数
total_train_step = 0 # 记录训练的次数
total_test_step = 0 # 记录测试的次数
epoch = 10 # 训练的轮数
# 添加tensorboard
writer = SummaryWriter('./logs')
for i in range(epoch):
print('-----第 {} 轮训练开始-----'.format(i+1))
# 训练步骤开始
tmodel.train()
for data in train_dataloader:
imgs,targets = data
outputs = tmodel(imgs)
loss = loss_fn(outputs,targets)
# 优化器优化模型
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_train_step += 1
if total_train_step % 100 == 0:
print("训练次数:{}, Loss:{}".format(total_train_step,loss.item()))
writer.add_scalar("train_loss",loss.item(),total_train_step)
# 测试步骤开始
tmodel.eval()
total_test_loss = 0
total_accuracy = 0
with torch.no_grad():
for data in test_dataloader:
imgs,targets = data
outputs = tmodel(imgs)
loss = loss_fn(outputs,targets)
total_test_loss += loss.item()
accuacy = (outputs.argmax(1) == targets).sum()
total_accuracy += accuacy
print("整体测试集上的Loss:{}".format(total_test_loss))
print("整体测试集上的Accuracy:{}".format(total_accuracy/test_data_size))
writer.add_scalar("test_loss",total_test_loss,total_test_step)
writer.add_scalar("test_accuracy",total_accuracy,total_test_step)
total_test_step += 1
torch.save(tmodel,"./models/tmodel_{}.pth".format(i))
print('模型已保存')
writer.close()
11.2 GPU训练
import torch
# 方法一
if torch.cuda.is_available():
xxx.cuda()
# 方法二
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
xxx.to(device)
免费算力平台:google colab
在GPU上训练的模型加载到CPU时需要映射到CPU,设置map_location=torch.device('cpu')
11.3 完整的模型验证套路
利用已训练好的模型,提供输入来验证
import torch
from PIL import Image
import torchvision
import torch.nn as nn
image_path = "data/dog.png"
image = Image.open(image_path)
image = image.convert('RGB')
transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),
torchvision.transforms.ToTensor()])
image = transform(image)
# print(image.shape)
# 网络模型
class T_model(nn.Module):
def __init__(self):
super().__init__()
self.model = nn.Sequential(
nn.Conv2d(3,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,64,5,1,2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64*4*4,64),
nn.Linear(64,10)
)
def forward(self,x):
return self.model(x)
# 加载网络模型
model = torch.load("models/tmodel_9.pth") # 加载训练好的网络模型
# print(model)
image = torch.reshape(image,(1,3,32,32))
model.eval()
with torch.no_grad():
output = model(image) # 预测
print(output)
result =output.argmax(1)
print(result)