Layer-wise Relevance Propagation을 Chainer에서 구현
1. Layer-wise Relevance Propagation(LRP)
원논문은 이 로, 자세한 것은 이하 참조.
Qiita : 딥 러닝의 판단 근거를 이해하는 방법
나는 LRP를
일단 데이터를 순 전파시켜, 출력층으로부터 각 층의 출력과 가중치를 바탕으로 공헌도를 구해 가는 수법
라고 이해합니다.
2. Chainer
국산 신경망을 위한 프레임워크입니다.
일단, 순전파시키면 데이터가 수주 연결되어 남기 때문에, 개인적으로는 사용하기 쉽고 좋아합니다.
Chainer: A flexible framework for neural networks
3. 구현 (chainer v2.0.0)
Chainer는 한번, 순전파시키면 데이터와 생성된 레이어의 종류를 참조할 수 있으므로, 그것을 이용해 구현합니다 버그등이 있을지도 모릅니다.
아래의 코드는 최소한의 선형 결합과 컨볼루션, 풀링에만 대응하고 있습니다.
또한 입력 z의 shape는 (데이터 수, 출력 뉴런 수)를 상정하고 있습니다.
import chainer
import numpy as np
def LRP(z, epsilon=0):
creator = z.creator
var = z
# relevance value
r = np.zeros(z.data.shape)
for i, d in enumerate(z.data):
r[i, d.argmax()] = d.max()
while(creator is not None):
x = creator.inputs[0].data
y = creator.outputs[0]().data
if len(creator.inputs) > 1:
w = creator.inputs[1].data
if creator.label == "LinearFunction":
_y = y + epsilon*np.sign(y)
r = x.reshape(r.shape[0], -1) * (np.dot(r/_y, w))
elif creator.label == "Convolution2DFunction":
_y = y + epsilon*np.sign(y)
r = x * chainer.functions.deconvolution_2d(r.reshape(y.shape)/_y,
w).data
elif creator.label == "MaxPooling2D":
r = chainer.functions.unpooling_2d(
r.reshape(y.shape),
ksize=creator.kh,
stride=creator.sy,
outsize=x.shape[2:]).data
var = creator.inputs[0]
creator = var.creator
return r
일단 출력층의 데이터가 사라지지 않도록 아래의 후크를 순전파 시 추가했습니다.
from chainer.function import FunctionHook
class RetainOutputHook(FunctionHook):
def forward_postprocess(self, function, in_data):
function.retain_outputs([0])
''' Example
with RetainOutputHook():
z = model.predict(x)
'''
4. 출력 예
아래의 네트워크(n_units=100)에 MNIST를 학습시켜 입력에 대한 LRP를 시각화했습니다.
class CNN(chainer.Chain):
def __init__(self, n_units):
super(CNN, self).__init__()
with self.init_scope():
self.conv1 = chainer.links.Convolution2D(in_channels=1, out_channels=n_units//2, ksize=3, stride=1)
self.conv2 = chainer.links.Convolution2D(in_channels=None, out_channels=n_units, ksize=3, stride=1)
self.l = chainer.links.Linear(None, 10)
def __call__(self, x):
x = chainer.functions.relu(self.conv1(x))
x = chainer.functions.max_pooling_2d(x, ksize=2, stride=2)
x = chainer.functions.relu(self.conv2(x))
x = chainer.functions.max_pooling_2d(x, ksize=2, stride=2)
return self.l(x)
왼쪽: 입력 이미지 오른쪽: LRP
Reference
이 문제에 관하여(Layer-wise Relevance Propagation을 Chainer에서 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/likeman/items/6ebee15e72ef1a9f3c03
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
국산 신경망을 위한 프레임워크입니다.
일단, 순전파시키면 데이터가 수주 연결되어 남기 때문에, 개인적으로는 사용하기 쉽고 좋아합니다.
Chainer: A flexible framework for neural networks
3. 구현 (chainer v2.0.0)
Chainer는 한번, 순전파시키면 데이터와 생성된 레이어의 종류를 참조할 수 있으므로, 그것을 이용해 구현합니다 버그등이 있을지도 모릅니다.
아래의 코드는 최소한의 선형 결합과 컨볼루션, 풀링에만 대응하고 있습니다.
또한 입력 z의 shape는 (데이터 수, 출력 뉴런 수)를 상정하고 있습니다.
import chainer
import numpy as np
def LRP(z, epsilon=0):
creator = z.creator
var = z
# relevance value
r = np.zeros(z.data.shape)
for i, d in enumerate(z.data):
r[i, d.argmax()] = d.max()
while(creator is not None):
x = creator.inputs[0].data
y = creator.outputs[0]().data
if len(creator.inputs) > 1:
w = creator.inputs[1].data
if creator.label == "LinearFunction":
_y = y + epsilon*np.sign(y)
r = x.reshape(r.shape[0], -1) * (np.dot(r/_y, w))
elif creator.label == "Convolution2DFunction":
_y = y + epsilon*np.sign(y)
r = x * chainer.functions.deconvolution_2d(r.reshape(y.shape)/_y,
w).data
elif creator.label == "MaxPooling2D":
r = chainer.functions.unpooling_2d(
r.reshape(y.shape),
ksize=creator.kh,
stride=creator.sy,
outsize=x.shape[2:]).data
var = creator.inputs[0]
creator = var.creator
return r
일단 출력층의 데이터가 사라지지 않도록 아래의 후크를 순전파 시 추가했습니다.
from chainer.function import FunctionHook
class RetainOutputHook(FunctionHook):
def forward_postprocess(self, function, in_data):
function.retain_outputs([0])
''' Example
with RetainOutputHook():
z = model.predict(x)
'''
4. 출력 예
아래의 네트워크(n_units=100)에 MNIST를 학습시켜 입력에 대한 LRP를 시각화했습니다.
class CNN(chainer.Chain):
def __init__(self, n_units):
super(CNN, self).__init__()
with self.init_scope():
self.conv1 = chainer.links.Convolution2D(in_channels=1, out_channels=n_units//2, ksize=3, stride=1)
self.conv2 = chainer.links.Convolution2D(in_channels=None, out_channels=n_units, ksize=3, stride=1)
self.l = chainer.links.Linear(None, 10)
def __call__(self, x):
x = chainer.functions.relu(self.conv1(x))
x = chainer.functions.max_pooling_2d(x, ksize=2, stride=2)
x = chainer.functions.relu(self.conv2(x))
x = chainer.functions.max_pooling_2d(x, ksize=2, stride=2)
return self.l(x)
왼쪽: 입력 이미지 오른쪽: LRP
Reference
이 문제에 관하여(Layer-wise Relevance Propagation을 Chainer에서 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/likeman/items/6ebee15e72ef1a9f3c03
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import chainer
import numpy as np
def LRP(z, epsilon=0):
creator = z.creator
var = z
# relevance value
r = np.zeros(z.data.shape)
for i, d in enumerate(z.data):
r[i, d.argmax()] = d.max()
while(creator is not None):
x = creator.inputs[0].data
y = creator.outputs[0]().data
if len(creator.inputs) > 1:
w = creator.inputs[1].data
if creator.label == "LinearFunction":
_y = y + epsilon*np.sign(y)
r = x.reshape(r.shape[0], -1) * (np.dot(r/_y, w))
elif creator.label == "Convolution2DFunction":
_y = y + epsilon*np.sign(y)
r = x * chainer.functions.deconvolution_2d(r.reshape(y.shape)/_y,
w).data
elif creator.label == "MaxPooling2D":
r = chainer.functions.unpooling_2d(
r.reshape(y.shape),
ksize=creator.kh,
stride=creator.sy,
outsize=x.shape[2:]).data
var = creator.inputs[0]
creator = var.creator
return r
from chainer.function import FunctionHook
class RetainOutputHook(FunctionHook):
def forward_postprocess(self, function, in_data):
function.retain_outputs([0])
''' Example
with RetainOutputHook():
z = model.predict(x)
'''
아래의 네트워크(n_units=100)에 MNIST를 학습시켜 입력에 대한 LRP를 시각화했습니다.
class CNN(chainer.Chain):
def __init__(self, n_units):
super(CNN, self).__init__()
with self.init_scope():
self.conv1 = chainer.links.Convolution2D(in_channels=1, out_channels=n_units//2, ksize=3, stride=1)
self.conv2 = chainer.links.Convolution2D(in_channels=None, out_channels=n_units, ksize=3, stride=1)
self.l = chainer.links.Linear(None, 10)
def __call__(self, x):
x = chainer.functions.relu(self.conv1(x))
x = chainer.functions.max_pooling_2d(x, ksize=2, stride=2)
x = chainer.functions.relu(self.conv2(x))
x = chainer.functions.max_pooling_2d(x, ksize=2, stride=2)
return self.l(x)
왼쪽: 입력 이미지 오른쪽: LRP
Reference
이 문제에 관하여(Layer-wise Relevance Propagation을 Chainer에서 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/likeman/items/6ebee15e72ef1a9f3c03텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)