Chanlefe commited on
Commit
088d0d6
Β·
verified Β·
1 Parent(s): d47a309

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +197 -0
app.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ from transformers import (
4
+ BertForSequenceClassification,
5
+ BertTokenizer,
6
+ CLIPProcessor,
7
+ CLIPModel,
8
+ pipeline
9
+ )
10
+ from PIL import Image
11
+ import pytesseract
12
+ import numpy as np
13
+ import cv2
14
+
15
+ class BertClipMemeAnalyzer:
16
+ def __init__(self):
17
+ # BERT for sentiment analysis
18
+ self.bert_sentiment = pipeline(
19
+ "sentiment-analysis",
20
+ model="nlptown/bert-base-multilingual-uncased-sentiment"
21
+ )
22
+
23
+ # Alternative: Use a BERT model specifically
24
+ # self.bert_model = BertForSequenceClassification.from_pretrained(
25
+ # "bert-base-uncased",
26
+ # num_labels=3 # positive, negative, neutral
27
+ # )
28
+ # self.bert_tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
29
+
30
+ # CLIP for zero-shot image classification
31
+ self.clip_model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
32
+ self.clip_processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
33
+
34
+ # Define meme categories for CLIP
35
+ self.meme_categories = [
36
+ "a hateful meme",
37
+ "a non-hateful meme",
38
+ "a funny meme",
39
+ "an offensive meme",
40
+ "a wholesome meme",
41
+ "a sarcastic meme",
42
+ "a political meme",
43
+ "a neutral meme"
44
+ ]
45
+
46
+ def extract_text_from_image(self, image):
47
+ """Extract text using OCR"""
48
+ try:
49
+ image_cv = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
50
+ gray = cv2.cvtColor(image_cv, cv2.COLOR_BGR2GRAY)
51
+ enhanced = cv2.convertScaleAbs(gray, alpha=1.5, beta=0)
52
+ text = pytesseract.image_to_string(enhanced)
53
+ return text.strip()
54
+ except:
55
+ return ""
56
+
57
+ def classify_with_clip(self, image):
58
+ """Use CLIP to classify meme type"""
59
+ # Prepare inputs
60
+ inputs = self.clip_processor(
61
+ text=self.meme_categories,
62
+ images=image,
63
+ return_tensors="pt",
64
+ padding=True
65
+ )
66
+
67
+ # Get predictions
68
+ with torch.no_grad():
69
+ outputs = self.clip_model(**inputs)
70
+ logits_per_image = outputs.logits_per_image
71
+ probs = logits_per_image.softmax(dim=1)
72
+
73
+ # Get results
74
+ results = []
75
+ for i, (category, prob) in enumerate(zip(self.meme_categories, probs[0])):
76
+ results.append({
77
+ 'category': category.replace("a ", "").replace(" meme", ""),
78
+ 'score': prob.item()
79
+ })
80
+
81
+ # Sort by score
82
+ results.sort(key=lambda x: x['score'], reverse=True)
83
+ return results
84
+
85
+ def analyze_meme(self, text_input, image):
86
+ output = "## 🎭 Meme Analysis Results\n\n"
87
+
88
+ # Extract text if image provided
89
+ extracted_text = ""
90
+ if image is not None:
91
+ extracted_text = self.extract_text_from_image(image)
92
+ if extracted_text:
93
+ output += f"### πŸ“ Extracted Text (OCR):\n`{extracted_text}`\n\n"
94
+
95
+ # Combine texts
96
+ full_text = text_input or ""
97
+ if extracted_text:
98
+ full_text = f"{full_text} {extracted_text}".strip()
99
+
100
+ # BERT Sentiment Analysis
101
+ if full_text:
102
+ output += "### 🧠 BERT Sentiment Analysis:\n"
103
+ sentiment_results = self.bert_sentiment(full_text)
104
+
105
+ # Map to your categories
106
+ label_map = {
107
+ '1 star': 'Very Negative',
108
+ '2 stars': 'Negative',
109
+ '3 stars': 'Neutral',
110
+ '4 stars': 'Positive',
111
+ '5 stars': 'Very Positive',
112
+ 'POSITIVE': 'Positive',
113
+ 'NEGATIVE': 'Negative',
114
+ 'NEUTRAL': 'Neutral'
115
+ }
116
+
117
+ sentiment = sentiment_results[0]
118
+ mapped_label = label_map.get(sentiment['label'], sentiment['label'])
119
+ output += f"**{mapped_label}** (Confidence: {sentiment['score']:.1%})\n\n"
120
+ else:
121
+ output += "### 🧠 BERT Sentiment Analysis:\n"
122
+ output += "No text provided for sentiment analysis\n\n"
123
+
124
+ # CLIP Meme Classification
125
+ if image is not None:
126
+ output += "### πŸ–ΌοΈ CLIP Meme Classification:\n"
127
+ clip_results = self.classify_with_clip(image)
128
+
129
+ # Top prediction
130
+ top = clip_results[0]
131
+ output += f"**Primary Classification: {top['category'].title()}** ({top['score']:.1%})\n\n"
132
+
133
+ # Hateful/Non-hateful specific
134
+ hateful_score = next(r['score'] for r in clip_results if 'hateful' in r['category'])
135
+ non_hateful_score = next(r['score'] for r in clip_results if 'non-hateful' in r['category'])
136
+
137
+ if hateful_score > non_hateful_score:
138
+ output += f"⚠️ **Hate Detection: Potentially Hateful** ({hateful_score:.1%})\n\n"
139
+ else:
140
+ output += f"βœ… **Hate Detection: Non-hateful** ({non_hateful_score:.1%})\n\n"
141
+
142
+ # All classifications
143
+ output += "**All Classifications:**\n"
144
+ for result in clip_results:
145
+ bar = "β–ˆ" * int(result['score'] * 20)
146
+ output += f"- {result['category'].title()}: {bar} {result['score']:.1%}\n"
147
+ else:
148
+ output += "### πŸ–ΌοΈ CLIP Meme Classification:\n"
149
+ output += "No image provided for classification\n\n"
150
+
151
+ # Summary
152
+ output += "\n### πŸ“Š Summary:\n"
153
+ if full_text:
154
+ output += f"- Text analyzed: {len(full_text.split())} words\n"
155
+ if image:
156
+ output += f"- Image analyzed: βœ“\n"
157
+ if extracted_text:
158
+ output += f"- OCR successful: βœ“\n"
159
+
160
+ return output
161
+
162
+ # Initialize
163
+ analyzer = BertClipMemeAnalyzer()
164
+
165
+ # Create interface
166
+ demo = gr.Interface(
167
+ fn=analyzer.analyze_meme,
168
+ inputs=[
169
+ gr.Textbox(
170
+ label="πŸ“ Text Input (Optional)",
171
+ placeholder="Enter meme text or leave empty for OCR...",
172
+ lines=2
173
+ ),
174
+ gr.Image(
175
+ label="πŸ–ΌοΈ Upload Meme",
176
+ type="pil"
177
+ )
178
+ ],
179
+ outputs=gr.Markdown(label="Analysis Results"),
180
+ title="🎭 BERT + CLIP Meme Analyzer",
181
+ description="""
182
+ This analyzer uses:
183
+ - **BERT**: For sentiment analysis of text (Positive/Negative/Neutral)
184
+ - **CLIP**: For zero-shot meme classification (Hateful/Non-hateful, Funny, etc.)
185
+ - **OCR**: To extract text from meme images
186
+
187
+ Upload a meme to see both text sentiment and visual classification!
188
+ """,
189
+ examples=[
190
+ ["", "examples/meme1.jpg"],
191
+ ["I love this community!", None],
192
+ ["This is offensive", "examples/meme2.jpg"]
193
+ ],
194
+ theme=gr.themes.Soft()
195
+ )
196
+
197
+ demo.launch()