pytorch学习【2】


打开tensorboard

tensorboard --logdir="D:\6.PyCharm\1项目代码\test\logs_池化层"

前置API:

# 1.root="./dataset"当前文件的相对位置 , 2.train=True是为训练集(不是测试集), 3.transform=将图片使用该方法转换, 4.download=True下载到root路径中
dataset = torchvision.datasets.CIFAR10(root='./dataset',train=False,transform=transform,download=True)  # 下载测试集

# 1.dataset=test_set:数据集, 2.batch_size=4:一次取四张图片, 3.shuffle=False(默认):不打乱顺序, 4.num_workers=0:进程数, 5.drop_last=False(默认):保留最后不能整除
dataloader = DataLoader(dataset=dataset, batch_size=64)

# 标签要不同、step要不同
writer.add_images("input", imgs, step)
writer.add_images("output", output, step)

1.卷积层:提取特征

卷积层API:

# 输入的通道数、输出的通道数、卷积核大小、步长(默认1)、填充(默认0)
self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)
# 输出通道数out_channels = 卷积核的个数
#
import torchvision
import torch
from torch.utils.data import DataLoader
from torch import nn
from torch.nn import Conv2d
from torch.utils.tensorboard import SummaryWriter
# torchvision->transforms->[Compose...]
# torchvision->datasets->CIFAR10
# torch.utils.data-> DataLoader
# torch.nn->Module
# torch.utils.tensorboard->SummaryWriter
'''
# 图像格式预处理
'''
transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])

'''
# 读入数据集
'''
# 1.root="./dataset"当前文件的相对位置 , 2.train=True是为训练集(不是测试集), 3.transform=将图片使用该方法转换, 4.download=True下载到root路径中
dataset = torchvision.datasets.CIFAR10(root='./dataset',train=False,transform=transform,download=True)  # 下载测试集

'''
# 小批量的数据读入
'''
# 1.dataset=test_set:数据集, 2.batch_size=4:一次取四张图片, 3.shuffle=False(默认):不打乱顺序, 4.num_workers=0:进程数, 5.drop_last=False(默认):保留最后不能整除
dataloader = DataLoader(dataset=dataset, batch_size=64)

'''
# 建立模型
'''
class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, 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

mymodule = MyModule()
# print(mymodule)

writer = SummaryWriter("./logs_卷积层")


# data是64张图片
step = 0
for data in dataloader:
    # imgs = 64张图片,targets =64张图片的正确标签
    imgs, targets = data
    output = mymodule(imgs)
    writer.add_images("input", imgs, step)
    # 图片展示需要三个通道
    output = torch.reshape(output, (-1, 3, 30, 30))
    writer.add_images("output", output, step)
    step = step + 1
    # print(imgs.shape)
    # print(output.shape)

writer.close()

2.池化层:减少特征

池化不需要reshape了,因为通道数没有改变(MaxPool2d没有参数涉及到通道数)

池化层API

# 1.kernel_size=3:池化核大小 2.ceil_mode=true:向上取整, 3.步长stride=kernel_size(默认)
self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=True)
import torch
import torchvision.datasets
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader

# 图片预处理
from torch.utils.tensorboard import SummaryWriter

transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])
# 加载数据集
dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=transform, download=True)
# 小批量读入
dataloader = DataLoader(dataset=dataset,batch_size=64)


class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        # 1.kernel_size=3:池化核大小 2.ceil_mode=true:向上取整, 3.stride=kernel_size(默认)
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=True)

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

mymodule = MyModule()

writer = SummaryWriter("./logs_池化层")
step = 0
for data in dataloader:
    imgs, targets = data
    output = mymodule(imgs)
    writer.add_images("input", imgs, step)
    writer.add_images("output", output, step)
    step = step + 1

writer.close()

在这里插入图片描述
在这里插入图片描述

3.非线性激活

3.1ReLU函数

ReLU函数API:

torch.nn.ReLU(inplace=False)

具体函数:ReLU(x) =max(0,x)
图像:
在这里插入图片描述

3.1.1处理tensor

import torch
from torch import nn
from torch.nn import ReLU
input = torch.tensor([[1, -0.5],
              [-1, 3]])

input = torch.reshape(input, (-1, 1, 2, 2))
class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.relu1 = ReLU()

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

mymodule = MyModule()

output = mymodule(input)
print(output)

3.1.2处理图片

将图片过ReLU函数

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

transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])
dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=transform, download=True)
dataloader = DataLoader(dataset=dataset, batch_size=64)

class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.relu1 = ReLU()
        self.sigmoid1 = Sigmoid()

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

mymodule = MyModule()

writer = SummaryWriter("./logs_非线性激活ReLU")
step = 0
for data in dataloader:
    imgs, targets = data
    writer.add_images("input", imgs, step)
    output = mymodule(imgs)
    writer.add_images("output", output, step)
    step += 1

writer.close()

几乎没有差别
在这里插入图片描述

3.2Sigmoid函数

API

torch.nn.Sigmoid(*args, **kwargs)

在这里插入图片描述
在这里插入图片描述

3.2.1处理图片

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

transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])
dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=transform, download=True)
dataloader = DataLoader(dataset=dataset, batch_size=64)

class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.relu1 = ReLU()
        self.sigmoid1 = Sigmoid()

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

mymodule = MyModule()

writer = SummaryWriter("./logs_非线性激活Sigmoid")
step = 0
for data in dataloader:
    imgs, targets = data
    writer.add_images("input", imgs, step)
    output = mymodule(imgs)
    writer.add_images("output", output, step)
    step += 1

writer.close()

在这里插入图片描述

4.线性层

API:

in_features (int) – 每个输入样本的大小
out_features (int) – 每个输出样本的大小
bias (bool) – 默认True
torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.nn import Linear
dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64)

class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.linear1 = Linear(196608, 10)

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

mymodule = MyModule()

for data in dataloader:
    imgs, targets = data
    print(imgs.shape)
    # print(64*3*32*32)
    # input = torch.reshape(imgs, (1, 1, 1, -1))
    input = torch.flatten(imgs)
    print(input.shape)
    output = mymodule(input)
    print(output.shape)

在这里插入图片描述

5.小实战+Sequential使用

在这里插入图片描述
如果前后尺寸不变的话,那么padding=(f-1)/2,f是卷积核的尺寸,也就是5,所以padding=(5-1)/2=2

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


class My(nn.Module):
    def __init__(self):
        super(My, self).__init__()
        # 繁琐版本
        '''
        # 公式推算出来的s and p (卷积核中心对准最边缘的那个==》5/2=2)
        self.conv1 = Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2)
        # 公式推算
        self.maxpool1 = MaxPool2d(kernel_size=2, stride=2, padding=0)
        # 公式推算
        self.conv2 = Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2)
        # 公式推算
        self.maxpool2 = MaxPool2d(kernel_size=2, stride=2, padding=0)
        self.conv3 = Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2)
        self.maxpool3 = MaxPool2d(kernel_size=2, stride=2, padding=0)
        self.flatten = Flatten()
        self.linear1 = Linear(1024, 64)
        self.linear2 = Linear(64, 10)
        '''
        # 简化版本
        self.model1 = Sequential(
            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, 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.model1(x)
        return x
my = My()
print(my)
# 模型是否错误、验证
input = torch.ones((64, 3, 32, 32))
output = my(input)
print(output.shape)

writer = SummaryWriter("./logs_Sequential")
writer.add_graph(my, input)
writer.close()

在这里插入图片描述
在这里插入图片描述

6.损失函数

6.1L1Loss

在这里插入图片描述

6.2MSELoss

在这里插入图片描述

6.3CrossEntropyLoss

在这里插入图片描述

egg:
在这里插入图片描述

import torch
from torch.nn import L1Loss, MSELoss, CrossEntropyLoss
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))
targets = torch.reshape(targets, (1, 1, 1, 3))

# egg:L1Loss(reduction='sum') 下边三个损失函数都可以使用
# reduction='sum':差值的绝对值相加
# reduction='mean'(默认):差值的绝对值相加的平均值
loss = L1Loss()
loss_mse = MSELoss()

ans1 = loss(inputs, targets)
ans2 = loss_mse(inputs, targets)

print(ans1)
print(ans2)


# 预测概率
x = torch.tensor([0.1, 0.2, 0.3])
# 真实值
y = torch.tensor([1])
# 必须有3=》分类的类数
x = torch.reshape(x, (1, 3))
loss_cross = CrossEntropyLoss()
ans3 = loss_cross(x, y)
print(ans3)

7.反向传播

就一句话:loss.backward()
import torch
import torchvision.datasets
from torch import nn
from torch.nn import Conv2d,MaxPool2d,Flatten,Linear,Sequential,CrossEntropyLoss
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

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


class My(nn.Module):
    def __init__(self):
        super(My, self).__init__()
        # 简化版本
        self.model1 = Sequential(
            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, x):
        # 简化版本
        x = self.model1(x)
        return x


my = My()
# 参数:一张图片的[各个分类的概率、真实分类]
# 比如三分类,参数就是,预测概率[0.1,0.2,0.3] 真实分类[1]
loss_cross = CrossEntropyLoss()
for data in dataloader:
    imgs, targets = data
    outputs = my(imgs)
    # print(outputs)  # 一张图片预测的分类的概率[10个概率值]
    # print(targets)  # 真实分类

    loss = loss_cross(outputs, targets)
    # 损失函数的反向传播
    loss.backward()
    print("每bacth图片上的损失值:", loss)

8.优化器

引入
optim = torch.optim.SGD(my.parameters(), lr=0.01)

三步:1.清零 2.反向传播 3.调优
loss = loss_cross(outputs, targets)
optim.zero_grad()  #参数置0
loss.backward()  #方向传播、求梯度
optim.step()  #参数调优
import torch
import torchvision.datasets
from torch import nn
from torch.nn import Conv2d,MaxPool2d,Flatten,Linear,Sequential,CrossEntropyLoss
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

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


class My(nn.Module):
    def __init__(self):
        super(My, self).__init__()
        # 简化版本
        self.model1 = Sequential(
            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, x):
        # 简化版本
        x = self.model1(x)
        return x


my = My()
loss_cross = CrossEntropyLoss()
optim = torch.optim.SGD(my.parameters(), lr=0.01)
for k in range(20):
    sum_loss = 0
    for data in dataloader:
        imgs, targets = data
        outputs = my(imgs)
        loss = loss_cross(outputs, targets)
        optim.zero_grad()  #参数置0
        loss.backward()  #方向传播、求梯度
        optim.step()  #参数调优
        sum_loss += loss
    print("每一轮的损失值:", sum_loss)

9.加载现有模型、并且修改

import os
import torchvision
from torchvision import models
from torchvision.models import vgg16
from torch import nn

# 修改下载路径
os.environ['TORCH_HOME']='D:\\6.PyCharm\\1项目代码\\test\models'
# 不自带参数
vgg16_false = vgg16(weights=None)
# 自带参数
vgg16_true = vgg16(weights=models.VGG16_Weights.DEFAULT)

print(vgg16_true)
# print(vgg16_false)

vgg16_true.add_module('add_linear1', nn.Linear(1000, 10))
print(vgg16_true)

vgg16_true.classifier.add_module('add_linear2', nn.Linear(1000, 10))
print(vgg16_true)

vgg16_true.classifier[6] = nn.Linear(4096, 10)
print(vgg16_true)

添加

vgg16_true.add_module('add_linear', nn.Linear(1000, 10))

在这里插入图片描述

vgg16_true.classifier.add_module('add_linear', nn.Linear(1000, 10))

在这里插入图片描述
修改

vgg16_true.classifier[6] = nn.Linear(4096, 10)

原来:
在这里插入图片描述
修改后:
在这里插入图片描述

10.网络模型的保存和读入

10.1网上加载的模型

获取模型:

os.environ['TORCH_HOME']='D:\\6.PyCharm\\1项目代码\\study_pytorch\models'
vgg16 = torchvision.models.vgg16(weights=torchvision.models.VGG16_Weights.DEFAULT)

保存模型:

# 保存模型法1:保存参数,保存结构
torch.save(vgg16, "./vgg16_1.pth")

# 保存模型法2:保存参数,不保存结构
torch.save(vgg16.state_dict(), "./vgg16_2.pth")

加载模型:

# 加载法1:
# weights_only不知道社么意思
load_model1 = torch.load('./vgg16_1.pth', weights_only=False)
print(load_model1)

在这里插入图片描述

# 加载法2:
# 1.输出是参数字典
load_model2 = torch.load('./vgg16_2.pth', weights_only=False)
print(load_model2)
# 2.输出的结构
vgg16 = torchvision.models.vgg16(weights=torchvision.models.VGG16_Weights.DEFAULT)  # 获取模型
vgg16.load_state_dict(torch.load('./vgg16_2.pth', weights_only=False))  # 加载参数->放入模型
print(vgg16)

在这里插入图片描述
在这里插入图片描述

10.2加载自定义模型

保存模型:
文件1.py:

# 保存模型法1:自定义模型
class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, 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

mymodule = MyModule()
torch.save(mymodule, "./mymodule.pth")

文件2.py:

# 加载法1:自定义模型
mymodule = torch.load('./mymodule.pth', weights_only=False)
print(mymodule)

以上代码回会出错。
解决办法:
1.加入class MyModule(nn.Module):XXXX自己模型的代码。

# 保存模型法1:自定义模型
class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, 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
# 加载法1:自定义模型
mymodule = torch.load('./mymodule.pth', weights_only=False)
print(mymodule)

2.from model import *直接导入,注意model是.py模型文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿斯卡码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值