zseid
commited on
Commit
•
f832251
1
Parent(s):
50eb0da
remove old code, set inference steps
Browse files
app.py
CHANGED
@@ -27,89 +27,14 @@ STABLE_MODELS = ["Stable Diffusion v1.5", "Midjourney"]
|
|
27 |
results = dict()
|
28 |
results[STABLE_MODELS[0]] = process_analysis(os.path.join(EVAL_DATA_DIRECTORY,'raw',"stable_diffusion_raw_processed.csv"))
|
29 |
results[STABLE_MODELS[1]] = process_analysis(os.path.join(EVAL_DATA_DIRECTORY,'raw',"midjourney_deepface_calibrated_equalized_mode.csv"))
|
30 |
-
|
31 |
scheduler = PNDMScheduler.from_pretrained("runwayml/stable-diffusion-v1-5", subfolder="scheduler", prediction_type="v_prediction")
|
32 |
pipe = DiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", scheduler=scheduler)
|
33 |
pipe = pipe.to(device)
|
34 |
|
35 |
-
tokenizer = pipe.tokenizer
|
36 |
-
text_encoder = pipe.text_encoder
|
37 |
-
|
38 |
-
#
|
39 |
-
# AUTHORS NOTE:
|
40 |
-
# Being absolutely explicit: the genders and ethnicities listed here
|
41 |
-
# are reductive. This is done not to erase but make analysis here
|
42 |
-
# simpler, tractable and easier to understand
|
43 |
-
#
|
44 |
-
GENDERS = ["male", "female"]
|
45 |
-
ETHNICITIES = ["black", "white", "asian"]
|
46 |
LOOKS = sorted(list(generate_traits()['tag']))#["beautiful", "stunning", "handsome", "ugly", "plain", "repulsive", "arrogant", "trustworthy"]
|
47 |
JOBS = sorted(list(generate_occupations()['tag']))#["CEO", "doctor", "nurse", "cashier", "janitor", "engineer", "pilot", "dentist", "leader"]
|
48 |
-
RENDERPREFIX = "a high quality photo of a"
|
49 |
-
|
50 |
-
def echoToken(token):
|
51 |
-
res = getMostSimilar(tokenizer, text_encoder, token)
|
52 |
-
return ",".join(res)
|
53 |
-
|
54 |
-
def getEmbeddingForToken(tokenizer, token):
|
55 |
-
token_ids = tokenizer.encode(token)[1:-1]
|
56 |
-
if len(token_ids) != 1:
|
57 |
-
print(len(token_ids))
|
58 |
-
raise
|
59 |
-
token_id = token_ids[0]
|
60 |
-
return token_id, text_encoder.get_input_embeddings().weight.data[token_id].unsqueeze(0)
|
61 |
-
|
62 |
-
def getMostSimilar(tokenizer, text_encoder, token, numResults=50):
|
63 |
-
internal_embs = text_encoder.text_model.embeddings.token_embedding.weight
|
64 |
-
tID, tok = getEmbeddingForToken(tokenizer, token)
|
65 |
-
|
66 |
-
cos = torch.nn.CosineSimilarity(dim=1, eps=1e-6)
|
67 |
-
scores = cos(internal_embs.to("cpu").to(torch.float32), tok.to("cpu").to(torch.float32))
|
68 |
-
sorted_scores, sorted_ids = torch.sort(scores, descending=True)
|
69 |
-
best_ids = sorted_ids[0:numResults].detach().numpy()
|
70 |
-
best_scores = sorted_scores[0:numResults].detach().numpy()
|
71 |
-
|
72 |
-
res = []
|
73 |
-
for best_id, best_score in zip(best_ids, best_scores):
|
74 |
-
#res.append((tokenizer.decode(best_id), best_score))
|
75 |
-
res.append("[" + tokenizer.decode(best_id) + "," + str(best_score) + "]")
|
76 |
-
return res[1:]
|
77 |
-
|
78 |
-
def computeTermSimilarity(tokenizer, text_encoder, termA, termB):
|
79 |
-
inputs = tokenizer([termA, termB], padding=True, return_tensors="pt").to("cpu")
|
80 |
-
outputs = text_encoder(**inputs)
|
81 |
-
cos = torch.nn.CosineSimilarity(dim=-1, eps=1e-6)
|
82 |
-
val = cos(outputs.pooler_output[0], outputs.pooler_output[1]).item()
|
83 |
-
return float(val)
|
84 |
|
85 |
-
def computeJob(tokenizer, text_encoder, job):
|
86 |
-
res = {}
|
87 |
-
neutralPrompt = " ".join([RENDERPREFIX, job])
|
88 |
-
titleText = neutralPrompt
|
89 |
-
for gender in GENDERS:
|
90 |
-
for ethnicity in ETHNICITIES:
|
91 |
-
prompt = " ".join([RENDERPREFIX, ethnicity, gender, job])
|
92 |
-
val = computeTermSimilarity(tokenizer, text_encoder, prompt, neutralPrompt)
|
93 |
-
res[prompt] = val
|
94 |
-
|
95 |
-
return titleText, sorted(res.items(), reverse=True)
|
96 |
-
|
97 |
-
def computeLook(tokenizer, text_encoder, look):
|
98 |
-
res = {}
|
99 |
-
titleText = " ".join([RENDERPREFIX,
|
100 |
-
look,
|
101 |
-
"[",
|
102 |
-
"|".join(GENDERS),
|
103 |
-
"]"])
|
104 |
-
|
105 |
-
for gender in GENDERS:
|
106 |
-
neutralPromptGender = " ".join([RENDERPREFIX, look, gender])
|
107 |
-
for ethnicity in ETHNICITIES:
|
108 |
-
prompt = " ".join([RENDERPREFIX, look, ethnicity, gender])
|
109 |
-
val = computeTermSimilarity(tokenizer, text_encoder, prompt, neutralPromptGender)
|
110 |
-
res[prompt] = val
|
111 |
-
|
112 |
-
return titleText, sorted(res.items(), reverse=True)
|
113 |
|
114 |
# via https://stackoverflow.com/questions/57316491/how-to-convert-matplotlib-figure-to-pil-image-object-without-saving-image
|
115 |
def fig2img(fig):
|
@@ -120,40 +45,6 @@ def fig2img(fig):
|
|
120 |
img = Image.open(buf)
|
121 |
return img
|
122 |
|
123 |
-
def computePlot(title, results, scaleXAxis=True):
|
124 |
-
x = list(map(lambda x:x[0], results))
|
125 |
-
y = list(map(lambda x:x[1], results))
|
126 |
-
|
127 |
-
fig, ax = plt.subplots(1, 1, figsize=(10, 5))
|
128 |
-
y_pos = np.arange(len(x))
|
129 |
-
|
130 |
-
hbars = ax.barh(y_pos, y, left=0, align='center')
|
131 |
-
ax.set_yticks(y_pos, labels=x)
|
132 |
-
ax.invert_yaxis() # labels read top-to-bottom
|
133 |
-
ax.set_xlabel('Cosine similarity - take care to note compressed X-axis')
|
134 |
-
ax.set_title('Similarity to "' + title + '"')
|
135 |
-
|
136 |
-
# Label with specially formatted floats
|
137 |
-
ax.bar_label(hbars, fmt='%.3f')
|
138 |
-
minR = np.min(y)
|
139 |
-
maxR = np.max(y)
|
140 |
-
diffR = maxR-minR
|
141 |
-
|
142 |
-
if scaleXAxis:
|
143 |
-
ax.set_xlim(left=minR-0.1*diffR, right=maxR+0.1*diffR)
|
144 |
-
else:
|
145 |
-
ax.set_xlim(left=0.0, right=1.0)
|
146 |
-
plt.tight_layout()
|
147 |
-
plt.close()
|
148 |
-
return fig2img(fig)
|
149 |
-
|
150 |
-
def computeJobBias(job):
|
151 |
-
title, results = computeJob(tokenizer, text_encoder, job)
|
152 |
-
return computePlot(title, results)
|
153 |
-
|
154 |
-
def computeLookBias(look):
|
155 |
-
title, results = computeLook(tokenizer, text_encoder, look)
|
156 |
-
return computePlot(title, results)
|
157 |
def trait_graph(model,hist=True):
|
158 |
tda_res,occ_res = results[model]
|
159 |
pass_gen = evaluate_gender_by_adjectives(tda_res)
|
@@ -209,7 +100,7 @@ def adj_example(adj):
|
|
209 |
prompt = f"a {adj} person photorealistic"
|
210 |
return example_analysis(prompt)
|
211 |
def example_analysis(prompt):
|
212 |
-
pil_img = pipe(prompt).images[0]
|
213 |
# pil_img = Image.open('./this-is-fine.0.jpg')
|
214 |
df = process_image_pil(pil_img,prompt)
|
215 |
rgb_tup = (128,128,128)
|
@@ -251,7 +142,7 @@ def cached_results(model):
|
|
251 |
|
252 |
if __name__=='__main__':
|
253 |
disclaimerString = ""
|
254 |
-
example_analysis("a abrupt person")
|
255 |
with gr.Blocks() as demo:
|
256 |
gr.Markdown("# Facial Adjectival Color and Income Auditor")
|
257 |
gr.Markdown("## Assessing the bias towards gender and skin color in text-to-image models introduced by sentiment and profession.")
|
|
|
27 |
results = dict()
|
28 |
results[STABLE_MODELS[0]] = process_analysis(os.path.join(EVAL_DATA_DIRECTORY,'raw',"stable_diffusion_raw_processed.csv"))
|
29 |
results[STABLE_MODELS[1]] = process_analysis(os.path.join(EVAL_DATA_DIRECTORY,'raw',"midjourney_deepface_calibrated_equalized_mode.csv"))
|
30 |
+
|
31 |
scheduler = PNDMScheduler.from_pretrained("runwayml/stable-diffusion-v1-5", subfolder="scheduler", prediction_type="v_prediction")
|
32 |
pipe = DiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", scheduler=scheduler)
|
33 |
pipe = pipe.to(device)
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
LOOKS = sorted(list(generate_traits()['tag']))#["beautiful", "stunning", "handsome", "ugly", "plain", "repulsive", "arrogant", "trustworthy"]
|
36 |
JOBS = sorted(list(generate_occupations()['tag']))#["CEO", "doctor", "nurse", "cashier", "janitor", "engineer", "pilot", "dentist", "leader"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
# via https://stackoverflow.com/questions/57316491/how-to-convert-matplotlib-figure-to-pil-image-object-without-saving-image
|
40 |
def fig2img(fig):
|
|
|
45 |
img = Image.open(buf)
|
46 |
return img
|
47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
def trait_graph(model,hist=True):
|
49 |
tda_res,occ_res = results[model]
|
50 |
pass_gen = evaluate_gender_by_adjectives(tda_res)
|
|
|
100 |
prompt = f"a {adj} person photorealistic"
|
101 |
return example_analysis(prompt)
|
102 |
def example_analysis(prompt):
|
103 |
+
pil_img = pipe(prompt,num_inference_steps=29).images[0]
|
104 |
# pil_img = Image.open('./this-is-fine.0.jpg')
|
105 |
df = process_image_pil(pil_img,prompt)
|
106 |
rgb_tup = (128,128,128)
|
|
|
142 |
|
143 |
if __name__=='__main__':
|
144 |
disclaimerString = ""
|
145 |
+
# example_analysis("a abrupt person")
|
146 |
with gr.Blocks() as demo:
|
147 |
gr.Markdown("# Facial Adjectival Color and Income Auditor")
|
148 |
gr.Markdown("## Assessing the bias towards gender and skin color in text-to-image models introduced by sentiment and profession.")
|