一、Tensor类型
tensor有不同的数据类型,每种类型分别对应有CPU版本GPU(除了halfensor,它只有GPU版本),默认的tensor是FloatTensor,可通过torch.set_default_tensor_type修改默认tensor类型(如果默认是GPU版本,所有的操作都将在GPU上进行)。
In [102]: import torch as t
In [103]: t.set_default_tensor_type('torch.DoubleTensor')
HalfTensor是专门为GPU版本设计的,他可以极大地缓解GPU显存不足的问题,同样的元素个数,显存占用只有FloatTensor的一半。但他的不足之处在于由于他所能表示的数值大小和精度有限,所以可能存在溢出等问题。
表格:tensor数据类型
数据类型 | CPU tensor | GPU tensor |
---|---|---|
32bit浮点 | torch.FloatTensor | torch.cuda.FloatTensor |
64bit浮点 | torch.DoubleTensor | torch.cuda.DoubleTenso |
16bit半精度浮点 | N/A | torch.cuda.HalfTensor |
8bit无符号整型(0~255) | torch.ByteTensor | torch.cudaByteTensor |
8bit有符号整型(-128~127) | torch.CharTensor | torch.cuda.CharTensor |
16bit有符号整型 | torch.ShortTensor | torch.cuda.ShortTensor |
32bit有符号整型 | torch.IntTensor | torch.cuda.IntTensor |
64bit有符号整型 | torch.LongTensor | torch.cuda.LongTensor |
(1)各种数据类型之间的转换
type(new_type)
是最通用的做法,除此之外还有float、long、half等快捷方法。
In [107]: x=t.Tensor(3,4)
In [108]: x
Out[108]:
tensor([[6.2305e-307, 9.3461e-307, 8.4559e-307, 9.3460e-307],
[3.5604e-307, 1.3796e-306, 9.3461e-307, 1.3351e-306],
[1.4242e-306, 1.3351e-306, 1.0681e-306, 1.6912e-306]])
In [109]: y=x.type('torch.FloatTensor')
In [110]: y
Out[110]:
tensor([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]], dtype=torch.float32)
(2)CPU tensor 与GPU tensor之间的转换
通过tensor.cuda(CPU–>GPU)和tensor.cpu(GPU–>CPU)实现.选要注意的是,并不是所有的电脑都有GPU,比如说我的这台就没有,所以无法为大家举出他们之间转换的例子和代码,那么如何查看自己的电脑有没有cuda呢?只需一行代码
In [112]: print(t.cuda.is_available())
False
可以看到cuda.is_available是False,这意味着此电脑没有cuda。
小技巧:使用tensor的new方法可以调用该张量的对应类型的构造方法,生成一个与当前tensor类型一致的tensor。
In [115]: x
Out[115]:
tensor([[6.2305e-307, 9.3461e-307, 8.4559e-307, 9.3460e-307],
[3.5604e-307, 1.3796e-306, 9.3461e-307, 1.3351e-306],
[1.4242e-306, 1.3351e-306, 1.0681e-306, 1.6912e-306]],
dtype=torch.float64)
In [116]: y=x.new()
In [117]: y
Out[117]: tensor([], dtype=torch.float64)
二、tensor的逐元素操作
逐元素操作,顾名思义,就是对tensor的每一个元素进行操作。所以逐元素操作前后的tensor的形状是保持不变的。
表格:常见逐元素操作
函数 | 功能 |
---|---|
abs/sqrt/div/exp/fmod/log/pow | 绝对值/平方根/除法/指数/求余/求幂 |
cos/sin/asin/atan2/cosh | 三角函数 |
ceil/round/floor/trunc | 上取整/四舍五入/下取整/只保留整数部分 |
clamp(int,min,max) | 超过min和max部分截断 |
sigmoid/tanh | 激活函数 |
对与很多操作,pytorch都实现了运算符重载,所以可以直接使用运算符。例如a**2等价于torch.pow(a,2),a*2等价于torch.mul(a,2)。
接下来看几个例子
绝对值函数:abs(input, out=None) -> Tensor
Example::
>>> torch.abs(torch.tensor([-1, -2, 3]))
tensor([ 1, 2, 3])
三角函数arcsin:asin(input, out=None) -> Tensor
Example::
>>> a = torch.randn(4)
>>> a
tensor([-0.5962, 1.4985, -0.4396, 1.4525])
>>> torch.asin(a)
tensor([-0.6387, nan, -0.4552, nan])
四舍五入函数(torch.round):round(input, out=None) -> Tensor
Example::
>>> a = torch.randn(4)
>>> a
tensor([ 0.9920, 0.6077, 0.9734, -1.0362])
>>> torch.round(a)
tensor([ 1., 1., 1., -1.])
截断函数(clamp):
clamp(x,min,max)(截断函数)的输出满足以下表达式:
需要注意的是,如果输入的tensor是float类型或者double类型,那么传入的参数max和min必须是实数,否则应该传入整形Integer的max与min。
clamp(input, min, max, out=None) -> Tensor
Example::
>>> a = torch.randn(4)
>>> a
tensor([-1.7120, 0.1734, -0.0478, -0.0922])
>>> torch.clamp(a, min=-0.5, max=0.5)
tensor([-0.5000, 0.1734, -0.0478, -0.0922])
激活函数(sigmoid):
激活函数的目标是将神经网络非线性化sigmoid(input, out=None) -> Tensor
Example::
>>> a = torch.randn(4)
>>> a
tensor([ 0.9213, 1.0887, -0.8858, -1.7683])
>>> torch.sigmoid(a)
tensor([ 0.7153, 0.7481, 0.2920, 0.1458])
三、Tensor的归并操作
归并操作可以使tensor沿着某一维度进行指定操作。如加法sum,既可以计算整个tensor的和,也可以计算每一列或者每一行的和,所以经过归并运算后,输出的tensor形状往往会比输入形状小。
表格:常用的归并操作
函数 | 功能 |
---|---|
mean/sum/median/mode | 均值/和/中位数/众数 |
norm/dist | 范数/距离 |
sta/var | 标准差/方差 |
cumsum/cumprod | 累加/累乘 |
mean(input, dim, keepdim=False, out=None) -> Tensor
如均值函数的构造方法所示,归并函数大多都有一个参数dim,dim的作用在于指定操作在哪个维度进行(类似于numpy库的axis),而另一个参数keepdim的作用在于是否要保留维度1,它是一个boolean类型的参数,若为True则会保留,否则不保留,默认值为False
表格:参数dim,keepdim与输出形状之间的关系
假设输入形状为(m,n,k)
dim | keepdim | 输出形状 |
---|---|---|
dim=0 | True | (1,n,k) |
dim=0 | False | (n,k) |
dim=1 | True | (m,1,k) |
dim=1 | False | (m,k) |
dim=2 | True | (m,n,1) |
dim=2 | Fasle | (m,n) |
举例:
(1)均值函数:mean(input, dim, keepdim=False, out=None) -> Tensor
Example::
>>> a = torch.randn(4, 4)
>>> a
tensor([[-0.3841, 0.6320, 0.4254, -0.7384],
[-0.9644, 1.0131, -0.6549, -1.4279],
[-0.2951, -1.3350, -0.7694, 0.5600],
[ 1.0842, -0.9580, 0.3623, 0.2343]])
>>> torch.mean(a, 1)
tensor([-0.0163, -0.5085, -0.4599, 0.1807])
>>> torch.mean(a, 1, True)
tensor([[-0.0163],
[-0.5085],
[-0.4599],
[ 0.1807]])
(2)距离(dist):dist(input, other, p=2) -> Tensor
Example::
>>> x = torch.randn(4)
>>> x
tensor([-1.5393, -0.8675, 0.5916, 1.6321])
>>> y = torch.randn(4)
>>> y
tensor([ 0.0967, -1.0511, 0.6295, 0.8360])
>>> torch.dist(x, y, 3.5)
tensor(1.6727)
>>> torch.dist(x, y, 3)
tensor(1.6973)
(3)累乘(cumprod):cumprod(input, dim, out=None, dtype=None) -> Tensor
Example::
>>> a = torch.randn(10)
>>> a
tensor([ 0.6001, 0.2069, -0.1919, 0.9792, 0.6727, 1.0062, 0.4126,
-0.2129, -0.4206, 0.1968])
>>> torch.cumprod(a, dim=0)
tensor([ 0.6001, 0.1241, -0.0238, -0.0233, -0.0157, -0.0158, -0.0065,
0.0014, -0.0006, -0.0001])
>>> a[5] = 0.0
>>> torch.cumprod(a, dim=0)
tensor([ 0.6001, 0.1241, -0.0238, -0.0233, -0.0157, -0.0000, -0.0000,
0.0000, -0.0000, -0.0000])
四、比较函数
表格:常用比较函数
比较函数 | 功能 |
---|---|
gt/lt/ge/le/eq/ne | 大于/小于/大于等于/小于等于/等于/不等于 |
topk | 最大的k个数 |
sort | 排序 |
max/min | 比较两个tensor的最大值和最小值 |
说明:比较函数中有一些是逐元素比较,操作类似于逐元素操作,还有一些并不是逐元素操作。而表中的第一行函数(大于/小于/大于等于/小于等于/等于/不等于)实现了运算符重载,也就是说可以使用a>=b,a=b,a!=b等。另一方面,mx/min函数比较特殊,以max为例,他有以下三种情况
(1)t.max(tensor):返回tensor中最大的一个数
(2)t.max(tensor,dim):指定某一维上最大的数,返回tensor及其下标
(3)t.max(tensor1,tensor2):比较两个tensor相比较大的元素
相对而言,max的第三种情况可能有点不易理解,下面举例说明:
构造方法:max(input, other, out=None) -> Tensor
属性说明:
Args:
input (Tensor): the input tensor.
other (Tensor): the second input tensor
out (Tensor, optional): the output tensor.
Example::
>>> a = torch.randn(4)
>>> a
tensor([ 0.2942, -0.7416, 0.2653, -0.1584])
>>> b = torch.randn(4)
>>> b
tensor([ 0.8722, -1.7421, -0.4141, -0.5055])
>>> torch.max(a, b)
tensor([ 0.8722, -0.7416, 0.2653, -0.1584])
五、线性代数
表格:常用的线性代数函数
函数 | 功能 | 构造方法 | 举例 | 说明 |
---|---|---|---|---|
trace | 对角线元素之和(矩阵的迹) | trace(input) -> Tensor | ![]() | 输入的需为二维矩阵 |
diag | 对角线元素 | diag(input, diagonal=0, out=None) -> Tensor | ![]() | 如果diagonal =0,则为主对角线。如果diagonal >0,它位于主对角线之上。如果diagonal <0,则它位于主对角线之下。 |
triu/tril | 矩阵的上三角/下三角 | triu(input, diagonal=0, out=None) -> Tensor | ![]() | 属性diagonal与diag函数类似。 |
mm/bmm | 矩阵乘法,batch的矩阵乘法 | mm(input, mat2, out=None) -> Tensor | ![]() | 无 |
addmm/addbmm/addmv | 矩阵运算 | addmm(beta=1, input, alpha=1, mat1, mat2, out=None) -> Tensor | ![]() | 对于类型为’floatTensor’或’doubleTensor’的输入,参数’beta’和’alpha’必须是实数,否则它们应该是整数。 |
t | 转置 | t(input) -> Tensor | ![]() | 矩阵的转置会导致存储空间不连续,需调用它的contiguous方法将他转为连续 |
dot/cross | 内积/外积 | dot(input, tensor) -> Tensor | ![]() | 可以把两个tensor看作两个向量,利用向量内积的公式即可 |
inverse | 求逆矩阵 | inverse(input, out=None) -> Tensor | ![]() | 无 |