კომპიუტერული ხედვა Jupyter ნოუთბუქი · TensorFlow

სტილის ტრანსფერი

ეს არის პრაქტიკული ნოუთბუქი. წაიკითხე კოდი და შედეგები აქ, ან გაუშვი ინტერაქტიულად Google Colab-ში ან Jupyter-ში.

ქვემოთ მოყვანილი მაგალითი არის შთაგონებული ამ ბლოგის პოსტით და ბევრი კოდი არის ნასესხები იქიდან. სტილის გადაცემის კიდევ ერთი კარგი მაგალითი 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>

ეს გაკვეთილი არის Microsoft “AI for Beginners” კურსის ქართული თარგმანი, გავრცელებული MIT ლიცენზიით.