机器学习Day5——Pytorch深度学习框架学习

本栏目为本人自学B站各位好心的博主所录视频过程中记录下来的笔记,出处基本来自于B站视频博主以及csdn中各位大佬的解释,我只起到了转载的作用。因来源过于复杂,因此无法标注来源。

1.本文环境说明

  • Pytorch版本说明
# CUDA 10.2
conda install pytorch==1.10.0 torchvision==0.11.0 torchaudio==0.10.0 cudatoolkit=10.2 -c pytorch

通过Pycharm将Anaconda中虚拟环境结合一起开发,同时利用Jupyter notebook工具。

通过以下命令可以在Anaconda虚拟环境中下载Jupyter notebook:

conda install nb_conda

小tips:

Python学习中两大查看package内部结构的法宝

  1. dir()查看包内部有多少分隔空间
  2. help()查看某函数说明书

2.Pytorch数据的加载

自定义数据类MyData,继承父类(Dataset),必须至少实现两个魔术方法:getitemlen

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.label_dir = label_dir
        self.path = os.path.join(root_dir,label_dir)
        self.img_path_list = os.listdir(self.path)


    def __getitem__(self, idx):
        img_name = self.img_path_list[idx]
        img_item_path = os.path.join(self.root_dir,self.label_dir,img_name)
        img = Image.open(img_item_path)
        label = self.label_dir
        return img,label

    def __len__(self):
        return len(self.img_path_list)

3.tensorboard的使用

  • 函数图像的加载
  1. 导入相关包
from torch.utils.tensorboard import SummaryWriter
  1. 实例化对象
writer = SummaryWriter("Logs")

参数说明:
实例化时填入的参数为writer对象输出结果的目录所在位置,由程序员指定

  1. 添加图表标题和函数表达式和x轴变量
for i in range(100):
    writer.add_scalar("y=x",i,i)

常用参数
tag 图标题
scalar_value 需要保存的数值,对应于坐标轴的纵轴
global_step 对应于坐标轴的横轴

  1. 打开所绘制的函数图像
# 在命令行中输入以下命令
# logdir是指的writer对象所填的结果输出目录
# port是指打开图像的指定端口号,一般默认为6006
tensorboard --logdir=Logs --port=6007
  • 图片的加载
from torch.utils.tensorboard import SummaryWriter
from PIL import Image
import numpy as np

writer = SummaryWriter("Logs")
image_path = "dataset/train/ants/0013035.jpg"
img_PIL = Image.open(image_path)
img_array = np.array(img_PIL)

writer.add_image("train",img_array,1,dataformats="HWC")
writer.close()

注:add_image中可接受Torch.tensor和numpy.array等图片数据格式,但不支持PIL格式的,因此要进行数据格式转换。此外,转换为numpy.array格式时,还需要对HWC进行一次调整,调整为CHW

4.transforms的使用

from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from PIL import Image

img_path = "dataset/train/ants/0013035.jpg"
img_PTL = Image.open(img_path)
writer = SummaryWriter("Logs")

# ToTensor类的使用,将数据类型转化为tensor
tensor_transform = transforms.ToTensor()
img_tensor = tensor_transform(img_PTL)
writer.add_image("Tensor_img",img_tensor)

# Normalize类的使用,对图片进行标准化,第一个参数为mean,第二个参数为std
normalize_transform = transforms.Normalize([0.5,0.5,0.5],[1,1,1])
img_normalize = normalize_transform(img_tensor)
writer.add_image("Normalize_img",img_normalize)

# Resize类的使用,对图片不按照比例进行放缩,参数为一个元组,分别表示长和宽
resize_transform = transforms.Resize((512,512))
img_resize = resize_transform(img_tensor)
writer.add_image("Resize_img",img_resize)

# Compose类的使用,对图片进行一系列操作,如转换数据类型,归一化,放缩等等
compose_transform = transforms.Compose([
    transforms.Resize((256, 256)),    # 调整图像大小为 256x256
    transforms.RandomCrop(224),       # 随机裁剪为 224x224
    transforms.RandomHorizontalFlip(),# 随机水平翻转
    transforms.ToTensor(),            # 转换为张量
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # 标准化
])
img_compose = compose_transform(img_PTL)
writer.add_image("Compose_img",img_compose)

writer.close()

5.卷积层

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

data = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(data,batch_size=64)

class MyModel(nn.Module):
    
    def __init__(self):
        super(MyModel, self).__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

mymodel = MyModel()
writer = SummaryWriter("../Logs")
step = 0
for data in dataloader:
    imgs_input,target = data
    writer.add_images("input images",imgs_input,global_step=step)
    imgs_output = mymodel.forward(imgs_input)
    imgs_output = torch.reshape(imgs_output,[-1,3,30,30])
    writer.add_images("output images",imgs_output,global_step=step)
    step = step + 1

writer.close()

6.池化层(最大池化)

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

dataset = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=4)

class PoolModel(nn.Module):
    def __init__(self):
        super(PoolModel, self).__init__()
        self.MaxPool = MaxPool2d(kernel_size=4)

    def forward(self,input):
        output = self.MaxPool(input)
        return output

poolmodel = PoolModel()
writer = SummaryWriter("../Logs")
step = 0
for data in dataloader:
    imgs_input,targets = data
    writer.add_images("input images",imgs_input,global_step=step)
    imgs_output = poolmodel.forward(imgs_input)
    writer.add_images("output images",imgs_output,global_step=step)
    step = step + 1

writer.close()

7.非线性激活层(Sigmoid)

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

dataset = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=36)

class SigmoidModel(nn.Module):
    def __init__(self):
        super(SigmoidModel, self).__init__()
        self.sigmoid1 = Sigmoid()

    def forward(self,input):
        output = self.sigmoid1(input)
        return output

sigmoidmodel = SigmoidModel()
writer = SummaryWriter("../Logs")
step = 0
for data in dataloader:
    imgs_input,targets = data
    writer.add_images("input images",imgs_input,step)
    imgs_output = sigmoidmodel(imgs_input)
    writer.add_images("output images",imgs_output,step)
    step = step + 1

writer.close()

8.Sequential容器

import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.tensorboard import SummaryWriter

class Mymodel(nn.Module):
    def __init__(self):
        super(Mymodel, self).__init__()
        # self.conv1 = Conv2d(in_channels=3,out_channels=32,kernel_size=5,stride=1,padding=2)
        # self.maxpool1 = MaxPool2d(kernel_size=2)
        # self.conv2 = Conv2d(in_channels=32,out_channels=32,kernel_size=5,stride=1,padding=2)
        # self.maxpool2 = MaxPool2d(kernel_size=2)
        # self.conv3 = Conv2d(in_channels=32,out_channels=64,kernel_size=5,stride=1,padding=2)
        # self.maxpool3 = MaxPool2d(kernel_size=2)
        # self.flatten = Flatten()
        # self.linear1 = Linear(1024,64)
        # self.linear2 = Linear(64,10)

        self.sequential1 = Sequential(
            Conv2d(3,32,5,1,2),
            MaxPool2d(2),
            Conv2d(32,32,5,1,2),
            MaxPool2d(2),
            Conv2d(32,64,5,1,2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024,64),
            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)

        x = self.sequential1(x)
        return x

mymodel = Mymodel()
writer = SummaryWriter("../Logs")
input = torch.ones(64,3,32,32)
writer.add_graph(mymodel,input)
writer.close()

9.损失函数

9.1 L1和MSE

import torch
from torch.nn import L1Loss,MSELoss

input = torch.tensor([1,7,9],dtype=torch.float32)
target = torch.tensor([3,8,1],dtype=torch.float32)

input = torch.reshape(input,[1,1,1,3])
target = torch.reshape(target,[1,1,1,3])

loss_L1 = L1Loss(reduction="sum")
result_L1 = loss_L1(input,target)
print("L1_loss为:",result_L1)

loss_MSE = MSELoss()
result_MSE = loss_MSE(input,target)
print("MSE_loss为:",result_MSE)

9.2 CrossEntropyLoss

import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential, CrossEntropyLoss
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=36)

class Mymodel(nn.Module):
    def __init__(self):
        super(Mymodel, self).__init__()
        self.sequential1 = Sequential(
            Conv2d(3,32,5,1,2),
            MaxPool2d(2),
            Conv2d(32,32,5,1,2),
            MaxPool2d(2),
            Conv2d(32,64,5,1,2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024,64),
            Linear(64,10)
        )

    def forward(self,x):
        x = self.sequential1(x)
        return x

mymodel = Mymodel()
loss = CrossEntropyLoss()
for data in dataloader:
    imgs_input,targets = data
    imgs_output = mymodel(imgs_input)
    result = loss(imgs_output,targets)
    print(result)

10.优化器

随机梯度下降(SGD)

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential, CrossEntropyLoss
from torch.optim import SGD
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=36)

class Mymodel(nn.Module):
    def __init__(self):
        super(Mymodel, self).__init__()
        self.sequential1 = Sequential(
            Conv2d(3,32,5,1,2),
            MaxPool2d(2),
            Conv2d(32,32,5,1,2),
            MaxPool2d(2),
            Conv2d(32,64,5,1,2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024,64),
            Linear(64,10)
        )

    def forward(self,x):
        x = self.sequential1(x)
        return x

mymodel = Mymodel()
loss = CrossEntropyLoss()
optimizer = SGD(mymodel.parameters(),lr=0.01)
for epoch in range(20):
    running_loss = 0.0
    for data in dataloader:
        imgs_input,targets = data
        imgs_output = mymodel(imgs_input)
        result = loss(imgs_output,targets)
        optimizer.zero_grad()
        result.backward()
        optimizer.step()
        running_loss = result + running_loss
    print("第{}轮的损失为: {}".format(epoch,running_loss))

11.模型的添加与修改

import torchvision
from torch import nn

vgg16_false = torchvision.models.vgg16(pretrained=False)
vgg16_true = torchvision.models.vgg16(pretrained=True)
print(vgg16_true)
print(vgg16_false)
# 添加模型
vgg16_true.classifier.add_module('add_linear', nn.Linear(1000, 10))
print(vgg16_true)
# 修改模型
vgg16_false.classifier[6] = nn.Linear(4096, 10)
print(vgg16_false)

12.模型的保存与加载

12.1 模型的保存

import torch
import torchvision
from torch import nn

vgg16 = torchvision.models.vgg16(pretrained=False)
# 保存方式1,模型结构+模型参数
torch.save(vgg16, "vgg16_method1.pth")

# 保存方式2,模型参数(官方推荐)
torch.save(vgg16.state_dict(), "vgg16_method2.pth")

# 陷阱
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)

    def forward(self, x):
        x = self.conv1(x)
        return x

tudui = Tudui()
torch.save(tudui, "tudui_method1.pth")

12.2 模型的加载

import torch
import torchvision
from torch import nn

# 方式1,加载模型结构+模型参数
model1 = torch.load("vgg16_method1.pth")
print(model1)

# 方式2,加载模型参数
model2 = torchvision.models.vgg16(pretrained=False)
model2.load_state_dict(torch.load("vgg16_method2.pth"))
print(model2)

# 陷阱
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)

    def forward(self, x):
        x = self.conv1(x)
        return x

model3 = torch.load('tudui_method1.pth')
print(model3)

13.完整的模型训练过程

13.1 普通版

import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter
from torch import nn
from torch.nn import Sequential ,CrossEntropyLoss
from torch.utils.data import DataLoader

# 1.准备数据集
train_dataset = torchvision.datasets.CIFAR10(root="../dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_dataset = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
print("训练数据集的长度为:",len(train_dataset))
print("测试数据集的长度为:",len(test_dataset))

# 2.加载数据集
train_dataloader = DataLoader(train_dataset,batch_size=64)
test_dataloader = DataLoader(test_dataset,batch_size=64)

# 3.创建网络模型
class CIFAR10_Model(nn.Module):
    def __init__(self):
        super(CIFAR10_Model, self).__init__()
        self.model = 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(1024,64),
            nn.Linear(64,10)
        )

    def forward(self,x):
        x = self.model(x)
        return x

cifar10_model = CIFAR10_Model()

# 4.损失函数
loss = CrossEntropyLoss()

# 5.优化器
optimizer = torch.optim.SGD(cifar10_model.parameters(),lr=1e-2)

# 6.设置训练参数及可视化
## 训练次数(一个batch算作一次)
total_train_step = 0
## 测试次数(一个batch算作一次)
total_test_step = 0
## 训练轮数
epoch = 30
## tensorboard可视化
writer = SummaryWriter("CIFAR10_Model_logs")

# 7.开始训练
for i in range(epoch):
    print("----------------第{}轮训练开始---------------".format(i))

    # 训练步骤开始
    cifar10_model.train()
    for data in train_dataloader:
        imgs_input,targets = data
        imgs_output = cifar10_model(imgs_input)
        loss_train = loss(imgs_output,targets)

        # 优化器开始优化
        optimizer.zero_grad()
        loss_train.backward()
        optimizer.step()

        total_train_step = total_train_step + 1
        if total_train_step % 100 == 0:
            print("第{}次训练的Loss为: {}".format(total_train_step, loss_train))
            writer.add_scalar("loss_train",loss_train,total_train_step)

    # 测试步骤开始
    cifar10_model.eval()
    total_test_loss = 0
    total_test_accurate = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs_input,targets = data
            imgs_output = cifar10_model(imgs_input)
            loss_test = loss(imgs_output,targets)
            total_test_loss = total_test_loss + loss_test
            right_nums = (imgs_output.argmax(1) == targets).sum()
            total_test_accurate = total_test_accurate + right_nums

    print("第{}轮训练后,在测试集上的损失loss为:{}".format(i,total_test_loss))
    print("第{}轮训练后,在测试集上的正确率accuracy为:{}%".format(i, (total_test_accurate/len(test_dataset))*100))
    writer.add_scalar("loss_test",total_test_loss,total_test_step)
    writer.add_scalar("accuracy_test",(total_test_accurate/len(test_dataset))*100,total_test_step)
    total_test_step = total_test_step + 1

    torch.save(cifar10_model,"cifar10_model_{}.pth".format(i))
    print("第{}轮训练的模型已保存".format(i))

writer.close()

13.2 利用GPU加速版

import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter
from torch import nn
from torch.nn import Sequential ,CrossEntropyLoss
from torch.utils.data import DataLoader
import time

# 0.设置训练的设备
device = torch.device("cuda")

# 1.准备数据集
train_dataset = torchvision.datasets.CIFAR10(root="../dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_dataset = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
print("训练数据集的长度为:",len(train_dataset))
print("测试数据集的长度为:",len(test_dataset))

# 2.加载数据集
train_dataloader = DataLoader(train_dataset,batch_size=64)
test_dataloader = DataLoader(test_dataset,batch_size=64)

# 3.创建网络模型
class CIFAR10_Model(nn.Module):
    def __init__(self):
        super(CIFAR10_Model, self).__init__()
        self.model = 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(1024,64),
            nn.Linear(64,10)
        )

    def forward(self,x):
        x = self.model(x)
        return x

cifar10_model = CIFAR10_Model()
cifar10_model = cifar10_model.to(device)

# 4.损失函数
loss = CrossEntropyLoss()
loss = loss.to(device)

# 5.优化器
optimizer = torch.optim.SGD(cifar10_model.parameters(),lr=1e-2)

# 6.设置训练参数及可视化
## 训练次数(一个batch算作一次)
total_train_step = 0
## 测试次数(一个batch算作一次)
total_test_step = 0
## 训练轮数
epoch = 30
## tensorboard可视化
writer = SummaryWriter("../CIFAR10_Model_logs")
## 计时器
start_time = time.time()

# 7.开始训练
for i in range(epoch):
    print("----------------第{}轮训练开始---------------".format(i))

    # 训练步骤开始
    cifar10_model.train()
    for data in train_dataloader:
        imgs_input,targets = data
        imgs_input = imgs_input.to(device)
        targets = targets.to(device)
        imgs_output = cifar10_model(imgs_input)
        loss_train = loss(imgs_output,targets)

        # 优化器开始优化
        optimizer.zero_grad()
        loss_train.backward()
        optimizer.step()

        total_train_step = total_train_step + 1
        if total_train_step % 100 == 0:
            end_time = time.time()
            print("第{}次训练的Loss为: {}".format(total_train_step, loss_train))
            print("第{}次训练的费时为: {}".format(total_train_step, end_time-start_time))
            writer.add_scalar("loss_train",loss_train,total_train_step)

    # 测试步骤开始
    cifar10_model.eval()
    total_test_loss = 0
    total_test_accurate = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs_input,targets = data
            imgs_input = imgs_input.to(device)
            targets = targets.to(device)
            imgs_output = cifar10_model(imgs_input)
            loss_test = loss(imgs_output,targets)
            total_test_loss = total_test_loss + loss_test
            right_nums = (imgs_output.argmax(1) == targets).sum()
            total_test_accurate = total_test_accurate + right_nums

    print("第{}轮训练后,在测试集上的损失loss为:{}".format(i,total_test_loss))
    print("第{}轮训练后,在测试集上的正确率accuracy为:{}%".format(i, (total_test_accurate/len(test_dataset))*100))
    writer.add_scalar("loss_test",total_test_loss,total_test_step)
    writer.add_scalar("accuracy_test",(total_test_accurate/len(test_dataset))*100,total_test_step)
    total_test_step = total_test_step + 1

    torch.save(cifar10_model,"cifar10_model_{}.pth".format(i))
    print("第{}轮训练的模型已保存".format(i))

writer.close()

14.模型验证

from PIL import Image
from torch import nn
from torch.nn import Sequential
import torchvision
import torch
# 0.指定设备
device = torch.device("cuda")

# 1.准备数据
img_path = "../images/airplane.jpg"
img = Image.open(img_path)
img = img.convert("RGB")
## 设置转换器
transform = torchvision.transforms.Compose([
    torchvision.transforms.Resize((32,32)),
    torchvision.transforms.ToTensor()
])
img = transform(img)
## 设置batch
img = torch.reshape(img,(1,3,32,32))
## 设置为cuda模式
img = img.to(device)

# 2.加载网络模型
class CIFAR10_Model(nn.Module):
    def __init__(self):
        super(CIFAR10_Model, self).__init__()
        self.model = 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(1024,64),
            nn.Linear(64,10)
        )

    def forward(self,x):
        x = self.model(x)
        return x
cifar10_model = torch.load("../train_models/cifar10_model_26.pth",map_location=device)

# 3.验证模型
cifar10_model.eval()
with torch.no_grad():
    output_img = cifar10_model(img)
target_index = output_img.argmax(1)
print(output_img)
print(target_index)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值