Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
RAGRights
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lifo
Anaïs Halftermeyer
RAGRights
Commits
c5c42ada
Commit
c5c42ada
authored
Jun 19, 2026
by
Delvallez Delvallez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
outils de visulistaion des résultats
parent
9d73694e
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
448 additions
and
0 deletions
+448
-0
compte_noeuds_sensible.py
mechir/tools/compte_noeuds_sensible.py
+165
-0
graphiques-to-planches.py
mechir/tools/graphiques-to-planches.py
+283
-0
No files found.
mechir/tools/compte_noeuds_sensible.py
0 → 100755
View file @
c5c42ada
#!/usr/bin/env python
import
json
import
numpy
as
np
import
sys
import
seaborn
as
sns
import
matplotlib.pyplot
as
plt
import
argparse
from
pathlib
import
Path
from
itertools
import
combinations
def
compter_noeuds_sensibles
(
json_path
,
pert_type
):
"""
Compte le nombre de perturbations pour lesquelles chaque noeud
est considéré comme sensible.
Parameters
----------
json_path : str
Chemin du fichier JSON.
est_sensible : callable
Fonction prenant (mean, std) et renvoyant True ou False.
Returns
-------
np.ndarray
Matrice des comptes.
"""
with
open
(
json_path
,
"r"
,
encoding
=
"utf-8"
)
as
f
:
data
=
json
.
load
(
f
)
premiere_perturbation
=
next
(
iter
(
data
.
values
()))
shape
=
np
.
array
(
premiere_perturbation
[
"patching_mean"
])
.
shape
compteurs
=
np
.
zeros
(
shape
,
dtype
=
int
)
compteur_pert
=
{}
for
perturbation
,
valeurs
in
data
.
items
():
if
pert_type
==
"all"
or
pert_type
==
perturbation_type
(
perturbation
):
mean
=
np
.
array
(
valeurs
[
"patching_mean"
])
std
=
np
.
array
(
valeurs
[
"patching_std"
])
resc_mean
=
(
np
.
sign
(
mean
)
/
np
.
absolute
(
mean
)
.
max
())
*
np
.
absolute
(
mean
)
resc_std
=
(
np
.
sign
(
std
)
/
np
.
absolute
(
std
)
.
max
())
*
np
.
absolute
(
std
)
compteur_pert
[
perturbation
]
=
{}
compteur_pert
[
perturbation
][
"carte"
]
=
((
np
.
abs
(
mean
)
>
0.1
)
&
(
np
.
abs
(
resc_mean
)
>
0.5
))
|
(
resc_std
>
0.5
)
compteur_pert
[
perturbation
][
"noeuds_sensibles"
]
=
[]
for
i
in
range
(
mean
.
shape
[
0
]):
for
j
in
range
(
mean
.
shape
[
1
]):
if
compteur_pert
[
perturbation
][
"carte"
][
i
,
j
]:
compteur_pert
[
perturbation
][
"noeuds_sensibles"
]
.
append
((
i
,
j
,
mean
[
i
,
j
],
std
[
i
,
j
],
resc_mean
[
i
,
j
],
resc_std
[
i
,
j
]))
compteur_pert
[
perturbation
][
"total"
]
=
np
.
sum
(
compteur_pert
[
perturbation
][
"carte"
])
compteurs
+=
compteur_pert
[
perturbation
][
"carte"
]
return
compteurs
,
compteur_pert
def
plot_noeuds_sensibles
(
noeuds_sensibles
,
title
,
save_path
):
ax
=
sns
.
heatmap
(
noeuds_sensibles
,
cmap
=
"Reds"
,
vmin
=
0
,
vmax
=
noeuds_sensibles
.
max
(),
xticklabels
=
True
,
yticklabels
=
True
,
annot
=
True
,
annot_kws
=
{
"size"
:
8
},
)
plt
.
title
(
title
)
plt
.
xlabel
(
"Head"
)
plt
.
ylabel
(
"Layer"
)
if
save_path
:
plt
.
savefig
(
save_path
)
plt
.
close
()
else
:
plt
.
show
()
def
perturbation_type
(
pert
):
if
"->"
in
pert
:
return
"replace"
if
pert
[
0
]
==
"+"
:
return
"append"
if
pert
[
-
1
]
==
"+"
:
return
"prepend"
raise
RuntimeWarning
(
"Unreachable"
)
def
stats
(
noeuds_perts
,
path
):
s
=
"Nombre de noeuds relevés par perturbation"
for
pert
,
values
in
noeuds_perts
.
items
():
s
+=
f
"
\n
{pert} : {values["
total
"]}"
for
pert
,
values
in
noeuds_perts
.
items
():
s
+=
f
"
\n
{pert} : "
for
i
,
j
,
mean
,
std
,
rmean
,
rstd
in
values
[
"noeuds_sensibles"
]:
s
+=
f
"
\n\t
({i}, {j}) {mean:.2f}, {std:.2f} | {rmean:.2f}, {rstd:.2f}"
print
(
s
)
if
path
:
with
open
(
path
,
'w'
)
as
f
:
f
.
write
(
s
)
def
cli
():
parser
=
argparse
.
ArgumentParser
(
description
=
(
"Génère une matrice récapitulative des noeuds "
"sensibles pour le lot de matrices de sensibilité à des"
" perturbations fourni."
)
)
parser
.
add_argument
(
"input_json"
,
help
=
"Fichier JSON contennant les matrices de sensibilité aux perturbation."
,
)
parser
.
add_argument
(
"-t"
,
"--title"
,
default
=
"Noeuds sensibles"
,
help
=
(
"Titre du graphique généré "
"(défaut : pNoeuds sensibles)."
),
)
parser
.
add_argument
(
"-s"
,
"--save"
,
default
=
False
,
type
=
Path
,
help
=
(
"Chemin de répertoire pour la sauvegarde des informations"
"(défaut : False (affiche mais ne sauvegarde pas))."
),
)
parser
.
add_argument
(
"-p"
,
"--perturbationtype"
,
default
=
"all"
,
choices
=
[
'all'
,
'replace'
,
'append'
,
'prepend'
],
help
=
(
"Chemin de sauvegarde du graphique"
"(défaut : False (affiche mais ne sauvegarde pas))."
),
)
return
parser
.
parse_args
()
if
__name__
==
"__main__"
:
args
=
cli
()
noeuds_sensibles
,
noeuds_perts
=
compter_noeuds_sensibles
(
args
.
input_json
,
pert_type
=
args
.
perturbationtype
)
save_path
=
False
if
not
args
.
save
else
Path
(
args
.
save
)
save_stats_path
=
False
if
not
args
.
save
else
save_path
/
f
"StatsSensibiliteNoeuds-{args.perturbationtype}.txt"
save_plot_path
=
False
if
not
args
.
save
else
save_path
/
f
"SensibiliteNoeuds-{args.perturbationtype}.png"
stats
(
noeuds_perts
,
save_stats_path
)
plot_noeuds_sensibles
(
noeuds_sensibles
,
title
=
args
.
title
,
save_path
=
save_plot_path
)
mechir/tools/graphiques-to-planches.py
0 → 100755
View file @
c5c42ada
#!/usr/bin/env python
import
subprocess
from
pathlib
import
Path
import
argparse
def
image_ou_blanche
(
chemin
,
taille
):
"""
Retourne les arguments ImageMagick correspondant soit à une image
existante, soit à une image blanche de substitution.
Parameters
----------
chemin : Path
Chemin de l'image recherchée.
taille : str
Taille de l'image blanche (ex. "1000x600").
Returns
-------
list[str]
Arguments à insérer dans la commande ImageMagick.
"""
if
chemin
.
exists
():
return
[
str
(
chemin
)]
else
:
print
(
f
"Image absente : {chemin.name}"
)
return
[
"-size"
,
taille
,
"xc:white"
]
def
perturbation_type
(
pert
):
if
"->"
in
pert
:
return
"replace"
if
pert
[
0
]
==
"+"
:
return
"append"
if
pert
[
-
1
]
==
"+"
:
return
"prepend"
raise
RuntimeWarning
(
"Unreachable"
)
def
generer_planche
(
dossier
,
sortie
=
"planche_globale.png"
,
nb_colonnes
=
3
,
keep_temp
=
False
,
pert_type
=
"all"
):
"""
Génère une grande planche récapitulative.
Chaque perturbation donne lieu à une tuile :
- score en haut ;
- mean et std côte à côte ;
- meanV2 et stdV2 si disponibles.
Parameters
----------
dossier : str
Dossier contenant les images.
sortie : str
Nom de l'image finale.
nb_colonnes : int
Nombre de tuiles par ligne dans la planche finale.
"""
dossier
=
Path
(
dossier
)
prefix
=
"PerturbationScore_"
perturbations
=
sorted
(
f
.
stem
[
len
(
prefix
):]
for
f
in
dossier
.
glob
(
f
"{prefix}*.png"
)
)
tuiles
=
[]
for
pert
in
perturbations
:
if
pert_type
==
"all"
or
perturbation_type
(
pert
)
==
pert_type
:
score
=
dossier
/
f
"PerturbationScore_{pert}.png"
mean
=
dossier
/
f
"ComponentPatching-mean_{pert}.png"
std
=
dossier
/
f
"ComponentPatching-std_{pert}.png"
mean_v2
=
dossier
/
f
"ComponentPatching-mean_{pert}V2.png"
std_v2
=
dossier
/
f
"ComponentPatching-std_{pert}V2.png"
tuile
=
dossier
/
f
"__tuile_{pert}.png"
# Ligne mean/std
cmd
=
[
"magick"
,
"("
,
*
image_ou_blanche
(
mean
,
"1000x600"
),
"-resize"
,
"x600"
,
")"
,
"("
,
*
image_ou_blanche
(
std
,
"1000x600"
),
"-resize"
,
"x600"
,
")"
,
"+append"
,
]
if
mean_v2
.
exists
()
or
std_v2
.
exists
():
ligne_v2
=
dossier
/
f
"__ligneV2_{pert}.png"
subprocess
.
run
(
[
"magick"
,
"("
,
*
image_ou_blanche
(
mean_v2
,
"1000x600"
),
"-resize"
,
"x600"
,
")"
,
"("
,
*
image_ou_blanche
(
std_v2
,
"1000x600"
),
"-resize"
,
"x600"
,
")"
,
"+append"
,
str
(
ligne_v2
),
],
check
=
True
,
)
ligne_bas
=
dossier
/
f
"__bas_{pert}.png"
subprocess
.
run
(
cmd
+
[
str
(
ligne_bas
)],
check
=
True
,
)
subprocess
.
run
(
[
"magick"
,
str
(
score
),
"-resize"
,
"1500x400"
,
str
(
ligne_bas
),
str
(
ligne_v2
),
"-append"
,
str
(
tuile
),
],
check
=
True
,
)
ligne_v2
.
unlink
()
ligne_bas
.
unlink
()
else
:
ligne_bas
=
dossier
/
f
"__bas_{pert}.png"
subprocess
.
run
(
cmd
+
[
str
(
ligne_bas
)],
check
=
True
,
)
subprocess
.
run
(
[
"magick"
,
str
(
score
),
"-resize"
,
"1500x400"
,
str
(
ligne_bas
),
"-append"
,
str
(
tuile
),
],
check
=
True
,
)
ligne_bas
.
unlink
()
tuiles
.
append
(
tuile
)
if
not
tuiles
:
raise
RuntimeError
(
"Aucune perturbation trouvée."
)
# Construction de la planche globale
lignes
=
[]
for
i
in
range
(
0
,
len
(
tuiles
),
nb_colonnes
):
ligne
=
dossier
/
f
"__planche_ligne_{i}.png"
subprocess
.
run
(
[
"magick"
]
+
[
str
(
t
)
for
t
in
tuiles
[
i
:
i
+
nb_colonnes
]]
+
[
"+append"
,
str
(
ligne
)],
check
=
True
,
)
lignes
.
append
(
ligne
)
subprocess
.
run
(
[
"magick"
]
+
[
str
(
l
)
for
l
in
lignes
]
+
[
"-append"
,
sortie
],
check
=
True
,
)
print
(
f
"Planche enregistrée dans : {sortie}"
)
# nettoyage
if
not
keep_temp
:
for
f
in
tuiles
+
lignes
:
f
.
unlink
()
def
main
():
parser
=
argparse
.
ArgumentParser
(
description
=
(
"Génère une planche récapitulative à partir des "
"graphiques produits lors des expériences de perturbation."
)
)
parser
.
add_argument
(
"input_dir"
,
help
=
"Dossier contenant les images à regrouper."
,
)
parser
.
add_argument
(
"-o"
,
"--output"
,
default
=
"planche_globale.png"
,
help
=
(
"Nom du fichier image généré "
"(défaut : planche_globale.png)."
),
)
parser
.
add_argument
(
"-c"
,
"--cols"
,
type
=
int
,
default
=
4
,
help
=
(
"Nombre de triplets affichés par ligne "
"dans la planche finale (défaut : 4)."
),
)
parser
.
add_argument
(
"--keep-temp"
,
action
=
"store_true"
,
help
=
(
"Conserve les images intermédiaires "
"créées pendant l'assemblage."
),
)
parser
.
add_argument
(
"-p"
,
"--pert_type"
,
choices
=
[
"all"
,
"replace"
,
"append"
,
"prepend"
],
default
=
"all"
,
help
=
(
"Restreindre la place à un certain type de perturbation."
),
)
args
=
parser
.
parse_args
()
generer_planche
(
dossier
=
args
.
input_dir
,
sortie
=
args
.
output
,
nb_colonnes
=
args
.
cols
,
keep_temp
=
args
.
keep_temp
,
pert_type
=
args
.
pert_type
)
if
__name__
==
"__main__"
:
main
()
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment