Spaces:
Sleeping
Sleeping
Samuel Stevens
commited on
Commit
•
d4005aa
1
Parent(s):
9cbc5ff
more image examples; no open-ended prediction
Browse files- app.py +107 -84
- examples/Onoclea-hintonii.jpg +0 -0
- examples/Onoclea-sensibilis.jpg +0 -0
- examples/coral-snake.jpeg +3 -0
- examples/milk-snake.png +3 -0
- make_txt_embedding.py +16 -6
app.py
CHANGED
@@ -33,13 +33,19 @@ preprocess_img = transforms.Compose(
|
|
33 |
|
34 |
ranks = ("Kingdom", "Phylum", "Class", "Order", "Family", "Genus", "Species")
|
35 |
|
36 |
-
open_domain_examples = [
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
]
|
42 |
zero_shot_examples = [
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
[
|
44 |
"examples/Carnegiea-gigantea.png",
|
45 |
"Carnegiea gigantea\nSchlumbergera opuntioides\nMammillaria albicoma",
|
@@ -52,6 +58,18 @@ zero_shot_examples = [
|
|
52 |
"examples/Actinostola-abyssorum.png",
|
53 |
"Animalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola abyssorum\nAnimalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola bulbosa\nAnimalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola callosa\nAnimalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola capensis\nAnimalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola carlgreni",
|
54 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
]
|
56 |
|
57 |
|
@@ -153,89 +171,94 @@ if __name__ == "__main__":
|
|
153 |
status_msg = f"{done}/{total} ({done / total * 100:.1f}%) indexed"
|
154 |
|
155 |
with gr.Blocks() as app:
|
156 |
-
img_input = gr.Image()
|
157 |
-
|
158 |
-
with gr.Tab("Open-Ended"):
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
with gr.Tab("Zero-Shot"):
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
zero_shot_callback.setup(
|
220 |
-
[img_input, zero_shot_output], flagging_dir="logs/flagged"
|
221 |
-
)
|
222 |
-
zero_shot_flag_btn.click(
|
223 |
-
lambda *args: zero_shot_callback.flag(args),
|
224 |
-
[img_input, zero_shot_output],
|
225 |
-
None,
|
226 |
-
preprocess=False,
|
227 |
)
|
228 |
|
229 |
-
|
230 |
-
|
231 |
)
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
|
|
|
|
|
|
237 |
)
|
238 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
239 |
zero_shot_btn.click(
|
240 |
fn=zero_shot_classification,
|
241 |
inputs=[img_input, classes_txt],
|
|
|
33 |
|
34 |
ranks = ("Kingdom", "Phylum", "Class", "Order", "Family", "Genus", "Species")
|
35 |
|
36 |
+
# open_domain_examples = [
|
37 |
+
# ["examples/Ursus-arctos.jpeg", "Species"],
|
38 |
+
# ["examples/Phoca-vitulina.png", "Species"],
|
39 |
+
# ["examples/Felis-catus.jpeg", "Genus"],
|
40 |
+
# ["examples/Sarcoscypha-coccinea.jpeg", "Order"],
|
41 |
+
# ]
|
42 |
zero_shot_examples = [
|
43 |
+
[
|
44 |
+
"examples/Ursus-arctos.jpeg",
|
45 |
+
"brown bear\nblack bear\npolar bear\nkoala bear\ngrizzly bear",
|
46 |
+
],
|
47 |
+
["examples/milk-snake.png", "coral snake\nmilk snake"],
|
48 |
+
["examples/coral-snake.jpeg", "coral snake\nmilk snake"],
|
49 |
[
|
50 |
"examples/Carnegiea-gigantea.png",
|
51 |
"Carnegiea gigantea\nSchlumbergera opuntioides\nMammillaria albicoma",
|
|
|
58 |
"examples/Actinostola-abyssorum.png",
|
59 |
"Animalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola abyssorum\nAnimalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola bulbosa\nAnimalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola callosa\nAnimalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola capensis\nAnimalia Cnidaria Hexacorallia Actiniaria Actinostolidae Actinostola carlgreni",
|
60 |
],
|
61 |
+
[
|
62 |
+
"examples/Sarcoscypha-coccinea.jpeg",
|
63 |
+
"scarlet elf cup (coccinea)\nscharlachroter kelchbecherling (austriaca)\ncrimson cup (dudleyi)\nstalked scarlet cup (occidentalis)",
|
64 |
+
],
|
65 |
+
[
|
66 |
+
"examples/Onoclea-hintonii.jpg",
|
67 |
+
"Onoclea attenuata\nOnoclea boryana\nOnoclea hintonii\nOnoclea intermedia\nOnoclea sensibilis",
|
68 |
+
],
|
69 |
+
[
|
70 |
+
"examples/Onoclea-sensibilis.jpg",
|
71 |
+
"Onoclea attenuata\nOnoclea boryana\nOnoclea hintonii\nOnoclea intermedia\nOnoclea sensibilis",
|
72 |
+
],
|
73 |
]
|
74 |
|
75 |
|
|
|
171 |
status_msg = f"{done}/{total} ({done / total * 100:.1f}%) indexed"
|
172 |
|
173 |
with gr.Blocks() as app:
|
174 |
+
img_input = gr.Image(height=512)
|
175 |
+
|
176 |
+
# with gr.Tab("Open-Ended"):
|
177 |
+
# with gr.Row():
|
178 |
+
# with gr.Column():
|
179 |
+
# rank_dropdown = gr.Dropdown(
|
180 |
+
# label="Taxonomic Rank",
|
181 |
+
# info="Which taxonomic rank to predict. Fine-grained ranks (genus, species) are more challenging.",
|
182 |
+
# choices=ranks,
|
183 |
+
# value="Species",
|
184 |
+
# type="index",
|
185 |
+
# )
|
186 |
+
# open_domain_btn = gr.Button("Submit", variant="primary")
|
187 |
+
# gr.Examples(
|
188 |
+
# examples=open_domain_examples,
|
189 |
+
# inputs=[img_input, rank_dropdown],
|
190 |
+
# )
|
191 |
+
|
192 |
+
# with gr.Column():
|
193 |
+
# open_domain_outputs = [
|
194 |
+
# gr.Label(num_top_classes=5, label=rank, show_label=True)
|
195 |
+
# for rank in reversed(ranks)
|
196 |
+
# ]
|
197 |
+
# open_domain_flag_btn = gr.Button("Flag Mistake", variant="primary")
|
198 |
+
|
199 |
+
# open_domain_callback = gr.HuggingFaceDatasetSaver(
|
200 |
+
# hf_token, "imageomics/bioclip-demo-open-domain-mistakes", private=True
|
201 |
+
# )
|
202 |
+
# open_domain_callback.setup(
|
203 |
+
# [img_input, *open_domain_outputs], flagging_dir="logs/flagged"
|
204 |
+
# )
|
205 |
+
# open_domain_flag_btn.click(
|
206 |
+
# lambda *args: open_domain_callback.flag(args),
|
207 |
+
# [img_input, *open_domain_outputs],
|
208 |
+
# None,
|
209 |
+
# preprocess=False,
|
210 |
+
# )
|
211 |
+
|
212 |
+
# with gr.Tab("Zero-Shot"):
|
213 |
+
with gr.Row():
|
214 |
+
with gr.Column():
|
215 |
+
classes_txt = gr.Textbox(
|
216 |
+
placeholder="Canis familiaris (dog)\nFelis catus (cat)\n...",
|
217 |
+
lines=3,
|
218 |
+
label="Classes",
|
219 |
+
show_label=True,
|
220 |
+
info="Use taxonomic names where possible; include common names if possible.",
|
221 |
+
)
|
222 |
+
zero_shot_btn = gr.Button("Submit", variant="primary")
|
223 |
+
|
224 |
+
with gr.Column():
|
225 |
+
zero_shot_output = gr.Label(
|
226 |
+
num_top_classes=5, label="Prediction", show_label=True
|
227 |
+
)
|
228 |
+
zero_shot_flag_btn = gr.Button("Flag Mistake", variant="primary")
|
229 |
+
|
230 |
+
with gr.Row():
|
231 |
+
gr.Examples(
|
232 |
+
examples=zero_shot_examples,
|
233 |
+
inputs=[img_input, classes_txt],
|
234 |
+
cache_examples=True,
|
235 |
+
fn=zero_shot_classification,
|
236 |
+
outputs=[zero_shot_output],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
)
|
238 |
|
239 |
+
zero_shot_callback = gr.HuggingFaceDatasetSaver(
|
240 |
+
hf_token, "imageomics/bioclip-demo-zero-shot-mistakes", private=True
|
241 |
)
|
242 |
+
zero_shot_callback.setup(
|
243 |
+
[img_input, zero_shot_output], flagging_dir="logs/flagged"
|
244 |
+
)
|
245 |
+
zero_shot_flag_btn.click(
|
246 |
+
lambda *args: zero_shot_callback.flag(args),
|
247 |
+
[img_input, zero_shot_output],
|
248 |
+
None,
|
249 |
+
preprocess=False,
|
250 |
)
|
251 |
|
252 |
+
# rank_dropdown.change(
|
253 |
+
# fn=change_output, inputs=rank_dropdown, outputs=open_domain_outputs
|
254 |
+
# )
|
255 |
+
|
256 |
+
# open_domain_btn.click(
|
257 |
+
# fn=open_domain_classification,
|
258 |
+
# inputs=[img_input, rank_dropdown],
|
259 |
+
# outputs=open_domain_outputs,
|
260 |
+
# )
|
261 |
+
|
262 |
zero_shot_btn.click(
|
263 |
fn=zero_shot_classification,
|
264 |
inputs=[img_input, classes_txt],
|
examples/Onoclea-hintonii.jpg
ADDED
examples/Onoclea-sensibilis.jpg
ADDED
examples/coral-snake.jpeg
ADDED
Git LFS Details
|
examples/milk-snake.png
ADDED
Git LFS Details
|
make_txt_embedding.py
CHANGED
@@ -74,24 +74,31 @@ def convert_txt_features_to_avgs(name_lookup):
|
|
74 |
all_features = torch.from_numpy(np.load(args.out_path)).to(device)
|
75 |
logger.info("Loaded text features from disk to %s.", device)
|
76 |
|
77 |
-
|
78 |
for name, index in tqdm(name_lookup.values()):
|
79 |
i = len(name) - 1
|
80 |
-
|
81 |
|
82 |
zeroed = 0
|
83 |
for i, rank in reversed(list(enumerate(ranks))):
|
84 |
if rank == "Species":
|
85 |
continue
|
86 |
-
for name, index in tqdm(
|
87 |
-
species = tuple(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
if not species:
|
89 |
logger.warning("No species for %s.", " ".join(name))
|
90 |
all_features[:, index] = 0.0
|
91 |
zeroed += 1
|
92 |
continue
|
93 |
|
94 |
-
|
95 |
values, indices = species
|
96 |
mean = all_features[:, indices].mean(dim=1)
|
97 |
all_features[:, index] = F.normalize(mean, dim=0)
|
@@ -99,7 +106,10 @@ def convert_txt_features_to_avgs(name_lookup):
|
|
99 |
out_path, ext = os.path.splitext(args.out_path)
|
100 |
np.save(f"{out_path}_avgs{ext}", all_features.cpu().numpy())
|
101 |
if zeroed:
|
102 |
-
logger.warning(
|
|
|
|
|
|
|
103 |
|
104 |
|
105 |
def get_name_lookup(catalog_path, cache_path):
|
|
|
74 |
all_features = torch.from_numpy(np.load(args.out_path)).to(device)
|
75 |
logger.info("Loaded text features from disk to %s.", device)
|
76 |
|
77 |
+
names_by_rank = [set() for rank in ranks]
|
78 |
for name, index in tqdm(name_lookup.values()):
|
79 |
i = len(name) - 1
|
80 |
+
names_by_rank[i].add((name, index))
|
81 |
|
82 |
zeroed = 0
|
83 |
for i, rank in reversed(list(enumerate(ranks))):
|
84 |
if rank == "Species":
|
85 |
continue
|
86 |
+
for name, index in tqdm(names_by_rank[i], desc=rank):
|
87 |
+
species = tuple(
|
88 |
+
zip(
|
89 |
+
*(
|
90 |
+
(d, i)
|
91 |
+
for d, i in name_lookup.descendants(prefix=name)
|
92 |
+
if len(d) >= 6
|
93 |
+
)
|
94 |
+
)
|
95 |
+
)
|
96 |
if not species:
|
97 |
logger.warning("No species for %s.", " ".join(name))
|
98 |
all_features[:, index] = 0.0
|
99 |
zeroed += 1
|
100 |
continue
|
101 |
|
|
|
102 |
values, indices = species
|
103 |
mean = all_features[:, indices].mean(dim=1)
|
104 |
all_features[:, index] = F.normalize(mean, dim=0)
|
|
|
106 |
out_path, ext = os.path.splitext(args.out_path)
|
107 |
np.save(f"{out_path}_avgs{ext}", all_features.cpu().numpy())
|
108 |
if zeroed:
|
109 |
+
logger.warning(
|
110 |
+
"Zeroed out %d nodes because they didn't have any genus or species-level labels.",
|
111 |
+
zeroed,
|
112 |
+
)
|
113 |
|
114 |
|
115 |
def get_name_lookup(catalog_path, cache_path):
|