深度学习代码框架-基于pytorch
课程学习链接:https://www.bilibili.com/video/BV1hE411t7RN?p=12&vd_source=7ceb7ef632bd249b5aacf41c00b5ea12
文章目录
数据集的构建-Dataset
可以自定义一个数据集对象,必须继承Dataset类!!,需要重写__getitem__函数和__len__函数。
自定义的数据集类:
from torch.utils.data import Dataset
from PIL import Image
import os
class Mydata(Dataset):
def __init__(self, root_dir, label_dir):
self.root_dir = root_dir
# self.root_dir = "dataset/train"
self.label_dir = label_dir
# self.label_dir = "ants"
self.img_list = os.listdir(os.path.join(root_dir, label_dir))
'''
os.path.join(root_dir, label_dir) = "dataset/train/ants" 为蚂蚁图片的相对路径
os.listdir()函数返回路径下的文件或文件夹列表
[918932.jpg,7894398,jpg,...,fadio.jpg]
'''
def __getitem__(self, idx):
img_name = self.img_list[idx]
img_path = os.path.join(self.root_dir, self.label_dir, img_name)
img = Image.open(img_path)
label = self.label_dir
return img, label
def __len__(self):
return len(self.img_path)
通过__init()函数中的文件名列表,可以在__getitem()方法中通过index获取图片
__getitem__函数的作用:在类实例化后,可以通过索引调用getitem函数
ants_dataset = Mydata("dataset/train", "ants")
img , label = ants_dataset[0]
数据加载器-Dataloader
dataloader用于将构建的数据集中的数据分批次的送入模型中。DataLoader类返回一个迭代器实例,可以通过迭代的方式获取实例中的数据和标签。
参数如下:
- dataset:指定数据集
- batch_size:指定一次将数据集中的几条样本送入神经网络
- shuffle:指定每一次epoch中是否先打乱,再以一个batch大小取数据
- num_work:用于多进程运行
- drop_last:指定最后剩下的不足batch_size数量的样本是否舍弃
代码如下:
import torchvision
from torch.utils.data import DataLoader
#用于获取torchvison中自带的数据集
test_data = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor())
test_loader = DataLoader(dataset=test_data, batch_size=4, shuffle=True, num_workers=0, drop_last=False)
#迭代的获取数据,data是一个二维列表,第0维代表数据,第一维代表标签
for data in test_loader:
print(data)
imgs, targets = data
print(imgs.shape)
print(targets)
dataset与dataloader
1.dataloader必须以dataset类为输入
2.sampler只负责输出数据集位置索引列表(可以是所有样本,也可以是一个batch的样本),而collate_fn可以输出real_batch(real_batch即为模型真正的输入),collate_fn有一个默认参数就是一个batch的数据,它通过sampler产出的index list去dataset中取得的(使用getitem方法)。而且collate_fn函数还得实现batch数据的重新组织(从batch->real_batch),例如通过默认参数的到的batch是这样的:[数据1,标签],[数据2,标签]…,要把它变为[数据1,数据2…] [标签,标签2…]
神经网络的基本骨架-nn.module
可以自定义一个模型类,必须继承Model类。在__init__()函数中,需要初始化父类(Model),同时,在定义forward()函数用于前向传播。
一般forward()输出预测值,传入loss_object对象
演示代码如下:
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
class Tutui(nn.Module):
def __init__(self) -> None:
super().__init__()
self.model = Sequrntial(
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, input):
output = self.model(input)
return output
#实例化土推模型
tutui = Tutui()
#把input传入神经网络,自动调用forward方法
#输入input还未定义
output = tutui(input)
print(output)
损失函数、反向传播、优化器
损失函数
很简单,直接实例化一个损失函数类,如L1Loss,输入预测值和标签,计算损失 l o s s loss loss
代码如下:
import torch
from torch.nn import L1Loss
predictive_value = torch.tensor([1, 2, 3], dtype=torch.float32)
label = torch.tensor([1, 2, 5], dtype=torch.float32)
predictive_value = torch.reshape(predictive_value, (1, 1, 1, 3))
label = torch.reshape(label, (1, 1, 1, 3))
loss_object = L1Loss()
loss_value = loss_object(predictive_value, label)
print(loss_value)
反向传播
根据得到的loss_value,调用backward方法。注意!调用backward方法的是不是创建的loss_object实例,而是得到的loss_value对象。
from torch.utils.data import Downloader
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
class Tutui(nn.Module):
def __init__(self) -> None:
super().__init__()
self.model = Sequrntial(
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, input):
output = self.model(input)
return output
dataset = torchvison.datasets.CIFAR10("./data", train=False, transform=torvison.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=1)
#交叉熵损失对象
loss_object = nn.CrossEntropyLoss()
#神经网络对象
tutui = Tutui()
for data in downloader:
imgs, targets = data
output = tutui(imgs)
#计算loss值
loss_value = loss_object(output, targets)
#反向传播!!!!!!
loss_value.backward()
优化器
优化器利用损失、反向传播反向优化模型的权重矩阵(参数)。注意!一定记得每条样本反向传播前,执行梯度清零操作optimizer.zero_grad() 。
参数优化基本步骤:
- 计算loss
- 梯度清零
- 反向传播——根据loss计算网络参数的梯度
- 优化!——根据计算的梯度对网络参数进行更新
一些参数:
- 第一个参数:设置神经网络中优化的参数,可以只优化部分层,也可以全部神经网络
- 学习率:即步长(梯度下架算法中每次走多远),一般设置 l r = 0.01 lr=0.01 lr=0.01
代码如下:
import torch
from torch.utils.data import Downloader
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
class Tutui(nn.Module):
def __init__(self) -> None:
super().__init__()
self.model = Sequrntial(
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, input):
output = self.model(input)
return output
dataset = torchvison.datasets.CIFAR10("./data", train=False, transform=torvison.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=1)
#交叉熵损失对象
loss_object = nn.CrossEntropyLoss()
#神经网络对象
tutui = Tutui()
#优化器对象!!!!!!!!
optim = torch.optim.SGD(tudui.parameter(), lr=0.01)
for epoch in range(20):
sum_loss = 0.0
for data in downloader:
imgs, targets = data
output = tutui(imgs)
#计算loss值
loss_value = loss_object(output, targets)
#梯度清零!!!!!!!!!!
optim.zero_grad()
#反向传播
loss_value.backward()
#优化!!!!!!!
optim.step()
sum_loss = sum_loss + loss_value
print(sum_loss)
模型的保存和加载
模型保存
- 保存方式1:既可以保存网络模型的结构,还可以保存模型的参数
import torch
import torchvison
#直接下载torchvison自带的模型,存入vgg16中
vgg16_model = torchvison.models.vgg16(pretrained=Flase)
#第一个参数是待保存的模型,第二个参数是保存路径
torch.save(vgg16_model, "vgg16_metod1.pth")
- 保存方式2:不保存网络模型的结构,只保存模型的参数(官方推荐)
state_dic()方法:将模型vgg16的状态(参数)保存成字典形式
import torch
import torchvison
#直接下载torchvison自带的模型,存入vgg16中
vgg16_model = torchvison.models.vgg16(pretrained=Flase)
#第一个参数是待保存的模型的状态,第二个参数是保存路径
torch.save(vgg16.state_dict(), "vgg16_metod2.pth")
模型加载
-
对应保存方式1的模型读取
如果加载的模型时自定义的,在加载模型前,需要定义好模型的结构,或是把包含模型结构的模块import进来from model_save import *
exmaple:
import torch
#参数是保存模型的路径
model = torch.load("./vgg16_method1.pth")
print(model)
- 对应保存方式2的模型读取
step1:新建网络模型
step2:加载字典
import torch
import torchvison
#新建模型
model = torchvison.model.vgg16(pretrained=False)
#加载模型状态字典
model.load_state_dict(torch.load("./vgg16_method2.pth"))
print(model)
数据可视化-Tensorboard
tensorboard主要功能:
- 数据可视化
- 模型网络架构可视化
- 跟踪模型指标,如损失、准确性等
启动Tensorboard
-
本地启动,在终端(Termianl)输入并运行
tensorboard --logdir=<directory_name>
Tensorboard代码
from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Image
#writer为tensorboard对象,logs指定tensorboard生成文件的存放目录
writer = SummaryWriter("logs")
# 图片获取和数据转换
img_PIL = Image.open("dataset/train/bees/16838648_415acd9e3f.jpg")
img_array = np.array(img_PIL)
writer.add_image("test", img_array, 2, dataformats="HWC")
# y=2x
for i in range(100):
writer.add_scalar("y=2x", 2*i, i)
#关闭tensorboard对象
writer.close()
更多推荐



所有评论(0)