Pytorch训练过程中改变模型参数 requires_grad 属性

本文详细介绍了在PyTorch中使用多GPU进行模型训练的方法,包括如何利用DataParallel类实现模型的复制与分布式处理,以及如何正确设置参数的requires_grad属性确保所有GPU上的参数都能参与梯度回传。
部署运行你感兴趣的模型镜像

如果模型只在一块GPU上跑,该过程非常简单,只需要训练中途迭代model的 parameters,然后改变各个param的requires_grad 属性即可:

for name, param in model.named_parameters():
    logger.info('parameter of %s'%name)
    logger.info('before requires_grad is : %s'%param.requires_grad)
    param.requires_grad = True
    logger.info('after requires_grad is : %s' % param.requires_grad)

但是如果模型是跑在多块GPU上,就要搞清楚pytorch是如何对同一个Module对象进行分布式处理的。

可以肯定的是,pytorch将gpu_0上的模型进行复制,放到其他GPU上,可以使用DataParallel类:

model.to(device)
    if n_gpu > 1:
        model = torch.nn.DataParallel(model)

DataParallel类有一个数据成员:module,可以获得该用于复制的basic module,通过改变该basic module的参数的requires_grad 属性,即可达到模型在平行计算过程中,各个参数参与梯度回传迭代:

for name, param in model.module.named_parameters():
    logger.info('parameter of %s'%name)
    logger.info('before requires_grad is : %s'%param.requires_grad)
    param.requires_grad = True
    logger.info('after requires_grad is : %s' % param.requires_grad)

这里需要确定的是:pytorch是否是只迭代更新gpu_0上的模型的参数,然后将更新后的参数复制到其他gpu上?还是各个gpu单独迭代模型参数?如果是前者,上述操作即可完成训练过程中改变参数requires_grad 属性,如果是后者,那上面的操作只更新了gpu_0上模型的参数属性,其他gpu上的模型参数属性未更新,是错误的。

验证上述猜想:

pytorch在每次前向传播的过程中,都会将主GPU上的模型,分发给各个GPU上,所以,梯度更新只会在主GPU上,更新模型的requires_grad 属性也只需要在主GPU上即可,参考:https://www.cnblogs.com/jfdwd/p/11466126.html

DataParallel并行计算只存在在前向传播

那如何确定哪一块GPU是主GPU?

您可能感兴趣的与本文相关的镜像

PyTorch 2.8

PyTorch 2.8

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

PyTorch 里,`requires_grad` 是 Tensor 的一个关键属性,它在自动求导系统里起着核心作用,能够对张量的梯度计算进行灵活控制。 当 `requires_grad` 属性设置为 `True` 时,PyTorch 会自动追踪对该张量开展的所有操作,并且记录计算历史。在调用 `backward()` 函数时,就能根据记录的计算历史反向传播,从而计算出该张量相对于某个标量值的梯度。例如,以下代码展示了 `requires_grad=True` 时的情况: ```python import torch x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True) y = x * 2 z = y.mean() z.backward() print(x.grad) ``` 上述代码里,由于 `x` 的 `requires_grad` 设为 `True`,PyTorch 会记录从 `x` 到 `z` 的计算过程。调用 `z.backward()` 时,就能算出 `x` 的梯度。 若 `requires_grad` 属性设置为 `False`,PyTorch 就不会追踪该张量的操作,调用 `backward()` 时也不会计算其梯度。例如: ```python import torch x = torch.tensor([1.0, 2.0, 3.0], requires_grad=False) y = x * 2 z = y.mean() try: z.backward() except RuntimeError as e: print(f"Error: {e}") ``` 在这个例子中,因为 `x` 的 `requires_grad` 为 `False`,调用 `z.backward()` 时会报错。 `requires_grad_()` 函数可以改变 Tensor 的 `requires_grad` 属性,这是一个原位操作,默认参数为 `requires_grad=True`,其主要用途是告知自动求导开始记录对 Tensor 的操作[^2]。例如: ```python import torch x = torch.tensor([1.0, 2.0, 3.0]) x.requires_grad_() y = x * 2 z = y.mean() z.backward() print(x.grad) ``` 在神经网络训练中,`requires_grad` 非常实用。比如冻结预训练模型的部分层时,只需把这些层的参数的 `requires_grad` 设置为 `False`,就可以避免在反向传播时计算这些参数的梯度,从而节省计算资源。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值