张量操作与线性回归
张量操作与线性回归
1、张量的操作
拼接
torch.cat()
1 | torch.cat(tensors, dim=0, out=None) |
功能:将张量按照 dim 维度进行拼接
- tensors: 张量序列
- dim: 要拼接的维度
代码示例:
1 | t = torch.ones((2, 3)) |
输出是:
1 | t_0:tensor([[1., 1., 1.], |
torch.stack()
1 | torch.stack(tensors, dim=0, out=None) |
功能:将张量在新创建的 dim 维度上进行拼接
- tensors: 张量序列
- dim: 要拼接的维度
代码示例:
1 | t = torch.ones((2, 3)) |
输出为:
1 | t_stack.shape:torch.Size([2, 3, 3]) |
注:第一次指定拼接的维度 dim =2,结果的维度是 [2, 3, 3]。后面指定拼接的维度 dim =0,由于原来的 tensor 已经有了维度 0,因此会把tensor 往后移动一个维度变为 [1,2,3],再拼接变为 [3,2,3]。
切分
torch.chunk()
1 | torch.chunk(input, chunks, dim=0) |
功能:将张量按照维度 dim 进行平均切分。若不能整除,则最后一份张量小于其他张量。
- input: 要切分的张量
- chunks: 要切分的份数
- dim: 要切分的维度
代码示例:
1 | a = torch.ones((2, 7)) # 7 |
输出为:
1 | 第1个张量:tensor([[1., 1., 1.], |
注:由于 7 不能整除 3,7/3 再向上取整是 3,因此前两个维度是 [2, 3],所以最后一个切分的张量维度是 [2,1]。
torch.split()
1 | torch.split(tensor, split_size_or_sections, dim=0) |
功能:将张量按照维度 dim 进行平均切分。可以指定每一个分量的切分长度。
- tensor: 要切分的张量
- split_size_or_sections: 为 int 时,表示每一份的长度,如果不能被整除,则最后一份张量小于其他张量;为 list 时,按照 list 元素作为每一个分量的长度切分。如果 list 元素之和不等于切分维度 (dim) 的值,就会报错。
- dim: 要切分的维度
代码示例:
1 | t = torch.ones((2, 5)) |
结果为:
1 | 第1个张量:tensor([[1., 1.], |
索引
torch.index_select()
1 | torch.index_select(input, dim, index, out=None) |
功能:在维度 dim 上,按照 index 索引取出数据拼接为张量 返回。
- input: 要索引的张量
- dim: 要索引的维度
- index: 要索引数据的序号
代码示例:
1 | # 创建均匀分布 |
输出为:
1 | t: |
torch.mask_select()
1 | torch.masked_select(input, mask, out=None) |
功能:按照 mask 中的 True 进行索引拼接得到一维张量 返回。
- 要索引的张量
- mask: 与 input 同形状的布尔类型张量
代码示例:
1 | t = torch.randint(0, 9, size=(3, 3)) |
结果为:
1 | t: |
注:最后返回的是一维张量。
变换
torch.reshape()
1 | torch.reshape(input, shape) |
功能:变换张量的形状。当张量在内存中是连续时,返回的张量和原来的张量共享数据内存,改变一个变量时,另一个变量也会被改变。
- input: 要变换的张量
- shape: 新张量的形状
代码示例:
1 | # 生成 0 到 8 的随机排列 |
结果为:
1 | t:tensor([1, 7, 2, 5, 3, 6, 0, 4]) |
注:在上面代码的基础上,修改原来的张量的一个元素,新张量也会被改变。
代码示例:
1 | # 修改张量 t 的第 0 个元素,张量 t_reshape 也会被改变 |
结果为:
1 | t:tensor([1024, 4, 3, 6, 5, 2, 7, 0]) |
torch.transpose()
1 | torch.transpose(input, dim0, dim1) |
功能:交换张量的两个维度。常用于图像的变换,比如把c*h*w
变换为h*w*c
。
- input: 要交换的张量
- dim0: 要交换的第一个维度
- dim1: 要交换的第二个维度
代码示例:
1 | #把 c * h * w 变换为 h * w * c |
结果为:
1 | t shape:torch.Size([2, 3, 4]) |
torch.t()
功能:2 维张量转置,对于 2 维矩阵而言,等价于torch.transpose(input, 0, 1)
。
torch.squeeze()
1 | torch.squeeze(input, dim=None, out=None) |
功能:压缩长度为 1 的维度。
- dim: 若为 None,则移除所有长度为 1 的维度;若指定维度,则当且仅当该维度长度为 1 时可以移除。
代码示例:
1 | # 维度 0 和 3 的长度是 1 |
结果为:
1 | t.shape: torch.Size([1, 2, 3, 1]) |
torch.unsqueeze()
1 | torch.unsqueeze(input, dim) |
功能:根据 dim 扩展维度,长度为 1。
2、张量的数学运算
主要分为:加减乘除,对数,指数,幂函数 和三角函数。
这里介绍一下常用的几种方法。
torch.add()
1 | torch.add(input, other, out=None) |
功能:逐元素计算 input + alpha * other。因为在深度学习中经常用到先乘后加的操作。
- input: 第一个张量
- alpha: 乘项因子
- other: 第二个张量
torch.addcdiv()
1 | torch.addcdiv(input, tensor1, tensor2, *, value=1, out=None) |
计算公式为:out ${i}=\operatorname{input}{i}+$ value $\times \frac{\text { tensor } 1*{i}}{\text { tensor } 2*{i}}$
torch.addcmul()
1 | torch.addcmul(input, tensor1, tensor2, *, value=1, out=None) |
计算公式为:out ${i}=$ input ${i}+$ value $\times$ tensor $1*{i} \times$ tensor $2*{i}$
3、线性回归
线性回归是分析一个变量 ($y$) 与另外一 (多) 个变量 ($x$) 之间的关系的方法。一般可以写成 $y=wx+b$。线性回归的目的就是求解参数$w, b$。
线性回归的求解可以分为 3 步:
- 确定模型:$y=wx+b$
- 选择损失函数,一般使用均方误差 MSE:$\frac{1}{m} \sum*{i=1}^{m}\left(y*{i}-\hat{y}{i}\right)^{2}$。其中 $ \hat{y}{i} $ 是预测值,$y$ 是真实值。
- 使用梯度下降法求解梯度 (其中 $lr$ 是学习率),并更新参数:
- $w = w - lr * w.grad$
- $b = b - lr * b.grad$
代码如下:
1 | import torch |
训练的直线的可视化如下:
在 80 次的时候,Loss 已经小于 1 了,因此停止了训练。
原文作者: 贺同学
原文链接: http://clarkhedi.github.io/2021/04/05/zhang-liang-cao-zuo-yu-xian-xing-hui-gui/
版权声明: 转载请注明出处(必须保留原文作者署名原文链接)