Python与PyTorch的浅拷贝与深拷贝

1.Python赋值操作的原理

在python中,x= something, 这样的赋值操作,准确的理解是:给存储something建立一个索引x (即存储地址), x通过访问something的存储内容,获得something的值。

在下面代码中:

# 情况1: 原变量地址不变,但是内容发生修改
a = torch.rand(4)
print('before a', a, id(a))
b = a 
print('before b', b, id(a))
a[2] = 5
print('after a', a, id(a))
print('after b', b, id(b))

输出:

before a tensor([0.7519, 0.1700, 0.7580, 0.2318]) 4613605632
before b tensor([0.7519, 0.1700, 0.7580, 0.2318]) 4613605632
after a tensor([0.7519, 0.1700, 5.0000, 0.2318]) 4613605632
after b tensor([0.7519, 0.1700, 5.0000, 0.2318]) 4613605632

解析:从上面id信息可以看出,在我们设置b = a 后,a,b均指向同一个内容。当对a[2]进行修改时,该地址内容变化后,对应a,b均发生变化。这是经典的使用赋值方法的浅拷贝方法。

# 情况2:原始变量指向新地址
a = torch.rand(4)
print('before a', a, id(a))
b = a 
print('before b', b, id(a))
a = torch.rand(4)
print('after a', a, id(a))
print('after b', b, id(b))
before a tensor([0.7991, 0.6592, 0.4349, 0.6903]) 4615172560
before b tensor([0.7991, 0.6592, 0.4349, 0.6903]) 4615172560
after a tensor([0.4795, 0.3145, 0.6954, 0.3496]) 4615149584
after b tensor([0.7991, 0.6592, 0.4349, 0.6903]) 4615172560

解析:b=a时,b指向a最初所指向的地址内容,后面重新对a的指向地址和内容进行更新,实际仅影响a的指向,对b没有影响。

2. copy()

copy()是python中常见的一个函数,属于浅拷贝的一种,但是在复制过程中会出现两种情况:

  • 第一种情况:当复制的对象种无复杂子对象的时候,原来值的改变不影响浅复制的值,同时原来值的id和浅拷贝的id不一致;
  • 第二种情况:当复制的对象种存在复杂子对象的时候,如果改变其中复杂子对象的值,浅复制的值也会发生改变;但是改变其他非复杂对象值,则不会影响赋值的值。主要原因是在 copy()中,将复杂子类使用一个公共镜像存储起来,当镜像改变了之后,另一个使用该镜像的值也发生改变。

import copy
a = [[1, 2], 3, 4]
print('before a', a, id(a))
b = copy.copy(a) 
print('before b', b, id(b))
a[0][0] = 0
print('after a', a, id(a))
print('after b', b, id(b))
a[2] = 5
print('after a', a, id(a))
print('after b', b, id(b))
before a [[1, 2], 3, 4] 4615194240
before b [[1, 2], 3, 4] 4614455104
after a [[0, 2], 3, 4] 4615194240
after b [[0, 2], 3, 4] 4614455104
after a [[0, 2], 3, 5] 4615194240
after b [[0, 2], 3, 4] 4614455104

3. deepcopy()

采用deepcopy函数进行赋值时,将被复制对象完全再复制一遍,生成一个新的独立的个体。

from copy import deepcopy
a = [[1, 2], 3, 4]
print('before a', a, id(a))
b = deepcopy(a) 
print('before b', b, id(b))
a[0][0] = 0
print('after a', a, id(a))
print('after b', b, id(b))
a[2] = 5
print('after a', a, id(a))
print('after b', b, id(b))
before a [[1, 2], 3, 4] 4614452352
before b [[1, 2], 3, 4] 4614564032
after a [[0, 2], 3, 4] 4614452352
after b [[1, 2], 3, 4] 4614564032
after a [[0, 2], 3, 5] 4614452352
after b [[1, 2], 3, 4] 4614564032

4. PyTorch中的深拷贝与浅拷贝

4.1. inplace=True

inplace=True的意思是原地操作,例如 x = x + 5, 就是对x进行原地操作,这样操作能够节省内存。

4.2. .Tensor, .tensor, .from_numpy, .as_tensor的区别

.Tensor和.tensor是深拷贝,在内存中创建一个额外的数据副本,不共享内存,所以不受数组改变的影响。

.from_numpy和as_tensor是浅拷贝,在内存中共享数据。

import numpy as np
import torcha = np.array([1, 2, 3, 4])
a1 = torch.from_numpy(a)
a2 = torch.Tensor(a)
a3 = torch.tensor(a)
a4 = torch.as_tensor(a)
print('before a', a, id(a))
print('before a1', a1, id(a1))
print('before a2', a2, id(a2))
print('before a3', a3, id(a3))
print('before a4', a4, id(a4))a[1] = 0
print('after a', a, id(a))
print('after a1', a1, id(a1))
print('after a2', a2, id(a2))
print('after a3', a3, id(a3))
print('after a4', a4, id(a4))
before a [1 2 3 4] 4615260944
before a1 tensor([1, 2, 3, 4]) 4615062928
before a2 tensor([1., 2., 3., 4.]) 4614685696
before a3 tensor([1, 2, 3, 4]) 4615208048
before a4 tensor([1, 2, 3, 4]) 4615436944
after a [1 0 3 4] 4615260944
after a1 tensor([1, 0, 3, 4]) 4615062928
after a2 tensor([1., 2., 3., 4.]) 4614685696
after a3 tensor([1, 2, 3, 4]) 4615208048
after a4 tensor([1, 0, 3, 4]) 4615436944

从这里来看,a和a1, a4两个变量相互影响。

4.3. .detach()和.clone()

.clone() 是深拷贝,创建新的存储地址,而不是引用保存旧的tensor,在梯度回传的时候,clone()充当中间变量,会将梯度传给源张量进行叠加,但是本身不保存其grad,值为None.

.detach()是浅拷贝,新的tesnor会脱离计算图,不回牵涉梯度计算。

import torchx = torch.tensor([2.0, 3.0, 4.0], requires_grad=True)
clone_x = x.clone()
detach_x = x.detach()
clone_detach_x = x.clone().detach()y = 2*x + 10
y.backward(torch.FloatTensor([1.0, 2.0, 1.0]))print(x.grad)
print(clone_x.requires_grad)
print(clone_x.grad)
print(detach_x.requires_grad)
print(clone_detach_x.requires_grad)
tensor([2., 4., 2.])
True
None
False
False
/var/folders/ll/nwlhsbw14ds8cs419pf18fn80000gn/T/ipykernel_20906/929467759.py:13: UserWarning: The .grad attribute of a Tensor that is not a leaf Tensor is being accessed. Its .grad attribute won't be populated during autograd.backward(). If you indeed want the .grad field to be populated for a non-leaf Tensor, use .retain_grad() on the non-leaf Tensor. If you access the non-leaf Tensor by mistake, make sure you access the leaf Tensor instead. See github.com/pytorch/pytorch/pull/30531 for more informations. (Triggered internally at /Users/runner/work/_temp/anaconda/conda-bld/pytorch_1670525473998/work/build/aten/src/ATen/core/TensorBody.h:485.)print(clone_x.grad)

4.4. contiguous函数

在pytorch中,很多操作都用到浅拷贝的思路,只是重新定义下标与元素的对应关系。

import torchx = torch.randn(3,2)
y = torch.transpose(x, 0, 1)
print('before')
print('x:', x)
print('y:', y)print('after')
y[0, 0] = 12
print('x:', x)
print('y:', y)

使用contiguous()之后,

import torchx = torch.randn(3,2)
y = torch.transpose(x, 0, 1).contiguous()
print('before')
print('x:', x)
print('y:', y)print('after')
y[0, 0] = 12
print('x:', x)
print('y:', y)

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

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

相关文章

一、1-2 5G-A通感融合基站产品及开通

1、通感融合定义和场景(阅读) 1.1通感融合定义 1.2通感融合应用场景 2、通感融合架构和原理(较难,理解即可) 2.1 感知方式 2.2 通感融合架构 SF(Sensing Function):核心网感知控制…

golang标准库path/filepath使用示例

文章目录 前言一、常用方法示例1.将相对路径转换为绝对路径2.获取路径中最后一个元素3.获取路径中除去最后一个元素的部分4.路径拼接5.将路径拆分为目录和文件名两部分6.返回一个相对路径7.文件路径遍历8.根据文件扩展名过滤文件9.使用正则表达式进行路径匹配 前言 path/filep…

HBase实训:纸币冠字号查询任务

一、实验目的 1. 理解分布式数据存储系统HBase的架构和工作原理。 2. 掌握HBase表的设计原则,能够根据实际业务需求设计合理的表结构。 3. 学习使用HBase Java API进行数据的插入、查询和管理。 4. 实践分布式数据存储系统在大数据环境下的应用,…

HarmonyOS NEXT应用开发边学边玩系列:从零实现一影视APP (三、影视搜索页功能实现)

在HarmonyOS NEXT开发环境中,可以使用nutpi/axios库来简化网络请求的操作。本文将展示如何使用HarmonyOS NEXT框架和nutpi/axios库,从零开始实现一个简单的影视APP,主要关注影视搜索页的功能实现。 为什么选择nutpi/axios? nutpi…

天机学堂3-ES+Caffeine

文章目录 day05-问答系统表 用户端分页查询问题目标效果代码实现 3.6.管理端分页查询问题ES相关 管理端互动问题分页实现三级分类3.6.5.2.多级缓存3.6.5.3.CaffeineTODO:使用Caffeine作为本地缓存,另外使用redis或者memcache作为分布式缓存,构…

重拾Python学习,先从把python删除开始。。。

自己折腾就是不行啊,屡战屡败,最近终于找到前辈教我 第一步 删除Python 先把前阵子折腾的WSL和VScode删掉。还是得用spyder,跟matlab最像,也最容易入手。 从VScode上搞python,最后安装到appdata上,安装插…

智能新浪潮:亚马逊云科技发布Amazon Nova模型

在2024亚马逊云科技re:Invent全球大会上,亚马逊云科技宣布推出新一代基础模型Amazon Nova,其隶属于Amazon Bedrock,这些模型精准切入不同领域,解锁多元业务可能,为人工智能领域带来革新。 带你认识一起了解Amazon Nova…

flutter 装饰类【BoxDecoration】

装饰类 BoxDecoration BoxDecoration 是 Flutter 中用于控制 Container 等组件外观的装饰类,它提供了丰富的属性来设置背景、边框、圆角、阴影等样式。 BoxDecoration 的主要属性 1.color 背景颜色。类型:Color?示例: color: Colors.blu…

Datawhale-self-llm-Phi-4 Langchain接入教程

本项目是一个围绕开源大模型、针对国内初学者、基于 AutoDL 平台的中国宝宝专属大模型教程,针对各类开源大模型提供包括环境配置、本地部署、高效微调等技能在内的全流程指导,简化开源大模型的部署、使用和应用流程,让更多的普通学生、研究者…

某讯一面,感觉问Redis的难度不是很大

前不久,有位朋友去某讯面试,他说被问到了很多关于 Redis 的问题,比如为什么用 Redis 作为 MySQL 的缓存?Redis 中大量 key 集中过期怎么办?如何保证缓存和数据库数据的一致性?我将它们整理出来,…

Python基于Django的图像去雾算法研究和系统实现(附源码,文档说明)

博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&#x1f3…

【开源免费】基于SpringBoot+Vue.JS欢迪迈手机商城(JAVA毕业设计)

本文项目编号 T 141 ,文末自助获取源码 \color{red}{T141,文末自助获取源码} T141,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

NVIDIA发布个人超算利器project digital,标志着ai元年的开启

上图NVIDIA公司创始人兼首席执行官 黄仁勋(Jensen Huang) 这些年被大家熟知的赛博朋克风格一直都是未来的代言词,可以承载人类记忆的芯片,甚至能独立思考的仿生人,现在,随着NVIDIA的project digital发布之后…

海云安开发者安全智能助手D10荣膺 “ AI标杆产品 ” 称号,首席科学家齐大伟博士入选2024年度 “ 十大杰出青年 ”

2024年12月27日,粤港澳大湾区AI领袖峰会在深圳成功举办,大会表彰了在人工智能技术创新、应用实践和产业发展等方面取得优异成绩的企业和个人,深圳海云安网络安全技术有限公司开发者安全智能助手D10荣膺“AI标杆产品”称号。同时,公…

第23篇 基于ARM A9处理器用汇编语言实现中断<五>

Q:怎样修改HPS Timer 0定时器产生的中断周期? A:在上一期实验的基础上,可以修改按键中断服务程序,实现红色LED上的计数值递增的速率,主程序和其余代码文件不用修改。 实现以下功能:按下KEY0…

R语言绘图

多组火山图 数据准备&#xff1a; 将CSV文件同一在一个路径下&#xff0c;用代码合并 确保文件列名正确 library(fs) library(dplyr) library(tidyr) library(stringr) library(ggplot2) library(ggfun) library(ggrepel)# 获取文件列表 file_paths <- dir_ls(path &quo…

项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(六)

文章目录 一、考试管理模块实现1、添加考试功能实现1.1 页面设计1.2 前端功能实现1.3 后端功能实现1.4 效果展示2、考试管理功能实现2.1 页面设计2.2 前端功能实现2.3 后端功能实现2.3.1 后端查询接口实现2.3.2 后端编辑接口实现2.3.3 后端删除接口实现2.4 效果展示二、代码下载…

HTML中如何保留字符串的空白符和换行符号的效果

有个字符串 储值门店{{thing3.DATA}}\n储值卡号{{character_string1.DATA}}\n储值金额{{amount4.DATA}}\n当前余额{{amount5.DATA}}\n储值时间{{time2.DATA}} &#xff0c; HTML中想要保留 \n的换行效果的有下面3种方法&#xff1a; 1、style 中 设置 white-space: pre-lin…

SpringMVC (2)

目录 1. RequestMapping 注解介绍 2. RequestMapping 使用 3. RequestMapping与请求方式 3.1 RequestMapping 支持Get和Post类型的请求 3.2 RequestMapping 指定接收某种请求 3.3 GetMapping和PostMapping 4. 传参 4.1 通过查询字符串传参 4.2 在 Body 中传参 4.2.1 …

RPA赋能内容创作:打造小红书入门词语图片的全自动化流程

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 用RPA全自动化批量生产【入门词语】图片做小红书商单&#xff0c;保姆级工具开发教程 最近由…