Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -7,8 +7,8 @@ from PIL import Image
|
|
| 7 |
vgg = tf.keras.applications.VGG19(include_top=False, weights="imagenet")
|
| 8 |
vgg.trainable = False
|
| 9 |
|
| 10 |
-
STYLE_LAYERS = [...] #
|
| 11 |
-
CONTENT_LAYER = [...] #
|
| 12 |
|
| 13 |
|
| 14 |
def gram_matrix(A):
|
|
@@ -18,63 +18,52 @@ def gram_matrix(A):
|
|
| 18 |
A = tf.convert_to_tensor(A)
|
| 19 |
|
| 20 |
if len(A.shape) == 4:
|
| 21 |
-
# (batch, H, W, C)
|
| 22 |
batch, H, W, C = A.shape
|
| 23 |
-
A = tf.reshape(A, (batch, H*W, C))
|
| 24 |
-
gram = tf.matmul(A, A, transpose_a=True) / tf.cast(H*W, tf.float32)
|
| 25 |
-
|
| 26 |
elif len(A.shape) == 3:
|
| 27 |
-
# (batch, N, C) already flattened
|
| 28 |
batch, N, C = A.shape
|
| 29 |
gram = tf.matmul(A, A, transpose_a=True) / tf.cast(N, tf.float32)
|
| 30 |
-
|
| 31 |
elif len(A.shape) == 2:
|
| 32 |
-
# (N, C) no batch
|
| 33 |
N, C = A.shape
|
| 34 |
-
A = tf.expand_dims(A, 0)
|
| 35 |
gram = tf.matmul(A, A, transpose_a=True) / tf.cast(N, tf.float32)
|
| 36 |
-
|
| 37 |
else:
|
| 38 |
raise ValueError(f"Unexpected tensor rank for gram_matrix: {A.shape}")
|
| 39 |
-
|
| 40 |
return gram
|
|
|
|
|
|
|
| 41 |
def compute_content_cost(a_C, a_G):
|
| 42 |
-
"""Content cost between content and generated image features."""
|
| 43 |
return tf.reduce_mean(tf.square(a_C - a_G))
|
| 44 |
|
|
|
|
| 45 |
def compute_style_cost(a_S, a_G):
|
| 46 |
-
"""Style cost using Gram matrices."""
|
| 47 |
J_style = 0
|
| 48 |
for s, g in zip(a_S, a_G):
|
| 49 |
J_style += tf.reduce_mean(tf.square(gram_matrix(s) - gram_matrix(g)))
|
| 50 |
return J_style / len(a_S)
|
| 51 |
|
|
|
|
| 52 |
def total_cost(J_content, J_style, alpha=10, beta=40):
|
| 53 |
-
"""Weighted sum of content + style."""
|
| 54 |
return alpha * J_content + beta * J_style
|
| 55 |
|
| 56 |
-
def clip_0_1(img):
|
| 57 |
-
"""Keep pixel values in [0,1]."""
|
| 58 |
-
return tf.clip_by_value(img, 0.0, 1.0)
|
| 59 |
|
| 60 |
def preprocess(img):
|
| 61 |
img = Image.fromarray(img).resize((256, 256))
|
| 62 |
arr = np.expand_dims(np.array(img) / 255.0, axis=0).astype(np.float32)
|
| 63 |
return tf.convert_to_tensor(arr)
|
| 64 |
|
| 65 |
-
|
|
|
|
| 66 |
content_tensor = preprocess(content)
|
| 67 |
style_tensor = preprocess(style)
|
| 68 |
|
| 69 |
-
# Extract features
|
| 70 |
a_C = vgg(content_tensor)
|
| 71 |
a_S = vgg(style_tensor)
|
| 72 |
|
| 73 |
-
# Init generated image
|
| 74 |
generated_image = tf.Variable(content_tensor)
|
| 75 |
-
|
| 76 |
-
# Optimize
|
| 77 |
opt = tf.keras.optimizers.Adam(learning_rate=0.01)
|
|
|
|
| 78 |
for i in range(steps):
|
| 79 |
with tf.GradientTape() as tape:
|
| 80 |
a_G = vgg(generated_image)
|
|
@@ -89,11 +78,15 @@ def style_transfer(content, style, steps=1000):
|
|
| 89 |
out_img = (generated_image[0].numpy() * 255).astype("uint8")
|
| 90 |
return Image.fromarray(out_img)
|
| 91 |
|
|
|
|
| 92 |
demo = gr.Interface(
|
| 93 |
fn=style_transfer,
|
| 94 |
-
inputs=[
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
| 96 |
outputs=gr.Image(type="pil", label="Stylized Image"),
|
| 97 |
)
|
| 98 |
|
| 99 |
-
demo.launch()
|
|
|
|
| 7 |
vgg = tf.keras.applications.VGG19(include_top=False, weights="imagenet")
|
| 8 |
vgg.trainable = False
|
| 9 |
|
| 10 |
+
STYLE_LAYERS = [...] # your style layers
|
| 11 |
+
CONTENT_LAYER = [...] # your content layer(s)
|
| 12 |
|
| 13 |
|
| 14 |
def gram_matrix(A):
|
|
|
|
| 18 |
A = tf.convert_to_tensor(A)
|
| 19 |
|
| 20 |
if len(A.shape) == 4:
|
|
|
|
| 21 |
batch, H, W, C = A.shape
|
| 22 |
+
A = tf.reshape(A, (batch, H * W, C))
|
| 23 |
+
gram = tf.matmul(A, A, transpose_a=True) / tf.cast(H * W, tf.float32)
|
|
|
|
| 24 |
elif len(A.shape) == 3:
|
|
|
|
| 25 |
batch, N, C = A.shape
|
| 26 |
gram = tf.matmul(A, A, transpose_a=True) / tf.cast(N, tf.float32)
|
|
|
|
| 27 |
elif len(A.shape) == 2:
|
|
|
|
| 28 |
N, C = A.shape
|
| 29 |
+
A = tf.expand_dims(A, 0)
|
| 30 |
gram = tf.matmul(A, A, transpose_a=True) / tf.cast(N, tf.float32)
|
|
|
|
| 31 |
else:
|
| 32 |
raise ValueError(f"Unexpected tensor rank for gram_matrix: {A.shape}")
|
|
|
|
| 33 |
return gram
|
| 34 |
+
|
| 35 |
+
|
| 36 |
def compute_content_cost(a_C, a_G):
|
|
|
|
| 37 |
return tf.reduce_mean(tf.square(a_C - a_G))
|
| 38 |
|
| 39 |
+
|
| 40 |
def compute_style_cost(a_S, a_G):
|
|
|
|
| 41 |
J_style = 0
|
| 42 |
for s, g in zip(a_S, a_G):
|
| 43 |
J_style += tf.reduce_mean(tf.square(gram_matrix(s) - gram_matrix(g)))
|
| 44 |
return J_style / len(a_S)
|
| 45 |
|
| 46 |
+
|
| 47 |
def total_cost(J_content, J_style, alpha=10, beta=40):
|
|
|
|
| 48 |
return alpha * J_content + beta * J_style
|
| 49 |
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
def preprocess(img):
|
| 52 |
img = Image.fromarray(img).resize((256, 256))
|
| 53 |
arr = np.expand_dims(np.array(img) / 255.0, axis=0).astype(np.float32)
|
| 54 |
return tf.convert_to_tensor(arr)
|
| 55 |
|
| 56 |
+
|
| 57 |
+
def style_transfer(content, style, steps):
|
| 58 |
content_tensor = preprocess(content)
|
| 59 |
style_tensor = preprocess(style)
|
| 60 |
|
|
|
|
| 61 |
a_C = vgg(content_tensor)
|
| 62 |
a_S = vgg(style_tensor)
|
| 63 |
|
|
|
|
| 64 |
generated_image = tf.Variable(content_tensor)
|
|
|
|
|
|
|
| 65 |
opt = tf.keras.optimizers.Adam(learning_rate=0.01)
|
| 66 |
+
|
| 67 |
for i in range(steps):
|
| 68 |
with tf.GradientTape() as tape:
|
| 69 |
a_G = vgg(generated_image)
|
|
|
|
| 78 |
out_img = (generated_image[0].numpy() * 255).astype("uint8")
|
| 79 |
return Image.fromarray(out_img)
|
| 80 |
|
| 81 |
+
|
| 82 |
demo = gr.Interface(
|
| 83 |
fn=style_transfer,
|
| 84 |
+
inputs=[
|
| 85 |
+
gr.Image(type="numpy", label="Content Image"),
|
| 86 |
+
gr.Image(type="numpy", label="Style Image"),
|
| 87 |
+
gr.Slider(100, 2000, value=1000, step=100, label="Number of Iterations")
|
| 88 |
+
],
|
| 89 |
outputs=gr.Image(type="pil", label="Stylized Image"),
|
| 90 |
)
|
| 91 |
|
| 92 |
+
demo.launch()
|