Spaces:
Sleeping
Sleeping
import json | |
import os | |
import streamlit as st | |
from PIL import Image | |
from streamlit_image_select import image_select | |
import app_lib.defaults as defaults | |
from app_lib.utils import SUPPORTED_DATASETS, SUPPORTED_MODELS | |
IMAGE_DIR = os.path.join("assets", "images") | |
IMAGE_NAMES = list(sorted(filter(lambda x: x.endswith(".jpg"), os.listdir(IMAGE_DIR)))) | |
IMAGE_PATHS = list(map(lambda x: os.path.join(IMAGE_DIR, x), IMAGE_NAMES)) | |
IMAGE_PRESETS = json.load(open("assets/image_presets.json")) | |
def _validate_class_name(class_name): | |
if class_name is None: | |
return (False, "Class name cannot be empty.") | |
if class_name.strip() == "": | |
return (False, "Class name cannot be empty.") | |
return (True, None) | |
def _validate_concepts(concepts): | |
if len(concepts) < 3: | |
return (False, "You must provide at least 3 concepts") | |
if len(concepts) > 10: | |
return (False, "Maximum 10 concepts allowed") | |
return (True, None) | |
def _get_significance_level(): | |
default = defaults.SIGNIFICANCE_LEVEL_VALUE | |
step = defaults.SIGNIFICANCE_LEVEL_STEP | |
return st.slider( | |
"Significance level", | |
help=f"The level of significance of the tests. Defaults to {default:.2F}.", | |
min_value=step, | |
max_value=1.0, | |
value=default, | |
step=step, | |
disabled=st.session_state.disabled, | |
) | |
def _get_tau_max(): | |
default = defaults.TAU_MAX_VALUE | |
step = defaults.TAU_MAX_STEP | |
return int( | |
st.slider( | |
"Length of test", | |
help=f"The maximum number of steps for each test. Defaults to {default}.", | |
min_value=step, | |
max_value=1000, | |
step=step, | |
value=default, | |
disabled=st.session_state.disabled, | |
) | |
) | |
def _get_number_of_tests(): | |
default = defaults.R_VALUE | |
step = defaults.R_STEP | |
return int( | |
st.slider( | |
"Number of tests per concept", | |
help=( | |
"The number of tests to average for each concept. " | |
f"Defaults to {default}." | |
), | |
min_value=step, | |
max_value=100, | |
step=step, | |
value=default, | |
disabled=st.session_state.disabled, | |
) | |
) | |
def _get_cardinality(concepts, concepts_ready): | |
default = defaults.CARDINALITY_VALUE | |
step = defaults.CARDINALITY_STEP | |
return st.slider( | |
"Size of conditioning set", | |
help=( | |
"The number of concepts to condition model predictions on. " | |
"Defaults to {default}." | |
), | |
min_value=1, | |
max_value=max(2, len(concepts) - 1), | |
value=default, | |
step=step, | |
disabled=st.session_state.disabled or not concepts_ready, | |
) | |
def _get_dataset_name(): | |
options = SUPPORTED_DATASETS | |
default_idx = options.index(defaults.DATASET_NAME) | |
return st.selectbox( | |
"Dataset", | |
options=options, | |
index=default_idx, | |
help=( | |
"Name of the dataset to use to train sampler." | |
f"Defaults to {SUPPORTED_DATASETS[default_idx]}." | |
), | |
disabled=st.session_state.disabled, | |
) | |
def get_model_name(): | |
options = list(SUPPORTED_MODELS.keys()) | |
default_idx = options.index(defaults.MODEL_NAME) | |
return st.selectbox( | |
"Model to test", | |
options=options, | |
index=default_idx, | |
help=( | |
"Name of the vision-language model to test the predictions of." | |
f"Defaults to {options[default_idx]}" | |
), | |
disabled=st.session_state.disabled, | |
) | |
def get_image(): | |
with st.sidebar: | |
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "png", "jpeg"]) | |
if uploaded_file is not None: | |
return (None, Image.open(uploaded_file)) | |
else: | |
DEFAULT = IMAGE_NAMES.index("bowl_ace.jpg") | |
image_idx = image_select( | |
label="or select one", | |
images=IMAGE_PATHS, | |
index=DEFAULT, | |
return_value="index", | |
) | |
image_name, image_path = IMAGE_NAMES[image_idx], IMAGE_PATHS[image_idx] | |
return (image_name, Image.open(image_path)) | |
def get_class_name(image_name=None): | |
default = ( | |
IMAGE_PRESETS[image_name.split(".")[0]]["class_name"] if image_name else "" | |
) | |
class_name = st.text_input( | |
"Class to predict", | |
help="Name of the class to build the zero-shot CLIP classifier with.", | |
value=default, | |
disabled=st.session_state.disabled, | |
placeholder="Type class name here", | |
) | |
class_ready, class_error = _validate_class_name(class_name) | |
return class_name, class_ready, class_error | |
def get_concepts(image_name=None): | |
default = ( | |
"\n".join(IMAGE_PRESETS[image_name.split(".")[0]]["concepts"]) | |
if image_name | |
else "" | |
) | |
concepts = st.text_area( | |
"Concepts to test", | |
help=( | |
"List of concepts to test the predictions of the model with. " | |
"Write one concept per line. Maximum 10 concepts allowed." | |
), | |
height=180, | |
value=default, | |
disabled=st.session_state.disabled, | |
placeholder="Type one concept\nper line", | |
) | |
concepts = concepts.split("\n") | |
concepts = [concept.strip() for concept in concepts] | |
concepts = [concept for concept in concepts if concept != ""] | |
concepts = list(set(concepts)) | |
concepts_ready, concepts_error = _validate_concepts(concepts) | |
return concepts, concepts_ready, concepts_error | |
def get_advanced_settings(concepts, concepts_ready): | |
with st.expander("Advanced settings"): | |
dataset_name = _get_dataset_name() | |
significance_level = _get_significance_level() | |
tau_max = _get_tau_max() | |
r = _get_number_of_tests() | |
cardinality = _get_cardinality(concepts, concepts_ready) | |
st.divider() | |
return significance_level, tau_max, r, cardinality, dataset_name | |