-
Notifications
You must be signed in to change notification settings - Fork 257
/
Copy pathneural_style_tutorial.html
1126 lines (903 loc) · 84.9 KB
/
neural_style_tutorial.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Neural Transfer Using PyTorch — PyTorch Tutorials 1.9.0+cu102 documentation</title>
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<!-- <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> -->
<link rel="stylesheet" href="../_static/copybutton.css" type="text/css" />
<link rel="stylesheet" href="../_static/gallery.css" type="text/css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.0-beta/dist/katex.min.css" type="text/css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.css" type="text/css" />
<link rel="stylesheet" href="../_static/katex-math.css" type="text/css" />
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<script src="../_static/js/modernizr.min.js"></script>
<!-- Preload the theme fonts -->
<link rel="preload" href="../_static/fonts/FreightSans/freight-sans-book.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/FreightSans/freight-sans-medium.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/IBMPlexMono/IBMPlexMono-Medium.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/FreightSans/freight-sans-bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/FreightSans/freight-sans-medium-italic.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<!-- Preload the katex fonts -->
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Math-Italic.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Main-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Main-Bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size1-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size4-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size2-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size3-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Caligraphic-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.2/css/all.css" integrity="sha384-vSIIfh2YWi9wW0r9iZe7RJPrKwp6bG+s9QZMoITbCckVJqGCCRhc+ccxNcdpHuYu" crossorigin="anonymous">
</head>
<div class="container-fluid header-holder tutorials-header" id="header-holder">
<div class="container">
<div class="header-container">
<a class="header-logo" href="https://pytorch.kr/" aria-label="PyTorch"></a>
<div class="main-menu">
<ul>
<li>
<a href="https://pytorch.kr/get-started">시작하기</a>
</li>
<li class="active">
<a href="https://tutorials.pytorch.kr">튜토리얼</a>
</li>
<li>
<a href="https://pytorch.kr/hub">허브</a>
</li>
<li>
<a href="https://discuss.pytorch.kr">커뮤니티</a>
</li>
</ul>
</div>
<a class="main-menu-open-button" href="#" data-behavior="open-mobile-menu"></a>
</div>
</div>
</div>
<body class="pytorch-body">
<div class="table-of-contents-link-wrapper">
<span>Table of Contents</span>
<a href="#" class="toggle-table-of-contents" data-behavior="toggle-table-of-contents"></a>
</div>
<nav data-toggle="wy-nav-shift" class="pytorch-left-menu" id="pytorch-left-menu">
<div class="pytorch-side-scroll">
<div class="pytorch-menu pytorch-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<div class="pytorch-left-menu-search">
<div class="version">
1.9.0+cu102
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search Tutorials" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<p class="caption"><span class="caption-text">파이토치(PyTorch) 레시피</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../recipes/recipes_index.html">모든 레시피 보기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../prototype/prototype_index.html">모든 프로토타입 레시피 보기</a></li>
</ul>
<p class="caption"><span class="caption-text">파이토치(PyTorch) 시작하기</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../beginner/basics/intro.html">파이토치(PyTorch) 기본 익히기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/basics/quickstart_tutorial.html">빠른 시작(Quickstart)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/basics/tensorqs_tutorial.html">텐서(Tensor)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/basics/data_tutorial.html">Dataset과 Dataloader</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/basics/transforms_tutorial.html">변형(Transform)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/basics/buildmodel_tutorial.html">신경망 모델 구성하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/basics/autogradqs_tutorial.html"><code class="docutils literal notranslate"><span class="pre">torch.autograd</span></code>를 사용한 자동 미분</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/basics/optimization_tutorial.html">모델 매개변수 최적화하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/basics/saveloadrun_tutorial.html">모델 저장하고 불러오기</a></li>
</ul>
<p class="caption"><span class="caption-text">파이토치(PyTorch) 배우기</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../beginner/deep_learning_60min_blitz.html">PyTorch로 딥러닝하기: 60분만에 끝장내기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/pytorch_with_examples.html">예제로 배우는 파이토치(PyTorch)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/nn_tutorial.html"><cite>torch.nn</cite> 이 <em>실제로</em> 무엇인가요?</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/tensorboard_tutorial.html">TensorBoard로 모델, 데이터, 학습 시각화하기</a></li>
</ul>
<p class="caption"><span class="caption-text">이미지/비디오</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/torchvision_tutorial.html">TorchVision 객체 검출 미세조정(Finetuning) 튜토리얼</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/transfer_learning_tutorial.html">컴퓨터 비전(Vision)을 위한 전이학습(Transfer Learning)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/fgsm_tutorial.html">적대적 예제 생성(Adversarial Example Generation)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/dcgan_faces_tutorial.html">DCGAN Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/vt_tutorial.html">Optimizing Vision Transformer Model for Deployment</a></li>
</ul>
<p class="caption"><span class="caption-text">오디오</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../beginner/audio_preprocessing_tutorial.html">Audio manipulation with torchaudio</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/audio_preprocessing_tutorial.html#audio-i-o">Audio I/O</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/audio_preprocessing_tutorial.html#resampling">Resampling</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/audio_preprocessing_tutorial.html#data-augmentation">Data Augmentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/audio_preprocessing_tutorial.html#feature-extractions">Feature Extractions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/audio_preprocessing_tutorial.html#feature-augmentation">Feature Augmentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/audio_preprocessing_tutorial.html#datasets">Datasets</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/speech_command_recognition_with_torchaudio_tutorial.html">Speech Command Recognition with torchaudio</a></li>
</ul>
<p class="caption"><span class="caption-text">텍스트</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../beginner/transformer_tutorial.html">nn.Transformer 와 TorchText 로 시퀀스-투-시퀀스(Sequence-to-Sequence) 모델링하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/char_rnn_classification_tutorial.html">기초부터 시작하는 NLP: 문자-단위 RNN으로 이름 분류하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/char_rnn_generation_tutorial.html">기초부터 시작하는 NLP: 문자-단위 RNN으로 이름 생성하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/seq2seq_translation_tutorial.html">기초부터 시작하는 NLP: Sequence to Sequence 네트워크와 Attention을 이용한 번역</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/text_sentiment_ngrams_tutorial.html">torchtext 라이브러리로 텍스트 분류하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/translation_transformer.html">nn.Transformer와 torchtext로 언어 번역하기</a></li>
</ul>
<p class="caption"><span class="caption-text">강화학습</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/reinforcement_q_learning.html">강화 학습 (DQN) 튜토리얼</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/mario_rl_tutorial.html">Train a Mario-playing RL Agent</a></li>
</ul>
<p class="caption"><span class="caption-text">PyTorch 모델을 프로덕션 환경에 배포하기</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/flask_rest_api_tutorial.html">Flask를 사용하여 Python에서 PyTorch를 REST API로 배포하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/Intro_to_TorchScript_tutorial.html">TorchScript 소개</a></li>
<li class="toctree-l1"><a class="reference internal" href="cpp_export.html">C++에서 TorchScript 모델 로딩하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="super_resolution_with_onnxruntime.html">(선택) PyTorch 모델을 ONNX으로 변환하고 ONNX 런타임에서 실행하기</a></li>
</ul>
<p class="caption"><span class="caption-text">Code Transforms with FX</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/fx_conv_bn_fuser.html">(beta) Building a Convolution/Batch Norm fuser in FX</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/fx_profiling_tutorial.html">(beta) Building a Simple CPU Performance Profiler with FX</a></li>
</ul>
<p class="caption"><span class="caption-text">프론트엔드 API</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/memory_format_tutorial.html">(베타) PyTorch를 사용한 Channels Last 메모리 형식</a></li>
<li class="toctree-l1"><a class="reference internal" href="cpp_frontend.html">Using the PyTorch C++ Frontend</a></li>
<li class="toctree-l1"><a class="reference internal" href="torch-script-parallelism.html">Dynamic Parallelism in TorchScript</a></li>
<li class="toctree-l1"><a class="reference internal" href="cpp_autograd.html">Autograd in C++ Frontend</a></li>
</ul>
<p class="caption"><span class="caption-text">PyTorch 확장하기</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="cpp_extension.html">Custom C++ and CUDA Extensions</a></li>
<li class="toctree-l1"><a class="reference internal" href="torch_script_custom_ops.html">Extending TorchScript with Custom C++ Operators</a></li>
<li class="toctree-l1"><a class="reference internal" href="torch_script_custom_classes.html">Extending TorchScript with Custom C++ Classes</a></li>
<li class="toctree-l1"><a class="reference internal" href="dispatcher.html">Registering a Dispatched Operator in C++</a></li>
<li class="toctree-l1"><a class="reference internal" href="extend_dispatcher.html">Extending dispatcher for a new backend in C++</a></li>
</ul>
<p class="caption"><span class="caption-text">모델 최적화</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../beginner/profiler.html">Profiling your PyTorch Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/tensorboard_profiler_tutorial.html">PyTorch Profiler With TensorBoard</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/hyperparameter_tuning_tutorial.html">Hyperparameter tuning with Ray Tune</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/parametrizations.html">Parametrizations Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/pruning_tutorial.html">가지치기 기법(Pruning) 튜토리얼</a></li>
<li class="toctree-l1"><a class="reference internal" href="dynamic_quantization_tutorial.html">(베타) LSTM 기반 단어 단위 언어 모델의 동적 양자화</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/dynamic_quantization_bert_tutorial.html">(베타) BERT 모델 동적 양자화하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/quantized_transfer_learning_tutorial.html">(베타) 컴퓨터 비전 튜토리얼을 위한 양자화된 전이학습(Quantized Transfer Learning)</a></li>
<li class="toctree-l1"><a class="reference internal" href="static_quantization_tutorial.html">(beta) Static Quantization with Eager Mode in PyTorch</a></li>
</ul>
<p class="caption"><span class="caption-text">병렬 및 분산 학습</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../beginner/dist_overview.html">PyTorch Distributed Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/model_parallel_tutorial.html">단일 머신을 사용한 모델 병렬화 모범 사례</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/ddp_tutorial.html">Getting Started with Distributed Data Parallel</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/dist_tuto.html">PyTorch로 분산 어플리케이션 개발하기</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/rpc_tutorial.html">Getting Started with Distributed RPC Framework</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/rpc_param_server_tutorial.html">Implementing a Parameter Server Using Distributed RPC Framework</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/dist_pipeline_parallel_tutorial.html">Distributed Pipeline Parallelism Using RPC</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/rpc_async_execution.html">Implementing Batch RPC Processing Using Asynchronous Executions</a></li>
<li class="toctree-l1"><a class="reference internal" href="rpc_ddp_tutorial.html">Combining Distributed DataParallel with Distributed RPC Framework</a></li>
<li class="toctree-l1"><a class="reference internal" href="../intermediate/pipeline_tutorial.html">Training Transformer models using Pipeline Parallelism</a></li>
<li class="toctree-l1"><a class="reference internal" href="ddp_pipeline.html">Training Transformer models using Distributed Data Parallel and Pipeline Parallelism</a></li>
</ul>
<p class="caption"><span class="caption-text">Mobile</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../beginner/deeplabv3_on_ios.html">Image Segmentation DeepLabV3 on iOS</a></li>
<li class="toctree-l1"><a class="reference internal" href="../beginner/deeplabv3_on_android.html">Image Segmentation DeepLabV3 on Android</a></li>
</ul>
</div>
</div>
</nav>
<div class="pytorch-container">
<div class="pytorch-page-level-bar" id="pytorch-page-level-bar">
<div class="pytorch-breadcrumbs-wrapper">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="pytorch-breadcrumbs">
<li>
<a href="../index.html">
Tutorials
</a> >
</li>
<li>Neural Transfer Using PyTorch</li>
<li class="pytorch-breadcrumbs-aside">
<a href="../_sources/advanced/neural_style_tutorial.rst.txt" rel="nofollow"><img src="../_static/images/view-page-source-icon.svg"></a>
</li>
</ul>
</div>
</div>
<div class="pytorch-shortcuts-wrapper" id="pytorch-shortcuts-wrapper">
Shortcuts
</div>
</div>
<section data-toggle="wy-nav-shift" id="pytorch-content-wrap" class="pytorch-content-wrap">
<div class="pytorch-content-left">
<div class="pytorch-call-to-action-links">
<div id="tutorial-type">advanced/neural_style_tutorial</div>
<div id="google-colab-link">
<img class="call-to-action-img" src="../_static/images/pytorch-colab.svg"/>
<div class="call-to-action-desktop-view">Run in Google Colab</div>
<div class="call-to-action-mobile-view">Colab</div>
</div>
<div id="download-notebook-link">
<img class="call-to-action-notebook-img" src="../_static/images/pytorch-download.svg"/>
<div class="call-to-action-desktop-view">Download Notebook</div>
<div class="call-to-action-mobile-view">Notebook</div>
</div>
<div id="github-view-link">
<img class="call-to-action-img" src="../_static/images/pytorch-github.svg"/>
<div class="call-to-action-desktop-view">View on GitHub</div>
<div class="call-to-action-mobile-view">GitHub</div>
</div>
</div>
<div class="rst-content">
<div role="main" class="main-content" itemscope="itemscope" itemtype="http://schema.org/Article">
<article itemprop="articleBody" id="pytorch-article" class="pytorch-article">
<div class="sphx-glr-download-link-note admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Click <a class="reference internal" href="#sphx-glr-download-advanced-neural-style-tutorial-py"><span class="std std-ref">here</span></a> to download the full example code</p>
</div>
<div class="sphx-glr-example-title section" id="neural-transfer-using-pytorch">
<span id="sphx-glr-advanced-neural-style-tutorial-py"></span><h1>Neural Transfer Using PyTorch<a class="headerlink" href="#neural-transfer-using-pytorch" title="Permalink to this headline">¶</a></h1>
<p><strong>Author</strong>: <a class="reference external" href="https://alexis-jacq.github.io">Alexis Jacq</a></p>
<p><strong>Edited by</strong>: <a class="reference external" href="https://github.com/winston6">Winston Herring</a></p>
<div class="section" id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
<p>This tutorial explains how to implement the <a class="reference external" href="https://arxiv.org/abs/1508.06576">Neural-Style algorithm</a>
developed by Leon A. Gatys, Alexander S. Ecker and Matthias Bethge.
Neural-Style, or Neural-Transfer, allows you to take an image and
reproduce it with a new artistic style. The algorithm takes three images,
an input image, a content-image, and a style-image, and changes the input
to resemble the content of the content-image and the artistic style of the style-image.</p>
<div class="figure">
<img alt="content1" src="../_images/neuralstyle.png" />
</div>
</div>
<div class="section" id="underlying-principle">
<h2>Underlying Principle<a class="headerlink" href="#underlying-principle" title="Permalink to this headline">¶</a></h2>
<p>The principle is simple: we define two distances, one for the content
(<span class="math">\(D_C\)</span>) and one for the style (<span class="math">\(D_S\)</span>). <span class="math">\(D_C\)</span> measures how different the content
is between two images while <span class="math">\(D_S\)</span> measures how different the style is
between two images. Then, we take a third image, the input, and
transform it to minimize both its content-distance with the
content-image and its style-distance with the style-image. Now we can
import the necessary packages and begin the neural transfer.</p>
</div>
<div class="section" id="importing-packages-and-selecting-a-device">
<h2>Importing Packages and Selecting a Device<a class="headerlink" href="#importing-packages-and-selecting-a-device" title="Permalink to this headline">¶</a></h2>
<p>Below is a list of the packages needed to implement the neural transfer.</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">torch</span></code>, <code class="docutils literal notranslate"><span class="pre">torch.nn</span></code>, <code class="docutils literal notranslate"><span class="pre">numpy</span></code> (indispensables packages for
neural networks with PyTorch)</li>
<li><code class="docutils literal notranslate"><span class="pre">torch.optim</span></code> (efficient gradient descents)</li>
<li><code class="docutils literal notranslate"><span class="pre">PIL</span></code>, <code class="docutils literal notranslate"><span class="pre">PIL.Image</span></code>, <code class="docutils literal notranslate"><span class="pre">matplotlib.pyplot</span></code> (load and display
images)</li>
<li><code class="docutils literal notranslate"><span class="pre">torchvision.transforms</span></code> (transform PIL images into tensors)</li>
<li><code class="docutils literal notranslate"><span class="pre">torchvision.models</span></code> (train or load pre-trained models)</li>
<li><code class="docutils literal notranslate"><span class="pre">copy</span></code> (to deep copy the models; system package)</li>
</ul>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">print_function</span>
<span class="kn">import</span> <span class="nn">torch</span>
<span class="kn">import</span> <span class="nn">torch.nn</span> <span class="k">as</span> <span class="nn">nn</span>
<span class="kn">import</span> <span class="nn">torch.nn.functional</span> <span class="k">as</span> <span class="nn">F</span>
<span class="kn">import</span> <span class="nn">torch.optim</span> <span class="k">as</span> <span class="nn">optim</span>
<span class="kn">from</span> <span class="nn">PIL</span> <span class="kn">import</span> <span class="n">Image</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
<span class="kn">import</span> <span class="nn">torchvision.transforms</span> <span class="k">as</span> <span class="nn">transforms</span>
<span class="kn">import</span> <span class="nn">torchvision.models</span> <span class="k">as</span> <span class="nn">models</span>
<span class="kn">import</span> <span class="nn">copy</span>
</pre></div>
</div>
<p>Next, we need to choose which device to run the network on and import the
content and style images. Running the neural transfer algorithm on large
images takes longer and will go much faster when running on a GPU. We can
use <code class="docutils literal notranslate"><span class="pre">torch.cuda.is_available()</span></code> to detect if there is a GPU available.
Next, we set the <code class="docutils literal notranslate"><span class="pre">torch.device</span></code> for use throughout the tutorial. Also the <code class="docutils literal notranslate"><span class="pre">.to(device)</span></code>
method is used to move tensors or modules to a desired device.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">device</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">device</span><span class="p">(</span><span class="s2">"cuda"</span> <span class="k">if</span> <span class="n">torch</span><span class="o">.</span><span class="n">cuda</span><span class="o">.</span><span class="n">is_available</span><span class="p">()</span> <span class="k">else</span> <span class="s2">"cpu"</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="loading-the-images">
<h2>Loading the Images<a class="headerlink" href="#loading-the-images" title="Permalink to this headline">¶</a></h2>
<p>Now we will import the style and content images. The original PIL images have values between 0 and 255, but when
transformed into torch tensors, their values are converted to be between
0 and 1. The images also need to be resized to have the same dimensions.
An important detail to note is that neural networks from the
torch library are trained with tensor values ranging from 0 to 1. If you
try to feed the networks with 0 to 255 tensor images, then the activated
feature maps will be unable to sense the intended content and style.
However, pre-trained networks from the Caffe library are trained with 0
to 255 tensor images.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Here are links to download the images required to run the tutorial:
<a class="reference external" href="https://tutorials.pytorch.kr/_static/img/neural-style/picasso.jpg">picasso.jpg</a> and
<a class="reference external" href="https://tutorials.pytorch.kr/_static/img/neural-style/dancing.jpg">dancing.jpg</a>.
Download these two images and add them to a directory
with name <code class="docutils literal notranslate"><span class="pre">images</span></code> in your current working directory.</p>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># desired size of the output image</span>
<span class="n">imsize</span> <span class="o">=</span> <span class="mi">512</span> <span class="k">if</span> <span class="n">torch</span><span class="o">.</span><span class="n">cuda</span><span class="o">.</span><span class="n">is_available</span><span class="p">()</span> <span class="k">else</span> <span class="mi">128</span> <span class="c1"># use small size if no gpu</span>
<span class="n">loader</span> <span class="o">=</span> <span class="n">transforms</span><span class="o">.</span><span class="n">Compose</span><span class="p">([</span>
<span class="n">transforms</span><span class="o">.</span><span class="n">Resize</span><span class="p">(</span><span class="n">imsize</span><span class="p">),</span> <span class="c1"># scale imported image</span>
<span class="n">transforms</span><span class="o">.</span><span class="n">ToTensor</span><span class="p">()])</span> <span class="c1"># transform it into a torch tensor</span>
<span class="k">def</span> <span class="nf">image_loader</span><span class="p">(</span><span class="n">image_name</span><span class="p">):</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">image_name</span><span class="p">)</span>
<span class="c1"># fake batch dimension required to fit network's input dimensions</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">loader</span><span class="p">(</span><span class="n">image</span><span class="p">)</span><span class="o">.</span><span class="n">unsqueeze</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="k">return</span> <span class="n">image</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="n">device</span><span class="p">,</span> <span class="n">torch</span><span class="o">.</span><span class="n">float</span><span class="p">)</span>
<span class="n">style_img</span> <span class="o">=</span> <span class="n">image_loader</span><span class="p">(</span><span class="s2">"./data/images/neural-style/picasso.jpg"</span><span class="p">)</span>
<span class="n">content_img</span> <span class="o">=</span> <span class="n">image_loader</span><span class="p">(</span><span class="s2">"./data/images/neural-style/dancing.jpg"</span><span class="p">)</span>
<span class="k">assert</span> <span class="n">style_img</span><span class="o">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="n">content_img</span><span class="o">.</span><span class="n">size</span><span class="p">(),</span> \
<span class="s2">"we need to import style and content images of the same size"</span>
</pre></div>
</div>
<p>Now, let’s create a function that displays an image by reconverting a
copy of it to PIL format and displaying the copy using
<code class="docutils literal notranslate"><span class="pre">plt.imshow</span></code>. We will try displaying the content and style images
to ensure they were imported correctly.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">unloader</span> <span class="o">=</span> <span class="n">transforms</span><span class="o">.</span><span class="n">ToPILImage</span><span class="p">()</span> <span class="c1"># reconvert into PIL image</span>
<span class="n">plt</span><span class="o">.</span><span class="n">ion</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">imshow</span><span class="p">(</span><span class="n">tensor</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">tensor</span><span class="o">.</span><span class="n">cpu</span><span class="p">()</span><span class="o">.</span><span class="n">clone</span><span class="p">()</span> <span class="c1"># we clone the tensor to not do changes on it</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># remove the fake batch dimension</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">unloader</span><span class="p">(</span><span class="n">image</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">image</span><span class="p">)</span>
<span class="k">if</span> <span class="n">title</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">pause</span><span class="p">(</span><span class="mf">0.001</span><span class="p">)</span> <span class="c1"># pause a bit so that plots are updated</span>
<span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">()</span>
<span class="n">imshow</span><span class="p">(</span><span class="n">style_img</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s1">'Style Image'</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">()</span>
<span class="n">imshow</span><span class="p">(</span><span class="n">content_img</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s1">'Content Image'</span><span class="p">)</span>
</pre></div>
</div>
<ul class="sphx-glr-horizontal">
<li><img alt="../_images/sphx_glr_neural_style_tutorial_001.png" class="sphx-glr-multi-img first" src="../_images/sphx_glr_neural_style_tutorial_001.png" />
</li>
<li><img alt="../_images/sphx_glr_neural_style_tutorial_002.png" class="sphx-glr-multi-img first" src="../_images/sphx_glr_neural_style_tutorial_002.png" />
</li>
</ul>
</div>
<div class="section" id="loss-functions">
<h2>Loss Functions<a class="headerlink" href="#loss-functions" title="Permalink to this headline">¶</a></h2>
<div class="section" id="content-loss">
<h3>Content Loss<a class="headerlink" href="#content-loss" title="Permalink to this headline">¶</a></h3>
<p>The content loss is a function that represents a weighted version of the
content distance for an individual layer. The function takes the feature
maps <span class="math">\(F_{XL}\)</span> of a layer <span class="math">\(L\)</span> in a network processing input <span class="math">\(X\)</span> and returns the
weighted content distance <span class="math">\(w_{CL}.D_C^L(X,C)\)</span> between the image <span class="math">\(X\)</span> and the
content image <span class="math">\(C\)</span>. The feature maps of the content image(<span class="math">\(F_{CL}\)</span>) must be
known by the function in order to calculate the content distance. We
implement this function as a torch module with a constructor that takes
<span class="math">\(F_{CL}\)</span> as an input. The distance <span class="math">\(\|F_{XL} - F_{CL}\|^2\)</span> is the mean square error
between the two sets of feature maps, and can be computed using <code class="docutils literal notranslate"><span class="pre">nn.MSELoss</span></code>.</p>
<p>We will add this content loss module directly after the convolution
layer(s) that are being used to compute the content distance. This way
each time the network is fed an input image the content losses will be
computed at the desired layers and because of auto grad, all the
gradients will be computed. Now, in order to make the content loss layer
transparent we must define a <code class="docutils literal notranslate"><span class="pre">forward</span></code> method that computes the content
loss and then returns the layer’s input. The computed loss is saved as a
parameter of the module.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">ContentLoss</span><span class="p">(</span><span class="n">nn</span><span class="o">.</span><span class="n">Module</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">target</span><span class="p">,):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">ContentLoss</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
<span class="c1"># we 'detach' the target content from the tree used</span>
<span class="c1"># to dynamically compute the gradient: this is a stated value,</span>
<span class="c1"># not a variable. Otherwise the forward method of the criterion</span>
<span class="c1"># will throw an error.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="o">.</span><span class="n">detach</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">input</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">loss</span> <span class="o">=</span> <span class="n">F</span><span class="o">.</span><span class="n">mse_loss</span><span class="p">(</span><span class="nb">input</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">input</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last"><strong>Important detail</strong>: although this module is named <code class="docutils literal notranslate"><span class="pre">ContentLoss</span></code>, it
is not a true PyTorch Loss function. If you want to define your content
loss as a PyTorch Loss function, you have to create a PyTorch autograd function
to recompute/implement the gradient manually in the <code class="docutils literal notranslate"><span class="pre">backward</span></code>
method.</p>
</div>
</div>
<div class="section" id="style-loss">
<h3>Style Loss<a class="headerlink" href="#style-loss" title="Permalink to this headline">¶</a></h3>
<p>The style loss module is implemented similarly to the content loss
module. It will act as a transparent layer in a
network that computes the style loss of that layer. In order to
calculate the style loss, we need to compute the gram matrix <span class="math">\(G_{XL}\)</span>. A gram
matrix is the result of multiplying a given matrix by its transposed
matrix. In this application the given matrix is a reshaped version of
the feature maps <span class="math">\(F_{XL}\)</span> of a layer <span class="math">\(L\)</span>. <span class="math">\(F_{XL}\)</span> is reshaped to form <span class="math">\(\hat{F}_{XL}\)</span>, a <span class="math">\(K\)</span>x<span class="math">\(N\)</span>
matrix, where <span class="math">\(K\)</span> is the number of feature maps at layer <span class="math">\(L\)</span> and <span class="math">\(N\)</span> is the
length of any vectorized feature map <span class="math">\(F_{XL}^k\)</span>. For example, the first line
of <span class="math">\(\hat{F}_{XL}\)</span> corresponds to the first vectorized feature map <span class="math">\(F_{XL}^1\)</span>.</p>
<p>Finally, the gram matrix must be normalized by dividing each element by
the total number of elements in the matrix. This normalization is to
counteract the fact that <span class="math">\(\hat{F}_{XL}\)</span> matrices with a large <span class="math">\(N\)</span> dimension yield
larger values in the Gram matrix. These larger values will cause the
first layers (before pooling layers) to have a larger impact during the
gradient descent. Style features tend to be in the deeper layers of the
network so this normalization step is crucial.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">gram_matrix</span><span class="p">(</span><span class="nb">input</span><span class="p">):</span>
<span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="nb">input</span><span class="o">.</span><span class="n">size</span><span class="p">()</span> <span class="c1"># a=batch size(=1)</span>
<span class="c1"># b=number of feature maps</span>
<span class="c1"># (c,d)=dimensions of a f. map (N=c*d)</span>
<span class="n">features</span> <span class="o">=</span> <span class="nb">input</span><span class="o">.</span><span class="n">view</span><span class="p">(</span><span class="n">a</span> <span class="o">*</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">*</span> <span class="n">d</span><span class="p">)</span> <span class="c1"># resise F_XL into \hat F_XL</span>
<span class="n">G</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">mm</span><span class="p">(</span><span class="n">features</span><span class="p">,</span> <span class="n">features</span><span class="o">.</span><span class="n">t</span><span class="p">())</span> <span class="c1"># compute the gram product</span>
<span class="c1"># we 'normalize' the values of the gram matrix</span>
<span class="c1"># by dividing by the number of element in each feature maps.</span>
<span class="k">return</span> <span class="n">G</span><span class="o">.</span><span class="n">div</span><span class="p">(</span><span class="n">a</span> <span class="o">*</span> <span class="n">b</span> <span class="o">*</span> <span class="n">c</span> <span class="o">*</span> <span class="n">d</span><span class="p">)</span>
</pre></div>
</div>
<p>Now the style loss module looks almost exactly like the content loss
module. The style distance is also computed using the mean square
error between <span class="math">\(G_{XL}\)</span> and <span class="math">\(G_{SL}\)</span>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">StyleLoss</span><span class="p">(</span><span class="n">nn</span><span class="o">.</span><span class="n">Module</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">target_feature</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">StyleLoss</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="o">=</span> <span class="n">gram_matrix</span><span class="p">(</span><span class="n">target_feature</span><span class="p">)</span><span class="o">.</span><span class="n">detach</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">input</span><span class="p">):</span>
<span class="n">G</span> <span class="o">=</span> <span class="n">gram_matrix</span><span class="p">(</span><span class="nb">input</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">loss</span> <span class="o">=</span> <span class="n">F</span><span class="o">.</span><span class="n">mse_loss</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">input</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="importing-the-model">
<h2>Importing the Model<a class="headerlink" href="#importing-the-model" title="Permalink to this headline">¶</a></h2>
<p>Now we need to import a pre-trained neural network. We will use a 19
layer VGG network like the one used in the paper.</p>
<p>PyTorch’s implementation of VGG is a module divided into two child
<code class="docutils literal notranslate"><span class="pre">Sequential</span></code> modules: <code class="docutils literal notranslate"><span class="pre">features</span></code> (containing convolution and pooling layers),
and <code class="docutils literal notranslate"><span class="pre">classifier</span></code> (containing fully connected layers). We will use the
<code class="docutils literal notranslate"><span class="pre">features</span></code> module because we need the output of the individual
convolution layers to measure content and style loss. Some layers have
different behavior during training than evaluation, so we must set the
network to evaluation mode using <code class="docutils literal notranslate"><span class="pre">.eval()</span></code>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cnn</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">vgg19</span><span class="p">(</span><span class="n">pretrained</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">features</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="n">device</span><span class="p">)</span><span class="o">.</span><span class="n">eval</span><span class="p">()</span>
</pre></div>
</div>
<p>Additionally, VGG networks are trained on images with each channel
normalized by mean=[0.485, 0.456, 0.406] and std=[0.229, 0.224, 0.225].
We will use them to normalize the image before sending it into the network.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cnn_normalization_mean</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">tensor</span><span class="p">([</span><span class="mf">0.485</span><span class="p">,</span> <span class="mf">0.456</span><span class="p">,</span> <span class="mf">0.406</span><span class="p">])</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="n">device</span><span class="p">)</span>
<span class="n">cnn_normalization_std</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">tensor</span><span class="p">([</span><span class="mf">0.229</span><span class="p">,</span> <span class="mf">0.224</span><span class="p">,</span> <span class="mf">0.225</span><span class="p">])</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="n">device</span><span class="p">)</span>
<span class="c1"># create a module to normalize input image so we can easily put it in a</span>
<span class="c1"># nn.Sequential</span>
<span class="k">class</span> <span class="nc">Normalization</span><span class="p">(</span><span class="n">nn</span><span class="o">.</span><span class="n">Module</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mean</span><span class="p">,</span> <span class="n">std</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">Normalization</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
<span class="c1"># .view the mean and std to make them [C x 1 x 1] so that they can</span>
<span class="c1"># directly work with image Tensor of shape [B x C x H x W].</span>
<span class="c1"># B is batch size. C is number of channels. H is height and W is width.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mean</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">tensor</span><span class="p">(</span><span class="n">mean</span><span class="p">)</span><span class="o">.</span><span class="n">view</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">std</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">tensor</span><span class="p">(</span><span class="n">std</span><span class="p">)</span><span class="o">.</span><span class="n">view</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">img</span><span class="p">):</span>
<span class="c1"># normalize img</span>
<span class="k">return</span> <span class="p">(</span><span class="n">img</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">mean</span><span class="p">)</span> <span class="o">/</span> <span class="bp">self</span><span class="o">.</span><span class="n">std</span>
</pre></div>
</div>
<p>A <code class="docutils literal notranslate"><span class="pre">Sequential</span></code> module contains an ordered list of child modules. For
instance, <code class="docutils literal notranslate"><span class="pre">vgg19.features</span></code> contains a sequence (Conv2d, ReLU, MaxPool2d,
Conv2d, ReLU…) aligned in the right order of depth. We need to add our
content loss and style loss layers immediately after the convolution
layer they are detecting. To do this we must create a new <code class="docutils literal notranslate"><span class="pre">Sequential</span></code>
module that has content loss and style loss modules correctly inserted.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># desired depth layers to compute style/content losses :</span>
<span class="n">content_layers_default</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'conv_4'</span><span class="p">]</span>
<span class="n">style_layers_default</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'conv_1'</span><span class="p">,</span> <span class="s1">'conv_2'</span><span class="p">,</span> <span class="s1">'conv_3'</span><span class="p">,</span> <span class="s1">'conv_4'</span><span class="p">,</span> <span class="s1">'conv_5'</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">get_style_model_and_losses</span><span class="p">(</span><span class="n">cnn</span><span class="p">,</span> <span class="n">normalization_mean</span><span class="p">,</span> <span class="n">normalization_std</span><span class="p">,</span>
<span class="n">style_img</span><span class="p">,</span> <span class="n">content_img</span><span class="p">,</span>
<span class="n">content_layers</span><span class="o">=</span><span class="n">content_layers_default</span><span class="p">,</span>
<span class="n">style_layers</span><span class="o">=</span><span class="n">style_layers_default</span><span class="p">):</span>
<span class="n">cnn</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">cnn</span><span class="p">)</span>
<span class="c1"># normalization module</span>
<span class="n">normalization</span> <span class="o">=</span> <span class="n">Normalization</span><span class="p">(</span><span class="n">normalization_mean</span><span class="p">,</span> <span class="n">normalization_std</span><span class="p">)</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="n">device</span><span class="p">)</span>
<span class="c1"># just in order to have an iterable access to or list of content/syle</span>
<span class="c1"># losses</span>
<span class="n">content_losses</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">style_losses</span> <span class="o">=</span> <span class="p">[]</span>
<span class="c1"># assuming that cnn is a nn.Sequential, so we make a new nn.Sequential</span>
<span class="c1"># to put in modules that are supposed to be activated sequentially</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">nn</span><span class="o">.</span><span class="n">Sequential</span><span class="p">(</span><span class="n">normalization</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># increment every time we see a conv</span>
<span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="n">cnn</span><span class="o">.</span><span class="n">children</span><span class="p">():</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">layer</span><span class="p">,</span> <span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">):</span>
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">name</span> <span class="o">=</span> <span class="s1">'conv_</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">layer</span><span class="p">,</span> <span class="n">nn</span><span class="o">.</span><span class="n">ReLU</span><span class="p">):</span>
<span class="n">name</span> <span class="o">=</span> <span class="s1">'relu_</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="c1"># The in-place version doesn't play very nicely with the ContentLoss</span>
<span class="c1"># and StyleLoss we insert below. So we replace with out-of-place</span>
<span class="c1"># ones here.</span>
<span class="n">layer</span> <span class="o">=</span> <span class="n">nn</span><span class="o">.</span><span class="n">ReLU</span><span class="p">(</span><span class="n">inplace</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">layer</span><span class="p">,</span> <span class="n">nn</span><span class="o">.</span><span class="n">MaxPool2d</span><span class="p">):</span>
<span class="n">name</span> <span class="o">=</span> <span class="s1">'pool_</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">layer</span><span class="p">,</span> <span class="n">nn</span><span class="o">.</span><span class="n">BatchNorm2d</span><span class="p">):</span>
<span class="n">name</span> <span class="o">=</span> <span class="s1">'bn_</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s1">'Unrecognized layer: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">layer</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">))</span>
<span class="n">model</span><span class="o">.</span><span class="n">add_module</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">layer</span><span class="p">)</span>
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">content_layers</span><span class="p">:</span>
<span class="c1"># add content loss:</span>
<span class="n">target</span> <span class="o">=</span> <span class="n">model</span><span class="p">(</span><span class="n">content_img</span><span class="p">)</span><span class="o">.</span><span class="n">detach</span><span class="p">()</span>
<span class="n">content_loss</span> <span class="o">=</span> <span class="n">ContentLoss</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
<span class="n">model</span><span class="o">.</span><span class="n">add_module</span><span class="p">(</span><span class="s2">"content_loss_</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="n">content_loss</span><span class="p">)</span>
<span class="n">content_losses</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">content_loss</span><span class="p">)</span>
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">style_layers</span><span class="p">:</span>
<span class="c1"># add style loss:</span>
<span class="n">target_feature</span> <span class="o">=</span> <span class="n">model</span><span class="p">(</span><span class="n">style_img</span><span class="p">)</span><span class="o">.</span><span class="n">detach</span><span class="p">()</span>
<span class="n">style_loss</span> <span class="o">=</span> <span class="n">StyleLoss</span><span class="p">(</span><span class="n">target_feature</span><span class="p">)</span>
<span class="n">model</span><span class="o">.</span><span class="n">add_module</span><span class="p">(</span><span class="s2">"style_loss_</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="n">style_loss</span><span class="p">)</span>
<span class="n">style_losses</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">style_loss</span><span class="p">)</span>
<span class="c1"># now we trim off the layers after the last content and style losses</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">model</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">model</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">ContentLoss</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">model</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">StyleLoss</span><span class="p">):</span>
<span class="k">break</span>
<span class="n">model</span> <span class="o">=</span> <span class="n">model</span><span class="p">[:(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)]</span>
<span class="k">return</span> <span class="n">model</span><span class="p">,</span> <span class="n">style_losses</span><span class="p">,</span> <span class="n">content_losses</span>
</pre></div>
</div>
<p>Next, we select the input image. You can use a copy of the content image
or white noise.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">input_img</span> <span class="o">=</span> <span class="n">content_img</span><span class="o">.</span><span class="n">clone</span><span class="p">()</span>
<span class="c1"># if you want to use white noise instead uncomment the below line:</span>
<span class="c1"># input_img = torch.randn(content_img.data.size(), device=device)</span>
<span class="c1"># add the original input image to the figure:</span>
<span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">()</span>
<span class="n">imshow</span><span class="p">(</span><span class="n">input_img</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s1">'Input Image'</span><span class="p">)</span>
</pre></div>
</div>
<img alt="../_images/sphx_glr_neural_style_tutorial_003.png" class="sphx-glr-single-img" src="../_images/sphx_glr_neural_style_tutorial_003.png" />
</div>
<div class="section" id="gradient-descent">
<h2>Gradient Descent<a class="headerlink" href="#gradient-descent" title="Permalink to this headline">¶</a></h2>
<p>As Leon Gatys, the author of the algorithm, suggested <a class="reference external" href="https://discuss.pytorch.org/t/pytorch-tutorial-for-neural-transfert-of-artistic-style/336/20?u=alexis-jacq">here</a>, we will use
L-BFGS algorithm to run our gradient descent. Unlike training a network,
we want to train the input image in order to minimise the content/style
losses. We will create a PyTorch L-BFGS optimizer <code class="docutils literal notranslate"><span class="pre">optim.LBFGS</span></code> and pass
our image to it as the tensor to optimize.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">get_input_optimizer</span><span class="p">(</span><span class="n">input_img</span><span class="p">):</span>
<span class="c1"># this line to show that input is a parameter that requires a gradient</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">optim</span><span class="o">.</span><span class="n">LBFGS</span><span class="p">([</span><span class="n">input_img</span><span class="o">.</span><span class="n">requires_grad_</span><span class="p">()])</span>
<span class="k">return</span> <span class="n">optimizer</span>
</pre></div>
</div>
<p>Finally, we must define a function that performs the neural transfer. For
each iteration of the networks, it is fed an updated input and computes
new losses. We will run the <code class="docutils literal notranslate"><span class="pre">backward</span></code> methods of each loss module to
dynamicaly compute their gradients. The optimizer requires a “closure”
function, which reevaluates the module and returns the loss.</p>
<p>We still have one final constraint to address. The network may try to
optimize the input with values that exceed the 0 to 1 tensor range for
the image. We can address this by correcting the input values to be
between 0 to 1 each time the network is run.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">run_style_transfer</span><span class="p">(</span><span class="n">cnn</span><span class="p">,</span> <span class="n">normalization_mean</span><span class="p">,</span> <span class="n">normalization_std</span><span class="p">,</span>
<span class="n">content_img</span><span class="p">,</span> <span class="n">style_img</span><span class="p">,</span> <span class="n">input_img</span><span class="p">,</span> <span class="n">num_steps</span><span class="o">=</span><span class="mi">300</span><span class="p">,</span>
<span class="n">style_weight</span><span class="o">=</span><span class="mi">1000000</span><span class="p">,</span> <span class="n">content_weight</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
<span class="sd">"""Run the style transfer."""</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Building the style transfer model..'</span><span class="p">)</span>
<span class="n">model</span><span class="p">,</span> <span class="n">style_losses</span><span class="p">,</span> <span class="n">content_losses</span> <span class="o">=</span> <span class="n">get_style_model_and_losses</span><span class="p">(</span><span class="n">cnn</span><span class="p">,</span>
<span class="n">normalization_mean</span><span class="p">,</span> <span class="n">normalization_std</span><span class="p">,</span> <span class="n">style_img</span><span class="p">,</span> <span class="n">content_img</span><span class="p">)</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">get_input_optimizer</span><span class="p">(</span><span class="n">input_img</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Optimizing..'</span><span class="p">)</span>
<span class="n">run</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">while</span> <span class="n">run</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o"><=</span> <span class="n">num_steps</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">closure</span><span class="p">():</span>
<span class="c1"># correct the values of updated input image</span>
<span class="n">input_img</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">clamp_</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">optimizer</span><span class="o">.</span><span class="n">zero_grad</span><span class="p">()</span>
<span class="n">model</span><span class="p">(</span><span class="n">input_img</span><span class="p">)</span>
<span class="n">style_score</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">content_score</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">sl</span> <span class="ow">in</span> <span class="n">style_losses</span><span class="p">:</span>
<span class="n">style_score</span> <span class="o">+=</span> <span class="n">sl</span><span class="o">.</span><span class="n">loss</span>
<span class="k">for</span> <span class="n">cl</span> <span class="ow">in</span> <span class="n">content_losses</span><span class="p">:</span>
<span class="n">content_score</span> <span class="o">+=</span> <span class="n">cl</span><span class="o">.</span><span class="n">loss</span>
<span class="n">style_score</span> <span class="o">*=</span> <span class="n">style_weight</span>
<span class="n">content_score</span> <span class="o">*=</span> <span class="n">content_weight</span>
<span class="n">loss</span> <span class="o">=</span> <span class="n">style_score</span> <span class="o">+</span> <span class="n">content_score</span>
<span class="n">loss</span><span class="o">.</span><span class="n">backward</span><span class="p">()</span>
<span class="n">run</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">run</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">%</span> <span class="mi">50</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"run </span><span class="si">{}</span><span class="s2">:"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">run</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Style Loss : </span><span class="si">{:4f}</span><span class="s1"> Content Loss: </span><span class="si">{:4f}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">style_score</span><span class="o">.</span><span class="n">item</span><span class="p">(),</span> <span class="n">content_score</span><span class="o">.</span><span class="n">item</span><span class="p">()))</span>
<span class="nb">print</span><span class="p">()</span>
<span class="k">return</span> <span class="n">style_score</span> <span class="o">+</span> <span class="n">content_score</span>
<span class="n">optimizer</span><span class="o">.</span><span class="n">step</span><span class="p">(</span><span class="n">closure</span><span class="p">)</span>
<span class="c1"># a last correction...</span>
<span class="n">input_img</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">clamp_</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">return</span> <span class="n">input_img</span>
</pre></div>
</div>
<p>Finally, we can run the algorithm.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">output</span> <span class="o">=</span> <span class="n">run_style_transfer</span><span class="p">(</span><span class="n">cnn</span><span class="p">,</span> <span class="n">cnn_normalization_mean</span><span class="p">,</span> <span class="n">cnn_normalization_std</span><span class="p">,</span>
<span class="n">content_img</span><span class="p">,</span> <span class="n">style_img</span><span class="p">,</span> <span class="n">input_img</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">()</span>
<span class="n">imshow</span><span class="p">(</span><span class="n">output</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s1">'Output Image'</span><span class="p">)</span>
<span class="c1"># sphinx_gallery_thumbnail_number = 4</span>
<span class="n">plt</span><span class="o">.</span><span class="n">ioff</span><span class="p">()</span>
<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</pre></div>
</div>
<img alt="../_images/sphx_glr_neural_style_tutorial_004.png" class="sphx-glr-single-img" src="../_images/sphx_glr_neural_style_tutorial_004.png" />
<p class="sphx-glr-script-out">Out:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>Building the style transfer model..
Optimizing..
run [50]:
Style Loss : 4.076129 Content Loss: 4.179603
run [100]:
Style Loss : 1.112122 Content Loss: 3.022104
run [150]:
Style Loss : 0.705541 Content Loss: 2.651006
run [200]:
Style Loss : 0.479787 Content Loss: 2.497939
run [250]:
Style Loss : 0.346855 Content Loss: 2.413625
run [300]:
Style Loss : 0.265441 Content Loss: 2.358365
</pre></div>
</div>
<p class="sphx-glr-timing"><strong>Total running time of the script:</strong> ( 1 minutes 18.380 seconds)</p>
<div class="sphx-glr-footer class sphx-glr-footer-example docutils container" id="sphx-glr-download-advanced-neural-style-tutorial-py">
<div class="sphx-glr-download docutils container">
<a class="reference download internal" download="" href="../_downloads/c878b3652382b3d55937db4fa120d407/neural_style_tutorial.py"><code class="xref download docutils literal notranslate"><span class="pre">Download</span> <span class="pre">Python</span> <span class="pre">source</span> <span class="pre">code:</span> <span class="pre">neural_style_tutorial.py</span></code></a></div>
<div class="sphx-glr-download docutils container">
<a class="reference download internal" download="" href="../_downloads/bf9ff7854c45c19c6d4cd29f1cc50c23/neural_style_tutorial.ipynb"><code class="xref download docutils literal notranslate"><span class="pre">Download</span> <span class="pre">Jupyter</span> <span class="pre">notebook:</span> <span class="pre">neural_style_tutorial.ipynb</span></code></a></div>
</div>
<p class="sphx-glr-signature"><a class="reference external" href="https://sphinx-gallery.readthedocs.io">Gallery generated by Sphinx-Gallery</a></p>
</div>
</div>
</article>
</div>
<footer>
<hr class="rating-hr hr-top">
<div class="rating-container">
<div class="rating-prompt">Rate this Tutorial</div>
<div class="stars-outer">
<i class="far fa-star" title="1 Star" data-behavior="tutorial-rating" data-count="1"></i>
<i class="far fa-star" title="2 Stars" data-behavior="tutorial-rating" data-count="2"></i>
<i class="far fa-star" title="3 Stars" data-behavior="tutorial-rating" data-count="3"></i>
<i class="far fa-star" title="4 Stars" data-behavior="tutorial-rating" data-count="4"></i>
<i class="far fa-star" title="5 Stars" data-behavior="tutorial-rating" data-count="5"></i>
</div>
</div>
<hr class="rating-hr hr-bottom"/>
<div role="contentinfo">
<p>
© Copyright 2021, PyTorch & PyTorch Korea Community.
</p>
</div>
<div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</div>
</footer>
</div>
</div>
<div class="pytorch-content-right" id="pytorch-content-right">
<div class="pytorch-right-menu" id="pytorch-right-menu">
<div class="pytorch-side-scroll" id="pytorch-side-scroll-right">
<ul>
<li><a class="reference internal" href="#">Neural Transfer Using PyTorch</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#underlying-principle">Underlying Principle</a></li>
<li><a class="reference internal" href="#importing-packages-and-selecting-a-device">Importing Packages and Selecting a Device</a></li>
<li><a class="reference internal" href="#loading-the-images">Loading the Images</a></li>
<li><a class="reference internal" href="#loss-functions">Loss Functions</a><ul>
<li><a class="reference internal" href="#content-loss">Content Loss</a></li>
<li><a class="reference internal" href="#style-loss">Style Loss</a></li>
</ul>
</li>
<li><a class="reference internal" href="#importing-the-model">Importing the Model</a></li>
<li><a class="reference internal" href="#gradient-descent">Gradient Descent</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</section>
</div>
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/clipboard.min.js"></script>
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/contrib/auto-render.min.js"></script>
<script type="text/javascript" src="../_static/katex_autorenderer.js"></script>
<script type="text/javascript" src="../_static/js/vendor/popper.min.js"></script>
<script type="text/javascript" src="../_static/js/vendor/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
<script type="text/javascript" src="../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
<script>
//add microsoft link
if(window.location.href.indexOf("/beginner/basics/")!= -1)
{
var url="https://docs.microsoft.com/learn/paths/pytorch-fundamentals/?wt.mc_id=aiml-7486-cxa";
switch(window.location.pathname.split("/").pop().replace('.html',''))
{
case"quickstart_tutorial":
url="https://docs.microsoft.com/learn/modules/intro-machine-learning-pytorch/9-quickstart?WT.mc_id=aiml-7486-cxa";
break;
case"tensorqs_tutorial":
url="https://docs.microsoft.com/learn/modules/intro-machine-learning-pytorch/2-tensors?WT.mc_id=aiml-7486-cxa";
break;
case"data_tutorial":
url="https://docs.microsoft.com/learn/modules/intro-machine-learning-pytorch/3-data?WT.mc_id=aiml-7486-cxa";
break;
case"transforms_tutorial":
url="https://docs.microsoft.com/learn/modules/intro-machine-learning-pytorch/4-transforms?WT.mc_id=aiml-7486-cxa";
break;
case"buildmodel_tutorial":
url="https://docs.microsoft.com/learn/modules/intro-machine-learning-pytorch/5-model?WT.mc_id=aiml-7486-cxa";
break;
case"autogradqs_tutorial":
url="https://docs.microsoft.com/learn/modules/intro-machine-learning-pytorch/6-autograd?WT.mc_id=aiml-7486-cxa";
break;
case"optimization_tutorial":
url="https://docs.microsoft.com/learn/modules/intro-machine-learning-pytorch/7-optimization?WT.mc_id=aiml-7486-cxa";
break;
case"saveloadrun_tutorial":
url="https://docs.microsoft.com/learn/modules/intro-machine-learning-pytorch/8-inference?WT.mc_id=aiml-7486-cxa";
}
$(".pytorch-call-to-action-links").children().first().before("<a href="+url+' data-behavior="call-to-action-event" data-response="Run in Microsoft Learn" target="_blank"><div id="microsoft-learn-link" style="padding-bottom: 0.625rem;border-bottom: 1px solid #f3f4f7;padding-right: 2.5rem;display: -webkit-box; display: -ms-flexbox; isplay: flex; -webkit-box-align: center;-ms-flex-align: center;align-items: center;"><img class="call-to-action-img" src="../../_static/images/microsoft-logo.svg"/><div class="call-to-action-desktop-view">Run in Microsoft Learn</div><div class="call-to-action-mobile-view">Learn</div></div></a>')
}
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-71919972-3"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-71919972-3');
</script>
<script>
$("[data-behavior='call-to-action-event']").on('click', function(){
ga('send', {
hitType: 'event',
eventCategory: $(this).attr("data-response"),
eventAction: 'click',
eventLabel: window.location.href
});
gtag('event', 'click', {
'event_category': $(this).attr("data-response"),
'event_label': $("h1").first().text(),
'tutorial_link': window.location.href
});
});
$("[data-behavior='tutorial-rating']").on('click', function(){
gtag('event', 'click', {
'event_category': 'Tutorial Rating',
'event_label': $("h1").first().text(),
'value': $(this).attr("data-count")
});
});
if (location.pathname == "/") {
$(".rating-container").hide();
$(".hr-bottom").hide();
}
</script>
<script type="text/javascript">