Dans la reconnaissance d'image, il est important de visualiser où le classificateur s'est concentré et reconnu. CNN a proposé une méthode pour propager le gradient de la fonction de perte à l'image d'entrée par rétro-propagation et visualiser l'intensité de sa valeur absolue, mais il y avait un problème de bruit. SmoothGrad est un moyen très simple de donner un bruit gaussien à l'image d'entrée et de faire la moyenne de plusieurs gradients pour une visualisation nette.
Comment il est moyenné
Smooth Grad
Vanilla Grad (méthode conventionnelle)
Le code et les articles TensorFlow peuvent être téléchargés à partir de ce qui suit. https://tensorflow.github.io/saliency/
J'ai également implémenté SmoothGrad pour étudier Chainer v2. Le modèle est un modèle VGG16 formé. L'environnement est Windows7 64bit Python 3.5.2 |Anaconda 4.2.0 (64-bit) La version de chainer est «2.0.0». Il ne prend pas en charge le GPU.
import
smoothgrad.py
import chainer
import chainer.functions as F
from chainer.variable import Variable
from chainer.links import VGG16Layers
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
config Nous le faisons en mode test, mais nous devons faire une propagation inverse, donc Définissez chainer.config comme suit.
smoothgrad.py
chainer.config.train=False
chainer.config.enable_backprop=True
Chargez le modèle VGG16. Le modèle fait environ 500 Mo, donc s'il n'a pas été téléchargé à l'avance, cela prendra un certain temps.
smoothgrad.py
model = VGG16Layers()
La taille d'image de VGG est de 224x224, alors redimensionnez-la.
smoothgrad.py
image = Image.open("cheetah.png ")
image = image.resize((224,224))
Définissez le nombre d'échantillons et le niveau de bruit. Le nombre d'échantillons est de 100 et le niveau de bruit est de 20%.
smoothgrad.py
sampleSize = 100
noiseLevel = 0.2 # 20%
sigma = noiseLevel*255.0
En raison de la mémoire utilisée, nous le ferons un par un cette fois. Premièrement, dans VGG16, la disposition des canaux est BGR, alors convertissez-la et soustrayez la valeur moyenne. Ensuite, tout en ajoutant du bruit d'image, la propagation et la perte vers l'avant sont calculées, et la propagation en retour est utilisée pour calculer le gradient. Ajoutez le dégradé obtenu à la liste.
smoothgrad.py
gradList = []
for _ in range(sampleSize):
x = np.asarray(image, dtype=np.float32)
# RGB to BGR
x = x[:,:,::-1]
#Soustrayez la moyenne
x -= np.array([103.939, 116.779, 123.68], dtype=np.float32)
x = x.transpose((2, 0, 1))
x = x[np.newaxis]
#Ajoute du bruit
x += sigma*np.random.randn(x.shape[0],x.shape[1],x.shape[2],x.shape[3])
x = Variable(np.asarray(x))
#FP et sortez la dernière couche
y = model(x, layers=['prob'])['prob']
#BP avec l'étiquette de prédiction la plus élevée
t = np.zeros((x.data.shape[0]),dtype=np.int32)
t[:] = np.argmax(y.data)
t = Variable(np.asarray(t))
loss = F.softmax_cross_entropy(y,t)
loss.backward()
#Ajouter un dégradé à la liste
grad = np.copy(x.grad)
gradList.append(grad)
#Effacer le dégradé
model.cleargrads()
Prenez la valeur absolue maximale pour chaque couche du dégradé et faites-en la moyenne pour l'image.
smoothgrad.py
G = np.array(gradList)
M = np.mean(np.max(np.abs(G),axis=2),axis=0)
M = np.squeeze(M)
plt.imshow(M,"gray")
plt.show()
En augmentant le nombre moyen de feuilles, j'ai essayé de visualiser l'image d'origine et la carte pour chaque pixel.
1 échantillon
2 échantillons
3 échantillons
10 échantillons
20 échantillons
30 échantillons
50 échantillons
75 échantillons
100 échantillons
Si vous visualisez à partir d'un échantillon sans donner de bruit, vous pouvez voir beaucoup de bruit comme indiqué ci-dessous.
Recommended Posts