<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>기분좋은 AI 세상을 함께 합니다.</title>
    <link>https://toofoo.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 18 Jun 2026 05:08:36 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>투푸월드</managingEditor>
    <image>
      <title>기분좋은 AI 세상을 함께 합니다.</title>
      <url>https://tistory1.daumcdn.net/tistory/6283570/attach/e115a2efbb164066a2aecd57dba84764</url>
      <link>https://toofoo.tistory.com</link>
    </image>
    <item>
      <title>부트스트랩(bootstrab)에서 사용하는 class명 정리</title>
      <link>https://toofoo.tistory.com/136</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;부트스트랩에서 사용하는 class명을 정리해 보았습니다. 부트스트랩을 안쓰더라도 개인적으로 프로젝트 할때 class명 네이밍시 너무 괴로워서 참고를 하기 위해서 정리하는것도 있습니다.&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;최대한 간단하게 정리하기 위해 젠코딩 방식으로 작성한 점 참고해주세요.&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;부트스트랩 네이밍은 시맨틱해서 네이밍만 봐도 이해는 가나 생소한것도 있어서 설명을 간단하게 적어놨습니다.&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;레이아웃&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.container (고정된 너비)&lt;/li&gt;
&lt;li&gt;.container-fluid (너비가 100%인 컨테이너)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;그리드&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부모요소 : .row&lt;/li&gt;
&lt;li&gt;자식요소 : .col-*-*&lt;/li&gt;
&lt;li&gt;ㄴ 첫번째 * : .xs, .sm, .md, .lg&lt;/li&gt;
&lt;li&gt;ㄴ 두번째 * : 컬럼 숫자(최대 12까지임)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;타이포그래피 / 텍스트&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;h1 ~ h6&lt;/li&gt;
&lt;li&gt;small&lt;/li&gt;
&lt;li&gt;mark&lt;/li&gt;
&lt;li&gt;abbr&lt;/li&gt;
&lt;li&gt;blockquote&lt;/li&gt;
&lt;li&gt;dl &amp;gt; dt + dd&lt;/li&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;li&gt;kbd&lt;/li&gt;
&lt;li&gt;pre&lt;/li&gt;
&lt;li&gt;.text-muted, .text-primary, .text-success, .text-info, .text-warning, .text-danger&lt;/li&gt;
&lt;li&gt;.bg-primary, .bg-success, .bg-info, .bg-warning, .bg-danger&lt;/li&gt;
&lt;li&gt;.lead : 단락을 돋보이게 만듬&lt;/li&gt;
&lt;li&gt;.text-left, .text-center, .text-right, .text-justfiy, .text-nowrap, .text-lowercase, .text-uppercase, .text-capitalize(앞 글자를 대문자로 바꿔줌)&lt;/li&gt;
&lt;li&gt;.list-unstyled&lt;/li&gt;
&lt;li&gt;.list-inline&lt;/li&gt;
&lt;li&gt;.dl-horizontal&lt;/li&gt;
&lt;li&gt;.pre-scrollable&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;테이블&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.table&lt;/li&gt;
&lt;li&gt;.table tr.success, .danger, .info, .warning, .active&lt;/li&gt;
&lt;li&gt;.table-striped&lt;/li&gt;
&lt;li&gt;.table-bordered&lt;/li&gt;
&lt;li&gt;.table-hover&lt;/li&gt;
&lt;li&gt;.table-condensed&lt;/li&gt;
&lt;li&gt;.table-responsive&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이미지&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.img-rounded&lt;/li&gt;
&lt;li&gt;.img-circle&lt;/li&gt;
&lt;li&gt;.img-thumbnail&lt;/li&gt;
&lt;li&gt;.img-responsive&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Responsive Embeds&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;div.embed-responsive.embed-responsive-16[4]by9[3] &amp;gt; .embed-responsive-item (16[4]by9[3] 은 영상 비율을 뜻합니다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Jumbotron / Page Header&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;div.jumbotron &amp;gt; h1 + p&lt;/li&gt;
&lt;li&gt;div.page-header &amp;gt; h1&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Wells (회색배경과 약간의 패딩과 둥근 테두리 디자인)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.well&lt;/li&gt;
&lt;li&gt;.well.well-sm, .well-lg&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Alerts&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.alert&lt;/li&gt;
&lt;li&gt;.alert.alert-success, .alert-info, .alert-warning, .alert-danger&lt;/li&gt;
&lt;li&gt;.alert &amp;gt; .alert-link&lt;/li&gt;
&lt;li&gt;.alert.alert-dismissible &amp;gt; a[data-_][aria-_]&lt;/li&gt;
&lt;li&gt;.alert.alert-dismissible.fade.in&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;버튼&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;버튼 스타일&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.btn&lt;/li&gt;
&lt;li&gt;.btn.btn-default&lt;/li&gt;
&lt;li&gt;.btn.btn-primary&lt;/li&gt;
&lt;li&gt;.btn.btn-success&lt;/li&gt;
&lt;li&gt;.btn.btn-info&lt;/li&gt;
&lt;li&gt;.btn.btn-warning&lt;/li&gt;
&lt;li&gt;.btn.btn-danger&lt;/li&gt;
&lt;li&gt;.btn.btn-link&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;버튼 사이즈&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.btn.btn-lg | sm | xs&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;블록 레벨 버튼&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.btn.btn-block&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;active / disabled 버튼&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.btn.active | disabled&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;버튼그룹&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;div.btn-group &amp;gt; .btn&lt;/li&gt;
&lt;li&gt;div.btn-group.btn-group-lg | sm | xs &amp;gt; .btn&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;수직 버튼 그룹&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;div.btn-group-vertical &amp;gt; .btn&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;양쪽 정렬 버튼 그룹&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.div.btn-group.btn-group-justified &amp;gt; .btn | .btn-group&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Badges and Labels&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.badge&lt;/li&gt;
&lt;li&gt;.btn &amp;gt; .badge&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Labels&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.label.label-default | primary | success | info | warning | danger&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Progress Bars&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.progress &amp;gt; .progress-bar&lt;/li&gt;
&lt;li&gt;.progress &amp;gt; .progress-bar.progress-bar-success | info | warning | danger&lt;/li&gt;
&lt;li&gt;.progress &amp;gt; .progress-bar.progress-bar-striped&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프로그래스바 스트라이프 애니메이션&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.progress &amp;gt; .progress-bar.progress-bar-striped.active&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Stacked Progress Bars&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.progress &amp;gt; .progress-bar + .progress-bar&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Pagination&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.pagination &amp;gt; a&lt;/li&gt;
&lt;li&gt;.pagination &amp;gt; .active&lt;/li&gt;
&lt;li&gt;.pagination &amp;gt; .disabled&lt;/li&gt;
&lt;li&gt;.pagination.pagination-lg || .pagination-sm&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Breadcrumbs&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.breadcrumb &amp;gt; .active&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Pager&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.pager&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Align Buttons&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.pager &amp;gt; .previous || .next&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;List Groups&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.list-group &amp;gt; .list-group-item&lt;/li&gt;
&lt;li&gt;.list-group &amp;gt; .list-group-item.active || .disabled&lt;/li&gt;
&lt;li&gt;.list-group &amp;gt; .list-group-item &amp;gt; .badge&lt;/li&gt;
&lt;li&gt;.list-group &amp;gt; .list-group-item.list-group-item-success || info || warning || danger&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Panels&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.panel.panel-default &amp;gt; .panel-body&lt;/li&gt;
&lt;li&gt;.panel.panel-default &amp;gt; .panel-heading + .panel-body + .panel-footer&lt;/li&gt;
&lt;li&gt;.panel-group &amp;gt; .panel.panel-default &amp;gt; .panel-body&lt;/li&gt;
&lt;li&gt;.panel.panel-default || primary || success || inof || warning ||danger &amp;gt; .panel-body&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Dropdowns&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.dropdown &amp;gt; .btn.btn-primary.dropdown-toggle[data-toggle=&quot;dropdown&quot;] + .dropdown-menu&lt;/li&gt;
&lt;li&gt;.dropdown-menu &amp;gt; .divider&lt;/li&gt;
&lt;li&gt;.dropdown-menu &amp;gt; .dropdown-header&lt;/li&gt;
&lt;li&gt;.dropdown-menu &amp;gt; .active || .disabled&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Collapse&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;button[data-toggle=&quot;collapse&quot;][data-target=&quot;#demo&quot;] + div#demo.collapse&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;펼침상태&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;div#demo.collapse.in&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Panel컴포넌트와 결합하여 사용이 가능&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.w3schools.com/bootstrap/bootstrap_collapse.asp&quot;&gt;마크업 참고 link&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;탭&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.nav.nav-tabs &amp;gt; .active &amp;gt; a[data-toggle=&quot;tab&quot;]&lt;/li&gt;
&lt;li&gt;.tab-content &amp;gt; div.tab-pane.fade.in.active&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Navigation Bar&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.nav navbar-nav &amp;gt; .active&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Form Layouts&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Vertical Form (default)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.form-group &amp;gt; input.form-control&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Inline Form&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.form-inline &amp;gt; .form-group &amp;gt; label + input.form-control&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Horizontal Form 테이블 처럼 제목:내용 형식&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.form-horizontal &amp;gt; .form-group &amp;gt; .control-label + .col-&lt;i&gt;-&lt;/i&gt; &amp;gt; input.form-control&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Form Inputs&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;input, textarea&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.form-group &amp;gt; input.form-control&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;checkbox&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;div.checkbox &amp;gt; label &amp;gt; input&lt;/li&gt;
&lt;li&gt;label.checkbox-inline &amp;gt; input&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;radio button&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;div.radio &amp;gt; label &amp;gt; input&lt;/li&gt;
&lt;li&gt;label.radio-inline &amp;gt; input&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;select list&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.form-group &amp;gt; label + select.form-control&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;검색영역&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.input-group &amp;gt; input.form-control + div.input-group-btn &amp;gt; .btn &amp;gt; i( 아이콘)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Input Sizing&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;input.input-sm || .input-lg&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Media Object&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.media &amp;gt; .media-left.media-top || .media-middle || .media-bottom + media-body &amp;gt; .media-heading&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처: &lt;a href=&quot;https://foodchain.tistory.com/160&quot;&gt;https://foodchain.tistory.com/160&lt;/a&gt; [Frontend Developer를 향해 !:티스토리] &lt;/p&gt;</description>
      <category>Development/CSS</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/136</guid>
      <comments>https://toofoo.tistory.com/136#entry136comment</comments>
      <pubDate>Tue, 23 Apr 2024 08:18:14 +0900</pubDate>
    </item>
    <item>
      <title>파이썬 % // -&amp;gt; ** @ 등 파이썬 기호 완벽정리</title>
      <link>https://toofoo.tistory.com/106</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 파이썬에서 * ** 란?&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;파이썬에 * (asterisk, 일명 별표)는 곱하기(연산자) 외에도 몇 가지 다른 용도로 쓰일 수 있습니다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;1) 모든 것 *&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;일반적으로 프로그래밍에서 일반적으로 *는 모든 것(Everything)의 의미로 통용됩니다.&lt;br /&gt;예를 들어, 다음처럼 쓰이곤 합니다. (아래의 예시 코드는 math 라는 라이브러리에서 모든 변수, 함수, 클래스를 가져온다는 의미입니다.)&lt;/p&gt;
&lt;pre class=&quot;moonscript&quot; style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot;&gt;&lt;code&gt;from math import *&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ec185e;&quot; href=&quot;https://stackoverflow.com/questions/2386714/why-is-import-bad&quot;&gt;이런 코드 습관은 안좋다는 의견&lt;/a&gt;이 많으니 참고해주세요.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2) 가변인자 *args **kwargs&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;보통 함수는 인자(argument)를 넣게끔 설계합니다. 이때 들어가는 인자의 개수를 한정하고 싶지 않을 때 *args (arguments)를 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot; style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot;&gt;&lt;code&gt;def girls_who_want_me(*args):
    print(args)

girls_who_want_me(&quot;뉴진스 하니&quot;, &quot;아이유&quot;, &quot;비비&quot;, &quot;수지&quot;)

&amp;gt;&amp;gt;&amp;gt; (&quot;뉴진스 하니&quot;, &quot;아이유&quot;, &quot;비비&quot;, &quot;수지&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 딕셔너리 형식으로 인자를 넣고 싶다면 **kwargs (keyword argments)를 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot;&gt;&lt;code&gt;def workout_log(**kwargs):
    print(kwargs)

workout_log(squat=&quot;180kg&quot;, deadlift=&quot;200kg&quot;, benchpress=&quot;120kg&quot;)

&amp;gt;&amp;gt;&amp;gt; {'squat': '180kg', 'deadlift': '200kg', 'benchpress': '120kg'}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. 파이썬에서 함수를 정의할 때 : -&amp;gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;함수를 정의할 때, :와 -&amp;gt; 를 주석으로 쓸 수 있습니다.&lt;br /&gt;구체적으로, 안전한 프로그래밍을 위해 함수를 정의할 때 변수의 자료형태(type)와 return 값의 자료형태(type)을 명시하는 용도로 쓰입니다. 코드의 작동에 영향을 주지는 않지만, 실수를 미연에 방지하는 프로그래밍을 가능하게 합니다.&lt;br /&gt;예시 코드를 보시죠!&lt;/p&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot;&gt;&lt;code&gt;def make_profile(hometown : str, age : int) -&amp;gt; str:
    profile = hometown + str(age)
    return profile

make_profile(&quot;기안&quot;, 84)

&amp;gt;&amp;gt;&amp;gt; '기안84'&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. 파이썬에서 &amp;hellip; 란?&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음 코드를 실행하면 신기한 결과가 나옵니다.&lt;/p&gt;
&lt;pre class=&quot;gams&quot; style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot;&gt;&lt;code&gt;print(...)

&amp;gt;&amp;gt;&amp;gt; Ellipsis&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;네, 출력된 것처럼 파이썬은 Ellipsis라는 객체를 가지고 있습니다. Ellipsis란 사전적으로는 생략, 생략부호(&amp;hellip;)라는 의미를 가집니다. 그럼&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ec185e;&quot; href=&quot;https://docs.python.org/3.9/library/constants.html#Ellipsis&quot;&gt;Python 공식 문서에서는 어떻게 정의&lt;/a&gt;돼있을까요?&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;color: #828282;&quot; data-ke-size=&quot;size16&quot;&gt;The same as the ellipsis literal &amp;ldquo;&amp;hellip;&amp;rdquo;. Special value used mostly in conjunction with extended slicing syntax for user-defined container data types.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;뭔가 확장 슬라이싱과 관련돼있는거 같죠? 바로 코드로 봐봅시다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot;&gt;&lt;code&gt;matrix = np.array(range(8)).reshape(2,2,2)
print(matrix)

&amp;gt;&amp;gt;&amp;gt; array([[[0, 1],
        [2, 3]],

       [[4, 5],
        [6, 7]]])

print(matrix[...])

&amp;gt;&amp;gt;&amp;gt; array([[[0, 1],
        [2, 3]],

       [[4, 5],
        [6, 7]]])

print(matrix[0,...])

&amp;gt;&amp;gt;&amp;gt; array([[0, 1],
       [2, 3]])
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 외에도 Ellipsis는 어떤 동작도 수행하지 않으므로 pass처럼 사용할 수도 있습니다. 일단 만들고 자세한 나중에 구현하려고 할 때 다음처럼 쓸 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot;&gt;&lt;code&gt;def something_cool():
    pass

def something_cool():
    ...&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 파이썬에서 @ 는?&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;@는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ec185e;&quot; href=&quot;https://peps.python.org/pep-0318/&quot;&gt;파이썬에서 데코레이터(decorator)&lt;/a&gt;라는 녀석입니다. 데코레이터는 함수에 무언가 내용을 추가하고 싶을 때 사용하는 기능입니다. 단순히 함수에 바로 내용을 추가하지 않고 데코레이터를 쓰는 이유는 다른 함수들에도 반복적으로 추가할 수 있도록 관리하기 위해서입니다. 바로 예시를 보시죠.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/da7MBo/btsrqx43wgI/fkl9oZJUjJosAi8CbETzl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/da7MBo/btsrqx43wgI/fkl9oZJUjJosAi8CbETzl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/da7MBo/btsrqx43wgI/fkl9oZJUjJosAi8CbETzl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fda7MBo%2Fbtsrqx43wgI%2Ffkl9oZJUjJosAi8CbETzl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;848&quot; height=&quot;533&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot;&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;color: #232323; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; text-align: start; font-size: 16px; background-color: initial;&quot;&gt;이처럼 함수를 활용해서 데코레이터를 구현할 수도 있고, 다음처럼 class의 형태로도 구현이 가능합니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WhDb5/btsrjpNhYmn/k6wJzY7x0D6LFKsqT0S5lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WhDb5/btsrjpNhYmn/k6wJzY7x0D6LFKsqT0S5lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WhDb5/btsrjpNhYmn/k6wJzY7x0D6LFKsqT0S5lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWhDb5%2FbtsrjpNhYmn%2Fk6wJzY7x0D6LFKsqT0S5lk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;606&quot; height=&quot;687&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: 1.62em; letter-spacing: -1px;&quot;&gt;5. 파이썬에서 % 의미는?&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;%는 파이썬에서 문자열 포메팅(string formatting)을 할 때 씁니다. 문자열 포메팅이란 출력하는 문자열의 특정 위치에 특정한 값(변수)을 삽입하여 출력하는 것을 의미합니다. 다음처럼 사용할 수 있습니다. %기호 뒤에는 자료형을 가리키는 문자를 씁니다.(%s : 문자열, %d : 정수, %f : 실수,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ec185e;&quot; href=&quot;https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting&quot;&gt;기타등등&lt;/a&gt;)&lt;/p&gt;
&lt;pre class=&quot;vim&quot; style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot;&gt;&lt;code&gt;coolnames = [&quot;Cool J&quot;, &quot;Cool guy&quot;, &quot;Cool gaay&quot;]
for coolname in coolnames:
    print(&quot;I am %s&quot; % coolname)

&amp;gt;&amp;gt;&amp;gt; I am Cool J
I am Cool guy
I am Cool gaay
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #232323; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이상으로 파이썬에서 * ** : -&amp;gt; ; &amp;hellip; @ % 기호들이 어떻게 쓰이는지에 대해 알아보았습니다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>Development/Python</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/106</guid>
      <comments>https://toofoo.tistory.com/106#entry106comment</comments>
      <pubDate>Thu, 17 Aug 2023 05:44:44 +0900</pubDate>
    </item>
    <item>
      <title>[pytorch] 모델 저장하기 &amp;amp; 불러오기</title>
      <link>https://toofoo.tistory.com/105</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이 문서에서는 PyTorch 모델을 저장하고 불러오는 다양한 방법을 제공합니다. 이 문서 전체를 다 읽는 것도 좋은 방법이지만, 필요한 사용 예의 코드만 참고하는 것도 고려해보세요.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #262626; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모델을 저장하거나 불러올 때는 3가지의 핵심 함수와 익숙해질 필요가 있습니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #212529; text-align: left;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;color: #262626;&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://pytorch.org/docs/stable/torch.html?highlight=save#torch.save&quot;&gt;torch.save&lt;/a&gt;: 직렬화된 객체를 디스크에 저장합니다. 이 함수는 Python의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://docs.python.org/3/library/pickle.html&quot;&gt;pickle&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 사용하여 직렬화합니다. 이 함수를 사용하여 모든 종류의 객체의 모델, Tensor 및 사전을 저장할 수 있습니다.&lt;/li&gt;
&lt;li style=&quot;color: #262626;&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://pytorch.org/docs/stable/torch.html?highlight=torch%20load#torch.load&quot;&gt;torch.load&lt;/a&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://docs.python.org/3/library/pickle.html&quot;&gt;pickle&lt;/a&gt;을 사용하여 저장된 객체 파일들을 역직렬화하여 메모리에 올립니다. 이 함수는 데이터를 장치에 불러올 때에도 사용됩니다. (&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://toofoo.tistory.com/105#device&quot;&gt;장치 간 모델 저장하기 &amp;amp; 불러오기&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;참고)&lt;/li&gt;
&lt;li style=&quot;color: #262626;&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://pytorch.org/docs/stable/generated/torch.nn.Module.html?highlight=load_state_dict#torch.nn.Module.load_state_dict&quot;&gt;torch.nn.Module.load_state_dict&lt;/a&gt;: 역직렬화된&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 사용하여 모델의 매개변수들을 불러옵니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;에 대한 더 자세한 정보는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://toofoo.tistory.com/105#state-dict&quot;&gt;state_dict가 무엇인가요?&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 참고하세요.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #262626; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;목차:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;color: #262626;&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://toofoo.tistory.com/105#state-dict&quot;&gt;state_dict가 무엇인가요?&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: #262626;&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://toofoo.tistory.com/105#inference&quot;&gt;추론(inference)를 위해 모델 저장하기 &amp;amp; 불러오기&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: #262626;&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://toofoo.tistory.com/105#checkpoint&quot;&gt;일반 체크포인트(checkpoint) 저장하기 &amp;amp; 불러오기&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: #262626;&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://toofoo.tistory.com/105#multiple&quot;&gt;여러 개(multiple)의 모델을 하나의 파일에 저장하기&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: #262626;&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://toofoo.tistory.com/105#warmstart&quot;&gt;다른 모델의 매개변수를 사용하여 빠르게 모델 시작하기(warmstart)&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: #262626;&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://toofoo.tistory.com/105#device&quot;&gt;장치(device)간 모델 저장하기 &amp;amp; 불러오기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div id=&quot;state-dict&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;
&lt;h2 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;state_dict&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;가 무엇인가요?&lt;/h2&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;PyTorch에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.nn.Module&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모델의 학습 가능한 매개변수(예. 가중치와 편향)들은 모델의 매개변수에 포함되어 있습니다(model.parameters()로 접근합니다).&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;는 간단히 말해 각 계층을 매개변수 텐서로 매핑되는 Python 사전(dict) 객체입니다. 이 때, 학습 가능한 매개변수를 갖는 계층(합성곱 계층, 선형 계층 등) 및 등록된 버퍼들(batchnorm의 running_mean)만이 모델의&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;에 항목을 가짐을 유의하시기 바랍니다. 옵티마이저 객체(&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.optim&lt;/span&gt;) 또한 옵티마이저의 상태 뿐만 아니라 사용된 하이퍼 매개변수(Hyperparameter) 정보가 포함된&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 갖습니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;객체는 Python 사전이기 때문에 쉽게 저장하거나 갱신하거나 바꾸거나 되살릴 수 있으며, PyTorch 모델과 옵티마이저에 엄청난 모듈성(modularity)을 제공합니다.&lt;/p&gt;
&lt;div id=&quot;id4&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;예제:&lt;/h3&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://tutorials.pytorch.kr/beginner/blitz/cifar10_tutorial.html&quot;&gt;&lt;span&gt;분류기(Classifier) 학습하기&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;튜토리얼에서 사용한 간단한 모델의&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell0&quot; class=&quot;ruby&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;# 모델 정의
class TheModelClass(nn.Module):
    def __init__(self):
        super(TheModelClass, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# 모델 초기화
model = TheModelClass()

# 옵티마이저 초기화
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

# 모델의 state_dict 출력
print(&quot;Model's state_dict:&quot;)
for param_tensor in model.state_dict():
    print(param_tensor, &quot;\t&quot;, model.state_dict()[param_tensor].size())

# 옵티마이저의 state_dict 출력
print(&quot;Optimizer's state_dict:&quot;)
for var_name in optimizer.state_dict():
    print(var_name, &quot;\t&quot;, optimizer.state_dict()[var_name])
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출력:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell1&quot; class=&quot;yaml&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;Model's state_dict:
conv1.weight     torch.Size([6, 3, 5, 5])
conv1.bias   torch.Size([6])
conv2.weight     torch.Size([16, 6, 5, 5])
conv2.bias   torch.Size([16])
fc1.weight   torch.Size([120, 400])
fc1.bias     torch.Size([120])
fc2.weight   torch.Size([84, 120])
fc2.bias     torch.Size([84])
fc3.weight   torch.Size([10, 84])
fc3.bias     torch.Size([10])

Optimizer's state_dict:
state    {}
param_groups     [{'lr': 0.001, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [4675713712, 4675713784, 4675714000, 4675714072, 4675714216, 4675714288, 4675714432, 4675714504, 4675714648, 4675714720]}]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;inference&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;
&lt;h2 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size26&quot;&gt;추론(inference)를 위해 모델 저장하기 &amp;amp; 불러오기&lt;/h2&gt;
&lt;div id=&quot;id5&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;state_dict&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;저장하기 / 불러오기 (권장)&lt;/h3&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저장하기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell2&quot; class=&quot;css&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save(model.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불러오기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell3&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.eval()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #f3f4f7;&quot;&gt;
&lt;p style=&quot;background-color: #54c7ec; color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;PyTorch 버전 1.6에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;torch.save&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;가 새로운 Zip파일-기반의 파일 포맷을 사용하도록 변경되었습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;torch.load&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;는 예전 방식의 파일들을 읽어올 수 있도록 하고 있습니다. 어떤 이유에서든&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;torch.save&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;가 예전 방식을 사용하도록 하고 싶다면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;kwarg&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;매개변수로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;_use_new_zipfile_serialization=False&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 전달하세요.&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;추론을 위해 모델을 저장할 때는 그 모델의 학습된 매개변수만 저장하면 됩니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.save()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 사용하여 모델의&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 저장하는 것이 나중에 모델을 사용할 때 가장 유연하게 사용할 수 있는, 모델 저장 시 권장하는 방법입니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;PyTorch에서는 모델을 저장할 때&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;.pt&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;또는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;.pth&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;확장자를 사용하는 것이 일반적인 규칙입니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;추론을 실행하기 전에 반드시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.eval()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 호출하여 드롭아웃 및 배치 정규화를 평가 모드로 설정하여야 합니다. 이 과정을 거치지 않으면 일관성 없는 추론 결과가 출력됩니다.&lt;/p&gt;
&lt;div style=&quot;background-color: #f3f4f7;&quot;&gt;
&lt;p style=&quot;background-color: #54c7ec; color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;load_state_dict()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수에는 저장된 객체의 경로가 아닌, 사전 객체를 전달해야 하는 것에 유의하세요. 따라서 저장된&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;load_state_dict()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수에 전달하기 전에 반드시 역직렬화를 해야 합니다. 예를 들어,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;model.load_state_dict(PATH)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;과 같은 식으로 사용하면 안됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #f3f4f7;&quot;&gt;
&lt;p style=&quot;background-color: #54c7ec; color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;만약 (검증 손실(validation loss) 결과에 따라) 가장 성능이 좋은 모델만 유지할 계획이라면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;best_model_state&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;=&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;model.state_dict()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;은 모델의 복사본이 아닌 모델의 현재 상태에 대한 참조(reference)만 반환한다는 사실을 잊으시면 안됩니다! 따라서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;best_model_state&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 직렬화(serialize)하거나,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;best_model_state&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;=&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;deepcopy(model.state_dict())&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 사용해야 합니다. 그렇지 않으면, 제일 좋은 성능을 내는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #6c6c6d;&quot;&gt;best_model_state&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;은 계속되는 학습 단계에서 갱신될 것입니다. 결과적으로, 최종 모델의 상태는 과적합(overfit)된 상태가 됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;id6&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;전체 모델 저장하기/불러오기&lt;/h3&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저장하기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell4&quot; class=&quot;css&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save(model, PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불러오기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell5&quot; class=&quot;makefile&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;# 모델 클래스는 어딘가에 반드시 선언되어 있어야 합니다.
model = torch.load(PATH)
model.eval()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;이 저장하기/불러오기 과정은 가장 직관적인 문법을 사용하며 적은 양의 코드를 사용합니다. 이러한 방식으로 모델을 저장하는 것은 Python의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://docs.python.org/3/library/pickle.html&quot;&gt;pickle&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모듈을 사용하여 전체 모듈을 저장하게 됩니다. 하지만 pickle은 모델 그 자체를 저장하지 않기 때문에 직렬화된 데이터가 모델을 저장할 때 사용한 특정 클래스 및 디렉토리 경로(구조)에 얽매인다는 것이 이 방식의 단점입니다. 대신에 클래스가 위치한 파일의 경로를 저장해두고, 불러오는 시점에 사용합니다. 이러한 이유 때문에, 만들어둔 코드를 다른 프로젝트에서 사용하거나 리팩토링 후에 다양한 이유로 동작하지 않을 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;PyTorch에서는 모델을 저장할 때&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;.pt&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;또는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;.pth&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;확장자를 사용하는 것이 일반적인 규칙입니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;추론을 실행하기 전에는 반드시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.eval()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 호출하여 드롭아웃 및 배치 정규화를 평가 모드로 설정하여야 합니다. 이것을 하지 않으면 추론 결과가 일관성 없게 출력됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;torchscript&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;TorchScript 포맷으로 모델 내보내기/가져오기&lt;/h3&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;훈련된 모델로 추론을 수행하는 일반적인 방법 중 하나는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://pytorch.org/docs/stable/jit.html&quot;&gt;TorchScript&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 사용하는 것입니다. TorchScript는 파이썬 환경이나 C++와 같은 고성능 환경에서 실행할 수 있는 파이토치 모델의 중간 표현(IR; Intermediate Representation)입니다. TorchScript는 확장된 추론 및 배포에 권장되는 모델 형식이기도 합니다.&lt;/p&gt;
&lt;div style=&quot;background-color: #f3f4f7;&quot;&gt;
&lt;p style=&quot;background-color: #54c7ec; color: #ffffff;&quot; data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;TorchScript 형식을 사용하면 모델 클래스를 정의하지 않고도 내보낸 모델을 읽어 오거나 추론을 실행할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Export:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell6&quot; class=&quot;makefile&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;model_scripted = torch.jit.script(model) # TorchScript 형식으로 내보내기
model_scripted.save('model_scripted.pt') # 저장하기
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Load:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell7&quot; class=&quot;gams&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;model = torch.jit.load('model_scripted.pt')
model.eval()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;추론 실행 전, 드롭아웃 및 배치(batch) 정규화 레이어를 평가 모드로 설정하기 위해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.eval()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 호출해야 합니다. 이 호출 과정이 없으면 일관성 없는 추론 결과가 나타납니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;TorchScript에 대한 추가 정보는 전용&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://tutorials.pytorch.kr/beginner/Intro_to_TorchScript_tutorial.html&quot;&gt;자습서&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;에서 찾을 수 있습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #ee4c2c;&quot; href=&quot;https://tutorials.pytorch.kr/advanced/cpp_export.html&quot;&gt;C++ 환경&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;문서를 참고하여 트레이싱(Tracing) 변환을 수행하는 방법과 C++ 환경에서 TorchScript 모듈을 실행하는 방법을 익힐 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;checkpoint&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;
&lt;h2 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size26&quot;&gt;추론 / 학습 재개를 위해 일반 체크포인트(checkpoint) 저장하기 &amp;amp; 불러오기&lt;/h2&gt;
&lt;div id=&quot;id7&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;저장하기:&lt;/h3&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell8&quot; class=&quot;gams&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save({
            'epoch': epoch,
            'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer.state_dict(),
            'loss': loss,
            ...
            }, PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;id8&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;불러오기:&lt;/h3&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell9&quot; class=&quot;pgsql&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;model = TheModelClass(*args, **kwargs)
optimizer = TheOptimizerClass(*args, **kwargs)

checkpoint = torch.load(PATH)
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']
loss = checkpoint['loss']

model.eval()
# - or -
model.train()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;추론 또는 학습 재개를 위해 일반 체크포인트를 저장할 때는 반드시 모델의&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;보다 많은 것들을 저장해야 합니다. 모델이 학습을 하며 갱신되는 버퍼와 매개변수가 포함된 옵티마이저의&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;도 함께 저장하는 것이 중요합니다. 그 외에도 마지막 에폭(epoch), 최근에 기록된 학습 손실, 외부&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.nn.Embedding&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;계층 등도 함께 저장합니다. 결과적으로, 이런 체크포인트는 종종 모델만 저장하는 것보다 2~3배 정도 커지게 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;여러가지를 함께 저장하려면, 사전(dictionary) 자료형으로 만든 후&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.save()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 사용하여 직렬화합니다. PyTorch가 이러한 체크포인트를 저장할 때는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;.tar&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;확장자를 사용하는 것이 일반적인 규칙입니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;항목들을 불러올 때에는 먼저 모델과 옵티마이저를 초기화한 후,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.load()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 사용하여 사전을 불러옵니다. 이후로는 저장된 항목들을 사전에 원하는대로 사전에 질의하여 쉽게 접근할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;추론을 실행하기 전에는 반드시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.eval()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 호출하여 드롭아웃 및 배치 정규화를 평가 모드로 설정하여야 합니다. 이것을 하지 않으면 추론 결과가 일관성 없게 출력됩니다. 만약 학습을 계속하고 싶다면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.train()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 호출하여 학습 모드로 전환되도록 해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;multiple&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;
&lt;h2 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size26&quot;&gt;여러개(multiple)의 모델을 하나의 파일에 저장하기&lt;/h2&gt;
&lt;div id=&quot;id9&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;저장하기:&lt;/h3&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell10&quot; class=&quot;gcode&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save({
            'modelA_state_dict': modelA.state_dict(),
            'modelB_state_dict': modelB.state_dict(),
            'optimizerA_state_dict': optimizerA.state_dict(),
            'optimizerB_state_dict': optimizerB.state_dict(),
            ...
            }, PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;id10&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;불러오기:&lt;/h3&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell11&quot; class=&quot;pgsql&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;modelA = TheModelAClass(*args, **kwargs)
modelB = TheModelBClass(*args, **kwargs)
optimizerA = TheOptimizerAClass(*args, **kwargs)
optimizerB = TheOptimizerBClass(*args, **kwargs)

checkpoint = torch.load(PATH)
modelA.load_state_dict(checkpoint['modelA_state_dict'])
modelB.load_state_dict(checkpoint['modelB_state_dict'])
optimizerA.load_state_dict(checkpoint['optimizerA_state_dict'])
optimizerB.load_state_dict(checkpoint['optimizerB_state_dict'])

modelA.eval()
modelB.eval()
# - or -
modelA.train()
modelB.train()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;GAN, Seq2Seq 또는 앙상블 모델과 같이 여러개의 여러개의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.nn.Modules&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 구성된 모델을 저장하는 경우에는 일반 체크포인트를 저장할 때와 같은 방식을 따릅니다. 즉, 각 모델의&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;와 해당 옵티마이저를 사전으로 저장합니다. 앞에서 언급했던 것과 같이, 학습을 재개하는데 필요한 다른 항목들을 사전에 추가하여 저장할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;PyTorch가 이러한 체크포인트를 저장할 때는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;.tar&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;확장자를 사용하는 것이 일반적인 규칙입니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;항목들을 불러올 때에는 먼저 모델과 옵티마이저를 초기화한 후,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.load()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 사용하여 사전을 불러옵니다. 이후로는 저장된 항목들을 사전에 원하는대로 사전에 질의하여 쉽게 접근할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;추론을 실행하기 전에는 반드시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.eval()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 호출하여 드롭아웃 및 배치 정규화를 평가 모드로 설정하여야 합니다. 이것을 하지 않으면 추론 결과가 일관성 없게 출력됩니다. 만약 학습을 계속하고 싶다면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.train()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 호출하여 학습 모드로 설정해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;warmstart&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;
&lt;h2 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size26&quot;&gt;다른 모델의 매개변수를 사용하여 빠르게 모델 시작하기(warmstart)&lt;/h2&gt;
&lt;div id=&quot;id11&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;저장하기:&lt;/h3&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell12&quot; class=&quot;css&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save(modelA.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;id12&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;불러오기:&lt;/h3&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell13&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;modelB = TheModelBClass(*args, **kwargs)
modelB.load_state_dict(torch.load(PATH), strict=False)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;부분적으로 모델을 불러오거나, 모델의 일부를 불러오는 것은 전이학습 또는 새로운 복잡한 모델을 학습할 때 일반적인 시나리오입니다. 학습된 매개변수를 사용하면, 일부만 사용한다 하더라도 학습 과정을 빠르게 시작할 수 있고, 처음부터 시작하는 것보다 훨씬 빠르게 모델이 수렴하도록 도울 것입니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;몇몇 키를 제외하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;의 일부를 불러오거나, 적재하려는 모델보다 더 많은 키를 갖고 있는&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 불러올 때에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;load_state_dict()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;strict&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;인자를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;False&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 설정하여 일치하지 않는 키들을 무시하도록 해야 합니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;한 계층에서 다른 계층으로 매개변수를 불러오고 싶지만, 일부 키가 일치하지 않을 때에는 적재하려는 모델의 키와 일치하도록&lt;span&gt;&amp;nbsp;&lt;/span&gt;state_dict&lt;span&gt;&amp;nbsp;&lt;/span&gt;의 매개변수 키의 이름을 변경하면 됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;device&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;
&lt;h2 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size26&quot;&gt;장치(device)간 모델 저장하기 &amp;amp; 불러오기&lt;/h2&gt;
&lt;div id=&quot;gpu-cpu&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;GPU에서 저장하고 CPU에서 불러오기&lt;/h3&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저장하기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell14&quot; class=&quot;css&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save(model.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불러오기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell15&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;device = torch.device('cpu')
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH, map_location=device))
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;GPU에서 학습한 모델을 CPU에서 불러올 때는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.load()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;map_location&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;인자에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.device('cpu')&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 전달합니다. 이 경우에는 Tensor에 저장된 내용들은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;map_location&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;인자를 사용하여 CPU 장치에 동적으로 재배치됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;gpu-gpu&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;GPU에서 저장하고 GPU에서 불러오기&lt;/h3&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저장하기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell16&quot; class=&quot;css&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save(model.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불러오기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell17&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;device = torch.device(&quot;cuda&quot;)
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.to(device)
# 모델에서 사용하는 input Tensor들은 input = input.to(device) 을 호출해야 합니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;GPU에서 학습한 모델을 GPU에서 불러올 때에는, 초기화된&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.to(torch.device('cuda'))&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 호출하여 CUDA 최적화된 모델로 변환해야 합니다. 또한, 모델에 데이터를 제공하는 모든 입력에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;.to(torch.device('cuda'))&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수를 호출해야 합니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;my_tensor.to(device)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 호출하면 GPU에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;my_tensor&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;의 복사본을 반환하기 때문에, Tensor를 직접 덮어써야 합니다:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;my_tensor&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;=&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;my_tensor.to(torch.device('cuda'))&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;cpu-gpu&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;CPU에서 저장하고 GPU에서 불러오기&lt;/h3&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저장하기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell18&quot; class=&quot;css&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save(model.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불러오기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell19&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;device = torch.device(&quot;cuda&quot;)
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH, map_location=&quot;cuda:0&quot;))  # 사용할 GPU 장치 번호를 선택합니다.
model.to(device)
# 모델에서 사용하는 input Tensor들은 input = input.to(device) 을 호출해야 합니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;CPU에서 학습한 모델을 GPU에서 불러올 때는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.load()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;map_location&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;인자에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;cuda:device_id&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 설정합니다. 이렇게 하면 모델이 해당 GPU 장치에 불러와집니다. 다음으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.to(torch.device('cuda'))&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 호출하여 모델의 매개변수 Tensor들을 CUDA Tensor들로 변환해야 합니다. 마지막으로 모든 모델 입력에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;.to(torch.device('cuda'))&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 사용하여 CUDA 최적화된 모델을 위한 데이터로 만들어야 합니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;my_tensor.to(device)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 호출하면 GPU에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;my_tensor&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;의 복사본을 반환합니다. 이 동작은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;my_tensor&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 덮어쓰지 않기 때문에, Tensor를 직접 덮어써야 합니다:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;my_tensor&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;=&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;my_tensor.to(torch.device('cuda'))&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&quot;torch-nn-dataparallel&quot;&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; color: #262626;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.nn.DataParallel&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모델 저장하기&lt;/h3&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저장하기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell20&quot; class=&quot;css&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save(model.module.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불러오기:&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell21&quot; class=&quot;vala&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;# 사용할 장치에 불러옵니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.nn.DataParallel&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;은 병렬 GPU 활용을 가능하게 하는 모델 래퍼(wrapper)입니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;DataParallel&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모델을 범용적으로 저장하려면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.module.state_dict()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 사용하면 됩니다. 이렇게 하면 원하는 모든 장치에 원하는 방식으로 유연하게 모델을 불러올 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #262626;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Total running time of the script:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;( 0 minutes 0.000 seconds)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Deep Learning/pytorch</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/105</guid>
      <comments>https://toofoo.tistory.com/105#entry105comment</comments>
      <pubDate>Thu, 17 Aug 2023 04:09:27 +0900</pubDate>
    </item>
    <item>
      <title>[Pytorch] 장치간 모델 불러오기 (GPU / CPU)</title>
      <link>https://toofoo.tistory.com/104</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. GPU에서 모델을 저장하고 CPU에서 불러오기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. GPU에서 저장하고 GPU에서 불러오기&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. CPU에서 모델을 저장하고 GPU에서 불러오기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. GPU에서 모델을 저장하고 CPU에서 불러오기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GPU 모델 저장&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1692212585068&quot; class=&quot;css&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torch.save(model.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저장한 모델을 CPU에서 로드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1692212585069&quot; class=&quot;reasonml&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;device = torch.device('cpu')
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH, map_location=device))&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;위와 같이 GPU에서 학습한 모델을 CPU에서 불러올 때는 torch.load() 함수의 map_location 인자에 'cpu' 값을 전달함&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;이 경우에는 Tensor에 저장된 내용들은 map_location 인자를 사용하여 CPU 장치에 동적으로 재배치됨&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. GPU에서 모델을 저장하고 GPU에서 불러오기&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GPU모델 저장 (위와 동일)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1692212585071&quot; class=&quot;css&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torch.save(model.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저장한 모델을 GPU에서 로드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1692212585071&quot; class=&quot;reasonml&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;device = torch.device(&quot;cuda&quot;)
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.to(device)
# 모델에서 사용하는 input Tensor들은 input = input.to(device) 을 호출해야 합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;GPU에서 학습된 모델을 GPU에서 불러올 때에는&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;초기화된 model에 model.to(torch.device('cuda')) 를 호출하여 CUDA 최적화된 모델로 변환해야함&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한, 모델에 데이터를 제공하는 모든 입력에 .to(torch.device('cuda')) 함수를 호출해야함&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;my_tensor.to(device) 를 호출하면 GPU에 my_tensor의 복사본을 반환하기 때문에 Tensor를 직접 덮어써야함&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;my_tensor = my_tensor.to(torch.device('cuda'))&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. CPU에서 모델을 저장하고 GPU에서 불러오기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CPU모델 저장 (위와 동일)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1692212585074&quot; class=&quot;css&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torch.save(model.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저장한 모델을 GPU에서 로드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1692212585074&quot; class=&quot;reasonml&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;device = torch.device(&quot;cuda&quot;)
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH, map_location=&quot;cuda:0&quot;))  # 사용할 GPU 장치 번호를 선택합니다.
model.to(device)
# 모델에서 사용하는 input Tensor들은 input = input.to(device) 을 호출해야 합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;CPU에서 학습한 모델을 GPU에서 불러올 때는 torch.load() 함수의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;map_location 인자에 cuda:device_id 을 설정하면 모델이 해당&amp;nbsp;GPU 장치에 로드됨&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;다음으로 model.to(torch.device('cuda')) 을 호출하여 모델의 매개변수 Tensor들을 CUDA Tensor들로 변환해야 함&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;마지막으로 모든 모델 입력에 .to(torch.device('cuda')) 을 사용하여 CUDA 최적화된 모델을 위한 데이터로 만들어야 함&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;my_tensor.to(device) 를 호출하면 GPU에 my_tensor 의 복사본을 반환하며, 이 동작은 my_tensor 를 덮어쓰지 않기 때문에, Tensor를 직접 덮어써야 함&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;my_tensor = my_tensor.to(torch.device('cuda')) .&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;font-family: 'Nanum Gothic'; background-color: #ffffff; color: #262626; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.nn.DataParallel&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모델 저장하기&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #262626; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저장하기:&lt;/b&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell20&quot; class=&quot;css&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;torch.save(model.module.state_dict(), PATH)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #262626; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불러오기:&lt;/b&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;
&lt;div style=&quot;background-color: #f8f8f8;&quot;&gt;
&lt;pre id=&quot;codecell21&quot; class=&quot;vala&quot; style=&quot;background-color: #f3f4f7; color: #212529;&quot;&gt;&lt;code&gt;# 사용할 장치에 불러옵니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #262626; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;torch.nn.DataParallel&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;은 병렬 GPU 활용을 가능하게 하는 모델 래퍼(wrapper)입니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;DataParallel&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모델을 범용적으로 저장하려면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3f4f7; color: #6c6c6d;&quot;&gt;model.module.state_dict()&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 사용하면 됩니다. 이렇게 하면 원하는 모든 장치에 원하는 방식으로 유연하게 모델을 불러올 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #ee2323;&quot;&gt;&lt;b&gt;만일 map_location 을 설정하지 않는 경우 아래와 같은 에러를 맞이한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #000000; color: #000000; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;RuntimeError: Attempting to deserialize object on a CUDA device but torch.cuda.is_available() is False. If you are running on a CPU-only machine, please use torch.load with map_location=torch.device('cpu') to map your storages to the CPU.&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Deep Learning/pytorch</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/104</guid>
      <comments>https://toofoo.tistory.com/104#entry104comment</comments>
      <pubDate>Thu, 17 Aug 2023 04:06:58 +0900</pubDate>
    </item>
    <item>
      <title>CycleGAN</title>
      <link>https://toofoo.tistory.com/102</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. CycleGAN&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.1 연구 배경&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;CycleGAN 모델을 만든 저자는 한국인으로 이전의 pix2pix라는 연구의 확장이 CycleGAN이라 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qDWX6/btsq5bBNAqi/SCtXRaDiKGqrGFHJ87hedK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qDWX6/btsq5bBNAqi/SCtXRaDiKGqrGFHJ87hedK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qDWX6/btsq5bBNAqi/SCtXRaDiKGqrGFHJ87hedK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqDWX6%2Fbtsq5bBNAqi%2FSCtXRaDiKGqrGFHJ87hedK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1151&quot; height=&quot;536&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lj5ll/btreZ1ZpTsw/TKN33v1Q40e0dJqPVAfebk/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 48] CycleGAN 모델의 결과&quot;&gt;&lt;/span&gt;[그림 48] CycleGAN 모델의 결과&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;CycleGAN은 특정 화풍, 질감을 다른 사진에 적용할 수 있는가에 대한 질문에 답을 하기 위해 만들어진 모델이라 할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2 핵심 아이디어&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특징이 겹치지 않는 서로 다른 이미지 집합(Unpaired)을 학습하기 위해 순환 일관성 손실 함수(Cycle Consistency)를 사용하였다는 것이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;437&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGaoYS/btsq8IMJHZE/XaQc1W6xoO9j5c0BPMA8yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGaoYS/btsq8IMJHZE/XaQc1W6xoO9j5c0BPMA8yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGaoYS/btsq8IMJHZE/XaQc1W6xoO9j5c0BPMA8yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGaoYS%2Fbtsq8IMJHZE%2FXaQc1W6xoO9j5c0BPMA8yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;506&quot; height=&quot;437&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;437&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C97js/btre6DvW3cC/2lGGTZEtKczbkb35DMVbK1/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 49] 순환 일관성 손실 함수&quot;&gt;&lt;/span&gt;[그림 49] 순환 일관성 손실 함수&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;일종의 역함수라고 할 수 있다. 하지만 G를 통해 변환한 것이 F를 통해 재 변환될 때 원본과 최대한 가까워 지도록 loss 값을 설정하여 학습하는 것이라 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 Paired는 x좌표 값이 y좌표 값에 대응되는 정보가 담기지만 Unpaired는 대응되는 정보가 존재하지 않는 것이 특징이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dffIR7/btsrgi0Ksff/uGHrWZ7mxwIMmPjEvTC3Uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dffIR7/btsrgi0Ksff/uGHrWZ7mxwIMmPjEvTC3Uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dffIR7/btsrgi0Ksff/uGHrWZ7mxwIMmPjEvTC3Uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdffIR7%2Fbtsrgi0Ksff%2FuGHrWZ7mxwIMmPjEvTC3Uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;574&quot; height=&quot;357&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2nbaZ/btre5wql5px/sk2LY2duuUozM2zmkKGkw0/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 50] Pair &amp;amp;amp; Unpaired dataset&quot;&gt;&lt;/span&gt;[그림 50] Pair &amp;amp; Unpaired dataset&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;paired의 경우 pix2pix 모델에서 사용했다 할 수 있고 unpaired의 경우 cycleGAN에서 사용하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 unpaired dataset에서의 translate를 위해 사용한 함수는 순환 일관성 손실함수인데 그 전체는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0D3PK/btsrgqLfzcI/6HoUZxGTVBoavmsBK9cXe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0D3PK/btsrgqLfzcI/6HoUZxGTVBoavmsBK9cXe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0D3PK/btsrgqLfzcI/6HoUZxGTVBoavmsBK9cXe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0D3PK%2FbtsrgqLfzcI%2F6HoUZxGTVBoavmsBK9cXe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;830&quot; height=&quot;168&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjoT7L/btreZ16d5L7/QXrk8D7kjxb6NyaDMBJrk1/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 51] 순환 일관성 손실 함수&quot;&gt;&lt;/span&gt;[그림 51] 순환 일관성 손실 함수&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;크게 어려울 것 없다. 역함수를 통해 나온 값이 만약 x'라면(strict하지 않기 때문에 x'가 나옴) x와의 차이가 줄어들도록 loss 값을 설정한 것이다. 마찬가지로 y'가 나온다면 y와의 차이 값이 줄어들도록 만든것이 순환 일관성 손실함수라 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.3 실험 결과&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnB5n7/btsrat9LBF1/8vtHmakUoTzwAYnyXhQ4TK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnB5n7/btsrat9LBF1/8vtHmakUoTzwAYnyXhQ4TK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnB5n7/btsrat9LBF1/8vtHmakUoTzwAYnyXhQ4TK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnB5n7%2Fbtsrat9LBF1%2F8vtHmakUoTzwAYnyXhQ4TK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;819&quot; height=&quot;472&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCfaba/btre0cGqBlm/Yzp7JdgiTqq2U8ZrtoTknk/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 52] CycleGAN 모델이 생성한 이미지 (실험 결과)&quot;&gt;&lt;/span&gt;[그림 52] CycleGAN 모델이 생성한 이미지 (실험 결과)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;CycleGAN 모델의 실험 결과로 좌측의 Input 값을 넣으면 우측의 모네, 반고흐 등의 화풍으로 바꿔주는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 CycleGAN에서는 실제 위성사진을 지도로 바꿔주고 지도를 실제 위성사진으로 얼마나 잘 바꾸어주는 가에 대한 실험도 하였고 아래 그림과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/X28FH/btsraunjFex/kDIxKFFJeldVTI3vpiaDQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/X28FH/btsraunjFex/kDIxKFFJeldVTI3vpiaDQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/X28FH/btsraunjFex/kDIxKFFJeldVTI3vpiaDQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FX28FH%2FbtsraunjFex%2FkDIxKFFJeldVTI3vpiaDQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1248&quot; height=&quot;611&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGt3pZ/btreZ1ZqhcN/LSQ367go6mnx55fm19mNJ1/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 53] CycleGAN 모델이 수행한 Photo-Map, Map-Photo 결과&quot;&gt;&lt;/span&gt;[그림 53] CycleGAN 모델이 수행한 Photo-Map, Map-Photo 결과&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;어색하거나 엉뚱한 결과를 내는 다른 모델들에 비해 Ground truth와 가장 유사한 그림을 만들어내는 것을 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 CycleGAN을 평가하기 위한 평가 메트릭으로는 AMT와 FCN-Score를 사용하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;AMT: 사람에게 어떤 것이 진짜인지 평가하는 방식으로 별도의 Metric이 없는 GAN에게 가장 강력한 점수&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;FCN Score: YOLO와 같은 객체 탐지 모델을 사용해 변환된 이미지에서 얼마나 사물을 잘 인식하는가?&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pKuFy/btsrfhnu0Kh/rvIdQZ4id38dETKkiNSuj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pKuFy/btsrfhnu0Kh/rvIdQZ4id38dETKkiNSuj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pKuFy/btsrfhnu0Kh/rvIdQZ4id38dETKkiNSuj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpKuFy%2Fbtsrfhnu0Kh%2FrvIdQZ4id38dETKkiNSuj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;749&quot; height=&quot;257&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0Ifnd/btreX3cnwYL/rdlxYiVovDxtyKk9DMTDe1/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 54] AMT&quot;&gt;&lt;/span&gt;[그림 54] AMT&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;CycleGAN이 다른 모델들에 비해 Map&amp;rarr;Photo, Photo&amp;rarr;Map에서 가장 우수한 성능을 보이는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 FCN Score에서도 마찬가지로 CycleGAN이 다른 모델들과 비교하여 뛰어난 성능을 보이는 것을 알 수 있다. (pix2pix은 저자의 연구실에서 하던 이전 연구)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;263&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdGzbN/btsrf2wZDE5/XikcfhdZWx1CrSwlnXoyx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdGzbN/btsrf2wZDE5/XikcfhdZWx1CrSwlnXoyx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdGzbN/btsrf2wZDE5/XikcfhdZWx1CrSwlnXoyx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdGzbN%2Fbtsrf2wZDE5%2FXikcfhdZWx1CrSwlnXoyx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;730&quot; height=&quot;263&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;263&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blGYFZ/btre4Orrfbg/thq3JKMwtKTkr0kVE7DHm1/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 54] FCN-Score&quot;&gt;&lt;/span&gt;[그림 54] FCN-Score&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.4 한계점&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;색상이나 질감은 변경할 수 있으나 객체의 모양은 바꿀 수 없는 것이 단점이다. 이는 여러 장의 데이터를 학습하여 분위기(화풍, 질감) 변경에만 초점을 두기 때문이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VTh2Y/btsrgi0KsiC/zadwD3vZjxspkV9BEc2u80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VTh2Y/btsrgi0KsiC/zadwD3vZjxspkV9BEc2u80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VTh2Y/btsrgi0KsiC/zadwD3vZjxspkV9BEc2u80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVTh2Y%2Fbtsrgi0KsiC%2FzadwD3vZjxspkV9BEc2u80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;663&quot; height=&quot;420&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;420&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WkU5R/btre1bHtbAr/02YntHoWiWb36rgUgTt3C1/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 55] CycleGAN의 한계점&quot;&gt;&lt;/span&gt;[그림 55] CycleGAN의 한계점&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.5 Contribution Point&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주요 컨트리뷰션 포인트는 기존의 pix2pix 모델에 순환일관성 손실함수를 도입하여 unpaired한 데이터셋에서도 동작하게 만들었다는 것이 핵심이라 할 수 있다&lt;/p&gt;</description>
      <category>Deep Learning/pytorch</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/102</guid>
      <comments>https://toofoo.tistory.com/102#entry102comment</comments>
      <pubDate>Mon, 14 Aug 2023 14:13:20 +0900</pubDate>
    </item>
    <item>
      <title>SRGAN (Super Resolution GAN)</title>
      <link>https://toofoo.tistory.com/101</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. SRGAN (Super Resolution GAN)&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;SRGAN은 Super Resolution GAN을 의미하는 것으로 한마디로 말하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;&lt;b&gt;저화질의 이미지&lt;/b&gt;&lt;/u&gt;를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;&lt;b&gt;고화질의 이미지&lt;/b&gt;&lt;/u&gt;로 바꾸는 모델이라 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.1 연구 배경&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존의 SR 모델에서 목적 함수를 MSE (Mean Square Error)로 학습하여 높은 PSNR (Peak Signal-to-Noise Ratio)를 가진다. 하지만 High Frequency 성분을 갖는 detail이 결여되어 있기 때문에 Texture를 표현하는 것이 어렵다는 점을 극복하기 위해 진행 된 연구이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mgRrn/btsq5XJ67VN/tI5BIEDR0ryyMgXcf1b1T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mgRrn/btsq5XJ67VN/tI5BIEDR0ryyMgXcf1b1T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mgRrn/btsq5XJ67VN/tI5BIEDR0ryyMgXcf1b1T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmgRrn%2Fbtsq5XJ67VN%2FtI5BIEDR0ryyMgXcf1b1T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;734&quot; height=&quot;290&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUNMO8/btre7s8LTPZ/0f6jiCeZyn4M1mfnIy21g1/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 37] SRGAN과 타 모델 간의 성능 비교&quot;&gt;&lt;/span&gt;[그림 37] SRGAN과 타 모델 간의 성능 비교&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 말해 MSE는 이미지가 조금 흐릿한 형태를 띠게 되는데 이는 MSE loss function은 average(평균제곱오차)를 학습하기 때문이다. 전반적으로 smooth한 정보를 얻어서 high frequency content를 표현하지 못한다는 것이다. 다시 말해 평균을 loss로 잡았기 때문에 이미지의 고주파수 영역이 평균 값으로 회귀 된다는 의미이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2 PSNR&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 PSNR을 설명하면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;최대 신호대비 잡음비&lt;/b&gt;라고 할 수 있다. 구체적으로, 신호가 가질 수 있는 최대 전력에 대한 잡음의 전력이다. 주로 동영상이 압축될 때 화질 손실 정보를 평가할때 사용하는 지표로, 높을 수록 결과 값이 좋다 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1022&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDQ5qC/btsrgumuhoK/zAosHsnLDrUbmfjOqGUcUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDQ5qC/btsrgumuhoK/zAosHsnLDrUbmfjOqGUcUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDQ5qC/btsrgumuhoK/zAosHsnLDrUbmfjOqGUcUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDQ5qC%2FbtsrgumuhoK%2FzAosHsnLDrUbmfjOqGUcUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1022&quot; height=&quot;354&quot; data-origin-width=&quot;1022&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxhCj2/btreZ0e5kYf/XNKLGfwkHXdbDZlgOgNMx0/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 38] PSNR 수치 저하에 따른 이미지 화질 비교&quot;&gt;&lt;/span&gt;[그림 38] PSNR 수치 저하에 따른 이미지 화질 비교&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이러한 PSNR의 단점은 원본 이미지와 왜곡 이미지 사이의 수치적 차이로 평가하기 때문에 사람 인지와 일치되지 않는 품질 점수를 산출한다는 것이다. 예를 들면 아래 그림과 같다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HcCHC/btsq50fOl4C/5OKb6uXYix9cFA4CMe5UnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HcCHC/btsq50fOl4C/5OKb6uXYix9cFA4CMe5UnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HcCHC/btsq50fOl4C/5OKb6uXYix9cFA4CMe5UnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHcCHC%2Fbtsq50fOl4C%2F5OKb6uXYix9cFA4CMe5UnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;797&quot; height=&quot;312&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beItU6/btre4OroZEk/L2lbGXkxDS9c5qKgKkAb00/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 39] 비슷한 PSNR 수치에 대한 인지적 품질의 차이&quot;&gt;&lt;/span&gt;[그림 39] 비슷한 PSNR 수치에 대한 인지적 품질의 차이&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;PSNR 값은 유사하지만 품질을 제대로 반영하지 못하는 것과 같다. 이는 PSNR을 산출하는 수식에 내재한 단점이라 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqNnTn/btsrdkdBU1x/bgqDMqJbKZr9RIkkJt0Ehk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqNnTn/btsrdkdBU1x/bgqDMqJbKZr9RIkkJt0Ehk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqNnTn/btsrdkdBU1x/bgqDMqJbKZr9RIkkJt0Ehk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqNnTn%2FbtsrdkdBU1x%2FbgqDMqJbKZr9RIkkJt0Ehk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;744&quot; height=&quot;298&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zpGVq/btre5u64W1a/Gh4GBJTYFzTemgtqFJGlk0/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 40] PSNR 산출 수식&quot;&gt;&lt;/span&gt;[그림 40] PSNR 산출 수식&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;핵심은 맨 아랫줄만 확인하면 이해할 수 있다. PSNR은 MAX에 log scale을 취한 것에 MSE에 log scale을 취한 것을 빼준다. 하지만 앞서 언급하였던 MSE를 사용하기 때문에 이미지의 고주파수 영역을 나타내지 못하고 결과적으로 PSNR 값에 따른 이미지의 품질이 사람의 인지와 달라지는 것이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 단점을 극복하기 위해 대안으로 사용하는 것은 SSIM, MOS, PSNR-HVS, PSNR-HVS-M, VIF 등이 있긴하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/catjJb/btsq1d8giOr/7BQytMMPNgh2ldSknzc2f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/catjJb/btsq1d8giOr/7BQytMMPNgh2ldSknzc2f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/catjJb/btsq1d8giOr/7BQytMMPNgh2ldSknzc2f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcatjJb%2Fbtsq1d8giOr%2F7BQytMMPNgh2ldSknzc2f1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;725&quot; height=&quot;296&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TamZe/btre33WJGcC/ndKDiQRUDB6klif33vKafk/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 41] PSNR의 대안인 SSIM (1에 가까울 수록 좋음)&quot;&gt;&lt;/span&gt;[그림 41] PSNR의 대안인 SSIM (1에 가까울 수록 좋음)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 다시 SRGAN 모델로 돌아와서, 결과적으로 이 연구에서 하고자 하는 핵심은 해상도를 평가하는 PSNR이라는 수치는 높더라도 실제 사람의 눈으로 봤을 때 해상도가 높지 않다. 따라서 실제로 눈으로 보더라도 해상도가 높게 나올 수 있도록 만들겠다는 것이 이 연구의 핵심이라 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.3 연구 핵심&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같은 단점을 해결하기 위한 핵심 방안으로, 인지적 유사성에 주목한 perceptual loss를 사용하였다는 것이다. percepual loss는 크게 2가지인 content loss와 adversarial loss로 구성된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;519&quot; data-origin-height=&quot;136&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/42hQb/btsrfhufKkQ/k4xn3Qam7Uo6MRWOKBxSCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/42hQb/btsrfhufKkQ/k4xn3Qam7Uo6MRWOKBxSCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/42hQb/btsrfhufKkQ/k4xn3Qam7Uo6MRWOKBxSCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F42hQb%2FbtsrfhufKkQ%2Fk4xn3Qam7Uo6MRWOKBxSCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;519&quot; height=&quot;136&quot; data-origin-width=&quot;519&quot; data-origin-height=&quot;136&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4MUoq/btreYoANJ6U/07jA0917d2CxMR05z5itZ0/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 42] perceptual loss&quot;&gt;&lt;/span&gt;[그림 42] perceptual loss&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5.3.1 content loss&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;pixel space에서 유사성 대신에 perceptual 유사성을 학습하기 위한 loss이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwphWH/btsq2hPPBdV/KgNkeJBU3wKlHB6IZ4O9Uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwphWH/btsq2hPPBdV/KgNkeJBU3wKlHB6IZ4O9Uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwphWH/btsq2hPPBdV/KgNkeJBU3wKlHB6IZ4O9Uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwphWH%2Fbtsq2hPPBdV%2FKgNkeJBU3wKlHB6IZ4O9Uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;752&quot; height=&quot;194&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kJ29V/btreYpsVoHM/5NXcDmApHhbkfg7iwkLYN0/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 43] content loss&quot;&gt;&lt;/span&gt;[그림 43] content loss&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;복잡할 것 없이 간단하게 이해하면 다음과 같다. LR(Low Resolution) 이미지를 즉, 저해상도 이미지를 생성자가 만들면 판별자가 판별할 것인데 N개를 판별한 합이 작아지도록 만드는 것이라 할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1.3.2 Adversarial loss&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;판별자를 속이기 위한 loss 함수라 할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TkkAx/btsrglDan99/nzhRMSXZTdhtrpO3rgA170/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TkkAx/btsrglDan99/nzhRMSXZTdhtrpO3rgA170/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TkkAx/btsrglDan99/nzhRMSXZTdhtrpO3rgA170/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTkkAx%2FbtsrglDan99%2FnzhRMSXZTdhtrpO3rgA170%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;811&quot; height=&quot;225&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQmNyN/btre5a168ot/pELiiv3BbqmPTY5bqRSI2K/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 44] adversarial loss&quot;&gt;&lt;/span&gt;[그림 44] adversarial loss&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 간략히만 이해하면 HR(고해상도)의 이미지에서 LR(저해상도)의 이미지를 빼고 제곱을 취해준 값의 합이 점점 줄어들도록 학습하는 것이라 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.4 아키텍처&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;논문에 언급된 아키텍처보다 더 직관적으로 설명되어 있는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://aigong.tistory.com/51&quot;&gt;그림&lt;/a&gt;을 확인할 수 있었고 아래와 같다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bauCp9/btsq1EqWQDX/koLbWwwKG1zPWvb3uoCOI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bauCp9/btsq1EqWQDX/koLbWwwKG1zPWvb3uoCOI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bauCp9/btsq1EqWQDX/koLbWwwKG1zPWvb3uoCOI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbauCp9%2Fbtsq1EqWQDX%2FkoLbWwwKG1zPWvb3uoCOI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;570&quot; height=&quot;374&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/May17/btre2excgZn/ADGV9kjRHKRBMP9ym1FHGK/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 45] SRGAN 아키텍처&quot;&gt;&lt;/span&gt;[그림 45] SRGAN 아키텍처&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Pretrained된 2개의 VGG net loss를 사용한다. (reconstructed image와 reference image의 feature map 사이의 유클리디안 거리를 계산하는 방법을 사용)&amp;nbsp;여기에서 사용된 VGG22는 low level feature map을 대표하는 loss이며, VGG54는 high level feature map을 대표하는 loss라고 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.5 실험결과&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;평가 방법 중 MOS (Mean Opinion Score)를 사용하였는데 이는 Perceptual Quaility를 표현하기 위함이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRz6AG/btsrfjewJFa/MT6pyDQ9XeEgh66OJtP0h0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRz6AG/btsrfjewJFa/MT6pyDQ9XeEgh66OJtP0h0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRz6AG/btsrfjewJFa/MT6pyDQ9XeEgh66OJtP0h0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRz6AG%2FbtsrfjewJFa%2FMT6pyDQ9XeEgh66OJtP0h0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;623&quot; height=&quot;317&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;317&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baq7jq/btre2ecSST7/S21TI4rKBRav9jkpSTZkOk/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 46] SRGAN 모델 성능 지표 비교&quot;&gt;&lt;/span&gt;[그림 46] SRGAN 모델 성능 지표 비교&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Set5와 Set14의 경우 데이터셋을 의미한다. 저자들은 MOS라고 하는 벤치마크 스코어를 사용하여 MSE를 사용하였을 때 보다 높은 MOS 스코어를 얻음을 보인다. 하지만 MOS라고 하는 것은 일종의 주관적인 평가로, 평가자 몇 명을 모집하여 사용하는 방식이라는 점에 있어서 정량적이라기 보다 정성적인 평가에 가깝다고 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주요 컨트리뷰션 포인트로는 크게 2가지로, 첫번째는 새로운 perceptual loss를 제안하였다는 점이고 두 번째로는 모호하지만 새로운 벤치마크 스코어인 MOS를 제안하였다는 것이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 VGG54를 저자들은 SRGAN이라고 부른다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.6 적용 결과&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;저자들은 유튜브에 자신들이 만든 SRGAN을 이용한 영화 화질을 높이는 것을 보였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtu.be/sUhbIdSd6dc&quot;&gt;https://youtu.be/sUhbIdSd6dc&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=sUhbIdSd6dc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/ir8FV/hyLBrX1HW3/ubnFU7kzXm98q7rK0wKwpK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=252_308_1026_456&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-original-url=&quot;&quot; data-video-title=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/sUhbIdSd6dc&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.7 국내 연구 사례&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;477&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTYvL3/btsrf3bAR0j/sTv761R84FzeHpEYQKKKY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTYvL3/btsrf3bAR0j/sTv761R84FzeHpEYQKKKY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTYvL3/btsrf3bAR0j/sTv761R84FzeHpEYQKKKY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTYvL3%2Fbtsrf3bAR0j%2FsTv761R84FzeHpEYQKKKY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;350&quot; height=&quot;477&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;477&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lSue9/btsq7ctETRP/IjApzXefn7foMqWcWjbTL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lSue9/btsq7ctETRP/IjApzXefn7foMqWcWjbTL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lSue9/btsq7ctETRP/IjApzXefn7foMqWcWjbTL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlSue9%2Fbtsq7ctETRP%2FIjApzXefn7foMqWcWjbTL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;542&quot; height=&quot;295&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;295&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[그림 47] SRGAN 국내 연구 사례&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 이러한 SRGAN을 사용하여 CCTV 영상의 화질을 개선하는 기법을 연구한 국내 연구 사례도 존재한다. 하지만 그럴듯하게 생성이 가능하다는 것이지 법적인 증거로서의 효력으로 채택되는 것은 별 개의 문제가 될 수 있겠다.&lt;/p&gt;</description>
      <category>Deep Learning/pytorch</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/101</guid>
      <comments>https://toofoo.tistory.com/101#entry101comment</comments>
      <pubDate>Mon, 14 Aug 2023 14:12:08 +0900</pubDate>
    </item>
    <item>
      <title>PGGAN (Progressive Growing GAN)</title>
      <link>https://toofoo.tistory.com/100</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. PGGAN (Progressive Growing GAN)&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.1 연구 배경&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;크게 2가지 단점을 극복하고자 PGGAN 모델이 만들어지게 되었다. 첫 번째로는 GAN을 고해상도로 만들면 판별자는 생성자가 생성한 이미지의 Real/Fake 여부를 구분하기 쉬워진다는 단점이 있고, 두 번째로는 고해상도로 만들어도 메모리 제약조건으로 batch size를 줄여야하고 줄이면 학습과정이 불안정해진다는 단점이 있었기 때문이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2 핵심 아이디어&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;PGGAN은 NVIDIA에서 진행한 연구이다. PGGAN의 핵심 아이디어는 4x4의 저해상도 이미지를 1024x1024 고해상도 이미지로 단계별(Progressive Growing)로 학습한다는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;406&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dWHoqX/btsq1a4wOyz/YqwdQZbfKQFrYRgOfcRRY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dWHoqX/btsq1a4wOyz/YqwdQZbfKQFrYRgOfcRRY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dWHoqX/btsq1a4wOyz/YqwdQZbfKQFrYRgOfcRRY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdWHoqX%2Fbtsq1a4wOyz%2FYqwdQZbfKQFrYRgOfcRRY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;406&quot; height=&quot;250&quot; data-origin-width=&quot;406&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sliDZ/btsrfhHNuqy/sdzfpNQHh4a2vpVsKTx6cK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sliDZ/btsrfhHNuqy/sdzfpNQHh4a2vpVsKTx6cK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sliDZ/btsrfhHNuqy/sdzfpNQHh4a2vpVsKTx6cK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/sliDZ/btsrfhHNuqy/sdzfpNQHh4a2vpVsKTx6cK/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;454&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[그림 34] PGGAN의 핵심 아이디어&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존에는 처음부터 고해상도 이미지를 학습하려다 보니 학습이 올바르게 되지 않았다. 이는 초등생에게 처음부터 미적분을 묻는 것과 같다고 한다. 따라서 기본적인 사칙연산에 해당하는 4x4, 8x8, 16x16으로 점진적으로 학습하게 되면 계속해서 간단한 문제를 묻는 것과 같기 때문에 학습이 더 잘된다고 한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 저해상도에서 보이는 Abstract을 우선적으로 학습 한 뒤 고해상도에서 보이는 Concrete(눈, 코, 입, 모공 등)를 학습하는 것이 특징이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 PGGAN의 장점은 크게 3가지로 나뉜다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 작은 이미지부터 점진적으로 학습하기 때문에 안정성 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. 처음부터 복잡한 질문을 하지 않기에 간단하다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3. 저해상도에서 학습할 때 충분한 학습을 하게 되며 학습 시간이 짧다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.3 실험 결과&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;가장 처음 설명한 Original GAN의 결과와 비교했을 때 비약적으로 발전한 것을 느낄 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUY2SH/btsrgqLeBrD/XP7z4GqLD8fkSQbCykQL91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUY2SH/btsrgqLeBrD/XP7z4GqLD8fkSQbCykQL91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUY2SH/btsrgqLeBrD/XP7z4GqLD8fkSQbCykQL91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUY2SH%2FbtsrgqLeBrD%2FXP7z4GqLD8fkSQbCykQL91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;512&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[그림 35] PGGAN 모델에서 생성한 이미지&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같은 이미지를 생성하기 위해 CelebA-HQ 데이터셋을 사용하여 30,000개의 유명인사 사진을 학습했다고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 PGGAN의 성능의 경우 Inception Score가 8.8에 달하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tjX62/btsq51lu2Nf/p7VqWdMybwK3jjdjFkZypK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tjX62/btsq51lu2Nf/p7VqWdMybwK3jjdjFkZypK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tjX62/btsq51lu2Nf/p7VqWdMybwK3jjdjFkZypK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtjX62%2Fbtsq51lu2Nf%2Fp7VqWdMybwK3jjdjFkZypK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;642&quot; height=&quot;379&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[그림 36] PGGAN의 성능 평가&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.4 Contribution Point&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;PGGAN의 핵심 컨트리뷰션 포인트는 기존의 DEGAN, EBGAN, BEGAN 등이 128x128 이미지 밖에 생성하지 못했던 것을 1024x1024의 해상도까지 끌어올린 것이 핵심이라 할 수 있다.&lt;/p&gt;</description>
      <category>Deep Learning/pytorch</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/100</guid>
      <comments>https://toofoo.tistory.com/100#entry100comment</comments>
      <pubDate>Mon, 14 Aug 2023 14:10:56 +0900</pubDate>
    </item>
    <item>
      <title>LSGAN (Least Square GAN)</title>
      <link>https://toofoo.tistory.com/99</link>
      <description>&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.1 연구 배경&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;LSGAN의 경우 단순히 loss 값만 변경하여 성능을 끌어올린 GAN 모델이다. 연구 배경으로는 Sigmoid cross entropy loss가 Gradient Vanishing 문제를 일으킨다는 것이다. 따라서 Sigmoid cross entropy loss &amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;L&lt;/b&gt;east&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;S&lt;/b&gt;quare loss로 변경하자는 것이 이 논문의 핵심이라 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WG5kh/btsq2jNCmuF/Q8XBFcJ2ld2l3aVqyqtv9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WG5kh/btsq2jNCmuF/Q8XBFcJ2ld2l3aVqyqtv9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WG5kh/btsq2jNCmuF/Q8XBFcJ2ld2l3aVqyqtv9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWG5kh%2Fbtsq2jNCmuF%2FQ8XBFcJ2ld2l3aVqyqtv9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;763&quot; height=&quot;303&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bA8QnB/btre4Nst5fx/1vnCtjkMyMPEhc001Xvp7K/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 30] LSGAN의 성능 향상 핵심 방안&quot;&gt;&lt;/span&gt;[그림 30] LSGAN의 성능 향상 핵심 방안&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 그림을 보면 분홍색 *(star)를 볼 수 있다. 분홍색 *는 Generator가 생성한 가짜 이미지라 보면 된다. 하지만 이 가짜이미지는 판별자를 속였고 때문에 더 이상 학습하지 않는(Gradient Vanishing) 것을 확인할 수 있다. 이 때 LSGAN 모델의 아이디어는 판별자를 속였더라도 더 정교하게 속이기 위해 실제 real과 동일한 수준으로 끌어올리자(추가 학습하자)는 것이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2 코드로 이해하는 LSGAN&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존의 GAN과의 가장 큰 차이점이라고 하면 아래와 같이 D의 loss 함수와 G의 loss 함수에 Least Square loss를 적용한 것이라 할 수 있다. (Cross Entropy loss &amp;rarr; Least Square loss)&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;203&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eznqdU/btsq2hI41me/e4ORrztK7vhbB9kNcCdTV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eznqdU/btsq2hI41me/e4ORrztK7vhbB9kNcCdTV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eznqdU/btsq2hI41me/e4ORrztK7vhbB9kNcCdTV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeznqdU%2Fbtsq2hI41me%2Fe4ORrztK7vhbB9kNcCdTV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;422&quot; height=&quot;203&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;203&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NkrhU/btsrcs3Vvme/5xso8gFgrf6xqrhuheJFLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NkrhU/btsrcs3Vvme/5xso8gFgrf6xqrhuheJFLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NkrhU/btsrcs3Vvme/5xso8gFgrf6xqrhuheJFLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNkrhU%2Fbtsrcs3Vvme%2F5xso8gFgrf6xqrhuheJFLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;389&quot; height=&quot;202&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[그림 31] Vanilla GAN(좌) LSGAN(우)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.3 실험 결과&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Original GAN보다 높은 퀄리티를 보이는 이미지를 생성하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btZCWP/btsq5YoLjj4/X3AvpPFbQPYp6qvbZVkK3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btZCWP/btsq5YoLjj4/X3AvpPFbQPYp6qvbZVkK3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btZCWP/btsq5YoLjj4/X3AvpPFbQPYp6qvbZVkK3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtZCWP%2Fbtsq5YoLjj4%2FX3AvpPFbQPYp6qvbZVkK3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;530&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/93j6J/btreYpfjOtL/uG0DCKATIHQfdjRXhJ7wiK/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 32] LSGAN 모델을 통한 이미지 생성 결과&quot;&gt;&lt;/span&gt;[그림 32] LSGAN 모델을 통한 이미지 생성 결과&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 이미지를 생성하기 위해 LSUN(풍경 데이터셋), CIFAR-10을 활용하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주요 컨트리뷰션 포인트 중 첫 번째는 High Quaility라는 것이고 두 번째는 More Stable하다는 것이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;GAN을 평가하는 metric은 크게 두 가지 중 하나인 Inception Score가 Facebook에서 만든 DCGAN보다 뛰어난 성능을 보이는 것을 확인할 수 있다. (나머지 하나는 프리쳇 거리(Frechet Distance))&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;249&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c086Zz/btsq1KxPnR4/RfdRIXMzRJzX3fl7G7QcM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c086Zz/btsq1KxPnR4/RfdRIXMzRJzX3fl7G7QcM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c086Zz/btsq1KxPnR4/RfdRIXMzRJzX3fl7G7QcM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc086Zz%2Fbtsq1KxPnR4%2FRfdRIXMzRJzX3fl7G7QcM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;738&quot; height=&quot;249&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;249&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FuPsi/btre4N66EeW/dxiabJIlr8YCK3LzHooUrK/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 33] LSGAN의 성능 평가&quot;&gt;&lt;/span&gt;[그림 33] LSGAN의 성능 평가&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;</description>
      <category>Deep Learning/pytorch</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/99</guid>
      <comments>https://toofoo.tistory.com/99#entry99comment</comments>
      <pubDate>Mon, 14 Aug 2023 14:10:11 +0900</pubDate>
    </item>
    <item>
      <title>DCGAN (Deep Convolutional GAN)</title>
      <link>https://toofoo.tistory.com/98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 GAN의 한계점은 크게 2가지로 나뉜다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. (성능 평가)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;GAN 모델의 성능을 객관적 수치로 표현할 수 있는 방안이 부재했다. GAN의 경우 결과 자체가 새롭게 만들어진 데이터이기 때문에 비교 가능한 정량적 척도가 없었다는 것이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. (성능 개선)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;GAN은 기존 네트워크 학습 방법과 다른 구조여서 학습이 불안정했다. GAN은 Saddle Problem 혹은 Minmax를 풀어야 하는 태생적으로 불안정한 구조이기 때문이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;실제 2016년 NIPS에서도 GAN의 안정화가 메인화두였다고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이의 두 단점을 모두 개선하여 GAN의 후속 연구가 줄줄이 이어나올 수 있도록 한 연구가 Facebook에서 개발한 DCGAN(Deep Convolutional GAN)이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. DCGAN (Deep Convolutional GAN)&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.1 DCGAN의 연구 배경&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기존의 GAN으로는 성능이 잘 나오지 않았는데 그 이유는 간단하게 Fully-Connected 되어 있는 구조이기 때문이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NJ6Um/btsq2PFCbcK/K5QNB3pokykWyuWxGllKrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NJ6Um/btsq2PFCbcK/K5QNB3pokykWyuWxGllKrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NJ6Um/btsq2PFCbcK/K5QNB3pokykWyuWxGllKrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNJ6Um%2Fbtsq2PFCbcK%2FK5QNB3pokykWyuWxGllKrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;798&quot; height=&quot;250&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwohhg/btreY2DU73G/7k7Edv7GZGB1IxKK6tjN5k/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림21] 기존 GAN의 구조&quot;&gt;&lt;/span&gt;[그림21] 기존 GAN의 구조&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 Facebook은 DCGAN이라고 하는 모델을 내놓으며 Fully-Connected 구조를 CNN으로 바꾸어 GAN의 성능 향상을 도모한 것이 핵심이라 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2 DCGAN의 아키텍처&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래는 DCGAN의 Generator에 해당하는 아키텍처이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7XmNr/btsq1aDsPLH/c9JLJ9bGHDExoh1h9CATl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7XmNr/btsq1aDsPLH/c9JLJ9bGHDExoh1h9CATl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7XmNr/btsq1aDsPLH/c9JLJ9bGHDExoh1h9CATl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7XmNr%2Fbtsq1aDsPLH%2Fc9JLJ9bGHDExoh1h9CATl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;658&quot; height=&quot;267&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crK4aU/btre33vwNqg/GEXZQ9OuV1HBNDYKUaENb1/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 22] DCGAN의 구조 (Generator)&quot;&gt;&lt;/span&gt;[그림 22] DCGAN의 구조 (Generator)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;DCGAN은 생성자 모델에 Transposed Convolutional Network를 사용하여 Up-Sampling하는데 사용하였다. 위 그림에는 나와 있지 않지만 판별자 모델에는 단순 Convolutional Network를 사용한 것이 특징이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Trasnposed Convolutional Network의 경우 기존의 컨볼루션 네트워크처럼 줄어드는 것이 아닌 확대되는 것이라 할 수 있다. 아래 왼쪽은 기존의 컨볼루션 네트워크고 오른쪽의 경우 Transposed 컨볼루션 네트워크이다.&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1170&quot; data-origin-height=&quot;849&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNXkEn/btsrfgIRxOf/eeXsxBCHmL2ZN8n6cqv4G0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNXkEn/btsrfgIRxOf/eeXsxBCHmL2ZN8n6cqv4G0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNXkEn/btsrfgIRxOf/eeXsxBCHmL2ZN8n6cqv4G0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cNXkEn/btsrfgIRxOf/eeXsxBCHmL2ZN8n6cqv4G0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1170&quot; height=&quot;849&quot; data-origin-width=&quot;1170&quot; data-origin-height=&quot;849&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKBGLp/btsq2lSbe6P/lLsEHTkjnfXtwsRMNiP7A1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKBGLp/btsq2lSbe6P/lLsEHTkjnfXtwsRMNiP7A1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKBGLp/btsq2lSbe6P/lLsEHTkjnfXtwsRMNiP7A1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bKBGLp/btsq2lSbe6P/lLsEHTkjnfXtwsRMNiP7A1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;986&quot; height=&quot;542&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[그림 23] Convolutional Network (좌), Transposed Convolutional Network (우)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;좌측 convolutional network는 5x5의 input에 3x3의 kernel을 사용하여 3x3의 output을 출력한다. 반면&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우측 Transposed Convolutional Network는 4x4의 input과 3x3의 kernel을 통해 6x6의 output을 출력한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;DCGAN은 Generator의 구조에 우측의 Transposed Convolutional Network를 사용하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 단순히 CNN으로 변경하는데 있어서 좋은 성능을 내지 못했다. 따라서 최적의 성능을 내기 위해 5가지 방법을 적용하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpoIpE/btsq1JTb24y/ngqka9hY3NPjf7uh6y3J10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpoIpE/btsq1JTb24y/ngqka9hY3NPjf7uh6y3J10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpoIpE/btsq1JTb24y/ngqka9hY3NPjf7uh6y3J10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpoIpE%2Fbtsq1JTb24y%2Fngqka9hY3NPjf7uh6y3J10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;259&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Huh5M/btreY3b2NXk/CXrO8T7epPAwuKTNvjJJJ0/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 24] DCGAN 아키텍처 가이드라인&quot;&gt;&lt;/span&gt;[그림 24] DCGAN 아키텍처 가이드라인&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 미분이 불가능한 Pooling Layer를 제거하고 미분 가능한 Convolution 레이어로 대체하였다. (Unpooling시 매우 이상한 사진을 생성한다 함)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. BatchNormalization 레이어를 추가하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3. fully-connected hidden layer를 삭제하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4. 생성자 모델에 ReLU 함수를 적용하고 출력의 activation function은 Tanh로 설정하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;5. 마지막으로 판별자 모든 레이어에 LeakyReLU를 적용하여 유연성을 더하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같은 intensive한 실험을 통해 알아낸 최적의 generator 구조가 [그림 22]라고 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;DCGAN의 전체 아키텍처는 아래와 같다. [그림 24]의 실험을 통해 알아낸 방법을 적용한 결과를 나타낸다. (출처:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://blog.naver.com/laonple/221201915691&quot;&gt;Here&lt;/a&gt;)&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DFhkm/btsrfhHNfY8/IGvnkqFkWQtkRWuenFny40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DFhkm/btsrfhHNfY8/IGvnkqFkWQtkRWuenFny40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DFhkm/btsrfhHNfY8/IGvnkqFkWQtkRWuenFny40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDFhkm%2FbtsrfhHNfY8%2FIGvnkqFkWQtkRWuenFny40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;490&quot; height=&quot;326&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;251&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qLdzL/btsrffXugFp/KM6U8dY7piJxnJqd2XkPXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qLdzL/btsrffXugFp/KM6U8dY7piJxnJqd2XkPXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qLdzL/btsrffXugFp/KM6U8dY7piJxnJqd2XkPXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqLdzL%2FbtsrffXugFp%2FKM6U8dY7piJxnJqd2XkPXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;378&quot; height=&quot;251&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;251&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[그림 25] DCGAN 전체 아키텍처&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.3 실험 결과&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;DCGAN을 사용하여 모델을 학습 시켜 이미지를 생성한 결과는 다음과 같다.&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d7bwBC/btsq1GoL1pk/Xd1rDmmUbclClBVNWtQ0qK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d7bwBC/btsq1GoL1pk/Xd1rDmmUbclClBVNWtQ0qK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d7bwBC/btsq1GoL1pk/Xd1rDmmUbclClBVNWtQ0qK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd7bwBC%2Fbtsq1GoL1pk%2FXd1rDmmUbclClBVNWtQ0qK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;216&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLkVrX/btsq1apTYqU/c5SPDrBkUnjdF2M9uQ0wl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLkVrX/btsq1apTYqU/c5SPDrBkUnjdF2M9uQ0wl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLkVrX/btsq1apTYqU/c5SPDrBkUnjdF2M9uQ0wl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLkVrX%2Fbtsq1apTYqU%2Fc5SPDrBkUnjdF2M9uQ0wl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;218&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[그림 26] DCGAN 모델의 이미지 생성 결과&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;얀르쿤의 GAN 모델보다 훨씬 더 다채롭고 가시적인 이미지를 생성하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같은 이미지를 생성하기 위해 학습에 사용한 데이터셋은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;LSUN&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(Large-scale Scene Understanding),&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ImageNet-1K&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Face dataset이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아래는 판별자 모델의 필터를 시각화한 결과이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddgY9J/btsrf1LBqQ4/7bkFwfk2BIIJ7v9RcaNSy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddgY9J/btsrf1LBqQ4/7bkFwfk2BIIJ7v9RcaNSy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddgY9J/btsrf1LBqQ4/7bkFwfk2BIIJ7v9RcaNSy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddgY9J%2Fbtsrf1LBqQ4%2F7bkFwfk2BIIJ7v9RcaNSy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;441&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r8O1A/btre4N0hIiQ/dGnFOLJu1OyDdj9lhhMRu1/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 27] Discriminator 필터 시각화&quot;&gt;&lt;/span&gt;[그림 27] Discriminator 필터 시각화&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각각의 filter들이 침대나 창문과 같이 침실의 일부를 학습하였고, 필터 시각화를 통해 기존의 모델들이 Black Box였던 문제점을 해소하였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 보간(Interpolation)을 수행하여 이미지의 각도를 변경이 가능함을 보였다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKGJxO/btsq0xyVVxH/fdMJtHgupXIeo28GtWg6L0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKGJxO/btsq0xyVVxH/fdMJtHgupXIeo28GtWg6L0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKGJxO/btsq0xyVVxH/fdMJtHgupXIeo28GtWg6L0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKGJxO%2Fbtsq0xyVVxH%2FfdMJtHgupXIeo28GtWg6L0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;365&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTEMuj/btre5a8OSlB/VVRFZI6l8IVlrPKgAdAbG0/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 28] 보간을 통한 각도 변경&quot;&gt;&lt;/span&gt;[그림 28] 보간을 통한 각도 변경&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 보간이란 수치해석학에서 사용되는 개념으로 두 점을 연결하는 방법이다. 보간을 사용하는 이유는 모든 점을 메모리에 올리면 비효율적이기 때문에 특징이 될 수 있는 점들만 대표적으로 메모리에 올려 계산하기 위해 사용된다. 종류에는 다항식 보간법, 스플라인 보간법, 라그랑지 보간법, 뉴턴 보간법 등의 여러 종류가 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 DCGAN을 통해 벡터 산술 연산(Vector Arithmetic)이 가능함을 보였다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDTVnX/btsrgvyT90N/qUnFQY8ao6KBazEXlEGq2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDTVnX/btsrgvyT90N/qUnFQY8ao6KBazEXlEGq2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDTVnX/btsrgvyT90N/qUnFQY8ao6KBazEXlEGq2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDTVnX%2FbtsrgvyT90N%2FqUnFQY8ao6KBazEXlEGq2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;736&quot; height=&quot;381&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;381&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHqFBH/btre4Gz8USl/djqkNFqbCJM9CnqaEuqJiK/img.png&quot; data-lightbox=&quot;lightbox&quot; data-alt=&quot;[그림 29] 벡터 산술 연산&quot;&gt;&lt;/span&gt;[그림 29] 벡터 산술 연산&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;선글라스 낀 남성 - 선글라스 벗은 남성 + 선글라스 벗은 여성 = 선글라스 낀 여성이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.4 주요 Contribution&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;DCGAN은 크게 5가지 컨트리뷰션이 있다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 대부분의 상황에서 언제나 안정적으로 학습하는 Convolution GAN 구조를 제안하였다는 점&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. word2vec과 같은 벡터 산술 연산이 가능하여 Generator를 semantic 수준에서 데이터를 생성할 수 있다는 점&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3. 판별자가 학습한 필터들을 시각화하여 특정 필터들이 특정 물체를 학습했다는 것을 보였다는 점&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4. 학습된 판별자 모델이 다른 비지도 학습 알고리즘과 비교해서 뒤쳐지지 않는 분류 성능을 보였다는 점&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;5. 마지막으로 모든 GAN 연구의 시작점이 될 수 있게 만들어준 연구라고 볼 수 있다.&lt;/p&gt;</description>
      <category>Deep Learning/pytorch</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/98</guid>
      <comments>https://toofoo.tistory.com/98#entry98comment</comments>
      <pubDate>Mon, 14 Aug 2023 14:08:44 +0900</pubDate>
    </item>
    <item>
      <title>About GAN (Generative Adversarial Nets)</title>
      <link>https://toofoo.tistory.com/97</link>
      <description>&lt;div style=&quot;color: #000000; text-align: right;&quot;&gt;&lt;span&gt;&lt;a style=&quot;color: #777777;&quot; href=&quot;https://roytravel.tistory.com/tag/GenerativeAdversarialNets%20%23GAN%20%23%EB%B9%84%EC%A7%80%EB%8F%84%ED%95%99%EC%8A%B5%20%23%EC%96%80%EB%A5%B4%EC%BF%A4%20%23YannLeCun%20%23DCGAN%20%23LSGAN%20%23PGGAN%20%23SRGAN%20%23CycleGAN%20%23IS%20%23FID%20%23KLD%20%23StarGAN%20%23PerceptualLoss&quot;&gt;GenerativeAdversarialNets #GAN #비지도학습 #얀르쿤 #YannLeCun #DCGAN #LSGAN #PGGAN #SRGAN #CycleGAN #IS #FID #KLD #StarGAN #PerceptualLoss&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5UGor/btsrgqdeWVJ/TR5rVvTWU2mrTmEtmHYLG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5UGor/btsrgqdeWVJ/TR5rVvTWU2mrTmEtmHYLG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5UGor/btsrgqdeWVJ/TR5rVvTWU2mrTmEtmHYLG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5UGor%2FbtsrgqdeWVJ%2FTR5rVvTWU2mrTmEtmHYLG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;768&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 1] GAN 모델이 생성한 이미지
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. GAN 모델 개요&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN이란 무엇인가? GAN은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Generative Adversarial Nets&lt;/b&gt;이라는 논문을 통해 나온 모델로 위와 같이 진짜와 동일해 보이는 이미지를 생성하는 모델이다. 그렇다면 우선 GAN은 언제 만들어졌고 어떠한 과정을 거쳐 성장하게 되었는가? 아래는 GAN의 History를 나타내는 그림이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ced9an/btsrcthfvJ6/4SDoZf6XJ0taGSikriZb8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ced9an/btsrcthfvJ6/4SDoZf6XJ0taGSikriZb8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ced9an/btsrcthfvJ6/4SDoZf6XJ0taGSikriZb8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fced9an%2FbtsrcthfvJ6%2F4SDoZf6XJ0taGSikriZb8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;868&quot; height=&quot;366&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 2] History of GAN
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN은 2014년 arXive에 처음 올라온 논문이며 이후, 인공지능 관련 학회인 NIPS에서 정식으로 게재되었다. 처음 GAN 모델이 소개된 이후 수 많은 GAN의 후속 연구들이 이어지고 있는 것을 확인할 수 있다. 위 [그림 2]에 기재된 연구의 경우 대표적인 논문들을 기재한 것이며 이외에도 포함되지 않은 연구들이 여럿 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN은 포스팅 되는 2021.09.14 시점으로 약 35,000회의 인용이 있는 것을 확인할 수 있고. 화두가 되었었던 Tensorflow가 발표되었던 논문보다도 더욱 많은 관심을 받고 있는 것을 확인할 수 있다.&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;131&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Klqwx/btsrcu1yvnb/yNqwFilMMFzk0EGCZYkSX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Klqwx/btsrcu1yvnb/yNqwFilMMFzk0EGCZYkSX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Klqwx/btsrcu1yvnb/yNqwFilMMFzk0EGCZYkSX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKlqwx%2Fbtsrcu1yvnb%2FyNqwFilMMFzk0EGCZYkSX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;131&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;131&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXPrCh/btsq1EYCmv4/wCnG1beIyITYt7txfSKQK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXPrCh/btsq1EYCmv4/wCnG1beIyITYt7txfSKQK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXPrCh/btsq1EYCmv4/wCnG1beIyITYt7txfSKQK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXPrCh%2Fbtsq1EYCmv4%2FwCnG1beIyITYt7txfSKQK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;133&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;133&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
[그림 3] GAN 모델과 Tensorflow 프레임워크의 인용수
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얀르쿤(&lt;span style=&quot;color: #000000;&quot;&gt;Yann LeCun)&lt;/span&gt;은 GAN 모델이 지난 20년간 딥러닝 분야에서 가장 멋진 아이디어라고 말한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;340&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kLh5b/btsq7b9ekNB/fUcvMO75Ol6S3gvI2XYKM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kLh5b/btsq7b9ekNB/fUcvMO75Ol6S3gvI2XYKM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kLh5b/btsq7b9ekNB/fUcvMO75Ol6S3gvI2XYKM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkLh5b%2Fbtsq7b9ekNB%2FfUcvMO75Ol6S3gvI2XYKM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;340&quot; height=&quot;190&quot; data-origin-width=&quot;340&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 4] 얀르쿤(Facebook, 딥러닝 3대 석학 中 1, 튜링상)
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 이 GAN이라고 하는 모델은 왜 각광받고 있고 후속 연구들이 이어지고 있는 것인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 이유가 있지만 그 중 단연 핵심이라 생각되는 것은 바로 기존의 지도학습의 한계 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 지도학습의 경우 데이터셋이 필수적으로 수반된다. 하지만 이러한 데이터셋을 만드는 과정에 드는 시간 등의 비용의 한계가 있기 때문에 어렵다는 것이다. 하지만 GAN은 지도학습에 사용되는 라벨 없이도 학습 가능한 비지도학습에 속하며, 데이터를 직접 생성하는 큰 장점을 가진다. 따라서 GAN의 경우 비지도학습의 선두주자로 불리고도 있으며, 몇몇의 사람들은 비지도학습이 더욱 각광받는 기술이 될 것이라 전망한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTXFem/btsq0xyNjog/Q9PNnQKgW4kDTQ95zKRsYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTXFem/btsq0xyNjog/Q9PNnQKgW4kDTQ95zKRsYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTXFem/btsq0xyNjog/Q9PNnQKgW4kDTQ95zKRsYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTXFem%2Fbtsq0xyNjog%2FQ9PNnQKgW4kDTQ95zKRsYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;688&quot; height=&quot;493&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 5] 머신러닝 분류체계(지도학습, 비지도학습, 강화학습)
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 처음 GAN이 나왔을 당시 논문에서 제시한 GAN 모델의 결과 중 일부이다.&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgR5cz/btsq0x6EImD/KpVROwlxc4RRSFOhiwEYpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgR5cz/btsq0x6EImD/KpVROwlxc4RRSFOhiwEYpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgR5cz/btsq0x6EImD/KpVROwlxc4RRSFOhiwEYpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgR5cz%2Fbtsq0x6EImD%2FKpVROwlxc4RRSFOhiwEYpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;379&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;499&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MmObj/btsrf2cwrLV/VmHe0LN3eUPBc8qkeF0GA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MmObj/btsrf2cwrLV/VmHe0LN3eUPBc8qkeF0GA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MmObj/btsrf2cwrLV/VmHe0LN3eUPBc8qkeF0GA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMmObj%2Fbtsrf2cwrLV%2FVmHe0LN3eUPBc8qkeF0GA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;744&quot; height=&quot;499&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;499&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
[그림 6] GAN 모델 결과
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽 그림은 MNIST 데이터셋을 학습하여 오른쪽 노란박스와 같이 모델이 숫자를 생성할 수 있음을 보였다. 또한 오른쪽 그림은 TFD(Torronto Faces Dataset)을 이용하여 학습한 뒤 GAN 모델이 사람의 얼굴을 생성할 수 있음을 보였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기의 결과물은 색채가 없고 화질이 좋지 않았다. 하지만 GAN 모델의 단점을 극복하는 연구들이 intensive하게 진행됨에 따라 아래와 같이 진짜 이미지와 구분하기 힘들 정도로 발전하는 단계가 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zmf3s/btsravGj0q5/8Hw5AEDZKijDyesuZCDk41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zmf3s/btsravGj0q5/8Hw5AEDZKijDyesuZCDk41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zmf3s/btsravGj0q5/8Hw5AEDZKijDyesuZCDk41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzmf3s%2FbtsravGj0q5%2F8Hw5AEDZKijDyesuZCDk41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;763&quot; height=&quot;255&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 7] GAN 모델 성능 발전
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 여기서 이러한 GAN 모델의 성능을 발전을 가능케 했던 대표적인 연구들을 살펴보고자 한다. 이를 위한 첫 단계로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;모카&lt;/b&gt;님의&amp;nbsp;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://ysbsb.github.io/gan/2020/06/17/GAN-newbie-guide.html&quot;&gt;블로그&lt;/a&gt;에서 아래와 같은 GAN 연구의 분류체계를 확인할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUPenV/btsrfi0Rojp/nKVXt7bzvkj3CKGIMe8rTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUPenV/btsrfi0Rojp/nKVXt7bzvkj3CKGIMe8rTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUPenV/btsrfi0Rojp/nKVXt7bzvkj3CKGIMe8rTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUPenV%2Fbtsrfi0Rojp%2FnKVXt7bzvkj3CKGIMe8rTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;384&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 8] Taxnomoy of GAN
&lt;p data-ke-size=&quot;size16&quot;&gt;모카님은 GAN을 크게 3가지로 Unconditional GAN, Conditional GAN, Super Resolution으로 나누었다. 분류체계의 기준은 어떻게 정하였는지는 잘 모르겠다. 하지만 서칭 결과 더 체계적이라 판단되는 분류체계는 찾을 수 없었다. 따라서 이를 기반으로 주요 연구들을 살펴보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 알아보고자 하는 대표적인 연구들은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yKFRO/btsq5baADZi/Kmce1axpwGO0Nefj4VZUX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yKFRO/btsq5baADZi/Kmce1axpwGO0Nefj4VZUX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yKFRO/btsq5baADZi/Kmce1axpwGO0Nefj4VZUX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyKFRO%2Fbtsq5baADZi%2FKmce1axpwGO0Nefj4VZUX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;854&quot; height=&quot;482&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;482&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 9] GAN의 대표적인 후속 연구
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 위 연구에 대해 한마디로 정리하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DCGAN&lt;/b&gt;: 얀르쿤이 GAN을 낳았다면 Facebook은 DCGAN을 통해 모든 후속연구가 이어질 수 있도록 키운 모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LSGAN&lt;/b&gt;: 기존 GAN에 적용된 Loss의 수식을 Least Square loss로 바꾸어 성능 향상을 도모한 모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;PGGAN&lt;/b&gt;: 기존 모델과 달리 점진적으로 학습하여 1024x1024의 고화질 이미지 생성을 가능하게 한 모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CycleGAN&lt;/b&gt;: 역함수 개념과 순환일관성 손실 함수를 이용해 특정 이미지의 화풍을 다른 이미지에 적용할 수 있게 한 모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;StarGAN&lt;/b&gt;: 단일 생성자/판별자로 Domain Transfer가 가능하도록 만든 모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SRGAN&lt;/b&gt;: GAN 모델의 인지적 해상도를 높여 고화질 이미지 생성을 가능하게 한 모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Original GAN&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1 Origianl GAN의 아키텍처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 GAN의 아키텍처를 확인해보면 아래의 왼쪽 그림과 같이 간단한 형태를 가진다.&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;215&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bh3tW6/btsrf2jh5lH/kSEwc9rXkmhA91kcYM7YB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bh3tW6/btsrf2jh5lH/kSEwc9rXkmhA91kcYM7YB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bh3tW6/btsrf2jh5lH/kSEwc9rXkmhA91kcYM7YB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbh3tW6%2Fbtsrf2jh5lH%2FkSEwc9rXkmhA91kcYM7YB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;460&quot; height=&quot;215&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;215&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJqmbR/btsq1awyiR7/kOuKSsrM4pQT0QyIlHx06K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJqmbR/btsq1awyiR7/kOuKSsrM4pQT0QyIlHx06K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJqmbR/btsq1awyiR7/kOuKSsrM4pQT0QyIlHx06K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJqmbR%2Fbtsq1awyiR7%2FkOuKSsrM4pQT0QyIlHx06K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;407&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
[그림 10] GAN 아키텍처 &amp;amp; z의 랜덤 dstirubtion
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN은 크게 2가지 모델로 이루어져 있다. Generator와 Discriminator로 이루어져 있어 동시에 두 개의 모델을 훈련하는 것이 특징이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 z라고 하는 것은 랜덤 벡터 z를 의미하는 것으로 오른쪽 그림의 uniform distribution이나 normal distribution을 따른다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 랜덤 벡터 z를 Generator의 입력으로 넣어 Fake를 생성한다. 이후 Real의 경우 실제 데이터셋을 의미하는 것으로 생성된 Fake와 실제 Real 이미지를 Discriminator의 입력으로 넣게 되면 Fake 또는 Real이라고 출력하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN은 최종 출력인 Fake와 Real의 확률이 1/2에 수렴하여 진짜와 가짜를 구분할 수 없도록 학습하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN을 더욱 이해하기 위해서는 확률밀도함수의 개념을 알아야 한다. 아래는 어떤 모종의 확률밀도함수를 나타내는 그래프이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2 확률 밀도 함수(PDF, Probability Density Function)&lt;/b&gt;&lt;/h3&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHNLpC/btsrdh8SXKk/bx5dVWk67jVIZgNMA8ozmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHNLpC/btsrdh8SXKk/bx5dVWk67jVIZgNMA8ozmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHNLpC/btsrdh8SXKk/bx5dVWk67jVIZgNMA8ozmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHNLpC%2Fbtsrdh8SXKk%2Fbx5dVWk67jVIZgNMA8ozmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;384&quot; height=&quot;160&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 11] 확률 밀도 함수(PDF, Probability Density Function)
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 확률밀도함수란 통계학에서 사용되는 개념으로, 용어에서부터 직관적으로 이해할 수 있듯 확률변수의 분포를 나타내는 것으로, 연속확률변수 x에 대한 f(x)를 의미하는 것이라 볼 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가령 최윤제님의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://www.youtube.com/watch?v=odpjk7_tGY0&amp;amp;ab_channel=naverd2&quot;&gt;발표자료&lt;/a&gt;에 있던 예시를 가져온 것은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJdNUV/btsq1F4hiFA/YzBcxVqD6exhtnkIp86mk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJdNUV/btsq1F4hiFA/YzBcxVqD6exhtnkIp86mk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJdNUV/btsq1F4hiFA/YzBcxVqD6exhtnkIp86mk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJdNUV%2Fbtsq1F4hiFA%2FYzBcxVqD6exhtnkIp86mk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;643&quot; height=&quot;304&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 12] 확률 밀도 함수에 대한 예시 1
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가령 GAN 모델에 안경을 낀 남성의 데이터를 학습시킨다고 할 경우, 안경을 낀 남성의 특징은 x1이라고 하는 벡터가 가지게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Em1ZV/btsq1EqMLeP/47F0gqG24p2lxp7lKmoTiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Em1ZV/btsq1EqMLeP/47F0gqG24p2lxp7lKmoTiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Em1ZV/btsq1EqMLeP/47F0gqG24p2lxp7lKmoTiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEm1ZV%2Fbtsq1EqMLeP%2F47F0gqG24p2lxp7lKmoTiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;312&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 13] 확률 밀도 함수에 대한 예시 2
&lt;p data-ke-size=&quot;size16&quot;&gt;흑발 여성의 데이터셋을 학습 시킬 경우, 흑발 여성에 대한 특징을 x2라고 하는 벡터가 가지게 되며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3NfLY/btsq5eZqnLK/9G4v0sAKNBrZkQagjw6vqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3NfLY/btsq5eZqnLK/9G4v0sAKNBrZkQagjw6vqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3NfLY/btsq5eZqnLK/9G4v0sAKNBrZkQagjw6vqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3NfLY%2Fbtsq5eZqnLK%2F9G4v0sAKNBrZkQagjw6vqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;657&quot; height=&quot;300&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 14] 확률 밀도 함수에 대한 예시 3
&lt;p data-ke-size=&quot;size16&quot;&gt;금발 여성의 데이터셋을 학습 시킬 경우 GAN 모델은 금발 여성에 대한 특징을 x3라고 하는 벡터에 학습시키게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 이렇게 학습된 확률밀도함수가 있을 때, 아래와 같이 GAN 모델이 생성한 이미지가 가지는 확률밀도함수와 둘 사이의 차이가 줄어들면 줄어들 수록 원래의 실제 이미지와 같아지는 원리라고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;291&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/doTZnm/btsq5ZgJ2FU/8HkUj61oi54vlSlsvvnTGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/doTZnm/btsq5ZgJ2FU/8HkUj61oi54vlSlsvvnTGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/doTZnm/btsq5ZgJ2FU/8HkUj61oi54vlSlsvvnTGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdoTZnm%2Fbtsq5ZgJ2FU%2F8HkUj61oi54vlSlsvvnTGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;291&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;291&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 15] 실데이터 학습을 통한 확률 변수의 분포와 모델이 생성한 이미지가 가지는 확률 변수
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 Original GAN의 논문에 실린 그림은 아래와 같다.&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l9YjU/btsq2O7AHKg/j9MRx4h7EKvP0Wh140KiTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l9YjU/btsq2O7AHKg/j9MRx4h7EKvP0Wh140KiTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l9YjU/btsq2O7AHKg/j9MRx4h7EKvP0Wh140KiTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl9YjU%2Fbtsq2O7AHKg%2Fj9MRx4h7EKvP0Wh140KiTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;766&quot; height=&quot;246&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 16] GAN의 학습 과정
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;※&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;검은 점선&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;원 데이터의 확률분포&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4da853;&quot;&gt;녹색 점선&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생성자가 만들어 내는 확률분포&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;파란 점선&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;판별자의 확률분포&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파란 점선인 판별자(Discriminator)는 학습이 진행됨에 따라 GAN이 만들어내는 녹색 점선(Generator)와 분포가 동일해지는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 (d)의 단계에서는 판별자가 Real/Fake를 분류하게 되어도 확률이 같기 때문에 분류를 해도 소용 없게 되며 생성자는 실제 데이터와 매우 흡사하게 이미지를 생성할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.3 수식으로 이해하는 GAN&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN은 생성자와 판별자의 경쟁구도이며, 경쟁을 통해 균형점(nash equilibrium)을 찾는 것이 목표라 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN에서 사용되는 수식은 아래와 같이 간단한 형태이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3Kcq0/btsq8J5LBAl/D6CAq11MKV6rJXZ70kysS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3Kcq0/btsq8J5LBAl/D6CAq11MKV6rJXZ70kysS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3Kcq0/btsq8J5LBAl/D6CAq11MKV6rJXZ70kysS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3Kcq0%2Fbtsq8J5LBAl%2FD6CAq11MKV6rJXZ70kysS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;851&quot; height=&quot;73&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 17] GAN의 수식
&lt;p data-ke-size=&quot;size16&quot;&gt;G(Generator)를 minimize하고 D(Discriminator)를 maximize한다고 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수식을 가장 빠르게 이해하는 방법 중 하나는 수식에 0을 만드는 요소라던지 극값을 넣어 간단한 형태로 환원시키는 것이다. 먼저 수식 내의 값들을 0으로 만들어 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 1: D(x)를 1로 만드는 경우 (판별자가 모든 것을 분류 가능한 경우)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D(x)=1인 상황은 logD(x)를 0으로 만드려는 것과 같다. D(x)=1이라는 의미는 판별자가 모든 것을 다 올바르게 Real/Fake 분류를 할 수 있음을 의미한다. 이렇게 되면 동시에 D(G(z))=1이 된다. 그 이유는 G가 아무리 진짜와 같은 이미지를 생성하더라도 D가 100%의 확률로 전부 잡아낼 수 있기 때문이다. 결과적으로 수식의 앞 부분은 logD(x)는 0이 되어 사라지고, 뒷 부분은 log(1-1)이 되어 무한에 수렴하게 된다. (log 함수 그래프 참조)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;232&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zHStu/btsq1JyG8ug/dY3DzxZjwYGwxRejxoNzCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zHStu/btsq1JyG8ug/dY3DzxZjwYGwxRejxoNzCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zHStu/btsq1JyG8ug/dY3DzxZjwYGwxRejxoNzCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzHStu%2Fbtsq1JyG8ug%2FdY3DzxZjwYGwxRejxoNzCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;232&quot; height=&quot;232&quot; data-origin-width=&quot;232&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 18] log 함수
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 2: G(z)를 1로 만드는 경우 (판별자가 모든 것을 분류하지 못하는 경우)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;G(z)=1인 상황은 생성자 G가 실제와 구분하지 못할 정도로 흡사하게 만들어 판별자 D가 하나도 구분하지 못하는 상황과 같다. 이렇게 되면 수식의 앞 부분인 logD(x)는 log0이 되어 무한에 수렴하게 되고, 뒷 부분인 log(1-D(G(z))는 0이 되어 사라지게 된다. (이 상황의 경우 minmax요소가 바뀜. min&amp;rarr;D, max&amp;rarr;G)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.4 코드로 이해하는 GAN&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN의 수식을 코드로 표현할 경우 아래와 같아진다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;243&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nWBPi/btsq1IT6dCh/P4ogCDaOECwOzEq47vVXN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nWBPi/btsq1IT6dCh/P4ogCDaOECwOzEq47vVXN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nWBPi/btsq1IT6dCh/P4ogCDaOECwOzEq47vVXN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnWBPi%2Fbtsq1IT6dCh%2FP4ogCDaOECwOzEq47vVXN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;505&quot; height=&quot;243&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;243&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 19] 코드로 표현한 GAN 모델
&lt;p data-ke-size=&quot;size16&quot;&gt;크게 4 영역으로 판별자 D의 layer, 생성자 G의 layer, D의 loss, G의 loss 부분으로 나뉜다. 핵심은 loss를 표현하는 영역으로 앞서 설명한 수식을 이용하여 위와 같이 작성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.5 실험 결과&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 앞서보았던 그림을 포함하여 크게 3종류인 (MNIST, TFD, CIFAR-10)의 데이터셋에 대해 학습하고 이를 생성자 모델을 사용하여 시각화 하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RHXug/btsq51eydGU/irhx5QIK6848lKyJOvSNTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RHXug/btsq51eydGU/irhx5QIK6848lKyJOvSNTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RHXug/btsq51eydGU/irhx5QIK6848lKyJOvSNTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRHXug%2Fbtsq51eydGU%2Firhx5QIK6848lKyJOvSNTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;377&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
[그림 20] GAN 모델 결과
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자와 얼굴의 경우 어느정도 식별 가능한 형태라 볼 수 있으며, 동물/사물에 대해서는 비교적 추상적으로나마 생성해내는 것을 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.6 한계점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 GAN의 한계점은 크게 2가지로 나뉜다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. (성능 평가)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN 모델의 성능을 객관적 수치로 표현할 수 있는 방안이 부재했다. GAN의 경우 결과 자체가 새롭게 만들어진 데이터이기 때문에 비교 가능한 정량적 척도가 없었다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. (성능 개선)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN은 기존 네트워크 학습 방법과 다른 구조여서 학습이 불안정했다. GAN은 Saddle Problem 혹은 Minmax를 풀어야 하는 태생적으로 불안정한 구조이기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 2016년 NIPS에서도 GAN의 안정화가 메인화두였다고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이의 두 단점을 모두 개선하여 GAN의 후속 연구가 줄줄이 이어나올 수 있도록 한 연구가 Facebook에서 개발한 DCGAN(Deep Convolutional GAN)이다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Deep Learning/pytorch</category>
      <author>투푸월드</author>
      <guid isPermaLink="true">https://toofoo.tistory.com/97</guid>
      <comments>https://toofoo.tistory.com/97#entry97comment</comments>
      <pubDate>Mon, 14 Aug 2023 13:32:06 +0900</pubDate>
    </item>
  </channel>
</rss>