[toc]
张量(Tensor)
概念
几何代数中定义的张量是基于向量和矩阵的推广,比如我们可以将标量视为零阶张量,矢量可以视为一阶张量,矩阵就是二阶张量。
- 0维张量/标量 标量是一个数字
- 1维张量/向量 1维张量称为“向量”。
- 2维张量 2维张量称为矩阵
- 3维张量 公用数据存储在张量 时间序列数据 股价 文本数据 彩色图片(RGB)
张量是现代机器学习的基础。它的核心是一个数据容器,多数情况下,它包含数字,有时候它也包含字符串,但这种情况比较少。因此可以把它想象成一个数字的水桶。
这里有一些存储在各种类型张量的公用数据集类型:
- 3维=时间序列
- 4维=图像
- 5维=视频
例子:一个图像可以用三个字段表示:
(width, height, channel) = 3D
相关操作
创建tensor
构造一个随机初始化的矩阵:
from __future__ import print_function
import torch
x = torch.rand(4, 3)
print(x)
构造一个矩阵全为 0,而且数据类型是 long.
x = torch.zeros(4, 3, dtype=torch.long)
print(x)
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
直接使用数据,构造一个张量:
x = torch.tensor([5.5, 3])
print(x)
tensor([5.5000, 3.0000])
基于已经存在的 tensor,创建一个 tensor :
x = x.new_ones(4, 3, dtype=torch.double) # 创建一个新的tensor,返回的tensor默认具有相同的 torch.dtype和torch.device
# 也可以像之前的写法 x = torch.ones(4, 3, dtype=torch.double)
print(x)
x = torch.randn_like(x, dtype=torch.float)
# 重置数据类型
print(x)
# 结果会有一样的size
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[ 0.2626, -0.6196, 1.0963],
[ 1.1366, -0.6543, 0.6040],
[-0.6623, 0.1115, 0.2433],
[ 1.1626, -2.3529, -0.9417]])
获取它的维度信息:
print(x.size())
print(x.shape)
torch.Size([4, 3])
返回的torch.Size其实就是一个tuple,⽀持所有tuple的操作。
还有一些常见的构造Tensor的函数:
函数 | 功能 |
---|---|
Tensor(*sizes) | 基础构造函数 |
tensor(data) | 类似于np.array |
ones(*sizes) | 全1 |
zeros(*sizes) | 全0 |
eye(*sizes) | 对角为1,其余为0 |
arange(s,e,step) | 从s到e,步长为step |
linspace(s,e,steps) | 从s到e,均匀分成step份 |
rand/randn(*sizes) | |
normal(mean,std)/uniform(from,to) | 正态分布/均匀分布 |
randperm(m) | 随机排列 |
三角函数
torch.abs(input, out=None)
torch.acos(input, out=None)
torch.asin(input, out=None)
torch.atan(input, out=None)
torch.atan2(input, inpu2, out=None)
torch.cos(input, out=None)
torch.cosh(input, out=None)
torch.sin(input, out=None)
torch.sinh(input, out=None)
torch.tan(input, out=None)
torch.tanh(input, out=None)
基本运算,加减乘除
Torch.add(input, value, out=None)
.add(input, value=1, other, out=None)
.addcdiv(tensor, value=1, tensor1, tensor2, out=None)
.addcmul(tensor, value=1, tensor1, tensor2, out=None)
torch.div(input, value, out=None)
.div(input, other, out=None)
torch.mul(input, value, out=None)
.mul(input, other, out=None)
对数运算
torch.log(input, out=None) # y_i=log_e(x_i)
torch.log1p(input, out=None) #y_i=log_e(x_i+1)
torch.log2(input, out=None) #y_i=log_2(x_i)
torch.log10(input,out=None) #y_i=log_10(x_i)
幂函数
torch.pow(input, exponent, out=None) # y_i=input^(exponent)
指数运算
torch.exp(tensor, out=None) #y_i=e^(x_i)
torch.expm1(tensor, out=None) #y_i=e^(x_i) -1
截断函数
torch.ceil(input, out=None) #返回向正方向取得最小整数
torch.floor(input, out=None) #返回向负方向取得最大整数
torch.round(input, out=None) #返回相邻最近的整数,四舍五入
torch.trunc(input, out=None) #返回整数部分数值
torch.frac(tensor, out=None) #返回小数部分数值
torch.fmod(input, divisor, out=None) #返回input/divisor的余数
torch.remainder(input, divisor, out=None) #同上
其他运算
torch.erf(tensor, out=None)
torch.erfinv(tensor, out=None)
torch.sigmoid(input, out=None)
torch.clamp(input, min, max out=None) #返回 input<min,则返回min, input>max,则返回max,其余返回input
torch.neg(input, out=None) #out_i=-1*(input)
torch.reciprocal(input, out=None) # out_i= 1/input_i
torch.sqrt(input, out=None) # out_i=sqrt(input_i)
torch.rsqrt(input, out=None) #out_i=1/(sqrt(input_i))
torch.sign(input, out=None) #out_i=sin(input_i) 大于0为1,小于0为-1
torch.lerp(start, end, weight, out=None)
降维操作
torch.argmax(input, dim=None, keepdim=False) #返回最大值排序的索引值
torch.argmin(input, dim=None, keepdim=False) #返回最小值排序的索引值
torch.cumprod(input, dim, out=None) #y_i=x_1 * x_2 * x_3 *…* x_i
torch.cumsum(input, dim, out=None) #y_i=x_1 + x_2 + … + x_i
torch.dist(input, out, p=2) #返回input和out的p式距离
torch.mean() #返回平均值
torch.sum() #返回总和
torch.median(input) #返回中间值
torch.mode(input) #返回众数值
torch.unique(input, sorted=False) #返回1-D的唯一的tensor,每个数值返回一次.
>>> output = torch.unique(torch.tensor([1, 3, 2, 3], dtype=torch.long))
>>> output
tensor([ 2, 3, 1])
torch.std( #返回标准差)
torch.var() #返回方差
torch.norm(input, p=2) #返回p-norm的范式
torch.prod(input, dim, keepdim=False) #返回指定维度每一行的乘积
对比操作
torch.eq(input, other, out=None) #按成员进行等式操作,相同返回1
torch.equal(tensor1, tensor2) #如果tensor1和tensor2有相同的size和elements,则为true
>>> torch.eq(torch.tensor([[1, 2], [3, 4]]), torch.tensor([[1, 1], [4, 4]]))
tensor([[ 1, 0],
[ 0, 1]], dtype=torch.uint8)
>>> torch.eq(torch.tensor([[1, 2], [3, 4]]), torch.tensor([[1, 1], [4, 4]]))
tensor([[ 1, 0],
[ 0, 1]], dtype=torch.uint8)
torch.ge(input, other, out=None) # input>= other
torch.gt(input, other, out=None) # input>other
torch.le(input, other, out=None) # input=<other
torch.lt(input, other, out=None) # input<other
torch.ne(input, other, out=None) # input != other 不等于
torch.max() # 返回最大值
torch.min() # 返回最小值
torch.isnan(tensor) #判断是否为’nan’
torch.sort(input, dim=None, descending=False, out=None) #对目标input进行排序
torch.topk(input, k, dim=None, largest=True, sorted=True, out=None) #沿着指定维度返回最大k个数值及其索引值
torch.kthvalue(input, k, dim=None, deepdim=False, out=None) #沿着指定维度返回最小k个数值及其索引值
频谱操作
torch.fft(input, signal_ndim, normalized=False)
torch.ifft(input, signal_ndim, normalized=False)
torch.rfft(input, signal_ndim, normalized=False, onesided=True)
torch.irfft(input, signal_ndim, normalized=False, onesided=True)
torch.stft(signa, frame_length, hop, …)
其他操作
torch.cross(input, other, dim=-1, out=None) #叉乘(外积)
torch.dot(tensor1, tensor2) #返回tensor1和tensor2的点乘
torch.mm(mat1, mat2, out=None) #返回矩阵mat1和mat2的乘积
torch.eig(a, eigenvectors=False, out=None) #返回矩阵a的特征值/特征向量
torch.det(A) #返回矩阵A的行列式
torch.trace(input) #返回2-d 矩阵的迹(对对角元素求和)
torch.diag(input, diagonal=0, out=None) #
torch.histc(input, bins=100, min=0, max=0, out=None) #计算input的直方图
torch.tril(input, diagonal=0, out=None) #返回矩阵的下三角矩阵,其他为0
torch.triu(input, diagonal=0, out=None) #返回矩阵的上三角矩阵,其他为0
自动微分库
PyTorch 中,所有神经网络的核心是 autograd包。autograd包为张量上的所有操作提供了自动求导机制。它是一个在运行时定义 ( define-by-run )的框架,这意味着反向传播是根据代码如何运行来决定的,并且每次迭代可以是不同的。
autograd.Variable 是这个包中最重要的类。它:
- 是张量的简单封装
- 记录了所有历史操作
- 将梯度保存在 .grad 中
- 可以帮助建立计算图
[图片上传失败...(image-6ee3bf-1634310841670)]
每次结束计算后,使用.backward()可以自动计算出所有梯度值:
>>> from torch.autograd import Variable
>>> x = torch.randn(3)
>>> x = Variable(x, requires_grad=True)
>>> y = x * 2
>>> while y.data.norm() < 1000:
... y = y * 2
...
>>> print(y)
Variable containing:
908.8007
549.7198
507.9812
[torch.FloatTensor of size 3]
# through .data we can access raw tensor
>>> print(y.data)
908.8007
549.7198
507.9812
[torch.FloatTensor of size 3]
# .grad_fn references a Function that has created the Variable
# (except for Variables created by the user - their grad_fn is None).
>>> print(y.grad_fn)
<MulBackward0 object at 0x7ffa1ea95470>
>>> print(x.grad_fn)
None
# we can call .backward() on a Variable to compute the derivatives.
# If Variable is a scalar (i.e. it holds a one element data), you don’t need to specify any arguments to backward(), however if it has more elements, you need to specify a gradient argument that is a tensor of matching shape.
>>> gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
>>> y.backward(gradients)
>>> print(x.grad)
Variable containing:
51.2000
512.0000
0.0512
[torch.FloatTensor of size 3]
神经网络
torch.nn包可以用来构建神经网络。一个nn.Module包含了layers和用于返回output的forward(input) 方法。
一般典型的神经网络训练步骤如下:
- 定义带学习参数 (learnable parameters or weights) 的神经网络;
- 输入数据集进行迭代计算;
- 使用神经网络处理输入;
- 计算损失;
- 将梯度返回到网络的参数中;
- 更新参数。
参考资料及相关材料
- Awesome-pytorch-list:目前已获12K Star,包含了NLP,CV,常见库,论文实现以及Pytorch的其他项目。
- PyTorch官方文档:官方发布的文档,十分丰富。
- Pytorch-handbook:GitHub上已经收获14.8K,pytorch手中书。
- PyTorch官方社区:在这里你可以和开发pytorch的人们进行交流。
- Tensor及其基本操作:罗列了Tensor各项操作
- 深入浅出PyTorch学习资料:教程浅显易懂,初学者必备。