pytorch知识整理

1.torch.device()

torch.device()主要作用是:在训练时指定使用GPU训练还是CPU训练。

使用方法:

# cuda:0  代表第几块GPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

2.nn.ModuleList()

nn.ModuleList()主要作用:我们可以把任意 nn.Module 的子类加到这个 list 里面,方法同 Python 自带的 list 一样,例如说extend,append操作。但不同是,加入到 nn.ModuleList 里面的 module 是会注册到整个网络上的,所有 nn.ModuleList 内部的 nn.Module 的 parameter 也被添加作为我们的网络的parameter。我们构建两个全连接层做一下测试:我们可以看到权重 (weithgs) 和偏置 (bias) 都在这个网络之内。

import torch.nn as nn

class test1_net(nn.Module):
    def __init__(self):
        super(test1_net, self).__init__()
        self.linears = nn.ModuleList([nn.Linear(5,5) for i in range(2)])
    def forward(self, x):
        for m in self.linears:
            x = m(x)
        return x

net1 = test1_net()
print(net1)
'''
test1_net(
  (linears): ModuleList(
    (0): Linear(in_features=5, out_features=5, bias=True)
    (1): Linear(in_features=5, out_features=5, bias=True)
  )
)
'''

for param in net1.parameters():
    print(type(param.data), param.size())
'''
<class 'torch.Tensor'> torch.Size([5, 5])
<class 'torch.Tensor'> torch.Size([5])
<class 'torch.Tensor'> torch.Size([5, 5])
<class 'torch.Tensor'> torch.Size([5])
'''

更加详细参考链接:https://blog.csdn.net/byron123456sfsfsfa/article/details/89930990

3.nn.Linear()

原理:全连接层的主要作用就是将前层(卷积、池化等层)计算得到的特征空间映射样本标记空间。简单的说就是将特征表示整合成一个值,其优点在于减少特征位置对于分类结果的影响,提高了整个网络的鲁棒性,鲁棒性即在一定的参数摄动下,维持它某些性能的特性。nn.Linear表示的是线性变换,原型数学里学到的线性函数:y=kx+b

在深度学习中,变量都是多维张量,乘法就是矩阵乘法,加法就是矩阵加法,因此nn.Linear()运行的真正的计算就是:output = weight @ input + bias
例子:建立一个Linear对象,其输入特征维度为3,输出维度为4。数据随机生成,weight和bias可以查看数据,weight的维度为4行3列,bias的维度是一维的,为4. 可以方便做广播操作

import torch.nn as nn
linear1 = nn.Linear(3, 4, bias=True)
print(linear1.weight)
'''
Parameter containing:
tensor([[ 0.0052, -0.0102, -0.5492],
        [ 0.0983,  0.1518,  0.2995],
        [ 0.5446,  0.2422, -0.1529],
        [ 0.0202, -0.4722, -0.1320]], requires_grad=True)
'''
print(linear1.bias)
'''
Parameter containing:
tensor([-0.4863,  0.1122,  0.1602,  0.3065], requires_grad=True)
'''
# 计算
import torch
x = torch.randn((2,3))
y1 = linear1(x)
print(y1.shape)
print(y1)
'''
torch.Size([2, 4])
tensor([[ 0.1484,  0.0809, -0.0806, -0.5291],
        [ 1.6042, -0.7190, -0.8004,  1.0664]], grad_fn=<AddmmBackward0>)
'''

更加详细链接:Pytorch nn.Linear的基本用法_iioSnail的博客-CSDN博客

4.nn.Parameter()

作用:Parameter:参数。在做神经网络的训练时,其实就是训练一个模型,这个模型就是去学习一个函数,这个函数可以准确的学习到我们想要到的东西,比如正确的对物体进行分类。函数的输入就是模型的输入:一张图像,得到的模型输出就是一个预测值。在我看的一篇论文Meshed-Memory Transformer for Image Captioning当中,是这样解释的当我们处理图像时,区域之间的关系建立先验知识的模型。例如,给定一个编码人的区域和一个编码篮球的区域,在没有任何先验知识的情况下很难推断球员或比赛的概念。同样,考虑到鸡蛋和烤面包的编码区域,使用关系的先验知识可以很容易地推断出图片描述了早餐的知识。而这个先验知识就是通过nn.parameter建立的。

论文中样例:

self.m_k = nn.Parameter(torch.FloatTensor(1, m, h * d_k)) # (1, 40, 8 * 64)
self.m_v = nn.Parameter(torch.FloatTensor(1, m, h * d_v)) # (1, 40, 8 * 64)
更加详细链接:Pytorch中nn.Parameter()参数的使用_每天都想要出去玩鸭~的博客-CSDN博客

 5.nn.init.xavier_uniform_()

作用:初始化,使用均匀分布 用值填充输入张量,预防一些参数过大或过小的情况,再保证方差一样的情况下进行缩放,便于计算。

import torch.nn as nn
linear1 = nn.Linear(2, 3, bias=True)
print(linear1.weight)
xu = nn.init.xavier_uniform_(linear1.weight)
print(linear1)
print(xu)
'''Parameter containing:
tensor([[-0.1114, -0.3342],
        [ 0.0629,  0.3060],
        [-0.4445, -0.4200]], requires_grad=True)
Linear(in_features=2, out_features=3, bias=True)
Parameter containing:
tensor([[-0.7165, -0.0940],
        [ 0.0299,  0.4402],
        [ 0.4945, -0.3356]], requires_grad=True)'''

6.nn.init.normal_()、nn.init.constant_()

 作用:初始化,nn.init.normal_ : 按正态分布对tensor随机赋值。nn.init.constant_ : 使用常数val对tensor赋值。用法同上。

初始化的一些用法Pytorch nn.init 参数初始化方法_Vic_Hao的博客-CSDN博客_nn.init.calculate_gain

7.nn.Dropout()

作用:为了防止或减轻过拟合,一般用在全连接层Dropout就是在不同的训练过程中随机扔掉一部分神经元。也就是让某个神经元的激活值以一定的概率p,让其停止工作,训练过程中不更新权值,也不参加神经网络的计算。但是它的权重得保留下来(只是暂时不更新而已),因为下次样本输入时它可能又得工作了。

用法:

import torch
x = torch.randn(3, 4)
dropout = nn.Dropout(p=0.2) 
x_drop = dropout(x)
print(x)
print(x_drop)
'''tensor([[-1.5766, -0.5238,  0.5143, -0.0836],
        [-3.1830, -0.7626,  0.5806, -0.0129],
        [-0.7500, -0.3818,  1.5403,  0.4114]])
tensor([[-1.9707, -0.6548,  0.6429, -0.0000],
        [-3.9787, -0.0000,  0.7257, -0.0162],
        [-0.0000, -0.4773,  1.9254,  0.5142]])'''

更加详细链接:pytorch中nn.Dropout的使用技巧_木盏的博客-CSDN博客_nn.dropout pytorch
 

 8.nn.LayerNorm()

原理:LayerNorm是归一化的一种方法,与BatchNorm不同的是它是对每单个batch进行的归一化,而BatchNorm(BN)是对所有Batch一起进行归一化。

注意:我们的输入是(1, 3, 4, 4),如果要完成LayerNorm(LN),我们只需要提供一个参数,即norm = nn.LayerNorm(3),但是如果只提供一个参数,默认为对最后一维进行归一化,所以我们需要将输入进行变化,即变为(1, 4, 4, 3)。样例如下

import torch
import torch.nn as nn
x = torch.randn([1, 3, 4, 4])
x = x.permute(0,2,3,1)
ln = nn.LayerNorm(3)
print(ln(x).permute(0,3,1,2))
'''tensor([[[[-0.1889, -0.5626,  1.0711,  0.9577],
          [ 1.2075,  1.0102, -0.2517, -1.0269],
          [-1.1925, -0.9310,  1.4074,  0.9917],
          [ 0.1890,  0.2050, -0.8575,  0.2097]],

         [[ 1.3082, -0.8423, -1.3351,  0.4223],
          [-1.2413, -1.3622, -1.0794, -0.3287],
          [-0.0621, -0.4564, -0.8236, -1.3690],
          [ 1.1192,  1.1093,  1.4026, -1.3160]],

         [[-1.1193,  1.4049,  0.2640, -1.3800],
          [ 0.0339,  0.3520,  1.3310,  1.3555],
          [ 1.2546,  1.3874, -0.5839,  0.3772],
          [-1.3083, -1.3143, -0.5451,  1.1063]]]], grad_fn=<PermuteBackward0>)'''

详细链接如下:nn.LayerNorm的实现及原理_harry_tea的博客-CSDN博客_layernorm

 9.nn.Embedding()

原理:nn.Embedding()主要适用在NLP中进行语言编码,我们在处理语言数据时,通常会把单词进行一个编号比如:a:1,而我们就会对这些单词进行一个编码,通常会使用这种方式,这里填一下one-hot编码,我们并不会使用这种,因为这种编码方式会使得单词编码后过于稀疏,很难构成之间的语义关系,因此我们会使用enbedding这种方式。

注意:这里参数10,为编码的单词共有多少个,单词只有在编号里才能进行编码,每一行都是进行单词编号后的一个稠密矩阵形式,可以看到编号为2的编码是相同的。代码如下:

import torch
import torch.nn as nn
embedding = nn.Embedding(10,4)
x = torch.LongTensor([[1,2,3],
                     [4,2,6]])
print(embedding(x))
'''tensor([[[-0.9006,  0.7501,  0.3422, -1.6497],
         [-0.3167,  0.7401, -1.4557,  2.2191],
         [ 0.2161,  0.2541, -0.3091,  1.0904]],

        [[-0.4814,  0.6302, -0.8751,  0.2819],
         [-0.3167,  0.7401, -1.4557,  2.2191],
         [-1.2459, -0.3328, -0.9408,  1.8342]]], grad_fn=<EmbeddingBackward0>)'''

更加详细链接:通俗讲解pytorch中nn.Embedding原理及使用_taoqick的博客-CSDN博客

10. nn.Embedding.from_pretrained()

原理:加载预训练好的词向量,我们在进行具体NLP任务时,一般通过对应的上面说得Embedding层做词向量的处理,再拿词向量去进行下游的处理,比如分类,但我们可以使用预训练好的词向量,会带来更优的性能。

样例如下:

import torch
import torch.nn as nn
weight = torch.FloatTensor([[1,2.3,3],
                     [4.1,5.3,6.2]])
embedding = nn.Embedding.from_pretrained(weight)
input = torch.LongTensor([0])
print(embedding(input))
# tensor([[1.0000, 2.3000, 3.0000]])

11.torch基础知识汇总

(1)torch.arange()

原理:输出一个Tensor类型的张量

用法:下面三个参数是开始,结尾以及步长参数,左闭右开形式。

import torch
torch.arange(1,5,2)
tensor([1, 3])
torch.arange(1,5,0.5)
tensor([1.0000, 1.5000, 2.0000, 2.5000, 3.0000, 3.5000, 4.0000, 4.5000])

更加详细链接:Torch.arange函数详解__湘江夜话_的博客-CSDN博客_torch.arange()

 (2)torch.sin()、torch.cos()

原理:对张量进行正弦余弦计算。

用法:

input = torch.arange(10)
input
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
input = input.view(1,-1)
input
tensor([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
sin = torch.sin(input)
sin
tensor([[ 0.0000,  0.8415,  0.9093,  0.1411, -0.7568, -0.9589, -0.2794,  0.6570,
          0.9894,  0.4121]])
cos = torch.cos(input)
cos
tensor([[ 1.0000,  0.5403, -0.4161, -0.9900, -0.6536,  0.2837,  0.9602,  0.7539,
         -0.1455, -0.9111]])

(3)torch.zeros()

原理:返回一个全为零的张量。

用法:

zeros = torch.zeros([3,4])
zeros
tensor([[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]])

(4)torch.sum()

原理:对输入的tensor数据的某一维度求和。

用法:

import torch
'''
1.torch.sum(input, dtype=None)
2.torch.sum(input, list: dim, bool: keepdim=False, dtype=None) → Tensor
 
input:输入一个tensor
dim:要求和的维度,可以是一个列表
keepdim:求和之后这个dim的元素个数为1,所以要被去掉,如果要保留这个维度,则应当keepdim=True
#If keepdim is True, the output tensor is of the same size as input except in the dimension(s) dim where it is of size 1. 
'''
sum = torch.ones(2,2,3)
s1 = torch.sum(sum,dim=0)
s2 = torch.sum(sum,dim=1)
s3 = torch.sum(sum,dim=-1)
print(sum)
print(s1)
print(s2)
print(s3)
'''
tensor([[[1., 1., 1.],
         [1., 1., 1.]],

        [[1., 1., 1.],
         [1., 1., 1.]]])
tensor([[2., 2., 2.],
        [2., 2., 2.]])
tensor([[2., 2., 2.],
        [2., 2., 2.]])
tensor([[3., 3.],
        [3., 3.]])'''

(5)torch.cat()

原理:将两个向量拼接在一起。

用法:

import torch
cat1 = torch.ones(2,3)
cat2 = torch.zeros(3,3)
cat3 = torch.randint(0,10,[2,4])
c1 = torch.cat((cat1,cat2),0) # 0按行拼接
c2 = torch.cat([cat1,cat3],1) # 1按列拼接
print(cat1)
print(cat2)
print(cat3)
print(c1)
print(c2)
'''tensor([[1., 1., 1.],
        [1., 1., 1.]])
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])
tensor([[2, 5, 8, 9],
        [0, 5, 4, 3]])
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])
tensor([[1., 1., 1., 2., 5., 8., 9.],
        [1., 1., 1., 0., 5., 4., 3.]])'''

(6)torch.matmul()

原理:两个张量矩阵相乘。

用法:

import torch
m1 = torch.ones(size=(2,3),dtype=torch.int64)
m2 = torch.randint(0,10,[3,4])
m = torch.matmul(m1,m2)
print(m1)
print(m2)
print(m)
'''
tensor([[1, 1, 1],
        [1, 1, 1]])
tensor([[7, 9, 3, 8],
        [6, 3, 8, 6],
        [6, 5, 3, 8]])
tensor([[19, 17, 14, 22],
        [19, 17, 14, 22]])
'''

(7)torch.softmax()

原理:非负性和归一化处理,把数据规整到0-1之间。

用法:

import torch
s1 = torch.randn([2,3])
s = torch.softmax(s1,-1)
print(s1)
print(s)
'''
tensor([[ 1.0598, -0.5518, -0.6113],
        [ 1.1284,  1.5232,  1.0603]])
tensor([[0.4828, 0.1115, 0.1582],
        [0.5172, 0.8884, 0.8418]])
'''

(8)expand()

原理:其将单个维度扩大成更大维度,从而返回一个新的tensor。

用法:

import torch
e1 = torch.rand([1,2,3])
ex = e1.expand(5,2,3)
print(e1)
print(ex)
'''
tensor([[[0.5190, 0.0167, 0.1989],
         [0.9708, 0.1636, 0.2861]]])
tensor([[[0.5190, 0.0167, 0.1989],
         [0.9708, 0.1636, 0.2861]],

        [[0.5190, 0.0167, 0.1989],
         [0.9708, 0.1636, 0.2861]],

        [[0.5190, 0.0167, 0.1989],
         [0.9708, 0.1636, 0.2861]],

        [[0.5190, 0.0167, 0.1989],
         [0.9708, 0.1636, 0.2861]],

        [[0.5190, 0.0167, 0.1989],
         [0.9708, 0.1636, 0.2861]]])
'''

(9)view()

原理:将张量转换为指定的形状,原始的数据不改变。

用法:

import torch
v1 = torch.rand([10,20,30])
v = v1.view(10,4,5,30)
print(v1.shape)
print(v.shape)
'''
torch.Size([10, 20, 30])
torch.Size([10, 4, 5, 30])'''

(10)permute()

原理:进行多个维度的交换或者可以成为维度重新排列。

用法:

import torch
v1 = torch.rand([10,20,30])
v = v1.view(10,4,5,30)
p = v.permute(0,2,1,3)
print(v1.shape)
print(v.shape)
print(p.shape)
'''
torch.Size([10, 20, 30])
torch.Size([10, 4, 5, 30])
torch.Size([10, 5, 4, 30])
'''

(11)contiguous()

原理:断开两个变量之间的依赖,类似于深拷贝。当调用contiguous()时,会强制拷贝一份tensor,让它的布局和原先创建的一模一样,但是两个tensor完全没有联系。

用法:

import torch
x = torch.randint(1,10,[2,3])
y = torch.transpose(x, 0, 1).contiguous()
print('修改前:')
print(x)
print(y)
y[0,0] = 20
print('修改后:')
print(x)
print(y)
'''
修改前:
tensor([[1, 1, 2],
        [6, 7, 9]])
tensor([[1, 6],
        [1, 7],
        [2, 9]])
修改后:
tensor([[1, 1, 2],
        [6, 7, 9]])
tensor([[20,  6],
        [ 1,  7],
        [ 2,  9]])
'''

(12)masked_fill()

原理:主要用在transformer的attention机制中,在时序任务中,主要是用来mask掉当前时刻后面时刻的序列信息。此时的mask主要实现时序上的mask。注意:mask与需要进行mask的数据张量可以进行广播机制才可以mask掉信息,可以多加尝试,就能理解,

UserWarning: masked_fill_ received a mask with dtype torch.uint8, this behavior is now deprecated,please use a mask with dtype torch.bool instead. (Triggered internally at  ..\aten\src\ATen\native\TensorAdvancedIndexing.cpp:1273.)
  y = x.masked_fill(mask,-1e9)在这种警告下,只需要把mask改为mask.bool()即可。

用法:

import torch
x = torch.randn([2,3,3,3])
mask = torch.ByteTensor([[[[1,1,0]]],[[[1,0,1]]]])
print(mask.shape)
y = x.masked_fill(mask,-1e9)
print(x)
print(y)
'''
torch.Size([2, 1, 1, 3])
tensor([[[[ 1.3619, -0.4189, -0.1962],
          [-0.1894,  0.7659, -0.0566],
          [-0.0452, -0.1162,  2.3200]],

         [[ 0.4708, -0.1103, -0.3525],
          [ 1.3103, -1.0162, -0.5674],
          [-0.2876,  0.8353,  0.3060]],

         [[ 0.9054, -0.3159, -0.0910],
          [-0.4321, -1.0281,  1.1053],
          [ 1.3831, -0.6604,  0.0584]]],


        [[[-0.0300, -0.5480,  1.1722],
          [ 1.3205, -0.4150, -0.0274],
          [-1.3144, -1.1835, -0.5252]],

         [[-0.8591, -0.7441, -0.1815],
          [-1.4285, -1.1140, -1.6022],
          [ 0.2987,  1.0611,  0.6514]],

         [[-0.9407,  0.9054,  0.1344],
          [ 1.0765,  0.4661,  0.3070],
          [ 0.6302,  0.7232,  0.9769]]]])
tensor([[[[-1.0000e+09, -1.0000e+09, -1.9618e-01],
          [-1.0000e+09, -1.0000e+09, -5.6642e-02],
          [-1.0000e+09, -1.0000e+09,  2.3200e+00]],

         [[-1.0000e+09, -1.0000e+09, -3.5254e-01],
          [-1.0000e+09, -1.0000e+09, -5.6742e-01],
          [-1.0000e+09, -1.0000e+09,  3.0595e-01]],

         [[-1.0000e+09, -1.0000e+09, -9.1025e-02],
          [-1.0000e+09, -1.0000e+09,  1.1053e+00],
          [-1.0000e+09, -1.0000e+09,  5.8403e-02]]],


        [[[-1.0000e+09, -5.4799e-01, -1.0000e+09],
          [-1.0000e+09, -4.1496e-01, -1.0000e+09],
          [-1.0000e+09, -1.1835e+00, -1.0000e+09]],

         [[-1.0000e+09, -7.4409e-01, -1.0000e+09],
          [-1.0000e+09, -1.1140e+00, -1.0000e+09],
          [-1.0000e+09,  1.0611e+00, -1.0000e+09]],

         [[-1.0000e+09,  9.0543e-01, -1.0000e+09],
          [-1.0000e+09,  4.6610e-01, -1.0000e+09],
          [-1.0000e+09,  7.2317e-01, -1.0000e+09]]]])
'''

(13)unsqueeze()、squeeze()

原理:unsqueeze()添加维度,squeeze()则相反,里面参数则是为第几维添加维度。squeeze()智能为维度为1的矩阵压缩维度。里面不需要添加任何参数。

用法:

import torch
x = torch.randn([2,3])
x_un = x.unsqueeze(1).unsqueeze(1)
print(x_un.shape)
x = x.squeeze()
print(x.shape)
'''
torch.Size([2, 1, 1, 3])
torch.Size([2, 3])
'''

(14)torch.triu()

原理:返回矩阵上三角部分,其余部分全是0。第一个参数为矩阵形式,第二个参数为diagonal,默认为0。

如果diagonal为空或者0,输入矩阵保留主对角线与主对角线以上的元素;
如果diagonal为正数n,输入矩阵保留主对角线与主对角线以上除去n行的元素;
如果diagonal为负数-n,输入矩阵保留主对角线与主对角线以上与主对角线下方h行对角线的元素;

用法:

import torch
t = torch.ones([3,3])
t
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
torch.triu(t,1)
tensor([[0., 1., 1.],
        [0., 0., 1.],
        [0., 0., 0.]])
torch.triu(t,-1)
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [0., 1., 1.]])
torch.triu(t,0)
tensor([[1., 1., 1.],
        [0., 1., 1.],
        [0., 0., 1.]])

(15)torch.mean()

原理:对张量Tensor取均值。

用法:

import torch
x = torch.randint(1,10,[2,2,3],dtype=torch.float64)
print(x)
mean = torch.mean(x) # 不指定维度,对所有元素做均值
print(mean)
mean = torch.mean(x,dim=1) # 指定维度做平均值
print(mean)
'''
tensor([[[9., 2., 7.],
         [7., 6., 9.]],

        [[6., 9., 5.],
         [8., 8., 7.]]], dtype=torch.float64)
tensor(6.9167, dtype=torch.float64)
tensor([[8.0000, 4.0000, 8.0000],
        [7.0000, 8.5000, 6.0000]], dtype=torch.float64)
'''

(16)torch.from_numpy()

原理:把数组转换成一个张量。

用法:

import numpy as np
import torch
x = np.random.randint(1,10,[3,4])
print(type(x))
y = torch.from_numpy(x)
print(type(y))
'''
<class 'numpy.ndarray'>
<class 'torch.Tensor'>
'''

持续更新中!!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值