size mismatch问题:训练权重不匹配问题
Posted python_Ezreal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了size mismatch问题:训练权重不匹配问题相关的知识,希望对你有一定的参考价值。
在测试二阶段和三阶段模型的时候程序一直报错:
RuntimeError: Error(s) in loading state_dict for Eff:
size mismatch for fc.weight: copying a param with shape torch.Size([18, 1000]) from checkpoint, the shape in current model is torch.Size([14, 1000]).
size mismatch for fc.bias: copying a param with shape torch.Size([18]) from checkpoint, the shape in current model is torch.Size([14]).
这个问题是参数的权重输出维度不同,查阅网上很多资料,也就是权重的fc层的参数不同,大佬都说把这个fc层忽略就好了。但是我找了好多感觉看不懂,最终找到了下面博主的博客。
https://blog.csdn.net/weixin_44966641/article/details/120083303
根据博主说的问题进行操作以后还是发现继续报错。
发现自己添加代码的位置错了:
eff_cls2(inner_model=Eff(num_classes=2), ckpt_path="D:\\\\a\\\\nzb_test-master\\\\nzb_test-master\\\\eff\\\\cls2.pth", data_pool=data_pool)
刚开始加在这里发现继续报错,问题一直得不到解决,然后就继续看自己的报错:
Traceback (most recent call last):
File "D:/a/nzb_test-master/nzb_test-master/test1.py", line 44, in <module>
data_pool=data_pool)
File "D:\\a\\nzb_test-master\\nzb_test-master\\process.py", line 318, in __init__
super().__init__(inner_model, ckpt_path, data_pool)
File "D:\\a\\nzb_test-master\\nzb_test-master\\process.py", line 39, in __init__
self.prepare()
File "D:\\a\\nzb_test-master\\nzb_test-master\\process.py", line 45, in prepare
self.inner_model.load_state_dict(ckpt)
File "D:\\ananconda\\envs\\yolo\\lib\\site-packages\\torch\\nn\\modules\\module.py", line 1498, in load_state_dict
self.__class__.__name__, "\\n\\t".join(error_msgs)))
发现错误在process里面的,于是我就进去找到了prepare函数,发现在里面找到了自己需要的东西,就根据博主的方法把下面两行代码加了进去。
ckpt.pop("fc.bias") ckpt.pop("fc.weight")
你的报错是什么,这里就些什么就好了,这个语句的意思是直接把权重当中的这两个层直接忽略掉,于是就不会进行报错了。
但是我的代码还在报错,没办法就回去继续看,发现我在引用模型的时候没有加strict=False,这个语句就是指忽略掉模型和参数文件中不匹配的参数。我的代码里面并没有,于是就这一句也加在了里面,代码就跑通了。
修改后的代码如下:
def prepare(self): self.inner_model.cuda() ckpt = torch.load(self.ckpt_path) ckpt.pop("fc.bias") ckpt.pop("fc.weight") self.inner_model.load_state_dict(ckpt,strict=False) self.inner_model.eval()
到此,错误完全解决了!!!!!!
ntQuerySystemInformtion 和它的 struct - size not mismatch 等疑问
【中文标题】ntQuerySystemInformtion 和它的 struct - size not mismatch 等疑问【英文标题】:ntQuerySystemInformtion and it's struct - size not mismatch and other doubts 【发布时间】:2020-11-26 02:08:18 【问题描述】:我很好奇为什么 API ntquerysysteminformtion 返回的大小不同于所有 nextEntryOffsets 的总和。我使用 SYSTEM_PROCESS_INFORMATION 结构调用 API,它返回按预期填充的结构的大小。
但是,如果我循环进入所有条目并对 NextEntryOffset 求和并与 API 返回的大小进行比较,它永远不会不匹配。
//call to API
int sum = 0;
pCurrent = nullptr;
pfw = (_SYSTEM_PROCESS_INFORMATION*)si;
do
pCurrent = pfw;
pfw = (_SYSTEM_PROCESS_INFORMATION*)((PUCHAR)pCurrent + pfw->NextEntryOffset);
sum += pCurrent->NextEntryOffset;
while (pCurrent->NextEntryOffset != 0);
如果我打印 API 返回的 sum 变量和长度的值,它们总是不相等的。
如果结构上没有字段,如何发现/计算每个条目的正确大小?我的猜测是它不起作用,因为在最后一个条目上 NextEntryOffset 为空,但这很奇怪,因为我看不到一种方法来计算每个条目的实际大小,而不仅仅是相信返回的长度。我想应该有办法吧?
我正在阅读非官方文档,它描述了在给定特定信息类(如我的)时,其输出缓冲区的开始以及整个缓冲区的不规则。我不明白它是如何工作的,但我假设,例如,如果有一个指向另一个结构的指针,这个指针大小 + 指向的数据或其他结构的大小被计算为总大小的一部分,这可能是动态的、正确的?
我还尝试查看此非官方文档中的字段偏移量是否按预期工作,但我未能访问它的内容。例如,它可以查看 UniqueProcessId 的假定地址,但是我找不到查看此地址内的值以确认的方法。
PVOID tmp = pCurrent + 0x50;
wprintf(L"ID: %d", *tmp);
失败了。我可以调用像 pCurrent.UniqueProcessId 这样的结构,它可以工作。但是如何在不依赖于结构的情况下移动数据呢?非常欢迎示例代码。
非常感谢。
【问题讨论】:
【参考方案1】:循环看起来正确。大小不匹配,因为您无法以这种方式测量返回缓冲区中最后一个结构的大小。发生了什么是结构是可变长度的。在现代 C 中,我们会将最后一个元素声明为 SYSTEM_THREAD_ENTRY 的灵活数组(其中大小在 NumberOfThreads 中给出),但来自 NTDLL 的东西是旧的。
编码它的“正确”方法(只要有任何权利)是将您需要的数据复制到您自己的数据结构中,然后丢弃原始缓冲区。
【讨论】:
感谢 Joshua 的快速回答,非常感谢。我不知道这种结构。有趣的是,我的声明中没有这个 SYSTEM_THREAD_ENTRY,我使用的是在互联网上找到的(来自 react OS?)。但是我有很多线程,但它没有成员。我不确定我失败的地方,是在结构定义上还是我需要对线程数和图像名进行一些手动求和,因为两者似乎都是可变的。您介意提供一个尺寸匹配的工作示例吗? :) 对不起,愚蠢的问题。如果我理解正确,当我调用 API 时,我并没有处理真实数据,它只是返回给我使用的副本,不是吗?只是为了理解和提高我与复制数据和丢弃原始数据相关的技能。我的意思是,即使我破坏了所有结构,我只会影响我自己的应用程序,因为原始结构从未发送给我,对吗? 所以要找出合适的尺寸,我应该像以前那样做我的总和 + pCurrent.numberofthreads * sizeof (struct SYSTEM_THREAD_ENTRY) 在每个条目中? @albfrk99:我认为你做不到。 API 可以返回一个有漏洞的数据结构。【参考方案2】:你得到的sum
只计算第一个到倒数第二个结构的长度,不包括最后一个的长度。正如其他答案所指出的,这是一个可变长度结构,每个结构在内存中紧跟一个或多个 SYSTEM_THREAD_INFORMATION
结构,这些结构为前面进程中的每个线程提供信息。
还有ImageName.Buffer
的内存空间(大小由系统决定),不用自己计算每个struct的大小,先通过NULL
得到需要的大小:
NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &length);
如果你想知道最后一个结构的大小,只需使用length-sum
。
另外,pCurrent + 0x50
等于&pCurrent[0x50]
,尝试用(char*)pCurrent + 0x50
测试。
变量数组见https://devblogs.microsoft.com/oldnewthing/20040826-00/?p=38043
【讨论】:
谢谢 Drake Wu - MSFT。我了解,以这种方式计算结构大小是不可能的。您说过调用 API 将第二个参数作为 NULL 传递,它将返回要分配的大小,但是如果在第二次调用时创建了一个新进程并且大小增加了怎么办?还是API保证当时的流程副本?关于在没有结构的情况下访问内容失败。我可以通过结构的成员和内存地址作为 pCurrent+offset 访问所有它们,但无论我用 (char *) 或类似的东西做什么,内容永远不会正确。以上是关于size mismatch问题:训练权重不匹配问题的主要内容,如果未能解决你的问题,请参考以下文章
pytorch 训练时错误size mismatch for module_list.88.Conv2d.weight: copying a param with shape torch.Size
解决vue版本不匹配的问题 Vue packages version mismatch:
ntQuerySystemInformtion 和它的 struct - size not mismatch 等疑问