小土堆pytorch学习笔记005 | 完结,✿✿ヽ(°▽°)ノ✿

目录

1、损失函数与反向传播

2、如何在搭建的网络中使用损失函数呢?

3、优化器

4、现有网络模型的使用及修改

例子:

5、模型训练保存+读取

(1)保存

(2)读取

6、完整的模型训练:

(1)代码

【model文件】:

【主文件】:

(2)运行截图:

(3)绘图展示:

(4)添加训练正确率的完整代码:

(5)总结!!!:

(6)使用GPU训练

7、 完整模型验证

(1)代码

(2)运行结果


1、损失函数与反向传播

①计算实际输出和目标之间的差距。

②为我们更新输出提供一定的依据。(反向传播)

损失函数例子实战:

小土堆pytorch学习笔记005 | 完结,✿✿ヽ(°▽°)ノ✿_第1张图片

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))  # 1batch_size  /  1channel  /   1行3列
targets = torch.reshape(targets, (1, 1, 1, 3))

# loss = L1Loss(reduction='sum')   # 损失,求和  (x-y)求和   结果:tensor(2.)
loss = L1Loss()   # 损失,求mean()   (x-y)求和/n   结果:tensor(0.6667)
result = loss(inputs, targets)
print("loss:",result)


loss_mse = nn.MSELoss()
result_mse = loss_mse(inputs, targets)    # 计算过程  (x-y)^2
print("mse_loss:", result_mse)   # tensor(1.3333)



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:",result_cross)

2、如何在搭建的网络中使用损失函数呢?

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

dataset = torchvision.datasets.CIFAR10("./test11_data", train=False,download=True,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=1)



class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1 = Sequential(
            Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
            MaxPool2d(2),
            Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
            MaxPool2d(2),
            Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(in_features=1024, out_features=64),
            Linear(in_features=64, out_features=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)
    result_loss.backward()  # 反向传播
    print(result_loss)

3、优化器

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

dataset = torchvision.datasets.CIFAR10("./test11_data", train=False,download=True,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=1)


class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1 = Sequential(
            Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
            MaxPool2d(2),
            Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
            MaxPool2d(2),
            Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(in_features=1024, out_features=64),
            Linear(in_features=64, out_features=10)
        )

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


loss = nn.CrossEntropyLoss()
tudui = Tudui()
optim = torch.optim.SGD(tudui.parameters(), lr=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()  # 将梯度清零
        result_loss.backward()  # 调用反向传播
        optim.step()
        running_loss = running_loss + result_loss
    print(running_loss)

4、现有网络模型的使用及修改

例子:

import torchvision
import ssl

from torch import nn

ssl._create_default_https_context = ssl._create_unverified_context
# train_data = torchvision.datasets.ImageNet("./test19_data",split='train',download=True,
#                                            transform=torchvision.transforms.ToTensor())

vgg16_false = torchvision.models.vgg16(pretrained=False)
vgg16_true = torchvision.models.vgg16(pretrained=True)
print(vgg16_true)

train_data = torchvision.datasets.CIFAR10('./test13_data', train=True, download=True,
                                          transform=torchvision.transforms.ToTensor())
# 在现有网络里面,添加一些东西
vgg16_true.classifier.add_module('add_linear', nn.Linear(1000, 10))
print(vgg16_true)

# 在现有网络里面,修改一些东西
print("修改之前vgg16_false:", vgg16_false)
vgg16_false.classifier[6] = nn.Linear(4096,10)
print("修改之后vgg16_false:", vgg16_false)


5、模型训练保存+读取

(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")

(2)读取

import torch
import torchvision
from torch import nn

# 方式1:加载模型
model = torch.load("./vgg16_method1.pth")
# print(model)


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


# 陷阱1(需要将Tudui引入)
from test20_model_save import *
model_tudui = torch.load("./tudui_method1.pth")
print(model_tudui)

6、完整的模型训练:

(1)代码

【model文件】:

import torch
from torch import nn


# 搭建神经网络
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__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):
        x = self.model(x)
        return x


if __name__ == '__main__':
    tudui = Tudui()
    input = torch.ones((64,3,32,32))
    output = tudui(input)
    print(output.shape)


【主文件】:

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

from pytorch_xiaotudui.model import Tudui

# 准备数据集
train_data = torchvision.datasets.CIFAR10("./test13_data", train=True, download=True,
                                          transform=torchvision.transforms.ToTensor())

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

# length  长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为: {}".format(train_data_size))
print("测试数据集的长度为: {}".format(test_data_size))

# 利用DataLoader加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 创建神经网络
tudui = Tudui()

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

# 优化器
learning_rate = 0.01  # 学习速率  或者写成 learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
total_train_step = 0  # 记录训练的参数
total_test_step = 0  # 记录测试的次数
epoch = 10  # 训练的轮数

# 添加tensorboard
writer = SummaryWriter("test22_logs")



for i in range(epoch):
    print("------------------第{}轮训练开始-----------".format(i+1))
    #训练步骤开始
    for data in train_dataloader:
        imgs,targets = data
        outputs = tudui(imgs)
        loss = loss_fn(outputs,targets)

        # 优化器优化模型
        optimizer.zero_grad()  # 将数据清零
        loss.backward()  # 反向传播
        optimizer.step()

        total_train_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)

    # 测试步骤开始
    total_test_loss = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            outputs = tudui(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_loss + loss
        print("整体测试集上的Loss:{}".format(total_test_loss))
        writer.add_scalar("test_loss", total_test_loss, total_test_step)
        total_test_step = total_test_step+1

        torch.save(tudui, "tudui_{}.pth".format(i))
        print("模型已保存")

writer.close()

(2)运行截图:

小土堆pytorch学习笔记005 | 完结,✿✿ヽ(°▽°)ノ✿_第2张图片

(3)绘图展示:

小土堆pytorch学习笔记005 | 完结,✿✿ヽ(°▽°)ノ✿_第3张图片

(4)添加训练正确率的完整代码:

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

from pytorch_xiaotudui.model import Tudui

# 准备数据集
train_data = torchvision.datasets.CIFAR10("./test13_data", train=True, download=True,
                                          transform=torchvision.transforms.ToTensor())

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

# length  长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为: {}".format(train_data_size))
print("测试数据集的长度为: {}".format(test_data_size))

# 利用DataLoader加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 创建神经网络
tudui = Tudui()

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

# 优化器
learning_rate = 0.01  # 学习速率  或者写成 learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
total_train_step = 0  # 记录训练的参数
total_test_step = 0  # 记录测试的次数
epoch = 10  # 训练的轮数

# 添加tensorboard
writer = SummaryWriter("test22_logs")


for i in range(epoch):
    print("------------------第{}轮训练开始-----------".format(i+1))
    # 训练步骤开始
    for data in train_dataloader:
        imgs,targets = data
        outputs = tudui(imgs)
        loss = loss_fn(outputs,targets)

        # 优化器优化模型
        optimizer.zero_grad()  # 将数据清零
        loss.backward()  # 反向传播
        optimizer.step()

        total_train_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)

    # 测试步骤开始
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            outputs = tudui(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_loss + loss.item()

            accuracy = (outputs.argmax(1) == targets).sum()
            total_accuracy = total_accuracy + accuracy

        print("整体测试集上的正确率:{}".format(total_accuracy/test_data_size))
        print("整体测试集上的Loss:{}".format(total_test_loss))
        writer.add_scalar("test_loss", total_test_loss, total_test_step)
        writer.add_scalar("test_accauray", total_accuracy/test_data_size, total_test_step)

        total_test_step = total_test_step+1

        torch.save(tudui, "tudui_{}.pth".format(i))
        print("模型已保存")

writer.close()

(5)总结!!!:

①创建dataset、dataloader加载数据

②搭建网络模型、创建网络模型实例

③定义损失函数

④定义优化器

⑤设置网络参数

⑥开始训练

⑦验证模型、保存模型

⑧将训练结果展示

(6)使用GPU训练

网络模型、数据(输入、标注)、损失函数        .cuda()  就可以。

如果自己笔记本上没有GPU的话,那么我们可以使用google提供的colab运行。(前提是要能访问上去,且要有个账号)。

界面有点儿类似,jupyter 那种。(部分截图如下, GPU跑的确实很快很快!!)

小土堆pytorch学习笔记005 | 完结,✿✿ヽ(°▽°)ノ✿_第4张图片

小土堆pytorch学习笔记005 | 完结,✿✿ヽ(°▽°)ノ✿_第5张图片

用GPU 跑完用时,1分钟45秒;用我的电脑,直接干到风扇转起来,呼呼响!!!

7、 完整模型验证

(1)代码

import torch
import torchvision.transforms
from PIL import Image
from torch import nn

image_path = "./imgs/airplane.png"
image = Image.open(image_path)
print(image)  # PIL格式的图片
image = image.convert('RGB')   # 因为png格式是4通道,除了RGB三通道外,还有一个透明度通道。

transforms = torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),
                                             torchvision.transforms.ToTensor()])

image = transforms(image)
print(image)  # tensor格式的图片


# 搭建神经网络
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__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):
        x = self.model(x)
        return x

model = torch.load("./tudui_9.pth", map_location=torch.device('cpu') )
print(model)
image = torch.reshape(image, (1, 3, 32, 32))
model.eval()
with torch.no_grad():
    output = model(image)
print(output)
print(output.argmax(1))

"""
数据:
    class_to_idx:
        0 airplane
        1 automobile
        2 bird
        3 cat
        4 deer
        5 dog
        6 frog
        7 horse
        8 ship
        9 truck
"""

(2)运行结果

小土堆pytorch学习笔记005 | 完结,✿✿ヽ(°▽°)ノ✿_第6张图片

小土堆pytorch学习笔记005 | 完结,✿✿ヽ(°▽°)ノ✿_第7张图片

你可能感兴趣的:(深度学习,学习,笔记,pytorch,机器学习,深度学习)