栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

pytorch基础(一)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

pytorch基础(一)

pytorch中nn.Parameter()函数

torch.nn.Parameter继承torch.Tensor,其作用将一个不可训练的类型为Tensor的参数转化为可训练的类型为parameter的参数,并将这个参数绑定到module里面,成为module中可训练的参数。
torch.nn.Parameter(Tensor data, bool requires_grad)
其中:data为传入Tensor类型参数,requires_grad默认值为True,表示可训练,False表示不可训练。
pytorch中torch.ones()

torch.ones(*sizes, out=None) → Tensor

返回一个全为1 的张量,形状由可变参数sizes定义。

pytorch中sum()函数

x.sum(),第0个维度是行,第1个维度是列
说明文档中
torch.sum
在给定维度的情况下,返回每一行的和。
如果keepdim=True,那么输出和输出的形状是相同的,除了dim维度变为1
例子如下:
x是一个五行三列的tensor
对x的每一行进行求和,结果应该是五行一列,形状还是2个维度,所以keepdim=True,因为列变成了1,所以dim=1,合并起来:x.sum(dim=1,keepdim=True)
对每一列进行求和,输出的结果应该是一行三列,形状还是两个维度,keepdim=True,这里行变成了1,所以dim=0,合并起来:x.sum(dim=0,keepdim=True)

import torch
x = torch.rand(5,3)
print(x)
y1 = x.sum(dim=1, keepdim=True)
print(y1)
y2 = x.sum(dim=1)
print(y2)
y3 = x.sum(dim=0, keepdim=True)
print(y3)
y4 = x.sum(dim=0)
print(y4)
y5 = x.sum(dim=[0,1])
print(y5)

例如:

X = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(X.sum(dim=0, keepdim=True)) # dim为0,按照相同的列求和,并在结果中保留列特征
print(X.sum(dim=1, keepdim=True)) # dim为1,按照相同的行求和,并在结果中保留行特征
print(X.sum(dim=0, keepdim=False)) # dim为0,按照相同的列求和,不在结果中保留列特征
print(X.sum(dim=1, keepdim=False)) # dim为1,按照相同的行求和,不在结果中保留行特征

结果:

可以简化着来看,已经给定的张量为23
假设对张量的每一行进行求和,则求和后的张量应为21,所以dim=1表示第二个元素。
如果对张量的每一列进行求和,求和后的张量应该为1*3,所以dim=0表示第一个元素。
如果keepdim=True,则求和后的应该还是为张量,保留维度。

pytorch中pad_sequence函数

自动填充函数

import torch
from transformers import BertTokenizer
from torch.nn.utils.rnn import pad_sequence,pack_padded_sequence,pack_sequence,pad_packed_sequence
if __name__ == '__main__':
    texts = [
        "你好我是一个NLP工程师",
        "中国人",
        "我要好好工作努力挣钱买房买车",
        "你",
        "老婆老婆老婆我爱你"
    ]
    tokenizer = BertTokenizer.from_pretrained('pretrained_models/chinese-bert-wwm-ext')
 
    # datas = [ torch.tensor(tokenizer(text)['input_ids'],dtype=torch.long)  for text in texts]
    datas = [tokenizer(text)['input_ids'] for text in texts]
 
    for data in datas:
        print(data)
 
    datas = [torch.tensor(data,dtype=torch.long) for data in datas]
    print(datas)
    pad_datas = pad_sequence(datas,batch_first=True,padding_value=0)
    print(pad_datas.shape)
    print(pad_datas)


结果中长度效果16的,就自动的填充了0,使得pad_datas成为等长的,可以组成batch,输入到模型中进行并行计算。

pytorch中pack_padded_sequence()函数

对经过padded_sequence进行压缩。经过padding后的tensor会含有很多无意义的padding_value,它对模型的效果最终有一定的影响,为了完全消除这个影响,就需要把这些无意义的padding_value进行压缩。
例子:

if __name__ == '__main__':
    texts = [
        "你好我是一个NLP工程师",
        "中国人",
        "我要好好工作努力挣钱买房买车",
        "你",
        "老婆老婆老婆我爱你"
    ]
    tokenizer = BertTokenizer.from_pretrained('pretrained_models/chinese-bert-wwm-ext')
 
    # datas = [ torch.tensor(tokenizer(text)['input_ids'],dtype=torch.long)  for text in texts]
    datas = [tokenizer(text)['input_ids'] for text in texts]
 
    lengths = [ len(data) for data in datas]
 
 
    for data in datas:
        print(data)
 
    datas = [torch.tensor(data,dtype=torch.long) for data in datas]
    print('datas',datas)
    pad_datas = pad_sequence(datas,batch_first=True,padding_value=0)
    print('pad_datas.shape',pad_datas.shape)
    print('pad_datas',pad_datas)
 
    pack_pad_datas = pack_padded_sequence(input=pad_datas,lengths = lengths ,batch_first=True, enforce_sorted=False)
    print('pack_pad_datas',pack_pad_datas)

结果:

pack_pad_datas PackedSequence(data=tensor([  101,   101,   101,   101,   101,  2769,   872,  5439,   704,   872,
         6206,  1962,  2038,  1744,   102,  1962,  2769,  5439,   782,  1962,
         3221,  2038,   102,  2339,   671,  5439,   868,   702,  2038,  1222,
          156,  2769,  1213, 10986,  4263,  2914,  2339,   872,  7178,  4923,
          102,   743,  2360,  2791,   102,   743,  6756,   102]), batch_sizes=tensor([5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1]), sorted_indices=tensor([2, 0, 4, 1, 3]), unsorted_indices=tensor([1, 3, 0, 4, 2]))

pytorch中pad_packed_sequence函数

对已经压缩过的数据进行填充恢复,联合pack_padded_sequence()来看,它们之间应该是互为逆操作的。

    pad_datas = pad_sequence(datas,batch_first=True,padding_value=0)
    print('pad_datas',pad_datas)
    pack_pad_datas = pack_padded_sequence(input=pad_datas,lengths = lengths ,batch_first=True, enforce_sorted=False)
    print('pack_pad_datas',pack_pad_datas)
 
    origin_data = pad_packed_sequence(sequence=pack_pad_datas,batch_first=True,padding_value=0)
    print('origin_data',origin_data)


经过pack_padded_sequence()压缩后的数据输入到RNN模型中,得到的结果也是没有padding_vaule的,维度和之前的那些没有压缩的数据对不齐,后续的操作就不好处理,则需要逆向填充回来对齐后,方便后续的操作。

pytorch中batch_first
batch_first=True

PyTorch中对于不同的网络层,输入的维度虽然不同,但是通常输入的第一个维度都是batch_size,比如torch.nn.Linear的输入(batch_size,in_features),torch.nn.Conv2d的输入(batch_size, C, H, W)。
RNN的输入却是(seq_len, batch_size, input_size),batch_size位于第二维度!你可以将batch_size和序列长度seq_len对换位置,此时只需要令batch_first=True。

pytorch中nn.Linear()函数

初始化一个全连接神经网络。

import torch
import torch.nn as nn


# 首先初始化一个全连接神经网络
full_connected = nn.Linear(12, 15)

# 输入
input = torch.randn(5, 12)

# 输出
output = full_connected(input)

print(output.shape)
print(full_connected.weight.shape)
print(full_connected.bias.shape)

# 结果展示
# output.shape:torch.Size([5, 15])
# full_connected.weight.shape: torch.Size([15, 12])
# full_connected.bias.shape: torch.Size([15])
pytorch中torch.Tensor和torch.tensor的区别

torch.Tensor()是Python类,更明确的说,是默认张量类型torch.FloatTensor()的别名,torch.Tensor([1,2]) 会调用Tensor类的构造函数__init__,生成单精度浮点类型的张量。

>>> a=torch.Tensor([1,2])
>>> a.type()
'torch.FloatTensor'

torch.tensor()仅仅是Python的函数,函数原型是:torch.tensor(data, dtype=None, device=None, requires_grad=False),torch.tensor()可以从data中的数据部分做拷贝(而不是直接引用),根据原始数据类型生成相应的torch.LongTensor,torch.FloatTensor,torch.DoubleTensor。

>>> a = torch.tensor([1, 2])
>>> a.type()
'torch.LongTensor'
>>> a = torch.tensor([1., 2.])
>>> a.type()
'torch.FloatTensor'
>>> a = np.zeros(2, dtype=np.float64)
>>> a = torch.tensor(a)
>>> a.type()
torch.DoubleTensor
pytorch中squeeze()函数

降维:torch.squeeze(input, dim=None, out=None)
函数功能:去除size为1的维度,包括行和列。当维度大于等于2时,squeeze()无作用。
当给定dim时,那么挤压操作只在给定维度上。即若tensor.size(dim) = 1,则去掉该维度。
其中squeeze(0)代表若第一维度值为1则去除第一维度
squeeze(1)代表若第二维度值为1则去除第二维度
-1,去除最后维度值为1的维度
当不给定dim时,将输入张量形状中的1 去除并返回。 如果输入是形如(A×1×B×1×C×1×D)(A×1×B×1×C×1×D),那么输出形状就为: (A×B×C×D)(A×B×C×D)
输入形状为: (A×1×B)(A×1×B), squeeze(input, 0) 将会保持张量不变,只有用 squeeze(input, 1),形状会变成 (A×B)(A×B)

a = torch.Tensor(1,3)
>>
tensor([[-1.37,4.56,-3.57]])
 
print a.squeeze(0) #第一个维度大小确实是1,所以可以去除
>>
tensor([-1.37,4.56,-3.57])
 
print a.squeeze(1) ##第二个维度大小是3,所以不能去除
>>
tensor([[-1.37,4.56,-3.57]])
 
#例子2
b = torch.Tensor(2,3)
print b
>>
tensor([[-3.17,3.09,1.43],
[0.00,0.00,0.00]])
 
print b.squeeze(0)##第一个维度大小不是1,所以不能去除
>>
tensor([[-3.17,3.09,1.43],
[0.00,0.00,0.00]])
 
print b.squeeze(1) ##第二个维度大小是3,所以不能去除
>>
tensor([[-3.17,3.09,1.43],
[0.00,0.00,0.00]])
 
#例子3
c = torch.Tensor(3,1)
print c
>>
tensor([[-3.54],
[3.09],
[0.00]])
 
print c.squeeze(0)##第一个维度大小不是1,所以不能去除
>>
tensor([[-3.54],
[3.09],
[0.00]])
 
print c.squeeze(1)#第二个维度大小确实是1,所以可以去除
>>
tensor([-3.54,3.09,0.00])
pytorch中unsqueeze()函数

增维: torch.unsqueeze(input, dim, out=None)
增加大小为1的维度,也就是返回一个新的张量,对输入的指定位置插入维度 1且必须指明维度。

x = torch.unsqueeze(x, 3) # 在第3个维度上扩展

0:最粗粒度的方向,在第1维插入一个维度
1:在第2维插入一个维度
2:最细粒度的方向,在第3维插入一个维度
-3:在倒数第3维插入一个维度

import torch

x = torch.ones(4)
print(x)
print(x.size())

y = torch.unsqueeze(x, 0)
print(y)
print(y.size())

z = torch.unsqueeze(x, 1)
print(z)
print(z.size())

例子:

import torch

x = torch.ones(3,4)
print(x)
print(x.size())

y = torch.unsqueeze(x, 0)
print(y)
print(y.size())

z = torch.unsqueeze(x, 1)
print(z)
print(z.size())

z1 = torch.unsqueeze(x, 2)
print(z1)
print(z1.size())

结果:

tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]])
torch.Size([3, 4])
tensor([[[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]]])
torch.Size([1, 3, 4])
tensor([[[1., 1., 1., 1.]],

        [[1., 1., 1., 1.]],

        [[1., 1., 1., 1.]]])
torch.Size([3, 1, 4])
tensor([[[1.],
         [1.],
         [1.],
         [1.]],

        [[1.],
         [1.],
         [1.],
         [1.]],

        [[1.],
         [1.],
         [1.],
         [1.]]])
torch.Size([3, 4, 1])

例子:

import torch

x = torch.ones(3,4,3)
print(x)
print(x.size())

y = torch.unsqueeze(x, 0)
print(y)
print(y.size())

z = torch.unsqueeze(x, 1)
print(z)
print(z.size())

z1 = torch.unsqueeze(x, 2)
print(z1)
print(z1.size())

z2 = torch.unsqueeze(x, 3)
print(z2)
print(z2.size())

输出的结果为:

结果为:

tensor([[[1., 1., 1.],
         [1., 1., 1.],
         [1., 1., 1.],
         [1., 1., 1.]],

        [[1., 1., 1.],
         [1., 1., 1.],
         [1., 1., 1.],
         [1., 1., 1.]],

        [[1., 1., 1.],
         [1., 1., 1.],
         [1., 1., 1.],
         [1., 1., 1.]]])
torch.Size([3, 4, 3])
tensor([[[[1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.]],

         [[1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.]],

         [[1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.]]]])
torch.Size([1, 3, 4, 3])
tensor([[[[1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.]]],


        [[[1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.]]],


        [[[1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.],
          [1., 1., 1.]]]])
torch.Size([3, 1, 4, 3])
tensor([[[[1., 1., 1.]],

         [[1., 1., 1.]],

         [[1., 1., 1.]],

         [[1., 1., 1.]]],


        [[[1., 1., 1.]],

         [[1., 1., 1.]],

         [[1., 1., 1.]],

         [[1., 1., 1.]]],


        [[[1., 1., 1.]],

         [[1., 1., 1.]],

         [[1., 1., 1.]],

         [[1., 1., 1.]]]])
torch.Size([3, 4, 1, 3])
tensor([[[[1.],
          [1.],
          [1.]],

         [[1.],
          [1.],
          [1.]],

         [[1.],
          [1.],
          [1.]],

         [[1.],
          [1.],
          [1.]]],


        [[[1.],
          [1.],
          [1.]],

         [[1.],
          [1.],
          [1.]],

         [[1.],
          [1.],
          [1.]],

         [[1.],
          [1.],
          [1.]]],


        [[[1.],
          [1.],
          [1.]],

         [[1.],
          [1.],
          [1.]],

         [[1.],
          [1.],
          [1.]],

         [[1.],
          [1.],
          [1.]]]])
torch.Size([3, 4, 3, 1])

进程已结束,退出代码为 0

pytorch中expand()函数

参考:【Pytorch】expand()用法==》扩展某个维度
只能在第0维扩展一个维数,比如原来是是(1,3,4)》(2,1,3,4),而在其他维度扩展不可以(1,3,4)》(1,2,3,4)【错误】
如果不增加维数,只是增加维度,要增加的原维度必须是1才可以在该维度增加维度,其他值均不可以。

import torch
#1
x = torch.randn(2, 1, 1)**#为1可以扩展为3和4**
x = x.expand(2, 3, 4)
print('x :', x.size())
>>> x : torch.Size([2, 3, 4])
#2
**#扩展一个新的维度必须在最前面,否则会报错**
x = x.expand(2, 3, 4, 6)
>>> RuntimeError: The expanded size of the tensor (3) must match the existing size (2) at non-singleton dimension 1.
x = x.expand(6, 2, 3, 4)
>>> x : torch.Size([6, 2, 3, 4])
#3
**#某一个维度为-1表示不改变该维度的大小**
x = x.expand(6, -1, -1, -1)
>>> x : torch.Size([6, 2, 1, 1])
pytorch中to(device)

.to(device) 可以指定CPU 或者GPU。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # 单GPU或者CPU
model.to(device)
#如果是多GPU
if torch.cuda.device_count() > 1:
  model = nn.DataParallel(model,device_ids=[0,1,2])
model.to(device)

.cuda() 只能指定GPU

#指定某个GPU
os.environ['CUDA_VISIBLE_DEVICE']='1'
model.cuda()
#如果是多GPU
os.environment['CUDA_VISIBLE_DEVICES'] = '0,1,2,3'
device_ids = [0,1,2,3]
net  = torch.nn.Dataparallel(net, device_ids =device_ids)
net  = torch.nn.Dataparallel(net) # 默认使用所有的device_ids 
net = net.cuda()
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/982848.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号