chore(eval): reconcile the distractor sets and refresh the sweep numbers

The Wikimedia collector truncated the whole basename at 60 characters, so 13
files lost their extension and cv2 could not read them by name - the distractor
sets were quietly scoring 13 images fewer than they held. It now truncates the
stem and keeps the extension, and the files on disk are renamed to match.

The search terms also pull in .djvu volumes whose page 1 Commons serves as a
JPEG thumbnail. Twelve book scans were in the sets; they contributed 0 false
accepts, and they are not shelves, so the collector filters them and the
manifests no longer list them.

With all 2650 crops readable the sweep is re-measured end to end: 3.09% at the
old lines, 0.30% at the shipped 4.0/4, image6 44 shown / 42 correct / 95.5%.
The accept sweep table and the verdict's far-unknown sentence now carry those
numbers instead of the pre-calibration ones.

Also: the fetched images are gitignored (manifests and results are not), the
l10/l11 shelf-tag crops that back the catalog corrections are committed, and a
stale pre-gate eval.json and a duplicate of eval/labels/image6.json are gone.
This commit is contained in:
kiyo9w 2026-09-29 04:17:54 +09:00
parent 4bdad66bbe
commit 5eb4bdf6c8
19 changed files with 646 additions and 253 deletions

View file

@ -25,3 +25,14 @@ stock-*/identity_head.pt
.gallery_cache_*.npz
.demo-token
config/local.env
# Fetched images. Every set keeps its manifest.json (source URL, licence,
# artist) and its results in git; the pixels are re-fetchable from those URLs
# and are 59 MB for the Wikimedia shelves alone.
data/external-shelves/*/*.jpg
data/external-shelves/*/*.jpeg
data/external-shelves/*/*.JPG
data/external-shelves/*/*.png
data/packshots/research/*/images/
data/packshots/research/*/pages/
data/packshots/research/*/*.jpg

View file

@ -141,7 +141,7 @@ def main() -> None:
info = image_info(sorted(found))
print(f" metadata for {len(info)} files")
kept, skipped = [], {"license": 0, "size": 0, "missing": 0}
kept, skipped = [], {"license": 0, "size": 0, "missing": 0, "not_a_photo": 0}
for title, entry in sorted(info.items()):
if not entry.get("url"):
skipped["missing"] += 1
@ -150,6 +150,12 @@ def main() -> None:
if not any(token in licence for token in PERMISSIVE):
skipped["license"] += 1
continue
# A book scan is not a shelf. The search terms pull in .djvu volumes
# whose page 1 is a title page, and Commons serves those as JPEG
# thumbnails, so the extension check has to be on the source title.
if any(title.lower().endswith(ext) for ext in (".djvu", ".pdf", ".svg", ".tif", ".tiff")):
skipped["not_a_photo"] += 1
continue
if (entry.get("width") or 0) < 1000 or (entry.get("height") or 0) < 700:
skipped["size"] += 1
continue
@ -158,9 +164,13 @@ def main() -> None:
print(f" keeping {len(kept)} (skipped: {skipped})")
manifest = []
for index, (title, entry) in enumerate(kept):
stem = os.path.basename(urllib.parse.urlparse(entry["url"]).path).replace(" ", "_")
stem = urllib.parse.unquote(stem)[:60]
name = f"{index:03d}_{stem}"
# Truncate the stem, never the extension: a 60-character cut on the
# whole basename drops it, and the file then has no type for cv2 or
# for anyone reading the directory.
stem, extension = os.path.splitext(
os.path.basename(urllib.parse.urlparse(entry["url"]).path).replace(" ", "_")
)
name = f"{index:03d}_{urllib.parse.unquote(stem)[:60]}{extension.lower()}"
path = os.path.join(root, name)
if not os.path.exists(path):
try:

View file

@ -0,0 +1,76 @@
{
"source": "data/packshots/source",
"output": "stock-lopia-clean",
"min_width": 120,
"min_height": 160,
"min_views": 1,
"duplicate_cosine": 0.98,
"min_name_ocr": 0.7,
"ocr": "vision",
"text_only_skus": [
"sku_l04",
"sku_l07",
"sku_l08",
"sku_l12"
],
"text_discriminated_siblings": [
{
"sku": "sku_l09",
"view": "sku_l09.jpg",
"sibling_sku": "sku_l10",
"sibling_view": "sku_l10.jpg",
"cosine": 0.9817,
"name_similarity": 0.333
}
],
"below_pyramid_floor": [],
"completeness": {
"live_ready": null,
"reason": "no --shelf-tags given; the completeness rule needs the shelf's SKU list",
"enrolled": 8,
"text_only": [
"sku_l04",
"sku_l07",
"sku_l08",
"sku_l12"
]
},
"skus": {
"sku_l01": [
"sku_l01.jpg"
],
"sku_l02": [
"sku_l02.jpg"
],
"sku_l03": [
"sku_l03.jpg"
],
"sku_l05": [
"sku_l05.jpg"
],
"sku_l06": [
"sku_l06.jpg"
],
"sku_l09": [
"sku_l09.jpg"
],
"sku_l10": [
"sku_l10.jpg"
],
"sku_l11": [
"sku_l11.jpg"
]
},
"refused": [
{
"sku": "sku_l04",
"view": "sku_l04.jpg",
"reason": "name/OCR 0.00 below 0.70: 明太手屋さんが つくつ た コ"
},
{
"sku": "sku_l07",
"view": "sku_l07.jpg",
"reason": "name/OCR 0.57 below 0.70: ラッキー マヨネーズ 調味料(アミノ酸)不使用"
}
]
}

View file

@ -0,0 +1,221 @@
{
"image": "add/image6.jpg",
"stock_dir": "stock-lopia-clean",
"labels": "eval/labels/image6.json",
"provenance": {
"catalog_hash": "3f1653d9d962073af96121250006b9b6d86113556797bbee65de68b60e87a64d",
"labels_hash": "5aabf029921ced767d4e14a18e8bccb55812dd974852c56e0931a98fa10366cf",
"image_hash": "a08b89ba37d27c9d5a81bcd56bcd042e6baf54d2f182bbaaf47e97f14c9cd525",
"code_revision": "68061635d9fef3097609945bfd9ac1935791b398"
},
"facings": 111,
"leakage": {
"excluded": 0,
"labels": []
},
"hub_share_limit": 0.3,
"enrollment": {
"catalog_skus": [
"sku_l01",
"sku_l02",
"sku_l03",
"sku_l04",
"sku_l05",
"sku_l06",
"sku_l07",
"sku_l08",
"sku_l09",
"sku_l10",
"sku_l11",
"sku_l12"
],
"enrolled_skus": [
"sku_l01",
"sku_l02",
"sku_l03",
"sku_l05",
"sku_l06",
"sku_l09",
"sku_l10",
"sku_l11"
],
"unenrolled_skus": {
"sku_l07": 6,
"sku_l04": 1,
"sku_l08": 1
},
"facings_without_enrollment": 8,
"scored_facings": 109
},
"results": {
"full": [
{
"lane": "local",
"accept": 2.0,
"margin": 0.15,
"in_catalog": 61,
"out_catalog": 48,
"enrolled": 53,
"correct": 48,
"wrong": 9,
"rejected": 52,
"catalog_ceiling": 0.8689,
"identity_ceiling": 0.9245,
"decision_ceiling": 0.8113,
"end_to_end_coverage": 0.7869,
"false_accepts": 9,
"unknown_false_accepts": 8,
"unenrolled_false_accepts": 0,
"false_accept_rate": 0.1667,
"near_unknown_false_accept_rate": 0.0,
"precision": 0.8421,
"max_sku_share": 0.2281,
"hub_sku": "sku_l09",
"hub_alarm": false,
"histogram": {
"sku_l09": 13,
"sku_l11": 10,
"sku_l10": 9,
"sku_l01": 5,
"sku_l03": 5,
"sku_l07": 5,
"sku_l06": 4,
"sku_l02": 3,
"sku_l05": 3
},
"per_sku": {
"sku_l01": {
"correct": 5,
"total": 5
},
"sku_l02": {
"correct": 2,
"total": 4
},
"sku_l03": {
"correct": 4,
"total": 4
},
"sku_l04": {
"correct": 0,
"total": 1
},
"sku_l05": {
"correct": 3,
"total": 3
},
"sku_l06": {
"correct": 4,
"total": 4
},
"sku_l07": {
"correct": 5,
"total": 6
},
"sku_l08": {
"correct": 0,
"total": 1
},
"sku_l09": {
"correct": 11,
"total": 13
},
"sku_l10": {
"correct": 9,
"total": 11
},
"sku_l11": {
"correct": 5,
"total": 9
}
},
"ms_per_crop": 26.7
}
],
"live": [
{
"lane": "local",
"accept": 2.0,
"margin": 0.15,
"in_catalog": 61,
"out_catalog": 48,
"enrolled": 53,
"correct": 41,
"wrong": 4,
"rejected": 64,
"catalog_ceiling": 0.8689,
"identity_ceiling": 0.8491,
"decision_ceiling": 0.6604,
"end_to_end_coverage": 0.6721,
"false_accepts": 4,
"unknown_false_accepts": 3,
"unenrolled_false_accepts": 0,
"false_accept_rate": 0.0625,
"near_unknown_false_accept_rate": 0.0,
"precision": 0.9111,
"max_sku_share": 0.2,
"hub_sku": "sku_l09",
"hub_alarm": false,
"histogram": {
"sku_l09": 9,
"sku_l10": 9,
"sku_l11": 7,
"sku_l07": 6,
"sku_l01": 4,
"sku_l03": 3,
"sku_l05": 3,
"sku_l06": 2,
"sku_l02": 1,
"sku_l04": 1
},
"per_sku": {
"sku_l01": {
"correct": 4,
"total": 5
},
"sku_l02": {
"correct": 1,
"total": 4
},
"sku_l03": {
"correct": 3,
"total": 4
},
"sku_l04": {
"correct": 1,
"total": 1
},
"sku_l05": {
"correct": 3,
"total": 3
},
"sku_l06": {
"correct": 2,
"total": 4
},
"sku_l07": {
"correct": 5,
"total": 6
},
"sku_l08": {
"correct": 0,
"total": 1
},
"sku_l09": {
"correct": 9,
"total": 13
},
"sku_l10": {
"correct": 9,
"total": 11
},
"sku_l11": {
"correct": 4,
"total": 9
}
},
"ms_per_crop": 20.9
}
]
}
}

View file

@ -0,0 +1,27 @@
"""Which facings are falsely accepted, and as what."""
import sys, cv2
sys.path.insert(0, "code")
from eval_identity import LocalLaneAdapter, load_labels, at_live_resolution, leaked, UNKNOWN, crop_of
from identity_lanes import DecisionPolicy
payload = load_labels("eval/labels/image6.json")
image = cv2.imread("add/image6.jpg")
facings = [f for f in payload["facings"] if f["label"] != "exclude"]
facings = [f for f in facings if leaked(image, f["box"], "stock-lopia-clean") is None]
enrolled = {"sku_l01","sku_l02","sku_l03","sku_l05","sku_l06","sku_l09","sku_l10","sku_l11"}
for live in (False, True):
picture = at_live_resolution(image) if live else image
scaled = facings if not live else [
{**f, "box": [int(round(v * picture.shape[1] / image.shape[1])) for v in f["box"]]}
for f in facings]
lane = LocalLaneAdapter("stock-lopia-clean")
print(f"=== {'live' if live else 'full'} ===")
for f in scaled:
crop = crop_of(picture, f["box"])
if crop.size == 0: continue
ranked = lane.rank(crop)
d = lane.decide(crop, ranked, accept=2.0, margin=0.0, scale="local")
ans = d.get("best_sku") if d.get("identity_level") == "accepted" else None
if ans and ans != f["label"]:
print(f" #{f['index']:>3} truth={f['label']:<9} answered={ans:<9} enrolled={f['label'] in enrolled}")

View file

@ -0,0 +1,54 @@
"""What the falsely-accepted crops actually read, and what the text lane scores.
The advisory says crops 82-97 are Kewpie Mayonnaise 450g - a product the
catalog does not hold - and that no catalog row can therefore win the text
ranking, so the veto at DecisionPolicy.decide never fires. This prints the
reads and the scores that claim depends on.
"""
import csv
import sys
import cv2
import numpy as np
sys.path.insert(0, "code")
from identity_lanes import TextLane, carries_identity # noqa: E402
from ocr import build_ocr_engine # noqa: E402
INDICES = [73, 82, 83, 84, 86, 94, 95, 96, 97]
rows = []
with open("stock-lopia-clean/stock.csv", encoding="utf-8") as handle:
for record in csv.reader(handle):
if len(record) >= 2 and record[0].startswith("sku_"):
rows.append({"sku_id": record[0], "product_name": record[1]})
engine = build_ocr_engine("vision")
lane = TextLane.from_catalog(rows, "stock-lopia-clean", ocr_engine=engine)
labels = {f["index"]: f for f in __import__("json").load(open("eval/labels/image6.json"))["facings"]}
image = cv2.imread("add/image6.jpg")
tiles = []
for index in INDICES:
facing = labels[index]
x1, y1, x2, y2 = facing["box"]
crop = image[y1:y2, x1:x2]
read = lane.read(crop)
scores = lane.scores_from_text(read)
top = sorted(scores.items(), key=lambda kv: -kv[1])[:3]
print(f"#{index:>3} truth={facing['label']:<9} carries={carries_identity(read)}")
print(f" read: {read[:110]}")
print(f" text top: {[(s, round(v, 3)) for s, v in top]}")
height, width = crop.shape[:2]
scale = 260.0 / max(1, height)
resized = cv2.resize(crop, (max(1, int(width * scale)), 260), interpolation=cv2.INTER_CUBIC)
canvas = np.full((300, 220, 3), 255, np.uint8)
canvas[30:290, : min(resized.shape[1], 220)] = resized[:, :220]
cv2.putText(canvas, str(index), (6, 22), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
tiles.append(canvas)
grid = np.vstack([np.hstack(tiles[:5]), np.hstack(tiles[5:])])
cv2.imwrite("data/evaluations/2026-09-29-session/scratch/fa_tiles.jpg", grid)
print("tile:", grid.shape)

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

View file

@ -0,0 +1,71 @@
"""Mass-only size contradiction, with full reads.
The first pass counted every quantity token, including percentages, so a crop
reading "カロリー 50% カット" looked like a 50 g package. Only mass units can
contradict a package size, so this restricts to g/kg and prints the whole read
for every accepted facing that carries one.
"""
import csv
import json
import re
import sys
import cv2
sys.path.insert(0, "code")
from eval_identity import LocalLaneAdapter, at_live_resolution, crop_of, leaked # noqa: E402
from identity_lanes import TextLane, normalize_text # noqa: E402
from ocr import build_ocr_engine # noqa: E402
MASS = re.compile(r"(\d+(?:\.\d+)?)\s*(KG|G)", re.IGNORECASE)
# Package sizes this product class actually comes in. Below it are OCR fragments
# of a longer number ("20" from 200); above it are concatenations ("5210").
PLAUSIBLE = (100.0, 2000.0)
def masses(text: str):
return {float(number) for number, _unit in MASS.findall(normalize_text(text))}
rows = []
with open("stock-lopia-clean/stock.csv", encoding="utf-8") as handle:
for record in csv.reader(handle):
if len(record) >= 2 and record[0].startswith("sku_"):
rows.append({"sku_id": record[0], "product_name": record[1]})
names = {row["sku_id"]: row["product_name"] for row in rows}
engine = build_ocr_engine("vision")
text_lane = TextLane.from_catalog(rows, "stock-lopia-clean", ocr_engine=engine)
local_lane = LocalLaneAdapter("stock-lopia-clean")
payload = json.load(open("eval/labels/image6.json"))
image = cv2.imread("add/image6.jpg")
facings = [f for f in payload["facings"] if f["label"] != "exclude"]
facings = [f for f in facings if leaked(image, f["box"], "stock-lopia-clean") is None]
for live in (False, True):
picture = at_live_resolution(image) if live else image
scaled = facings if not live else [
{**f, "box": [int(round(v * picture.shape[1] / image.shape[1])) for v in f["box"]]}
for f in facings]
print(f"=== {'live' if live else 'full'} ===")
for facing in scaled:
crop = crop_of(picture, facing["box"])
if crop.size == 0:
continue
ranked = local_lane.rank(crop)
decision = local_lane.decide(crop, ranked, accept=2.0, margin=0.0, scale="local")
if decision.get("identity_level") != "accepted":
continue
answer = decision.get("best_sku")
read = text_lane.read(crop)
read_masses = masses(read)
name_masses = masses(names.get(answer, ""))
if not read_masses or not name_masses:
continue
plausible = {m for m in read_masses if PLAUSIBLE[0] <= m <= PLAUSIBLE[1]}
veto = bool(plausible) and not (read_masses & name_masses)
correct = "correct" if answer == facing["label"] else "WRONG"
print(f" #{facing['index']:>3} {'VETO' if veto else 'keep'} {correct:<7} "
f"answer={answer:<9} read_m={sorted(read_masses)} name_m={sorted(name_masses)}")
print(f" read: {read[:120]}")

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

View file

@ -2,115 +2,129 @@
"dataset": "wikimedia-commons-2",
"catalog": "stock-lopia-clean",
"note": "Unrelated shelves: every accept is a false accept by construction.",
"images": 15,
"detections": 421,
"images": 17,
"detections": 462,
"false_accepts": 1,
"false_accept_rate": 0.0024,
"false_accept_rate": 0.0022,
"rows": [
{
"file": "000_1920px-2011年4月の牛乳_(5588310773).jpg",
"title": "File:2011年4月の牛乳 (5588310773).jpg",
"detections": 78,
"false_accepts": 1,
"ms": 2983
"ms": 3504
},
{
"file": "001_Candy_in_Japan_2005_(5256472).jpg",
"title": "File:Candy in Japan 2005 (5256472).jpg",
"detections": 12,
"false_accepts": 0,
"ms": 387
"ms": 408
},
{
"file": "004_page1-960px-History_of_the_Toledo_Police_Department.djvu.jpg",
"title": "File:History of the Toledo Police Department.djvu",
"detections": 24,
"file": "002_1920px-Empty_shelves_in_Tokyo_area_as_people_get_ready_for_t.jpg",
"title": "File:Empty shelves in Tokyo area as people get ready for typhoon Hagibis - Oct 11 2019 330pm.jpeg",
"detections": 8,
"false_accepts": 0,
"ms": 246
"ms": 101
},
{
"file": "003_1920px-HK_SW_上環_Sheung_Wan_德輔道西_88_Des_Voeux_Road_West_shop_.jpg",
"title": "File:HK SW 上環 Sheung Wan 德輔道西 88 Des Voeux Road West shop 惠康超級市場 Wellcome Supermarket goods August 2020 SS2 27.jpg",
"detections": 10,
"false_accepts": 0,
"ms": 1560
},
{
"file": "005_1920px-Illuminated_wooden_shelf_with_many_glass_jars_contain.jpg",
"title": "File:Illuminated wooden shelf with many glass jars containing cookies for sale in Tokyo.jpg",
"detections": 41,
"false_accepts": 0,
"ms": 2946
},
{
"file": "007_Japan_earthquake_store_shelves.jpg",
"title": "File:Japan earthquake store shelves.jpg",
"detections": 4,
"false_accepts": 0,
"ms": 97
"ms": 298
},
{
"file": "009_Milk_(2655574568).jpg",
"title": "File:Milk (2655574568).jpg",
"detections": 58,
"false_accepts": 0,
"ms": 1379
"ms": 2802
},
{
"file": "010_Natsuge-mikado_okashi.jpg",
"title": "File:Natsuge-mikado okashi.jpg",
"detections": 7,
"false_accepts": 0,
"ms": 259
"ms": 704
},
{
"file": "012_1920px-Supermarket_in_2006_(646332846).jpg",
"title": "File:Supermarket in 2006 (646332846).jpg",
"detections": 129,
"false_accepts": 0,
"ms": 2672
},
{
"file": "013_page1-1280px-Tangled_Hair.djvu.jpg",
"title": "File:Tangled Hair.djvu",
"detections": 0,
"false_accepts": 0,
"ms": 20
"ms": 6707
},
{
"file": "014_1920px-「ペヤング」予想通りの大売れ!_(18634213682).jpg",
"title": "File:「ペヤング」予想通りの大売れ! (18634213682).jpg",
"detections": 27,
"false_accepts": 0,
"ms": 324
"ms": 762
},
{
"file": "015_1920px-お客様各位_2008_国内産バター_(2429997079).jpg",
"title": "File:お客様各位 2008 国内産バター (2429997079).jpg",
"detections": 14,
"false_accepts": 0,
"ms": 529
"ms": 1499
},
{
"file": "016_1920px-パン売り場_手動ドア式_2016_(28574754416).jpg",
"title": "File:パン売り場 手動ドア式 2016 (28574754416).jpg",
"detections": 21,
"false_accepts": 0,
"ms": 543
"ms": 1842
},
{
"file": "017_1920px-プラレール_2015_(22339689873).jpg",
"title": "File:プラレール 2015 (22339689873).jpg",
"detections": 12,
"false_accepts": 0,
"ms": 254
"ms": 864
},
{
"file": "018_一家族様一本限り_(5588902836).jpg",
"title": "File:一家族様一本限り (5588902836).jpg",
"detections": 27,
"false_accepts": 0,
"ms": 1385
"ms": 3880
},
{
"file": "019_1920px-洗濯洗剤_(10852819193).jpg",
"title": "File:洗濯洗剤 (10852819193).jpg",
"detections": 8,
"false_accepts": 0,
"ms": 158
"ms": 704
},
{
"file": "020_1920px-申し訳ございませんが_ごめんなさい_お魚本日の調理は終了いたしました。_どうぞよろしくお願いします_(11.jpg",
"title": "File:申し訳ございませんが ごめんなさい お魚本日の調理は終了いたしました。 どうぞよろしくお願いします (11331761984).jpg",
"detections": 6,
"false_accepts": 0,
"ms": 957
},
{
"file": "021_1920px-要冷蔵_(4513315790).jpg",
"title": "File:要冷蔵 (4513315790).jpg",
"detections": 0,
"false_accepts": 0,
"ms": 21
"ms": 190
}
]
}

View file

@ -22,7 +22,7 @@
"queries": 1
},
{
"file": "002_1920px-Empty_shelves_in_Tokyo_area_as_people_get_ready_for_t",
"file": "002_1920px-Empty_shelves_in_Tokyo_area_as_people_get_ready_for_t.jpg",
"title": "File:Empty shelves in Tokyo area as people get ready for typhoon Hagibis - Oct 11 2019 330pm.jpeg",
"width": 4027,
"height": 3018,
@ -32,7 +32,7 @@
"queries": 1
},
{
"file": "003_1920px-HK_SW_上環_Sheung_Wan_德輔道西_88_Des_Voeux_Road_West_shop_",
"file": "003_1920px-HK_SW_上環_Sheung_Wan_德輔道西_88_Des_Voeux_Road_West_shop_.jpg",
"title": "File:HK SW 上環 Sheung Wan 德輔道西 88 Des Voeux Road West shop 惠康超級市場 Wellcome Supermarket goods August 2020 SS2 27.jpg",
"width": 4128,
"height": 3096,
@ -42,17 +42,7 @@
"queries": 1
},
{
"file": "004_page1-960px-History_of_the_Toledo_Police_Department.djvu.jpg",
"title": "File:History of the Toledo Police Department.djvu",
"width": 1105,
"height": 1500,
"license": "Public domain",
"artist": "<div class=\"fn value\">\nToledo (Ohio). Division of Police</div>",
"source": "https://commons.wikimedia.org/wiki/File%3AHistory_of_the_Toledo_Police_Department.djvu",
"queries": 1
},
{
"file": "005_1920px-Illuminated_wooden_shelf_with_many_glass_jars_contain",
"file": "005_1920px-Illuminated_wooden_shelf_with_many_glass_jars_contain.jpg",
"title": "File:Illuminated wooden shelf with many glass jars containing cookies for sale in Tokyo.jpg",
"width": 4037,
"height": 6055,
@ -62,7 +52,7 @@
"queries": 1
},
{
"file": "006_1920px-Interior_of_JUSCO_Shingu_Shopping_Center_20100213c.JP",
"file": "006_1920px-Interior_of_JUSCO_Shingu_Shopping_Center_20100213c.jpg",
"title": "File:Interior of JUSCO Shingu Shopping Center 20100213c.JPG",
"width": 3648,
"height": 2736,
@ -81,16 +71,6 @@
"source": "https://commons.wikimedia.org/wiki/File%3AJapan_earthquake_store_shelves.jpg",
"queries": 1
},
{
"file": "008_page1-960px-Judge_v067_n1726_(1914-11-14.Leslie-Judge)_(Darw",
"title": "File:Judge v067 n1726 (1914-11-14.Leslie-Judge) (Darwin-IA).djvu",
"width": 1192,
"height": 1500,
"license": "Public domain",
"artist": "",
"source": "https://commons.wikimedia.org/wiki/File%3AJudge_v067_n1726_%281914-11-14.Leslie-Judge%29_%28Darwin-IA%29.djvu",
"queries": 1
},
{
"file": "009_Milk_(2655574568).jpg",
"title": "File:Milk (2655574568).jpg",
@ -111,16 +91,6 @@
"source": "https://commons.wikimedia.org/wiki/File%3ANatsuge-mikado_okashi.jpg",
"queries": 1
},
{
"file": "011_page1-1920px-Overland_through_Asia._by_Knox,_Thomas_Wallace.",
"title": "File:Overland through Asia. by Knox, Thomas Wallace.djvu",
"width": 2596,
"height": 4212,
"license": "Public domain",
"artist": "<bdi><a href=\"https://en.wikipedia.org/wiki/en:Thomas_W._Knox\" class=\"extiw\" title=\"w:en:Thomas W. Knox\"><span title=\"American writer (1835-1896)\">Thomas W. Knox</span></a></bdi>",
"source": "https://commons.wikimedia.org/wiki/File%3AOverland_through_Asia._by_Knox%2C_Thomas_Wallace.djvu",
"queries": 1
},
{
"file": "012_1920px-Supermarket_in_2006_(646332846).jpg",
"title": "File:Supermarket in 2006 (646332846).jpg",
@ -131,16 +101,6 @@
"source": "https://commons.wikimedia.org/wiki/File%3ASupermarket_in_2006_%28646332846%29.jpg",
"queries": 1
},
{
"file": "013_page1-1280px-Tangled_Hair.djvu.jpg",
"title": "File:Tangled Hair.djvu",
"width": 1371,
"height": 2129,
"license": "Public domain",
"artist": "<bdi><a href=\"https://en.wikipedia.org/wiki/en:Yosano_Akiko\" class=\"extiw\" title=\"w:en:Yosano Akiko\"><span title=\"Japanese tanka poet (1878–1942)\">Akiko Yosano</span></a></bdi>",
"source": "https://commons.wikimedia.org/wiki/File%3ATangled_Hair.djvu",
"queries": 1
},
{
"file": "014_1920px-「ペヤング」予想通りの大売れ!_(18634213682).jpg",
"title": "File:「ペヤング」予想通りの大売れ! (18634213682).jpg",
@ -202,7 +162,7 @@
"queries": 1
},
{
"file": "020_1920px-申し訳ございませんが_ごめんなさい_お魚本日の調理は終了いたしました。_どうぞよろしくお願いします_(11",
"file": "020_1920px-申し訳ございませんが_ごめんなさい_お魚本日の調理は終了いたしました。_どうぞよろしくお願いします_(11.jpg",
"title": "File:申し訳ございませんが ごめんなさい お魚本日の調理は終了いたしました。 どうぞよろしくお願いします (11331761984).jpg",
"width": 4000,
"height": 2672,

View file

@ -2,297 +2,325 @@
"dataset": "wikimedia-commons",
"catalog": "stock-lopia-clean",
"note": "Unrelated shelves: every accept is a false accept by construction.",
"images": 41,
"detections": 1876,
"images": 45,
"detections": 2133,
"false_accepts": 7,
"false_accept_rate": 0.0037,
"false_accept_rate": 0.0033,
"rows": [
{
"file": "000_1920px-198円_中華弁当_2016_(25800617695).jpg",
"title": "File:198円 中華弁当 2016 (25800617695).jpg",
"detections": 2,
"false_accepts": 0,
"ms": 813
"ms": 1774
},
{
"file": "001_1920px-2011年4月の牛乳_(5588310773).jpg",
"title": "File:2011年4月の牛乳 (5588310773).jpg",
"detections": 78,
"false_accepts": 1,
"ms": 2983
"ms": 4553
},
{
"file": "002_1920px-20140909-0252_Costa_Mesa_Mitsuwa.JPG",
"title": "File:20140909-0252 Costa Mesa Mitsuwa.JPG",
"detections": 95,
"false_accepts": 0,
"ms": 2204
"ms": 3025
},
{
"file": "003_1920px-Aomori_Home_(4721758999).jpg",
"title": "File:Aomori Home (4721758999).jpg",
"detections": 76,
"false_accepts": 0,
"ms": 2995
"ms": 3634
},
{
"file": "004_1920px-Asakusa_15_-_making_rice_crackers_the_old_way_(155797.jpg",
"title": "File:Asakusa 15 - making rice crackers the old way (15579727827).jpg",
"detections": 14,
"false_accepts": 0,
"ms": 162
},
{
"file": "005_1920px-Asakusa_16_-_making_rice_crackers_the_old_way_(155794.jpg",
"title": "File:Asakusa 16 - making rice crackers the old way (15579472088).jpg",
"detections": 3,
"false_accepts": 0,
"ms": 131
},
{
"file": "006_1920px-Asakusa_17_-_making_rice_crackers_the_old_way_(155794.jpg",
"title": "File:Asakusa 17 - making rice crackers the old way (15579471588).jpg",
"detections": 4,
"false_accepts": 0,
"ms": 132
},
{
"file": "007_1920px-Asakusa_19_-_the_woman_selling_the_rice_crackers_(157.jpg",
"title": "File:Asakusa 19 - the woman selling the rice crackers (15764889785).jpg",
"detections": 3,
"false_accepts": 0,
"ms": 67
},
{
"file": "008_1920px-Azabudai-Hills---2025-04-05_015.jpg",
"title": "File:Azabudai-Hills---2025-04-05 015.jpg",
"detections": 37,
"false_accepts": 2,
"ms": 2272
"ms": 2113
},
{
"file": "010_1920px-Breathalyzers_in_a_MaxValu_supermarket.jpg",
"title": "File:Breathalyzers in a MaxValu supermarket.jpg",
"detections": 5,
"false_accepts": 0,
"ms": 306
"ms": 368
},
{
"file": "011_1920px-Chocolate_in_Japan_(5137097169).jpg",
"title": "File:Chocolate in Japan (5137097169).jpg",
"detections": 65,
"false_accepts": 1,
"ms": 2295
"ms": 3829
},
{
"file": "013_1920px-Confectionery_at_WCTC_Shopping_Center,_Koror_City,_Pa.jpg",
"title": "File:Confectionery at WCTC Shopping Center, Koror City, Palau.jpg",
"detections": 96,
"false_accepts": 0,
"ms": 6114
},
{
"file": "014_1920px-Deer_cookies_at_Nara,_Japan.jpg",
"title": "File:Deer cookies at Nara, Japan.jpg",
"detections": 10,
"false_accepts": 0,
"ms": 374
"ms": 733
},
{
"file": "015_1920px-ESL_Price_Tag.JPG",
"title": "File:ESL Price Tag.JPG",
"detections": 32,
"false_accepts": 0,
"ms": 1022
"ms": 1506
},
{
"file": "017_1920px-Food-with-physiological-energy-value-example.jpg",
"title": "File:Food-with-physiological-energy-value-example.jpg",
"detections": 10,
"false_accepts": 0,
"ms": 468
"ms": 454
},
{
"file": "019_1920px-HK_CWB_Wellcome_Shop_Supermarket_goods_Carbonated_sof.jpg",
"title": "File:HK CWB Wellcome Shop Supermarket goods Carbonated soft drink codd-neck bottles 波子汽水 Apple Ramune Japanese products July 2017 IX1.jpg",
"detections": 18,
"false_accepts": 0,
"ms": 712
},
{
"file": "021_1920px-Interior_of_Supermarket_in_Japan_02.jpg",
"title": "File:Interior of Supermarket in Japan 02.jpg",
"detections": 5,
"false_accepts": 0,
"ms": 234
"ms": 286
},
{
"file": "022_1920px-JP_日本_Japan_沖繩_OKINAWA_浦添市_Urasoe-city_AEON_Supermark.jpg",
"title": "File:JP 日本 Japan 沖繩 OKINAWA 浦添市 Urasoe-city AEON Supermarket food drinks February 2026 N13p 02.jpg",
"detections": 119,
"false_accepts": 0,
"ms": 4603
},
{
"file": "023_1920px-thumbnail.jpg",
"title": "File:JP 日本 Japan 沖繩 OKINAWA 那霸 Naha Omoromachi Shintoshin 新都心 Naha Main Place 商場 Shopping Mall shop Aeon Supermarket drink 益力多 January 2025 R12S 01.jpg",
"detections": 117,
"false_accepts": 0,
"ms": 2817
"ms": 2581
},
{
"file": "024_1920px-JaSupermarket_Instant_noodles.JPG",
"title": "File:JaSupermarket Instant noodles.JPG",
"detections": 97,
"false_accepts": 0,
"ms": 2613
"ms": 2750
},
{
"file": "026_1920px-Kawasaki-Inryo-1.jpg",
"title": "File:Kawasaki-Inryo-1.jpg",
"detections": 12,
"false_accepts": 0,
"ms": 701
},
{
"file": "027_page1-1920px-Mary_Barton_-_1848_-_Volume_1.djvu.jpg",
"title": "File:Mary Barton - 1848 - Volume 1.djvu",
"detections": 0,
"false_accepts": 0,
"ms": 19
"ms": 892
},
{
"file": "029_1920px-Miyazu_Mipple_1F_2021-04_ac.jpg",
"title": "File:Miyazu Mipple 1F 2021-04 ac.jpg",
"detections": 73,
"false_accepts": 0,
"ms": 700
"ms": 852
},
{
"file": "030_1920px-Octopus_rice_crackers_No,1.JPG",
"title": "File:Octopus rice crackers No,1.JPG",
"detections": 5,
"false_accepts": 0,
"ms": 237
"ms": 247
},
{
"file": "031_1920px-Octopus_senbei.JPG",
"title": "File:Octopus senbei.JPG",
"detections": 4,
"false_accepts": 0,
"ms": 136
"ms": 140
},
{
"file": "032_1920px-Okaki_for_sale_in_Kawagoe.jpg",
"title": "File:Okaki for sale in Kawagoe.jpg",
"detections": 27,
"false_accepts": 0,
"ms": 255
"ms": 267
},
{
"file": "033_Okonomiyaki_and_takoyaki_ingredients.jpg",
"title": "File:Okonomiyaki and takoyaki ingredients.jpg",
"detections": 39,
"false_accepts": 0,
"ms": 1216
"ms": 1228
},
{
"file": "035_1920px-SW_4963.jpg",
"title": "File:SW 4963.jpg",
"detections": 5,
"false_accepts": 0,
"ms": 238
"ms": 200
},
{
"file": "037_1920px-Soy_Sauce_selection_(6362318717).jpg",
"title": "File:Soy Sauce selection (6362318717).jpg",
"detections": 68,
"false_accepts": 0,
"ms": 1631
"ms": 1671
},
{
"file": "038_1920px-Soy_sauce_(5846027636).jpg",
"title": "File:Soy sauce (5846027636).jpg",
"detections": 103,
"false_accepts": 1,
"ms": 1603
"ms": 1626
},
{
"file": "039_1920px-Soy_sauce_in_supermarket.JPG",
"title": "File:Soy sauce in supermarket.JPG",
"detections": 71,
"false_accepts": 0,
"ms": 2729
"ms": 2380
},
{
"file": "040_1920px-Spice_Supermarket_Japan.JPG",
"title": "File:Spice Supermarket Japan.JPG",
"detections": 254,
"false_accepts": 0,
"ms": 2453
"ms": 2544
},
{
"file": "041_1920px-Strong_Zero_4962.jpg",
"title": "File:Strong Zero 4962.jpg",
"detections": 18,
"false_accepts": 0,
"ms": 838
"ms": 856
},
{
"file": "042_1920px-Supermarket_Digital_Displays_(2927051130).jpg",
"title": "File:Supermarket Digital Displays (2927051130).jpg",
"detections": 89,
"false_accepts": 1,
"ms": 3543
"ms": 3561
},
{
"file": "043_1920px-Tasty_Food_Abundance_in_Healthy_Europe.png",
"title": "File:Tasty Food Abundance in Healthy Europe.png",
"detections": 13,
"false_accepts": 0,
"ms": 605
},
{
"file": "046_page1-1920px-Things_Japanese_(1905).djvu.jpg",
"title": "File:Things Japanese (1905).djvu",
"detections": 0,
"false_accepts": 0,
"ms": 20
"ms": 1202
},
{
"file": "047_1920px-Tokyo---Ebisu-and-Shibuya---2026-02-04_162.jpg",
"title": "File:Tokyo---Ebisu-and-Shibuya---2026-02-04 162.jpg",
"detections": 74,
"false_accepts": 0,
"ms": 2095
"ms": 4770
},
{
"file": "048_1920px-Tokyo---Ebisu-and-Shibuya---2026-02-04_167.jpg",
"title": "File:Tokyo---Ebisu-and-Shibuya---2026-02-04 167.jpg",
"detections": 46,
"false_accepts": 0,
"ms": 1424
},
{
"file": "049_page1-1280px-Tono-Bungay.djvu.jpg",
"title": "File:Tono-Bungay.djvu",
"detections": 0,
"false_accepts": 0,
"ms": 19
"ms": 2557
},
{
"file": "050_1920px-Umami_Snack_(41957534).jpeg",
"title": "File:Umami Snack (41957534).jpeg",
"detections": 33,
"false_accepts": 0,
"ms": 1687
"ms": 3096
},
{
"file": "051_1920px-このかねをならすのはだーれ_(3079692697).jpg",
"title": "File:このかねをならすのはだーれ (3079692697).jpg",
"detections": 0,
"false_accepts": 0,
"ms": 20
"ms": 125
},
{
"file": "052_1920px-スーパーの野菜コーナー_2008_(2785121488).jpg",
"title": "File:スーパーの野菜コーナー 2008 (2785121488).jpg",
"detections": 25,
"false_accepts": 0,
"ms": 792
"ms": 1681
},
{
"file": "055_1920px-中央フード山手店_-_panoramio.jpg",
"title": "File:中央フード山手店 - panoramio.jpg",
"detections": 15,
"false_accepts": 0,
"ms": 183
"ms": 263
},
{
"file": "056_1920px-何このリポD人気⁈買い占めてしまおう。_(4025507198).jpg",
"title": "File:何このリポD人気⁈買い占めてしまおう。 (4025507198).jpg",
"detections": 38,
"false_accepts": 0,
"ms": 1700
"ms": 2912
},
{
"file": "057_1920px-味噌売り場_(16183474871).jpg",
"title": "File:味噌売り場 (16183474871).jpg",
"detections": 61,
"false_accepts": 0,
"ms": 2085
"ms": 3355
},
{
"file": "058_1920px-塩ひかえめ_(25347152904).jpg",
"title": "File:塩ひかえめ (25347152904).jpg",
"detections": 66,
"false_accepts": 0,
"ms": 2014
"ms": 3043
},
{
"file": "060_1920px-牛乳_豆乳_2016_(32081175436).jpg",
"title": "File:牛乳 豆乳 2016 (32081175436).jpg",
"detections": 103,
"false_accepts": 1,
"ms": 3198
"ms": 3677
},
{
"file": "061_1920px-表示価格より100円引_(38057600585).jpg",
"title": "File:表示価格より100円引 (38057600585).jpg",
"detections": 5,
"false_accepts": 0,
"ms": 580
"ms": 632
}
]
}

View file

@ -42,7 +42,7 @@
"queries": 2
},
{
"file": "004_1920px-Asakusa_15_-_making_rice_crackers_the_old_way_(155797",
"file": "004_1920px-Asakusa_15_-_making_rice_crackers_the_old_way_(155797.jpg",
"title": "File:Asakusa 15 - making rice crackers the old way (15579727827).jpg",
"width": 4288,
"height": 2848,
@ -52,7 +52,7 @@
"queries": 1
},
{
"file": "005_1920px-Asakusa_16_-_making_rice_crackers_the_old_way_(155794",
"file": "005_1920px-Asakusa_16_-_making_rice_crackers_the_old_way_(155794.jpg",
"title": "File:Asakusa 16 - making rice crackers the old way (15579472088).jpg",
"width": 4288,
"height": 2848,
@ -62,7 +62,7 @@
"queries": 1
},
{
"file": "006_1920px-Asakusa_17_-_making_rice_crackers_the_old_way_(155794",
"file": "006_1920px-Asakusa_17_-_making_rice_crackers_the_old_way_(155794.jpg",
"title": "File:Asakusa 17 - making rice crackers the old way (15579471588).jpg",
"width": 4288,
"height": 2848,
@ -72,7 +72,7 @@
"queries": 1
},
{
"file": "007_1920px-Asakusa_19_-_the_woman_selling_the_rice_crackers_(157",
"file": "007_1920px-Asakusa_19_-_the_woman_selling_the_rice_crackers_(157.jpg",
"title": "File:Asakusa 19 - the woman selling the rice crackers (15764889785).jpg",
"width": 4288,
"height": 2848,
@ -112,7 +112,7 @@
"queries": 2
},
{
"file": "013_1920px-Confectionery_at_WCTC_Shopping_Center,_Koror_City,_Pa",
"file": "013_1920px-Confectionery_at_WCTC_Shopping_Center,_Koror_City,_Pa.jpg",
"title": "File:Confectionery at WCTC Shopping Center, Koror City, Palau.jpg",
"width": 2305,
"height": 1731,
@ -141,16 +141,6 @@
"source": "https://commons.wikimedia.org/wiki/File%3AESL_Price_Tag.JPG",
"queries": 1
},
{
"file": "016_page1-1280px-Eliza_Scidmore--Jinrikisha_days_in_Japan.djvu.j",
"title": "File:Eliza Scidmore--Jinrikisha days in Japan.djvu",
"width": 1719,
"height": 2599,
"license": "Public domain",
"artist": "<bdi><a href=\"https://en.wikipedia.org/wiki/en:Eliza_Ruhamah_Scidmore\" class=\"extiw\" title=\"w:en:Eliza Ruhamah Scidmore\"><span title=\"American writer and photographer (1856-1928)\">Eliza Ruhamah Scidmore</span></a></bdi>",
"source": "https://commons.wikimedia.org/wiki/File%3AEliza_Scidmore--Jinrikisha_days_in_Japan.djvu",
"queries": 1
},
{
"file": "017_1920px-Food-with-physiological-energy-value-example.jpg",
"title": "File:Food-with-physiological-energy-value-example.jpg",
@ -162,17 +152,7 @@
"queries": 1
},
{
"file": "018_page1-1920px-Gissing_-_Isabel_Clarendon,_vol._I,_1886.djvu.j",
"title": "File:Gissing - Isabel Clarendon, vol. I, 1886.djvu",
"width": 2227,
"height": 3518,
"license": "Public domain",
"artist": "<bdi><a href=\"https://en.wikipedia.org/wiki/en:George_Gissing\" class=\"extiw\" title=\"w:en:George Gissing\"><span title=\"English novelist (1857–1903)\">George Gissing</span></a></bdi>",
"source": "https://commons.wikimedia.org/wiki/File%3AGissing_-_Isabel_Clarendon%2C_vol._I%2C_1886.djvu",
"queries": 1
},
{
"file": "019_1920px-HK_CWB_Wellcome_Shop_Supermarket_goods_Carbonated_sof",
"file": "019_1920px-HK_CWB_Wellcome_Shop_Supermarket_goods_Carbonated_sof.jpg",
"title": "File:HK CWB Wellcome Shop Supermarket goods Carbonated soft drink codd-neck bottles 波子汽水 Apple Ramune Japanese products July 2017 IX1.jpg",
"width": 2048,
"height": 1368,
@ -181,16 +161,6 @@
"source": "https://commons.wikimedia.org/wiki/File%3AHK_CWB_Wellcome_Shop_Supermarket_goods_Carbonated_soft_drink_codd-neck_bottles_%E6%B3%A2%E5%AD%90%E6%B1%BD%E6%B0%B4_Apple_Ramune_Japanese_products_July_2017_IX1.jpg",
"queries": 2
},
{
"file": "020_page1-960px-Henry_Theophilus_Finck_-_Lotos-time_in_Japan_(18",
"title": "File:Henry Theophilus Finck - Lotos-time in Japan (1895).djvu",
"width": 1000,
"height": 1500,
"license": "Public domain",
"artist": "<div class=\"fn value\">\nHenry Theophilus Finck</div>",
"source": "https://commons.wikimedia.org/wiki/File%3AHenry_Theophilus_Finck_-_Lotos-time_in_Japan_%281895%29.djvu",
"queries": 2
},
{
"file": "021_1920px-Interior_of_Supermarket_in_Japan_02.jpg",
"title": "File:Interior of Supermarket in Japan 02.jpg",
@ -202,7 +172,7 @@
"queries": 1
},
{
"file": "022_1920px-JP_日本_Japan_沖繩_OKINAWA_浦添市_Urasoe-city_AEON_Supermark",
"file": "022_1920px-JP_日本_Japan_沖繩_OKINAWA_浦添市_Urasoe-city_AEON_Supermark.jpg",
"title": "File:JP 日本 Japan 沖繩 OKINAWA 浦添市 Urasoe-city AEON Supermarket food drinks February 2026 N13p 02.jpg",
"width": 3060,
"height": 4080,
@ -241,16 +211,6 @@
"source": "https://commons.wikimedia.org/wiki/File%3AKawasaki-Inryo-1.jpg",
"queries": 2
},
{
"file": "027_page1-1920px-Mary_Barton_-_1848_-_Volume_1.djvu.jpg",
"title": "File:Mary Barton - 1848 - Volume 1.djvu",
"width": 2148,
"height": 3615,
"license": "Public domain",
"artist": "<div class=\"fn value\">\nElizabeth Cleghorn Gaskell</div>",
"source": "https://commons.wikimedia.org/wiki/File%3AMary_Barton_-_1848_-_Volume_1.djvu",
"queries": 1
},
{
"file": "029_1920px-Miyazu_Mipple_1F_2021-04_ac.jpg",
"title": "File:Miyazu Mipple 1F 2021-04 ac.jpg",
@ -302,7 +262,7 @@
"queries": 1
},
{
"file": "034_1920px-Rice_toppings_&_additional_ingredients_(5846028686).j",
"file": "034_1920px-Rice_toppings_&_additional_ingredients_(5846028686).jpg",
"title": "File:Rice toppings & additional ingredients (5846028686).jpg",
"width": 3072,
"height": 2304,
@ -391,36 +351,6 @@
"source": "https://commons.wikimedia.org/wiki/File%3ATasty_Food_Abundance_in_Healthy_Europe.png",
"queries": 1
},
{
"file": "044_page1-1920px-The_Philippine_Islands,_1493-1803_(Volume_27).d",
"title": "File:The Philippine Islands, 1493-1803 (Volume 27).djvu",
"width": 2181,
"height": 3622,
"license": "Public domain",
"artist": "<div class=\"fn value\">\nd. 1911 Emma Helen Blair</div>",
"source": "https://commons.wikimedia.org/wiki/File%3AThe_Philippine_Islands%2C_1493-1803_%28Volume_27%29.djvu",
"queries": 1
},
{
"file": "045_page1-1920px-The_Philippine_Islands,_1493-1803_(Volume_38).d",
"title": "File:The Philippine Islands, 1493-1803 (Volume 38).djvu",
"width": 2261,
"height": 3587,
"license": "Public domain",
"artist": "<div class=\"fn value\">\nd. 1911 Emma Helen Blair</div>",
"source": "https://commons.wikimedia.org/wiki/File%3AThe_Philippine_Islands%2C_1493-1803_%28Volume_38%29.djvu",
"queries": 1
},
{
"file": "046_page1-1920px-Things_Japanese_(1905).djvu.jpg",
"title": "File:Things Japanese (1905).djvu",
"width": 2332,
"height": 3684,
"license": "Public domain",
"artist": "Basil Hall Chamberlain (1850-1935)",
"source": "https://commons.wikimedia.org/wiki/File%3AThings_Japanese_%281905%29.djvu",
"queries": 1
},
{
"file": "047_1920px-Tokyo---Ebisu-and-Shibuya---2026-02-04_162.jpg",
"title": "File:Tokyo---Ebisu-and-Shibuya---2026-02-04 162.jpg",
@ -441,16 +371,6 @@
"source": "https://commons.wikimedia.org/wiki/File%3ATokyo---Ebisu-and-Shibuya---2026-02-04_167.jpg",
"queries": 1
},
{
"file": "049_page1-1280px-Tono-Bungay.djvu.jpg",
"title": "File:Tono-Bungay.djvu",
"width": 1757,
"height": 2916,
"license": "Public domain",
"artist": "<div class=\"fn value\">\nWells, H. G. (Herbert George), 1866-1946</div>",
"source": "https://commons.wikimedia.org/wiki/File%3ATono-Bungay.djvu",
"queries": 1
},
{
"file": "050_1920px-Umami_Snack_(41957534).jpeg",
"title": "File:Umami Snack (41957534).jpeg",

View file

@ -57,11 +57,12 @@ store-scoped, enrolled catalog, with live-video evidence accumulation**.
becomes retrieval plus verification (§6).
- **Open set is the dominant difficulty, and it comes in two kinds.** *Far*
unknowns (other categories) are rejected easily **once the accept lines are
calibrated against them**: 0.37 % and 0.24 % false accepts on 2297 crops from
56 unrelated Wikimedia supermarket photos, at a threshold that keeps 42 of 48
correct image6 labels. The audit's 0.2-0.7 % was measured on 602 crops from
the `add/` photos with the audit's own variant matcher; the shipped lane at
the shipped lines was 3.61 % until 2026-09-29 (§ Re-measured, far unknowns).
calibrated against them**: 3.09 % at the old lines, 0.30 % at the shipped
ones, on 2650 crops from 60 unrelated Wikimedia supermarket photos, at a
threshold that keeps 42 of 48 correct image6 labels. The audit's 0.2-0.7 %
was measured on 602 crops from the `add/` photos with the audit's own variant
matcher; the shipped lane at the shipped lines was 3.09 % until 2026-09-29
(§ Re-measured, far unknowns).
*Near*
unknowns (siblings of enrolled products: Kewpie 450 g next to Kewpie からし,
Pure Select plain next to Pure Select コクうま) produce genuine,
@ -396,7 +397,7 @@ with always-argmax, run on that same catalog.
Status 2026-09-29, offline on image6 plus the Wikimedia distractor sets:
**G2 passes** (95 % precision, full resolution). **G3's far-unknown half
passes** (0.37 % / 0.24 % on 2297 unrelated crops); its near-unknown half is
passes** (0.30 % on 2650 unrelated crops); its near-unknown half is
measured on image6 only, where the size gate rejects the documented 450 g case.
**G8 passes** (identity p95 well inside 60 ms). **G1, G4, G5, G6, G7 are not
yet measured on held-out data** - Tier 2 does not exist, and G4/G5 need a
@ -656,13 +657,16 @@ facings sit at p25 2.07 (full) and 2.87 (live), wrong ones at p75 1.00 and
1.66, so 2.0 is the boundary in both. Sweeping it at full resolution, through
the evaluator (`--accept`, columns as it defines them: end-to-end is
accepted-and-correct over the 64 in-catalog facings, precision is over the
facings it answered):
facings it answered). Re-measured 2026-09-29 after the accept lines were
calibrated against unrelated shelves (§ Far unknowns); the 2.0 row is what the
audit measured, the 4.0 row is the shipped line:
accept end-to-end precision false accepts
2.0 75% 91% 5
3.0 67% 91% 4
4.0 67% 93% 3
6.0 62% 95% 2
2.0 75% 92% 4
3.0 66% 93% 3
4.0 66% 95% 2
5.0 62% 98% 1
6.0 59% 97% 1
The line is still provisional - it is tuned on Tier 1 and needs Tier-2
calibration - but it does not need to differ by input path, and the design
@ -853,12 +857,9 @@ precision 86% -> 91%, false accepts 8 -> 5, coverage unchanged at 79%.
### Far unknowns: the accept lines were tuned on a shelf that has no unknowns
Every threshold in this document was fitted on image6, where each crop is a
facing of a product the shelf actually holds. That is a closed-set tuning set,
and it hid the far-unknown rate completely: the shipped lane accepted 83 of
2297 crops from 56 Wikimedia Commons supermarket photos of milk, soy and snack
shelves - 3.61 %, against G3's 1 %.
and it hid the far-unknown rate completely: the shipped lane accepted 82 of
2650 crops from 60 Wikimedia Commons supermarket photos of milk, soy and snack
shelves - 3.09 %, against G3's 1 %.
Those photos share nothing with the LOPIA catalog, so every accept is a false
accept by construction. Two mechanisms produced them:
@ -867,24 +868,24 @@ accept by construction. Two mechanisms produced them:
drops bigrams no catalog name contains, so a short garbage read can end up
with a perfect ratio on two pairs. 20 of 26 text-lane answers rested on
exactly two: `避くて おいしい` named `sku_l12` through おい/いし.
- **The local lane accepted pure geometry.** The residual 25 were matches with
no text overlap at all, scoring 2.26-4.81 against an accept line of 2.0.
- **The local lane accepted pure geometry.** The residual accepts were matches
with no text overlap at all, scoring 2.26-4.81 against an accept line of 2.0.
Both lines moved: `TEXT_MIN_SHARED` 2 -> 4, `LOCAL_ACCEPT` 2.0 -> 4.0. Measured
on 2297 distractor crops and 109 image6 facings:
on 2650 distractor crops and 109 image6 facings:
| `LOCAL_ACCEPT` | `TEXT_MIN_SHARED` | image6 shown / correct | precision | false accepts |
|---|---|---|---|---|
| 2.0 | 2 | 54 / 49 | 90.7 % | 83 (3.61 %) |
| 2.0 | 4 | 52 / 48 | 92.3 % | 30 (1.31 %) |
| **4.0** | **4** | **44 / 42** | **95.5 %** | **8 (0.35 %)** |
| 5.0 | 6 | 36 / 36 | 100.0 % | 0 (0.00 %) |
| 2.0 | 2 | 46 / 43 | 93.5 % | 82 (3.09 %) |
| 2.0 | 4 | 44 / 42 | 95.5 % | 8 (0.30 %) |
| **4.0** | **4** | **44 / 42** | **95.5 %** | **8 (0.30 %)** |
| 5.0 | 6 | 39 / 38 | 97.4 % | 3 (0.11 %) |
4.0/4 is the only region passing both G2 (>= 95 % precision) and G3 (<= 1 %
far-unknown) with coverage left. On the shipped evaluator that is 66 %
end-to-end at 95 % precision with 2 false accepts, against 77 % / 91 % / 5
before - the coverage is what the precision costs, and G2 is the gate that says
to pay it.
end-to-end at 95 % precision with 2 false accepts, against 75 % / 92 % / 4 at
the old 2.0 line - the coverage is what the precision costs, and G2 is the gate
that says to pay it.
Reproduce: `.venv/bin/python code/eval_distractors.py --stock stock-lopia-clean
--write data/external-shelves/wikimedia-commons data/external-shelves/wikimedia-commons-2`.