profplate commited on
Commit
fe7930f
·
verified ·
1 Parent(s): c465f77

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +98 -0
app.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from html import escape
3
+ from transformers import pipeline, BlipProcessor, BlipForConditionalGeneration
4
+ import torch
5
+
6
+ # Image captioning
7
+ blip_processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
8
+ blip_model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
9
+
10
+ # Binary sentiment
11
+ sentiment = pipeline("sentiment-analysis", model="distilbert/distilbert-base-uncased-finetuned-sst-2-english")
12
+
13
+ def analyze(image):
14
+ if image is None:
15
+ return "<p class='empty'>Upload an image to analyze its emotional sentiment.</p>"
16
+
17
+ # Generate caption
18
+ image = image.convert("RGB")
19
+ inputs = blip_processor(image, return_tensors="pt")
20
+ with torch.no_grad():
21
+ caption_ids = blip_model.generate(**inputs, max_new_tokens=50)
22
+ caption = blip_processor.decode(caption_ids[0], skip_special_tokens=True)
23
+ safe_caption = escape(caption)
24
+
25
+ # Classify sentiment
26
+ result = sentiment(caption)[0]
27
+ label = result["label"]
28
+ score = result["score"]
29
+ other_label = "NEGATIVE" if label == "POSITIVE" else "POSITIVE"
30
+ other_score = 1 - score
31
+
32
+ pos = score if label == "POSITIVE" else other_score
33
+ neg = score if label == "NEGATIVE" else other_score
34
+
35
+ pos_color = f"rgba(34,197,94,{0.2 + pos * 0.8})"
36
+ neg_color = f"rgba(239,68,68,{0.2 + neg * 0.8})"
37
+
38
+ return f"""
39
+ <div class="caption-box">
40
+ <div class="caption-label">BLIP sees:</div>
41
+ <div class="caption-text">"{safe_caption}"</div>
42
+ </div>
43
+ <div class="result-box">
44
+ <div class="bar-row">
45
+ <span class="bar-label">POSITIVE</span>
46
+ <div class="bar-track">
47
+ <div class="bar-fill" style="width:{pos*100:.1f}%;background:{pos_color}"></div>
48
+ </div>
49
+ <span class="bar-pct">{pos*100:.1f}%</span>
50
+ </div>
51
+ <div class="bar-row">
52
+ <span class="bar-label">NEGATIVE</span>
53
+ <div class="bar-track">
54
+ <div class="bar-fill" style="width:{neg*100:.1f}%;background:{neg_color}"></div>
55
+ </div>
56
+ <span class="bar-pct">{neg*100:.1f}%</span>
57
+ </div>
58
+ <div class="verdict {'pos' if label == 'POSITIVE' else 'neg'}">
59
+ {label} ({score*100:.1f}%)
60
+ </div>
61
+ </div>
62
+ """
63
+
64
+ with gr.Blocks(title="Image Binary Sentiment") as demo:
65
+ gr.Markdown("## Image Binary Sentiment\nUpload an image. BLIP describes it, then a sentiment model classifies the description as positive or negative.")
66
+
67
+ with gr.Row():
68
+ img_input = gr.Image(type="pil", label="Upload an image")
69
+ result = gr.HTML(
70
+ value="<p class='empty'>Your sentiment analysis will appear here.</p>",
71
+ css_template="""
72
+ .caption-box {
73
+ background: #f0f4ff; border-radius: 10px; padding: 14px 18px;
74
+ margin-bottom: 16px; border: 1px solid #d0d8f0;
75
+ }
76
+ .caption-label { font-size: 0.75em; color: #888; text-transform: uppercase; letter-spacing: 0.05em; }
77
+ .caption-text { font-size: 1.1em; margin-top: 4px; color: #333; }
78
+ .result-box { display: flex; flex-direction: column; gap: 10px; }
79
+ .bar-row { display: flex; align-items: center; gap: 10px; }
80
+ .bar-label { width: 80px; font-weight: 600; font-size: 0.85em; text-align: right; }
81
+ .bar-track {
82
+ flex: 1; height: 24px; background: #f0f0f0; border-radius: 6px; overflow: hidden;
83
+ }
84
+ .bar-fill { height: 100%; border-radius: 6px; transition: width 0.3s; }
85
+ .bar-pct { width: 55px; font-family: monospace; font-size: 0.85em; color: #666; }
86
+ .verdict {
87
+ text-align: center; font-weight: 700; font-size: 1.3em;
88
+ margin-top: 10px; padding: 10px; border-radius: 8px;
89
+ }
90
+ .verdict.pos { background: rgba(34,197,94,0.12); color: #16a34a; }
91
+ .verdict.neg { background: rgba(239,68,68,0.12); color: #dc2626; }
92
+ .empty { color: #999; text-align: center; padding: 40px 20px; }
93
+ """
94
+ )
95
+
96
+ img_input.change(fn=analyze, inputs=img_input, outputs=result)
97
+
98
+ demo.launch()