pytorch学习笔记

学习工具:
dir():打开,看见
help():官方的解释文档

加载数据

dir(torch.cuda.is_available) -----------注意,不是is_available()
输出前后带_ _,表明.is_available不是分割区,是函数在这里插入图片描述
————————————————————————————————————————————

三种写代码的不同
在这里插入图片描述
———————————————————————————————————————————————————————

windows里用\表示转译
在这里插入图片描述

———————————————————————————————————————————————————————
1.os.path.join() 拼接地址

2.os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。

它不包括 . 和 … 即使它在文件夹中。

只支持在 Unix, Windows 下使用。

加载数据代码

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

class MyData(Dataset):

    def __init__(self,root_dir, label_dir):
    # 为整个class提供全局变量
    # 为一些方法提供一些量
        self.root_dir = root_dir
        self.label_dir=label_dir
        self.path=os.path.join(self.root_dir,self.label_dir)
        self.img_path = os.listdir(self.path)

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

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

root_dir=r"data/dataset/train"
ants_label_dir="ants_image"
bees_label_dir="bees_image"
ants_dataset=MyData(root_dir,ants_label_dir)
bees_dataset=MyData(root_dir,bees_label_dir)

#合并
train_dataset = ants_dataset + bees_dataset

#img,label = ants_dataset[0]
#img.show()
#会展现出第0张蚂蚁的图片


ants_jpgname=ants_dataset.img_path
bees_jpgname=bees_dataset.img_path

for i in ants_jpgname:
    ants_lebelname=i.split('.jpg')[0]+'.txt'

    with open(r"D:\shenduxuexi\data\dataset\train\ants_label\{}".format(ants_lebelname),'w') as f:
        pass
        #这里是写入每张照片的信息


for i in bees_jpgname:
    bees_lebelname=i.split('.jpg')[0]+'.txt'

    with open(r"D:\shenduxuexi\data\dataset\train\bees_label\{}".format(bees_lebelname),'w') as f:
        pass
        #这里是写入每张照片的信息




Tenserboard

是TensorFlow提供的一个强大的可视化工具,也是一个Web应用程序套件,通过运行本地服务器,在浏览器中显示训练过程中记录的数据。
探究模型不同阶段是怎么输出的

from torch.utils.tensorboard import SummaryWriter
#创建实例
writer = SummaryWriter(logs)
#两种方法
writer.add_image()
writer.add_scalar()


writer.close()

writer.add_scalar():

 def add_scalar(
        self,
        tag,#标题
        scalar_value,#y轴
        global_step=None,#x轴
        walltime=None,
        new_style=False,
        double_precision=False,
    ):

在Terminal激活环境: conda cativate 环境名
打开端口:

tensorboard --logdir=logs
#logdir=事件文件所在文件夹名

#默认打开端口是6006
#指定端口防止与别人冲突:
tensorboard --logdir=logs --port=6007

在这里插入图片描述

writer.add_image()

  1. 利用Opencv读取图片,获得numpy类型图片数据

pip install opencv-python

import cv2
cv_img = cv2.imread(img_path)

在这里插入图片描述

  1. 用numpy.array(),对PIL图片进行转换。 用Image.open()打开的图像文件是PIL型
img=Image.open(image_path)
import numpy as np
img_array=np.array(img)
type(img_array)#数据类型
img_array.shape#数据维度

*PyCharm 错误:Empty suite:py文件不要以test开头 *

from torch.utils.tensorboard import SummaryWriter
from PIL import Image
import numpy as np
from PIL import Image

#创建实例
writer = SummaryWriter('logs')
image_path=r"D:\shenduxuexi\data\dataset\train\ants_image\0013035.jpg"
img_PIL=Image.open(image_path)
img_array=np.array(img_PIL)

print(type(img_array))
print(img_array.shape)

writer.add_image("test",img_array,1,dataformats='HWC')
#不改变tag,只改变step和图片地址,出来的图会在一个框内,可以看每一步是什么图片
#dataformats是看add_image文档得的

#y=x
for i  in range(100):
    writer.add_scalar("y=2x",2*i,i)
#多了logs文件夹,里面是tensorboard的事件文件

writer.close()

transform

主要是对图形进行变化、处理

transforms结构及用法
拿一定格式的图片,经过transforms.py的工具,得到想要的图片的结果or图片的变化

from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from PIL import Image
# python 用法
#   tensor数据类型
#   通过transforms.ToTensor去解决两个问题
#   1.transforms要怎么使用
#   2.why 需要Tensor数据类型
#       tensor数据类型包装了进行深度学习的时候需要的一些数据


img_path = r"D:\shenduxuexi\data\dataset\train\ants_image\0013035.jpg"
img = Image.open(img_path)
writer = SummaryWriter("logs1")

#1.transforms要怎么使用
#   实例化ToTensor,将图片转化为tensor类型
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)

#print(tensor_trans)
#   2.why 需要Tensor数据类型
#       tensor数据类型包装了进行深度学习的时候需要的一些数据

writer.add_image("Tensor_img",tensor_img)
writer.close()

常见的Transforms

在这里插入图片描述

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

writer = SummaryWriter("logs2")
img = Image.open(r'D:\shenduxuexi\images\0013035.jpg')


#ToTensor
trans_totensor=transforms.ToTensor()
img_tensor=trans_totensor(img)
writer.add_image("ToTensor",img_tensor)

#Normalize
#三个0表示 第一个通道 第一行 第一列
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([1,2,3],[2,4,5])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normlize",img_norm,1)

#Resize
print(img.size)
trans_resize=transforms.Resize((512,512))
img_resize=trans_resize(img)
#img 经过resize,PIL->PIL
print(img_resize)

#输出的是PIL类型,若想在tensorboard上显示,用ToTensor转化为tensor类型
img_resize=trans_totensor(img_resize)
writer.add_image("Resize",img_resize,0)

#Compose - resize
#   输入的是一个序列,不改变高和宽的比例,只改变最小边
trans_resize_2 = transforms.Resize(512)
#它包含了两个变换操作:首先是trans_resize_2,负责调整图像大小;其次是trans_totensor,将调整大小后的图像从PIL格式转换为PyTorch张量。
trans_compose = transforms.Compose([trans_resize_2,trans_totensor])
#应用了这个组合变换到原始图像img上。
img_resize_2 = trans_compose(img)
writer.add_image("Resize",img_resize_2,1)

#RandomCrop 随机裁剪,裁剪的结果是原图片的一部分
#如果RandomCrop中的数字大于图片大小就会报错
trans_random = transforms.RandomCrop(200)
trans_compose_2 = transforms.Compose([trans_random,trans_totensor])
for i in range(1,10):
    img_crop = trans_compose_2(img)
    writer.add_image("RandomCrop",img_crop,i)


writer.close()

主要看输入什么类型,输出什么类型
多看官方文档(阅读源码)
关注方法需要什么参数
不知道返回值是什么的时候,多print(),print(type))

torchvision数据集的使用

torchvision
torchvision.models提供了多种预训练模型
torchvision.datasets提供了数据集
torchvision.transforms提供了图像预处理功能

import torchvision
from torch.utils.tensorboard import SummaryWriter

#对图片进行一些操作
dataset_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])

#
train_set = torchvision.datasets.CIFAR10(root=r"./dataset",train=True,transform=dataset_transform,download=True)
test_set = torchvision.datasets.CIFAR10(root=r"./dataset",train=False,transform=dataset_transform,download=True)

# print(test_set[0])
# print(test_set.classes)
#
# img,target = test_set[0]
# print(img)
# print(target)

writer = SummaryWriter("p10")
for i in range(10):
    img,target = test_set[i]
    writer.add_image("test_set",img,i)

writer.close()


DataLoader的使用

DataLoader是PyTorch中用于数据预处理和批处理的核心工具。它可以按需加载数据并将其分批送入神经网络进行训练。DataLoader不仅支持数据的批量加载,还可以对数据进行打乱(shuffle)、多进程加载(multiprocessing loading)等操作,以提高数据处理的效率和模型训练的性能。

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

#准备的测试数据集
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)
#这种配置适合于测试阶段,因为测试通常不需要像训练那样频繁地更新模型权重,而且保持数据顺序可能有助于评估模型在特定数据顺序下的表现。

#测试数据集中第一张图片和target
img,target=test_data[0]
print(img.shape)
print(target)
for data in test_loader:
    imgs,targets = data
    print(imgs.shape)
    print(targets)

在这里插入图片描述

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

#准备的测试数据集
test_data = torchvision.datasets.CIFAR10("./dataset",train=True,transform=torchvision.transforms.ToTensor())

test_loader = DataLoader(dataset=test_data,batch_size=4,shuffle=True,num_workers=0,drop_last=False)
#这种配置适合于测试阶段,因为测试通常不需要像训练那样频繁地更新模型权重,而且保持数据顺序可能有助于评估模型在特定数据顺序下的表现。

#测试数据集中第一张图片和target
img,target=test_data[0]
print(img.shape)
print(target)

writer=SummaryWriter("dataloader")

#epoch,多次对这一批数据进行抓取,shuffle应该设置为True
for epoch in range(2):
    step = 0
    for data in test_loader:
        imgs,targets = data
        # print(imgs.shape)
        # print(targets)
        writer.add_images("epoch = {}".format(epoch), imgs, step)
        step=step+1

#不用epoch时:
# step = 0
# for data in test_loader:
#     imgs,targets = data
#     # print(imgs.shape)
#     # print(targets)
#     writer.add_images("test_data", imgs, step)
#     step=step+1


writer.close()

神经网络基本骨架——nn.Module

要创建一个自定义的神经网络模型,需要继承 nn.Module 类并重写其 init 和 forward 方法。在 init 方法中定义模型的层和参数,forward 方法定义模型的前向传播逻辑。

import torch
from torch import nn


class mod(nn.Module):
    def __init__(self):
        super().__init__()


    def forward(self,input):
        output = input+1
        return output

MOD=mod()
x=torch.tensor(1.0)
output=mod(x)
print(output)

卷积操作

stride (int or tuple, optional): 卷积步长,可以是单个整数或包含两个整数的元组 (stride_height, stride_width),默认为 1。
padding (int or tuple, optional): 输入张量两侧的零填充大小,可以是单个整数或包含两个整数的元组 (padding_height, padding_width),默认为 0。

import torch
import torch.nn.functional as F
input = torch.tensor([[1,2,0,3,1],
                      [0,1,2,3,1],
                      [1,2,1,0,0],
                      [5,2,3,1,1],
                      [2,1,0,1,1]])

kernel = torch.tensor([[1,2,1],
                       [0,1,0],
                       [2,1,0]])

#torch.reshape函数在PyTorch中用于改变张量的形状,而不改变其数据。
input = torch.reshape(input,(1,1,5,5))
                 #   (batchsize,channal,5,5)

kernel = torch.reshape(kernel,(1,1,3,3))

print(input.shape)
print(kernel.shape)

output1 = F.conv2d(input,kernel,stride=1)

print("output1 = \n",output1)

output2 = F.conv2d(input,kernel,stride=2)
print("output2 = \n",output2)

output3 = F.conv2d(input,kernel,stride=1,padding=1)
print("output3 = \n",output3)

在这里插入图片描述

卷积层

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

dataset = torchvision.datasets.CIFAR10(R"D:\shenduxuexi\dataset",train=False,transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader= DataLoader(dataset,batch_size=64)

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

ycb=Ycb()
print(ycb)
writer = SummaryWriter("nn_conv2")
step=0
for data in dataloader:
    imgs,targets=data
    output = ycb(imgs)
    # print(imgs.shape)
    # print(output.shape)

    #torch.Size([64, 3, 32, 32])
    writer.add_images("input",imgs,step)
#输出卷积后数据先看对应数据是否符合输出要求!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'''
    #output:torch.Size([64, 6, 30, 30])
    #    直接add_image(soutput)会报错,add_images函数要求通道数为3
    #    用torch.reshape改变通道数,其中第一个不知道写啥写-1,会自动计算
    output=torch.reshape(output, (-1, 3, 30, 30))
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'''
    writer.add_images("output", output, step)
    step=step+1
writer.close()



池化层

最大池化层——下采样

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

dataset = torchvision.datasets.CIFAR10(r"D:\shenduxuexi\dataset",train=False,download=True,transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset,batch_size=64)

# input = torch.tensor([[1,2,0,3,1],
#                       [0,1,2,3,1],
#                       [1,2,1,0,0],
#                       [5,2,3,1,1],
#                       [2,1,0,1,1]])
#
# input = torch.reshape(input,(-1,1,5,5))
# class Ycb()
# ....
# output = ycb(input)
# print(output)
class Ycb(nn.Module):
    def __init__(self):
        super().__init__()
        #ceil_mode:ceil  floor
        self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)

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

ycb=Ycb()
writer=SummaryWriter("nn_maxpool")
step=0
for data in dataloader:
    imgs,targets=data
    writer.add_images("input",imgs,step)
    output=ycb(imgs)
    #池化不会改变通道数,不用跟卷积一样改变
    writer.add_images("output",output,step)
    step=step+1

writer.close()

在这里插入图片描述

非线性激活

ReLU()
Sigmoid()

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

# input = torch.tensor([[1,-0.5],
#                       [-1,3]])
# output = torch.reshape(input,(-1,1,2,2))

dataset = torchvision.datasets.CIFAR10(r"D:\shenduxuexi\dataset",train=False,download=True,transform=torchvision.transforms.ToTensor())

dataloader = DataLoader(dataset,batch_size=64)

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

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

ycb=Ycb()

writer = SummaryWriter("relu")

step=0

for data in dataloader:
    imgs,targets = data
    writer.add_images("input",imgs,step)
    output=ycb(imgs)
    writer.add_images("output",output,step)

    step+=1
writer.close()

在这里插入图片描述

正则化层:对输入进行正则化,可以加快训练速度

线性层

先看弄成线性后的in_f是多少

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

dataset = torchvision.datasets.CIFAR10("D:\shenduxuexi\dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=64)



for data in dataloader:
    imgs,targets = data
    print(imgs.shape)
    output=torch.reshape(imgs,(1,1,1,-1))
    print(output.shape)

在这里插入图片描述

torch.flatten 是 PyTorch 库中的一个函数,用于将张量展平为一维张量。

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

dataset = torchvision.datasets.CIFAR10("D:\shenduxuexi\dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=64)

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

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

ycb=Ycb()
for data in dataloader:
    imgs,targets = data
    print(imgs.shape)
    output = torch.flatten(imgs)
    print(output.shape)

在这里插入图片描述

搭建实战,Sequential使用

Sequential写法!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
复刻
在这里插入图片描述

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

# class Ycb(nn.Module):
#     def __init__(self):
#         super().__init__()
#         self.conv1 = Conv2d(3, 32,5,padding=2)#padding是根据公式算的
#         self.maxpool1 = MaxPool2d(2)
#         self.conv2 = Conv2d(32,32,5,padding=2)
#         self.maxpool2 = MaxPool2d(2)
#         self.conv3 = Conv2d(32,64,5,padding=2)
#         self.maxpool3 = MaxPool2d(2)
#         self.flatten = Flatten()
#         self.linear1 = Linear(1024,64)
#         self.linear2 = 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)
#         return x

#若用Sequential,代码会更简洁
class Ycb(nn.Module):
    def __init__(self):
        super().__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


ycb = Ycb()
print(ycb)


input = torch.ones((64,3,32,32))
output = ycb(input)
print(output.shape)


writer=SummaryWriter("seq")

#add_graph函数通常用于将模型的计算图添加到TensorBoard中
writer.add_graph(ycb,input)
writer.close()

损失函数

1. 计算了实际输出与目标的差距
2. 为更新输出提供了一定的依据(反向传播) grad

nn_loss.py

import torch
from torch.nn import L1Loss
from torch import nn
inputs = torch.tensor([1,2,3.])
targets = torch.tensor([1,2,5.])

inputs=torch.reshape(inputs,(1,1,1,3))

targets=torch.reshape(targets,(1,1,1,3))
#MAE  平均绝对误差
loss=L1Loss()
result = loss(inputs,targets)


#MSE  均方误差
loss_mse=nn.MSELoss()
result_mse = loss_mse(inputs,targets)

#交叉熵
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)

nn_loss_network.py

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

dataset = torchvision.datasets.CIFAR10("D:\shenduxuexi\dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=64)

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

loss = nn.CrossEntropyLoss()
ycb = Ycb()
for data in dataloader:
    imgs,targets=data
    outputs=ycb(imgs)
    # #输出outputs和targets,看看选哪个损失函数,这里选的交叉熵
    # print(outputs)
    # print(targets)
    result_loss=loss(outputs,targets)
    print(result_loss)
    #一定是经过了loss的变量进行反向传播
    result_loss.backward()
#print(ycb)

优化器

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

dataset = torchvision.datasets.CIFAR10("D:\shenduxuexi\dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader = DataLoader(dataset,batch_size=64)

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

loss = nn.CrossEntropyLoss()
ycb = Ycb()
optim=torch.optim.SGD(ycb.parameters(),lr=0.01)#刚开始学习速率用大一点的,后来用小一点的

for epoch in range(20):
    #看每一轮loss是多少
    running_loss=0.0
    for data in dataloader:
        imgs,targets=data
        outputs=ycb(imgs)

        result_loss=loss(outputs,targets)
        #把优化器的参数设置为0
        optim.zero_grad()

        result_loss.backward()
        optim.step()

        running_loss=running_loss+result_loss
    print(running_loss)
    #会发现loss会慢慢变小

在这里插入图片描述

现有网络模型的使用和修改

import torchvision
import torch
import torchvision.datasets
from torch import nn
from torch.nn import ReLU, Sigmoid, Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
vgg16_false = torchvision.models.vgg16(weights=None)
vgg16_true = torchvision.models.vgg16(weights='DEFAULT')
print(vgg16_true)

vgg16_true的classifier结果:

  (classifier): Sequential(
    (0): Linear(in_features=25088, out_features=4096, bias=True)
    (1): ReLU(inplace=True)
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=4096, out_features=4096, bias=True)
    (4): ReLU(inplace=True)
    (5): Dropout(p=0.5, inplace=False)
    (6): Linear(in_features=4096, out_features=1000, bias=True)

1. 对vgg16_true加一层线性层

import torchvision
import torch
import torchvision.datasets
from torch import nn
from torch.nn import ReLU, Sigmoid, Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
vgg16_false = torchvision.models.vgg16(weights=None)
vgg16_true = torchvision.models.vgg16(weights='DEFAULT')

train_data = torchvision.datasets.CIFAR10("D:\shenduxuexi\dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)

#如何利用现有的网络,去改变他的结构  迁移学习
#以vgg16为前置网络
vgg16_true.classifier.add_module('add_linear',nn.Linear(1000,10))
print(vgg16_true)

结果会是

(classifier): Sequential(
    (0): Linear(in_features=25088, out_features=4096, bias=True)
    (1): ReLU(inplace=True)
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=4096, out_features=4096, bias=True)
    (4): ReLU(inplace=True)
    (5): Dropout(p=0.5, inplace=False)
    (6): Linear(in_features=4096, out_features=1000, bias=True)
    (add_linear): Linear(in_features=1000, out_features=10, bias=True)#多了这个
  )

2. 修改最后的线性层

import torchvision
import torch
import torchvision.datasets
from torch import nn
from torch.nn import ReLU, Sigmoid, Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
vgg16_false = torchvision.models.vgg16(weights=None)
vgg16_true = torchvision.models.vgg16(weights='DEFAULT')

train_data = torchvision.datasets.CIFAR10("D:\shenduxuexi\dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)

#如何利用现有的网络,去改变他的结构  迁移学习

# #以vgg16为前置网络,加层
# vgg16_true.classifier.add_module('add_linear',nn.Linear(1000,10))
# print(vgg16_true)

#2. 修改网络
print(vgg16_false)
vgg16_false.classifier[6] = nn.Linear(4096,10,True)
print(vgg16_false)

修改前
在这里插入图片描述
修改后
在这里插入图片描述

网络模型的保存与读取

一般保存和读取会在不同的文件里
方式1

import torchvision
import torch
import torchvision.datasets
from torch import nn
from torch.nn import ReLU, Sigmoid, Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
vgg16=torchvision.models.vgg16(pretrain=False)

#保存方式1     不仅保存了网络结构,也保存了一些网络参数
torch.save(vgg16,"vgg16_method1.pdh")#推荐后缀为pdh
#加载方式1  对应保存方式1
model = torch.load(("vgg16_method1.pdh"))

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

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

ycb=Ycb()
#保存
torch.save(ycb,"ycb_mothod1.pth")

#在另一个文件里加载
model=torch.load("ycb_mothod1.pth")

#会报错,需要把保存的文件在加载的文件里import   from model_save import *


方式2

import torchvision
import torch
import torchvision.datasets
from torch import nn
from torch.nn import ReLU, Sigmoid, Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
vgg16=torchvision.models.vgg16(pretrain=False)

#保存方式2(官方推荐)   把vgg16的参数保存成字典,只保存了模型参数
torch.save(vgg16.state_dict(),"vgg16_method2.pdh")
#加载方式2
#   因为保存方式2只保存了字典,所以要先载入模型
vgg16 = torchvision.models.vgg16(pretrained = False)
#   再把参数填充进去
vgg16.load_state_dict(torch.load(("vgg16_method1.pdh")))

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值