From b2ac69ac570c5bf82ab78a094d107b2645952874 Mon Sep 17 00:00:00 2001 From: Harald Scheidl <harald_scheidl@hotmail.com> Date: Fri, 4 Jan 2019 17:46:34 +0100 Subject: [PATCH] analyze pixel relevance using norm. histogram for p(x_i) distribution --- data/pixelRelevance.npy | Bin 13056 -> 13056 bytes data/translationInvarianceTexts.pickle | Bin 0 -> 304 bytes src/analyze.py | 65 +++++++++++++++++-------- 3 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 data/translationInvarianceTexts.pickle diff --git a/data/pixelRelevance.npy b/data/pixelRelevance.npy index 28a681aeb1dab442db4ecd2753dc75989cd0823f..d7ce72613b0217b0590b679842519e20daad520a 100644 GIT binary patch literal 13056 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 U;k)b8K2Dp7aZXlm4@g=A02nG6{Qv*} literal 13056 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 diff --git a/data/translationInvarianceTexts.pickle b/data/translationInvarianceTexts.pickle new file mode 100644 index 0000000000000000000000000000000000000000..55ac8fc3635f0050334b16b7fda9d7ea4e1c2ab5 GIT binary patch literal 304 zcmZo*jxA)+h+t-5U`Q-VEo6kVnBXjCIEw|&VvS${=>TbAgEGrf3)$iF9B>vVLYfP~ z<c7=hz*)R-79T`mSy5^sKU`1%&JqMmCxa{(f-=ie3x(nGB2dAi)Iw1NQ!Ij&fq@}8 Y5oD@3LRbR9lteJ45KL(VQzlgp0Eq2EfdBvi literal 0 HcmV?d00001 diff --git a/src/analyze.py b/src/analyze.py index ca94297..425e092 100644 --- a/src/analyze.py +++ b/src/analyze.py @@ -3,6 +3,7 @@ from __future__ import print_function import sys import math +import pickle import copy import numpy as np import cv2 @@ -12,12 +13,16 @@ from Model import Model, DecoderType from SamplePreprocessor import preprocess -class FilePaths: +# constants like filepaths +class Constants: "filenames and paths to data" fnCharList = '../model/charList.txt' fnAnalyze = '../data/analyze.png' fnPixelRelevance = '../data/pixelRelevance.npy' fnTranslationInvariance = '../data/translationInvariance.npy' + fnTranslationInvarianceTexts = '../data/translationInvarianceTexts.pickle' + gtText = 'are' + distribution = 'histogram' # 'histogram' or 'uniform' def odds(val): @@ -32,19 +37,28 @@ def analyzePixelRelevance(): "simplified implementation of paper: Zintgraf et al - Visualizing Deep Neural Network Decisions: Prediction Difference Analysis" # setup model - model = Model(open(FilePaths.fnCharList).read(), DecoderType.BestPath, mustRestore=True) + model = Model(open(Constants.fnCharList).read(), DecoderType.BestPath, mustRestore=True) # read image and specify ground-truth text - img = cv2.imread(FilePaths.fnAnalyze, cv2.IMREAD_GRAYSCALE) + img = cv2.imread(Constants.fnAnalyze, cv2.IMREAD_GRAYSCALE) (w, h) = img.shape assert Model.imgSize[1] == w - gt = 'are' # compute probability of gt text in original image - batch = Batch([gt], [preprocess(img, Model.imgSize)]) + batch = Batch([Constants.gtText], [preprocess(img, Model.imgSize)]) (_, probs) = model.inferBatch(batch, calcProbability=True, probabilityOfGT=True) origProb = probs[0] + grayValues = [0, 63, 127, 191, 255] + if Constants.distribution == 'histogram': + bins = [0, 31, 95, 159, 223, 255] + (hist, _) = np.histogram(img, bins=bins) + pixelProb = hist / sum(hist) + elif Constants.distribution == 'uniform': + pixelProb = [1.0 / len(grayValues) for _ in grayValues] + else: + raise Exception('unknown value for Constants.distribution') + # iterate over all pixels in image pixelRelevance = np.zeros(img.shape, np.float32) for x in range(w): @@ -52,37 +66,35 @@ def analyzePixelRelevance(): # try a subset of possible grayvalues of pixel (x,y) imgsMarginalized = [] - for g in [0, 63, 127, 191, 255]: + for g in grayValues: imgChanged = copy.deepcopy(img) imgChanged[x, y] = g imgsMarginalized.append(preprocess(imgChanged, Model.imgSize)) # put them all into one batch - batch = Batch([gt]*len(imgsMarginalized), imgsMarginalized) + batch = Batch([Constants.gtText]*len(imgsMarginalized), imgsMarginalized) # compute probabilities (_, probs) = model.inferBatch(batch, calcProbability=True, probabilityOfGT=True) # marginalize over pixel value (assume uniform distribution) - margProb = sum(probs)/len(probs) + margProb = sum([probs[i] * pixelProb[i] for i in range(len(grayValues))]) pixelRelevance[x, y] = weightOfEvidence(origProb, margProb) print(x, y, pixelRelevance[x, y], origProb, margProb) - np.save(FilePaths.fnPixelRelevance, pixelRelevance) - + np.save(Constants.fnPixelRelevance, pixelRelevance) def analyzeTranslationInvariance(): # setup model - model = Model(open(FilePaths.fnCharList).read(), DecoderType.BestPath, mustRestore=True) + model = Model(open(Constants.fnCharList).read(), DecoderType.BestPath, mustRestore=True) # read image and specify ground-truth text - img = cv2.imread(FilePaths.fnAnalyze, cv2.IMREAD_GRAYSCALE) + img = cv2.imread(Constants.fnAnalyze, cv2.IMREAD_GRAYSCALE) (w, h) = img.shape assert Model.imgSize[1] == w - gt = 'are' imgList = [] for dy in range(Model.imgSize[0]-h+1): @@ -91,32 +103,43 @@ def analyzeTranslationInvariance(): imgList.append(preprocess(targetImg, Model.imgSize)) # put images and gt texts into batch - batch = Batch([gt]*len(imgList), imgList) + batch = Batch([Constants.gtText]*len(imgList), imgList) # compute probabilities - (_, probs) = model.inferBatch(batch, calcProbability=True, probabilityOfGT=True) - np.save(FilePaths.fnTranslationInvariance, probs) + (texts, probs) = model.inferBatch(batch, calcProbability=True, probabilityOfGT=True) + + # save results to file + f = open(Constants.fnTranslationInvarianceTexts, 'wb') + pickle.dump(texts, f) + f.close() + np.save(Constants.fnTranslationInvariance, probs) def showResults(): # 1. pixel relevance - pixelRelevance = np.load(FilePaths.fnPixelRelevance) + pixelRelevance = np.load(Constants.fnPixelRelevance) plt.figure('Pixel relevance') plt.imshow(pixelRelevance, cmap=plt.cm.jet, vmin=-0.5, vmax=0.5) plt.colorbar() - img = cv2.imread(FilePaths.fnAnalyze, cv2.IMREAD_GRAYSCALE) + img = cv2.imread(Constants.fnAnalyze, cv2.IMREAD_GRAYSCALE) plt.imshow(img, cmap=plt.cm.gray, alpha=.4) # 2. translation invariance - probs = np.load(FilePaths.fnTranslationInvariance) + probs = np.load(Constants.fnTranslationInvariance) + f = open(Constants.fnTranslationInvarianceTexts, 'rb') + texts = pickle.load(f) + texts = ['%d:'%i + texts[i] for i in range(len(texts))] + f.close() + plt.figure('Translation invariance') plt.plot(probs, 'o-') - plt.xlabel('horizontal translation') - plt.ylabel('text probability') + plt.xticks(np.arange(len(texts)), texts, rotation='vertical') + plt.xlabel('horizontal translation and best path') + plt.ylabel('text probability of "%s"'%Constants.gtText) # show both plots plt.show() -- GitLab