当前位置: 首页 > article >正文

深度学习day2-Tensor 2

六 Tensor常见操作

Tensor:多维数组,用于存储和操作数据

1 获取元素值

data.item():单个元素tensor转为python数值

import torch
#标量
x=torch.tensor(1)
print(x.item())
#一阶
x=torch.tensor([100])
print(x.item())
#如果输入的数据超过1个,就不能用item函数取
#取出来的是基本数据的数字
x=torch.tensor([1,2])
print(x.item())

2 元素值运算

加减乘除幂次方取余取整等,带有_的方法会替换原始值

import torch
def test01():
    #带_结尾的函数基本都是直接操作原tensor
    x=torch.manual_seed(66)
    x=torch.randint(1,10,(3,3))
    print(x)
    #加
    x2=x.add(100)#返回一个新的数
    print(x2)
    x.add_(200)
    print(x)
    #减
    x=x.sub(1)
    print(x)
    x.sub_(100)
    print(x)
    #乘
    x=x.mul(2)
    print(x)
    x=x.mul_(2)
    print(x)
    #除
    x=x.div(4)
    print(x)
    x.div_(2)
    print(x)
​
    x=x.pow(2)#平方
    print(x)
​
    x=x**2
    print(x)
    x=x+10
    print(x)
    x=x-10
    print(x)
    x=x*10
    print(x)
    x=x/2
    print(x)
    x=x//2#取整
    print(x)
    x=x%2#取余
    print(x)
    x-=100#x=x-100
    print(x)
​
​
​
​
if __name__=='__main__':
    test01()

3 阿达玛积

矩阵对应位置的元素相乘,mul函数或者*

import torch
def test():
    x1=torch.tensor([1,2],
                   [3,4])
    x2=torch.tensor([1,2],
                   [3,4])
    #阿达玛积时必须形状一样
    x3=x1*x2
    print(x3)
    x4=x1.mul(x2)
    print(x4)
    
   
if __name__=='__main__':
    test()

4 Tensor相乘

将两个向量映射为一个标量,如果第一个矩阵是(N,M),那么第二个矩阵的shape必须是(M,P),最后两个矩阵的点积运算的shape为(N,P),使用@或者matmul完成

mm只能用于2维矩阵

import torch
def test2():
    x1=torch.tensor([1,2],
                   [3,4])
    x2=torch.tensor([1,2],
                   [3,4])
    x3=torch.matmul(x1,x2)
    x3=x1.matmul(x2)
    x3=x1 @ x2
    x3=x1.mm(x2)
    print(x3)
​
    x=torch.randint(1,4,(3,3,3))
    print(x)
    x2=torch.tensor(1,4,(3,3,3))
    print(x2)
    x3=x@x2
    x3=x.matmul(x2)
    print(x3)
    
if __name__=='__main__':
    test2()

5 索引操作

1.简单索引

根据指定的下标选取数据

import torch
​
​
def test():
    data = torch.randint(0, 10, (3, 4))
    print(data)
    # 1. 行索引
    print("行索引:", data[0])
    
    # 2. 列索引
    print("列索引:", data[:, 0])
    
    # 3. 固定位置索引:2种方式都行
    print("索引:", data[0, 0], data[0][0])
​
​
if __name__ == "__main__":
    test()

2.列表索引

import torch
def test():
    torch.manual_seed(66)
    x=torch.randint(1,10,(5,5,3))#5个模块,模块里面的size是(5×3)
    print(x)
    print(x.shape)
    print(x[1])#取下标为1,实际上排序为第2个的模块
    print(x[1,2])#取模块下标为1行数下标为2的数据
    print(x[1,2,1].item())#取出实际上排序为第2个模块里面第3行2列的数据6
    print(x[0:2])#0,1
    print(x[0:2,1])#第1个第2个模块里面的第2行
    print(x[0:2,1:3])#第1个第2个模块里面的第2.3行
    print(x[0:2,1:3,2])#第1个第2个模块里面的第2.3行的第3列
    print(x[[1,3]])#第2和第4个模块
    print(x[[1,3],1])#第2和第4个模块的第2行
    print(x[[1,3],[1,2]])#取第2个模块的第2行和第4个模块的第3行,并非笛卡尔积坐标,而是:[1,1]×[3,2]
    print(x[2,[1,3],0:2])#取第3个模块的2.4行的1-2列数据
    #注意点:如果填列表,那么列表中的下标的数字是讲究顺序的
    print(x[[3,1]])#可以不按顺序取,结果是有顺序的
    print(x[[1,3]])
    #切片:冒号左右两边不写就表示到开头或者末尾
    print(x[0,1,:2])
    print(x[-1])
    print(x[:-1])#不取最后一个
    print(x[:-2])
    print(x[1][1][1])#[]:成员访问符
    print(x[1,1])
    print(x[[1,1]])
 
​
if __name__ == "__main__":
    test()

3.布尔索引

def tool(x):
    return x%2==0#进行布尔运算得到跟tensor形状一样的布尔数组, 算术运算符例如x-得到原来的tensor
​
def test2():
    #tensor的布尔运算
    torch.manual_seed(66)
    x=torch.randint(1,10,(5,5))
    print(x)
    x2=x>8
    print(x2)
    x3=x[x2]
    print(x3)
    print(x[x==5])
    print(x[x%2==1])#取出所有的奇数
    print(x[tool(x)])
    
   
​
if __name__ == "__main__":
    test2()
#思考:找出第一列是偶数 第二列是奇数 第三列是闰年的行中的第4列和第5列数据
​
x=torch.tensor([],
               [],
               [])
​
x[:,0]%2==0
x[:,1]%2==1
(x[:,2]%4==0 and x[:,2]%100!=0) or (x[:,2]%400==0 )
x[:,3:5]

4.索引赋值

def test3():
    torch.manual_seed(66)
    x=torch.randint(1,10,(5,5))
    print(x)
    x2=x[1,1]
    print(x2)
    x[1,1]=100
    print(x)
    x[:,3]=200
    print(x)
    x[:,:]=99
    x.fill_(66)
    print(x)
​
​
if __name__=='__main__':
    test3()

6 张量拼接

cat:在现有的维度上拼接,不会增加新维度

stack:在新维度上堆叠,会增加一个新维度

1.torch.cat

orch.cat(concatenate):在现有维度上将多个张量连接到一起,这些张量在除了指定拼接的维度之外的所有维度上的大小必须相同

import torch
def test01():
    torch.manual_seed(66)
    x=torch.randint(1,10,(3,3))
    y=torch.randint(1,10,(2,3))
    print(x)
    print(y)
    z=torch.cat([x,y],dim=0)#0是行1是列#不能在1的维度上拼接,因为x有3行y只有2行
    print(z)
    
  
  if __name__=='__main__':
    test01()

2.torch.stack

torch.stack:在新维度上拼接张量,它会增加一个新的维度,然后沿着指定维度堆叠张量。这些张量必须具有相同的形状。

堆叠指沿着某个维度一人出一个交替添加(stack)

拼接指一人出完下个人再出完(cat)

import torch
def test02():
    torch.manual_seed(66)
    x=torch.randint(1,10,(3,3))
    y=torch.randint(1,10,(3,3))
    print(x)
    print(y)
    z=torch.stack((x,y),dim=0)#维度的堆叠
    z=torch.stack([x,y],dim=1)
    print(z)
​
def test03():
    torch.manual_seed(66)
    x=torch.randint(1,10,(3,3,2))
    y=torch.randint(1,10,(3,3,2))
    print(x)
    print(y)
    z=torch.stack([x,y],dim=3)
    print(z)
    
def test04():
    #加载本地图片为PIL对象
    img_pil=Image.open('./data/1.png')
    #把pil对象转化为张量
    transfer=transforms.ToTensor()
    img_tensor=transfer(img_pil)
    print(img_tensor)
    print(img_tensor.shape)
    print(img_tensor.shape)
    print(img_tensor)
    res=torch.stack([img_tensor[0],img_tensor[1],img_tensor[2]],dim=2)
    print(res,res.shape)
    print(sum(sum(res>100)))
​
if __name__=='__main__':
   test02()

7 形状操作

1.reshape

转换后的形状与原始形状具有相同的元素数量

import torch
def test01():
    x=torch.randint(1,10,(4,3))
    print(x)
    #reshape改变形状
    x2=torch.reshape(x,(2,6))#改变原x的数据内存空间和连续性,生成新的数据内存空间(具有连续性)
    print(x2)
    x3=torch.reshape(x,(2,2,3))
    print(x3)
    x4=torch.reshape(x,(3,5))#改变形状后的数量不能改变
    print(x4)
    #-1表示自动计算
    x5=torch.reshape(x,(-1,6))#-1相当于替代符,当不知道该填多少可以用-1替代
    print(x5)
    print(torch.reshape(x,(2,2,-1)))#-1表示某个维度的数量推出来,但是只能有一个维度为-1
    
   
​
if __name__=='__main__':
   test01()

2.view

特征:张量在内存中是连续的;返回的是原始张量视图,不重新分配内存,效率更高;

def test02():
    #内存上具有连续性才能view
    x=torch.randint(1,10,(4,3))
    print(x)
    x2=x.view((2,6))#view操作的是连续的原始张量视图,不重新分配内存,只是重新编了一个下标,速度快
    print(x2)#改变形状,由于没有改变原x中的数据内存空间,因此它改变形状比reshape快
​
    #非连续性不能view
    #x3=torch.randint(1,10,(4,3))
    #x4=torch.reshape(x3,(2,6))
    # x4=x3.t()#转置后x4的数据在内存中不连续
    # print(x4)
    # x5=x4.view(1,12)#改变形状,在内存中不连续的数据不能通过view来转换
    # print(x5)
​
    #改变形状后,数据是否共享内存
    x6=torch.randint(1,10,(4,3))
    x7=x6.view(2,6)
    x6[1,1]=100
    print(x6,x7)
    
   
 if __name__=='__main__':
   test02()

view:高效,但需要连续性

reshape:灵活,但涉及内存复制

3.transpose

用于交换张量的两个维度,返回原张量的视图(内存)

def test03():
    x=torch.randint(1,10,(4,3,2))
    print(x,x.shape)
    x2=torch.transpose(x,0,1)#只调换前2个维度
    print(x2,x2.shape)
    
  
 if __name__=='__main__':
   test03()

4.permute

用于改变张量的所有维度顺序,可以交换多个维度

def test04():
    x=torch.randint(0,255,(3,512,360))#包不包含255
    print(x)#(C,h,w)(0,1,2)
    x2=x.permute(1,2,0)#(h,w,c)
    print(x2,x2.shape)
   
  
 if __name__=='__main__':
   test04()

5.flatten

用于将张量展平为一维向量

tensor.flatten(start_dim=0, end_dim=-1)

  • start_dim:从哪个维度开始展平。

  • end_dim:在哪个维度结束展平。默认值为 -1,表示展平到最后一个维度。

def test05():
    x=torch.randint(0,255,(3,4))
    x2=x.flatten()
    print(x2)
​
    x=torch.randint(0,255,(3,4,2,2))
    x2=x.flatten(start_dim=1,end_dim=2)#(3,[],2)
    print(x)
    print(x2)
    
  
 if __name__=='__main__':
   test05()

6升维和降维

  • unsqueeze:用于在指定位置插入一个大小为 1 的新维度。

  • squeeze:用于移除所有大小为 1 的维度,或者移除指定维度的大小为 1 的维度。

1.squeeze降维
def test06():
    #数据降维
    x=torch.randint(0,255,(1,3,4,1))
    print(x)
    x2=x.squeeze()#全部
    print(x2)
    x3=x.squeeze(0).squeeze(-1)#指定维度
    print(x3)
    
 if __name__=='__main__':
   test06()

2.unsqueeze升维

def test07():
    #数据升维
    x=torch.randint(0,255,(3,4))
    print(x)
    x2=x.unsqueeze(0)
    print(x2)
    print(x2.shape)
​
    x2=x.unsqueeze(1)#(3,4)(3,1,4)
    print(x2)
    print(x2.shape)
 
if __name__=='__main__':
    test01()

8 张量分割

chunk(data,x):把data分成x份

split(data,x):把data按照大小为x进行分割

def test08():
    x=torch.randint(0,255,(21,4))
    x2=torch.split(x,2)#每个tensor有2行
    print(x2)
    x3=torch.chunk(x,2)#分割成2份
    print(x3)
​
​
​
if __name__=='__main__':
    test08()

9 广播机制

允许对不同形状的张量进行计算,广播机制会自动扩展较小维度的张量,使其与较大维度的张量兼容,实现计算

规则:每个张量的维度至少为1,满足右对齐

import torch
def test01():
    torch.manual_seed(66)
    x=torch.randint(1,10,(4,3))
    print(x)
    x2=torch.randint(1,10,(1,3))
    print(x2)
    x3=x+x2
    print(x3)
​
    x4=torch.randint(1,10,(4,3))
    x5=torch.randint(1,10,(4,1))
    print(x4)
    print(x5)
    x6=x4+x5
    print(x6)
def test02():
    data1d = torch.tensor([1, 2, 3])
    data2d = torch.tensor([[4], [2], [3]])
    print(data1d.shape, data2d.shape)
    # 进行计算:会自动进行广播机制
    print(data1d + data2d)
    
​
if __name__=='__main__':
    test01()
#2D和3D张量广播时会根据需要对两个张量进行形状扩展,从而能够进行运算。
​
def test003():
    # 2D 张量
    a = torch.tensor([[1, 2, 3], [4, 5, 6]])
    #2*3
    #2*2*3
    #[[[1, 2, 3], [4, 5, 6]],[[1, 2, 3], [4, 5, 6]]]
    
    # 3D 张量
    b = torch.tensor([[[2, 3, 4]], [[5, 6, 7]]])
    #2*1*3
    #2*2*3
    #[[[2, 3, 4],[2, 3, 4]], [[5, 6, 7],[5, 6, 7]]]
    print(a.shape, b.shape)
    
    # 进行运算
    result = a + b
    print(result, result.shape)
​
​
​
if __name__=='__main__':
    test03()

10 数学运算

1基本操作

import torch
def test():
    data = torch.tensor(
        [
            [1, 2, -3.5],  
            [4, 5, 6],  
            [10.5, 18.6, 19.6],  
            [11.05, 19.3, 20.6],  
        ]
    )
    print(data)
    x1=torch.floor(data)#向下取整(下指往下取整)
    print(x1)
    x2=torch.ceil(data)#向上取整(上指往大取整)
    print(x2)
    x3=torch.round(data)#四舍五入(内部用的py的round函数:四舍6入 5看整数的个位的奇数偶数,奇进偶不进)
    print(x3)
    x4=torch.trunc(data)#截断(只保留整数部分)
    print(x4)
    x5=torch.frac(data)#截断(只保留小数部分)
    print(x5)
    x6=torch.fix(data)#向0的方向取整,负数往向大的方向取整,正数往向小的方向取整
    print(x6)
    x7=data%2#取模
    print(x7)
    x8=torch.abs(data)#取绝对值(曼哈顿街道距离)
    print(x8)
    
if __name__=='__main__':
      test()
​

2三角函数

import torch   
def test02():
    #3.141592653  里面的是数字,相当于弧度
    print(torch.pi)
    deg=torch.pi/180#相当于度
    data=torch.tensor([0,90*deg,3])
    x=torch.sin(data)
    print(x)
    x=torch.cos(data)
    print(x)
    x=torch.sinh(data)#双曲正弦函数
    print(x)
    x=torch.cosh(data)#双曲余弦函数
    print(x)
    x=torch.tan(data)
    print(x)
    x=torch.tanh(data)#双曲正切函数
    print(x)
if __name__=='__main__':
     test02()

3统计学函数

import torch
import math
import cv2
def test03():
    torch.manual_seed(66)
    x=torch.randint(1,10,(4,3)).type(torch.float32)
    print(x)
    x1=x.mean()#平均数
    print(x1)
    x2=torch.mean(x)#平均数
    print(x2)
    x3=torch.sum(x)#求和
    print(x3)
    x5=torch.std(x)#标准差
    print(x5)
    x6=torch.var(x)#方差
    print(x6)
    x7=torch.median(x)#中位数
    print(x7)
    x8=torch.mode(x)#众数
    print(x8.values)
    x9=torch.max(x)#最大值
    print(x9)
    x9=torch.min(x)#最小值
    print(x9)
    x10=torch.sort(x)#排序
    print(x10)
    print(x10.values)#值
    print(x10.indices)#下标
    x11=x.sort()
    print(x11)
    arr=[8,10,11,13,14]
    res=arr.sort(key=lambda x:abs(x-10))#列表 谁离10近谁排前面
    print(res)
    def myabs(x):
        return abs(x-10)
    arr.sort(key=myabs)#列表
    print(arr)
    x=torch.tensor([1,1,1,2,3,4,5,2,3,4,5,6],dtype=torch.float32)
    print(torch.topk(x,3))#大概率是快排
    print(torch.histc(x,bins=5,min=2,max=4))#统计每个数出现的次数,指定个数
    print(torch.unique(x))#分类的数据集中看有几种类型
    print(torch.unique(x).shape)
    x=torch.tensor([1,1,1,2,3,4,5,2,3,4,5,6],dtype=torch.float32)
    print(torch.bincount(x))#统计每个数出现的次数,不指定个数
​
    img=cv2.imread("./data/1.png")
    img_tensor=torch.from_numpy(img).flatten()
    bincount=torch.bincount(img_tensor)
    print(bincount)
    res=torch.topk(bincount,1)#出现得最多的像素值
    print(res)
​
​
if __name__=='__main__':
    test()

11保存和加载

torch.save(x,"路径")

torch.load(x,"路径")

import torch
def test01():
    x=torch.tensor([1,2,3])
    torch.save(x,"./data/tensor.pth")#保存
​
def test01():
    device=torch.device("cuda" if torch.cuda.is_available() else "cpu")
    x=torch.load("./data/tensor.pth",map_location=device)#加载到指定设备
    x=x.cuda()#返回一个新的
    x=x.to("cuda")#返回一个新的
    print(x)
    print(x.device)
​
​
if __name__=='__main__':
    test01()

12并行化

torch.get_num_threads()#获取cpu的线程

torch.set_num_threads(4)#设置pytorch使用cpu的线程数量

import torch
def test03():
    count=torch.get_num_threads()#获取cpu的线程
    print(count)
​
def test04():
    torch.set_num_threads(4)#设置cpu的线程
    count=torch.get_num_threads()#获取cpu的线程
    print(count)
​
if __name__=='__main__':
    test03()


http://www.kler.cn/a/405140.html

相关文章:

  • 【2024亚太杯亚太赛APMCM C题】数学建模竞赛|宠物行业及相关产业的发展分析与策略|建模过程+完整代码论文全解全析
  • 【Golang】协程
  • 【前端】JavaScript中的indexOf()方法详解:基础概念与背后的应用思路
  • 【接口封装】—— 1、加载样式表
  • (十八)JavaWeb后端开发案例——会话/yml/过滤器/拦截器
  • 【java基础】微服务篇
  • 【Git】git从暂存区中移除文件
  • 山泽HDMI切换器:提升家庭娱乐与办公体验的利器
  • 支持向量机SVM——基于分类问题的监督学习算法
  • HBase 原理
  • 蓝桥杯每日真题 - 第19天
  • 第27天 安全开发-PHP应用TP 框架路由访问对象操作内置过滤绕过核心漏洞
  • 生产环境centos8 Red Hat8部署ansible and 一键部署mysql两主两从ansible脚本预告
  • 经验笔记:远端仓库和本地仓库之间的连接(以Gitee为例)
  • 在Sui 区块链上创建、部署和管理 NFT 的完整教程
  • java 设计模式 模板方法模式
  • shell脚本-笔记25
  • leetcode105:从前序与中序遍历构建二叉树
  • Java API 学习指南:从入门到精通的全面指导
  • 2.13 转换矩阵
  • 【数据库知识】mysql进阶-Mysql数据库的主从复制
  • Spring Boot核心概念:日志管理
  • SAP FICO 资产会计AA后台配置 (上)
  • PHP顺序查找和二分查找(也叫做折半查找)算法
  • Block Successive Upper Bound Minimization Method(BSUM)算法
  • Android 使用 LiveData/OnCheckedChangeListener 来监听变量变化