参数必须是tensor
import torch a=torch.tensor(1e-08,dtype=torch.float32) b=torch.tensor(0,dtype=torch.float32) torch.allclose(a,b)
import torch
a = torch.arange(6).reshape(2,3)
b = torch.arange(6).reshape(2,3)
torch.cat((a,b),dim=0)
tensor([[0, 1, 2],
[3, 4, 5],
[0, 1, 2],
[3, 4, 5]])
|
### 从一个维度扩展到多维度
```
import torch
torch.manual_seed(73)
a = torch.rand(5)
a
tensor([0.5286, 0.1616, 0.8870, 0.6216, 0.0459])
a.expand(5,5)
tensor([[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459]])
a.expand(2,5,5)
tensor([[[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459]],
[[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459],
[0.5286, 0.1616, 0.8870, 0.6216, 0.0459]]])
```
|
|
### 从多维扩展到多维
shape是多维度,但数据仍是只有一个向量
```
a = torch.rand(1,5)
a
tensor([[0.3856, 0.2258, 0.7837, 0.2052, 0.1868]])
b=a.expand(5,5)
b
tensor([[0.3856, 0.2258, 0.7837, 0.2052, 0.1868],
[0.3856, 0.2258, 0.7837, 0.2052, 0.1868],
[0.3856, 0.2258, 0.7837, 0.2052, 0.1868],
[0.3856, 0.2258, 0.7837, 0.2052, 0.1868],
[0.3856, 0.2258, 0.7837, 0.2052, 0.1868]])
a = torch.rand(1,1,1,5)
a
tensor([[[[0.9023, 0.9923, 0.4589, 0.7409, 0.4562]]]])
c = a.expand(-1,-1,5,5)
c
tensor([[[[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562]]]])
c = a.expand(1,1,5,5)
c
tensor([[[[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562]]]])
c = a.expand(-1,2,5,5)
c
tensor([[[[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562]],
[[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562]]]])
c = a.expand(1,2,5,5)
c
tensor([[[[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562]],
[[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562],
[0.9023, 0.9923, 0.4589, 0.7409, 0.4562]]]])
```
|
|
### singleton dimensions expand
expand英/ɪkˈspænd/美/ɪkˈspænd/
v.扩大;扩展(业务);增加;增强(尺码、数量或重要性);
Returns a new view of the :attr:`self` tensor with singleton dimensions expanded to a larger size.
Passing -1 as the size for a dimension means not changing the size of that dimension.
Tensor can be also expanded to a larger number of dimensions, and the
new ones will be appended at the front. For the new dimensions, the size cannot be set to -1.
|
|
|
|
|
|
|
|
|
|
|
二者数据为同一地址
import numpy as np import torch from torch import nn a = np.array([0.1, 0.2, 0.3]) t = torch.from_numpy(a) t[0]=0.3 print(a) # [0.3 0.2 0.3] print(t.dtype) # torch.float64 t = t.float() print(t.dtype) # torch.float32 numpy的浮点数默认为float64, torch的浮点数默认为float32
gather 英/ˈɡæðə(r)/ 美/ˈɡæðər/ v.搜集,收集,采集,集合 https://pytorch.org/docs/stable/generated/torch.gather.html torch.gather(input, dim, index, *, sparse_grad=False, out=None) → Tensor
2维
import torch
from torch import nn
t = torch.tensor([[1, 2], [3, 4]])
torch.gather(t, 1, torch.tensor([[0, 0], [1, 0]]))
tensor([[1, 1],
[4, 3]])
dim=1看矩阵得到[1,2]与[3,4]两个向量
[1,2]索引0上的数据是1
[3,4]索引0上的数据是3,索引1上的数据是4
注意:
索引的shape必须与原矩阵shape相同
比如,要取原矩阵第1行第1列上的数据,
那么,索引必须也要体现出行与列,那它就必定也是2维矩阵
指定维度上按索引取值且至少取一个值,故gather不会改变矩阵维度
import torch
from torch import nn
t = torch.tensor([[1], [3]])
torch.gather(t, 1, torch.tensor([[0], [0]]))
tensor([[1],
[3]])
原矩阵是2维,第2维只有一个元素,
并且要求第2维上必须取出一个元素,
那么使用gather取值,结果必定与原矩阵相同
3维
out[i][j][k] = input[index[i][j][k]][j][k] # if dim == 0 out[i][j][k] = input[i][index[i][j][k]][k] # if dim == 1 out[i][j][k] = input[i][j][index[i][j][k]] # if dim == 2
import torch
torch.tensor(1).item()
1
torch.tensor([1]).item()
1
[start,end]范围内,取steps个数,包含start,end
import torch torch.linspace(start=1,end=6,steps=6) tensor([1., 2., 3., 4., 5., 6.])
import torch import pandas as pd a=torch.linspace(start=1,end=120,steps=120).reshape(30,4) a.shape #torch.Size([30, 4])
import torch
probs = torch.tensor([[0.9, 0.1], [0.1, 0.9], [0.8, 0.2]])
probs
tensor([[0.9000, 0.1000],
[0.1000, 0.9000],
[0.8000, 0.2000]])
torch.log(probs)
tensor([[-0.1054, -2.3026],
[-2.3026, -0.1054],
[-0.2231, -1.6094]])
torch.log(torch.tensor(2.71828)) # tensor(1.0000)
$ y_{i} = \log_{e} (x_{i})$
𝑦𝑖=log𝑒(𝑥𝑖)
loge,也写作ln, 是一个单调函数,
在x=1时,其值为0,
在x=e时,其值为1,
记住这两个特殊的值,加上它的单调性,就可以推出:
ln,或者log2是一个增函数
x< 1时,其值小于0,
对于一个正数,以1为界,互为倒数的两组数记为x,1/x
将对数函数的底数记为a(a>0),记b=1/a
当a>1时,loga(x)是一个增函数,过(1,0),(a,1)两点
logb(x) = ln(x)/ln(b)=ln(x)/ln(1/a)=(-1)(ln(x)/ln(a))=ln(1/x)/ln(a)
=loga(1/x)
对应的,logb(x)就是一个减函数,过(b,1),(1,0)两点
masked_select,从矩阵中选取符合条件的数据排成一列
import torch
from torch import nn
t = torch.tensor([[1, 2, 3, 4, 0], [4,7,3,0, 0]])
mask=torch.zeros(t.shape)
mask = t!=mask
mask
tensor([[ True, True, True, True, False],
[ True, True, True, False, False]])
t.masked_select(mask)
tensor([1, 2, 3, 4, 4, 7, 3])
masked_fill_(mask, value)
将mask矩阵中为true位置的元素替换为value
从tensor中选出(与tensor同shape的)mask中标记为true/1的元素,并替换为指定的value
import torch
torch.manual_seed(73)
mask = torch.randint(low=0,high=2,size=(1,7))
mask
tensor([[0, 0, 0, 0, 0, 0, 1]])
score = torch.randint(low=0,high=7,size=(1,7)).float()
score
tensor([[2., 1., 2., 0., 5., 5., 4.]])
score = score.masked_fill_(mask,-float('inf'))
score
tensor([[2., 1., 2., 0., 5., 5., -inf]])
masked_fill_在注意力中用于将pad标记替换为0,即不计得分 或 注意力为0
import torch
torch.manual_seed(73)
batch_size=2
head_n1=4
seq_len1=5
seq_len2=5
score = torch.randn(batch_size,head_n1,5,5)
mask = torch.randint(low=0,high=2,size=(batch_size,1,1,5))
# [5,5]第二个5指一句话有5个词,第一个5指这句话被复制了5份
mask = mask.expand(batch_size,1,5,5)
mask
tensor([[[[0, 1, 0, 1, 1],
[0, 1, 0, 1, 1],
[0, 1, 0, 1, 1],
[0, 1, 0, 1, 1],
[0, 1, 0, 1, 1]]],
[[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]]])
#按照mask为1/true位置选出score中的元素,并使用负无穷填充
# mask = [b, 1, 5, 5],[5,5]第二个5指一句话有5个词,第一个5指这句话被复制了5份
score = score.masked_fill_(mask, -float('inf'))
#对score的倒数第一维,即最后一维做softmax
score = torch.softmax(score, dim=-1)
score.shape
torch.Size([2, 4, 5, 5])
score
tensor([[[[0.2033, 0.0000, 0.7967, 0.0000, 0.0000],
[0.7755, 0.0000, 0.2245, 0.0000, 0.0000],
[0.2173, 0.0000, 0.7827, 0.0000, 0.0000],
[0.6572, 0.0000, 0.3428, 0.0000, 0.0000],
[0.6494, 0.0000, 0.3506, 0.0000, 0.0000]],
...
...
...
[[0.2002, 0.0457, 0.0477, 0.6955, 0.0109],
[0.0463, 0.5003, 0.1162, 0.1059, 0.2313],
[0.0274, 0.3112, 0.0732, 0.2900, 0.2983],
[0.0923, 0.1678, 0.5336, 0.0851, 0.1212],
[0.0322, 0.6901, 0.0582, 0.1598, 0.0598]]]])
求整个矩阵的最大值,即不指定维度
import torch
a = torch.arange(6).reshape(2,3)
a
tensor([[0, 1, 2],
[3, 4, 5]])
torch.max(a)
tensor(5)
max:指定维度
values,index = torch.max(a,dim=1) print(values,index) tensor([2, 5]) tensor([2, 2]) index:所指定维度的“向量/列表”的索引
torch.stack(tensors, dim=0, *, out=None) → Tensor
tensors:要堆叠的张量序列(如列表或元组)。
dim:指定沿哪个维度堆叠(默认为 0)。
out(可选):输出张量。
核心功能
假设有 N 个形状为 (A, B, C) 的张量:
torch.stack 会将这些张量堆叠成一个形状为 (N, A, B, C) 的新张量(如果 dim=0)。
可以指定 dim 参数来改变堆叠的维度。
|
|
示例说明:dim=0 (默认)
import torch
x = torch.tensor([1, 2, 3])
y = torch.tensor([4, 5, 6])
z = torch.tensor([7, 8, 9])
stacked = torch.stack([x, y, z]) # dim=0
print(stacked)
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
示例 2:沿 dim=1 堆叠
stacked = torch.stack([x, y, z], dim=1)
print(stacked)
tensor([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
--------------------------------------------------------------------
|
torch.cat 是沿现有维度拼接,不增加新维度。 torch.stack 是创建新维度并堆叠,要求所有张量形状完全相同。 |
|
|
|
|
torch.rand
torch.rand(30)
tensor([0.1914, 0.2577, 0.2453, 0.2744, 0.9262, 0.8579, 0.9360, 0.6833, 0.2155,
0.8981, 0.2958, 0.3697, 0.2429, 0.5146, 0.9817, 0.5375, 0.1799, 0.0588,
0.6656, 0.6645, 0.0427, 0.9996, 0.9549, 0.0636, 0.2233, 0.4129, 0.4928,
0.8897, 0.8169, 0.4618])
Returns a tensor filled with random numbers from a uniform distribution
on the interval :math:`[0, 1)`
randint(low=0, high=1, size=(m,n)), [low,high)不包含high
torch.randint(0, 1, (3,7))
tensor([[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]])
import torch
x = torch.tensor([1, 2, 3])
x.repeat(4, 2)
tensor([
[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3]])
--------------------------------------------------------------------
|
|
|
|
|
|
|
|
tensor.round(decimals=3)
import torch a=torch.tensor(1.234535) a.round(decimals=3) # tensor(1.2350)
torch.softmax在元素全为-inf负无穷时,并不会转化为0, 至少需要一个数字
import torch
score = torch.randn(1,3)
mask = torch.tensor([1,1,1],dtype=torch.int) ==1
mask = mask.reshape(1,3)
mask
tensor([[True, True, True]])
score = score.masked_fill_(mask, -float('inf'))
score
tensor([[-inf, -inf, -inf]])
torch.softmax(score,dim=-1)
tensor([[nan, nan, nan]])
tensor.sort(key=func),排序后改变tensor内部顺序
import torch
pair_batch = [["一些 因 缘 发生 的 事 啊","像 梦幻 泡影 一样 难以捉摸"],
["如 朝露 与 闪电 一样 转瞬即逝","应该 这样 去 看"],
["它 一会 去 去 一会 又 来 来","有的 事 本就 如此 见多不怪"]
]
pair_batch.sort(key=lambda x: len(x[0].split(" ")), reverse=True)
pair_batch
[['它 一会 去 去 一会 又 来 来', '有的 事 本就 如此 见多不怪'],
['一些 因 缘 发生 的 事 啊', '像 梦幻 泡影 一样 难以捉摸'],
['如 朝露 与 闪电 一样 转瞬即逝', '应该 这样 去 看']]
squeeze英/skwiːz/ 美/skwiːz/ v.挤压;(从某物中)挤出; 削减,紧缩(资金); n.挤压;挤;减少
import torch from torch import nn torch.manual_seed(73) a = torch.rand(1,2,3) a.shape torch.Size([1, 2, 3]) x = torch.squeeze(a) x.shape torch.Size([2, 3])
a = torch.rand(2,1,3) a.shape torch.Size([2, 1, 3]) x = torch.squeeze(a) x.shape torch.Size([2, 3]) a = torch.rand(2,3,1) a.shape torch.Size([2, 3, 1]) x = torch.squeeze(a) x.shape torch.Size([2, 3])
import torch
a=torch.tensor([[1,2,3],[1,3,2]],dtype=torch.float32)
max_values,index = a.topk(1)
max_values
tensor([[3.],
[3.]])
index
tensor([[2],
[1]])
torch.gather(a, dim=1, index=index)
tensor([[3.],
[3.]])
view(1,-1)是二维矩阵,一个维度上为1,一个维度上自动伸缩
import torch a = torch.randn(2,3) a[0].shape torch.Size([3]) a[0].view(1,-1).shape torch.Size([1, 3])
import torch
torch.tril(torch.ones(1, 5, 5, dtype=torch.long))
tensor([[[1, 0, 0, 0, 0],
[1, 1, 0, 0, 0],
[1, 1, 1, 0, 0],
[1, 1, 1, 1, 0],
[1, 1, 1, 1, 1]]])
import torch
1-torch.tril(torch.ones(1, 5, 5, dtype=torch.long))
tensor([[[0, 1, 1, 1, 1],
[0, 0, 1, 1, 1],
[0, 0, 0, 1, 1],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 0]]])
torch.triu(input, diagonal=0, *, out=None)
diagonal 英/daɪˈæɡənl/ 美/daɪˈæɡənl/
adj.对角线的;斜线的 n.对角线;斜线
input:输入的二维张量(矩阵)。
diagonal:控制对角线的偏移量。
0(默认):主对角线及以上。
>0:主对角线之上第 diagonal 条对角线及以上。
<0:主对角线之下第 abs(diagonal) 条对角线及以上。
基本用法(主对角线及以上)
```
import torch
x = torch.tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
upper = torch.triu(x)
print(upper)
```
diagonal=1(不包括主对角线)
```
upper1 = torch.triu(x, diagonal=1)
print(upper1)
```
```
tensor([[0, 2, 3],
[0, 0, 6],
[0, 0, 0]])
```
|
```
import torch
sz=5
mask = torch.triu(torch.ones(sz, sz) * float('-inf'), diagonal=1)
```
mask
```
tensor([[0., -inf, -inf, -inf, -inf],
[0., 0., -inf, -inf, -inf],
[0., 0., 0., -inf, -inf],
[0., 0., 0., 0., -inf],
[0., 0., 0., 0., 0.]])
```
|
|
|
|
|
|
|
|
|
|
|
|
|
import torch from torch import nn torch.manual_seed(73) a = torch.rand(2,3) a.shape #torch.Size([2, 3]) x = torch.unsqueeze(a,dim=1) x.shape #torch.Size([2, 1, 3])torch zeros
最常见的zeros:2维
import torch
from torch import nn
a=torch.zeros((2,3), dtype=torch.long)
print(a,a.shape)
tensor([[0, 0, 0],
[0, 0, 0]]) torch.Size([2, 3])
a=torch.zeros(2,3, dtype=torch.long)
print(a,a.shape)
tensor([[0, 0, 0],
[0, 0, 0]]) torch.Size([2, 3])
普通的zeros:1维
a=torch.zeros([3], dtype=torch.long) print(a,a.shape) tensor([0, 0, 0]) torch.Size([3])
不常见的zeros:空有其形
a=torch.zeros([0], dtype=torch.long) print(a,a.shape) tensor([], dtype=torch.int64) torch.Size([0]) b = torch.ones(1, 1, dtype=torch.long) * 1 b tensor([[1]]) torch.cat((a,b),dim=0) tensor([[1]])
torch.rand(*sizes, out=None) → Tensor
torch.randn(*sizes, out=None) → Tensor
torch.normal(means, std, out=None) 注意:没有size参数
torch.normal(mean=torch.arange(1., 11.), std=torch.arange(1, 0, -0.1))
torch.normal(mean=0.5, std=torch.arange(1., 6.))
torch.normal(mean=torch.arange(1., 6.), std=1.0)
torch.normal(mean, std, size, *, out=None) 注意:有size参数
torch.normal(2, 3, size=(1, 4))
import torch
round(torch.normal(mean=torch.tensor(5.), std=torch.tensor(3.)).tolist(),2)
7.35