|
|
from collections import defaultdict
|
|
|
|
|
|
import pandas as pd
|
|
|
|
|
|
import streamlit as st
|
|
|
|
|
|
st.set_page_config(layout="wide")
|
|
|
SHORT_CAPTIONS = [
|
|
|
'ALIGN:align-base:coyo700m', 'OpenCLIP:ViT-B-32:openai', 'OpenCLIP:ViT-B-16:openai',
|
|
|
'OpenCLIP:ViT-L-14:openai', 'OpenCLIP:ViT-L-14-336:openai',
|
|
|
'OpenCLIP:ViT-B-32:laion2b_s34b_b79k', 'OpenCLIP:ViT-B-16:laion2b_s34b_b88k',
|
|
|
'OpenCLIP:ViT-L-14:laion2b_s32b_b82k', 'OpenCLIP:ViT-g-14:laion2b_s34b_b88k',
|
|
|
'OpenCLIP:ViT-H-14:laion2b_s32b_b79k', 'OpenCLIP:roberta-ViT-B-32:laion2b_s12b_b32k',
|
|
|
'OpenCLIP:ViT-B-16-SigLIP:webli', 'OpenCLIP:ViT-B-16-SigLIP-384:webli',
|
|
|
'OpenCLIP:ViT-L-16-SigLIP-256:webli', 'OpenCLIP:ViT-L-16-SigLIP-384:webli',
|
|
|
'OpenCLIP:ViT-SO400M-14-SigLIP:webli', 'OpenCLIP:coca_ViT-B-32:laion2b_s13b_b90k',
|
|
|
'OpenCLIP:coca_ViT-L-14:laion2b_s13b_b90k'
|
|
|
]
|
|
|
LONG_CAPTIONS = [
|
|
|
'DreamLIP:dreamlip-vitb16:cc3m-long', 'DreamLIP:dreamlip-vitb16:cc12m-long',
|
|
|
'DreamLIP:dreamlip-vitb16:yfcc15m-long', 'DreamLIP:dreamlip-vitb16:cc30m-long',
|
|
|
'FLAIR:flair-vitb16:cc3m-recap', 'FLAIR:flair-vitb16:cc12m-recap',
|
|
|
'FLAIR:flair-vitb16:yfcc15m-recap', 'FLAIR:flair-vitb16:cc30m-recap',
|
|
|
'CLIPS:CLIPS-Large-14-224:recap-datacomp1b', 'CLIPS:CLIPS-Large-14-336:recap-datacomp1b',
|
|
|
'CLIPS:CLIPS-Huge-14-224:recap-datacomp1b', 'LoTLIP:LoTLIP-ViT-B-32:lotlip100m',
|
|
|
'LoTLIP:LoTLIP-ViT-B-16:lotlip100m', 'Recap-CLIP:ViT-L-16-HTxt-Recap-CLIP:recap-datacomp1b',
|
|
|
'LongCLIP:longclip-vitb32:sharegpt4v-1m', 'LongCLIP:longclip-vitb16:sharegpt4v-1m',
|
|
|
'LongCLIP:longclip-vitl14:sharegpt4v-1m', 'LongCLIP:longclip-vitl14_336px:sharegpt4v-1m',
|
|
|
"TULIP:TULIP-ViT-L-14-RoPE:sharegpt4v-1m", "TULIP:TULIP-ViT-L-14-RoPE_CL512:sharegpt4v-1m",
|
|
|
'Jina-CLIP:jina-clip-v1:jinaai', 'Jina-CLIP:jina-clip-v2:jinaai'
|
|
|
]
|
|
|
COMPOSITIONALITY = [
|
|
|
"OpenCLIP:ViT-B-32:openai", 'StructuredCLIP:NegCLIP-ViT-B-32:coco-ft',
|
|
|
'StructuredCLIP:CE-CLIP-ViT-B-32:coco-ft', 'StructuredCLIP:DAC-LLM-ViT-B-32:cc3m-ft',
|
|
|
'StructuredCLIP:DAC-SAM-ViT-B-32:cc3m-ft', 'FSC-CLIP:fsc-clip-ViT-B-32:laioncoco-ft',
|
|
|
'FSC-CLIP:fsc-clip-ViT-B-16:laioncoco-ft', 'FSC-CLIP:fsc-clip-ViT-L-14:laioncoco-ft'
|
|
|
]
|
|
|
|
|
|
DECODERS = [
|
|
|
'vqascore:instructblip-flant5-xl:none', 'vqascore:clip-flant5-xl:none',
|
|
|
'vqascore:llava-v1.5-7b:none', 'vqascore:sharegpt4v-7b:none',
|
|
|
'visualgptscore:instructblip-flant5-xl:none', 'visualgptscore:clip-flant5-xl:none',
|
|
|
'visualgptscore:llava-v1.5-7b:none', 'visualgptscore:sharegpt4v-7b:none'
|
|
|
]
|
|
|
|
|
|
MODEL_GROUPS = {
|
|
|
"short_captions": SHORT_CAPTIONS,
|
|
|
"long_captions": LONG_CAPTIONS,
|
|
|
"compositionality": COMPOSITIONALITY,
|
|
|
"decoder-based": DECODERS
|
|
|
}
|
|
|
|
|
|
|
|
|
def format_df(df):
|
|
|
cols = []
|
|
|
for col in df.columns:
|
|
|
if col in ["family", "model", "tag"]:
|
|
|
continue
|
|
|
cols.append(col)
|
|
|
formatted_df = df.style.format({col: "{:.1f}" for col in cols})
|
|
|
return formatted_df
|
|
|
|
|
|
|
|
|
def print_table_overall(df, model_names, metric_group, metric_columns):
|
|
|
named_rows = df[["family", "model", "tag"]].apply(lambda row: ":".join(row), axis=1)
|
|
|
new_rows = []
|
|
|
for name in model_names:
|
|
|
new_rows.append(df[named_rows == name])
|
|
|
new_rows = pd.concat(new_rows, axis=0).reset_index(drop=True)
|
|
|
|
|
|
|
|
|
selected_cols = [f"{metric_group}-{col}" for col in metric_columns]
|
|
|
selected = new_rows[["family", "model", "tag"] + selected_cols]
|
|
|
selected.columns = ["family", "model", "tag"] + metric_columns
|
|
|
st.table(format_df(selected))
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
st.title("Interface")
|
|
|
df = pd.read_csv("data/250206/report.csv")
|
|
|
df_decoder = pd.read_csv("data/250206/decoder_report.csv")
|
|
|
df = pd.concat((df, df_decoder), axis=0).reset_index(drop=True)
|
|
|
|
|
|
selected = st.selectbox(
|
|
|
"Select the evaluation data, after filtering or before filtering:",
|
|
|
["after filtering", "before filtering"]
|
|
|
)
|
|
|
if selected == "before filtering":
|
|
|
st.write(
|
|
|
"It prints the accuracy gap; `filtered` - `unfiltered`. gap이 positive로 크면 filtering 후 accuracy가 더 높아짐"
|
|
|
)
|
|
|
df_all = pd.read_csv("data/250206/report_all_samples.csv")
|
|
|
df_decoder_all = pd.read_csv("data/250206/decoder_report_all.csv")
|
|
|
df_all = pd.concat((df_all, df_decoder_all), axis=0).reset_index(drop=True)
|
|
|
cols_all = [col for col in df.columns if col not in ["family", "model", "tag"]]
|
|
|
df[cols_all] = df[cols_all] - df_all[cols_all]
|
|
|
textonly_df = pd.read_csv("./data/250206/textonly_decoder_report.csv")
|
|
|
|
|
|
columns = list(df.columns)
|
|
|
col_dict = defaultdict(list)
|
|
|
for col in columns:
|
|
|
if "-" not in col:
|
|
|
continue
|
|
|
metric_group, metric_name = col.split("-")
|
|
|
if metric_group == "all_tasks":
|
|
|
continue
|
|
|
col_dict[metric_group].append(metric_name)
|
|
|
|
|
|
for metric_group, metric_columns in col_dict.items():
|
|
|
|
|
|
with st.expander(f"Expand: {metric_group}"):
|
|
|
if metric_group == "neg_start_positions":
|
|
|
st.write("- `add` 및 `replace` split에서 negative sentence 시작 토큰 위치 별 accuracy.")
|
|
|
st.write(
|
|
|
"- short caption model에서는 negative 판별이 가능한 context length에 한정해서 evaluation 가능. Long caption model에서는 negative sentence 시작 위치별로 정확도 비교 가능."
|
|
|
)
|
|
|
st.write(
|
|
|
"- Negative sentence 시작 위치 (토큰); `XS` <= 77 / 77 < `S` <= 128 / 128 < `M` <= 248 / `L` > 248."
|
|
|
)
|
|
|
|
|
|
if metric_group == "summary":
|
|
|
st.write(
|
|
|
"- operation별 `add_*`, `replace_*`, `swap_*` 그리고 negative type별 `relation`, `attribute`, `entity`으로 averaged accuracy."
|
|
|
)
|
|
|
|
|
|
for group, model_names in MODEL_GROUPS.items():
|
|
|
st.markdown(f"### {group} models")
|
|
|
if metric_group == "summary" and group == "short_captions":
|
|
|
st.markdown(
|
|
|
"- negative sentence의 시작 위치가 77 토큰 밖에 있는 sample들의 영향, 대체로 random chance accuracy에 아주 근접."
|
|
|
)
|
|
|
if metric_group == "summary" and group == "long_captions":
|
|
|
st.markdown(
|
|
|
"- Context lengths: `DreamLIP, FLAIR`: 77 / `CLIPS`: 80 / `LOTLIP, Recap-CLIP`: 128 / `LongCLIP`: 248 / `TULIP`: 248 or 512 / `Jina-CLIP`: 512"
|
|
|
)
|
|
|
st.markdown("- FLAIR 이후 `replace`의 난이도가 `swap`보다 쉬워지는 경우 종종 있음.")
|
|
|
st.markdown(
|
|
|
"- negative 대상별 난이도 (difficulty)는 `relation` > `entity` > `attrubite`."
|
|
|
)
|
|
|
st.markdown(
|
|
|
"- Context length가 충분한 모델도 random chance에 근접하는 케이스 많음 (대체로 50%대 accuracy, 좀 잘 나오면 60%대)"
|
|
|
)
|
|
|
|
|
|
if metric_group == "summary" and group == "compositionality":
|
|
|
st.markdown("- Pretrained CLIP 대비 fine-tuning 후에 정확도 약간 상승")
|
|
|
|
|
|
if metric_group == "summary" and group == "decoder-based":
|
|
|
|
|
|
st.markdown("- VQAScore는 Random chance accuracy에 근접하지만, 그래도 CLIP기반 모델보다 성능 좋음")
|
|
|
st.markdown(
|
|
|
"- VisualGPTScore의 경우 `add`는 정말 못하지만 `replace`나 `swap`같이 word level modification은 극단적으로 잘함. (왜?)"
|
|
|
)
|
|
|
st.markdown(
|
|
|
"- autoregressive text generation 관점에서, `add` split은 language prior가 없지만, `replace`나 `swap`은 아직 language bias (shortcut)로 정답을 판별할 여지가 있는건가?"
|
|
|
)
|
|
|
|
|
|
st.markdown(
|
|
|
"- VQAScore에서는 `replace`가 `swap`보다 우세, VisualGPTScore는 `swap`이 우세. "
|
|
|
)
|
|
|
st.markdown(
|
|
|
"- VQAScore, VisualGPTScore 공통적으로 negative type별 `relation` < `attribute` < `entity` 순으로 어려움."
|
|
|
)
|
|
|
|
|
|
if metric_group == "neg_start_positions" and group == "long_captions":
|
|
|
st.markdown(
|
|
|
"- 대체로 `XS` 위치 (negative sentence 시작이 77 토큰 이내)에서 정확도가 가장 높음. neg sentence가 이후에 시작될수록 정확도가 낮은 경향, but `L 그룹`; 248 토큰 이후 negative sample에서 정확도 증가할 수도 있음"
|
|
|
)
|
|
|
|
|
|
if metric_group == "neg_start_positions" and group == "decoder-based":
|
|
|
st.markdown(
|
|
|
"- InstructBLIP은 input context length 128, output context length는 256으로 제한. description을 input에 태우면 (VQAScore) context length 초과로 evaluation 불가, output에는 태우기 가능 (VisualGPTScore)"
|
|
|
)
|
|
|
print_table_overall(df, model_names, metric_group, metric_columns)
|
|
|
if selected == "after filtering" and group == "decoder-based":
|
|
|
st.write("### decoder-based models (zero-tensor images)")
|
|
|
if metric_group == "summary":
|
|
|
st.markdown(
|
|
|
"- Image 정보가 없을 때 전반적으로 accuracy 하락. VQAScore는 random chance accuracy (50%) 근처인 반면 VisualGPTScore는 여전히 text input만으로 `replace`, `swap` split에서 outperforming 가능"
|
|
|
)
|
|
|
st.markdown(
|
|
|
"- From VisualGPTScore, Output token propability is critical to identify negative descriptions, even one token change."
|
|
|
)
|
|
|
print_table_overall(textonly_df, model_names, metric_group, metric_columns)
|
|
|
st.markdown("---")
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
main()
|
|
|
|