ქვემოთ მოყვანილი მაგალითი არის შთაგონებული ამ ბლოგის პოსტით და ბევრი კოდი არის ნასესხები იქიდან. სტილის გადაცემის კიდევ ერთი კარგი მაგალითი CNTK ჩარჩოს გამოყენებით არის აქ. აქ არის ორიგინალური ნაშრომი მხატვრული სტილის ტრანსფერი-ზე.
სტილის გადაცემის ძირითადი იდეები შემდეგია:
- თეთრი ხმაურიდან დაწყებული, ჩვენ ვცდილობთ მიმდინარე სურათის $x$-ის ოპტიმიზაციას, რათა მინიმუმამდე დავიყვანოთ დაკარგვის ფუნქცია
- დაკარგვის ფუნქცია შედგება სამი კომპონენტისგან $\mathcal{L(x)} = \alpha\mathcal{L}_c(x,i) + \beta\mathcal{L}_s(x,s)+\gamma\mathcal{L}_t(x)$
- $\mathcal{L}_c$ - შინაარსის დაკარგვა - აჩვენებს, რამდენად ახლოსაა მიმდინარე სურათი $x$ ორიგინალ სურათთან $i$
- $\mathcal{L}_s$ - სტილის დაკარგვა - გვიჩვენებს, რამდენად ახლოსაა მიმდინარე სურათი $x$ სურათის სტილისთვის $s$
- $\mathcal{L}_t$ - ვარიაციის სრული დანაკარგი (ჩვენ არ განვიხილავთ მას ჩვენს მაგალითში) - დარწმუნდება, რომ მიღებული სურათი არის გლუვი, ანუ ის აჩვენებს სურათის მეზობელი პიქსელების საშუალო კვადრატულ შეცდომას $x$
დაკარგვის ეს ფუნქციები უნდა იყოს შემუშავებული ჭკვიანურად, ისე, რომ მაგალითად სტილის დაკარგვა შეესაბამებოდეს სურათების მსგავს სტილებს და არა რეალურ შინაარსს. ამისათვის ჩვენ შევადარებთ CNN-ის რამდენიმე ღრმა მახასიათებლის ფენას, რომელიც ათვალიერებს სურათს.
დავიწყოთ რამდენიმე სურათის ჩატვირთვით:
იტვირთება…გამოტანა
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 210k 100 210k 0 0 208k 0 0:00:01 0:00:01 --:--:-- 208k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 131k 100 131k 0 0 184k 0 --:--:-- --:--:-- --:--:-- 185k
იტვირთება…მოდით, ავტვირთოთ ეს სურათები და შევცვალოთ მათი ზომა $512\times512$-მდე. ასევე, ჩვენ გამოვქმნით შედეგად გამოსახულებას img_result შემთხვევითი მასივის სახით.
იტვირთება…გამოტანა

იტვირთება…იტვირთება…სტილის დაკარგვისა და შინაარსის დაკარგვის გამოსათვლელად, ჩვენ უნდა ვიმუშაოთ CNN-ის მიერ ამოღებულ ფუნქციების სივრცეში. ჩვენ შეგვიძლია გამოვიყენოთ სხვადასხვა CNN არქიტექტურა, მაგრამ სიმარტივისთვის ჩვენ ავირჩევთ VGG-16-ს, წინასწარ მომზადებულ ImageNet-ზე.
იტვირთება…მოდით შევხედოთ მოდელის არქიტექტურას:
იტვირთება…გამოტანა
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_3 (InputLayer) (None, None, None, 3) 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, None, None, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, None, None, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, None, None, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, None, None, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, None, None, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, None, None, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, None, None, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, None, None, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, None, None, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, None, None, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, None, None, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, None, None, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, None, None, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, None, None, 512) 0
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
_________________________________________________________________
შინაარსის დაკარგვა
შინაარსის დაკარგვა აჩვენებს, რამდენად ახლოსაა ჩვენი ამჟამინდელი სურათი $x$ თავდაპირველ სურათთან. ის უყურებს შუალედურ ფუნქციების ფენებს CNN-ში და ითვლის კვადრატულ შეცდომას. შიგთავსის დაკარგვა $l$ ფენაზე განისაზღვრება როგორც $$ \mathcal{L}c = {1\over2}\sum{i,j} (F_{ij}^{(l)}-P_{ij}^{(l)})^2 $$ სადაც $F^{(l)}$ და $P^{(l)}$ -- მახასიათებლები $l$-ზე.
იტვირთება…ვნახოთ, როგორ მოქმედებს სხვადასხვა ფენის ფუნქციები სურათზე. ამისათვის ჩვენ შევეცდებით მინიმუმამდე დავიყვანოთ შინაარსის დაკარგვა მხოლოდ ერთი ფენისთვის. ჩვენ გამოვიყენებთ fmin_l_bfgs_b ფუნქციას SciPy-დან, რომელიც იღებს ფუნქციის მინიმიზაციას და მის გრადიენტს (ჩვენს შემთხვევაში, help_loss ფუნქცია აბრუნებს დაკარგვის ფუნქციასაც და გრადიენტსაც).
მნიშვნელოვანი: ჩვენს შემთხვევაში, ყველა გამოთვლა ხორციელდება GPU-aware TensorFlow ჩარჩოს გამოყენებით. helper_loss ფუნქცია აბრუნებს გამოთვლით გრაფიკს, რომელიც შეიძლება გამოყენებულ იქნას მოცემული სურათის დანაკარგის გამოსათვლელად და ის იყენებს K.gradients-ს გრადიენტების ავტომატურად გამოსათვლელად.
იტვირთება…იტვირთება…იტვირთება…გამოტანა
<matplotlib.figure.Figure at 0x7fb265464b00>იტვირთება…გამოტანა
<matplotlib.figure.Figure at 0x7fb2620b26d8>იტვირთება…გამოტანა
<matplotlib.figure.Figure at 0x7fb2620b2908>სტილის დაკარგვა
სტილის დაკარგვა არის Style Transfer-ის მთავარი იდეა. ჩვენ ვადარებთ არა რეალურ მახასიათებლებს, არამედ მათ გრამის მატრიცებს, რომლებიც განისაზღვრება როგორც $$G=A\ჯერ A^T$$
გრამ მატრიცა კორელაციური მატრიცის მსგავსია და ის გვიჩვენებს, თუ როგორ არის დამოკიდებული ზოგიერთი ფილტრი სხვებზე. Style Loss გამოითვლება, როგორც დანაკარგების ჯამი სხვადასხვა ფენებიდან, რომლებიც ხშირად განიხილება შეწონილი კოეფიციენტებით.
მთლიანი დაკარგვის ფუნქცია სტილის გადაცემისთვის არის შინაარსის დაკარგვის და სტილის დაკარგვის ჯამი.
იტვირთება…ეს ყველაფერი ერთად
აქ calualate_loss ფუნქცია გამოთვლის მთლიან დანაკარგს:
იტვირთება…ქვემოთ მოცემული კოდი ასრულებს დანაკარგის რეალურ ოპტიმიზაციას. გაითვალისწინეთ, რომ GPU-სთან ერთად ოპტიმიზაციას მნიშვნელოვანი დრო სჭირდება. შეგიძლიათ რამდენჯერმე გაუშვათ ქვემოთ მოცემული უჯრედი შედეგის გასაუმჯობესებლად.
იტვირთება…გამოტანა
<matplotlib.figure.Figure at 0x7f43494f9630>იტვირთება…გამოტანა
<matplotlib.figure.Figure at 0x7f28933be2d0>დაამატეთ ვარიაციის დაკარგვა
ვარიაციის დაკარგვა საშუალებას გვაძლევს გავხადოთ სურათი ნაკლებად ხმაურიანი მეზობელ პიქსელებს შორის სხვაობის მინიმიზაციის გზით.
იტვირთება…იტვირთება…გამოტანა
<matplotlib.figure.Figure at 0x7fb25130ba58>