【深度学习框架体系的学习】pytorch

如何设计一个具有通用性的程序框架?一切都要基于长期的阅读手打思考

1.将繁琐且重复的事情做成高内聚的黑箱
2.将问题模块化:处理数据,构建网络,损失函数,优化函数,模型保存。五大模块
自己从0构建
1).文件夹model或者net:CIMIC-GAN.py(整体网络结构), common.py(部分小网络结构),还有一些和网络相关的配置文件yaml文件)。
2).文件夹data:存放数据集或者和数据集信息有关的配置文件(yaml文件),或者有数据预处理的内容。
3).文件夹utils:一些需要调用的方法,各种小工具。
4).文件夹script:写一下必要的小脚本,外部调用的小脚本。
5).文件夹runs:训练得到的结果,可以有权重文件夹weight。
6).文件夹methods:loss.py,evaluate.py数据后处理,画个图啥的。
7)train.py(训练入口)
8)test.py或者detect.py(测试入口)
3.把常用的东西定义出来,方便求解简单问题。

整体学习流程

首先千万不要一上来就学习一大堆的理论知识,因为会忘记,而且没实际用过的话记忆也不会深刻,只有自己亲自动手debug了之后才会非常深刻。举个例子比如添加参数组,尤其在一些工程类代码当中数量太多了,不同的参数组合会组合成不同的字典,yolo就会根据不同的参数组设置不同的优化策略。

从0到1

吃透源码,和学会吃透任何源码的方法,主要指debug调试。

从1到2

前提已经吃透代码
在原先的基础上修改成自己的东西:重新构建属于自己的项目结构,例如把功能性强的函数封装到一起。模仿开源代码的格式进行自己代码的构建。

杂七杂八的基础知识

Dataset是pytorch官方提供的类,我们只有先继承这个类才能官方的基础上重写。
class 某某某Dataset(Dataset):
非常常见的for i,data in enumerate(list_train):
enumerate函数的功能就是如果传进来的对象是一个列表,那么它就会对列表内的每一个元素进行一个标序号,从0开始标序号,本质上相当于一个双层循环。
训练集验证集测试集三种数据集的区别,首先train,test,valid内容上不能有完全的重合,也就是说必须是不一样的。验证集出现的目的,就是如果没有验证集的话,测试集只能等待训练集训练完了才能发挥作用,所以验证集的作用就是和训练集一样切割开来,每训练一个epoch就把验证集对应的部分传入网络参数当中测试一下,其实目的就是为了边训练就能便看到结果。所以再训练过程中是同时使用了训练集和验证集。
只要出现继承就一定会出现重写。
一般情况下如果碰到了一个函数不认识,千万不要百度,通过debug可以假如说可以知道输入内容,和等号左边输出得出来的是个什么东西,就能猜出官方定义的函数是个什么作用。如果想要深入了解官方函数的话,就只能用一个操作比较困难的remote debug了。
因为是大多数官方定义的类实例化出来的对象大多数都比较复杂,一旦实例化出一个对象,那么一定会执行被实例化类中的__int__函数。所以这个被实例化出来的对象在debug窗口中一定有几个实例化属性对应被实例化类的实例化方法__int__所初始化的实例化属性。
@staticmethod,类方法,不会出现self,也叫做静态方法。
对于代码中经常出现的for循环来讲,重要的不是in后面的函数,而是for后面的变量究竟是什么,因为for后面的变量一定是in后面的函数的返回值,debug的精髓就是通过返回值猜出函数的意思。
debug变量模块中只要出现了单引号就以一定是字符串,不管是在哪里出现。
当debug步过一句实例化对象时,一定会执行被实例化类里的方法,所以可以提前在那个类里的某个地方打好断点方便我们分析。
图片的大小和维度可能不是一样的,但是传到数据网络的tensor矩阵的shape必须是一样的。
循环的嵌套,比如说一条语句本身就在循环里,而这条语句每次执行一次都会调用其他类中的__xx__方法好几十次。
断点的作用甚至还可以判断验证有没有一个函数相互调,跳出去又跳回来的时候有没有经过其他地方,如果真的经过断点处的话会直接跳到断点处。断点加上条件也可以设置成条件断点。
长摁住ctrl把鼠标放在函数上就会显示一些需要传入的参数,还可以点进去。
pytorch提供了三种容器:
nn.Sequential相当于把初始化网络和前向传播合在一起了,顺序简化网络,相当于不用写forward函数了。但是为什么还是会经常看到forward函数呢?那是因为x.view这种类型的操作不在nn模块下,也不在F模块下。但是这种情况下在层的命名上会出现很多问题,所以要用字典的方式,在nn.Sequential里面加一个OrderDict,在每一层前面加上有序的命名字典,其实就是一个能起名字一个不能起名字,易于修改网络参数。此容器用于线性网络比较好。
ModuleList:不是顺序的,所以前向传播得自己写,也就是相当于通过循环构建网络,用于大量重复网络的构建。
ModuleDict:也就是通过参数定义的方式来使用不同的网络层,常用于可选择的网络层。
torch.nn:
nn.Parameter 表示可学习的参数如weight,bias
nn.Modeule:所有网络层的基类,管理网络属性
nn,functional:函数具体实现,如卷积池化激活函数等
nn.init;参数 初始化方法。
损失函数的重写可以有但不多见,优化函数的重写有但是更少。
一段代码打断点的顺序就是前面的数据和网络的定义先不打断点,直接到最后打断点,然后数据肯定会传到前面再再前面打断点。
程序中有时候会出现一些一个下划线这种返回值,_这种返回值一般代表没有什么乱用的返回值。
还有一些东西是通过debug没法看到的,比如有一些代码会是这种情况:
变量=X.方法1()方法2()方法3()方法4()方法5()
这种就有点恶心了,套了十万个方法,控制台中有一个python小按钮:
在这里插入图片描述
然后用print语句从内到外一句一句打印,一层一层往外扩,打印到方法5的时候必然也会出现方法1234.打印出来的结果再结合Debug模块中的变量列表就能知道是什么意思了。假如这一句报错了的话,这种方法还能一层一层排查是哪里出现了错误。
还有时候debug看不出来是什么,比如for循环中in后面一大坨不知道是什么玩意,就先先把那一坨单独拿出来做一行代码,这样就能看出来了。

自己写代码的套路

不管是什么可执行脚本肯定都有超参数的构建和解析:这些超参数肯定最后被存到了opt了,所以调用这些超参数的时候基本上都是opt.超参数。
自己写代码的时候也是需要不停的debug的。
尽量不要早类的外面定义变量。
高维表示的意思是变得更小了,信息更浓缩了的意思。比如[256,1984]会变成[256,128],这样的变化叫做高维表示。

GPU的训练模型的保存与加载

1.如果网络在gpu上,那么模型和数据也得放在gpu上。如果把网络和数据同时放在gpu上,那么输出的结果仍然在gpu上。
但为什么有时候label也要放在gpu上呢,因为有的代码会把inputs和label做一个比较判断,一个放在gpu上了,那么另外一个一必须要放在 gpu上。
查看动手学深度学习的模型和参数的保存和加载。

如何读深度学习大型工程类的项目代码

首先万变不离其宗,处理数据,构建网络,损失函数,优化函数,模型保存这五大模块是根本。因为这种代码一般是一个团队在维护,但凭个人就想把整个团队维护的东西都吃透显然不现实,就算可以做到也没有什么意义效率也不是特别高。所以学会忽略
忽略的意思就是学会抓主干,像什么tensorborad这种东西能跑通能用就可以了,不必深究,但是主干必须得好好debug一下。pycharm就提供了很好的把代码折起来的功能。有些函数具体是怎么实现的的咱们也不用管,只要debug前后输出和输入知道是干什么的就可以了。但是有一些函数关乎完成自己的课题就必须得改。
debug途中发现有些语句就没有执行,直接忽略,节省时间。
在开源代码把这五个模块都找到

dataset模块

第一步:重写__init__和__getitem__这两个函数。
第二步:把dataset传到dataloader里面。
这里针对pytorch主要有两个API

torch.utils.data.DataLoader

处理多个样本而言,先通过dataset得到单个训练样本之后,再通过dataloader将数据变成mini-bartch的形式,将多个样本组合成一个mini-batch,还能当训练一定epoch之后,将数据打乱,甚至还能将数据固定的保存再GPU中。

torch.utils.data.Dataset

处理单个训练样本,从磁盘读取数据集,包括标签,变形,预处理,最终把数据集映射变成x和y。

torchvision

torch内置的一些数据集可以直接通过torchvision导入,源码见官方文档Tutoriais。

daraset的类型

详细见官方文档Docs
map-style datasets就是指从磁盘里获取的数据集类型
还有一种实时流式的,iterable-style datasets.

Creating a Custom Dataset for your files

dataset

详情见pytorch官方源码
大多数情况数据集并没有内置,我们需要自己构建一个Dataset类,基于自己构建的dataset放入dataloader中,参与神经网络的训练。
我们自定义的 Dataset class类必须要继承一个类Dataset,且必须要实现三个函数,s: init, len, and getitem
init函数:传入一些磁盘路径啥的
len函数:直接返回数据集大小
getitem函数:核心,通过idx返回样本,主要是将数据加载到内存中,[idx, 0],通过第idx行,第0列就可以得到每一个数据样本文件的名称,再通过一些函数将数据加载到内存中。加载到内存后,会进行一些操作,可能对数据会进行一些处理比如说归一化,预处理,比如替换过滤文本字符,图形处理。就通过transform函数就可以进行一些预处理。[idx, 1],通过第idx行,第1列存储的是label,也能处理label。最后这个函数会返回一个元组或者字典。总之这个模块就是定义路径,数据预处理,外面自己肯定也要定义一个transform()函数和一个target_transform()函数,通过这两个函数分别对特征和标签进行一个预处理。

dataloader

由于数据存在噪声,为了使抗噪性增强使用mini-batch,每一个训练周期完成以后还能对数据打乱reshuffle也可以防止过拟合,还能调用多进程multiprocessing使数据的读取不会影响GPU模型训练的延迟,用多进程加载数据。
from torch.utils.data import DataLoader
train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)
更多源码见官方文档也啥也没有,直接看dataloader源码把,得先传入dataset实例化对象,同时还需要传入一些其他参数:
sampler,batch_sampler:如何采样,可以默认也可以自己实现,也可以自定义sampler方法
num_works:cpu核,多进程
pin_memory:不需要重复保存,可以将tensor保存在gpu中,其实用不用都无所谓。
drop_last:当总样本数量不是batch_size的整数倍的时候,丢掉最后一个小批次。
collate_fn:输入是一个batch,输出也是一个batch,就是对每一个batch进行一些操作例如pad,甚至更加复杂的操作。

迭代

把dataset塞到dataloader之后就可以进行遍历,每一次遍历都会得到一个batch_size的特征和标签,当设置shuffle等于true之后,遍历完所有batch,从头开始就会不一样了。
详细见官方文档
next(iter(train_dataloader)),先将train_dataloader变成一个迭代器,再用next()函数依次生成就可以了。

乱起八糟重要小知识

1.有时候代码文件名不够直观。代码冗余重复严重,需要大大的修改。优化代码内容。
2.非python文件千万不要加注释,尤其是一些配置文件
3.tqdm仅仅是训练时一个进度条的效果。
4.batch_size=16,并不是说拿出来一个列表,列表里面有16个元素,最后的输出是一个东西,这16个还要进行一个合并的操作。
5.tqdm函数左右是相等的,tqdm就是有一个进度条的效果。
6. [index][0]是用来去括号的。
7. 在终端打出python就相当于控制台,import XXX as XXX,就可以开始测试了。
8. range(闭区间,开区间),一般后面得加1。
9. 卷积神经网络最重要的两个参数就是输入通道数和输出通道数。因为池化层对通道数是没有变化的,但是卷积层一定是有变化的。当网络结构出现分支的时候,就需要把网络分支的前几层的输出通道数都存储起来,把输出通道数都存在一个列表里面,每当往一个新的卷积层传参数的时候,输入通道数就是这个列表[-1],这个列表的最后一个元素。
10.别一看到list就以为是列表,也有可能是range类型,从几到几。
11.见到负数就要下意识的想到是从后往前的索引。
12.列表推导式:在这里插入图片描述
if后面的是判断条件,如果满足,就执行前面的语句,如果不满足就执行else后面的语句。

编码知识

需要背会tips

/ 用来换行
不管遇到什么问题到要去官网的api搜一下
使用函数.masked_fill填充的时候为了不出现NAN,用-le9替换掉-np.inf
打印出来的tensor中有几个中括号就是几维的
去pytorch的官方文档中看一下雅可比矩阵:torch.autograd.functional.jacobian()
torch.bmm()矩阵的乘法
由列表推导式生成的张量列表一般要配合torch.cat()函数使用,torch.cat对列表使用,作用就是根据内层的中括号合并tensor,并将多个tensor合并成一个tensor。
torch.unsqueeze()扩维就是用来为每一个tensor增加中括号的作用
torch.ones()还有torch.zeros()括号里面都跟的是形状
看一个tensor有几维,看中括号的层数就知道,几层中括号就是几维,从0开始数,转置的时候就知道了
在实例化对象后面直接加括号,就相当于调用该实例的forward方法。
几维矩阵是指,这个矩阵的形状有几个数字组成,而不是数字的值是多少。
构建出来的mask矩阵中的元素要么为一要么为负无穷,且维度和原矩阵相同,因为与1相乘维度不变,与-inf相乘经过softmax会变成0。
dilation空洞
卷积虽然是下采样,但是通道数会越来越多。
一定要好好理解kernel_size的含义,卷积和的通道数x卷积核长x卷积核宽。
complex指的是torch当中复数的数据类型,
一般多继承会使用super这个函数。
列表推导式转字典推导式,推导式内部还能再加判断。

需要背会的常见API
创建

torch.set_default_tensor_type(torch.DoubleTensor)
torch.zeros(2,3)
torch.ones(5)
torch.zeros_like(input)
torch.ones_like(input)
torch.arange(1, 4) (左闭右开)用于遍历生成连续索引,如果之传入一个参数默认传入参数end
torch.range(1, 4, 0.5) (左闭右闭)这两组api常用于for循环的in后面
torch.linspace(3, 10, steps=5) torch.logspace(start=0.1, end=1.0, steps=1) 创建线性的和创建对数的
torch.eye(3) 二维对角矩阵
torch.full((2, 3), 3.141592) 传入一个已有张量并用数据填充

索引切片连接聚合

torch.cat(tensors, dim=0, *, out=None) → Tensor 非常常用是需要传入张量组成的列表,除了要cat的张量其他维度必须一样
torch.stack() cat是续接,而stack是叠加,相当于使用cat维度不变但是对应维度长度会变,但是使用stack会直接多出1维
torch.chunk() 均匀分割
torch.split() 指定大小分割
dsplit hsplit dstack hstack 纵向分割,横向分割 深度堆叠,广度堆叠
torch.gather(A张量,dim=?,B张量) 看了老半天,就是将B的索引对应dim维度上用B该索引对应的位置的元素 替换掉,生成一套和B形状一模一样的索引,对应这些索引再用A的元素填充。
torch.reshape((之前的形状),(之后的形状)) 反正不管怎么reshape,乘起来肯定都是一样的。
torch.Tensor.scatter_ 有autoplace版本和inplace版inplace在pytorch中是加下划线和gather很像
torch.squeeze() 删除掉长度为一维度
torch.unsqueeze() 新增维度,就是一个加中括号的
torch.take(张量A,张量B) 将张量B的元素本身视为索引,通过索引取到张量A对应的元素并生成新的张量,并碾成一维
torch.tile(张量A,元组或列表(,)) 很重要,复制拷贝,传入元组中数字的个数一定要和张量A的维数是一致的,数字是几,就相当于于该数字对应的维度复制即份,数字是1不做改变,例:[[2,2]],(1,2)—>复制出来新张量对应维度的数字翻倍[[2,4]]
torch.transpose() 常用了都,老生长谈了
torch.unbind() 返回给定维度降维后组成的元组,指降给定维度这一维
torch.where(条件,x,y) 很常用,首先前提是是x张量和y张量的形状要相同,满足条件的位置用x的元素,否则用y的元素

随机采样

torch.manuml_seed(seed) 为生成随机数固定一个种子,只要种子固定,每次运行代码都会从同样的分布中采样,主要是为了模型或者超参数的可复现,主要是为了模型参数的随机初始化。
torch.bernoulli(概率) 返回伯努利采样的结果,只返回0或者1
torch.normal(mean.std) 高斯分布

张量的扩维

torch.unsqueeze()

列表转tensor

方法一 torch.Tensor(列表).to(torch.int32)
方法二 torch.cat(列表)

由列表推导式生成列表

[torch.arange(max(tgt_len)) for _ in src_len]

随机初始化

torch.randint(2,5,(batch_size,))
torch.randn(5)

数值矩阵转布尔矩阵

.to(torch.bool)

生成随机数

torch.rand() 均匀分布,0为闭区间,1为开区间
torch.randn()标准正态分布
torch.randint(最小,最大,(形状)) 从任意整数区间随机得到整数
torch.randperm(n)构建随机组合,只需要传入一个上界n,就会返回0到n-1这些数随机的一个shuffle,然后返回一个随机shuffle的列表。

类型转换

to()括号里写要转换的类型
to(torch.int32)

有步长的函数

1.数组切片df[:,0::2]从0开始步长为2的偶数列,数组切片df[:,1::2]从0开始步长为2的奇数列,这里的数组也可以是tensor里有双层中括号
2.arange函数有步长
3.for循环也有步长

默写

1.生成特定形状的且经过padding的一个mini-batch的随机向量:
定好的序列长度=torch.randint(2,5,(mini-batch的形状))
或者直接把形状不随机生成了,直接把实际序列形状定死
定好的序列长度=torch.Tensor([2,4]).to(torch.int32)
torch.cat([torch.unsqueeze(F.pad(torch.randint(1,词表长度,(L,)),(0,定好的序列长度-L)),0) for L in src_len])

2.平均生成序列
torch.arange(填空一个数两个数三个数都可以).reshape((-1,1))转换成一列
.reshape还有加一层中括号的作用,之前讲到的torch.unsqueeze()也有增加中括号的作用
.reshape((-1,1))转换成一列,这里几层括号没有任何区别
.reshape((1,-1))转换成一行

3.掩码矩阵的构造方式
1)先确定掩码矩阵的形状和维度
2)通过列表推导式求出有效矩阵,

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: PyTorch深度学习简明实战电子版是一本帮助读者入门深度学习框架PyTorch的书籍。本书内容详细,分为四个部分,分别是:PyTorch初步、图像分类、目标检测以及深度强化学习,能够帮助读者系统地学习深度学习的基础知识、理解和掌握PyTorch框架下的常用模型和算法,并能够在实践中应用这些模型和算法解决实际问题。 在PyTorch初步部分,本书介绍了PyTorch框架的基本使用方法和特点,包括如何创建和操作张量、构建计算图、定义和训练模型等方面的内容。图像分类部分介绍了卷积神经网络(CNN)的基础理论和实现方法,并使用PyTorch框架构建了一个CNN模型,用于解决图像分类问题。目标检测部分介绍了目标检测的基础知识和Mask R-CNN算法,并使用PyTorch实现了Mask R-CNN模型,应用于目标检测问题。深度强化学习部分介绍了深度强化学习的基本理论和实现方法,并使用PyTorch框架实现了深度Q网络(DQN)算法,应用于OpenAI Gym游戏环境中。 本书的内容涵盖了深度学习的多个方面,适合广大读者学习和实践。同时,本书使用Python语言和PyTorch框架,使得读者能够快速上手,掌握深度学习的基础知识和PyTorch框架的用法。最后,本书提供了大量实例代码和练习题,帮助读者深入理解和应用所学知识。 ### 回答2: PyTorch深度学习简明实战电子版是一本介绍PyTorch深度学习框架的实战教程。本书分为三个部分,第一部分是基础知识,包括PyTorch的基本操作、张量、自动求导、线性回归模型等内容;第二部分介绍深度学习的常用模型,包括卷积神经网络、循环神经网络、生成对抗网络等;第三部分是应用案例,包括图像分类、目标检测、自然语言处理等。 书中的案例非常实用,深入浅出地介绍了每个模型的实现原理和使用方法。而且,书中使用的数据集是实际的数据集,例如MNIST手写数字识别、CIFAR-10图像分类等,能够充分体现PyTorch在实际应用中的优势。 本书的特色在于其简洁明了的讲解方式,将深度学习框架PyTorch的基本操作及其应用形象生动地展现出来。此外,本书还提供了丰富的代码实现、调试和性能优化技巧,为读者提供了一系列实用的工具来应对实际问题。 总之,PyTorch深度学习简明实战电子版是一本非常实用的教材,不仅能够帮助读者快速掌握PyTorch的各项功能,还能够让读者在实践中深入理解深度学习的实现原理。该书对于人工智能相关行业的从业者、学生以及对深度学习感兴趣的读者都是一本值得阅读的好书。 ### 回答3: PyTorch深度学习简明实战电子版是一本针对深度学习初学者推出的实战教程,主要原因是PyTorch是一个非常适合于初学者的深度学习框架,其将深度学习任务分解成容易理解和实现的步骤。此书包含了丰富的实际应用案例,以及详细的实现代码和运行结果分析。通过阅读本书,读者可以学习深度学习的核心概念,如神经网络、梯度下降、损失函数等,并且能够了解如何使用PyTorch中的各种工具来构建和训练深度神经网络。本书还着重强调了PyTorch的动态图机制,这一点与其他深度学习框架的静态图机制不同,动态图机制允许我们更加直观地进行模型设计和调试。在本书中,作者还涉及了一些高级技术,如循环神经网络、深度卷积网络等,从而为读者提供更加全面的知识体系。总之,PyTorch深度学习简明实战电子版是一本值得推荐的实战教程,既适合初学者入门,也可以帮助专业人士深入了解PyTorch的实际应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值