clip-reply-demo / app.py
ceyda's picture
Update app.py
5ffe5df
import nmslib
import numpy as np
import streamlit as st
from transformers import AutoTokenizer, CLIPProcessor
from model import FlaxHybridCLIP
from PIL import Image
import jax.numpy as jnp
import os
import jax
# st.header('Under construction')
st.sidebar.title("CLIP React Demo")
st.sidebar.write("[Model Card](https://huggingface.co/flax-community/clip-reply)")
sc= st.sidebar.columns(2)
sc[0].image("./huggingface_explode3.png",width=150)
sc[1].write(" ")
sc[1].write(" ")
sc[1].markdown("## Researching fun")
with st.sidebar.expander("Motivation",expanded=True):
st.markdown(
"""
Reaction GIFs became an integral part of communication.
They convey complex emotions with many levels, in a short compact format.
If a picture is worth a thousand words then a GIF is worth more.
A lot of people would agree it is not always easy to find the perfect reaction GIF.
This is just a first step in the more ambitious goal of GIF/Image generation.
"""
)
top_k=st.sidebar.slider("Show top-K", min_value=1, max_value=50, value=20)
col_count=4
file_names=os.listdir("./jpg")
file_names.sort()
show_val=st.sidebar.button("show all validation set images")
if show_val:
cols=st.sidebar.columns(col_count)
for i,im in enumerate(file_names):
j=i%col_count
cols[j].image("./jpg/"+im)
st.write("# Search Reaction GIFs with CLIP ")
st.write(" ")
st.write(" ")
@st.cache(allow_output_mutation=True)
def load_model():
model = FlaxHybridCLIP.from_pretrained("ceyda/clip-reply")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
processor.tokenizer = AutoTokenizer.from_pretrained("cardiffnlp/twitter-roberta-base")
return model, processor
@st.cache(allow_output_mutation=True)
def load_image_index():
index = nmslib.init(method='hnsw', space='cosinesimil')
index.loadIndex("./features/image_embeddings", load_data=True)
return index
image_index = load_image_index()
model, processor = load_model()
# TODO
def add_image_emb(image):
image = Image.open(image).convert("RGB")
inputs = processor(text=[""], images=image, return_tensors="jax", padding=True)
inputs["pixel_values"] = jnp.transpose(inputs["pixel_values"], axes=[0, 2, 3, 1])
features = model(**inputs).image_embeds
image_index.addDataPoint(features)
def query_with_images(query_images,query_text):
images=[]
for im in query_images:
img=Image.open(im).convert("RGB")
if im.name.endswith(".gif"):
img.seek(0)
images.append(img)
inputs = processor(text=[query_text], images=images, return_tensors="jax", padding=True)
inputs["pixel_values"] = jnp.transpose(inputs["pixel_values"], axes=[0, 2, 3, 1])
outputs = model(**inputs)
logits_per_image = outputs.logits_per_image.reshape(-1)
# st.write(logits_per_image)
probs = jax.nn.softmax(logits_per_image)
# st.write(probs)
# st.write(list(zip(images,probs)))
results = sorted(list(zip(images,probs)),key=lambda x: x[1], reverse=True)
# st.write(results)
return zip(*results)
q_cols=st.columns([5,2,5])
examples = ["OMG that is disgusting","I'm so scared right now"," I got the job 🎉","Congratulations to all the flax-community week teams","You're awesome","I love you ❤️"]
example_input = q_cols[0].radio("Example Queries :",examples,index=4,help="These are examples I wrote off the top of my head. They don't occur in the dataset")
q_cols[2].markdown(
"""
Searches among the validation set images if not specified
(There may be non-exact duplicates)
"""
)
query_text = q_cols[0].text_input("Write text you want to get reaction for", value=example_input)
query_images = q_cols[2].file_uploader("(optional) Upload images to rank them",type=['jpg','jpeg','gif'], accept_multiple_files=True)
if query_images:
st.write("Ranking your uploaded images with respect to input text:")
with st.spinner("Calculating..."):
ids, dists = query_with_images(query_images,query_text)
else:
st.write("Found these images within validation set:")
with st.spinner("Calculating..."):
proc = processor(text=[query_text], images=None, return_tensors="jax", padding=True)
vec = np.asarray(model.get_text_features(**proc))
ids, dists = image_index.knnQuery(vec, k=top_k)
show_gif=st.checkbox("Play GIFs",value=True,help="Will play the original animation. Only first frame is used in training!")
ext = "jpg" if not show_gif else "gif"
res_cols=st.columns(col_count)
for i,(id_, dist) in enumerate(zip(ids, dists)):
j=i%col_count
with res_cols[j]:
if isinstance(id_, np.int32):
st.image(f"./{ext}/{file_names[id_][:-4]}.{ext}")
# st.write(file_names[id_])
st.write(1.0 - dist, help="score")
else:
st.image(id_)
st.write(dist, help="score")
# Credits
st.sidebar.caption("Made by [Ceyda Cinarel](https://huggingface.co/ceyda)")