【个人笔记 | Pytorch课程 | 整理中ing】

article/2025/10/23 17:30:21

【小土堆】

小土堆课程视频

笔记others:

入门与Dataset数据加载

【入门/数据/预处理】

pycharm     安装:https://www.jetbrains.com/pycharm/、指南、

可以在右上写代码,可以在左下控制台写程序(一般用于调试)

conda-Pytorch 

深度学习框架的自动微分技术根据实现原理的不同,分为以Google的TensorFlow为代表的图方法,以facebook的Pytorch为代表的↓

安装过程太慢:下载安装包,复制到Anaconda3=>pkgs

conda install --use-local 包名

torch.cuda.is_available() 

 1、安装: 指南1★、PyTorch、自己写的环境配置Blog√

看电脑python版本 、conda info -e

pip list:可以查看Python中安装了哪些第三方库

查看GPU是否支持cuda-link:设备管理器-显示适配器  or  任务管理器-性能-GPU、方法

虽然Pytorch完全可以在CPU模式下运行,但大多数情况都是使用GPU支持的Pytorch,需要GPU的支持,所以要下载CUDA.(以后要用再说,可新环境下装)

镜像安装、★Anaconda配置Pytorch、

conda activate pytorch
jupyter notebook

2、两大法宝函数

dir()函数:打开、看见,可以当作一个文件夹 (能让我们知道工具箱以及工具箱中的分隔区有什么东西)

help()函数:说明书,在jupyter notebook中使用 排版清晰(能让我们知道每个工具是如何使用的)

3、加载数据(P6)

笔记others:Dateset、

蜜蜂蚂蚁 二分类数据集

from torch.utils.data import Dataset(从torch的大工具箱里的常用工具区utils里关于数据的data)

查看官方文件×3:①help(Dataset)②Dataset??③按住Ctrl+鼠标点击

class MyData(继承Dataset):

init初始化类去创建实例:一般为整个class提供全局变量,在这里就是为后面的getitem方法和len提供需要的变量(可以放在后面再来写)

一个函数中的变量不能传递个另一个函数中的变量,而self可以把self中指定的内容给后面的函数使用,就相当于指定了一个类中的全局变量。

def __init__(self,root_dir,label_dir):self.root_dir = root_dir //文件夹目录"dataset/train"self.label_dir = label_dir //标签目录"ants"//↓拼在一起,获得每一个标签文件的地址 "dataset/train/ants"self.path = os.path.join(self.root_dir,self.label_dir) //组成列表,就是每一个具体jpg所组成的列表self.img_path = os.listdir(self.path) 

  

getitem(idx作为索引):通过idx索引获取图片地址

获取文件夹中所有图片:import os

首先设置dir_path=r"/" 然后将该文件夹下所有内容转换成列表img_path_list =  os.listdir(dir_path) (可以使用img_path_list[0]来查看第一个文件)

获取其中的每一个图片,就是从img_path汇总读取对应位置,因为要引用上面init定义的变量所以要加self。现在找到名称了,还需要找到它在该目录下的相对路径。

def __getitem__(self,idx):img_name = self.img_path[idx]img_item_path = os.path.join(self.root_door,self.label_dir,img_name)//读取图片img = Image.open(img_item_path)//labellabel = self.label_dirreturn img,label

len长度返回,就是返回img路径列表长度

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

然后可以写一个了

root_dir = "dataset/train"

ants_label_dir = "ants"

bees_label_dir = "bees"

ants_dataset = MyData(root_dir,ants_label_dir)

bees_dataset = MyData(root_dir,bees_label_dir)

弹幕提示:报错的把ants_dataset[0]换成ants_dataset.__getitem__(0)

还有一种方式就是将二者数据集拼接:train_dataset = ants_dateset+bees_dateset

复制相对路径:Ctrl+Shift+C         全局路径:Ctrl+Alt+Shift+C

#Python Console逐步显示
from PIL import Image
img_path= ....jpg" #具体图片路径,记得\\进行语义转换
img = Image.open(img_path)
img.show()

4、TensorBoard使用 ​

PyTorch下的Tensorboard 使用:用于数据可视化的工具(对transform后的图像进行展示)原本是tensorflow的可视化工具,pytorch从1.2.0开始支持tensorboard。之前的版本也可以使用tensorboardX代替。直接pip之后有可能打开的tensorboard网页是全白的,如果有这种问题,解决方法是卸载之后安装更低版本的tensorboard(直接pip install就可以了)

通过loss可以看我们需要选择什么样的模型(when符合预期)

add_scalar与add_image(弹幕:PLT也能达到同样的效果)

 tensorboard ValueError: Duplicate plugins for name projector  ★有效!

add_scalar(tag, scalar_value, global_step=None, ):将我们所需要的数据保存在文件里面供可视化使用
tag(字符串):保存图的名称
scalar_value(浮点型或字符串):y轴数据(步数)
global_step(int):x轴数据

// logdir=事件文件所在文件夹名
// 在项目文件夹Terminal下:默认端口6006
tensorboard --logdir=logs
// 如果修改端口为6007
tensorboard --logdir=logs --port=6007

writer.add_scalar("目标函数",global_step,scalar_value)
#global_step 对应x轴;scalar_value对应y轴

writer.add_scalar("y=x",i,i)       # y = x 下图1
writer.add_scalar("y=2x",2*i,i)    # y = 2x 下图2
writer.add_scalar("y=2x",3*i,i)    # y = 3x 下图3

看到图3有个过渡拟合过程。解决办法:①logs下文件全部删除②run③在Terminal下新开local并再次输入命令(tensorboard --logdir=logs) 就得到想要的图像了(出问题就设置绝对路径)

Tensorboard: SummaryWriter类(pytorch版) :大意是将条目直接写入 log_dir 中的事件文件以供 TensorBoard 使用(`SummaryWriter` 类提供了一个高级 API,用于在给定目录中创建事件文件,并向其中添加摘要和事件)。tensorboard --logdir=XXXX(XXXX就是你要求tensorboard writer把文件写入的那个地方在上图中就是logs),为了防止端口冲突,可以设置一个特别的端口,就是在上面的命令后再加一个 --port=端口

add_image(self, tag, img_tensor, global_step=none, walltime=none, dataformats=‘CHW’)

add_image(self, tag, img_tensor, global_step=none, walltime=none, dataformats=‘CHW’)

绘制图片,可用于检查模型的输入,监测 feature map 的变化,或是观察 weight。
tag:就是保存图的名称
img_tensor:图片的类型要是torch.Tensor, numpy.array, or  这三种

                OpenCV读取的数据格式就是Numpy型,可以print(type(img))看一下类型,常用pil
global_step:第几张图片
dataformats=‘CHW’,默认CHW,tensor是CHW,numpy是HWC

                这里可能会报错,可以debug或者print(xxx.shape)查看一下,if维度问题就在这改

完整代码:某张图片的路径给img_path;         打开这张图片到img_PIL;         因为add_image要求图片类型为tensor/numpy/string,而pil查看type(img_path为pil),所以先转成numpy;[可以print一下type和shape(opencv读取的数据格式是Numpy)];        然后就可以设置add_image里的参数了,up遇到的一个问题就是dataformats注意一下shape

from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Imagewriter = SummaryWriter("logs")
image_path = "data/train/ants_image/6240329_72c01e663e.jpg"
img_PIL = Image.open(image_path)
img_array = np.array(img_PIL)
print(type(img_array))
print(img_array.shape)writer.add_image("train", img_array, 1, dataformats='HWC')
# y = 2x
for i in range(100):writer.add_scalar("y=2x", 3*i, i)writer.close()

 5、torchvision中的transforms ​

①使用的时候注意input和output的类型;

②多看官方文档,关注方法需要什么参数(在使用的时候就去看它官方文档中的init文件,对功能和参数都有很清晰的解释

③不知道返回值or数据是什么类型or有TypeError报错的haul,就print、print(type())、debug

④借助一下tensorboard工具查看得到的图片 

Alt+Enter 导入库                Ctrl+P 看要加什么参数

视频笔记:

from torchvision import transforms ->进入transform 定义了很多class的工具箱

torchvision.transforms中的compose,常用的是(PIL/numpy)ToTensor√、Normalize、Resize

关于__call__的使用(双下划线就是内置参数)

class Person:def __call__(self,name):print("__call__"+" Hello"+name)
person = Person()
person("zahngsan")//可以ctrl+P看有没有参数输入提示
//输出:__call__ Hello zhangsanclass Person:def hello(self,name)print("hello"+name)
person = Person()
person.hello("zhangsan")
//输出:zhangsan

 关于ToTensor的使用

 关于Normalize的使用(传入RGB三个通道的均值和标准差)(输入PIL图片)

关于resize的使用(输入是PIL)

(下面2实际代码参数换位置会报TypeError类型错误)

关于随机裁剪RandomCrop的使用

 6、torchvision中数据集的使用:Dataset和Dataloader

官网torchvision中数据集(datasets、)(迅雷工具)

import torchvision
from torch.utils.tensorboard import SummaryWriterdataset_transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()
])train_set = torchvision.datasets.CIFAR10(root="./dataset", train=True, transform=dataset_transform, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, transform=dataset_transform, download=True)writer = SummaryWriter("p10")
for i in range(10):img, target = test_set[i]writer.add_image("test_set", img, i)writer.close()

shuffle取数据的时候batchsize里图片顺序是被打乱的

【神经网络】

 1、Pytorch中的torch.nn、nn.Module、Conv2d卷积、maxpool最大池化、非线性激活、线性else

小结:学会看Pytorch官方文档、tensorboard工具来可视化(入门) 、ctrl+P参数

torch.nn        container↓

Module

Base class for all neural network modules.(模板,你们拿去用吧/修改吧在init和forward)

Sequential

A sequential container. (☆ self.model =  nn.sequential(,,,,,)

ModuleList

Holds submodules in a list.

ModuleDict

Holds submodules in a dictionary.

ParameterList

Holds parameters in a list.

ParameterDict

Holds parameters in a dictionary.

import torch.nn as nn
import torch.nn.functional as Fclass Model(nn.Module):def __init__(self):super().__init__()self.conv1 = nn.Conv2d(1, 20, 5)self.conv2 = nn.Conv2d(20, 20, 5)def forward(self, x):x = F.relu(self.conv1(x))return F.relu(self.conv2(x))

 以nn.Module为例,好用工具之"代码 -> 生成 -> 重写 ->挑你要的方法"

卷积conv2d(主要是5参数,再主要是前两参数in_channel,out_channel,kernel,stride,padding)

(1channel)

output_c=2c

首先传入Input和Kernel发现都是只有HW(左图),而conv要求通道minibatch、channel、H、W,所以要利用Torch.reshape进行改变。(例子nn.conv2d,output2是步长2,output3是paddding=1)

nn.Conv1d

Applies a 1D convolution over an input signal composed of several input planes.

nn.Conv2d

Applies a 2D convolution over an input signal composed of several input planes.(主要用2d

nn.Conv3d

Applies a 3D convolution over an input signal composed of several input planes.

在跟着up写conv2d时遇到的一些问题:

报错1:urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1122)>还有module 'urllib' has no attribute 'urlopen'

原因及解决办法(方法2):是由于python版本之间差异导致的,Python 3中urllib2用urllib.request替代;所以把所有位置都换成带有.request,继续报错,关闭ssl本地认证(加进代码),然后写入main主函数里(不放在里面也可以跑通)。

报错2:自己去写第一步输出卷积的时候,加载的是之前已经下载好的数据集;然后有下面一个报错,是因为conv2d这里写错了,改成Conv2d并且红色灯泡Import就可以解决了 。

报错3:SyntaxError: Non-UTF-8 code starting with '\xba' in file

解决方法:在代码最开头加上这句(我小写也不行)

# coding=UTF-8

接着就是借助tensorboard工具可视化过程一下

报错4:设置的output_c是6,而RGB三通道无法显示,所以up提供了reshape方法,但不严谨

然后取terminal终端去输入↓命令,就打开了。

tensorboard --logdir=logs

最终版:

# coding=UTF-8
import torchvision.datasets
import torch
import torchvision
from torch import nn, conv2d
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriterimport ssl
ssl._create_default_https_context = ssl._create_unverified_contextclass SUNDAY(nn.Module):def __init__(self):super(SUNDAY, self).__init__()self.conv1 = Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1)# self.conv1 = conv2d(in_channel=3,output_channel=6,kernel_size=3,stride=1)def forward(self,x):x=self.conv1(x)return xif __name__ == '__main__':dataset = torchvision.datasets.CIFAR10(r'./data', train=False, transform=torchvision.transforms.ToTensor(),download=True)dataloader = DataLoader(dataset, batch_size=64)sunday = SUNDAY()# print(sunday)# 然后想看data里每一张图片,所以writer =SummaryWriter("../logs")step =0 #global_stepfor data in dataloader:imgs, targets = data  # 现在已经使tensor格式所以可以直接送入到网络当中output = sunday(imgs)  # 就是data中的图片数据imgs送入神经网络SUNDAY中经过forward卷积操作得到的结果print(imgs.shape)  # 看一下conv1是否实现# torch.Size([64, 3, 32, 32])print(output.shape)# torch.Size([64, 6, 30, 30])writer.add_images("input", imgs, step)output = torch.reshape(output, (-1,3,30,30)) # 不知道第一个数是多少的时候就写-1,会自动根据后面writer.add_images("output", output, step)step = step+1

MaxPool2d 最大池化-下采样(目的是为了保留特征 同时 减小数据量)

Parameters:kernel_size、stride、padding、dilation空洞卷积、ceil_mode

最大池化中stride参数默认值是kernel_size(卷积中默认是1)

true=保留,默认的ceil_mode是false也就是不保留

写个程序来实现和验证一下这个过程和结果

如果出现RuntimeError:"max_pool2d_with_indices_cpu"not implemented for 'Long',就可以在后面加上dtype=float32,这样1就会变成1.0(浮点型)【最大池化】

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 SummaryWriterdataset = torchvision.datasets.CIFAR10(r'./data', train=False, transform=torchvision.transforms.ToTensor(), download=True)
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]])
# print(input.shape)
# input = torch.reshape(input, (-1, 1, 5, 5))
# print(input.shape)class SUNDAY(nn.Module):def __init__(self):super(SUNDAY, self).__init__()self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=False)def forward(self, input):output = self.maxpool1(input)return outputsunday = SUNDAY()
# output = sunday(input)
# print(output)writer = SummaryWriter("../log_maxpool")
step = 0for data in dataloader:imgs, targets = datawriter.add_images("input", imgs, step)output = sunday(imgs)writer.add_images("output", output, step)step = step + 1writer.close()          

在terminal运行tensorboard --logdir=max_pool查看Imgs-output结果

Non-linear Activations非线性激活ReLU、Sigmoid:向神经网络中引入一些非线性的特征,才可以训练处符合更多特征的模型,提高模型的泛化性

nn.ReLU、nn.Sigmoid(以ReLU为例)

 

import torch
import torchvision
from torch import nn
from torch.nn import ReLU, Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriterdataset = torchvision.datasets.CIFAR10(r'./data', train=False, transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset, batch_size=64)class SUNDAY(nn.Module):def __init__(self):super(SUNDAY, self).__init__()self.sigmoid1 = Sigmoid()def forward(self, input):output = self.sigmoid1(input)return outputsunday = SUNDAY()writer = SummaryWriter("../logs_sigmoid")
step = 0
for data in dataloader:imgs, targets = datawriter.add_images("input", imgs, global_step=step)output = sunday(imgs)writer.add_images("output",output,global_step=step)step +=1writer.close()# relu函数
# input = torch.Tensor([[1, -0.5],
#                       [-1, 3]])
# output = torch.reshape(input, (-1, 1, 2, 2))
# print(output.shape)
#
# class SUNDAY(nn.Module):
#     def __init__(self):
#         super(SUNDAY, self).__init__()
#         self.relu1 = ReLU()
#
#     def forward(self,input):
#         output = self.relu1(input)
#         return output
#
# sunday = SUNDAY()
# output = sunday(input)
# print(output)

Normalizetion Layers(加快训练速度):注意一下num_feature=C     [batchsize、C、H、W]

线性层使用的也比较多;Dropout是在训练的过程中以概率p将input中随机变成0,防止过拟合;Distance Functions就是计算两者之间的误差等;Loss Funtion;RecurrentLayer用于文字识别中较多;TransformerLayers;

Linear:torch.nn.Linear(in_featuresout_featuresbias=Truedevice=Nonedtype=None),线性层现在多用来做分类任务的分类头

import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10(r'./data', train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64)class SUNDAY(nn.Module):def __init__(self):super(SUNDAY, self).__init__()self.linear1 = Linear(196608,10)def forward(self, input):# output = self.linear1(input)# return outputreturn self.linear1(input)sunday = SUNDAY()for data in dataloader:imgs, targets = dataprint(imgs.shape)output = torch.reshape(imgs,(1,1,1,-1))print(output.shape)# sunday = SUNDAY(output)output = sunday(output)print(output.shape)

过程报错×2:

TypeError: __init__() takes 1 positional argument but 2 were given(实例化格式使用错误)

AttributeError: 'Tensor' object has no attribute 'linear1'(forward里参数传递顺序出错)

RuntimeError: mat1 and mat2 shapes cannot be multiplied (1x49152 and 196608x10)(显然这只是中间过程,不必纠结。下图左1,看出reshape可以改变shape;fatten拼在一起,左3)

关于reshape:torch.reshape用来改变tensor的shape;其中的-1代表的含义-根据剩余自行排定;

CAFIR10 module structure:Conv2d参数、MaxPool2d参数、

根据输入输出和kernel_size计算padding(就是看原本计算出的输出中HW是不是32x32)

如果不指定,默认stride跟最大池化窗口大小一致(不是和conv一样为1)。

网络搭建完毕如下,需要验证其是否正确(可以验证后修改比如Linear中参数看是否会报错)

import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linearclass SUNDAY(nn.Module):def __init__(self):super(SUNDAY, 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(in_features=1024, out_features=64) #删除这两行,print看网络输出的是什么self.linear2 = Linear(in_features=64, out_features= 10) # torch.size([64,1024])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 xsunday = SUNDAY()
print(sunday)
input = torch.ones((64,3,32,32)) # batchsize,C,H,W
print(sunday(input).shape)

sequential使用:运行结果如下(与上面对比一下)、others笔记

import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear# 使用sequent
class SUNDAY(nn.Sequential):def __init__(self):super(SUNDAY, self).__init__()self.model1 = nn.Sequential(Conv2d(3, 32, 5, padding=2), #使用sequential时用逗号分割层与层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):return self.model1(x)sunday = SUNDAY()
print(sunday)
input = torch.ones(64, 3, 32, 32)
print(sunday(input).shape)# tensorboard --logdir=log_seq终端查看,双击网络展示细节
writer = SummaryWriter("../log_seq")
writer.add_graph(sunday, input)
writer.close()

2、损失函数与反向传播

报错:

TypeError: new() received an invalid combination of arguments - got (list, dtype=torch.dtype), but expected one of:(一些语法和拼写大小问题.tensor不是.Tensor、torch.float32√和numpy.float、以及基本的NN.L1Loss()这里后面的括号)

RuntimeError: Boolean value of Tensor with more than one value is ambiguous(Input/output需要reshape一下,但是我没有reshape,debug查看了一下二者的值(下1);reshape之后也看了一下(下3);发现自己loss拼写错位,修改后没有reshape也可以进行计算)【再看tprch.nn具体文档的时候注意一下函数中的参数及shape要求】

还有报错原因是我想把一些代码合并,或如下图注释中的错误代码,一开始想着为什么不直接把input和output传到L1Loss里面去,但是报错上面第一条。  后面去看了loss.py(下下图),一个是定义这个loss功能,一个是使用它,简单了解就是一个用来声明,一个用来使用,前者参数定义的是我这个Loss是计算什么的,后者参数传入需要计算的内容。

import torch
# from torch.nn import L1Loss
from torch import nninput = torch.tensor([1, 2, 3], dtype = torch.float32)
output = torch.tensor([1, 2, 5], dtype = torch.float32)input = torch.reshape(input, (1, 1, 1, 3))
output = torch.reshape(output, (1, 1, 1, 3))loss_mean = nn.L1Loss()
loss_sum = nn.L1Loss(reduction='sum')
loss_mse = nn.MSELoss()print(loss_mean(input, output))
print(loss_sum(input, output))
print(loss_mse(input, output))# up使用方法
# loss = L1Loss()
# loss2 = L1Loss(reduction='sum')
# result = loss(input, output)
# result = loss2(input, output)
# print(result)

关于交叉熵损失函数,up讲解时和现在官方文档有一些差别 

 反向传播是对result_loss计算,不是对loss(可以debug看,加上.backward()后grad会更新),一定会有的一行代码时optim.zero_grad(),上一次的梯度对下一次的梯度来说无用要清零

torch.optim主要是传入param和lr(一开始可设置比较大)

接下来的部分 主要围绕: 

3、现有模型的使用和修改、保存于读取

torchvision-module选VGG16-使用ImageNet训练(需要下载到本地)、others笔记[很清晰 针不戳]

尝试了一下,默认pretrained=True,也可以在()设定

可以发现得到的是1000个分类,但是如果想要把预训练运用到CIFAR10分类就需要修改。(如果预训练设置为True还是会去下载权重,因为我只想看输出的变换,所以可以用pretrained为False直接进行修改就可以了,虽然vgg16预训练权重不算特别大):一种方法就是在最后添加一个线性层,从10000->10;另一种使用线性层直接将第七层([6]因为从0开始)直接改成in_f=4096, out_f=10

然后就是要对我们训练的模型的权重.pth文件进行保存

保存方式1:模型结构+模型参数       torch.save(model,"路径名称")、torch.load("路径名称")

save文件load文件

方式1陷阱:

改了一下:(torch版本不同会有一些不同) 

保存方式2:模型参数          直接import模型 从save文件中(up的vgg16,我的model)

save文件 pth小load文件

4、完整的模型训练套路(以CIFAR10数据集)

模型:model.py【train中记得from model import *】

训练过程:train.py 首先train/test数据集 => dataloader加载数据 => 创建网络模型 => 损失函数、优化器 、设置网络中的参数(训练次数、测试次数、训练轮数) => main主函数中写训练过程

tudui.train()进入训练状态 => for从dataloader中不断取数据,并计算loss => 将loss送入优化器中进行优化 => 采用特定方式对结果进行输出设置(比如train-step%100输出loss和add_scalar绘图) 

tudui.eval()进入验证/测试状态 对网络进行验证/测试 => 建议设置with torch.no_grad(): 因为验证不需要梯度调整和优化  =>计算loss和误差等 => 展示

在此基础上对代码进行完善,比如训练100次输出loss,保存每个epoch的pth,tensorboard可视化中间loss,计算准确率,with torch.no_grad():测试的时候,就不要梯度变化和调优了

argmax(0-纵向 1-横向;对应大概率类别的下标位置)

 然后对于训练代码中的tudui.train()和tudui.eval()声明进入某种模式,对特定的比如Droupout、BatchNorm等特定层使用时要调用(使用这些层的时候声明一下)

使用GPU进行训练

方式1: 找到↓三个参数,然后.cuda()返回就可以了

import time计时小工具= time.time()

谷歌Colaboratory、Kaggle、

方式2:在一开始定义训练的设备torch.device("xxx")      说明:使用该方法不需要对网络和Loss进行另外赋值,直接.to(device)就行;但是对于数据需要进行赋值操作。

 

5、完整的模型验证(测试,demo)套路-利用已经训练好的模型,然后给它提供输入

1

而我们写的网络要求32x32,所以需要进行resize操作,需要注意的是Resize之后是32x32,这作为Resize的整体的第一个参数,所以要括号,就是.Resize((32,32)其他参数)

2

接下来就是加载网络模型

借助 .argmax(1)输出,预测不准确的原因是训练不足够(我自己这里是[5],换个飞机就错误了)

 同时up演示了一种,从gpu中训练得到的pth在cpu中加载的时候会报错,需要对应到cpu上

3代码几个注意点:①注意使用的函数的输入/输出的格式和维度/尺寸(tensor/PIL/) ,如果不一致就使用Resize( (H , W ))和reshape(batchsize, C, H, W);②图片格式通道RGB;③在训练好的模型后进行验证或测试时,使用model.eval()和with torch.no_grad:(网络中有Dropout和batchnorm);④最后就是得到的output是不同类别的概率,借助argmax(1)变成利于阅读的类别下标

import torch
import torchvision
from PIL import Image
from torch import nnimg_path = "./imgs/dog.png"
# img_path = "./imgs/airplane.png"
img = Image.open(img_path)img = img.convert('RGB') #png格式有4通道rgb+1透明度 ☆★transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32, 32)),torchvision.transforms.ToTensor()])
img = transform(img)
# print(img) #这个输出就是tensor类型的img
# print(img.shape)#加载网络模型
class SUNDAY(nn.Module):def __init__(self):super(SUNDAY, 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 xmodel = torch.load("tudui_0.pth")
# model = torch.load("tudui_29_gup.pth",map_location=torch.device("cpu"))
# print(model)
img = img.reshape(1, 3, 32, 32) # 注意尺寸和维度☆★model.eval() # 这两行是为了养成良好的代码习惯when网络中dropout/BatchNorm☆★
with torch.no_grad():output = model(img)output = output.argmax(1) # 转换成利于解读的方式☆★
print(output)

最后讲解了一下命令行run()注意一下路径和数据集是否正确

 谢谢小土堆!  

【唐宇迪】

学一个算法、读一篇论文、啃一个源码

积累二三十个,面向复制粘贴编程,创新点就来了;

CV: ctrl+C、ctr+V

在理解完源码和论文之后,从源码中去积累         

论文读再多不如debug一遍收获的多;

大同小异 看不懂论文、看不懂网络、看不懂代码 => 积累的不够呀

Day1: 深度学习CNN卷积神经网络算法精讲

1. 神经网络模型知识点分析

2. 神经网络模型架构解读

3. 卷积神经网络整体架构及参数设计

Day2:AI领域最火模块transformer实例解读

1. 深度学习CNN卷积神经网络算法精讲

2. 当下最火模块注意力机制解读

3. 视觉领域transformer应用实例

4. 视觉当下最新研究方向与进展 两天的内容一样重要

【预习视频Day1】

transform:数据增强

.ToTensor():无论图像是用啥工具读取进来的都要转换成tensor格式[张量-矩阵] [Numpy-array]

.Normalize()标准化

batch:一次做八题,一次送几张

Dataloader:

dataset.ImageFolder

resnet:至少不比原来差

VGG:大量3x3卷积堆叠(16/19层):随着网络结构加深,56layer比20效果变差

model_name=’resnet’ 迁移学习/预训练模型(都用现成的)

遍地都是预训练模型(做好搬运工 抄作业记得不要把名字也抄上了啊喂 | 自己的输出修改    )

迁移学习:

data少:   

冻住前几层-提取特征:用别人的预训练模型权重不做改动

越往右面越接近输出层,做自己的分类任务

data多:少冻几层

优化器设置:

学习率lr:权重参数更新幅度

变化幅度:一开始幅度大一点没事,后面接近答案不可以一步子跨过终点,所以后面lr要小一点

学习率衰减策略:lr经过多少step衰减成原来的几分之几

训练模块:

1000个样本,batch=100样本,1epoch表示把整个数据集都遍历一遍

∴1epoch=10batch,即1epoch迭代10次,每次迭代10batch

#训练(更新参数)和验证(期末考试)if train if val

前向传播要计算loss、_preds=torch.max(outpts,1)要得到当前预测各类别的最大概率

backwards反向传播(框架已实现)w更新

#计算损失与打印操作

指标:accuracy、val_loss

加载训练好的模型:

保存好训练好的模型、制定好路径

需要保证所有输入数据的大小规格保持一致,训练的时候多大 测试的时候也要多大

制作好数据源:input-transform=224x224

所以在测试时候,要先处理数据:

def process_image(image_path):# 读取测试数据img = Image.open(image_path)# Resize,thumbnail方法只能进行缩小,所以进行了判断if img.size[0] > img.size[1]:img.thumbnail((10000, 256))else:img.thumbnail((256, 10000))# Crop操作left_margin = (img.width-224)/2bottom_margin = (img.height-224)/2right_margin = left_margin + 224top_margin = bottom_margin + 224img = img.crop((left_margin, bottom_margin, right_margin,   top_margin))# 相同的预处理方法img = np.array(img)/255mean = np.array([0.485, 0.456, 0.406]) #provided meanstd = np.array([0.229, 0.224, 0.225]) #provided stdimg = (img - mean)/std# 注意颜色通道应该放在第一个位置img = img.transpose((2, 0, 1))return img

【transformer Day2】

文本的例子->图像的例子

之前的算法谁离我近我就考虑谁,比如这里x2考虑x1最多,但是并不一定是最接近的就是最重要的/关系紧密的,是要考虑上下文语境的。

同一个词语在不同的语境中表示的意思是有所区别的 => 关注一个词,同时考虑上下文信息

注意力机制做的事情:把平稳特征转换成层次分明

引入三个辅助向量:Q(由这个词出发去问别人)、K(被问到的时候要回答的)、V,那怎么用Query和Key衡量词与词之间的上下文的关系呢?

向量之间内积越小关系越差;向量之间内积越大关系越好。

由谁出发提供一个Query向量,谁被问到要提供一个key向量。所以x1访问x1就是q1`k1、x1访问x2就是q1`k2,所以这里要做的就是权重赋值,多少给x1多少给x2

原始输入只有x1,x2,怎么得到QKV?通过训练得到kqv:用三组权重参数矩阵,分别训练得到三组权重向量QKV

输入序列中的每一个token都有qkv

multi-headed多头注意力机制:

 

CNN vs Transformer

Transformer优点:三个臭皮匠顶上诸葛亮;

缺点:每个点与其他点都要计算很慢,且input大效果好但是特征多也复杂;同时一个点真的需要跟所有的点都要求他们之间的关系呢?=>不同的注意力机制(周围点、横向轴向点)=>现在transformer都在解决的一个问题是怎么简化计算。

transformer的应用:物体检测、轨迹估计、时间序列、 关键点匹配

自注意力机制:一张图片中点与这张图中其他点之间的位置关系;CrossAtention跨图片


http://chatgpt.dhexx.cn/article/k4qxhovq.shtml

相关文章

计算机网络笔记

目录 第一章 计算机网络和因特网 1.1 什么是因特网 1.1.1 组成描述 1.1.2 服务描述 、 1.1.3 协议 1.2 网络的边缘 1.2.1 接入网 1.2.2 物理媒体 1.3 网络核心 1.3.1 分组交换 1.3.2 电路交换 1.3.3 分组交换和电路交换的对比 1.3.4 网络的网络 1.4 分组交换…

PyTorch深度学习-跟着小土堆学习

目录 学习视频链接一些问题P4&#xff1a;Python/PyTorch学习中两大法宝函数-dir()、help()P5&#xff1a;PyCharm及Jupyter使用及对比P6&#xff1a;PyTorch加载数据初认识P7&#xff1a;Dataset类代码实战P8&#xff1a;TensorBoard的使用&#xff08;一&#xff09;P9&#…

[零基础][最简单的教程]图像多分类问题的解决——基于resnet50的pytorch的实现

文章目录 前言一、开始任务的前提条件二、深度学习通用框架三、修改代码前&#xff0c;使用者需要明确的问题1.图片分成三个集&#xff0c;并放在正确的位置2.明确你是几分类问题3.明确你是使用的模型网络 四、图像分类通用pytorch框架——具体代码实现一、输入处理模块0.引入库…

深入探索 Android 网络优化(一、网络筑基篇)上

前言 成为一名优秀的Android开发&#xff0c;需要一份完备的知识体系&#xff0c;在这里&#xff0c;让我们一起成长为自己所想的那样~。 网络优化一直被认为是移动优化水最深的领域之一&#xff0c;因此要想对网络进行深入优化&#xff0c;我们就必须先打下比较扎实的网络基础…

计算机网络(自顶向下方法)学习笔记

目录 第一章 计算机网络和因特网 1.1 什么是因特网 1.1.1 组成描述 1.1.2 服务描述 1.1.3 协议 1.2 网络的边缘 1.2.1 接入网 1.2.2 物理媒体 1.3 网络核心 1.3.1 分组交换 1.3.2 电路交换 1.3.3 分组交换和电路交换的对比 1.3.4 网络的网络 1.4 分组交换中的时延…

【我是土堆 - PyTorch教程】学习随手记(已更新 | 已完结 | 10w字超详细版)

目录 1. Pytorch环境的配置及安装 如何管理项目环境&#xff1f; 如何看自己电脑cuda版本&#xff1f; 安装Pytorch 2. Python编辑器的选择、安装及配置 PyCharm PyCharm神器 Jupyter&#xff08;可交互&#xff09; 3. Python学习中的两大法宝函数 说明 实战操…

SpringCloud(H版以及Alibaba版本)的学习笔记(三)

本笔记学习自B站尚硅谷Springcloud时所记录 学习视频链接源码地址【码云】 笔记内容包括了&#xff1a;Springcloud的H版以及Alibaba版本 H版具体内容包括&#xff1a;Eureka、Zookeeper、Consul、Ribbon、OpenFeign、Hystrix、Gateway、Config、Bus、Stream、Sleuth等技术的…

JavaScript——onblur事件失效问题解决方案

基本概念 问题分析 改了写法&#xff0c;把事件写在函数里&#xff0c;然后直接调用&#xff0c;发现一直提示函数未定义&#xff0c;这个和浏览器渲染页面过程有关&#xff0c;就是当浏览器渲染到该标签时&#xff0c;事件函数还没定义&#xff0c;就报错。 解决方案 添加…

html dom onblur,html的DOM中Event对象onblur事件用法实例

html的DOM中Event对象onblur事件用法实例 本文实例讲述了html的DOM中Event对象onblur事件用法。分享给大家供大家参考。具体分析如下&#xff1a; onblur 事件会在对象失去焦点时发生。 语法如下&#xff1a; 复制代码 代码如下: οnblur"SomeJavaScriptCode" SomeJa…

onBlur事件与onfocus事件 (js)

jQuery 参考手册 - 事件 一、jQuery的 onBlur方法 定义和用法 1、当元素失去焦点时发生 blur 事件。 2、blur() 函数触发 blur 事件&#xff0c;或者如果设置了 function 参数&#xff0c;该函数也可规定当发生 blur 事件时执行的代码。 提示&#xff1a;早前&#xff0c;…

利用onblur事件实现文本框中英文字母全部转换成大写

利用onblur事件实现文本框中英文字母全部转换成大写 <body>文本框中输入&#xff1a;<input type"text" id"inp" value"" onblur"aA()" /><br><br>失去焦点后&#xff1a;<input type"text" id…

onfocus 事件onblur 事件

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <head> <script> function myFunction(x){x.style.background"red"; } </script> <…

js中 onblur事件和onchange事件的区别

onchange事件&#xff1a;会判断输入框中的内容是否和原来的内容相同&#xff0c;和原来的内容相同则不会出现提示框&#xff0c;不相同才出现提示框 现在数量是 2 修改为 2 &#xff0c;没有出现提示框 修改为其他内容&#xff1a;出现提示框

onblur事件和onfocus事件失效

先看onblur事件和onfocus事件的定义&#xff1a; <element οnblur"SomeJavaScriptCode"> <element οnfοcus"SomeJavaScriptCode"> 双引号中的内容是一段js代码&#xff0c;也可以是一个事件函数 在看几个例子&#xff1a; <!DOCTYPE htm…

html onblur 函数执行了2次,JavaScript“onblur事件”调用函数失效 原因与解决方法

由于JavaScript事件有很多,例如: 鼠标事件:onclick 键盘事件:onkeydown、onkeypress 表单事件:onblur、onchange 窗口事件属性:onerror、onload 因此,如果你遇到其它的JavaScript事件调用函数失效,解决方法也同理。 以我这里为例子: 今天我在调试代码的时候,发现我的…

js onfocus事件、js onblur事件

onfocus事件&#xff1a; html元素获取到焦点所触发的事件&#xff0c;通常用于 <input>输入框标签&#xff0c;<select>下拉列表标签&#xff0c;以及<a>超链接标签&#xff0c;不是所有html元素都支持onfocus事件。 onblur事件: html元素失去焦点所触发的…

onblur事件

代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><input type"text"id"user"><script>document.g…

onblur和onchange

onblur onblur 事件会在对象失去焦点时发生。 onblur 经常用于Javascript验证代码&#xff0c;一般用于表单输入框。 提示&#xff1a;onblur 相反事件为 onfocus 事件 。 案例&#xff1a; <body>文本框输入:<input type"text" name"" id"w…

JavaScript常用事件之onchange()事件、onblur()事件

一、onchange()事件 1、功能&#xff1a;onchange 事件会在域的内容改变时发生,也可用于单选框与复选框改变后触发的事件。 2、语法&#xff1a;οnchange"SomeJavaScriptCode" 参数&#xff1a;SomeJavaScriptCode&#xff08;必需。规定该事件发生时执行的 JavaS…

SD卡和SDIO

SD卡和SDIO SDIO &#xff08;1&#xff09;简介 SDIO&#xff0c;全称&#xff1a; Secure Digital Input and Output &#xff0c;即安全数字输入输出接口。它是在SD卡接口的基础上发展而来&#xff0c;它可以兼容之前的SD卡&#xff0c;并可以连接SDIO接口设备&#xff0c;…