Spaces:
Runtime error
Runtime error
temp-9384289
commited on
Commit
·
22e9492
1
Parent(s):
08f4f2e
fashion
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- README.md +3 -4
- app.py +100 -49
- error.png +0 -0
- tester/generation/1714572460.3130271/generated_image.png +0 -0
- tester/generation/1714572509.416096/generated_image.png +0 -0
- tester/generation/1714572566.812253/generated_image.png +0 -0
- tester/generation/1714572647.7270982/generated_image.png +0 -0
- tester/generation/1714572710.317538/generated_image.png +0 -0
- tester/generation/1714572806.7208629/generated_image.png +0 -0
- tester/generation/1714572814.196703/generated_image.png +0 -0
- tester/generation/1714573171.4095411/generated_image.png +0 -0
- tester/generation/1714573180.905479/generated_image.png +0 -0
- tester/generation/1714573283.9210691/generated_image.png +0 -0
- tester/generation/1714573371.120304/generated_image.png +0 -0
- tester/generation/1714573470.715162/generated_image.png +0 -0
- tester/generation/1714573663.655377/generated_image.png +0 -0
- tester/generation/1714573777.020148/generated_image.png +0 -0
- tester/generation/1714573785.923063/generated_image.png +0 -0
- tester/generation/1714573935.654328/generated_image.png +0 -0
- tester/generation/1714573935.654328/keeper.png +0 -0
- tester/generation/1714573935.654328/real_deal.png +0 -0
- tester/generation/1714573949.9718158/generated_image.png +0 -0
- tester/generation/1714573949.9718158/keeper.png +0 -0
- tester/generation/1714573949.9718158/real_deal.png +0 -0
- tester/generation/1714573959.174764/generated_image.png +0 -0
- tester/generation/1714573959.174764/keeper.png +0 -0
- tester/generation/1714573959.174764/real_deal.png +0 -0
- tester/generation/1714573968.372562/generated_image.png +0 -0
- tester/generation/1714573968.372562/keeper.png +0 -0
- tester/generation/1714573968.372562/real_deal.png +0 -0
- tester/generation/1714573976.232955/generated_image.png +0 -0
- tester/generation/1714573976.232955/keeper.png +0 -0
- tester/generation/1714573976.232955/real_deal.png +0 -0
- tester/generation/1714573985.865299/generated_image.png +0 -0
- tester/generation/1714573985.865299/keeper.png +0 -0
- tester/generation/1714573985.865299/real_deal.png +0 -0
- tester/generation/1714573993.039063/generated_image.png +0 -0
- tester/generation/1714573993.039063/keeper.png +0 -0
- tester/generation/1714573993.039063/real_deal.png +0 -0
- tester/generation/1714573998.791243/generated_image.png +0 -0
- tester/generation/1714573998.791243/keeper.png +0 -0
- tester/generation/1714573998.791243/real_deal.png +0 -0
- tester/generation/1714574004.814992/generated_image.png +0 -0
- tester/generation/1714574004.814992/keeper.png +0 -0
- tester/generation/1714574004.814992/real_deal.png +0 -0
- tester/generation/1714574008.685722/generated_image.png +0 -0
- tester/generation/1714574008.685722/keeper.png +0 -0
- tester/generation/1714574008.685722/real_deal.png +0 -0
- tester/generation/1714574012.8655639/generated_image.png +0 -0
- tester/generation/1714574012.8655639/keeper.png +0 -0
README.md
CHANGED
@@ -1,13 +1,12 @@
|
|
1 |
---
|
2 |
title: ModelProblems
|
3 |
-
emoji:
|
4 |
colorFrom: pink
|
5 |
-
colorTo:
|
6 |
sdk: gradio
|
7 |
sdk_version: 4.28.3
|
8 |
app_file: app.py
|
9 |
-
pinned:
|
10 |
license: mit
|
11 |
---
|
12 |
|
13 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
title: ModelProblems
|
3 |
+
emoji: ⚖️
|
4 |
colorFrom: pink
|
5 |
+
colorTo: green
|
6 |
sdk: gradio
|
7 |
sdk_version: 4.28.3
|
8 |
app_file: app.py
|
9 |
+
pinned: true
|
10 |
license: mit
|
11 |
---
|
12 |
|
|
app.py
CHANGED
@@ -13,25 +13,46 @@ from PIL import Image
|
|
13 |
from huggingface_hub import from_pretrained_keras
|
14 |
from math import sqrt, ceil
|
15 |
import numpy as np
|
|
|
16 |
import pandas as pd
|
17 |
import gradio as gr
|
|
|
18 |
|
19 |
modelieo=[
|
20 |
'nathanReitinger/MNIST-diffusion',
|
21 |
'nathanReitinger/MNIST-diffusion-oneImage',
|
22 |
'nathanReitinger/MNIST-GAN',
|
23 |
-
'nathanReitinger/MNIST-GAN-noDropout'
|
|
|
24 |
]
|
25 |
|
26 |
-
def get_sims(gen_filepath, gen_label, file_path, hunting_time_limit):
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
print("how long to hunt", hunting_time_limit)
|
32 |
if hunting_time_limit == None:
|
33 |
hunting_time_limit = 2
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
lowest_score = 10000
|
36 |
lowest_image = None
|
37 |
lowest_image_path = ''
|
@@ -39,8 +60,14 @@ def get_sims(gen_filepath, gen_label, file_path, hunting_time_limit):
|
|
39 |
start = time.time()
|
40 |
|
41 |
for i in range(len(train_labels)):
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
###
|
46 |
# get a real image (of correct number)
|
@@ -84,38 +111,54 @@ def get_sims(gen_filepath, gen_label, file_path, hunting_time_limit):
|
|
84 |
return [lowest_image_path, lowest_score]
|
85 |
|
86 |
|
87 |
-
def digit_recognition(filename):
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
-
low_score_log = ''
|
114 |
-
this_label_for_this_image = int(output[0]['label'])
|
115 |
return {'full': output, 'number': this_label_for_this_image}
|
116 |
|
117 |
|
118 |
-
def get_other(original_image, hunting_time_limit):
|
119 |
RANDO = str(time.time())
|
120 |
file_path = 'tester/' + 'generation' + "/" + RANDO + '/'
|
121 |
os.makedirs(file_path)
|
@@ -127,17 +170,21 @@ def get_other(original_image, hunting_time_limit):
|
|
127 |
plt.close()
|
128 |
print('[+] done saving generation')
|
129 |
print("[-] what digit is this")
|
130 |
-
|
|
|
|
|
131 |
print(ret['full'])
|
132 |
print(ret['number'])
|
133 |
print("[+]", ret['number'])
|
134 |
print("[-] show some most similar numbers")
|
135 |
if ret["full"][0]['score'] <= 0.90:
|
136 |
-
print("[!] error in image
|
137 |
-
|
|
|
138 |
gen_filepath = file_path + 'generated_image.png'
|
139 |
gen_label = ret['number']
|
140 |
-
ret_sims = get_sims(gen_filepath, gen_label, file_path, hunting_time_limit)
|
|
|
141 |
print("[+] done sims")
|
142 |
# get the file-Path
|
143 |
return (file_path + 'generated_image.png', ret_sims)
|
@@ -169,25 +216,29 @@ def generate_and_save_images(model):
|
|
169 |
def TextToImage(Prompt,inference_steps, model):
|
170 |
model_id = model
|
171 |
if 'GAN' in model_id:
|
172 |
-
print("
|
173 |
model = from_pretrained_keras(model)
|
174 |
image = generate_and_save_images(model)
|
|
|
175 |
else:
|
|
|
176 |
pipe = DiffusionPipeline.from_pretrained(model_id)
|
177 |
the_randomness = int(str(time.time())[-1])
|
178 |
print('seed', the_randomness)
|
179 |
image = pipe(generator= torch.manual_seed(the_randomness), num_inference_steps=inference_steps).images[0]
|
180 |
|
181 |
-
# pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
|
182 |
-
# pipe = pipe.to("cpu")
|
183 |
-
|
184 |
prompt = Prompt
|
185 |
print(prompt)
|
186 |
hunting_time_limit = None
|
187 |
if prompt.isnumeric():
|
188 |
hunting_time_limit = abs(int(prompt))
|
|
|
|
|
|
|
|
|
|
|
189 |
|
190 |
-
original_image, other_images = get_other(image, hunting_time_limit)
|
191 |
the_file = other_images[0]
|
192 |
the_rmse = other_images[1]
|
193 |
ai_gen = Image.open(open(original_image, 'rb'))
|
@@ -198,10 +249,10 @@ def TextToImage(Prompt,inference_steps, model):
|
|
198 |
return [ai_gen, another_one]
|
199 |
|
200 |
df = pd.DataFrame({
|
201 |
-
"Model" : ['MNIST-diffusion', 'MNIST-diffusion-oneImage', 'MNIST-GAN', 'MNIST-GAN-noDropout'],
|
202 |
-
"Class (Architecture)" : ['UNet2DModel', 'UNet2DModel', 'Sequential', 'Sequential'],
|
203 |
-
"Dataset Examples" : [60000, 1, 60000, 60000],
|
204 |
-
"Notes" : ['Similar architecture as Stable Diffusion, different training data', 'Toy model, purposed to store protected content', 'GANs are not as likely to store protected content', 'less dropout, more copying?']
|
205 |
})
|
206 |
|
207 |
# Applying style to highlight the maximum value in each row
|
@@ -219,7 +270,7 @@ with gr.Blocks() as app:
|
|
219 |
"<hr>"
|
220 |
"<h1><center>Do machine learing models store protected content?</center></h1>" +
|
221 |
"<p><center><span style='color: red;'>Enter a time to hunt for copies (seconds), select a model, and hit submit!</center></p>" +
|
222 |
-
"<p><center><strong>These image generation models will give you a 'bespoke' generation ❤ of an <a href='https://paperswithcode.com/dataset/mnist'>MNIST hand-drawn digit</a></p>
|
223 |
"<p><center>then the program will search in training data (for <i>n</i> seconds) to find similar images: <a href='https://medium.com/@mygreatlearning/rmse-what-does-it-mean-2d446c0b1d0e'>RMSE</a>, lower is more similar</p>" +
|
224 |
"<p><a href='https://nathanreitinger.umiacs.io'>@nathanReitinger</a></p>"
|
225 |
)
|
|
|
13 |
from huggingface_hub import from_pretrained_keras
|
14 |
from math import sqrt, ceil
|
15 |
import numpy as np
|
16 |
+
from transformers import pipeline
|
17 |
import pandas as pd
|
18 |
import gradio as gr
|
19 |
+
import base64
|
20 |
|
21 |
modelieo=[
|
22 |
'nathanReitinger/MNIST-diffusion',
|
23 |
'nathanReitinger/MNIST-diffusion-oneImage',
|
24 |
'nathanReitinger/MNIST-GAN',
|
25 |
+
'nathanReitinger/MNIST-GAN-noDropout',
|
26 |
+
'nathanReitinger/FASHION-diffusion-oneImage'
|
27 |
]
|
28 |
|
29 |
+
def get_sims(gen_filepath, gen_label, file_path, hunting_time_limit, data_type):
|
30 |
+
if data_type == 'mnist':
|
31 |
+
(train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data()
|
32 |
+
train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')
|
33 |
+
train_images = (train_images - 127.5) / 127.5 # Normalize the images to [-1, 1]
|
34 |
+
else:
|
35 |
+
(train_images, train_labels), (_, _) = tf.keras.datasets.fashion_mnist.load_data()
|
36 |
+
train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')
|
37 |
+
train_images = (train_images - 127.5) / 127.5 # Normalize the images to [-1, 1]
|
38 |
|
39 |
print("how long to hunt", hunting_time_limit)
|
40 |
if hunting_time_limit == None:
|
41 |
hunting_time_limit = 2
|
42 |
|
43 |
+
train_label_mapping = {
|
44 |
+
0: 'T - shirt / top',
|
45 |
+
1: 'Trouser',
|
46 |
+
2: 'Pullover',
|
47 |
+
3: 'Dress',
|
48 |
+
4: 'Coat',
|
49 |
+
5: 'Sandal',
|
50 |
+
6: 'Shirt',
|
51 |
+
7: 'Sneaker',
|
52 |
+
8: 'Bag',
|
53 |
+
9: 'Ankle boot'
|
54 |
+
}
|
55 |
+
|
56 |
lowest_score = 10000
|
57 |
lowest_image = None
|
58 |
lowest_image_path = ''
|
|
|
60 |
start = time.time()
|
61 |
|
62 |
for i in range(len(train_labels)):
|
63 |
+
if data_type == 'fashion':
|
64 |
+
label_option = train_label_mapping[train_labels[i]]
|
65 |
+
else:
|
66 |
+
label_option = train_labels[i]
|
67 |
+
# print(data_type, i, label_option, gen_label)
|
68 |
+
if label_option == gen_label:
|
69 |
+
|
70 |
+
print('match on types!')
|
71 |
|
72 |
###
|
73 |
# get a real image (of correct number)
|
|
|
111 |
return [lowest_image_path, lowest_score]
|
112 |
|
113 |
|
114 |
+
def digit_recognition(filename, data_type):
|
115 |
+
|
116 |
+
if data_type == 'mnist':
|
117 |
+
# API_URL = "https://api-inference.huggingface.co/models/farleyknight/mnist-digit-classification-2022-09-04"
|
118 |
+
# special_string = '-h-f-_-RT-U-J-E-M-Pb-GC-c-i-v-sji-bMsQmxuh-x-h-C-W-B-F-W-z-Gv-'
|
119 |
+
# is_escaped = special_string.replace("-", '')
|
120 |
+
# bear = "Bearer " + is_escaped
|
121 |
+
# headers = {"Authorization": bear}
|
122 |
+
# # get a prediction on what number this is
|
123 |
+
# def query(filename):
|
124 |
+
# with open(filename, "rb") as f:
|
125 |
+
# data = f.read()
|
126 |
+
# response = requests.post(API_URL, headers=headers, data=data)
|
127 |
+
# return response.json()
|
128 |
+
|
129 |
+
# # use latest model to generate a new image, return path
|
130 |
+
# ret = False
|
131 |
+
# output = None
|
132 |
+
# while ret == False:
|
133 |
+
# output = query(filename + 'generated_image.png')
|
134 |
+
# if 'error' in output:
|
135 |
+
# time.sleep(10)
|
136 |
+
# ret = False
|
137 |
+
# else:
|
138 |
+
# ret = True
|
139 |
+
|
140 |
+
# slower than inferenceAPI, but no tokens needed
|
141 |
+
pipe = pipeline("image-classification", model="farleyknight/mnist-digit-classification-2022-09-04")
|
142 |
+
output = pipe(filename + 'generated_image.png')
|
143 |
+
print(output)
|
144 |
+
this_label_for_this_image = int(output[0]['label'])
|
145 |
+
|
146 |
+
else:
|
147 |
+
|
148 |
+
|
149 |
+
pipe = pipeline("image-classification", model="nathanReitinger/FASHION-vision")
|
150 |
+
output = pipe(filename + 'generated_image.png')
|
151 |
+
this_label_for_this_image = output[0]['label']
|
152 |
+
print(output)
|
153 |
+
print(this_label_for_this_image)
|
154 |
+
|
155 |
+
|
156 |
+
print(output, this_label_for_this_image)
|
157 |
|
|
|
|
|
158 |
return {'full': output, 'number': this_label_for_this_image}
|
159 |
|
160 |
|
161 |
+
def get_other(original_image, hunting_time_limit, data_type):
|
162 |
RANDO = str(time.time())
|
163 |
file_path = 'tester/' + 'generation' + "/" + RANDO + '/'
|
164 |
os.makedirs(file_path)
|
|
|
170 |
plt.close()
|
171 |
print('[+] done saving generation')
|
172 |
print("[-] what digit is this")
|
173 |
+
print(data_type)
|
174 |
+
# sys.exit()
|
175 |
+
ret = digit_recognition(file_path, data_type)
|
176 |
print(ret['full'])
|
177 |
print(ret['number'])
|
178 |
print("[+]", ret['number'])
|
179 |
print("[-] show some most similar numbers")
|
180 |
if ret["full"][0]['score'] <= 0.90:
|
181 |
+
print("[!] error in image recognition, likely to not find a similar score")
|
182 |
+
return (file_path + 'generated_image.png', ['error.png', -1])
|
183 |
+
# sys.exit()
|
184 |
gen_filepath = file_path + 'generated_image.png'
|
185 |
gen_label = ret['number']
|
186 |
+
ret_sims = get_sims(gen_filepath, gen_label, file_path, hunting_time_limit, data_type)
|
187 |
+
print(ret_sims)
|
188 |
print("[+] done sims")
|
189 |
# get the file-Path
|
190 |
return (file_path + 'generated_image.png', ret_sims)
|
|
|
216 |
def TextToImage(Prompt,inference_steps, model):
|
217 |
model_id = model
|
218 |
if 'GAN' in model_id:
|
219 |
+
print("--> GAN <--")
|
220 |
model = from_pretrained_keras(model)
|
221 |
image = generate_and_save_images(model)
|
222 |
+
|
223 |
else:
|
224 |
+
print("--> DIFFUSION <--")
|
225 |
pipe = DiffusionPipeline.from_pretrained(model_id)
|
226 |
the_randomness = int(str(time.time())[-1])
|
227 |
print('seed', the_randomness)
|
228 |
image = pipe(generator= torch.manual_seed(the_randomness), num_inference_steps=inference_steps).images[0]
|
229 |
|
|
|
|
|
|
|
230 |
prompt = Prompt
|
231 |
print(prompt)
|
232 |
hunting_time_limit = None
|
233 |
if prompt.isnumeric():
|
234 |
hunting_time_limit = abs(int(prompt))
|
235 |
+
|
236 |
+
if 'FASHION' in model_id:
|
237 |
+
data_type = 'fashion'
|
238 |
+
if 'MNIST' in model_id:
|
239 |
+
data_type = 'mnist'
|
240 |
|
241 |
+
original_image, other_images = get_other(image, hunting_time_limit, data_type=data_type)
|
242 |
the_file = other_images[0]
|
243 |
the_rmse = other_images[1]
|
244 |
ai_gen = Image.open(open(original_image, 'rb'))
|
|
|
249 |
return [ai_gen, another_one]
|
250 |
|
251 |
df = pd.DataFrame({
|
252 |
+
"Model" : ['MNIST-diffusion', 'MNIST-diffusion-oneImage', 'MNIST-GAN', 'MNIST-GAN-noDropout', 'FASHION-diffuion-oneImage'],
|
253 |
+
"Class (Architecture)" : ['UNet2DModel', 'UNet2DModel', 'Sequential', 'Sequential', 'UNet2DModel'],
|
254 |
+
"Dataset Examples" : [60000, 1, 60000, 60000, 1],
|
255 |
+
"Notes" : ['Similar architecture as Stable Diffusion, different training data', 'Toy model, purposed to store protected content', 'GANs are not as likely to store protected content', 'less dropout, more copying?', 'same diffusion, different data (more variance in data)']
|
256 |
})
|
257 |
|
258 |
# Applying style to highlight the maximum value in each row
|
|
|
270 |
"<hr>"
|
271 |
"<h1><center>Do machine learing models store protected content?</center></h1>" +
|
272 |
"<p><center><span style='color: red;'>Enter a time to hunt for copies (seconds), select a model, and hit submit!</center></p>" +
|
273 |
+
"<p><center><strong>These image generation models will give you a 'bespoke' generation ❤ of an <a href='https://paperswithcode.com/dataset/mnist'>MNIST hand-drawn digit</a> or the <a href='https://www.tensorflow.org/datasets/catalog/fashion_mnist'>fashion dataset</a></p> " +
|
274 |
"<p><center>then the program will search in training data (for <i>n</i> seconds) to find similar images: <a href='https://medium.com/@mygreatlearning/rmse-what-does-it-mean-2d446c0b1d0e'>RMSE</a>, lower is more similar</p>" +
|
275 |
"<p><a href='https://nathanreitinger.umiacs.io'>@nathanReitinger</a></p>"
|
276 |
)
|
error.png
ADDED
![]() |
tester/generation/1714572460.3130271/generated_image.png
ADDED
![]() |
tester/generation/1714572509.416096/generated_image.png
ADDED
![]() |
tester/generation/1714572566.812253/generated_image.png
ADDED
![]() |
tester/generation/1714572647.7270982/generated_image.png
ADDED
![]() |
tester/generation/1714572710.317538/generated_image.png
ADDED
![]() |
tester/generation/1714572806.7208629/generated_image.png
ADDED
![]() |
tester/generation/1714572814.196703/generated_image.png
ADDED
![]() |
tester/generation/1714573171.4095411/generated_image.png
ADDED
![]() |
tester/generation/1714573180.905479/generated_image.png
ADDED
![]() |
tester/generation/1714573283.9210691/generated_image.png
ADDED
![]() |
tester/generation/1714573371.120304/generated_image.png
ADDED
![]() |
tester/generation/1714573470.715162/generated_image.png
ADDED
![]() |
tester/generation/1714573663.655377/generated_image.png
ADDED
![]() |
tester/generation/1714573777.020148/generated_image.png
ADDED
![]() |
tester/generation/1714573785.923063/generated_image.png
ADDED
![]() |
tester/generation/1714573935.654328/generated_image.png
ADDED
![]() |
tester/generation/1714573935.654328/keeper.png
ADDED
![]() |
tester/generation/1714573935.654328/real_deal.png
ADDED
![]() |
tester/generation/1714573949.9718158/generated_image.png
ADDED
![]() |
tester/generation/1714573949.9718158/keeper.png
ADDED
![]() |
tester/generation/1714573949.9718158/real_deal.png
ADDED
![]() |
tester/generation/1714573959.174764/generated_image.png
ADDED
![]() |
tester/generation/1714573959.174764/keeper.png
ADDED
![]() |
tester/generation/1714573959.174764/real_deal.png
ADDED
![]() |
tester/generation/1714573968.372562/generated_image.png
ADDED
![]() |
tester/generation/1714573968.372562/keeper.png
ADDED
![]() |
tester/generation/1714573968.372562/real_deal.png
ADDED
![]() |
tester/generation/1714573976.232955/generated_image.png
ADDED
![]() |
tester/generation/1714573976.232955/keeper.png
ADDED
![]() |
tester/generation/1714573976.232955/real_deal.png
ADDED
![]() |
tester/generation/1714573985.865299/generated_image.png
ADDED
![]() |
tester/generation/1714573985.865299/keeper.png
ADDED
![]() |
tester/generation/1714573985.865299/real_deal.png
ADDED
![]() |
tester/generation/1714573993.039063/generated_image.png
ADDED
![]() |
tester/generation/1714573993.039063/keeper.png
ADDED
![]() |
tester/generation/1714573993.039063/real_deal.png
ADDED
![]() |
tester/generation/1714573998.791243/generated_image.png
ADDED
![]() |
tester/generation/1714573998.791243/keeper.png
ADDED
![]() |
tester/generation/1714573998.791243/real_deal.png
ADDED
![]() |
tester/generation/1714574004.814992/generated_image.png
ADDED
![]() |
tester/generation/1714574004.814992/keeper.png
ADDED
![]() |
tester/generation/1714574004.814992/real_deal.png
ADDED
![]() |
tester/generation/1714574008.685722/generated_image.png
ADDED
![]() |
tester/generation/1714574008.685722/keeper.png
ADDED
![]() |
tester/generation/1714574008.685722/real_deal.png
ADDED
![]() |
tester/generation/1714574012.8655639/generated_image.png
ADDED
![]() |
tester/generation/1714574012.8655639/keeper.png
ADDED
![]() |