Spaces:
Runtime error
Runtime error
clean up
Browse files
Home.py
CHANGED
|
@@ -6,24 +6,28 @@ st.set_page_config(layout='wide')
|
|
| 6 |
|
| 7 |
st.title('About')
|
| 8 |
|
|
|
|
| 9 |
# INTRO
|
| 10 |
-
intro_text = """
|
|
|
|
| 11 |
The thesis concentrates mostly on the second part, exploring different avenues for understanding the space. Using a multitude of vision generative models, it discusses possibilities for the systematic exploration of space, including disentanglement properties and coverage of various guidance methods.
|
| 12 |
It also explores the possibility of comparison across latent spaces and investigates the differences and commonalities across different learning experiments. Furthermore, the thesis investigates the role of stochasticity in newer models.
|
| 13 |
As a case study, this thesis adopts art historical data, spanning classic art, photography, and modern and contemporary art.
|
| 14 |
-
|
| 15 |
-
The project aims to interpret the StyleGAN2 model by several techniques.
|
| 16 |
-
> “What concepts are disentangled in the latent space of StyleGAN2”\n
|
| 17 |
-
> “Can we quantify the complexity of such concepts?”.
|
| 18 |
-
|
| 19 |
"""
|
| 20 |
st.write(intro_text)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
# 4 PAGES
|
| 23 |
st.subheader('Pages')
|
| 24 |
-
sections_text = """Overall, there are
|
| 25 |
-
1)
|
| 26 |
-
2)
|
|
|
|
| 27 |
...
|
| 28 |
"""
|
| 29 |
st.write(sections_text)
|
|
|
|
| 6 |
|
| 7 |
st.title('About')
|
| 8 |
|
| 9 |
+
st.subheader('General aim of the Ph.D. (to be updated)')
|
| 10 |
# INTRO
|
| 11 |
+
intro_text = """
|
| 12 |
+
This project investigates the nature and nurture of latent spaces, with the aim of formulating a theory of this particular vectorial space. It draws together reflections on the inherent constraints of latent spaces in particular architectures and considers the learning-specific features that emerge.
|
| 13 |
The thesis concentrates mostly on the second part, exploring different avenues for understanding the space. Using a multitude of vision generative models, it discusses possibilities for the systematic exploration of space, including disentanglement properties and coverage of various guidance methods.
|
| 14 |
It also explores the possibility of comparison across latent spaces and investigates the differences and commonalities across different learning experiments. Furthermore, the thesis investigates the role of stochasticity in newer models.
|
| 15 |
As a case study, this thesis adopts art historical data, spanning classic art, photography, and modern and contemporary art.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
"""
|
| 17 |
st.write(intro_text)
|
| 18 |
+
st.subheader('On this experiment')
|
| 19 |
+
st.write(
|
| 20 |
+
"""The project aims to interpret the StyleGAN3 model trained on Textiles using disentanglement methods.
|
| 21 |
+
> “What features are disentangled in the latent space of StyleGAN3”\n
|
| 22 |
+
> “Can we quantify the complexity, quality and relations of such features?”.
|
| 23 |
+
""")
|
| 24 |
|
| 25 |
# 4 PAGES
|
| 26 |
st.subheader('Pages')
|
| 27 |
+
sections_text = """Overall, there are 3 features in this web app:
|
| 28 |
+
1) Textiles manipulation
|
| 29 |
+
2) Features comparison
|
| 30 |
+
3) Vectors algebra manipulation
|
| 31 |
...
|
| 32 |
"""
|
| 33 |
st.write(sections_text)
|
pages/{1_Textiles_Disentanglement.py → 1_Textiles_Manipulation.py}
RENAMED
|
@@ -20,10 +20,14 @@ BACKGROUND_COLOR = '#bcd0e7'
|
|
| 20 |
SECONDARY_COLOR = '#bce7db'
|
| 21 |
|
| 22 |
|
| 23 |
-
st.title('Disentanglement
|
| 24 |
st.markdown(
|
| 25 |
"""
|
| 26 |
-
This is a demo of the Disentanglement
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
""",
|
| 28 |
unsafe_allow_html=False,)
|
| 29 |
|
|
@@ -73,9 +77,6 @@ if 'num_factors' not in st.session_state:
|
|
| 73 |
if 'best' not in st.session_state:
|
| 74 |
st.session_state.best = True
|
| 75 |
|
| 76 |
-
# def on_change_random_input():
|
| 77 |
-
# st.session_state.image_id = st.session_state.image_id
|
| 78 |
-
|
| 79 |
# ----------------------------- INPUT ----------------------------------
|
| 80 |
st.header('Input')
|
| 81 |
input_col_1, input_col_2, input_col_3, input_col_4 = st.columns(4)
|
|
@@ -83,8 +84,7 @@ input_col_1, input_col_2, input_col_3, input_col_4 = st.columns(4)
|
|
| 83 |
with input_col_1:
|
| 84 |
with st.form('image_form'):
|
| 85 |
|
| 86 |
-
|
| 87 |
-
st.write('**Choose or generate a random image to test the disentanglement**')
|
| 88 |
chosen_image_id_input = st.empty()
|
| 89 |
image_id = chosen_image_id_input.number_input('Image ID:', format='%d', step=1, value=st.session_state.image_id)
|
| 90 |
|
|
@@ -103,16 +103,15 @@ with input_col_1:
|
|
| 103 |
with input_col_2:
|
| 104 |
with st.form('text_form_1'):
|
| 105 |
|
| 106 |
-
st.write('**Choose
|
| 107 |
-
type_col = st.selectbox('
|
| 108 |
-
colors_button = st.form_submit_button('Choose the defined color')
|
| 109 |
|
| 110 |
st.write('**Set range of change**')
|
| 111 |
chosen_color_lambda_input = st.empty()
|
| 112 |
color_lambda = chosen_color_lambda_input.number_input('Lambda:', min_value=-100, step=1, value=7)
|
| 113 |
-
color_lambda_button = st.form_submit_button('Choose the defined
|
| 114 |
|
| 115 |
-
if
|
| 116 |
st.session_state.image_id = image_id
|
| 117 |
st.session_state.concept_ids = type_col
|
| 118 |
st.session_state.color_lambda = color_lambda
|
|
@@ -121,23 +120,22 @@ with input_col_2:
|
|
| 121 |
with input_col_3:
|
| 122 |
with st.form('text_form'):
|
| 123 |
|
| 124 |
-
st.write('**
|
| 125 |
chosen_saturation_lambda_input = st.empty()
|
| 126 |
saturation_lambda = chosen_saturation_lambda_input.number_input('Lambda:', min_value=-100, step=1, key=0, value=0)
|
| 127 |
-
saturation_lambda_button = st.form_submit_button('Choose the defined lambda for saturation')
|
| 128 |
|
| 129 |
-
st.write('**
|
| 130 |
chosen_value_lambda_input = st.empty()
|
| 131 |
value_lambda = chosen_value_lambda_input.number_input('Lambda:', min_value=-100, step=1, key=1, value=0)
|
| 132 |
-
value_lambda_button = st.form_submit_button('Choose the defined lambda for
|
| 133 |
|
| 134 |
-
if
|
| 135 |
st.session_state.saturation_lambda = int(saturation_lambda)
|
| 136 |
st.session_state.value_lambda = int(value_lambda)
|
| 137 |
|
| 138 |
with input_col_4:
|
| 139 |
with st.form('text_form_2'):
|
| 140 |
-
st.write('Use best
|
| 141 |
best = st.selectbox('Option:', tuple([True, False]), index=0)
|
| 142 |
sign = True
|
| 143 |
num_factors=10
|
|
@@ -155,10 +153,6 @@ with input_col_4:
|
|
| 155 |
extremes = st.selectbox('Extremes option:', tuple([True, False]), index=1)
|
| 156 |
|
| 157 |
choose_options_button = st.form_submit_button('Choose the defined options')
|
| 158 |
-
# st.write('**Choose a latent space to disentangle**')
|
| 159 |
-
# # chosen_text_id_input = st.empty()
|
| 160 |
-
# # concept_id = chosen_text_id_input.text_input('Concept:', value=st.session_state.concept_id)
|
| 161 |
-
# space_id = st.selectbox('Space:', tuple(['Z', 'W']))
|
| 162 |
if choose_options_button:
|
| 163 |
st.session_state.best = best
|
| 164 |
if st.session_state.best is False:
|
|
@@ -186,7 +180,7 @@ with input_col_4:
|
|
| 186 |
# ---------------------------- SET UP OUTPUT ------------------------------
|
| 187 |
epsilon_container = st.empty()
|
| 188 |
st.header('Image Manipulation')
|
| 189 |
-
st.
|
| 190 |
|
| 191 |
header_col_1, header_col_2 = st.columns([1,1])
|
| 192 |
output_col_1, output_col_2 = st.columns([1,1])
|
|
@@ -201,7 +195,7 @@ output_col_1, output_col_2 = st.columns([1,1])
|
|
| 201 |
|
| 202 |
# ---------------------------- DISPLAY COL 1 ROW 1 ------------------------------
|
| 203 |
with header_col_1:
|
| 204 |
-
st.write(f'Original image')
|
| 205 |
|
| 206 |
with header_col_2:
|
| 207 |
if st.session_state.best:
|
|
@@ -217,8 +211,15 @@ with header_col_2:
|
|
| 217 |
tmp_sat = concept_vectors[concept_vectors['color'] == 'Saturation'][concept_vectors['extremes'] == st.session_state.extremes]
|
| 218 |
saturation_separation_vector, performance_saturation = tmp_sat.reset_index().loc[0, ['vector', 'score']]
|
| 219 |
|
| 220 |
-
st.write(
|
| 221 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
# ---------------------------- DISPLAY COL 2 ROW 1 ------------------------------
|
| 223 |
|
| 224 |
if st.session_state.space_id == 'Z':
|
|
@@ -234,3 +235,4 @@ with output_col_1:
|
|
| 234 |
with output_col_2:
|
| 235 |
image_updated = generate_composite_images(model, original_image_vec, [color_separation_vector, saturation_separation_vector, value_separation_vector], lambdas=[st.session_state.color_lambda, st.session_state.saturation_lambda, st.session_state.value_lambda])
|
| 236 |
st.image(image_updated)
|
|
|
|
|
|
| 20 |
SECONDARY_COLOR = '#bce7db'
|
| 21 |
|
| 22 |
|
| 23 |
+
st.title('Disentanglement on Textile Datasets')
|
| 24 |
st.markdown(
|
| 25 |
"""
|
| 26 |
+
This is a demo of the Disentanglement experiment on the [iMET Textiles Dataset](https://www.metmuseum.org/art/collection/search/85531).
|
| 27 |
+
|
| 28 |
+
In this page, the user can adjust the colors of textile images generated by an AI by simply traversing the latent space of the AI.
|
| 29 |
+
The colors can be adjusted following the human-intuitive encoding of HSV, adjusting the main Hue of the image with an option of 7 colors + Gray,
|
| 30 |
+
the saturation (the amount of Gray) and the value of the image (the amount of Black).
|
| 31 |
""",
|
| 32 |
unsafe_allow_html=False,)
|
| 33 |
|
|
|
|
| 77 |
if 'best' not in st.session_state:
|
| 78 |
st.session_state.best = True
|
| 79 |
|
|
|
|
|
|
|
|
|
|
| 80 |
# ----------------------------- INPUT ----------------------------------
|
| 81 |
st.header('Input')
|
| 82 |
input_col_1, input_col_2, input_col_3, input_col_4 = st.columns(4)
|
|
|
|
| 84 |
with input_col_1:
|
| 85 |
with st.form('image_form'):
|
| 86 |
|
| 87 |
+
st.write('**Choose or generate a random base image**')
|
|
|
|
| 88 |
chosen_image_id_input = st.empty()
|
| 89 |
image_id = chosen_image_id_input.number_input('Image ID:', format='%d', step=1, value=st.session_state.image_id)
|
| 90 |
|
|
|
|
| 103 |
with input_col_2:
|
| 104 |
with st.form('text_form_1'):
|
| 105 |
|
| 106 |
+
st.write('**Choose hue to vary**')
|
| 107 |
+
type_col = st.selectbox('Hue:', tuple(COLORS_LIST), index=7)
|
|
|
|
| 108 |
|
| 109 |
st.write('**Set range of change**')
|
| 110 |
chosen_color_lambda_input = st.empty()
|
| 111 |
color_lambda = chosen_color_lambda_input.number_input('Lambda:', min_value=-100, step=1, value=7)
|
| 112 |
+
color_lambda_button = st.form_submit_button('Choose the defined hue and lambda')
|
| 113 |
|
| 114 |
+
if color_lambda_button:
|
| 115 |
st.session_state.image_id = image_id
|
| 116 |
st.session_state.concept_ids = type_col
|
| 117 |
st.session_state.color_lambda = color_lambda
|
|
|
|
| 120 |
with input_col_3:
|
| 121 |
with st.form('text_form'):
|
| 122 |
|
| 123 |
+
st.write('**Choose saturation variation**')
|
| 124 |
chosen_saturation_lambda_input = st.empty()
|
| 125 |
saturation_lambda = chosen_saturation_lambda_input.number_input('Lambda:', min_value=-100, step=1, key=0, value=0)
|
|
|
|
| 126 |
|
| 127 |
+
st.write('**Choose value variation**')
|
| 128 |
chosen_value_lambda_input = st.empty()
|
| 129 |
value_lambda = chosen_value_lambda_input.number_input('Lambda:', min_value=-100, step=1, key=1, value=0)
|
| 130 |
+
value_lambda_button = st.form_submit_button('Choose the defined lambda for value and saturation')
|
| 131 |
|
| 132 |
+
if value_lambda_button:
|
| 133 |
st.session_state.saturation_lambda = int(saturation_lambda)
|
| 134 |
st.session_state.value_lambda = int(value_lambda)
|
| 135 |
|
| 136 |
with input_col_4:
|
| 137 |
with st.form('text_form_2'):
|
| 138 |
+
st.write('Use the best vectors (after hyperparameter tuning)')
|
| 139 |
best = st.selectbox('Option:', tuple([True, False]), index=0)
|
| 140 |
sign = True
|
| 141 |
num_factors=10
|
|
|
|
| 153 |
extremes = st.selectbox('Extremes option:', tuple([True, False]), index=1)
|
| 154 |
|
| 155 |
choose_options_button = st.form_submit_button('Choose the defined options')
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
if choose_options_button:
|
| 157 |
st.session_state.best = best
|
| 158 |
if st.session_state.best is False:
|
|
|
|
| 180 |
# ---------------------------- SET UP OUTPUT ------------------------------
|
| 181 |
epsilon_container = st.empty()
|
| 182 |
st.header('Image Manipulation')
|
| 183 |
+
st.write('Using selected vectors to modify the original image...')
|
| 184 |
|
| 185 |
header_col_1, header_col_2 = st.columns([1,1])
|
| 186 |
output_col_1, output_col_2 = st.columns([1,1])
|
|
|
|
| 195 |
|
| 196 |
# ---------------------------- DISPLAY COL 1 ROW 1 ------------------------------
|
| 197 |
with header_col_1:
|
| 198 |
+
st.write(f'### Original image')
|
| 199 |
|
| 200 |
with header_col_2:
|
| 201 |
if st.session_state.best:
|
|
|
|
| 211 |
tmp_sat = concept_vectors[concept_vectors['color'] == 'Saturation'][concept_vectors['extremes'] == st.session_state.extremes]
|
| 212 |
saturation_separation_vector, performance_saturation = tmp_sat.reset_index().loc[0, ['vector', 'score']]
|
| 213 |
|
| 214 |
+
st.write('### Modified image')
|
| 215 |
+
st.write(f"""
|
| 216 |
+
Change in hue: {st.session_state.concept_ids} of amount: {np.round(st.session_state.color_lambda, 2)},
|
| 217 |
+
in: saturation of amount: {np.round(st.session_state.saturation_lambda, 2)},
|
| 218 |
+
in: value of amount: {np.round(st.session_state.value_lambda, 2)}.\
|
| 219 |
+
Verification performance of hue vector: {performance_color},
|
| 220 |
+
saturation vector: {performance_saturation/100},
|
| 221 |
+
value vector: {performance_value/100}""")
|
| 222 |
+
|
| 223 |
# ---------------------------- DISPLAY COL 2 ROW 1 ------------------------------
|
| 224 |
|
| 225 |
if st.session_state.space_id == 'Z':
|
|
|
|
| 235 |
with output_col_2:
|
| 236 |
image_updated = generate_composite_images(model, original_image_vec, [color_separation_vector, saturation_separation_vector, value_separation_vector], lambdas=[st.session_state.color_lambda, st.session_state.saturation_lambda, st.session_state.value_lambda])
|
| 237 |
st.image(image_updated)
|
| 238 |
+
|
pages/{2_Colours_comparison.py → 2_Network_comparison.py}
RENAMED
|
@@ -24,7 +24,11 @@ st.set_page_config(layout='wide')
|
|
| 24 |
|
| 25 |
st.title('Comparison among color directions')
|
| 26 |
st.write('> **How do the color directions relate to each other?**')
|
| 27 |
-
st.write(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
|
| 29 |
|
| 30 |
annotations_file = './data/textile_annotated_files/seeds0000-100000_S.pkl'
|
|
@@ -46,10 +50,8 @@ with dnnlib.util.open_url('./data/textile_model_files/network-snapshot-005000.pk
|
|
| 46 |
|
| 47 |
COLORS_LIST = ['Gray', 'Red Orange', 'Yellow', 'Green', 'Light Blue', 'Blue', 'Purple', 'Pink', 'Saturation', 'Value']
|
| 48 |
|
| 49 |
-
if 'image_id' not in st.session_state:
|
| 50 |
-
st.session_state.image_id = 0
|
| 51 |
if 'concept_ids' not in st.session_state:
|
| 52 |
-
st.session_state.concept_ids =
|
| 53 |
if 'sign' not in st.session_state:
|
| 54 |
st.session_state.sign = False
|
| 55 |
if 'extremes' not in st.session_state:
|
|
@@ -60,10 +62,8 @@ if 'cl_method' not in st.session_state:
|
|
| 60 |
st.session_state.cl_method = False
|
| 61 |
if 'num_factors' not in st.session_state:
|
| 62 |
st.session_state.num_factors = False
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
if 'space_id' not in st.session_state:
|
| 66 |
-
st.session_state.space_id = 'W'
|
| 67 |
|
| 68 |
# ----------------------------- INPUT ----------------------------------
|
| 69 |
st.header('Input')
|
|
@@ -76,7 +76,7 @@ with input_col_1:
|
|
| 76 |
st.write('**Choose a series of colors to compare**')
|
| 77 |
# chosen_text_id_input = st.empty()
|
| 78 |
# concept_id = chosen_text_id_input.text_input('Concept:', value=st.session_state.concept_id)
|
| 79 |
-
concept_ids = st.multiselect('Color (including Saturation and Value):', tuple(COLORS_LIST), default=
|
| 80 |
choose_text_button = st.form_submit_button('Choose the defined colors')
|
| 81 |
|
| 82 |
if choose_text_button:
|
|
@@ -85,27 +85,33 @@ with input_col_1:
|
|
| 85 |
|
| 86 |
with input_col_2:
|
| 87 |
with st.form('text_form_1'):
|
| 88 |
-
st.write('
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
cl_method
|
| 93 |
-
regularization
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
choose_options_button = st.form_submit_button('Choose the defined options')
|
| 98 |
-
# st.write('**Choose a latent space to disentangle**')
|
| 99 |
-
# # chosen_text_id_input = st.empty()
|
| 100 |
-
# # concept_id = chosen_text_id_input.text_input('Concept:', value=st.session_state.concept_id)
|
| 101 |
-
# space_id = st.selectbox('Space:', tuple(['Z', 'W']))
|
| 102 |
if choose_options_button:
|
| 103 |
-
st.session_state.
|
| 104 |
-
st.session_state.
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
|
|
|
|
|
|
| 109 |
# ---------------------------- SET UP OUTPUT ------------------------------
|
| 110 |
epsilon_container = st.empty()
|
| 111 |
st.header('Comparison')
|
|
@@ -115,23 +121,28 @@ header_col_1, header_col_2 = st.columns([3,1])
|
|
| 115 |
output_col_1, output_col_2 = st.columns([3,1])
|
| 116 |
|
| 117 |
# ---------------------------- DISPLAY COL 1 ROW 1 ------------------------------
|
| 118 |
-
|
| 119 |
-
tmp =
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
info = tmp.loc[:, ['vector', 'score', 'color', 'kwargs']].values
|
| 121 |
concept_ids = [i[2] for i in info] #+ ' ' + i[3]
|
| 122 |
|
| 123 |
with header_col_1:
|
| 124 |
-
st.write('Similarity graph')
|
| 125 |
|
| 126 |
with header_col_2:
|
| 127 |
-
st.write('Information')
|
| 128 |
|
| 129 |
with output_col_2:
|
| 130 |
for i,concept_id in enumerate(concept_ids):
|
| 131 |
-
st.write(f'Color {info[i][2]}
|
|
|
|
|
|
|
| 132 |
|
| 133 |
with output_col_1:
|
| 134 |
-
|
| 135 |
edges = []
|
| 136 |
for i in range(len(concept_ids)):
|
| 137 |
for j in range(len(concept_ids)):
|
|
|
|
| 24 |
|
| 25 |
st.title('Comparison among color directions')
|
| 26 |
st.write('> **How do the color directions relate to each other?**')
|
| 27 |
+
st.write("""
|
| 28 |
+
This page provides a simple network-based framework to inspect the vector similarity (cosine similarity) among the found color vectors.
|
| 29 |
+
The nodes are the colors chosen for comparison and the strength of the edge represents the similarity.
|
| 30 |
+
|
| 31 |
+
""")
|
| 32 |
|
| 33 |
|
| 34 |
annotations_file = './data/textile_annotated_files/seeds0000-100000_S.pkl'
|
|
|
|
| 50 |
|
| 51 |
COLORS_LIST = ['Gray', 'Red Orange', 'Yellow', 'Green', 'Light Blue', 'Blue', 'Purple', 'Pink', 'Saturation', 'Value']
|
| 52 |
|
|
|
|
|
|
|
| 53 |
if 'concept_ids' not in st.session_state:
|
| 54 |
+
st.session_state.concept_ids = COLORS_LIST
|
| 55 |
if 'sign' not in st.session_state:
|
| 56 |
st.session_state.sign = False
|
| 57 |
if 'extremes' not in st.session_state:
|
|
|
|
| 62 |
st.session_state.cl_method = False
|
| 63 |
if 'num_factors' not in st.session_state:
|
| 64 |
st.session_state.num_factors = False
|
| 65 |
+
if 'best' not in st.session_state:
|
| 66 |
+
st.session_state.best = True
|
|
|
|
|
|
|
| 67 |
|
| 68 |
# ----------------------------- INPUT ----------------------------------
|
| 69 |
st.header('Input')
|
|
|
|
| 76 |
st.write('**Choose a series of colors to compare**')
|
| 77 |
# chosen_text_id_input = st.empty()
|
| 78 |
# concept_id = chosen_text_id_input.text_input('Concept:', value=st.session_state.concept_id)
|
| 79 |
+
concept_ids = st.multiselect('Color (including Saturation and Value):', tuple(COLORS_LIST), default=COLORS_LIST)
|
| 80 |
choose_text_button = st.form_submit_button('Choose the defined colors')
|
| 81 |
|
| 82 |
if choose_text_button:
|
|
|
|
| 85 |
|
| 86 |
with input_col_2:
|
| 87 |
with st.form('text_form_1'):
|
| 88 |
+
st.write('Use the best vectors (after hyperparameter tuning)')
|
| 89 |
+
best = st.selectbox('Option:', tuple([True, False]), index=0)
|
| 90 |
+
sign = True
|
| 91 |
+
num_factors=10
|
| 92 |
+
cl_method='LR'
|
| 93 |
+
regularization=0.1
|
| 94 |
+
extremes=True
|
| 95 |
+
if st.session_state.best is False:
|
| 96 |
+
st.write('Options for StyleSpace (not available for Saturation and Value)')
|
| 97 |
+
sign = st.selectbox('Sign option:', tuple([True, False]), index=1)
|
| 98 |
+
num_factors = st.selectbox('Number of factors option:', tuple([1, 5, 10, 20, False]), index=4)
|
| 99 |
+
st.write('Options for InterFaceGAN (not available for Saturation and Value)')
|
| 100 |
+
cl_method = st.selectbox('Classification method option:', tuple(['LR', 'SVM', False]), index=2)
|
| 101 |
+
regularization = st.selectbox('Regularization option:', tuple([0.1, 1.0, False]), index=2)
|
| 102 |
+
st.write('Options for InterFaceGAN (only for Saturation and Value)')
|
| 103 |
+
extremes = st.selectbox('Extremes option:', tuple([True, False]), index=1)
|
| 104 |
+
|
| 105 |
choose_options_button = st.form_submit_button('Choose the defined options')
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
if choose_options_button:
|
| 107 |
+
st.session_state.best = best
|
| 108 |
+
if st.session_state.best is False:
|
| 109 |
+
st.session_state.sign = sign
|
| 110 |
+
st.session_state.num_factors = num_factors
|
| 111 |
+
st.session_state.cl_method = cl_method
|
| 112 |
+
st.session_state.regularization = regularization
|
| 113 |
+
st.session_state.extremes = extremes
|
| 114 |
+
|
| 115 |
# ---------------------------- SET UP OUTPUT ------------------------------
|
| 116 |
epsilon_container = st.empty()
|
| 117 |
st.header('Comparison')
|
|
|
|
| 121 |
output_col_1, output_col_2 = st.columns([3,1])
|
| 122 |
|
| 123 |
# ---------------------------- DISPLAY COL 1 ROW 1 ------------------------------
|
| 124 |
+
if st.session_state.best:
|
| 125 |
+
tmp = concept_vectors[concept_vectors['color'].isin(st.session_state.concept_ids)].groupby('color').first().reset_index()
|
| 126 |
+
else:
|
| 127 |
+
tmp = concept_vectors[concept_vectors['color'].isin(st.session_state.concept_ids)]
|
| 128 |
+
tmp = tmp[tmp['sign'] == st.session_state.sign][tmp['extremes'] == st.session_state.extremes][tmp['num_factors'] == st.session_state.num_factors][tmp['cl_method'] == st.session_state.cl_method][tmp['regularization'] == st.session_state.regularization]
|
| 129 |
+
|
| 130 |
info = tmp.loc[:, ['vector', 'score', 'color', 'kwargs']].values
|
| 131 |
concept_ids = [i[2] for i in info] #+ ' ' + i[3]
|
| 132 |
|
| 133 |
with header_col_1:
|
| 134 |
+
st.write('### Similarity graph')
|
| 135 |
|
| 136 |
with header_col_2:
|
| 137 |
+
st.write('### Information')
|
| 138 |
|
| 139 |
with output_col_2:
|
| 140 |
for i,concept_id in enumerate(concept_ids):
|
| 141 |
+
st.write(f'''Color: {info[i][2]}.\
|
| 142 |
+
Settings: {info[i][3]}\
|
| 143 |
+
''')
|
| 144 |
|
| 145 |
with output_col_1:
|
|
|
|
| 146 |
edges = []
|
| 147 |
for i in range(len(concept_ids)):
|
| 148 |
for j in range(len(concept_ids)):
|
pages/3_Vectors_algebra.py
CHANGED
|
@@ -20,10 +20,13 @@ BACKGROUND_COLOR = '#bcd0e7'
|
|
| 20 |
SECONDARY_COLOR = '#bce7db'
|
| 21 |
|
| 22 |
|
| 23 |
-
st.title('
|
| 24 |
st.markdown(
|
| 25 |
"""
|
| 26 |
-
This
|
|
|
|
|
|
|
|
|
|
| 27 |
""",
|
| 28 |
unsafe_allow_html=False,)
|
| 29 |
|
|
@@ -35,12 +38,6 @@ concept_vectors = pd.read_csv('./data/stored_vectors/scores_colors_hsv.csv')
|
|
| 35 |
concept_vectors['vector'] = [np.array([float(xx) for xx in x]) for x in concept_vectors['vector'].str.split(', ')]
|
| 36 |
concept_vectors['score'] = concept_vectors['score'].astype(float)
|
| 37 |
|
| 38 |
-
concept_vectors['sign'] = [True if 'sign:True' in val else False for val in concept_vectors['kwargs']]
|
| 39 |
-
concept_vectors['extremes'] = [True if 'extremes method:True' in val else False for val in concept_vectors['kwargs']]
|
| 40 |
-
concept_vectors['regularization'] = [float(val.split(',')[1].strip('regularization: ')) if 'regularization:' in val else False for val in concept_vectors['kwargs']]
|
| 41 |
-
concept_vectors['cl_method'] = [val.split(',')[0].strip('classification method:') if 'classification method:' in val else False for val in concept_vectors['kwargs']]
|
| 42 |
-
concept_vectors['num_factors'] = [int(val.split(',')[1].strip('number of factors:')) if 'number of factors:' in val else False for val in concept_vectors['kwargs']]
|
| 43 |
-
|
| 44 |
concept_vectors = concept_vectors.sort_values('score', ascending=False).reset_index()
|
| 45 |
|
| 46 |
with dnnlib.util.open_url('./data/textile_model_files/network-snapshot-005000.pkl') as f:
|
|
@@ -52,46 +49,25 @@ COLORS_NEGATIVE = COLORS_LIST + ['None']
|
|
| 52 |
if 'image_id' not in st.session_state:
|
| 53 |
st.session_state.image_id = 52921
|
| 54 |
if 'colors' not in st.session_state:
|
| 55 |
-
st.session_state.colors = [COLORS_LIST[
|
| 56 |
if 'non_colors' not in st.session_state:
|
| 57 |
st.session_state.non_colors = ['None']
|
| 58 |
-
if 'space_id' not in st.session_state:
|
| 59 |
-
st.session_state.space_id = 'W'
|
| 60 |
if 'color_lambda' not in st.session_state:
|
| 61 |
-
st.session_state.color_lambda =
|
| 62 |
-
if 'saturation_lambda' not in st.session_state:
|
| 63 |
-
st.session_state.saturation_lambda = 0
|
| 64 |
-
if 'value_lambda' not in st.session_state:
|
| 65 |
-
st.session_state.value_lambda = 0
|
| 66 |
-
if 'sign' not in st.session_state:
|
| 67 |
-
st.session_state.sign = False
|
| 68 |
-
if 'extremes' not in st.session_state:
|
| 69 |
-
st.session_state.extremes = False
|
| 70 |
-
if 'regularization' not in st.session_state:
|
| 71 |
-
st.session_state.regularization = False
|
| 72 |
-
if 'cl_method' not in st.session_state:
|
| 73 |
-
st.session_state.cl_method = False
|
| 74 |
-
if 'num_factors' not in st.session_state:
|
| 75 |
-
st.session_state.num_factors = False
|
| 76 |
-
if 'best' not in st.session_state:
|
| 77 |
-
st.session_state.best = True
|
| 78 |
-
|
| 79 |
-
# def on_change_random_input():
|
| 80 |
-
# st.session_state.image_id = st.session_state.image_id
|
| 81 |
|
| 82 |
# ----------------------------- INPUT ----------------------------------
|
| 83 |
epsilon_container = st.empty()
|
| 84 |
st.header('Image Manipulation with Vector Algebra')
|
| 85 |
|
| 86 |
-
header_col_1, header_col_2, header_col_3, header_col_4 = st.columns([1,
|
| 87 |
-
input_col_1, output_col_2, output_col_3, input_col_4 = st.columns([1,
|
| 88 |
|
| 89 |
# --------------------------- INPUT column 1 ---------------------------
|
| 90 |
with input_col_1:
|
| 91 |
with st.form('image_form'):
|
| 92 |
|
| 93 |
# image_id = st.number_input('Image ID: ', format='%d', step=1)
|
| 94 |
-
st.write('**Choose or generate a random image
|
| 95 |
chosen_image_id_input = st.empty()
|
| 96 |
image_id = chosen_image_id_input.number_input('Image ID:', format='%d', step=1, value=st.session_state.image_id)
|
| 97 |
|
|
@@ -108,26 +84,22 @@ with input_col_1:
|
|
| 108 |
st.session_state.image_id = image_id
|
| 109 |
|
| 110 |
with header_col_1:
|
| 111 |
-
st.write('Input image selection')
|
| 112 |
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
else:
|
| 116 |
-
original_image_vec = annotations['w_vectors'][st.session_state.image_id]
|
| 117 |
-
|
| 118 |
-
img = generate_original_image(original_image_vec, model, latent_space=st.session_state.space_id)
|
| 119 |
|
| 120 |
with output_col_2:
|
| 121 |
st.image(img)
|
| 122 |
|
| 123 |
with header_col_2:
|
| 124 |
-
st.write('Original image')
|
| 125 |
|
| 126 |
with input_col_4:
|
| 127 |
with st.form('text_form_1'):
|
| 128 |
|
| 129 |
-
st.write('**
|
| 130 |
-
colors = st.multiselect('Color:', tuple(COLORS_LIST), default=[COLORS_LIST[
|
| 131 |
colors_button = st.form_submit_button('Choose the defined colors')
|
| 132 |
|
| 133 |
st.session_state.image_id = image_id
|
|
@@ -138,8 +110,8 @@ with input_col_4:
|
|
| 138 |
lambdas = []
|
| 139 |
negative_cols = []
|
| 140 |
for color in colors:
|
| 141 |
-
st.write(color)
|
| 142 |
-
st.write('**Set range of change**')
|
| 143 |
chosen_color_lambda_input = st.empty()
|
| 144 |
color_lambda = chosen_color_lambda_input.number_input('Lambda:', min_value=-100, step=1, value=5, key=color+'_number')
|
| 145 |
lambdas.append(color_lambda)
|
|
@@ -155,6 +127,8 @@ with input_col_4:
|
|
| 155 |
st.session_state.non_colors = negative_cols
|
| 156 |
|
| 157 |
|
|
|
|
|
|
|
| 158 |
# print(st.session_state.colors)
|
| 159 |
# print(st.session_state.color_lambda)
|
| 160 |
# print(st.session_state.non_colors)
|
|
@@ -176,11 +150,14 @@ with header_col_3:
|
|
| 176 |
negative_separation_vectors.append('None')
|
| 177 |
## n1 − (n1T n2)n2
|
| 178 |
# print(negative_separation_vectors, separation_vectors)
|
| 179 |
-
st.write(
|
|
|
|
|
|
|
| 180 |
|
| 181 |
# ---------------------------- DISPLAY COL 2 ROW 1 ------------------------------
|
| 182 |
|
| 183 |
-
|
| 184 |
with output_col_3:
|
| 185 |
-
image_updated = generate_composite_images(model, original_image_vec, separation_vectors,
|
|
|
|
|
|
|
| 186 |
st.image(image_updated)
|
|
|
|
| 20 |
SECONDARY_COLOR = '#bce7db'
|
| 21 |
|
| 22 |
|
| 23 |
+
st.title('Vector algebra using disentangled vectors')
|
| 24 |
st.markdown(
|
| 25 |
"""
|
| 26 |
+
This page offers the possibility to edit the colors of a given textile image using vector algebra and projections.
|
| 27 |
+
It allows to select several colors to move towards and against (selecting a positive or negative lambda).
|
| 28 |
+
Furthermore, it offers the possibility of conditional manipulation, by moving in the direction of a color n1 without affecting the color n2.
|
| 29 |
+
This is done using a projected direction n1 - (n1.T n2) n2.
|
| 30 |
""",
|
| 31 |
unsafe_allow_html=False,)
|
| 32 |
|
|
|
|
| 38 |
concept_vectors['vector'] = [np.array([float(xx) for xx in x]) for x in concept_vectors['vector'].str.split(', ')]
|
| 39 |
concept_vectors['score'] = concept_vectors['score'].astype(float)
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
concept_vectors = concept_vectors.sort_values('score', ascending=False).reset_index()
|
| 42 |
|
| 43 |
with dnnlib.util.open_url('./data/textile_model_files/network-snapshot-005000.pkl') as f:
|
|
|
|
| 49 |
if 'image_id' not in st.session_state:
|
| 50 |
st.session_state.image_id = 52921
|
| 51 |
if 'colors' not in st.session_state:
|
| 52 |
+
st.session_state.colors = [COLORS_LIST[5], COLORS_LIST[7]]
|
| 53 |
if 'non_colors' not in st.session_state:
|
| 54 |
st.session_state.non_colors = ['None']
|
|
|
|
|
|
|
| 55 |
if 'color_lambda' not in st.session_state:
|
| 56 |
+
st.session_state.color_lambda = [5]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
# ----------------------------- INPUT ----------------------------------
|
| 59 |
epsilon_container = st.empty()
|
| 60 |
st.header('Image Manipulation with Vector Algebra')
|
| 61 |
|
| 62 |
+
header_col_1, header_col_2, header_col_3, header_col_4 = st.columns([1,1,1,1])
|
| 63 |
+
input_col_1, output_col_2, output_col_3, input_col_4 = st.columns([1,1,1,1])
|
| 64 |
|
| 65 |
# --------------------------- INPUT column 1 ---------------------------
|
| 66 |
with input_col_1:
|
| 67 |
with st.form('image_form'):
|
| 68 |
|
| 69 |
# image_id = st.number_input('Image ID: ', format='%d', step=1)
|
| 70 |
+
st.write('**Choose or generate a random image**')
|
| 71 |
chosen_image_id_input = st.empty()
|
| 72 |
image_id = chosen_image_id_input.number_input('Image ID:', format='%d', step=1, value=st.session_state.image_id)
|
| 73 |
|
|
|
|
| 84 |
st.session_state.image_id = image_id
|
| 85 |
|
| 86 |
with header_col_1:
|
| 87 |
+
st.write('### Input image selection')
|
| 88 |
|
| 89 |
+
original_image_vec = annotations['w_vectors'][st.session_state.image_id]
|
| 90 |
+
img = generate_original_image(original_image_vec, model)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
|
| 92 |
with output_col_2:
|
| 93 |
st.image(img)
|
| 94 |
|
| 95 |
with header_col_2:
|
| 96 |
+
st.write('### Original image')
|
| 97 |
|
| 98 |
with input_col_4:
|
| 99 |
with st.form('text_form_1'):
|
| 100 |
|
| 101 |
+
st.write('**Colors to vary (including Saturation and Value)**')
|
| 102 |
+
colors = st.multiselect('Color:', tuple(COLORS_LIST), default=[COLORS_LIST[5], COLORS_LIST[7]])
|
| 103 |
colors_button = st.form_submit_button('Choose the defined colors')
|
| 104 |
|
| 105 |
st.session_state.image_id = image_id
|
|
|
|
| 110 |
lambdas = []
|
| 111 |
negative_cols = []
|
| 112 |
for color in colors:
|
| 113 |
+
st.write('### '+color )
|
| 114 |
+
st.write('**Set range of change (can be negative)**')
|
| 115 |
chosen_color_lambda_input = st.empty()
|
| 116 |
color_lambda = chosen_color_lambda_input.number_input('Lambda:', min_value=-100, step=1, value=5, key=color+'_number')
|
| 117 |
lambdas.append(color_lambda)
|
|
|
|
| 127 |
st.session_state.non_colors = negative_cols
|
| 128 |
|
| 129 |
|
| 130 |
+
with header_col_4:
|
| 131 |
+
st.write('### Color settings')
|
| 132 |
# print(st.session_state.colors)
|
| 133 |
# print(st.session_state.color_lambda)
|
| 134 |
# print(st.session_state.non_colors)
|
|
|
|
| 150 |
negative_separation_vectors.append('None')
|
| 151 |
## n1 − (n1T n2)n2
|
| 152 |
# print(negative_separation_vectors, separation_vectors)
|
| 153 |
+
st.write('### Output Image')
|
| 154 |
+
st.write(f'''Change in colors: {str(st.session_state.colors)},\
|
| 155 |
+
without affecting colors {str(st.session_state.non_colors)}''')
|
| 156 |
|
| 157 |
# ---------------------------- DISPLAY COL 2 ROW 1 ------------------------------
|
| 158 |
|
|
|
|
| 159 |
with output_col_3:
|
| 160 |
+
image_updated = generate_composite_images(model, original_image_vec, separation_vectors,
|
| 161 |
+
lambdas=st.session_state.color_lambda,
|
| 162 |
+
negative_colors=negative_separation_vectors)
|
| 163 |
st.image(image_updated)
|