Pytorch学习——张量、计算图与 autograd

    技术2022-07-11  91

    张量

    张量是什么?

    张量是一个多维数组,它是标量、向量、矩阵的高维拓展。

    张量的属性和性质

    Variable

    Tensor

    Tensor 增加 3 种属性

    张量的创建

    1. 直接创建

    torch.tensor( data, # 数据, 可以是list, numpy dtype=None, # 数据类型,默认与data的一致 device=None, requires_grad=False, pin_memory=False) torch.from_numpy() # tensor 与原 ndarray 共享内存

    2. 依据数值创建

    # 依size创建全0张量 torch.zeros(*size, # size: 张量的形状, 如(3, 3)、 (3, 224,224) out=None, # 输出的张量,和返回的张量指向同一内存地址 dtype=None, layout=torch.strided, # 内存中布局形式, 有strided,sparse_coo等 device=None, requires_grad=False) # 依input形状创建全0张量 torch.zeros_like(input, # 创建与input同形状的全0张量 dtype=None, layout=None, device=None, requires_grad=False) # 全1张量,参数同上 torch.ones() torch.ones_like() # 依input形状创建指定数据的张量(剩余参数隐藏) # t = torch.full((3, 3), 1) torch.full(size, # 张量的形状, 如(3, 3) fill_value, # 张量的值 ) # 创建等差的1维张量 torch.arange(start=0, end, step=1) # 创建均分的1维张量 torch.linspace(start, end, steps=100) # 数列长度 # 创建对数均分的1维张量 torch.logspace(start, end, steps=100, # 数列长度 base=10.0) # 对数函数的底,默认为10 # 创建单位对角矩阵(2维张量) torch.eye(n, # 矩阵行数 m=None, # 矩阵列数 )

    3. 依概率分布创建张量

    # 生成正态分布(高斯分布) torch.normal(mean, std, out=None) 四种模式: mean为标量, std为标量 mean为标量, std为张量 mean为张量, std为标量 mean为张量, std为张量 # 生成标准正态分布 torch.randn(*size) # 张量的形状 torch.randn_like() # 在区间[0, 1)上,生成均匀分布 torch.rand(*size) torch.rand_like() # 区间[low, high)生成整数均匀分布 torch.randint() torch.randint_like() # 生成生成从0到n-1的随机排列 torch.randperm(n) # 以input为概率,生成伯努力分布( 0-1分布,两点分布) torch.bernoulli()

    张量的操作:拼接、切分、索引和变换

    张量拼接与切分

    拼接 # 将张量按维度dim进行拼接 torch.cat(tensors, # 张量序列 dim=0, # 要拼接的维度 out=None) torch.cat([torch.ones((2, 3)), torch.ones((2, 3))], dim=0) # 在第 0 维拼接,shape(4, 3) # 在 新创建的维度dim上 进行拼接 torch.stack(tensors, # 张量序列 dim=0, # 要拼接的维度 out=None) 切分 # 将张量按维度dim进行平均切分;返回值:张量列表 torch.chunk(input, # 要切分的张量 chunks, # 要切分的份数 dim=0) # 要切分的维度 # 将张量按维度dim进行切分;返回值:张量列表 torch.split(tensor, # 要切分的张量 split_size_or_sections, # 为int时,表示每一份的长度;为list时,按list元素切分 dim=0) # 要切分的维度

    张量索引与变换

    索引 # 在维度dim上,按index索引数据;返回值:依index索引数据拼接的张量 torch.index_select(input, # 要索引的张量 dim, # 要索引的维度 index, # 要索引数据的序号 torch.tensor([0, 2], dtype=torch.long) out=None) # 按mask中的True进行索引;返回值:一维张量 torch.masked_select(input, # 要索引的张量 mask, # 与input同形状的布尔类型张量 out=None) 变换 # 变换张量形状(注意事项:当张量在内存中是连续时,新张量与input共享数据内存) torch.reshape(input, shape) # 交换张量的两个维度 torch.transpose(input, # 要变换的张量 dim0, # 要交换的维度 dim1) # 要交换的维度 # 2维张量转置 torch.t(input) # 压缩长度为1的维度(轴) torch.squeeze(input, dim=None, # 若为None,移除所有长度为1的轴;若指定维度,当且仅当该轴长度为1时,可以被移除; out=None)

    张量数学运算

    # 加减乘除 torch.add() torch.addcdiv() torch.addcmul() torch.sub() torch.div() torch.mul() # 对数,指数,幂函数 torch.log(input, out=None) torch.log10(input, out=None) torch.log2(input, out=None) torch.exp(input, out=None) torch.pow() # 三角函数 torch.abs(input, out=None) torch.acos(input, out=None) torch.cosh(input, out=None) torch.cos(input, out=None) torch.asin(input, out=None) torch.atan(input, out=None) torch.atan2(input, other, out=None) # 逐元素计算 # input + alpha × other torch.add(input, # 第一个张量 alpha=1, # 乘项因子 other, # 第二个张量 out=None)

    计算图与动态图机制

    计算图:用来描述运算的有向无环图

    计算图有两个主要元素: 结点( Node)和边( Edge)

    结点表示数据,如向量,矩阵,张量

    边表示运算,如加减乘除卷积等

    叶子结点:用户创建的结点称为叶子结点,如 X 与 W

    is_leaf: 指示张量是否为叶子结点

    grad_fn: 记录创建该张量时所用的方法(函数)

    动态图vs 静态图

    根据计算图搭建方式,可将计算图分为动态图和静态图

    动态图:运算与搭建同时进行;灵活 易调节

    静态图:先搭建图, 后运算;高效 不灵活

    autograd

    autograd—自动求导系统

    # 自动求取梯度 torch.autograd.backward(tensors, # 用于求导的张量,如 loss grad_tensors=None, # 多梯度权重 retain_graph=None, # 保存计算图 create_graph=False) # 创建导数计算图,用于高阶求导 # 求取梯度 torch.autograd.grad(outputs, # 用于求导的张量,如 loss inputs, # 需要梯度的张量 grad_outputs=None, retain_graph=None, create_graph=False) 如果想保存计算图再次计算,retain_graph 需要设置为 Truegrad_tensors 传入一个张量,不同的梯度有不同的权重torch.autograd.grad() 能计算多阶导数(比如二阶为调用两次,每次的 output 参数不同)

    注意:

    计算梯度后梯度不会自动清零,需要手动 w.grad.zero_()依赖于叶子结点的结点, requires_grad 默认为 True叶子结点不可执行 in-place 操作,否则反向传播无法计算
    Processed: 0.028, SQL: 9