当前位置:   article > 正文

关于神经网络的权重信息和特征图的可视化_可视化pth

可视化pth

目录

1. 介绍

2. 隐藏层特征图的可视化

2.1 AlexNet 网络

2.2 forward 

2.3 隐藏层特征图可视化

2.4 测试代码

3. 训练参数的可视化

3.1 从网络里面可视化参数

3.1.1 测试代码

3.1.2 参数的字典信息

3.1.3 参数可视化

3.2 从保存的权重参数文件(.pth)里面可视化参数


1. 介绍

神经网络中间的隐藏层往往是不可见的,之前的网络都是输入图像的可视化,或者输出结果分类或者分割的可视化。

然而中间隐藏层的输出也是可以可视化的,因为输出的信息就是一个多维的数组,而图像也是用数组表示的。

2. 隐藏层特征图的可视化

这里用AlexNet网络进行演示

2.1 AlexNet 网络

代码:

  1. import torch.nn as nn
  2. class AlexNet(nn.Module):
  3. def __init__(self, num_classes=1000):
  4. super(AlexNet, self).__init__()
  5. self.features = nn.Sequential(
  6. nn.Conv2d(3, 48, kernel_size=11, stride=4, padding=2), # input[3, 224, 224] output[48, 55, 55]
  7. nn.ReLU(inplace=True),
  8. nn.MaxPool2d(kernel_size=3, stride=2), # output[48, 27, 27]
  9. nn.Conv2d(48, 128, kernel_size=5, padding=2), # output[128, 27, 27]
  10. nn.ReLU(inplace=True),
  11. nn.MaxPool2d(kernel_size=3, stride=2), # output[128, 13, 13]
  12. nn.Conv2d(128, 192, kernel_size=3, padding=1), # output[192, 13, 13]
  13. nn.ReLU(inplace=True),
  14. nn.Conv2d(192, 192, kernel_size=3, padding=1), # output[192, 13, 13]
  15. nn.ReLU(inplace=True),
  16. nn.Conv2d(192, 128, kernel_size=3, padding=1), # output[128, 13, 13]
  17. nn.ReLU(inplace=True),
  18. nn.MaxPool2d(kernel_size=3, stride=2), # output[128, 6, 6]
  19. )
  20. self.classifier = nn.Sequential(
  21. nn.Dropout(p=0.5),
  22. nn.Linear(128 * 6 * 6, 2048),
  23. nn.ReLU(inplace=True),
  24. nn.Dropout(p=0.5),
  25. nn.Linear(2048, 2048),
  26. nn.ReLU(inplace=True),
  27. nn.Linear(2048, num_classes),
  28. )
  29. def forward(self, x):
  30. outputs = []
  31. for name, module in self.features.named_children():
  32. x = module(x) # forward
  33. if 'Conv2d' in str(module): # 只打印卷积层的输出
  34. outputs.append(x)
  35. return outputs

AlexNet网络的结构如图:

 

2.2 forward 

这里AlexNet 网络的forward过程和之前定义的有所区别

如下:

 

这里的named_children() 会返回两个值,name是模块的名称,module是模块本身

调试信息如下:

也就是说:name是第一个名称,module是第二个模块本身

所以这里的forward在features里面传递

注意这里没有classifier,这里是self.fetures里面的name_children

 

2.3 隐藏层特征图可视化

如图,这里将卷积层的输出保存在outputs里面,然后再return

 

因为AlexNet 有五个卷积层,所以这里会显示五张特征图,如下:

 

 

 

 

 

2.4 测试代码

代码如下:

  1. import os
  2. os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
  3. import torch
  4. from alexnet_model import AlexNet
  5. import matplotlib.pyplot as plt
  6. import numpy as np
  7. from PIL import Image
  8. from torchvision import transforms
  9. # 预处理
  10. transformer = transforms.Compose([transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
  11. # 实例化模型
  12. model = AlexNet(num_classes=5)
  13. model_weight_path = "./AlexNet.pth"
  14. model.load_state_dict(torch.load(model_weight_path))
  15. # load image
  16. img = Image.open("./tulips.png")
  17. img = transformer(img)
  18. img = torch.unsqueeze(img, dim=0)
  19. out_put = model(img) # forward自动调用,所有会返回里面的outputs
  20. for feature_map in out_put:
  21. im = np.squeeze(feature_map.detach().numpy()) # 去掉 batch维度,detach去掉梯度传播
  22. im = np.transpose(im, [1, 2, 0]) # change channels
  23. num_feature = im.shape[2] # plt展示的size
  24. n = int(num_feature ** 0.5)+1
  25. plt.figure() # 展示特征图
  26. for i in range(num_feature): # 改成 12,就只显示12张特征图
  27. plt.subplot(n, n, i+1)
  28. plt.axis('off')
  29. plt.imshow(im[:, :, i], cmap='gray')
  30. plt.show()

其中:

model会自动调用里面的forward,因此直接接收返回值就行了

其次,这里将batch维度删去了,然后将channel返回到最后一个位置,所以打印的时候,需要将图像的每一个channel输出 im[: ,: ,i]

 

3. 训练参数的可视化

当模型训练好的时候,参数是可以显示的。这里可以将AlexNet 实例化,也可以不需要建立模型,直接从参数文件 .pth里面载入也可以。这里演示两种方法

3.1 从网络里面可视化参数

网络的结构如下

3.1.1 测试代码

代码:

  1. import os
  2. os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
  3. import torch
  4. from alexnet_model import AlexNet
  5. import matplotlib.pyplot as plt
  6. import numpy as np
  7. # 实例化模型
  8. model = AlexNet(num_classes=5)
  9. model_weight_path = "./AlexNet.pth"
  10. model.load_state_dict(torch.load(model_weight_path))
  11. weights_keys = model.state_dict().keys() # 获取训练参数字典里面keys
  12. for key in weights_keys:
  13. # remove num_batches_tracked para(in bn)
  14. if "num_batches_tracked" in key: # bn层也有参数
  15. continue
  16. # [卷积核个数,卷积核的深度, 卷积核 h,卷积核 w]
  17. weight_value = model.state_dict()[key].numpy() # 返回 key 里面具体的值
  18. # mean, std, min, max
  19. weight_mean = weight_value.mean()
  20. weight_std = weight_value.std()
  21. weight_min = weight_value.min()
  22. weight_max = weight_value.max()
  23. print("{} layer:mean:{}, std:{}, min:{}, max:{}".format(key,weight_mean,weight_std,weight_min,weight_max))
  24. # 绘制参数的直方图
  25. plt.close()
  26. weight_vec = np.reshape(weight_value, [-1])
  27. plt.hist(weight_vec, bins=50) # 将 min-max分成50份
  28. plt.title(key)
  29. plt.show()

3.1.2 参数的字典信息

网络参数是一个字典存在的,这里打印里面的key值,

odcit(ordered dictionary) 是一个有序字典

这里序号0,3,6....是因为网络只有这里层才有权重

3.1.3 参数可视化

这里显示的有点多,所以只展示部分的

 

 

 

 

输出控制台的信息:

3.2 从保存的权重参数文件(.pth)里面可视化参数

代码:

  1. import os
  2. os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
  3. import torch
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. # create model
  7. model_weight_path = "./AlexNet.pth"
  8. param_dict = torch.load(model_weight_path)
  9. weights_keys = param_dict.keys()
  10. for key in weights_keys:
  11. # remove num_batches_tracked para(in bn)
  12. if "num_batches_tracked" in key:
  13. continue
  14. # [卷积核个数,卷积核的深度, 卷积核 h,卷积核 w]
  15. weight_value = param_dict[key].numpy()
  16. # mean, std, min, max
  17. weight_mean = weight_value.mean()
  18. weight_std = weight_value.std()
  19. weight_min = weight_value.min()
  20. weight_max = weight_value.max()
  21. print("{} layer:mean:{}, std:{}, min:{}, max:{}".format(key,weight_mean,weight_std,weight_min,weight_max))
  22. # 绘制参数的直方图
  23. plt.close()
  24. weight_vec = np.reshape(weight_value, [-1])
  25. plt.hist(weight_vec, bins=50) # 将 min-max分成50份
  26. plt.title(key)
  27. plt.show()

其中载入参数的字典文件如下:

 

打印的信息:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/514411
推荐阅读
  

闽ICP备14008679号