深度学习常用语句for param in params问题:为什么修改param之后,params对应元素也随之改变?

python 复制代码
def sgd(params, lr, batch_size):  #@save
    """小批量随机梯度下降"""
    with torch.no_grad():
        for param in params:
            param -= lr * param.grad / batch_size
            param.grad.zero_()

sgd([w, b], lr, batch_size)

上述代码中,param遍历params的所有元素,并进行sgd梯度下降,但是其仅仅对param进行修改,为何params元素会随之改变?

于是我进行实验,发现无论是最简单的数组还是np.array(ndarray格式),都是只修改了param而不修改params,如下图所示:

于是询问copilot:

然而为何源码中的params会改变?继续询问:

继续:

由 你 发送:

为什么一个是副本,一个是引用,两者有什么区别,如何判断

由 Copilot 发送:

这是一个很好的问题!在 Python 中,变量是如何传递的取决于它们的类型和使用方式。让我们详细解释一下副本和引用的区别,以及如何判断它们:

副本

当你创建一个变量的副本时,你实际上是在内存中创建了一个新的对象,并将原始对象的值复制到这个新对象中。修改副本不会影响原始对象。

例如:

Python

复制代码
a = 10
b = a  # 创建副本
b += 5
print(a)  # 输出 10
print(b)  # 输出 15

.

在这个例子中,ab 是两个独立的变量,修改 b 不会影响 a

引用

当你创建一个变量的引用时,你实际上是在创建一个指向原始对象的指针。修改引用会直接影响原始对象。

例如:

Python

复制代码
a = [1, 2, 3]
b = a  # 创建引用
b.append(4)
print(a)  # 输出 [1, 2, 3, 4]
print(b)  # 输出 [1, 2, 3, 4]

在这个例子中,ab 指向同一个列表对象,修改 b 会直接影响 a

如何判断

判断一个变量是副本还是引用,主要取决于变量的类型和操作方式:

  1. 不可变对象(如整数、字符串、元组):赋值操作通常会创建副本。
  2. 可变对象(如列表、字典、集合):赋值操作通常会创建引用。

在你的代码中:

Python

复制代码
for param in params:
    param -= lr * param.grad / batch_size

paramparams 列表中的元素的引用,因此修改 param 会直接影响 params 列表中的元素。

于是可以肯定,数据类型不同,同样的语句,params会出现修改和不修改两种情况,见下图:

可见tensor类型是可以通过该语句直接修改params的值,而ndarray则不行。

相关推荐
大嘴皮猴儿3 小时前
零基础入门:跨境电商产品图片多语言翻译的完整流程与跨马翻译实操
大数据·数据库·人工智能·自动翻译·教育电商
明月醉窗台3 小时前
[Jetson] 在Jetson Xavier AGX编译opencv+cuda
人工智能·opencv·计算机视觉·cuda·jetson
秋名山码民3 小时前
2026 年生成式优化引擎新范式:陕西灵怡秦智科技灵怡云系统深度解析 —— 从流量争夺到语义共鸣的营销变革
人工智能·科技
Yao.Li3 小时前
Dify Workflow 硬核解读(万字长文)
人工智能·python
艾莉丝努力练剑3 小时前
【QT】QT快捷键整理
linux·运维·服务器·开发语言·图像处理·人工智能·qt
2601_955363153 小时前
B端拓客号码核验:行业困局拆解与技术升级的理性思考氪迹科技法人号码核验系统、阶梯式价格
大数据·人工智能
帐篷Li3 小时前
阿里林俊旸离职后首发长文:AI从“推理思维“迈向“智能体思维“的五大挑战
人工智能
一次旅行3 小时前
飞书接入龙虾后失联解决方法
前端·人工智能·chrome·飞书
2601_955363153 小时前
技术赋能B端拓客:号码核验行业的破局之路与价值深耕,氪迹科技法人,股东号码核验系统
大数据·人工智能
Th13360703 小时前
技术赋能B端拓客:号码核验行业的困局突破与发展新路径,氪迹科技股东号码筛选系统,阶梯式价格
大数据·人工智能