即使没有进行前向传播,nn.ModuleList()的权重也会被调整

我在尝试使用nn.ModuleList()进行多任务学习,但当它们之前被训练过时,所有列表元素(即任务)的权重都会被调整。以下代码(基于这个笔记本)创建了一个名为MTL的神经网络对象。

...

神经网络的结构如下:

...

权重的初始值是(你的会有所不同):

...

输出:

...

以下代码训练了神经网络,并在每个epoch后打印权重。第一个epoch将训练共享层和nn.ModuleList()的第一个元素(即任务1)。第二个epoch将训练共享层和nn.ModuleList()的第二个元素(即任务2)。

...

输出:

...

在第一个epoch之后,任务1的权重被调整,但任务2的权重没有调整(符合预期),但在第二个epoch之后,两个任务的权重都被调整了。这不应该发生。

你也可以看到,当你在整个小批量中打印权重时(只需取消注释print语句),即使所有层都被冻结且没有进行计算,权重总是会为第一个任务调整。

除了optimizer.zero_grad()之外,还有什么其他缓存我需要清除吗?


回答:

如果你在训练过程中监控MTL.scoring_list[0][6].weight.gradMTL.scoring_list[1][6].weight.grad,你会注意到,在第一个epoch中,MTL.scoring_list[1][6].weight.grad是None,而在第二个epoch中,MTL.scoring_list[0][6].weight.grad是一个零张量。

查看各种优化器的.step()源代码,似乎它们并不检查.requires_grad。它们只检查.grad是否为None。所以即使.grad是一个零张量,optimizer.step仍然会执行其操作。这是否会影响冻结的权重,取决于优化器执行的具体计算。

作为一个快速修复,你可以在param.requires_grad = False之后添加param.grad = None,这样优化器就会完全忽略这些参数。这似乎解决了问题。但你可能仍然需要考虑这对优化器在未来epoch的计算有何影响。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注