pytorch-初学

pytorch 初学

tensor基础

修改方式

  1. 不修改自身数据,如x.add(y),返回一个新的tensor
  2. 修改自身数据,如x.add_(y)(运算符带下划线后缀),运算结果存在X中

torch.Tensor和torch.tensor的区别

  1. Tensor的数据类型默认为FloatTensor,而tensor从数据中推断数据类型
  2. tensor(1)返回一个固定值1,而Tensor(1)返回一个大小为1的张量,初始值随机
  3. Tensor(2,3)返回一个两行三列的张量,元素值随机,tensor([2,3])则返回一个值为[2,3]的张量

创建Tensor

#生成一个单位矩阵
torch.eye(2,2)
#自动生成全是0的矩阵
torch.zeros(2,3)
#根据规则生成数据
torch.linspace(1,10,4) # tensor([ 1., 4., 7., 10.])
#生成满足均匀分布随机数
torch.rand(2,3)
#生成满足标准高斯分布(均值为0、标准差为1)随机数
torch.randn(2,3)
#返回所给数据形状相同,值全为0的张量
torch.zeros_like(torch.rand(2,3))

修改Tensor形状

截图

代码示例

#生成一个形状为2x3的矩阵
x = torch.randn(2, 3)
#查看矩阵的形状
x.size() #结果为torch.Size([2, 3])
#查看x的维度
x.dim() #结果为2
#把x变为3x2的矩阵
x.view(3,2)
#把x展平为1维向量
y=x.view(-1)
y.shape
#在开始添加一个维度
z=torch.unsqueeze(y,0)
#查看z的形状
z.size() #结果为torch.Size([1, 6])
#计算Z的元素个数
z.numel() #结果为6

torch.view与torch.reshape的异同

  1. reshape()可以由torch.reshape(),也可由
    torch.Tensor.reshape()调用。view()只可torch.Tensor.view()
    来调用。
  2. 对于一个将要被view的Tensor,新的size必须与原来的size与
    stride兼容。否则,在view之前必须调用contiguous()方法。
  3. view同样也是返回与input数据量相同,但形状不同的tensor
    。若满足view的条件,则不会copy,若不满足,则会copy
  4. 如果您只想重塑张量,应该使用torch.reshape。 如果还关注
    内存使用情况并希望确保两个张量共享相同的数据,应该使
    用torch.view。

索引操作

  • Tensor的索引操作与Numpy类似,一般情况下索引结果与源数据共享
    内存。从tensor获取元素除了可以通过索引,也可借助一些函数,常
    用的选择函数

截图

代码示例

#设置一个随机种子
torch.manual_seed(100)
#生成一个形状为2x3的矩阵
x = torch.randn(2, 3)
#根据索引获取第1行,所有数据
x[0,:]
#获取最后一列数据
x[:,-1]
#生成是否大于0的Bool张量
mask=x>0
#获取大于0的值
torch.masked_select(x,mask)
#获取非0下标,即行,列索引
torch.nonzero(mask)
#获取指定索引对应的值,输出根据以下规则得到
#out[i][j] = input[index[i][j]][j] # if dim == 0
index=torch.LongTensor([[0,1,1]])
torch.gather(x,0,index)
#out[i][j] = input[i][index[i][j]] # if dim == 1
index=torch.LongTensor([[0,1,1],[1,1,1]])
a=torch.gather(x,1,index)
#从a还原x并保存到一个2x3的矩阵z,z和x完全一样
z=torch.zeros(2,3)
z.scatter_(1,index,a)

逐元素操作

  • 与Numpy一样,tensor也有逐元素操作(element-wise),操作内
    容相似,但使用函数可能不尽相同。数学运算(+、-、*、/和**)都
    属于逐元操作,逐元素操作输入与输出的形状相同。

截图

代码示例

  • 这些操作均创建新的tensor,如果需要就地操作,可以使用
    这些方法的下划线版本,例如abs_。
t = torch.randn(1, 3)
t1 = torch.randn(3, 1)
t2 = torch.randn(1, 3)
#t+t2逐元素相加
t+t2
#t+0.1*(t1/t2)
torch.addcdiv(t, 0.1, t1, t2)
#计算sigmoid
torch.sigmoid(t)
#将t限制在[0,1]之间
torch.clamp(t,0,1)
#t+2进行就地运算
t.add_(2)

广播机制

  • 前面我们看到了如何在相同形状的两
    个张量上执行逐元素操作。 在某些情
    况下,即使形状不同,我们仍然可以
    通过调用广播机制(broadcasting
    mechanism)来执行逐元素操作。
    这种机制的工作方式如下:
  • 首先,通过适当复制元素来扩展一个或两
    个数组, 以便在转换之后,两个张量具
    有相同的形状。
  • 其次,对生成的数组执行逐元素操作。

代码示例

A1 = torch.arange(0, 40,10).reshape(4, 1)
B1 = torch.arange(0, 3)
#Tensor自动实现广播
C=A1+B1
#我们可以根据广播机制,手工进行配置
#根据规则1,B1需要向A1看齐,把B1变为(1,3)
B2=B1.unsqueeze(0) #B2的形状为1x3
#使用expand函数重复数组,分别创建的4x3的矩阵
A2=A1.expand(4,3)
B3=B2.expand(4,3)
#然后进行相加,C1与C结果一致
C1=A2+B3

归并操作

  • 归并操作顾名思义,就是对输入进行归并或合计等操作,这类操作的
    输入输出形状一般不相同,而且往往是输入大于输出形状。归并操作
    可以对整个tensor,也可以沿着某个维度进行归并。

截图

代码示例

  • 归并操作一般涉及一个dim参数,指定沿哪个维进行归并。另
    一个参数是keepdim,说明输出结果中是否保留维度1,缺省情况是
    False,即不保留
#生成一个含6个数的向量
a=torch.linspace(0,10,6)
#使用view方法,把a变为2x3矩阵
a=a.view((2,3))
#沿y轴方向累加,即dim=0
b=a.sum(dim=0) #b的形状为[3]
#沿y轴方向累加,即dim=0,并保留含1的维度
b=a.sum(dim=0,keepdim=True) #b的形状为[1,3]

连接合并操作

  • Pytorch可以把多个张量连结在一起, 把它们端对端地叠起来形成一
    个更大的张量。我们只需要提供张量列表,并给出沿哪一维(dim)连结
    。比较常用的行数包括,torch.cat, torch.stack

torch.cat()

  • torch.cat(sequence, dimension=0) → Tensor
    – 在给定维度上对输入的张量序列sequence 进行连接操作。
    参数:
    sequence (Sequence) – 可以是任意相同Tensor类型的python 序列
    dimension (int, optional) – 沿着此维连接张量序列。

代码示例

#把X,Y张量端对端地叠起来形成一个更大的张量。
#沿第一维方向和第二维方向
X = torch.arange(12, dtype=torch.float32).reshape((3,4))
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)
#沿第一维方向
>>>tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[ 2., 1., 4., 3.],
[ 1., 2., 3., 4.],
[ 4., 3., 2., 1.]]),
#沿第二维方向
>>>tensor([[ 0., 1., 2., 3., 2., 1., 4., 3.],
[ 4., 5., 6., 7., 1., 2., 3., 4.],
[ 8., 9., 10., 11., 4., 3., 2., 1.]]))

torch.stack()

  • torch.stack(sequence, dim=0) → Tensor
    – 沿着一个新维度对输入张量序列进行连接。 序列中所有的张量都应该为相同形
    状。
    – 参数:
    • sequence (Sequence) – 待连接的张量序列
    • dim (int) – 插入的维度。必须介于 0 与 待连接的张量序列数之间。

代码示例

#把X,Y张量端对端地叠起来形成一个更大的张量。
X = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
Y = torch.tensor([[10, 11, 12], [13, 14, 15], [16, 17, 18]]) #沿第一维方向
torch.stack((X, Y), dim=0)
>>>tensor([[[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9]],
[[10, 11, 12],
[13, 14, 15],
[16, 17, 18]]])

#沿第二维方向
torch.stack((X, Y), dim=1)
>>> tensor([[[ 1, 2, 3],
[10, 11, 12]],
[[ 4, 5, 6],
[13, 14, 15]],
[[ 7, 8, 9],
[16, 17, 18]]])

#沿第三维方向
torch.stack((X, Y), dim=2)
>>>tensor([[[ 1, 10],
[ 2, 11],
[ 3, 12]],
[[ 4, 13],
[ 5, 14],
[ 6, 15]],
[[ 7, 16],
[ 8, 17],
[ 9, 18]]])

比较操作

  • 比较操作一般进行逐元素比较,有些是按指定方向比较。

截图

代码示例

x=torch.linspace(0,10,6).view(2,3)
#tensor([[ 0., 2., 4.],
# [ 6., 8., 10.]])
#求所有元素的最大值
torch.max(x) #结果为10
#求第一维方向的最大值
torch.max(x,dim=0) #结果为[6,8,10] ,对应索引为tensor([[1, 1, 1]
#求最大的k=1个元素
torch.topk(x,1,dim=0) #结果为[6,8,10],对应索引为tensor([[1, 1, 1]

矩阵操作

  • 机器学习和深度学习中存在大量的矩阵运算,用的比较多的有两种,
    一种是逐元素乘法,另外一种是点积乘法。Pytorch中常用的矩阵函数

截图

代码示例

  • ①torch的dot与Numpy的dot有点不同,torch中dot对两个为一维张
    量进行点积运算,Numpy中的dot无此限制。
    ②mm是对二维的矩阵进行点积,bmm对含batch的矩阵进行点积运
    算。
    ③转置运算会导致存储空间不连续,需要调用contiguous方法
a=torch.tensor([2, 3])
b=torch.tensor([3, 4])
torch.dot(a,b) #运行结果为18 The excution result is 18
x=torch.randint(10,(2,3))
y=torch.randint(6,(3,4))
torch.mm(x,y)
x=torch.randint(10,(2,2,3))
y=torch.randint(6,(2,3,4))
torch.bmm(x,y)

pytorch与numpy比较

  • Pytorch与Numpy有很多类似
    的地方,并且有很多相同的操
    作函数名称,或虽然函数名称
    不同但含义相同;当然也有一
    些虽然函数名称相同,但含义
    不尽相同。

截图

posted @ 2023-03-09 17:56  梧桐灯下江楚滢  阅读(39)  评论(0编辑  收藏  举报