torch值得注意的语法

1. nn.AdaptiveAvgPool2d()

相比 nn.AvgPool2d() 多了个自适应,只需要关注输出维度的大小 output_size ,具体的实现过程和参数选择自动确定。
在这里插入图片描述
例子:

x = F.AdaptiveAvgPool2d(x, (part, 1))		# 分成part个列向量
x = F.adaptive_avg_pool2d(x, (1, 1))		# 变成一个列向量
设置全局平均池化层:
model_base.avgpool = nn.AdaptiveAvgPool2d((1, 1))

2. F.softmax(x, dim=xx)

在三维tensor的例子中,

dim=0表示对第一维度相同位置的数据做归一化(固定其他维度,只变换该维度的数值之和为1)

[0][0][0]+[1][0][0]=0.0159+0.9841=1
[0][0][1]+[1][0][1]=0.6464+0.3536=1

dim=1表示对第二维度(某列)做归一化,

[0][0][0]+[0][1][0]=0.1058+0.8942=1
[1][0][0]+[1][1][0]=0.3189+0.6811=1

dim=2表示对第三维度(某行)做归一化,

[0][0][0]+[0][0][1]+[0][0][2]=0.0042+0.4726+0.5232=1
[1][0][0]+[1][0][1]+[1][0][2]=0.2029+0.2015+0.5955=0.9999=1

dim=-1表示对倒数第一维度做归一化(和dim=2效果一样)。

3. ReLU激活函数的几个变形

在这里插入图片描述
另外:
在这里插入图片描述

4. __ repr__() 方法

是类的实例化对象用来做“自我介绍”的方法。具体的,通过重写类的 repr() 方法,当执行 print(类的实例对象) 的时候,我们得到的信息不再是<main.CLanguage object at 0x000001A7275221D0>,而是执行 print(class.__ repr__()),可以输出repr中的信息。

class ABC:
    def __repr__(self):
        return "help information"

abc = ABC()
print(abc)
"""
help information
"""

5. __ getitem__(self, index):

在加载数据集的时候,通常要在类中要设计这个函数。因为定义的dataset对象要传给dataloader,dataloader在“load data”的时候,需要dataset对象有这个getitem方法取数据。

数据集本质应当是所有数据样本的一个列表,因此每个样本都有对应的索引index。我们取用一个样本最简单的方式就是用该样本的index从数据列表中把它取出来,__getitem__做的事情就是返回第index个样本的具体数据。其实变相是支持了 [idx] 的切片操作。

6. nn.CrossEntropy Loss()

交叉熵能够衡量同一个随机变量中的两个不同概率分布的差异程度,在机器学习中就表示为真实概率分布与预测概率分布之间的差异。交叉熵的值越小,模型预测效果就越好。交叉熵在分类问题中常常与softmax是标配,softmax将输出的结果进行处理,使其多个分类的预测值和为1,再通过交叉熵来计算损失。

交叉熵公式表示为:
在这里插入图片描述
其中,p是标签,是真实概率分布;q是预测值。上面的式子计算了两个概率分布之间的差异。具体的,如:
在这里插入图片描述
一个batch的loss为:(对每个样本的loss求平均数)
在这里插入图片描述
其中,m是样本个数,n是类别数。

7. torch.nn.functional.nll_loss

负对数似然损失(Negative Log Likelihood Loss)。

利用网络的output和真实标签target计算softmax+交叉熵损失的过程为:
(1)sm=softmax(output); 将output归一化到[0,1]
(2)logsm=log(sm); 取对数
(3)loss=-logsm.*target ;取出真实类别对应的数值,去负号。

NLLLoss相当于只执行(3),因此需要手动完成(1)和(2),其输入应为logsm;
CrossEntropyLoss相当于同时完成三步。

为什么NLL Loss的计算方式可以用来求损失值?
Softmax计算出来的值范围在[0,1],值的含义表示对应类别的概率,也就是说,每行(代表每张图)中最接近于1的值对应的类别,就是该图片概率最大的类别;那么经过log求值,计算出来的值在负无穷到0之间,最接近于0的值对应最大概率类别;去负号之后,也是最接近于0的值,如果此时每行中的最小值对应的类别值与Target中的类别值相同,那么每行中的最小值求和取平均就是最小,极端的情况就是0。总结一下就是,与真实类别对应的预测值越大,NLL Loss求出来的值就越接近于0,这不正是损失值的本意所在吗,所以NLLLoss可以用来求损失值。

8. torch.transpose()

交换tensor的两个维度。

>>> cc=torch.randn((2,3,4))
>>> dd=torch.transpose(cc,1,2)
>>> cc.size()
torch.Size([2, 3, 4])
>>> dd.size()
torch.Size([2, 4, 3])

9. np.argsort()

numpy.argsort(a, axis=1)

功能: 将矩阵a按照axis排序,并返回排序后的下标
参数: a:输入矩阵, axis:需要排序的维度
返回值: 输出排序后的下标

# 1.对于二维输入:
x = np.array([[1,5,4],[-1,6,9]])
# [[ 1  5  4]
# [-1  6  9]]

# 2.axis=0,表示沿着行向下(每列)的元素进行排序  
np.argsort(x,axis=0)
# array([[1, 0, 0],
#        [0, 1, 1]], dtype=int64)

# 3.axis=1,沿着列向右(每行)的元素进行排序
np.argsort(x,axis=1)
# array([[0, 2, 1],
#        [0, 1, 2]], dtype=int64)

#####注意:是将该行数值从小到大排序后,依次输出每个数值原来的索引。

10. dtype和type的区别

s.dtype表示的是s里面的数据的类型,type表示的是s本身的类型

s = np.array([1, 2, 3])
print(s.dtype, type(s))

输出:
int64 		<class 'numpy.ndarray'>

11. np.unique(array, return_index=True)

array重复的元素只保留一个,返回包含不同元素的数组。

array:输入的数组,除非特别指定axis,数组将被展平为1-D形式进行处理。

return_index: 如果为True,返回数组提供不重复值(unique)元素的索引下标(如果有多个返回第一个)

例子:
在这里插入图片描述

12. numpy.random.choice

#numpy.random.choice(a, size=None, replace=True, p=None)
#从a(只要是ndarray都可以,但必须是一维的)中随机抽取数字,并组成指定大小(size)的数组
#replace:True表示可以取相同数字,False表示不可以取相同数字
#数组p:与数组a相对应,表示取数组a中每个元素的概率,默认为选取每个元素的概率相同。

例子:
np.random.choice(5, 3)	#在[0, 5)内输出3个数字并组成一维数组(ndarray)

13. transforms.Compose()

torchvision.transforms是pytorch中的图像预处理包。一般用Compose把多个步骤整合到一起。

Resize:把给定的图片resize到given size

RandomCrop((args.img_h, args.img_w)):对图片随机裁剪多大的尺寸

ToPILImage:将tensor或者ndarray的数据转换为 PIL Image 类型数据

ToTensor:把一个PIL图像或者numpy转化为一个tensor。通道数提前,值为[0,255]的图像(HxWxC)变成一个在[0,1]的tensor(CxHxW)

Normalize:使用均值和标准差来归一化tensor。对数据按通道进行标准化(注意是HxWxC),即先减均值,再除以标准差。

RandomHorizontalFlip:以0.5的概率水平翻转给定的PIL图像

RandomVerticalFlip:以0.5的概率竖直翻转给定的PIL图像

RandomResizedCrop:将PIL图像裁剪成任意大小和纵横比

Grayscale:将图像转换为灰度图像

RandomGrayscale:将图像以一定的概率转换为灰度图像

Pad(padding, fill=0):对图像进行填充。padding参数是设置图像周围填充多少个行或列。 当为2时,图像上下左右均填充2行。fill表示填充的值是什么。

14. nn.MarginRankingLoss()

在这里插入图片描述
输入的y只能有两个取值,也就是1或者-1。当y=1的时候,表示我们预期x1的排名要比x2高。反之,期望表示x2排名要比x1高。

15. tensor.expand( )

其将单个维度扩大成更大维度,返回一个新的tensor。

>>> import torch
>>> a=torch.tensor([[2],[3],[4]])
>>> print(a.size())
torch.Size([3, 1])
>>> a.expand(3,2)
tensor([[2, 2],
    [3, 3],
    [4, 4]])
>>> a
tensor([[2],
    [3],
    [4]])
    
由此得出结论,a通过expand()函数扩展某一维度后自身不会发生变化

16. torch.sum(dim, keepdim=True)

对输入的tensor数据的某一维度dim求和。dim:要求和的维度;keepdim:求和之后这个dim的元素个数为1,所以要被去掉,如果要保留这个维度,则应当keepdim=True。

17. with torch.no_grad():

在使用pytorch时,并不是所有的操作都需要进行计算图的生成(构建计算过程,以便梯度反向传播等操作)。而对于tensor的计算操作,默认是要进行计算图的构建的,在这种情况下,如果想强制之后的内容不进行计算图构建,可以使用 with torch.no_grad()。不使用该语句,输出结果最后会显示grad_fn=<AddmmBackward>,表示计算的结果在一个计算图当中,可以进行梯度反传等操作。

18. PyTorch中的ModuleList和Sequential

简介

nn.Sequential里面的模块按照顺序进行排列的,所以必须确保前一个模块的输出大小和下一个模块的输入大小是一致的。

nn.ModuleList,它是一个储存不同 module,并自动将每个 module 的 parameters 添加到网络之中的容器。你可以把任意 nn.Module 的子类 (比如 nn.Conv2d, nn.Linear 之类的) 加到这个 list 里面,但不同于一般的 list。

使用 Python 的 list 添加的卷积层和它们的 parameters并没有自动注册到我们的网络中,如果用其实例化的网络进行训练的时候,因为这些层的parameters不在整个网络之中,所以其网络参数也不会被更新,也就是无法训练。

区别

(1)nn.Sequential内部实现了forward函数,因此可以不用写forward函数。而nn.ModuleList则没有实现内部forward函数。

(2)nn.Sequential里面的模块按照顺序进行排列的,所以必须确保前一个模块的输出大小和下一个模块的输入大小是一致的。而nn.ModuleList 并没有定义一个网络,它只是将不同的模块储存在一起,网络的执行顺序是根据 forward 函数来决定的。

(3)有的时候网络中有很多相似或者重复的层,考虑用 for 循环来创建它们,而不是一行一行地写。那么这里我们使用ModuleList。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值