1.3 张量操作与线性回归

本章代码:https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson1/linear_regression.py

张量的操作

拼接

torch.cat()

torch.cat(tensors, dim=0, out=None)

功能:将张量按照 dim 维度进行拼接

  • tensors: 张量序列

  • dim: 要拼接的维度

代码示例:

t = torch.ones((2, 3))
t_0 = torch.cat([t, t], dim=0)
t_1 = torch.cat([t, t], dim=1)
print("t_0:{} shape:{}\nt_1:{} shape:{}".format(t_0, t_0.shape, t_1, t_1.shape))

输出是:

t_0:tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]]) shape:torch.Size([4, 3])
t_1:tensor([[1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1.]]) shape:torch.Size([2, 6])

torch.stack()

功能:将张量在新创建的 dim 维度上进行拼接

  • tensors: 张量序列

  • dim: 要拼接的维度

代码示例:

输出为:

第一次指定拼接的维度 dim =2,结果的维度是 [2, 3, 3]。后面指定拼接的维度 dim =0,由于原来的 tensor 已经有了维度 0,因此会把tensor 往后移动一个维度变为 [1,2,3],再拼接变为 [3,2,3]。

切分

torch.chunk()

功能:将张量按照维度 dim 进行平均切分。若不能整除,则最后一份张量小于其他张量。

  • input: 要切分的张量

  • chunks: 要切分的份数

  • dim: 要切分的维度

代码示例:

输出为:

由于 7 不能整除 3,7/3 再向上取整是 3,因此前两个维度是 [2, 3],所以最后一个切分的张量维度是 [2,1]。

torch.split()

功能:将张量按照维度 dim 进行平均切分。可以指定每一个分量的切分长度。

  • tensor: 要切分的张量

  • split_size_or_sections: 为 int 时,表示每一份的长度,如果不能被整除,则最后一份张量小于其他张量;为 list 时,按照 list 元素作为每一个分量的长度切分。如果 list 元素之和不等于切分维度 (dim) 的值,就会报错。

  • dim: 要切分的维度

代码示例:

结果为:

索引

torch.index_select()

功能:在维度 dim 上,按照 index 索引取出数据拼接为张量返回。

  • input: 要索引的张量

  • dim: 要索引的维度

  • index: 要索引数据的序号

代码示例:

输出为:

torch.mask_select()

功能:按照 mask 中的 True 进行索引拼接得到一维张量返回。

  • 要索引的张量

  • mask: 与 input 同形状的布尔类型张量

代码示例:

结果为:

最后返回的是一维张量。

变换

torch.reshape()

功能:变换张量的形状。当张量在内存中是连续时,返回的张量和原来的张量共享数据内存,改变一个变量时,另一个变量也会被改变。

  • input: 要变换的张量

  • shape: 新张量的形状

代码示例:

结果为:

在上面代码的基础上,修改原来的张量的一个元素,新张量也会被改变。

代码示例:

结果为:

torch.transpose()

功能:交换张量的两个维度。常用于图像的变换,比如把c*h*w变换为h*w*c

  • input: 要交换的变量

  • dim0: 要交换的第一个维度

  • dim1: 要交换的第二个维度

代码示例:

结果为:

torch.t()

功能:2 维张量转置,对于 2 维矩阵而言,等价于torch.transpose(input, 0, 1)

torch.squeeze()

功能:压缩长度为 1 的维度。

  • dim: 若为 None,则移除所有长度为 1 的维度;若指定维度,则当且仅当该维度长度为 1 时可以移除。

代码示例:

结果为:

torch.unsqueeze()

功能:根据 dim 扩展维度,长度为 1。

张量的数学运算

主要分为 3 类:加减乘除,对数,指数,幂函数 和三角函数。

这里介绍一下常用的几种方法。

torch.add()

功能:逐元素计算 input + alpha * other。因为在深度学习中经常用到先乘后加的操作。

  • input: 第一个张量

  • alpha: 乘项因子

  • other: 第二个张量

torch.addcdiv()

计算公式为:out ${i}=\operatorname{input}{i}+$ value $\times \frac{\text { tensor } 1_{i}}{\text { tensor } 2_{i}}$

torch.addcmul()

计算公式为:out ${i}=$ input ${i}+$ value $\times$ tensor $1_{i} \times$ tensor $2_{i}$

线性回归

线性回归是分析一个变量 ($y$) 与另外一 (多) 个变量 ($x$) 之间的关系的方法。一般可以写成 $y=wx+b$。线性回归的目的就是求解参数$w, b$。

线性回归的求解可以分为 3 步:

  1. 确定模型:$y=wx+b$

  2. 选择损失函数,一般使用均方误差 MSE:$\frac{1}{m} \sum_{i=1}^{m}\left(y_{i}-\hat{y}{i}\right)^{2}$。其中 $ \hat{y}{i} $ 是预测值,$y$ 是真实值。

  3. 使用梯度下降法求解梯度 (其中 $lr$ 是学习率),并更新参数:

    • $w = w - lr * w.grad$

    • $b = b - lr * b.grad$

代码如下:

训练的直线的可视化如下:

在 80 次的时候,Loss 已经小于 1 了,因此停止了训练。

参考资料

如果你觉得这篇文章对你有帮助,不妨点个赞,让我有更多动力写出好文章。

我的文章会首发在公众号上,欢迎扫码关注我的公众号张贤同学

最后更新于

这有帮助吗?