Deva8 commited on
Commit
8514413
Β·
verified Β·
1 Parent(s): fe2053c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +202 -212
app.py CHANGED
@@ -4,281 +4,271 @@ from huggingface_hub import hf_hub_download
4
  from PIL import Image
5
  import zipfile
6
  import os
7
- import random
8
 
9
- # Global variables
10
- df = None
11
- images_dir = None
12
 
13
- def setup_dataset():
14
- """Download and setup the dataset (called once on startup)"""
15
- global df, images_dir
16
-
17
- print("Loading metadata...")
18
- # Load metadata
19
- csv_path = hf_hub_download(
20
- repo_id="Deva8/Generative-VQA-V2-Curated",
21
- filename="main_metadata.csv",
22
- repo_type="dataset"
23
- )
24
- df = pd.read_csv(csv_path)
25
-
26
- print("Downloading images zip (this may take a few minutes)...")
27
- # Download zip file
28
- zip_path = hf_hub_download(
29
- repo_id="Deva8/Generative-VQA-V2-Curated",
30
- filename="gen_vqa_v2-images.zip",
31
- repo_type="dataset"
32
- )
33
-
34
- # Extract images
35
- images_dir = "./extracted_images"
36
- if not os.path.exists(images_dir):
37
- print("Extracting images...")
38
- os.makedirs(images_dir, exist_ok=True)
39
- with zipfile.ZipFile(zip_path, 'r') as zip_ref:
40
- zip_ref.extractall(images_dir)
41
-
42
- print(f"βœ“ Dataset ready! {len(df)} examples loaded.")
43
- return f"Dataset loaded successfully! {len(df):,} examples available."
44
 
45
- def get_random_sample():
46
- """Get a random sample from the dataset"""
47
- if df is None:
48
- return None, "Please wait, dataset is loading...", "", ""
49
-
50
- # Get random row
51
- sample = df.sample(1).iloc[0]
52
-
53
- # Load image
54
- img_path = os.path.join(images_dir, sample['file_name'])
55
- img = Image.open(img_path)
56
-
57
- question = sample['question']
58
- answer = sample['answer']
59
- metadata = f"Image ID: {sample['image_id']} | Question ID: {sample['question_id']}"
60
-
61
- return img, question, answer, metadata
62
 
63
- def search_by_question(query):
64
- """Search for questions containing the query"""
65
- if df is None:
66
- return None, "Dataset not loaded yet", "", ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
- if not query or len(query.strip()) < 3:
69
- return None, "Please enter at least 3 characters to search", "", ""
70
 
71
- # Search for matching questions
72
- matches = df[df['question'].str.contains(query, case=False, na=False)]
 
73
 
74
  if len(matches) == 0:
75
- return None, f"No questions found containing '{query}'", "", ""
76
 
77
- # Get random match
78
  sample = matches.sample(1).iloc[0]
 
79
 
80
- # Load image
81
- img_path = os.path.join(images_dir, sample['file_name'])
82
- img = Image.open(img_path)
83
-
84
- question = sample['question']
85
- answer = sample['answer']
86
- metadata = f"Image ID: {sample['image_id']} | Question ID: {sample['question_id']} | Found {len(matches)} matches"
87
-
88
- return img, question, answer, metadata
89
 
90
- def search_by_answer(query):
91
- """Search for specific answers"""
92
- if df is None:
93
- return None, "Dataset not loaded yet", "", ""
 
94
 
95
- if not query or len(query.strip()) < 1:
96
- return None, "Please enter an answer to search", "", ""
97
 
98
- # Search for matching answers
99
- matches = df[df['answer'].str.lower() == query.lower().strip()]
 
100
 
101
  if len(matches) == 0:
102
- return None, f"No examples found with answer '{query}'", "", ""
103
 
104
- # Get random match
105
  sample = matches.sample(1).iloc[0]
 
106
 
107
- # Load image
108
- img_path = os.path.join(images_dir, sample['file_name'])
109
- img = Image.open(img_path)
110
-
111
- question = sample['question']
112
- answer = sample['answer']
113
- metadata = f"Image ID: {sample['image_id']} | Question ID: {sample['question_id']} | Found {len(matches)} examples with this answer"
114
-
115
- return img, question, answer, metadata
116
 
117
- def get_statistics():
118
  """Get dataset statistics"""
119
- if df is None:
120
- return "Dataset not loaded yet"
121
-
122
- stats = f"""
123
- # πŸ“Š Dataset Statistics
124
-
125
- - **Total Examples**: {len(df):,}
126
- - **Unique Images**: {df['image_id'].nunique():,}
127
- - **Unique Answers**: {df['answer'].nunique():,}
128
-
129
- ## Top 10 Most Common Answers:
130
-
131
- """
132
 
 
133
  top_answers = df['answer'].value_counts().head(10)
134
- for i, (answer, count) in enumerate(top_answers.items(), 1):
135
- stats += f"{i}. **{answer}** - {count} examples\n"
136
-
137
- stats += f"\n## Question Length Distribution:\n"
138
- stats += f"- Average: {df['question'].str.split().str.len().mean():.1f} words\n"
139
- stats += f"- Min: {df['question'].str.split().str.len().min()} words\n"
140
- stats += f"- Max: {df['question'].str.split().str.len().max()} words\n"
141
 
142
- stats += f"\n## Answer Length Distribution:\n"
143
- stats += f"- Average: {df['answer'].str.split().str.len().mean():.2f} words\n"
144
- stats += f"- Single word answers: {(df['answer'].str.split().str.len() == 1).sum():,} ({(df['answer'].str.split().str.len() == 1).sum() / len(df) * 100:.1f}%)\n"
 
 
 
 
 
 
 
 
145
 
146
  return stats
147
 
148
- # Initialize dataset on startup
149
- print("Starting dataset setup...")
150
- setup_status = setup_dataset()
151
- print(setup_status)
152
 
153
- # Create Gradio interface
154
- with gr.Blocks(title="Generative VQA v2 Dataset Explorer", theme=gr.themes.Soft()) as demo:
155
- gr.Markdown("""
156
- # 🎯 Generative VQA-V2-Curated Dataset Explorer
157
 
158
- Explore the **Generative VQA v2 Curated** dataset - a balanced, cleaned version of VQA v2
159
- optimized for generative visual question answering.
160
-
161
- **Dataset**: [Deva8/Generative-VQA-V2-Curated](https://huggingface.co/datasets/Deva8/Generative-VQA-V2-Curated)
162
 
163
- ---
 
164
  """)
165
 
166
  with gr.Tabs():
167
- # Tab 1: Random Samples
168
- with gr.Tab("🎲 Random Samples"):
169
- gr.Markdown("### Click the button to see random examples from the dataset")
170
-
171
- with gr.Row():
172
- random_btn = gr.Button("πŸ”„ Get Random Sample", variant="primary", size="lg")
173
 
174
  with gr.Row():
175
- with gr.Column(scale=1):
176
- random_image = gr.Image(label="Image", type="pil")
177
-
178
- with gr.Column(scale=1):
179
- random_question = gr.Textbox(label="❓ Question", lines=2)
180
- random_answer = gr.Textbox(label="βœ… Answer", lines=1)
181
- random_metadata = gr.Textbox(label="ℹ️ Metadata", lines=1)
182
 
183
- random_btn.click(
184
- fn=get_random_sample,
185
- outputs=[random_image, random_question, random_answer, random_metadata]
186
  )
187
 
188
- # Tab 2: Search by Question
189
- with gr.Tab("πŸ” Search Questions"):
190
- gr.Markdown("### Search for questions containing specific keywords")
191
 
192
  with gr.Row():
193
- question_query = gr.Textbox(
194
- label="Search Query",
195
- placeholder="e.g., 'color', 'many', 'wearing', 'holding'",
196
- lines=1
197
  )
198
- question_search_btn = gr.Button("πŸ”Ž Search", variant="primary")
199
 
200
  with gr.Row():
201
- with gr.Column(scale=1):
202
- question_image = gr.Image(label="Image", type="pil")
203
-
204
- with gr.Column(scale=1):
205
- question_text = gr.Textbox(label="❓ Question", lines=2)
206
- question_answer = gr.Textbox(label="βœ… Answer", lines=1)
207
- question_metadata = gr.Textbox(label="ℹ️ Metadata", lines=1)
208
 
209
- question_search_btn.click(
210
- fn=search_by_question,
211
- inputs=[question_query],
212
- outputs=[question_image, question_text, question_answer, question_metadata]
213
- )
214
 
215
- # Tab 3: Search by Answer
216
- with gr.Tab("🎯 Search Answers"):
217
  gr.Markdown("### Find examples with specific answers")
218
 
219
  with gr.Row():
220
- answer_query = gr.Textbox(
221
- label="Answer to Search",
222
- placeholder="e.g., 'red', 'cat', '2', 'eating'",
223
- lines=1
224
  )
225
- answer_search_btn = gr.Button("πŸ”Ž Search", variant="primary")
226
 
227
- gr.Markdown("**Popular answers**: white, black, blue, red, 2, 3, brown, green, pizza, dog")
228
 
229
  with gr.Row():
230
- with gr.Column(scale=1):
231
- answer_image = gr.Image(label="Image", type="pil")
232
-
233
- with gr.Column(scale=1):
234
- answer_question = gr.Textbox(label="❓ Question", lines=2)
235
- answer_text = gr.Textbox(label="βœ… Answer", lines=1)
236
- answer_metadata = gr.Textbox(label="ℹ️ Metadata", lines=1)
237
 
238
- answer_search_btn.click(
239
- fn=search_by_answer,
240
- inputs=[answer_query],
241
- outputs=[answer_image, answer_question, answer_text, answer_metadata]
242
- )
243
 
244
- # Tab 4: Statistics
245
- with gr.Tab("πŸ“Š Statistics"):
246
- gr.Markdown("### Dataset Statistics and Analysis")
247
-
248
- stats_btn = gr.Button("πŸ“ˆ Show Statistics", variant="primary")
249
- stats_output = gr.Markdown()
250
 
251
- stats_btn.click(
252
- fn=get_statistics,
253
- outputs=[stats_output]
254
- )
255
 
256
  gr.Markdown("""
257
  ---
258
 
259
- ## About This Dataset
260
-
261
- **Generative VQA-V2-Curated** is a cleaned and balanced version of VQA v2:
262
 
263
- - βœ… Removed yes/no questions
264
- - βœ… Balanced answer distribution (max 600 per answer)
 
265
  - βœ… Filtered ambiguous questions
266
- - βœ… 135,268 high-quality QA pairs
267
- - βœ… 1,251 unique answer classes
268
-
269
- **License**: CC BY 4.0 (COCO + VQA v2)
270
 
271
- **Citation**:
272
- ```bibtex
273
- @misc{devarajan_genvqa_2026,
274
- author = {Devarajan},
275
- title = {Generative-VQA-V2-Curated},
276
- year = {2026},
277
- publisher = {Hugging Face},
278
- }
279
- ```
280
  """)
281
 
282
- # Launch the app
283
  if __name__ == "__main__":
284
  demo.launch()
 
4
  from PIL import Image
5
  import zipfile
6
  import os
 
7
 
8
+ # ==================== Configuration ====================
9
+ REPO_ID = "Deva8/Generative-VQA-V2-Curated"
10
+ CACHE_DIR = "./dataset_cache"
11
 
12
+ # Global state
13
+ dataset_state = {
14
+ "df": None,
15
+ "images_dir": None,
16
+ "loaded": False,
17
+ "error": None
18
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ # ==================== Dataset Loading ====================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ def initialize_dataset():
23
+ """Download and setup the dataset"""
24
+ if dataset_state["loaded"]:
25
+ return
26
+
27
+ try:
28
+ print("πŸ“₯ Downloading metadata...")
29
+ csv_path = hf_hub_download(
30
+ repo_id=REPO_ID,
31
+ filename="main_metadata.csv",
32
+ repo_type="dataset",
33
+ cache_dir=CACHE_DIR
34
+ )
35
+ dataset_state["df"] = pd.read_csv(csv_path)
36
+ print(f"βœ“ Loaded {len(dataset_state['df']):,} examples")
37
+
38
+ print("πŸ“¦ Downloading images (10GB, please wait)...")
39
+ zip_path = hf_hub_download(
40
+ repo_id=REPO_ID,
41
+ filename="gen_vqa_v2-images.zip",
42
+ repo_type="dataset",
43
+ cache_dir=CACHE_DIR
44
+ )
45
+
46
+ dataset_state["images_dir"] = os.path.join(CACHE_DIR, "extracted")
47
+ if not os.path.exists(dataset_state["images_dir"]):
48
+ print("πŸ“‚ Extracting images...")
49
+ os.makedirs(dataset_state["images_dir"], exist_ok=True)
50
+ with zipfile.ZipFile(zip_path, 'r') as zf:
51
+ zf.extractall(dataset_state["images_dir"])
52
+
53
+ dataset_state["loaded"] = True
54
+ print("βœ… Dataset ready!")
55
+
56
+ except Exception as e:
57
+ dataset_state["error"] = str(e)
58
+ print(f"❌ Error: {e}")
59
+
60
+ # Load dataset on startup
61
+ initialize_dataset()
62
+
63
+ # ==================== Helper Functions ====================
64
+
65
+ def load_image(file_path):
66
+ """Load image with error handling"""
67
+ try:
68
+ full_path = os.path.join(dataset_state["images_dir"], file_path)
69
+ return Image.open(full_path).convert('RGB')
70
+ except Exception as e:
71
+ print(f"Error loading image: {e}")
72
+ return None
73
+
74
+ def check_dataset():
75
+ """Check if dataset is loaded"""
76
+ if not dataset_state["loaded"]:
77
+ msg = dataset_state["error"] if dataset_state["error"] else "Dataset is loading..."
78
+ return None, f"⏳ {msg}", "", ""
79
+
80
+ # ==================== Main Functions ====================
81
+
82
+ def show_random():
83
+ """Display a random example"""
84
+ check = check_dataset()
85
+ if check:
86
+ return check
87
+
88
+ sample = dataset_state["df"].sample(1).iloc[0]
89
+ img = load_image(sample['file_name'])
90
+
91
+ return (
92
+ img,
93
+ sample['question'],
94
+ sample['answer'],
95
+ f"Image ID: {sample['image_id']} | Question ID: {sample['question_id']}"
96
+ )
97
+
98
+ def search_question(query):
99
+ """Search by question keywords"""
100
+ check = check_dataset()
101
+ if check:
102
+ return check
103
 
104
+ if not query or len(query.strip()) < 2:
105
+ return None, "Enter at least 2 characters", "", ""
106
 
107
+ matches = dataset_state["df"][
108
+ dataset_state["df"]['question'].str.contains(query, case=False, na=False)
109
+ ]
110
 
111
  if len(matches) == 0:
112
+ return None, f"No matches for '{query}'", "", ""
113
 
 
114
  sample = matches.sample(1).iloc[0]
115
+ img = load_image(sample['file_name'])
116
 
117
+ return (
118
+ img,
119
+ sample['question'],
120
+ sample['answer'],
121
+ f"Found {len(matches):,} matches | Showing random example"
122
+ )
 
 
 
123
 
124
+ def search_answer(query):
125
+ """Search by answer"""
126
+ check = check_dataset()
127
+ if check:
128
+ return check
129
 
130
+ if not query:
131
+ return None, "Enter an answer", "", ""
132
 
133
+ matches = dataset_state["df"][
134
+ dataset_state["df"]['answer'].str.lower() == query.lower().strip()
135
+ ]
136
 
137
  if len(matches) == 0:
138
+ return None, f"No examples with answer '{query}'", "", ""
139
 
 
140
  sample = matches.sample(1).iloc[0]
141
+ img = load_image(sample['file_name'])
142
 
143
+ return (
144
+ img,
145
+ sample['question'],
146
+ sample['answer'],
147
+ f"Found {len(matches):,} examples | Showing random"
148
+ )
 
 
 
149
 
150
+ def get_stats():
151
  """Get dataset statistics"""
152
+ if not dataset_state["loaded"]:
153
+ return "Dataset loading..."
 
 
 
 
 
 
 
 
 
 
 
154
 
155
+ df = dataset_state["df"]
156
  top_answers = df['answer'].value_counts().head(10)
 
 
 
 
 
 
 
157
 
158
+ stats = f"""# πŸ“Š Dataset Statistics
159
+
160
+ **Total Examples:** {len(df):,}
161
+ **Unique Images:** {df['image_id'].nunique():,}
162
+ **Unique Answers:** {df['answer'].nunique():,}
163
+
164
+ ## Top 10 Answers
165
+
166
+ """
167
+ for i, (ans, count) in enumerate(top_answers.items(), 1):
168
+ stats += f"{i}. **{ans}** - {count:,} examples\n"
169
 
170
  return stats
171
 
172
+ # ==================== Gradio Interface ====================
 
 
 
173
 
174
+ with gr.Blocks(
175
+ title="VQA Dataset Explorer",
176
+ theme=gr.themes.Soft(primary_hue="blue")
177
+ ) as demo:
178
 
179
+ gr.Markdown("""
180
+ # 🎯 Generative VQA-V2 Dataset Explorer
 
 
181
 
182
+ Explore 135K+ curated visual question-answer pairs from the
183
+ [Generative-VQA-V2-Curated](https://huggingface.co/datasets/Deva8/Generative-VQA-V2-Curated) dataset.
184
  """)
185
 
186
  with gr.Tabs():
187
+
188
+ # Random Samples Tab
189
+ with gr.TabItem("🎲 Random"):
190
+ gr.Markdown("### Browse random examples")
191
+ btn_random = gr.Button("πŸ”„ Show Random Example", variant="primary", size="lg")
 
192
 
193
  with gr.Row():
194
+ img_random = gr.Image(label="Image", height=400)
195
+ with gr.Column():
196
+ q_random = gr.Textbox(label="❓ Question", lines=3)
197
+ a_random = gr.Textbox(label="βœ… Answer", lines=2)
198
+ m_random = gr.Textbox(label="ℹ️ Info", lines=1)
 
 
199
 
200
+ btn_random.click(
201
+ show_random,
202
+ outputs=[img_random, q_random, a_random, m_random]
203
  )
204
 
205
+ # Question Search Tab
206
+ with gr.TabItem("πŸ” Search Questions"):
207
+ gr.Markdown("### Find questions containing keywords")
208
 
209
  with gr.Row():
210
+ query_q = gr.Textbox(
211
+ label="Search",
212
+ placeholder="e.g., color, wearing, many, holding",
213
+ scale=4
214
  )
215
+ btn_q = gr.Button("πŸ”Ž Search", variant="primary", scale=1)
216
 
217
  with gr.Row():
218
+ img_q = gr.Image(label="Image", height=400)
219
+ with gr.Column():
220
+ q_q = gr.Textbox(label="❓ Question", lines=3)
221
+ a_q = gr.Textbox(label="βœ… Answer", lines=2)
222
+ m_q = gr.Textbox(label="ℹ️ Info", lines=1)
 
 
223
 
224
+ btn_q.click(search_question, inputs=[query_q], outputs=[img_q, q_q, a_q, m_q])
225
+ query_q.submit(search_question, inputs=[query_q], outputs=[img_q, q_q, a_q, m_q])
 
 
 
226
 
227
+ # Answer Search Tab
228
+ with gr.TabItem("🎯 Search Answers"):
229
  gr.Markdown("### Find examples with specific answers")
230
 
231
  with gr.Row():
232
+ query_a = gr.Textbox(
233
+ label="Answer",
234
+ placeholder="e.g., red, cat, pizza, 2",
235
+ scale=4
236
  )
237
+ btn_a = gr.Button("πŸ”Ž Search", variant="primary", scale=1)
238
 
239
+ gr.Markdown("**Popular:** white, black, blue, red, 2, 3, dog, cat, pizza")
240
 
241
  with gr.Row():
242
+ img_a = gr.Image(label="Image", height=400)
243
+ with gr.Column():
244
+ q_a = gr.Textbox(label="❓ Question", lines=3)
245
+ a_a = gr.Textbox(label="βœ… Answer", lines=2)
246
+ m_a = gr.Textbox(label="ℹ️ Info", lines=1)
 
 
247
 
248
+ btn_a.click(search_answer, inputs=[query_a], outputs=[img_a, q_a, a_a, m_a])
249
+ query_a.submit(search_answer, inputs=[query_a], outputs=[img_a, q_a, a_a, m_a])
 
 
 
250
 
251
+ # Statistics Tab
252
+ with gr.TabItem("πŸ“Š Stats"):
253
+ gr.Markdown("### Dataset overview and analysis")
254
+ btn_stats = gr.Button("πŸ“ˆ Load Statistics", variant="primary")
255
+ stats_md = gr.Markdown()
 
256
 
257
+ btn_stats.click(get_stats, outputs=[stats_md])
 
 
 
258
 
259
  gr.Markdown("""
260
  ---
261
 
262
+ ### About
 
 
263
 
264
+ This dataset is a curated version of VQA v2 with:
265
+ - βœ… No yes/no questions
266
+ - βœ… Balanced answer distribution
267
  - βœ… Filtered ambiguous questions
 
 
 
 
268
 
269
+ **Dataset:** [Deva8/Generative-VQA-V2-Curated](https://huggingface.co/datasets/Deva8/Generative-VQA-V2-Curated)
270
+ **License:** CC BY 4.0
 
 
 
 
 
 
 
271
  """)
272
 
 
273
  if __name__ == "__main__":
274
  demo.launch()