kshitizrimal / deepStyle
Jedná se o implementaci několika technik popsaných v článcích TensorFlow:
- Image Style Transfer Using Convolutional Neural Networksby Leon A. Gatys, Alexander S. Ecker, Matthias Bethge
- Artistic style transfer for videosby Manuel Ruder, Alexey Dosovitskiy, Thomas Brox
- Preserving Color in Neural Artistic Style Transferby Leon A. Gatys, Matthias Bethge, Aaron Hertzmann, Eli Shechtman
Dále jsou uvedeny techniky pro sémantickou segmentaci a vícenásobný přenos stylu.
Algoritmus neuronového stylu syntetizuje pastiš oddělením a kombinací obsahu jednoho obrazu se stylem jiného obrazu pomocí konvolučních neuronových sítí (CNN). Níže je uveden příklad přenosu uměleckého stylu Hvězdné noci na fotografii afrického lva:
Přenos stylu různých uměleckých děl na stejný obsah obrazu přináší kvalitativně přesvědčivé výsledky:
Zde reprodukujeme obrázek 3 z prvního příspěvku, na kterém je fotografie nábřeží řeky Neckar v německém Tübingenu ztvárněna ve stylu 5 různých ikonických obrazů Ztroskotání Minotaura, Hvězdná noc, Kompozice VII, Výkřik, Sedící akt:
Tradeoff obsah / styl
Relativní váhu stylu a obsahu lze řídit.
Zde vykreslujeme s rostoucí váhou stylu aplikovanou na červenou Cannu:
Více obrázků stylů
K prolínání více uměleckých stylů lze použít více než jeden obrázek stylu.
Horní řada (zleva doprava): Hvězdná noc + Výkřik, Výkřik + Kompozice VII, Sedící akt + Kompozice VII
Dolní řada (zleva doprava): Sedící akt + Hvězdná noc, Nadduše + Svěžest chladu, David Bowie + Lebka
Interpolace stylů
Při použití více stylových obrázků lze řídit stupeň prolnutí mezi obrázky.
Horní řada (zleva doprava): obsahový obrázek, .2 Hvězdná noc + .8 Výkřik, .8 Hvězdná noc + .2 Výkřik
Dolní řada (zleva doprava): .2 Nadduše + .8 Svěžest chladu, .5 Nadduše + .5 Svěžest chladu, .8 Nadduše + .2 Svěžest chladu
Přenos stylu, ale ne barvy
Barevné schéma původního obrázku lze zachovat zahrnutím příznaku --original_colors
. Barvy se přenášejí pomocí barevných prostorů YUV, YCrCb, CIE L*a*b* nebo CIE L*u*v*.
Tady reprodukujeme obrázek 1 a obrázek 2 ve třetím dokumentu s použitím přenosu pouze luminance:
Zleva doprava: obraz obsahu, stylizovaný obraz, stylizovaný obraz s původními barvami obrazu obsahu
Textury
Algoritmus není omezen na umělecké styly malby. Lze jej použít i na fotografické textury a vytvořit tak pareidolické obrazy.
Segmentace
Styl lze přenést na sémantické segmentace v obsahovém obrazu.
Na popředí a pozadí obrazu obsahu lze přenést více stylů.
Zleva doprava: obrázek obsahu, styl popředí, styl pozadí, maska popředí, maska pozadí, stylizovaný obrázek
Video
Animace lze vykreslit použitím algoritmu na každý zdrojový snímek. Pro dosažení nejlepších výsledků je gradientní sestup inicializován s dříve stylizovaným snímkem deformovaným na aktuální snímek podle optického toku mezi dvojicí snímků. Ztrátové funkce pro časovou konzistenci se používají k penalizaci pixelů vylučujících vyřazené oblasti a hranice pohybu.
Vrchní řádek (zleva doprava): zdrojové snímky, vizualizovaný optický tok podle země
Dolní řádek (zleva doprava): vyřazené oblasti a hranice pohybu, stylizované snímky
Inicializace gradientního sestupu
Inicializace gradientního sestupu se řídí pomocí --init_img_type
pro jednotlivé snímky a --init_frame_type
nebo --first_frame_type
pro videosnímky. Bílý šum umožňuje generovat libovolný počet různých snímků. Zatímco inicializace s pevným obrázkem konverguje vždy ke stejnému výstupu.
Převzali jsme obrázek 6 z prvního článku:
Horní řada (zleva doprava): Inicializováno obrázkem obsahu, obrázkem stylu, bílým šumem (RNG seed 1)
Dolní řádek (zleva doprava): Inicializováno bílým šumem (semena RNG 2, 3, 4)
Reprezentace vrstev
Složitost prvků a velikost receptivního pole se směrem dolů v hierarchii CNN zvyšuje.
Zde reprodukujeme obrázek 3 z původního článku:
1 x 10^-5 | 1 x 10^-4 | 1 x 10^-3 | 1 x 10^-2 | |
conv1_1 | ||||
conv2_1 | ||||
conv3_1 | ||||
conv4_1 | ||||
conv5_1 |
Řádky: rostoucí podmnožiny vrstev CNN; i.Tj. „conv4_1“ znamená použití „conv1_1“, „conv2_1“, „conv3_1“, „conv4_1“.
Sloupce: poměr alfa/beta rekonstrukce obsahu a stylu (viz Content / Style Tradeoff).
Nastavení
Závislosti:
- tensorflow
- opencv
Nepovinné (ale doporučené) závislosti:
- CUDA 7.5+
- cuDNN 5.0+
Po instalaci závislostí:
- Stáhněte váhy modelu VGG-19 (viz část „Modely VGG-VD z projektu Very Deep Convolutional Networks for Large-Scale Visual Recognition“). Více informací o síti VGG-19 najdete zde.
- Po stažení zkopírujte soubor s váhami
imagenet-vgg-verydeep-19.mat
do adresáře projektu.
Použití
Základní použití
Jeden obrázek
- Kopírování 1 obrázku obsahu do výchozího adresáře obsahu obrázku
./image_input
- Kopírování 1 nebo více obrázků stylu do výchozího adresáře stylu
./styles
- Spustit příkaz:
bash stylize_image.sh <path_to_content_image> <path_to_style_image>
Příklad:
bash stylize_image.sh ./image_input/lion.jpg ./styles/kandinsky.jpg
Poznámka: Mezi podporované formáty obrázků patří: .png
, .jpg
, .ppm
, .pgm
Poznámka: Cesty k obrázkům by neměly obsahovat znak ~
, který představuje váš domovský adresář; místo toho byste měli použít relativní cestu nebo absolutní cestu.
Video snímky
- Kopírování 1 videa s obsahem do výchozího adresáře s obsahem videa
./video_input
- Kopírování 1 nebo více obrázků stylu do výchozího adresáře stylu
./styles
- Příkaz:
bash stylize_video.sh <path_to_video> <path_to_style_image>
Příklad:
bash stylize_video.sh ./video_input/video.mp4 ./styles/kandinsky.jpg
Poznámka: Podporované formáty videa zahrnují: .mp4
, .mov
, .mkv
Pokročilé použití
Jednotlivé obrázky nebo videosnímky
- Kopírování obrázků obsahu do výchozího adresáře s obsahem obrázků
./image_input
nebo kopírování videosnímků do výchozího adresáře s obsahem videa./video_input
- Kopírování 1 nebo více obrázků stylu do výchozího adresáře stylu
./styles
- Spustit příkaz se specifickými argumenty:
python neural_style.py <arguments>
Příklad (jeden snímek):
python neural_style.py --content_img golden_gate.jpg \ --style_imgs starry-night.jpg \ --max_size 1000 \ --max_iterations 100 \ --original_colors \ --device /cpu:0 \ --verbose;
Chcete-li použít více stylových snímků, předejte seznam názvů snímků a vah snímků oddělený mezerou takto:
--style_imgs starry_night.jpg the_scream.jpg --style_imgs_weights 0.5 0.5
Příklad (videosnímky):
python neural_style.py --video \ --video_input_dir ./video_input/my_video_frames \ --style_imgs starry-night.jpg \ --content_weight 5 \ --style_weight 1000 \ --temporal_weight 1000 \ --start_frame 1 \ --end_frame 50 \ --max_size 1024 \ --first_frame_iterations 3000 \ --verbose;
Poznámka: Při použití --init_frame_type prev_warp
musíte mít předem vypočtený zpětný a dopředný optický tok mezi snímky. Viz ./video_input/make-opt-flow.sh
a ./video_input/run-deepflow.sh
Argumenty
-
--content_img
: Název souboru obsahového snímku. Příklad:lion.jpg
-
--content_img_dir
: Relativní nebo absolutní cesta k adresáři s obrazem obsahu. Výchozí hodnota:./image_input
-
--style_imgs
: Názvy souborů s obrázky stylů. Chcete-li použít více obrázků stylů, předejte seznam oddělený mezerami. Příklad:--style_imgs starry-night.jpg
-
--style_imgs_weights
: Váhy prolnutí pro každý obrázek stylu. Výchozí hodnota:1.0
(předpokládá pouze 1 obrázek stylu) -
--style_imgs_dir
: Relativní nebo absolutní cesta k adresáři s obrázky stylů. Výchozí:./styles
-
--init_img_type
: Obrázek použitý k inicializaci sítě. Možné volby:content
,random
,style
. Výchozí:content
-
--max_size
: Maximální šířka nebo výška vstupních obrázků. Výchozí hodnota:512
-
--content_weight
: Váha pro funkci ztráty obsahu. Výchozí hodnota:5e0
-
--style_weight
: Váha pro funkci ztráty stylu. Výchozí hodnota:1e4
-
--tv_weight
: Váha pro celkovou variační ztrátovou funkci. Výchozí hodnota:1e-3
-
--temporal_weight
: Váha pro časovou ztrátovou funkci. Výchozí hodnota:2e2
-
--content_layers
: Prostorově oddělené názvy vrstev VGG-19 použité pro obraz obsahu. Výchozí:conv4_2
-
--style_layers
: Prostorově oddělené názvy vrstev VGG-19 použité pro obraz stylu. Výchozí:relu1_1 relu2_1 relu3_1 relu4_1 relu5_1
-
--content_layer_weights
: Prostorově oddělené váhy jednotlivých vrstev obsahu vůči ztrátě obsahu. Výchozí:1.0
-
--style_layer_weights
: Prostorově oddělené váhy každé vrstvy stylu ke ztrátě. Výchozí:0.2 0.2 0.2 0.2 0.2
-
--original_colors
: Logický příznak určující, zda se přenáší styl, ale ne barvy: Barevné prostory (YUV, YCrCb, CIE L*u*v*, CIE L*a*b*) pro převod jasové shody na původní barvy. Volby:yuv
,ycrcb
,luv
,lab
. Výchozí hodnota:yuv
-
--style_mask
: Logický příznak určující, zda se styl přenáší do maskovaných oblastí. -
--style_mask_imgs
: Názvy souborů obrázků masky stylu (příklad:face_mask.png
). Chcete-li použít více obrazů masky stylu, předejte seznam oddělený mezerou. Příklad:--style_mask_imgs face_mask.png face_mask_inv.png
-
--noise_ratio
: Hodnota interpolace mezi obrazem obsahu a obrazem šumu, pokud je síť inicializována pomocírandom
. Výchozí hodnota:1.0
-
--seed
: Semeno pro generátor náhodných čísel. Výchozí hodnota:0
-
--model_weights
: Váhy a zkreslení sítě VGG-19. Ke stažení zde. Výchozí:imagenet-vgg-verydeep-19.mat
-
--pooling_type
: Typ sdružování v konvoluční neuronové síti. Možnost volby:avg
,max
. Výchozí:avg
-
--device
: Zařízení GPU nebo CPU. Režim GPU je velmi doporučený, ale vyžaduje NVIDIA CUDA. Možné volby:/gpu:0
/cpu:0
. Výchozí hodnota:/gpu:0
-
--img_output_dir
: Adresář, do kterého se má zapisovat výstup. Výchozí:./image_output
-
--img_name
: Název výstupního souboru. Výchozí:result
-
--verbose
: Logický příznak určující, zda se mají příkazy vypisovat do konzoly.
Optimalizační argumenty
-
--optimizer
: Optimalizátor minimalizace ztrát. L-BFGS dává lepší výsledky. Adam využívá méně paměti. Možnost volby:lbfgs
,adam
. Výchozí hodnota:lbfgs
-
--learning_rate
: Parametr rychlosti učení pro optimalizátor Adam. Výchozí hodnota:1e0
-
--max_iterations
: Maximální počet iterací pro optimalizátor Adam nebo L-BFGS. Výchozí hodnota:1000
-
--print_iterations
: Počet iterací mezi tiskovými příkazy optimalizátoru. Výchozí hodnota:50
-
--content_loss_function
: Různé konstanty K ve ztrátové funkci obsahu. Volby:1
,2
,3
. Výchozí hodnota:1
Argumenty videosnímku
-
--video
: Logický příznak určující, zda uživatel vytváří video. -
--start_frame
: Číslo prvního snímku. Výchozí hodnota:1
-
--end_frame
: Číslo posledního snímku. Výchozí hodnota:1
-
--first_frame_type
: Obrázek použitý k inicializaci sítě během vykreslování prvního snímku. Možné volby:content
,random
,style
. Výchozí hodnota:random
-
--init_frame_type
: Obrázek použitý k inicializaci sítě během každého vykreslování po prvním snímku. Na výběr jsou následující možnosti:prev_warped
,prev
,content
,random
,style
. Výchozí hodnota:prev_warped
-
--video_input_dir
: Relativní nebo absolutní cesta k adresáři vstupních rámců. Výchozí hodnota:./video_input
-
--video_output_dir
: Relativní nebo absolutní cesta k adresáři, do kterého se budou zapisovat výstupní snímky. Výchozí:./video_output
-
--content_frame_frmt
: Formátovací řetězec vstupních snímků. Výchozí:frame_{}.png
-
--backward_optical_flow_frmt
: Formátovací řetězec souborů zpětného optického toku. Výchozí:backward_{}_{}.flo
-
--forward_optical_flow_frmt
: Formátovací řetězec souborů dopředného optického toku. Výchozí hodnota:forward_{}_{}.flo
-
--content_weights_frmt
: Formátovací řetězec souborů konzistence optického toku. Výchozí:reliable_{}_{}.txt
-
--prev_frame_indices
: Předchozí snímky, které se mají vzít v úvahu pro dlouhodobou časovou konzistenci. Výchozí hodnota:1
-
--first_frame_iterations
: Maximální počet iterací optimalizátoru prvního snímku. Výchozí hodnota:2000
-
--frame_iterations
: Maximální počet iterací optimalizátoru pro každý snímek po prvním snímku. Výchozí hodnota:800
Dotazy a chyby
Zasílejte dotazy nebo problémy:
Paměť
Ve výchozím nastavení používá neural-style-tf
pro konvoluce grafický procesor NVIDIA cuDNN a pro optimalizaci L-BFGS, které poskytují lepší a rychlejší výsledky, ale mohou spotřebovávat mnoho paměti. Spotřebu paměti můžete snížit následujícími způsoby:
- Použít Adama: Přidáním příznaku
--optimizer adam
můžete místo L-BFGS použít Adama. To by mělo výrazněsnížit využití paměti, ale pro dosažení dobrých výsledků bude nutné vyladit další parametry; zejména byste měliexperimentovat s různými hodnotami--learning_rate
,--content_weight
,--style_weight
- Zmenšit velikost obrázku:
Podrobnosti o implementaci
Všechny obrázky byly vykresleny na počítači s:
- CPU: Intel Core i7-6800K @ 3,40GHz × 12
- GPU: GeForce GTX 1080/PCIe/SSE2
- OS: NVIDIA GeForce GTX 1080/PCIe/SSE2
- :
- CUDA: 8.0
- python: 2.7.12
- tensorflow: 0.10.0rc
- opencv: 2.4.9.1
Poděkování
Implementace vychází z projektů:
- Implementace jazyka Torch (Lua) ‚neural-style‘ od jcjohnson
- Implementace jazyka Torch (Lua) ‚artistic-videos‘ od manuelruder
Zdrojové videosnímky byly získány z:
- MPI Sintel Flow Dataset
Umělecké snímky byly vytvořeny moderními umělci:
- Alex Grey
- Minjae Lee
- Leonid Afremov
- Françoise Nielly
- James Jean
- Ben Giles
- Callie Fink
- H.R. Giger
- Voka
Umělecké obrazy vytvořili populární historičtí umělci:
- Vincent Van Gogh
- Wassily Kandinsky
- Georgia O’Keeffe
- Jean-Michel Basquiat
- Édouard Manet
- Pablo Picasso
- Joseph Mallord William Turner
- Frida Kahlo
Skripty shellu Bash pro testování vytvořil můj bratr Sheldon Smith.
Citace
Pokud se vám tento kód bude hodit pro váš výzkum, citujte prosím:
@misc{Smith2016, author = {Smith, Cameron}, title = {neural-style-tf}, year = {2016}, publisher = {GitHub}, journal = {GitHub repository}, howpublished = {\url{https://github.com/cysmith/neural-style-tf}},}
.