In [22]:
# Stiahneme potrebný kód.
!git clone https://github.com/michalgregor/Neural-Style-Transfer.git
Cloning into 'Neural-Style-Transfer'...
remote: Enumerating objects: 49, done.
remote: Counting objects: 100% (49/49), done.
remote: Compressing objects: 100% (41/41), done.
remote: Total 1381 (delta 22), reused 19 (delta 8), pack-reused 1332
Receiving objects: 100% (1381/1381), 66.84 MiB | 12.57 MiB/s, done.
Resolving deltas: 100% (803/803), done.
In [0]:
# Import potrebných balíčkov
import matplotlib.pyplot as plt
from google.colab import files
import sys
In [24]:
# Uistíme sa, že máme všetky potrebné dáta
!mkdir -p data
!wget -nc -O data/cat.jpg https://www.dropbox.com/s/a5ux951zo01gd5z/cat.jpg?dl=1
!wget -nc -O data/picaso.jpg https://www.dropbox.com/s/l1gjon5gvjpefuv/picaso.jpg?dl=1
File ‘data/cat.jpg’ already there; not retrieving.
File ‘data/picaso.jpg’ already there; not retrieving.

Neuromaľby

Tento notebook ukazuje, ako sa dá použiť algoritmus na neuro umelecké štýly z "A Neural Algorithm of Artistic Style". Implementáciu, ktorú budeme používať, sa dá nájsť v repozitári github. Tento notebook súbor je tiež adaptáciou notebook súboru z toho istého repozitára.

Pozrime sa, aké parametre má skript, ktorý je súčasťou tohto repozitára:

In [25]:
dir_path = "Neural-Style-Transfer"
NETWORK = 'INetwork' + '.py'

# Zoznam argumentov, ktoré podporuje skript Network.py
!{sys.executable} {dir_path}/{NETWORK} -h
Using TensorFlow backend.
usage: INetwork.py [-h] [--style_masks STYLE_MASKS [STYLE_MASKS ...]]
                   [--content_mask CONTENT_MASK] [--color_mask COLOR_MASK]
                   [--image_size IMG_SIZE] [--content_weight CONTENT_WEIGHT]
                   [--style_weight STYLE_WEIGHT [STYLE_WEIGHT ...]]
                   [--style_scale STYLE_SCALE]
                   [--total_variation_weight TV_WEIGHT] [--num_iter NUM_ITER]
                   [--model MODEL] [--content_loss_type CONTENT_LOSS_TYPE]
                   [--rescale_image RESCALE_IMAGE]
                   [--rescale_method RESCALE_METHOD]
                   [--maintain_aspect_ratio MAINTAIN_ASPECT_RATIO]
                   [--content_layer CONTENT_LAYER] [--init_image INIT_IMAGE]
                   [--pool_type POOL] [--preserve_color COLOR]
                   [--min_improvement MIN_IMPROVEMENT]
                   base ref [ref ...] res_prefix

Neural style transfer with Keras.

positional arguments:
  base                  Path to the image to transform.
  ref                   Path to the style reference image.
  res_prefix            Prefix for the saved results.

optional arguments:
  -h, --help            show this help message and exit
  --style_masks STYLE_MASKS [STYLE_MASKS ...]
                        Masks for style images
  --content_mask CONTENT_MASK
                        Masks for the content image
  --color_mask COLOR_MASK
                        Mask for color preservation
  --image_size IMG_SIZE
                        Minimum image size
  --content_weight CONTENT_WEIGHT
                        Weight of content
  --style_weight STYLE_WEIGHT [STYLE_WEIGHT ...]
                        Weight of style, can be multiple for multiple styles
  --style_scale STYLE_SCALE
                        Scale the weighing of the style
  --total_variation_weight TV_WEIGHT
                        Total Variation weight
  --num_iter NUM_ITER   Number of iterations
  --model MODEL         Choices are 'vgg16' and 'vgg19'
  --content_loss_type CONTENT_LOSS_TYPE
                        Can be one of 0, 1 or 2. Readme contains the required
                        information of each mode.
  --rescale_image RESCALE_IMAGE
                        Rescale image after execution to original dimentions
  --rescale_method RESCALE_METHOD
                        Rescale image algorithm
  --maintain_aspect_ratio MAINTAIN_ASPECT_RATIO
                        Maintain aspect ratio of loaded images
  --content_layer CONTENT_LAYER
                        Content layer used for content loss.
  --init_image INIT_IMAGE
                        Initial image used to generate the final image.
                        Options are 'content', 'noise', or 'gray'
  --pool_type POOL      Pooling type. Can be "ave" for average pooling or
                        "max" for max pooling
  --preserve_color COLOR
                        Preserve original color in image
  --min_improvement MIN_IMPROVEMENT
                        Defines minimum improvement required to continue
                        script

Parametre Network.py

Na tomto mieste nastavíme všetky potrebné parametre pre skript Network.py.

In [0]:
# Veľkosť obrázka
IMAGE_SIZE = 400

# Váhy chybových kritérií
CONTENT_WEIGHT = 0.025
STYLE_WEIGHT = 1.0
STYLE_SCALE = 1.0
TOTAL_VARIATION_WEIGHT = 8.5e-5
CONTENT_LOSS_TYPE = 0

# Argumenty pre optimalizáciu
NUM_ITERATIONS = 10
MODEL = 'vgg16'
RESCALE_IMAGE = 'false'
# nastavte false ak je málo pamäte (OOM)
MAINTAIN_ASPECT_RATIO = 'true'  

# Argumenty pre transfer štýlu
# číslo 5_2 meňte len na niečo v podobnom formáte
CONTENT_LAYER = 'conv5_2'
INITIALIZATION_IMAGE = 'content'
POOLING_TYPE = 'max'

# Ďalšie argumenty
PRESERVE_COLOR = 'false'
MIN_IMPROVEMENT = 0.0

Obrázok s obsahom

Po spustení nasledujúcej bunky je možné nahrať obrázok s obsahom. Prípustné je vybrať len 1 obrázok.

In [0]:
CONTENT_IMAGE_FN = "data/cat.jpg"
In [0]:
# content_img = files.upload()
# CONTENT_IMAGE_FN = list(content_img)[0]
In [29]:
fig = plt.figure(figsize=(10, 10))
img = plt.imread(CONTENT_IMAGE_FN)
plt.axis('off')
plt.title('Obrázok s obsahom')
plt.imshow(img)
Out[29]:
<matplotlib.image.AxesImage at 0x7fb851354588>

Obrázok so štýlom

Po spustení nasledujúcej bunky je možné nahrať obrázok so štýlom. Prípustné je vybrať len 1 obrázok.

In [0]:
STYLE_IMAGE_FN = "data/picaso.jpg"
In [0]:
# style_img = files.upload()
# style_filename = list(style_img)[0]
In [32]:
fig = plt.figure(figsize=(10, 10))
img = plt.imread(STYLE_IMAGE_FN)
plt.axis('off')
plt.title('Obrázok so štýlom')
plt.imshow(img)
Out[32]:
<matplotlib.image.AxesImage at 0x7fb851332208>

Generovanie obrázku

Spustením nasledujúcich buniek sa vygeneruje obrázok.

In [0]:
import os

RESULT_DIR = "generated/"
RESULT_PREFIX = RESULT_DIR + "gen"
FINAL_IMAGE_PATH = RESULT_PREFIX + "_at_iteration_%d.png" % (NUM_ITERATIONS)

if not os.path.exists(RESULT_DIR):
  os.makedirs(RESULT_DIR)
In [13]:
!{sys.executable} {dir_path}/{NETWORK} {CONTENT_IMAGE_FN} {STYLE_IMAGE_FN} {RESULT_PREFIX} \
  --image_size {IMAGE_SIZE} --content_weight {CONTENT_WEIGHT} --style_weight \
  {STYLE_WEIGHT} --style_scale {STYLE_SCALE} --total_variation_weight \
  {TOTAL_VARIATION_WEIGHT} --content_loss_type {CONTENT_LOSS_TYPE} --num_iter \
  {NUM_ITERATIONS} --model {MODEL} --rescale_image {RESCALE_IMAGE} \
  --maintain_aspect_ratio {MAINTAIN_ASPECT_RATIO} --content_layer {CONTENT_LAYER} \
  --init_image {INITIALIZATION_IMAGE} --pool_type {POOLING_TYPE} --preserve_color \
  {PRESERVE_COLOR} --min_improvement {MIN_IMPROVEMENT}
Using TensorFlow backend.
WARNING: Logging before flag parsing goes to stderr.
W0830 14:56:09.692447 139830378010496 deprecation_wrapper.py:119] From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:541: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.

W0830 14:56:09.695646 139830378010496 deprecation_wrapper.py:119] From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:66: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.

W0830 14:56:09.696222 139830378010496 deprecation_wrapper.py:119] From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:4432: The name tf.random_uniform is deprecated. Please use tf.random.uniform instead.

W0830 14:56:09.726229 139830378010496 deprecation_wrapper.py:119] From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:4267: The name tf.nn.max_pool is deprecated. Please use tf.nn.max_pool2d instead.

Downloading data from https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5
58892288/58889256 [==============================] - 4s 0us/step
W0830 14:56:14.546358 139830378010496 deprecation_wrapper.py:119] From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:190: The name tf.get_default_session is deprecated. Please use tf.compat.v1.get_default_session instead.

W0830 14:56:14.546627 139830378010496 deprecation_wrapper.py:119] From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:197: The name tf.ConfigProto is deprecated. Please use tf.compat.v1.ConfigProto instead.

2019-08-30 14:56:14.560438: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2200000000 Hz
2019-08-30 14:56:14.562595: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x3b1f9c0 executing computations on platform Host. Devices:
2019-08-30 14:56:14.562640: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): <undefined>, <undefined>
2019-08-30 14:56:14.568036: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcuda.so.1
2019-08-30 14:56:14.804362: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-30 14:56:14.805016: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x3b1fb80 executing computations on platform CUDA. Devices:
2019-08-30 14:56:14.805044: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): Tesla T4, Compute Capability 7.5
2019-08-30 14:56:14.806058: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-30 14:56:14.806601: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1640] Found device 0 with properties: 
name: Tesla T4 major: 7 minor: 5 memoryClockRate(GHz): 1.59
pciBusID: 0000:00:04.0
2019-08-30 14:56:14.816607: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcudart.so.10.0
2019-08-30 14:56:14.978973: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcublas.so.10.0
2019-08-30 14:56:15.053685: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcufft.so.10.0
2019-08-30 14:56:15.073156: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcurand.so.10.0
2019-08-30 14:56:15.255818: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcusolver.so.10.0
2019-08-30 14:56:15.359190: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcusparse.so.10.0
2019-08-30 14:56:15.697668: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcudnn.so.7
2019-08-30 14:56:15.697901: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-30 14:56:15.698617: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-30 14:56:15.699143: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1763] Adding visible gpu devices: 0
2019-08-30 14:56:15.701656: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcudart.so.10.0
2019-08-30 14:56:15.702890: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1181] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-08-30 14:56:15.702924: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1187]      0 
2019-08-30 14:56:15.702934: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1200] 0:   N 
2019-08-30 14:56:15.707031: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-30 14:56:15.707681: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-30 14:56:15.708168: W tensorflow/core/common_runtime/gpu/gpu_bfc_allocator.cc:40] Overriding allow_growth setting because the TF_FORCE_GPU_ALLOW_GROWTH environment variable is set. Original config value was 0.
2019-08-30 14:56:15.708212: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1326] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 14221 MB memory) -> physical GPU (device: 0, name: Tesla T4, pci bus id: 0000:00:04.0, compute capability: 7.5)
Model loaded.
W0830 14:56:18.816777 139830378010496 deprecation.py:323] From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_grad.py:1205: add_dispatch_support.<locals>.wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.where in 2.0, which has the same broadcast rule as np.where
Starting iteration 1 of 10
2019-08-30 14:56:21.457851: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcublas.so.10.0
2019-08-30 14:56:22.115485: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcudnn.so.7
Current loss value: 117689330.0  Improvement : 0.000 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_1.png
Iteration 1 completed in 13s
Starting iteration 2 of 10
Current loss value: 35782400.0  Improvement : 69.596 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_2.png
Iteration 2 completed in 6s
Starting iteration 3 of 10
Current loss value: 20027554.0  Improvement : 44.030 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_3.png
Iteration 3 completed in 6s
Starting iteration 4 of 10
Current loss value: 14474294.0  Improvement : 27.728 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_4.png
Iteration 4 completed in 6s
Starting iteration 5 of 10
Current loss value: 11715739.0  Improvement : 19.058 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_5.png
Iteration 5 completed in 6s
Starting iteration 6 of 10
Current loss value: 10015922.0  Improvement : 14.509 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_6.png
Iteration 6 completed in 6s
Starting iteration 7 of 10
Current loss value: 8887704.0  Improvement : 11.264 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_7.png
Iteration 7 completed in 6s
Starting iteration 8 of 10
Current loss value: 8032433.5  Improvement : 9.623 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_8.png
Iteration 8 completed in 6s
Starting iteration 9 of 10
Current loss value: 7311348.0  Improvement : 8.977 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_9.png
Iteration 9 completed in 6s
Starting iteration 10 of 10
Current loss value: 6799690.0  Improvement : 6.998 %
Rescaling Image to (400, 400)
Image saved as generated/gen_at_iteration_10.png
Iteration 10 completed in 6s
In [14]:
fig = plt.figure(figsize=(10, 10))
img = plt.imread(FINAL_IMAGE_PATH)
plt.axis('off')
plt.title('Generated image')
plt.imshow(img)
Out[14]:
<matplotlib.image.AxesImage at 0x7fb8516f0a58>

(Nepovinné) Transfer farieb

Ak chcete, aby sa do preštýlovaného obrázku preniesli farby z pôvodného obrázku s obsahom, spustite nasledujúce bunky.

In [36]:
COLOR_TRANSFER = 'color_transfer.py'
COLOR_FINAL_IMAGE_PATH = FINAL_IMAGE_PATH[:-4] + '_%s_color.png'

# Optional - Use Histogram matching (0 for no, 1 for yes)
HISTOGRAM_MATCH = 0

if HISTOGRAM_MATCH == 0:
  COLOR_FINAL_IMAGE_PATH = COLOR_FINAL_IMAGE_PATH % ('original')
else:
  COLOR_FINAL_IMAGE_PATH = COLOR_FINAL_IMAGE_PATH % ('histogram')

!{sys.executable} {dir_path}/{COLOR_TRANSFER} {CONTENT_IMAGE_FN} {FINAL_IMAGE_PATH} --hist_match {HISTOGRAM_MATCH}
Image saved at path : generated/gen_at_iteration_10_original_color.png
In [37]:
fig = plt.figure(figsize=(10, 10))
img = plt.imread(COLOR_FINAL_IMAGE_PATH)
plt.axis('off')
plt.title('Color Transferred Generated image')
plt.imshow(img)
Out[37]:
<matplotlib.image.AxesImage at 0x7fb851288550>

Úloha 1: Aplikácia na iný obrázok/štýl

Aplikujte ten istý postup na iné obrázky so štýlom a obsahom.

Poznámka: Dá sa použiť vyššie uvedený kód: stačí odkomentovať časti, pomocou ktorých sa dajú nahrať nové obrázky.


In [0]: