pytorch数据类型+tensor数据创建+索引切片操作+维度的变换+broadcasting机制+拼接和拆分+数学运算+统计属性

 

目录

 

一、pytorch数据类型

1、pytorch中的string类型如何表示?

2、核实数据类型

3、维度介绍

(1)标量

(2)Dim1

(3)Dim2

(4)Dim3

(5)Dim4

二、tensor数据的创建

1、从numpy进行导入

2、从list里面导入

3、未初始化

4、随机常见tensor数组

5、生成所有数值都一样的tensor数值——full,传入形状参数和数值参数

6、arange生成等差数组,一般不用range

7、linspace 传入三个参数,第三个是步长,前两个是起始值和终止值,左闭右开

8、logspace是以10位底的指数函数,传参进来的是10的指数值

9、ones/zeros/eye

10、randprem打散索引值,协同两组数据变化

三、索引和切片

1、索引

2、切片取值

(1)连续取值

(2)隔段取值

(3)index_select 传入选中的维度,传入要取的索引值(必须以tensor格式传入)

(4)...省略号取值

(5)mask取值

(6)take取值

四、维度变换

1、view、reshape降维、升维

2、unsqueeze(增加维度,一般来说增加的维度里只有一个值)

3、squeeze减少维度

 4、expand——更加推荐的方法

5、repeat——实实在在得发生了数据存储

6、transpose(交换两个维度值的位置)

7、permute

五、broadcasting机制

1、什么是broadcasting

2、why broadcasting

3、什么情况下使用broadcasting机制?

4、从最小维度开始匹配,我们默认越高维度越相似,而小维度上各有各的不同

六、拼接和拆分

1、拼接

(1)cat

(2)stack

2、拆分

七、数学运算

1、加减乘除

2、矩阵相乘 matmul 是按照矩阵的方式相乘

·Torch.mm(只适用于二维矩阵,不建议使用)

·Torch.matmul

·@

案例:降维

二维即以上的数组进行矩阵相乘:matmul

3、次方、开方根、开方根倒数

4、指数运算

5、取近似值

八、统计属性

1、norm——范数

2、mean——均值、sum——求和、prob累乘、max——最大值、min——最小值

3、argmin——最小值的位置;argmax——最大值的位置

 5、比较大小

拓展:where、gather

5、kthvalue——第几个的数值和位置

6、topk——top几的位置和数值


一、pytorch数据类型

1、pytorch中的string类型如何表示?

(1)没有对string的支持内键

(2)how to denote string:

1>One-hot并不体现语义

2>Embedding—word2vec

2、核实数据类型

import torch
import numpy as np
a = torch.randn(2, 3)
#randn是随机建立一个2行3列的二维数组
print(a.type())
#torch.FloatTensor

print(type(a))
#<class 'torch.Tensor'>


#合法化检验
print(isinstance(a, torch.FloatTensor))
#True

3、维度介绍

(1)标量

一般用于最后的熵值计算结果的表示,只需要一个0维度的标量来表达

shape不需要加括号,size()需要加括号

a = torch.tensor(1.)
print(a)
#tensor(1.)

b = torch.tensor(1.3)
print(b)
#tensor(1.3000)

a = torch.tensor(2.2)

print(a.shape)
#torch.Size([])
print(len(a.shape))
#0零维的向量,也就是一个标量

print(a.size())
#torch.Size([])

(2)Dim1

一般会用在bias、线性层的输入

c = torch.tensor([1.1])
d = torch.tensor([1.1, 2.2])
print(c, d)
#tensor([1.1000]) tensor([1.1000, 2.2000])

e = torch.FloatTensor(2)
print(e)
#生成一个长度为2的dim1的tensor数据
#tensor([0., 0.])

f = torch.FloatTensor(1)
#生成一个长度为1的dim1的tensor数据
print(f)
#tensor([0.])

(3)Dim2

一般用在batch,当输入多张图片时,第一个数字是图片的个数,第二个是打平图片之后的一维点数

t1 = np.ones((2, 1))
print(t1)
'''
[[1.]
 [1.]]
'''

k = torch.from_numpy(data)
print(k)
#tensor([1., 1.], dtype=torch.float64)

a = torch.randn(2, 3) #或者是torch.FloatTensor(2, 3)
print(a)
'''
tensor([[ 0.9476,  0.8075, -1.6457],
        [-0.4735, -0.8509, -0.6772]])
'''

print(a.shape)
#torch.Size([2, 3])

print(a.size(0))
#第一维度的大小
#2

print(a.size(1))
#3

print(a.shape[1])
#3

(4)Dim3

适合RNN的文字处理

b = torch.rand(1, 2, 3)
#随机生成的数字在0-1之间均匀分布
print(b)
'''
tensor([[[0.7244, 0.2569, 0.2767],
         [0.7456, 0.2834, 0.8144]]])
'''

print(b.shape)
#torch.Size([1, 2, 3])

print(b[0])
'''
tensor([[0.7244, 0.2569, 0.2767],
        [0.7456, 0.2834, 0.8144]])
'''

print(list(b.shape))
#[1, 2, 3]

(5)Dim4

适合CNN

第一个数字是图片的个数,第二个数字是图片的通道,通道为1是灰色图像,通道为3的是菜色图像,后两位数字28*28是minis数据集的长和宽

numel()检测占用内存值
c = torch.rand(2, 1, 28, 28)
print(c)
'''
tensor([[[[0.8450, 0.4577, 0.0375,  ..., 0.3396, 0.1341, 0.7081],
          [0.6733, 0.3496, 0.7041,  ..., 0.0523, 0.5972, 0.6742],
          [0.0264, 0.6056, 0.7649,  ..., 0.1025, 0.3801, 0.6365],
          ...,
          [0.9703, 0.1519, 0.6940,  ..., 0.9999, 0.6778, 0.3041],
          [0.0407, 0.6849, 0.1991,  ..., 0.4033, 0.1786, 0.9286],
          [0.3482, 0.0666, 0.4701,  ..., 0.7877, 0.5240, 0.0252]]],


        [[[0.2246, 0.2970, 0.2059,  ..., 0.9483, 0.2796, 0.0238],
          [0.5209, 0.5017, 0.2875,  ..., 0.3323, 0.4449, 0.5933],
          [0.1048, 0.0413, 0.9015,  ..., 0.4967, 0.1048, 0.6319],
          ...,
          [0.6737, 0.9206, 0.9469,  ..., 0.4061, 0.6017, 0.6666],
          [0.7382, 0.7990, 0.3033,  ..., 0.5636, 0.2971, 0.1573],
          [0.8480, 0.7790, 0.9052,  ..., 0.6815, 0.6486, 0.1487]]]])
'''


print(c.shape)
#torch.Size([2, 1, 28, 28])

print(c.numel())
#c占用的字节
#1568

print(c.dim())
#4

二、tensor数据的创建

1、从numpy进行导入

import torch
import numpy as np


#1、从numpy中导入
a = np.array([2, 3.3])
print(a)
#[2.  3.3]

b = torch.from_numpy(a)
print(b)
#tensor([2.0000, 3.3000], dtype=torch.float64)

c = np.ones((2, 3))
d = torch.from_numpy(c)
print(d)
'''
tensor([[1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)

'''

2、从list里面导入

小写的tensor括号里接收的是现有数据,而大写Terson、FloatTensor里面一般来说接受的是形状,也可以接受现成的数据,括号里用中括号时表示现成的数据,括号时输入的形状

#2、从list里面直接导入,当数据量不大的时候
a = torch.tensor([2, 3.2])
print(a)
#tensor([2.0000, 3.2000])

b = torch.FloatTensor([2, 3.2])
print(b)
#tensor([2.0000, 3.2000])

c = torch.tensor([[2, 3], [1, 4]])
print(c)
'''
tensor([[2, 3],
        [1, 4]])
'''

3、未初始化

#3、未初始化,未初始化时一定要跟一个写入数据的步骤

a = torch.empty(2, 3)
print(a)
#数值是随机给出的
'''
tensor([[0.0000e+00, 0.0000e+00, 1.4013e-45],
        [0.0000e+00, 1.4013e-45, 0.0000e+00]])
'''

b = torch.FloatTensor(1, 3, 4)
print(b)
#数据非常不规则
'''
nsor([[[0.0000, 1.8750, 0.0000, 1.8750],
         [0.0000, 1.8750, 0.0000, 1.8750],
         [0.0000, 1.8750, 0.0000, 1.8750]]])
'''
c = torch.IntTensor(1, 2, 3)
print(c)
'''
tensor([[[0, 0, 1],
         [0, 1, 0]]], dtype=torch.int32)
'''

d = torch.FloatTensor(2, 3)
print(d)
'''
tensor([[1.6543e+22, 8.3798e-43, 8.4078e-45],
        [0.0000e+00, 1.4013e-45, 0.0000e+00]])

'''
一般来说,tensor默认的数据类型是FloatTensor,在增强学习使用比较多的是doubleTensor类型,我们可以自定义默认类型
a = torch.tensor([1.3, 2])
print(a.type())
#torch.FloatTensor

torch.set_default_tensor_type(torch.DoubleTensor)
print(torch.tensor([1.3, 2]).type())
#torch.DoubleTensor

4、随机常见tensor数组

rand生成的数值分布在0-1之间
a = torch.rand(3, 3)
print(a)
'''
tensor([[0.3414, 0.9625, 0.9899],
        [0.4586, 0.3740, 0.8750],
        [0.7262, 0.5502, 0.9147]])
'''

b = torch.rand_like(a)
print(b)
'''
tensor([[0.9480, 0.1978, 0.4089],
        [0.9161, 0.3314, 0.4368],
        [0.1124, 0.8861, 0.9626]])
'''

randint随机生成整数值
c = torch.randint(1, 10, [3, 3])
print(c)
'''

#标准正太分布
a = torch.randn(3, 3)
print(a)
'''
tensor([[ 1.3423,  0.5951, -1.2756],
        [-0.0795, -0.7977,  0.3281],
        [-0.4175, -1.1260, -0.3014]])
'''


#标准正太分布
a = torch.randn(3, 3)
print(a)
'''
tensor([[ 1.3423,  0.5951, -1.2756],
        [-0.0795, -0.7977,  0.3281],
        [-0.4175, -1.1260, -0.3014]])
'''

tensor([[4, 4, 6],
        [8, 4, 9],
        [4, 7, 2]])
'''

5、生成所有数值都一样的tensor数值——full,传入形状参数和数值参数

#5、full,数组数字全部相同
a = torch.full([2, 3], 7)
print(a)
'''
tensor([[7., 7., 7.],
        [7., 7., 7.]])
'''

b = torch.full([], 7)
print(b)
#tensor(7.)

c = torch.full([1], 7)
print(c)
#tensor([7.])

6、arange生成等差数组,一般不用range

#arange/range 生成等差数列,左闭右开,默认等差为1
a = torch.arange(0, 10)
print(a)
#tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

b = torch.arange(0, 10, 2)
print(b)
#tensor([0, 2, 4, 6, 8])

#c = torch.range(0, 10)
#print(c)
#tensor([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])

7、linspace 传入三个参数,第三个是步长,前两个是起始值和终止值,左闭右开

#linspace,需要传三个参数,第三个参数为步长,即排列几个数
a = torch.linspace(0, 10, steps=4)
print(a)
#tensor([ 0.0000,  3.3333,  6.6667, 10.0000])

b = torch.linspace(0, 10, steps=10)
print(b)
'''
tensor([ 0.0000,  1.1111,  2.2222,  3.3333,  4.4444,  5.5556,  6.6667,  7.7778,
         8.8889, 10.0000])
'''

c = torch.linspace(0, 10, steps=11)
print(c)
#tensor([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])

8、logspace是以10位底的指数函数,传参进来的是10的指数值

d = torch.logspace(0, -1, steps=10)
print(d)
#从10的0次方到10的负一次方进行等差排列,排列10个数
'''
tensor([1.0000, 0.7743, 0.5995, 0.4642, 0.3594, 0.2783, 0.2154, 0.1668, 0.1292,
        0.1000])
'''

9、ones/zeros/eye

print(torch.ones(3, 3))
'''
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
'''
print(torch.zeros(3, 3))
'''
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])
'''
print(torch.eye(3, 4))
#eye--单位矩阵
'''
tensor([[1., 0., 0., 0.],
        [0., 1., 0., 0.],
        [0., 0., 1., 0.]])
'''

10、randprem打散索引值,协同两组数据变化

#randperm协同打散
print("###############################")

ta = torch.rand(2, 3)
tb = torch.rand(2, 2)

idx = torch.randperm(2)
#长度为2的数据进行打散
print(idx)
#tensor([0, 1])

print(ta[idx])
'''
tensor([[0.5607, 0.0153, 0.3796],
        [0.3243, 0.7399, 0.8882]])
'''

print(tb[idx])
'''
tensor([[0.6173, 0.7833],
        [0.7570, 0.9795]])
'''

print(ta, tb)
'''
tensor([[0.3339, 0.2769, 0.5866],
        [0.4238, 0.8009, 0.6605]]) 
tensor([[0.9526, 0.6434],
        [0.8490, 0.8654]])
'''

三、索引和切片

1、索引

import torch
import numpy as np

a = torch.rand(4, 3, 28, 28)
print(a[0].shape)
#我们采用的是dim为4的tensor数据,第一个数表示batch,即第几张图片,查看第一张图片的属性值
#torch.Size([3, 28, 28])

print(a[0, 0].shape)
#torch.Size([28, 28])

print(a[0, 0, 2, 4].shape)
#当我们取一个图片具体的行和列,应该返回一个标量
#torch.Size([])

2、切片取值

(1)连续取值

#切片,连续取值
a = torch.rand(4, 3, 28, 28)
print(a.shape)
#torch.Size([4, 3, 28, 28])

print(a[:2].shape)
#取前两张图片的形状
#torch.Size([2, 3, 28, 28])

print(a[:2, 1:, :, :].shape)
#取前两张图片第一个通道的所有行和列
#torch.Size([2, 2, 28, 28])

print(a[:2, -1:, :, :].shape)
#取前两张图片的最后一个通道的所有行和列
#torch.Size([2, 1, 28, 28])

(2)隔段取值

#隔断取值
print(a[:, :, 0:28:2, 0:28:2].shape)
#torch.Size([4, 3, 14, 14])

print(a[:, :, ::2, ::2].shape)
#torch.Size([4, 3, 14, 14])

(3)index_select 传入选中的维度,传入要取的索引值(必须以tensor格式传入)

#selct by specific index
b = a.index_select(0, torch.tensor([1, 2]))
print(b.shape)
#torch.Size([2, 3, 28, 28]) 索引以tensor的形式写 在第一个维度上取索引为1和2的值,即取了两张照片的数据

c = a.index_select(1, torch.tensor([1, 2]))
print(c.shape)
#四张照片都取第2/3个通道上的行列数值
#torch.Size([4, 2, 28, 28])

d = a.index_select(2, torch.arange(28))
print(d.shape)
#torch.Size([4, 3, 28, 28])

e = a.index_select(3, torch.arange(28))
print(d.shape)
#torch.Size([4, 3, 28, 28])

(4)...省略号取值

#...省略号仅仅是为了方便
a = torch.rand(4, 3, 28, 28)
print(a.shape)
#torch.Size([4, 3, 28, 28])

print(a[...].shape)
#取所有维度的所有值
#torch.Size([4, 3, 28, 28])

print(a[0, ...].shape)
#取第一个维度上的所有值
#torch.Size([3, 28, 28])

print(a[:, 1, ...].shape)
#取第一个通道上的所有照片的所有行列值
#torch.Size([4, 28, 28])

print(a[..., :2].shape)
#前面的维度都取,列只取前两列的值
#torch.Size([4, 3, 28, 2])

(5)mask取值

#select by mask,不建议使用
x = torch.randn(3, 4)
print(x)
'''
tensor([[-1.5627,  0.3179, -0.1547,  1.1593],
        [-0.7747,  0.1811,  2.0539, -0.2417],
        [ 0.2367, -1.3491,  1.1154,  0.3998]])
'''

mask = x.ge(0.5)
#将数值大于0.5的数变为1,其余的值还是0
print(mask)
'''
tensor([[0, 0, 0, 1],
        [0, 0, 1, 0],
        [0, 0, 1, 0]], dtype=torch.uint8)
'''

c = torch.masked_select(x, mask)
print(c)
'''
tensor([1.1593, 2.0539, 1.1154])
'''

print(c.shape)
#torch.Size([3]) 会把维度打平,只返回值大于0.5的数值的个数

(6)take取值

#select by flatten index

src = torch.tensor([[4, 3, 5], [6, 7, 8]])

x = torch.take(src, torch.tensor([0, 2, 5]))
#take函数把数组打平了,然后输入要取的索引值
print(x)
#tensor([4, 5, 8])

四、维度变换

1、view、reshape降维、升维

import torch

#view、reshape
a = torch.rand(4, 1, 28, 28)
print(a.shape)
#torch.Size([4, 1, 28, 28])

b = a.view(4, 28*28)
#把行和列的数据合并到一起
print(b.shape)
#torch.Size([4, 784])

c = a.view(4*28, 28)
print(c.shape)
#torch.Size([112, 28])

d = a.view(4*1*28, 28)
print(d.shape)
#torch.Size([112, 28])

e = a.view(4, 28, 28, 1)
print(e.shape)
#torch.Size([4, 28, 28, 1])
#破坏了数据本身的逻辑

2、unsqueeze(增加维度,一般来说增加的维度里只有一个值)

unsqueeze里面传入增加维度的位置(索引值)

#unsuqueeze
a = torch.rand(4, 1, 28, 28)
print(a.shape)
#torch.Size([4, 1, 28, 28])

b = a.unsqueeze(0)
print(b.shape)
#torch.Size([1, 4, 1, 28, 28])

c = a.unsqueeze(4)
print(c.shape)
#torch.Size([4, 1, 28, 28, 1])

a = torch.tensor([1.2, 2.3])
b = a.unsqueeze(-1)

print(b)
'''
tensor([[1.2000],
        [2.3000]])
'''

c = a.unsqueeze(0)
print(c)
#tensor([[1.2000, 2.3000]])

实际案例

要给一个思维数据(图片数据)增加一个偏置


#案例
b = torch.rand(32)

f = torch.rand(4, 32, 14, 14)
b = b.unsqueeze(1).unsqueeze(2).unsqueeze(0)

print(b.shape)
#torch.Size([1, 32, 1, 1])

3、squeeze减少维度

b = torch.rand(32)
b = b.unsqueeze(1).unsqueeze(2).unsqueeze(0)

print(b.shape)
#torch.Size([1, 32, 1, 1])


print(b.squeeze().shape)
#如果不传参的话,是把能删的都删了
#torch.Size([32])

print(b.squeeze(-1).shape)
#torch.Size([1, 32, 1])

print(b.squeeze(0).shape)
#torch.Size([32, 1, 1])

 4、expand——更加推荐的方法

#Expand
b = torch.rand(32)
b = b.unsqueeze(1).unsqueeze(2).unsqueeze(0)
#unsqueeze传入位置,增加维度的位置

b = b.expand(4, 32, 14, 14)
#expand传入的是形状——希望数组拓展成什么形状,expand只支持在1的位置进行扩展

print(b.shape)
torch.Size([4, 32, 14, 14])

b = b.expand(-1, 32, -1, -1)
-1的意思是对该维度不进行扩展
print(b.shape)
torch.Size([1, 32, 1, 1])

5、repeat——实实在在得发生了数据存储

expand传入的是形状,而repeat传入的是增加的倍数值

print(b.shape)
#torch.Size([1, 32, 1, 1])

#b = b.repeat(4, 1, 1, 1)
#print(b.shape)
#torch.Size([4, 32, 1, 1])


b = b.repeat(4, 1, 32, 32)
print(b.shape)
#torch.Size([4, 32, 32, 32])

6、transpose(交换两个维度值的位置)

transpose还需要contiguous一下,把数据连续一下再做变换

#transpose
a = torch.rand(4, 3, 32, 32)
print(a.shape)
#torch.Size([4, 3, 32, 32])

a1 = a.transpose(1, 3).contiguous().view(4, 3*32*32).view(4, 3, 32, 32)
#把1和3维度进行交换之后,变成了(4,32,32,3)然后将后面的三列进行了合并,最后拆分的时候1、3维度进行了交换,这样是不对的,数据遭到了破坏

a2 = a.transpose(1, 3).contiguous().view(4, 3*32*32).view(4, 32, 32, 3).transpose(1, 3)
print(a1.shape, a2.shape)
#torch.Size([4, 3, 32, 32]) torch.Size([4, 3, 32, 32])
#虽然形状是一样的,但是表示的含义却大不相同

print(torch.all(torch.eq(a, a1)))
#tensor(0, dtype=torch.uint8)  表示a和a1不相同

print(torch.all(torch.eq(a, a2)))
#tensor(1, dtype=torch.uint8) 表示a和a2相同

数据的存储、维度顺序非常重要,需要时刻谨记

7、permute

b = torch.rand(4, 3, 28, 32)
b = b.transpose(1, 3) #把1,3维度进行了交换,列在行前面了,这样图片的内容也发生了变化,我们进而将行和列进行一下变换
print(b.shape)
#orch.Size([4, 32, 28, 3])

b = b.transpose(1, 2)
print(b.shape)
#torch.Size([4, 28, 32, 3])

#这样的过程用permute一次性就可以完成

a = torch.rand(4, 3, 28, 31)
a = a.permute(0, 2, 3, 1)
#重新安排位置
print(a.shape)
#torch.Size([4, 28, 31, 3])

五、broadcasting机制

1、什么是broadcasting

(1)expand

(2)without copying data

主要思想

2、why broadcasting

(1)本身有现实意义;

(2)可以节省内存消耗

3、什么情况下使用broadcasting机制?

match from last dim!

·如果当前的dim维度上等于1,扩展在此维度上扩展数值量

·如果维度值为空, 可以自动生成维度并扩展维度值

·否则,则不能进行传播

4、从最小维度开始匹配,我们默认越高维度越相似,而小维度上各有各的不同

[32, 32]给每行每列加一个base基底;

[3, 1, 1]相等于是给每个通道都加个值;

[1, 1, 1, 1]像素点增加了一个值

六、拼接和拆分

1、拼接

stack和cat的区别

cat在指定维度上可以值不同,但是stack在指定维度上的值必须相同

(1)cat

import torch


#cat

a = torch.rand(4, 32, 8)
b = torch.rand(5, 32, 8)

c = torch.cat([a, b], dim=0) #以第一维度为准进行拼接
print(c.shape)
#torch.Size([9, 32, 8])
#现实意义可以理解为两个老师分别统计4/5个班的成绩,每个班有32个学生,每个学生有8门课的成绩,将两个老师统计的数据整合起来


a1 = torch.rand(4, 3, 32, 32)
a2 = torch.rand(5, 3, 32, 32)

d = torch.cat([a1, a2], dim=0)
print(d.shape)
#torch.Size([9, 3, 32, 32])

b1 = torch.rand(4, 1, 32, 32)
e = torch.cat([a1, b1], dim=1)
#在拼接的时候,只有传入的dim维度的那一维度可以不一样,其他维度的数值都必须相同
print(e.shape)
#torch.Size([4, 4, 32, 32])

a1 = torch.rand(4, 3, 16, 32)
a2 = torch.rand(4, 3, 16, 32)
b = torch.cat([a1, a2], dim=2)
print(b.shape)
#torch.Size([4, 3, 32, 32])

(2)stack

#stack
a1 = torch.rand(4, 3, 16, 32)
a2 = torch.rand(4, 3, 16, 32)
c = torch.stack([a1, a2], dim=2)
print(c.shape)
#torch.Size([4, 3, 2, 16, 32])
#stack会在dim=2的维度前增加一个维度
#现实意义是:两个老师分别统计两个班的成绩,一个班有32个人,每个人有8门课的成绩,将他们stack起来,可以表示(2,32,8)
#如果用cat的话,则表示为(64,8)则现实意义上来说不如stack好

2、拆分

(1)split按照长度进行拆分

b = torch.rand(32, 8)
a = torch.rand(32, 8)
c = torch.stack([a, b], dim=0)
print(c.shape)
#torch.Size([2, 32, 8])

aa, bb = c.split(1, dim=0)
print(aa.shape, bb.shape)
#torch.Size([1, 32, 8]) torch.Size([1, 32, 8])

d = torch.rand(5, 32, 8)
a1, a2, a3 = d.split([1, 2, 2], dim=0)
print(a1.shape, a2.shape, a3.shape)
#torch.Size([1, 32, 8]) torch.Size([2, 32, 8]) torch.Size([2, 32, 8])
#把5个班级的成绩进行拆分,拆分成3的模块,一个模块1个班级,两个模块两个班级
#split是按照拆分的长度进行传参的

(2)chunk按照数量进行拆分

#chunk,传参传入的是拆分模块的数量,会自动均匀分配

b = torch.rand(32, 8)
a = torch.rand(32, 8)
c = torch.stack([a, b], dim=0)
print(c.shape)
aa, bb = c.chunk(2, dim=0)
#把两个班级的成绩拆分成两个模块进行比较,split传入的是拆分的长度,拆成长度为1等同于拆成2个模块
print(aa.shape, bb.shape)
#torch.Size([1, 32, 8]) torch.Size([1, 32, 8])

七、数学运算

1、加减乘除

在torch里面,a+b = add(a,b); a - b = sub(a, b); a*b = mul(a, b); a / b=div(a, b)

import torch

a = torch.rand(3, 4)
b = torch.rand(4)
#这两个tensor数组可以直接运算,因为根据broading机制来说,它会自动把b数组转换为跟a数组一样的形状进行运算

print(a+b)
'''
tensor([[1.6960, 1.1914, 1.1556, 1.4485],
        [1.6178, 1.0697, 1.1246, 1.1632],
        [1.5524, 0.5618, 0.9049, 1.3834]])
'''

print(torch.add(a, b))
'''
tensor([[1.0804, 0.9328, 1.1746, 0.9296],
        [0.8897, 0.6246, 1.3664, 0.5070],
        [1.2556, 0.3952, 1.2464, 0.7305]])
'''

print(torch.all(torch.eq(a+b, torch.add(a, b))))
#tensor(1, dtype=torch.uint8)

print(torch.all(torch.eq(a-b, torch.sub(a, b))))
#tensor(1, dtype=torch.uint8)

print(torch.all(torch.eq(a*b, torch.mul(a, b))))
#tensor(1, dtype=torch.uint8)

print(torch.all(torch.eq(a/b, torch.div(a, b))))
#tensor(1, dtype=torch.uint8)

2、矩阵相乘 matmul 是按照矩阵的方式相乘

·Torch.mm(只适用于二维矩阵,不建议使用)

·Torch.matmul

·@

#矩阵相乘运算
a = torch.full([2, 2], 3)
b = torch.ones(2, 2)
c = torch.mm(a, b)
print(c)
'''
tensor([[6., 6.],
        [6., 6.]])
'''

d = torch.matmul(a, b)
print(d)
'''
tensor([[6., 6.],
        [6., 6.]])
'''

e = a@b
print(e)
'''
tensor([[6., 6.],
        [6., 6.]])
'''

案例:降维

#一个案例,降维

x = torch.rand(4, 748)
w = torch.rand(512, 748)
#这里的传参的标注是,前面是我们降维的目标,希望降低到多少维度,后面是我们原本的维度

k = x@w.t()
#在这里t()是只适合二维矩阵的转置函数,二维即以上的用transpose
print(k.shape)
#torch.Size([4, 512])

二维即以上的数组进行矩阵相乘:matmul

默认后面两个维度进行矩阵相乘计算

当前面的维度数值相同,直接计算,当么有维度或维度为1时,根据广播机制进行计算,但是当维度的数值个数不为1的时候,没有办法计算,如下案例a与b2无法进行矩阵相乘

a = torch.rand(4, 3, 28, 64)
b = torch.rand(4, 3, 64, 32)
c = torch.matmul(a, b)
print(c.shape)
#torch.Size([4, 3, 28, 32])

b1 = torch.rand(4, 1, 64, 32)
c1 = torch.matmul(a, b1)
#这里的a 和 b1在第二个维度上不一致,但是根据broadcasting机制,它会自动把1的地方扩充为a的维度值,然后进行运算
print(c.shape)
#torch.Size([4, 3, 28, 32])

'''
b2 = torch.rand(4, 64, 32)
#此时的b2和a没办法进行矩阵相乘,因为他们都没有1这个维度值,所以没办法进行扩充
c2 = torch.matmul(a, b2)
print(c2.shape)
#RuntimeError: The size of tensor a (3) must match the size of tensor b (4) at non-singleton dimension 1
'''

3、次方、开方根、开方根倒数

a = torch.full([2, 2], 3)
b = a.pow(2)
print(b)
'''
tensor([[9., 9.],
        [9., 9.]])
'''

b1 = a ** 2
print(b1)
'''
tensor([[9., 9.],
        [9., 9.]])
'''

c = b1.sqrt()
#对c取平方根
print(c)
'''
tensor([[3., 3.],
        [3., 3.]])
'''

d = b1.rsqrt()
#取平方根的倒数
print(d)
'''
tensor([[0.3333, 0.3333],
        [0.3333, 0.3333]])
'''

d1 = b1 ** (0.5)
print(d1)
'''
tensor([[3., 3.],
        [3., 3.]])

4、指数运算

#e的指数函数tensor数据
a = torch.exp(torch.ones(2, 2))
print(a)
'''
tensor([[2.7183, 2.7183],
        [2.7183, 2.7183]])
'''

b = torch.log(a)
#log函数默认以e为底
print(b)
'''
tensor([[1.0000, 1.0000],
        [1.0000, 1.0000]])
'''

5、取近似值

floor()取小

ceil()取大

round()四舍五入

trunc()取整数

frac()取小数

裁剪——clamp

打印参数w的梯度:w.grad.norm(2)

torch里面的clamp类似于numpy里面的climp把数值范围进行裁剪 

#approximation
a = torch.tensor(3.14)
print(a.floor())
#tensor(3.)
print(a.ceil())
#tensor(4.)
print(a.round())
#tensor(3.)
print(torch.tensor(3.5).round())
#tensor(4.)
print(a.trunc())
#tensor(3.)
print(a.frac())
#tensor(0.1400)

#clamp——裁剪
grad = torch.rand(2, 3) * 15
print(grad.max())
#tensor(9.3662)

print(grad.median())
#tensor(5.9054)

print(grad.clamp(10))
#梯度的最小限定是10
'''
tensor([[10., 10., 10.],
        [10., 10., 10.]])
'''

print(grad.clamp(0, 10))
#给出限定范围,0-10之间,大于10的部分都变为10
'''
tensor([[ 0.2897,  3.3792,  6.4364],
        [ 3.5287, 10.0000,  8.6903]])

'''

八、统计属性

1、norm——范数

注意:norm不等于normalize(正则化)

vector norm 不等同于 matrix norm

第一范数

第二范数

import torch

#范式
a = torch.full([8], 1)
b = a.reshape(2, 4)
c = a.reshape(2, 2, 2)

print(b)
'''
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.]])
'''

print(c)
'''
tensor([[[1., 1.],
         [1., 1.]],

        [[1., 1.],
         [1., 1.]]])
'''

#求a,b,c的第一范式
print(a.norm(1))
#tensor(8.)
print(b.norm(1))
#tensor(8.)
print(c.norm(1))
#tensor(8.)

x1 = b.norm(1, dim=1)
#以行为标准,对列进行操作,求每一行的第一范式
print(x1)
#tensor([4., 4.])

x2 = b.norm(2, dim=1)
#以行位标准,对每一列进行操作,求每一行的第二范式
print(x2)
#tensor([2., 2.])

print(c.norm(1, dim=0))
#以第一维度为标准,对每行每列的对应数值进行操作,求第一范数
'''
tensor([[2., 2.],
        [2., 2.]])
'''

print(c.norm(2, dim=0))
'''
tensor([[1.4142, 1.4142],
        [1.4142, 1.4142]])
'''

2、mean——均值、sum——求和、prob累乘、max——最大值、min——最小值

a = torch.arange(8).view(2, 4).float()
print(a)
'''
tensor([[0., 1., 2., 3.],
        [4., 5., 6., 7.]])
'''

print(a.min())
#tensor(0.)
print(a.max())
#tensor(7.)
print(a.prod())
#prod是累乘的意思
#tensor(0.)
print(a.sum())
#tensor(28.)

3、argmin——最小值的位置;argmax——最大值的位置

a = torch.arange(8).view(2, 4).float()
print(a)
#当我们没有指定维度的时候,返回的位置是把数组打平之后的位置索引
print(a.argmax())
#tensor(7)
print(a.argmin())
#tensor(0)

a = a.view(1, 2, 4)
print(a.argmax())
#tensor(7)
print(a.argmin())
#tensor(0)

a = torch.rand(2, 3, 4)
print(a.argmax())
#tensor(10)

a = torch.randn(4, 10)
print(a[0])
'''
tensor([-2.2259, -0.3194, -0.2529, -1.2658,  0.0792,  0.5460, -1.9197,  0.2636,
        -0.0684, -1.4274])
'''

print(a.argmax())
#tensor(31)

print(a.argmax(dim=1))
#tensor([6, 8, 0, 1])
#以dim=1为标准是取dim=0的维度上的每张照片(这里仅仅是举了一个应用场景)的最大值
#以列为标准,取每一行上的最大值

print(a.argmax(dim=0))
#tensor([2, 3, 1, 1, 0, 3, 1, 1, 0, 1])
#以行为标准,取每一列上的最大值

dim,keepdim

a = torch.randn(4, 10).float()
print(a)
'''
tensor([[-0.5399,  2.2001,  1.2691,  0.9019,  0.6524, -0.7588, -0.2862, -0.8736,
          0.2056,  0.3449],
        [-0.1167,  2.1540, -0.2391, -1.2638,  0.2705, -0.7601,  0.8635, -1.4094,
          0.4610, -0.4595],
        [-1.6827,  0.8954,  0.2086, -0.8916,  0.4781, -0.0702,  1.0478,  1.4631,
          1.3250, -0.7159],
        [ 0.6034,  0.7537, -0.4327, -0.6153,  0.6938,  0.2003,  0.9891,  0.2207,
         -1.4104, -0.1738]])
'''
print(a.max(dim=1))
'''
torch.return_types.max(
values=tensor([2.2001, 2.1540, 1.4631, 0.9891]),
indices=tensor([1, 1, 7, 6]))
'''
#max返回的是最大值的数值和索引位置

print(a.max(dim=1, keepdim=True))
'''
torch.return_types.max(
values=tensor([[2.2001],
        [2.1540],
        [1.4631],
        [0.9891]]),
indices=tensor([[1],
        [1],
        [7],
        [6]]))
'''

print(a.argmax(dim=1, keepdim=True))
'''
tensor([[4],
        [4],
        [4],
        [6]])
'''

a = torch.randn(4, 10).float()
print(a.topk(3, dim=1))
#以列为标准,找每一行的前三大的值
'''
torch.return_types.topk(
values=tensor([[1.1169, 0.4949, 0.4045],
        [3.1041, 1.2796, 0.8438],
        [0.9410, 0.6610, 0.4236],
        [1.7050, 0.2118, 0.1091]]),
indices=tensor([[7, 1, 9],
        [9, 8, 6],
        [3, 7, 0],
        [5, 2, 3]]))
'''



 5、比较大小

#基本比较运算
a = torch.randn(4, 10).float()
print(a > 0)
#由于pytorch里面没有string类型,所以判断值返回的是0和1
'''
tensor([[1, 0, 1, 1, 1, 1, 1, 0, 0, 1],
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [1, 0, 0, 1, 1, 1, 0, 0, 0, 0],
        [0, 0, 1, 1, 1, 1, 0, 1, 0, 1]], dtype=torch.uint8)
'''
print(torch.gt(a, 0))
#其功能同上
'''
tensor([[1, 0, 1, 1, 1, 1, 1, 0, 0, 1],
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [1, 0, 0, 1, 1, 1, 0, 0, 0, 0],
        [0, 0, 1, 1, 1, 1, 0, 1, 0, 1]], dtype=torch.uint8)
'''

print(a != 0)
'''
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, 1, 1, 1, 1]], dtype=torch.uint8)
'''

b = torch.ones(2, 3)
b1 = torch.randn(2, 3)
print(torch.eq(b, b1))
'''
tensor([[0, 0, 0],
        [0, 0, 0]], dtype=torch.uint8)
'''

print(torch.eq(b, b))
'''
tensor([[1, 1, 1],
        [1, 1, 1]], dtype=torch.uint8)
'''

print(torch.equal(b, b))
#True

拓展:where、gather

where

#where
cond = torch.rand(2, 2)
print(cond)
'''
tensor([[0.3904, 0.8854],
        [0.7794, 0.7720]])
'''

a = torch.zeros(2, 2)
b = torch.ones(2, 2)

x = torch.where(cond > 0.5, a, b)
#大于0.5的地方用a来代替,否则用b来赋值,赋值是在对应的位置赋对应数组的值

print(x)
'''
tensor([[1., 1.],
        [0., 1.]])
'''

gather

#gather

prob = torch.randn(4, 10)
idx = prob.topk(dim=1, k=3)
print(idx)
'''
torch.return_types.topk(
values=tensor([[1.2111, 1.0892, 1.0405],
        [2.6614, 0.9915, 0.9800],
        [0.9517, 0.5465, 0.4751],
        [2.0146, 0.2789, 0.0141]]),
indices=tensor([[6, 3, 1],
        [2, 8, 9],
        [6, 1, 8],
        [4, 3, 2]]))
'''

idx = idx[1]
label = torch.arange(10) + 100
print(label)
#tensor([100, 101, 102, 103, 104, 105, 106, 107, 108, 109])

x = torch.gather(label.expand(4, 10), dim=1, index=idx.long())
print(x)
'''
ensor([[105, 108, 107],
        [106, 100, 108],
        [108, 107, 100],
        [107, 101, 105]])
'''

5、kthvalue——第几个的数值和位置

a = torch.randn(4, 10).float()
print(a.kthvalue(8, dim=1))
#kthvalue默认取第k小的值,且只能是取第k小的值,第8小的值就是第三大的值
'''
torch.return_types.kthvalue(
values=tensor([0.4045, 0.8438, 0.4236, 0.1091]),
indices=tensor([9, 6, 0, 3]))
'''

6、topk——top几的位置和数值

a = torch.randn(4, 10).float()
print(a.topk(3, dim=1, largest=False))
#largest=False表示改变排序方式,从小到大排列,取最小的三个值
'''
torch.return_types.topk(
values=tensor([[-0.6322, -0.4538,  0.0437],
        [-1.9131, -1.8761, -0.9199],
        [-0.8112, -0.6957, -0.5263],
        [-0.6981, -0.6127, -0.4714]]),
indices=tensor([[6, 0, 3],
        [4, 3, 0],
        [1, 2, 9],
        [6, 4, 7]]))
'''

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值