Градиент слоев нагруженной нейронной сети в Chainer - PullRequest
0 голосов
/ 01 ноября 2018

Я загружаю предварительно обученную модель в Chainer:

net=chainer.links.VGG16Layers(pretrained_model='auto')

Затем я делаю прямой проход с некоторыми данными и добавляю слой потерь:

acts = net.predict([image]).array loss=chainer.Variable(np.array(np.sum(np.square(acts-one_hot))))

Теперь вопрос в том, как сделать обратный проход и получить градиенты разных слоев?

Типичный обратный метод не работает.

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Если вы хотите получить .grad входного изображения, вам нужно обернуть входное значение chainer.Variable.
Однако VGGLayers.extract() не поддерживает вводы Variable, поэтому в этом случае вам следует вызвать .forward() или его функцию обтекания __call__().

import chainer
from chainer import Variable
from chainer import functions as F
from cv2 import imread
from chainer.links.model.vision import vgg

net = vgg.VGG16Layers(pretrained_model='auto')

# convert raw image (np.ndarray, dtype=uint32) to a batch of Variable(dtype=float32)
img = imread("path/to/image")
img = Variable(vgg.prepare(img))
img = img.reshape((1,) + img.shape)  # (channel, width, height) -> (batch, channel, width, height)

# just call VGG16Layers.forward, which is wrapped by __call__()
prob = net(img)['prob']
intermediate = F.square(prob)
loss = F.sum(intermediate)

# calculate grad
img_grad = chainer.grad([loss], [img])  # returns Variable
print(img_grad.array) # some ndarray
0 голосов
/ 04 ноября 2018

Точка 1.
НЕ вызывайте VGGLayers.predict(), который не предназначен для вычисления backprop.
НЕ используйте VGGLayers.extract() вместо.

Точка 2.
НЕ применяйте np.square() и np.sum() непосредственно к chainer.Variable.
НЕ используйте F.square() и F.sum() вместо chainer.Variable.

Точка 3.
Используйте loss.backward(), чтобы получить .grad для изучаемых параметров. (шаблон 1)
Используйте loss.backward(retain_grad=True), чтобы получить .grad для всех переменных. (шаблон 2)
Используйте chainer.grad(), чтобы получить .grad для определенной переменной. (шаблон 3)

код:

import chainer
from chainer import functions as F, links as L
from cv2 import imread

net = L.VGG16Layers(pretrained_model='auto')
img = imread("/path/to/img")
prob = net.extract([img], layers=['prob'])['prob']  # NOT predict, which overrides chainer.config['enable_backprop'] as False
intermediate = F.square(prob)
loss = F.sum(intermediate)

# pattern 1:
loss.backward()
print(net.fc8.W.grad)  # some ndarray
print(intermediate.grad)  # None
###########################################
net.cleargrads()
intermediate.grad = None
prob.grad = None
###########################################

# pattern 2:
loss.backward(retain_grad=True)
print(net.fc8.W.grad)  # some ndarray
print(intermediate.grad)  # some ndarray

###########################################
net.cleargrads()
intermediate.grad = None
prob.grad = None
###########################################

# pattern 3:
print(chainer.grad([loss], [net.fc8.W]))  # some ndarray
print(intermediate.grad)  # None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...