pytorch线性回归代码_[PyTorch 学习笔记] 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()

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

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

  • tensors: 张量序列
  • dim: 要拼接的维度

代码示例:

t = torch.ones((2, 3))
# dim =2
t_stack = torch.stack([t, t, t], dim=2)
print("\nt_stack.shape:{}".format(t_stack.shape))
# dim =0
t_stack = torch.stack([t, t, t], dim=0)
print("\nt_stack.shape:{}".format(t_stack.shape))

输出为:

t_stack.shape:torch.Size([2, 3, 3])
t_stack.shape:torch.Size([3, 2, 3])

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

切分

torch.chunk()

torch.chunk(input, chunks, dim=0)

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

  • input: 要切分的张量
  • chunks: 要切分的份数
  • dim: 要切分的维度

代码示例:

a = torch.ones((2, 7))  # 7
list_of_tensors = torch.chunk(a, dim=1, chunks=3)   # 3
for idx, t in enumerate(list_of_tensors):
print("第{}个张量:{}, shape is {}".format(idx+1, t, t.shape))

输出为:

第1个张量:tensor([[1., 1., 1.],
        [1., 1., 1.]]), shape is torch.Size([2, 3])
第2个张量:tensor([[1., 1., 1.],
        [1., 1., 1.]]), shape is torch.Size([2, 3])
第3个张量:tensor([[1.],
        [1.]]), shape is torch.Size([2, 1])

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

torch.split()

torch.split(tensor, split_size_or_sections, dim=0)

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

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

代码示例:

t = torch.ones((2, 5))
list_of_tensors = torch.split(t, [2, 1, 2], dim=1)
for idx, t in enumerate(list_of_tensors):
print("第{}个张量:{}, shape is {}".format(idx+1, t, t.shape))

结果为:

第1个张量:tensor([[1., 1.],
        [1., 1.]]), shape is torch.Size([2, 2])
第2个张量:tensor([[1.],
        [1.]]), shape is torch.Size([2, 1])
第3个张量:tensor([[1., 1.],
        [1., 1.]]), shape is torch.Size([2, 2])

索引

torch.index_select()

torch.index_select(input, dim, index, out=None)

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

  • input: 要索引的张量
  • dim: 要索引的维度
  • index: 要索引数据的序号

代码示例:

# 创建均匀分布
t = torch.randint(0, 9, size=(3, 3))
# 注意 idx 的 dtype 不能指定为 torch.float
idx = torch.tensor([0, 2], dtype=torch.long)
# 取出第 0 行和第 2 行
t_select = torch.index_select(t, dim=0, index=idx)
print("t:\n{}\nt_select:\n{}".format(t, t_select))

输出为:

t:
tensor([[4, 5, 0],
        [5, 7, 1],
        [2, 5, 8]])
t_select:
tensor([[4, 5, 0],
        [2, 5, 8]])

torch.mask_select()

torch.masked_select(input, mask, out=None)

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

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

代码示例:

t = torch.randint(0, 9, size=(3, 3))
mask = t.le(5)  # ge is mean greater than or equal/   gt: greater than  le  lt
# 取出大于 5 的数
t_select = torch.masked_select(t, mask)
print("t:\n{}\nmask:\n{}\nt_select:\n{} ".format(t, mask, t_select))

结果为:

t:
tensor([[4, 5, 0],
        [5, 7, 1],
        [2, 5, 8]])
mask:
tensor([[ True,  True,  True],
        [ True, False,  True],
        [ True,  True, False]])
t_select:
tensor([4, 5, 0, 5, 1, 2, 5])

最后返回的是一维张量。

变换

torch.reshape()

torch.reshape(input, shape)

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

  • input: 要变换的张量
  • shape: 新张量的形状

代码示例:

# 生成 0 到 8 的随机排列
t = torch.randperm(8)
# -1 表示这个维度是根据其他维度计算得出的
t_reshape = torch.reshape(t, (-1, 2, 2))
print("t:{}\nt_reshape:\n{}".format(t, t_reshape))

结果为:

t:tensor([5, 4, 2, 6, 7, 3, 1, 0])
t_reshape:
tensor([[[5, 4],
         [2, 6]],

        [[7, 3],
         [1, 0]]])

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

代码示例:

# 修改张量 t 的第 0 个元素,张量 t_reshape 也会被改变
t[0] = 1024
print("t:{}\nt_reshape:\n{}".format(t, t_reshape))
print("t.data 内存地址:{}".format(id(t.data)))
print("t_reshape.data 内存地址:{}".format(id(t_reshape.data)))

结果为:

t:tensor([1024,    4,    2,    6,    7,    3,    1,    0])
t_reshape:
tensor([[[1024,    4],
         [   2,    6]],

        [[   7,    3],
         [   1,    0]]])
t.data 内存地址:2636803119936
t_reshape.data 内存地址:2636803119792

torch.transpose()

torch.transpose(input, dim0, dim1)

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

  • input: 要交换的变量
  • dim0: 要交换的第一个维度
  • dim1: 要交换的第二个维度

代码示例:

#把 c * h * w 变换为 h * w * c
t = torch.rand((2, 3, 4))
t_transpose = torch.transpose(t, dim0=1, dim1=2)    # c*h*w     h*w*c
print("t shape:{}\nt_transpose shape: {}".format(t.shape, t_transpose.shape))

结果为:

t shape:torch.Size([2, 3, 4])
t_transpose shape: torch.Size([2, 4, 3])

torch.t()

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

torch.squeeze()

torch.squeeze(input, dim=None, out=None)

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

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

代码示例:

    # 维度 0 和 3 的长度是 1
    t = torch.rand((1, 2, 3, 1))
    # 可以移除维度 0 和 3
    t_sq = torch.squeeze(t)
    # 可以移除维度 0
    t_0 = torch.squeeze(t, dim=0)
    # 不能移除 1
    t_1 = torch.squeeze(t, dim=1)
    print("t.shape: {}".format(t.shape))
    print("t_sq.shape: {}".format(t_sq.shape))
    print("t_0.shape: {}".format(t_0.shape))
    print("t_1.shape: {}".format(t_1.shape))

结果为:

t.shape: torch.Size([1, 2, 3, 1])
t_sq.shape: torch.Size([2, 3])
t_0.shape: torch.Size([2, 3, 1])
t_1.shape: torch.Size([1, 2, 3, 1])

torch.unsqueeze()

torch.unsqueeze(input, dim)

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

张量的数学运算

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

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

torch.add()

torch.add(input, other, out=None)
torch.add(input, other, *, alpha=1, out=None)

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

  • input: 第一个张量
  • alpha: 乘项因子
  • other: 第二个张量

torch.addcdiv()

torch.addcdiv(input, tensor1, tensor2, *, value=1, out=None)

计算公式为:out value

torch.addcmul()

torch.addcmul(input, tensor1, tensor2, *, value=1, out=None)

计算公式为:out input value tensor tensor

线性回归

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

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

  1. 确定模型:
  2. 选择损失函数,一般使用均方误差 MSE:。其中 是预测值, 是真实值。
  3. 使用梯度下降法求解梯度 (其中 是学习率),并更新参数:

代码如下:

import torch
import matplotlib.pyplot as plt
torch.manual_seed(10)

lr = 0.05  # 学习率

# 创建训练数据
x = torch.rand(20, 1) * 10  # x data (tensor), shape=(20, 1)
# torch.randn(20, 1) 用于添加噪声
y = 2*x + (5 + torch.randn(20, 1))  # y data (tensor), shape=(20, 1)

# 构建线性回归参数
w = torch.randn((1), requires_grad=True) # 设置梯度求解为 true
b = torch.zeros((1), requires_grad=True) # 设置梯度求解为 true

# 迭代训练 1000 次
for iteration in range(1000):

    # 前向传播,计算预测值
    wx = torch.mul(w, x)
    y_pred = torch.add(wx, b)

    # 计算 MSE loss
    loss = (0.5 * (y - y_pred) ** 2).mean()

    # 反向传播
    loss.backward()

    # 更新参数
    b.data.sub_(lr * b.grad)
    w.data.sub_(lr * w.grad)

    # 每次更新参数之后,都要清零张量的梯度
    w.grad.zero_()
    b.grad.zero_()

    # 绘图,每隔 20 次重新绘制直线
    if iteration % 20 == 0:

        plt.scatter(x.data.numpy(), y.data.numpy())
        plt.plot(x.data.numpy(), y_pred.data.numpy(), 'r-', lw=5)
        plt.text(2, 20, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color':  'red'})
        plt.xlim(1.5, 10)
        plt.ylim(8, 28)
        plt.title("Iteration: {}\nw: {} b: {}".format(iteration, w.data.numpy(), b.data.numpy()))
        plt.pause(0.5)

        # 如果 MSE 小于 1,则停止训练
        if loss.data.numpy()             break

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

87a7b7575453f4c2bdaa55751e9ad1f1.gif


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

参考资料

  • 深度之眼 PyTorch 框架班

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/394759.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《UNIXLinux程序设计教程》一2.1 UNIX 输入输出基本概念

2.1 UNIX 输入输出基本概念 在任何一种操作系统中,程序开始读写一个文件的内容之前,必须首先在程序与文件之间建立连接或通信通道,这一过程称为打开文件。打开一个文件的目的可能是要读其中的数据,也可能是要往其中写入数据&…

c语言编常见算法,5个常见C语言算法

5个常见C语言算法十进制转换为二进制的递归程序字符串逆置的递归程序整数数位反序&#xff0c;例如12345->54321四舍五入程序(考虑正负数)二分法查找的递归函数#include#include#include//十进制转换为二进制的递归程序voidDecimalToBinary(int n){if(n<0){printf("…

利用Kinect将投影变得可直接用手操控

Finally 总算是到了这一天了&#xff01;假期里算法想不出来&#xff0c;或者被BUG折磨得死去活来的时候&#xff0c;总是YY着什么时候能心情愉快地坐在电脑前写一篇项目总结&#xff0c;今天总算是抽出时间来总结一下这神奇的几个月。 现在回过头来看&#xff0c;上学期退出AC…

springboot自动配置的原理_SpringBoot自动配置原理

SpringBoot的启动入口就是一个非常简单的run方法&#xff0c;这个run方法会加载一个应用所需要的所有资源和配置&#xff0c;最后启动应用。通过查看run方法的源码&#xff0c;我们发现&#xff0c;run方法首先启动了一个监听器&#xff0c;然后创建了一个应用上下文Configurab…

Django first lesson 环境搭建

pycharm ide集成开发环境 &#xff08;提高开发效率&#xff09; 解释器/编译器编辑器调试环境虚拟机连接 设置VirtualBox端口 操作1 操作2 点击号添加&#xff0c;名称为SSH&#xff0c;其中主机端口为物理机的端口&#xff0c;这里设置为1234&#xff0c;子系统端口为虚拟机的…

《Drupal实战》——3.3 使用Views创建列表

3.3 使用Views创建列表 我们接着讲解Views的设置&#xff0c;首先做一个简单的实例。 3.3.1 添加内容类型“站内公告” 添加一个内容类型“站内公告”&#xff0c;属性配置如表3-1所示。 为该内容类型设置Pathauto的模式news/[node:nid]&#xff0c;并且我们在这里将节点类型…

idea mybatis generator插件_SpringBoot+MyBatis+Druid整合demo

最近自己写了一个SpringBootMybatis(generator)druid的demo1. mybatisgenerator逆向工程生成代码1. pom文件pom文件添加如下内容&#xff0c;引入generator插件org.mybatis.generator mybatis-generator-maven-plugin 1.3.5 mysql …

python isalnum函数_探究Python中isalnum()方法的使用

探究Python中isalnum()方法的使用 isalnum()方法检查判断字符串是否包含字母数字字符。 语法 以下是isalnum()方法的语法&#xff1a; str.isa1num() 参数 NA 返回值 如果字符串中的所有字符字母数字和至少有一个字符此方法返回 true&#xff0c;否则返回false。 例子 下面的例…

动态规划算法——最长上升子序列

今天我们要讲的是最长上升子序列&#xff08;LIS&#xff09;。【题目描述】给定N个数&#xff0c;求这N个数的最长上升子序列的长度。【样例输入】      【样例输出】7        42 5 3 4 1 7 6那么什么是最长上升子序列呢&#xff1f; 就是给你一个序列…

如何快速掌握一门新技术/语言/框架

IT行业中的企业特点是都属于知识密集型企业。这种企业的核心竞争力与员工的知识和技能密切相关。而如果你在企业中扮演的是工程师的角色的话&#xff0c;那么 你的核心竞争力就是IT相关的知识与技能的储备情况。而众所周知&#xff0c;IT行业是一个大量产生新知识的地方&#x…

c语言今天星期几问题,C语言输入今天星期几

满意答案迷茫03222015.07.24采纳率&#xff1a;55% 等级&#xff1a;9已帮助&#xff1a;665人123456789101112131415161718192021#include<stdio.h>int main(void){ enum weekday{ sun, mon, tue, wed, thu, fri, sat }; int n; printf("输入星期数(0-…

备忘录模式 详解

定义 在不破坏封装性的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态&#xff1b; 行为型模式 角色 发起人角色&#xff08;Originator&#xff09;&#xff1a;记录当前时刻的内部状态&#xff0c;负责定义哪些属于备份范围的状态&#xf…

dll oem证书导入工具_技术干货 | 恶意代码分析之反射型DLL注入

欢迎各位添加微信号&#xff1a;qinchang_198231 加入安全 交流群 和大佬们一起交流安全技术01技术概要这是一种允许攻击者从内存而非磁盘向指定进程注入DLL的技术&#xff0c;该技术比常规的DLL注入更为隐蔽&#xff0c;因为除了不需要磁盘上的实际DLL文件之外&#xff0c;它…

锐捷亮相GITC:请互联网企业为我点个赞!

【51CTO.com原创稿件】GITC全球互联网技术大会已成功举办四届&#xff0c;今年的会议现场依然是摩肩接踵围观者众。围绕互联网热点技术&#xff0c;众人根据云、大数据、安全、运维、基础架构的不同主题&#xff0c;各自聚成小圈子展开深入交流。 锐捷的展位在主会场的内侧&…

react.lazy 路由懒加载_React lazy/Suspense使用及源码解析

React v16.6.0已经发布快一年了&#xff0c;为保障项目迭代发布&#xff0c;没有及时更新react版本&#xff0c;最近由于开启了新项目&#xff0c;于是使用新的react版本进行了项目开发。项目工程如何搭建&#xff0c;如何满足兼容性要求&#xff0c;如何规范化等等这里不作为介…

c语言数据结构系统化,C语言数据结构+数据库+操作系统

http://cv.qiaobutang.com/post/55c419b20cf2009bd4607795第二部分是专业相关的C &#xff0c;数据库&#xff0c;操作系统&#xff0c;数据结构。http://c.biancheng.net/cpp/u/shuju/数据(Data)是信息的载体&#xff0c;它能够被计算机识别、存储和加工处理。它是计算机程序加…

c语言判断一个序列是不是另一个的子序列

1 #include <stdio.h>2 #include <string.h>//添加字符串头文件3 4 int Subsequence(char s[], char t[]) 5 {6 int m,n,i,j;7 n strlen(s); //n表示序列S的长度8 m strlen(t); //m表示序列T的长度9 i0; 10 j0; 11 if (m>…

linux中python如何调用matlab的数据_特征锦囊:如何在Python中处理不平衡数据

今日锦囊特征锦囊&#xff1a;如何在Python中处理不平衡数据? Index1、到底什么是不平衡数据2、处理不平衡数据的理论方法3、Python里有什么包可以处理不平衡样本4、Python中具体如何处理失衡样本印象中很久之前有位朋友说要我写一篇如何处理不平衡数据的文章&#xff0c;整理…

Hadoop不适合哪些场景 哪些场景适合?

Hadoop设计的目的主要包括下面几个方面&#xff0c;也就是所谓的适用场景&#xff1a; 1&#xff1a;超大文件 可以是几百M&#xff0c;几百T这个级别的文件。 2&#xff1a;流式数据访问 Hadoop适用于一次写入&#xff0c;多次读取的场景&#xff0c;也就是数据复制进去之后&a…

阿里Android p6准备,项目经历准备篇——如何准备阿里巴巴P6/P7前端面试

项目经历准备篇——如何准备阿里巴巴P6/P7前端面试在上次的校招文章之后&#xff0c;有很多同学问有没有社招相关的东西可以写一篇&#xff0c;现在它来了。比起校招&#xff0c;社招更加看重项目经历项目经历反应的思考。本文针对的是想进入阿里的P6/P7同学&#xff0c;着重讲…