Spaces:
Sleeping
Sleeping
adding explanations and similar samples
Browse files- closest_sample.py +42 -0
- explanations.py +80 -0
- fossils_paths.csv +0 -0
- pca_fossils_170_finer.pkl +3 -0
- pca_leaves_170_finer.pkl +3 -0
closest_sample.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sklearn.decomposition import PCA
|
2 |
+
import pickle as pk
|
3 |
+
import numpy as np
|
4 |
+
import pandas as pd
|
5 |
+
|
6 |
+
|
7 |
+
|
8 |
+
pca_fossils = pk.load(open('pca_fossils_170_finer.pkl','rb'))
|
9 |
+
pca_leaves = pk.load(open('pca_leaves_170_finer.pkl','rb'))
|
10 |
+
embedding_fossils = np.load('embedding_fossils_170_finer.npy')
|
11 |
+
#embedding_leaves = np.load('embedding_leaves.npy')
|
12 |
+
|
13 |
+
fossils_pd= pd.read_csv('fossils_paths.csv')
|
14 |
+
|
15 |
+
def pca_distance(pca,sample,embedding):
|
16 |
+
s = pca.transform(sample.reshape(1,-1))
|
17 |
+
all = pca.transform(embedding[:,-1])
|
18 |
+
distances = np.linalg.norm(all - s, axis=1)
|
19 |
+
print(distances)
|
20 |
+
return np.argsort(distances)[:5]
|
21 |
+
|
22 |
+
def return_paths(argsorted,files):
|
23 |
+
paths= []
|
24 |
+
for i in argsorted:
|
25 |
+
paths.append(files[i])
|
26 |
+
return paths
|
27 |
+
|
28 |
+
|
29 |
+
def get_images(embedding):
|
30 |
+
|
31 |
+
#pca_embedding_fossils = pca_fossils.transform(embedding_fossils[:,-1])
|
32 |
+
|
33 |
+
pca_d =pca_distance(pca_fossils,embedding,embedding_fossils)
|
34 |
+
|
35 |
+
fossils_paths = fossils_pd['file_name'].values
|
36 |
+
|
37 |
+
paths = return_paths(pca_d,fossils_paths)
|
38 |
+
print(paths)
|
39 |
+
paths= [path.replace('/gpfs/data/tserre/irodri15/Fossils/new_data/leavesdb-v1_1/images/Fossil/Florissant_Fossil/512/full/jpg/',
|
40 |
+
'/media/data_cifs/projects/prj_fossils/data/processed_data/leavesdb-v1_1/images/Fossil/Florissant_Fossil/original/full/jpg/') for path in paths]
|
41 |
+
print(paths)
|
42 |
+
return paths
|
explanations.py
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import xplique
|
2 |
+
import tensorflow as tf
|
3 |
+
from xplique.attributions import (Saliency, GradientInput, IntegratedGradients, SmoothGrad, VarGrad,
|
4 |
+
SquareGrad, GradCAM, Occlusion, Rise, GuidedBackprop,
|
5 |
+
GradCAMPP, Lime, KernelShap)
|
6 |
+
|
7 |
+
import numpy as np
|
8 |
+
import matplotlib.pyplot as plt
|
9 |
+
from inference_resnet import inference_resnet_finer, preprocess, _clever_crop
|
10 |
+
BATCH_SIZE = 1
|
11 |
+
|
12 |
+
def show(img, p=False, **kwargs):
|
13 |
+
img = np.array(img, dtype=np.float32)
|
14 |
+
|
15 |
+
# check if channel first
|
16 |
+
if img.shape[0] == 1:
|
17 |
+
img = img[0]
|
18 |
+
|
19 |
+
# check if cmap
|
20 |
+
if img.shape[-1] == 1:
|
21 |
+
img = img[:,:,0]
|
22 |
+
elif img.shape[-1] == 3:
|
23 |
+
img = img[:,:,::-1]
|
24 |
+
|
25 |
+
# normalize
|
26 |
+
if img.max() > 1 or img.min() < 0:
|
27 |
+
img -= img.min(); img/=img.max()
|
28 |
+
# check if clip percentile
|
29 |
+
if p is not False:
|
30 |
+
img = np.clip(img, np.percentile(img, p), np.percentile(img, 100-p))
|
31 |
+
plt.imshow(img, **kwargs)
|
32 |
+
plt.axis('off')
|
33 |
+
|
34 |
+
#return img
|
35 |
+
|
36 |
+
|
37 |
+
|
38 |
+
def explain(model, input_image,size=600, n_classes=171) :
|
39 |
+
"""
|
40 |
+
Generate explanations for a given model and dataset.
|
41 |
+
:param model: The model to explain.
|
42 |
+
:param X: The dataset.
|
43 |
+
:param Y: The labels.
|
44 |
+
:param explainer: The explainer to use.
|
45 |
+
:param batch_size: The batch size to use.
|
46 |
+
:return: The explanations.
|
47 |
+
"""
|
48 |
+
|
49 |
+
# we only need the classification part of the model
|
50 |
+
class_model = tf.keras.Model(model.input, model.output[1])
|
51 |
+
|
52 |
+
explainers = [
|
53 |
+
Saliency(class_model),
|
54 |
+
IntegratedGradients(class_model, steps=50, batch_size=BATCH_SIZE),
|
55 |
+
SmoothGrad(class_model, nb_samples=50, batch_size=BATCH_SIZE),
|
56 |
+
#GradCAM(class_model),
|
57 |
+
]
|
58 |
+
cropped,repetitions = _clever_crop(input_image,(size,size))
|
59 |
+
size_repetitions = int(size//(repetitions.numpy()+1))
|
60 |
+
X = preprocess(cropped,size=size)
|
61 |
+
Y = np.argmax(class_model.predict(np.array([X])))
|
62 |
+
X = np.expand_dims(X, 0)
|
63 |
+
explanations = []
|
64 |
+
for e,explainer in enumerate(explainers):
|
65 |
+
print(f'{e}/{len(explainers)}')
|
66 |
+
Y = tf.one_hot([Y], n_classes)
|
67 |
+
phi = np.abs(explainer(X, Y))[0]
|
68 |
+
|
69 |
+
if len(phi.shape) == 3:
|
70 |
+
phi = np.mean(phi, -1)
|
71 |
+
|
72 |
+
show(X[0][:,size_repetitions:2*size_repetitions,:])
|
73 |
+
show(phi[:,size_repetitions:2*size_repetitions], p=1, alpha=0.4)
|
74 |
+
|
75 |
+
plt.savefig(f'phi_{e}.png')
|
76 |
+
explanations.append(f'phi_{e}.png')
|
77 |
+
|
78 |
+
print('Done')
|
79 |
+
|
80 |
+
return explanations
|
fossils_paths.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
pca_fossils_170_finer.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1c622f5bb61b70fed1de24ad012524ee126fee662c7fe019bb966b6eea5b6922
|
3 |
+
size 27685
|
pca_leaves_170_finer.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:a43b8b1e1998f01fdf5f4a05458b9884fdd3ac9c3fa7e01875ca4e5e48078879
|
3 |
+
size 27685
|