深度學習不少方向所謂改進模型、改進網絡都是在按照人的主觀思想在改進,經常在說模型的本質是提取特徵,但並不知道它提取了什麼特徵、哪些區域對於識別真正起做用、也不知道網絡是根據什麼得出了分類結果。爲了加強結果的可解釋性,須要給出模型的一些可視化圖來證實模型或新methods對於任務的做用,這一點不只能增長新模型或新methods可信度;還能夠根據可視化某個網絡的結果分析其不足之處,從而提出新的改進方法。(寫論文還能夠用來湊字數、湊工做量:)python
無特殊說明,本文中所用的網絡是:網絡
torchvision.models.resnet50(pretrained=True)
所用的圖片爲
app
'''方法1,直接可視化''' import torch import torchvision import cv2 from PIL import Image import torchvision.models as models import torch.nn as nn from matplotlib import pyplot as plt import math '''1,加載訓練模型''' resnet50 = models.resnet50(pretrained=True) print(resnet50) '''2,提取CNN層,非必須''' conv_layers = [] model_weights = [] model_children = list(models.resnet50().children()) counter = 0 for i in range(len(model_children)): if type(model_children[i]) == nn.Conv2d: counter += 1 model_weights.append(model_children[i].weight) conv_layers.append(model_children[i]) elif type(model_children[i]) == nn.Sequential: for j in range(len(model_children[i])): for child in model_children[i][j].children(): if type(child) == nn.Conv2d: counter += 1 model_weights.append(child.weight) conv_layers.append(child) '''3,讀取數據''' img = cv2.cvtColor(cv2.imread('data.jpg'), cv2.COLOR_BGR2RGB) img = torchvision.transforms.Compose([ torchvision.transforms.ToPILImage(), torchvision.transforms.Resize((1050, 1680)), torchvision.transforms.ToTensor(), torchvision.transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ])(img).unsqueeze(0) '''4,特徵映射,這裏繪製第一層卷積的feature map''' featuremaps = [conv_layers[0](img)] plt.figure(1) for i in range(64): plt.subplot(8, 8, i + 1) plt.axis('off') plt.imshow(featuremaps[0][0, i, :, :].detach(), cmap='gray') plt.show()
for i in range(64): plt.subplot(8, 8, i+1) plt.axis('off') plt.imshow(model_weights[0][i][0, :, :].detach(), cmap='gray') plt.show()
計算梯度及全局平均池化:ide
加權:函數
2,從網上找了一個模型,效果就挺好的
學習
識別青蛙的結果頗有意思,這意味着網絡關注的重點不在於青蛙,反而在於青蛙周圍的環境,並且網絡的預測結果仍是正確的!
優化
from torch.utils.tensorboard import SummaryWriter import torch import torch.nn as nn import torch.nn.functional as F ''' 1,初始化writer ''' writer = SummaryWriter('runs/resnet50') # 指定寫入文件的位置 ''' 2,加載模型 ''' class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 6, 5) self.pool = nn.MaxPool2d(2, 2) self.fc1 = nn.Linear(6 * 12 * 12, 120) self.fc2 = nn.Linear(120, 84) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = x.view(-1, 6 * 12 * 12) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) return x net = Net() ''' 3,添加網絡結構 ''' writer.add_graph(net, torch.randn(1, 1, 28, 28)) writer.close()