Tensor

detach()

这个是针对想冻结网络model里面的某些参数不参与训练时使用的。并且它是会返回一个新的tensor。

y = x.detach()

这种情况下,y和x共同一个内存,即一个修改另一个也会跟着改变。此时x还是可以正常求导。所以很多时候用的时候是x = x.detach()。

torch.cat 与 torch.stack

torch.cat不会增加新的维度,原来几个维度,还是几个维度
torch.stack会增加一个新的维度,让n维的tensor变成n+1维

x1_torch = torch.zeros(3,1)
y1_torch = torch.ones(3,1)xy_1 = torch.cat([x1_torch, y1_torch], dim = 1)
xy_2 = torch.stack([x1_torch, y1_torch], dim=1)

xy_1的shape=(3,2)

xy_1 = tensor(
[[0., 1.],
[0., 1.],
[0., 1.]])

xy_2的shape= (3,2,1)

xy_2 = tensor(
[ [[0.],[1.]],
[[0.],[1.]],
[[0.], [1.]] ])

矩阵运算

x = torch.Tensor([[1,2],[3,4]])
矩阵相乘 按照矩阵运算法则:

y1 = x @ x.T
y2 = x.matmul(x.T)

y1=y2=tensor(
[[ 5., 11.],
[11., 25.]])

元素之间相乘:

y3 = x * x.T
y4 = x.mul(x.T)

y3 = y4 = tensor(
[[ 1., 4.],
[ 9., 16.]])

与numpy数据交换:

Tensor --> numpy

x_numpy = x_torch.numpy()

numpy --> Tensor

x_torch = torch.from_numpy(x_numpy)

但是需要注意的是,这两个之间共享底层存储,所以更改一个会影响另一个。如果要想阻断之间的关系,可以在numpy数据后面加上 copy()。

数据处理

Datasets & DataLoaders

pytorch的数据处理中最关键的就是这两个类

  • torch.utils.data.DataLoader 主要用于训练的迭代器,使用比较简单
  •   train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
    
  • torch.utils.data.Dataset 做自己数据集的关键类,最关键的是继承类中一定要重载__init____len____getitem__这三个函数。常用模板如下:
  •   class Dataset_name(Dataset):def __init__(self, flag='train'):assert flag in ['train', 'test', 'valid']self.flag = flagself.__load_data__()def __getitem__(self, index):passdef __len__(self):passdef __load_data__(self, csv_paths: list):passprint("train_X.shape:{}\ntrain_Y.shape:{}\nvalid_X.shape:{}\nvalid_Y.shape:{}\n".format(self.train_X.shape, self.train_Y.shape, self.valid_X.shape, self.valid_Y.shape))
    

`

Torchvision.transform

在训练之前,数据基本都需要进行数据增强,各种剪裁等数据变换,因此这个模块是必不可少的。

torchvision.transforms.Compose

这是一个类,主要作用是把所有的数据处理集合成一个操作

  • 输入参数:它接收的元素为Torchvision.transform里面的方法组成的list
  •   T =  transforms.Compose([transforms.CenterCrop(10), transforms.ToTensor()])
    
  • 使用方法:直接对该类的实例传入图片即可,图片的格式需要是PIL或者Tensor。如果是opencv,需要把ToTensor()方法放到第一个。它调用定义的源码为:
  •      def __call__(self, img):for t in self.transforms:img = t(img)return img
    
  • 该类不可用于转移动端的代码,如果转移动端,需要将其替换为如下,并且输出还必须只能是Tensor类型。
   transforms = torch.nn.Sequential(transforms.CenterCrop(10),transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
)
scripted_transforms = torch.jit.script(transforms)

torchvision.transforms.ToTensor

因为图片的读取一般分为opencv和PIL,但都需要转为tensor,或者互转,opencv中的存储方式为(h,w,c),但是tensor中一般都存储为(c,h,w),而pil也是一种特殊的格式;但是这一切都可以用ToTensor一键搞定。

#img_cv.shape = (448, 800, 3)
#img_pil.size = (800, 448)
cv2tensor =  torchvision.transforms.ToTensor()(img_cv)
#cv2tensor.shape : torch.Size([3, 448, 800])
pil2tensor = torchvision.transforms.ToTensor()(img_pil)
#pil2tensor.shape : torch.Size([3, 448, 800])

搭建模型 build model

搭建模型包括:

  1. 构建模型,其中又包括:

    • 定义单独的网络层,即__init__函数;
    • 把它们拼在一起,确定各层的执行顺序,即forward函数。
  2. 权值初始化。

torch.nn

PyTorch 把与深度学习模型搭建相关的全部类全部在 torch.nn 这个子模块中。
根据类的功能分类,常用的有如下几个部分:

  • 模型运算层:

    • 卷积层:torch.nn.Conv2d
    • 池化层:torch.nn.MaxPool2d
    • 线性层:torch.nn.Linear
    • 等等
  • 容器类,如 torch.nn.Module
  • 工具函数类 Utilities,用的较少,日后遇见可以补充。

而在 torch.nn 下面还有一个子模块 torch.nn.functional,基本上是 torch.nn里对应类的函数,比如torch.nn.ReLU的对应函数是 torch.nn.functional.relu,这两者的功能一样,运行效率也不同,但是也有很大的区别:

  1. 调用方式不同 torch.nn.XXX是类,使用前必须先进行实例化,而torch.nn.functional是函数,使用前必须传入所有参数,如果是卷积层需要传入权重。
inputs = torch.rand(64, 3, 244, 244)
conv = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1)
out = conv(inputs)weight = torch.rand(64,3,3,3)
bias = torch.rand(64)
out = nn.functional.conv2d(inputs, weight, bias, padding=1)
  1. nn.Xxx继承于nn.Module, 能够很好的与nn.Sequential结合使用, 而nn.functional.xxx无法与nn.Sequential结合使用。
  2. nn.Xxx是nn.functional.xxx的类封装,并且nn.Xxx都继承于一个共同祖先nn.Module。这一点导致nn.Xxx除了具有nn.functional.xxx功能之外,内部附带了nn.Module相关的属性和方法,例如train(), eval(),load_state_dict, state_dict 等。所以一般尽量选择torch.nn的方式来进行模型构建。
    因为上述区别,PyTorch官方推荐:
    具有学习参数的(例如,conv2d, linear, batch_norm)采用nn.Xxx方式;
    没有学习参数的(例如,maxpool, loss func, activation func)等根据个人选择使用nn.functional.xxx或者nn.Xxx方式。如果要某些层参数共享,则需要通过这种方式。
    但关于dropout,个人强烈推荐使用nn.Xxx方式,因为一般情况下只有训练阶段才进行dropout,在eval阶段都不会进行dropout。使用nn.Xxx方式定义dropout,在调用model.eval()之后,model中所有的dropout layer都关闭,但以nn.function.dropout方式定义dropout,在调用model.eval()之后并不能关闭dropout。

nn.Module

所有自定义的神经网络都要继承 torch.nn.Module。定义单独的网络层在 init 函数中实现,把定义好的网络层拼接在一起在 forward 函数中实现。继承了nn.Moudle的模型类有两个重要的函数:parameters 存储了模型的权重;modules 存储了模型的结构。

功能图:

继承关系图:

3个搭建模型的辅助工具

nn.Sequential

这是一个序列容器,既可以放在模型外面单独构建一个模型,也可以放在模型里面成为模型的一个层。

# 单独成为一个模型
model1 = nn.Sequential(nn.Conv2d(1,20,5),nn.ReLU(),nn.Conv2d(20,64,5),nn.ReLU())
# 成为模型的一部分
class LeNetSequential(nn.Module):def __init__(self, classes):super(LeNetSequential, self).__init__()self.features = nn.Sequential(nn.Conv2d(3, 6, 5),nn.ReLU(),nn.MaxPool2d(kernel_size=2, stride=2),nn.Conv2d(6, 16, 5),nn.ReLU(),nn.MaxPool2d(kernel_size=2, stride=2),)self.classifier = nn.Sequential(nn.Linear(16*5*5, 120),nn.ReLU(),nn.Linear(120, 84),nn.ReLU(),nn.Linear(84, classes),)def forward(self, x):x = self.features(x)x = x.view(x.size()[0], -1)x = self.classifier(x)return x

放在模型里面的话,模型还是需要 init 和 forward 函数。

这样构建出来的模型的层没有名字:

>>> model2 = nn.Sequential(
...           nn.Conv2d(1,20,5),
...           nn.ReLU(),
...           nn.Conv2d(20,64,5),
...           nn.ReLU()
...         )
>>> model2
Sequential((0): Conv2d(1, 20, kernel_size=(5, 5), stride=(1, 1))(1): ReLU()(2): Conv2d(20, 64, kernel_size=(5, 5), stride=(1, 1))(3): ReLU()
)

为了方便区分不同的层,我们可以使用 collections 里的 OrderedDict 函数:

>>> from collections import OrderedDict
>>> model3 = nn.Sequential(OrderedDict([
...           ('conv1', nn.Conv2d(1,20,5)),
...           ('relu1', nn.ReLU()),
...           ('conv2', nn.Conv2d(20,64,5)),
...           ('relu2', nn.ReLU())
...         ]))
>>> model3
Sequential((conv1): Conv2d(1, 20, kernel_size=(5, 5), stride=(1, 1))(relu1): ReLU()(conv2): Conv2d(20, 64, kernel_size=(5, 5), stride=(1, 1))(relu2): ReLU()
)

torch.nn.ModuleList

将网络层存储进一个列表,可以使用列表生成式快速生成网络,生成的网络层可以被索引,也拥有列表的方法 append,extend 或 insert。提高搭建模型效率。

>>> class MyModule(nn.Module):
...     def __init__(self):
...         super(MyModule, self).__init__()
...         self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])
...         self.linears.append(nn.Linear(10, 1)) # append
...     def forward(self, x):
...         for i, l in enumerate(self.linears):
...             x = self.linears[i // 2](x) + l(x)
...         return x>>> myModeul = MyModule()
>>> myModeul
MyModule((linears): ModuleList((0): Linear(in_features=10, out_features=10, bias=True)(1): Linear(in_features=10, out_features=10, bias=True)(2): Linear(in_features=10, out_features=10, bias=True)(3): Linear(in_features=10, out_features=10, bias=True)(4): Linear(in_features=10, out_features=10, bias=True)(5): Linear(in_features=10, out_features=10, bias=True)(6): Linear(in_features=10, out_features=10, bias=True)(7): Linear(in_features=10, out_features=10, bias=True)(8): Linear(in_features=10, out_features=10, bias=True)(9): Linear(in_features=10, out_features=10, bias=True)(10): Linear(in_features=10, out_features=1, bias=True) # append 进的层)
)

torch.nn.ModuleDict

这个函数与上面的 torch.nn.Sequential(OrderedDict(…)) 的行为非常类似,并且拥有 keys,values,items,pop,update 等词典的方法:

>>> class MyDictDense(nn.Module):
...     def __init__(self):
...         super(MyDictDense, self).__init__()
...         self.params = nn.ModuleDict({...                 'linear1': nn.Linear(512, 128),
...                 'linear2': nn.Linear(128, 32)
...         })
...         self.params.update({'linear3': nn.Linear(32, 10)}) # 添加层...     def forward(self, x, choice='linear1'):
...         return torch.mm(x, self.params[choice])>>> net = MyDictDense()
>>> print(net)
MyDictDense((params): ModuleDict((linear1): Linear(in_features=512, out_features=128, bias=True)(linear2): Linear(in_features=128, out_features=32, bias=True)(linear3): Linear(in_features=32, out_features=10, bias=True))
)>>> print(net.params.keys())
odict_keys(['linear1', 'linear2', 'linear3'])>>> print(net.params.items())
odict_items([('linear1', Linear(in_features=512, out_features=128, bias=True)), ('linear2', Linear(in_features=128, out_features=32, bias=True)), ('linear3', Linear(in_features=32, out_features=10, bias=True))])

pytorch autograd 自动求导机制

PyTorch 的 Autograd
目录:

  • 计算图
  • 一个具体的例子
  • 叶子张量
  • inplace 操作
  • 动态图,静态图

浅谈 PyTorch 中的 tensor 及使用
目录:

  • tensor.requires_grad
  • torch.no_grad()
  • 反向传播及网络的更新
  • tensor.detach()
  • CPU and GPU
  • tensor.item()

这两天篇文章关于自动求导机制讲的太深入浅出了,完全不需要自己总结,直接照搬即可……

Train and Optimizing

从上一章知道自动求导机制之后,其实模型训练基本就呼之欲出了。

  1. 设置loss函数
  2. 设置优化函数
  3. 实施后向计算即可:
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

所以常规的网络模型训练的模版如下:

model = Your_model().to(args.device)
criterion = torch.nn.MSELoss()
optimizer = torch.optim.Adam(Your_model.parameters(),lr=args.learning_rate)train_loss = []
valid_loss = []
train_epochs_loss = []
valid_epochs_loss = []def train_loop(dataloader, model, loss_fn, optimizer):size = len(dataloader.dataset)for batch, (X, y) in enumerate(dataloader):# Compute prediction and losspred = model(X)loss = loss_fn(pred, y)# Backpropagationoptimizer.zero_grad()loss.backward()optimizer.step()if batch % 100 == 0:loss, current = loss.item(), batch * len(X)print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")def test_loop(dataloader, model, loss_fn):size = len(dataloader.dataset)num_batches = len(dataloader)test_loss, correct = 0, 0with torch.no_grad():for X, y in dataloader:pred = model(X)test_loss += loss_fn(pred, y).item()correct += (pred.argmax(1) == y).type(torch.float).sum().item()test_loss /= num_batchescorrect /= sizeprint(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")epochs = 10
for t in range(epochs):print(f"Epoch {t+1}\n-------------------------------")train_loop(train_dataloader, model, loss_fn, optimizer)test_loop(test_dataloader, model, loss_fn)
print("Done!")

save and load model

只保存参数

一般的训练只需要保存参数,这样更方便

model = models.vgg16(pretrained=True)
torch.save(model.state_dict(), 'model_weights.pth')

在读取这个参数时,必须先对模型进行实例化,才能load参数。

model = models.vgg16() # we do not specify pretrained=True, i.e. do not load default weights
model.load_state_dict(torch.load('model_weights.pth'))
model.eval()

保存参数+网络结构

#保存参数+网络结构
torch.save(model, 'model.pth')
#加载
model = torch.load('model.pth')

Torchvision

torchvision.utils.make_grid

输入参数:

  • shape =(B x C x H x W)的tensor 或者 形状一致的tensor组成的list。
  • nrow :这一行显示多少张图片,如果要加一个batch=8的一组图片,nrow=2,这就是显示4行。默认是8
    这个函数的输出可以做为Tensorboard中的add_image的输入参数
dataiter = iter(trainloader)
images, labels = dataiter.next()
img_grid = torchvision.utils.make_grid(images,nrow=2)

torchvision.utils.save_image

可视化工具Tensorboard

主要分为:实例化writer --> 写入数据 --> 浏览器查看

实例化writer
tensorboard在一个文件夹下,只能读取一个event文件,所以实例化的时候需要利用时间戳创建不同的文件夹,避免一个文件夹出现多个文件。

from torch.utils.tensorboard import SummaryWriterwriter = SummaryWriter('./runs/' + time.strftime("%Y-%m-%d-%H_%M_%S",time.localtime(time.time())))

这样便会在当前目录下创建:

写入数据
最主要是写入loss这样的训练数据,然后也可以查看当前训练结果。

if (i + 1) % args.log_train_loss_interval == 0:writer.add_scalar('loss', loss, step)if (i + 1) % args.log_train_images_interval == 0:writer.add_image('train_pred_pha', make_grid(pred_pha, nrow=5), step)

浏览器查看

进入到runs目录,运行:

tensorboard --logdir=./

如果是在远程服务器上,本地打开cmd,执行:

ssh -L 16006:127.0.0.1:6006 root@xx.xxxx.xx.xxx

登录进去之后,在浏览器输入:

http://127.0.0.1:16006/

pytorch 入门教程 常用知识整理相关推荐

  1. MYSQL数据库常用知识整理

    为什么80%的码农都做不了架构师?>>>    MYSQL数据库常用知识整理 什么是MYSQL MYSQL的特性 MYSQL存储引擎的分类以及数据文件的介绍 MYSQL赋权 MYSQ ...

  2. HTML3天快速入门教程(详细整理附案例)

    前言 最近微信小程序后期学习框架遇到瓶颈,听的有点懵,所以不得不先来补一下前端基础知识,即前端三件套HTML.CSS.JavaScript ,因为小程序里面很多知识点与前端三件套大同小异,正好也进行对 ...

  3. 最全面 Nginx 入门教程 + 常用配置解析

    http://blog.csdn.net/shootyou/article/details/6093562 个人整理资料,转帖注明出处,谢谢~ Nginx介绍和安装 一个简单的配置文件 模块介绍 常用 ...

  4. 总结 | 深度学习之Pytorch入门教程

    AI博士笔记系列推荐 周志华<机器学习>手推笔记正式开源!可打印版本附pdf下载链接 本篇笔记的目录: 后台回复"8003"获取pdf版本 一.整体学习的建议     ...

  5. 【慕课网】人工智能-语音入门|公开课知识整理

    人工智能-语音入门 该博客是慕课网视频教程的笔者自我小结,原视频传送门 References: 语音增强理论与实践-[美]罗艾洲等 [译]高毅等 WAV和PCM的关系和区别 AudioSet数据集 知 ...

  6. 理想国pytorch入门教程

    01.简介 pytorch是一个能在CPU和GPU上运行并解决各类深度学习问题的深度学习框架 可以将其看作是支持GPU计算和自动微分计算的Numpy库 pytorch是一个灵活,容易学习的python ...

  7. 深度学习为什么选择Pytorch?史上最详细Pytorch入门教程

    目录 前言 一. Pytorch介绍 1.常见的深度学习框架 2.Pytorch框架的崛起 3.Pytorch与Tensorflow多方位比较 二.Tensors 1.Tensor的创建 2.Tens ...

  8. 腾讯团队实力打造flutter入门教程,吐血整理

    前言 这些题目是网友去美团等一线互联网公司面试被问到的题目.笔者从自身面试经历.各大网络社交技术平台搜集整理而成,熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率. 主要分为以下几部分: (1 ...

  9. CSS入门保姆级知识整理!!看到就是赚到!(1)

    CSS基础知识 1.1基本概念 CSS(Cascading Style Sheet) 层叠样式表,为了实现页面内容和表现形式的分离.层叠的含义是可以对一个元素多次设置样式,最后的结果是多次样式叠加的结 ...

  10. docker 入门教程(常用命令汇总)

    文章目录 1. 系统启动/重启/停用 docker 2. docker镜像 2.1 查看镜像列表 2.2 查找镜像 2.3 拉取镜像 2.4 构建镜像 2.5 添加标签 2.6 推送镜像&镜像 ...

最新文章

  1. Python CNN风格迁移
  2. GAN生成对抗网络-PIX2PIXGAN原理与基本实现-图像翻译09
  3. java 堆转储快照_捕获Java堆转储的7个选项
  4. [Err] 22007 - [SQL Server]从 nvarchar 数据类型到 datetime 数据类型的转换产生一个超出范围的值。
  5. 一调计算机专业综合理论试卷,一调计算机专业综合理论试卷(盐城)(新编)
  6. (2/2)Canvas的交互存为图片-爬坑篇
  7. HTML5-Tab标签
  8. R语言︱ 数据库SQL-R连接与SQL语句执行(RODBC、sqldf包)
  9. 毕业设计别再做 XX 管理系统了!!!
  10. 关于 U盘被写保护的问题
  11. dell塔式服务器显示卡端口类型,戴尔T610塔式服务器
  12. Spring Cloud Eureka 全解 (5) - 自我保护机制
  13. cub数据集多少张图片_细粒度分类数据集汇总
  14. npm ERR path /Users/user/Desktop/app/node_modules/node-sass
  15. 打官司除了找律师,还能找谁?
  16. 一段有趣的代码,喂仓鼠
  17. 软件测试证述职报告ppt,实验室检测员的述职报告ppt
  18. HTML5+CSS期末大作业:运动体育网站设计主题——体育铅球(5页)带注册 期末作业HTML代码
  19. 设置什么加快计算机启动速度,如何设置CPU加速对电脑启动速度的方法(更改CPU数量可开机提速)...
  20. 游戏辅助制作核心--植物大战僵尸逆向之自动捡取阳光(二)

热门文章

  1. (附源码)spring boot大学毕业设计管理系统 毕业设计 030945
  2. [论文评析]Density‑based weighting for imbalanced regression,Machine Learning,2021
  3. C++控制台五子棋(带背景音乐)
  4. IO字节流读取文本中文乱码
  5. f(!gotop.length) return false;
  6. QT开发之老板无法拒绝的辞职信
  7. 程序员史诗级必读书单吐血整理四个维度系列80+本书(珍藏版)
  8. JUL配置文件进行相关配置
  9. 购物中心最好的无线AP是什么?
  10. MySql基础篇之SQL语句(DDL、DML、DQL、RCL)