Leeps commited on
Commit
85db9e9
·
1 Parent(s): e12bb2b

Add shared MoMA codebook option

Browse files
Files changed (1) hide show
  1. app.py +40 -8
app.py CHANGED
@@ -189,7 +189,13 @@ TOKENIZER_CODE = """# This tab builds a tiny image tokenizer from one image.
189
  patches = split_image_into_grid(image, grid_size, patch_size)
190
  vectors = flatten_each_patch_to_rgb_numbers(patches)
191
 
192
- codebook = k_means(vectors, codebook_size)
 
 
 
 
 
 
193
  token_ids = nearest_code_for_each_patch(vectors, codebook)
194
 
195
  # The compressed image is now a grid of integers.
@@ -770,14 +776,32 @@ def learned_codebook_rows(centroids, assignments, errors):
770
 
771
 
772
  @spaces.GPU(duration=30)
773
- def tokenize_image(image, grid_size, patch_size, codebook_size, iterations, seed):
774
  grid_size = max(4, min(32, int(grid_size)))
775
  patch_size = max(4, min(32, int(patch_size)))
776
  codebook_size = max(2, min(64, int(codebook_size)))
777
  prepared = prepare_tokenizer_image(image, grid_size, patch_size)
778
  patches = image_to_patches(prepared, grid_size, patch_size)
779
  vectors = patches.reshape(len(patches), -1)
780
- centroids, assignments, errors = learn_codebook(vectors, codebook_size, iterations, seed)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
  reconstruction_vectors = centroids[assignments]
782
  reconstruction = patches_to_image(reconstruction_vectors.reshape(len(patches), patch_size, patch_size, 3), grid_size, patch_size)
783
  token_grid = draw_token_id_grid(assignments, grid_size)
@@ -787,25 +811,25 @@ def tokenize_image(image, grid_size, patch_size, codebook_size, iterations, seed
787
  summary = (
788
  f"Encoded the image into a {grid_size}x{grid_size} grid: {grid_size * grid_size} discrete token IDs.\n"
789
  f"Each token represents one {patch_size}x{patch_size} RGB patch. "
790
- f"The codebook has {len(centroids)} learned entries from this image.\n"
791
  f"Mean reconstruction error per patch: {float(errors.mean()):.6f}. "
792
  "Lower error means the learned codebook patch is closer to the original patch."
793
  )
794
  return prepared, token_grid, reconstruction, error_map, gallery, rows, summary
795
 
796
 
797
- def initial_tokenizer(grid_size, patch_size, codebook_size, iterations, seed):
798
  items, message = load_moma_items()
799
- outputs = tokenize_image(items[0]["img"], grid_size, patch_size, codebook_size, iterations, seed)
800
  summary = f"{message}\n\n{outputs[-1]}"
801
  return (moma_gallery_items(),) + outputs[:-1] + (summary,)
802
 
803
 
804
- def tokenize_moma_selection(grid_size, patch_size, codebook_size, iterations, seed, evt: gr.SelectData):
805
  items, _ = load_moma_items()
806
  index = evt.index if isinstance(evt.index, int) else 0
807
  index = max(0, min(index, len(items) - 1))
808
- return tokenize_image(items[index]["img"], grid_size, patch_size, codebook_size, iterations, seed)
809
 
810
 
811
  def probability_rows(record):
@@ -1055,6 +1079,11 @@ def build_app():
1055
  with gr.Row():
1056
  tokenizer_codebook_size = gr.Slider(4, 48, value=16, step=1, label="Codebook size")
1057
  tokenizer_iterations = gr.Slider(2, 30, value=10, step=1, label="K-means iterations")
 
 
 
 
 
1058
  tokenizer_seed = gr.Number(value=7, precision=0, label="Codebook seed")
1059
  tokenize_button = gr.Button("Tokenize uploaded image", variant="primary")
1060
 
@@ -1235,6 +1264,7 @@ def build_app():
1235
  tokenizer_codebook_size,
1236
  tokenizer_iterations,
1237
  tokenizer_seed,
 
1238
  ]
1239
  tokenizer_outputs = [
1240
  tokenizer_original,
@@ -1261,6 +1291,7 @@ def build_app():
1261
  tokenizer_codebook_size,
1262
  tokenizer_iterations,
1263
  tokenizer_seed,
 
1264
  ],
1265
  outputs=tokenizer_outputs,
1266
  show_progress="minimal",
@@ -1274,6 +1305,7 @@ def build_app():
1274
  tokenizer_codebook_size,
1275
  tokenizer_iterations,
1276
  tokenizer_seed,
 
1277
  ],
1278
  outputs=tokenizer_outputs,
1279
  show_progress="minimal",
 
189
  patches = split_image_into_grid(image, grid_size, patch_size)
190
  vectors = flatten_each_patch_to_rgb_numbers(patches)
191
 
192
+ # The codebook can be trained on this image only,
193
+ # or on patches from all loaded MoMA images.
194
+ training_vectors = vectors
195
+ if codebook_source == "All loaded MoMA images":
196
+ training_vectors = flatten_patches_from_many_images(moma_images)
197
+
198
+ codebook = k_means(training_vectors, codebook_size)
199
  token_ids = nearest_code_for_each_patch(vectors, codebook)
200
 
201
  # The compressed image is now a grid of integers.
 
776
 
777
 
778
  @spaces.GPU(duration=30)
779
+ def tokenize_image(image, grid_size, patch_size, codebook_size, iterations, seed, codebook_source):
780
  grid_size = max(4, min(32, int(grid_size)))
781
  patch_size = max(4, min(32, int(patch_size)))
782
  codebook_size = max(2, min(64, int(codebook_size)))
783
  prepared = prepare_tokenizer_image(image, grid_size, patch_size)
784
  patches = image_to_patches(prepared, grid_size, patch_size)
785
  vectors = patches.reshape(len(patches), -1)
786
+
787
+ if codebook_source == "All loaded MoMA images":
788
+ items, _ = load_moma_items()
789
+ training_vectors = []
790
+ for item in items:
791
+ train_image = prepare_tokenizer_image(item["img"], grid_size, patch_size)
792
+ train_patches = image_to_patches(train_image, grid_size, patch_size)
793
+ training_vectors.append(train_patches.reshape(len(train_patches), -1))
794
+ training_vectors = np.concatenate(training_vectors, axis=0)
795
+ centroids, _, _ = learn_codebook(training_vectors, codebook_size, iterations, seed)
796
+ source_text = f"all {len(items)} loaded MoMA images ({len(training_vectors)} training patches)"
797
+ else:
798
+ training_vectors = vectors
799
+ centroids, _, _ = learn_codebook(training_vectors, codebook_size, iterations, seed)
800
+ source_text = f"this image only ({len(training_vectors)} training patches)"
801
+
802
+ distances = squared_distances(vectors, centroids)
803
+ assignments = np.argmin(distances, axis=1).astype(np.int32)
804
+ errors = distances[np.arange(len(vectors)), assignments]
805
  reconstruction_vectors = centroids[assignments]
806
  reconstruction = patches_to_image(reconstruction_vectors.reshape(len(patches), patch_size, patch_size, 3), grid_size, patch_size)
807
  token_grid = draw_token_id_grid(assignments, grid_size)
 
811
  summary = (
812
  f"Encoded the image into a {grid_size}x{grid_size} grid: {grid_size * grid_size} discrete token IDs.\n"
813
  f"Each token represents one {patch_size}x{patch_size} RGB patch. "
814
+ f"The codebook has {len(centroids)} learned entries trained from {source_text}.\n"
815
  f"Mean reconstruction error per patch: {float(errors.mean()):.6f}. "
816
  "Lower error means the learned codebook patch is closer to the original patch."
817
  )
818
  return prepared, token_grid, reconstruction, error_map, gallery, rows, summary
819
 
820
 
821
+ def initial_tokenizer(grid_size, patch_size, codebook_size, iterations, seed, codebook_source):
822
  items, message = load_moma_items()
823
+ outputs = tokenize_image(items[0]["img"], grid_size, patch_size, codebook_size, iterations, seed, codebook_source)
824
  summary = f"{message}\n\n{outputs[-1]}"
825
  return (moma_gallery_items(),) + outputs[:-1] + (summary,)
826
 
827
 
828
+ def tokenize_moma_selection(grid_size, patch_size, codebook_size, iterations, seed, codebook_source, evt: gr.SelectData):
829
  items, _ = load_moma_items()
830
  index = evt.index if isinstance(evt.index, int) else 0
831
  index = max(0, min(index, len(items) - 1))
832
+ return tokenize_image(items[index]["img"], grid_size, patch_size, codebook_size, iterations, seed, codebook_source)
833
 
834
 
835
  def probability_rows(record):
 
1079
  with gr.Row():
1080
  tokenizer_codebook_size = gr.Slider(4, 48, value=16, step=1, label="Codebook size")
1081
  tokenizer_iterations = gr.Slider(2, 30, value=10, step=1, label="K-means iterations")
1082
+ tokenizer_codebook_source = gr.Radio(
1083
+ ["This image only", "All loaded MoMA images"],
1084
+ value="This image only",
1085
+ label="Learn codebook from",
1086
+ )
1087
  tokenizer_seed = gr.Number(value=7, precision=0, label="Codebook seed")
1088
  tokenize_button = gr.Button("Tokenize uploaded image", variant="primary")
1089
 
 
1264
  tokenizer_codebook_size,
1265
  tokenizer_iterations,
1266
  tokenizer_seed,
1267
+ tokenizer_codebook_source,
1268
  ]
1269
  tokenizer_outputs = [
1270
  tokenizer_original,
 
1291
  tokenizer_codebook_size,
1292
  tokenizer_iterations,
1293
  tokenizer_seed,
1294
+ tokenizer_codebook_source,
1295
  ],
1296
  outputs=tokenizer_outputs,
1297
  show_progress="minimal",
 
1305
  tokenizer_codebook_size,
1306
  tokenizer_iterations,
1307
  tokenizer_seed,
1308
+ tokenizer_codebook_source,
1309
  ],
1310
  outputs=tokenizer_outputs,
1311
  show_progress="minimal",