本篇博客是学习B站霹雳吧啦Wz教学视频的总结
本节所用到的程序和教学视频链接:
查看中间特征层
在书写 网络的类的过程中,于forward函数中增加记录层参数的数组:
def forward(self, x):
outputs = []
for name, module in self.features.named_children():
x = module(x)
if name in ["0", "3", "6"]:
outputs.append(x)
return output
- namd_children 返回包含子模块的迭代器,同时产生模块的名称以及模块本身。
- for循环遍历网络中的每个层结构,output记录符合名字的层结构矩阵参数
- 这样forward函数会返回我们指定的层的矩阵参数
在分析程序中
import torch
from alexnet_model import AlexNet
from resnet_model import resnet34
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
from torchvision import transforms
data_transform = transforms.Compose(
[transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
# data_transform = transforms.Compose(
# [transforms.Resize(256),
# transforms.CenterCrop(224),
# transforms.ToTensor(),
# transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
# create model
model = AlexNet(num_classes=5)
# model = resnet34(num_classes=5)
# load model weights
model_weight_path = "./AlexNet.pth" # "./resNet34.pth"
model.load_state_dict(torch.load(model_weight_path))
print(model)
# load image
img = Image.open("../tulip.jpg")
# [N, C, H, W]
img = data_transform(img)
# expand batch dimension
img = torch.unsqueeze(img, dim=0)
# forward
out_put = model(img)
for feature_map in out_put:
# [N, C, H, W] -> [C, H, W]
im = np.squeeze(feature_map.detach().numpy())
# [C, H, W] -> [H, W, C]
im = np.transpose(im, [1, 2, 0])
# show top 12 feature maps
plt.figure()
for i in range(12):
ax = plt.subplot(3, 4, i+1)
# [H, W, C]
plt.imshow(im[:, :, i], cmap='gray')
plt.show()
- 我们首先导入模型参数和要预测的图片
- 使用out_put = model(img)来得到输出结果
- for feature_map in out_put: 会遍历out_put中的每个元素
- feature_map.detach() 会将feature_map转化为一个tensor,然后使用.numpy()将其转化为数组
- np.squeeze 缩小tensor矩阵的维度,这里就将batch_size维度去掉了
- np.transpose 来对img进行重构(tensor格式的数据是[C,H,W],图像显示是希望的数据格式是[H,W,C])
- camp=‘gray’ 是用来输出灰度图片的
查看卷积核
import torch
from alexnet_model import AlexNet
from resnet_model import resnet34
import matplotlib.pyplot as plt
import numpy as np
# create model
model = AlexNet(num_classes=5)
# model = resnet34(num_classes=5)
# load model weights
model_weight_path = "./AlexNet.pth" # "resNet34.pth"
model.load_state_dict(torch.load(model_weight_path))
print(model)
weights_keys = model.state_dict().keys()
for key in weights_keys:
# remove num_batches_tracked para(in bn)
if "num_batches_tracked" in key:
continue
# [kernel_number, kernel_channel, kernel_height, kernel_width]
weight_t = model.state_dict()[key].numpy()
# read a kernel information
# k = weight_t[0, :, :, :]
# calculate mean, std, min, max
weight_mean = weight_t.mean()
weight_std = weight_t.std(ddof=1)
weight_min = weight_t.min()
weight_max = weight_t.max()
print("mean is {}, std is {}, min is {}, max is {}".format(weight_mean,
weight_std,
weight_max,
weight_min))
# plot hist image
plt.close()
weight_vec = np.reshape(weight_t, [-1])
plt.hist(weight_vec, bins=50)
plt.title(key)
plt.show()
- weights_keys = model.state_dict().keys() 来提取模型中层的关键字
- weight_t = model.state_dict()[key].numpy() 提取关键字对应的特征参数
- 之后计算相应的参数,并进行显示