土堆教程笔记【PyTorch】

立山  论坛元老 | 2025-4-12 09:25:28 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1857|帖子 1857|积分 5571

官网:torch — PyTorch 2.6 documentation
Pycharm

解释器

一般搞深度学习都用虚拟情况的解释器,为了满足不同的项目所必要的不同的包的版本。
1. system interpreter表示当地的解释器

也就是你电脑系统里安装的解释器
2. Virtual Environment—Python的虚拟情况

anaconda可以帮我们创建虚拟情况
a. 创建虚拟情况

  1. conda create -n name python = 3.8
复制代码
b. 检察系统中已经存在的情况, * 在哪就是当前在哪个情况。

  1. conda info --envs
复制代码
c. 激活情况

  1. conda activate xxx
复制代码
d. 退出情况

  1. conda deactivate
复制代码
3. conda Enviroment

Anaconda内里附带安装的Python解释器

PyTorch下载命令


  • 输入 ↓ ,检察cuda版本
  1. nvcc -V
复制代码

  • 建议挑选conda的而不是wheel的命令,conda支持虚拟情况而且能自动办理依靠标题。
常见标题


  • 高版本的解释器在anaconda3虚拟路径文件夹envs下边。
  • 不表现In[2],打开终端,↓
  1. pip install ipython
复制代码

  • jupyter默认只安装在base情况当中,如果base情况没有安装pytorch,那么jupyter是没有办法使用pytorch的。
方案1:在base情况里安装pytorch
方案2:在pytorch情况里安装jupyter

  • 装库时报错Caused by SSLError(SSLZeroReturnError(6, 'TLS/SSL connection has been closed (EOF)
把代理关了。

  • 导入PIL时报错找不到模块
  1. module = self._system_import(name, *args, **kwargs)
  2. ImportError: DLL load failed while importing _imaging: 找不到指定的模块。
复制代码
办理方法:卸载了pywin32包

  • 报错
  1. LooseVersion = distutils.version.LooseVersion AttributeError: module 'distutils' has no attribute 'version'
复制代码
办理方法:注释掉控制台init方法的4-7和第10行。

  • 页面太小标题
修改固态盘的页面巨细,最小值是内存的1.5倍,最大值是内存的3倍。

  • 调用tensorboard不表现图像
低沉tensorboard版本
  1. pip install tensorboard==2.12.0
复制代码

  • 在调用pillow的add_image方法时报错
  1. image = image.resize((scaled_width, scaled_height), Image.ANTIALIAS)
  2. AttributeError: module 'PIL.Image' has no attribute 'ANTIALIAS'
复制代码
新版本pillow(10.0.0之后)Image.ANTIALIAS 被移除了,取而代之的是Image.LANCZOS or Image.Resampling.LANCZOS,干系描述可以可以在pillow的releasenotes中查到。点进去报错的文件,ANTIALIAS改成LANCZOS就可以了。
在 Jupyter Notebook 中切换/使用 conda 虚拟情况



服务器上配置有多个 conda 虚拟情况,在使用jupyter notebook时必要使用其中的一个情况,但是其默认还是使用 base 情况。Jupyter 在一个名为 kernel 的单独进程中运行用户的代码。kernel 可以是不同的 Python 安装在不同的 conda 情况或虚拟情况。
方法1:使用 nb_conda_kernels 添加所有情况(推荐)

  1. conda activate my-conda-env    # this is the environment for your project and code
  2. conda install ipykernel
  3. conda deactivate
  4. conda activate base      # could be also some other environment
  5. conda install nb_conda_kernels
  6. jupyter notebook
复制代码
注意:这里的 conda install nb_conda_kernels 是在 base 情况下操作的。
安装好后,打开 jupyter notebook 就会表现所有的 conda 情况啦,点击随意切换。
方法2:为 conda 情况创建特别内核

  1. conda create -n my-conda-env    # creates new virtual env
  2. conda activate my-conda-env     # activate environment in terminal
  3. conda install ipykernel      # install Python kernel in new conda env
  4. ipython kernel install --user --name=my-conda-env-kernel  # configure Jupyter to use Python kernel
  5. jupyter notebook      # run jupyter from system
复制代码
只有 Python 内核会在 conda 情况中运行,系统中的 Jupyter 或不同的 conda 情况将被使用——它没有安装在 conda 情况中。通过调用ipython kernel install将 jupyter 配置为使用 conda 情况作为内核.
windows/mac/linux jupyter notebook 切换默认情况
方法3:在 conda 情况中运行 Jupyter 服务器和内核

  1. conda create -n my-conda-env   # creates new virtual env
  2. conda activate my-conda-env    # activate environment in terminal
  3. conda install jupyter     # install jupyter + notebook
  4. jupyter notebook       # start server + kernel
复制代码
这种方法就是为每一个 conda 情况 都安装 jupyter。
Jupyter 将完全安装在 conda 情况中。不同版本的 Jupyter 可用于不同的 conda 情况,但此选项可能有点矫枉过正。
在情况中包含内核就充足了,内核是运行代码的封装 Python 的组件。Jupyter notebook 的别的部门可以被视为编辑器或检察器,并且没有须要为每个情况单独安装它并将其包含在每个 env.yml 文件中。
常用函数


  • 检察当前路径的包
  1. dir(torch)
复制代码

  • 检察方法的资助文档
  1. help(torch.cuda.is_available())  / 还有一种方式获取官方文档信息:xxxx ??
复制代码
跳到句首
  1. shift+enter
复制代码
数据加载

DataSet抽象类

提供一种方式去获取数据及其label。
DataLoader类

torch.utils.data.DataLoader是一个迭代器,方便我们去多线程地读取数据,并且可以实现batchsize以及
shuffle 的读取等。为后边的网络提供不同的数据情势。


  • 如何获取每一个数据及其label
  • 告诉我们统共有多少数据
神经网络经常必要对一个数据迭代多次,只有知道当前有多少个数据,进行练习时才知道要练习多少次,才气把整个数据集迭代完。
  1. from torch.utils.data import  Dataset
  2. import os
  3. #读取图片
  4. from PIL import Image
  5. class MyDataset(Dataset):
  6. #加载磁盘图片到内存
  7. #路径分成两部分是因为后续还要用蜜蜂的,拼接方便
  8.     def __init__(self,root_dir,label_dir):
  9.         self.root_dir = root_dir
  10.         self.label_dir = label_dir
  11.         self.path = os.path.join(self.root_dir,self.label_dir)
  12.         #而得到每一张图片的地址
  13.         self.img_path = os.listdir(self.path)
  14.     def __getitem__(self, idx):
  15.         img_name = self.img_path[idx]
  16.         img_item_path = os.path.join(self.root_dir,self.label_dir,img_name)
  17.         #读取图片
  18.         img = Image.open(img_item_path)
  19.         label = self.label_dir
  20.         return img,label
  21.     def __len__(self):
  22.         return len(self.img_path)
  23. root_dir = "dataset/train"
  24. label_dir = "ants"
  25. ants_dataset = MyDataset(root_dir,label_dir)
  26. bees_dataset = MyDataset(root_dir,label_dir)
  27. ants_dataset[0]
复制代码
TensorBoard(PyTorch1.1之后)

demo

  1. from torch.utils.tensorboard import SummaryWriter
  2. #日志的所在地址
  3. writer = SummaryWriter("D:\PythonProject\Introduction\logs")
  4. #第一个参数相当于表头,绘图
  5. for i in range(100):
  6.     writer.add_scalar('y=x',3 * i, i)
  7. writer.close()
复制代码
检察logs

在控制台输入
  1. tensorboard --logdir=logs
复制代码
指定端口,防止当别人也在访问时跟别人冲突
  1. tensorboard --logdir=logs --port=6007
复制代码
注意:如果出现拟合,那么可以删掉logs下边的文件,重新运行。
添加图像

通过打印发现,此范例不得当当作tensorboard的添加图片的输入范例。
  1. PyDev console: using IPython 8.12.2
  2. Python 3.8.20 (default, Oct  3 2024, 15:19:54) [MSC v.1929 64 bit (AMD64)] on win32
  3. img_path = "dataset/train/ants/0013035.jpg"
  4. from PIL import Image
  5. img = Image.open(img_path)
  6. print(type(img))
  7. <class 'PIL.JpegImagePlugin.JpegImageFile'>
复制代码
so,使用Opencv读取图片,得到numpy范例图片数据
使用numpy.array(),对PIL图片进行转换。
Transforms单张图片

输入图像到transforms.py,它像一个工具箱,把一些数据范例转化为tensor(神经网络 的专用数据范例,包装了很多神经网络必要的参数),或者resize.
  1. from torch.utils.tensorboard import SummaryWriter
  2. from torchvision import transforms
  3. from PIL import Image
  4. #通过transform.Totensor解决俩问题
  5. #1. transform应该如何使用
  6. #2. 为什么需要一个Tensor的数据类型
  7. img_path = "dataset/train/ants/0013035.jpg"
  8. img = Image.open(img_path)
  9. writer = SummaryWriter('logs')
  10. tensor_trans = transforms.ToTensor()
  11. tensor_img = tensor_trans(img)
  12. # print(tensor_img)
  13. # print(img)
  14. writer.add_image("Tensor_img", tensor_img, 3)
  15. writer.close()
复制代码
图片不表现的把logs下其他的文件删掉,关掉终端打开再重新运行。
归一化----加速收敛

正则化是防止过拟合
让不同的特征在数值上保持一致,制止某些特征对模型的影响过大,从而更好地学习到数据当中的模式和关系。归一化之后,均值为0,标准差为1.


__call__介绍,把对象当函数用。

  1. class Person:
  2.     def __call__(self, name):
  3.         print("__call__"+"Hello"+name)
  4.     def hello(self,name):
  5.         print("hello"+name)
  6. #__xxx__这种都是内置函数,可以对其进行重写
  7. person = Person()
  8. #__call__可以直接使用对象里加参数,而不用.的方式。
  9. person("zhangsan")
  10. person.hello("lisi")
复制代码
忽略巨细写匹配:

settings ----> 搜索case------>Generral下的Code Completion------->取勾Match case
Compose()的用法

Compose()中的参数必要是一个列表,Python中,列表的情势为[xx,xx,xx,xx,...]
在Compose()中,数据必要是transforms范例,以是,Compose(transsforms参数1,transsforms参数2,...)
用于将多个数据预处置惩罚操作组合成一个整体的变换,具体而言,按列表次序进行转换。巨细,裁剪,翻转,归一化等。
  1. from torch.utils.tensorboard import SummaryWriter
  2. from torchvision import transforms
  3. from PIL import Image
  4. #通过transform.Totensor解决俩问题
  5. #1. transform应该如何使用
  6. #2. 为什么需要一个Tensor的数据类型
  7. img_path = "dataset/train/ants/0013035.jpg"
  8. img = Image.open(img_path)
  9. writer = SummaryWriter('logs')
  10. tensor_trans = transforms.ToTensor()
  11. tensor_img = tensor_trans(img)
  12. # print(tensor_img)
  13. # print(img)
  14. #writer.add_image("Tensor_img", tensor_img, 3)
  15. print(tensor_img[0][0][0])
  16. #Normalize,归一化,提供三个均值,三个标准差
  17. tensor_norm = transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])
  18. #把图片归一化
  19. img_norm = tensor_norm(tensor_img)
  20. print(img_norm[0][0][0])
  21. writer.add_image("Normalize", img_norm,2)
  22. #Resize
  23. print(img.size)
  24. tran_resize = transforms.Resize((512,512))
  25. #img PIL -> resize -> img_resize PIL
  26. #这个方法需要传入PIL类型的img
  27. img_resize = tran_resize(img)
  28. # img_resize PIL -> toTensor ->img_resize tensor
  29. img_resize = tensor_trans(img_resize)
  30. writer.add_image("Resize", img_resize,0)
  31. print(img_resize)
  32. #Compose
  33. trans_resize_2 = transforms.Resize(512)
  34. trans_compose = transforms.Compose([trans_resize_2 , tensor_trans])
  35. trans_resize_2 = trans_compose(img)
  36. writer.add_image("Resize2", trans_resize_2,1)
  37. #RandomCrop,随机裁剪
  38. trans_random = transforms.RandomCrop((512,512))
  39. trans_compose_2 = transforms.Compose([trans_random , tensor_trans])
  40. #循环的目的是为了展示随机效果
  41. for i in range(10):
  42.     img_crop = trans_compose_2(img)
  43.     writer.add_image("RandomCrop", img_crop,i)
  44. writer.close()
复制代码
torchvision中的数据集的使用

单纯加载数据集CIFAR10 torchvision.datasets — Torchvision master documentation
  1. import torchvision
  2. train_set = torchvision.datasets.CIFAR10(root='./data', train=True, download=True)
  3. test_set = torchvision.datasets.CIFAR10(root='./data', train=False, download=True)
  4. #打印的是target,就是标签
  5. print(test_set[0])
  6. print(test_set.classes)
  7. img , target = test_set[0]
  8. print(img)
  9. print(target)
  10. print(test_set.classes[target])
  11. #对于PIL数据集直接调用这个方法就可以展示图片了
  12. img.show()
复制代码
对数据集变换
  1. import torchvision
  2. from torch.utils.tensorboard import SummaryWriter
  3. dataset_transform = torchvision.transforms.Compose([
  4.     torchvision.transforms.ToTensor(),
  5.     #因为图片太小了就只进行这一个变换
  6. ])
  7. train_set = torchvision.datasets.CIFAR10(root='./data', train=True,transform=dataset_transform, download=True)
  8. test_set = torchvision.datasets.CIFAR10(root='./data', train=False,transform=dataset_transform, download=True)
  9. print(test_set[0])
  10. #输出的是tensor数据类型,那么就可以用tensorboard进行一个显示
  11. writer = SummaryWriter(log_dir='p10')
  12. for i in range(10):
  13.     img, target = test_set[i]
  14.     #ctrl+p
  15.     #此时img是tensor类型的
  16.     writer.add_image("test_set", img, i)
  17. writer.close()
复制代码
在终端输入命令
  1. tensorboard --logdir="p10"
复制代码
如果下载太慢的话,可以打开数据集函数进去复制连接本身下载,然后放在对应的文件夹下。
DataLoader的使用

加载器,可以批量加载
参数:
num_workers : 使用多少进程去加载,但是可能只能linux用,win可能报错BrokenPipeErrror,默认值为0,代表使用主进程进行加载。
drop_last : 末了的余数图片要不要加载,false就是不舍弃的意思
shuffle : 遍历完一遍以后才会打乱,而且是在每轮练习当中打乱,一个epoch打乱一次
target不是标签,是标签存放的位置,标签列表是classes,真正的标签是classes[target]
batchsize打印:
  1. import torch
  2. import torchvision
  3. from torch.utils.data import DataLoader
  4. #准备的测试数据集
  5. test_data = torchvision.datasets.CIFAR10(root='./data', train=False, download=False,transform=torchvision.transforms.ToTensor())
  6. test_loader = DataLoader(test_data, batch_size=4, shuffle=True,num_workers=0,drop_last=False)
  7. #测试数据集中第一张图片
  8. img ,target = test_data[0]
  9. print(img.shape)
  10. print(target)
  11. #data是test_loader里的每一个对象,test_loader是可迭代对象
  12. for data in test_loader:
  13.     imgs , targets = data
  14.     print(imgs.shape)
  15.     print(targets)
  16. #输出的tensor是把每个图片的target融合在一起了。
复制代码


验证shuffle
  1. #验证shuffle
  2. for epoch in range(2):
  3.     step = 0
  4.     for data in test_loader:
  5.         imgs, targets = data
  6.         writer.add_images("Epoch:{}".format(epoch), imgs, step)
  7.         step += 1
复制代码
总代码:
  1. import torchimport torchvisionfrom torch.utils.data import DataLoaderfrom torch.utils.tensorboard import SummaryWriter#预备的测试数据集test_data = torchvision.datasets.CIFAR10(root='./data', train=False, download=False,transform=torchvision.transforms.ToTensor())test_loader = DataLoader(test_data, batch_size=4, shuffle=True,num_workers=0,drop_last=False)#测试数据集中第一张图片img ,target = test_data[0]print(img.shape)print(target)#data是test_loader里的每一个对象,test_loader是可迭代对象    # print(imgs.shape)    # print(targets)#输出的tensor是把每个图片的target融合在一起了。writer = SummaryWriter(log_dir='./dataloader')step = 0for data in test_loader:    imgs , targets = data    writer.add_images("test_data", imgs, step)    step += 1#验证shuffle
  2. for epoch in range(2):
  3.     step = 0
  4.     for data in test_loader:
  5.         imgs, targets = data
  6.         writer.add_images("Epoch:{}".format(epoch), imgs, step)
  7.         step += 1writer.close()
复制代码
mini-batch

随机梯度降落

nn.Module

关于神经网络的工具,一般在torch.nn里边。神经网络的根本骨架,一般是被继承的父类
conv2常用参数

padding ----- 添补,更好的使用边缘信息,如许可以均匀使用数据,默认是不进行添补的。
bias ------ 偏置参数
padding_mode ------- 添补模式,一般默认是0
dilation -------- 空洞卷积
卷积demo,因为nn.Module函数当中内置了call函数,以是把参数放进对象里,会自动调用forward函数。是在call函数里调用的。
  1. import torch
  2. from torch import nn
  3. class MyNet(nn.Module):
  4.     def __init__(self):
  5.         super().__init__()
  6.     def forward(self, input):
  7.         output = input + 1
  8.         return output
  9. my_net = MyNet()
  10. x =torch.tensor(1.0)
  11. y = my_net(x)
  12. print(y)
复制代码
为什么要调解形状,因为我们一开始打印出来发现只有高和宽,不满足conv2d的api要求输入的形状。
  1. import torch
  2. input = torch.tensor([[1,2,0,3,1],
  3.                       [0,1,2,3,1],
  4.                       [1,2,1,0,0],
  5.                       [5,2,3,1,1],
  6.                       [2,1,0,1,1]])
  7. kernel = torch.tensor([[1,2,1],
  8.                        [0,1,0],
  9.                        [2,1,0]])
  10. #这个尺寸只有高和宽
  11. print(input.shape)
  12. #torch.Size([5, 5])
  13. print(kernel.shape)
  14. #torch.Size([3, 3])
复制代码


pytorch给我们提供了尺寸变换
  1. input = torch.reshape(input,(1,1,5,5))
  2. kernel = torch.reshape(kernel,(1,1,3,3))
复制代码
变换以后就可以使用卷积进行输入
  1. output = F.conv2d(input,kernel,stride=1)
  2. output2 = F.conv2d(input,kernel,stride=2)
  3. print(output)
  4. print(output2)
复制代码
  1. import torch
  2. import torchvision
  3. from torch import nn
  4. from torch.utils.data import DataLoader
  5. from torch.utils.tensorboard import SummaryWriter
  6. dataset = torchvision.datasets.CIFAR10(root='./data', train=False,
  7.                                        transform=torchvision.transforms.ToTensor(),
  8.                                        download=False)
  9. dataloader = DataLoader(dataset, batch_size=64)
  10. class MyNet(nn.Module):
  11.     def __init__(self):
  12.         super(MyNet, self).__init__()
  13.         self.conv1 = nn.Conv2d(3, 6, 3)
  14.     def forward(self, x):
  15.         x = self.conv1(x)
  16.         return x
  17. my_net = MyNet()
  18. writer = SummaryWriter("./logs")
  19. #可以打印网络结构
  20. #print(my_net)
  21. step = 0
  22. for data in dataloader:
  23.     imgs, targets = data
  24.     output = my_net(imgs)
  25.     print(output.shape)
  26.     print(imgs.shape)
  27.     #torch.Size([64, 3, 32, 32])
  28.     writer.add_images("input", imgs, step)
  29.     #torch.Size([64, 6, 30, 30])
  30.     #-1是占位符,会被自动计算那个地方的值是多少
  31.     output = torch.reshape(output, (-1,3,30,30))
  32.     writer.add_images("output", output, step)
  33.     step += 1
复制代码
参数:dilation:空洞卷积,卷积核是隔一个的。
  1. import torchimport 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)#ctrl+p,提示参数#(卷积核数量,通道数,,)#一个卷积核天生一个通道input = torch.reshape(input,(1,1,5,5))
  2. kernel = torch.reshape(kernel,(1,1,3,3))print(input.shape)print(kernel.shape)output = F.conv2d(input,kernel,stride=1)output2 = F.conv2d(input,kernel,stride=2)output3 = F.conv2d(input,kernel,stride=1,padding=1)print(output)print(output2)print(output3)
复制代码
池化层

https://github.com/vdumoulin/conv_arithmetic
空洞卷积表示图↑
ceil_mode ------- 当卷积核卷出去以后,true,保存,false,不保存
卷积:提取特征
池化:降维
demo
  1. import torch
  2. import torchvision
  3. from torch import nn
  4. from torch.utils.data import DataLoader
  5. from torch.utils.tensorboard import SummaryWriter
  6. dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False,
  7.                                        transform=torchvision.transforms.ToTensor())
  8. dataloader = DataLoader(dataset, batch_size=4)
  9. input = torch.tensor([
  10.     [1,2,0,3,1],
  11.     [0,1,2,3,1],
  12.     [1,2,1,0,0],
  13.     [5,2,3,1,1],
  14.     [2,1,0,1,1]
  15. ], dtype=torch.float32)
  16. input = torch.reshape(input,(-1,1,5,5))
  17. print(input.shape)
  18. class MyNet(nn.Module):
  19.     def __init__(self):
  20.         super(MyNet, self).__init__()
  21.         self.maxpool1 = nn.MaxPool2d(kernel_size=3, ceil_mode=True)
  22.     def forward(self, x):
  23.         output = self.maxpool1(x)
  24.         return output
  25. mynet = MyNet()
  26. #print(mynet(input))
  27. writer = SummaryWriter('./logs_maxpool')
  28. steps = 0
  29. for data in dataloader:
  30.     imgs,targets = data
  31.     writer.add_images("input", imgs, steps)
  32.     output = mynet(imgs)
  33.     writer.add_images("output", output, steps)
  34.     steps += 1
  35. writer.close()
复制代码
非线性激活

  1. import torch
  2. import torchvision
  3. from torch.utils.data import DataLoader
  4. from torch.utils.tensorboard import SummaryWriter
  5. input = torch.tensor([[1,-0.5],
  6.                       [-1,3]])
  7. output = torch.reshape(input,(-1,1,2,2))
  8. print(output)
  9. dataset = (torchvision.datasets.CIFAR10(root='./data', train=False, download=False,
  10.                                         transform=torchvision.transforms.ToTensor()))
  11. dataloader = DataLoader(dataset, batch_size=64)
  12. class MyNet(torch.nn.Module):
  13.     def __init__(self):
  14.         super(MyNet, self).__init__()
  15.         self.relu1 = torch.nn.ReLU()
  16.         self.sigmoid = torch.nn.Sigmoid()
  17.     def forward(self, x):
  18.         output = self.sigmoid(x)
  19.         return output
  20. mynet = MyNet()
  21. writer = SummaryWriter('./logs_relu')
  22. step = 0
  23. for data in dataloader:
  24.     imgs,targets = data
  25.     writer.add_images("input",imgs,step)
  26.     output = mynet(imgs)
  27.     writer.add_images("output",imgs,step)
  28.     step += 1
  29. writer.close()
  30. output = mynet(input)
  31. print(output)
复制代码


Sequential

让代码看起来更简洁。
demo:对cifar10进行简单分类的神经网络,好像是颠末一次最大池化,尺寸就减半。


已知输入尺寸和输出尺寸,联立两个公式,可以反解出padding。dilation接纳默认的1,就是不进行膨胀。


倒数第二个和倒数第三个,倒数第一个和倒数第二个之间还分别各自有一个线性层。
  1. import torch
  2. from torch import nn
  3. from torch.nn import MaxPool2d, Flatten, Conv2d, Linear
  4. from torch.utils.tensorboard import SummaryWriter
  5. class MyNet(nn.Module):
  6.     def __init__(self):
  7.         super(MyNet, self).__init__()
  8.         # self.conv1 = nn.Conv2d(3, 32, kernel_size=5,
  9.         #                        padding=2)
  10.         # self.maxpool1 = nn.MaxPool2d(2)
  11.         # self.conv2 = nn.Conv2d(32, 32,5, padding=2)
  12.         # self.maxpool2 = nn.MaxPool2d(2)
  13.         # self.conv3 = nn.Conv2d(32, 64,5, padding=2)
  14.         # self.maxpool3 = MaxPool2d(2)
  15.         # self.flatten = Flatten()
  16.         # #从图片里看出来的,64*4*4
  17.         # self.linear1 = nn.Linear(1024,64)
  18.         # self.linear2 = nn.Linear(64,10)
  19.         self.model1 = nn.Sequential(
  20.             Conv2d(3, 32, kernel_size=5, padding=2),
  21.             MaxPool2d(2),
  22.             Conv2d(32, 32, kernel_size=5, padding=2),
  23.             MaxPool2d(2),
  24.             Conv2d(32, 64, kernel_size=5, padding=2),
  25.             MaxPool2d(2),
  26.             Flatten(),
  27.             Linear(1024, 64),
  28.             Linear(64,10)
  29.         )
  30.     def forward(self, x):
  31.         x = self.model1(x)
  32.         # x = self.conv1(x)
  33.         # x = self.maxpool1(x)
  34.         # x = self.conv2(x)
  35.         # x = self.maxpool2(x)
  36.         # x = self.conv3(x)
  37.         # x = self.maxpool3(x)
  38.         # x = self.flatten(x)
  39.         # x = self.linear1(x)
  40.         # x = self.linear2(x)
  41.         return x
  42. my_net = MyNet()
  43. print(my_net)
  44. input = torch.ones((64, 3, 32, 32))
  45. output = my_net(input)
  46. print(output.shape)
  47. writer = SummaryWriter("./logs_seq")
  48. writer.add_graph(my_net, input)
  49. writer.close()
复制代码
损失函数

L1Loss

  1. import torch
  2. from torch.nn import L1Loss
  3. inputs = torch.tensor([1,2,3],dtype=torch.float32)
  4. targets = torch.tensor([1,2,5],dtype=torch.float32)
  5. inputs = torch.reshape(inputs,(1,1,1,3))
  6. targets = torch.reshape(targets,(1,1,1,3))
  7. loss = L1Loss(reduction='sum')
  8. result = loss(inputs,targets)
  9. print(result)
  10. #2.
复制代码
MSELoss

  1. loss_mse = nn.MSELoss()
  2. result_mse = loss_mse(result,targets)
  3. print(result_mse)
  4. #1.3333
复制代码
交织熵

  1. x = torch.tensor([0.1,0.2,0.3])
  2. y = torch.tensor([1])
  3. x = torch.reshape(x,(1,3))
  4. loss_cross = nn.CrossEntropyLoss()
  5. result_cross = loss_cross(x,y)
  6. print(result_cross)
  7. #tensor(1.1019)
复制代码
用之前的网络来对数据集进行分类,不外此时的分类是没有意义的,因为还没有颠末练习。
  1. import torch
  2. import torchvision
  3. from torch import nn
  4. from torch.nn import MaxPool2d, Flatten, Conv2d, Linear
  5. from torch.utils.data import DataLoader
  6. from torch.utils.tensorboard import SummaryWriter
  7. dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False,
  8.                                        transform=torchvision.transforms.ToTensor())
  9. dataloader = DataLoader(dataset,batch_size=1)
  10. class MyNet(nn.Module):
  11.     def __init__(self):
  12.         super(MyNet, self).__init__()
  13.         self.model1 = nn.Sequential(
  14.             Conv2d(3, 32, kernel_size=5, padding=2),
  15.             MaxPool2d(2),
  16.             Conv2d(32, 32, kernel_size=5, padding=2),
  17.             MaxPool2d(2),
  18.             Conv2d(32, 64, kernel_size=5, padding=2),
  19.             MaxPool2d(2),
  20.             Flatten(),
  21.             Linear(1024, 64),
  22.             Linear(64,10)
  23.         )
  24.     def forward(self, x):
  25.         x = self.model1(x)
  26.         return x
  27. my_net = MyNet()
  28. loss = nn.CrossEntropyLoss()
  29. for data in dataloader:
  30.     imgs,targets = data
  31.     outputs = my_net(imgs)
  32.     result_loss = loss(outputs, targets)
  33.     print(result_loss)
  34.     #tensor(2.2306, grad_fn=<NllLossBackward>)
  35. #tensor(2.2557, grad_fn=<NllLossBackward>)
  36. #tensor(2.3920, grad_fn=<NllLossBackward>)
  37. #......
  38.     # print(outputs)
  39.     # print(targets)
复制代码
反向传播


  • 计算现实输出和目标之间的差距
  • 为我们更新输出提供肯定的依据,方向传播,grad。
一开始是没有梯度的,后来运行完37行,


就出现梯度了,有利于反向传播。


优化器

eg:lr是学习速率

  1. optimizer = optim.SGD(model.named_parameters(), lr=0.01, momentum=0.9)
  2. optimizer = optim.Adam([('layer0', var1), ('layer1', var2)], lr=0.0001)
复制代码
demo

  1. import torch
  2. import torchvision
  3. from torch import nn
  4. from torch.nn import MaxPool2d, Flatten, Conv2d, Linear
  5. from torch.utils.data import DataLoader
  6. from torch.utils.tensorboard import SummaryWriter
  7. dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False,
  8.                                        transform=torchvision.transforms.ToTensor())
  9. dataloader = DataLoader(dataset,batch_size=1)
  10. class MyNet(nn.Module):
  11.     def __init__(self):
  12.         super(MyNet, self).__init__()
  13.         self.model1 = nn.Sequential(
  14.             Conv2d(3, 32, kernel_size=5, padding=2),
  15.             MaxPool2d(2),
  16.             Conv2d(32, 32, kernel_size=5, padding=2),
  17.             MaxPool2d(2),
  18.             Conv2d(32, 64, kernel_size=5, padding=2),
  19.             MaxPool2d(2),
  20.             Flatten(),
  21.             Linear(1024, 64),
  22.             Linear(64,10)
  23.         )
  24.     def forward(self, x):
  25.         x = self.model1(x)
  26.         return x
  27. my_net = MyNet()
  28. optim = torch.optim.SGD(my_net.parameters(), lr=0.01)
  29. loss = nn.CrossEntropyLoss()
  30. for epoch in range(20):
  31.     running_loss = 0.0
  32.     for data in dataloader:
  33.         imgs,targets = data
  34.         outputs = my_net(imgs)
  35.         result_loss = loss(outputs, targets)
  36.         #梯度清零
  37.         optim.zero_grad()
  38.         #优化器需要每个参数的梯度
  39.         result_loss.backward()
  40.         #给每个参数进行调优
  41.         optim.step()
  42.         running_loss += result_loss
  43.     print(running_loss)
  44. #print(result_loss)
复制代码
现有网络模型的使用以及修改

  1. import torchvision.datasets
  2. from torch import nn
  3. from torchvision import transforms
  4. #train_data = torchvision.datasets.ImageNet("./data_image_net",split='train',
  5.      #                                      download=True,transform=transforms.ToTensor())
  6. vgg16_false = torchvision.models.vgg16(pretrained=False)
  7. #打印的是已经预训练好的网络架构,参数都是在训练之后的
  8. vgg16_true = torchvision.models.vgg16(pretrained=True)
  9. print(vgg16_true)
  10. train_data = torchvision.datasets.CIFAR10(root='./data', train=True, download=False
  11.                                           ,transform=torchvision.transforms.ToTensor())
  12. #把vgg16当一个前置的网络结构
  13. vgg16_true.classifier.add_module('add_linear',nn.Linear(1000, 10))
  14. print(vgg16_true)
  15. vgg16_false.classifier[6]=nn.Linear(4096, 10)
复制代码
网络模型保存

方式1

模型结构+模型参数
  1. import torch
  2. import torchvision
  3. vgg16 = torchvision.models.vgg16(pretrained=False)
  4. #保存方式1
  5. torch.save(vgg16,"vgg16_method1.pth")
复制代码
加载模型
  1. #保存方式1,加载模型
  2. model = torch.load("vgg16_method1.pth")
  3. print(model)
复制代码
如果是用方式1并且是自定义模型的话,肯定要让访问的代码能够访问到模型定义的地方。
方式2---字范例例

模型参数(官方推荐,好像是如许比较小)
  1. #保存方式2
  2. torch.save(vgg16.state_dict(),"vgg16_state_dict.pth")
复制代码
加载模型,字典情势打印出来就看不见网络结构了,也可以再恢复成网络结构的。
  1. #方式2加载方式
  2. #如果你想恢复成网络模型结构
  3. vgg16 = torchvision.models.vgg16(pretrained=False)
  4. model = torch.load("vgg16_state_dict.pth")
  5. print(model)
  6. print(vgg16)
复制代码
模型练习

item和本身的区别:



train.py

  1. import torch
  2. import torchvision
  3. from model import *
  4. train_data = torchvision.datasets.CIFAR10(root='./data', train=True, download=True,transform=torchvision.transforms.ToTensor())
  5. test_data = torchvision.datasets.CIFAR10(root='./data', train=False, download=True,transform=torchvision.transforms.ToTensor())
  6. train_data_size = len(train_data)
  7. test_data_size = len(test_data)
  8. print("训练数据集的长度是:{}".format(train_data_size))
  9. print("测试数据集的长度为:{}".format(test_data_size))
  10. #加载数据集
  11. train_dataloader = torch.utils.data.DataLoader(train_data,
  12.                                                batch_size=64,
  13.                                                )
  14. #ctrl+d复制本行到下一行
  15. test_dataloader = torch.utils.data.DataLoader(test_data, batch_size=64,)
  16. #创建网络模型
  17. mynet = MyNet()
  18. #损失函数,交叉熵
  19. loss_function = torch.nn.CrossEntropyLoss()
  20. #优化器
  21. optimizer = torch.optim.SGD(mynet.parameters(), lr=0.001, momentum=0.9)
  22. #设置训练网络的一些参数
  23. #记录训练的次数
  24. total_train_step = 0
  25. total_test_step = 0
  26. epoch = 10
  27. for i in range(epoch):
  28.     print("第{}轮训练开始".format(i+1))
  29.     for data in train_dataloader:
  30.         imgs,targets = data
  31.         outputs = mynet(imgs)
  32.         loss = loss_function(outputs, targets)
  33.         optimizer.zero_grad()
  34.         loss.backward()
  35.         optimizer.step()
  36.         total_train_step += 1
  37.         print("训练次数:{},Loss{}".format(total_train_step,loss.item()))
复制代码
model.py

  1. import torch
  2. from torch import nn
  3. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
  4. #搭建神经网络
  5. class MyNet(nn.Module):
  6.     def __init__(self):
  7.         super(MyNet, self).__init__()
  8.         self.model1 = nn.Sequential(
  9.             Conv2d(3, 32, kernel_size=5, padding=2),
  10.             MaxPool2d(2),
  11.             Conv2d(32, 32, kernel_size=5, padding=2),
  12.             MaxPool2d(2),
  13.             Conv2d(32, 64, kernel_size=5, padding=2),
  14.             MaxPool2d(2),
  15.             Flatten(),
  16.             Linear(1024, 64),
  17.             Linear(64,10)
  18.         )
  19.     def forward(self, x):
  20.         x = self.model1(x)
  21.         return x
  22. if __name__ == '__main__':
  23.     mynet = MyNet()
  24.     #64张图片
  25.     input = torch.ones((64,3,32,32))
  26.     output = mynet(input)
  27.     print(output.shape)
复制代码
test

  1. import torch
  2. import torchvision
  3. from torch.utils.tensorboard import SummaryWriter
  4. from model import *
  5. train_data = torchvision.datasets.CIFAR10(root='./data', train=True, download=True,transform=torchvision.transforms.ToTensor())
  6. test_data = torchvision.datasets.CIFAR10(root='./data', train=False, download=True,transform=torchvision.transforms.ToTensor())
  7. train_data_size = len(train_data)
  8. test_data_size = len(test_data)
  9. print("训练数据集的长度是:{}".format(train_data_size))
  10. print("测试数据集的长度为:{}".format(test_data_size))
  11. #加载数据集
  12. train_dataloader = torch.utils.data.DataLoader(train_data,
  13.                                                batch_size=64,
  14.                                                )
  15. #ctrl+d复制本行到下一行
  16. test_dataloader = torch.utils.data.DataLoader(test_data, batch_size=64,)
  17. #创建网络模型
  18. mynet = MyNet()
  19. #损失函数,交叉熵
  20. loss_function = torch.nn.CrossEntropyLoss()
  21. #优化器
  22. optimizer = torch.optim.SGD(mynet.parameters(), lr=0.001, momentum=0.9)
  23. #设置训练网络的一些参数
  24. #记录训练的次数
  25. total_train_step = 0
  26. total_test_step = 0
  27. epoch = 10
  28. writer = SummaryWriter('./logs_train')
  29. for i in range(epoch):
  30.     print("第{}轮训练开始".format(i+1))
  31.     for data in train_dataloader:
  32.         imgs,targets = data
  33.         outputs = mynet(imgs)
  34.         loss = loss_function(outputs, targets)
  35.         optimizer.zero_grad()
  36.         loss.backward()
  37.         optimizer.step()
  38.         total_train_step += 1
  39.         if total_train_step % 100 == 0:
  40.             print("训练次数:{},Loss{}".format(total_train_step,loss.item()))
  41.             writer.add_scalar('train_loss', loss.item(), total_train_step)
  42.     #测试步骤开始
  43.     total_test_loss = 0
  44.     total_accuracy = 0
  45.     with torch.no_grad():
  46.         for data in test_dataloader:
  47.             imgs , targets = data
  48.             outputs = mynet(imgs)
  49.             loss = loss_function(outputs, targets)
  50.             total_test_loss += loss.item() == targets
  51.             accurancy = outputs.argmax(1)
  52.             total_accuracy+=accurancy
  53.     print("整体测试集上的loss:{}".format(total_test_loss))
  54.     print("整体测试集上的正确率{}".format(total_accuracy))
  55.     writer.add_scalar("test_loss",total_test_loss, total_test_step)
  56.     writer.add_scalar("test_accuracy",total_accuracy, total_test_step)
  57.     total_test_step+=1
  58.     torch.save(mynet,"mynet_{}.pth".format(i))
  59.     print("模型已保存")
  60. writer.close()
复制代码
规范tips

当网络中有dropout层等东西的时间,可以调用他们
练习之前
  1. mynet.train()
复制代码
测试之前
  1. mynet.eval()
复制代码
使用GPU练习

思路:在如下几处加入干系代码



  • 网络模型
  • 数据(输入,标注)
  • 损失函数
  • .cuda
方法1

  1. if torch.cuda.is_available():
  2.     loss_function = loss_function.cuda()
  3. if torch.cuda.is_available():
  4.     imgs = imgs.cuda()
  5.     targets = targets.cuda()
复制代码
方法2

  1. .to(device)
  2. Device = torch.device("cpu")
  3. Device = torch.device("gpu")
  4. #定义训练的设备
  5. device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
  6. #电脑上如果有多张显卡,这样来指定显卡
  7. Torch.device("cuda:0")
  8. Torch.device("cuda:1")
  9. imgs, targets = imgs.to(device), targets.to(device)
复制代码
  1. import torch
  2. import torch.nn as nn
  3. import torchvision
  4. import time
  5. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
  6. from torch.utils.tensorboard import SummaryWriter
  7. #定义训练的设备
  8. device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
  9. class MyNet(nn.Module):
  10.     def __init__(self):
  11.         super(MyNet, self).__init__()
  12.         self.model1 = nn.Sequential(
  13.             Conv2d(3, 32, kernel_size=5, padding=2),
  14.             MaxPool2d(2),
  15.             Conv2d(32, 32, kernel_size=5, padding=2),
  16.             MaxPool2d(2),
  17.             Conv2d(32, 64, kernel_size=5, padding=2),
  18.             MaxPool2d(2),
  19.             Flatten(),
  20.             Linear(1024, 64),
  21.             Linear(64,10)
  22.         )
  23.     def forward(self, x):
  24.         x = self.model1(x)
  25.         return x
  26. train_data = torchvision.datasets.CIFAR10(root='./data', train=True, download=True,transform=torchvision.transforms.ToTensor())
  27. test_data = torchvision.datasets.CIFAR10(root='./data', train=False, download=True,transform=torchvision.transforms.ToTensor())
  28. train_data_size = len(train_data)
  29. test_data_size = len(test_data)
  30. print("训练数据集的长度是:{}".format(train_data_size))
  31. print("测试数据集的长度为:{}".format(test_data_size))
  32. #加载数据集
  33. train_dataloader = torch.utils.data.DataLoader(train_data,
  34.                                                batch_size=64,
  35.                                                )
  36. #ctrl+d复制本行到下一行
  37. test_dataloader = torch.utils.data.DataLoader(test_data, batch_size=64,)
  38. #创建网络模型
  39. mynet = MyNet()
  40. mynet.to(device)
  41. #损失函数,交叉熵
  42. loss_function = torch.nn.CrossEntropyLoss()
  43. loss_function.to(device)
  44. # if torch.cuda.is_available():
  45. #     loss_function = loss_function.cuda()
  46. #优化器
  47. optimizer = torch.optim.SGD(mynet.parameters(), lr=0.001, momentum=0.9)
  48. #设置训练网络的一些参数
  49. #记录训练的次数
  50. total_train_step = 0
  51. total_test_step = 0
  52. epoch = 10
  53. writer = SummaryWriter('./logs_train')
  54. start_time = time.time()
  55. for i in range(epoch):
  56.     print("第{}轮训练开始".format(i+1))
  57.     for data in train_dataloader:
  58.         imgs,targets = data
  59.         imgs, targets = imgs.to(device), targets.to(device)
  60.         # if torch.cuda.is_available():
  61.         #     imgs = imgs.cuda()
  62.         #     targets = targets.cuda()
  63.         outputs = mynet(imgs)
  64.         loss = loss_function(outputs, targets)
  65.         optimizer.zero_grad()
  66.         loss.backward()
  67.         optimizer.step()
  68.         total_train_step += 1
  69.         if total_train_step % 100 == 0:
  70.             end_time = time.time()
  71.             print(end_time - start_time)
  72.             print("训练次数:{},Loss{}".format(total_train_step,loss.item()))
  73.             writer.add_scalar('train_loss', loss.item(), total_train_step)
  74.     #测试步骤开始
  75.     total_test_loss = 0
  76.     total_accuracy = 0
  77.     with torch.no_grad():
  78.         for data in test_dataloader:
  79.             imgs , targets = data
  80.             imgs, targets = imgs.to(device), targets.to(device)
  81.             # if torch.cuda.is_available():
  82.             #     imgs = imgs.cuda()
  83.             #     targets = targets.cuda()
  84.             outputs = mynet(imgs)
  85.             loss = loss_function(outputs, targets)
  86.             total_test_loss += loss.item()
  87.             accurancy = (outputs.argmax(1) == targets).sum()
  88.             total_accuracy+=accurancy.item()
  89.     print("整体测试集上的loss:{}".format(total_test_loss))
  90.     print("整体测试集上的正确率{}".format(total_accuracy))
  91.     writer.add_scalar("test_loss",total_test_loss, total_test_step)
  92.     writer.add_scalar("test_accuracy",total_accuracy, total_test_step)
  93.     total_test_step+=1
  94.     torch.save(mynet,"mynet_{}.pth".format(i))
  95.     print("模型已保存")
  96. writer.close()
复制代码
模型验证

使用已经练习好的模型,给它提供输入。
tips:
png图像是4通道,除了rgb以外ia,还有一个透明通道。
  1. image = image.convert('RGB')
复制代码
demo
  1. import torch
  2. import torchvision
  3. from PIL import Image
  4. from torch import nn
  5. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
  6. class MyNet(nn.Module):
  7.     def __init__(self):
  8.         super(MyNet, self).__init__()
  9.         self.model1 = nn.Sequential(
  10.             Conv2d(3, 32, kernel_size=5, padding=2),
  11.             MaxPool2d(2),
  12.             Conv2d(32, 32, kernel_size=5, padding=2),
  13.             MaxPool2d(2),
  14.             Conv2d(32, 64, kernel_size=5, padding=2),
  15.             MaxPool2d(2),
  16.             Flatten(),
  17.             Linear(1024, 64),
  18.             Linear(64,10)
  19.         )
  20.     def forward(self, x):
  21.         x = self.model1(x)
  22.         return x
  23. image_path = "./images/dog.png"
  24. image = Image.open(image_path)
  25. print(image)
  26. transform = torchvision.transforms.Compose([
  27.     torchvision.transforms.Resize((32,32)),
  28.     torchvision.transforms.ToTensor()])
  29. image = transform(image)
  30. print(image.shape)
  31. model = torch.load("mynet_9.pth",map_location=torch.device('cpu'))
  32. print(model)
  33. image = torch.reshape(image, (1,3,32,32))
  34. model.eval()
  35. with torch.no_grad():
  36.     output = model(image)
  37. print(output)
  38. print(output.argmax(1))
复制代码











免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立山

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表