本周完成的计划
论文阅读1
Abstract(摘要)
1. Introduction(介绍)
2. Methods(方法)
2.1. Positive Attention Shifting Block in fd1
2.2. Negative Attention Shifting Block in fd2
2.3. Loss Functions(损失函数)
3. Experiments(实验)
4. Results and Discussion(结果与讨论)
5. Conclusion(结论)
论文阅读2
Abstract(摘要)
1. INTRODUCTION(介绍)
2.METHODOLOGY(方法)
3.EXPERIMENTS(实验)
4.CONCLUSION(结论)
pytorch代码学习
1.易混模块和参数的函数
2.PyTorch深入了解模型保存
3.学习率调整策略
4.torchsummary:计算神经网络模型各层输出特征图的尺寸和参数
本周完成的计划
- 阅读半监督论文, Learning Morphological Feature Perturbations for Semi-Supervised Segmentation(半监督分割的形态学特征扰动学习)
- 回顾弱监督论文,Multi-Layer Pseudo-Supervision for Histopathology Tissue Semantic Segmentation using Patch-level Classification Labels(利用Patch组织病理学组织语义分类的多层伪监督法)
- 学习pytorch几个容易混淆的知识点
- 跑教师病理组织分割项目
论文阅读1
Learning Morphological Feature Perturbations for Semi-Supervised Segmentation(半监督分割的形态学特征扰动学习)
Abstract(摘要)
,它对学习特征的扰动有不变的预测。MisMatch由编码器和双头解码器组成。另一个解码器在相同的未标记图像上学习对前景的负面关注,从而产生被侵蚀的特征。然后,我们对成对预测应用的一致性正则,MisMatch在基于CT基于肺血管分割任务和MRI脑肿瘤分割任务的表现优于最先进的半监督方法。另外,我们表示,MisMatch它的有效性来自于比监督学习更好的模型校准。
1. Introduction(介绍)
半监督学习(SSL)旨在利用无标签数据解决标签稀缺问题。SSL成功是基于聚类假设,即属于同一聚类的数据点更有可能属于同一类别(Cahpelle等人,2006)。将聚类假设与平滑度假设相结合也很常见,平滑度假设认为数据点在聚类中心的密度更大。一个理想的聚类假设例子如下图1所示,一个是圆形的,另一个是三角形的,分别代表两个不同类别的数据点。当建立聚类假设时,最佳决策边界应位于两种不同类型的数据点之间的低密度区域。我们用图1来解释一致性的正则化SSL在分类中发挥作用的直观原因。
集群假设最佳决策边界位于低密度区域。。在这里,我们有两个圆和三角形数据点组。箭头:扰动。虚线:决策边界。
(a)干扰位于高密度区域的红色数据点时,两个红色干扰的数据点仍将分为同一圈,因此一致性损失为零;
(b)当干扰低密度区域的蓝色数据点时,两个蓝色干扰的数据点将有两个不同的预测值,这两个预测值之间的差异将有助于培训模型的一致性损失。聚类边缘数据点上的干扰将跨越低密度区域,导致分类结果错误,从而制定有效的一致性损失值,驱动决策边界向低密度区域移动。
2. Methods(方法)
MisMatch背后的总体概念是利用不同的注意力机制来分别扩张和侵蚀前景特征,这些特征在一个一致性驱动的框架中被结合起来进行半监督性分割。如图2所示,MisMatch是一个框架,可以集成到任何基于编码器-解码器的分割架构中。
MisMatch学习对前景的信心不变的预测:解码器fd1扩张前景特征,解码器fd2侵蚀前景特征。最后的预测是fd1和fd2的输出之间的平均值。可以使用任何编码器-解码器分割网络。
经典的形态学操作在图像层面上改变了前景的边界,而我们的网络拓扑结构被设计为影响特征层面。我们结合了两个概念。,研究结果(Wei等人,2018年;Chen等人,2017年;Luo等人,2016年;Xu等人,2020b)表明,
我们使用U-net(Ronneberger等人,2015)作为主干,因为它在医学成像领域很受欢迎。我们的MisMatch(图2)有两个组件:一个编码器(fe)和一个双头解码器(fd1和fd2)。
第一个解码器(fd1)包括一系列积极的注意力转移块,它扩张了前景。第二个解码器(fd2)包含一系列负面注意力转移块,它侵蚀了前景。第二个解码器(fd2)包含一系列负面注意力转移块,它侵蚀了前景。
2.1. Positive Attention Shifting Block in fd1
积极注意转移块(PASB)(图2中的粉色块)通过积极注意前景来扩张前景特征,每个PASB有两个平行的分支,即主分支和侧分支。
主分支用于处理视觉信息,它的结构与标准U-net中的解码器块相同,包括两个连续的卷积层,核大小为3,然后是ReLU和归一化层。侧枝被用来生成一个扩张的注意力掩码,以引导主枝放大其前景特征。为此,侧面分支使用了两个连续的Atrous卷积层,核大小为3,扩张率为5,每个卷积层后面都有ReLU和一个归一化层。为了学习每个像素的特征变化幅度,我们在侧枝的末端应用一个Sigmoid函数。我们使用侧枝的输出与主枝的输出进行元素明智的乘法,以扰乱主枝的特征。然后,我们在被扰动的主分支输出上应用一个跳过连接,以产生PASB的最终输出。
2.2. Negative Attention Shifting Block in fd2
负面注意力转移块(图2中的紫色块)利用对前景的负面注意力侵蚀前景特征。继PASB之后,我们再次将NASB设计成两个平行的分支。
主分支与PASB中的分支相同。侧枝与主枝相似,但在每个卷积层上有一个跳过连接。我们还在侧枝的输出上应用一个Sigmoid函数来学习每个像素的扰动幅度。我们还在侧枝的输出上应用一个Sigmoid函数来学习每个像素的扰动幅度。然后,我们把从侧面分支学到的侵蚀注意掩码与主分支的输出相乘,我们还在扰动的主分支输出上应用跳过连接,以产生NASB的最终输出。
2.3. Loss Functions(损失函数)
我们使用流式训练设置,以避免在有限的标记数据上过度拟合,因此模型在每个历时中不会重复看到标记数据。对于标记的数据,我们对每个解码器的输出应用标准的Dice损失(Milletari等人,2016)。对于无标签的数据,我们在两个解码器的输出之间应用了一个平均平方误差损失。这种一致性正则化是由介于(0.0005到0.004)之间的超参数α加权的。
3. Experiments(实验)
主干网是一个二维U型网(Ronneberger等人,2015),在第一个编码器中有24个通道。为了确保公平的比较,我们在所有基线上使用相同的U型网作为主干网。第一条基线在主干线上利用监督训练,用标记的数据进行训练,用翻转和高斯噪声进行增强,被称为 "Sup1"。为了研究无标签数据如何提高性能,我们的第二条基线 "Sup2 "利用MisMatch的监督训练,并进行同样的增强。因为MisMatch使用了一致性正则化,所以我们专注于与五种一致性正则化的SSL方法进行比较:
1)"平均教师"(MT)(Tarvainen和Valpola,2017),使用高斯噪声,它启发了目前大多数最先进的SSL方法。
2)目前最先进的模型称为 "FixMatch"(FM)(Sohn等人,2020)。为了使FixMatch适用于分割任务,我们使用高斯噪声作为弱增强,使用没有剪切的 "RandomAug"(Cubuk等人,2020)作为强增强。我们不使用剪切法进行扩增,因为它损害了成对密集输出的像素的空间对应关系。
3)采用多头解码器的最先进模型(Ouali等人,2020)进行分割(CCT),随机特征增强包括Dropout(Srivastava等人,2014)、V AT(Miyato等人,2017)和CutOut(DeVries和Taylor,2017)等,这一基线也与最近开发的模型相似(French等人,2020;Ke等人,2020)。
4)最近在医学成像方面又有一个模型(Chen等人,2019),使用图像重建作为额外的正则化(MTA),用高斯噪声增强。
5)一个带有两个标准解码器的U型网络,我们分别在每个解码器中直接对特征进行传统的侵蚀和扩张,并以高斯噪声(Morph)进行增强"。我们的MisMatch模型是在没有任何增强的情况下进行训练的。训练和实施的细节见附录A。
4. Results and Discussion(结果和讨论)
1)MisMatch的性能一直大大超过有监督的基线,例如在5个标记的切片上比Sup1提高24%,CARVE。
MisMatch(MM)与CAR VE上的基线对比。衡量标准是 "交叉联合"(IoU):10倍交叉验证下的平均值(std)。P值来自Mann-Whitney U-Test对MisMatch的测试。红色:最佳模型。蓝色:第二好的模型。
2)在表1中,MisMatch在不同的数据集上始终优于之前的SSL方法(Sohn等人,2020;Tarvainen和Valpola,2017;Chen等人,2019;Ouali等人,2020),例如在CARVE上使用6.25%的标签(100片与1600片全标签相比)时的统计差异(表1)。
3)训练数据的多样性对测试性能影响很大(图3),例如,在CAR VE的第3折中,MisMatch优于全标签训练,在第7和第8折中,MisMatch的表现与全标签训练相当,而在其他折中,MisMatch的表现比全标签训练差。
4)更多标记的训练数据始终产生较高的平均IU和较低的标准偏差(表2)。
我们对MisMatch解码器的结构进行了消融研究(图4),对CAR VE的5个标记的切片进行了交叉验证。
1) “MM-a”是一个双头U型网络,在解码器中带有标准卷积块,该模型可以被视为没有特征扰动,但是,由于随机初始化,它们本质上略有不同,我们将U型网络的解码器表示为fd0
2) “MM-b”是U-net的标准译码器和负注意转移译码器fd2,这一译码器介于无扰动和扰动之间;
3) “MM-c”是U-net的标准译码器和正注意转移译码器fd1,该译码器介于无扰动和学习扩张扰动之间;
4) “MM”,fd1和fd2(我们的)。
如图4所示,我们的MisMatch("MM")在10个实验中的8个实验中优于其他组合,在其余2个实验中,它的表现与其他组合相当。我们还用同样的实验设置在0、0.0005、0.001、0.002、0.004测试了α。最佳的α出现在表4中的0.002。
我们认为MisMatch利用未标记的图像来改善模型校准(Guo等人,2017),导致更好的分割性能。模型校准反映了网络预测的可信度,这在临床应用中是至关重要的。按照(Guo等人,2017),我们将Bm设定为预测置信度在区间Im内的所有像素的子集。我们将准确性定义为在每个置信区间内有多少像素被正确分类。
Bm的精确度是:其中,ˆyi是预测的标签,yi是Bm中像素i处的地面真实标签。Bm内的平均置信度是用ˆpi来定义的,它是网络在每个像素的原始概率输出:比较每个区间的准确度和置信度的图称为可靠性图(图5),准确度和置信度之间的差距称为预期校准误差,差距越小,网络的校准就越好。如图5所示,MisMatch产生了更好的校准预测结果。预期校准误差的分析见附录D。
5. Conclusion(结论)
。MisMatch通过减少90%以上所需的训练标签的数量,保证了强大的临床效用:当只对10%的标签进行训练时,MisMatch达到了与使用所有可用标签训练的模型(IoU:77%)相似的性能(IoU:75%)。未来的工作将把MisMatch扩展到多类3D任务,因为很多医学图像都是体积型的。
论文阅读2
Multi-Layer Pseudo-Supervision for Histopathology Tissue Semantic Segmentation using Patch-level Classification Labels(利用Patch级分类标签进行组织病理学组织语义分割的多层伪监督法)
Abstract(摘要)
在千兆像素的整张WSI图像上绘制这种标签是非常昂贵和耗时的。在本文中,我们patch级的我们提出了一个包括分类和分割阶段的两步模型。在分类阶段,我们提出了一个基于CAM的模型,通过斑块级标签生成伪掩码。在分割阶段,我们通过我们提出的多层伪监督实现了组织语义分割。我们提出的模型优于两种最先进的WSSS方法。
1. INTRODUCTION(介绍)
在本文中,我们提出了一个简单而有效的CNN模型,用于仅使用patch级注释的组织病理学组织语义分割。。
在分类阶段,我们提出了一个基于CAM的分类模型来生成伪标签。为了避免discriminative区域萎缩问题,我们提出了渐进式Dropout注意力(PDA),逐步停用高亮区域,并
在分割阶段,我们通过多层分类网络产生的伪掩码来训练一个语义分割模型,我们称之为多层伪监督(MLPS)。MLPS可以提供来自不同阶段的信息,以减少patch级和像素级标签之间的信息差距。此外我们提出了一个分类门机制,以减少非优势组织类别的假阳性率。
与完全监督模型相比,我们的模型显示了可比的定量和定性结果,对MIoU和FwIoU来说只有2%左右的差距。事实证明,所提出的模型比人工标注的速度快10倍。本文的主要贡献总结如下:
- 我们提出了一个只使用patch级分类标签的组织病理学图像的语义分割模型,这大大节省了病理学家的注释时间。
- 提出了具有渐进式Dropout关注的多层伪监督,以减少补丁级和像素级标签之间的信息差距。并引入了分类门机制以减少假阳性率。
- 我们提出的模型在两个数据集上与弱监督的语义分割模型相比,取得了最先进的性能,并与完全监督的基线性能相当。
- 第一个LUAD数据集被发布,用于弱监督的组织语义分割。
2.METHODOLOGY(方法)
在本文中,我们提出了一个组织语义分割模型,只使用patch级标签,以减轻注释工作。图2展示了我们提出的模型的系统设计。
让我们把分类阶段的给定训练数据表示为,
是分类模型的多标签预测分类结果,这个阶段的目标是只使用patch级标签y来生成密集的像素级伪标签p。
有了分类阶段产生的伪标签,我们可以为分割模型形成一个新的训练数据,即,其中P是X的伪标签集,具有参数φseg的分割模型fseg产生了最终的语义分割结果s。
在训练分类模型时,特征图(Class Activation Maps,CAM)提供了可用于物体定位和分割的 discriminative 物体位置线索。受此启发,,首先训练一个分类模型。由于组织的分布在某种程度上是随机和分散的,它可能在一个patch中包含多个组织类型。因此,。
如图2(a)所示,给定一个输入patch x,我们首先提取深层特征图,如下所示。
其中m表示从最后一层提取的特征图。为了提供更丰富、更全面的特征表示,我们提出了Progressive Dropout Attention ,以防止分类模型过度关注最具 discriminative 的区域。
其中A是Dropout注意力图。在Dropout Attention后,第k个组织类别的概率可以通过全局平均池和全连接层来计算。
其中GAP(-)表示全局平均池化。 Multi-label soft margin loss 被应用于分类网络中。
有了训练好的多标签分类模型,通过梯度加权类激活映射(Grad-CAM)为下一个分割模型生成像素级伪标签p。
虽然分类模型可以为分割任务提供空间位置线索,但这两个任务的目标仍然是不同的。随着训练过程的深入,从patch级标签到像素级标签仍然存在巨大的信息差距。因此,如何最大化这种稀疏注释的价值以缩小差距仍然是一个极端的任务。为了克服上述两个挑战,我们提出了渐进式Dropout注意力。
提出的Dropout Attention的想法是简单而直观的。我们希望神经网络能够从稀疏的标签中学习尽可能多的信息。在训练过程中,不允许分类模型只依靠最具鉴别力的区域来 "make easy money"。相反,CNN模型必须学习更完整和全面的空间信息。因此,我们将所有组织类别的类激活图中最significant的区域 deactivate,如图2(a)所示。
这样的策略会削弱最具discriminative的区域的贡献,迫使神经网络通过非优势区域进行多标签分类,在提取深层特征时可以有效扩大激活区域。根据这个想法,我们首先为每个类别生成一个类激活图(CAM),由特征图m的加权和组成。其中Mk表示第k类的CAM。
对于每个Mk,我们设置了一个dropout cutoff β,以deactivate最突出的区域,并刷新CAMs,如下所示。其中,i和j表示坐标,是有Dropout的CAM。
注意,β是一个相对值,它取决于类激活图的最大值,其中,μ是dropout系数。
最后,dropout注意力图A是所有deactivated CAM的平均值。
正如我们上面提到的,当训练过程进一步进行时,被激活的区域会逐渐缩小到一个较小的区域。根据这一观察,我们提出了一种基于dropout注意力的反向操作,称为渐进式dropout注意力(PDA)。PDA逐步扩大deactivated的区域,以对抗这种萎缩的问题。我们将原来的dropout系数μ重新设计为渐进式dropout系数,它不再是一个常量值。当训练epoch增加时,渐进式dropout系数μ将自适应地减少,直到μ满足下限l。
其中t是正在进行的epoch,σ是衰减率,我们在实践中设定σ=0.985,l=0.65。为了更好地初始化分类模型,在前三个epoch中,初始μ被设置为1。在第3个epoch后,我们开始dropout,并逐步扩大dropout区域,以逐渐增加分类的难度。有了渐进式dropout attention,discriminative区域收缩问题得到了极大的缓解,分类模型可以学习到更丰富、更广泛的特征表示,可以生成更精确的伪掩码,如图4所示。
在分割阶段,我们在伪掩码p的监督下训练一个语义分割模型fseg,以得到输入patch x的语义分割结果s。
在这一阶段,提出了多层伪监督和分类门机制这两个具体设计,以进一步提高语义分割的性能。
由于patch级标签和像素级标签之间的信息差距,从分类网络中学习到的空间信息仍然是不完整的,即使有渐进式dropout attention。为了减少差距,我们必须为分割模型带来更多的信息。然后我们计算语义分割结果和所有伪标签之间的交叉熵损失。
其中λi是超参数。我们在实践中设定λ1 = 0.2,λ2 = 0.2,λ3 = 0.6。
。对于那些非优势组织类别,如坏死和淋巴细胞,它们将被优势组织类别所支配。为了克服长尾问题,减少非优势类别的假阳性率,我们提出了一个分类门机制。在我们提出的框架中,。因为分类模型是由真实标签训练的,而分割模型是由伪标签训练的。基于这一观察,我们为每个输出通道引入一个门。让表示分割模型中第k个组织类别的输出概率图,其中n是类别的数量,d是概率图的维度。对于每个类别k,如果来自分类模型的组织类别的预测概率小于阈值,就意味着这个类别的存在率低。然后我们将通过归零来 ”close the gate” of the probability map 。
然后,通过对概率图o进行argmax操作,可以得到语义分割结果。在实验中我们设置
其中(i,j)表示坐标。
我们上面定义的模型是patch级语义分割模型,接下来,我们将介绍如何实现整个WSI图像的语义分割。如图3所示,我们首先从整个WSI图像中裁剪出重叠区域超过50%的patch。
利用分割模型,可以为每个patch生成n个通道的probability maps (概率图),然后我们将概率图缝合到WSI级别。 对于重叠区域,我们计算了每个像素位置处每个类别的概率平均值。然后通过argmax运算得到整个WSI图像的语义分割结果。
3. EXPERIMENTS(实验)
与现有的两个模型相比,我们提出的模型可以生成更精确的组织边界。
4.CONCLUSION(结论)
在本文中,我们提出了一种用于癌症组织病理学图像的组织级语义分割模型。在方法上,我们提出了一些技术创新,以最小化patch级和像素级标注之间的信息差距,并实现了出色的语义分割性能。为了对计算病理学和癌症研究领域做出贡献,。通过应用我们提出的模型,我们还不断为不同的癌症类型生成更多的组织级语义分割数据。
pytorch代码学习
1.易混的模块和参数的几个函数
对pytorch中比较容易搞混的几个名称和内容进行对比主要包括下面几个内容:
- model.modules(), model.named_modules()
- model.children(), model.named_children()
- model.parameters(), model.named_parameters(),
- model.state_dict()
"""
本文通过一个例子实验来观察并讲解PyTorch中model.modules(), model.named_modules(), model.children(), model.named_children(),
model.parameters(), model.named_parameters(), model.state_dict()这些model实例方法的返回值。例子如下:
"""
import torch
from torch import nn
class Net(nn.Module):
def __init__(self,num_class=10):
super(Net, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(in_channels=3,out_channels=6,kernel_size=3),
nn.BatchNorm2d(6),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2,stride=2),
nn.Conv2d(in_channels=6,out_channels=9,kernel_size=3),
nn.BatchNorm2d(9),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2,stride=2)
)
self.classifier = nn.Sequential(
nn.Linear(9*8*8,128),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(128,num_class)
)
def forward(self,x):
output = self.features(x)
output = output.view(output.size()[0],-1)
output = self.classifier(output)
return output
# 创建模型
model = Net()
# 如上代码定义了一个由两层卷积层,两层全连接层组成的网络模型。
# 值得注意的是,这个Net由外到内有3个层次:
"""
model = Net(
(features): Sequential(
(0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
(1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
(5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(6): ReLU(inplace=True)
(7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(classifier): Sequential(
(0): Linear(in_features=576, out_features=128, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=128, out_features=10, bias=True)
)
)
"""
# print("model = ",model)
"""
网络Net本身是一个nn.Module的子类,它又包含了features和classifier两个由Sequential容器组成的nn.Module子类,
features和classifier各自又包含众多的网络层,它们都属于nn.Module子类,所以从外到内共有3个层次。
"""
# 下面我们来看这几个实例方法的返回值都是什么。
# model.modules() = <generator object Module.modules at 0x0000020038D3B350>
# model.named_modules() = <generator object Module.named_modules at 0x0000020038D3B350>
print("model.modules() = ",model.modules())
print("model.named_modules() = ",model.named_modules())
# model.children() = <generator object Module.children at 0x000001E80786E2E0>
# model.named_children() = <generator object Module.named_children at 0x000001E80786E2E0>
print("model.children() = ",model.children())
print("model.named_children() = ",model.named_children())
# model.parameters() = <generator object Module.parameters at 0x000001D3A2D083C0>
# model.named_parameters() = <generator object Module.named_parameters at 0x000001D3A2D083C0>
print("model.parameters() = ",model.parameters())
print("model.named_parameters() = ",model.named_parameters())
# model.state_dict() = OrderedDict([('features.0.weight', tensor([[[[-0.0342, 0.1146, -0.0751],.....
# print("model.state_dict() = ",model.state_dict())
"""
可以看出,除了model.state_dict()返回的是一个字典,其他几个方法返回值都显示的是一个生成器,
是一个可迭代变量,我们通过列表推导式用for循环将返回值取出来进一步进行观察:
"""
model_modules = [x for x in model.modules()]
"""
model_modules = [Net(
(features): Sequential(
(0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
(1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
(5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(6): ReLU(inplace=True)
(7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(classifier): Sequential(
(0): Linear(in_features=576, out_features=128, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=128, out_features=10, bias=True)
)
), Sequential(
(0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
(1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
(5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(6): ReLU(inplace=True)
(7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
), Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1)), BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), ReLU(inplace=True), MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False), Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1)), BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), ReLU(inplace=True), MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False), Sequential(
(0): Linear(in_features=576, out_features=128, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=128, out_features=10, bias=True)
), Linear(in_features=576, out_features=128, bias=True), ReLU(inplace=True), Dropout(p=0.5, inplace=False), Linear(in_features=128, out_features=10, bias=True)]
"""
# print("model_modules = ",model_modules)
"""
由结果可以看出:
model.modules()迭代遍历模型的所有子层,本例子中指,
Net(),features(),classifier(),以及nn.xxx构成的卷积,池化,ReLU,Linear,BN,Dropout等
都是nn.Module子类,也就是modle.modules()会迭代的遍历它们所有对象。
可以看出,model_modules列表中共有15个元素,首先是整个Net,然后遍历了Net下的features子层,进一步遍历了feature下的所有层,
然后又遍历了classifier子层以及其下的所有层。所以说model.modules()能够迭代地遍历模型的所有子层。
"""
"""
model_named_modules = [('', Net(
(features): Sequential(
(0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
(1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
(5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(6): ReLU(inplace=True)
(7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(classifier): Sequential(
(0): Linear(in_features=576, out_features=128, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=128, out_features=10, bias=True)
)
)), ('features', Sequential(
(0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
(1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
(5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(6): ReLU(inplace=True)
(7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)), ('features.0', Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))), ('features.1', BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)), ('features.2', ReLU(inplace=True)), ('features.3', MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)), ('features.4', Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))), ('features.5', BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)), ('features.6', ReLU(inplace=True)), ('features.7', MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)), ('classifier', Sequential(
(0): Linear(in_features=576, out_features=128, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=128, out_features=10, bias=True)
)), ('classifier.0', Linear(in_features=576, out_features=128, bias=True)), ('classifier.1', ReLU(inplace=True)), ('classifier.2', Dropout(p=0.5, inplace=False)), ('classifier.3', Linear(in_features=128, out_features=10, bias=True))]
"""
model_named_modules = [x for x in model.named_modules()]
# print("model_named_modules = ",model_named_modules)
"""
顾名思义,它就是有名字的model.modules()。model.named_modules()不但
返回模型的所有子层,还会返回这些层的名字。
可以看出,model.named_modules()也遍历了15个元素,但每个元素都有了自己的名字,从名字可以看出,
除了在模型定义时有命名的features和classifier,其它层的名字都是PyTorch内部按一定规则自动命名的。
返回层以及层的名字的好处是可以按名字通过迭代的方法修改特定的层,如果在模型定义的时候就给每个层起了名字,
比如卷积层都是conv1,conv2...的形式,那么我们可以这样处理:
for name, layer in model.named_modules():
if 'conv' in name:
对layer进行处理
"""
"""
当然,在没有返回名字的情形中,采用isinstance()函数也可以完成上述操作:
for layer in model.modules():
if isinstance(layer, nn.Conv2d):
对layer进行处理
"""
model_children = [x for x in model.children()]
# print("model_children = ",model_children)
"""
model_children = [Sequential(
(0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
(1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
(5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(6): ReLU(inplace=True)
(7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
), Sequential(
(0): Linear(in_features=576, out_features=128, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=128, out_features=10, bias=True)
)]
"""
"""
如果把这个网络模型Net按层次从外到内进行划分的话,features和classifier是Net的子层,而conv2d, ReLU, BatchNorm, Maxpool2d这些有时features的子层,
Linear, Dropout, ReLU等是classifier的子层,上面的model.modules()不但会遍历模型的子层,还会遍历子层的子层,以及所有子层。
而model.children()只会遍历模型的子层,这里即是features和classifier
可以看出,它只遍历了两个元素,即features和classifier.
"""
model_named_children = [x for x in model.named_children()]
# print("model_named_children = ",model_named_children)
"""
model_named_children = [('features', Sequential(
(0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
(1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
(5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(6): ReLU(inplace=True)
(7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)), ('classifier', Sequential(
(0): Linear(in_features=576, out_features=128, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=128, out_features=10, bias=True)
))]
"""
"""
model.named_children()就是带名字的model.children(), 相比model.children(),
model.named_children()不但迭代的遍历模型的子层,还会返回子层的名字:
对比上面的model.children(), 这里的model.named_children()
还返回了两个子层的名称:features 和 classifier .
"""
model_parameters = [x for x in model.parameters()]
# print("model_parameters = ",model_parameters)
"""
迭代地返回模型的所有参数。
"""
model_named_parameters = [x for x in model.named_parameters()]
# print("model_named_parameters = ",model_named_parameters)
"""
model_named_parameters = [('features.0.weight', Parameter containing:
tensor([[[[ 0.0350, 0.0103, 0.1016],
[-0.1339, 0.1515, 0.1680],
[-0.0698, -0.0406, 0.0864]],
[[-0.1830, -0.0817, 0.0382],
[-0.1305, -0.0943, 0.0407],
[ 0.0353, 0.1068, -0.1145]],
[[-0.1619, -0.0422, -0.0821],
[ 0.0567, -0.1495, 0.0950],
[ 0.0903, -0.1243, -0.1422]]],
[[[-0.0305, 0.0149, 0.0102],
[ 0.1704, -0.1404, 0.0244],
[ 0.0490, -0.0901, 0.1811]],
[[-0.0258, 0.1664, -0.0227],
[ 0.0043, -0.0295, -0.0112],
[-0.1794, 0.0269, 0.0688]],
[[ 0.1838, 0.0892, -0.1854],
[ 0.1217, -0.1055, 0.1548],
[-0.1136, 0.1164, -0.1127]]],
[[[-0.1000, -0.0226, 0.0203],
[ 0.1791, -0.0128, -0.1299],
[ 0.1420, 0.0108, -0.1067]],
[[ 0.1317, -0.1859, -0.0801],
[ 0.0392, -0.0918, -0.0631],
[ 0.0047, 0.0786, 0.0613]],
[[-0.0692, 0.0892, -0.1899],
[-0.0533, 0.1172, -0.1542],
[-0.0785, 0.0462, 0.0684]]],
[[[ 0.0124, 0.1793, -0.0063],
[-0.0957, -0.0683, 0.1323],
[-0.1145, 0.0799, 0.1016]],
[[-0.0175, 0.1211, 0.0306],
[-0.1402, 0.0101, -0.0253],
[-0.0217, 0.1320, 0.0575]],
[[ 0.0924, 0.0992, -0.1721],
[-0.1088, 0.0864, 0.0491],
[ 0.1400, 0.0665, 0.0087]]],
[[[-0.1451, -0.1380, 0.0535],
[-0.1722, 0.1474, 0.0659],
[ 0.0804, 0.1919, -0.1452]],
[[ 0.1174, 0.1427, -0.1740],
[-0.0788, -0.0937, 0.1732],
[-0.0168, 0.0534, 0.1858]],
[[ 0.1235, -0.1223, -0.1094],
[ 0.0097, -0.0980, 0.1445],
[-0.1352, 0.1720, -0.0109]]],
[[[-0.1285, -0.1427, 0.1380],
[-0.1085, -0.0668, -0.1830],
[-0.0872, -0.0166, 0.0485]],
[[-0.1093, -0.0880, -0.1125],
[-0.1451, 0.1625, -0.1856],
[-0.1510, 0.0299, 0.1619]],
[[-0.0407, 0.0116, -0.1543],
[ 0.1722, -0.1791, -0.0838],
[ 0.1276, 0.1317, -0.0685]]]], requires_grad=True)), ('features.0.bias', Parameter containing:
tensor([ 0.0677, 0.0136, -0.1695, 0.0557, -0.0463, -0.1873],
requires_grad=True)), ('features.1.weight', Parameter containing:
tensor([1., 1., 1., 1., 1., 1.], requires_grad=True)), ('features.1.bias', Parameter containing:
tensor([0., 0., 0., 0., 0., 0.], requires_grad=True)), ('features.4.weight', Parameter containing:
tensor([[[[-0.0724, -0.1141, 0.0105],
[-0.1128, -0.0751, 0.1208],
[ 0.0953, 0.1177, -0.0444]],
[[ 0.0957, -0.1216, 0.0293],
[ 0.1293, 0.0983, -0.0347],
[ 0.1343, 0.0386, 0.0112]],
[[-0.0560, 0.0995, 0.0643],
[-0.0586, -0.0472, 0.0290],
[-0.0611, -0.1101, 0.0827]],
[[ 0.0525, 0.1166, 0.0700],
[ 0.0142, -0.0692, -0.0835],
[ 0.0243, -0.1282, -0.0282]],
[[ 0.0162, -0.1156, -0.0433],
[-0.0868, -0.1142, 0.0250],
[-0.0299, -0.0039, -0.0724]],
[[-0.1259, -0.1108, -0.0686],
[ 0.0741, 0.0572, 0.0359],
[ 0.0952, 0.0263, -0.1288]]],
[[[ 0.0185, 0.0808, -0.1170],
[-0.0757, -0.0199, 0.1268],
[-0.0362, 0.0034, 0.0579]],
[[-0.0528, -0.1009, 0.0548],
[ 0.1096, 0.1081, 0.0112],
[ 0.0492, 0.0263, -0.1221]],
[[ 0.0851, 0.1073, 0.0807],
[ 0.0136, -0.0085, -0.0158],
[ 0.0051, 0.1234, -0.1120]],
[[ 0.0973, 0.0102, -0.0802],
[ 0.0484, -0.0545, -0.0322],
[-0.0933, -0.0746, -0.0595]],
[[ 0.1175, 0.0084, -0.0093],
[ 0.0529, -0.0679, -0.0656],
[-0.0310, 0.0018, 0.0773]],
[[-0.0662, 0.0908, 0.0016],
[ 0.0542, 0.0713, -0.0626],
[ 0.0094, -0.0947, 0.0817]]],
[[[-0.0301, 0.0898, -0.0228],
[-0.1076, -0.1124, 0.0680],
[-0.1019, 0.0581, 0.0945]],
[[ 0.0332, -0.0941, -0.0758],
[-0.1314, 0.0705, 0.0255],
[-0.0424, 0.0831, 0.1061]],
[[ 0.0841, -0.0150, -0.0069],
[ 0.1205, 0.1154, 0.1192],
[ 0.1314, -0.0572, -0.0537]],
[[ 0.0459, -0.1302, 0.0496],
[-0.1219, 0.0894, 0.1038],
[-0.1248, 0.0557, -0.0805]],
[[ 0.0088, 0.1010, -0.1095],
[-0.0311, -0.0550, 0.0131],
[-0.0652, 0.0236, -0.1046]],
[[ 0.0475, -0.0349, -0.1173],
[ 0.0346, -0.0733, -0.0914],
[-0.0344, 0.0186, 0.0769]]],
[[[ 0.1303, 0.0428, -0.0268],
[-0.0286, 0.0107, 0.0120],
[-0.0309, 0.1230, -0.0535]],
[[ 0.0120, -0.0188, 0.1058],
[ 0.0150, -0.0027, 0.0316],
[-0.1111, 0.1085, 0.0616]],
[[-0.1200, -0.0523, 0.1007],
[ 0.0953, 0.0342, -0.0743],
[-0.0097, 0.0769, 0.0222]],
[[-0.1126, 0.0587, -0.0308],
[-0.0166, -0.0589, -0.0744],
[-0.0695, -0.1091, 0.0833]],
[[ 0.0272, 0.0990, 0.1173],
[-0.0356, -0.0556, -0.0878],
[ 0.0579, -0.0674, 0.0777]],
[[ 0.1267, -0.1126, 0.0829],
[ 0.1207, 0.0637, 0.0447],
[ 0.0101, 0.0537, 0.0130]]],
[[[-0.0861, -0.1215, -0.0174],
[-0.0884, 0.0968, 0.1005],
[-0.0225, -0.1242, -0.0878]],
[[-0.0664, 0.0387, 0.0136],
[-0.1168, -0.1265, -0.1013],
[ 0.0073, -0.0823, -0.0221]],
[[ 0.0765, 0.0109, -0.0760],
[ 0.1172, -0.0953, -0.0571],
[ 0.0735, -0.0136, 0.1066]],
[[-0.1084, -0.0231, 0.0387],
[ 0.0644, 0.0232, 0.0378],
[-0.0725, -0.0773, 0.0961]],
[[ 0.0749, -0.1018, 0.0645],
[ 0.0643, -0.1131, 0.0713],
[ 0.1302, -0.0467, 0.1238]],
[[ 0.0891, 0.0968, -0.0872],
[-0.0176, -0.0625, 0.1247],
[ 0.0764, 0.0404, -0.0692]]],
[[[-0.0216, 0.0178, 0.0861],
[ 0.0194, -0.0809, 0.0016],
[-0.0975, 0.0677, 0.1178]],
[[ 0.0833, 0.0980, 0.0511],
[ 0.1035, -0.1361, -0.0866],
[-0.0882, -0.0723, -0.1111]],
[[-0.0383, -0.0263, -0.1000],
[ 0.1271, -0.0439, 0.0261],
[-0.0635, -0.0281, 0.0110]],
[[-0.0581, -0.0064, -0.1025],
[ 0.0285, -0.1292, -0.0303],
[ 0.0677, -0.0345, -0.1033]],
[[ 0.0643, -0.0275, -0.0674],
[ 0.0137, -0.0164, -0.1115],
[-0.0091, -0.0434, 0.0677]],
[[ 0.0144, 0.0092, 0.0296],
[ 0.1309, 0.0381, 0.0780],
[-0.0869, 0.1254, -0.1286]]],
[[[ 0.1236, -0.0180, -0.0362],
[ 0.0333, -0.0795, 0.0484],
[-0.0631, 0.0950, -0.0140]],
[[-0.1278, -0.0398, -0.1113],
[ 0.0188, 0.0812, -0.0135],
[-0.1257, -0.0858, 0.0594]],
[[ 0.1007, -0.0060, -0.1020],
[ 0.0128, -0.0452, 0.1216],
[-0.0290, 0.1182, -0.0886]],
[[ 0.1055, -0.0874, 0.0793],
[-0.1203, 0.0965, -0.0028],
[-0.0659, -0.0722, -0.1219]],
[[ 0.1211, 0.1321, 0.0527],
[ 0.0980, 0.1168, -0.0974],
[ 0.1002, 0.1068, -0.1127]],
[[ 0.1175, 0.0850, -0.0614],
[-0.0260, -0.1330, -0.0162],
[ 0.0337, -0.1211, 0.1081]]],
[[[-0.0436, -0.0912, -0.0291],
[-0.0602, -0.0715, -0.0935],
[ 0.0571, 0.0199, -0.1161]],
[[ 0.0630, -0.0065, -0.0129],
[ 0.0259, -0.0638, -0.1152],
[ 0.1032, -0.0629, 0.1348]],
[[ 0.0283, 0.0265, 0.0824],
[ 0.0419, 0.1153, 0.0783],
[-0.0305, -0.0472, 0.1295]],
[[-0.0471, 0.0886, 0.0463],
[-0.1360, 0.1348, -0.0625],
[ 0.0093, -0.1020, -0.0061]],
[[ 0.0762, -0.0925, 0.0034],
[-0.0250, 0.1321, 0.0676],
[ 0.0202, 0.0511, 0.0705]],
[[ 0.0154, 0.0837, -0.1195],
[ 0.0962, -0.1176, -0.0937],
[ 0.0501, -0.0946, 0.0148]]],
[[[ 0.1006, -0.0208, -0.0947],
[ 0.0609, 0.0735, 0.0179],
[-0.0887, 0.0736, 0.0908]],
[[ 0.0615, 0.0844, 0.1163],
[ 0.0101, 0.1171, 0.0063],
[ 0.0951, -0.0245, 0.0926]],
[[ 0.0617, -0.1190, 0.0921],
[-0.0887, 0.0842, 0.0813],
[ 0.0695, -0.0479, -0.1015]],
[[-0.0942, 0.0839, -0.0549],
[-0.0322, 0.0255, 0.0583],
[-0.0235, -0.0031, -0.0904]],
[[ 0.0492, -0.1012, -0.1180],
[ 0.1149, -0.1011, 0.1090],
[-0.1046, 0.0475, 0.0074]],
[[ 0.1330, -0.0620, -0.0341],
[ 0.1162, -0.0675, 0.1036],
[-0.0829, 0.1141, 0.1092]]]], requires_grad=True)), ('features.4.bias', Parameter containing:
tensor([-0.1039, -0.0869, -0.1233, -0.0459, -0.1086, 0.0432, -0.1133, -0.0032,
-0.0533], requires_grad=True)), ('features.5.weight', Parameter containing:
tensor([1., 1., 1., 1., 1., 1., 1., 1., 1.], requires_grad=True)), ('features.5.bias', Parameter containing:
tensor([0., 0., 0., 0., 0., 0., 0., 0., 0.], requires_grad=True)), ('classifier.0.weight', Parameter containing:
tensor([[-0.0251, -0.0396, -0.0007, ..., -0.0369, 0.0107, -0.0136],
[ 0.0282, 0.0286, -0.0107, ..., -0.0259, -0.0243, 0.0128],
[-0.0040, -0.0160, 0.0199, ..., 0.0042, 0.0202, 0.0083],
...,
[-0.0053, -0.0384, 0.0213, ..., 0.0212, 0.0064, 0.0371],
[-0.0165, 0.0144, 0.0372, ..., 0.0067, 0.0081, 0.0246],
[ 0.0252, 0.0121, 0.0270, ..., 0.0198, 0.0189, 0.0359]],
requires_grad=True)), ('classifier.0.bias', Parameter containing:
tensor([ 0.0270, -0.0172, -0.0298, -0.0216, 0.0406, 0.0319, -0.0077, -0.0330,
0.0081, 0.0351, -0.0081, -0.0159, -0.0218, 0.0039, 0.0179, -0.0331,
0.0327, -0.0105, -0.0353, 0.0173, -0.0245, 0.0340, -0.0339, 0.0197,
-0.0213, 0.0108, 0.0151, 0.0069, 0.0055, 0.0140, -0.0325, 0.0326,
-0.0298, 0.0407, -0.0258, -0.0060, -0.0400, 0.0373, -0.0285, 0.0070,
-0.0244, 0.0277, 0.0181, 0.0407, 0.0009, -0.0053, 0.0084, -0.0228,
-0.0253, -0.0039, -0.0155, 0.0268, 0.0145, -0.0323, 0.0054, -0.0212,
0.0382, 0.0414, 0.0335, 0.0016, 0.0216, 0.0190, -0.0323, -0.0201,
-0.0303, 0.0161, -0.0102, -0.0151, 0.0376, -0.0008, -0.0278, 0.0340,
0.0245, 0.0333, -0.0357, 0.0360, -0.0164, -0.0272, -0.0353, -0.0341,
0.0313, 0.0314, -0.0316, -0.0152, 0.0298, -0.0136, 0.0370, -0.0074,
-0.0113, -0.0387, -0.0400, -0.0066, -0.0038, 0.0089, 0.0039, 0.0406,
-0.0034, -0.0166, -0.0147, 0.0264, -0.0278, -0.0152, 0.0165, -0.0356,
0.0098, 0.0388, -0.0060, 0.0240, 0.0119, -0.0141, -0.0204, 0.0157,
-0.0112, 0.0071, -0.0315, -0.0159, -0.0276, -0.0006, -0.0177, -0.0044,
0.0107, -0.0113, -0.0066, -0.0123, -0.0133, 0.0377, -0.0155, -0.0191],
requires_grad=True)), ('classifier.3.weight', Parameter containing:
tensor([[-0.0437, 0.0575, -0.0551, ..., 0.0620, 0.0798, 0.0225],
[ 0.0187, -0.0032, 0.0537, ..., 0.0614, 0.0683, -0.0728],
[-0.0069, -0.0273, -0.0102, ..., 0.0648, 0.0244, 0.0425],
...,
[ 0.0728, 0.0716, -0.0784, ..., 0.0721, -0.0252, 0.0415],
[ 0.0329, -0.0779, 0.0010, ..., -0.0502, -0.0827, -0.0699],
[ 0.0164, 0.0267, 0.0574, ..., 0.0434, -0.0673, -0.0557]],
requires_grad=True)), ('classifier.3.bias', Parameter containing:
tensor([ 0.0429, 0.0720, 0.0268, 0.0733, 0.0722, 0.0473, -0.0661, -0.0637,
-0.0498, -0.0619], requires_grad=True))]
"""
"""
如果你是从前面看过来的,就会知道,这里就是迭代的返回带有名字的参数,
会给每个参数加上带有 .weight或 .bias的名字以区分权重和偏置:
"""
state_dicts = model.state_dict()
# print("state_dicts = ",state_dicts)
for k in state_dicts:
print("k = ",k," v = ",state_dicts[k])
"""
state_dicts = OrderedDict([('features.0.weight', tensor([[[[-0.1120, 0.1490, 0.1126],
[-0.1723, 0.1112, -0.1769],
[ 0.1773, 0.1917, 0.0526]],
[[-0.1734, 0.1511, 0.1650],
[ 0.0675, -0.0678, 0.0216],
[ 0.1885, 0.1664, -0.1246]],
[[ 0.1417, 0.1417, 0.0409],
[-0.0858, -0.0144, -0.1439],
[ 0.0473, 0.0736, -0.0034]]],
[[[ 0.1588, -0.0245, 0.0427],
[ 0.0336, -0.0181, 0.1024],
[ 0.0696, -0.1315, -0.0653]],
[[-0.0196, -0.1345, -0.1009],
[-0.1496, -0.0704, 0.1776],
[ 0.0123, -0.0073, 0.0899]],
[[ 0.0317, -0.1059, -0.1572],
[-0.0766, -0.1680, 0.0808],
[-0.1485, 0.1683, 0.0383]]],
[[[-0.0897, -0.0250, 0.0031],
[ 0.0386, 0.1260, -0.0847],
[-0.0467, -0.0684, -0.1173]],
[[-0.1226, 0.1384, 0.0689],
[ 0.1758, -0.1891, -0.1873],
[ 0.1391, 0.0112, -0.1604]],
[[-0.0956, 0.1639, 0.1126],
[ 0.0309, -0.1016, -0.0393],
[-0.0270, -0.0333, -0.1562]]],
[[[ 0.0270, 0.0296, 0.0771],
[-0.0868, -0.1124, -0.0439],
[ 0.1779, -0.0512, 0.0108]],
[[ 0.1261, 0.0209, 0.1148],
[ 0.1882, -0.0144, -0.1624],
[-0.0143, 0.1711, 0.0430]],
[[ 0.1367, -0.0869, -0.1644],
[ 0.1404, -0.0255, 0.1486],
[-0.0415, -0.0261, 0.0015]]],
[[[-0.0011, 0.0968, 0.0957],
[-0.1461, -0.0302, -0.1816],
[-0.0779, 0.0440, -0.0650]],
[[ 0.1433, 0.1455, -0.0765],
[ 0.0740, 0.0872, -0.0867],
[-0.0946, -0.0586, -0.1586]],
[[-0.1641, -0.1063, 0.0597],
[ 0.0933, -0.1327, 0.1658],
[-0.0651, -0.0454, -0.0592]]],
[[[-0.1577, 0.0530, -0.1889],
[-0.0094, 0.0694, -0.0912],
[ 0.0916, 0.1582, 0.0685]],
[[-0.0960, 0.0386, 0.0987],
[ 0.0258, -0.1619, 0.0385],
[-0.0475, 0.0387, 0.0350]],
[[ 0.0571, -0.0815, -0.1121],
[ 0.0839, 0.1473, 0.0897],
[-0.0518, -0.0513, -0.1895]]]])), ('features.0.bias', tensor([ 0.1110, 0.1084, -0.1312, 0.0584, -0.0216, 0.0522])), ('features.1.weight', tensor([1., 1., 1., 1., 1., 1.])), ('features.1.bias', tensor([0., 0., 0., 0., 0., 0.])), ('features.1.running_mean', tensor([0., 0., 0., 0., 0., 0.])), ('features.1.running_var', tensor([1., 1., 1., 1., 1., 1.])), ('features.1.num_batches_tracked', tensor(0)), ('features.4.weight', tensor([[[[ 1.2339e-01, 3.6456e-02, -8.1264e-02],
[ 7.2834e-02, 7.7740e-02, -8.1412e-02],
[-1.3442e-01, -9.6639e-02, -8.1537e-02]],
[[-7.9242e-02, -1.6356e-02, -2.0175e-02],
[ 6.3926e-02, 4.6489e-02, -4.7286e-02],
[-4.3791e-02, 1.2156e-02, -3.7545e-02]],
[[ 8.3428e-02, -2.5146e-02, 1.3393e-01],
[-8.8177e-02, -9.2821e-02, 4.6915e-03],
[ 3.7843e-02, 1.1423e-01, 2.4096e-02]],
[[ 1.2078e-01, 6.6416e-02, 1.0651e-01],
[ 5.8561e-02, -9.9513e-02, -7.7436e-02],
[ 6.5392e-02, -3.4283e-02, -1.0200e-01]],
[[ 2.9786e-02, -6.0475e-02, -8.6477e-02],
[ 3.8416e-02, 4.0239e-02, 1.0487e-01],
[ 1.2980e-02, 4.3307e-02, -1.2445e-02]],
[[-1.0675e-01, -1.3109e-04, -1.1331e-01],
[-1.2819e-01, -6.0414e-02, -9.1673e-02],
[ 2.8632e-02, 4.8303e-02, -4.8784e-02]]],
[[[-2.0327e-02, -7.4646e-02, 1.1771e-01],
[-2.3229e-02, -1.3199e-01, 6.3986e-02],
[ 1.0935e-01, -7.1119e-02, -6.8069e-03]],
[[ 4.2655e-02, -4.0028e-02, 5.8079e-02],
[-2.8356e-02, -8.9192e-02, 5.8191e-02],
[-1.1162e-01, 1.3061e-01, -1.3425e-02]],
[[ 2.9063e-02, -1.1770e-01, -1.1862e-01],
[ 7.7019e-02, -1.1078e-01, -4.1114e-02],
[-6.0020e-02, -9.5343e-02, -9.3102e-02]],
[[-1.3583e-01, -8.4821e-02, 1.1639e-01],
[-4.4931e-02, -2.6818e-03, -1.3142e-01],
[-1.3248e-01, 3.5738e-02, 6.3704e-02]],
[[-9.5148e-02, -5.4758e-02, -8.5132e-02],
[ 5.9926e-02, -9.9971e-03, -1.2893e-01],
[-1.6311e-02, -1.6571e-02, -9.0908e-02]],
[[-1.2931e-01, -1.0908e-01, -8.0463e-02],
[-8.5217e-02, 9.4868e-02, -4.9266e-03],
[ 1.0161e-01, -1.2998e-01, -1.0456e-01]]],
[[[ 1.3086e-01, -1.0726e-01, -3.0973e-02],
[ 7.5602e-03, 4.0852e-03, -5.7365e-02],
[ 9.6861e-02, 5.1707e-03, 1.0884e-01]],
[[-6.5375e-02, 1.2043e-01, -6.0518e-02],
[ 9.7843e-02, -5.3584e-02, -4.3394e-02],
[-1.0804e-01, -7.3304e-02, -1.1025e-01]],
[[ 3.9323e-02, 4.3915e-02, -1.1270e-01],
[ 8.8957e-02, 3.9222e-02, 1.1955e-01],
[-5.8752e-02, -7.9406e-02, 8.1920e-02]],
[[-1.4651e-02, 1.2826e-01, -7.3560e-02],
[-6.7479e-03, 1.1927e-01, 9.5392e-03],
[-1.3190e-01, 9.2025e-02, 7.7550e-02]],
[[ 2.1855e-02, 2.6536e-02, -8.8161e-02],
[ 1.0861e-01, -1.8487e-02, 8.6501e-02],
[-8.3951e-02, -1.0361e-01, 4.6002e-03]],
[[-7.4299e-02, -6.3769e-02, 2.5605e-02],
[ 9.6181e-02, 1.2735e-01, 1.2609e-01],
[-7.3185e-02, -4.5585e-02, 6.2157e-02]]],
[[[ 2.6107e-02, -1.1989e-01, -8.6688e-02],
[ 8.6597e-02, -4.4664e-02, 3.2112e-02],
[-1.0814e-01, -7.2253e-02, -7.4629e-02]],
[[-3.9608e-02, -7.4466e-02, -1.2369e-01],
[ 6.2269e-02, -5.3591e-02, 1.0797e-01],
[ 5.8163e-02, -1.3221e-01, 1.0001e-01]],
[[ 9.5225e-02, 1.1649e-01, -7.3289e-03],
[-1.2376e-01, -2.4160e-02, -7.7053e-02],
[ 1.1293e-01, 3.0768e-02, -1.2418e-01]],
[[-5.3918e-02, -9.2364e-02, -1.0816e-02],
[-2.0389e-03, -1.0363e-01, 6.8401e-02],
[-6.7831e-02, 1.1953e-01, 4.0812e-02]],
[[-1.1983e-01, 8.5739e-02, -2.8247e-02],
[-8.8285e-03, -1.4419e-02, 6.0807e-02],
[-1.0024e-02, 1.0961e-01, -4.1463e-02]],
[[-6.1104e-02, 1.1612e-01, -1.0832e-01],
[-2.8441e-02, 3.5046e-02, 7.0129e-03],
[-1.4531e-02, 1.3536e-02, -1.2058e-01]]],
[[[ 5.5127e-02, -3.7674e-02, -3.0895e-03],
[ 7.4091e-02, 3.5885e-02, -3.1326e-03],
[ 9.0708e-02, -1.1664e-01, 3.1442e-02]],
[[-1.1080e-01, 1.2293e-01, 5.3925e-02],
[ 4.7981e-02, 1.1144e-01, -1.1489e-01],
[-1.2803e-01, 2.7881e-02, 1.3296e-01]],
[[-1.2624e-01, -6.5688e-02, 3.5976e-02],
[-3.0632e-02, -7.7391e-02, -6.7752e-02],
[ 5.9872e-02, 6.2385e-02, -4.8133e-02]],
[[-9.4431e-02, -6.3459e-02, 9.0059e-02],
[-3.1814e-02, -8.3559e-03, -1.9724e-02],
[ 7.4525e-02, 3.5408e-02, 1.3036e-01]],
[[ 1.1507e-01, 1.9809e-02, -1.1319e-01],
[-6.8824e-02, -9.7140e-02, 2.5071e-02],
[ 5.1618e-02, -1.3364e-01, 1.2377e-01]],
[[-1.6939e-03, 2.5055e-04, 1.6423e-02],
[ 1.1560e-01, 8.5741e-02, -9.4489e-02],
[-7.9593e-02, 4.4569e-02, -4.4471e-02]]],
[[[ 7.8615e-02, 4.1079e-02, -5.3803e-02],
[ 1.7017e-02, 5.2484e-02, -1.4643e-02],
[-5.3499e-02, 1.0117e-01, -1.2375e-01]],
[[-1.2176e-03, 2.8521e-02, -8.7684e-02],
[ 5.2779e-02, 1.2218e-01, 7.8400e-02],
[-1.0264e-01, 3.2854e-02, 1.0255e-01]],
[[-6.4508e-02, -4.0940e-02, 1.0328e-01],
[ 6.1570e-02, -4.1444e-02, 1.0093e-01],
[-1.1605e-01, 1.2389e-01, -1.3214e-02]],
[[-9.5283e-02, 2.7124e-02, 2.2692e-02],
[-1.2656e-01, 5.7397e-02, -1.3197e-01],
[ 9.7042e-02, -7.5878e-02, 5.2598e-02]],
[[-6.0347e-02, 3.4859e-02, 1.1488e-01],
[ 7.9926e-02, 6.6939e-02, 1.1487e-01],
[-3.0942e-03, 9.8462e-02, -3.0900e-02]],
[[ 9.5505e-02, -1.2781e-01, 4.7567e-02],
[-9.1119e-02, 9.7449e-02, 6.4211e-02],
[-6.0627e-02, -4.7606e-02, 1.0843e-01]]],
[[[-1.3378e-01, 9.7107e-02, -1.3604e-01],
[ 6.7992e-02, -4.7438e-02, 6.3659e-03],
[-1.1243e-01, -8.3477e-02, 5.0870e-02]],
[[-2.9983e-02, 9.8946e-03, 9.8673e-03],
[-4.2389e-02, 8.9317e-02, -7.8672e-02],
[-3.4808e-02, -9.8673e-02, -8.0076e-02]],
[[ 1.2528e-01, 9.5739e-02, 1.2877e-01],
[ 5.6588e-02, 4.7093e-02, 9.6125e-02],
[ 1.7334e-02, -7.8798e-02, 7.2877e-02]],
[[ 8.8860e-02, -1.2521e-01, 3.0678e-02],
[-9.4911e-02, -3.0096e-02, -1.2500e-01],
[-9.8543e-02, -6.1643e-02, -8.5940e-02]],
[[ 1.1547e-01, -7.9756e-02, 3.6319e-02],
[-5.8380e-02, 1.0619e-01, 9.0940e-02],
[-1.3119e-01, 4.8893e-02, -8.5568e-02]],
[[ 4.0550e-02, -8.9834e-02, 1.1359e-01],
[ 1.2870e-01, 1.3285e-01, -1.0320e-01],
[-3.2039e-02, -7.4832e-02, 3.7275e-02]]],
[[[-8.3612e-02, -1.1438e-01, -8.3008e-02],
[-3.7290e-02, -5.1211e-03, -1.6722e-02],
[-2.3919e-02, -8.4471e-02, 1.1062e-01]],
[[-4.9339e-02, -1.2613e-01, -2.4665e-02],
[-1.3429e-01, 7.2360e-02, 6.5418e-03],
[-4.8754e-02, -3.2074e-02, -6.0722e-02]],
[[-1.2371e-01, 1.1780e-01, -4.6866e-02],
[-1.3454e-01, -5.8887e-02, 6.1087e-02],
[ 7.6493e-02, -1.7035e-02, -6.2266e-02]],
[[-6.8178e-03, 3.6235e-02, -3.7017e-02],
[ 9.0602e-02, -1.5369e-02, -1.0495e-01],
[-7.2129e-02, -7.3497e-02, 7.6392e-02]],
[[ 2.3970e-02, 5.4974e-02, -1.3256e-01],
[-1.2