文章目录
一:参考资料
- Python 深度学习:基于Pytorch
- Pytorch 官方文档
- Dive-into-DL-Pytorch
二:创建Tensor
2.1 构造函数
torch.tensor(data, dtype=None, device=None, requires_grad=False, pin_memory=False) → Tensor
parameters:
- data (array_like) – list, tuple, NumPy ndarray, scalar, and other types.
- dtype (torch.dtype, optional) – 默认从data中推断.
- device (torch.device, optional) – CPU 或 GPU
- requires_grad (bool, optional) –记录 autograd
- pin_memory (bool, optional) – If set, returned tensor would be allocated in the pinned memory. Works only for CPU tensors. Default: False.
注
torch.Tensor与torch.tensor的区别:
- torch.Tensor是torch.empty和torch.tensor之间的一种混合,但是,当传入数据时,torch.Tensor使用全局默认dtype(FloatTensor),而torch.tensor是从数据中推断数据类型。
- torch.tensor(1)返回一个固定值1,而torch.Tensor(1)返回一个大小为1的张量,它是随机初始化的值。
import torch
t1=torch.Tensor(1)
t2=torch.tensor(1)
print("t1的值{},t1的数据类型{}".format(t1,t1.type()))
print("t2的值{},t2的数据类型{}".format(t2,t2.type()))
Output:
t1的值tensor([-3.]),t1的数据类型torch.FloatTensor
t2的值1,t2的数据类型torch.LongTensor
2.2 依据数值创建
函数 | 功能 |
---|---|
torch.zeros (*size) → Tensor | 返回指定size的张量,元素初始值为 0 |
torch.zeros_like (input) → Tensor | 返回与input 的size相同的张量,元素初始值化0 |
torch.ones (*size) → Tensor | 返回指定size的张量,元素初始化为 1 |
torch.ones_like (input) → Tensor | 返回与input 的size相同的张量,元素初始值化1 |
torch.eye (n, m=None) → Tensor | n阶单位阵 |
torch.empty (*size) → Tensor | 固定大小 但是 uninitialized data |
torch.empty_like (input) → Tensor | |
torch.full (size, fill_value) → Tensor | 元素全是fill_value,大小有size指定 |
torch.full_like (input, fill_value) -> Tensor | |
torch.diag (input, diagonal=0, out=None) → Tensor | 将input作为对角线元素生成矩阵,diagonal>0,往右上移,<0左下移 |
注
上面的函数参数都有 out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, memory_format=torch.preserve_format。like类的没有out这个参数
2.3 依据序列创建
函数 | 功能 |
---|---|
torch.arange (start=0, end, step=1) → Tensor | 在区间 [start,end) 以 step 为间隔生成一个序列张量,一共有(end-start)/step 向上取整,个数字 |
torch.linspace (start, end, steps=100) → Tensor | 从 start 到 end(包括) 均匀分成 steps个数,步长 = e n d − s t a r t s t e p s − 1 =\dfrac{end-start}{steps-1} =steps−1end−start |
torch.logspace (start, end, steps=100, base=10.0) → Tensor | 从 b a s e s t a r t base^{start} basestart 到 b a s e e n d base^{end} baseend |
注
:上面函数可以带 out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False 这些参数
2.4 依据概率分布创建
函数 | 功能 |
---|---|
torch.rand (*size) → Tensor | 满足 [0,1) 上均匀分布 的随机数 |
torch.rand_like (input) → Tensor | |
torch.randint (low=0, high, size, *) -> Tensor | [low,high) 上满足 均匀分布 的随机整数 |
torch.randint_like (input, low=0, high) -> Tensor | |
torch.randn (*size) → Tensor | 满足标准正态分布,也就是 mean =0 std=1的随机数 |
torch.randn_like (input) → Tensor | |
torch.normal (mean, std, size) → Tensor | 满足参数为 (mean,std) ,大小由 size 指定的 正态分布的随机数 |
torch.poisson (input *) → Tensor | 满足泊松分布的随机数 |
torch.randperm (n) → LongTensor | 由 0到 n-1 (包括) 这 n个 整数构成的 的一个随机排列 |
torch.bernoulli (input) → Tensor | 满足伯努利分布的随机数,input 概率值 |
注
- 和一般的创建tensor的函数一样,上面的函数可以带( out=None, dtype=torch.int64, layout=torch.strided, device=None, requires_grad=False)这些参数,其中带有like类的函数没有out这个参数
- 随机生成的函数多一个参数:generator=None 这个参数指定伪随机生成器
三:Tensor 数据操作
3.1 索引与选择 Index and Seclect
[] 索引出来的结果与原数据共享内存,也即修改一个,另一个会跟着修改。
函数 | 功能 |
---|---|
index_select (input, dim, index) | 在指定维度dim上选取,比如选取某些行、某些列 |
masked_select (input, mask) | 按照 mask 中的 True 进行索引,mask 为与input同形状的布尔型张量,返回值为一维张量 |
a[a>0] | 使用ByteTensor进行选取 |
nonzero (input) | 非0元素的下标 |
gather (input, dim, index) | 根据 index,在 dim 维度上选取数据,输出的 size与 index 一样 |
torch.take (input, index) → Tensor | 将 input 拉成1 D,根据 index 选取元素 |
torch.where (condition, x, y) → Tensor | o u t i = { x i if condition y i otherwise \mathrm{out}_{i}=\left\{\begin{array}{ll}\mathrm{x}_{i} & \text { if condition } \\ \mathrm{y}_{i} & \text { otherwise }\end{array}\right. outi={xiyi if condition otherwise |
Examples 1
>>> x = torch.randn(3, 4)
>>> x
tensor([[ 0.1427, 0.0231, -0.5414, -1.0009],
[-0.4664, 0.2647, -0.1228, -1.1068],
[-1.1734, -0.6571, 0.7230, -0.6004]])
>>> indices = torch.tensor([0, 2])
>>> torch.index_select(x, 0, indices) # 第 0 维的索引维 indices ,也就是 indices(0,2) 行
tensor([[ 0.1427, 0.0231, -0.5414, -1.0009],
[-1.1734, -0.6571, 0.7230, -0.6004]])
>>> torch.index_select(x, 1, indices) # 第一维的索引维indices ,也就是 indices(0,2) 列
tensor([[ 0.1427, -0.5414],
[-0.4664, -0.1228],
[-1.1734, 0.7230]])
Examples 2
>>> x = torch.randn(3, 4)
>>> x
tensor([[ 0.3552, -2.3825, -0.8297, 0.3477],
[-1.2035, 1.2252, 0.5002, 0.6248],
[ 0.1307, -2.0608, 0.1244, 2.0139]])
>>> mask = x.ge(0.5) # 不小于0.5
>>> mask
tensor([[False, False, False, False],
[False, True, True, True],
[False, False, False, True]])
>>> torch.masked_select(x, mask)
tensor([ 1.2252, 0.5002, 0.6248, 2.0139]) #返回一维
Examples 3
>>> x = torch.randn(3, 4)
>>> x
tensor([[-0.6096, 0.1961, 1.0903, -0.1686],
[-0.8089, 0.3873, 0.1475, -1.1008],
[ 1.0032, -0.1281, 0.0260, 0.9894]])
>>> x[x>0]
tensor([0.1961, 1.0903, 0.3873, 0.1475, 1.0032, 0.0260, 0.9894]) # 一维的
# Examples 3 中的 x
>>> x.nonzero()
tensor([[0, 0],
[0, 1],
[0, 2],
[0, 3],
[1, 0],
[1, 1],
[1, 2],
[1, 3],
[2, 0],
[2, 1],
[2, 2],
[2, 3]])
Examples 5
For a 3-D tensor the output is specified by:
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
>>> t = torch.tensor([[1,2],[3,4]])
>>> torch.gather(t, 1, torch.tensor([[0,0],[1,0]])) #index 为 [[(0,0),(0,0)],[(1,1),(1,0)]]
tensor([[ 1, 1],
[ 4, 3]])
3.2 拼接与切分
函数 | 功能 |
---|---|
torch.cat ( tensors, dim=0, out=None ) → Tensor | Concatenates 级联 |
torch.chunk (input, chunks, dim=0) → List of Tensors | 将 input 按照 dim 平均切分成 chunks 块,如果不能整除,最后一份张量小于其他张量 |
torch.split (tensor, split_size_or_sections, dim=0) | 按照 split_size_or_sections 分成块 |
torch.stack (tensors, dim=0, out=None) → Tensor | 产生一个新的维度 dim 为插入的维度 |
torch.unbind (input, dim=0) → seq | 沿着dim 将 input 拆成一个tensor 序列 |
torch.unsqueeze (input, dim) → Tensor | 升维, 原来input shape 为 (3,4),dim=1,返回一个(3,1,4)的tensor |
torch.squeeze(input,dim)
压缩长度为1的维度,dim为None,移除所有长度为1的轴,若指定维度,当且仅当该轴长度为1时可以被移除
Examples 1
>>> x = torch.randn(2, 3)
>>> x
tensor([[ 0.6580, -1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497]])
>>> torch.cat((x, x, x), 0) #在 dim=0 上级联,shape[dim] 会发生改变 ,其他维度需相同 ,(2+2+2,3)
tensor([[ 0.6580, -1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497],
[ 0.6580, -1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497],
[ 0.6580, -1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497]])
>>> torch.cat((x, x, x), 1) #(2,3+3+3)
tensor([[ 0.6580, -1.0969, -0.4614, 0.6580, -1.0969, -0.4614, 0.6580,
-1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497, -0.1034, -0.5790, 0.1497, -0.1034,
-0.5790, 0.1497]])
Examples 3
>>> a = torch.randn(7,8)
>>> a
tensor([[-0.6586, -0.1249, 2.5296, -0.2587, -0.2179, 0.0734, -1.5676, -0.8640],
[ 0.0432, 2.2907, -0.8363, 0.6039, -0.3681, 2.5227, -1.7094, 0.4246],
[ 1.6146, -0.2714, 0.3340, -0.6700, -0.5026, 0.9048, -0.6028, -2.3012],
[-0.6840, 0.4188, -0.6200, 1.0690, -0.3554, 1.4191, -0.0220, -0.7918],
[-0.0436, 0.5721, 1.3277, -1.6127, 0.4684, -1.2540, 1.2461, 0.8962],
[ 0.6750, 0.1900, 0.3397, -0.7727, 0.1751, 1.4288, 0.8574, 1.2476],
[-0.0482, -0.8391, -0.3110, 0.1880, 1.2450, 1.2107, 0.0068, -0.9960]])
>>> b = torch.split(a,2,dim=1) # 2列一组,一共 8/2 shape[dim]/split_size_or_sections = 4组
>>> b
(tensor([[-0.6586, -0.1249],
[ 0.0432, 2.2907],
[ 1.6146, -0.2714],
[-0.6840, 0.4188],
[-0.0436, 0.5721],
[ 0.6750, 0.1900],
[-0.0482, -0.8391]]), tensor([[ 2.5296, -0.2587],
[-0.8363, 0.6039],
[ 0.3340, -0.6700],
[-0.6200, 1.0690],
[ 1.3277, -1.6127],
[ 0.3397, -0.7727],
[-0.3110, 0.1880]]), tensor([[-0.2179, 0.0734],
[-0.3681, 2.5227],
[-0.5026, 0.9048],
[-0.3554, 1.4191],
[ 0.4684, -1.2540],
[ 0.1751, 1.4288],
[ 1.2450, 1.2107]]), tensor([[-1.5676, -0.8640],
[-1.7094, 0.4246],
[-0.6028, -2.3012],
[-0.0220, -0.7918],
[ 1.2461, 0.8962],
[ 0.8574, 1.2476],
[ 0.0068, -0.9960]]))
>>> c = torch.split(a,[1,2,3,2],dim=1) # 按照 [1,2,3,2]分组
>>> c
(tensor([[-0.6586],
[ 0.0432],
[ 1.6146],
[-0.6840],
[-0.0436],
[ 0.6750],
[-0.0482]]), tensor([[-0.1249, 2.5296],
[ 2.2907, -0.8363],
[-0.2714, 0.3340],
[ 0.4188, -0.6200],
[ 0.5721, 1.3277],
[ 0.1900, 0.3397],
[-0.8391, -0.3110]]), tensor([[-0.2587, -0.2179, 0.0734],
[ 0.6039, -0.3681, 2.5227],
[-0.6700, -0.5026, 0.9048],
[ 1.0690, -0.3554, 1.4191],
[-1.6127, 0.4684, -1.2540],
[-0.7727, 0.1751, 1.4288],
[ 0.1880, 1.2450, 1.2107]]), tensor([[-1.5676, -0.8640],
[-1.7094, 0.4246],
[-0.6028, -2.3012],
[-0.0220, -0.7918],
[ 1.2461, 0.8962],
[ 0.8574, 1.2476],
[ 0.0068, -0.9960]]))
Examples 4
a = torch.randn(2,3)
b = torch.stack([a,a,a,a],dim=1)
c = torch.stack([a,a,a,a],dim=0)
print(a.size())
print(b.size())
print(c.size())
Out
torch.Size([2, 3])
torch.Size([2, 4, 3])
torch.Size([4, 2, 3])
3.3 改变形状
方法一:用view()
来改变Tensor的形状:
x = torch.rand(5,3)
y = x.view(15)
z = x.view(-1,5)
print(x.size(),y.size(),z.size())
print("x = {}\ny = {}\nz = {}".format(x,y,z))
Out
torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])
x = tensor([[0.4824, 0.5660, 0.5901],
[0.1146, 0.9807, 0.2759],
[0.0948, 0.6217, 0.6715],
[0.3495, 0.1522, 0.0315],
[0.5226, 0.7303, 0.3773]])
y = tensor([0.4824, 0.5660, 0.5901, 0.1146, 0.9807, 0.2759, 0.0948, 0.6217, 0.6715,
0.3495, 0.1522, 0.0315, 0.5226, 0.7303, 0.3773])
z = tensor([[0.4824, 0.5660, 0.5901, 0.1146, 0.9807],
[0.2759, 0.0948, 0.6217, 0.6715, 0.3495],
[0.1522, 0.0315, 0.5226, 0.7303, 0.3773]])
x += 1
print(x)
print(y) # 也加了1
Out
tensor([[1.8382, 1.7962, 1.2575],
[1.9119, 1.1908, 1.0544],
[1.5590, 1.5573, 1.9642],
[1.5535, 1.2833, 1.1861],
[1.5805, 1.8435, 1.5936]])
tensor([1.8382, 1.7962, 1.2575, 1.9119, 1.1908, 1.0544, 1.5590, 1.5573, 1.9642,
1.5535, 1.2833, 1.1861, 1.5805, 1.8435, 1.5936])
注
view() 返回的新Tensor与源Tensor虽然可能有不同的 size ,但是是共享 data 的,也即更改其中的一个,另外一个也会跟着改变。(顾名思义,view仅仅是改变了对这个张量的观察角度,内部数据并未改变)
方法二:Pytorch还提供了一个reshape()
可以改变形状,但是此函数并不能保证返回的是其拷贝,所以不推荐使用。如果我们想返回一个真正新的副本(即不共享data内存)推荐先用clone
创造一个副本然后再使用view
x_cp = x.clone().view(15)
x -= 1
print(x)
print(x_cp)
Out
tensor([[0.8382, 0.7962, 0.2575],
[0.9119, 0.1908, 0.0544],
[0.5590, 0.5573, 0.9642],
[0.5535, 0.2833, 0.1861],
[0.5805, 0.8435, 0.5936]])
tensor([1.8382, 1.7962, 1.2575, 1.9119, 1.1908, 1.0544, 1.5590, 1.5573, 1.9642,
1.5535, 1.2833, 1.1861, 1.5805, 1.8435, 1.5936])
3.4 逐元素操作 Pointwise Ops
四则运算
函数 | 功能 |
---|---|
torch.add (input, other, out=None) | o u t = i n p u t i + o t h e r i out = input_i + other_i out=inputi+otheri |
torch.add (input, other, *, alpha=1, out=None) | o u t i = i n p u t i + o t h e r i × a l p h a out_i = input_i +other_i × alpha outi=inputi+otheri×alpha |
torch.addcdiv (input, tensor1, tensor2, *, value=1, out=None) → Tensor | o u t i = i n p u t i + v a l u e × t e n s o r 1 i t e n s o r 2 i out_i = input_i + value × \frac{tensor1_i}{tensor2_i} outi=inputi+value×tensor2itensor1i |
torch.addcmul (input, tensor1, tensor2, *, value=1, out=None) → Tensor | o u t i = i n p u t i + v a l u e × t e n s o r 1 i × t e n s o r 2 i out_i = input_i + value × tensor1_i × tensor2_i outi=inputi+value×tensor1i×tensor2i |
torch.mul (input, other, out=None) | out i = _{i}= i= other × \times × input i _{i} i |
torch.div (input, other, out=None) → Tensor | o u t i = input i other out_{i}=\frac{\text { input }_{i}}{\text { other }} outi= other input i |
torch.true_divide (dividend, divisor) → Tensor | 在运算之前先转换成浮点数 |
torch.remainder (input, other, out=None) → Tensor | 余数若除数input 为浮点数(整数),out 也为浮点数(整数) |
torch.fmod (input, other, out=None) → Tensor | 余数,与被除数一致 |
torch.neg (input, out=None) → Tensor | out = − 1 × =-1 \times =−1× input |
幂函数
函数 | 功能 |
---|---|
torch.pow (input, exponent, out=None) → Tensor | out i = x i exponent i \operatorname{out}_{i}=x_{i}^{\text {exponent }_{i}} outi=xiexponent i |
torch.reciprocal (input, out=None) → Tensor | out i = 1 input i _{i}=\frac{1}{\text { input }_{i}} i= input i1 |
torch.square (input, out=None) → Tensor | 平方 |
torchsqrt (input, out=None) → Tensor | out i = input i _{i}=\sqrt{\text { input }_{i}} i= input i |
torch.rsqrt (input, out=None) → Tensor | out i = 1 input i _{i}=\frac{1}{\sqrt{\text { input }_{i}}} i= input i1 |
三角函数
函数 | 功能 |
---|---|
torch.sin input,out=None) → Tensor | out i = sin ( input i ) _{i}=\sin \left(\text { input }_{i}\right) i=sin( input i) |
torch.sinh input,out=None) → Tensor | out i = sinh ( input i ) _{i}=\sinh \left(\text { input }_{i}\right) i=sinh( input i) |
torch.asin (input, out=None) → Tensor | out i = sin − 1 ( input i ) \operatorname{out}_{i}=\sin ^{-1}\left(\operatorname{input}_{i}\right) outi=sin−1(inputi) |
torch.cos input,out=None) → Tensor | out i = cos ( input i ) _{i}=\cos \left(\text { input }_{i}\right) i=cos( input i) |
torch.cosh input,out=None) → Tensor | out i = cosh ( input i ) _{i}=\cosh \left(\text { input }_{i}\right) i=cosh( input i) |
torch.tan (input, out=None) → Tensor | out i = tan ( input i ) _{i}=\tan \left(\text { input }_{i}\right) i=tan( input i) |
torch.tanh (input, out=None) → Tensor | out i = tanh ( input i ) _{i}=\tanh \left(\text { input }_{i}\right) i=tanh( input i) |
torch.atan (input, out=None) → Tensor | out i = tan − 1 ( input i ) \operatorname{out}_{i}=\tan ^{-1}\left(\text {input }_{i}\right) outi=tan−1(input i) |
绝对值 取整
函数 | 功能 |
---|---|
torch.abs (input, out=None) → Tensor | out i = ∣ _{i}=\vert i=∣ input i ∣ _{i} \vert i∣ |
torch.ceil (input, out=None) → Tensor | out i = ⌈ input i ⌉ = ⌊ input i ⌋ + 1 _{i}=\left\lceil\text { input }_{i}\right\rceil=\left\lfloor\text { input }_{i}\right\rfloor+1 i=⌈ input i⌉=⌊ input i⌋+1 |
torch.floor (input, out=None) → Tensor | out i = ⌊ input i ⌋ _{i}=\left\lfloor\text { input }_{i}\right\rfloor i=⌊ input i⌋ |
torch.round (input, out=None) → Tensor | 就近取整 |
torch.clamp (input, min, max, out=None) → Tensor | y i = { min if x i < min x i if min ≤ x i ≤ max max if x i > max y_{i}=\left\{\begin{array}{ll}\min & \text { if } x_{i}<\min \\x_{i} & \text { if } \min \leq x_{i} \leq \max \\\max & \text { if } x_{i}>\max\end{array}\right. yi=⎩⎨⎧minximax if xi<min if min≤xi≤max if xi>max |
torch.trunc (input, out=None) → Tensor | 截取整数部分 |
torch.frac (input, out=None) → Tensor | 小数部分 |
torch.sign (input, out=None) → Tensor | out i = sgn ( input i ) _{i}=\operatorname{sgn}\left(\text { input }_{i}\right) i=sgn( input i) |
对数 指数 exp 激活函数
函数 | 功能 |
---|---|
torch.exp (input, out=None) → Tensor | y i = e x i y_{i}=e^{x_{i}} yi=exi |
torch.erf (input, out=None) → Tensor | erf ( x ) = 2 π ∫ 0 x e − t 2 d t \operatorname{erf}(x)=\frac{2}{\sqrt{\pi}} \int_{0}^{x} e^{-t^{2}} d t erf(x)=π2∫0xe−t2dt |
torch.erfc (input, out=None) → Tensor | erfc ( x ) = 1 − 2 π ∫ 0 x e − t 2 d t \operatorname{erfc}(x)=1-\frac{2}{\sqrt{\pi}} \int_{0}^{x} e^{-t^{2}} d t erfc(x)=1−π2∫0xe−t2dt |
torch.sigmoid (input, out=None) → Tensor | out i = 1 1 + e − input i _{i}=\frac{1}{1+e^{-\text {input }_{i}}} i=1+e−input i1 |
torch.log (input, out=None) → Tensor | y i = log e ( x i ) y_{i}=\log _{e}\left(x_{i}\right) yi=loge(xi) |
torch.log10 (input, out=None) → Tensor | y i = log 10 ( x i ) y_{i}=\log _{10}\left(x_{i}\right) yi=log10(xi) |
逻辑运算
函数 | 功能 |
---|---|
torch.bitwise_not (input, out=None) → Tensor | NOT |
torch.logical_not (input, out=None) → Tensor | |
torch.bitwise_and (input, other, out=None) → Tensor | AND |
torch.logical_and (input, other, out=None) → Tensor | |
torch.bitwise_or (input, other, out=None) → Tensor | OR |
torch.logical_or (input, other, out=None) → Tensor | |
torch.bitwise_xor (input, other, out=None) → Tensor | XOR 当两两数值相同为否,而数值不同时为真 |
torch.logical_xor (input, other, out=None) → Tensor |
3.5 归并操作 Reduction Ops
最大值最小值
函数 | 功能 |
---|---|
torch.argmax (input) → LongTensor | 所有元素中最大值的indices |
torch.argmax (input, dim, keepdim=False) → LongTensor | |
torch.argmin (input) → LongTensor | 所有元素的最小值的 indices |
torch.argmin (input, dim, keepdim=False, out=None) → LongTensor |
注
- 在 4.4 中大部分函数都有两个常用方法,第一个是对所有元素进行操作,另外一个是沿着 dim 维度进行操作,如果 dim= i ,那么结果的 shape 为 ( a 1 , a 2 , . . . a i − 1 , 1 , a i + 1 , . . . a n ) (a_1,a_2,...a_{i-1},1,a_{i+1},...a_n) (a1,a2,...ai−1,1,ai+1,...an)
>>> a = torch.randn(4, 4)
>>> a
tensor([[ 1.3398, 0.2663, -0.2686, 0.2450],
[-0.7401, -0.8805, -0.3402, -1.1936],
[ 0.4907, -1.3948, -1.0691, -0.3132],
[-1.6092, 0.5419, -0.2993, 0.3195]])
>>> torch.argmax(a, dim=1) # dim=1, (4,4)->(4,1) 所以每行元素比较
-》tensor([ 0, 2, 0, 1])
第二个参数 keepdim 默认False 结果会少一维
a = torch.randn(4, 4)
b = a.argmax(dim=1,keepdim=False) #类似与 torch.squeeze()
print(b.size())
c = a.argmax(dim = 1,keepdim = True)
print(c.size())
Out
torch.Size([4])
torch.Size([4, 1])
中位数 众数
函数 | 功能 |
---|---|
torch.median (input) → Tensor | median value 中位数 |
torch.median (input, dim=-1, keepdim=False, out=None) -> (Tensor, LongTensor) | 中位数 across a dimension |
torch.mode (input, dim=-1, keepdim=False, out=None) -> (Tensor, LongTensor) | 众数 |
求和求积
函数 | 功能 |
---|---|
torch.prod (input, dtype=None) → Tensor | 所有元素乘积 |
torch.prod (input, dim, keepdim=False, dtype=None) → Tensor | |
torch.cumprod (input, dim, out=None, dtype=None) → Tensor | y i = x 1 ∗ x 2 ∗ . . . ∗ x i y_i = x_1 *x_2*...*x_i yi=x1∗x2∗...∗xi |
torch.sum (input, dtype=None) → Tensor | 求和 |
torch.sum (input, dim, keepdim=False, dtype=None) → Tensor | |
torch.cumsum (input, dim, out=None, dtype=None) → Tensor | y i = x 1 + x 2 + . . . + x i y_i=x_1+x_2+...+x_i yi=x1+x2+...+xi |
范数
函数 | 功能 |
---|---|
torch.dist (input, other, p=2) → Tensor | the p-norm of (input - other) |
torch.norm (input, p=‘fro’, dim=None, keepdim=False, out=None, dtype=None) | 范数 |
均值 方差 标准差
函数 | 功能 |
---|---|
torch.mean (input) → Tensor | mean value 平均值 |
torch.mean (input, dim, keepdim=False, out=None) → Tensor | |
torch.var (input, unbiased=True) → Tensor | variance 方差 |
torch.var (input, dim, keepdim=False, unbiased=True, out=None) → Tensor | |
torch.std (input, unbiased=True) → Tensor | standard-deviation 标准差 |
torch.std (input, dim, unbiased=True, keepdim=False, out=None) → Tensor | |
torch.var_mean (input, unbiased=True) -> (Tensor, Tensor) | (var,mean) |
torch.var_mean (input, dim, keepdim=False, unbiased=True) -> (Tensor, Tensor) | |
torch.std_mean (input, unbiased=True) -> (Tensor, Tensor) | (std,mean) |
torch.std_mean (input, dim, unbiased=True, keepdim=False) -> (Tensor, Tensor) |
-
unbiased=False 采用的是有偏估计:
s n 2 = 1 n ∑ i = 1 n ( x i − x ˉ ) 2 = ∑ i = 1 n ( x i 2 ) n − ( ∑ i = 1 n x i ) 2 n 2 s_{n}^{2}=\frac{1}{n} \sum_{i=1}^{n}\left(x_{i}-\bar{x}\right)^{2}=\frac{\sum_{i=1}^{n}\left(x_{i}^{2}\right)}{n}-\frac{\left(\sum_{i=1}^{n} x_{i}\right)^{2}}{n^{2}} sn2=n1i=1∑n(xi−xˉ)2=n∑i=1n(xi2)−n2(∑i=1nxi)2
unbiased=True 采用 Bessel’s correction,在前面有偏估计上乘以 n/(n-1) 结果为
s 2 = 1 n − 1 ∑ i = 1 n ( x i − x ˉ ) 2 = ∑ i = 1 n ( x i 2 ) n − 1 − ( ∑ i = 1 n x i ) 2 ( n − 1 ) n = ( n n − 1 ) s n 2 s^{2}=\frac{1}{n-1} \sum_{i=1}^{n}\left(x_{i}-\bar{x}\right)^{2}=\frac{\sum_{i=1}^{n}\left(x_{i}^{2}\right)}{n-1}-\frac{\left(\sum_{i=1}^{n} x_{i}\right)^{2}}{(n-1) n}=\left(\frac{n}{n-1}\right) s_{n}^{2} s2=n−11i=1∑n(xi−xˉ)2=n−1∑i=1n(xi2)−(n−1)n(∑i=1nxi)2=(n−1n)sn2
去重复
函数 | 功能 |
---|---|
torch.unique (input, sorted=True, return_inverse=False, return_counts=False, dim=None) | 剩下的元素是唯一的,比如[1, 1, 2, 2, 3, 1, 1, 2],结果 [1,2,3] |
torch.unique_consecutive (input, return_inverse=False, return_counts=False, dim=None) | 只是去除连续重复值比如[1, 1, 2, 2, 3, 1, 1, 2],结果[1,2, 3, 1, 2] |
x = torch.tensor([3,3, 1, 2, 2, 3, 1, 1, 2])
print(torch.unique(x))
print(torch.unique(x,sorted=False, return_inverse=True, return_counts=True))
print(torch.unique_consecutive(x))
Out
tensor([1, 2, 3])
(tensor([3, 1, 2]), tensor([0, 0, 1, 2, 2, 0, 1, 1, 2]), tensor([3, 3, 3]))
tensor([3, 1, 2, 3, 1, 2])
flatten
|torch.flatten
(input, start_dim=0, end_dim=-1) → Tensor| 沿着维度dim展平|
3.6 比较操作 Comparison Ops
排序(自身比较)
函数 | 功能 |
---|---|
torch.argsort (input, dim=-1, descending=False) → LongTensor | 排序返回的是indices |
torch.max (input) → Tensor | 所有元素最大 value |
torch.max (input, dim, keepdim=False, out=None) -> (Tensor, LongTensor) | (values, indices) |
torch.min (input) → Tensor | 所有元素最小值 |
torch.min (input, dim, keepdim=False, out=None) -> (Tensor, LongTensor) | |
torch.sort (input, dim=-1, descending=False, out=None) -> (Tensor, LongTensor) | 排序 (values, indices) descending=False 升序 |
torch.topk (input, k, dim=None, largest=True, sorted=True, out=None) -> (Tensor, LongTensor) | 前K最大(values, indices) largest=True 最大值,若为False 为最小值 |
torch.kthvalue (input, k, dim=None, keepdim=False, out=None) -> (Tensor, LongTensor) | 第k小(values, indices) |
torch.cummax (input, dim, out=None) -> (Tensor, LongTensor) | 返回一个(values, indices), y i = m a x ( x 1 , . . . . x i ) y_i = max(x_1,....x_i) yi=max(x1,....xi) |
torch.cummin (input, dim, out=None) -> (Tensor, LongTensor) | 和上面类似变成min |
x = torch.randn(3, 4)
sorted, indices = torch.sort(x, 0)
print(x)
print(sorted)
print(indices)
Out
tensor([[-1.1400, 1.3991, -1.9378, 0.7082],
[-0.8467, 0.6668, 0.7851, -1.0828],
[-0.8349, 0.7770, 0.1208, -1.6714]])
tensor([[-1.1400, 0.6668, -1.9378, -1.6714], # 竖着排
[-0.8467, 0.7770, 0.1208, -1.0828],
[-0.8349, 1.3991, 0.7851, 0.7082]])
tensor([[0, 1, 0, 2],
[1, 2, 2, 1],
[2, 0, 1, 0]])
比较(不同tensor比较)
函数 | 功能 |
---|---|
torch.eq (input, other, out=None) → Tensor | 每个位置元素是否相等 |
torch.equal (input, other) → bool | 相同大小和元素 |
torch.ge (input, other, out=None) → Tensor | i n p u t i ≥ o t h e r i input_i\geq other_i inputi≥otheri |
torch.gt (input, other, out=None) → Tensor | i n p u t i > o t h e r i input_i > other_i inputi>otheri |
torch.le (input, other, out=None) → Tensor | i n p u t i ≤ o t h e r i input_i\leq other_i inputi≤otheri |
torch.lt (input, other, out=None) → Tensor | i n p u t i < o t h e r i input_i < other_i inputi<otheri |
torch.ne (input, other, out=None) → Tensor | i n p u t i ≠ o t h e r i input_i\neq other_i inputi=otheri |
torch.isnan () | 是否是nan |
torch.max (input, other, out=None) → Tensor | out i = max ( tensor i , other i ) _{i}=\max \left(\text { tensor }_{i}, \text { other }_{i}\right) i=max( tensor i, other i) |
torch.min (input, other, out=None) → Tensor | out i = min ( tensor i , other i ) _{i}=\min \left(\text { tensor }_{i}, \text { other }_{i}\right) i=min( tensor i, other i) |
3.7 线性代数
矩阵迹,转置,逆矩阵,行列式
函数 | 功能 |
---|---|
torch.trace (input) → Tensor | 迹(对角线之和) |
torch.t (input) → Tensor | 二维矩阵转置 |
torch.transpose (input, dim0, dim1) → Tensor | 交换两个维度 |
torch.det (input) → Tensor | 行列式 |
内积 外积 矩阵乘法
函数 | 功能 |
---|---|
torch.dot (input, tensor) → Tensor | 内积不支持广播 |
torch.cross (input, other, dim=-1, out=None) → Tensor | 外积 |
torch.cartesian_prod (*tensors) | cartesian product 笛卡尔积 |
torch.mv (input, vec, out=None) → Tensor | 矩阵和向量乘积 |
torch.mm (input, mat2, out=None) → Tensor | 矩阵乘法,不支持广播 |
torch.bmm (input, mat2, out=None) → Tensor | batch 矩阵乘法 (b,n,m) (b,m,p) → \rightarrow → (b,n,p) |
torch.matmul (input, other, out=None) → Tensor | batch 矩阵乘法,支持广播 |
torch.chain_matmul (*matrices) | 多个矩阵乘法 |
torch.addr (input, vec1, vec2, *, beta=1, alpha=1, out=None) → Tensor | out = β =\beta =β input + α ( vec 1 ⊗ vec 2 ) +\alpha(\operatorname{vec} 1 \otimes \operatorname{vec} 2) +α(vec1⊗vec2) 外积 |
torch.addmv (input, mat, vec, *, beta=1, alpha=1, out=None) → Tensor | 矩阵向量乘法:out = β =\beta =β input + α ( mat @ vec ) +\alpha(\text { mat } @ \text { vec }) +α( mat @ vec ) |
torch.addmm (input, mat1, mat2, *, beta=1, alpha=1, out=None) → Tensor | 矩阵乘法:out = β =\beta =β input + α ( mat 1 i @ mat 2 i ) +\alpha\left(\operatorname{mat} 1_{i} @ \operatorname{mat} 2_{i}\right) +α(mat1i@mat2i) |
torch.addbmm (input, batch1, batch2, *, beta=1, alpha=1, out=None) → Tensor | out = β =\beta =β input + α ( ∑ i = 0 b − 1 batch 1 i @ batch 2 i ) +\alpha\left(\sum_{i=0}^{b-1} \operatorname{batch} 1_{i} @ \operatorname{batch} 2_{i}\right) +α(∑i=0b−1batch1i@batch2i) |
torch.baddbmm (input, batch1, batch2, *, beta=1, alpha=1, out=None) → Tensor | out i = β _{i}=\beta i=β input i + α ( batch 1 i @ batch 2 i ) _{i}+\alpha\left(\text { batch } 1_{i} @ \text { batch } 2_{i}\right) i+α( batch 1i@ batch 2i) |
>>> # vector x vector
>>> tensor1 = torch.randn(3)
>>> tensor2 = torch.randn(3)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([])
>>> # matrix x vector (3,4)×(4)->(3,1)->(3)
>>> tensor1 = torch.randn(3, 4)
>>> tensor2 = torch.randn(4)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([3])
>>> # batched matrix x broadcasted vector (3,4)×(4,1)->(3,1)->(3)
>>> tensor1 = torch.randn(10, 3, 4)
>>> tensor2 = torch.randn(4)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([10, 3])
>>> # batched matrix x batched matrix (3,4)×(4,5)->(3,5)
>>> tensor1 = torch.randn(10, 3, 4)
>>> tensor2 = torch.randn(10, 4, 5)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([10, 3, 5])
>>> # batched matrix x broadcasted matrix
>>> tensor1 = torch.randn(10, 3, 4)
>>> tensor2 = torch.randn(4, 5)
>>> torch.matmul(tensor1, tensor2).size()
torch.Size([10, 3, 5])
四:广播机制
与Numpy中的广播机制相同
五:运算的内存开销
共享内存:索引操作,y[:] = y + x,torch.add(x, y, out=y),y += x, y.add_(x)
不共享内存:y = x + y
注
:虽然view
返回的Tensor与源Tensor是共享data的,但是依然是一个新的Tensor(因为Tensor除了包含data外还有一些其他属性),二者id(内存地址)并不一致。
六:Tensor和NumPy相互转换
所有在CPU上的Tensor(除了CharTensor)都支持与NumPy数组相互转换
- 方法一:直接用
torch.tensor()
,将Numpy 转换成 Tensor,此方法总是会进行数据拷贝(就会消耗更多的时间和空间),返回的Tensor和原来的数据不再共享内存 - 方法二:使用
from_numpy()
和numpy()
进行 Numpy 和 Tensor 之间相互转换,返回的Tensor和原来的数据共享内存
item()
, 一个标量Tensor转换成一个Python number
>>> x = torch.randn(1)
>>> print(x)
>>> print(x.item())
tensor([1.4942])
1.4942256212234497
七:Tensor on GPU
用方法 to() 可以将Tensor在CPU和GPU(需要硬件支持)之间相互移动。
# 以下代码只有在PyTorch GPU版本上才会执行
if torch.cuda.is_available():
device = torch.device("cuda") # GPU torch.device("cuda:X")
y = torch.ones_like(x, device=device) # 直接创建一个在GPU上的Tensor
x = x.to(device) # 等价于 .to("cuda")
z = x + y
print(z)
print(z.to("cpu", torch.double)) # to()还可以同时更改数据类型
八:Pytorch 与 Numpy 比较