WDK学习笔记_Pytorch框架的使用

Pytorch框架的使用

摘要

在工程方面:学习了Pytorch框架的使用,在数据处理上,用Dataset从文件中读取数据并编号,用Dataloader对数据分批次打包,便于训练时使用小批量梯度下降对model进行优化;在可视化上,用Tensorboard实现了搭建model的可视化和训练数据的可视化实践;在model上,搭建了CNN-DNN模型对手写数字识别进行了分类,在没任何调参和对model完善的情况下准确率80%左右。
在学术方面:本周详细看了欧拉观点和拉格朗日观点对流体运动的描述,进行了部分推导,部分学习了SVM如何将低纬度的数据映射到高纬度进行分类的数学推导。


一、数据处理

在Pytorch中,读取数据主要涉及两个类—Dataset和Dataloader:

  1. Dataset常用于文件中数据读取,读取每个数据及其对应的Label(标签)。
  2. Dataloader对Dataset读取的数据进行打包,分Batch送入神经网络。

1.1 Dataset的重载

Dataset官方文档
创建类Mydataset,继承父类Dataset,重写初始化函数、__getitem__函数和__len__函数。下面代码的效果是,读取上一级目录文件dataset/val/中ants和bees的图片数据。其中函数的作用:

  1. os.path.join: 输入文件地址,将地址连接后输出,如:os.path.join(“dataset”, “val”) = dataset/val
  2. os.listdir: 输入文件地址,输出该地址中的文件名列表。
  3. Image.open: 输入图片地址,输出该图片。
import os.path

from PIL import Image
from torch.utils.data import Dataset

class Mydataset(Dataset):
    def __init__(self, root_dir, label_dir):
        self.label_dir = label_dir
        self.root_label_dir = os.path.join(root_dir, label_dir)
        self.imgs_dir_list = os.listdir(self.root_label_dir)

    def __getitem__(self, idex):#输入图片索引,返回图片及其label
        img_path = self.imgs_dir_list[idex]
        img = Image.open(os.path.join(self.root_label_dir, img_path))
        img_label = self.label_dir
        return img, img_label

    def __len__(self):#返回图片的长度
        return len(self.imgs_dir_list)

root_dir = "../dataset/val"
ants_dir = "ants"
bees_dir = "bees"
ants_dataset = Mydataset(root_dir, ants_dir)
bees_dataset = Mydataset(root_dir, bees_dir)
img, label = ants_dataset.__getitem__(2)
img.show()
print(label)

1.2 DataLoader

DataLoader官方文档
作用:将数据分批次打包

import torch
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

trans_tensor = torchvision.transforms.ToTensor() #实例化图片转tensor的类
train_data = torchvision.datasets.MNIST("./data_minst", train=True, transform=trans_tensor, download=True)
test_data = torchvision.datasets.MNIST("./data_minst", train=False, transform=trans_tensor, download=True)
writer =SummaryWriter("./logs")

batch = 50
train_data_batch = DataLoader(train_data, batch_size=batch)
test_data_batch = DataLoader(test_data, batch_size=batch)

i = 0
for data in train_data_batch:
    img, label = data
    print(img.shape)
    img = torch.reshape(img, (batch, 1, 28, 28))
    writer.add_images("手写数字", img, i)
    i += 1

writer.close()

在这里插入图片描述

二、可视化

Tensorboard官方文档

2.1 Tensorboard的使用

2.1.1 Tensorboard根据数据绘图

from torch.utils.tensorboard import SummaryWriter#从tensorboard中导入类SummaryWriter
writer = SummaryWriter("./logs")#类的实例化
for i in range(100):
    writer.add_scalar("y=x^2", i**2, i)#添加数据
writer.close()

在这里插入图片描述

2.1.2 Tensorboard显示图片

  1. writer.add_images: 输入张量格式为(n, m, h, w),n代表图片数量,m代表通道数,h,w代表图片像素。
import torch
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("./logs")
img = Image.open("./image/0013035.jpg")
tensor_trans = transforms.ToTensor()
img = tensor_trans(img)
print(img.shape)
img = torch.reshape(img,(1,3,512,768))
writer.add_images("image", img)
writer.close()

在这里插入图片描述

2.1.3 Tensorboard显示model网络结构

  1. writer.add_graph():输入model类和model的输入。
import torch
from torch import nn
from torch.utils.tensorboard import SummaryWriter


class CnnModel(nn.Module):
    def __init__(self):
        super(CnnModel, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=3, stride=1, padding=0)
        self.pool1 = nn.MaxPool2d(2)
        self.conv2 = nn.Conv2d(3, 3, 3, 1, 0)
        self.pool2 = nn.MaxPool2d(2)
        self.flaten = nn.Flatten()
        self.linear = nn.Linear(75, 10)
        self.sofmax = nn.Softmax(1)

    def forward(self, x):
        x = self.conv1(x)
        x = self.pool1(x)
        x = self.conv2(x)
        x = self.pool2(x)
        x = self.flaten(x)
        x = self.linear(x)
        x = self.sofmax(x)
        return x

if __name__ == '__main__':      #测试model是否正确
    x = torch.ones(1, 1, 28, 28)
    model = CnnModel()
    output = model.forward(x)
    writer = SummaryWriter("./logs_model")
    writer.add_graph(model, x)
    writer.close()

在这里插入图片描述

三、模型实践

torch.nn官方文档

3.1 手写数字识别

从torchvision中读取手写数据集,用torchvision.transforms.ToTensor将图片转换为张量,用DataLoader将数据集分批次打包,从nn.Module中继承模型类,用nn.Conv2d搭建卷积层,nn.MaxPool2dl搭建池化层,nn.Linear搭建线性层,nn.Flatten()将数据拉平,nn.Sofemax()作为激活函数。搭建的模型用tensorboard可视化如下图:
在这里插入图片描述

3.1.1 Model程序

import torch
from torch import nn

class CnnModel(nn.Module):
    def __init__(self):
        super(CnnModel, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=3, stride=1, padding=0)
        self.pool1 = nn.MaxPool2d(2)
        self.conv2 = nn.Conv2d(3, 3, 3, 1, 0)
        self.pool2 = nn.MaxPool2d(2)
        self.flaten = nn.Flatten()
        self.linear = nn.Linear(75, 10)
        self.sofmax = nn.Softmax(1)

    def forward(self, x):
        x = self.conv1(x)
        x = self.pool1(x)
        x = self.conv2(x)
        x = self.pool2(x)
        x = self.flaten(x)
        x = self.linear(x)
        x = self.sofmax(x)
        return x

if __name__ == '__main__':      #测试model是否正确
    x = torch.ones(1, 1, 28, 28)
    model = CnnModel()
    output = model.forward(x)
    print(output.shape)
    print(output)

3.1.2 主函数程序

读取数据集并将image数据转换为张量,每50张图片作为一个批次,丢入model进行训练,用交叉熵作为损失函数,记录model每个批次的loss值和每一个epoach数据集全部的损失值,训练完后,用torch.save保持训练好后model的全部参数。

import torch
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from Model import *		#导入Model

#读取图片并转换为tensor型数据
trans_tensor = torchvision.transforms.ToTensor() #实例化图片转tensor的类
train_data = torchvision.datasets.MNIST("./data_minst", train=True, transform=trans_tensor, download=True)
test_data = torchvision.datasets.MNIST("./data_minst", train=False, transform=trans_tensor, download=True)

writer =SummaryWriter("./logs")

#将数据分批量打包
batch = 50
train_data_batch = DataLoader(train_data, batch_size=batch)
test_data_batch = DataLoader(test_data, batch_size=batch)

#模型实例化
MinModel = CnnModel()

#优化器实例化
learingrate = 1e-2
optimizer = torch.optim.SGD(MinModel.parameters(), lr=learingrate)

#损失函数
loss_f = nn.CrossEntropyLoss()

epoach = 20
train_size = 1


for i in range(epoach):
    total_loss = 0
    print("——————————第{}轮训练开始——————————————".format(i+1))
    for data in train_data_batch:
        img, label = data   #取出img和label
        y = MinModel(img)   #得到model输出
        loss = loss_f(y, label)    #计算损失值
        writer.add_scalar("Loss值随训练次数的变化", loss, train_size)
        total_loss += loss  #每一轮的累计损失值
        optimizer.zero_grad()   #每一次训练将梯度清0
        loss.backward()     #自动求导
        optimizer.step()    #用优化器自动更新参数

        acc_train = ((y.argmax(1)==label).sum())/batch
        writer.add_scalar("准确率随训练次数的变化", acc_train, train_size)

        if(train_size%100==0): #每训练100次输出此batch的损失值
            print("第{}次训练的loss值为{}".format(train_size, loss))
        train_size += 1

    print("********第{}轮训练全部的loss值是:{}***********".format(i+1, total_loss))

torch.save(MinModel, "./Model_save/model.pth") #保持model

writer.close()

在这里插入图片描述

总结

实现了用pytorch框架从0开始搭建网络,用手写数字的数据集进行了实践,掌握了用tensorboard实现model和训练数据的可视化。在论文方面,较系统的认识了欧拉和拉格朗日对流体运动的观点。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值