torch.mul(a, b) 是矩阵a和b对应位相乘,即点乘,纬度不同时会触发broadcast机制;
torch.mm(a, b) 是矩阵相乘,a的列数必须等于b的行数,但当torch.mm用于大于二维矩阵时将报错。;
torch.matmul(a, b) 也是矩阵相乘,也可用于高纬矩阵相乘,可理解为比torch.mm() 强大一些。
torch.utils.data.TensorDataset(data_tensor, target_tensor)
#用于包装数据和标签张量的数据集
data_tensor (Tensor) - 包含样本数据
target_tensor (Tensor) - 包含样本目标(标签)
torch.utils.data.DataLoader(dataset, batch_size, shuffle, num_workers)
#用于随机读取小批量数据
dataset - 待加载的数据
batch_size - 小批量数据数目(default = 1)
shuffle - bool型,当为True时,每个epoch遍历数据时会打乱数据集顺序
num_workers - 进程数,可使用多进程来加速数据读取
#用于初始化模型参数,如权重W和偏差b
init.normal_(net[0].weight, mean = 0, std = 0.01) #正态分布
init.constant_(net[0].bias, val = 0) #也可以直接修改bias的data: net[0].bias.data.fill_(0)
#使用sequential搭建网络,sequential是一个有序的容器,网络层将按照在传入sequential的顺序依次被添加到计算图中
#方法一:
net = torch.nn.Sequential(
torch.nn.Linear(num_inputs, 1)
#还可以继续添加网络层
)
#方法二:
net = torch.nn.Sequential()
net.add_module('linear', torch.nn.Linear(num_inputs, 1))
#可以继续net.add_module()
# 方法三
from collections import OrderedDict #有序字典
net = nn.Sequential(OrderedDict([
('linear', torch.nn.Linear(num_inputs, 1))
# ......
]))
#可以用过net.parameters()来得到模型的所有可学习参数
for param in net.parameters():
print(param)
输出为:
Parameter containing:
tensor([[ 0.4563, -0.2125]], requires_grad=True)
Parameter containing:
tensor([-0.4482], requires_grad=True)
通常在定义完模型后利用以下来初始化模型参数:
for param in net.parameters():
nn.init.normal_(param, mean=0,std=0.01)
#在torch里面,view函数相当于numpy的reshape
output = output.view(-1,1)
# -1表示一个不确定的数,表示不确定要reshape成几行,但是肯定要reshape成1列
# 一般样本数m的位置用-1代替,即不必确定有多少个样本
str.startswith(str, beg=0,end=len(string));方法用于检查字符串是否是以指定子字符串开头
如果是则返回 True,否则返回 False。
str -- 检测的字符串。
strbeg -- 可选参数用于设置字符串检测的起始位置。
strend -- 可选参数用于设置字符串检测的结束位置。
sys.platform用于判断操作系统类型,有'win32'、 'linux2'
# 用于设置训练模型的线程数
num_workers = 0 if sys.platform.startwith('win32') else 4
通过W.requires_grad_(requires_grad=True)来用in-place的方式改变requires_grad属性
如果将其属性.requires_grad设置为True,它将开始追踪在其上的所有操作(这样就可以利用链式法则进行梯度传播了)。
缺失情况下默认 requires_grad = False
#用来收集输入的特定维度指定位置的数值
input(tensor) - 待操作数
dim(int) - 待操作的维度
index(LongTensor) - 待获取input中数据的位置索引
out- 输出和index的维度是一致的
#super()用于继承父类的一些函数
首先找到LinearNet的父类(nn.Module),然后把类LinearNet的对象self转换为类Module的对象,然后“被转换”的类Module对象调用自己的__init__函数
#用于将Tensor()从计算图中分离
tensor.detach()返回一个新的tensor,从当前计算图中分离下来的,将tensor的requires_grad改为false,得到的这个tensor永远不需要计算其梯度,不具有grad。
注意:即使之后重新将它的requires_grad置为true,它也不会具有梯度grad
tensor.detach_()将一个tensor从创建它的图中分离,并把它设置成叶子tensor
其实就相当于变量之间的关系本来是x -> m -> y,这里的叶子tensor是x,但是这个时候对m进行了m.detach_()操作,其实就是进行了两个操作:
1. 将m的grad_fn的值设置为None,这样m就不会再与前一个节点x关联,这里的关系就会变成x, m -> y,此时的m就变成了叶子结点
2. 然后会将m的requires_grad设置为False,这样对y进行backward()时就不会求m的梯度
总结:其实detach()和detach_()很像,两个的区别就是detach_()是对本身的更改,detach()则是生成了一个新的tensor
比如x -> m -> y中如果对m进行detach(),后面如果反悔想还是对原来的计算图进行操作还是可以的;
但是如果是进行了detach_(),那么原来的计算图也发生了变化,就不能反悔了。
#用于生成一个范围序列
torch.range(start=1, end=6) 的结果是会包含end,且其类型默认为torch.float32;
torch.arange(start=1, end=6)的结果并不包含end,且其类型默认为torch.int64
#用于清空tensor变量之前保存的梯度
调用backward()函数之前都要将梯度清零,因为如果梯度不清零,pytorch中会将上次计算的梯度和本次计算的梯度累加。
这样逻辑的好处是,当我们的硬件限制不能使用更大的bachsize时,使用多次计算较小的bachsize的梯度平均值来代替;坏处当然是每次都要清零梯度。
使用优化器时,用函数optimizer.zero_grad()梯度清零。
# PyTorch提供的包括softmax运算和交叉熵损失计算的函数,相比于自行分步实现的softmax和交叉熵
# 损失函数,它具有更好的数值稳定性。
标准正态分布: torch.randn(sizes, out=None) → Tensor
[0,1)之间的均匀分布: torch.rand(sizes, out=None) → Tensor
离散正态分布: torch.normal(means, std, out=None) → Tensor
线性间距向量: torch.linspace(start, end, steps=100, out=None) → Tensor
cat是concatnate的意思,即连在一起的、连锁的;
该函数将两个张量x, y 拼接在一起,dim =0指按行拼接;dim=1指按列拼接;dim=2指数据整体拼接,与拼接之前的维度保持相同;dim=-1指每个最内部的子列表直接相连。
# 可理解为dim是几,则按第几维进行连结。
PyTorch的nn.Linear()是用于设置网络中的线性全连接层的,需全连接层的输入与输出都是二维张量,一般形状为[batch_size, size];
in_features - 输入神经元结点的个数:即输入的[batch_size, size]中的size;
out_features - 输出全连接层的神经元个数,即输出的二维张量的形状为[batch_size,output_size];
从输入输出的张量的shape角度来理解,相当于一个输入为[batch_size, in_features]的张量变换成了[batch_size, out_features]的输出张量。
loss的x, y 的维度是一样的,可以是向量或者矩阵,i 是下标;
一般损失函数都是直接计算 batch 的数据,因此返回的 loss 结果都是维度为 (batch_size, ) 的向量;
(1)如果 reduce = False,那么 size_average 参数失效,直接返回向量形式的 loss
(2)如果 reduce = True,那么 loss 返回的是标量
a)如果 size_average = True,返回 loss.mean();
b)如果 size_average = False,返回 loss.sum();
将tensor用从均匀分布中抽样得到的值进行填充
# 读写tensor
torch.save(x, 'x.pt')
torch.load('x.pt')
# 读写模型
net.state_dict()返回模型所有可训练参数;
state_dict是一个从参数名称隐射到参数Tesnor的字典对象;
只有具有可学习参数的层(卷积层、线性层等)才有state_dict中的条目;
优化器(optim)也有一个state_dict,其中包含关于优化器状态以及所使用的超参数的信息。
PyTorch中保存和加载训练模型有两种常见的方法:
1. 仅保存和加载模型参数(state_dict);
2. 保存和加载整个模型。
方法一:保存和加载state_dict(推荐方式)
保存:torch.save(model.state_dict(), PATH) # 推荐的文件后缀名是pt或pth
加载:model = TheModelClass(*args, **kwargs) # 给定一个模型
model.load_state_dict(torch.load(PATH))
方法二:保存和加载整个模型
保存:torch.save(model, PATH)
加载:torch.load(PATH)
d=torch.stack(list,dim=n), list= [a,b,c]
list 中的每个元素为tensor,输出d的类型也是tensor
因为是按照dim进行list中所有元素叠加,则d的dim轴就有len(list)个元素。
F.avg_pool1d(input, kenerl_size)
input维度 - (batch_size,channels,width)三维输入,channel可以看成高度
kenerl_size - 一维:表示width的跨度 eg. kenerl_size=3
假设kernel_size=2,则每俩列相加求平均,stride默认和kernel_size保持一致,越界则丢弃;
F.avg_pool2d(input, kenerl_size)
input维度 -(batch_size, channels, height, width)四维输入
kenerl_size - 二维:表示width的跨度,channel和输入的channle一致;
如果数据是三维,则channel为1.(如果只写一个数n,kenerl=(n,n))
stride默认和kenerl一致,这是个二维的,所以在height和width上均和kenerl一致,越界同样丢弃。
# argmax(dim)得到最大值的序号索引
对于一个维度为(d_0, d_1)的矩阵来说,我们想要求每一行中最大数的在该行中的列号索引,最后得到的就是一个维度为(d_0, 1)的矩阵。可以看到列数d_1消失了。
举个例子:
a= tensor([[0.8338, 0.6953, 0.7558, 0.5803],
[0.2105, 0.7638, 0.0912, 0.3341],
[0.5585, 0.8019, 0.6590, 0.2268]])
b = torch.argmax(a, dim=1)
print(b)
print(b.size())
tensor([0, 1, 1]) # 表示a中每一行中最大数对应的索引
torch.Size([3]) # 可以看到a的列数消失了
# output = torch.max(input, dim)
input - 输入一个tensor
dim - max函数索引的维度0/1,dim=0是每列的最大值,dim=1是每行的最大值
函数会返回两个tensor:第一个tensor是每行的最大值;第二个tensor是每行最大值的索引。
unsqueeze(arg):增添第arg个维度为1,以插入的形式填充;
squeeze(arg):删除第arg个维度(如果所指维度不为1,则不会进行删除)。
torch.randperm(n, out=None, dtype=torch.int64, layout=torch.strided, device=None, requires_grad=False)
y = torch.randperm(n)
y是把1到n这些数随机打乱得到的一个数字序列。
expand()返回当前张量在某维扩展更大后的张量。扩展(expand)张量不会分配新的内存,只是在存在的张量上创建一个新的视图(view),将大小等于1的维度扩展到更大的尺寸。
>> x = torch.tensor([1, 2, 3])
>> x.expand(2, 3)
tensor([[1, 2, 3],
[1, 2, 3]])
>> x = torch.randn(2, 1, 1, 4)
>> x.expand(-1, 2, 3, -1)
torch.Size([2, 2, 3, 4])
repeat()沿着特定的维度重复这个张量,与expand()不同的是,这个函数拷贝张量的数据。
>> x = torch.tensor([1, 2, 3])
>> x.repeat(3, 2)
tensor([[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3]])
>> x2 = torch.randn(2, 3, 4)
>> x2.repeat(2, 1, 3).shape
torch.Tensor([4, 3, 12])
torch.clamp(input, min, max, out=None) → Tensor
操作定义如下:
| min, if x_i < min
y_i = | x_i, if min <= x_i <= max
| max, if x_i > max
>>> a = torch.randint(1, 10, (1,10))
>>> print(a)
tensor([[9, 6, 7, 7, 3, 1, 4, 8, 1, 3]])
>>> a = torch.clamp(a, 4, 8)
>>> print(a)
tensor([[8, 6, 7, 7, 4, 4, 4, 8, 4, 4]])
permute(dims)用于将tensor的维度换位。
参数:参数是一系列的整数,代表原来张量的维度。比如三维就有0,1,2这些dimension。
>>> x = torch.randn(2, 3, 5)
>>> x.size()
torch.Size([2, 3, 5])
>>> x.permute(2, 0, 1).size()
torch.Size([5, 2, 3])
contiguous:view只能用在内存分布相邻的variable上,如果在view之前用了transpose, permute
等,需要用contiguous()
来返回一个contiguous copy。
一种可能的解释是:
有些tensor并不是占用一整块内存,而是由不同的数据块组成,而tensor的view()操作依赖于内存是整块的,这时只需要执行contiguous()
这个函数,把tensor变成在内存中连续分布的形式。
判断是否contiguous用torch.Tensor.is_contiguous()
函数。
import torch
x = torch.ones(10, 10)
x.is_contiguous() # True
x.transpose(0, 1).is_contiguous() # False
x.transpose(0, 1).contiguous().is_contiguous() # True
# 构建卷积层,kernel的尺寸也可为矩形eg.=(5, 3),padding = ((k_h - 1) / 2, (k_w - 1) / 2)
nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(5, 3), padding=(2, 1), stride=(2,1))
# 卷积核尺寸一般取奇数
# 卷积后的图片尺寸为: ((n + 2*p -f)/s +1)×((n + 2*p -f)/s +1) 小数均向下取整
# 池化层也可以在输入的高和宽两侧的填充并调整窗口的移动步幅来改变输出形状
# 默认情况下,MaxPool2d实例里步幅和池化窗口形状相同。
# 也可以指定非正方形的池化窗口,并分别指定高和宽上的填充和步幅:
nn.MaxPool2d((2, 4), padding=(1, 2), stride=(2, 3))
# nn模块中的Sigmoid激活函数
resize PIL图像(python中的标准图像类),如果size为一个sequence(h, w),则将图像resize成这个尺寸;
如果size为一个int值,则将短边resize成这个尺寸,长边安装对应比例进行缩放,比如 (size * height / width, size)。
interpolation 采用何种插值方法,默认为双线性。
#用Compose()把所有变形操作合并串联起来。
mytrans = torchvision.transforms.Compose(
transform1,
transform2,
...,
)
nn.BatchNorm1d(num_features)用于全连接层,参数为全连接层输出个数;
nn.BatchNorm2d(num_features)用于卷积层,参数为卷积层输出通道数;
torchvision的models包提供了常用的预训练模型。
如果希望获取更多的预训练模型,可以使用使用pretrained-models.pytorch仓库。
欢迎关注【OAOA】