File size: 3,219 Bytes
40f633f
ef48bcf
062bda3
a894b74
ef48bcf
 
 
 
 
3dc0018
 
a332564
 
3dc0018
 
 
 
 
 
ef48bcf
 
 
 
 
a332564
 
ef48bcf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40f633f
ef48bcf
 
 
 
 
 
 
 
 
 
 
a894b74
ef48bcf
 
062bda3
ef48bcf
 
40f633f
062bda3
 
 
ef48bcf
062bda3
 
 
 
 
 
ef48bcf
 
 
 
062bda3
 
 
ef48bcf
062bda3
ef48bcf
4ebffee
3dc0018
 
ef48bcf
 
 
062bda3
ef48bcf
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import copy
import enum
import pandas as pd
from typing import List, Optional

import requests
import streamlit as st


MODEL_DESCRIPTION = """
**keras_2_0**: Current production model\n
**keras_image_embeddings_3_0**: same as `keras_300_epochs_3_0` but with image embedding as input\n
**keras_300_epochs_3_0**: trained on 300 epochs with product name, ingredients, OCR-extracted ingredients and nutriments as input\n
**keras_ingredient_ocr_3_0**: same as `keras_sota_3_0`, but trained on less epochs\n
**keras_baseline_3_0**: model trained with product name, ingredients and nutriments as input\n
**keras_original_3_0**: same inputs as **keras_2_0** (product name + ingredients), but retrained\n
**keras_product_name_only_3_0**: model with only product name as input
"""

http_session = requests.Session()

@enum.unique
class NeuralCategoryClassifierModel(enum.Enum):
    keras_2_0 = "keras-2.0"
    keras_image_embeddings_3_0 = "keras-image-embeddings-3-0"
    keras_300_epochs_3_0 = "keras-300-epochs-3-0"
    keras_ingredient_ocr_3_0 = "keras-ingredient-ocr-3.0"
    keras_baseline_3_0 = "keras-baseline-3.0"
    keras_original_3_0 = "keras-original-3.0"
    keras_product_name_only_3_0 = "keras-product-name-only-3.0"


LOCAL_DB = False

if LOCAL_DB:
    ROBOTOFF_BASE_URL = "http://localhost:5500/api/v1"
else:
    ROBOTOFF_BASE_URL = "https://robotoff.openfoodfacts.org/api/v1"

PREDICTION_URL = ROBOTOFF_BASE_URL + "/predict/category"


@st.cache
def get_predictions(barcode: str, model_name: str, threshold: Optional[float] = None):
    data = {"barcode": barcode, "predictors": ["neural"], "neural_model_name": model_name}
    if threshold is not None:
        data["threshold"] = threshold

    r = requests.post(PREDICTION_URL, json=data)
    r.raise_for_status()
    return r.json()["neural"]

def display_predictions(
    barcode: str,
    model_names: List[str],
    threshold: Optional[float] = None,
):
    debug = None
    for model_name in model_names:
        response = get_predictions(barcode, model_name, threshold)
        response = copy.deepcopy(response) 
        if model_name != NeuralCategoryClassifierModel.keras_2_0.name and "debug" in response:
            if debug is None:
                debug = response["debug"]
            response.pop("debug")
        st.markdown(f"**{model_name}**")
        st.write(pd.DataFrame(response["predictions"]))
    
    if debug is not None:
        st.markdown("**v3 debug information**")
        st.write(debug)



st.sidebar.title("Category Prediction Demo")
query_params = st.experimental_get_query_params()

default_barcode = query_params["barcode"][0] if "barcode" in query_params else ""
barcode = st.sidebar.text_input(
    "Product barcode", default_barcode
)
threshold = st.sidebar.number_input("Threshold", format="%f", value=0.5) or None

st.sidebar.write("---\n# Model description\n" + MODEL_DESCRIPTION)
model_names = st.multiselect(
    "Name of the model",
    [x.name for x in NeuralCategoryClassifierModel],
    default=[x.name for x in NeuralCategoryClassifierModel],
)

if barcode:
    barcode = barcode.strip()
    display_predictions(
        barcode=barcode,
        threshold=threshold,
        model_names=model_names,
    )