当前位置: 首页 > news >正文

微信公众好第三方网站怎么做重庆移动网站建设

微信公众好第三方网站怎么做,重庆移动网站建设,苏州调查公司有哪些,ip域名找网站目录 P4 PyCharm和Jupyter的对比 P5 PyTorch加载数据 P6 Dataset类代码实现 P7 Tensorboard 写日志 读取日志文件 Tensorboard 读图片 P10 Transforms使用 Transforms用途 常见的Transforms工具 P14 torchvision数据集使用 P15 Dataloader使用 P16 nn.Module模块使…目录 P4 PyCharm和Jupyter的对比 P5 PyTorch加载数据 P6 Dataset类代码实现 P7 Tensorboard 写日志 读取日志文件 Tensorboard 读图片 P10 Transforms使用 Transforms用途 常见的Transforms工具 P14 torchvision数据集使用 P15 Dataloader使用 P16   nn.Module模块使用 P17 卷积原理 步幅、填充原理 P18 神经网络——卷积层  搭建卷积层 ​编辑 卷积层处理图片 Tensorboard显示 P19最大池化层 池化层处理数据 池化层处理图片 P20 神经网络——非线性激活 P21 神经网络——线性层及其他层 Linear Layers线性层 线性拉平 P22 搭建小实战和顺序使用 ​编辑 搭建神经网络 Sequential神经网络 Tensorboard显示网络(强推) P23 损失函数与逆向传播 损失函数反向传播 P24 优化器 SGD随机梯度下降 神经网络优化一轮 神经网络优化多轮 神经网络学习率优化 P25 网络模型使用及修改 下载网络模型 ​编辑 查看函数用法 网络模型添加 网络模型修改 P26 网络模型保存与读取 网络模型保存(方式一) 网络模型导入(方式一) 网络模型保存(方式二) 网络模型导入(方式二) 网络陷阱 P27 完整模型训练套路 CIFAR 10 model 网络模型 DataLoader加载数据集 测试网络正确 网络训练数据 查看训练损失 保存每一轮后参数 argmax作用 打印正确率最终版代码 特殊层作用 P30 利用GPU训练 方式一 方式二 运行Terminal语句 P32 完整模型验证套路 验证狗是否识别 P33 查看开源项目 parser.add_argument 本文基于B站“我是土堆”的课程记录学习笔记原视频讲解P4. PyCharm及Jupyter使用及对比_哔哩哔哩_bilibili P4 PyCharm和Jupyter的对比 测试程序 #用来测试的错误代码,a是字符型b是整型所以加在一起会报错 print(Start) a hello word b 2019 c a b print(c)#正确的代码把b也写成字符型 print(Start) a hello word b 2019 c a b print(c) python控制台运行代码可读性比较差可以用来做调试Jupyter可用于小项目或调试。 P5 PyTorch加载数据 Dataset提供一种方式去获取数据及其lable。 要实现的功能 如何获取每一数据及其lable告诉我们总共有多少个数据知道训练的时候要迭代多少次 在Jupyter里查看Dataset的官方文档解释 from torch.utils.data import Dataset help(Dataset)#第二种查看方式 Dataset?? 函数def __init__(selfxxxx): 初始化类创建特例实例时要运行的函数为整个class提供共一个全局变量为后面的函数如getitem,length等方法提供它们需要的一些量。这个类中定义的一些self.xx...能够成为全局变量方便后续的使用。xx为所需的全局变量 函数def __getitem__(self,idx): idx一般作为数据的编号根据图片地址的列表获取每一条数据。 函数def __len__(self): 获取数据集的长度有多少条数据。 P6 Dataset类代码实现 数据集下载https://download.pytorch.org/tutorial/hymenoptera_data.zip from torch.utils.data import Dataset from PIL import Image import osclass MyData(Dataset): def __init__(self,root_dir,label_dir): # 该魔术方法当创建一个事例对象时会自动调用该函数self.root_dir root_dir # self.root_dir 相当于类中的全局变量self.label_dir label_dir self.path os.path.join(self.root_dir,self.label_dir) # 字符串拼接根据是Windows或Lixus系统情况进行拼接 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.label_dirreturn img, labeldef __len__(self):return len(self.img_path)root_dir Data/FirstTypeData/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) print(len(ants_dataset)) print(len(bees_dataset)) train_dataset ants_dataset bees_dataset # train_dataset 就是两个数据集的集合了 print(len(train_dataset))img,label train_dataset[200] print(label,label) img.show() Datalodader为后面的网络提供不同的数据形式。将数据打包 P7 Tensorboard 写日志 from torch.utils.tensorboard import SummaryWriter writer SummaryWriter(logs) # 创建一个logs文件夹writer写的文件都在该文件夹下 #writer.add_image() for i in range(100):writer.add_scalar(y2x,2*i,i) writer.close() 运行之后会产生一个log目录和一个日志文件 读取日志文件 在 Anaconda 终端里面激活py3.6.3环境再输入 tensorboard --logdirlogs #你自己的logs路径 命将网址赋值浏览器的网址栏回车即可查看tensorboard显示日志情况。 ② 为避免多人使用端口导致冲突也可以在后面加上后缀使得端口独立 tensorboard --logdirC:\Users\wangy\Desktop\03CV\logs --port6007 ③ 输入网址可得Tensorboard界面。 Tensorboard 读图片 from torch.utils.tensorboard import SummaryWriter from PIL import Image import numpy as npimg_path1 Data/FirstTypeData/train/ants/0013035.jpg img_PIL1 Image.open(img_path1) img_array1 np.array(img_PIL1)img_path2 Data/SecondTypeData/train/bees_image/17209602_fe5a5a746f.jpg img_PIL2 Image.open(img_path2) img_array2 np.array(img_PIL2)writer SummaryWriter(logs) writer.add_image(test,img_array1,1,dataformatsHWC) # 1 表示该图片在第1步 writer.add_image(test,img_array2,2,dataformatsHWC) # 2 表示该图片在第2步 writer.close() 通过这种方式可以很直观的观察训练过程中给model提供了哪些数据或者说想对model测试的时候可以看到它每阶段的输出结果或者可以看到每个阶段的一些不同的显示。 P10 Transforms使用 Transforms用途 ① Transforms当成工具箱的话里面的class就是不同的工具。例如像totensor、resize这些工具。 ② Transforms拿一些特定格式的图片经过Transforms里面的工具获得我们想要的结果。 transforms.Totensor使用 from torchvision import transforms from PIL import Imageimg_path Data/FirstTypeData/val/bees/10870992_eebeeb3a12.jpg img Image.open(img_path) tensor_trans transforms.ToTensor() # 创建 transforms.ToTensor类 的实例化对象 tensor_img tensor_trans(img) # 调用 transforms.ToTensor类 的__call__的魔术方法 print(tensor_img) 需要Tensor数据类型原因 Tensor有一些属性比如反向传播、梯度等属性它包装了神经网络需要的一些属性。 常见的Transforms工具 Transforms的工具主要关注他的输入、输出、作用。 Compose()用法 Compose()中的参数需要是一个列表Python中列表的表示形式为[数据1数据2….] 在Compose中数据需要是 transforms类型所以得到Compose([transforms参数1transforms参数2....] Compose类就是把不同的transform结合在一起。 transforms.Compose([transforms.Centercrop(10),transforms.ToTensor(), ]) P14 torchvision数据集使用 pytorch提供的数据集APItorchvision — Torchvision master documentation torchvision数据集介绍 ① torchvision中有很多数据集当我们写代码时指定相应的数据集指定一些参数它就可以自行下载。 ② CIFAR-10数据集包含60000张32×32的彩色图片一共10个类别其中50000张训练图片10000张测试图片。 运行代码下载数据集 import torchvision train_set torchvision.datasets.CIFAR10(root./dataset,trainTrue,downloadTrue) # root为存放数据集的相对路线 test_set torchvision.datasets.CIFAR10(root./dataset,trainFalse,downloadTrue) # trainTrue是训练集trainFalse是测试集 查看CIFAR10数据集内容 import torchvision train_set torchvision.datasets.CIFAR10(root./dataset,trainTrue,downloadTrue) # root为存放数据集的相对路线 test_set torchvision.datasets.CIFAR10(root./dataset,trainFalse,downloadTrue) # trainTrue是训练集trainFalse是测试集 print(test_set[0]) # 输出的3是target print(test_set.classes) # 测试数据集中有多少种img, target test_set[0] # 分别获得图片、target print(img) print(target)print(test_set.classes[target]) # 3号target对应的种类 img.show() 与Transform结合 定义Transform的图像变换下载数据时加入transform dataset_transform torchvision.transforms.Compose([torchvision.transforms.ToTensor()]) train_set torchvision.datasets.CIFAR10(root./dataset,trainTrue,transformdataset_transform,downloadTrue) # 将ToTensor应用到数据集中的每一张图片每一张图片转为Tensor数据类型 test_set torchvision.datasets.CIFAR10(root./dataset,trainFalse,transformdataset_transform,downloadTrue) P15 Dataloader使用 ① Dataset只是去告诉我们程序我们的数据集在什么位置数据集第一个数据给它一个索引0它对应的是哪一个数据。 ② Dataloader就是把数据加载到神经网络当中Dataloader所做的事就是每次从Dataset中取数据至于怎么取是由Dataloader中的参数决定的。 加载数据的参数中dataset数据位置batch_size每次加载的数据量shuffle是否要打乱数据num_works设置多进程默认0只设置主进程dorp_last选数据如果有不足batch_size个剩余数的话要不要丢弃True丢弃。 import torchvision from torch.utils.data import DataLoader# 准备的测试数据集 test_data torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor()) img, target test_data[0] print(img.shape) print(img)# batch_size4 使得 img0, target0 dataset[0]、img1, target1 dataset[1]、img2, target2 dataset[2]、img3, target3 dataset[3]然后这四个数据作为Dataloader的一个返回 test_loader DataLoader(datasettest_data,batch_size4,shuffleTrue,num_workers0,drop_lastFalse) # 用for循环取出DataLoader打包好的四个数据 for data in test_loader:imgs, targets data # 每个data都是由4张图片组成imgs.size 为 [4,3,32,32]四张32×32图片三通道targets由四个标签组成 print(imgs.shape)print(targets) dataloder返回的是图片和标签的打包形式比如batch_size4返回的是4个img叠起来的imgs和4个target叠起来的targets。下面可以看到 imgs的形状是4个33232形状的图片而targets包含了4个标签分别是2368对应四张图片。 Tensorboard展示Dataloader多轮次 shuffle如果设置为False则第一个epoch和第二个epoch的图片顺序都一样设置为True则每次取的图片顺序都不一样。 import torchvision from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter# 准备的测试数据集 test_data torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor()) # batch_size4 使得 img0, target0 dataset[0]、img1, target1 dataset[1]、img2, target2 dataset[2]、img3, target3 dataset[3]然后这四个数据作为Dataloader的一个返回 test_loader DataLoader(datasettest_data,batch_size64,shuffleTrue,num_workers0,drop_lastTrue) # 用for循环取出DataLoader打包好的四个数据 writer SummaryWriter(logs) for epoch in range(2):step 0for data in test_loader:imgs, targets data # 每个data都是由4张图片组成imgs.size 为 [4,3,32,32]四张32×32图片三通道targets由四个标签组成 writer.add_images(Epoch{}.format(epoch),imgs,step)step step 1writer.close() P16   nn.Module模块使用 torch.nn — PyTorch 2.4 documentation 关于神经网络的使用在torch.nn里边其中nn是Neural network的缩写 nn.Module模块使用 ① nn.Module是对所有神经网络提供一个基本的类。init初始化函数forward前向传播函数接受输入处理后输出。x指输入 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这个类即nn.Module为父类nn.Module为所有神经网络提供一个模板对其中一些我们不满意的部分进行修改。 import torch from torch import nnclass Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() # 继承父类的初始化def forward(self, input): # 将forward函数进行重写output input 1return outputtudui Tudui() x torch.tensor(1.0) # 创建一个值为 1.0 的tensor output tudui(x) print(output) super(Myclass, self).__init__() ① 简单理解就是子类把父类的__init__()放到自己的__init__()当中这样子类就有了父类的__init__()的那些东西。 ② Myclass类继承nn.Modulesuper(Myclass, self).__init__()就是对继承自父类nn.Module的属性进行初始化。而且是用nn.Module的初始化方法来初始化继承的属性。 ③ super().__init()__()来通过初始化父类属性以初始化自身继承了父类的那部分属性这样一来作为nn.Module的子类就无需再初始化那一部分属性了只需初始化新加的元素。 ③ 子类继承了父类的所有属性和方法父类属性自然会用父类方法来进行初始化。 forward函数 ① 使用pytorch的时候不需要手动调用forward函数只要在实例化一个对象中传入对应的参数就可以自动调用 forward 函数。 ② 因为 PyTorch 中的大部分方法都继承自 torch.nn.Module而 torch.nn.Module 的__call__(self)函数中会返回 forward()函数 的结果因此PyTroch中的 forward()函数等于是被嵌套在了__call__(self)函数中因此forward()函数可以直接通过类名被调用而不用实例化对象。 P17 卷积原理 torch.nn.functional.conv2d — PyTorch 2.4 documentation ① 卷积核不停的在原图上进行滑动对应元素相乘再相加。 ② 下图为每次滑动移动1格然后再利用原图与卷积核上的数值进行计算得到缩略图矩阵的数据如下图右所示。 stride1时默认横向、纵向的步幅都为1。stride2时表示横向和纵向步幅都为2即计算完第一个之后卷积核移两步。先横向走再纵向走 代码实现 import torch import torch.nn.functional as Finput 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]])print(input.shape) print(kernel.shape) input torch.reshape(input, (1,1,5,5)) kernel torch.reshape(kernel, (1,1,3,3)) print(input.shape) print(kernel.shape)output F.conv2d(input, kernel, stride1) print(output) 代码中原始input的形状为torch.Size([5, 5])但是从官方文档里可以看到还要有batch批次、channel通道的维度所以还要把input的形状改一下用到了reshape。F是卷积函数。 padding表示填充 默认为0即不填充padding1时表示在输入图像周围添加一圈默认值都为0再根据步幅去做计算。 代码实现 import torch import torch.nn.functional as Finput 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]])print(input.shape) print(kernel.shape) input torch.reshape(input, (1,1,5,5)) kernel torch.reshape(kernel, (1,1,3,3)) print(input.shape) print(kernel.shape)output3 F.conv2d(input, kernel, stride1, padding1) # 周围只填充一层 print(output3) 步幅、填充原理 ① 步幅卷积核经过输入特征图的采样间隔。设置步幅的目的希望减小输入参数的数目减少计算量。 ② 填充在输入特征图的每一边添加一定数目的行列。设置填充的目的希望每个输入方块都能作为卷积窗口的中心或使得输出的特征图的长、宽 输入的特征图的长、宽。 ③ 一个尺寸 a * a 的特征图经过 b * b 的卷积层步幅stride c填充padding d若d等于0也就是不填充输出的特征图的尺寸 a-b/ c1若d不等于0也就是填充输出的特征图的尺寸 a2d-b/ c1。 例子1一个特征图尺寸为4 * 4的输入使用3 * 3的卷积核步幅1填充0输出的尺寸(4 - 3)/1 1 2。 例子2 一个特征图尺寸为5 * 5的输入使用3 * 3的卷积核步幅1填充1输出的尺寸(5 2 * 1 - 3)/1 1 5。 例子3一个特征图尺寸为5 * 5的输入 使用3 * 3的卷积核步幅2填充0输出的尺寸(5-3)/2 1 2。 例子4一个特征图尺寸为6 * 6的输入 使用3 * 3的卷积核步幅2填充1输出的尺寸(6 2 * 1 - 3)/2 1 2.5 1 3.5 向下取整3降采样边长减少1/2。 P18 神经网络——卷积层  Conv2d — PyTorch 2.4 documentation Conv1d代表一维卷积Conv2d代表二维卷积Conv3d代表三维卷积。 torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1, biasTrue, padding_modezeros, deviceNone, dtypeNone) in_channels输入的通道数out_channels输出的通道数out_channels1时卷积层生成一个卷积核做计算out_channels2时卷积层生成一个卷积核做计算这两个卷积核不一定完全一样叠加起来的两个输出即为2个通道 kernel_size卷积核大小定义为3就是3*3大小也可以定义一个不规则的元组。卷积核的内部参数不用设置训练过程中会自动调整stride卷积过程中步幅大小padding卷积过程中填充的选项dilation卷积核当中的卷积核的对应位即距离。也叫空洞卷积没有空洞时默认为1 groups一般为1修改的话代表分组卷积bias一般为True是否对卷积后结果加上偏置padding_mode如果加上padding要按什么方式及填充dtype数据类型intfloat... 常用前五个参数需要设置之后可以根据实际计算出输出N是batch_size 搭建卷积层 import torch from torch import nn import torchvision from torch.nn import Conv2d from torch.utils.data import DataLoaderdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64) class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.conv1 Conv2d(in_channels3,out_channels6,kernel_size3,stride1,padding0) # 彩色图像输入为3层我们想让它的输出为6层选3 * 3 的卷积 def forward(self,x):x self.conv1(x)return xtudui Tudui() print(tudui) 卷积层处理图片 import torch import torchvision from torch import nn from torch.nn import Conv2d from torch.utils.data import DataLoaderdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64) class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.conv1 Conv2d(in_channels3,out_channels6,kernel_size3,stride1,padding0) # 彩色图像输入为3层我们想让它的输出为6层选3 * 3 的卷积 def forward(self,x):x self.conv1(x)return xtudui Tudui() for data in dataloader:imgs, targets dataoutput tudui(imgs)print(imgs.shape) # 输入为3通道32×32的64张图片print(output.shape) # 输出为6通道30×30的64张图片 Tensorboard显示 import torch import torchvision from torch import nn from torch.nn import Conv2d from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64) class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.conv1 Conv2d(in_channels3,out_channels6,kernel_size3,stride1,padding0) # 彩色图像输入为3层我们想让它的输出为6层选3 * 3 的卷积 def forward(self,x):x self.conv1(x)return xtudui Tudui() writer SummaryWriter(logs) step 0 for data in dataloader:imgs, targets dataoutput tudui(imgs)print(imgs.shape) print(output.shape) writer.add_images(input, imgs, step)output torch.reshape(output,(-1,3,30,30)) # 把原来6个通道拉为3个通道为了保证所有维度总数不变其余的分量分到第一个维度中writer.add_images(output, output, step)step step 1 这里有一个这样的变换output torch.reshape(output,(-1,3,30,30))因为6个通道不知道怎么显示只能显示3个通道所以在这里换成3通道输出显示的-1代表如果你不知道怎么写这个维度就设置成-1它自己会计算。如果这样设置的话原本我们应该看到一个批次的64张图片呈8*8的形式排列现在看到的是64*2张图片呈8*16的形式排列因为通道里的改变作用到了批次上。P19最大池化层 MaxPool2d — PyTorch 2.4 documentation torch.nn.MaxPool2d(kernel_size, strideNone, padding0, dilation1, return_indicesFalse, ceil_modeFalse) kernel_size池化核大小 stride步幅默认为跟池化核大小一样比如池化核3*3那么stride3 dilation空洞卷积 ceil_model当池化核对输入不能完全覆盖时3*3的核在移动过程中只覆盖了输入图像的6个数字是否还要保留当前步计算的结果。 另外提一下ceiling与floor的区别是遇到小数如2.31向上取整还是向下取整。 最大池化层的计算规则是每次计算时只留下最大的那个数。比如3*3的池化核依次跟输入图像的九个数字相乘最终只留下1个最大值这也对应了MaxPool2d。 池化层处理数据 import torch from torch import nn from torch.nn import MaxPool2dinput 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]], dtype torch.float32) input torch.reshape(input,(-1,1,5,5)) print(input.shape)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.maxpool MaxPool2d(kernel_size3, ceil_modeTrue)def forward(self, input):output self.maxpool(input)return outputtudui Tudui() output tudui(input) print(output)#结果#torch.Size([1, 1, 5, 5]) #tensor([[[[2., 3.], # [5., 1.]]]]) 池化层处理图片 import torch import torchvision from torch import nn from torch.nn import MaxPool2d from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.maxpool MaxPool2d(kernel_size3, ceil_modeTrue)def forward(self, input):output self.maxpool(input)return outputtudui Tudui() writer SummaryWriter(logs) step 0for data in dataloader:imgs, targets datawriter.add_images(input, imgs, step)output tudui(imgs)writer.add_images(output, output, step)step step 1 池化使得数据由5 * 5 变为3 * 3,甚至1 * 1的这样导致计算的参数会大大减小。例如1080P的电影经过池化的转为720P的电影、或360P的电影后同样的网速下视频更为不卡。 P20 神经网络——非线性激活 ReLU — PyTorch 2.4 documentation ReLU进行截断input大于0时还是取inputinput小于0时截断为0输入有batch_size维度。这里的input如果是图片的话就是针对每个像素值来计算的了。 inplace为原地替换若为True则变量的值被替换。若为False则会创建一个新变量将函数处理后的值赋值给新变量原始变量的值没有修改。  右边这个的input保留了原始值没被替换。 import torch from torch import nn from torch.nn import ReLUinput torch.tensor([[1,-0.5],[-1,3]]) input torch.reshape(input,(-1,1,2,2)) print(input.shape)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.relu1 ReLU()def forward(self, input):output self.relu1(input)return outputtudui Tudui() output tudui(input) print(output)#输出#torch.Size([1, 1, 2, 2]) #tensor([[[[1., 0.], # [0., 3.]]]]) Tensorboard显示图片 import torch import torchvision from torch import nn from torch.nn import ReLU from torch.nn import Sigmoid from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.relu1 ReLU()self.sigmoid1 Sigmoid()def forward(self, input):output self.sigmoid1(input)return outputtudui Tudui() writer SummaryWriter(logs) step 0for data in dataloader:imgs, targets datawriter.add_images(input, imgs, step)output tudui(imgs)writer.add_images(output, output, step)step step 1 非线性变换的主要目的是给网络中引入一些非线性特征非线性越多的话才能训练出符合各种曲线或特征的模型。 P21 神经网络——线性层及其他层 Normalization Layers正则化层对输入采用正则化可以加快神经网络的训练速度 Dropout Layers训练过程中随机把一些输入的tensor数据类型的元素变为0变为0的概率为p Linear Layers线性层 神经网络训练的就是函数系数Kk与d。对这两个系数不断调优k指weightd指bias。 torch.nn.Linear(in_features, out_features, biasTrue, deviceNone, dtypeNone)把特定的输入转成想要的输出比如4096个feature经过线性层变成1000个feature。 线性拉平 import torch import torchvision from torch import nn from torch.nn import ReLU from torch.nn import Sigmoid from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64)for data in dataloader:imgs, targets dataprint(imgs.shape)#图片尺寸变换torch.Size([64, 3, 32, 32])--》torch.Size([1, 1, 1, 196608])output torch.reshape(imgs,(1,1,1,-1))#图片尺寸变换torch.Size([64, 3, 32, 32])--》torch.Size([196608])#output torch.flatten(imgs) # 方法二拉平。展开为一维print(output.shape) P22 搭建小实战和顺序使用 ① 把网络结构放在Sequential里面好处就是代码写起来比较简介、易懂。 ② 可以根据神经网络每层的尺寸根据下图的公式计算出神经网络中的参数。 搭建神经网络 import torch import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linearclass Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.conv1 Conv2d(3,32,5,padding2)self.maxpool1 MaxPool2d(2)self.cov2 Conv2d(32,32,5,padding2)self.maxpool2 MaxPool2d(2)self.conv3 Conv2d(32,64,5,padding2)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 xtudui Tudui() print(tudui)#查看网络结构 Sequential神经网络 import torch import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequentialclass Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 Sequential(Conv2d(3,32,5,padding2),MaxPool2d(2),Conv2d(32,32,5,padding2),MaxPool2d(2),Conv2d(32,64,5,padding2),MaxPool2d(2),Flatten(),Linear(1024,64),Linear(64,10))def forward(self, x):x self.model1(x)return xtudui Tudui() input torch.ones((64,3,32,32)) output tudui(input) print(output.shape) 代码变得更加简洁了! Tensorboard显示网络(强推) 可以看到网络结构和每一步送到网络里的数据尺寸大小。 import torch import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64,drop_lastTrue)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 Sequential(Conv2d(3,32,5,padding2),MaxPool2d(2),Conv2d(32,32,5,padding2),MaxPool2d(2),Conv2d(32,64,5,padding2),MaxPool2d(2),Flatten(),Linear(1024,64),Linear(64,10))def forward(self, x):x self.model1(x)return xtudui Tudui() writer SummaryWriter(logs)tudui Tudui() input torch.ones((64,3,32,32)) output tudui(input) print(output.shape)writer.add_graph(tudui, input) writer.close() P23 损失函数与逆向传播 torch.nn — PyTorch 2.4 documentation ① Loss损失函数一方面计算实际输出和目标之间的差距。 ② Loss损失函数另一方面为我们更新输出提供一定的依据反向传播。每一个卷积核的参数设置了一个梯度grad采用反向传播的时候每一个要更新的参数都会求出来一个对应的梯度在优化过程中可以根据梯度对当中的参数进行优化最终达到loss降低的目的。 反向传播可以计算出每个节点的梯度可以选择合适的优化器对参数优化以降低loss。 nn.L1Loss        网络输出与目标依次做减法取绝对值相加最后取平均 nn.CrossEntropyLoss      交叉熵损失 以交叉熵损失函数为例 import torch import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size1,drop_lastTrue)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 Sequential(Conv2d(3,32,5,padding2),MaxPool2d(2),Conv2d(32,32,5,padding2),MaxPool2d(2),Conv2d(32,64,5,padding2),MaxPool2d(2),Flatten(),Linear(1024,64),Linear(64,10))def forward(self, x):x self.model1(x)return xtudui Tudui() for data in dataloader:imgs, targets dataoutputs tudui(imgs)print(outputs)print(targets) ​ 结果给出了每张图片属于各个类别的概率一般会取最大值作为模型的预测类别与实际标签对比。 损失函数反向传播 ① 反向传播通过梯度来更新参数使得loss损失最小如下图所示。 ​ import torch import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64,drop_lastTrue)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 Sequential(Conv2d(3,32,5,padding2),MaxPool2d(2),Conv2d(32,32,5,padding2),MaxPool2d(2),Conv2d(32,64,5,padding2),MaxPool2d(2),Flatten(),Linear(1024,64),Linear(64,10))def forward(self, x):x self.model1(x)return xloss nn.CrossEntropyLoss() # 交叉熵 tudui Tudui() for data in dataloader:imgs, targets dataoutputs tudui(imgs)result_loss loss(outputs, targets) # 计算实际输出与目标输出的差距result_loss.backward() # 计算出来的 loss 值有 backward 方法属性反向传播来计算每个节点的更新的参数。这里查看网络的属性 grad 梯度属性刚开始没有反向传播计算出来后才有后面优化器会利用梯度优化网络参数。 print(ok) P24 优化器 torch.optim — PyTorch 2.4 documentation ① 损失函数调用backward方法就可以调用损失函数的反向传播方法就可以求出我们需要调节的梯度我们就可以利用我们的优化器就可以根据梯度对参数进行调整达到整体误差降低的目的。 ② 梯度要清零如果梯度不清零会导致梯度累加。 for input, target in dataset:optimizer.zero_grad() #梯度清零避免上一步的梯度影响不可省output model(input) #获得输出loss loss_fn(output, target) #计算损失loss.backward() #反向传播得到参数梯度optimizer.step() #根据梯度更新参数 不同的优化器有不同的算法不过应用的时候主要修改params参数和lr学习率 SGD随机梯度下降 torch.optim.SGD(params, lr0.001, momentum0, dampening0, weight_decay0, nesterovFalse, *, maximizeFalse, foreachNone, differentiableFalse, fusedNone) 大致思路定义优化器梯度清零调用损失函数反向传播模型参数调优 神经网络优化一轮 import torch import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64,drop_lastTrue)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 Sequential(Conv2d(3,32,5,padding2),MaxPool2d(2),Conv2d(32,32,5,padding2),MaxPool2d(2),Conv2d(32,64,5,padding2),MaxPool2d(2),Flatten(),Linear(1024,64),Linear(64,10))def forward(self, x):x self.model1(x)return xloss nn.CrossEntropyLoss() # 交叉熵 tudui Tudui() optim torch.optim.SGD(tudui.parameters(),lr0.01) # 随机梯度下降优化器 for data in dataloader:imgs, targets dataoutputs tudui(imgs)result_loss loss(outputs, targets) # 计算实际输出与目标输出的差距optim.zero_grad() # 梯度清零result_loss.backward() # 反向传播计算损失函数的梯度optim.step() # 根据梯度对网络的参数进行调优print(result_loss) # 对数据只看了一遍只看了一轮所以loss下降不大 神经网络优化多轮 import torch import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64,drop_lastTrue)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 Sequential(Conv2d(3,32,5,padding2),MaxPool2d(2),Conv2d(32,32,5,padding2),MaxPool2d(2),Conv2d(32,64,5,padding2),MaxPool2d(2),Flatten(),Linear(1024,64),Linear(64,10))def forward(self, x):x self.model1(x)return xloss nn.CrossEntropyLoss() # 交叉熵 tudui Tudui() optim torch.optim.SGD(tudui.parameters(),lr0.01) # 随机梯度下降优化器 for epoch in range(20):running_loss 0.0for data in dataloader:imgs, targets dataoutputs tudui(imgs)result_loss loss(outputs, targets) # 计算实际输出与目标输出的差距optim.zero_grad() # 梯度清零result_loss.backward() # 反向传播计算损失函数的梯度optim.step() # 根据梯度对网络的参数进行调优running_loss running_loss result_lossprint(running_loss) # 对这一轮所有误差的总和 神经网络学习率优化 import torch import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) dataloader DataLoader(dataset, batch_size64,drop_lastTrue)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 Sequential(Conv2d(3,32,5,padding2),MaxPool2d(2),Conv2d(32,32,5,padding2),MaxPool2d(2),Conv2d(32,64,5,padding2),MaxPool2d(2),Flatten(),Linear(1024,64),Linear(64,10))def forward(self, x):x self.model1(x)return xloss nn.CrossEntropyLoss() # 交叉熵 tudui Tudui() optim torch.optim.SGD(tudui.parameters(),lr0.01) # 随机梯度下降优化器 scheduler torch.optim.lr_scheduler.StepLR(optim, step_size5, gamma0.1) # 每过 step_size 更新一次优化器更新是学习率为原来的学习率的的 0.1 倍 for epoch in range(20):running_loss 0.0for data in dataloader:imgs, targets dataoutputs tudui(imgs)result_loss loss(outputs, targets) # 计算实际输出与目标输出的差距optim.zero_grad() # 梯度清零result_loss.backward() # 反向传播计算损失函数的梯度optim.step() # 根据梯度对网络的参数进行调优scheduler.step() # 学习率太小了所以20个轮次后相当于没走多少running_loss running_loss result_lossprint(running_loss) # 对这一轮所有误差的总和 P25 网络模型使用及修改 Models and pre-trained weights — Torchvision 0.19 documentation VGG模型中常用的是VGG16和VGG19 pretrained如果为True相当于下载到的网络模型其中的一些参数已经在mox数据集中训练好了在数据集中能取得不错的效果。为False的话说明参数都是初始化的参数没有在任何数据集上训练。 下载网络模型 import torchvision#trauin_data torchvision.datasets.ImageNet(./dataset,splittrain,downloadTrue,transformtorchvision.transforms.ToTensor()) # 这个数据集没有办法再公开的访问了 vgg16_true torchvision.models.vgg16(pretrainedTrue) # 下载卷积层对应的参数是多少、池化层对应的参数时多少这些参数时ImageNet训练好了的 vgg16_false torchvision.models.vgg16(pretrainedFalse) # 没有预训练的参数 print(ok) print(vgg16_true) 查看函数用法 import torchvision help(torchvision.models.vgg16) 网络模型添加 import torchvision from torch import nndataset torchvision.datasets.CIFAR10(./dataset,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue) vgg16_true torchvision.models.vgg16(pretrainedTrue) # 下载卷积层对应的参数是多少、池化层对应的参数时多少这些参数时ImageNet训练好了的 vgg16_true.add_module(add_linear,nn.Linear(1000,10)) # 在VGG16后面添加一个线性层使得输出为适应CIFAR10的输出CIFAR10需要输出10个种类 #vgg16_true.classifier.add_module(add_linear,nn.Linear(1000,10))#如果想加在VGG里的特定部分如classifier中就多加一层 print(vgg16_true) 网络模型修改 import torchvision from torch import nnvgg16_false torchvision.models.vgg16(pretrainedFalse) # 没有预训练的参数 print(vgg16_false) vgg16_false.classifier[6] nn.Linear(4096,10) print(vgg16_false) P26 网络模型保存与读取 网络模型保存(方式一) 保存网络模型的结构和模型参数参数为模型和保存地址 import torchvision import torch vgg16 torchvision.models.vgg16(pretrainedFalse) torch.save(vgg16,./model/vgg16_method1.pth) # 保存方式一模型结构 模型参数 print(vgg16) 网络模型导入(方式一) 对应于模型保存方式一只要有模型的地址就可以 import torch model torch.load(./model/vgg16_method1.pth) # 保存方式一对应的加载模型 print(model) 网络模型保存(方式二) 把VGG16中的参数保存成python中的一个字典并指定路径。只保存了模型参数官方推荐因为保存下来的更小。 import torchvision import torch vgg16 torchvision.models.vgg16(pretrainedFalse) torch.save(vgg16.state_dict(),./model/vgg16_method2.pth) # 保存方式二模型参数官方推荐,不再保存网络模型结构 print(vgg16) 网络模型导入(方式二) 对应于模型保存方式二注意加载方式的变化如果还用上面的加载方式只会加载出保存的字典不会加载出网络模型。 import torch import torchvision vgg16 torchvision.models.vgg16(pretrainedFalse) print(vgg16) vgg16.load_state_dict(torch.load(./model/vgg16_method2.pth)) # 将模型参数导入到模型结构中 print(vgg16) 网络陷阱 创建一个自定义的网络结构实例化一个模型。 import torch from torch import nnclass Tudui(nn.Module):def __init__(self):super(Tudui,self).__init__()self.conv1 nn.Conv2d(3,64,kernel_size3)def forward(self,x):x self.conv1(x)return xtudui Tudui() torch.save(tudui, ./model/tudui_method1.pth) 用保存方式一保存下来模型并用对应的加载方式来导入模型发现报错说 用方式一的话要让加载程序能够访问到模型定义的方式 import torch from torch import nn# 确保网络模型是我们想要的网络模型,要在加载前还写明网络模型 class Tudui(nn.Module):def __init__(self):super(Tudui,self).__init__()self.conv1 nn.Conv2d(3,64,kernel_size3)def forward(self,x):x self.conv1(x)return x#tudui Tudui # 不需要写这一步不需要创建网络模型 model torch.load(./model/tudui_method1.pth) # 无法直接加载方式一保存的网络结构 print(model) 上面这个是把网络结构直接复制过来了但我们实际应用的时候会把网络结构单独放在一个文件里直接import就行 import torch import model_save import * # 它就相当于把 model_save.py 里的网络模型定义写到这里了#tudui Tudui # 不需要写这一步不需要创建网络模型 model torch.load(tudui_method1.pth) print(model) P27 完整模型训练套路 CIFAR 10 model 网络模型 ① 下面用 CIFAR 10 model网络来完成分类问题网络模型如下图所示。 DataLoader加载数据集 import torchvision from torch import nn from torch.utils.data import DataLoader# 准备数据集 train_data torchvision.datasets.CIFAR10(./dataset,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue) test_data torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) # length 长度 train_data_size len(train_data) test_data_size len(test_data) # 如果train_data_size10则打印训练数据集的长度为10 print(训练数据集的长度{}.format(train_data_size)) print(测试数据集的长度{}.format(test_data_size))# 利用 Dataloader 来加载数据集 train_dataloader DataLoader(train_data_size, batch_size64) test_dataloader DataLoader(test_data_size, batch_size64)#输出# 训练数据集的长度50000# 测试数据集的长度10000 测试网络正确 import torch from torch import nn# 搭建神经网络 class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 nn.Sequential(nn.Conv2d(3,32,5,1,2), # 输入通道3输出通道32卷积核尺寸5×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(), # 展平后变成 64*4*4 了nn.Linear(64*4*4,64),nn.Linear(64,10))def forward(self, x):x self.model1(x)return xif __name__ __main__:tudui Tudui()input torch.ones((64,3,32,32))output tudui(input)print(output.shape) # 测试输出的尺寸是不是我们想要的#输出 #torch.Size([64, 10]) train文件和moudle文件要在一个目录底下 网络训练数据 import torchvision from torch import nn from torch.utils.data import DataLoader# from model import * 相当于把 model中的所有内容写到这里这里直接把 model 写在这里 class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 nn.Sequential(nn.Conv2d(3,32,5,1,2), # 输入通道3输出通道32卷积核尺寸5×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(), # 展平后变成 64*4*4 了nn.Linear(64*4*4,64),nn.Linear(64,10))def forward(self, x):x self.model1(x)return x# 准备数据集 train_data torchvision.datasets.CIFAR10(./dataset,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue) test_data torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) # length 长度 train_data_size len(train_data) test_data_size len(test_data) # 如果train_data_size10则打印训练数据集的长度为10 print(训练数据集的长度{}.format(train_data_size)) print(测试数据集的长度{}.format(test_data_size))# 利用 Dataloader 来加载数据集 train_dataloader DataLoader(train_data, batch_size64) test_dataloader DataLoader(test_data, batch_size64)# 创建网络模型 tudui Tudui() # 损失函数 loss_fn nn.CrossEntropyLoss() # 交叉熵fn 是 fuction 的缩写# 优化器 learning 0.01 # 1e-2 就是 0.01 的意思 optimizer torch.optim.SGD(tudui.parameters(),learning) # 随机梯度下降优化器 # 设置网络的一些参数 # 记录训练的次数 total_train_step 0# 训练的轮次 epoch 10for i in range(epoch):print(-----第 {} 轮训练开始-----.format(i1))# 训练步骤开始for data in train_dataloader:imgs, targets dataoutputs tudui(imgs)loss loss_fn(outputs, targets) # 计算实际输出与目标输出的差距# 优化器对模型调优optimizer.zero_grad() # 梯度清零loss.backward() # 反向传播计算损失函数的梯度optimizer.step() # 根据梯度对网络的参数进行调优total_train_step total_train_step 1#print(训练次数{}Loss{}.format(total_train_step,loss)) # 方式一获得loss值print(训练次数{}Loss{}.format(total_train_step,loss.item())) # 方式二获得loss值 补充xx.item()将原本的tensor类型转换成一个数字。 查看训练损失 ① 在pytorch中tensor有一个requires_grad参数如果设置为True则反向传播时该tensor就会自动求导。 ② tensor的requires_grad的属性默认为False若一个节点叶子变量自己创建的tensorrequires_grad被设置为True那么所有依赖它的节点requires_grad都为True即使其他相依赖的tensor的requires_grad False ③ 当requires_grad设置为False时反向传播时就不会自动求导了因此大大节约了显存或者说内存。 ④ with torch.no_grad的作用在该模块下所有计算得出的tensor的requires_grad都自动设置为False。 ⑤ 即使一个tensor命名为x的requires_grad True在with torch.no_grad计算由x得到的新tensor命名为w-标量requires_grad也为False且grad_fn也为None,即不会对w求导。 ⑥ torch.no_grad()停止计算梯度不能进行反向传播。 # 添加 tensorboard writer SummaryWriter(logs)for i in range(epoch):print(-----第 {} 轮训练开始-----.format(i1))# 训练步骤开始for data in train_dataloader:imgs, targets dataoutputs tudui(imgs)loss loss_fn(outputs, targets) # 计算实际输出与目标输出的差距# 优化器对模型调优optimizer.zero_grad() # 梯度清零loss.backward() # 反向传播计算损失函数的梯度optimizer.step() # 根据梯度对网络的参数进行调优total_train_step total_train_step 1if total_train_step % 100 0:print(训练次数{}Loss{}.format(total_train_step,loss.item())) # 方式二获得loss值writer.add_scalar(train_loss,loss.item(),total_train_step)# 测试步骤开始每一轮训练后都查看在测试数据集上的loss情况total_test_loss 0with torch.no_grad(): # 没有梯度计算节约内存for data in test_dataloader: # 测试数据集提取数据imgs, targets dataoutputs tudui(imgs)loss loss_fn(outputs, targets) # 仅data数据在网络模型上的损失total_test_loss total_test_loss loss.item() # 所有lossprint(整体测试集上的Loss{}.format(total_test_loss))writer.add_scalar(test_loss,total_test_loss,total_test_step)total_test_step total_test_step 1writer.close() 输入 tensorboard --logdirlogs 命令将网址赋值浏览器的网址栏回车即可查看tensorboard显示日志情况。 保存每一轮后参数 for i in range(epoch):print(-----第 {} 轮训练开始-----.format(i1))# 训练步骤开始for data in train_dataloader:imgs, targets dataoutputs tudui(imgs)loss loss_fn(outputs, targets) # 计算实际输出与目标输出的差距# 优化器对模型调优optimizer.zero_grad() # 梯度清零loss.backward() # 反向传播计算损失函数的梯度optimizer.step() # 根据梯度对网络的参数进行调优total_train_step total_train_step 1if total_train_step % 100 0:print(训练次数{}Loss{}.format(total_train_step,loss.item())) # 方式二获得loss值writer.add_scalar(train_loss,loss.item(),total_train_step)# 测试步骤开始每一轮训练后都查看在测试数据集上的loss情况total_test_loss 0with torch.no_grad(): # 没有梯度了for data in test_dataloader: # 测试数据集提取数据imgs, targets dataoutputs tudui(imgs)loss loss_fn(outputs, targets) # 仅data数据在网络模型上的损失total_test_loss total_test_loss loss.item() # 所有lossprint(整体测试集上的Loss{}.format(total_test_loss))writer.add_scalar(test_loss,total_test_loss,total_test_step)total_test_step total_test_step 1torch.save(tudui, ./model/tudui_{}.pth.format(i)) # 保存每一轮训练后的结果print(模型已保存)writer.close() argmax作用 按照行或列取出概率值最大的索引作为预测标签 import torch outputs torch.tensor([[0.1,0.2],[0.05,0.4]]) print(outputs.argmax(0)) # 竖着看最大值的索引 print(outputs.argmax(1)) # 横着看最大值的索引 preds outputs.argmax(0) targets torch.tensor([0,1]) print((preds targets).sum()) # 对应位置相等的个数#输出#tensor([0, 1]) #tensor([1, 1]) #tensor(2) 打印正确率最终版代码 import torchvision import torch from torch import nn from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter# from model import * 相当于把 model中的所有内容写到这里这里直接把 model 写在这里 class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 nn.Sequential(nn.Conv2d(3,32,5,1,2), # 输入通道3输出通道32卷积核尺寸5×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(), # 展平后变成 64*4*4 了nn.Linear(64*4*4,64),nn.Linear(64,10))def forward(self, x):x self.model1(x)return x# 准备数据集 train_data torchvision.datasets.CIFAR10(./dataset,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue) test_data torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) # length 长度 train_data_size len(train_data) test_data_size len(test_data) # 如果train_data_size10则打印训练数据集的长度为10 print(训练数据集的长度{}.format(train_data_size)) print(测试数据集的长度{}.format(test_data_size))# 利用 Dataloader 来加载数据集 train_dataloader DataLoader(train_data, batch_size64) test_dataloader DataLoader(test_data, batch_size64)# 创建网络模型 tudui Tudui() # 损失函数 loss_fn nn.CrossEntropyLoss() # 交叉熵fn 是 fuction 的缩写# 优化器 learning 0.01 # 1e-2 就是 0.01 的意思 optimizer torch.optim.SGD(tudui.parameters(),learning) # 随机梯度下降优化器 # 设置网络的一些参数 # 记录训练的次数 total_train_step 0 # 记录测试的次数 total_test_step 0# 训练的轮次 epoch 10# 添加 tensorboard writer SummaryWriter(logs)for i in range(epoch):print(-----第 {} 轮训练开始-----.format(i1))# 训练步骤开始tudui.train() # 当网络中有dropout层、batchnorm层时这些层能起作用for data in train_dataloader:imgs, targets dataoutputs tudui(imgs)loss loss_fn(outputs, targets) # 计算实际输出与目标输出的差距# 优化器对模型调优optimizer.zero_grad() # 梯度清零loss.backward() # 反向传播计算损失函数的梯度optimizer.step() # 根据梯度对网络的参数进行调优total_train_step total_train_step 1if total_train_step % 100 0:print(训练次数{}Loss{}.format(total_train_step,loss.item())) # 方式二获得loss值writer.add_scalar(train_loss,loss.item(),total_train_step)# 测试步骤开始每一轮训练后都查看在测试数据集上的loss情况tudui.eval() # 当网络中有dropout层、batchnorm层时这些层不能起作用total_test_loss 0total_accuracy 0with torch.no_grad(): # 没有梯度了for data in test_dataloader: # 测试数据集提取数据imgs, targets dataoutputs tudui(imgs)loss loss_fn(outputs, targets) # 仅data数据在网络模型上的损失total_test_loss total_test_loss loss.item() # 所有lossaccuracy (outputs.argmax(1) targets).sum()total_accuracy total_accuracy accuracyprint(整体测试集上的Loss{}.format(total_test_loss))print(整体测试集上的正确率{}.format(total_accuracy/test_data_size))writer.add_scalar(test_loss,total_test_loss,total_test_step)writer.add_scalar(test_accuracy,total_accuracy/test_data_size,total_test_step) total_test_step total_test_step 1torch.save(tudui, ./model/tudui_{}.pth.format(i)) # 保存每一轮训练后的结果#torch.save(tudui.state_dict(),tudui_{}.path.format(i)) # 保存方式二 print(模型已保存)writer.close() 特殊层作用 ① model.train()和model.eval()的区别主要在于Batch Normalization和Dropout两层。 ② 如果模型中有BN层(Batch Normalization和 Dropout需要在训练时添加model.train()。model.train()是保证BN层能够用到每一批数据的均值和方差。对于Dropoutmodel.train()是随机取一部分网络连接来训练更新参数。 ③ 不启用 Batch Normalization 和 Dropout。 如果模型中有BN层(Batch Normalization和Dropout在测试时添加model.eval()。model.eval()是保证BN层能够用全部训练数据的均值和方差即测试过程中要保证BN层的均值和方差不变。对于Dropoutmodel.eval()是利用到了所有网络连接即不进行随机舍弃神经元。 ④ 训练完train样本后生成的模型model要用来测试样本。在model(test)之前需要加上model.eval()否则的话有输入数据即使不训练它也会改变权值。这是model中含有BN层和Dropout所带来的的性质。 ⑤ 在做one classification的时候训练集和测试集的样本分布是不一样的尤其需要注意这一点。 P30 利用GPU训练 方式一 GPU训练主要有三部分网络模型、数据(输入、标注)、损失函数这三部分放到GPU上。xx.cuda()数据在训练和测试时每批次放入gpu上。 import torchvision import torch from torch import nn from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter# from model import * 相当于把 model中的所有内容写到这里这里直接把 model 写在这里 class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 nn.Sequential(nn.Conv2d(3,32,5,1,2), # 输入通道3输出通道32卷积核尺寸5×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(), # 展平后变成 64*4*4 了nn.Linear(64*4*4,64),nn.Linear(64,10))def forward(self, x):x self.model1(x)return x# 准备数据集 train_data torchvision.datasets.CIFAR10(./dataset,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue) test_data torchvision.datasets.CIFAR10(./dataset,trainFalse,transformtorchvision.transforms.ToTensor(),downloadTrue) # length 长度 train_data_size len(train_data) test_data_size len(test_data) # 如果train_data_size10则打印训练数据集的长度为10 print(训练数据集的长度{}.format(train_data_size)) print(测试数据集的长度{}.format(test_data_size))# 利用 Dataloader 来加载数据集 train_dataloader DataLoader(train_data, batch_size64) test_dataloader DataLoader(test_data, batch_size64)# 创建网络模型 tudui Tudui() if torch.cuda.is_available():tudui tudui.cuda() # 网络模型转移到cuda上# 损失函数 loss_fn nn.CrossEntropyLoss() # 交叉熵fn 是 fuction 的缩写 if torch.cuda.is_available():loss_fn loss_fn.cuda() # 损失函数转移到cuda上# 优化器 learning 0.01 # 1e-2 就是 0.01 的意思 optimizer torch.optim.SGD(tudui.parameters(),learning) # 随机梯度下降优化器 # 设置网络的一些参数 # 记录训练的次数 total_train_step 0 # 记录测试的次数 total_test_step 0# 训练的轮次 epoch 10# 添加 tensorboard writer SummaryWriter(logs)for i in range(epoch):print(-----第 {} 轮训练开始-----.format(i1))# 训练步骤开始tudui.train() # 当网络中有dropout层、batchnorm层时这些层能起作用for data in train_dataloader:imgs, targets dataif torch.cuda.is_available():imgs imgs.cuda() # 数据放到cuda上targets targets.cuda() # 数据放到cuda上outputs tudui(imgs)loss loss_fn(outputs, targets) # 计算实际输出与目标输出的差距# 优化器对模型调优optimizer.zero_grad() # 梯度清零loss.backward() # 反向传播计算损失函数的梯度optimizer.step() # 根据梯度对网络的参数进行调优total_train_step total_train_step 1if total_train_step % 100 0:print(训练次数{}Loss{}.format(total_train_step,loss.item())) # 方式二获得loss值writer.add_scalar(train_loss,loss.item(),total_train_step)# 测试步骤开始每一轮训练后都查看在测试数据集上的loss情况tudui.eval() # 当网络中有dropout层、batchnorm层时这些层不能起作用total_test_loss 0total_accuracy 0with torch.no_grad(): # 没有梯度了for data in test_dataloader: # 测试数据集提取数据imgs, targets data # 数据放到cuda上if torch.cuda.is_available():imgs imgs.cuda() # 数据放到cuda上targets targets.cuda()outputs tudui(imgs)loss loss_fn(outputs, targets) # 仅data数据在网络模型上的损失total_test_loss total_test_loss loss.item() # 所有lossaccuracy (outputs.argmax(1) targets).sum()total_accuracy total_accuracy accuracyprint(整体测试集上的Loss{}.format(total_test_loss))print(整体测试集上的正确率{}.format(total_accuracy/test_data_size))writer.add_scalar(test_loss,total_test_loss,total_test_step)writer.add_scalar(test_accuracy,total_accuracy/test_data_size,total_test_step) total_test_step total_test_step 1torch.save(tudui, ./model/tudui_{}.pth.format(i)) # 保存每一轮训练后的结果#torch.save(tudui.state_dict(),tudui_{}.path.format(i)) # 保存方式二 print(模型已保存)writer.close() 有谷歌账号的话谷歌的colab可以免费使用GPU具体使用方法自寻。 方式二 电脑上有两个显卡时可以用指定cuda:0、cuda:1。把原来的.cuda()换成.to(device) import torchvision import torch from torch import nn from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter import time# 定义训练的设备 #device torch.device(cpu) #device torch.device(cuda) # 使用 GPU 方式一 #device torch.device(cuda:0) # 使用 GPU 方式二 device torch.device(cuda if torch.cuda.is_available() else cpu)....# 创建网络模型 tudui Tudui() tudui tudui.to(device) # 也可以不赋值直接 tudui.to(device) # 损失函数 loss_fn nn.CrossEntropyLoss() # 交叉熵fn 是 fuction 的缩写 loss_fn loss_fn.to(device) # 也可以不赋值直接loss_fn.to(device)# 优化器 learning 0.01 # 1e-2 就是 0.01 的意思 optimizer torch.optim.SGD(tudui.parameters(),learning) # 随机梯度下降优化器 # 设置网络的一些参数 # 记录训练的次数 total_train_step 0 # 记录测试的次数 total_test_step 0# 训练的轮次 epoch 10# 添加 tensorboard writer SummaryWriter(logs) start_time time.time()for i in range(epoch):print(-----第 {} 轮训练开始-----.format(i1))# 训练步骤开始tudui.train() # 当网络中有dropout层、batchnorm层时这些层能起作用for data in train_dataloader:imgs, targets data imgs imgs.to(device) # 也可以不赋值直接 imgs.to(device)targets targets.to(device) # 也可以不赋值直接 targets.to(device)outputs tudui(imgs)......# 测试步骤开始每一轮训练后都查看在测试数据集上的loss情况tudui.eval() # 当网络中有dropout层、batchnorm层时这些层不能起作用total_test_loss 0total_accuracy 0with torch.no_grad(): # 没有梯度了for data in test_dataloader: # 测试数据集提取数据imgs, targets data # 数据放到cuda上imgs imgs.to(device) # 也可以不赋值直接 imgs.to(device)targets targets.to(device) # 也可以不赋值直接 targets.to(device)outputs tudui(imgs)...........writer.close() 运行Terminal语句 ① 运行terminal上运行的命令可以在代码块中输入语句在语句前加一个感叹号。 ② 输入 !nvidia-smi可以查看显卡配置。 P32 完整模型验证套路 获取图片的的相对路径返回到上一层级再写实际路径 image_path ../imgs/dog.png 验证狗是否识别 ① 完整的模型验证(测试demo)套路利用已经训练好的模型然后给它提供输入。 import torchvision from PIL import Image from torch import nn import torchimage_path imgs/dog.png image Image.open(image_path) # PIL类型的Image image image.convert(RGB) # 4通道的RGBA转为3通道的RGB图片 print(image)transform torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)), torchvision.transforms.ToTensor()])image transform(image) print(image.shape)class Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__() self.model1 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.model1(x)return xmodel torch.load(model/tudui_29.pth,map_locationtorch.device(cpu)) # GPU上训练的东西映射到CPU上 print(model) image torch.reshape(image,(1,3,32,32)) # 转为四维符合网络输入需求 model.eval() with torch.no_grad(): # 不进行梯度计算减少内存计算output model(image) output model(image) print(output) print(output.argmax(1)) # 概率最大类别的输出 P33 查看开源项目 parser.add_argument ① 像运行Tensorboar一样在Terminal终端可以命令运行.py文件。 ② 如下图所示Terminal终端运行.py文件时--变量 后面的值是给变量进行赋值赋值后再在.py文件中运行。例如 ./datasets/maps 是给前面的dataroot赋值maps_cyclegan是给前面的name赋值cycle_gan是给前面的model赋值。 ③ required表示必须需要指定参数default表示有默认的参数了。Terminal终端命令语句如果不对该默认变量新写入直接调用默认的参数如果对该默认变量新写入则默认的参数被新写入的参数覆盖。 课代表https://github.com/AccumulateMore/CV100-122
http://www.hkea.cn/news/14305351/

相关文章:

  • 做个小程序电子商务seo是什么意思
  • 东营网站建设服务电话安阳网络教研平台官网
  • 做网站一定要买服务器么华为手机价格大全
  • 做外贸怎样打开国外网站中美今天最新消息
  • 网站建设邮如何做网站推广 求指点
  • 在哪找人做网站万网
  • 做钻石的网站做网站需要的公司
  • 获取网站访客qq号码邯郸网站改版找谁做
  • 网站文本编辑器北京死亡病例最新消息
  • 济南商城网站建设多少钱织梦网站入侵
  • 高端网站建设与制作推广运营怎么做
  • wordpress指定目录文章一键优化大师
  • 高校门户网站建设问题音乐网站需求分析
  • 资讯网站的优势济南建站都选企汇优先做后付
  • 罗定城乡建设规划局网站php图片怎么导入wordpress
  • 广州市建设注册中心网站十堰网站seo方法
  • 没有域名 怎么做网站链接wordpress图片墙插件
  • 合肥建设企业网站wordpress加模板
  • 百度推广 网站要备案吗外贸流程询盘
  • 做毕业网站的流程校园活动策划案的范文
  • 保定网站建设哪家好无人区在线影院免费高清
  • 好的用户体验网站 学校广州市财经商贸职业学校
  • 专门教做甜品的网站js特效网站展示
  • 电子商务成功网站的案例软件定制与开发
  • seo 网站结构影视文化网站建设
  • 哪个网站可以做翻译兼职重庆网络公司价格
  • 做网站开发哪种语言更稳定高效自己主机做网站服务器吗
  • ppt做的好的网站有哪些内容网站专题设计稿
  • 顺德网站建设公司价格网站怎么能被百度收录
  • 免费发做网站themegallery模板网