<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>simpling</title>
    <link>https://simpling.tistory.com/</link>
    <description>인공지능 및 파이썬 공부를 하며 정리하는 공간입니다.</description>
    <language>ko</language>
    <pubDate>Tue, 23 Jun 2026 21:08:27 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Like_Me</managingEditor>
    <image>
      <title>simpling</title>
      <url>https://tistory1.daumcdn.net/tistory/3491598/attach/aa233df8524e46a4870360b002373363</url>
      <link>https://simpling.tistory.com</link>
    </image>
    <item>
      <title>3박 4일 후쿠오카 여행</title>
      <link>https://simpling.tistory.com/80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;덥고 습한 6월 말이지만 이직을 하게 되어 쉬는 날이 생겨 친구와 여행을 갔다. 지난 오사카, 교토가 너무 좋았어서 이번에도 일본으로 가기로 했고 가까운 후쿠오카를 택했다. 이번 여행의 콘셉트는 소도시 여행이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 아침에 출발하는 비행기를 타고 내려 11시쯤 일본에 도착했다. 배가 고파서 바로 유명한 &lt;a href=&quot;https://maps.app.goo.gl/mrXd8xA5Mw11vd3Q9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;카와미야 함바그&lt;/a&gt; 하카타점을 방문했다. 줄을 1시간 정도 기다리고 들어가서 먹었는데, 속은 익혀져있지 않았고 따로 나오는 뜨거운 돌에 조금씩 찢어서 익혀 먹는 방식이었다. 처음 먹어보는 데 굉장히 맛있었다. 한국에서 맛있는 고기를 구워 먹는 것과 비슷한 맛이 났다. 아마 다음에 가면 또 먹을 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dEUWC8/btsIgGKFvoK/GRtreaB4XnZejaOHZoIHn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dEUWC8/btsIgGKFvoK/GRtreaB4XnZejaOHZoIHn0/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; width=&quot;361&quot; height=&quot;271&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dEUWC8/btsIgGKFvoK/GRtreaB4XnZejaOHZoIHn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdEUWC8%2FbtsIgGKFvoK%2FGRtreaB4XnZejaOHZoIHn0%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eXJY3o/btsId5TpqpE/FVRirHkmKOfyXVKX09DdUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eXJY3o/btsId5TpqpE/FVRirHkmKOfyXVKX09DdUk/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; width=&quot;302&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eXJY3o/btsId5TpqpE/FVRirHkmKOfyXVKX09DdUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeXJY3o%2FbtsId5TpqpE%2FFVRirHkmKOfyXVKX09DdUk%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6HkUj/btsIfVn0PwJ/t8vsaObHFmKcfbNXdk1wR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6HkUj/btsIfVn0PwJ/t8vsaObHFmKcfbNXdk1wR0/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 35.5814%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6HkUj/btsIfVn0PwJ/t8vsaObHFmKcfbNXdk1wR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6HkUj%2FbtsIfVn0PwJ%2Ft8vsaObHFmKcfbNXdk1wR0%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNdOs4/btsIehMShvw/rgspOTc0XaDSx3K9YIKk6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNdOs4/btsIehMShvw/rgspOTc0XaDSx3K9YIKk6k/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.2558%; margin-top: 10px;&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNdOs4/btsIehMShvw/rgspOTc0XaDSx3K9YIKk6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNdOs4%2FbtsIehMShvw%2FrgspOTc0XaDSx3K9YIKk6k%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함바그로 배를 채운 후, 숙소에 짐을 내려놓고 바깥 구경을 했다. 주변에 있던 백화점을 방문해서 이리저리 둘러보았고, 일본 다이소나 인형 뽑기 같은 것들을 봤다. 캐릭터 천국인 일본이라 다양한 인형이 있었다. 다이소는 한국과 비슷했지만 동전 지갑이 필요했어서 하나 구매하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjCkbf/btsIfgNb9hP/q1r0NKhSeXVBp3e7JSQ6Pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjCkbf/btsIfgNb9hP/q1r0NKhSeXVBp3e7JSQ6Pk/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjCkbf/btsIfgNb9hP/q1r0NKhSeXVBp3e7JSQ6Pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjCkbf%2FbtsIfgNb9hP%2Fq1r0NKhSeXVBp3e7JSQ6Pk%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR5mFE/btsIfdpqaX6/sVgpcLKUy2ZBwEWdmTeh41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR5mFE/btsIfdpqaX6/sVgpcLKUy2ZBwEWdmTeh41/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR5mFE/btsIfdpqaX6/sVgpcLKUy2ZBwEWdmTeh41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR5mFE%2FbtsIfdpqaX6%2FsVgpcLKUy2ZBwEWdmTeh41%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저녁 먹을 시간이 되어 백화점 안에 있던 &lt;a href=&quot;https://maps.app.goo.gl/mR3aiioUMc69YvcZ8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;덴푸라집&lt;/a&gt;을 방문하였다. 구글 평점이 3.8이었는데 괜찮겠지 하고 들어갔다. 명란 튀김, 새우튀김, 양파 튀김 등이 나왔는데.. 생각보다 너무 별로였다. 특히 명란은 너무 짰고 튀김이 바삭하지 않았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mSODL/btsIeDoDtGN/7gjbTWAnOPsjFgkGNKSL60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mSODL/btsIeDoDtGN/7gjbTWAnOPsjFgkGNKSL60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mSODL/btsIeDoDtGN/7gjbTWAnOPsjFgkGNKSL60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmSODL%2FbtsIeDoDtGN%2F7gjbTWAnOPsjFgkGNKSL60%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;260&quot; height=&quot;195&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밖에 나가 다시 숙소로 가는 데 비가 엄청 왔다. 바람도 많이 불어 시원해서 좋았다. 우산 쓰며 하카타 역에서 한 컷 찍고 편의점에서 푸딩과 요거트를 사서 먹고 잤다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt3RFS/btsId0YSwI4/RpDzg65LnWJv0ItmD41f1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt3RFS/btsId0YSwI4/RpDzg65LnWJv0ItmD41f1k/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt3RFS/btsId0YSwI4/RpDzg65LnWJv0ItmD41f1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt3RFS%2FbtsId0YSwI4%2FRpDzg65LnWJv0ItmD41f1k%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPB1FN/btsIe3tOhOS/4uSVo9k7kPB8IzM3gZE8ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPB1FN/btsIe3tOhOS/4uSVo9k7kPB8IzM3gZE8ik/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPB1FN/btsIe3tOhOS/4uSVo9k7kPB8IzM3gZE8ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPB1FN%2FbtsIe3tOhOS%2F4uSVo9k7kPB8IzM3gZE8ik%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 아침을 먹진 않지만 일어나니 배고파서 스키야를 방문했다. 지난 교토 여행에서 먹었던 갓김치 규동을 먹었는데 너무 맛있었다. 그리고 텐진으로 넘어가&amp;nbsp;&lt;a href=&quot;https://maps.app.goo.gl/s5DL1Q33or1xUwkN6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;돈키호테&lt;/a&gt;를 방문해서 쇼핑하며 여러 선물을 샀다. 지금 생각해보니 괜히 2일 차에 돈키호테를 갔다. 남은 여행동안 짐을 다 들고 다녀야 했다.. ㅠㅠ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EVMR5/btsIfxgSgWG/NTPUVJL13weQpCOKb2wg0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EVMR5/btsIfxgSgWG/NTPUVJL13weQpCOKb2wg0K/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; width=&quot;556&quot; height=&quot;741&quot; style=&quot;width: 35.5814%; margin-right: 10px;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EVMR5/btsIfxgSgWG/NTPUVJL13weQpCOKb2wg0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEVMR5%2FbtsIfxgSgWG%2FNTPUVJL13weQpCOKb2wg0K%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFdsC8/btsIfFeGTES/tlmZxVsi3F55HwANwqv18K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFdsC8/btsIfFeGTES/tlmZxVsi3F55HwANwqv18K/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.2558%;&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFdsC8/btsIfFeGTES/tlmZxVsi3F55HwANwqv18K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFdsC8%2FbtsIfFeGTES%2FtlmZxVsi3F55HwANwqv18K%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 도시로 넘어가기 전 &lt;a href=&quot;https://maps.app.goo.gl/2keHUqxo2Z9iiY7T6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링고 애플파이&lt;/a&gt; 라는 애플파이를 파는 곳에 방문했다. 유튜브 추천으로 갔는데 너무 맛있어서 여행 동안 3번이나 방문해서 먹었다. 오리지널 애플파이만 먹었지만 복숭아가 들어있는 것도 맛있다고 한다. 찾아가기 좀 어려웠는데, 공항선 가는 길을 찾아 지하로 내려가면 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wkSgr/btsIekv3Cc5/NaUOc24WKNSqesb8QeGN0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wkSgr/btsIekv3Cc5/NaUOc24WKNSqesb8QeGN0K/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 38.1168%; margin-right: 10px;&quot; data-widthpercent=&quot;39.02&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wkSgr/btsIekv3Cc5/NaUOc24WKNSqesb8QeGN0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwkSgr%2FbtsIekv3Cc5%2FNaUOc24WKNSqesb8QeGN0K%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1ZOWj/btsIeTY1OcF/Tz9nKSdT5wlnyPxJQGKFKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1ZOWj/btsIeTY1OcF/Tz9nKSdT5wlnyPxJQGKFKK/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 38.1168%; margin-right: 10px;&quot; data-widthpercent=&quot;39.02&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1ZOWj/btsIeTY1OcF/Tz9nKSdT5wlnyPxJQGKFKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1ZOWj%2FbtsIeTY1OcF%2FTz9nKSdT5wlnyPxJQGKFKK%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bh1FJo/btsIeFs9yBs/zFjeGlGwFPeg8K2YotE3j1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bh1FJo/btsIeFs9yBs/zFjeGlGwFPeg8K2YotE3j1/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 21.4407%;&quot; data-widthpercent=&quot;21.96&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bh1FJo/btsIeFs9yBs/zFjeGlGwFPeg8K2YotE3j1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbh1FJo%2FbtsIeFs9yBs%2FzFjeGlGwFPeg8K2YotE3j1%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;링고파이를 맛있게 먹고 이토시마로 건너갔다. 이토시마의 &lt;a href=&quot;https://maps.app.goo.gl/LrHw7LbTbP4fzgGb6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;토모&lt;/a&gt;라는 숙소에 머물렀는데 자전거도 빌릴 수 있어서(물론 유료) 자전거를 타고 소도시 여행을 하기로 했다. 다행히 이때 비가 오진 않았다. 먼저 점심을 먹으러 갔는데 자전거로 20~30분 정도 타고 갔던 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/exfjQJ/btsIeGTat1I/onZMSZfZkitCiKHJAwWpH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/exfjQJ/btsIeGTat1I/onZMSZfZkitCiKHJAwWpH0/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/exfjQJ/btsIeGTat1I/onZMSZfZkitCiKHJAwWpH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FexfjQJ%2FbtsIeGTat1I%2FonZMSZfZkitCiKHJAwWpH0%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdGKOY/btsIf12PZnU/f8fcphWeyE0u0GUgklKc5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdGKOY/btsIf12PZnU/f8fcphWeyE0u0GUgklKc5k/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdGKOY/btsIf12PZnU/f8fcphWeyE0u0GUgklKc5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdGKOY%2FbtsIf12PZnU%2Ff8fcphWeyE0u0GUgklKc5k%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crllnY/btsIfDA8A7A/GUQmWIjYFnFh4FHZpglEqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crllnY/btsIfDA8A7A/GUQmWIjYFnFh4FHZpglEqK/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%;&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crllnY/btsIfDA8A7A/GUQmWIjYFnFh4FHZpglEqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrllnY%2FbtsIfDA8A7A%2FGUQmWIjYFnFh4FHZpglEqK%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://maps.app.goo.gl/fKNANXeySDbCrWqq7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;시장 같은 곳에 위치한 곳&lt;/a&gt;이었고 회덮밥을 시켜 먹었다. 굉장히 신선하고 맛있었다. 다만 여행객이 안 오는 곳이라 아무도 영어를 못해서 의사소통은 조금 힘들었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt6FQO/btsIegmRaZu/7AJepP6K7uIpz6ma5YLFW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt6FQO/btsIegmRaZu/7AJepP6K7uIpz6ma5YLFW0/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt6FQO/btsIegmRaZu/7AJepP6K7uIpz6ma5YLFW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt6FQO%2FbtsIegmRaZu%2F7AJepP6K7uIpz6ma5YLFW0%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OttU0/btsIgjhT3Hc/WPzxQKTkFLKhRSYVgWxnP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OttU0/btsIgjhT3Hc/WPzxQKTkFLKhRSYVgWxnP1/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OttU0/btsIgjhT3Hc/WPzxQKTkFLKhRSYVgWxnP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOttU0%2FbtsIgjhT3Hc%2FWPzxQKTkFLKhRSYVgWxnP1%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밥을 다 먹고 '부부바위'라는 곳이 유명하다고 하여 자전거를 타고 가려고 했으나, 엉덩이가 너무 아파서 그냥 숙소로 돌아갔다. 부부바위까지 1시간 거리라 갔다 왔으면 큰일 날 뻔했다. 다시 숙소로 돌아가는 길에 주변 마을 구경을 했는데 상당히 신축 건물이 많았다. 다만 사람은 거의 없었고 마주치는 분들은 나이가 많으신 분들밖에 없었다. 초고령 사회의 일본이라 그런지 소도시는 젊은 사람이 거의 없었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWNbf6/btsIeBj17OM/eohSYCJfwdDpKFTywoArZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWNbf6/btsIeBj17OM/eohSYCJfwdDpKFTywoArZ0/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWNbf6/btsIeBj17OM/eohSYCJfwdDpKFTywoArZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWNbf6%2FbtsIeBj17OM%2FeohSYCJfwdDpKFTywoArZ0%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beSCnD/btsIfZxaHm2/Lyk2mTDjJCLJ6V9tHYaEZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beSCnD/btsIfZxaHm2/Lyk2mTDjJCLJ6V9tHYaEZK/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beSCnD/btsIfZxaHm2/Lyk2mTDjJCLJ6V9tHYaEZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeSCnD%2FbtsIfZxaHm2%2FLyk2mTDjJCLJ6V9tHYaEZK%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자전거를 반납하고는 버스를 타고 부부바위로 가려고 했으나, 버스가 1시간 뒤에 온다고 하여 목적지를 변경하였다. 좀 더 &lt;a href=&quot;https://maps.app.goo.gl/1cuXb5xVDHxFbiqy9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;가까운 바닷가 쪽 신사&lt;/a&gt;로 버스를 타고 갔다. 버스에 내려서 조금 걸어가야 하는데, 옆이 숲이라 벌레가 좀 많이 나왔다.. 신사는 생각보다 별거 없었고, 바다도 엄청 아름답진 않았다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TmjIN/btsIeCiUnA7/fUaicu7HfN3fDCrTnL2K8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TmjIN/btsIeCiUnA7/fUaicu7HfN3fDCrTnL2K8k/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.2558%; margin-right: 10px;&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TmjIN/btsIeCiUnA7/fUaicu7HfN3fDCrTnL2K8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTmjIN%2FbtsIeCiUnA7%2FfUaicu7HfN3fDCrTnL2K8k%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9pwZk/btsIfGkl3gK/2fSNkkfo91VflI4ktFt4x1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9pwZk/btsIfGkl3gK/2fSNkkfo91VflI4ktFt4x1/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 35.5814%;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9pwZk/btsIfGkl3gK/2fSNkkfo91VflI4ktFt4x1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9pwZk%2FbtsIfGkl3gK%2F2fSNkkfo91VflI4ktFt4x1%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TGK5U/btsIfxHXjwK/qPIYA4pidKebDMP8vrqirk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TGK5U/btsIfxHXjwK/qPIYA4pidKebDMP8vrqirk/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TGK5U/btsIfxHXjwK/qPIYA4pidKebDMP8vrqirk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTGK5U%2FbtsIfxHXjwK%2FqPIYA4pidKebDMP8vrqirk%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ci77Nk/btsIfdiGAQg/o4EHnZ2dAZdkP0THHymbVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ci77Nk/btsIfdiGAQg/o4EHnZ2dAZdkP0THHymbVk/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-top: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ci77Nk/btsIfdiGAQg/o4EHnZ2dAZdkP0THHymbVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fci77Nk%2FbtsIfdiGAQg%2Fo4EHnZ2dAZdkP0THHymbVk%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이대로 숙소로 가기는 아쉽고 소화도 시킬 겸 숙소까지 걸어가기로 했다. 1시간 좀 넘게 걸어야 하는 거리였다. 일본의 소도시 감성을 제대로 느낄 수 있어서 좋았다. 일본을 걷다 보면 느껴지는 게 큰 강이 정말 많더라. (어쩌면 같은 강을 여러 번 마주치는 것일지도 모르겠다.) 그래서 더 아름답게 느껴졌던 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBq8PA/btsIfEtknOe/wRAEKhxz59NgV3V0KOi7YK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBq8PA/btsIfEtknOe/wRAEKhxz59NgV3V0KOi7YK/img.png&quot; style=&quot;width: 63.2558%; margin-right: 10px;&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBq8PA/btsIfEtknOe/wRAEKhxz59NgV3V0KOi7YK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBq8PA%2FbtsIfEtknOe%2FwRAEKhxz59NgV3V0KOi7YK%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQwRYx/btsIgpbns43/yWjmRviul5nyxVb7xQqeAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQwRYx/btsIgpbns43/yWjmRviul5nyxVb7xQqeAk/img.png&quot; style=&quot;width: 35.5814%;&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQwRYx/btsIgpbns43/yWjmRviul5nyxVb7xQqeAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQwRYx%2FbtsIgpbns43%2FyWjmRviul5nyxVb7xQqeAk%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rzFnc/btsIfiYAOYa/bRjW9nqk7sCI1ICWNzWOb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rzFnc/btsIfiYAOYa/bRjW9nqk7sCI1ICWNzWOb1/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rzFnc/btsIfiYAOYa/bRjW9nqk7sCI1ICWNzWOb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrzFnc%2FbtsIfiYAOYa%2FbRjW9nqk7sCI1ICWNzWOb1%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q9ehu/btsIftZTuHO/klTNSLMPzyjuYdNTE7XgC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q9ehu/btsIftZTuHO/klTNSLMPzyjuYdNTE7XgC0/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-top: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q9ehu/btsIftZTuHO/klTNSLMPzyjuYdNTE7XgC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq9ehu%2FbtsIftZTuHO%2FklTNSLMPzyjuYdNTE7XgC0%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숙소로 가는 길에 &lt;a href=&quot;https://maps.app.goo.gl/rKDkeBBQP13tD8ru8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공원&lt;/a&gt;이 있어 잠시 쉬었는데, 풍경과 새소리가 너무 완벽하였다. 평화가 느껴지는 공간에서 쉬니 너무 좋았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3G2RD/btsIf3l3o7A/5ksXugxKX2kaGDVclzRrPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3G2RD/btsIf3l3o7A/5ksXugxKX2kaGDVclzRrPK/img.png&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3G2RD/btsIf3l3o7A/5ksXugxKX2kaGDVclzRrPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3G2RD%2FbtsIf3l3o7A%2F5ksXugxKX2kaGDVclzRrPK%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4xeiA/btsIgDNYL8Q/yKhjgGdVP3TuNglj7iPwY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4xeiA/btsIgDNYL8Q/yKhjgGdVP3TuNglj7iPwY1/img.png&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4xeiA/btsIgDNYL8Q/yKhjgGdVP3TuNglj7iPwY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4xeiA%2FbtsIgDNYL8Q%2FyKhjgGdVP3TuNglj7iPwY1%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IHlQ6/btsIffU5uTU/QDXCDXutkrvhu0IhZ5faX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IHlQ6/btsIffU5uTU/QDXCDXutkrvhu0IhZ5faX1/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%;&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IHlQ6/btsIffU5uTU/QDXCDXutkrvhu0IhZ5faX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIHlQ6%2FbtsIffU5uTU%2FQDXCDXutkrvhu0IhZ5faX1%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1시간 넘게 걸으니 배가 고파 바로 식사를 하러 갔다. '&lt;a href=&quot;https://maps.app.goo.gl/hrYRcWvjCD4LHGhj8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;니쿠모리&lt;/a&gt;'라는 양식집이었는데, 알고보니 사장님이 한국 분이셨다. 젊으신 분이었는데 일본인과 결혼하여 사신다고 하였다. 굉장히 친절하시고 요리도 잘하시는 분이셨다. 돈을 더 벌어서 큰 도시로 가실 거라고 했는데 꼭 이루시길 ㅎㅎ. 음식이 다 맛있었는데, 특히 아사히 슈퍼 드라이 생맥과 구운 카레가 감동이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WpQXF/btsIgnxQtdv/p3xVCw645lpywlkrVQ0Ad0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WpQXF/btsIgnxQtdv/p3xVCw645lpywlkrVQ0Ad0/img.png&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WpQXF/btsIgnxQtdv/p3xVCw645lpywlkrVQ0Ad0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWpQXF%2FbtsIgnxQtdv%2Fp3xVCw645lpywlkrVQ0Ad0%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dod3E1/btsIeCJ0xZZ/ouXcBokrEIzwM8TtGvnpPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dod3E1/btsIeCJ0xZZ/ouXcBokrEIzwM8TtGvnpPK/img.png&quot; style=&quot;width: 49.4186%;&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dod3E1/btsIeCJ0xZZ/ouXcBokrEIzwM8TtGvnpPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdod3E1%2FbtsIeCJ0xZZ%2FouXcBokrEIzwM8TtGvnpPK%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyGHnP/btsIfjpCP4L/q7GukLmDPd3e3H6RzQUEy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyGHnP/btsIfjpCP4L/q7GukLmDPd3e3H6RzQUEy0/img.png&quot; style=&quot;width: 63.2558%; margin-right: 10px; margin-top: 10px;&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyGHnP/btsIfjpCP4L/q7GukLmDPd3e3H6RzQUEy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyGHnP%2FbtsIfjpCP4L%2Fq7GukLmDPd3e3H6RzQUEy0%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kLHQE/btsIe0qlt1Y/eGpZLwtzkGjK7aOg1y4o10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kLHQE/btsIe0qlt1Y/eGpZLwtzkGjK7aOg1y4o10/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 35.5814%; margin-top: 10px;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kLHQE/btsIe0qlt1Y/eGpZLwtzkGjK7aOg1y4o10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkLHQE%2FbtsIe0qlt1Y%2FeGpZLwtzkGjK7aOg1y4o10%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밥을 다 먹고 아쉬워서 편의점 아이스크림을 사러 갔다. 일본 아이스크림은 뭔가 다를까 하여 사서 먹었는데 너무 맛있었다. 특히 콘 형태로 되어있던 게(제일 오른쪽 사진) 너무 맛있었다. (월드콘 업그레이드 버전 느낌)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zw1x3/btsIeDIWiff/bi7FKJqRymy0uGuVJFCSGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zw1x3/btsIeDIWiff/bi7FKJqRymy0uGuVJFCSGK/img.png&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zw1x3/btsIeDIWiff/bi7FKJqRymy0uGuVJFCSGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzw1x3%2FbtsIeDIWiff%2Fbi7FKJqRymy0uGuVJFCSGK%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/70s9o/btsIeTSiD3q/ROrIBCyKd6EGHlygAAHk5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/70s9o/btsIeTSiD3q/ROrIBCyKd6EGHlygAAHk5K/img.png&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/70s9o/btsIeTSiD3q/ROrIBCyKd6EGHlygAAHk5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F70s9o%2FbtsIeTSiD3q%2FROrIBCyKd6EGHlygAAHk5K%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Btmco/btsIfV2EWWo/pIhxjDtJNwkpOHykgOReiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Btmco/btsIfV2EWWo/pIhxjDtJNwkpOHykgOReiK/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%;&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Btmco/btsIfV2EWWo/pIhxjDtJNwkpOHykgOReiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBtmco%2FbtsIfV2EWWo%2FpIhxjDtJNwkpOHykgOReiK%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3일 차 아침에도 스키야로 아침을 먹으러 갔다. 파 규동과 가라아게를 먹었는데 꽤 맛있었다. 다만 스키야는 모든 음식의 간이 센 듯하다. 이때부터 비가 좀 많이 와서 우산을 쓰고 다녔는데 시원하여 좋았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QnJXN/btsIeBRRBLp/JGzdqE1uT4IIGfyvCaLMk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QnJXN/btsIeBRRBLp/JGzdqE1uT4IIGfyvCaLMk0/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QnJXN/btsIeBRRBLp/JGzdqE1uT4IIGfyvCaLMk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQnJXN%2FbtsIeBRRBLp%2FJGzdqE1uT4IIGfyvCaLMk0%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bohhpv/btsIfICwFT1/VKihJHKvtO9d8hIuGsA1jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bohhpv/btsIfICwFT1/VKihJHKvtO9d8hIuGsA1jk/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bohhpv/btsIfICwFT1/VKihJHKvtO9d8hIuGsA1jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbohhpv%2FbtsIfICwFT1%2FVKihJHKvtO9d8hIuGsA1jk%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bclk0d/btsIflnutnX/ZRr3V4aISQ91rAWjhdmdJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bclk0d/btsIflnutnX/ZRr3V4aISQ91rAWjhdmdJ1/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.9644%;&quot; data-widthpercent=&quot;47.06&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bclk0d/btsIflnutnX/ZRr3V4aISQ91rAWjhdmdJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbclk0d%2FbtsIflnutnX%2FZRr3V4aISQ91rAWjhdmdJ1%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밥을 다 먹고는 다음 소도시인 가라쓰로 넘어갔다. 이곳은 예전 도요토미 히데요시가 조선을 침략할 때 거점으로 쓰던 곳으로 가라쓰성을 만들었다고 한다. &lt;a href=&quot;https://maps.app.goo.gl/9dqWGfnQbijeTk787&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;숙소&lt;/a&gt; 체크인 시간이 되지 않아 대기할 곳이 필요하였고 바람이 너무 불어서 &lt;a href=&quot;https://maps.app.goo.gl/yUBhX9QhaPSNp12z5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;주변 카페&lt;/a&gt;를 방문했다. 카페에서 구운 떡이 올려진 단팥죽을 시켰다. 떡이 구워져서 겉은 바삭하고 속은 쫄깃하였다. 한편 단팥죽은 달달했는데, 우리나라보다 묽은 형태였다. 숙소 근처라서 방문한 곳이었는데 분위기도 좋고 점원 분들도 매우 친절하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vWnYp/btsIghRVR44/fHw4xtEOZ26spsN5bU0rwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vWnYp/btsIghRVR44/fHw4xtEOZ26spsN5bU0rwk/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vWnYp/btsIghRVR44/fHw4xtEOZ26spsN5bU0rwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvWnYp%2FbtsIghRVR44%2FfHw4xtEOZ26spsN5bU0rwk%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bacd2j/btsIe2Iu4H3/r8spVTG0UPVwHbbLvXRrZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bacd2j/btsIe2Iu4H3/r8spVTG0UPVwHbbLvXRrZ0/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bacd2j/btsIe2Iu4H3/r8spVTG0UPVwHbbLvXRrZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbacd2j%2FbtsIe2Iu4H3%2Fr8spVTG0UPVwHbbLvXRrZ0%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbk0Iz/btsIeEHQpa1/g1MHEZc0D7C1fnMUcM8VHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbk0Iz/btsIeEHQpa1/g1MHEZc0D7C1fnMUcM8VHk/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.9644%;&quot; data-widthpercent=&quot;47.06&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbk0Iz/btsIeEHQpa1/g1MHEZc0D7C1fnMUcM8VHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbbk0Iz%2FbtsIeEHQpa1%2Fg1MHEZc0D7C1fnMUcM8VHk%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숙소에 짐을 풀고는 '&lt;a href=&quot;https://maps.app.goo.gl/fkDCHRtfR343qQmt7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;니지노마쓰바라&lt;/a&gt;' 라는 숲을 방문했다. 꽤 유명한 숲이라고 해서 갔는데 비가 너무 와서 흙이 너무 질퍽하여 일찍 나왔다. 비가 안 올 때 방문했다면 훨씬 아름답고 좋았을 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLZCNY/btsIfH4EW4e/3MifkKMz2Z2GVTMKDR7JB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLZCNY/btsIfH4EW4e/3MifkKMz2Z2GVTMKDR7JB1/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.2558%; margin-right: 10px;&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLZCNY/btsIfH4EW4e/3MifkKMz2Z2GVTMKDR7JB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLZCNY%2FbtsIfH4EW4e%2F3MifkKMz2Z2GVTMKDR7JB1%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bufZO5/btsIfdJMRud/RFUNNzoNownoPnNnjTxo10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bufZO5/btsIfdJMRud/RFUNNzoNownoPnNnjTxo10/img.png&quot; width=&quot;493&quot; height=&quot;657&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 35.5814%;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bufZO5/btsIfdJMRud/RFUNNzoNownoPnNnjTxo10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbufZO5%2FbtsIfdJMRud%2FRFUNNzoNownoPnNnjTxo10%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; 다음으로 점심을 먹으러 &lt;a href=&quot;https://maps.app.goo.gl/ySNUZYksw4KxQpaq9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;우동집&lt;/a&gt;을 향했다. 가락국수집은 숲에서 도보로 50분 정도 거리라 걸어갔다. 이 날 너무 습하고 구름이 없어지며 해가 비추자 너무 더워서 후회하며 걸어갔다. 가락국수집에는 대부분 현지인 분들이었다. 로컬 맛집이라고 하여 찾아갔는데 맞았던 것 같다. 많은 메뉴가 있었지만 그냥 가장 비싼 거로 시켰다. 면을 하드/소프트로 선택할 수 있는데 하드를 선택하여 먹었다. (다시 돌아가면 소프트로 먹을 것 같다 ㅎㅎ.) 국물은 좀 달달한 느낌이었고 위에 올려진 고기나 새우튀김은 맛있었다. 면은 우리나라와 다르게 좀 단단한 느낌이 났고 전체적인 맛은 괜찮았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cziw5b/btsIgOB1nB3/IwXozWhhkQCWLFubUdsA3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cziw5b/btsIgOB1nB3/IwXozWhhkQCWLFubUdsA3k/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 35.5814%; margin-right: 10px;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cziw5b/btsIgOB1nB3/IwXozWhhkQCWLFubUdsA3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcziw5b%2FbtsIgOB1nB3%2FIwXozWhhkQCWLFubUdsA3k%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EMWnm/btsIf0QsYrM/0QpAk2CdkYak5r4Sifi7k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EMWnm/btsIf0QsYrM/0QpAk2CdkYak5r4Sifi7k0/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.2558%;&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EMWnm/btsIf0QsYrM/0QpAk2CdkYak5r4Sifi7k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEMWnm%2FbtsIf0QsYrM%2F0QpAk2CdkYak5r4Sifi7k0%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점심을 먹고 숙소까지 걸어갔다. 그나마 구름이 좀 끼며 시원해져서 걸을만하였다. 숙소에서 좀 쉬다가 가라쓰성을 갔다. 가라쓰성을 가까이서 보니 꽤 멋있었다. 일본 특유의 성 느낌이 많이 났다. 아쉽게 시간이 좀 늦어 안을 들어가 볼 수는 없었다. 바닷가에 지어져서 풍경도 괜찮았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHHcv7/btsIfE74Glp/Y4oVjx9odmdikw33rKZbMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHHcv7/btsIfE74Glp/Y4oVjx9odmdikw33rKZbMk/img.png&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHHcv7/btsIfE74Glp/Y4oVjx9odmdikw33rKZbMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHHcv7%2FbtsIfE74Glp%2FY4oVjx9odmdikw33rKZbMk%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rs3TO/btsIeiSAqhG/ir7iWfOeKlYtsHnaWECkck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rs3TO/btsIeiSAqhG/ir7iWfOeKlYtsHnaWECkck/img.png&quot; style=&quot;width: 45.9644%; margin-right: 10px;&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;47.06&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rs3TO/btsIeiSAqhG/ir7iWfOeKlYtsHnaWECkck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frs3TO%2FbtsIeiSAqhG%2Fir7iWfOeKlYtsHnaWECkck%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzWAfi/btsIfHp43fm/gsRAQlMa9vAakUjj0Mfef0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzWAfi/btsIfHp43fm/gsRAQlMa9vAakUjj0Mfef0/img.png&quot; data-origin-width=&quot;2316&quot; data-origin-height=&quot;3088&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzWAfi/btsIfHp43fm/gsRAQlMa9vAakUjj0Mfef0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzWAfi%2FbtsIfHp43fm%2FgsRAQlMa9vAakUjj0Mfef0%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;2316&quot; height=&quot;3088&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 시내 구경을 하다 &lt;a href=&quot;https://maps.app.goo.gl/WeQQNp7JTPeZU8TGA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;가라츠&amp;nbsp;신사&lt;/a&gt;에 방문하였다. 이곳은 꽤 크고 멋있었다. 구경을 끝내고 저녁으로 오징어 회를 먹으러 갔다. 처음으로는 &lt;a href=&quot;https://maps.app.goo.gl/vK1XuYM9ZbrvvCaz9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;야마시게&lt;/a&gt;라는 곳을 방문하였는데, 오후 6시였음에도 예약이 꽉차서 먹을 수 없었다. 다음으로 &lt;a href=&quot;https://maps.app.goo.gl/uky4QGbn8q7F8mJi8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;겐요 오라는&lt;/a&gt; 곳을 방문하였는데, 다행히 자리가 있어 먹을 수 있었다. 오징어의 몸통을 잘라서 회로 올려주고 다리와 머리는 그냥 장식용으로 함께 나왔다. 좀 잔인해 보이긴 했는데 꽤 쫄깃하고 달달하여 맛있었다. 썰어져 나온 것을 다 먹으면 나머지 부분들도 튀겨서 주었는데, 이것도 맛있었다. 다만 오징어 회 말고는 그저 그래서 돈이 살짝 아까웠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmkOJP/btsIggFyMDv/muQDJXQtcXJQyJvL8pxrB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmkOJP/btsIggFyMDv/muQDJXQtcXJQyJvL8pxrB1/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 38.1168%; margin-right: 10px;&quot; data-widthpercent=&quot;39.02&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmkOJP/btsIggFyMDv/muQDJXQtcXJQyJvL8pxrB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmkOJP%2FbtsIggFyMDv%2FmuQDJXQtcXJQyJvL8pxrB1%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4feb7/btsIftlktYn/wXpLgUkjqz6WEExPRXEDu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4feb7/btsIftlktYn/wXpLgUkjqz6WEExPRXEDu0/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 38.1168%; margin-right: 10px;&quot; data-widthpercent=&quot;39.02&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4feb7/btsIftlktYn/wXpLgUkjqz6WEExPRXEDu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4feb7%2FbtsIftlktYn%2FwXpLgUkjqz6WEExPRXEDu0%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ML1QX/btsIfGdFWOT/r9XRwsObMOuWKEz3N9nzsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ML1QX/btsIfGdFWOT/r9XRwsObMOuWKEz3N9nzsK/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 21.4407%;&quot; data-widthpercent=&quot;21.96&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ML1QX/btsIfGdFWOT/r9XRwsObMOuWKEz3N9nzsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FML1QX%2FbtsIfGdFWOT%2Fr9XRwsObMOuWKEz3N9nzsK%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밥을 다 먹고 아쉬워서 다시 편의점에 들러 과자와 푸딩을 사서 숙소로 돌아갔다. 감자칩과 수플레 푸딩을 샀는데, 수플레 푸딩은 진짜 너무 맛있었다. 다음에 일본에 간다면 꼭 다시 먹을 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2dljO/btsIgNb3tL2/Ha7Tk9WD5ZpcDkhM195Mu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2dljO/btsIgNb3tL2/Ha7Tk9WD5ZpcDkhM195Mu0/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 21.4407%; margin-right: 10px;&quot; data-widthpercent=&quot;21.95&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2dljO/btsIgNb3tL2/Ha7Tk9WD5ZpcDkhM195Mu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2dljO%2FbtsIgNb3tL2%2FHa7Tk9WD5ZpcDkhM195Mu0%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIA2EN/btsIed4UHaF/DOouk0Vkfk5NQN9WFGcQT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIA2EN/btsIed4UHaF/DOouk0Vkfk5NQN9WFGcQT1/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 38.1168%; margin-right: 10px;&quot; data-widthpercent=&quot;39.02&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIA2EN/btsIed4UHaF/DOouk0Vkfk5NQN9WFGcQT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIA2EN%2FbtsIed4UHaF%2FDOouk0Vkfk5NQN9WFGcQT1%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K3Iwv/btsIgNwoXaG/dSMSHts70g8Wfh2nxyCeKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K3Iwv/btsIgNwoXaG/dSMSHts70g8Wfh2nxyCeKK/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 38.1168%;&quot; data-widthpercent=&quot;39.03&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K3Iwv/btsIgNwoXaG/dSMSHts70g8Wfh2nxyCeKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK3Iwv%2FbtsIgNwoXaG%2FdSMSHts70g8Wfh2nxyCeKK%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여행 마지막 날 후쿠오카로 버스를 타고 돌아갔다. 버스를 타니 1시간 밖에 걸리지 않았다. 꽤 먼 거리임에도 길이 전혀 막히지 않아 금방 도착한 것 같다. 도착해서 바로 점심을 먹으러 &lt;a href=&quot;https://maps.app.goo.gl/jxro16u6n9wKrJ3y6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;멘야 카네토라라는&lt;/a&gt; 츠케멘 집을 방문했다. 이미 맛집으로 많이 알려진 곳이라 비가 엄청 쏟아짐에도 줄이 길었다. 그런데 문제가 이 집은 현금밖에 받지 않는다는 것이었다(본점만 온리캐시). 그래서 가지고 있던 현금을 다 털어보니 정확히 1엔이 부족했다.. 앞 줄에 있던 분들이 한국 분들이셔서 사정을 설명하였더니 1엔을 흔쾌히 주셨다. 그래서 너무 감사하게도 츠케멘을 먹을 수 있었다. 츠케멘은 간이 좀 강했는데 꽤 맛있었다. (솔직히 줄 서서 먹을 정도는 아닌 것 같다..ㅋㅋ)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crtWM3/btsIeUqfDwv/HaI9oiabsFDoWS6ZcykCz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crtWM3/btsIeUqfDwv/HaI9oiabsFDoWS6ZcykCz1/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crtWM3/btsIeUqfDwv/HaI9oiabsFDoWS6ZcykCz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrtWM3%2FbtsIeUqfDwv%2FHaI9oiabsFDoWS6ZcykCz1%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMnX6e/btsIfxOQzH4/bqWwC3uKaB1QeZqBlROLYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMnX6e/btsIfxOQzH4/bqWwC3uKaB1QeZqBlROLYK/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMnX6e/btsIfxOQzH4/bqWwC3uKaB1QeZqBlROLYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMnX6e%2FbtsIfxOQzH4%2FbqWwC3uKaB1QeZqBlROLYK%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PVKyx/btsIgocyPCe/9Bev1e4TSvvrRSaxiqWa3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PVKyx/btsIgocyPCe/9Bev1e4TSvvrRSaxiqWa3k/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.9644%;&quot; data-widthpercent=&quot;47.06&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PVKyx/btsIgocyPCe/9Bev1e4TSvvrRSaxiqWa3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPVKyx%2FbtsIgocyPCe%2F9Bev1e4TSvvrRSaxiqWa3k%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점심을 먹고 시간이 좀 남아 카페에서 좀 쉬다가 길거리에서 푸딩도 사 먹고(망고맛 너무 맛있음) 덴진역에 있는 파르코몰을 구경하였다. 원피스와 짱구 관련한 스토어가 있어 구경을 하며 시간을 보냈다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9DENS/btsIfGktULY/WdfOJVAKPsm4LlXOqZwauk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9DENS/btsIfGktULY/WdfOJVAKPsm4LlXOqZwauk/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9DENS/btsIfGktULY/WdfOJVAKPsm4LlXOqZwauk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9DENS%2FbtsIfGktULY%2FWdfOJVAKPsm4LlXOqZwauk%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tK42o/btsIfvwIOt3/7KJv9zYBOyrBcgomTEJ9Hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tK42o/btsIfvwIOt3/7KJv9zYBOyrBcgomTEJ9Hk/img.png&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.9644%; margin-right: 10px;&quot; data-widthpercent=&quot;47.06&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tK42o/btsIfvwIOt3/7KJv9zYBOyrBcgomTEJ9Hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtK42o%2FbtsIfvwIOt3%2F7KJv9zYBOyrBcgomTEJ9Hk%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;4032&quot; height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/INSrR/btsIfuq4LQE/tCwPbIDgv8bckGamWUJZRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/INSrR/btsIfuq4LQE/tCwPbIDgv8bckGamWUJZRk/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/INSrR/btsIfuq4LQE/tCwPbIDgv8bckGamWUJZRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FINSrR%2FbtsIfuq4LQE%2FtCwPbIDgv8bckGamWUJZRk%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현금을 점심에 다 쓴 상태라 출금을 해야하나 싶었는데, ATM기를 확인해 보니 10000엔 단위로 출금이 가능하였다.. 너무 큰 금액이라 덴진역에서 후쿠오카 공항역까지 걸어가야 하나 싶어서 천천히 걸어가다가 카드가 되나 확인하기 위해 덴진미나미역에 들어갔다. 마스터 카드는 불가능했고 비자카드는 전철을 탈 때 쓸 수 있었는데, 아쉽게도 나는 마스터카드밖에 없었다. 그래서 절망하던 도중 우연히 옆에 있던 한국 분들이 우리의 얘기를 듣게 되었고 400엔을 주신다고 했다. 한국 돈을 보내드린다고 했는데 그것도 괜찮다고 거절하셔서 다 같이 사진도 찍고 인스타그램 친구를 맺었다. 부산에서 오신 쾌남 2분 정말 감사합니다. ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 저녁으로 모츠나베 라는 음식을 먹으러 갔다. 처음 먹어보는 음식인 만큼 구글 평점을 신경 써서 선택하였다. 그러다 &lt;a href=&quot;https://maps.app.goo.gl/dJu1yaw2T8kFYFv58&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이치후지 텐진점&lt;/a&gt;을 방문하였는데, 예약을 할 수 있었지만 그냥 일찍 가서 줄을 서기로 했다. 다행히 바로 들어갈 수 있었고 모츠나베를 시켰다. 특이하게 음료를 필수로 시켜야 해서 맥주 2잔도 함께 시켰다. 모츠나베는 정말 맛있었다. 첫날 먹었던 함바그 다음으로 맛있었던 것 같다. 거기다 볶음밥까지 해 먹었는데 완벽했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AFZgI/btsIfdwoCVq/2iIBmOCKSKco1nDzvzIg2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AFZgI/btsIfdwoCVq/2iIBmOCKSKco1nDzvzIg2K/img.png&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AFZgI/btsIfdwoCVq/2iIBmOCKSKco1nDzvzIg2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAFZgI%2FbtsIfdwoCVq%2F2iIBmOCKSKco1nDzvzIg2K%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/muJlC/btsIezUgiQ6/1msdpfAgY1ebUxFem97tI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/muJlC/btsIezUgiQ6/1msdpfAgY1ebUxFem97tI0/img.png&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/muJlC/btsIezUgiQ6/1msdpfAgY1ebUxFem97tI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmuJlC%2FbtsIezUgiQ6%2F1msdpfAgY1ebUxFem97tI0%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgXZ0c/btsIglAaw6R/wFCPSxrm3zHELHdAAOcX3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgXZ0c/btsIglAaw6R/wFCPSxrm3zHELHdAAOcX3k/img.png&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%;&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgXZ0c/btsIglAaw6R/wFCPSxrm3zHELHdAAOcX3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgXZ0c%2FbtsIglAaw6R%2FwFCPSxrm3zHELHdAAOcX3k%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;3024&quot; height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모츠나베로 알차게 배를 채우고 링고 애플파이에 다시 들러 선물용 애플파이를 구매하여 공항으로 갔다. 3박 4일 너무 재밌었다. 후쿠오카는 새롭고 맛있는 음식을 많이 접할 수 있어서 좋았던 것 같다. (날씨 좋았을 때 왔다면 더 좋았을 것 같다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후쿠오카를 간다면 함바그, 모츠나베, 애플파이, 수플레 푸딩을 강하게 추천한다.&lt;/p&gt;</description>
      <category>Story/여행</category>
      <category>일본여행</category>
      <category>후쿠오카</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/80</guid>
      <comments>https://simpling.tistory.com/80#entry80comment</comments>
      <pubDate>Fri, 28 Jun 2024 13:13:06 +0900</pubDate>
    </item>
    <item>
      <title>한국투자증권 OpenAPI 사용하기(2) - KIS Developers</title>
      <link>https://simpling.tistory.com/78</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://simpling.tistory.com/70&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;지난 글&lt;/a&gt;에서는 한국투자증권의 api를 쉽게 사용할 수 있게 만들어진 mojito 사용법을 알아보았습니다. 하지만 아쉽게도 mojito에 모든 기능들이 다 구현되어 있지는 않아서 추가로 필요한 기능들은 스스로 추가해 주어야 합니다. 그래서 이번에는 현재(2024/02/25) mojito 버전(0.1.6)에 구현되어 있지 않은 기능을 추가하는 방법을 알아보겠습니다. 그러기 위해서는 먼저 &lt;a href=&quot;https://pypi.org/project/mojito2/#history&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;mojito&lt;/a&gt;를 가상환경에 설치해 주시고, &lt;a href=&quot;https://apiportal.koreainvestment.com/apiservice/apiservice-domestic-stock#L_aade4c72-5fb7-418a-9ff2-254b4d5f0ceb&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;KIS developers&lt;/a&gt;에 접속하시면 됩니다. 이번 글에서는 '&lt;u&gt;&lt;b&gt;호가 정보&lt;/b&gt;&lt;/u&gt;'와 '&lt;u&gt;&lt;b&gt;주문 체결 조회&lt;/b&gt;&lt;/u&gt;'를 하는 메서드를 추가해 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 호가 정보를 불러오는 함수를 먼저 만들어보겠습니다. API 문서의 국내주식시세-&amp;gt;주식현재가 호가/예상 체결에 들어가 보면 호가 정보를 불러오는 url 정보를 볼 수 있습니다(참고로 실전 domain, 모의 domain url 정보가 다른데 이는 이미 mojito에 반영되어 있으므로 그 밑의 URL 정보만 가져오면 됩니다.). 또한 request에 필요한 header와 query parameter를 볼 수 있는데, header에 들어가는 정보는 대부분 mojito 내부에서 이미 처리되어 그냥 넘기기만 하면 되는 정보들이 대부분이고 'tr_id' 정도만 따로 같이 넘기면 됩니다. 한편 query parameter에 해당하는 '&lt;span style=&quot;background-color: #ffffff; color: #444444; text-align: left;&quot;&gt;FID_COND_MRKT_DIV_CODE'와 ' &lt;span style=&quot;background-color: #ffffff; color: #444444; text-align: left;&quot;&gt;FID_INPUT_ISCD'는 따로 처리해 주면 되는데, 여기에서는 삼성전자에 대한 정보를 불러오는 것을 예시로 코드를 작성해 보면 아래와 같습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1708839861190&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# mojito의 KoreaInvestment 클래스의 메서드로 추가.
def fetch_hoga(self, code:str='005930'):
    # code에 대한 호가창 정보를 return 하는 함수.
    path = &quot;/uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn&quot;
	# self.base_url은 모의투자(mock)인지 실전투자인지에 따라 달라진다.
	url = f&quot;{self.base_url}/{path}&quot;
    headers = {
        &quot;content-type&quot;: &quot;application/json&quot;,
        &quot;authorization&quot;: self.access_token,
        &quot;appkey&quot;: self.api_key,
        &quot;appsecret&quot;: self.api_secret,
        &quot;tr_id&quot;: &quot;FHKST01010200&quot; # 주식 현재가호가 에상체결.
    }
    params = {
        &quot;FID_COND_MRKT_DIV_CODE&quot;: 'J',
        &quot;FID_INPUT_ISCD&quot;: code
    }
    resp = requests.get(url, headers=headers, params=params)
    resp = resp.json()
    return resp&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #444444; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #444444; text-align: left;&quot;&gt;이를 사용해서 정보를 프린트해 보는 코드는 아래와 같습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1708840392565&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import mojito
import yaml

print(mojito.__version__)

with open(&quot;data/koreainvestment.yaml&quot;) as f:
    info_data = yaml.load(f, Loader=yaml.FullLoader)

key = info_data['key']
secret = info_data['secret']
acc_no = info_data['acc_no']

broker = mojito.KoreaInvestment(
    api_key=key,
    api_secret=secret,
    acc_no=acc_no
)

code = '005930' # 삼성전자
hoga_info = broker.fetch_hoga(code)

if hoga_info['rt_cd'] != '0':
    print(f&quot;{code}, 호가 호출 실패 msg : {hoga_info['msg1']}&quot;)
# 매수 호가1
maesu_hoga1 = int(hoga_info['output1']['bidp1'])
# 매수 호가 잔량1
maesu_hoga_qnt1 = int(hoga_info['output1']['bidp_rsqn1'])
# 매도 호가1
maedo_hoga1 = int(hoga_info['output1']['askp1'])
# 매도 호가 잔량1
maedo_hoga_qnt1 = int(hoga_info['output1']['askp_rsqn1'])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #444444;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;호가 정보로 리턴되는 값은 크게 output1/output2로 나뉘는데, output1에는 매수/매도 호가 가격과 그 잔량에 대한 정보 등을 제공해 주고, output2에는 주식 최고가, 시가, 체결가 등이 제공됩니다. 저는 output2에서는 현재 체결가에 대한 정보를 쓰고 있는데 이는 동시호가 때 사용하면 유용합니다. 참고로 모든 값이 string으로 리턴되므로 정수로 변환하고 싶으면 위와 같이 int로 감싸주어야 합니다!&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 주식 일별 주문 체결 조회를 하는 방법을 알아보겠습니다. 이는 매수/매도 주문을 하고 해당 주문으로 실제 체결이 얼마큼 됐는지 미체결량은 얼마인지 파악하기 위해서 사용합니다. API 문서의 국내주식주문-&amp;gt;주식일별주문체결조회에 들어가면 어떻게 요청을 해야 하는지 나와 있습니다. 호가 정보 요청 때와 같이 url 정보를 가져오고, header에 들어가는 'tr_id' 정보를 가져오는데 여기서는 모의 투자와 실전 투자가 구분되어 들어간다는 것을 유의해야 합니다(또한 당일 주문에 대한 정보만 요청할 거라 3개월 이내에 대한 정보만 고려합니다. 그 이전 정보를 고려하시는 분들은 해당 정보를 다르게 작성하여 요청하시면 됩니다.). Query parameter에는 많은 정보들이 들어가게 되는데 Description에 나온 설명을 읽어보면 쉽게 파악이 됩니다. 모두 고려하여 예시 코드를 작성해 보면 아래와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1708842801819&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import datetime
def fetch_chegyul(self, code: str = '005930', ODNO: str = '', CCLD_DVSN: str = '체결',
                SLL_BUY_DVSN_CD: str = '전체'):
    &quot;&quot;&quot;주식 일별 주문 체결 조회
    Args:
        SLL_BUY_DVSN_CD (str): 매도매수구분코드, (전체, 매도, 매수)
        code (str): 상품번호, 공란: 전체 조회
        CCLD_DVSN (str): 체결구분, (전체, 체결, 미체결)
        ODNO (str): 주문번호, &quot;&quot; (Null 값 설정)
    &quot;&quot;&quot;
    CCLD_DVSN = {&quot;전체&quot;: &quot;00&quot;, &quot;체결&quot;: &quot;01&quot;, '미체결': '02'}[CCLD_DVSN]
    SLL_BUY_DVSN_CD = {&quot;전체&quot;: &quot;00&quot;, &quot;매도&quot;: &quot;01&quot;, '매수': '02'}[SLL_BUY_DVSN_CD]
    path = &quot;/uapi/domestic-stock/v1/trading/inquire-daily-ccld&quot;
    url = f&quot;{self.base_url}/{path}&quot;
    headers = {
        &quot;content-type&quot;: &quot;application/json&quot;,
        &quot;authorization&quot;: self.access_token,
        &quot;appkey&quot;: self.api_key,
        &quot;appsecret&quot;: self.api_secret,
        &quot;tr_id&quot;: 'VTTC8001R' if self.mock else &quot;TTTC8001R&quot;  # 주식 일별 주문 체결 조회(3개월이내)
    }
    params = {
        'CANO': self.acc_no_prefix,
        'ACNT_PRDT_CD': self.acc_no_postfix,
        'INQR_STRT_DT': datetime.datetime.now().strftime('%Y%m%d'),  # YYYYMMDD
        'INQR_END_DT': datetime.datetime.now().strftime('%Y%m%d'),  # YYYYMMDD
        'SLL_BUY_DVSN_CD': SLL_BUY_DVSN_CD,  # 매도매수구분코드, 00:전체, 01:매도, 02:매수
        'INQR_DVSN': '00',  # 조회구분, 00:역순, 01:정순
        'PDNO': code,  # 상품번호, 공란: 전체 조회
        'CCLD_DVSN': CCLD_DVSN,  # 체결구분, 00:전체, 01:체결, 02:미체결
        'ORD_GNO_BRNO': '',  # 주문채번지점번호, 	&quot;&quot; (Null 값 설정)
        'ODNO': ODNO,  # 주문번호, &quot;&quot; (Null 값 설정)
        'INQR_DVSN_3': '00',  # 조회구분3, 00:전체, 01:현금, 02:융자, 03:대출, 04:대주
        'INQR_DVSN_1': '',
        # 연속조회검색조건100, 공란 : 최초 조회시, 이전 조회 Output CTX_AREA_FK100 값 : 다음페이지 조회시(2번째부터)
        &quot;CTX_AREA_FK100&quot;: &quot;&quot;,
        # 연속조회키100, 공란 : 최초 조회시, 이전 조회 Output CTX_AREA_NK100 값 : 다음페이지 조회시(2번째부터)
        &quot;CTX_AREA_NK100&quot;: &quot;&quot;
    }
    resp = requests.get(url, headers=headers, params=params)
    resp = resp.json()
    return resp&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #444444; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #444444; text-align: left;&quot;&gt;코드가 길긴 하지만, 설명이 많아서 그런 것이고 실제 중요한 변수는 함수에 넣어주는 code, ODNO(주문번호), CCLD_DVSN(체결 구분), SLL_BUY_DVSN_CD(매수/매도 구분 코드)입니다. 이는 주문한 정보를 잘 가지고 있다가 체결 정보가 궁금할 때 전달하여 정보를 받으면 됩니다. 메서드 사용 예시 코드는 아래와 같습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1708843365818&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;code = &quot;005930&quot; # 삼성전자 코드
# 매수 주문
order = broker.create_limit_buy_order(
    symbol=code, 
    price=60000,  # 지정가 매수시 가격단위를 고려해야 함.
    quantity=5
)

# 체결 정보 조회
chegyul_info = broker.fetch_chegyul(
    code, order['output']['ODNO'], '체결', '전체')
# 총체결금액
tot_ccld_amt = int(chegyul_info['output1'][0]['tot_ccld_amt'])
# 총체결수량
tot_ccld_qty = int(chegyul_info['output1'][0]['tot_ccld_qty'])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;체결 정보 조회도 리턴되는 값이 크게 output1/output2로 나뉘는데, output1이 조회한 주문번호(ODNO)에 대해서 체결된 정보를 전달해 주고, output2는 해당 종목(code)에 대해 체결된 다른 정보까지 합산해서 보여줍니다. 그러므로 똑같은 ' &lt;span style=&quot;background-color: #ffffff; color: #444444; text-align: left;&quot;&gt;tot_ccld_amt'여도 output1, output2에서 나오는 값이 다를 수 있다는 점을 주의해야 합니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>퀀트투자</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/78</guid>
      <comments>https://simpling.tistory.com/78#entry78comment</comments>
      <pubDate>Sun, 25 Feb 2024 15:48:44 +0900</pubDate>
    </item>
    <item>
      <title>PPO paper 리뷰</title>
      <link>https://simpling.tistory.com/77</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Proximal Policy Optimization (PPO ([1]))는 OpenAI에서 작성한 논문으로 현재(2023년 12월)까지도 많이 사용되는 안정적인 알고리즘이다.&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: #0070d1;&quot; href=&quot;https://simpling.tistory.com/75&quot;&gt;TD3([2]) 글&lt;/a&gt;에서 말했던 것처럼 actor-critic 방법은 GAN과 같이 network 2개를 한 번에 학습시키는 방법이라 상당히 어려운 방법이다. 특히 가치함수의 불안정성이 학습에 영향을 미쳐 TD3에서도 이를 해결하기 위해 가치함수를 더 많이 학습하는 방법을 사용한다. PPO는 on-policy로 정책을 업데이트하면서 안정적으로 actor-critic을 학습할 수 있는 방법을 제안한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPO는 TRPO(Trust Region Policy Optimization ([3])) 방법을 근사하여 푼 방법이라고 볼 수 있다. TRPO에서 제안한 방법을 수식으로 쓰면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ max_{\theta} \hat{\mathbb{E}}_{t} [ \frac{\pi_{\theta} (a_{t}|s_{t})} {\pi_{\theta_{old}} (a_{t}|s_{t}) } \hat{A_{t}}] $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&amp;nbsp; \textit{s.t.} \quad&amp;nbsp; \hat{\mathbb{E}}_{t} [KL[\pi_{\theta_{old}}(\cdot|s_{t}), \pi_{\theta}(\cdot|s_{t})] ] \leq \delta&amp;nbsp;$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정책의 변화량을 제한하는 제약 조건을 만족하면서 목적함수를 최적화하는 방법이다. 보통의 경우 이런 제약조건이 걸려있으면 풀기가 매우 어렵다(구현도 어렵고 최적화도 어려움). 그래서 TRPO에서는 KL 텀을 loss에 같이 주어 최적화하는 방법을 선택했다. 하지만 이런 penalty도 학습에 어려움을 주고 loss에 얼마 큼의 가중치를 줄 것인지도 hyperparameter로 선택해야 한다. 두 정책 함수 간의 비율 $ r_{t} (\theta) = \frac{\pi_{\theta}(a_{t}|s_{t})} {\pi_{\theta_{old}}(a_{t}|s_{t})} $ 로 나타내면 TRPO의 목적함수는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ L^{CPI}(\theta) = \mathbb{E}_{t} [r_{t} (\theta) \hat{A}_{t}] $$&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편 PPO는 두 목적함수 간의 비율이 1에서 멀어지지 않게 만드는 clip 방식을 제안했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ L^{CLIP}(\theta) = \mathbb{E}_{t} [min(r_{t}(\theta)\hat{A}_{t}, clip(r_{t}(\theta), 1-\epsilon, 1+\epsilon) \hat{A}_{t})]&amp;nbsp; $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;min 안의 첫 번째 수식은 기존의 목적 함수와 같고, 두 번째는 정책 비율의 범위를 정해서 나온 값이다. 2개의 값을 비교하여 작은 값을 취함으로써 $\pi_{\theta}$를 보수적으로 업데이트하도록 만든다. ($\hat{A}_{t}$가 양수인 경우를 가정했을 때, $r_{t} &amp;lt; 1-\epsilon$이면 $(1-\epsilon)\hat{A}_{t}$가 되고 $1-\epsilon \leq r_{t} \leq 1+\epsilon$ 이면 $r_{t}(\theta) \hat{A}_{t}$, $r_{t} &amp;gt; 1+\epsilon$이면 $(1+\epsilon)\hat{A}_{t}$ 가 된다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPO에서는 Advantage function $\hat{A}_{t}$ 추산 시 generalized advantage estimator의 truncated version을 이용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \hat{A}_{t} = \delta_{t} + (\gamma \lambda) \delta_{t+1} +\cdots + (\gamma \lambda)^{T-t+1} \delta_{T-1} $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;($\lambda$: bias/variance의 controlling 도구로 사용됨. (다시 말하면 얼마나 MC/TD 스럽게 훈련할지 정함.))&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 정책함수 $\pi_{\theta}$에 대한 엔트로피 $ \mathit{H}(\pi_{\theta}(a_{t}|s_{t})) $가 maximize 되도록 loss 함수에 더해준다. 이는 같은 상태일 때 여러 행동을 탐험하도록 도와주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면 PPO의 loss는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ L_{t}^{CLIP+VF+S}(\theta) = \mathbb{E}_{t}[L_{t}^{CLIP}(\theta) - c_{1}L_{t}^{VF}(\theta) + c_{2} S[\pi_{\theta}](s_{t}) ] $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPO는 특이하게 on-policy를 사용하지만 모아둔 샘플을 여러 번에 걸쳐 업데이트를 하는 방식을 사용한다. 이는 $L^{CLIP}$의 구조 덕분에 정책 함수가 너무 멀어지지 않아서 가능한 선택으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직까지도 PPO는 많이 사용되는데 위에서 설명한 방법들도 효과가 있겠지만 실제 구현 시 들어간 트릭들이 중요한 역할을 했다고 알려져 있다. 이는 논문 [4]에서 다양한 실험을 통해 그 효과를 보여주고 있다. [4]에서 소개한 PPO의 추가 트릭들은 fig 1과 같은 9개다.&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;1306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxWI7u/btsBVzSFEDq/SEjOl0ZcGe7KpOzZBrzlV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxWI7u/btsBVzSFEDq/SEjOl0ZcGe7KpOzZBrzlV0/img.png&quot; data-alt=&quot;Fig 1. PPO tricks ([4])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxWI7u/btsBVzSFEDq/SEjOl0ZcGe7KpOzZBrzlV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxWI7u%2FbtsBVzSFEDq%2FSEjOl0ZcGe7KpOzZBrzlV0%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;531&quot; height=&quot;542&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1306&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. PPO tricks ([4])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1, 2, 5, 6, 7, 9는 모두 대상 값들을 scaling 하는 트릭들인 것을 볼 수 있다. 이는 variance를 줄여주는 방법들로 볼 수 있다. 강화학습은 특성상 variance가 클 수 있어서 이런 트릭들이 주요하게 작용했을 것으로 생각된다. 3번 방법은 생소한 방법인데 심층 신경망 최적화 문제가 ill condition으로 시작하지 않게 도움을 줄 수 있다고 알려져 있다고 한다(정확하지 않은 것 같기도 함.). 4번의 learning rate annealing 방법은 강화 학습뿐 아니라 지도 학습 등에서 일반적으로 사용되는 방법으로 초반에 안정적인 학습과 중반, 후반에 flat minima를 찾는 데 도움을 준다. 8번 방법은 이산 행동 공간의 경우, softmax 함수의 초기 시작값을 균등하게 만드는 데 영향을 주어 초기 exploration에 좋다고 한다.&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;1418&quot; data-origin-height=&quot;788&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oV39f/btsBQpwZNDj/vYOqBNg3LkvLHpnBrK41Zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oV39f/btsBQpwZNDj/vYOqBNg3LkvLHpnBrK41Zk/img.png&quot; data-alt=&quot;Fig 2. Results ([4])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oV39f/btsBQpwZNDj/vYOqBNg3LkvLHpnBrK41Zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoV39f%2FbtsBQpwZNDj%2FvYOqBNg3LkvLHpnBrK41Zk%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;560&quot; height=&quot;311&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;788&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Results ([4])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 2에는 여러 방법들을 적용한 결과를 보여주는 데, 가장 효과가 커 보이는 것은 rewards를 normalization 한 부분으로 보인다. 여기서 사용한 방법은 OpenAI 공개한 방법과 같이 (rewards-mean)/(std+1e-8)의 형식으로 이루어진 코드를 사용했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 이후에도 여러 ablation study를 진행하였는데, PPO가 메인으로 주장했던 $L^{CLIP}$과 같은 방법보단 code level에서 사용했던 여러 트릭들이 더 중요했던 것으로 밝혀졌다. 이런 것들을 보다 보면 강화학습은 최대한 안정적으로 학습을 시키는 트릭들을 잘 익혀놓는 것이 중요해 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Ref&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1]&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://arxiv.org/abs/1707.06347&quot;&gt;https://arxiv.org/abs/1707.06347&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702365608946&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/doISAc/hyULRzrBTa/l8VuDkQqfblwLaXZh5pt21/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/pFwo0/hyUL1ow2bi/w3XXmbAnClctz8jmS8rff1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot; data-og-url=&quot;https://arxiv.org/abs/1707.06347v2&quot; data-og-source-url=&quot;https://arxiv.org/abs/1707.06347&quot; data-og-host=&quot;arxiv.org&quot; data-og-description=&quot;We propose a new family of policy gradient methods for reinforcement learning, which alternate between sampling data through interaction with the environment, and optimizing a &amp;quot;surrogate&amp;quot; objective function using stochastic gradient ascent. Whereas standar&quot; data-og-title=&quot;Proximal Policy Optimization Algorithms&quot; data-og-type=&quot;website&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://arxiv.org/abs/1707.06347&quot; data-source-url=&quot;https://arxiv.org/abs/1707.06347&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/doISAc/hyULRzrBTa/l8VuDkQqfblwLaXZh5pt21/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/pFwo0/hyUL1ow2bi/w3XXmbAnClctz8jmS8rff1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;Proximal Policy Optimization Algorithms&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;We propose a new family of policy gradient methods for reinforcement learning, which alternate between sampling data through interaction with the environment, and optimizing a &quot;surrogate&quot; objective function using stochastic gradient ascent. Whereas standar&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2]&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://arxiv.org/pdf/1802.09477.pdf&quot;&gt;https://arxiv.org/pdf/1802.09477.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3]&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://arxiv.org/abs/1502.05477&quot;&gt;https://arxiv.org/abs/1502.05477&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702365608947&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bGj8ea/hyUIzf8vHf/EleK68O8cBuBZO7B9UcrQ0/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/beD11S/hyUIxo5dIU/uCqfW8ENPMU7sYgxpl0RE0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot; data-og-url=&quot;https://arxiv.org/abs/1502.05477v5&quot; data-og-source-url=&quot;https://arxiv.org/abs/1502.05477&quot; data-og-host=&quot;arxiv.org&quot; data-og-description=&quot;We describe an iterative procedure for optimizing policies, with guaranteed monotonic improvement. By making several approximations to the theoretically-justified procedure, we develop a practical algorithm, called Trust Region Policy Optimization (TRPO).&quot; data-og-title=&quot;Trust Region Policy Optimization&quot; data-og-type=&quot;website&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://arxiv.org/abs/1502.05477&quot; data-source-url=&quot;https://arxiv.org/abs/1502.05477&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bGj8ea/hyUIzf8vHf/EleK68O8cBuBZO7B9UcrQ0/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/beD11S/hyUIxo5dIU/uCqfW8ENPMU7sYgxpl0RE0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;Trust Region Policy Optimization&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;We describe an iterative procedure for optimizing policies, with guaranteed monotonic improvement. By making several approximations to the theoretically-justified procedure, we develop a practical algorithm, called Trust Region Policy Optimization (TRPO).&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] &lt;a href=&quot;https://arxiv.org/abs/2005.12729&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/2005.12729&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702369367937&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Implementation Matters in Deep Policy Gradients: A Case Study on PPO and TRPO&quot; data-og-description=&quot;We study the roots of algorithmic progress in deep policy gradient algorithms through a case study on two popular algorithms: Proximal Policy Optimization (PPO) and Trust Region Policy Optimization (TRPO). Specifically, we investigate the consequences of &amp;quot;&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2005.12729&quot; data-og-url=&quot;https://arxiv.org/abs/2005.12729v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/V3k5a/hyUIu67rSI/0XYRVJlIG2WzsXXBoqk9bk/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/j3Zfs/hyULWATaXV/ecxKZO2NxZj09QKk1kanr1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2005.12729&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2005.12729&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/V3k5a/hyUIu67rSI/0XYRVJlIG2WzsXXBoqk9bk/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/j3Zfs/hyULWATaXV/ecxKZO2NxZj09QKk1kanr1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Implementation Matters in Deep Policy Gradients: A Case Study on PPO and TRPO&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We study the roots of algorithmic progress in deep policy gradient algorithms through a case study on two popular algorithms: Proximal Policy Optimization (PPO) and Trust Region Policy Optimization (TRPO). Specifically, we investigate the consequences of &quot;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/강화학습</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/77</guid>
      <comments>https://simpling.tistory.com/77#entry77comment</comments>
      <pubDate>Wed, 13 Dec 2023 22:22:06 +0900</pubDate>
    </item>
    <item>
      <title>TD3 paper 리뷰</title>
      <link>https://simpling.tistory.com/75</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;TD3 (Addressing function approximation error in actor-critic methods ([1]))&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TD3라고 알려진 방법은 Double-Q learning에서 network를 2개 만들어 maximization bias를 피하는 방법을 쓰는 것이 &lt;a href=&quot;https://simpling.tistory.com/74&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;에서 소개한 DDQN에서 target network를 학습 network에서 복사해서 사용하는 것보다 좋다고 주장한다. 하지만 기존처럼 Q-learning이 아닌 Actor-critic을 전제로 한다. 저자는 Actor-critic에는 overestimation bias와 가치함수 추정치의 분산 문제가 있어 학습을 불안정하게 만든다고 주장한다. 실제 실험 결과를 보면, DDPG 알고리즘도 overestimation bias 현상이 일어나고 있고 논문에서 제안한 CDQ 방법이 더 안정적 성능을 내는 것으로 보이며(Fig 1), DDQN 방법보다 Double Q-learning 방법이 overestimation bias 문제를 완화시켜 준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vZrhb/btsBJcbLFdP/OBXhaxf03jk4CHJVSozrwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vZrhb/btsBJcbLFdP/OBXhaxf03jk4CHJVSozrwK/img.png&quot; data-alt=&quot;Fig 1. [1]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vZrhb/btsBJcbLFdP/OBXhaxf03jk4CHJVSozrwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvZrhb%2FbtsBJcbLFdP%2FOBXhaxf03jk4CHJVSozrwK%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;365&quot; height=&quot;226&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. [1]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CDQ(Clipped Double Q-learning)은 기존 Double Q-learning 같이 Q-network를 따로 생성하여 2개 사용하는 방법이다(Actor-Critic에서는 정책도 따로 만드는게 맞지만 여기서는 효율을 위해 한 개만 생성한다). 기존과 다른 점은 target을 만들 때 2개 중 minimum 값을 사용한다는 점이다. 이를 통해 overestimation bias 문제를 완화시켜 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ Target = r+\gamma min_{i=1,2} Q_{\theta_{i}} (s', \pi_{\phi}(s')) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편 function approximation으로 인한 에러로 인해 분산이 커지는 문제도 있다. Target network가 제대로 추산되지 않을 경우가 문제인데, 이는 policy 업데이트 시 악영향을 끼친다. 따라서 가치함수 추산 오차를 줄이기 위해 가치함수를 정책보다 더 자주 업데이트 하는 방법을 제시한다. (2개 네트워크를 같이 업데이트하는 것은 당연히 어렵고 오차가 클 수밖에 없을 듯하다.)&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;709&quot; data-origin-height=&quot;451&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LHAWe/btsBGx8RyzE/rBc3Jnfh3yagAKcPQLHWS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LHAWe/btsBGx8RyzE/rBc3Jnfh3yagAKcPQLHWS1/img.png&quot; data-alt=&quot;Fig 2. [1]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LHAWe/btsBGx8RyzE/rBc3Jnfh3yagAKcPQLHWS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLHAWe%2FbtsBGx8RyzE%2FrBc3Jnfh3yagAKcPQLHWS1%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;431&quot; height=&quot;274&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;451&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. [1]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 2는 정책을 고정했을 때와 학습했을 때 target network를 업데이트하는 정도에 따라 value 추정치의 분산을 확인한 것이다. 확실히 slow update 방법이 좋은 효과를 보인다. ( $ \theta \leftarrow \tau \theta + (1-\tau)\theta'&amp;nbsp; $)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Determinisitc policy에서는 정책이 디렉-델타 함수와 같이 narrow 분포를 가질 수 있다. 이 또한 function approximation으로 인한 오류로 target variance가 증가하게 한다. 그래서 target policy smoothing regularization을 도입한다. 이는 동일한 state에서 유사한 정책의 경우 유사한 값을 가지게 하는 것으로 정책 분포가 좀 더 넓어지게 만들어주는 효과가 있다. 방법은 아래 수식과 같이 gaussian noise($\epsilon$)로 perturb를 주는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ Target = r + min_{i=1,2} \mathbb{E}_{\epsilon} [Q_{\theta'_{i}}(s', \pi_{\phi}(s') + \epsilon) ] $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(실제 구현시에는 noise에 대해 기댓값 계산을 하진 않고 one-sample mc로 추정한다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUaKqP/btsBG3NfJgP/77L1RnZZiALwo0KTQiXdDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUaKqP/btsBG3NfJgP/77L1RnZZiALwo0KTQiXdDK/img.png&quot; data-alt=&quot;Fig 3. TD3 algorithm ([1])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUaKqP/btsBG3NfJgP/77L1RnZZiALwo0KTQiXdDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUaKqP%2FbtsBG3NfJgP%2F77L1RnZZiALwo0KTQiXdDK%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;447&quot; height=&quot;484&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. TD3 algorithm ([1])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고리즘을 확인해보면, 위에서 설명한 방법들을 모두 쓰고 있는데 특히 policy gradient를 가끔 업데이트시키는 부분을 보면 target network도 soft update를 사용해서 같이 업데이트하는 것을 볼 수 있다. 여러모로 분산을 줄이고 최대한 안정적으로 훈련시키기 위해 여러 가지를 고려했음을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1042&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cM0V1G/btsBGUv47yE/6UFdagluKhxJozMMHFvBl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cM0V1G/btsBGUv47yE/6UFdagluKhxJozMMHFvBl0/img.png&quot; data-alt=&quot;Fig 4. EXP results ([1])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cM0V1G/btsBGUv47yE/6UFdagluKhxJozMMHFvBl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcM0V1G%2FbtsBGUv47yE%2F6UFdagluKhxJozMMHFvBl0%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;1042&quot; height=&quot;515&quot; data-origin-width=&quot;1042&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. EXP results ([1])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 4의 실험 결과를 보면 TD3가 average return이 높을 뿐 아니라 안정적으로 학습되는 모습을 볼 수 있다. RL은 학습 기반의 stochastic optimization 방법이라 어려워서 디테일한 방법 혹은 트릭이 중요하게 작용되는 것 같다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Ref&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://arxiv.org/abs/1802.09477&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1802.09477&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/강화학습</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/75</guid>
      <comments>https://simpling.tistory.com/75#entry75comment</comments>
      <pubDate>Mon, 11 Dec 2023 20:35:57 +0900</pubDate>
    </item>
    <item>
      <title>DQN 부터 DDPG 까지 정리</title>
      <link>https://simpling.tistory.com/74</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DQN (Deep Q Learning [1])&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DQN은 sensory input (image 등)으로부터 정책을 곧바로 배우는 첫 번째 심층강화학습 모델이다. 그만큼 강화학습 분야에서 근본이 되는 논문이다. 여러 방법을 사용해서 기존에 있던 문제들을 해결하여 좋은 성능을 낸 논문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DQN이 해결한 3가지 문제.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Sensory input을 RL agent에 적용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 차원의 저주 때문에 이미지나 시그널 등의 데이터를 RL에 사용하기 어려웠다. 하지만 DQN이 나오기 전 AlexNet과 같은 잘 작동하는 CNN이 등장한 때라 이 문제를 해결할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) Experience replay를 활용해 샘플 간 시간적 연관성을 줄임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MDP는 순차적으로 진행이 되고, 최근의 경험들은 서로 연관성을 가질 수밖에 없는 문제가 있다. 이를 해결하기 위해 batch단위로 업데이트하는 방법을 제시했는데, 이 방법을 experience replay라고 한다. 당연히 여러 경험(데이터)을 가지고 업데이트하는 것이 훨씬 안정적으로 훈련될 수밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Experience replay는 replay buffer (memory, buffer 등으로도 불린다)라고 불리는 큐(queue)에 최근의 경험(s, a, r, s')을 저장하여 사용한다. 큐를 사용하므로 정해진 데이터 양이 쌓인 순간부터 오래된 샘플은 버리게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Experience replay는 배치 단위로 학습할 수 있다는 강력한 장점이 있지만 off-policy 기법에만 적용 가능하다는 한계가 잇다. 그러므로 REINFORCE 알고리즘을 사용한 정책 업데이트나 SARSA 같은 on-policy 방법에는 적용이 불가능하다. Target이 되는 $r+\gamma Q(s', a')$과 학습하는 $Q(s, a)$가 있을 때, off policy는 target에 사용되는 정책(Q)이 독립이라 미리 저장해 둔 s, a, r, s'을 사용가능한 반면, on policy는 target을 만들 때 정책과 학습할 때 정책이 같아서 정책을 업데이트하면 바뀌어 버려 사용이 불가능하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) Target network 도입으로 moving target 문제 해결.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수를 근사하여 사용하지 않는 Q-learning은 특정한 Q(s, a) 업데이트가 다른 Q(s, a)에 영향을 미치지 않지만, Neual network를 사용하는 방법과 같은 함수 근사 방법은 업데이트를 하면 파라미터가 바뀌어 버려 다른 Q(s, a)에도 영향을 줄 수밖에 없게 된다. 이렇게 되면 학습하는 함수 자체를 target으로 사용하는 강화학습 특성상 target이 움직여버리는 이슈가 생긴다. 이를 해결하기 위해 DQN에서는 'target network'라는 아이디어를 제시한다. 원래 네트워크를 복사해서 일정 업데이트 동안 그대로 유지하여 타깃으로 사용하는 것이다(당연히 일정 업데이트 이후에는 다시 원래 네트워크를 복사해서 사용). 매우 간단한 아이디어인데 잘 되는 방법인 듯하다. 하지만 이 또한 일정 업데이트 이후 타깃 네트워크가 바뀌어 버리므로 학습이 불안정할 가능성이 있는 방법이긴 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Double DQN ([3])&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Double DQN은 maximization bias를 완화하기 위해 나온 논문이다. Neural network를 쓰기 전에 나온 Double Q-learning의 아이디어를 가져왔다.&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;773&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bx2ab3/btsBq1vSLm1/wUyrKBsu0t78ie7xopGPPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bx2ab3/btsBq1vSLm1/wUyrKBsu0t78ie7xopGPPk/img.png&quot; data-alt=&quot;Fig 1. Double Q-learning 알고리즘 ([2])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bx2ab3/btsBq1vSLm1/wUyrKBsu0t78ie7xopGPPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbx2ab3%2FbtsBq1vSLm1%2FwUyrKBsu0t78ie7xopGPPk%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;500&quot; height=&quot;260&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Double Q-learning 알고리즘 ([2])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Maximization bias 문제는 Q-learning 자체의 overestimation bias와 function approximation 오류로 인해 생긴다고 한다. 이를 해결하기 위해 타깃과 업데이트를 하는 함수를 따로 사용하는 방법이다. (Double DQN에서는 target network를 origin network에서 일정 주기마다 복사하여 사용한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 알고리즘을 보면 $Q^{A}$를 업데이트 할 때, a*는 여전히 $Q^{A}$에서 가져오지만 그에 대한 평가는 $Q^{B}$를 사용하여 타깃을 구한다. (이는 DQN에서 봤던 target network를 사용하는 것과 비슷해 보이는데 사실 다르다. target network는 a*와 평가를 모두 $Q^{B}$가 하는 형태이다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBz2gl/btsBHsZTeWS/AX7H2s71qWhIHKR6JcIxcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBz2gl/btsBHsZTeWS/AX7H2s71qWhIHKR6JcIxcK/img.png&quot; data-alt=&quot;Fig 2. DDQN result ([3])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBz2gl/btsBHsZTeWS/AX7H2s71qWhIHKR6JcIxcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBz2gl%2FbtsBHsZTeWS%2FAX7H2s71qWhIHKR6JcIxcK%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;1263&quot; height=&quot;596&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. DDQN result ([3])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig2를 보면 일반적인 Q-learning은 overestimation을 하고, Double Q-learning은 훨씬 덜한 것을 볼 수 있다. 이런 간단한 알고리즘이 문제를 많이 완화하여 주는 것으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Prioritized Replay&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Replay buffer에서 experience를 샘플링할 때 가중치를 주는 아이디어이다. 가중치는 벨만 에러가 높으면 크게 주고, 낮으면 작게 주는 방식이다. $$ Bellman error = r_{i}+\gamma max_{a'} Q_{\theta} (s'_{i}, a') - Q_{\theta} (s_{i}, a_{i}) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Dueling Network&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nbLZE/btsBxXAH0x9/jSzbDNQmwipuciRU2vWwpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nbLZE/btsBxXAH0x9/jSzbDNQmwipuciRU2vWwpk/img.png&quot; data-alt=&quot;Fig 3. dueling network architecture ([4])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nbLZE/btsBxXAH0x9/jSzbDNQmwipuciRU2vWwpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnbLZE%2FbtsBxXAH0x9%2FjSzbDNQmwipuciRU2vWwpk%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;484&quot; height=&quot;462&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. dueling network architecture ([4])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dueling network는 fig 3의 위의 그림처럼 한 번에 $Q(s, a)$를 구했던 것을, 아래처럼 $V(s)+A(s, a)$로 나누어서 구하기 위해 구조를 만든 방법이다. $Q(s, a)$를 학습했을 때는 특정 state에서 하나의 action에 대해 Q-value를 얻으면 그 값에 대해서만 업데이트가 되고 다른 action에 대해서는 업데이트가 되지 않았다(NN이기 때문에 실제로는 영향을 미치긴 함). 하지만 V(s)를 학습하게 되며 동일한 state의 다른 action에 대해서도 간접적으로 학습을 할 수 있게 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brPjkA/btsBylaewp3/VYXMiNUyAjoZtx9682mgY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brPjkA/btsBylaewp3/VYXMiNUyAjoZtx9682mgY0/img.png&quot; data-alt=&quot;Fig 4. dueling network result ([4])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brPjkA/btsBylaewp3/VYXMiNUyAjoZtx9682mgY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrPjkA%2FbtsBylaewp3%2FVYXMiNUyAjoZtx9682mgY0%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;287&quot; height=&quot;396&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. dueling network result ([4])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 fig 4의 위 그림같이 행동이 환경에 영향을 주지 않는(장애물이 없어 행동이 영향이 없음) 경우 state를 학습하는데 유용하다. Fig 4 아래 그림은 장애물이 있어 Advantage 함수가 활성화됨을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 $ Q(s,a;\theta, \alpha, \beta)$를 $V(s; \theta, \alpha) + A(s, a; &amp;nbsp;\theta, \beta)$ 로 유일하게 분해할 수 없는 문제가 있다. 이를 위해 기준점을 정해놓아야 한다. 이를 위해 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;$ Q(s,a;\theta, \alpha, \beta) $ = $ V(s; \theta, \alpha)$ + $A(s,a; \theta, \beta) - max_{a'} A(s,a;\theta, \beta)$로 변형하면, a*=$argmax_{a' \in \mathit{A}} Q(s,a')$일 때 $Q(s,a^{*};\theta, \alpha, \beta)=V(s;\theta,\beta)$ 이므로, a*에 대해 $A(s,a; \theta, \beta) - max_{a'} A(s,a;\theta, \beta)$가 0이 되어 고정할 수 있게 된다(유일하게 분해가능!). 논문에서는 max를 사용하진 않고 mean을 사용하는데(Advantage net의 output들에 대한 평균), 이는 이론적으로 덜 타당해 보이지만 max 보다 훈련을 원활하게 하기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Deep Deterministic Policy Gradient (DDPG([5]))&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DDPG는 연속적 행동 공간에 대한 정책을 최적화하는데, 이를 위해 DQN과 Deterministic PG를 합친 방법이다. DQN 같은 Q-learning은 연속적 행동 공간을 학습시키기 어렵다. 이를 위해서 행동을 이산화 하여 행동을 엄청 쪼개던가(상태 가치 함수의 경우) input으로 행동을 받던가 해야 하는데(행동 가치 함수의 경우), 전자의 경우는 이산화를 많이 해도 (연속 공간이므로) 최적 정책을 찾을 수 없고 비효율 적이다. 후자는 Q-learning target 계산에 필요한 $max_{a'} Q_{\theta} (s', a')$를 찾는 것이 매우 힘들다. $Q_{\theta}(s', a')$이 보통 a'에 대해 볼록 함수가 아니기 때문이다(non-convex). 그러므로 연속적 정책 함수 $\pi(a|s)$를 사용하여 Q를 학습하는 방법인 Actor-critic을 사용하게 된다. 다만 여기서 정책 함수는 deterministic 하다는 특징을 갖는다. 그 이유는 deterministic 한 정책 함수는 Q(s, a)의 기댓값 계산 시 정책이 영향을 끼치지 않아서 Q(critic)를 학습할 때 off-policy 학습이 가능하기 때문이다(replay buffer 사용 가능!). 또한 cost 함수 계산 시에도 정책에 대한 expectation이 필요 없어져서 추산치에 대한 variance가 줄어들기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;off-policy로 학습하게 되었으니 행동 정책을 선택해야 한다. 여기서는 Ornstein-Uhlenbeck 과정을 이용한다. 이는 시간적으로 서로 연관된 확률 변수를 생성하고, langevin equation 형태는 다음과 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \frac {dx_{t}} {dt} = -\theta x_{t} + \sigma \eta(t) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$\eta (t)$: white noise 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 시간적으로 연관된 확률 변수를 이용하므로 episode별로 따로 이용해야 한다. Ornstein-Uhlenbeck 과정을 코드로 표현하면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1702084378843&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class OrnsteinUhlenbeckProcess:
    def __init__(self, mu):
        self.theta, self.dt, self.sigma = 0.1, 0.01, 0.1
        self.mu = mu
        self.x_prev = np.zeros_like(self.mu)

    def __call__(self):
        x = self.x_prev + self.theta * (self.mu - self.x_prev) * self.dt + self.sigma * np.sqrt(self.dt) * np.random.normal(size=self.mu.shape)
        self.x_prev = x
        return x&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 논문에서는 soft-target update를 사용하는데, 기존 DQN에서 moving target issue를 해결하기 위해 도입한 target network를 한 번에 업데이트하는 것이 아니라 조금씩 업데이트해 나가는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Ref&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://arxiv.org/abs/1312.5602&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1312.5602&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1701473618799&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Playing Atari with Deep Reinforcement Learning&quot; data-og-description=&quot;We present the first deep learning model to successfully learn control policies directly from high-dimensional sensory input using reinforcement learning. The model is a convolutional neural network, trained with a variant of Q-learning, whose input is raw&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1312.5602&quot; data-og-url=&quot;https://arxiv.org/abs/1312.5602v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mPmZ5/hyUE5Z0C9k/VhiK2wpe4FatuagYeTsn21/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/E551b/hyUE1i0iqf/lrnh4758qxajNmq9HRKtr0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1312.5602&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1312.5602&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mPmZ5/hyUE5Z0C9k/VhiK2wpe4FatuagYeTsn21/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/E551b/hyUE1i0iqf/lrnh4758qxajNmq9HRKtr0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Playing Atari with Deep Reinforcement Learning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We present the first deep learning model to successfully learn control policies directly from high-dimensional sensory input using reinforcement learning. The model is a convolutional neural network, trained with a variant of Q-learning, whose input is raw&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] &lt;a href=&quot;https://proceedings.neurips.cc/paper_files/paper/2010/file/091d584fced301b442654dd8c23b3fc9-Paper.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://proceedings.neurips.cc/paper_files/paper/2010/file/091d584fced301b442654dd8c23b3fc9-Paper.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3] &lt;a href=&quot;https://arxiv.org/abs/1509.06461&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1509.06461&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1701787001516&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Deep Reinforcement Learning with Double Q-learning&quot; data-og-description=&quot;The popular Q-learning algorithm is known to overestimate action values under certain conditions. It was not previously known whether, in practice, such overestimations are common, whether they harm performance, and whether they can generally be prevented.&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1509.06461&quot; data-og-url=&quot;https://arxiv.org/abs/1509.06461v3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bLHhYe/hyUE0rtbnq/E9N82nAgAIoKa9vejmgXAk/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/lVIUR/hyUIw3muV3/X4GRoJWoCgpDOthjMpr39K/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1509.06461&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1509.06461&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bLHhYe/hyUE0rtbnq/E9N82nAgAIoKa9vejmgXAk/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/lVIUR/hyUIw3muV3/X4GRoJWoCgpDOthjMpr39K/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Deep Reinforcement Learning with Double Q-learning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The popular Q-learning algorithm is known to overestimate action values under certain conditions. It was not previously known whether, in practice, such overestimations are common, whether they harm performance, and whether they can generally be prevented.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] &lt;a href=&quot;https://arxiv.org/abs/1511.06581&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1511.06581&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1701986526526&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Dueling Network Architectures for Deep Reinforcement Learning&quot; data-og-description=&quot;In recent years there have been many successes of using deep representations in reinforcement learning. Still, many of these applications use conventional architectures, such as convolutional networks, LSTMs, or auto-encoders. In this paper, we present a n&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1511.06581&quot; data-og-url=&quot;https://arxiv.org/abs/1511.06581v3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sb4tW/hyUIEgHCDo/zGm0gMtdmV6IJgKBbxQXW1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/wq0Nn/hyUIFfAmhY/w3xnKu6oA7VUajZvwoP79K/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1511.06581&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1511.06581&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sb4tW/hyUIEgHCDo/zGm0gMtdmV6IJgKBbxQXW1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/wq0Nn/hyUIFfAmhY/w3xnKu6oA7VUajZvwoP79K/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Dueling Network Architectures for Deep Reinforcement Learning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In recent years there have been many successes of using deep representations in reinforcement learning. Still, many of these applications use conventional architectures, such as convolutional networks, LSTMs, or auto-encoders. In this paper, we present a n&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[5] &lt;a href=&quot;https://arxiv.org/abs/1509.02971&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/1509.02971&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702082709563&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Continuous control with deep reinforcement learning&quot; data-og-description=&quot;We adapt the ideas underlying the success of Deep Q-Learning to the continuous action domain. We present an actor-critic, model-free algorithm based on the deterministic policy gradient that can operate over continuous action spaces. Using the same learnin&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1509.02971&quot; data-og-url=&quot;https://arxiv.org/abs/1509.02971v6&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cMEJ40/hyUIrotrM6/9R7KKKN3jybCrl8Nyy5pgK/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/gLQY6/hyUICXOFH4/BkYcXTNRVB1csEG2SE4NWk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1509.02971&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1509.02971&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cMEJ40/hyUIrotrM6/9R7KKKN3jybCrl8Nyy5pgK/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/gLQY6/hyUICXOFH4/BkYcXTNRVB1csEG2SE4NWk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Continuous control with deep reinforcement learning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We adapt the ideas underlying the success of Deep Q-Learning to the continuous action domain. We present an actor-critic, model-free algorithm based on the deterministic policy gradient that can operate over continuous action spaces. Using the same learnin&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/강화학습</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/74</guid>
      <comments>https://simpling.tistory.com/74#entry74comment</comments>
      <pubDate>Sat, 2 Dec 2023 11:39:44 +0900</pubDate>
    </item>
    <item>
      <title>RL 기초 개념 정리</title>
      <link>https://simpling.tistory.com/72</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;RL을 공부하다 나오는 개념들을 따로 공부하다 보면 궁금한 것들이 생기고 앞의 내용들을 다시 살펴보곤 하는데, 그러면서 찾아본 내용과 알게 된 내용들을 흐름에 맞게 간단히 정리해 보았다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;환경(에 대한 정보)을 아는가 모르는가.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Model based 방법: 환경에 대한 정보를 알고 있는 경우 (예를 들면 오목 게임 같은 경우 내가 어떤 수를 두었을 때 미래에 펼쳐질 경우의 수들을 계산 가능한 것과 같은 경우) 사용하는 방법이나 현실에서는 거의 없으므로 이 방법은 사용하기 어려움. (근사하는 방법도 있으나 부정확할 경우 오류가 커질 수 있음.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Model free 방법: 환경에 대한 정보를 모르는 경우 사용되며, 현실에 적용하기 적합하다. 그러므로 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;대부분의 알려진 방법들이 이에 해당한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Model free를 위한 2가지 방법: Monte-Carlo, Temporal difference&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Monte-Carlo (MC): MC 방법은 RL뿐 아니라 많은 통계학 분야에서 사용되는 방법으로, 무작위 샘플을 통해 통계적 근사를 얻는 방법이다. RL에서는 에피소드를 끝날 때마다 얻어진 return(reward의 합)에 근접하도록 학습된다. $ V(S_{t}) \leftarrow V(S_{t}) + \alpha (G_{t} - V(S_{t}))$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Temporal Difference (TD): 일반적으로 많이 사용되는 방법으로 말 그대로 일시적 차이를 이용해 학습한다. $ V(S_{t}) \leftarrow V(S_{t}) + \alpha (R_{t+1} + \gamma V(S_{t+1}) - V(S_{t})) $ 와 같이 나타내며(마르코프를 가정하므로 가능함) Monte-Carlo(MC) 방법과 다르게 에피소드 중간중간 업데이트 할 수 있다는 장점이 있다. 또한 MC는 에피소드가 끝나고 받게 되는 보상을 이용해서 업데이트하는 반면, TD는 실제 보상($R_{t+1}$)과 다음 step에 대한 미래 추정 가치($V(S_{t+1})$)를 이용해서 학습하게 된다는 차이가 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Q learning 그리고 SARSA (Off policy, On policy)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q learning과 SARSA는 비슷해 보여 헷갈리기 쉬운 개념이지만 중요한 차이가 있으므로 간단하게 짚고 넘어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q learning: $Q(s, a)$가 $r+\gamma max_{a'} Q(s', a') - Q(s, a)$에 가까워지도록 업데이트하는 방법.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SARSA: $Q(s, a)$가 $r+\gamma Q(s', a') - Q(s, a)$에 가까워지도록 업데이트하는 방법.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 방법 모두 행동 a를 Q(s, a)를 활용해서 결정(행동 정책 $\mu$를 활용해서($\epsilon$ greedy 과 같은)) 하고 행동 a를 환경에 가한 후 차이가 생긴다. Q learning의 경우엔 Q(s, a)를 평가할 때, 모든 행동 a'에서 Q(s', a')이 maximize 되는 것을 직접 찾는 off-policy(행동 정책($\mu$)과 평가 정책($\pi$)이 다른 방법)이다. 반면 SARSA는 a'이 s'에서 행동 정책($\mu$)을 활용해 미리 결정되어 사용되는 on-policy(행동 정책과 평가 정책이 같은 방법)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(뒤에서 과거 메모리(replay buffer)를 사용해서 훈련을 하는 방법이 나오는데, 이는 off-policy에만 적용이 가능하다. 왜냐하면 매 episode(혹은 step)마다 정책이 업데이트가 되는데, on-policy의 경우 이 정책을 이용해서 행동을 결정하게 되기 때문에 과거(업데이트 전) 행동 정책에 의해 결정된 (s, a, r, s')를 다시 사용할 수 없게 된다. 반면 off-policy는 행동 정책이 따로 분리되어 있어서 과거에 저장해둔 (s, a, r, s')를 사용해도 무방하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Policy Gradient&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가치 기반 강화학습과 다르게 데이터로부터 정책을 만드는 방법을 정책 기반 강화학습이라 한다. 행동 가치 함수 $Q^{\pi}(s, a)$로부터 정책을 만드는 기존의 방법과 다르게 직접 정책 함수를 이용하는 것이라 gradient 방법을 사용할 수 있게 된다. 정책 함수 $\pi_{\theta}(a|s)$의 좋고 나쁨을 판단하는 기준 $J(\theta)$를 만들고 기준에 대한 정책 함수의 gradient를 계산하여 경사 상승법(정책을 좋은 방향으로 만들기 위해)을 활용해 정책을 최적화해 나가는 것이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 함수 $J(\theta) = V^{\pi_{\theta}}(s_{0})$로 정의 가능하다. $s_{0}$: 고정된 시작 상태, $V^{\pi_{\theta}}(s_{0})$는 $s_{0}$의 상태에 대한 가치함숫값이다. $$\mathbf {\triangledown}_{\theta} J(\theta)&amp;nbsp; \propto \mathbb {E}_{\pi}[\mathbf {\triangledown}_{\theta} ln \pi_{\theta} (a|s) Q^{\pi}(s, a)]$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적 함수에 대한 gradient를 구하는 과정은 길지만 모두 생략하고 간략히 표현하면 위와 같다. gradient를 이용한 방법은 방향이 중요하므로 위와 같이 비례를 이용한 방법이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;REINFORCE 알고리즘&lt;/u&gt;은 위와 같은 정책 경사에서 MC 방법을 도입한 것이다. $Q^{\pi}(s, a)$를 구하기 위해 MC 방법을 사용해서 $G_{t}$로 대신 추산하여 사용하는 것이다. ($Q^{\pi}(s, a) \overset {\underset {\mathrm {def}}{}}{=}&amp;nbsp; \mathbb {E}_{\pi} [G_{t}|S_{t}=s, A_{t}=a]$)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\mathbf {\triangledown}_{\theta} J(\theta)&amp;nbsp; \propto \mathbb {E}_{\pi}[\mathbf {\triangledown}_{\theta} ln \pi_{\theta} (a|s) G_{t} ]$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 수식을 파이썬으로 구현해 보면 아래와 같은 형태가 될 수 있다.(업데이트 부분만 첨부)&lt;/p&gt;
&lt;pre id=&quot;code_1700982790204&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def update(self, states, actions, rewards):
    g = 0
    for s, a, r in zip(states, actions, rewards):
        g = r + self.gamma * g
        dist = Categorical(logits=self.policy(s))
        prob = dist.probs[a]

        # add 'self_eps' to prevent numerical problems of logarithms
        pg_loss = - torch.log(prob + self._eps) * g

        self.opt.zero_grad()

        pg_loss.backward()
        self.opt.step()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Baseline 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 REINFORCE 알고리즘은 MC 방법이기 때문에 다른 MC 방법들처럼 편향이 작지만 분산이 크다는 단점이 있다. 이를 위해 'Baseline' b(s)를 사용하는데 아래와 같이 행동 가치함수에서 Baseline을 빼서 분산을 낮추는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\mathbf {\triangledown}_{\theta} J(\theta)&amp;nbsp; \propto \mathbb {E}_{\pi}[\mathbf {\triangledown}_{\theta} ln \pi_{\theta} (a|s) Q^{\pi}(s, a) - b(s)]$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(위의 식이 성립함과 분산을 낮춰준다는 증명은 &lt;a href=&quot;https://hcnoh.github.io/2022-07-13-reinforcement-learning-03&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;에 나와있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Baseline은 행동 a에 대해 독립적인 함수라면 뭐든지 가능하다. 하지만 어떻게 적당한 값을 찾을지는 문제이다. 간단한 트릭은 리턴 $G_{t}$를 표준화시켜 버리는 것이다. $G_{t}^{*} = \frac {G_{t}-\bar {G}}{\sigma(G)}$. 이런 트릭은 실제로 엄청 잘되는 방법으로 [1]에서 보여주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Actor-Critic&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Q Actor-Critic&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Actor-Critic은 $\triangledown_{\theta} J(\theta)$를 업데이트할 때 MC 방법으로 $Q^{\pi}(s, a)$ 대신 $G_{t}$를 썼던 것과 다르게, MC, TD 등으로 $Q^{\pi}(s,a) $를 학습한다는 아이디어를 사용한 방법이다. Actor는 $\pi_{\theta} (a|s)$로 나타내고 Critic은 $Q_{\phi}^{\pi}(s, a)$로 표현된다. Actor는 위의 policy gradient에서 $G_{t}$ 부분을 $Q^{\pi}_{\phi}$ 로 바꾼 $\mathbf {\triangledown}_{\theta} J(\theta)&amp;nbsp; \propto \mathbb {E}_{\pi}[\mathbf{\triangledown}_{\theta} ln \pi_{\theta} (a|s) Q^{\pi}_{\phi} ]$의 형태로 업데이트 할 수 있고, Critic은(SARSA style) $\triangledown_{\phi}(r+\gamma Q_{\phi}(s', a') - Q_{\phi}(s,a))^{2}$의 형태로 업데이트 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Advantage Actor-Critic&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;'Advantage'라는 개념이 있다. Advantage function은 $A^{\pi}(s, a) = Q^{\pi}(s, a) - V^{\pi}(s)$로 정의된다. 이는 REINFORCE에서 봤던 'Baseline (b(s))'과 관계가 있다. b(s)는 행동 a에 독립적인 함수라면 가능하며 분산을 낮춰준다는 장점이 있었다. $V^{\pi}$가 조건을 만족하고 Advantage 함수를 해석해 보면 '상황 s에서 행동 a가 얼마나 다른 행동에 비해 좋은가'를 보여주므로 의미도 있어 Baseline으로 사용되기 괜찮아 보인다. 하지만 문제가 있다. $Q^{\pi}(s, a)$와 $V^{\pi}(s)$를 모르므로 둘 다 학습해야 한다는 것이다. 최종적으로 Actor까지 합해서 $ Q^{\pi}_{\phi}(s, a), V^{\pi}_{\psi}(s), \pi_{\theta}(a|s)$ 3개의 모델을 학습하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \mathbf {\triangledown}_{\theta} J(\theta)&amp;nbsp; \propto \mathbb {E}_{\pi}[\mathbf {\triangledown}_{\theta} ln \pi_{\theta} (a|s) A^{\pi}_{\phi, \psi}(s, a)] $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TD Actor-Critic&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;True 행동 가치 함수 $Q^{\pi}(s, a) \overset {\underset {\mathrm {def}}{}}{=}&amp;nbsp; \mathbb{E}_{\pi} [r+\gamma V^{\pi}(s')|S_{t}=s, A_{t}=a]$이고 (True) TD error $\delta^{\pi} &amp;nbsp;\overset {\underset {\mathrm {def}}{}}{=} r+V^{\pi}(s') - V^{\pi}(s)$로 나타낼 수 있다. 그러므로 $ \mathbb {E}_{\pi}[\delta^{\pi}|s, a] =&amp;nbsp; \mathbb {E}_{\pi}[ r+V^{\pi}(s') | s, a] - V^{\pi}(s)$ = $Q^{\pi}(s, a) - V^{\pi}(s) = A^{\pi}(s, a)$로 유도된다. 즉, (True) TD error는 Advantage function의 불편추정량이다. 현실적으로 True TD error는 알기 어려우니 TD error의 추산을 사용해야 한다. 이런 방법을 이용하면 Advantage Actor-Critic과 달리 행동 가치 함수 $Q_{\phi}^{\pi}(s, a)$를 따로 학습할 필요가 없어진다. $V^{\pi}_{\psi}(s)$과 $\pi_{\theta}(a|s)$만 학습하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \mathbf {\triangledown}_{\theta} J(\theta)&amp;nbsp; \propto \mathbb {E}_{\pi}[\mathbf {\triangledown}_{\theta} ln \pi_{\theta} (a|s) \delta^{\pi}_{\psi}(s, a)] $$&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;Ref.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://arxiv.org/abs/2005.12729&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/2005.12729&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1700983413052&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Implementation Matters in Deep Policy Gradients: A Case Study on PPO and TRPO&quot; data-og-description=&quot;We study the roots of algorithmic progress in deep policy gradient algorithms through a case study on two popular algorithms: Proximal Policy Optimization (PPO) and Trust Region Policy Optimization (TRPO). Specifically, we investigate the consequences of &amp;quot;&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2005.12729&quot; data-og-url=&quot;https://arxiv.org/abs/2005.12729v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zMg5r/hyUE8AYz19/R5zifJTSId4eVOAxUkrzI1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/QVYO4/hyUB83HGOw/x6kR5RC7W3NerxQ7fuZGMk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2005.12729&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2005.12729&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zMg5r/hyUE8AYz19/R5zifJTSId4eVOAxUkrzI1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/QVYO4/hyUB83HGOw/x6kR5RC7W3NerxQ7fuZGMk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Implementation Matters in Deep Policy Gradients: A Case Study on PPO and TRPO&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We study the roots of algorithmic progress in deep policy gradient algorithms through a case study on two popular algorithms: Proximal Policy Optimization (PPO) and Trust Region Policy Optimization (TRPO). Specifically, we investigate the consequences of &quot;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/강화학습</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/72</guid>
      <comments>https://simpling.tistory.com/72#entry72comment</comments>
      <pubDate>Fri, 24 Nov 2023 19:43:17 +0900</pubDate>
    </item>
    <item>
      <title>한국투자증권 OpenAPI 사용하기(1) - mojito</title>
      <link>https://simpling.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자동 매매 프로그램을 만들기 위해 다양한 증권사의 API를 사용한 적이 있습니다. 키움, 대신, 이베스트 등을 사용했었는데, 사용하기 쉬운 느낌은 아니었습니다. 사용해 본 적도 없는 PyQT나 이벤트 처리 등을 하는 게 낯설어 처음엔 좀 헤매기도 했습니다. 그런데 드디어 &lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;한국투자증권이 Rest API 기반의 오픈 API 서비스를 제공하기 시작했습니다. 이를 모히토(mojito) ([1])라는 라이브러리로 사용하기 쉽게 만들어 주신 고마운 분도 계십니다. 이 라이브러리를 사용하면 파이썬 기초만 아시는 분들도 자동 매매 프로그램을 만들 수 있을 정도로 좋아 보여 이를 활용해서 퀀트 투자를 할 수 있는 방법에 대해 알아보겠습니다.&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;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;당연히 한투증권의 api를 사용하기 위해서는 계좌 개설 및 open api를 사용하기 위한 key와 secret key를 알아야 합니다. 이에 대한 방법은 [1]에 이미 잘 나와 있어 생략하고 삼성전자를 매수하는 방법을 알아보겠습니다.&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;&lt;span style=&quot;color: #24292f;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;우선 필요한 라이브러리들을 불러오고 미리 저장해둔 key, secret, 계좌번호를 모두 불러옵니다. 한투 api와 연결하기 위해 mojito를 사용해 broker 인스턴스를 생성해 줍니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1699075834043&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import mojito
import yaml

print(mojito.__version__)

with open(&quot;data/koreainvestment.yaml&quot;) as f:
    info_data = yaml.load(f, Loader=yaml.FullLoader)

key = info_data['key']
secret = info_data['secret']
acc_no = info_data['acc_no']

broker = mojito.KoreaInvestment(
    api_key=key,
    api_secret=secret,
    acc_no=acc_no
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #24292f;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이후 현재 계좌에 대한 정보를 불러오겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1699076636912&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE 잔고 조회
balance_info = broker.fetch_balance()

for comp in balance_info['output1']:
    print(comp['pdno'])  # 종목코드
    print(comp['prdt_name'])  # 종목명
    print(comp['hldg_qty'])  # 보유수량
    print(comp['ord_psbl_qty'])  # 주문 가능 수량
    print(comp['pchs_amt'])  # 매입금액
    print(comp['evlu_amt'])  # 평가금액
    print(&quot;-&quot; * 40)

# 총 평가금액
tot_evlu_amt = balance_info['output2']['tot_evlu_amt']
# 예수금
dnca_tot_amt = balance_info['output2']['dnca_tot_amt']
# 금일 매수 금액
thdt_buy_amt = balance_info['output2']['thdt_buy_amt']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #24292f;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;위에서 내가 가진 종목에 대한 정보(output1)와 계좌에 대한 정보(output2)를 볼 수 있습니다. output2에서 불러온 예수금에 대한 정보와 현재 삼성전자 가격을 사용해서 매수 주문을 넣어보겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1699076834888&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE 현재가 조회 (장 종료 후에는 종가)
prpr = broker.fetch_price(&quot;005930&quot;)
print(prpr['rt_cd'])  # 0이면 성공 아니면 실패
print(&quot;Open:  &quot;, prpr['output']['stck_oprc'])   # 시가
print(&quot;High : &quot;, prpr['output']['stck_hgpr'])    # 고가
print(&quot;Low  : &quot;, prpr['output']['stck_lwpr'])     # 저가
print(&quot;Close: &quot;, prpr['output']['stck_prpr'])    # 종가


want_buy_price = prpr['output']['stck_prpr'] # 종가를 기준으로 매수
want_buy_quantity = dnca_tot_amt//want_buy_price
# NOTE 지정가 매수
maesu = broker.create_limit_buy_order(
    symbol=&quot;005930&quot;,  # 삼성전자 코드
    price=want_buy_price,  # 지정가 매수시 가격단위를 고려해야 함.
    quantity=want_buy_quantity
)
if maesu['rt_cd'] == '0':
    print(&quot;삼성전자 매수 주문 성공.&quot;)
else:
    print(&quot;삼성전자 매수 주문 실패.&quot;)
    
'''
예시 output, NOTE 영업점커드와 주문번호는 주문 취소시 필요하다!
{'msg1': '주문 전송 완료 되었습니다.',
 'msg_cd': 'APBK0013',
 'output': {'KRX_FWDG_ORD_ORGNO': '91252', # 영업점코드
            'ODNO': '0000026614', # 주문번호
            'ORD_TMD': '090312'}, # 주문시각(시분초HHMMSS)
 'rt_cd': '0'} # rt_cd로 성공체크.
'''&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;삼성전자를 현재가격(종가) 기준으로 예수금의 전부를 사용해서 매수하는 코드를 작성했습니다. api를 사용할 때 주의할 점 중에 하나가 주문 혹은 조회가 실패할 수 있는 경우가 있다는 것입니다. 현재는 실패했을 때 print만 하도록 처리했지만 실제 거래를 할 때는 따로 처리해야 합니다. 성공할 때까지 하던지 아니면 넘기던지 다양한 경우를 생각해 볼 수 있을 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;코드 아래에 maesu 가 리턴받는 예시도 작성해 놨는데, 영업점 코드, 주문 번호는 추후 필요할 수 있으니 여러 종목을 주문하고자 할 때는 반드시 따로 저장해 둬야 합니다. 주문 취소는 아래와 같은 방법을 쓰면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1699077237182&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE 주문 취소
resp = broker.cancel_order(
    org_no=maesu['output']['KRX_FWDG_ORD_ORGNO'],
    order_no=maesu['output']['ODNO'],
    quantity=want_buy_quantity,  # 잔량전부 취소시 원주문 수량과 일치해야함
    total=True   # 잔량전부를 의미
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;주문 취소도 전량을 하는 방법과 그렇지 않은 방법이 있는데 여기서는 전량을 취소하는 방법에 대한 코드입니다. 위에서 매수 주문을 하고 얻은 영업점 코드와 주문 번호를 가지고 취소를 해야 함을 볼 수 있습니다.&amp;nbsp;&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;간단한 예시를 알아봤는데, 모히토 라이브러리를 사용하다 보니 확실히 사용하기 쉽고 편하다는 강력한 장점이 느껴졌습니다. 다만 아쉬운 점은 다른 증권사 api에 비해 가격 데이터를 불러오는 것(실시간+과거 모두)이 훨씬 느리더군요. 하지만 단기 트레이딩을 위한 툴을 만드려고 하는 것이 아니라면 충분해 보이고, 특히 퀀트 투자를 하고자 하는 분들이 사용하기 적합해 보입니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #24292f;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Ref&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #24292f;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;[1] &lt;a href=&quot;https://wikidocs.net/165190&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wikidocs.net/165190&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1699075112495&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;01) 모히토 모듈&quot; data-og-description=&quot;[TOC] ## 모히토 (Mojito) 모듈 2022년 드디어 국내 증권사 최초로 한국투자증권이 Rest API 기반의 오픈API 서비스를 제공하기 시작했습니다. 이제 누구&amp;hellip;&quot; data-og-host=&quot;wikidocs.net&quot; data-og-source-url=&quot;https://wikidocs.net/165190&quot; data-og-url=&quot;https://wikidocs.net/165190&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iwS9b/hyUrEf1Cf7/sSryRjUQlYKVEWhPO3LVsK/img.png?width=100&amp;amp;height=116&amp;amp;face=0_0_100_116,https://scrap.kakaocdn.net/dn/c7Pyj4/hyUrxBbovr/HAaUZ62HyUKp34JE013sX0/img.png?width=600&amp;amp;height=498&amp;amp;face=0_0_600_498&quot;&gt;&lt;a href=&quot;https://wikidocs.net/165190&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wikidocs.net/165190&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iwS9b/hyUrEf1Cf7/sSryRjUQlYKVEWhPO3LVsK/img.png?width=100&amp;amp;height=116&amp;amp;face=0_0_100_116,https://scrap.kakaocdn.net/dn/c7Pyj4/hyUrxBbovr/HAaUZ62HyUKp34JE013sX0/img.png?width=600&amp;amp;height=498&amp;amp;face=0_0_600_498');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;01) 모히토 모듈&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[TOC] ## 모히토 (Mojito) 모듈 2022년 드디어 국내 증권사 최초로 한국투자증권이 Rest API 기반의 오픈API 서비스를 제공하기 시작했습니다. 이제 누구&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wikidocs.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>퀀트투자</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/70</guid>
      <comments>https://simpling.tistory.com/70#entry70comment</comments>
      <pubDate>Sat, 4 Nov 2023 15:04:59 +0900</pubDate>
    </item>
    <item>
      <title>일봉 데이터를 주봉, 월봉으로 변환하기 (with python)</title>
      <link>https://simpling.tistory.com/69</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;FinanceDataReader([1]) 라이브러리를 사용하면 다양한 주식 혹은 index 등에 대한 일봉 데이터를 가져오기 쉽습니다. 하지만 투자를 할 때 주봉, 월봉도 고려하고 싶어 집니다. 이를 위해 python을 사용해 일봉 데이터를 변환하는 방법을 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주가 데이터는 보통 dataframe 으로 나타내고, python에는 이를 처리하기 위한 pandas라는 강력한 툴이 있습니다. 이 pandas에는 resample([2])이라는 강력한 method도 있습니다. 이 method 에는 'rule'이라는 변수를 넣어야 하는데, 데이터를 resample 할 기준에 대한 값으로, 'Y', 'M', 'W', 'D', 'H', 'T'(min) 등이 들어갈 수 있습니다. 예를 들어 'W'로 값을 넣으면 데이터를 주별로 resample 해주는 것입니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 강력한 method로 손쉽게 데이터를 변환할 수 있는데 &lt;u&gt;&lt;b&gt;주의해야 할 점&lt;/b&gt;&lt;/u&gt;이 있습니다. 데이터가 &lt;span style=&quot;background-color: #ffffff; color: #323232; text-align: start;&quot;&gt;datetime-like index를 가지거나 column 중에 하나가 datetime-like이고 method의 변수 'on'에 해당 column의 이름을 넣어줘야 한다는 점입니다. FinanceDataReader로 데이터를 읽어오는 경우는 index가 datetime으로 되어 있으니 그대로 넣어주시면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 코드 예시는 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1698479537555&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
import FinanceDataReader as fdr

def get_week_month_df(df, period='W'):
    wm_df = pd.DataFrame()
    wm_df = pd.concat([wm_df, df[['Open']].resample(period).first()], axis=1)
    wm_df = pd.concat([wm_df, df[['High']].resample(period).max()], axis=1)
    wm_df = pd.concat([wm_df, df[['Low']].resample(period).min()], axis=1)
    wm_df = pd.concat([wm_df, df[['Close']].resample(period).last()], axis=1)
    wm_df = pd.concat([wm_df, df[['Volume']].resample(period).mean()], axis=1)
    return wm_df
    
# KOSPI Index 코스피 지수 데이터 
kospi_df = fdr.DataReader('KS11')
week_kospi_df = get_week_month_df(df, period='W')
month_kospi_df = get_week_month_df(df, period='M')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 FinanceDataReader 를 사용하면 손쉽게 아래와 같이 일봉, 주봉 등의 그래프를 그려볼 수도 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;일봉.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5S4CB/btszjEv7HH3/wK6rAmjyC02nuVBlk0VQG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5S4CB/btszjEv7HH3/wK6rAmjyC02nuVBlk0VQG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5S4CB/btszjEv7HH3/wK6rAmjyC02nuVBlk0VQG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5S4CB%2FbtszjEv7HH3%2FwK6rAmjyC02nuVBlk0VQG0%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;600&quot; height=&quot;210&quot; data-filename=&quot;일봉.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;주봉.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNpTnM/btszi5OhJxv/UwxjJERJ43FHP2YjauEPD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNpTnM/btszi5OhJxv/UwxjJERJ43FHP2YjauEPD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNpTnM/btszi5OhJxv/UwxjJERJ43FHP2YjauEPD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNpTnM%2Fbtszi5OhJxv%2FUwxjJERJ43FHP2YjauEPD0%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;600&quot; height=&quot;210&quot; data-filename=&quot;주봉.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 그래프 작성 코드는 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1698480015523&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
import FinanceDataReader as fdr


df = fdr.DataReader('KS11', '2023-01-01', '2023-10-25')  # 일부

# 차트 설정
config = {'title': 'KOSPI 일봉',
          'width': 600,
          'height': 300,
          'volume': True,
          }

fdr.chart.config(config=config)
fdr.chart.plot(df)


def get_week_month_df(df, period='W'):
    wm_df = pd.DataFrame()
    wm_df = pd.concat([wm_df, df[['Open']].resample(period).first()], axis=1)
    wm_df = pd.concat([wm_df, df[['High']].resample(period).max()], axis=1)
    wm_df = pd.concat([wm_df, df[['Low']].resample(period).min()], axis=1)
    wm_df = pd.concat([wm_df, df[['Close']].resample(period).last()], axis=1)
    wm_df = pd.concat([wm_df, df[['Volume']].resample(period).mean()], axis=1)
    return wm_df


# 차트 설정
config = {'title': 'KOSPI 주봉',
          'width': 600,
          'height': 300,
          'volume': True,
          }

week_df = get_week_month_df(df)
fdr.chart.config(config=config)
fdr.chart.plot(week_df)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Reference&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://github.com/FinanceData/FinanceDataReader&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/FinanceData/FinanceDataReader&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698478921623&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - FinanceData/FinanceDataReader: Financial data reader&quot; data-og-description=&quot;Financial data reader. Contribute to FinanceData/FinanceDataReader development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/FinanceData/FinanceDataReader&quot; data-og-url=&quot;https://github.com/FinanceData/FinanceDataReader&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pd2Ez/hyUkgnjXdg/k7Op1eTT93BGEjsIQCx6u0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/FinanceData/FinanceDataReader&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/FinanceData/FinanceDataReader&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pd2Ez/hyUkgnjXdg/k7Op1eTT93BGEjsIQCx6u0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - FinanceData/FinanceDataReader: Financial data reader&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Financial data reader. Contribute to FinanceData/FinanceDataReader development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] &lt;a href=&quot;https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698479087822&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;pandas.DataFrame.resample &amp;mdash; pandas 2.1.2 documentation&quot; data-og-description=&quot;The timestamp on which to adjust the grouping. The timezone of origin must match the timezone of the index. If string, must be one of the following: Note Only takes effect for Tick-frequencies (i.e. fixed frequencies like days, hours, and minutes, rather t&quot; data-og-host=&quot;pandas.pydata.org&quot; data-og-source-url=&quot;https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html&quot; data-og-url=&quot;https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;pandas.DataFrame.resample &amp;mdash; pandas 2.1.2 documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The timestamp on which to adjust the grouping. The timezone of origin must match the timezone of the index. If string, must be one of the following: Note Only takes effect for Tick-frequencies (i.e. fixed frequencies like days, hours, and minutes, rather t&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pandas.pydata.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>퀀트투자</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/69</guid>
      <comments>https://simpling.tistory.com/69#entry69comment</comments>
      <pubDate>Sat, 28 Oct 2023 17:00:24 +0900</pubDate>
    </item>
    <item>
      <title>대신증권 API로 데이터 가져오기 (분봉, 일봉) with python</title>
      <link>https://simpling.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;퀀트 혹은 백테스팅을 위해서는 과거 주가 데이터는 필수입니다. 이를 수집하기 위한 많은 방법이 있는데, 일봉 데이터를 얻으려면 FinanceDataReader([1])를 사용하여 일봉 데이터를 가져오는 방법이 가장 간단해 보입니다. 하지만 분봉 수준의 데이터는 증권사 api를 사용해야 합니다. 키움, 이베스트, 대신 증권 등에서 모두 이를 지원하는데 대신 증권에서 제공하는 api가 가장 많은 데이터를 가져올 수 있어 이를 이용하여 가져와보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 우선 대신증권 api를 이용하는 만큼 &lt;span style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot;&gt;CYBOS Touch 어플에서 비대면 계좌개설을 해야하고, &lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;정회원 ID&lt;span&gt;&amp;nbsp;&lt;/span&gt;등록도 마쳐야 합니다. (&lt;a href=&quot;https://www.creontrade.com/g.ds?m=2222&amp;amp;p=2015&amp;amp;v=2885&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.creontrade.com/g.ds?m=2222&amp;amp;p=2015&amp;amp;v=2885&lt;/a&gt; 페이지 참조). &lt;/span&gt;&lt;/span&gt;ID 등록을 마치면 범용 공인인증서를 등록하면 끝납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) &lt;a href=&quot;https://www.daishin.com/g.ds?m=1101&amp;amp;p=12294&amp;amp;v=11949&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.daishin.com/g.ds?m=1101&amp;amp;p=12294&amp;amp;v=11949&lt;/a&gt; 에서 CYBOS5를 설치하고 실행하면 아래와 같은 화면이 나옵니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;779&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3QWeF/btszkBlhfrB/lYL49YlP86GJpnwlYJo8Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3QWeF/btszkBlhfrB/lYL49YlP86GJpnwlYJo8Ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3QWeF/btszkBlhfrB/lYL49YlP86GJpnwlYJo8Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3QWeF%2FbtszkBlhfrB%2FlYL49YlP86GJpnwlYJo8Ik%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;502&quot; height=&quot;274&quot; data-origin-width=&quot;779&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[주의!]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 실행 시 CYBOS5(맨 왼쪽) 탭으로 실행되는데 반드시 CYBOS plus 탭으로 변경하여 로그인해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;vscode 혹은 pycharm 등의 IDLE를 사용시에 반드시 '권리자 권한으로 실행'을 하셔야 합니다!&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;위의 사항을 지키지 않으면 'pywintypes.com_error: (-2147221005, '잘못된 클래스 문자열입니다.', None, None)' 에러가 발생합니다.&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;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;원래 이 사항들을 마치면 코딩을 열심히 해서 api를 써야겠지만, 감사하게도 잘 만들어진 툴이 존재해 이를 사용하겠습니다. 먼저 가상환경을 잘 세팅해줘야 하는데, 콘다를 기준으로 세팅하는 방법을 알려드리겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;증권사 api는 64bit가 아닌 32bit에서 작동되어서 32bit 환경을 구성해야 합니다. 따라서 아래와 같은 명령어를 터미널에 써주세요.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1698472952125&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda create -n 32bit_env # 가상환경 생성
conda activate 32bit_env # 가상환경 실행
conda config --env --set subdir win-32 # 32bit 세팅
conda install python=3.8
conda install pandas=1.1
pip install PyQt5
pip install pypiwin32
pip install tqdm&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot;&gt;세팅을 맞친 후 Creon-Datareader &lt;a href=&quot;https://github.com/gyusu/Creon-Datareader&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/gyusu/Creon-Datareader&lt;/a&gt;([2])라는 깃헙 페이지에서 코드를 다운로드하시고 압축을 풀어준 후 'python creon_datareader.py' 명령어를 실행시켜 주시면 됩니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에는 github에 표시된 대로 따라해서 실행하시면 됩니다.&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;Reference&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://github.com/FinanceData/FinanceDataReader&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/FinanceData/FinanceDataReader&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698472097859&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - FinanceData/FinanceDataReader: Financial data reader&quot; data-og-description=&quot;Financial data reader. Contribute to FinanceData/FinanceDataReader development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/FinanceData/FinanceDataReader&quot; data-og-url=&quot;https://github.com/FinanceData/FinanceDataReader&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pd2Ez/hyUkgnjXdg/k7Op1eTT93BGEjsIQCx6u0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/FinanceData/FinanceDataReader&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/FinanceData/FinanceDataReader&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pd2Ez/hyUkgnjXdg/k7Op1eTT93BGEjsIQCx6u0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - FinanceData/FinanceDataReader: Financial data reader&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Financial data reader. Contribute to FinanceData/FinanceDataReader development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] &lt;a href=&quot;https://github.com/gyusu/Creon-Datareader&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/gyusu/Creon-Datareader&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698472193499&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - gyusu/Creon-Datareader: 대신증권(Creon) PLUS API를 이용한 주가 데이터 수집 프로그램&quot; data-og-description=&quot;대신증권(Creon) PLUS API를 이용한 주가 데이터 수집 프로그램. Contribute to gyusu/Creon-Datareader development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/gyusu/Creon-Datareader&quot; data-og-url=&quot;https://github.com/gyusu/Creon-Datareader&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/veWVe/hyUkdRH0eN/GoPktB4hTsC0K6qgLZwRo0/img.png?width=1200&amp;amp;height=600&amp;amp;face=1008_114_1081_194&quot;&gt;&lt;a href=&quot;https://github.com/gyusu/Creon-Datareader&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/gyusu/Creon-Datareader&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/veWVe/hyUkdRH0eN/GoPktB4hTsC0K6qgLZwRo0/img.png?width=1200&amp;amp;height=600&amp;amp;face=1008_114_1081_194');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - gyusu/Creon-Datareader: 대신증권(Creon) PLUS API를 이용한 주가 데이터 수집 프로그램&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;대신증권(Creon) PLUS API를 이용한 주가 데이터 수집 프로그램. Contribute to gyusu/Creon-Datareader development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3] &lt;a href=&quot;https://wikidocs.net/3680&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wikidocs.net/3680&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698472482974&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;2) CYBOS Plus 로그인&quot; data-og-description=&quot;CYBOS Plus에 로그인하려면 통신 ID와 공인인증서를 등록해야 합니다. 대신증권 홈페이지의 [고객센터] &amp;rarr; [신규고객가이드] &amp;rarr; [처음 방문고객안내] 페이지를 참조해서 그림&amp;hellip;&quot; data-og-host=&quot;wikidocs.net&quot; data-og-source-url=&quot;https://wikidocs.net/3680&quot; data-og-url=&quot;https://wikidocs.net/3680&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9LPQp/hyUltUcmyz/KU3NegHxuUu04zI4dRgHH1/img.jpg?width=100&amp;amp;height=123&amp;amp;face=0_0_100_123,https://scrap.kakaocdn.net/dn/bPL6Rf/hyUkbsN0fp/nkcIP4LgJEi9KoPfopIga1/img.png?width=779&amp;amp;height=425&amp;amp;face=0_0_779_425,https://scrap.kakaocdn.net/dn/bJImMP/hyUj99z4x5/CHElkLQOiFcKZ9rGkPoLqK/img.png?width=975&amp;amp;height=290&amp;amp;face=0_0_975_290&quot;&gt;&lt;a href=&quot;https://wikidocs.net/3680&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wikidocs.net/3680&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9LPQp/hyUltUcmyz/KU3NegHxuUu04zI4dRgHH1/img.jpg?width=100&amp;amp;height=123&amp;amp;face=0_0_100_123,https://scrap.kakaocdn.net/dn/bPL6Rf/hyUkbsN0fp/nkcIP4LgJEi9KoPfopIga1/img.png?width=779&amp;amp;height=425&amp;amp;face=0_0_779_425,https://scrap.kakaocdn.net/dn/bJImMP/hyUj99z4x5/CHElkLQOiFcKZ9rGkPoLqK/img.png?width=975&amp;amp;height=290&amp;amp;face=0_0_975_290');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2) CYBOS Plus 로그인&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CYBOS Plus에 로그인하려면 통신 ID와 공인인증서를 등록해야 합니다. 대신증권 홈페이지의 [고객센터] &amp;rarr; [신규고객가이드] &amp;rarr; [처음 방문고객안내] 페이지를 참조해서 그림&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wikidocs.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>퀀트투자</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/68</guid>
      <comments>https://simpling.tistory.com/68#entry68comment</comments>
      <pubDate>Sat, 28 Oct 2023 15:04:06 +0900</pubDate>
    </item>
    <item>
      <title>해석 가능한 신경망 (Interpretable Neural Network)</title>
      <link>https://simpling.tistory.com/67</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! 오늘은 '해석 가능한 신경망'에 대해 알아보는 시간을 가져볼까 합니다. 머신러닝에 관심이 많은 분들이라면 한 번쯤 들어보셨을 이야기인데요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 해석 가능한 신경망이 필요한가요?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머신러닝 모델, 특히 딥러닝 모델은 '블랙박스'라는 별명이 있죠. 이는 모델의 내부 동작 방식이 복잡하고 불투명하기 때문입니다. 하지만 이런 불투명성은 신뢰성 저하를 가져오며, 오류 발생 시 원인 분석을 어렵게 만듭니다. 특히 의료, 금융 등과 같이 중요한 분야에서는 심각한 문제를 일으킬 수 있죠. 그래서 '왜' 그런 결과가 나왔는지 이해하고 설명할 수 있는 '해석 가능한 신경망'이 필요하게 되었습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;해석 가능한 신경망을 어떻게 만드나요?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해석 가능한 신경망을 만드는 방법에는 여러 가지가 있습니다. 대표적으로 feature importance를 이용한 방법이 있는데, Python 코드와 함께 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 피처 중요도(Feature Importance)&lt;/b&gt;: 모델의 예측에 대한 각 피쳐의 기여도를 측정하는 방법입니다. 랜덤 포레스트나 그래디언트 부스팅과 같은 트리 기반 모델의 경우, scikit-learn은 피팅 후 각 피쳐의 중요도를 알려주는 기능을 제공합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1698384510722&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor

# Load data
boston = load_boston()
X = boston[&quot;data&quot;]
Y = boston[&quot;target&quot;]

# Train model
rf = RandomForestRegressor()
rf.fit(X, Y)

# Print feature importance
print(sorted(zip(map(lambda x: round(x, 4), rf.feature_importances_), boston[&quot;feature_names&quot;]), reverse=True))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. LIME (Local Interpretable Model-agnostic Explanations)&lt;/b&gt;: &lt;span style=&quot;color: #000000; letter-spacing: 0px;&quot;&gt;LIME은 예측을 중심으로 국소적으로 해석 가능한 모형을 학습함으로써 모든 분류기의 예측을 해석 가능하고 신뢰 가능한 방식으로 설명합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1698384536458&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import lime
import lime.lime_tabular

# Create Lime explainer
explainer = lime.lime_tabular.LimeTabularExplainer(X, feature_names=boston[&quot;feature_names&quot;], class_names=['price'], verbose=True, mode='regression')

# Explain a prediction
i = 20
exp = explainer.explain_instance(X[i], rf.predict)
exp.show_in_notebook(show_table=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. SHAP (SHapley Additive exPlanations)&lt;/b&gt;: &lt;span style=&quot;color: #000000; letter-spacing: 0px;&quot;&gt;SHAP 값은 해당 피쳐가 일부 기준선 값을 가질 경우 예측한 값과 비교하여 해당 피쳐에 대한 특정 값의 영향을 해석합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1698384561566&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import shap

# Create SHAP explainer
explainer = shap.TreeExplainer(rf)

# Calculate SHAP values
shap_values = explainer.shap_values(X)

# Visualize a prediction's explanation
shap.initjs()
shap.force_plot(explainer.expected_value, shap_values[0,:], X[0])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 다음과 같은 방법도 사용되고 있습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;더 간단한 구조: 해석 가능한 신경망은 일반적으로 해석이 더 직관적인 결정 트리, 규칙 기반 모델, 또는 attention mechanism과 같은 간단한 구조를 사용합니다.&lt;/li&gt;
&lt;li&gt;Attention Mechanism: Transformer와 같은 모델에서의 attention mechanism은 예측을 만드는 데 있어 다양한 입력 요소의 중요성을 시각화하는 데 사용될 수 있습니다.&lt;/li&gt;
&lt;li&gt;규칙 기반 모델: 규칙 기반 모델은 종종 '만약 ~라면, ~한다'는 규칙을 정의하여 모델의 결정에 대한 명확한 설명을 제공하는 데 사용됩니다.&lt;/li&gt;
&lt;li&gt;민감도 분석: 민감도 분석은 입력 데이터를 약간 변형하면서 모델 예측이 어떻게 변하는지 관찰함으로써 모델의 동작에 대한 통찰을 얻는 데 사용됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;앞으로의 연구 방향성.&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Model-agnositc 방법: SHAP와 LIME과 같은 model-agnostic 방법론은 계속해서 발전하며 다양한 모델에 적용되게 될 것입니다.&lt;/li&gt;
&lt;li&gt;하이브리드 모델: 연구자들은 복잡한 딥러닝 모델의 높은 성능과 해석 가능한 신경망의 투명성을 결합하는 작업을 진행 중입니다.&lt;/li&gt;
&lt;li&gt;규제 준수: 모델 해명에 관한 규제가 늘어나면서, 이러한 요구를 충족시키기 위해 해석 가능한 신경망에 대한 연구가 확대될 것입니다.&lt;/li&gt;
&lt;li&gt;인간-AI 협력: 미래의 연구는 해석 가능한 신경망을 더 사용자 친화적으로 만들어 인간과 AI의 협력과 의사결정을 개선하는 데 초점을 맞출 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 해석 가능한 머신러닝에 대한 관심과 연구가 점점 늘어나고 있는 추세입니다. 이는 모델의 해석력과 성능을 높이는 것뿐만 아니라, 데이터의 편향을 탐지하고, 모델의 잠재적인 문제점을 발견하며, 법적 및 윤리적 고려사항을 준수하는 것에 의해 주도되고 있습니다. 많은 규제 기관들이 알고리즘의 투명성과 해석 가능성을 요구하고 있으며, 이러한 요구는 앞으로 더욱 강화될 것으로 예상됩니다. 미래의 연구는 더욱 복잡한 해석 방법을 개발하는 것을 넘어, 본질적으로 해석 가능한 모델을 설계하는 데 초점을 맞출 것입니다. 이는 예측뿐만 아니라 그 예측이 왜 이루어졌는지 설명할 수 있는 머신러닝 모델을 만드는 것을 의미합니다. &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;앞으로의 연구를 통해 해석 가능한 신경망의 성능이 향상되고 다양한 분야에서의 적용성이 확대될 것이라 기대해봅니다.&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <category>interpretable</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/67</guid>
      <comments>https://simpling.tistory.com/67#entry67comment</comments>
      <pubDate>Fri, 27 Oct 2023 14:45:28 +0900</pubDate>
    </item>
    <item>
      <title>데이터를 수식으로 변경! Symbolic Regression 이란?</title>
      <link>https://simpling.tistory.com/66</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI는 많은 데이터와 큰 모델을 사용하며 발전을 이루어왔습니다. 하지만 항상 black-box라는 한계로 신뢰하지 못한다는 치명적 단점을 가지고 있습니다. 최근에는 많은 데이터를 학습한 덕분에 좋은 성능을 내는 Large language model(LLM)이 많이 공개되고 있지만 여전히 엉뚱한 답변을 내놓는 hallucination이 나타나는 경우가 많이 있습니다. 이런 문제를 해결하기 위해 interpretable AI에 대한 연구가 많이 이루어지고 있습니다. 이번 글에서는 그중 한 갈래인 symbolic regression에 대해 소개하려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Symbolic Regression 이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Symbolic regression은 input x, output y에 대한 set이 있을 때 이 x, y의 관계를 설명해 주는 수식을 만들어내는 것을 말합니다.&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;572&quot; data-origin-height=&quot;413&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WT2Am/btszjq4ImM0/GYej5m9CSadRPqMV49RCdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WT2Am/btszjq4ImM0/GYej5m9CSadRPqMV49RCdk/img.png&quot; data-alt=&quot;$y=x^{3}+x-3$&amp;amp;amp;nbsp; &amp;amp;amp;nbsp;함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WT2Am/btszjq4ImM0/GYej5m9CSadRPqMV49RCdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWT2Am%2Fbtszjq4ImM0%2FGYej5m9CSadRPqMV49RCdk%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;338&quot; height=&quot;244&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;413&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;$y=x^{3}+x-3$&amp;amp;nbsp; &amp;amp;nbsp;함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 위와 같은 (x,y) set이 주어질 때 이 함수가 $y=x^{3}+x-3$ 함수라는 것을 밝히는 것이 symbolic regression 인 것입니다! 이러한 강력한 장점 덕분에 심볼릭 회귀는 다양한 분야에서 사용됩니다. 과학과 공학에서는 물리학, 화학, 생물학 등의 복잡한 시스템을 모델링하는 데 사용되며(예를 들어 데이터는 있지만 밝혀지지 않은 수학적 관계를 밝히기 위해 연구함), 금융에서는 시장 동향을 예측하는 데 사용됩니다. 또한, 기계 학습과 데이터 분석에서도 심볼릭 회귀는 복잡한 패턴을 찾는 데 있어 중요한 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;심볼릭 회귀에 대한 주요 포인트&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심볼릭 회귀는 위에서 볼 수 있듯 데이터 중심 방법입니다. 이는 변수들 사이의 기본적인 관계를 가장 잘 설명하는 수학적 방정식을 찾기 위해 데이터를 탐색합니다. 심볼릭 회귀는 Deep Neural Network와 같은 복잡한 기계 학습 모델보다 더 해석 가능한 모델을 생성한다는 점에서 강력한 장점이 있습니다. 이러한 심볼릭 방정식은 변수들 사이의 관계에 대한 통찰력을 제공합니다. 이러한 장점 때문에 간결하고 해석 가능한 모델을 찾는 것이 중요한 물리학, 생물학, 금융, 공학 등 여러 분야에서 응용되고 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고리즘은 유전 프로그래밍이 대표적이며, SymPy와 같은 심볼릭 회귀 소프트웨어 패키지, 그리고 Eureqa와 같은 상업용 도구를 포함한 다양한 알고리즘을 사용하여 수행될 수 있습니다. 최근에는 Neural Network를 사용한 모델이 많이 나오고 있습니다. 대표적으로 Large Transformer 모델을 사용하여 supervised learning 한 모델을 개발하고 있습니다([1]). 또한 하이브리드 모델로 eureqa와 GNN을 함께 사용하여 dark matter를 모델링한 논문([2])도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 심볼릭 회귀는 계산적으로 많은 자원을 요구할 수 있으며, 최적의 심볼릭 표현을 찾기 위한 탐색은 많은 수의 수학적 연산을 필요로 할 수 있습니다. 고차원 또는 잡음이 많은 데이터셋에서는 잘 안 되는 경우가 굉장히 많아 보통 간단한 경우에서 많이 사용되고 있습니다. (이를 해결하기 위해 AI를 적극 사용하고 연구 중이긴 합니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 말했듯, 심볼릭 회귀의 주요 방법론 중 하나는 유전 프로그래밍입니다. 유전 프로그래밍은 랜덤 하게 생성된 함수 세트에서 시작하여, 선택, 교차, 변이 등의 연산을 통해 최적의 함수를 찾는 알고리즘입니다. 강화학습 혹은 Neural Network를 사용한 방법도 꾸준히 나오고는 있지만 여전히 baseline은 유전 프로그래밍 base 방법이 많이 사용되고 있고, 유전 프로그래밍과 AI 기반 방법을 함께 쓰는 hybrid 모델도 많이 나오는 추세입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 간단한 심볼릭 회귀를 구현하는 파이썬 코드 예제입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1698387482362&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from gplearn.genetic import SymbolicRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.utils.random import check_random_state
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
import graphviz

# Ground truth
x0 = np.arange(-1, 1, .1)
x1 = np.arange(-1, 1, .1)
x0, x1 = np.meshgrid(x0, x1)
y_truth = x0**2 - x1**2 + x1 - 1

ax = plt.figure().gca(projection='3d')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.set_xticks(np.arange(-1, 1.01, .5))
ax.set_yticks(np.arange(-1, 1.01, .5))
surf = ax.plot_surface(x0, x1, y_truth, rstride=1, cstride=1, color='green', alpha=0.5)
plt.show()

rng = check_random_state(0)

# Training samples
X_train = rng.uniform(-1, 1, 100).reshape(50, 2)
y_train = X_train[:, 0]**2 - X_train[:, 1]**2 + X_train[:, 1] - 1

# Testing samples
X_test = rng.uniform(-1, 1, 100).reshape(50, 2)
y_test = X_test[:, 0]**2 - X_test[:, 1]**2 + X_test[:, 1] - 1

est_gp = SymbolicRegressor(population_size=5000, generations=20, stopping_criteria=0.01,
                           p_crossover=0.7, p_subtree_mutation=0.1,
                           p_hoist_mutation=0.05, p_point_mutation=0.1,
                           max_samples=0.9, verbose=1,
                           parsimony_coefficient=0.01, random_state=0)
est_gp.fit(X_train, y_train)
print(est_gp._program)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://arxiv.org/abs/2204.10532&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/2204.10532&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698386786370&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;End-to-end symbolic regression with transformers&quot; data-og-description=&quot;Symbolic regression, the task of predicting the mathematical expression of a function from the observation of its values, is a difficult task which usually involves a two-step procedure: predicting the &amp;quot;skeleton&amp;quot; of the expression up to the choice of numer&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2204.10532&quot; data-og-url=&quot;https://arxiv.org/abs/2204.10532v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ckfWmj/hyUkaUFQtv/UmJpc0t8H1lQVnaJkZs4f1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/Qd4L6/hyUj7p7Wr8/lkCb1rOOaLelEtimUpcMYk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2204.10532&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2204.10532&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ckfWmj/hyUkaUFQtv/UmJpc0t8H1lQVnaJkZs4f1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/Qd4L6/hyUj7p7Wr8/lkCb1rOOaLelEtimUpcMYk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;End-to-end symbolic regression with transformers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Symbolic regression, the task of predicting the mathematical expression of a function from the observation of its values, is a difficult task which usually involves a two-step procedure: predicting the &quot;skeleton&quot; of the expression up to the choice of numer&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] &lt;a href=&quot;https://arxiv.org/abs/2006.11287&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/2006.11287&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698387495731&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Discovering Symbolic Models from Deep Learning with Inductive Biases&quot; data-og-description=&quot;We develop a general approach to distill symbolic representations of a learned deep model by introducing strong inductive biases. We focus on Graph Neural Networks (GNNs). The technique works as follows: we first encourage sparse latent representations whe&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2006.11287&quot; data-og-url=&quot;https://arxiv.org/abs/2006.11287v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/3JUeG/hyUlrV6qyx/BoPFrwebMh4Z6vyJA1Pf90/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/ct3ly6/hyUkkXhJae/BJEY3nn4f3Gb5RoOKKO3Nk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2006.11287&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2006.11287&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/3JUeG/hyUlrV6qyx/BoPFrwebMh4Z6vyJA1Pf90/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/ct3ly6/hyUkkXhJae/BJEY3nn4f3Gb5RoOKKO3Nk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Discovering Symbolic Models from Deep Learning with Inductive Biases&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We develop a general approach to distill symbolic representations of a learned deep model by introducing strong inductive biases. We focus on Graph Neural Networks (GNNs). The technique works as follows: we first encourage sparse latent representations whe&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/66</guid>
      <comments>https://simpling.tistory.com/66#entry66comment</comments>
      <pubDate>Tue, 15 Aug 2023 14:57:00 +0900</pubDate>
    </item>
    <item>
      <title>일본 (오사카 + 교토) 3박 4일여행</title>
      <link>https://simpling.tistory.com/65</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;3박 4일의 일본 여행기.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무 계획 없이 친구와 오사카로 떠났다. 첫날은 무작정 간사이 국제공항에 내려 도톤보리로 향했다. 가장 유명하다고 하여 맛집을 기대하며 갔다. 기차를 잘 못 타는 바람에 거의 2시간 정도 걸려 도착했다. 검색해 보니 40분이면 이동하는 거리였다.. 도톤보리에 가니 유명한 풍경들이 보였다. 다른 사람들처럼 글리코상 앞에서 한 컷 찍었다. 알고 보니 글리코 제과 회사 광고라는데 왜 유명해진 거지?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1o3Vi/btsiSQLrP3a/sCMDsnIaBn7WTHN2jrciN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1o3Vi/btsiSQLrP3a/sCMDsnIaBn7WTHN2jrciN1/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; width=&quot;230&quot; height=&quot;307&quot; data-widthpercent=&quot;50&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1o3Vi/btsiSQLrP3a/sCMDsnIaBn7WTHN2jrciN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1o3Vi%2FbtsiSQLrP3a%2FsCMDsnIaBn7WTHN2jrciN1%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNW0MK/btsjlEdFEdX/OyLU6UXIhI5S2hofr5NcRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNW0MK/btsjlEdFEdX/OyLU6UXIhI5S2hofr5NcRk/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNW0MK/btsjlEdFEdX/OyLU6UXIhI5S2hofr5NcRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNW0MK%2FbtsjlEdFEdX%2FOyLU6UXIhI5S2hofr5NcRk%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저녁을 안 먹어서 바로 근처 맛집을 찾아 헤매었는데, 이미 늦은 시간이라 닫은 곳들도 있었다. 핫플이라 그런지 늦은 시간에도 줄 서는 곳도 많았다. 다행히 괜찮아 보이는 라멘집을 찾아 주문하고 들어갔다. 요즘 일본은 카드나 페이를 쓸 수 있다고 해서 환전을 5만 원만 해갔는데 카드가 안 돼서 당황했다. 기차랑 라멘으로 첫날부터 2만 원 가까이 써버렸다. 라멘은 고기가 그릇 주위에 잔뜩 쌓여 나왔는데 계란과 면은 꽤 맛있었지만, 고기는 퍽퍽하여 약간 실망했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blLZab/btsiOj9aviE/3A070tAqUfqlKuTcxtUsPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blLZab/btsiOj9aviE/3A070tAqUfqlKuTcxtUsPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blLZab/btsiOj9aviE/3A070tAqUfqlKuTcxtUsPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblLZab%2FbtsiOj9aviE%2F3A070tAqUfqlKuTcxtUsPk%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;253&quot; height=&quot;337&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밤이 늦어 숙소로 돌아가는데 일본 영화나 만화에서 보았던 감성의 거리가 보였다. 번화가를 조금 벗어나니 아파트는 보이지 않았고 건물들이 낮아 탁 트인 모습이었다. 차들의 앞부분은 레이처럼 납작한 형태가 많이 보였다. 거리는 깨끗했는데 밤이라 살짝 으스스한 모습이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SYNno/btsiJAcKpCE/LoAx6uiFXUxtbMiIGcK6vK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SYNno/btsiJAcKpCE/LoAx6uiFXUxtbMiIGcK6vK/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.2558%; margin-right: 10px;&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SYNno/btsiJAcKpCE/LoAx6uiFXUxtbMiIGcK6vK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSYNno%2FbtsiJAcKpCE%2FLoAx6uiFXUxtbMiIGcK6vK%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qf7Im/btsiRF4nrnA/vZ8JZmy2bkpBNuSHfTPCC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qf7Im/btsiRF4nrnA/vZ8JZmy2bkpBNuSHfTPCC1/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 35.5814%;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qf7Im/btsiRF4nrnA/vZ8JZmy2bkpBNuSHfTPCC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqf7Im%2FbtsiRF4nrnA%2FvZ8JZmy2bkpBNuSHfTPCC1%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SZ2nJ/btsiJ8NWVpZ/pst7H6OznQxsbDGe48Ik6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SZ2nJ/btsiJ8NWVpZ/pst7H6OznQxsbDGe48Ik6k/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 35.5814%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SZ2nJ/btsiJ8NWVpZ/pst7H6OznQxsbDGe48Ik6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSZ2nJ%2FbtsiJ8NWVpZ%2Fpst7H6OznQxsbDGe48Ik6k%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZDaKy/btsiOeAbXKC/oNK908YKHEtF2lARdqPWh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZDaKy/btsiOeAbXKC/oNK908YKHEtF2lARdqPWh1/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.2558%; margin-top: 10px;&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZDaKy/btsiOeAbXKC/oNK908YKHEtF2lARdqPWh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZDaKy%2FbtsiOeAbXKC%2FoNK908YKHEtF2lARdqPWh1%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숙소는 7만 원 치고 깨끗했다. 일본은 돼지코가 필요하다고 해서 가져갔는데 묵었던 모든 숙소에는 usb-a를 사용하여 연결할 수 있는 잭이 침대 옆에 있어 사용하지 않았다. 침대 옆에 모든 조명을 조절할 수 있는 스위치가 있어서 너무 좋았다. 한국도 빨리 도입해야 할 듯..&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;a href=&quot;https://goo.gl/maps/ioui76q2ZE72QQU48&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://goo.gl/maps/ioui76q2ZE72QQU48&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686384305161&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;天ぷらまきの梅田店 &amp;middot; 일본 〒530-0012 Osaka, Kita Ward, Shibata, 1 Chome&amp;minus;1&amp;minus;3 阪急三番街南館 2F&quot; data-og-description=&quot;★★★★☆ &amp;middot; 튀김 전문식당&quot; data-og-host=&quot;www.google.co.kr&quot; data-og-source-url=&quot;https://goo.gl/maps/ioui76q2ZE72QQU48&quot; data-og-url=&quot;https://www.google.co.kr/maps/place/%E5%A4%A9%E3%81%B7%E3%82%89%E3%81%BE%E3%81%8D%E3%81%AE%E6%A2%85%E7%94%B0%E5%BA%97/@34.7029216,135.4949511,17z/data=!3m1!5s0x6000e6918b31faf7:0x4ceb5b05bf8a75a5!4m7!3m6!1s0x6000e792a9a5104f:0xd5cbbe8240b54615!8m2!3d34.704169!4d135.4983578!15sCh_smrDrqZTri6Tsl60g642067-M652866eI7YKk64W4WiMiIeyasOuplOuLpCDsl60g642067-M6528IOuniO2CpOuFuJIBF3RlbXB1cmFfZGlzaF9yZXN0YXVyYW504AEA!16s%2Fg%2F11cs3_dxm7?hl=ko&amp;amp;entry=tts&amp;amp;shorturl=1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lwlmM/hySW8Xka0s/KASgFhj4p6j9XDcfk2aepk/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256&quot;&gt;&lt;a href=&quot;https://goo.gl/maps/ioui76q2ZE72QQU48&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://goo.gl/maps/ioui76q2ZE72QQU48&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lwlmM/hySW8Xka0s/KASgFhj4p6j9XDcfk2aepk/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;天ぷらまきの梅田店 &amp;middot; 일본 〒530-0012 Osaka, Kita Ward, Shibata, 1 Chome&amp;minus;1&amp;minus;3 阪急三番街南館 2F&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;★★★★☆ &amp;middot; 튀김 전문식당&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.google.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이곳은 오마카세처럼 그때그때 튀겨서 설명을 해주는 시스템이어서 따뜻한 튀김을 먹을 수 있었다. 당연히 설명은 전혀 알아듣진 못했다..(영어를 아예 못하셔서 번역기로 간신히 대화했다) 정말 맛있었고 다시 가고 싶을 만한 맛집이었다. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;양이 좀 아쉬워서 다 먹은 후에 일본 편의점에 들러 계란 샌드위치 하나를 먹었다. 친구가 추천해 줘 먹었는데 꽤 맛있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HeZp6/btsiOflBrus/o8AkdHldxdDgFPytsIO0J0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HeZp6/btsiOflBrus/o8AkdHldxdDgFPytsIO0J0/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 35.5814%; margin-right: 10px;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HeZp6/btsiOflBrus/o8AkdHldxdDgFPytsIO0J0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHeZp6%2FbtsiOflBrus%2Fo8AkdHldxdDgFPytsIO0J0%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1GyqY/btsiRERWk33/KGJZ97iGurbz6DhwREDRzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1GyqY/btsiRERWk33/KGJZ97iGurbz6DhwREDRzK/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.2558%;&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1GyqY/btsiRERWk33/KGJZ97iGurbz6DhwREDRzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1GyqY%2FbtsiRERWk33%2FKGJZ97iGurbz6DhwREDRzK%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ejRjw2/btsiPQFkau0/Sj3K5Bu35lKcEdSFO4Rbd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ejRjw2/btsiPQFkau0/Sj3K5Bu35lKcEdSFO4Rbd0/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ejRjw2/btsiPQFkau0/Sj3K5Bu35lKcEdSFO4Rbd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FejRjw2%2FbtsiPQFkau0%2FSj3K5Bu35lKcEdSFO4Rbd0%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z9QIe/btsiQJeSyzM/RnSn0ltN2CxOs8NT96Wy60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z9QIe/btsiQJeSyzM/RnSn0ltN2CxOs8NT96Wy60/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-top: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z9QIe/btsiQJeSyzM/RnSn0ltN2CxOs8NT96Wy60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz9QIe%2FbtsiQJeSyzM%2FRnSn0ltN2CxOs8NT96Wy60%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점심을 해결하고 부족한 현금을 채우기 위해 우메다역 안에 있는 환전소를 찾았지만 현금만 가능하다고 해서 절망했는데 다행히 세븐일레븐에 있는 atm기를 사용하면 현금을 인출할 수 있다고 해서 만 엔을 인출했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;돈을 뽑은 후 바로 기차를 타고 교토로 넘어갔다. 이번에는 제대로 기차를 타서 금방 도착했다. 교토에서는 짐을 내려놓기 위해 바로 숙소로 향했다. 교토는 역사가 깊은 도시라고 들었는데, 가는 길에도 느낄 수 있었다. 한옥과 같은 오래된 집의 형태가 많이 보였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7x1SV/btsiQ68Q1mJ/7ewxIF4TmHa1kg1vWEobqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7x1SV/btsiQ68Q1mJ/7ewxIF4TmHa1kg1vWEobqk/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.9644%; margin-right: 10px;&quot; data-widthpercent=&quot;47.06&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7x1SV/btsiQ68Q1mJ/7ewxIF4TmHa1kg1vWEobqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7x1SV%2FbtsiQ68Q1mJ%2F7ewxIF4TmHa1kg1vWEobqk%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/POWH1/btsjkGXo01Q/oPfoZMYBQDhs1utHv6yFf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/POWH1/btsjkGXo01Q/oPfoZMYBQDhs1utHv6yFf1/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; width=&quot;400&quot; height=&quot;533&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/POWH1/btsjkGXo01Q/oPfoZMYBQDhs1utHv6yFf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPOWH1%2FbtsjkGXo01Q%2FoPfoZMYBQDhs1utHv6yFf1%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQe8nv/btsjnIsMzSn/s3SZFLSfArvcqhUXKXk5EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQe8nv/btsjnIsMzSn/s3SZFLSfArvcqhUXKXk5EK/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQe8nv/btsjnIsMzSn/s3SZFLSfArvcqhUXKXk5EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQe8nv%2FbtsjnIsMzSn%2Fs3SZFLSfArvcqhUXKXk5EK%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘째 날은 뭐 할까 고민하다 유명한 곳들을 둘러보기로 했다(유명한 데는 이유가 있을 테니?). 그래서 바로 '기요미즈데라'로 향했다. 숙소에서 걸어서 40분 정도 거리라 걸어갔다. 한국에서도 가까운 곳은 걸어 다니며 여행했는데, 외국에서 걸어 다니니 색다른 풍경을 직접 볼 수 있어 좋았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CqmrD/btsiQ68Q5Dz/fiqyKnjkKRrtFk7SHWXZRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CqmrD/btsiQ68Q5Dz/fiqyKnjkKRrtFk7SHWXZRk/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CqmrD/btsiQ68Q5Dz/fiqyKnjkKRrtFk7SHWXZRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCqmrD%2FbtsiQ68Q5Dz%2FfiqyKnjkKRrtFk7SHWXZRk%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baS6Jg/btsiPjOruho/93zgks6NBqmiZb0WJ7s2q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baS6Jg/btsiPjOruho/93zgks6NBqmiZb0WJ7s2q0/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baS6Jg/btsiPjOruho/93zgks6NBqmiZb0WJ7s2q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaS6Jg%2FbtsiPjOruho%2F93zgks6NBqmiZb0WJ7s2q0%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdTc4U/btsiJAcKZrO/Jw2ZQnJxkFcQSArsExHt9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdTc4U/btsiJAcKZrO/Jw2ZQnJxkFcQSArsExHt9k/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdTc4U/btsiJAcKZrO/Jw2ZQnJxkFcQSArsExHt9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdTc4U%2FbtsiJAcKZrO%2FJw2ZQnJxkFcQSArsExHt9k%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnQymd/btsiNwAZDjz/vUH6Nn79K2M7sAI3TGuNk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnQymd/btsiNwAZDjz/vUH6Nn79K2M7sAI3TGuNk0/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnQymd/btsiNwAZDjz/vUH6Nn79K2M7sAI3TGuNk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnQymd%2FbtsiNwAZDjz%2FvUH6Nn79K2M7sAI3TGuNk0%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Asha5/btsjjDGzgBH/CqbBN8TTcPGO8hkWS8VEO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Asha5/btsjjDGzgBH/CqbBN8TTcPGO8hkWS8VEO1/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.9644%; margin-top: 10px;&quot; data-widthpercent=&quot;47.06&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Asha5/btsjjDGzgBH/CqbBN8TTcPGO8hkWS8VEO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAsha5%2FbtsjjDGzgBH%2FCqbBN8TTcPGO8hkWS8VEO1%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://goo.gl/maps/fZjpX3UCk5tkkahH8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://goo.gl/maps/fZjpX3UCk5tkkahH8&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686380624430&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;규카츠 교토가츠규 폰토쵸 본점 &amp;middot; 188 Zaimokucho, Nakagyo Ward, Kyoto, 604-8017 일본&quot; data-og-description=&quot;★★★★☆ &amp;middot; 일식당 및 일정식집&quot; data-og-host=&quot;www.google.co.kr&quot; data-og-source-url=&quot;https://goo.gl/maps/fZjpX3UCk5tkkahH8&quot; data-og-url=&quot;https://www.google.co.kr/maps/place/%EA%B7%9C%EC%B9%B4%EC%B8%A0+%EA%B5%90%ED%86%A0%EA%B0%80%EC%B8%A0%EA%B7%9C+%ED%8F%B0%ED%86%A0%EC%B5%B8+%EB%B3%B8%EC%A0%90/@35.0071023,135.7706168,18z/data=!4m7!3m6!1s0x60010894b53f74b7:0x4d8d6addee097c86!8m2!3d35.0069903!4d135.7709993!15sCgnqt5zsubTsuKBaDCIK6recIOy5tOy4oJIBIGNhc3VhbF9qYXBhbmVzZV9zdHlsZV9yZXN0YXVyYW504AEA!16s%2Fg%2F11b8_rmml0?hl=ko&amp;amp;entry=tts&amp;amp;shorturl=1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/K7FSL/hySW8iGC0L/kVKg1DMsguk9jLA4jB7eV1/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256&quot;&gt;&lt;a href=&quot;https://goo.gl/maps/fZjpX3UCk5tkkahH8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://goo.gl/maps/fZjpX3UCk5tkkahH8&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/K7FSL/hySW8iGC0L/kVKg1DMsguk9jLA4jB7eV1/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;규카츠 교토가츠규 폰토쵸 본점 &amp;middot; 188 Zaimokucho, Nakagyo Ward, Kyoto, 604-8017 일본&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;★★★★☆ &amp;middot; 일식당 및 일정식집&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.google.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평점은 배신하지 않았다. 한국에서 먹어본 것은 비교도 안될 정도로 너무 맛있었다. 맥주랑 말차 맥주를 같이 먹어 봤는데 말차 맥주보단 그냥 맥주가 더 맛있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvQWbO/btsjpFvTzvd/LtkvXlua3U0VWLkzc5smBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvQWbO/btsjpFvTzvd/LtkvXlua3U0VWLkzc5smBK/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 21.4407%; margin-right: 10px;&quot; data-widthpercent=&quot;21.95&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvQWbO/btsjpFvTzvd/LtkvXlua3U0VWLkzc5smBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvQWbO%2FbtsjpFvTzvd%2FLtkvXlua3U0VWLkzc5smBK%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAHw0F/btsjkiPzG5j/AdnvH0MrodJd2ueFZ1zw11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAHw0F/btsjkiPzG5j/AdnvH0MrodJd2ueFZ1zw11/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 38.1168%; margin-right: 10px;&quot; data-widthpercent=&quot;39.02&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAHw0F/btsjkiPzG5j/AdnvH0MrodJd2ueFZ1zw11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAHw0F%2FbtsjkiPzG5j%2FAdnvH0MrodJd2ueFZ1zw11%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqpZzw/btsjmBABAUq/XZ2q3CYAbLZm7iU0HhV0JK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqpZzw/btsjmBABAUq/XZ2q3CYAbLZm7iU0HhV0JK/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 38.1168%;&quot; data-widthpercent=&quot;39.03&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqpZzw/btsjmBABAUq/XZ2q3CYAbLZm7iU0HhV0JK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqpZzw%2FbtsjmBABAUq%2FXZ2q3CYAbLZm7iU0HhV0JK%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배부르게 먹고 산책할 겸 주변을 돌아다니다 일본 놀이터에서 시소랑 그네를 타고 놀았다. Pontocho park라는 곳인데 park라고 하기엔 작은 놀이터 느낌이었다. 오래된 느낌이긴 했지만 동심으로 돌아가기 좋은 곳이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zZAEV/btsjlmxgBT5/7t1318ILrGeS2LQFqqkZk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zZAEV/btsjlmxgBT5/7t1318ILrGeS2LQFqqkZk0/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zZAEV/btsjlmxgBT5/7t1318ILrGeS2LQFqqkZk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzZAEV%2FbtsjlmxgBT5%2F7t1318ILrGeS2LQFqqkZk0%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HXMt2/btsjjBhBY0q/EU2pxHfspOAcYLq59zaVw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HXMt2/btsjjBhBY0q/EU2pxHfspOAcYLq59zaVw1/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HXMt2/btsjjBhBY0q/EU2pxHfspOAcYLq59zaVw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHXMt2%2FbtsjjBhBY0q%2FEU2pxHfspOAcYLq59zaVw1%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J6BfD/btsjpDdIFZz/vqDDNoDShCq66FOmtnvFDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J6BfD/btsjpDdIFZz/vqDDNoDShCq66FOmtnvFDk/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%;&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J6BfD/btsjpDdIFZz/vqDDNoDShCq66FOmtnvFDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ6BfD%2FbtsjpDdIFZz%2FvqDDNoDShCq66FOmtnvFDk%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&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;세 번째 날은 교토에서 점심까지 먹고 다시 오사카를 넘어갈 생각이었다. 아침 일찍 일어나 교토가와라마치역 근처의 스키야에서 간단히 아침을 먹었다. 갓김치와 고기가 올려진 덮밥이었는데 간단하면서 너무 맛있었다. 강추!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://goo.gl/maps/ajBg8wJcvj7nbbML7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://goo.gl/maps/ajBg8wJcvj7nbbML7&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686387695945&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;스키야 시조키야마치점 &amp;middot; 109 Hashimotocho, Shimogyo Ward, Kyoto, 600-8011 일본&quot; data-og-description=&quot;★★★★☆ &amp;middot; 쇠고기덮밥 전문점&quot; data-og-host=&quot;www.google.co.kr&quot; data-og-source-url=&quot;https://goo.gl/maps/ajBg8wJcvj7nbbML7&quot; data-og-url=&quot;https://www.google.co.kr/maps/place/%EC%8A%A4%ED%82%A4%EC%95%BC+%EC%8B%9C%EC%A1%B0%ED%82%A4%EC%95%BC%EB%A7%88%EC%B9%98%EC%A0%90/@35.0039557,135.7687586,17.87z/data=!3m1!5s0x60010895541e7d1d:0x86e1e07ad17d9262!4m7!3m6!1s0x60010895541f0e75:0x2ed97c640cd10b2!8m2!3d35.0036351!4d135.7707647!15sCgnsiqTtgqTslbwiA4gBAVoMIgrsiqTtgqQg7JW8kgEZYmVlZl9yaWNlX2Jvd2xfcmVzdGF1cmFudOABAA!16s%2Fg%2F1tffd2mb?hl=ko&amp;amp;entry=tts&amp;amp;shorturl=1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/B8DJU/hySVERkizO/nwHncKnvEczvnGVnCCyTLK/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256&quot;&gt;&lt;a href=&quot;https://goo.gl/maps/ajBg8wJcvj7nbbML7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://goo.gl/maps/ajBg8wJcvj7nbbML7&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/B8DJU/hySVERkizO/nwHncKnvEczvnGVnCCyTLK/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;스키야 시조키야마치점 &amp;middot; 109 Hashimotocho, Shimogyo Ward, Kyoto, 600-8011 일본&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;★★★★☆ &amp;middot; 쇠고기덮밥 전문점&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.google.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밥을 먹고 은각사라는 곳을 향했다. 대부분 걸어서 여행을 다녔지만 (짐도 무겁고 비도 많이 와서 ㅎㅎ..) 이번에는 버스를 타보기로 했다. 일본 버스는 한국과 반대로 뒷문으로 타고 앞문으로 내리는 구조였다. 또한 요금을 내릴 때 내는 것이었는데, 현금의 경우 잔돈을 거슬러 주지 않는다고 나와서 가지고 있던 현금을 바꿔서 버스를 탔다. 버스를 한 번밖에 안 타봐서 일반화하긴 어렵지만 직접 마이크를 차시고 매 정류장마다 뭐라고 설명을 하시는 것을 보고 상당히 친절하다고 느꼈다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIBCwj/btsjmB8u3lP/uRyLdxc7xi3ZmVRkC5Eiik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIBCwj/btsjmB8u3lP/uRyLdxc7xi3ZmVRkC5Eiik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIBCwj/btsjmB8u3lP/uRyLdxc7xi3ZmVRkC5Eiik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIBCwj%2FbtsjmB8u3lP%2FuRyLdxc7xi3ZmVRkC5Eiik%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;396&quot; height=&quot;528&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은각사 티켓을 사서 내부를 들어갔는데 일본 만화에 나올법한 아름다운 절이 보였다. 비가 와서 언어의 정원과 비슷한 모습으로 보이기도 했다. 생각보다 코스가 길진 않았고 다 보는데 40분 정도 걸린 것 같다. 교토에 오면 한 번쯤 볼만한 아름다운 곳이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3Wbrf/btsjk6hgh23/elczuRo4VUKYtfN1UBOPk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3Wbrf/btsjk6hgh23/elczuRo4VUKYtfN1UBOPk0/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3Wbrf/btsjk6hgh23/elczuRo4VUKYtfN1UBOPk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3Wbrf%2Fbtsjk6hgh23%2FelczuRo4VUKYtfN1UBOPk0%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cytKEf/btsjkiWrrft/rD0YTJciPs8bDwJ2nlRGV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cytKEf/btsjkiWrrft/rD0YTJciPs8bDwJ2nlRGV0/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 25.855%; margin-right: 10px;&quot; data-widthpercent=&quot;26.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cytKEf/btsjkiWrrft/rD0YTJciPs8bDwJ2nlRGV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcytKEf%2FbtsjkiWrrft%2FrD0YTJciPs8bDwJ2nlRGV0%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cC379F/btsjnITQOqb/9CZQRIZ96Ky2LkOYjqwZI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cC379F/btsjnITQOqb/9CZQRIZ96Ky2LkOYjqwZI1/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.9644%;&quot; data-widthpercent=&quot;47.06&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cC379F/btsjnITQOqb/9CZQRIZ96Ky2LkOYjqwZI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcC379F%2FbtsjnITQOqb%2F9CZQRIZ96Ky2LkOYjqwZI1%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은각사를 보고 헤이안 신궁으로 향했는데 이곳으로 갈 때는 그냥 걸어갔다. 처음에는 낭만 있었지만 곧 무거운 가방과 비 때문에 힘들어져서 점심에 가기로 했던 초밥집을 먼저 갔다. '도요 초밥'이라는 곳으로 헤이안 신궁 근처에 있는 곳인데 구글맵 평점이 4.6이라 많은 기대를 품고 갔다. 식당에 들어가니 일본 특유의 아담한 분위기가 보였고, 다른 외국인들이 맛있게 식사를 먹고 있길래 더욱 기대가 커졌다. 우리는 초밥세트를 시켰고 특이하게 오이 초밥? 같은 것도 함께 나왔다. 타마고나 새우 같은 것들은 맛있었는데 다른 것은 그냥 평범했다. 기대를 너무 해서 그런 것일 수도.. 하지만 사장님이 영어도 잘하시고 친절하셔서 만족스러웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://goo.gl/maps/3F8pCLVSYNCCg5o4A&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://goo.gl/maps/3F8pCLVSYNCCg5o4A&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686383150406&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;도요 스시 &amp;middot; 44-5 Okazaki Minamigoshocho, Sakyo Ward, Kyoto, 606-8334 일본&quot; data-og-description=&quot;★★★★★ &amp;middot; 스시/초밥집&quot; data-og-host=&quot;www.google.co.kr&quot; data-og-source-url=&quot;https://goo.gl/maps/3F8pCLVSYNCCg5o4A&quot; data-og-url=&quot;https://www.google.co.kr/maps/place/%EB%8F%84%EC%9A%94+%EC%8A%A4%EC%8B%9C/@35.0157902,135.7848614,18z/data=!4m6!3m5!1s0x600108e3f3402263:0x7e5a42fedfa964eb!8m2!3d35.0157902!4d135.7856579!16s%2Fg%2F1tfjqlvg?hl=ko&amp;amp;entry=tts&amp;amp;shorturl=1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/5UJ5H/hySVGIl4ER/YTw3dIG70cTl5MfmoKjRXk/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256&quot;&gt;&lt;a href=&quot;https://goo.gl/maps/3F8pCLVSYNCCg5o4A&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://goo.gl/maps/3F8pCLVSYNCCg5o4A&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/5UJ5H/hySVGIl4ER/YTw3dIG70cTl5MfmoKjRXk/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;도요 스시 &amp;middot; 44-5 Okazaki Minamigoshocho, Sakyo Ward, Kyoto, 606-8334 일본&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;★★★★★ &amp;middot; 스시/초밥집&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.google.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wgWHS/btsjqwexoZe/HpNiUReJ4eeI0141aiftn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wgWHS/btsjqwexoZe/HpNiUReJ4eeI0141aiftn1/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wgWHS/btsjqwexoZe/HpNiUReJ4eeI0141aiftn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwgWHS%2FbtsjqwexoZe%2FHpNiUReJ4eeI0141aiftn1%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAqKtC/btsjkioyM1B/D5Ky2KD9vLGAfltDKkTpl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAqKtC/btsjkioyM1B/D5Ky2KD9vLGAfltDKkTpl0/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAqKtC/btsjkioyM1B/D5Ky2KD9vLGAfltDKkTpl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAqKtC%2FbtsjkioyM1B%2FD5Ky2KD9vLGAfltDKkTpl0%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cm2vd6/btsjkMQvZnC/C2miLSr9rhjMBzoNf1gKD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cm2vd6/btsjkMQvZnC/C2miLSr9rhjMBzoNf1gKD1/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.5581%;&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cm2vd6/btsjkMQvZnC/C2miLSr9rhjMBzoNf1gKD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcm2vd6%2FbtsjkMQvZnC%2FC2miLSr9rhjMBzoNf1gKD1%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 빗속을 뚫고 헤이안 신궁을 갔는데, 이곳은 입장료가 따로 없었다. 그만큼 볼 것도 별로 없었다.. 한 바퀴 휙 둘러보고 산조역으로 향했다. 이번에도 걸어서 가며 일본 학교를 한번 보고 싶었는데, 한 번도 보지 못했다. 알아보지 못한 걸 수도 있는데 좀 아쉬웠다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kTDEr/btsjnG9yB4c/AQiS1DubmN3X4ByYK8NFU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kTDEr/btsjnG9yB4c/AQiS1DubmN3X4ByYK8NFU0/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kTDEr/btsjnG9yB4c/AQiS1DubmN3X4ByYK8NFU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkTDEr%2FbtsjnG9yB4c%2FAQiS1DubmN3X4ByYK8NFU0%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brnRZ3/btsjkhJWdwh/G8IFfSg4UyYsCDtgetK2G1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brnRZ3/btsjkhJWdwh/G8IFfSg4UyYsCDtgetK2G1/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brnRZ3/btsjkhJWdwh/G8IFfSg4UyYsCDtgetK2G1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrnRZ3%2FbtsjkhJWdwh%2FG8IFfSg4UyYsCDtgetK2G1%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;산조역에서 도톤보리를 갔다. 도착해서 저녁으로 장어덮밥을 먹기로 했다. 이번에도 구글맵 평점이 높은 곳을 찾아갔다. 도톤보리 메인 거리에서 좀 떨어진 곳이었는데 도착해서 좀 쎄 했던 것이 건물 입구에 죽은 장어가 떨어져 있었고, 가게에 들어서니 아무도 없었던 것이다(음식을 다 먹고 나갈 때까지 우리밖에 없었음..). 하지만 무거운 가방을 메고 빗길을 왔기에 애써 무시하며 장어덮밥과 기린 생맥주를 시켰다. 먼저 생맥이 나와 한 모금 들이켰는데 환상적이었다. 맥주를 마시니 걱정이 좀 사라졌는데 한참을 기다려도 장어덮밥은 나오지 않았다. 주방에서는 열심히 장어를 굽고 계시길래 아무 말하진 않았고, 거의 1시간을 기다린 끝에야 장어덮밥을 먹을 수 있었다. 한국에서도 일본식 장어덮밥을 먹었었는데 솔직히 그보다 맛있거나 하진 않았다. 그냥 무난하게 맛있는 장어 정도인 듯하다.&amp;nbsp;&amp;nbsp;&lt;a href=&quot;https://goo.gl/maps/HsWuiFtyGGcNtKsM8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://goo.gl/maps/HsWuiFtyGGcNtKsM8&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1686385607059&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Sumibiyaki Unagi no Nedoko &amp;middot; 일본 〒542-0083 Osaka, Chuo Ward, Higashishinsaibashi, 2 Chome&amp;minus;6&amp;minus;11 高津リーズビル 2&quot; data-og-description=&quot;★★★★☆ &amp;middot; 민물장어 요리 전문식당&quot; data-og-host=&quot;www.google.co.kr&quot; data-og-source-url=&quot;https://goo.gl/maps/HsWuiFtyGGcNtKsM8&quot; data-og-url=&quot;https://www.google.co.kr/maps/place/Sumibiyaki+Unagi+no+Nedoko/@34.6704085,135.5040018,16z/data=!4m7!3m6!1s0x6000e71452abdc91:0xd56a97ad32c650e4!8m2!3d34.6704085!4d135.5040018!15sCgzsnqXslrTrja7rsKVaDyIN7J6l7Ja0IOuNruuwpZIBEHVuYWdpX3Jlc3RhdXJhbnSaASRDaGREU1VoTk1HOW5TMFZKUTBGblNVUkNYMHRFYkhCQlJSQULgAQA!16s%2Fg%2F1thhkd71?hl=ko&amp;amp;entry=tts&amp;amp;shorturl=1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cdVvBg/hySVFo8FP8/16LFGfUAfiE9LNwKORROFk/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256&quot;&gt;&lt;a href=&quot;https://goo.gl/maps/HsWuiFtyGGcNtKsM8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://goo.gl/maps/HsWuiFtyGGcNtKsM8&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cdVvBg/hySVFo8FP8/16LFGfUAfiE9LNwKORROFk/img.jpg?width=256&amp;amp;height=256&amp;amp;face=0_0_256_256');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Sumibiyaki Unagi no Nedoko &amp;middot; 일본 〒542-0083 Osaka, Chuo Ward, Higashishinsaibashi, 2 Chome&amp;minus;6&amp;minus;11 高津リーズビル 2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;★★★★☆ &amp;middot; 민물장어 요리 전문식당&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.google.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckCTnv/btsjnHm5ErN/zHetMJeBpyyHHZgrnGFQI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckCTnv/btsjnHm5ErN/zHetMJeBpyyHHZgrnGFQI1/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckCTnv/btsjnHm5ErN/zHetMJeBpyyHHZgrnGFQI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckCTnv%2FbtsjnHm5ErN%2FzHetMJeBpyyHHZgrnGFQI1%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqgOzb/btsjlYwcT6V/Lw5poAoeSDLSzliWKjqctk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqgOzb/btsjlYwcT6V/Lw5poAoeSDLSzliWKjqctk/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;50&quot; style=&quot;width: 49.4186%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqgOzb/btsjlYwcT6V/Lw5poAoeSDLSzliWKjqctk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqgOzb%2FbtsjlYwcT6V%2FLw5poAoeSDLSzliWKjqctk%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식사를 끝내고 후식으로 타코야끼를 먹으러 도톤보리 메인 거리로 갔다. 그곳에는 5m마다 타코야끼 집이 있었고 그중 줄이 적은 곳으로 들어가서 먹었다. 여러 소스가 뿌려진 타코야끼를 선택해서 먹었는데 꽤 맛있었다. 그런데 솔직히 다시 꼭 먹어야겠다 정도는 아니었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도톤보리에 있는 스타벅스에서 잠깐 쉬려고 들어가서 음료를 마셨다. 다음날 11시에 비행기를 타야 해서 간사이 공항 근처에 숙소를 잡아놔서 밤에 숙소 쪽으로 가려고 했는데 시간이 좀 남아서 뭘 할지 생각하려고 했다. 그러다 숙소까지 얼마나 걸리는지 구글맵을 검색해 보니 비가 너무 많이 와서 열차 운행이 중단되었다고 나왔다. 갑자기 접한 정보에 서둘러 난바역을 가서 알아보니 정말 비 때문에 무슨 문제가 생겨 열차를 운행하지 않는다는 말을 들었다. 혹시 다시 운행하지 않을까 싶어 1시간 정도를 기다려 봤지만 기적은 없었다. 결국 택시를 타려고 택시 정류장을 향했고, 우리끼리 타는 것보다 동행을 구해서 가면 좋을 것 같아서 몇 분에게 물어봤지만 같은 방향은 없었다. 택시 정류장의 줄은 엄청 길어 한참을 기다렸는데 다행히 중간에 어플을 사용해서 택시를 따로 불러서 탈 수 있었다. (다른 사람들은 왜 택시 어플을 사용하지 않는지 궁금해서 우리 앞에 선 일본인에게 물어봤는데, 그냥 줄을 서면 탈 수 있기 때문이라고 했다. 아직 일본인들에게는 이런 어플이 익숙하지 않은 듯하다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zgLzO/btsjkGQFjgm/l0QlnY49kyRdysk3q6dMPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zgLzO/btsjkGQFjgm/l0QlnY49kyRdysk3q6dMPK/img.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1080&quot; data-is-animation=&quot;false&quot; style=&quot;width: 63.2558%; margin-right: 10px;&quot; data-widthpercent=&quot;64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zgLzO/btsjkGQFjgm/l0QlnY49kyRdysk3q6dMPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzgLzO%2FbtsjkGQFjgm%2Fl0QlnY49kyRdysk3q6dMPK%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;1440&quot; height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b128OB/btsjjDmh1Uh/a0qSztGkg0h2gtE1wEXP81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b128OB/btsjjDmh1Uh/a0qSztGkg0h2gtE1wEXP81/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot; data-is-animation=&quot;false&quot; style=&quot;width: 35.5814%;&quot; data-widthpercent=&quot;36&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b128OB/btsjjDmh1Uh/a0qSztGkg0h2gtE1wEXP81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb128OB%2FbtsjjDmh1Uh%2Fa0qSztGkg0h2gtE1wEXP81%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;1080&quot; height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어플에서 나온 예상 택시비는 15만 원이었는데 도착해 보니 20만 원이었다..ㅠㅠ 갑자기 예상치 못하게 큰돈이 나가버렸다. 다음날 아침엔 날씨가 화창해졌는데 확인해 보니 아직도 기차는 운행을 하지 않았다. 다행히 간사이 공항을 가는 전철은 운행해서 탈 수 있었고, 마지막으로 면세점에서 간단히 쇼핑을 하고 한국으로 복귀했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 일본 여행이었는데 너무 재미있었고 인상 깊었던 것들이 많이 있다. 앞으로는 자주 가려고 한다. 사람들은 너무 친절하고 맛있는 음식들도 많아서 천국과 같았다. 오사카는 다음에 꼭 다시 방문해서 여러 맛집을 가보고 싶다.&lt;/p&gt;</description>
      <category>Story/여행</category>
      <category>교토</category>
      <category>오사카</category>
      <category>일본여행</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/65</guid>
      <comments>https://simpling.tistory.com/65#entry65comment</comments>
      <pubDate>Tue, 6 Jun 2023 17:47:04 +0900</pubDate>
    </item>
    <item>
      <title>Image Foundation Model &amp;amp; Transfer methods</title>
      <link>https://simpling.tistory.com/64</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 사회적으로 가장 핫한 주제가 ChatGPT와 같은 Foundation Model이다. 불과 몇 년 전만 해도 AI를 사용해서 실질적인 이익을 얻는 것은 아직 시간이 걸릴 것이라는 의견이 많았는데 OpenAI의 ChatGPT 열풍으로 변곡점을 맞이한 듯하다. 뿐만 아니라 최근 나오는 이미지 생성 모델들 또한 엄청난 성능을 보이며 많은 이들이 사용하고 있다. 덕분에 많은 기업들이 빅 모델(big model)을 만드는 것에 뛰어들고 있다(Fig 1). 이번 글에서는 자연어 생성 모델은 생략하고 이미지 생성(stable diffusion)과 이미지 분류(CLIP)에 관한 모델과 big 모델을 튜닝하기 위한 몇 가지 알고리즘을 소개한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/leqqe/btsdJg9w5eh/1xYbaT3jGHyPlsppgWD8Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/leqqe/btsdJg9w5eh/1xYbaT3jGHyPlsppgWD8Ok/img.png&quot; data-alt=&quot;Fig 1. Foundation models [1]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/leqqe/btsdJg9w5eh/1xYbaT3jGHyPlsppgWD8Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fleqqe%2FbtsdJg9w5eh%2F1xYbaT3jGHyPlsppgWD8Ok%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;1186&quot; height=&quot;492&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Foundation models [1]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Zero-shot Image Classification&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPT 모델과 같은 자연어 생성 모델은 알고리즘 특성상 온라인에 있는 많은 글을 크롤링하여 학습시킬 수 있다. 그러다 보니 데이터의 양이 엄청나게 많아 학습도 잘 되고 zero-shot에서도 잘 작동하는 것이 특징이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWPEWp/btsdHP5Gfa5/WAtCRL34dzFCj0If4PI8o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWPEWp/btsdHP5Gfa5/WAtCRL34dzFCj0If4PI8o0/img.png&quot; data-alt=&quot;Fig 2. GPT-3 training data [2]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWPEWp/btsdHP5Gfa5/WAtCRL34dzFCj0If4PI8o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWPEWp%2FbtsdHP5Gfa5%2FWAtCRL34dzFCj0If4PI8o0%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;374&quot; height=&quot;230&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. GPT-3 training data [2]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 Image classification 모델 같은 경우 많은 논문에서 ImageNet 정도의 학습 데이터를 사용하는 것만으로 많은 데이터를 사용한 것으로 여긴다. 데이터의 차원이 높기 때문에 학습이 오래 걸리는 것도 한몫하지만, 보통의 classification 알고리즘은 모델의 head에서 각 class별 확률을 뽑아내서 정답과 비교하여 학습시키는 구조였기 때문에 자연어 모델과 같이 온라인에 있는 일반적인 데이터를 사용하지 못하고 labeling이 잘 되어 있는 데이터를 사용해야 했기 때문이다. ImageNet은 1400만 개 정도의 데이터밖에 없지만(Fig 3) GPT-3의 훈련 데이터는 500 billion에 육박한다. 압도적 차이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6jlHe/btsdHPxOIAs/BKhrLfdlKx19aesO7YSEq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6jlHe/btsdHPxOIAs/BKhrLfdlKx19aesO7YSEq0/img.png&quot; data-alt=&quot;Fig 3. ImageNet Dataset [3]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6jlHe/btsdHPxOIAs/BKhrLfdlKx19aesO7YSEq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6jlHe%2FbtsdHPxOIAs%2FBKhrLfdlKx19aesO7YSEq0%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;482&quot; height=&quot;287&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. ImageNet Dataset [3]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째로 이런 한계를 극복한 OpenAI의 Learning Transferable Visual Models From Natural Language Supervision([4]) 논문을 소개한다. CLIP이라는 알고리즘으로 많이 알려져 있다. 이 알고리즘은 contrastive learning을 사용하여 온라인상의 많은 데이터를 사용할 수 있게 만들었고 zero-shot에서 매우 좋은 성능을 보인다. 논문에서 제시한 알고리즘은 Fig 4와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dI5V43/btsdG9ch3cJ/eIvNOBxMUTvLUu4Pn4JZh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dI5V43/btsdG9ch3cJ/eIvNOBxMUTvLUu4Pn4JZh0/img.png&quot; data-alt=&quot;Fig 4. CLIP 알고리즘 [4]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dI5V43/btsdG9ch3cJ/eIvNOBxMUTvLUu4Pn4JZh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdI5V43%2FbtsdG9ch3cJ%2FeIvNOBxMUTvLUu4Pn4JZh0%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;1206&quot; height=&quot;582&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. CLIP 알고리즘 [4]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 온라인에 있는 사진과 사진에 대한 caption에 대한 정보를 함께 가져온다. 그리고 Image의 feature를 뽑는 모델과(Image Encoder) caption에 대한 feature를 뽑는 모델(Text Encoder)을 만든다. 각 모델에서 나온 feature는 Fig 4의 (1)의 그림처럼 각각 inner product 해준다. Contrastive learning처럼 같은 정보(image에 대응하는 caption, $I_{i} T_{i}$, 파란색 칸) 끼리는 maximize 하되 다른 정보(하얀색 칸)는 minimize 하도록 학습시키는 방식이다. 이러한 알고리즘은 이미 잘 동작하는 것이 많이 알려져 있기 때문에 좋은 아이디어인 듯하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test를 할 때는 Fig 4의 (2)와 (3)과 같이 사용하는데, 예를 들어 CIFAR10 데이터라고 하면 plane, car, dog 등 10개의 class가 존재한다. 각 class에 해당하는 caption (예를 들어 'a photo of plane')을 Text Encoder에 통과시켜 class 별 feature를 뽑고 classification 하고 싶은 Image를 Image Encoder에 통과시켜 feature를 뽑은 후 내적하여 가장 높은 값을 보이는 것이 예측 값이라고 생각하는 것이다. 실제로 이 알고리즘은 zero-shot에서 좋은 성능을 보였을 뿐 아니라 distribution shift 문제에서도 robust 한 성능을 보여주는 등의 좋은 결과로 주목받았다. 뿐만 아니라 이후에는 classification이 아닌 image generation 등의 모델에서도 쓰이며 성능을 높이는데 일조했다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Stable Diffusion&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Diffusion 모델은 original image $X_{0}$에 noise를 섞은 것을 모델을 통해 denoising 하는 과정을 배우는 알고리즘이며 VAE, GAN 등의 생성 모델보다 좋은 성능을 보여주며 많은 주목을 받았다. 하지만 초기 모델은 Fig 5와 같이 이미지를 통째로 denoising 하기 위해 많은 파라미터가 사용되어 computational cost가 큰 단점이 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3832&quot; data-origin-height=&quot;1348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wq0V5/btsdH243IE1/cATVN1rCPneoTltXRYqjN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wq0V5/btsdH243IE1/cATVN1rCPneoTltXRYqjN0/img.png&quot; data-alt=&quot;Fig 5. Diffusion model architecture [6]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wq0V5/btsdH243IE1/cATVN1rCPneoTltXRYqjN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwq0V5%2FbtsdH243IE1%2FcATVN1rCPneoTltXRYqjN0%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;596&quot; height=&quot;210&quot; data-origin-width=&quot;3832&quot; data-origin-height=&quot;1348&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Diffusion model architecture [6]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 극복한 것이 stable diffusion이다. Stable diffusion 모델의 알고리즘은 간단하다. 미리 auto encoder를 학습시키고 encoder를 사용하여 image를 압축시킨 후에 diffusion과 denoising을 하겠다는 것이 핵심이다. 이렇게 하면 computational cost가 훨씬 줄어드는 장점이 있을 뿐 아니라, Fig 6에서처럼 condition을 쉽게 latent에 추가하여 넣어줄 수 있다. (Condition으로 text를 넣어줄 때 위에서 봤던 CLIP과 같은 알고리즘 모델의 text encoder를 사용하면 더 좋은 성능을 보인다고 한다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;349&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/74kd8/btsdFgiXatJ/ky9Mrv8RpnIrIEH6lrTB4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/74kd8/btsdFgiXatJ/ky9Mrv8RpnIrIEH6lrTB4k/img.png&quot; data-alt=&quot;Fig 6. Stable diffusion architecture [5]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/74kd8/btsdFgiXatJ/ky9Mrv8RpnIrIEH6lrTB4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F74kd8%2FbtsdFgiXatJ%2Fky9Mrv8RpnIrIEH6lrTB4k%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;562&quot; height=&quot;349&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;349&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Stable diffusion architecture [5]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Foudation Model &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Transfer&lt;span&gt; Method&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Foundation model은 보통 많은 데이터와 큰 모델을 사용하여 잘 작동한다. 하지만 파라미터가 너무 많아 down stream task에 적용하기 위해 tuning을 할 때는 문제가 된다. 모델을 통째로 tuning 하기에는 개인이나 작은 기업이 하기에 부담일 수 있고 효율적이지도 않다. 그래서 효율성을 개선한 방법들이 많이 나왔는데 몇 가지만 소개한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Adapter&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 간단하게 사용할 수 있는 방법은 모델 사이에 layer를 끼워 넣는 방법이다. 이를 adapter라고 한다 [9].&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;606&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sVLD3/btsdGlEmmnh/PIHHxyPp9OIa0pMdgCfgW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sVLD3/btsdGlEmmnh/PIHHxyPp9OIa0pMdgCfgW1/img.png&quot; data-alt=&quot;Fig 7. Adapter [9]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sVLD3/btsdGlEmmnh/PIHHxyPp9OIa0pMdgCfgW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsVLD3%2FbtsdGlEmmnh%2FPIHHxyPp9OIa0pMdgCfgW1%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;277&quot; height=&quot;203&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Adapter [9]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 Fig 7과 같은 구조로 feed-forward layer 다음에 넣으며, 원래 모델은 freeze 시킨 후 adapter만 학습시키는 방식이다. 훈련할 파라미터가 훨씬 적어져서 효율적이라는 장점이 있지만 inference latency가 증가하게 되는 단점이 존재한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Prefix-tuning&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자연어 생성 모델에서 사용되는 구조로 많은 논문에서 baseline으로 사용하고 있다. 그만큼 잘 동작하기도 하고 효율적인 알고리즘이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ud7iU/btsdInOHHI8/KNYYTELsZV2wg0Ii9YpcUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ud7iU/btsdInOHHI8/KNYYTELsZV2wg0Ii9YpcUk/img.png&quot; data-alt=&quot;Fig 8. Prefix-tuning [7]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ud7iU/btsdInOHHI8/KNYYTELsZV2wg0Ii9YpcUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUd7iU%2FbtsdInOHHI8%2FKNYYTELsZV2wg0Ii9YpcUk%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;553&quot; height=&quot;380&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Prefix-tuning [7]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prefix라는 말과 같이 모델의 input 앞에 추가 token에 해당하는 random 벡터를 넣고 이 벡터를 학습시키는 방식이다. 논문의 intuition을 보면 질문에 해당하는 맥락에 관한 정보를 같이 넣어주면 모델이 더 좋은 정보를 뱉어줄 것이라고 기대할 수 있기 때문에 이런 방법을 사용했다고 한다. 예를 들어 ChatGPT에게 '서울의 최고 명소는 어디야?' 같은 질문을 할 때, 앞에 '서울은 한국의 수도인데'라는 식으로 추가 정보를 넣어주면 더 좋은 대답을 얻을 수 있을 텐데, 이를 사람이 일일이 실험해 보긴 어려우니 학습을 통해 얻겠다는 방법이라고 볼 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;LoRA&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LoRA는 &lt;span style=&quot;color: #000000;&quot;&gt;Low-Rank Adaptation of Large Language Models의 줄임말이다. Low-Rank만 adaptaiton 하여 tuning 한다는 것인데 이를 이해하려면 &lt;span style=&quot;color: #000000;&quot;&gt;INTRINSIC DIMENSIONALITY EXPLAINS THE EFFECTIVENESS OF LANGUAGE MODEL FINE-TUNING([10])에 나온 내용을 알아야 한다. 이 논문에서는 꽤 흥미로운 내용과 실험에 대해 소개해준다. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Auto Encoder 같은 차원 압축 알고리즘에 이미지 같은 고차원 데이터를 넣어 작은 차원의 벡터로 만들고 다시 원래 이미지로 복원해도 거의 같은 이미지가 나온다. 그 이유는 데이터가 고차원 공간에 존재하지만 대부분의 공간은 noise이고 실제 의미를 갖는 공간은 굉장히 작기 때문에, 낮은 차원에 mapping 해도 정보를 거의 잃지 않기 때문이다. 마찬가지로 모델도 굉장히 큰 차원에 존재하지만 낮은 차원에 mapping 할 수 있다고 생각할 수 있다. 그래서 원래 모델의 파라미터가 D개였다면 &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;tuning 시에는 d(d&amp;lt;&amp;lt;D) 개의 파라미터만 사용하고 d의 파라미터를 D로 바꿔주는 random matrix ($P: R^{d} -&amp;gt; R^{D}$)를 사용했을 때에도 성능이 잘 나오는지 논문에서 실험을 해본다.&lt;/span&gt;&lt;/span&gt;&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;982&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p6Mkw/btsdEB1ZgfS/rviP9dCdHuu70R1iLvFk2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p6Mkw/btsdEB1ZgfS/rviP9dCdHuu70R1iLvFk2k/img.png&quot; data-alt=&quot;Fig 10. 파라미터 d를 사용하여 tuning 했을 때 결과 그래프 [10]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p6Mkw/btsdEB1ZgfS/rviP9dCdHuu70R1iLvFk2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp6Mkw%2FbtsdEB1ZgfS%2FrviP9dCdHuu70R1iLvFk2k%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;595&quot; height=&quot;397&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 10. 파라미터 d를 사용하여 tuning 했을 때 결과 그래프 [10]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 10은 그 결과를 보여주는데, x축이 차원 d를 나타내고 y축은 accuracy다. MRPC와 QQP 데이터 모두에서 d가 충분히 작아도 그냥 tuning을 하는 것에서 성능 저하가 크지 않음을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 영감을 받아 LoRA가 만들어진다. 작은 차원의 파라미터만 사용해서 tuning 해도 충분히 좋은 finetuning 성능이 나온다는 것을 이용하여, Fig 11과 같이 matrix A와 B를 사용하여 훈련하겠다는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;653&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFUdwT/btsdGmJ4vIb/Ks5mxSRPnj0GsKAWGwjnck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFUdwT/btsdGmJ4vIb/Ks5mxSRPnj0GsKAWGwjnck/img.png&quot; data-alt=&quot;Fig 11. LoRA architecture [8]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFUdwT/btsdGmJ4vIb/Ks5mxSRPnj0GsKAWGwjnck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFUdwT%2FbtsdGmJ4vIb%2FKs5mxSRPnj0GsKAWGwjnck%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;295&quot; height=&quot;325&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;653&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 11. LoRA architecture [8]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A와 B는 모두 learnable parameter이고 원래 dxd의 matrix를 가지는 모델과 다르게 r차원으로 한번 차원 축소하는 과정이 들어간다. 위의 알고리즘([10])과 다른 것은 random projection 방식을 쓰지 않는다는 것이다. 그러니 성능은 더 잘 나오게 된다. 이 알고리즘의 가장 큰 장점은 inference latency가 생기지 않는다는 것이다. 왜냐하면 아래 수식과 같이 tuning시 W(parameter)가 변하는 $\Delta W$를 $BA$로 mapping 한 것이므로 자연스레 더해서 계산하면 되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ h = W_{0}x + \Delta Wx $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ = W_{0}x + BAx $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ = (W_{0}+BA)x $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드로 보면 Fig 12와 같이 작성되어 evaluation 시 원래 matrix와 BA를 미리 더하고 계산하는 식으로 만들 수 있다.&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;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HYLL3/btsdJpMfjrn/VYIk14RLcDjQzyDXlVkI00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HYLL3/btsdJpMfjrn/VYIk14RLcDjQzyDXlVkI00/img.png&quot; data-alt=&quot;Fig 12. code of LoRA [11]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HYLL3/btsdJpMfjrn/VYIk14RLcDjQzyDXlVkI00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHYLL3%2FbtsdJpMfjrn%2FVYIk14RLcDjQzyDXlVkI00%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;515&quot; height=&quot;193&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 12. code of LoRA [11]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LoRA는 Language model에 적용하기 위한 모델이었지만, 작은 모델이라 쉽게 공유할 수 있다는 장점도 있고, 대부분의 network에서 사용가능하며, 원하는 down stream task이 변할 때마다 갈아 끼우며 사용가능하여 stable diffusion 커뮤니티에서 활발히 공유되며 사용 중이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://lastweekin.ai/p/gpt-3-foundation-models-and-ai-nationalism&quot;&gt;https://lastweekin.ai/p/gpt-3-foundation-models-and-ai-nationalism&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683029885565&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;GPT-3, Foundation Models, and AI Nationalism&quot; data-og-description=&quot;Geopolitical Implications of the 'Year of Monster Models'&quot; data-og-host=&quot;lastweekin.ai&quot; data-og-source-url=&quot;https://lastweekin.ai/p/gpt-3-foundation-models-and-ai-nationalism&quot; data-og-url=&quot;https://lastweekin.ai/p/gpt-3-foundation-models-and-ai-nationalism&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/wo23G/hyStKiIo9s/lcc6lsGp6vKVJRaFXpuFA0/img.jpg?width=1200&amp;amp;height=497&amp;amp;face=0_0_1200_497,https://scrap.kakaocdn.net/dn/cr5jf6/hyStXPQRI8/cChB20Jkiolu22k6UdPvfk/img.jpg?width=1200&amp;amp;height=497&amp;amp;face=0_0_1200_497,https://scrap.kakaocdn.net/dn/eDxOv/hyStTGHEUT/C9aLlk0BmrxjnkqK6QNtsK/img.jpg?width=1456&amp;amp;height=1015&amp;amp;face=0_0_1456_1015&quot;&gt;&lt;a href=&quot;https://lastweekin.ai/p/gpt-3-foundation-models-and-ai-nationalism&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://lastweekin.ai/p/gpt-3-foundation-models-and-ai-nationalism&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/wo23G/hyStKiIo9s/lcc6lsGp6vKVJRaFXpuFA0/img.jpg?width=1200&amp;amp;height=497&amp;amp;face=0_0_1200_497,https://scrap.kakaocdn.net/dn/cr5jf6/hyStXPQRI8/cChB20Jkiolu22k6UdPvfk/img.jpg?width=1200&amp;amp;height=497&amp;amp;face=0_0_1200_497,https://scrap.kakaocdn.net/dn/eDxOv/hyStTGHEUT/C9aLlk0BmrxjnkqK6QNtsK/img.jpg?width=1456&amp;amp;height=1015&amp;amp;face=0_0_1456_1015');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GPT-3, Foundation Models, and AI Nationalism&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Geopolitical Implications of the 'Year of Monster Models'&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;lastweekin.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] &lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/GPT-3#GPT-3.5&quot;&gt;https://en.wikipedia.org/wiki/GPT-3#GPT-3.5&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683030444913&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;GPT-3 - Wikipedia&quot; data-og-description=&quot;From Wikipedia, the free encyclopedia 2020 text-generating language model Generative Pre-trained Transformer 3 (GPT-3) is an autoregressive language model released in 2020 that uses deep learning to produce human-like text. When given a prompt, it will gen&quot; data-og-host=&quot;en.wikipedia.org&quot; data-og-source-url=&quot;https://en.wikipedia.org/wiki/GPT-3#GPT-3.5&quot; data-og-url=&quot;https://en.wikipedia.org/wiki/GPT-3#GPT-3.5&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/GPT-3#GPT-3.5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://en.wikipedia.org/wiki/GPT-3#GPT-3.5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GPT-3 - Wikipedia&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;From Wikipedia, the free encyclopedia 2020 text-generating language model Generative Pre-trained Transformer 3 (GPT-3) is an autoregressive language model released in 2020 that uses deep learning to produce human-like text. When given a prompt, it will gen&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;en.wikipedia.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[3] &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://paperswithcode.com/dataset/imagenet&quot;&gt;https://paperswithcode.com/dataset/imagenet&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683030700304&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Papers with Code - ImageNet Dataset&quot; data-og-description=&quot;The ImageNet dataset contains 14,197,122 annotated images according to the WordNet hierarchy. Since 2010 the dataset is used in the ImageNet Large Scale Visual Recognition Challenge (ILSVRC), a benchmark in image classification and object detection. The pu&quot; data-og-host=&quot;paperswithcode.com&quot; data-og-source-url=&quot;https://paperswithcode.com/dataset/imagenet&quot; data-og-url=&quot;https://paperswithcode.com/dataset/imagenet&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/m1M99/hyStPRSV1e/3HsanUF9nN1lzU5NuRpFwk/img.jpg?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000,https://scrap.kakaocdn.net/dn/qKOwn/hyStMAQjKV/w50XQC7QAEYRi2shBZrJo1/img.jpg?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://paperswithcode.com/dataset/imagenet&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://paperswithcode.com/dataset/imagenet&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/m1M99/hyStPRSV1e/3HsanUF9nN1lzU5NuRpFwk/img.jpg?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000,https://scrap.kakaocdn.net/dn/qKOwn/hyStMAQjKV/w50XQC7QAEYRi2shBZrJo1/img.jpg?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Papers with Code - ImageNet Dataset&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The ImageNet dataset contains 14,197,122 annotated images according to the WordNet hierarchy. Since 2010 the dataset is used in the ImageNet Large Scale Visual Recognition Challenge (ILSVRC), a benchmark in image classification and object detection. The pu&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;paperswithcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[4] &lt;a href=&quot;https://arxiv.org/abs/2103.00020&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2103.00020&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683030907371&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Learning Transferable Visual Models From Natural Language Supervision&quot; data-og-description=&quot;State-of-the-art computer vision systems are trained to predict a fixed set of predetermined object categories. This restricted form of supervision limits their generality and usability since additional labeled data is needed to specify any other visual co&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2103.00020&quot; data-og-url=&quot;https://arxiv.org/abs/2103.00020v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/EV0Md/hyStL9LUcx/wu9V5lQpjdT2BIYQZpQT40/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/dpC8RE/hyStVEyRHO/CLowfYmhXFE2aEUgG2aTLk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2103.00020&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2103.00020&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/EV0Md/hyStL9LUcx/wu9V5lQpjdT2BIYQZpQT40/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/dpC8RE/hyStVEyRHO/CLowfYmhXFE2aEUgG2aTLk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Learning Transferable Visual Models From Natural Language Supervision&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;State-of-the-art computer vision systems are trained to predict a fixed set of predetermined object categories. This restricted form of supervision limits their generality and usability since additional labeled data is needed to specify any other visual co&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[5] &lt;a href=&quot;https://arxiv.org/abs/2112.10752&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2112.10752&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683032098159&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;High-Resolution Image Synthesis with Latent Diffusion Models&quot; data-og-description=&quot;By decomposing the image formation process into a sequential application of denoising autoencoders, diffusion models (DMs) achieve state-of-the-art synthesis results on image data and beyond. Additionally, their formulation allows for a guiding mechanism t&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2112.10752&quot; data-og-url=&quot;https://arxiv.org/abs/2112.10752v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dnkBzT/hyStXh4CLV/wpurtcac1ulYDPfEoqpJ51/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/hG6B5/hyStL9NmFn/RE4Fkr7QPnbktJEE5t6Ysk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2112.10752&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2112.10752&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dnkBzT/hyStXh4CLV/wpurtcac1ulYDPfEoqpJ51/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/hG6B5/hyStL9NmFn/RE4Fkr7QPnbktJEE5t6Ysk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;High-Resolution Image Synthesis with Latent Diffusion Models&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;By decomposing the image formation process into a sequential application of denoising autoencoders, diffusion models (DMs) achieve state-of-the-art synthesis results on image data and beyond. Additionally, their formulation allows for a guiding mechanism t&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[6] &lt;a href=&quot;https://arxiv.org/abs/2006.11239&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2006.11239&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683032359574&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Denoising Diffusion Probabilistic Models&quot; data-og-description=&quot;We present high quality image synthesis results using diffusion probabilistic models, a class of latent variable models inspired by considerations from nonequilibrium thermodynamics. Our best results are obtained by training on a weighted variational bound&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2006.11239&quot; data-og-url=&quot;https://arxiv.org/abs/2006.11239v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ssxCR/hyStYH5lJt/Q0DZnz7inu55B6DrPnSGP1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/zVesq/hyStPqPRvc/0DNP5cBJlj3fo6J07Bw2Tk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2006.11239&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2006.11239&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ssxCR/hyStYH5lJt/Q0DZnz7inu55B6DrPnSGP1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/zVesq/hyStPqPRvc/0DNP5cBJlj3fo6J07Bw2Tk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Denoising Diffusion Probabilistic Models&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We present high quality image synthesis results using diffusion probabilistic models, a class of latent variable models inspired by considerations from nonequilibrium thermodynamics. Our best results are obtained by training on a weighted variational bound&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[7] &lt;a href=&quot;https://arxiv.org/abs/2101.00190&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2101.00190&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683033988435&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Prefix-Tuning: Optimizing Continuous Prompts for Generation&quot; data-og-description=&quot;Fine-tuning is the de facto way to leverage large pretrained language models to perform downstream tasks. However, it modifies all the language model parameters and therefore necessitates storing a full copy for each task. In this paper, we propose prefix-&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2101.00190&quot; data-og-url=&quot;https://arxiv.org/abs/2101.00190v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b8ZESP/hyStMHFK7K/9galnRh7jrSkZRwkcEIDu1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/rety4/hyStOrWwuE/UmxQwd6k2zve3rToei44F0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2101.00190&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2101.00190&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b8ZESP/hyStMHFK7K/9galnRh7jrSkZRwkcEIDu1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/rety4/hyStOrWwuE/UmxQwd6k2zve3rToei44F0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Prefix-Tuning: Optimizing Continuous Prompts for Generation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Fine-tuning is the de facto way to leverage large pretrained language models to perform downstream tasks. However, it modifies all the language model parameters and therefore necessitates storing a full copy for each task. In this paper, we propose prefix-&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[8] &lt;a href=&quot;https://arxiv.org/abs/2106.09685&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2106.09685&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683034009460&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;LoRA: Low-Rank Adaptation of Large Language Models&quot; data-og-description=&quot;An important paradigm of natural language processing consists of large-scale pre-training on general domain data and adaptation to particular tasks or domains. As we pre-train larger models, full fine-tuning, which retrains all model parameters, becomes le&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2106.09685&quot; data-og-url=&quot;https://arxiv.org/abs/2106.09685v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/PGHkx/hyStPj4ITW/RG5uljk1oDfovfF3FWEFTK/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/oL63h/hyStOep8Nt/kmrv3ygXRsv0r2yZsZkz10/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2106.09685&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2106.09685&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/PGHkx/hyStPj4ITW/RG5uljk1oDfovfF3FWEFTK/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/oL63h/hyStOep8Nt/kmrv3ygXRsv0r2yZsZkz10/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;LoRA: Low-Rank Adaptation of Large Language Models&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;An important paradigm of natural language processing consists of large-scale pre-training on general domain data and adaptation to particular tasks or domains. As we pre-train larger models, full fine-tuning, which retrains all model parameters, becomes le&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[9] &lt;a href=&quot;https://arxiv.org/abs/1902.00751&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1902.00751&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683034055282&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Parameter-Efficient Transfer Learning for NLP&quot; data-og-description=&quot;Fine-tuning large pre-trained models is an effective transfer mechanism in NLP. However, in the presence of many downstream tasks, fine-tuning is parameter inefficient: an entire new model is required for every task. As an alternative, we propose transfer &quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1902.00751&quot; data-og-url=&quot;https://arxiv.org/abs/1902.00751v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/LHGGL/hyStMt8kCX/uW5RzZqvXsRF5gpEGA8WH1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/cmT3qo/hyStSukJ0u/TDwlQnynRRoAwnWICzVxBk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1902.00751&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1902.00751&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/LHGGL/hyStMt8kCX/uW5RzZqvXsRF5gpEGA8WH1/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/cmT3qo/hyStSukJ0u/TDwlQnynRRoAwnWICzVxBk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Parameter-Efficient Transfer Learning for NLP&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Fine-tuning large pre-trained models is an effective transfer mechanism in NLP. However, in the presence of many downstream tasks, fine-tuning is parameter inefficient: an entire new model is required for every task. As an alternative, we propose transfer&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[10] &lt;a href=&quot;https://arxiv.org/abs/2012.13255&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2012.13255&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683034926892&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning&quot; data-og-description=&quot;Although pretrained language models can be fine-tuned to produce state-of-the-art results for a very wide range of language understanding tasks, the dynamics of this process are not well understood, especially in the low data regime. Why can we use relativ&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2012.13255&quot; data-og-url=&quot;https://arxiv.org/abs/2012.13255v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/76AZe/hyStRhVgPw/GzzKt8hTyNUpck3bAAUe20/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/ccCeIZ/hyStWpZIss/mqqeyS2ZHTdzidf9VEa111/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2012.13255&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2012.13255&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/76AZe/hyStRhVgPw/GzzKt8hTyNUpck3bAAUe20/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/ccCeIZ/hyStWpZIss/mqqeyS2ZHTdzidf9VEa111/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Although pretrained language models can be fine-tuned to produce state-of-the-art results for a very wide range of language understanding tasks, the dynamics of this process are not well understood, especially in the low data regime. Why can we use relativ&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[11] &lt;a href=&quot;https://github.com/microsoft/LoRA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/microsoft/LoRA&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1683035906897&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - microsoft/LoRA: Code for loralib, an implementation of &amp;quot;LoRA: Low-Rank Adaptation of Large Language Models&amp;quot;&quot; data-og-description=&quot;Code for loralib, an implementation of &amp;quot;LoRA: Low-Rank Adaptation of Large Language Models&amp;quot; - GitHub - microsoft/LoRA: Code for loralib, an implementation of &amp;quot;LoRA: Low-Rank Adaptati...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/microsoft/LoRA&quot; data-og-url=&quot;https://github.com/microsoft/LoRA&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dVu38b/hyStOZOPWO/InIuukWtu8QDa6TFPIFya1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/microsoft/LoRA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/microsoft/LoRA&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dVu38b/hyStOZOPWO/InIuukWtu8QDa6TFPIFya1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - microsoft/LoRA: Code for loralib, an implementation of &quot;LoRA: Low-Rank Adaptation of Large Language Models&quot;&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Code for loralib, an implementation of &quot;LoRA: Low-Rank Adaptation of Large Language Models&quot; - GitHub - microsoft/LoRA: Code for loralib, an implementation of &quot;LoRA: Low-Rank Adaptati...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/64</guid>
      <comments>https://simpling.tistory.com/64#entry64comment</comments>
      <pubDate>Tue, 2 May 2023 22:20:44 +0900</pubDate>
    </item>
    <item>
      <title>객체 지향 프로그래밍 [Python]</title>
      <link>https://simpling.tistory.com/63</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;객체 지향 프로그래밍(OOP, Object-Oriented Programming)&lt;/b&gt;은 객체들의 집합으로 프로그램의 상호 작용을 표현하는 프로그래밍 방법 중 하나다. Python을 처음 배울 때 기본적인 내용을 배웠지만 객체 지향 방법의 장, 단점과 어떨 때 사용하고 어떻게 사용하는 것이 좋은지 잘 알지 못해 현업에서 사용하는 데 애를 먹었다. 그래서 이 글에서는 객체 지향 프로그래밍을 사용하는데 필요한 내용들과 지켜야하는 원칙들을 예시와 함께 남긴다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;클래스(class) VS 객체(object) VS 인스턴스(instance)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;클래스는 만들고자하는 객체 들의 공통적 성질을 묶어 추상화하여 표현한 것을 말한다.&amp;nbsp;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 말이 어렵게 느껴질 수 있는데, 예를 들면 현실에서 '사람'이라는 개념도 여러 사람들의 공통적 성질을 묶어 추상화하여 표현한 것이라고 할 수 있다.&lt;/li&gt;
&lt;li&gt;'사람'은 이름과 나이라는 특성을 가지고 있고 노래를 부르거나 자기 소개를 하는 등의 행동을 할 수 있는 것을 우리는 알고 있다. 그런 공통적 특성을 가진 것을 '사람'이라는 추상적 표현으로 정의했기 때문이다.&lt;/li&gt;
&lt;li&gt;이와같이 아래의 코드처럼 'Person'이라는 class에 공통적으로 가지는 특성과 행동을 정의하여 표현할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;객체는 개별적 실체로 존재하는 것들을 말한다.&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;나 혹은 이 글을 읽고 있는 독자는 모두 '사람'이지만 각각 이름과 나이 등의 다른 특성을 가진다. 이런 개별적 존재를 객체라고 부른다.&lt;/li&gt;
&lt;li&gt;아래 코드에서도 'brian'과 'jenny'라는 서로 다른 특성을 갖는 객체를 구현한 것을 볼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인스턴스는 컴퓨터 메모리에 올라온 '객체'를 표현하는 말이다.&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인스턴스는 소프트웨어적 관점에서 객체를 표현하는 말이라고 생각할 수 있다. 즉, 실제 메모리를 점유하고 있는 객체이고, 객체는 클래스의 인스턴스라고 표현하기도 한다.&lt;/li&gt;
&lt;li&gt;인스턴스는 객체에 속하는 표현이다.&lt;/li&gt;
&lt;li&gt;아래 코드에서 'brian'과 'jenny'는 메모리를 가지고 있으므로 인스턴스다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1674969623845&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Person:
	def __init__(self, name, age):
		self.name = name
		self.age = age
    
	def introduce(self):
		print(f&quot;My name is {self.name} and I'm {self.age} years old&quot;)
        
# instance of Person class
brian = Person(&quot;brian&quot;, 27)
jenny = Person(&quot;jenny&quot;, 25)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;객체 지향 프로그래밍 장점&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상속성, 다형성, 캡슐화 덕분에 재사용성이 높은 코드를 작성할 수 있다.&lt;/li&gt;
&lt;li&gt;설계 원칙만 잘 지킨다면 코드의 확장과 디버깅이 쉽다.&lt;/li&gt;
&lt;li&gt;실제 세계를 표방한 프로그래밍 방법이라 직관적이고 이해가 쉽다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;객체 지향 프로그래밍 단점&lt;/b&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설계 자체가 까다로워 개발 시간이 많이 소요될 수 있다.&lt;/li&gt;
&lt;li&gt;처리 속도가 다른 프로그래밍 패러다임에 비해 상대적으로 느리다.&lt;/li&gt;
&lt;li&gt;추상 객체, 상속 등이 많아지면 코드가 복잡해서 전체 구조를 파악하기 어려워진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;객체 지향 프로그래밍 특징&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;추상화&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;핵심적 개념이나 기능을 간추려내는 것을 말한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ex) 사람은 나이, 이름을 가지고 있고 걷거나 말하는 행동을 한다.&lt;/li&gt;
&lt;li&gt;ex) 은행나무는 은행을 열매로 가지고 가을에 노란 잎을 갖는 특성을 갖는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;u&gt;추상화는 객체 지향 프로그래밍 설계 원칙에서 중요한 역할을 한다.&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;ex) 아래 코드1에서 여러 총기에 대한 공통적 기능인 shot을 Gun이라는 클래스에서 추상화하여 표현하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캡슐화&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체의 속성과 메서드를 하나로 묶고 일부를 외부에 감추어 은닉하는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;상속성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상위 클래스의 특성을 하위 클래스가 이어받아서 &lt;u&gt;재사용하거나 추가, 확장&lt;/u&gt;하는 것을 말한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;u&gt;상위 클래스의 특성을 변경하진 않는다!&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;코드의 재사용성, 계층적 관계 생성, 유지 보수성 측면에서 중요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;다형성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나의 메서드나 클래스가 다양한 방법으로 동작하는 것을 말한다. 대표적으로 오버로딩, 오버라이딩이 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오버로딩은 같은 이름을 가진 메서드를 여러 개 두는 것을 말한다.(파이썬은 지원하지 않음!)&lt;/li&gt;
&lt;li&gt;오버라이딩은 상위 클래스로부터 상속받은 메서드를 하위 클래스가 재정의하는 것을 의미한다.&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1675083083510&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 코드1
from abc import ABCMeta, abstractmethod

class Gun(metaclass=ABCMeta):
    name = 'gun'

    @abstractmethod
    def shot(self, hp):
        pass


class AK(Gun):
    damage = 30
    bullet = 50

    def shot(self, hp):
        self.bullet -= 1
        return hp-self.damage


class Snipe(Gun):
    name = 'Snipe'

    @abstractmethod
    def zoom(self):
        pass


class TRG(Snipe):
    damage = 100
    bullet = 5

    def shot(self, hp):
        self.bullet -= 1
        return hp-self.damage

    def zoom(self):
        return print(&quot;Zoom in&quot;)


class User:
    def __init__(self, hp, gun: Gun):
        self.hp = hp
        self.gun = gun

    def attack(self, user):
        user.hp = self.gun.shot(user.hp)
        return user


user1 = User(hp=100, gun=AK())
user2 = User(hp=100, gun=TRG())

user2 = user1.attack(user2)
user2.hp  # 70&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;객체 지향 프로그래밍 설계 원칙(SOLID)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;단일 책임 원칙(SRP, Single Responsibility Principle)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 클래스는 각각 하나의 책임만 가져야 하는 원칙이다.&lt;/li&gt;
&lt;li&gt;예를 들어, 데이터 처리를 하는 클래스가 있다면 그 클래스는 데이터 처리에 관한 것만 수행하며 수정할 때도 데이터 처리에 관련된 수정이어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;개방-폐쇄 원칙(OCP, Open Closed Principle)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유지 보수 사항이 생기면 코드를 쉽게 확장할 수 있도록 하고 수정할 때는 닫혀 있어야 하는 원칙이다.&lt;/li&gt;
&lt;li&gt;즉, 기존의 코드는 잘 변경하지 않으면서도 확장은 쉽게할 수 있어야 한다.&lt;/li&gt;
&lt;li&gt;이는 이상적인 원칙인 듯 보이는데, 추상화와 상속을 잘 이용하여 구현해야 지킬 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변화가 예상되는 것을 미리 추상화하여 유연함을 얻고 상속을 적극 이용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ex) 코드1을 보면, &lt;u&gt;&lt;b&gt;User&lt;/b&gt;가 받는 무기는 언제든 변할 수 있다.&lt;/u&gt; 그러므로 이를 미리 추상화하여 'shot'이라는 공통의 기능을 갖는 &lt;b&gt;'Gun'&lt;/b&gt;이라는 클래스를 만들면, 무기를 다양하게 확장&amp;amp;변화시키려고 할 때 기존의 코드는 변경하지 않으면서 확장은 쉽게 할 수 있게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;리스코프 치환 원칙(LSP, Liskov Substitution Principle)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스는 '상속'이라는 특성을 가지고 있고, 상속을 통해 부모-자식 이라는 계층이 만들어진다. 이때 부모 객체 자리에 자식 객체를 넣어도 시스템이 문제없이 돌아가게 만들어야 하는 원칙이다.&lt;/li&gt;
&lt;li&gt;위에서 '&lt;b&gt;상속성&lt;/b&gt;'이라는 특성에 대해 말할 때 상위 클래스의 특성을 하위 클래스가 이어받아 &lt;b&gt;재사용하거나 확장&lt;/b&gt;할 수 있는 것이라고 했다. 즉, 원래 부모 클래스에서 있던 특성 자체는 그대로 자식 클래스에도 있어야 정상이므로 부모 객체 자리에 자식 객체를 대신 넣어도 프로그램은 정상적으로 돌아가야 하는 것이 맞다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터페이스 분리 원칙(ISP, Interface Segregation Principle)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나의 일반적인 인터페이스보다 구체적인 여러 개의 인터페이스를 만들어야 하는 원칙이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여기서 인터페이스는 python에서는 추상클래스라고 이해해도 될 듯 하다.&lt;/li&gt;
&lt;li&gt;즉 General한 추상클래스 하나를 만들지 말고 각 특성별로 추상클래스를 만들라는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ex) 코드1에서 AK는 Gun을 상속받지만, TRG는 Snipe 클래스를 상속받는다. Snipe 클래스 또한 Gun을 상속받는 것은 마찬가지지만 zoom이라는 추가 기능이 있기 때문에 Gun과는 따로 추상클래스를 만들어준 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;의존 역전 원칙(DIP, Dependency Inversion Principle)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자신보다 변하기 쉬운 것에 의존 하던 것을 추상화된 인터페이스나 상위 클래스를 두어 변하기 쉬운 것의 변화에 영향을 받지 않게 하는 원칙이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;u&gt;상위 계층은 하위 계층의 변화에 대한 구현으로부터 독립해야 한다!&amp;nbsp;&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;이 원칙은 개방-폐쇄 원칙과 관련되어 보인다. 위에서 보았던 예시처럼 User는 Gun이라는 추상화된 클래스를 input으로 받게 되어 변하기 쉬운 것의 변화에 영향을 받지 않게 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;u&gt;원칙이 지켜지기 위해서 추상화 계층은 다른 구현이 변해도 변하면 안된다는 기본 규칙을 지켜야한다.&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>python</category>
      <category>객체지향프로그래밍</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/63</guid>
      <comments>https://simpling.tistory.com/63#entry63comment</comments>
      <pubDate>Sun, 29 Jan 2023 17:56:13 +0900</pubDate>
    </item>
    <item>
      <title>Mask + Neural Network = ?</title>
      <link>https://simpling.tistory.com/59</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 딥러닝에서 mask는 pruning시에 사용하게 된다. 예를 들어 Lottery ticket hypothesis([1])의 경우 훈련을 마친 모델 파라미터의 magnitude를 기준으로 mask를 생성한다. 일정 값보다 작은 파라미터는 0, 나머지는 1인 mask가 생성된다. 다른 많은 pruning 방법에서도 binary mask를 생성하는 방식을 따른다. Mask는 pruning 뿐 아니라 다양한 task에서 사용되는데, 이번 글에서 그와 관련된 논문들에 대해 간단히 정리해보고자 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Mask is all you need&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Intro에서 언급한 것과 같이 mask는 pruning에서 많이 사용된다. Pruning에서 mask가 어떤 역할을 하는지 &lt;b&gt;Deconstructing &lt;/b&gt;&lt;b&gt;Lottery Tickets: Zeros, Signs, and the Supermask([3])&lt;/b&gt;에서 나오는데, 특히 이 논문에서는 supermask라는 흥미로운 개념이 등장한다. &lt;u&gt;Supermask는 모델을 학습시키지 않은 상태(init)에서 mask만 씌웠을 때 좋은 성능을 내도록 만드는 mask를 일컫는 용어다.&lt;/u&gt; 논문에서는 lottery ticket hypothesis의 방법을 이용해 구한 magnitude based mask를 initialize에 씌워도 원래의 initialize 모델보다 좋은 성능을 낸다는 것을 보여준다. 거기에 더해 모델은 그대로 두고 mask를 학습시키는 방법으로 모델을 학습시킬 때와 비슷한 성능을 낸다는 것을 보여준다. 이는 후속 논문 &lt;b&gt;Proving the Lottery Ticket&amp;nbsp;Hypothesis: Pruning is All You Need([5])&lt;/b&gt; 에서 증명된다. 적당한 조건을 만족하는 (over-parameterized, bounded weights 등) network에서는 weight를 optimize 하는 것과 pruning을 하는 것이 유사하다는 내용이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Continual learning, Transfer learning, Meta learning, Uncertainty estimation&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;1074&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AKAp1/btrTUEvAe9F/sqEF4IbGWwKKIkjGh0zlj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AKAp1/btrTUEvAe9F/sqEF4IbGWwKKIkjGh0zlj0/img.png&quot; data-alt=&quot;Fig 1. Supermasks in Superposition ([2])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AKAp1/btrTUEvAe9F/sqEF4IbGWwKKIkjGh0zlj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAKAp1%2FbtrTUEvAe9F%2FsqEF4IbGWwKKIkjGh0zlj0%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;1074&quot; height=&quot;472&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Supermasks in Superposition ([2])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Super mask는 initial network만으로 좋은 성능을 내도록 만들어 준다는 강력한 특징을 가진다. 이를 이용하여 &lt;b&gt;Supermasks in Superposition([2])&lt;/b&gt;에서는 continual learning에 적용한다. 기본이 되는 initial base network가 있고 supermasks를 implicitly 저장하고 있는 hopfield network가 있다. Hopfield network는 새로운 task가 주어졌을 때 output entropy가 작은 mask를 찾아준다. Mask를 이용한 다른 continual learning 방법으로 &lt;b&gt;Pack-Net([6])&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;1311&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUrONV/btrTYBLI8fh/Jz6z19E2SbFDDUtCi8GJtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUrONV/btrTYBLI8fh/Jz6z19E2SbFDDUtCi8GJtK/img.png&quot; data-alt=&quot;Fig 2. Pack-Net ([6])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUrONV/btrTYBLI8fh/Jz6z19E2SbFDDUtCi8GJtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUrONV%2FbtrTYBLI8fh%2FJz6z19E2SbFDDUtCi8GJtK%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;1311&quot; height=&quot;613&quot; data-origin-width=&quot;1311&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Pack-Net ([6])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Package network를 나타내는 말로 여러 task를 network 하나에 packaging 한다는 의미다. 학습 방법은 간단한데, 특정 task를 훈련한 모델에서 중요하지 않은(magnitude가 작은) parameter를 pruning 하고 재학습한 후, new task를 학습시켜가는 방식이다. 이렇게 되면 old task, new task를 어느 정도 잘 맞출 수 있게 된다. 이 아이디어로 transfer learning에 적용한 &lt;b&gt;PAC-net: a model pruning approach to inductive transfer learning([7])&lt;/b&gt;도 있다. 논문의 제목처럼 pretrained data에서 배운 prior knowledge를 유지하며 transfer learning 하려고 할 때 좋은 성능을 낸다.&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;987&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Mr5va/btrTRZ8nWfy/tNKyKOrZOEIdsPIyW2dMyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mr5va/btrTRZ8nWfy/tNKyKOrZOEIdsPIyW2dMyk/img.png&quot; data-alt=&quot;Fig 3. Meta-ticket ([8])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mr5va/btrTRZ8nWfy/tNKyKOrZOEIdsPIyW2dMyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMr5va%2FbtrTRZ8nWfy%2FtNKyKOrZOEIdsPIyW2dMyk%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;987&quot; height=&quot;316&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Meta-ticket ([8])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편 &lt;b&gt;Meta-ticket([8])&lt;/b&gt;에서는 기존 MAML 방식에서 mask를 사용하는 방법을 도입하여 meta-learning을 수행한다. Randomly intialized neural network에서 각 task별 mask를 만들어 sub-network(ticket)을 찾는 방식이다. 기본 MAML 보다는 잘 되지만, 2022년 논문임을 감안하면 성능이 엄청 좋진 않은 듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mask는 uncertainty estimates에도 사용된다. 보통 uncertainty estimation에서 baseline으로 이용되는 방법은 ensemble([11])이다. 또한 &lt;b&gt;MC-dropout([10])&lt;/b&gt;도 많이 사용되는데 mask를 이용한 방법이다. Ensemble은 좋은 성능을 보여주지만 학습을 여러 번 해야 한다는 치명적 단점이 존재한다. 한편 MC-dropout은 훈련을 한 번만 해도 되지만 성능이 좋지 못하다. 그 이유는 MC-dropout시 사용되는 mask들이 overlap 되는 부분이 많아 예측 값의 correlation이 높아서라고 알려져 있다. Ensemble은 서로 다른 initialize에서 시작하여 훈련하므로 다양한 inference 결과 값을 내놓기 때문에 좋은 성능을 낸다. 그래서 mask를 사용하되 overlap 되는 부분을 조절하는 방법을 제시한 &lt;b&gt;Mask ensembles for uncertainty estimation([9])&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;References&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://arxiv.org/abs/1803.03635&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1803.03635&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670660714773&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks&quot; data-og-description=&quot;Neural network pruning techniques can reduce the parameter counts of trained networks by over 90%, decreasing storage requirements and improving computational performance of inference without compromising accuracy. However, contemporary experience is that &quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1803.03635&quot; data-og-url=&quot;https://arxiv.org/abs/1803.03635v5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iU2rD/hyQQuI5Y6F/uhRFyoeGR9KXBgPWPki951/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1803.03635&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1803.03635&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iU2rD/hyQQuI5Y6F/uhRFyoeGR9KXBgPWPki951/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Neural network pruning techniques can reduce the parameter counts of trained networks by over 90%, decreasing storage requirements and improving computational performance of inference without compromising accuracy. However, contemporary experience is that&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] &lt;a href=&quot;https://arxiv.org/abs/2006.14769&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2006.14769&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670661037469&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Supermasks in Superposition&quot; data-og-description=&quot;We present the Supermasks in Superposition (SupSup) model, capable of sequentially learning thousands of tasks without catastrophic forgetting. Our approach uses a randomly initialized, fixed base network and for each task finds a subnetwork (supermask) th&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2006.14769&quot; data-og-url=&quot;https://arxiv.org/abs/2006.14769v3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lEy8j/hyQQpVkSi7/NJmk9la1U4VuQoqbXvP2jK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2006.14769&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2006.14769&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lEy8j/hyQQpVkSi7/NJmk9la1U4VuQoqbXvP2jK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Supermasks in Superposition&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We present the Supermasks in Superposition (SupSup) model, capable of sequentially learning thousands of tasks without catastrophic forgetting. Our approach uses a randomly initialized, fixed base network and for each task finds a subnetwork (supermask) th&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3] &lt;a href=&quot;https://arxiv.org/abs/1905.01067&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1905.01067&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670661343366&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Deconstructing Lottery Tickets: Zeros, Signs, and the Supermask&quot; data-og-description=&quot;The recent &amp;quot;Lottery Ticket Hypothesis&amp;quot; paper by Frankle &amp;amp; Carbin showed that a simple approach to creating sparse networks (keeping the large weights) results in models that are trainable from scratch, but only when starting from the same initial weights. &quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1905.01067&quot; data-og-url=&quot;https://arxiv.org/abs/1905.01067v4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sNuuz/hyQQvVxCGB/qc3sQzpUyUzvwaD2KihhKk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1905.01067&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1905.01067&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sNuuz/hyQQvVxCGB/qc3sQzpUyUzvwaD2KihhKk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Deconstructing Lottery Tickets: Zeros, Signs, and the Supermask&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The recent &quot;Lottery Ticket Hypothesis&quot; paper by Frankle &amp;amp; Carbin showed that a simple approach to creating sparse networks (keeping the large weights) results in models that are trainable from scratch, but only when starting from the same initial weights.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] &lt;a href=&quot;https://arxiv.org/abs/1911.13299&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1911.13299&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671341578572&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;What's Hidden in a Randomly Weighted Neural Network?&quot; data-og-description=&quot;Training a neural network is synonymous with learning the values of the weights. By contrast, we demonstrate that randomly weighted neural networks contain subnetworks which achieve impressive performance without ever training the weight values. Hidden in &quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1911.13299&quot; data-og-url=&quot;https://arxiv.org/abs/1911.13299v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/IocR6/hyQU02UsjK/SjZoc4ATi105ko4LPLF4qK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1911.13299&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1911.13299&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/IocR6/hyQU02UsjK/SjZoc4ATi105ko4LPLF4qK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;What's Hidden in a Randomly Weighted Neural Network?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Training a neural network is synonymous with learning the values of the weights. By contrast, we demonstrate that randomly weighted neural networks contain subnetworks which achieve impressive performance without ever training the weight values. Hidden in&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[5] &lt;a href=&quot;https://arxiv.org/abs/2002.00585&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2002.00585&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671341916804&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Proving the Lottery Ticket Hypothesis: Pruning is All You Need&quot; data-og-description=&quot;The lottery ticket hypothesis (Frankle and Carbin, 2018), states that a randomly-initialized network contains a small subnetwork such that, when trained in isolation, can compete with the performance of the original network. We prove an even stronger hypot&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2002.00585&quot; data-og-url=&quot;https://arxiv.org/abs/2002.00585v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/btOEcg/hyQWxx32gY/7AryYVilaAm0eW3jmbZlok/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2002.00585&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2002.00585&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/btOEcg/hyQWxx32gY/7AryYVilaAm0eW3jmbZlok/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Proving the Lottery Ticket Hypothesis: Pruning is All You Need&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The lottery ticket hypothesis (Frankle and Carbin, 2018), states that a randomly-initialized network contains a small subnetwork such that, when trained in isolation, can compete with the performance of the original network. We prove an even stronger hypot&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[6] &lt;a href=&quot;https://arxiv.org/abs/1711.05769&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1711.05769&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671345730901&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;PackNet: Adding Multiple Tasks to a Single Network by Iterative Pruning&quot; data-og-description=&quot;This paper presents a method for adding multiple tasks to a single deep neural network while avoiding catastrophic forgetting. Inspired by network pruning techniques, we exploit redundancies in large deep networks to free up parameters that can then be emp&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1711.05769&quot; data-og-url=&quot;https://arxiv.org/abs/1711.05769v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dN4VTm/hyQU6IS45t/KJeWoi2kKkvy2Zd8RgEk2K/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1711.05769&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1711.05769&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dN4VTm/hyQU6IS45t/KJeWoi2kKkvy2Zd8RgEk2K/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PackNet: Adding Multiple Tasks to a Single Network by Iterative Pruning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This paper presents a method for adding multiple tasks to a single deep neural network while avoiding catastrophic forgetting. Inspired by network pruning techniques, we exploit redundancies in large deep networks to free up parameters that can then be emp&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[7] &lt;a href=&quot;https://arxiv.org/abs/2206.05703&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2206.05703&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671346196456&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;PAC-Net: A Model Pruning Approach to Inductive Transfer Learning&quot; data-og-description=&quot;Inductive transfer learning aims to learn from a small amount of training data for the target task by utilizing a pre-trained model from the source task. Most strategies that involve large-scale deep learning models adopt initialization with the pre-traine&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2206.05703&quot; data-og-url=&quot;https://arxiv.org/abs/2206.05703v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/egyPIB/hyQUW0BvlR/tkeTK0BOUPF922uiHSUNJ0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2206.05703&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2206.05703&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/egyPIB/hyQUW0BvlR/tkeTK0BOUPF922uiHSUNJ0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PAC-Net: A Model Pruning Approach to Inductive Transfer Learning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Inductive transfer learning aims to learn from a small amount of training data for the target task by utilizing a pre-trained model from the source task. Most strategies that involve large-scale deep learning models adopt initialization with the pre-traine&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[8] &lt;a href=&quot;https://arxiv.org/pdf/2205.15619.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/pdf/2205.15619.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[9] &lt;a href=&quot;https://arxiv.org/abs/2012.08334&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2012.08334&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671347034903&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Masksembles for Uncertainty Estimation&quot; data-og-description=&quot;Deep neural networks have amply demonstrated their prowess but estimating the reliability of their predictions remains challenging. Deep Ensembles are widely considered as being one of the best methods for generating uncertainty estimates but are very expe&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2012.08334&quot; data-og-url=&quot;https://arxiv.org/abs/2012.08334v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bkcOt7/hyQUUBJfyz/2lONhvsGnOZrm1JLatcWZ1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2012.08334&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2012.08334&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bkcOt7/hyQUUBJfyz/2lONhvsGnOZrm1JLatcWZ1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Masksembles for Uncertainty Estimation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Deep neural networks have amply demonstrated their prowess but estimating the reliability of their predictions remains challenging. Deep Ensembles are widely considered as being one of the best methods for generating uncertainty estimates but are very expe&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[10] &lt;a href=&quot;https://arxiv.org/abs/1506.02142&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1506.02142&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671347099867&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning&quot; data-og-description=&quot;Deep learning tools have gained tremendous attention in applied machine learning. However such tools for regression and classification do not capture model uncertainty. In comparison, Bayesian models offer a mathematically grounded framework to reason abou&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1506.02142&quot; data-og-url=&quot;https://arxiv.org/abs/1506.02142v6&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bKywhd/hyQU78SCaR/FWHVZd5Y3SSEyboXsHINO0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1506.02142&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1506.02142&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bKywhd/hyQU78SCaR/FWHVZd5Y3SSEyboXsHINO0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Deep learning tools have gained tremendous attention in applied machine learning. However such tools for regression and classification do not capture model uncertainty. In comparison, Bayesian models offer a mathematically grounded framework to reason abou&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[11] &lt;a href=&quot;https://arxiv.org/abs/1612.01474&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1612.01474&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671347741860&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Simple and Scalable Predictive Uncertainty Estimation using Deep Ensembles&quot; data-og-description=&quot;Deep neural networks (NNs) are powerful black box predictors that have recently achieved impressive performance on a wide spectrum of tasks. Quantifying predictive uncertainty in NNs is a challenging and yet unsolved problem. Bayesian NNs, which learn a di&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1612.01474&quot; data-og-url=&quot;https://arxiv.org/abs/1612.01474v3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/T9AsV/hyQWAaxEGz/Qb845daPmQUbmLkjPjLTCK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1612.01474&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1612.01474&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/T9AsV/hyQWAaxEGz/Qb845daPmQUbmLkjPjLTCK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Simple and Scalable Predictive Uncertainty Estimation using Deep Ensembles&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Deep neural networks (NNs) are powerful black box predictors that have recently achieved impressive performance on a wide spectrum of tasks. Quantifying predictive uncertainty in NNs is a challenging and yet unsolved problem. Bayesian NNs, which learn a di&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>Mask</category>
      <category>pruning</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/59</guid>
      <comments>https://simpling.tistory.com/59#entry59comment</comments>
      <pubDate>Sun, 18 Dec 2022 16:23:22 +0900</pubDate>
    </item>
    <item>
      <title>Lottery ticket hypothesis 와 후속 연구 정리</title>
      <link>https://simpling.tistory.com/58</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI는 대용량의 데이터와 큰 모델을 기반으로 많은 발전을 이루고 있다. 하지만 많은 데이터와 거대 모델을 학습시키는 것은 많은 비용이 들게 된다. 큰 모델은 저장 용량이 클 뿐 아니라 예측을 할 때 많은 연산을 요구하기 때문에 효율적이지 않다. 특히 스마트폰 같은 작은 기계에서 사용하기에 적합하지 않다. 그에 따라 모델의 크기를 줄여 메모리를 줄이며 연산량을 줄여보자 하는 시도가 많이 이루어졌고 대표적인 분야로 knowledge distilation, &lt;u&gt;pruning&lt;/u&gt; 등이 있다. 이번 글에서는 pruning, 특히 ICLR 2019에서 best paper를 받은 &lt;u&gt;lottery ticket hypothesis&lt;/u&gt;에 대한 해석과 단점을 극복한 후속 논문들을 살펴볼 것이다.&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;*&lt;/b&gt; &lt;b&gt;Global pruning &amp;amp; Local pruning &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Global pruning은 pruning시 모든(혹은 일부) layer를 한 번에 비교하여 pruning 할 parameter를 정하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Local pruning은 각 layer별로 따로 비교하여 pruning 할 parameter를 정하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* One-shot pruning &amp;amp; Iterative pruning&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전체 pruning 하고 싶은 비율이 80%라고 할 때, one-shot 방법은 한 번에 80%를 pruning 하는 것이고, iterative 방법은 여러 번에 걸쳐 pruning을 해서 80%까지 도달하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* Layer-collapse&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- One-shot 방법이 iterative 방법에 비해 간단하고 cost가 적지만 보통 성능이 떨어진다. 주요한 요인으로 '&lt;u&gt;layer collapse&lt;/u&gt;'가 있다. Layer collapse는 여러 layer를 한 번에 비교하여 pruning을 해버리면 특정 layer의 parameter가 모두 사라지는 경우가 생길 수 있다. 그런 경우는 보통 magnitude를 사용하여 pruning 하는 경우에 발생하는데, 각 layer의 size에 따라 parameter 분포가 달라지기 때문이다. 예를 들어, layer size가 크면 0 근처의 parameter가 많게 되고 size가 작으면 넓게 분포하여 0 근처의 값은 적게 된다. 그렇게 되면 size가 큰 layer부터 pruning 되는 현상이 발생할 수 있게 된다. 다만 iterative 하게 pruning을 하게 되면 처음엔 큰 layer부터 pruning 할 수 있겠지만 그다음 iteration에서는 size가 작아졌으므로 덜 pruning 되는 식으로 balance를 맞출 수 있게 된다.([2])&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* Winning ticket&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Winning ticket은 lottery ticket 방법으로 얻어진 mask와 initial parameter $\theta_{0}$를 element-wise 하여 구한 model($m\odot\theta$)을 의미한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Lottery Ticket Hypothesis (LTH)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lottery ticket hypothesis는 &lt;a href=&quot;https://simpling.tistory.com/50&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;지난 글&lt;/a&gt;에서 설명한 적이 있다. 다시 간단히 설명하면,&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;b&gt;Initialize -&amp;gt; Train -&amp;gt; Pruning&lt;/b&gt;&lt;span&gt;&lt;b&gt;-&amp;gt; Initialize -&amp;gt; Train&lt;/b&gt;의 과정으로 학습시키는 방법이다. 2번째 initialize 시 pruning 된 곳을 제외하고는 첫 번째 initialize와 같이 해주는 것이 특징이다.&lt;/span&gt;&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;1249&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bD8R3m/btrSaItemue/2lL9BxkHsecSB6rcj06Bak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bD8R3m/btrSaItemue/2lL9BxkHsecSB6rcj06Bak/img.png&quot; data-alt=&quot;figure 1. algorithm of LTH ([1])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bD8R3m/btrSaItemue/2lL9BxkHsecSB6rcj06Bak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbD8R3m%2FbtrSaItemue%2F2lL9BxkHsecSB6rcj06Bak%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;1249&quot; height=&quot;205&quot; data-origin-width=&quot;1249&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 1. algorithm of LTH ([1])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 기존의 방법 혹은, pruning 하지 않는 모델을 넘는 성능을 보여주어 주목받은 논문으로 왜 이 방법이 잘 되는지에 대한 후속 논문과 단점을 극복한 후속 논문들이 많이 나오게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;LTH의 특징과 그에 따른 후속 논문 소개&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1.&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;훈련이 끝난 모델을 기준으로 pruning을 하고 다시 initialize를 하므로&lt;/span&gt; 훈련을 여러 번(최소 2번 이상) 반복해야 한다는 것이다.(LTH는 magnitude based pruning을 하므로 iterative pruning을 사용한다) 그러므로 computational cost가 너무 크다. 이는 치명적 한계이므로 후속 연구가 활발히 나오고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;* 후속 연구&lt;/b&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;- &lt;b&gt;Efficient Lottery Ticket Finding: Less Data is More&lt;/b&gt;([3]): 모든 데이터를 다 사용하면 오래 걸리니 중요한 일부 데이터(core set)만 골라서 훈련하는 방법이다. 데이터에는 학습하기 어렵거나 pruning 때 쉽게 잊어버리는 데이터가 있고 그런 데이터만 잘 골라 훈련시키면 효율적인 훈련이 될 수 있다. 따라서 논문에선 학습이 잘 안 되는 데이터 혹은 full model과&amp;nbsp; subnetworks가 서로 다르게 inference 하는 데이터를 고르는 방법을 제시한다.&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;Drawing Early-Bird Tickets: Towards More Efficient Training of Deep Networks&lt;/b&gt;([4]): Winning ticket이 학습 초반에 발견 가능하다는 사실을 발견한 논문이다. 이 사실을 이용하여 epoch 마다 mask를 만들고, 만들어지는 mask를 저장해두어 mask의 변화(distance)가 충분히 작아지면 종료하는 방법을 택한 것이다. 이렇게 하면 초반 epoch 까지만 학습시켜도 마지막까지 돌렸을 때 얻어지는 mask와 유사한 mask를 얻을 수 있다는 것이다.&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;One ticket to win them all: generalizing lottery ticket initializations across datasets and optimizers&lt;/b&gt;([6]): Image domain에서 특정 dataset으로 만든 winning ticket으로 다른 데이터에 학습시켜도 잘 적용된다는 내용이다. Fashion-MNIST, Cifar10, Cifar100, ImageNet으로 실험하였다. 만약 domain이 비슷하다면 한번 찾아놓은 winning ticket으로 훈련해보는 것도 좋은 방법일 듯하다.&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;SNIP: Single-shot Network Pruning based on Connection Sensitivity&lt;/b&gt;([7]): 이 논문은 학습 전 각 weight를 끊고(0으로 만들고) loss가 어떻게 변하는지 gradient를 얻어 전체 weight 중 작은 값을 갖는 것들을 pruning 하는 방법이다. 이러한 방법을 connection sensitivity라고 부른다. 학습을 하지 않아도 된다는 강력한 장점을 가지고 있지만, 각 weight를 고립시켜 끊어버리고 영향을 확인하는 방법이라 전체 network에서 중요한 connection도 끊을 수 있다는 단점이 있다.&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;PICKING WINNING TICKETS BEFORE TRAINING BY PRESERVING GRADIENT FLOW&lt;/b&gt;([8]): SNIP은 weights의 interaction을 고려하지 않고 pruning 하기 때문에 network flow에 중요한 weight를 pruning 할 수 있다. 이런 현상은 gradient norm 감소로 드러난다(practical 하게 찾음). 그래서 이 논문에서는 Gradient Signal Preservation(GraSP)라는 방법을 제안한다. SNIP과 다르게 weights 간의 interaction을 고려하기 위해 gradient 뿐 아니라 hessian matrix를 사용하는 것이 특징이다(hessian-gradient product). GraSP는 pruning 후에도 gradient norm의 감소를 최소화하여 gradient flow를 유지하는 방법이다. SNIP과 마찬가지로 학습을 하지 않아도 된다는 장점이 있다.&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;Winning the Lottery Ahead of Time: Efficient Early Network Pruning&lt;/b&gt;([10]): 기존 LTH에 대한 연구는 unstructured pruning에 집중되어 연구가 많이 되었으나, unstructured pruning은 weight를 0으로 만드는 것뿐이라 실질적인 메모리 개선이나 훈련 속도 증가, inference 속도 증가 등을 기대하긴 어려웠다. 그래서 &lt;span&gt;이 논문은 기존 논문들보다 structured pruning을 통해 좋은 구조를 찾고 성능까지 얻어내는 모델을 얻는 것을 목표로 한다. 우선 pruning은 학습을 아예 하지 않는 방법을 선택하진 않고, &lt;a href=&quot;https://simpling.tistory.com/56&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;NTK&lt;/a&gt;가 안정될 때까지(거의 변하지 않을 때까지) 학습한 후, pruning 하는 방법을 택한다. NTK는 network의 width가 매우 클 때 파라미터가 거의 변하지 않을 경우 변하지 않게 된다. 하지만 width가 작더라도 훈련이 충분히 된 상태에서 파라미터가 거의 변하지 않게 될 때도 NTK는 constant에 수렴한다. 이를 이용한 방법으로 structured pruning도 안정적으로 수행하여 좋은 성능을 보여준다. (이 방법은 init으로 rewind하진 않고 pruning 한 곳에서 추가 학습하는 방법을 취한다. [5]랑 관련되어 noise가 적은 곳에서 시작한다고 생각할 수 있을 듯하다.)&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;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Comparing Rewinding and Fine-tuning in Neural Network Pruning&lt;/b&gt;&lt;span&gt;([14]): (이 논문은 이전처럼 시간과 직접 관련된 내용은 아니다.) LTH이전 pruning에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;Initialize -&amp;gt; Train -&amp;gt; Pruning -&amp;gt; Finetuning&lt;/u&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;방법으로 pruning 했으나 이 방법보단 다시 rewind 하여 훈련하는 LTH의 성능이 더 좋음이 여러 논문에서 나타났다. 이 논문에서도 weight rewind가 성능이 좋다는 것을 보여주었다. 추가로 모델 대신 learning rate을 rewind 하고 이전처럼 pruning 후 finetuning 하는 방법도 비슷하게 좋은 성능을 보여준다고 주장하였다.&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;size18&quot;&gt;2. 작은 크기의 모델은 winning ticket을 찾기 수월하나, 크기가 큰 모델은 작은 learning rate를 사용하거나 warm up scheduling을 사용해야 찾을 수 있었다. (LTH는 큰 neural network 안에는 많은 sub network가 있고 그 안에는 원래의 모델보다 좋거나 비슷한 것(winning ticket)이 있다는 것을 가정한다. 모델이 클수록 sub network가 기하급수로 늘어나고 그중 winning ticket을 찾는 것은 더 어렵다고 해석할 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;* 후속 연구&lt;/b&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;- &lt;b&gt;Linear Mode Connectivity and the Lottery Ticket Hypothesis&lt;/b&gt;([5]): LTH의 저자가 작성한 논문으로, lottery ticket을 찾고 rewind 후 재학습할 때, 학습 초기의 SGD noise가 LTH의 성공을 좌우한다는 내용이다. 즉, iterative magnitude pruning(IMP)는 SGD noise가 적을 때 학습이 잘 된다는 이야기다. 다행히 SGD noise는 학습 초기에 안정화되어 이 시기가 지난 곳으로 rewind 하는 방법을 선택할 수 있다. 다만 이 논문의 한계로 그 지점을 찾을 수 있는 방법을 제시하지 않았고 그냥 여러 번의 실험을 통해 그런 곳이 존재한다는 사실만 보여준다. 이 연구는 기존에 warm up scheduling이 왜 잘 동작했는지 알려준다. 초기에 매우 작은 learning rate에서 시작하여 점점 커지는 이 방법은 학습 초기 큰 SGD noise에 강건한 최적화를 가능하게 하므로 IMP가 잘 작동하게 해 준 것이다. ([9] 참고)&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;Gradient Flow in Sparse Neural Networks and How Lottery Tickets Win&lt;/b&gt;([11]): 초기 SGD noise의 제어가 winning ticket을 찾는 것에 중요한 역할을 한다는 것을 보았다. 그런데 SGD noise가 큰 것이 무엇이 문제가 되는 것일까? [5] 논문에도 나왔지만, 초기 SGD noise가 큰 구간 이후부터 학습시킨 모델은 linear 하게 파라미터를 interpolation 했을 때 loss가 증가하지 않는 것으로 나왔다. 이를 linear mode connectivity라고 한다. [11] 논문에서도 이를 보여주는 데, 같은 initialize에서 다른 random seed를 사용하여 여러 번 학습했을 때 winning ticket을 잘 찾는 경우는 항상 거의 비슷한 (loss landscape) 영역으로 최적화가 된다는 것이다. 단순히 같은 곳으로 최적화가 된다는 것이 중요한 것은 아니고, winning ticket solution 영역으로 잘 찾아갔다고 생각하면 된다. 이는 &lt;a href=&quot;https://simpling.tistory.com/50&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;지난 글&lt;/a&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. LTH는 실제로 많은 경우에 좋은 성능을 보이는 것으로 보인다. 거기다 unstructured pruning의 경우까지 훈련 속도를 증가시킨다. 왜 winning ticket은 더 빠르게 converge 하고 좋은 성능을 낼 수 있을까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qls3l/btrScPFAe8U/IsIcDLjzyCwNuhKh4WHX51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qls3l/btrScPFAe8U/IsIcDLjzyCwNuhKh4WHX51/img.png&quot; data-alt=&quot;각 선은 남아있는 parameter의 비율에 따른 학습 진행 결과이다.([1])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qls3l/btrScPFAe8U/IsIcDLjzyCwNuhKh4WHX51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqls3l%2FbtrScPFAe8U%2FIsIcDLjzyCwNuhKh4WHX51%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;921&quot; height=&quot;290&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;각 선은 남아있는 parameter의 비율에 따른 학습 진행 결과이다.([1])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;* 후속 연구&lt;/b&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;- &lt;b&gt;Deconstructing Lottery Tickets: Zeros, Signs, and the Supermask&lt;/b&gt;([12]): LTH가 빠르게 학습이 될 수 있는 이유는, 학습이 완료된 모델의 parameter 중 magnitude가 작은 부분을 아예 0으로 만든 후, 나머지 부분만 원래의 initialize로 돌려놓고 재학습하는 것이 가장 주요한 원인이다. [12] 논문에서는 manitude가 작은 parameter를 0으로 만드는 것이 중요함을 실험으로 보여준다. 또한 random initialize + mask (winning ticket)가 random initialize만 한 모델보다 (둘 다 intialize임에도) 높은 성능을 보여준다. 그 이유는 mask 자체가 훈련이 끝난 optimal 한 모델을 참고하여 작은 파라미터를 0으로 무시하도록 만든 것이니 winning ticket은 random initialize보다 optimal에 좀 더 가까운 모델이라고 할 수 있기 때문이다. 결론적으로 winning ticket은 optimal에 더 가까운 포인트에서 훈련했으므로 같은 iteration 만큼 학습시켜도 그냥 random initi보다 더 많이 학습한 효과가 날 것이고 그에 따라 더 빨리 converge 하고 좋은 성능을 내는 것이라 생각된다([13]을 참고한 뇌피셜이다).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://arxiv.org/abs/1803.03635&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1803.03635&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669525879961&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks&quot; data-og-description=&quot;Neural network pruning techniques can reduce the parameter counts of trained networks by over 90%, decreasing storage requirements and improving computational performance of inference without compromising accuracy. However, contemporary experience is that &quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1803.03635&quot; data-og-url=&quot;https://arxiv.org/abs/1803.03635v5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bzXg7g/hyQH6at7xE/0ExLQv3o12cSQOw1UMramK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1803.03635&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1803.03635&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bzXg7g/hyQH6at7xE/0ExLQv3o12cSQOw1UMramK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Neural network pruning techniques can reduce the parameter counts of trained networks by over 90%, decreasing storage requirements and improving computational performance of inference without compromising accuracy. However, contemporary experience is that&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;a href=&quot;https://arxiv.org/abs/2006.05467?fbclid=IwAR3nVFrrgTmNhgv9TKJ7pezEgS-KIVyOFnw-3y_crZ3xsb8teGYZ6z9G9DY&quot;&gt;https://arxiv.org/abs/2006.05467?fbclid=IwAR3nVFrrgTmNhgv9TKJ7pezEgS-KIVyOFnw-3y_crZ3xsb8teGYZ6z9G9DY&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1669528767884&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Pruning neural networks without any data by iteratively conserving synaptic flow&quot; data-og-description=&quot;Pruning the parameters of deep neural networks has generated intense interest due to potential savings in time, memory and energy both during training and at test time. Recent works have identified, through an expensive sequence of training and pruning cyc&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2006.05467?fbclid=IwAR3nVFrrgTmNhgv9TKJ7pezEgS-KIVyOFnw-3y_crZ3xsb8teGYZ6z9G9DY&quot; data-og-url=&quot;https://arxiv.org/abs/2006.05467v3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bSimdE/hyQHWlrGVd/DVNR1JbWkY41Ei0X2bJPdk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2006.05467?fbclid=IwAR3nVFrrgTmNhgv9TKJ7pezEgS-KIVyOFnw-3y_crZ3xsb8teGYZ6z9G9DY&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2006.05467?fbclid=IwAR3nVFrrgTmNhgv9TKJ7pezEgS-KIVyOFnw-3y_crZ3xsb8teGYZ6z9G9DY&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bSimdE/hyQHWlrGVd/DVNR1JbWkY41Ei0X2bJPdk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Pruning neural networks without any data by iteratively conserving synaptic flow&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Pruning the parameters of deep neural networks has generated intense interest due to potential savings in time, memory and energy both during training and at test time. Recent works have identified, through an expensive sequence of training and pruning cyc&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3] &lt;a href=&quot;https://arxiv.org/abs/2106.03225&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2106.03225&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669543004298&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Efficient Lottery Ticket Finding: Less Data is More&quot; data-og-description=&quot;The lottery ticket hypothesis (LTH) reveals the existence of winning tickets (sparse but critical subnetworks) for dense networks, that can be trained in isolation from random initialization to match the latter's accuracies. However, finding winning ticket&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2106.03225&quot; data-og-url=&quot;https://arxiv.org/abs/2106.03225v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/4kLAl/hyQH7tUiW3/ODkkRGEkOmUDvARWxPilgk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2106.03225&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2106.03225&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/4kLAl/hyQH7tUiW3/ODkkRGEkOmUDvARWxPilgk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Efficient Lottery Ticket Finding: Less Data is More&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The lottery ticket hypothesis (LTH) reveals the existence of winning tickets (sparse but critical subnetworks) for dense networks, that can be trained in isolation from random initialization to match the latter's accuracies. However, finding winning ticket&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] &lt;a href=&quot;https://arxiv.org/abs/1909.11957&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1909.11957&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669543323450&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Drawing Early-Bird Tickets: Towards More Efficient Training of Deep Networks&quot; data-og-description=&quot;(Frankle &amp;amp; Carbin, 2019) shows that there exist winning tickets (small but critical subnetworks) for dense, randomly initialized networks, that can be trained alone to achieve comparable accuracies to the latter in a similar number of iterations. However, &quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1909.11957&quot; data-og-url=&quot;https://arxiv.org/abs/1909.11957v5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/obpdr/hyQH6Pkm0D/iwm4uNDZUsd9VPJQKkJmXk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1909.11957&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1909.11957&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/obpdr/hyQH6Pkm0D/iwm4uNDZUsd9VPJQKkJmXk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Drawing Early-Bird Tickets: Towards More Efficient Training of Deep Networks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;(Frankle &amp;amp; Carbin, 2019) shows that there exist winning tickets (small but critical subnetworks) for dense, randomly initialized networks, that can be trained alone to achieve comparable accuracies to the latter in a similar number of iterations. However,&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[5] &lt;a href=&quot;https://arxiv.org/abs/1912.05671&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1912.05671&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669543679444&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Linear Mode Connectivity and the Lottery Ticket Hypothesis&quot; data-og-description=&quot;We study whether a neural network optimizes to the same, linearly connected minimum under different samples of SGD noise (e.g., random data order and augmentation). We find that standard vision models become stable to SGD noise in this way early in trainin&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1912.05671&quot; data-og-url=&quot;https://arxiv.org/abs/1912.05671v4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/djmx8t/hyQH0hgJjt/0kpk7hr0fB258ku8llMSN0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1912.05671&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1912.05671&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/djmx8t/hyQH0hgJjt/0kpk7hr0fB258ku8llMSN0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Linear Mode Connectivity and the Lottery Ticket Hypothesis&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;We study whether a neural network optimizes to the same, linearly connected minimum under different samples of SGD noise (e.g., random data order and augmentation). We find that standard vision models become stable to SGD noise in this way early in trainin&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[6] &lt;a href=&quot;https://arxiv.org/abs/1906.02773&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1906.02773&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669545127445&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;One ticket to win them all: generalizing lottery ticket initializations across datasets and optimizers&quot; data-og-description=&quot;The success of lottery ticket initializations (Frankle and Carbin, 2019) suggests that small, sparsified networks can be trained so long as the network is initialized appropriately. Unfortunately, finding these &amp;quot;winning ticket&amp;quot; initializations is computati&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1906.02773&quot; data-og-url=&quot;https://arxiv.org/abs/1906.02773v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cjle0D/hyQH7OgPFP/5X9Me9TTS44D1qijaXnAN1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1906.02773&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1906.02773&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cjle0D/hyQH7OgPFP/5X9Me9TTS44D1qijaXnAN1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;One ticket to win them all: generalizing lottery ticket initializations across datasets and optimizers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The success of lottery ticket initializations (Frankle and Carbin, 2019) suggests that small, sparsified networks can be trained so long as the network is initialized appropriately. Unfortunately, finding these &quot;winning ticket&quot; initializations is computati&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[7] &lt;a href=&quot;https://arxiv.org/abs/1810.02340&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1810.02340&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669547392505&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;SNIP: Single-shot Network Pruning based on Connection Sensitivity&quot; data-og-description=&quot;Pruning large neural networks while maintaining their performance is often desirable due to the reduced space and time complexity. In existing methods, pruning is done within an iterative optimization procedure with either heuristically designed pruning sc&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1810.02340&quot; data-og-url=&quot;https://arxiv.org/abs/1810.02340v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dHioRZ/hyQH530n8p/L99LVB2bJbGz7kZ7tXU9Ek/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1810.02340&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1810.02340&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dHioRZ/hyQH530n8p/L99LVB2bJbGz7kZ7tXU9Ek/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SNIP: Single-shot Network Pruning based on Connection Sensitivity&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Pruning large neural networks while maintaining their performance is often desirable due to the reduced space and time complexity. In existing methods, pruning is done within an iterative optimization procedure with either heuristically designed pruning sc&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[8] &lt;a href=&quot;https://arxiv.org/abs/2002.07376&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2002.07376&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670041936590&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Picking Winning Tickets Before Training by Preserving Gradient Flow&quot; data-og-description=&quot;Overparameterization has been shown to benefit both the optimization and generalization of neural networks, but large networks are resource hungry at both training and test time. Network pruning can reduce test-time resource requirements, but is typically &quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2002.07376&quot; data-og-url=&quot;https://arxiv.org/abs/2002.07376v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bKxeIU/hyQMuBO8AZ/MprzH2nkUtKfHetZgF5420/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2002.07376&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2002.07376&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bKxeIU/hyQMuBO8AZ/MprzH2nkUtKfHetZgF5420/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Picking Winning Tickets Before Training by Preserving Gradient Flow&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Overparameterization has been shown to benefit both the optimization and generalization of neural networks, but large networks are resource hungry at both training and test time. Network pruning can reduce test-time resource requirements, but is typically&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[9] &lt;a href=&quot;https://arxiv.org/abs/1903.01611&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1903.01611&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670041966592&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Stabilizing the Lottery Ticket Hypothesis&quot; data-og-description=&quot;Pruning is a well-established technique for removing unnecessary structure from neural networks after training to improve the performance of inference. Several recent results have explored the possibility of pruning at initialization time to provide simila&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1903.01611&quot; data-og-url=&quot;https://arxiv.org/abs/1903.01611v3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bNHS1P/hyQMrrz44p/QxaZwhQkcxBpJP7Yl7y9E0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1903.01611&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1903.01611&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bNHS1P/hyQMrrz44p/QxaZwhQkcxBpJP7Yl7y9E0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Stabilizing the Lottery Ticket Hypothesis&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Pruning is a well-established technique for removing unnecessary structure from neural networks after training to improve the performance of inference. Several recent results have explored the possibility of pruning at initialization time to provide simila&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[10] &lt;a href=&quot;https://arxiv.org/abs/2206.10451&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2206.10451&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670042801354&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Winning the Lottery Ahead of Time: Efficient Early Network Pruning&quot; data-og-description=&quot;Pruning, the task of sparsifying deep neural networks, received increasing attention recently. Although state-of-the-art pruning methods extract highly sparse models, they neglect two main challenges: (1) the process of finding these sparse models is often&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2206.10451&quot; data-og-url=&quot;https://arxiv.org/abs/2206.10451v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cNvOFk/hyQMxZCZjk/kmot0osi04hUmj9liswxiK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2206.10451&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2206.10451&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cNvOFk/hyQMxZCZjk/kmot0osi04hUmj9liswxiK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Winning the Lottery Ahead of Time: Efficient Early Network Pruning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Pruning, the task of sparsifying deep neural networks, received increasing attention recently. Although state-of-the-art pruning methods extract highly sparse models, they neglect two main challenges: (1) the process of finding these sparse models is often&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[11] &lt;a href=&quot;https://arxiv.org/abs/2010.03533&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2010.03533&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670051009513&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Gradient Flow in Sparse Neural Networks and How Lottery Tickets Win&quot; data-og-description=&quot;Sparse Neural Networks (NNs) can match the generalization of dense NNs using a fraction of the compute/storage for inference, and also have the potential to enable efficient training. However, naively training unstructured sparse NNs from random initializa&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2010.03533&quot; data-og-url=&quot;https://arxiv.org/abs/2010.03533v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dJnDZS/hyQL71AxhK/TVHUBk0PDRln0bwVuAjWg0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2010.03533&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2010.03533&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dJnDZS/hyQL71AxhK/TVHUBk0PDRln0bwVuAjWg0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Gradient Flow in Sparse Neural Networks and How Lottery Tickets Win&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Sparse Neural Networks (NNs) can match the generalization of dense NNs using a fraction of the compute/storage for inference, and also have the potential to enable efficient training. However, naively training unstructured sparse NNs from random initializa&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[12] &lt;a href=&quot;https://arxiv.org/abs/1905.01067&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1905.01067&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670052919037&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Deconstructing Lottery Tickets: Zeros, Signs, and the Supermask&quot; data-og-description=&quot;The recent &amp;quot;Lottery Ticket Hypothesis&amp;quot; paper by Frankle &amp;amp; Carbin showed that a simple approach to creating sparse networks (keeping the large weights) results in models that are trainable from scratch, but only when starting from the same initial weights. &quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1905.01067&quot; data-og-url=&quot;https://arxiv.org/abs/1905.01067v4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ppk4o/hyQMCtd0Jz/YNfXEce61E45nyl2YBhqXk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1905.01067&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1905.01067&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ppk4o/hyQMCtd0Jz/YNfXEce61E45nyl2YBhqXk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Deconstructing Lottery Tickets: Zeros, Signs, and the Supermask&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The recent &quot;Lottery Ticket Hypothesis&quot; paper by Frankle &amp;amp; Carbin showed that a simple approach to creating sparse networks (keeping the large weights) results in models that are trainable from scratch, but only when starting from the same initial weights.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[13] &lt;a href=&quot;https://arxiv.org/abs/1705.08741&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1705.08741&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670053767886&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Train longer, generalize better: closing the generalization gap in large batch training of neural networks&quot; data-og-description=&quot;Background: Deep learning models are typically trained using stochastic gradient descent or one of its variants. These methods update the weights using their gradient, estimated from a small fraction of the training data. It has been observed that when usi&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1705.08741&quot; data-og-url=&quot;https://arxiv.org/abs/1705.08741v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/PbTxw/hyQMyK7RNa/5WdMExpYFqkWItrrzy2lOk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1705.08741&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1705.08741&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/PbTxw/hyQMyK7RNa/5WdMExpYFqkWItrrzy2lOk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Train longer, generalize better: closing the generalization gap in large batch training of neural networks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Background: Deep learning models are typically trained using stochastic gradient descent or one of its variants. These methods update the weights using their gradient, estimated from a small fraction of the training data. It has been observed that when usi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[14] &lt;a href=&quot;https://arxiv.org/abs/2003.02389&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2003.02389&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670054486423&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Comparing Rewinding and Fine-tuning in Neural Network Pruning&quot; data-og-description=&quot;Many neural network pruning algorithms proceed in three steps: train the network to completion, remove unwanted structure to compress the network, and retrain the remaining structure to recover lost accuracy. The standard retraining technique, fine-tuning,&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2003.02389&quot; data-og-url=&quot;https://arxiv.org/abs/2003.02389v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/CF6UK/hyQMuhFHZl/WhXAiQaKFNjV6HrqnDAfnK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2003.02389&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2003.02389&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/CF6UK/hyQMuhFHZl/WhXAiQaKFNjV6HrqnDAfnK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Comparing Rewinding and Fine-tuning in Neural Network Pruning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Many neural network pruning algorithms proceed in three steps: train the network to completion, remove unwanted structure to compress the network, and retrain the remaining structure to recover lost accuracy. The standard retraining technique, fine-tuning,&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/58</guid>
      <comments>https://simpling.tistory.com/58#entry58comment</comments>
      <pubDate>Sun, 27 Nov 2022 17:34:17 +0900</pubDate>
    </item>
    <item>
      <title>Neural Tangent Kernel 리뷰</title>
      <link>https://simpling.tistory.com/56</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 리뷰할&amp;nbsp;&amp;nbsp;&lt;a href=&quot;https://arxiv.org/abs/1806.07572&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Neural Tangent Kernel (NTK)&lt;/a&gt; 논문은 NIPS 2018에 실린 논문으로 많은 인용수를 자랑하는 파급력 높은 논문입니다. 하지만 논문을 이해하려면 수학적 배경지식이 많이 필요해서 읽기가 어렵습니다. 다행히 설명을 잘해놓은 &lt;a href=&quot;https://rajatvd.github.io/NTK/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;외국 블로그([2])&lt;/a&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;&lt;u&gt;이 논문은 2 hidden layer와 infinite nodes의 neural network는 linear model로 근사하여 생각할 수 있고, 그 덕분에 문제를 convex 하게 만들어 해가 반드시 존재한다는 것을 보여줍니다.&lt;/u&gt; 어떻게 linear model로 근사하여 생각할 수 있다는 것인지 차근차근 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Taylor Expansion&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Taylor expansion은 매우 작은 영역에서 함수를 근사하는 방법입니다. Update된 parameter $ w $와 initial parameter $ w_{0} $에 대해 1차 derivative까지 근사하여 taylor expansion 하면 아래와 같이 나타낼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ y(w) \approx y(w_{0}) + \triangledown_{w} y(w_{0})^{T} (w-w_{0}) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 언급했듯 taylor expansion은 매우 작은 영역에서 잘 성립하는 방법입니다. 위의 식이 성립하려면 initial parameter $w_{0}$와 $w$ 사이의 차이가 별로 나지 않아야 합니다. 흥미롭게도 $w$와 $w_{0}$는 network width가 커질수록(node가 많아질수록) 그 차이가 줄어듭니다. 이는 직관적으로 당연한 결과인데, &lt;span&gt;parameter가 많아질수록 조금의 변화로 큰 변화를 일으킬 수 있기 때문입니다. 이에 대한 실험 결과가 블로그([2])에 나와있어 figure 1에 가져왔습니다.&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;1770&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tmabG/btrEDRCx9o2/GIO2k87tujNdK2m3FEcLX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tmabG/btrEDRCx9o2/GIO2k87tujNdK2m3FEcLX0/img.png&quot; data-alt=&quot;Figure 1. Width가 커질수록 loss가 빠르게 줄어들고(left) $ w $와 $ w_{0} $의 차이가 작은 것을(right) 볼 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tmabG/btrEDRCx9o2/GIO2k87tujNdK2m3FEcLX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtmabG%2FbtrEDRCx9o2%2FGIO2k87tujNdK2m3FEcLX0%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;694&quot; height=&quot;284&quot; data-origin-width=&quot;1770&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1. Width가 커질수록 loss가 빠르게 줄어들고(left) $ w $와 $ w_{0} $의 차이가 작은 것을(right) 볼 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;왼쪽 그림의 x축은 업데이트 횟수이고 y축은 training loss이며 width가 다를 때 어떻게 변화하는지 보여줍니다. Width가 클수록 적은 step만으로 training loss가 빠르게 작아짐을 볼 수 있습니다. 오른쪽 그림의 y축은 $ w_{0} $로부터 n번 update 한 parameter $ w_{n} $까지의 거리를 나타냅니다. Width가 클수록 움직인 거리가 작아짐을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;Gradient Flow&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Width가 infinite이면 taylor expansion으로 근사하는 것을 사용할 수 있다는 것을 알 수 있습니다. 이제 gradient flow를 전개하여 width가 infinite이면 해가 반드시 존재한다는 것을 보이겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Parameter $w$가 업데이트 되는 것은 다음과 같이 표현할 수 있습니다. ($\eta$는 learning rate)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;$$ w_{k+1} = w_{k} - \eta \triangledown_{w} L(w_{k}) $$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;$$ \frac{w_{k+1}-w_{k}}{\eta} = -\triangledown_{w} L(w_{k})&amp;nbsp; $$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;$ \eta $(&lt;span&gt;learning rate)&lt;/span&gt;가 매우 작아 0에 근사하여 continuous하게 update 한다고 생각하면 다음과 같이 표현할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;$$ \frac {dw(t)}{dt} = -\triangledown_{w} L(w(t)) $$&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여기서 dt는 보통 time에 대한 변화량을 나타내는데, continuous 하게 변화한다고 생각하여 그렇게 표현한 것뿐입니다. 실제로는 update 횟수라고 생각하면 됩니다. 이제 $\frac {dw(t)}{dt} = \dot {w} $ 로 나타내서 표현하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;$$ \dot{w} = -\triangledown_{w} L(w(t)) $$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Loss function은 mean squared error로 가정하여 gradient를 계산하면 다음과 같습니다. ($\bar {y}$는 label)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;$$ \dot{w} = -\triangledown y(w)(y(w)-\bar {y}) $$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 y의 변화량 $ \dot {y(w)} $를 chain rule로 나타내고 위에서 구한 $\dot {w}$를 대입하면 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;$$ \dot{y(w)} = \triangledown y(w)^{T}\dot {w} = -\triangledown y(w)^{T} \triangledown y(w) (y(w)-\bar {y}) $$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;위의 식에서 $ \triangledown y(w) $는 parameter에 대한 gradient이므로 non-linear입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$\triangledown y(w)$를 kernel의 basis function $\phi(x)$라고 생각하면 kernel $ H(w)=\triangledown y(w)^{T} \triangledown y(w) $라고 치환해줄 수 있습니다. 이때 &lt;u&gt;H(w)를 Neural Tangent Kernel(NTK)라고 합니다&lt;/u&gt;!! (이렇게 kernel로 치환하여 생각하면 non-linear 하여 풀지 못했던 식을 쉽게 만들어 주어 해가 존재함을 보일 때 중요하게 사용됩니다.) 또한 위에서 본 것처럼 width가 무한 대면 $ \triangledown y(w(t)) \approx \triangledown y(w_{0}) $이므로 $ H(w(t)) \approx H(w_{0}) $ 가 성립합니다. 정리해서 다시 쓰면 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \dot {y(w)} = -H(w_{0})(y(w)-\bar {y}) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ y(w)-\bar {y} $를 $u$라고 치환하면 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \dot {u} = -H(w_{0})u $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ u(t) = u(0) e^{-H(w_{0})t} $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, $H(w_{0})$가 positive definite 하여(논문에서 증명) t가 증가할 때 $u(t)$는 항상 0으로 가게 됩니다!! $u(t)$는 prediction - label이었으므로 training loss가 0이 된다는 것을 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 Neural Tanget Kernel을 사용하여 width가 무한대일 때 loss를 0으로 만드는 해가 반드시 존재함을 보였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1806.07572&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[1] https://arxiv.org/abs/1806.07572&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1655022777850&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Neural Tangent Kernel: Convergence and Generalization in Neural Networks&quot; data-og-description=&quot;At initialization, artificial neural networks (ANNs) are equivalent to Gaussian processes in the infinite-width limit, thus connecting them to kernel methods. We prove that the evolution of an ANN during training can also be described by a kernel: during g&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1806.07572&quot; data-og-url=&quot;https://arxiv.org/abs/1806.07572v4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dmhYi2/hyOJEtdMBM/HHNvWRLgtjIKaGorj8FDd0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1806.07572&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1806.07572&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dmhYi2/hyOJEtdMBM/HHNvWRLgtjIKaGorj8FDd0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Neural Tangent Kernel: Convergence and Generalization in Neural Networks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;At initialization, artificial neural networks (ANNs) are equivalent to Gaussian processes in the infinite-width limit, thus connecting them to kernel methods. We prove that the evolution of an ANN during training can also be described by a kernel: during g&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rajatvd.github.io/NTK/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[2] https://rajatvd.github.io/NTK/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1655022767921&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Understanding the Neural Tangent Kernel&quot; data-og-description=&quot;My attempt at distilling the ideas behind the neural tangent kernel that is making waves in recent theoretical deep learning research.&quot; data-og-host=&quot;rajatvd.github.io&quot; data-og-source-url=&quot;https://rajatvd.github.io/NTK/&quot; data-og-url=&quot;https://rajatvd.github.io/NTK/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bV0Vwe/hyOJzMcBYZ/TcHV9j5QPkoXILvKvB0CWk/img.png?width=1073&amp;amp;height=586&amp;amp;face=0_0_1073_586,https://scrap.kakaocdn.net/dn/bbgHQn/hyOJyNiKq3/9mWeJexlhfr353A8pKKKlk/img.png?width=782&amp;amp;height=577&amp;amp;face=0_0_782_577,https://scrap.kakaocdn.net/dn/plC4D/hyOJHQ0nUj/FT1PkkLWn4j0qfILoqs9U1/img.png?width=749&amp;amp;height=577&amp;amp;face=0_0_749_577&quot;&gt;&lt;a href=&quot;https://rajatvd.github.io/NTK/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rajatvd.github.io/NTK/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bV0Vwe/hyOJzMcBYZ/TcHV9j5QPkoXILvKvB0CWk/img.png?width=1073&amp;amp;height=586&amp;amp;face=0_0_1073_586,https://scrap.kakaocdn.net/dn/bbgHQn/hyOJyNiKq3/9mWeJexlhfr353A8pKKKlk/img.png?width=782&amp;amp;height=577&amp;amp;face=0_0_782_577,https://scrap.kakaocdn.net/dn/plC4D/hyOJHQ0nUj/FT1PkkLWn4j0qfILoqs9U1/img.png?width=749&amp;amp;height=577&amp;amp;face=0_0_749_577');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Understanding the Neural Tangent Kernel&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;My attempt at distilling the ideas behind the neural tangent kernel that is making waves in recent theoretical deep learning research.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rajatvd.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/56</guid>
      <comments>https://simpling.tistory.com/56#entry56comment</comments>
      <pubDate>Sun, 12 Jun 2022 18:55:54 +0900</pubDate>
    </item>
    <item>
      <title>강화학습 기초 다지기 (2) - 강화학습 문제 풀이 기법 (DP, MC, TD)</title>
      <link>https://simpling.tistory.com/55</link>
      <description>&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;첫 번째로 환경에 대해서 알 때 &lt;b&gt;동적 계획법(Dynamic Programming: DP)&lt;/b&gt; 방법을 사용할 수 있다. '환경'에 대해서 안다는 것은 상태와 행동에 대한 보상 함수 R과 상태천이 행렬 P를 안다는 의미다. 이는 현실적이지 않다는 단점이 존재하지만 매우 효율적이고 문제를 해결하기 쉽다는 장점이 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동적 계획법은 큰 문제를 분할한 작은 문제의 최적 값이 큰 문제에서도 최적 값이어야 한다. 또한 큰 문제의 해를 구하기 위해서, 작은 문제의 최적 해를 재사용할 수 있어야 한다. &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이때, &lt;b&gt;정책 평가(Policy Evaluation: PE)&lt;/b&gt;, &lt;b&gt;정책 개선(Policy Improvement: PI)&lt;/b&gt;을 사용하여 해결한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;정책 평가 알고리즘은 $ V_{0}^{\pi}(s) $에서 시작하며, 반복해서 $ V_{t+1}^{\pi}(s) \leftarrow \sum_{a \in \textit {A}} \pi(a|s) (R_{s}^{a} + \gamma \sum_{s' \in S} P_{ss'}^{a} V_{t}^{\pi} (s')) $를 만들어내며 $ V_{t}^{\pi}(s) $와 비교하여 error가 일정 이하일 때까지 반복하는 것을 실행한다. 여기서 가치 함수 $ V^{\pi}(s) $를 받아 정책 개선 알고리즘을 실행한다. 정책 개선 알고리즘은&amp;nbsp; $ Q^{\pi}(s, a) = R_{s}^{a} + \gamma \sum_{s' \in S} P_{ss'}^{a} V^{\pi} (s') $를 이용해 $Q^{\pi}(s, a)$를 계산하고 이를 이용해 정책 $ \pi $를 $ \pi^{'} $로 업데이트한다. 마지막으로 이 두 알고리즘을 계속 반복하는 것을 &lt;b&gt;정책 반복(Policy iteration)이라고&lt;/b&gt; 부른다. 정책 개선 정리로 얻은 개선된 정책 $ \pi^{'} $이 $ \pi $ 보다 더 좋다는 것은 정책 개선 정리에 의해 증명되어 있으나 여기서는 생략한다. &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&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;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;한편 환경(R, P)에 대해 모르는 대부분의 현실적 상황에서는 동적 계획법을 사용할 수 없다. 이때는 Monte Carlo(MC), Temporal-Difference(TD) 같은 방법을 사용할 수 있다. TD기법은 &lt;span&gt;현재 상태가 다음 상태에 영향을 주는 방법으로 Bootstrap 방법이다. 한편 MC 방법은 직접 계산하기 어려운 값을 많은 시행을 통해 추산하는 방법이다.&lt;/span&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;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span&gt;먼저 MC 방법은 $G_{t}$를 여러 번 시뮬레이션해서 그 시뮬레이션 값의 평균을 계산하면 $ V_{\pi}(s) $와 비슷해진다는 점을 이용하는 것이다. MC는 불편 추정기법이라 시뮬레이션 횟수가 적으면 추정치의 불확실성이 커지며 횟수가 늘어날수록 분산이 줄고 참 값과 같아진다. 시뮬레이션 하나하나를 에피소드라고 부르며 에피소드마다 (상태, 행동, 보상)을 정책 $ \pi $를 이용해 생성한다. 이를 이용해 각 state에 대한 평균을 구해 $ V^{\pi}(s) $를 계산한다. MC를 여러 번 반복할 때 기존의 $ G_{t} $를 이용해야 하므로 메모리가 많이 필요할 수 있다. 그래서 다음과 같은 방법을 사용한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span&gt;$$ \begin {align*} \mu_{k} &amp;amp;= \frac {1}{k} \sum_{j=1}^{k} x_{j} \\ &amp;amp;= \frac {1}{k} (x_{k}+\sum_{j=1}^{k-1} x_{j}) \\ &amp;amp;= \frac {1}{k} (x_{k}+(k-1)\mu_{k-1}) \\ &amp;amp;= \mu_{k-1} + \frac {1}{k} ( x_{k} - \mu_{k-1})&amp;nbsp; &amp;nbsp;\end {align*} $$&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span&gt;이는 기존에 알던 지식 + 새로 알게 된 지식으로 해석할 수 있다. 기존 지식을 다 저장하지 말고 $\mu_{k-1}$만 알고 있다면 메모리를 많이 쓰지 않을 수 있다. MC 방법은 환경에 대한 지식이 필요 없고 직관적이라는 장점이 있다. 다만 episode가 끝나야 적용할 수 있고, 각 상태와 행동의 관계에 대해 전혀 활용하지 않으며 정확한 값을 얻기 위해서는 시뮬레이션을 여러 번 반복해야 한다는 단점이 존재한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span&gt;세 번째로, Temporal-Difference(TD) 방법은 현재 알고 있는 값을 활용해 모르는 값을 추정하는 방법이다. MC와 같이 환경에 대한 지식이 필요 없으며, DP처럼 각 상태와 행동의 관계를 최대한 이용해 계산량을 줄일 수 있다는 장점이 있다. 대신 불편 추정량은 아니고 markovian을 가정하므로 추산 오차가 발생할 수 있다. MC 비해서는 추정치의 분산이 낮아 빠른 속도로 좋은 추정치를 얻을 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span&gt;MC 방법과 달리 markov를 가정하여 $ G_{t} = R_{t+1} + \gamma V(S_{t+1}) $으로 Return을 구할 수 있다. 이런 경우를 1-step TD라고 부르며 n-step TD의 경우 $ G_{t}^{(n)} = R_{t+1} + \gamma R_{t+2} +.. + \gamma ^{n-1} R_{t+n} + \gamma^{n} V(S_{t+n}) $ 로 나타낼 수 있다. Return을 이용하여 $ V(s) \leftarrow V(s) + \alpha (G_{t} - V(s)) $ 로 가치 함수를 업데이트한다. 이 식은 MC에서도 사용할 수 있는데, 적당히 작은 $ \alpha $에 대해 참값으로 수렴함이 증명되어 있다. 식을 보면 $ V(s) $가 $ R_{t+1} + \gamma V(S_{t+1}) $에 가깝게 만드는 것이 목표다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/강화학습</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/55</guid>
      <comments>https://simpling.tistory.com/55#entry55comment</comments>
      <pubDate>Sun, 8 May 2022 18:39:35 +0900</pubDate>
    </item>
    <item>
      <title>강화학습 기초 다지기 (1) - 마르코프</title>
      <link>https://simpling.tistory.com/54</link>
      <description>&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마르코프 특성 (Markov Property)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'마르코프 하다'라는 것은 미래 상태 $s_{t+1}$은 현재 상태 $s_{t}$에만 의존한다는 것을 의미한다. 다른 말로 하면 현재 상태를 알면, 그 이전의 모든 역사를 아는 것과 동일하게 미래 상태 $s_{t+1}$를 추론할 수 있다는 의미다. 이를 수식으로 표현하면 다음과 같이 나타낼 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ P(s_{t+1}|s_{t}) = P(s_{t+1}|s_{t}, s_{t-1},..., s_{0}) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마르코프 과정 (Markov Process - MP : $&amp;lt;S, P&amp;gt;$)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마르코프 특성을 만족하는 상태의 반복을 마르코프 과정(Markov process)이라고 부른다. 마르코프 특성은 상태 집합 S와 상태 천이 행렬 P으로 이루어진 튜플이다. S는 모든 상태에 대한 집합을 의미하고, 상태 천이 행렬은 현재 상태에서 다음 상태로 이동할 확률을 표현한 행렬이다. 상태가 n 개라면 상태 천이 행렬은 $n \times n$이 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마르코프 보상 과정 (Markov Reward Process - MRP : $&amp;lt;S, P, R,\gamma&amp;gt;$)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마르코프 보상 과정은 마르코프 과정에서 보상 함수 $\textit {R}$ $(R: \textit {S} \to \mathbb {R})$과 감가율 $\gamma \in [0,1]$를 포함한 것이다.&amp;nbsp;보상 함수와 감가율을 알기 위해서는 리턴 $G_{t}$ 개념을 알아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리턴 $G_{t}$는 현재 시점 t부터 전체 미래에 대한 감가 된 보상의 합이다. 수식으로 나타내면 다음과 같이 나타낼 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ G_{t} = R_{t+1} + \gamma R_{t+2} + \gamma^{2} R_{t+3} +... = \sum_{a=1}^{\infty} \gamma^{a-1} R_{t+a} $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 나중에 강화 학습 agent가 현재 상태로부터 미래에 일을 고려하여 판단할 수 있게 해주는 좋은 장치로 사용된다. 보상은 agent가 특정 행동을 했을 때 줄 수 있고 감가율 $\gamma$를 조절하며 미래에 대한 보상을 조절할 수 있다. 감가율은 보상이 무한히 커지는 것을 방지하며 너무 먼 미래에 대한 이익보단 가까운 미래에 대한 보상을 최대화하기 위해 사용된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;가치 함수와 벨만 항등식&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가치 함수 V(s)는 현재 상태 s에서 미래의 감가 된 보상의 합 ($G_{t}$)의 기댓값을 의미한다(즉, 리턴의 기댓값). 이는 수식으로 다음과 같이 표현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ V(s) = \mathbb {E}[G_{t}|S_{t}=s] $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가치 함수는 벨만 항등식 (bellman equation)에 의해 다음과 같이 표현될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \begin {align*} V(s) &amp;amp;= \mathbb {E}[G_{t}|S_{t}=s] \\ &amp;amp;= \mathbb {E}[R_{t+1} + \gamma R_{t+2} + \gamma^{2} R_{t+3} +.. | S_{t}=s] \\ &amp;amp;= \mathbb {E}[R_{t+1} + \gamma (R_{t+2} + \gamma R_{t+3} +... )|S_{t} = s] \\ &amp;amp;= \mathbb {E}[R_{t+1} + \gamma G_{t+1} | S_{t} = s]&amp;nbsp; \\ &amp;amp;= \mathbb {E}[R_{t+1}+\gamma V(S_{t+1})|S_{t} = s]&amp;nbsp; \\ &amp;amp;= R(s) + \gamma \sum_{s' \in S_{t+1}} P_{ss'} V(s') \end {align*} $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 벨만 방정식은 선형 연립방정식을 통해 다음과 같이 표현이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ v = R + \gamma Pv $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 $ v = (I-\gamma P)^{-1} R$ 로 해를 구할 수 있다. 하지만 상태 개수(n)가 커질수록 직접적으로 문제를 푸는 것이 어려워져서 dynamic programming, monte carlo, temporal difference 등의 방법을 이용하여 문제를 풀게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마르코프 결정 과정 (Markov Decision Process - MDP : $&amp;lt;S, A, P, R,\gamma&amp;gt;$)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마르코프 결정 과정은 MRP에 행동을 추가한 확률 과정이다. 행동 집합 $A$가 추가되었으므로 상태 천이 행렬 P과 보상 함수 R도 상태 s뿐 아니라 행동 a까지 고려하여야 한다. $$P_{ss'}^{a} = P [S_{t+1}=s' | S_{t} = s, A_{t} = a]$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ R: S \times A \to \mathbb {R} $$&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정책 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정책 함수 $\pi$는 현재 상태에서 수행할 행동의 확률 분포를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \pi(a|s) = P(A_{t}=a|S_{t}=s) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마르코프 특성을 가정하여 현재 상태만을 가지고 의사결정을 한다. 좋은 $\pi$를 가지고 있으면 많은 보상을 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;상태 가치 함수와 행동 가치 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상태 가치 함수는 $V_{\pi}(s) = \mathbb {E}_{\pi}[G_{t}|S_{t}=s]$으로 표현된다. 현재 상태 s에서 정책 $\pi$를 따른다면 얻을 수 있는 미래 가치의 감가 총합을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행동 가치 함수는 $Q_{\pi}(s, a) = \mathbb {E}_{\pi}[G_{t}|S_{t}=s, A_{t}=a]$으로 표현된다. 현재 상태 s에서 a라는 행동을 취한 후, 정책 $\pi$를 따른다면 얻을 미래 가치의 감가 총합을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 상태 가치 함수와 행동 가치 함수는 관련되어 있고 서로를 다음과 같이 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ V_{\pi}(s) = \sum_{a \in A} \pi(a|s) Q_{\pi}(s, a) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(현재 상태 s에서 a라는 행동을 할 확률이 $\pi(a|s)$이므로, 각 상태와 행동에 대한 가치 $Q_{\pi}$를 $\pi(a|s)$로 평균을 내면 현재 상태의 가치 $V_{\pi}(s)$가 된다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ Q_{\pi}(s, a) = R_{s}^{a} + \gamma \sum_{s' \in S} P_{ss'}^{a} V_{\pi}(s') $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(현재 상태 s에서 a라는 행동을 하면, $R_{s}^{a}$의 보상을 받고 확률적으로 어떤 s'들에 도달하게 된다. 각 도달한 s'에서 각각의 가치 $V_{\pi}(s')$과 s'을 얻을 확률 $P_{ss'}$를 곱하여 모두 더해 s'에서 얻을 기댓값을 구하고 $\gamma$만큼 감가 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;최적 가치 함수와 최적 정책&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적 상태 가치 함수는 $ V^{*}(s) = max_{\pi} V_{\pi} (s) $ 로 정의할 수 있다. 이는 존재하는 모든 정책들 중에 모든 상태 s에서 가장 높은 $V_{\pi}(s)$를 만드는 $\pi$를 적용했을 때 얻는 $V_{\pi}$(s)를 의미한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적 행동 가치 함수는 $ Q^{*}(s, a) = max_{\pi} Q_{\pi}(s, a) $ 로 정의할 수 있다. 이는 존재하는 모든 정책들 중에 모든 상태, 행동 조합에서 가장 높은 $Q_{\pi}(s, a)$를 만드는 $\pi$를 적용했을 때 얻는 $Q_{\pi}(s, a)$를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MDP를 풀기 위해서는 최적 가치 함수를 찾거나 그것을 만드는 최적 정책 $\pi$를 찾아야 한다.&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/강화학습</category>
      <category>강화학습</category>
      <category>마르코프</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/54</guid>
      <comments>https://simpling.tistory.com/54#entry54comment</comments>
      <pubDate>Sun, 1 May 2022 21:28:19 +0900</pubDate>
    </item>
    <item>
      <title>다양한 Hyperparameter Optimization 방법 리뷰</title>
      <link>https://simpling.tistory.com/52</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Machine Learning 알고리즘들은 강력한 성능을 보여주고 있다. 하지만 데이터가 커지면서 좋은 &lt;b&gt;HyperParameter(HP)&lt;/b&gt;를 찾는 것은 점점 비용이 많이 드는 어려운 문제가 되었다. 보통 찾아야 하는 HP는 여러 개이고 그 범위가 클 수도 있기 때문에 좋은 HP 조합을 찾는 것은 어렵다. 이런 문제는 과거부터 있었고 다양한 방법이 제시되어왔다. 이에 대해 간단히 정리해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. Manual Search&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Manual search는 사용하기 쉬운 방법이다. 사용자가 경험적으로 괜찮다고 여기는 HP 조합을 선정하여 tuning을 하는 방식이다. 경험이 부족하면 사용하기 어렵고 자동화된 알고리즘이 아니라 사용자의 시간을 많이 쓸 수 있다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. Grid Search&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Grid search는 단순하지만 여전히 널리 사용되는 방법이다. 말 그대로 각각의 HP 구간을 정해놓고 일정 구간으로 잘라 모든 조합을 search 해보는 방식이다. &lt;span&gt;사용하기 쉬우면서도 좋은 성능을 보여 kaggle 같은 데이터 competition에서도 종종 사용되는 것으로 알고 있다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&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;1183&quot; data-origin-height=&quot;691&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMFjBg/btrvJTEBany/seuQrliXTAda1ZLYTA5ei0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMFjBg/btrvJTEBany/seuQrliXTAda1ZLYTA5ei0/img.png&quot; data-alt=&quot;Figure 1. grid search ([1])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMFjBg/btrvJTEBany/seuQrliXTAda1ZLYTA5ei0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMFjBg%2FbtrvJTEBany%2FseuQrliXTAda1ZLYTA5ei0%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;492&quot; height=&quot;287&quot; data-origin-width=&quot;1183&quot; data-origin-height=&quot;691&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1. grid search ([1])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. Random Search&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Random search는 말 그대로 random 하게 HP를 뽑아 search 하는 방식이다. 이 방법은 HP의 개수, 구간이 클수록 성능이 저하되는 특징이 있다. 반대로 HP 개수가 적고 구간이 좁으면 괜찮은 성능을 보여준다. 하지만 성능이 guarantee 되지 않고 random 하다는 특성 때문에 많이 사용되지는 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. Bayesian Optimization&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Bayesian Optimization(BO)&lt;/b&gt;는 오래됐지만 좋은 성능을 내는 유명한 방법이다. 이 알고리즘은 black box model의 optimization을 위한 방법으로 HP search에서도 많아 사용된다. Black box model이란 실제로 evaluation 해보지 않으면 그 모델이 어떤 output을 낼지 모르는 모델을 말한다. 예를 들어 특정 HP(input)로 neural network를 학습시켰을 때 어떤 성능(output)을 낼지 실제 훈련해보지 않으면 모르는 경우가 이에 해당한다. 여기서 neural network 훈련이 evaluation 과정이고 한 번의 evaluation에 cost가 많이 들어가므로 이를 최대한 적게 하며 좋은 HP를 찾는 것이 목표이다. x가 input이고 black box model을 f(x)라고 할 때 $argmax_{x} f(x)$ (maximize 하므로 HP search에서는 f(x)가 학습이 끝난 모델의 valid accuracy 정도가 될 수 있다.)를 하는 과정이라고 생각하면 된다. 이를 위해 surrogate model과 acqusition function을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Surrogate model&lt;/b&gt;은 실제 evaluation 한 &lt;span&gt;여러&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;(input, output) pair를 가지고 다른 지점에서의 성능을 예측하는 것을 담당한다(f(x)를 예측하는 모델을 찾는 것). 대표적으로 gaussian process나 bayesian neural network를 사용하여 posterior를 예측한다. Figure 2 위의 그림은 point 3개를 가지고 GP를 사용하여 예측한 모델이다. Posterior 이므로 mean(직선)과 variance(점선)를 함께 예측하여 나타내었다. 이미 evaluation 된 부분과 그 근처 영역은 variance(uncertainty)가 낮으며 멀리 떨어질수록 커지는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Acqusition function&lt;/b&gt;은 surrogate model로 추정한 전체 영역의 분포를 가지고 다음에 evaluation 할 point를 선택하는 역할을 한다. Figure 2 아래 그림을 보면 gp surrogate model에서 variance가 가장 큰 지점의 value가 가장 크게 나온 것을 볼 수 있다. 그 영역이 탐사해볼 만한 지점이니 다음에 evaluation 해보라는 것이다. 다만 항상 variance가 큰 지점을 선택하는 것은 아니고 acqusition function도 종류가 여러 개 있다. 보통 사용하는 방법은 &lt;b&gt;Expected Improvement (EI)&lt;/b&gt;로 아래 식과 같이 나타낸다. $$ \int_{y*}^{\infty} (f(x)-y*) P(y|x) dy $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;y*은 여태까지 evaluation 한 f(x) 값 중 가장 최댓값(최적 값)을 나타내며 P(y|x)는 surrogate model로 예측한 posterior 분포이다. 식을 해석해보면 y*보다 큰 부분에 해당하는 영역이 크면서 mean값이 y*보다 클수록 expected improvement가 커진다. 그러므로 variance만 무조건 크다고 선택되는 것도 아니고 최적점 근처의 point만 선택되는 것도 아니게 된다. 이는 figure 3을 보면 알 수 있다. (Figure 3에서는 y*를 $f(x^{+})$로 표현하였으며 초록색 영역이 $ \int_{y*}^{\infty} p(y|x) dy $를 나타낸다.)&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;701&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXuC6r/btrvLJgGgUH/i2J6OMzZfVQE4aks9wZ2KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXuC6r/btrvLJgGgUH/i2J6OMzZfVQE4aks9wZ2KK/img.png&quot; data-alt=&quot;Figure 2. Surrogate model (GP) and Acquisition function ([2])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXuC6r/btrvLJgGgUH/i2J6OMzZfVQE4aks9wZ2KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXuC6r%2FbtrvLJgGgUH%2Fi2J6OMzZfVQE4aks9wZ2KK%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;701&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;701&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 2. Surrogate model (GP) and Acquisition function ([2])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvSkDp/btrvLI275Zt/KZ317TuKSYfLW8F0iG2SR0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvSkDp/btrvLI275Zt/KZ317TuKSYfLW8F0iG2SR0/img.jpg&quot; data-alt=&quot;Figure 3. Expected Improvement([3])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvSkDp/btrvLI275Zt/KZ317TuKSYfLW8F0iG2SR0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvSkDp%2FbtrvLI275Zt%2FKZ317TuKSYfLW8F0iG2SR0%2Fimg.jpg&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;550&quot; height=&quot;401&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 3. Expected Improvement([3])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적인 알고리즘은 Figure 4에 잘 나와있다. 이를 다시 써보면 아래와 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1. Surrogate model을 사용하기 위해서는 evaluation 된 points가 필요하므로 random HP를 사용하여 evaluation 한다.&lt;br /&gt;2. Evaluation된 point로 surrogate model f를 만든다. (GP 등을 사용하여)&lt;br /&gt;3. Acqusition function을 maximize 하는 point(HP or x)를 고른다.&lt;br /&gt;4. Evaluation 한다.&lt;br /&gt;5. 2~4 과정을 충분히 반복한다.&lt;br /&gt;6. 가장 좋은 성능의 모델을 return 한다.&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1246&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/095AF/btrvJZKHfAE/bLcPZn4R1ru1hKf7cXhvd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/095AF/btrvJZKHfAE/bLcPZn4R1ru1hKf7cXhvd0/img.png&quot; data-alt=&quot;Figure 4. BO algorithm ([2])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/095AF/btrvJZKHfAE/bLcPZn4R1ru1hKf7cXhvd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F095AF%2FbtrvJZKHfAE%2FbLcPZn4R1ru1hKf7cXhvd0%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;1246&quot; height=&quot;391&quot; data-origin-width=&quot;1246&quot; data-origin-height=&quot;391&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 4. BO algorithm ([2])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. Hyperband&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bayesian Optimization 방법은 좋은 성능을 보여주지만 느리다는 단점이 있다. 게다가 sequential based 방법이라 parallelize도 어렵다. 한편 hyperband 방법은 매우 빠르며 좋은 성능을 보여준다. Hyperband는 &lt;b&gt;Successive HAlving(SHA)&lt;/b&gt; 방법을 기반으로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SHA는 figure 5와 같은 방법으로 이루어진다. X축의 budget은 epoch이나 데이터 크기 등을 의미하는데 편의상 여기서는 epoch이라고 해보겠다. 그림처럼 처음 여러 개의 HP를 선택(random 하게 선택함)하여 evaluation 하되 모든 budget(R)을 사용하지 않고 일정 budget을 사용하여 평가하고 성능이 뒤떨어지는 비율($\eta$)을 정하여 제거해 나가는 알고리즘이다. 이는 모든 budget을 사용하지 않아도 최종 성능을 어느 정도 근사할 것이라는 가정을 한다. 다만 SHA 방법은 몇 개(n)의 HP로 시작하며, 어떤 구간(r)에서 줄여나갈지 정해 줘야 한다는 것이다. 이를 개선한 게 hyperband 알고리즘이다.&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;457&quot; data-origin-height=&quot;286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vBgLP/btrvL5w1opD/i02oAk0D7WjRycCmjOiL81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vBgLP/btrvL5w1opD/i02oAk0D7WjRycCmjOiL81/img.png&quot; data-alt=&quot;Figure 5. successive halving ([5])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vBgLP/btrvL5w1opD/i02oAk0D7WjRycCmjOiL81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvBgLP%2FbtrvL5w1opD%2Fi02oAk0D7WjRycCmjOiL81%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;457&quot; height=&quot;286&quot; data-origin-width=&quot;457&quot; data-origin-height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 5. successive halving ([5])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hyperband 알고리즘은 최대 budget(R)과 step마다 줄어드는 비율($\eta$)을 주면 n과 r을 여러 개 만들어 SHA를 실행하게 된다. 예를 들어 R=81, $\eta$=3일 때 figure 6의 table처럼 여러 번의 SHA를 실행하는 것이다. SHA를 사용한 방법은 시간이 엄청나게 단축되며 parallelize가 가능(random sampling에 기반하므로)하다는 강력한 장점이 있다. 다만, 근본적으로 random sampling에 기반하기 때문에 HP search 범위가 넓으면 optimal 한 HP를 찾는 것은 어렵다는 것이 여러 논문에 나와있다([4], [5], [6]).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nSMgO/btrvLg61Z2o/lQKj0HV4iYwWwYfVciJZrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nSMgO/btrvLg61Z2o/lQKj0HV4iYwWwYfVciJZrk/img.png&quot; data-alt=&quot;Figure 6. Example of hyperband ([4])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nSMgO/btrvLg61Z2o/lQKj0HV4iYwWwYfVciJZrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnSMgO%2FbtrvLg61Z2o%2FlQKj0HV4iYwWwYfVciJZrk%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;592&quot; height=&quot;217&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 6. Example of hyperband ([4])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. Bayesian Optimization Hyperband&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Bayesian Optimization Hyperband (BOHB)&lt;/b&gt; 방법은 &lt;b&gt;Bayesian Optimization(BO)&lt;/b&gt;과 &lt;b&gt;HyperBand(HB)&lt;/b&gt;의 장점을 합치며 단점을 개선한 방법이다. BO는 다른 방법보다 optimal solution을 찾는데 더 좋지만 시간이 오래 걸리고 parallelize가 불가하다는 단점이 있다. 반면 HB는 random sampling을 하므로 parallelize가 가능하며 시간이 덜 걸린다는 장점이 있지만 optimal solution을 찾는데 좋지 않다. 그러므로 surrogate model과 acquisition funciton을 사용하여 optimal solution을 찾는데 도움을 주며 evaluation을 할 때는 hyperband를 사용하여 BO와 HB의 장점을 살리고 단점을 극복하는 것이 BOHB의 핵심이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BOHB는 &lt;b&gt;TPE([7]) &lt;/b&gt;알고리즘을 사용한다. TPE는 기존 surrogate model에서 posterior(P(y|x))를 직접 예측했던 것과 달리 bayes rule을 사용하는 방법이다. Bayes rule은 $ P(y|x) = \frac {P(x|y) P(y)} {P(x)} $를 의미한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P(x|y)는 figure 7, figure 8과 같이 y*를 기준으로 큰 값과 작은 값으로 나누고 해당 데이터들의 kernel density estimation을 통해 l(x), g(x)를 만들어 구한다. (kernel density estimation은 kernel을 사용하여 확률 밀도 함수를 만드는 것이다.([9]))&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;205&quot; data-origin-height=&quot;55&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRBmxN/btrvJ0wfpLD/BXTjrrYq15nRhX7TmdCJ2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRBmxN/btrvJ0wfpLD/BXTjrrYq15nRhX7TmdCJ2K/img.png&quot; data-alt=&quot;Figure 7. ([7])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRBmxN/btrvJ0wfpLD/BXTjrrYq15nRhX7TmdCJ2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRBmxN%2FbtrvJ0wfpLD%2FBXTjrrYq15nRhX7TmdCJ2K%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;205&quot; height=&quot;55&quot; data-origin-width=&quot;205&quot; data-origin-height=&quot;55&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 7. ([7])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1345&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqEKzJ/btrvNR5PZzB/gZT2PmsafQBMUQYAYVxcJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqEKzJ/btrvNR5PZzB/gZT2PmsafQBMUQYAYVxcJ0/img.png&quot; data-alt=&quot;Figure 8. ([8])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqEKzJ/btrvNR5PZzB/gZT2PmsafQBMUQYAYVxcJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqEKzJ%2FbtrvNR5PZzB%2FgZT2PmsafQBMUQYAYVxcJ0%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;1345&quot; height=&quot;412&quot; data-origin-width=&quot;1345&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 8. ([8])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 figure 9와 같이 &lt;b&gt;Expected Improvement(EI)&lt;/b&gt;를 기존의 수식에서 P(y|x)를 bayes rule로 바꾸어 유도한다. 그러면 최종적으로 EI를 maximize 하는 것은 $\frac {l(x)} {g(x)}$를 maximize 하는 것과 같은 것이 된다&lt;u&gt;(TPE, BOHB 논문에서는 위의 BO 설명과 다르게 $argmin_{x} f(x)$가 목적함수라서 EI식이 반대이다.)&lt;/u&gt;. 즉 l(x)의 밀도가 높으면서 g(x)의 밀도가 낮은 영역(HP)을 찾는 것이 된다.&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;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pkl4s/btrvJ9tPYXw/mJ6rdyNUnOn9OgDoncKGZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pkl4s/btrvJ9tPYXw/mJ6rdyNUnOn9OgDoncKGZk/img.png&quot; data-alt=&quot;Figure 9. Expected Improvement in the TPE ([7])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pkl4s/btrvJ9tPYXw/mJ6rdyNUnOn9OgDoncKGZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpkl4s%2FbtrvJ9tPYXw%2FmJ6rdyNUnOn9OgDoncKGZk%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;241&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 9. Expected Improvement in the TPE ([7])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BOHB는 evaluation시 HB를 사용하여 여러 개의 HP를 sampling 해와야 하는데 기존과 다르게 random sampling이 아니라 TPE를 사용하는 방법이다. 그런데 기존 BO는 EI가 maximize 되는 값 하나만 sampling 하여 evaluation 했기 때문에 여러 개를 sampling 하기 위해서는 다른 방법이 필요하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. y*보다 좋은 성능을 보이는 sample 중 몇 개($ N_{s} $)를 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2. bandwidth를 크게 하여 l'(x)를&lt;/span&gt; 구하고(bandwidth가 커질수록 다양성이 커짐) x를 하나 sampling.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. $ N_{s} $개 중 $\frac {l(x)} {g(x)}$가 maximize 되는 값을 뽑는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정을 반복하여 서로 겹치지 않는 HP를 여러개 sampling 하도록 만들었다. 이렇게 하면 parallelize도 가능하다는 장점이 있다. (사실 TPE를 쓰지 않고 Gaussian Process등의 posterior를 modeling하는 방법도 비슷하게 할 수 있을 것 같다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TPE modeling시 기존에는 full budget으로 이루어진 데이터들을 사용했다면 여기에서는 HB 알고리즘을 사용하므로 적은 budget의 데이터들로도 modeling이 가능하여 더 빠르게 surrogate model을 사용할 수 있다는 장점이 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;279&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SNJu3/btrvOgY9z5j/1iGkh438BPZi6Ukoqz5hoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SNJu3/btrvOgY9z5j/1iGkh438BPZi6Ukoqz5hoK/img.png&quot; data-alt=&quot;Figure 9. Results or BOHB ([6])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SNJu3/btrvOgY9z5j/1iGkh438BPZi6Ukoqz5hoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSNJu3%2FbtrvOgY9z5j%2F1iGkh438BPZi6Ukoqz5hoK%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;495&quot; height=&quot;279&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;279&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 9. Results or BOHB ([6])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과로 figure 9과 같이 BOHB는 HB만큼 빠르며 optimal solution까지 찾을 수 있는 좋은 결과를 얻었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] &lt;a href=&quot;https://arxiv.org/abs/1912.06059&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1912.06059&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647067621601&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Grid Search, Random Search, Genetic Algorithm: A Big Comparison for NAS&quot; data-og-description=&quot;In this paper, we compare the three most popular algorithms for hyperparameter optimization (Grid Search, Random Search, and Genetic Algorithm) and attempt to use them for neural architecture search (NAS). We use these algorithms for building a convolution&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1912.06059&quot; data-og-url=&quot;https://arxiv.org/abs/1912.06059v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dk9eCC/hyNGIJC8M6/cdhWvSRB0P8zYB3Jumd0Vk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1912.06059&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1912.06059&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dk9eCC/hyNGIJC8M6/cdhWvSRB0P8zYB3Jumd0Vk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Grid Search, Random Search, Genetic Algorithm: A Big Comparison for NAS&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In this paper, we compare the three most popular algorithms for hyperparameter optimization (Grid Search, Random Search, and Genetic Algorithm) and attempt to use them for neural architecture search (NAS). We use these algorithms for building a convolution&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] &lt;a href=&quot;https://arxiv.org/abs/1807.02811&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1807.02811&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647068506646&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;A Tutorial on Bayesian Optimization&quot; data-og-description=&quot;Bayesian optimization is an approach to optimizing objective functions that take a long time (minutes or hours) to evaluate. It is best-suited for optimization over continuous domains of less than 20 dimensions, and tolerates stochastic noise in function e&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1807.02811&quot; data-og-url=&quot;https://arxiv.org/abs/1807.02811v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bMEUGX/hyNFzt0XgB/cRKt6cVRqkKRzXro7KokEK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1807.02811&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1807.02811&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bMEUGX/hyNFzt0XgB/cRKt6cVRqkKRzXro7KokEK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;A Tutorial on Bayesian Optimization&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Bayesian optimization is an approach to optimizing objective functions that take a long time (minutes or hours) to evaluate. It is best-suited for optimization over continuous domains of less than 20 dimensions, and tolerates stochastic noise in function e&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3] &lt;a href=&quot;https://www.mdpi.com/2079-9292/8/11/1267/htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.mdpi.com/2079-9292/8/11/1267/htm&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647070568233&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;An Approach to Hyperparameter Optimization for the Objective Function in Machine Learning&quot; data-og-description=&quot;In machine learning, performance is of great value. However, each learning process requires much time and effort in setting each parameter. The critical problem in machine learning is determining the hyperparameters, such as the learning rate, mini-batch s&quot; data-og-host=&quot;www.mdpi.com&quot; data-og-source-url=&quot;https://www.mdpi.com/2079-9292/8/11/1267/htm&quot; data-og-url=&quot;https://www.mdpi.com/2079-9292/8/11/1267&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhX5ja/hyNFEa1P2W/lKvhgJKiLFSrcRLESLnfOk/img.jpg?width=550&amp;amp;height=435&amp;amp;face=0_0_550_435,https://scrap.kakaocdn.net/dn/EuyvT/hyNFMGUjBR/KlOZMxPX2COuRsEPosG6n1/img.png?width=160&amp;amp;height=160&amp;amp;face=0_0_160_160&quot;&gt;&lt;a href=&quot;https://www.mdpi.com/2079-9292/8/11/1267/htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.mdpi.com/2079-9292/8/11/1267/htm&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhX5ja/hyNFEa1P2W/lKvhgJKiLFSrcRLESLnfOk/img.jpg?width=550&amp;amp;height=435&amp;amp;face=0_0_550_435,https://scrap.kakaocdn.net/dn/EuyvT/hyNFMGUjBR/KlOZMxPX2COuRsEPosG6n1/img.png?width=160&amp;amp;height=160&amp;amp;face=0_0_160_160');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;An Approach to Hyperparameter Optimization for the Objective Function in Machine Learning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In machine learning, performance is of great value. However, each learning process requires much time and effort in setting each parameter. The critical problem in machine learning is determining the hyperparameters, such as the learning rate, mini-batch s&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.mdpi.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] &lt;a href=&quot;https://arxiv.org/abs/1603.06560&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1603.06560&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647071211688&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Hyperband: A Novel Bandit-Based Approach to Hyperparameter Optimization&quot; data-og-description=&quot;Performance of machine learning algorithms depends critically on identifying a good set of hyperparameters. While recent approaches use Bayesian optimization to adaptively select configurations, we focus on speeding up random search through adaptive resour&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1603.06560&quot; data-og-url=&quot;https://arxiv.org/abs/1603.06560v4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vAeij/hyNGASnawN/1tDqNCkTKazdmRs2U33HS0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1603.06560&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1603.06560&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vAeij/hyNGASnawN/1tDqNCkTKazdmRs2U33HS0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Hyperband: A Novel Bandit-Based Approach to Hyperparameter Optimization&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Performance of machine learning algorithms depends critically on identifying a good set of hyperparameters. While recent approaches use Bayesian optimization to adaptively select configurations, we focus on speeding up random search through adaptive resour&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[5] &lt;a href=&quot;https://arxiv.org/abs/2003.05689&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2003.05689&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647071299100&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Hyper-Parameter Optimization: A Review of Algorithms and Applications&quot; data-og-description=&quot;Since deep neural networks were developed, they have made huge contributions to everyday lives. Machine learning provides more rational advice than humans are capable of in almost every aspect of daily life. However, despite this achievement, the design an&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2003.05689&quot; data-og-url=&quot;https://arxiv.org/abs/2003.05689v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1XC64/hyNGJBMsSU/9qjQkDkInl06sw5GJ8oW91/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2003.05689&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2003.05689&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1XC64/hyNGJBMsSU/9qjQkDkInl06sw5GJ8oW91/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Hyper-Parameter Optimization: A Review of Algorithms and Applications&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Since deep neural networks were developed, they have made huge contributions to everyday lives. Machine learning provides more rational advice than humans are capable of in almost every aspect of daily life. However, despite this achievement, the design an&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[6] &lt;a href=&quot;https://arxiv.org/abs/1807.01774&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/1807.01774&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647082751636&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;BOHB: Robust and Efficient Hyperparameter Optimization at Scale&quot; data-og-description=&quot;Modern deep learning methods are very sensitive to many hyperparameters, and, due to the long training times of state-of-the-art models, vanilla Bayesian hyperparameter optimization is typically computationally infeasible. On the other hand, bandit-based c&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1807.01774&quot; data-og-url=&quot;https://arxiv.org/abs/1807.01774v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/GCU0k/hyNGIiGxC6/sQv5YCjjp6NovaHxMAgZn1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1807.01774&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1807.01774&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/GCU0k/hyNGIiGxC6/sQv5YCjjp6NovaHxMAgZn1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;BOHB: Robust and Efficient Hyperparameter Optimization at Scale&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Modern deep learning methods are very sensitive to many hyperparameters, and, due to the long training times of state-of-the-art models, vanilla Bayesian hyperparameter optimization is typically computationally infeasible. On the other hand, bandit-based c&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[7] &lt;a href=&quot;https://proceedings.neurips.cc/paper/2011/file/86e8f7ab32cfd12577bc2619bc635690-Paper.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://proceedings.neurips.cc/paper/2011/file/86e8f7ab32cfd12577bc2619bc635690-Paper.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[8] &lt;a href=&quot;https://www.koreascience.or.kr/article/JAKO202025863869794.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.koreascience.or.kr/article/JAKO202025863869794.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[9] &lt;a href=&quot;https://darkpgmr.tistory.com/147&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://darkpgmr.tistory.com/147&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647085194994&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Kernel Density Estimation(커널밀도추정)에 대한 이해&quot; data-og-description=&quot;얼마전 한 친구가 KDE라는 용어를 사용하기에 KDE가 뭐냐고 물어보니 Kernel Density Estimation이라 한다. 순간, Kernel Density Estimation이 뭐지? 하는 의구심이 생겨서 그 친구에게 물어보니 자기도 잘 모른.&quot; data-og-host=&quot;darkpgmr.tistory.com&quot; data-og-source-url=&quot;https://darkpgmr.tistory.com/147&quot; data-og-url=&quot;https://darkpgmr.tistory.com/147&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cz2ZfI/hyNFAzNZo9/JVSFC74nDA7WqQ7NuoJVwK/img.png?width=550&amp;amp;height=216&amp;amp;face=0_0_550_216,https://scrap.kakaocdn.net/dn/bDvx3P/hyNGGLXewf/PCnI8Jc73qsVpQiT8ZE3Pk/img.png?width=550&amp;amp;height=216&amp;amp;face=0_0_550_216,https://scrap.kakaocdn.net/dn/bNrjVn/hyNGKHzSZV/1LJwWtQMRV939sTBO0V6V0/img.png?width=480&amp;amp;height=480&amp;amp;face=0_0_480_480&quot;&gt;&lt;a href=&quot;https://darkpgmr.tistory.com/147&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://darkpgmr.tistory.com/147&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cz2ZfI/hyNFAzNZo9/JVSFC74nDA7WqQ7NuoJVwK/img.png?width=550&amp;amp;height=216&amp;amp;face=0_0_550_216,https://scrap.kakaocdn.net/dn/bDvx3P/hyNGGLXewf/PCnI8Jc73qsVpQiT8ZE3Pk/img.png?width=550&amp;amp;height=216&amp;amp;face=0_0_550_216,https://scrap.kakaocdn.net/dn/bNrjVn/hyNGKHzSZV/1LJwWtQMRV939sTBO0V6V0/img.png?width=480&amp;amp;height=480&amp;amp;face=0_0_480_480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Kernel Density Estimation(커널밀도추정)에 대한 이해&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;얼마전 한 친구가 KDE라는 용어를 사용하기에 KDE가 뭐냐고 물어보니 Kernel Density Estimation이라 한다. 순간, Kernel Density Estimation이 뭐지? 하는 의구심이 생겨서 그 친구에게 물어보니 자기도 잘 모른.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;darkpgmr.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/52</guid>
      <comments>https://simpling.tistory.com/52#entry52comment</comments>
      <pubDate>Sat, 12 Mar 2022 23:26:32 +0900</pubDate>
    </item>
    <item>
      <title>Graph Neural Network 설명 - Introduction to GNN</title>
      <link>https://simpling.tistory.com/51</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 graph neural network의 원리를 이해하고 앞으로 공부해나가는데 도움을 주기 위한 목적으로 작성되었습니다. 그러므로 너무 상세한 내용은 제거하고 전체적인 구조를 이해하는데 초점을 뒀습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Graph&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프는 많은 데이터가 가지고 있는 구조이다. 대표적으로 social graph, molecular graph 등이 있다. figure 1처럼 여러 개의 node(혹은 vertex)와 edge가 연결되어 있는 구조를 말한다. social graph 라면 node가 한 명의 사람이 될 수 있을 것이고 edge는 그 사이의 관계가 될 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;922&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DNgfH/btrul3ugBVt/zczOY3kmuDvEkTclYeK6s1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DNgfH/btrul3ugBVt/zczOY3kmuDvEkTclYeK6s1/img.jpg&quot; data-alt=&quot;figure 1. molecular graph. Image from dreamstime&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DNgfH/btrul3ugBVt/zczOY3kmuDvEkTclYeK6s1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDNgfH%2Fbtrul3ugBVt%2FzczOY3kmuDvEkTclYeK6s1%2Fimg.jpg&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;298&quot; height=&quot;172&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;922&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 1. molecular graph. Image from dreamstime&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람들은 각자의 개성을 가지고 있고 다르므로 node에 이런 정보를 담을 수 있으며 다른 사람과의 관계 또한 직장 동료, 친구, 가족, 원수지간까지 다양할 것이다. 이러한 정보는 edge에 담을 수 있다. 이렇게 정보를 담은 graph는 어떻게 나타내며 neural network에서는 어떻게 쓸까? 이에 대한 내용을 알아볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Adjacency Matrix &amp;amp; Feature Matrix&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;402&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dueWdF/btruiPW3Kl0/sZ5LboPt3SHWhUXLzAklK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dueWdF/btruiPW3Kl0/sZ5LboPt3SHWhUXLzAklK0/img.png&quot; data-alt=&quot;figure 2. simple graph structure&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dueWdF/btruiPW3Kl0/sZ5LboPt3SHWhUXLzAklK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdueWdF%2FbtruiPW3Kl0%2FsZ5LboPt3SHWhUXLzAklK0%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;206&quot; height=&quot;190&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 2. simple graph structure&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Figure 2와 같은 간단한 그래프 구조가 있다고 생각해 본다. 이런 구조를 matrix로 표현할 때 node 간의 관계(edge)를 표현하는 adjacency matrix와 node에 담긴 정보를 나타내는 feature matrix가 필요하다.&lt;/p&gt;
&lt;div id=&quot;SE-7d374587-4b18-4309-9b61-f9212a1475e7&quot;&gt;
&lt;p id=&quot;SE-c6f30aac-540d-4f08-8e69-38463a99e12c&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;$$ Adjacency \; matrix \; A = \left [ \begin {matrix} 0&amp;amp;1&amp;amp;0&amp;amp;0 \\ 1&amp;amp;0&amp;amp;1&amp;amp;1 \\ 0&amp;amp;1&amp;amp;0&amp;amp;0 \\ 0&amp;amp;1&amp;amp;0&amp;amp;0 \\ \end {matrix} \right] $$&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ Feature \; matrix \; F = \left [ \begin {matrix} 0&amp;amp;1&amp;amp;1 \\ 1&amp;amp;0&amp;amp;1 \\ 1&amp;amp;0&amp;amp;1 \\ 0&amp;amp;1&amp;amp;1 \end {matrix} \right] $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Adjacency matrix A의 각 성분 $A_{i, j}$는 i번째 node와 j번째 node가 연결되어 있는지를 보여준다. 연결되어 있다면 1, 아니라면 0으로 숫자를 가진다. 따라서 A는 node 개수만큼의 row(행)과 column(열)을 가지는 matrix이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 위와 같은 graph는 edge에 방향이 있지 않아서 undirected graph라고 하며 adjacency matrix는 symmetric 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- edge에 방향이 있는 경우는 directed graph라고 하며 adjacency matrix가 symmetric 하지 않은 형태다. (예를 들어 1-&amp;gt;2로 연결된 edge라면 1행 2열은 1의 값을 갖지만 2행 1열은 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;Feature matrix F의 각 성분 $F_{i, j}$는 i번째 node의 j번째 feature는 무엇인지 보여준다. 여기서는 1번 node와 4번 node가 같은 색이고 2번 node와 3번 node가 같은 색이므로 같은 feature를 가졌다고 생각하여 행렬을 표현하였다. 각 node는 feature를 3개 가지고 있다고 가정하여 column(열)은 3개이며 node는 총 4개이므로 row(행)가 4개인 구조의 matrix를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Graph Convolution Network (GCN)&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;700&quot; data-origin-height=&quot;549&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tg6Dc/btrup9Hb4YC/bTXlBTZKuEjIzKI9BtQ3aK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tg6Dc/btrup9Hb4YC/bTXlBTZKuEjIzKI9BtQ3aK/img.png&quot; data-alt=&quot;figure 3. Image from [1]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tg6Dc/btrup9Hb4YC/bTXlBTZKuEjIzKI9BtQ3aK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftg6Dc%2Fbtrup9Hb4YC%2FbTXlBTZKuEjIzKI9BtQ3aK%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;428&quot; height=&quot;336&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;549&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 3. Image from [1]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graph structure를 matrix로 표현하는 방법을 간단히 알아보았다. Graph는 edge가 node 간의 연결을 이루는 구조이므로 edge로 연결된 node끼리의 정보 교환이 중요하다 할 수 있다. 예를 들어 social graph의 경우 서로 연결된 가족이라면 비슷한 정보를 가지고 있을 수 있고 어떤 예측을 하는데 서로 도움이 될 수 있다. 이를 위해 graph structure를 고려하여 연산을 하는 방법이 필요한데 그중 하나가 convolution을 이용한 방법이다. Figure 3 (a)를 보면 정배열된 node 간의 정보를 spatial 하게 얻어서 사용하는 방법이 convolution이고 이런 특성 때문에 Image 계열에서 많이 사용된다. 대표적인 특징으로 3가지가 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;- Spatial feature extraction : 주변 node의 정보를 가져와 feature를 추출한다.&lt;br /&gt;- Weight Sharing : weight를 각 영역별로 따로 사용하는 게 아니라 공유하여 사용한다.&lt;br /&gt;- Translation invariance : image의 경우 그림을 조금 shift 하더라도 같은 결과를 가져오게 한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 특성을 가져와 figure 3 (b)처럼 그래프에서도 주변 node의 정보를 spatial 하게 얻어 정보를 업데이트하는 방법을 고안한 것이 graph convolution network다. Figure 1의 경우에 대입해서 생각해보면 2번 node를 업데이트할 때는 1,3,4 node를 사용하지만 다른 node는 2번 node만을 사용하는 것이다. (실제로는 자기 자신의 정보도 중요하므로 자신의 정보도 함께 사용하여 업데이트한다. 즉 adjacency matrix의 대각 성분은 1이 된다.) 실제 연산은 $AFW$ matrix 연산으로 이루어진다. A는 adjacency matrix이며 F는 feature matrix, W는 weight matrix이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ F_{2}^{l+1} = \sigma(F_{1}^{l} W^{l} + F_{2} W^{l} + F_{3}^{l} W^{l} + F_{4}^{l} W^{l}) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 식은 l+1 번째 layer를 통과한 2번째 row(node)의 vector를 나타낸 것이다. $\sigma$는 activation funciton을 나타낸다. Weight matrix는 sharing 하여 모든 feature vector 연산에서 똑같이 적용된다. 예시에서는 2번째 node를 업데이트하므로 1,2,3,4 node를 모두 이용하여 업데이트하게 된다. 1번째 node였다면 1,2 node만을 이용해서 업데이트를 해야 한다. F와 W만을 이용해서는 이런 spatial 한 feature를 뽑지는 못하여 adjacency matrix A를 사용한다. Weight sharing을 사용해 업데이트된 matrix와 adjacency matrix를 연산하게 되면 각 node에 연결된 node의 feature 만을 이용하여 다음 업데이트를 하게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1351&quot; data-origin-height=&quot;835&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gulfx/btrueyBNlfV/2juQJ6ar02KIscoPBO5D3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gulfx/btrueyBNlfV/2juQJ6ar02KIscoPBO5D3k/img.png&quot; data-alt=&quot;figure 4. matrix 연산 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gulfx/btrueyBNlfV/2juQJ6ar02KIscoPBO5D3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGulfx%2FbtrueyBNlfV%2F2juQJ6ar02KIscoPBO5D3k%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;1351&quot; height=&quot;835&quot; data-origin-width=&quot;1351&quot; data-origin-height=&quot;835&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 4. matrix 연산 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 figure 2의 graph를 업데이트한다 했을 때 figure 4와 같이 matrix가 연산된다. A는 $4 \times 4$, F는 $4 \times 3$, W는 $3 \times 64$ 의 matrix를 가진다고 하겠다. $FW$를 연산하면 $4 \times 64$의 matrix가 되고 이는 각 node의 feature가 64 dimension으로 커져 고차원의 정보를 가지고 있다고 생각할 수 있다. 이 matrix와 A를 연산하면 $4 \times 64$의 matix가 되고 이 과정에서 연결된 node의 정보만을 가져와서 다시 업데이트하는 과정을 거치는 것이다. 마지막으로 graph structure로 연산을 끝낸 값을 node-wise summation을 해도 permutation invariance 하다고 한다. GCN은 convolution이 가지고 있는 특징들을 가지고 있어 graph 연산에서 강력한 이점을 가지고 있다.&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;추가로 adjacency matrix와 weight matrix를 여러 번 반복해서 사용하게 되면 직접 연결된 node의 정보뿐 아니라 건너 건너 연결된 node의 정보까지 이용할 수 있다. 예를 들어 figure 2의 graph 구조를 연산할 때, 첫 번째 연산에서 2번 node는 1,2,3,4 node를 이용하여 정보를 업데이트했을 것이다. 그다음 연산을 한번 더할 때 1번 node를 업데이트하기 위해 2번 node의 정보를 가져와서 사용한다면 그 node의 정보에는 기존에 업데이트된 1,2,3,4 node의 정보가 담겨 있을 것이기 때문에 1번 node와 직접 연결되지 않은 node의 정보도 이용할 수 있게 된다. 이런 식으로 여러 번 반복하면 convolution처럼 receptive field가 커지는 효과를 얻을 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Graph pooling &amp;amp; message passing&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graph neural network에도 정보를 업데이트하기 위한 다양한 방법이 있다. 그중 pooling과 message passing을 간단히 알아보겠다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Graph pooling&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pooing은 convolution neural network에서도 많이 쓰이는 방법이다. 보통 max pooling이나 average pooling을 많이 사용한다. 이름처럼 뽑은 feature에서 max값만 뽑거나 평균을 내어서 low dimension으로 만드는 방법이다. Graph pooling도 비슷하다. Figure 5의 그림과 같이 복잡한 구조의 graph structure를 단순하게 만드는 데 사용할 수 있다. &lt;span&gt;CNN처럼 max값을 추출하거나 average 값을 추출할 수 있다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&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;622&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tUgTA/btrupIDwFOZ/9KJT2KYAKsmJ4OjSczqT30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tUgTA/btrupIDwFOZ/9KJT2KYAKsmJ4OjSczqT30/img.png&quot; data-alt=&quot;figure 5. graph pooling.([3])&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tUgTA/btrupIDwFOZ/9KJT2KYAKsmJ4OjSczqT30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtUgTA%2FbtrupIDwFOZ%2F9KJT2KYAKsmJ4OjSczqT30%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;622&quot; height=&quot;270&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 5. graph pooling.([3])&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편 graph pooling은 edge나 node의 정보를 서로 전달하고자 할 때도 사용할 수 있다([2]). Social graph를 예로 들어 보겠다. 각각의 사람들에 대한 정보가 node에 담겨 있고 edge로 node가 연결되어 있다고 할 때, 사람들의 정보를 보고 관계가 좋은지 나쁜지 binary classification (edge prediction)을 하고 싶다고 해보겠다. 이때 pooling을 이용하여 다음의 단계로 prediction을 수행할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1. Edge별로 연결된 node의 정보(features)를 모은다.&lt;br /&gt;2. 정보(features)를 합쳐서 edge로 보낸다. (pooling)&lt;br /&gt;3. Parameter를 이용해서 classification을 수행한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 edge prediction 뿐 아니라 node prediction, global prediction도 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Message passing&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Message passing은 node 혹은 edge 간의 연관성을 고려하면서 feature를 업데이트하기 위한 방법이다([2], [4]). 예를 들어 node를 주변 node 정보를 이용해서 업데이트하고 싶을 때 message passing은 다음과 같이 이루어진다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1. Edge로 연결되어 있는 node의 정보(features, messages)를 모은다.&lt;br /&gt;2. 모든 정보를 aggregate function (sum, average 등)을 이용하여 합친다.&lt;br /&gt;3. Update function(parameter)을 이용해서 새로운 정보로 업데이트한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Message passing을 여러 번 반복하여 receptive field를 넓힐 수 있고 더 좋은 representation을 얻을 수 있다.&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;간단히 graph neural network에 대한 기초 내용들을 정리해보았다. GNN은 추천 시스템, 분자구조 예측 등에서 사용된다고 알고 있다. 그 외에도 graph로 이루어진 데이터는 무수히 많고 다양한 영역에서 사용될 수 있는 잠재력이 많은 방법이라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1901.00596&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[1] https://arxiv.org/abs/1901.00596&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1645842408911&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;A Comprehensive Survey on Graph Neural Networks&quot; data-og-description=&quot;Deep learning has revolutionized many machine learning tasks in recent years, ranging from image classification and video processing to speech recognition and natural language understanding. The data in these tasks are typically represented in the Euclidea&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1901.00596&quot; data-og-url=&quot;https://arxiv.org/abs/1901.00596v4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bh7aDg/hyNw0kFXiJ/CxVkhHYkPtthVGQjIn1eQk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1901.00596&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1901.00596&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bh7aDg/hyNw0kFXiJ/CxVkhHYkPtthVGQjIn1eQk/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;A Comprehensive Survey on Graph Neural Networks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Deep learning has revolutionized many machine learning tasks in recent years, ranging from image classification and video processing to speech recognition and natural language understanding. The data in these tasks are typically represented in the Euclidea&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] &lt;a href=&quot;https://distill.pub/2021/gnn-intro/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://distill.pub/2021/gnn-intro/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1645842515196&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;A Gentle Introduction to Graph Neural Networks&quot; data-og-description=&quot;What components are needed for building learning algorithms that leverage the structure and properties of graphs?&quot; data-og-host=&quot;distill.pub&quot; data-og-source-url=&quot;https://distill.pub/2021/gnn-intro/&quot; data-og-url=&quot;https://distill.pub/2021/gnn-intro&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/csey5t/hyNxIWYvjL/76jn212wzuuevyUDl0Hkfk/img.jpg?width=917&amp;amp;height=384&amp;amp;face=0_0_917_384,https://scrap.kakaocdn.net/dn/dTFcSS/hyNxK1ySV8/u9jteaKow7gFuEgqH0C51K/img.jpg?width=917&amp;amp;height=384&amp;amp;face=0_0_917_384&quot;&gt;&lt;a href=&quot;https://distill.pub/2021/gnn-intro/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://distill.pub/2021/gnn-intro/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/csey5t/hyNxIWYvjL/76jn212wzuuevyUDl0Hkfk/img.jpg?width=917&amp;amp;height=384&amp;amp;face=0_0_917_384,https://scrap.kakaocdn.net/dn/dTFcSS/hyNxK1ySV8/u9jteaKow7gFuEgqH0C51K/img.jpg?width=917&amp;amp;height=384&amp;amp;face=0_0_917_384');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;A Gentle Introduction to Graph Neural Networks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;What components are needed for building learning algorithms that leverage the structure and properties of graphs?&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;distill.pub&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3] &lt;a href=&quot;https://arxiv.org/abs/2012.05716&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/abs/2012.05716&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1645854321025&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Utilising Graph Machine Learning within Drug Discovery and Development&quot; data-og-description=&quot;Graph Machine Learning (GML) is receiving growing interest within the pharmaceutical and biotechnology industries for its ability to model biomolecular structures, the functional relationships between them, and integrate multi-omic datasets - amongst other&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2012.05716&quot; data-og-url=&quot;https://arxiv.org/abs/2012.05716v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bf3nf2/hyNw4m9rgI/9uwKBkkraSbWsex3X43H8k/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2012.05716&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2012.05716&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bf3nf2/hyNw4m9rgI/9uwKBkkraSbWsex3X43H8k/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Utilising Graph Machine Learning within Drug Discovery and Development&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Graph Machine Learning (GML) is receiving growing interest within the pharmaceutical and biotechnology industries for its ability to model biomolecular structures, the functional relationships between them, and integrate multi-omic datasets - amongst other&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] &lt;a href=&quot;https://arxiv.org/pdf/1704.01212.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/pdf/1704.01212.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <category>GNN</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/51</guid>
      <comments>https://simpling.tistory.com/51#entry51comment</comments>
      <pubDate>Fri, 25 Feb 2022 23:06:42 +0900</pubDate>
    </item>
    <item>
      <title>Neural Network Pruning - 모델 경량화</title>
      <link>https://simpling.tistory.com/50</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pruning은 neural network를 경량화하고자 할 때 사용하는 방법입니다. Figure 1은 pruning을 잘 보여주는 그림입니다. 모든 node가 연결이 되어있던 왼쪽 그림으로 오른쪽과 같이 synapse(혹은 edge)와 neuron(혹은 node)를 없애는 것입니다. 당연히 무작정 없애면 안 되고 보통은 parameter가 0에 가깝다거나 훈련을 거의 안 했다거나 하는 지표를 가지고 판단하여 pruning 하게 됩니다. 실제로는 그림처럼 아예 없앤다고 이해하기보다 0으로 만들었다고 생각하면 됩니다. (이는 pruning 방법에 따라 아예 없앨 수도 있긴 합니다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;390&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZdoRP/btrufDP1L5j/4t0K1SbcGwS6ePIsDffv0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZdoRP/btrufDP1L5j/4t0K1SbcGwS6ePIsDffv0k/img.png&quot; data-alt=&quot;figure 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZdoRP/btrufDP1L5j/4t0K1SbcGwS6ePIsDffv0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZdoRP%2FbtrufDP1L5j%2F4t0K1SbcGwS6ePIsDffv0k%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;687&quot; height=&quot;390&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;390&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Structured vs Un&lt;b&gt;structured&lt;/b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pruning은 경량화를 위한 필수 방법인만큼 여러 방법들이 연구되어 오고 있습니다. 대표적으로 unstructured pruning과 structured pruning입니다. figure 2를 보면 두 알고리즘의 차이가 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽의 &lt;b&gt;structured 방법&lt;/b&gt;은 대표적으로 channel pruning([1])이 있는데 convolution network에서 상대적으로 필요 없는 channel을 뽑아서 없애는 방법입니다. 이런 식으로 structured pruning은 어떤 구조를 통째로 날려버리는 방법입니다. 이 방법의 장점은 구조를 날리는 것이니 matrix 연산을 안 해도 되므로 pytorch, tensorflow 같은 프레임워크와 잘 호환되어 inference 속도를 개선할 수 있다는 것입니다. 하지만 단점으로는 구조를 통째로 날리는 것이다 보니 pruning 하는 비율을 높게 하기는 어렵다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오른쪽 그림의 &lt;b&gt;unstructured 방법&lt;/b&gt;은 figure 1에서 보았던 그림과 같이 구조와 상관없이 그냥 특정 기준을 세워서 (보통 0 근처의 weight) 가지치기하듯 weight를 0으로 만들어버리는 것입니다. 이 방법의 장점은 필요 없다고 판단되는 weight를 0으로 만드는 것이라 높은 비율로 pruning 할 수 있다는 것입니다. 뒤에서 보겠지만 95%까지 pruning 하더라도 좋은 성능을 내곤 합니다. 하지만 단점으로는 pruning을 했으나 실제로는 0의 값을 가지므로 기존의 프레임워크를 사용하여 matrix 연산을 할 때 계산을 하긴 해야 하므로 실질적인 inference 속도를 개선하지는 못합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1345&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bauHUC/btruc7cVjPQ/ufLEJT96fvfNHkhtBtCEWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bauHUC/btruc7cVjPQ/ufLEJT96fvfNHkhtBtCEWk/img.png&quot; data-alt=&quot;figure 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bauHUC/btruc7cVjPQ/ufLEJT96fvfNHkhtBtCEWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbauHUC%2Fbtruc7cVjPQ%2FufLEJT96fvfNHkhtBtCEWk%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;1345&quot; height=&quot;321&quot; data-origin-width=&quot;1345&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RETHINKING THE VALUE OF NETWORK PRUNING&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unstructured pruning 방법과 Structured pruning 방법은 장, 단점이 반대이기도 하며 해석하는 시각도 조금 다릅니다. 보통 pruning은 훈련을 &lt;b&gt;Initialize -&amp;gt; Train -&amp;gt; Pruning -&amp;gt; Finetuning&lt;/b&gt;의 방식으로 진행하곤 합니다. 이는 여러 논문에서 나온 실험 결과를 보면 알 수 있습니다. 하지만 이는 &lt;span&gt;Unstructured pruning 방법에 해당하며 &lt;/span&gt;Structured pruning은 &lt;span&gt;&lt;b&gt;Initialize -&amp;gt; Train -&amp;gt; Pruning&lt;/b&gt;&lt;span&gt;&lt;b&gt; -&amp;gt; Initialize -&amp;gt; Train&lt;/b&gt;의 방식이 더 좋다고 [2] 논문에서는 주장합니다. [2] 논문에서는 이를 통해 Structured pruning 방법으로 찾은 weights 보다는 남아있는 구조가 중요하며 이는 Neural Architecture Search로도 활용할 수 있음을 보여주었습니다. Pruning으로 얻은 구조는 실제로 좋은 성능을 보여주었고 이는 신선하고 좋은 아이디어인 것 같습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;Lottery ticket hypothesis&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;한편, Unstructured pruning 방법임에도 Finetuning을 하지 않고 다시 initialize를 통해 훈련을 한 모델이 오히려 더 좋은 성능을 낸다는 연구도 있습니다([3]). 다만, 이 논문은 기존과는 조금 다르게 initialize를 처음 train 하기 전 parameter로 다시 돌려보내어 훈련하는 것을 가정합니다. Figure 3을 보면 이에 대한 알고리즘이 잘 나와 있습니다. 이 논문에서는 커다란 neural network 안에는 여러 개의 sub network가 있으며 그 안에는 성능이 원래의 모델과 비슷하거나 더 좋은 모델이 있다고 가정합니다. 그리고 그런 sub network를 winning ticket이라고 칭합니다. 이런 winning ticket은 훈련 후 pruning 하여 구할 수 있고 처음 initialize로 돌려보내어 학습하면 상당히 좋은 성능을 얻을 수 있다고 보여줍니다.&lt;/span&gt;&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;1249&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IRdV5/btruedRxggV/21bFKam4G3psvOMLieBlHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IRdV5/btruedRxggV/21bFKam4G3psvOMLieBlHK/img.png&quot; data-alt=&quot;figure 3. algorithm of [3] paper&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IRdV5/btruedRxggV/21bFKam4G3psvOMLieBlHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIRdV5%2FbtruedRxggV%2F21bFKam4G3psvOMLieBlHK%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;1249&quot; height=&quot;205&quot; data-origin-width=&quot;1249&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 3. algorithm of [3] paper&lt;/figcaption&gt;
&lt;/figure&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Gradient Flow in sparse neural networks&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 pruning 후 random initialize 하여 훈련하는 것과 이렇게 다시 처음의 initialize로 돌려서 훈련하는 것, structured pruning 방법은 무엇이 다르기에 이렇게 다른 성능을 보여주는 것일까요? 이는 ([4]) 논문에서 잘 보여줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unstructured pruning 후 fintuning이 아닌 random initialize를 했을 때 성능이 좋지 않았던 이유는 initialize를 제대로 해주지 않았기 때문입니다. Neural network의 initialize는 훈련 시 굉장히 중요하여 연구도 많이 이루어지고 있습니다. 현재는 Xavier 혹은 He initialize를 쓰고 있습니다. 그런데 이는 모든 node가 잘 연결되어 있을 때 사용하는 방법입니다. figure 4를 보면 왼쪽과 같은 dense layer는 기존의 initialize가 잘 통하지만 오른쪽과 같이 pruning을 했을 경우는 다르게 initialize 해야 한다는 얘기입니다. 그래서 논문에서는 각 output node 별로 연결된 노드를 따로 계산하여 initialize 하는 방식을 제안하고 실제로 성능을 개선시키는 데 성공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Figure 5에는 spare layer에서 기존과 같이 initialize를 하면 훈련 시작 시 &lt;u&gt;gradient norm&lt;/u&gt;이 굉장히 작아 학습이 어렵다는 사실을 보여줍니다. Scratch가 기존의 initialize를 사용한 것이고 Scratch+가 이들이 제안한 initialize 방법으로 학습한 것입니다. 한편 Lottery 방법은 Scratch와 비슷하게 gradient norm이 작음을 알 수 있습니다. 그렇다면 Lottery는 왜 잘되는 것일까요?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xAy7R/btrul3zFKQj/LGtr3CAk0Hi9wSop0Gv7hK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xAy7R/btrul3zFKQj/LGtr3CAk0Hi9wSop0Gv7hK/img.png&quot; data-alt=&quot;figure 4&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xAy7R/btrul3zFKQj/LGtr3CAk0Hi9wSop0Gv7hK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxAy7R%2Fbtrul3zFKQj%2FLGtr3CAk0Hi9wSop0Gv7hK%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;724&quot; height=&quot;358&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 4&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p 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;472&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BcxdE/btrujJIvoVA/socrBWv1waK8kYgkfQkn41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BcxdE/btrujJIvoVA/socrBWv1waK8kYgkfQkn41/img.png&quot; data-alt=&quot;figure 5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BcxdE/btrujJIvoVA/socrBWv1waK8kYgkfQkn41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBcxdE%2FbtrujJIvoVA%2FsocrBWv1waK8kYgkfQkn41%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;472&quot; height=&quot;433&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 5&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 figure 6에 나와 있습니다. Lottery는 initialize를 했을 때 random initialize 보다 pruning solution에 가까웠고 학습한 후에는 훨씬 가까워져서 같은 basin안에 들어가게 된다는 것입니다. 여러 번 반복하여도 같은 결과를 얻는다고 합니다. 그러니 정리하면 기존의 unstructured pruning 방법은 initialize 문제로 random initialize 후 재학습했을 때 잘 작동하지 않았으며, Lottery ticket 방법은 애초에 잘 배웠던 대로 재학습을 했기 때문에 좋은 성능을 보였던 것입니다. 이는 lottery ticket 논문이나 rethinking the value of network pruning 논문에서 learning rate를 작게 했을 때 winning ticket의 성능이 좋았다는 결과와 통합니다. Initialize point에서 멀리 갈수록 다시 re-learning 하기 어려울 것이므로 winning ticket이 잘 작동하지 않는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPAc7t/btrueebWdvg/GEXdhP6dF8Aq8KCuQNSrnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPAc7t/btrueebWdvg/GEXdhP6dF8Aq8KCuQNSrnk/img.png&quot; data-alt=&quot;figure 6. loss landscape of a sparse model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPAc7t/btrueebWdvg/GEXdhP6dF8Aq8KCuQNSrnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPAc7t%2FbtrueebWdvg%2FGEXdhP6dF8Aq8KCuQNSrnk%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;1168&quot; height=&quot;253&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;253&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 6. loss landscape of a sparse model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 Pruning 방법들은 장, 단점이 존재하여 잘 알아두면 좋은 것 같고 neural network를 이해하는 데 도움이 많이 됩니다. 앞으로도 좋은 논문이 나오면 많이 리뷰를 해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1707.06168&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[1] https://arxiv.org/abs/1707.06168&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1645705839187&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Channel Pruning for Accelerating Very Deep Neural Networks&quot; data-og-description=&quot;In this paper, we introduce a new channel pruning method to accelerate very deep convolutional neural networks.Given a trained CNN model, we propose an iterative two-step algorithm to effectively prune each layer, by a LASSO regression based channel select&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1707.06168&quot; data-og-url=&quot;https://arxiv.org/abs/1707.06168v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bfAoji/hyNv2JEQkI/mIYEdiV4L4MNudMhUDzcr1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1707.06168&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1707.06168&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bfAoji/hyNv2JEQkI/mIYEdiV4L4MNudMhUDzcr1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Channel Pruning for Accelerating Very Deep Neural Networks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In this paper, we introduce a new channel pruning method to accelerate very deep convolutional neural networks.Given a trained CNN model, we propose an iterative two-step algorithm to effectively prune each layer, by a LASSO regression based channel select&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1810.05270&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[2] https://arxiv.org/abs/1810.05270&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1645706318949&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Rethinking the Value of Network Pruning&quot; data-og-description=&quot;Network pruning is widely used for reducing the heavy inference cost of deep models in low-resource settings. A typical pruning algorithm is a three-stage pipeline, i.e., training (a large model), pruning and fine-tuning. During pruning, according to a cer&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1810.05270&quot; data-og-url=&quot;https://arxiv.org/abs/1810.05270v2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/czngCN/hyNv6yvNcf/zVSqnK8ZWW5kdVL6F8GFv0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1810.05270&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1810.05270&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/czngCN/hyNv6yvNcf/zVSqnK8ZWW5kdVL6F8GFv0/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Rethinking the Value of Network Pruning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Network pruning is widely used for reducing the heavy inference cost of deep models in low-resource settings. A typical pruning algorithm is a three-stage pipeline, i.e., training (a large model), pruning and fine-tuning. During pruning, according to a cer&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1803.03635&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[3] https://arxiv.org/abs/1803.03635&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1645706721604&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks&quot; data-og-description=&quot;Neural network pruning techniques can reduce the parameter counts of trained networks by over 90%, decreasing storage requirements and improving computational performance of inference without compromising accuracy. However, contemporary experience is that &quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/1803.03635&quot; data-og-url=&quot;https://arxiv.org/abs/1803.03635v5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cvQ5S2/hyNwg80rjo/KK7jjK7kwvRiIDTK0eTYM1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1803.03635&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/1803.03635&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cvQ5S2/hyNwg80rjo/KK7jjK7kwvRiIDTK0eTYM1/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Neural network pruning techniques can reduce the parameter counts of trained networks by over 90%, decreasing storage requirements and improving computational performance of inference without compromising accuracy. However, contemporary experience is that&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2010.03533&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[4] https://arxiv.org/abs/2010.03533&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1645706760923&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Gradient Flow in Sparse Neural Networks and How Lottery Tickets Win&quot; data-og-description=&quot;Sparse Neural Networks (NNs) can match the generalization of dense NNs using a fraction of the compute/storage for inference, and also have the potential to enable efficient training. However, naively training unstructured sparse NNs from random initializa&quot; data-og-host=&quot;arxiv.org&quot; data-og-source-url=&quot;https://arxiv.org/abs/2010.03533&quot; data-og-url=&quot;https://arxiv.org/abs/2010.03533v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cd7rc7/hyNwagCcVn/dag1yiiHFBebwlw4BkklNK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2010.03533&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://arxiv.org/abs/2010.03533&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cd7rc7/hyNwagCcVn/dag1yiiHFBebwlw4BkklNK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Gradient Flow in Sparse Neural Networks and How Lottery Tickets Win&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Sparse Neural Networks (NNs) can match the generalization of dense NNs using a fraction of the compute/storage for inference, and also have the potential to enable efficient training. However, naively training unstructured sparse NNs from random initializa&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;arxiv.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/50</guid>
      <comments>https://simpling.tistory.com/50#entry50comment</comments>
      <pubDate>Thu, 24 Feb 2022 22:32:34 +0900</pubDate>
    </item>
    <item>
      <title>비전공자 학사 출신의 AI 연구원 도전기 (2)</title>
      <link>https://simpling.tistory.com/48</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;안녕하세요. &lt;a href=&quot;https://simpling.tistory.com/46&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;지난 글&lt;/span&gt;&lt;/a&gt;에 이어서 이번에는 실력을 쌓기 위해 어떤 것들을 했는지 구체적으로 풀어보겠습니다. 많은 도움이 되시길 바랍니다.&lt;br&gt; &lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기초를 탄탄히?!&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;AI 공부는 프로그래밍, 영어, 수학, 통계학 실력을 필요로 합니다. 참고로 저는 처음 공부를 시작했을 때 프로그래밍을 잘 알지 못했습니다. 영어 공부도 수능 이후로 해본 적이 없었고 수학은 그나마 학과 공부로 조금 한 정도였습니다. (상중하로 표현하자면 프로그래밍 하, 영어 중, 수학 중 정도 실력이었습니다.) 그러면 '이것들을 기초부터 탄탄히 쌓아야 할까?'라는 고민을 자연스레 하게 됩니다. 하지만 저는 졸업과 동시에 취업이 목표였기 때문에 시간이 1년 반 정도밖에 남지 않은 상황이었습니다. 그래서 'AI 공부를 바로 시작하되 모르는 게 나올 때마다 공부해보자'라는 생각으로 무작정 시작했습니다. 지금 와서 생각해봐도 이때 기초 공부를 생략하고 바로 시작한 것이 좋은 선택이었다고 생각이 듭니다. 기초 공부만 하다가 지친 경우를 많이 봤기 때문입니다.&lt;br&gt; &lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;유명한데는 이유가 있다.&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;AI 기초는 유명한 유튜브 강의인 김성훈 교수님의 '&lt;a href=&quot;https://www.youtube.com/watch?v=BS6O0zOGX4E&amp;amp;list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;모두의 딥러닝&lt;/span&gt;&lt;/a&gt;'을 수강하였습니다. (저는 시즌1을 수강하였는데 현재는 2까지 나온 것으로 알고 있습니다. 딥러닝 이론과 그것을 구현하는 방법까지 한국말로 친절하게 설명해 주셔서 한국 입문자에게 적절한 강의라 생각합니다.) 강의도 길지 않고 핵심적인 부분들을 설명해 주셔서 빠르게 기초를 마칠 수 있었습니다. 이미 느끼셨을 수 있는데 저는 기초에서 시간을 많이 끌지 않고 실전으로 넘어가서 부딪히며 배우는 것을 좋아하는 타입입니다. 그런 저에게 적합한 강의였다고 생각합니다. (기초를 더 탄탄히하고 넘어가고 싶으신 분들은 &lt;a href=&quot;https://www.youtube.com/channel/UCBa5G_ESCn8Yd4vw5U-gIcg&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;stanford&lt;/span&gt;&lt;/a&gt;의 앤드류 응 교수님이나 첼시핀 교수님 강의를 추천드립니다. 영어가 부담스럽다면 패스트캠퍼스, 인프런 등의 한국 강의도 괜찮다고 생각합니다.)&lt;br&gt; &lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;파이썬, 피할 수 없다면 즐겁게.&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;딥러닝을 배울 때, 실험할 때 가장 많이 쓰는 언어는 파이썬입니다. '모두의 딥러닝'을 볼 때 파이썬을 잘 몰라 기초 공부의 필요성을 느꼈습니다. 그래서 파이썬 사용법을 익히기 시작했습니다. 파이썬은 '&lt;a href=&quot;https://nomadcoders.co/python-for-beginners&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;nomad coder의 크롤링 강의&lt;/span&gt;&lt;/a&gt;'로 배웠습니다. 무료 강의면서 기초적인 내용을 간단하고 짧게 설명해주며 웹에 있는 데이터를 끌어올 수 있는 스킬까지 알려주어 좋은 강의라 생각됩니다. 혹시 아직 기초를 모르신다면 추천드립니다. &lt;br&gt;사실 딥러닝을 위한 파이썬 공부는 이 정도만 했어도 충분했을 것 같은데 하다 보니 재미를 많이 느꼈습니다. 그래서 selenium, django, flask 등을 이용해서 여러 사이트를 크롤링해 오거나 웹사이트를 만들어보며 많은 공부를 했습니다. 중간에 딴 길로 새긴 했지만 결과적으로 그런 경험들이 나중에 프로젝트를 할 때, 회사에서 일할 때 큰 장점이 되었다고 생각합니다.&lt;br&gt; &lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;두 마리 토끼를 한번에!&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;첫 번째 글에서 비전공 학사 출신의 한계를 극복하기 위해 나름의 전략을 짰다는 것을 말씀드렸습니다. 크게 2 가지로 회사에서 원하는 내용을 충족시키기, 취업이 안될 때를 대비하기입니다. 첫 프로젝트를 시작할 때도 이를 고려한 것을 하고자 했습니다. 마침 저는 예전에 경제학을 공부했었고 AI 투자 프로그램을 만들어봐도 재미있겠다고 생각했습니다. AI 자체의 공부도 많이 될뿐더러 잘 되면 굳이 취업 안 해도 되겠다는 원대한(?) 꿈에 부풀어 프로젝트를 기획했습니다.&lt;br&gt;먼저 AI를 만들려면 데이터가 필요합니다. 증권사 api 사용법을 익혀서 과거 가격 데이터들을 불러왔고, 파이썬을 배울 때 익혀 두었던 크롤링 기술을 사용하여 재무제표를 수집했습니다. 처음에 무작정 데이터를 때려 넣고 AI를 만들면 안 될게 뻔해서 다른 기업들에서는 어떻게 연구하는지를 조사할 필요가 있었습니다. 대표적으로 &lt;a href=&quot;https://www.qraftec.com/&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;qraft technologies&lt;/span&gt;&lt;/a&gt;라는 회사의 블로그와 유튜브를 많이 참고했습니다. 데이터 전처리, AI modeling, 프로그램 제작을 하며 통계, 수학, 영어, 프로그래밍에 한계를 많이 느꼈고 그때마다 극복하기 위해 공부를 많이 했습니다. 최종적으로 AI를 사용해 실시간 trading이 가능한 프로그램까지 만들었습니다. 이 한 프로젝트만 3개월 정도의 시간을 사용했습니다. 수익을 내는 데는 실패했지만 실제 문제를 풀어보며 많은 공부를 하여 얻은 것과 느낀 게 많은 프로젝트였습니다.&lt;br&gt; &lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;기타 프로젝트들은 논문을 보고 직접 구현까지 해보는 것, &lt;a href=&quot;https://dacon.io/&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;dacon&lt;/span&gt;&lt;/a&gt; 같은 data competition 플랫폼에서 열리는 대회에 참여해보는 것이었습니다. 수상까지는 힘들었으나 역시 많은 경험을 할 수 있었습니다. AI 공부를 하시는 분이라면 MNIST나 CIFAR 같은 잘 알려진 데이터셋을 가지고 기본 공부만 하지 마시고 real world problem을 풀어보는 것을 해보시길 추천드립니다. 그 과정에서 필요한 공부들을 해나가다 보면 결국 회사가 원하는 능력들을 갖추게 됩니다. 다음에는 여러 deep learning 분야에서 하는 일들, 실제 회사에서 하는 일들 등에 대해 적어볼 예정입니다. &lt;span style=&quot;color: #555555;&quot;&gt;궁금한 게 있으시면 댓글로 남겨주세요:)&lt;/span&gt;&lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;/p&gt;</description>
      <category>Story</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/48</guid>
      <comments>https://simpling.tistory.com/48#entry48comment</comments>
      <pubDate>Sat, 20 Nov 2021 13:39:14 +0900</pubDate>
    </item>
    <item>
      <title>비전공자 학사 출신의 AI 연구원 도전기 (1)</title>
      <link>https://simpling.tistory.com/46</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;안녕하세요. 오늘은 AI 공부를 시작하고 취업을 하기까지의 얘기를 해보려고 합니다. 제가 했던 고민들을 다른 분들도 많이 하고 계실 거라 생각하여 도움을 드리고자 글을 쓰게 되었습니다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;비전공자 학사로는 AI 취업하기 힘들어!&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;저는 서울 중위권 대학교를 다니며 3학년 2학기부터 프로그래밍과 AI에 관심이 생겨 공부하기 시작했습니다. &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;학과는 AI나 프로그래밍과는 관련이 없는 비전공자 였습니다. 그래서 &lt;span&gt;그전까진 프로그래밍이나 통계학을 전혀 몰랐습니다. &lt;/span&gt;졸업이 1년 반밖에 남지 않은 시점에서 공부를 시작했기 때문에 이걸로 취업을 할 수 있을까 걱정을 많이 했습니다. 주변에 얘기를 해보거나 인터넷에 검색을 해보면 아래와 같은 부정적인 말들만 한가득 돌아왔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;'석사 이상이 아니면 AI 연구원으로 취업하기는 힘들다' &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;'tensorflow 좀 다룬다고 취업을 할 수 있겠냐'&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;'컴공이나 수학, 통계학과 처럼 관련 전공이 아니면 AI 쪽 취업이 힘들다'&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;'학사 출신은 취업을 해도 연봉이 적다'&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;철저한 계획을 세워보자&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼에도 AI 공부는 매력적이고 재미있었습니다. 다가올 미래에 가장 큰 영향력을 끼칠 것이 분명해 보였고 그 중심에 있으면 많은 기회가 생기겠다는 생각이 들었습니다. 그래서 '철저한 계획을 세워 도전해보고 취업에 실패해도 살 수 있는 플랜 B까지 세워보자!'라는 생각을 하게 되었습니다. 먼저 어떤 방향으로 학습할지 계획을 세우기 위해 취업 사이트를 들어가 보았습니다. AI 연구원 공고를 여러 개 보며 회사에서 원하는 기술이나 자격조건을 살펴보았습니다. 90% 이상이 전공자나 석사 이상의 스펙을 요구했습니다. 하지만 그것은 제가 어찌할 수 없는 영역이니 할 수 있는 것들에 집중했습니다. 할 수 있는 것들을 대략 정리해보니 아래와 같았습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;- 논문을 읽고 아이디어를 구현할 수 있는 능력&lt;br /&gt;- 딥러닝을 잘 이해하고 있으며 최신 AI 논문을 읽고 아이디어를 공유할 수 있는 능력&lt;br /&gt;- MySql, Python 프로그래밍 역량 보유&lt;br /&gt;- ML/DL을 사용하여 문제를 해결해 본 경험&lt;br /&gt;- Tensorflow, Keras, Pytorch 등의 Framework에 익숙한 사람&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 연구를 하는 것이다 보니 AI 지식, 수학, 영어, 프로그래밍, 의사소통 능력을 중요하게 생각하는 것을 알 수 있습니다. 석사 이상의 학력이나 전공자를 우대하는 것은 결국 위의 능력이 어느 정도 있다는 것을 보증할 수 있기 때문입니다. 하지만 비전공자에 학사인 제가 그런 능력을 보유했다는 것을 보여주어야 하므로 블로그를 시작했습니다. 거기에 플랜 B를 위한 구글 애드센스 부수입 창출까지 더해 일석이조의 효과를 얻게 되었습니다. (공부한 내용들을 다 적기는 힘들어 많이 올리지는 못했으나 공부와 취업에 많은 도움이 되었습니다. 그러니 블로그는 꼭 하시길 추천드립니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;부딪히며 성장하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키워야 하는 능력(목표)을 정확히 아니 공부를 위한 계획을 세우기 수월했습니다. 우선 기초 강의를 들으며 AI와 프로그래밍을 같이 공부하기 시작했습니다. 기초가 중요하지만 시간을 오래끌 수 없어 빠르게 끝내고 실전을 통해 부족한 부분들을 채우며 기반을 탄탄히 다지기로 했습니다. 논문을 읽고 구현해보는 능력을 키우기 위해 무작정 논문 하나를 잡고 여러 번 읽으며 이해하기 위해 노력했고 실제 구현까지 해보는 것에 도전했습니다. 당연히 처음에는 너무 어려워 일주일 넘게 걸리는 경우도 많았습니다. 하지만 이때의 경험이 AI 연구원이 되기 위해 반드시 거쳐야 하는 길이 었고 가파른 성장의 발판이었다고 생각합니다. 논문 구현과 더불어 실제 프로젝트들을 여러 개 해보며 수학, AI, 프로그래밍 관련 실력을 쌓아갔습니다. 이와 관련된 내용들은 많아서 다음에 정리해 보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;밑져야 본전&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1년 반의 시간이 금방 흘러 졸업을 앞두고 여러 회사에 AI researcher, AI engineer, Data Scientist 등의 직무에 지원을 했습니다. 대부분 조사했던 바와 같이 석사 이상 혹은 경력자를 원했으나 &lt;u&gt;'그냥 한번 넣어보자. 밑져야 본전이다!'&lt;/u&gt; 라는 심정으로 지원을 마구 했습니다. 예상대로 대부분의 회사에서 서류 탈락을 하긴 했지만 다행히 통과한 몇 개 기업이 있었습니다. '네카라쿠배당토' 급의 큰 IT 회사는 아니었지만 나름 괜찮아 보이는 회사들이었습니다. 면접은 운이 좋아 대부분 붙게 되었고 여러 곳의 오퍼를 받았습니다. 충격적이었던 것은 제시하는 연봉의 편차가 엄청 컸다는 것입니다. 공교롭게 면접에 붙은 첫 회사가 가장 낮은 연봉을 제시해서 그곳에 갈 뻔했던 아찔한 기억이 있습니다. 혹시 한 곳에 면접을 봐서 붙었다고 바로 가지 마시고 꼭 여러 곳을 보고 가시기 바랍니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;현재&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 AI 관련 스타트업에서 AI researcher로 1년 정도 근무하고 있습니다. 연봉, 업무, 근무 환경 등에 상당히 만족하며 다니고 있습니다. 오늘은 제가 AI 직무에 취업하기 위해 어떤 식으로 준비했는지를 간단히 소개해 드렸습니다. 다음에는 진행했던 프로젝트와 어떤 공부를 했는지, 스타트업을 가려한다면 어떤 점을 봐야할지 등에 대해 글을 써보려 합니다. 궁금한 게 있으시면 댓글로 남겨주세요:)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Story</category>
      <category>취업</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/46</guid>
      <comments>https://simpling.tistory.com/46#entry46comment</comments>
      <pubDate>Sun, 7 Nov 2021 19:03:57 +0900</pubDate>
    </item>
    <item>
      <title>Python multiprocessing 으로 병렬처리</title>
      <link>https://simpling.tistory.com/45</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;CPU를 사용해서 python을 처리하려다 보면 병렬 처리가 간절한 경우들이 생긴다. 이때 사용할 수 있는 간단한 방법이 python에 내장된 multiprocessing 라이브러리다. 사용법도 간단하고 직관적이라 바로 적용하기 간편하다는 장점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;multiprocessing 관련 가이드를 보면 오히려 글이 너무 길고 사용 방법이 복잡해 보여서 거부감이 들기 쉽다. 이 글에서는 가장 간단하게 적용할 수 있는 방법을 코드와 함께 남겨 놓는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 코드를 먼저 보면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1635661865733&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from multiprocessing import Pool, cpu_count
import psutil


def _check_usage_of_cpu_and_memory():

    memory_usage = psutil.virtual_memory().percent
    available_memory = psutil.virtual_memory().available * 100 / \
        psutil.virtual_memory().total
    cpu_usage = psutil.cpu_percent()

    print(f&quot;cpu usage: {cpu_usage}&quot;)
    print(f&quot;memory usage: {memory_usage}&quot;)
    print(f&quot;available_memory: {available_memory}&quot;)


def f(x):
    for _ in range(10000):
        x += 1
    _check_usage_of_cpu_and_memory()
    return x


cpu_num = cpu_count()

if __name__ == '__main__':
    print(f&quot;cpu 개수 : {cpu_num}&quot;)
    with Pool(processes=cpu_num) as p:
        print(p.map(f, range(100)))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;multiprocessing 라이브러리에서 Pool과 cpu_count를 import 했다. Pool은 병렬 처리하도록 도와주는 함수이며 cpu_count는 컴퓨터에 내장된 cpu (thread) 개수를 보여준다. 여기서는 간단히 10000번 동안 +1을 해주어 return 해주는 f(x)라는 함수를 만들어 분산 처리하는 예시를 들었다. pool.map을 사용하여 함수 f(x)에 0~99 (range(100)) 를 넣어 return값을 받는 과정을 병렬로 처리하였다. 1 process라면 100번 for문을 돌아야겠지만 여기서는 병렬 처리가 되어 훨씬 빠르게 종료된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pool 객체를 사용할 때 processes 개수에 cpu_count를 이용해 받은 숫자를 넘겨줬는데 반드시 그럴 필요는 없다. 함수를 처리할 때 cpu 사용량을 체크해보고 여유가 많이 남는다면 더 크게 줄 수도 있다. 이는 직접 돌려 보며 확인을 하면 되는데 작업 관리자를 통해 볼 수도 있지만 python을 통해서도 볼 수 있다. 그걸 위해 psutil 라이브러리를 import 하였고 _check_usage_of_cpu_and_memory 함수에서 사용하였다. 변수명과 print 문을 보고 충분히 이해할 수 있을 것이라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 간단히 multiprocessing 처리를 하는 것을 알아 보았다. 처음부터 복잡한 글을 보며 익히는 것보다 기본에서 살을 붙여가며 학습하는 것이 좋다고 생각한다. 이제 기본을 파악했다면 &lt;a href=&quot;https://docs.python.org/ko/3/library/multiprocessing.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;자세한 가이드&lt;/a&gt;를 참고해보아도 좋을 것 같다.&lt;/p&gt;</description>
      <category>python</category>
      <category>CPU</category>
      <category>multiprocessing</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/45</guid>
      <comments>https://simpling.tistory.com/45#entry45comment</comments>
      <pubDate>Sun, 31 Oct 2021 15:49:39 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: BatchEnsemble: An Alternative Approach to Efficient Ensemble and Lifelong Learning</title>
      <link>https://simpling.tistory.com/43</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;&lt;a href=&quot;https://arxiv.org/abs/2002.06715&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;BatchEnsemble: An Alternative Approach to Efficient Ensemble and Lifelong Learning&lt;/span&gt;&lt;/a&gt;&quot; (ICLR 2020) - Wen et al.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 모델을 사용하여 Ensemble을 하면 보통 single model을 사용하는 것보다 좋은 성능을 가져온다. 하지만 모델을 여러 개 training 해야 하므로 모델 개수만큼 computational cost가 발생하게 된다. 이번 논문은 이런 단점을 극복하기 위해 나온 논문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 사람이 함께 문제를 풀면 더 좋은 결과를 가져오는 경우가 많다. 이런 직관적 이유에서인지 Ensemble 방법은 오래전부터 사용해왔다. 실제 performance가 좋았고 많은 연구가 되어왔다. 단점도 존재하였는데 training시 computational cost가 많이 든다는 것, memory를 많이 차지할 수 있다는 점이다. 이런 문제 때문에 &lt;a href=&quot;https://simpling.tistory.com/23?category=380620&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;stochastic weight averaging (SWA)&lt;/a&gt; 같이 gradient descent를 하는 도중 여러 weight를 sampling을 하는 방법이나 MCMC를 사용하여 model을 sampling 하는 논문들이 나오고 있다. 아쉽게도 실제 Ensemble 보다는 보통 결과가 좋지 못하다. 그 이유로는 하나의 local minima 내에서 sampling을 하기 때문이라고 생각되고 있다. 서로 다른 initialization에서 training을 하여 다른 minima로 업데이트된 모델들이 좋은 Ensemble 결과를 가진다는&amp;nbsp;&lt;a href=&quot;https://arxiv.org/abs/1912.02757&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문&lt;/a&gt;이 생각을 뒷받침 해주고 있다. 이번에 소개하는 논문은 빠른 training과 memory efficient 한 장점을 가지면서도 여러 initialization에서 업데이트된 파라미터들로 좋은 성능을 낸다는 강점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법은 아래 Figure 2에 나온 것이 전부인데 상당히 simple하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;439&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcv5Ju/btrhX0273sQ/ZiOQbrxzl59kI1gmywgK4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcv5Ju/btrhX0273sQ/ZiOQbrxzl59kI1gmywgK4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcv5Ju/btrhX0273sQ/ZiOQbrxzl59kI1gmywgK4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbcv5Ju%2FbtrhX0273sQ%2FZiOQbrxzl59kI1gmywgK4k%2Fimg.png&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;439&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;W는 neural network backbone에 해당하는 weight matrix이며 $r_{i}, s_{i}$가 새로운 ensemble weight를 만들어내는 parameter이다. $\bar {W}_{i} = W \circ F_{i}$ $ where F_{i} = r_{i} s_{i}^{T}$ 로 계산되어 $\bar {W}_{i}$가 ensemble model의 weight가 된다. 학습 시 mini-batch를 i 개수만큼 쪼개서 sub-batch를 만들고 각각의 batch로 $r_{i}, s_{i}$를 학습시킨다. 한편 backbone이 되는 W는 공통으로 학습시킨다. 이렇게 했을 때 서로 다른 initialize로부터 학습된 $r_{i}, s_{i}$ parameter로 i개만큼의 ensemble 모델을 만들 수 있으며 parameter 크기가 작으므로 memory efficient 하다는 장점이 있다. 추가로 backbone W는 그대로 두고 새로운 task를 학습시킬 때 $r_{i}, s_{i}$ parameter만 학습시킬 수도 있으므로 lifelong learning에도 효과적으로 쓰일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&lt;b&gt;Experiments&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;575&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmv3qa/btrhUkPhtIZ/3MQyW0UEvDnSjxoOeSYgC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmv3qa/btrhUkPhtIZ/3MQyW0UEvDnSjxoOeSYgC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmv3qa/btrhUkPhtIZ/3MQyW0UEvDnSjxoOeSYgC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdmv3qa%2FbtrhUkPhtIZ%2F3MQyW0UEvDnSjxoOeSYgC1%2Fimg.png&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;575&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Figure 3에서 lifelong learning 실험 결과를 잘 보여주고 있다. performance가 좋을 뿐 아니라 time &amp;amp; memory cost가 굉장히 작음을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;419&quot; data-origin-height=&quot;200&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dynd6H/btrhV0ifllz/7gRB99MTb3ioykhpcBsW7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dynd6H/btrhV0ifllz/7gRB99MTb3ioykhpcBsW7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dynd6H/btrhV0ifllz/7gRB99MTb3ioykhpcBsW7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdynd6H%2FbtrhV0ifllz%2F7gRB99MTb3ioykhpcBsW7k%2Fimg.png&quot; data-origin-width=&quot;419&quot; data-origin-height=&quot;200&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Classification에도 Single model이나 MC-dropout을 사용한 ensemble 방법보다 좋은 성능을 내고 있다. 아쉽게 이 논문에서도 Naive Ensemble 방법을 뛰어넘지는 못했지만 훨씬 efficient하다는 점을 생각할 때 큰 발전이라고 생각한다.&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>Ensemble</category>
      <category>swa</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/43</guid>
      <comments>https://simpling.tistory.com/43#entry43comment</comments>
      <pubDate>Sat, 16 Oct 2021 19:12:09 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: Bayesian Meta-Learning for the Few-Shot Setting via Deep Kernels</title>
      <link>https://simpling.tistory.com/42</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;&lt;a href=&quot;https://proceedings.neurips.cc//paper/2020/file/b9cfe8b6042cf759dc4c0cccb27a6737-Paper.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;Bayesian Meta-Learning for the Few-Shot Setting via Deep Kernels&lt;/span&gt;&lt;/a&gt;&quot; (NIPS 2020) - M Patacchiola et al.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Meta-learning 은 new task의 적은 데이터를 빠르게 학습시켜 test 데이터를 잘 맞추고 싶을 때 사용하는 알고리즘이다.&amp;nbsp; 대표적인 방법으로 gradient based meta learning의 MAML이 있다. 이번 논문은 gaussian process를 사용한 model-based meta learning 방법이다. neural process는 gaussian process를 흉내 낸 방법인 반면 이 논문은 직접 사용한다는 차이점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAML과 같은 gradient-based meta learning의 방법은 inner loop와 outer loop가 존재한다. inner loop 에서는 task 별 adaptation을 시행하고 outer loop에서는 meta update를 진행한다. 이런 방법은 new task가 들어왔을 때 적은 데이터로 빠르게 adaptation 하여 좋은 성능을 내는 point를 찾아준다. 하지만 2번 미분을 구해야 해서 training 시간이 오래 걸린다는 치명적 단점이 존재한다. 그래서 이 논문에서는 inner loop를 gaussian process를 사용하여 대체하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/span&gt;&lt;/h3&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1059&quot; data-origin-height=&quot;559&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dh3zrw/btrhjXM447Z/rs9LtttOgWKTwJUNSYuaC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dh3zrw/btrhjXM447Z/rs9LtttOgWKTwJUNSYuaC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dh3zrw/btrhjXM447Z/rs9LtttOgWKTwJUNSYuaC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdh3zrw%2FbtrhjXM447Z%2Frs9LtttOgWKTwJUNSYuaC1%2Fimg.png&quot; data-origin-width=&quot;1059&quot; data-origin-height=&quot;559&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 논문에서 제시하는 방법은 간단하다. task-common parameter $\phi, \theta$를 training시 optimize한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 어떻게 task-specific 한 문제를 맞추나에 대한 문제가 생긴다. 이를 해결하기 위해 inner loop를 gaussian process로 대체하고 task에 대한 파라미터 $\rho$를 marginalize 하는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;83&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lmriU/btrhvOVTuCY/wLVS7P3r2ZlQOwFo821Fw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lmriU/btrhvOVTuCY/wLVS7P3r2ZlQOwFo821Fw0/img.png&quot; data-alt=&quot;marginalization over each set of task specific parameters&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lmriU/btrhvOVTuCY/wLVS7P3r2ZlQOwFo821Fw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlmriU%2FbtrhvOVTuCY%2FwLVS7P3r2ZlQOwFo821Fw0%2Fimg.png&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;83&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;marginalization over each set of task specific parameters&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 inner loop를 따로 두지 않아도 되어 빠른 학습이 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 정리하면, 학습시에는 kernel에 대한 hyper-parameter와 neural network를 task-common 하게 학습하고 test 시에 new data $T^{x}_{*}$을 사용하여 gaussian process regression으로 posterior 분포를 찾게 하는 것이다. gp 특성상 kernel function을 뭘 쓸지를 잘 정하는 게 중요한 문제가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&lt;b&gt;Experiments&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본래 MAML이나 기타 variants들은 regression에서 별로 좋은 성능을 보이지 않는다. 하지만 이 논문의 방법은 kernel을 사용한 gaussian process를 사용하므로 상당히 smooth하고 예쁜 curve를 만들어낸다 (물론 좋은 kernel을 쓸 경우에).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;333&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqmmhK/btrhgjKoACz/OlABWTSBJbVI72MNWAhl21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqmmhK/btrhgjKoACz/OlABWTSBJbVI72MNWAhl21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqmmhK/btrhgjKoACz/OlABWTSBJbVI72MNWAhl21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqmmhK%2FbtrhgjKoACz%2FOlABWTSBJbVI72MNWAhl21%2Fimg.png&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;333&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;meta learning 논문 실험에 자주 등장하는 sin 곡선에 대한 실험과 head trajectry estimation 실험이다. Deep Kernel Transfer (DKT)가 이 논문에서 제시한 방법의 결과다. (a) 결과를 보면 상당히 잘 맞춘 결과를 볼 수 있다. 다만 RBF kernel는 smooth 하지만 fitting이 잘 되어 있지는 않은 반면 Spectral kernel은 잘 맞췄다. 사실 Spectral kernel 자체가 cos term이 들어가기 때문에 주기 함수를 맞추는데 유리하기 때문인 것 같다. 반면 (b)는 RBF로 괜찮은 성능을 보인다. gp 특성상 uncertainty까지 보여주니 상당히 좋아 보인다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;334&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqqI7k/btrhh8aNQWc/Qe0biS1b08fofhwkcEeL50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqqI7k/btrhh8aNQWc/Qe0biS1b08fofhwkcEeL50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqqI7k/btrhh8aNQWc/Qe0biS1b08fofhwkcEeL50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqqI7k%2Fbtrhh8aNQWc%2FQe0biS1b08fofhwkcEeL50%2Fimg.png&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;334&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;classification도 기존 알고리즘보다 좋은 성능을 보였다고 하는데 여기서도 kernel dependency가 큰 것 같다. 이런 면에서는 neural process 계열이 더 편한(?) 알고리즘이라 할 수 있을 것 같다.&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/42</guid>
      <comments>https://simpling.tistory.com/42#entry42comment</comments>
      <pubDate>Mon, 11 Oct 2021 23:10:39 +0900</pubDate>
    </item>
    <item>
      <title>Multi-task learning &amp;amp; Meta-learning</title>
      <link>https://simpling.tistory.com/41</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글은 Multi-task learning과 Meta-learning 알고리즘 비교와 특징을 비교하여 설명한다.&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;Multi-task learning은 처음 딥러닝을 공부할 때부터 많이 들어온 알고리즘이다. 알고리즘의 목적은 여러 task를 함께 풀어내어 좋은 성능을 내는 것이다. 여러 task를 함께 학습하여 general 한 feature를 뽑게 하여 학습에 도움을 주며 한 번에 여러 개를 풀 수 있으므로 efficient 한 장점이 있다.&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;Meta-learning은 익숙하지 않은 경우가 많을 것 같다. 논문은 많이 나왔지만 실제 사용하여 문제를 푸는 경우는 거의 못봤기 때문인 것 같다. 알고리즘의 목적은 unseen task에 대해 few 개의 데이터를 주었을 때 그것을 빠르게 학습하도록 만드는 것이다. 사람은 이미 meta-learning이 잘 되어서 처음 보는 꽃을 하나 보여주고 여러 사진 속에서 해당 꽃을 찾아보라고 했을 때 굉장히 잘 찾는다. 하지만 neural network는 그렇지 않았다. 이런 문제를 해결하기 위해 제시된 알고리즘이다. 이 방법은 learning to learn 이라고도 불린다. 말 그대로 학습하는 것을 배워서 보지 못한 데이터를 잘 배워보자 라는 것이다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한마디로 multi-task learning은 학습하는 task를 잘 푸는 것이 목적이라면 meta-learning은 학습하지 않은 task를 잘 푸는 것이 목적이다. 목적이 다르니 알고리즘도 많이 다르다. multi-task learning은 보통 hard parameter sharing 방법을 많이 사용한다. 그래서 fig1과 같은 구조를 가진다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;536&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5pJ2E/btrfqis14Dq/7K3Mh70ajHzhV2pG44Aoxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5pJ2E/btrfqis14Dq/7K3Mh70ajHzhV2pG44Aoxk/img.png&quot; data-alt=&quot;fig1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5pJ2E/btrfqis14Dq/7K3Mh70ajHzhV2pG44Aoxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5pJ2E%2Fbtrfqis14Dq%2F7K3Mh70ajHzhV2pG44Aoxk%2Fimg.png&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;536&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;fig1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터로부터 shared layers에서 공통 feature를 뽑게 된다. 그리고 task specific layer를 통과하여 각 task에 대한 예측값을 inference 한다. 이때 shared-layers에서 general한 좋은 feature를 뽑아서 각 task의 데이터가 부족해도 좋은 성능을 낼 수 있길 원하는 것이다.&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;meta learning은 학습시 데이터를 크게 meta-train, meta-test로 나눈다. 그리고 그 안에서 다시 train set (support set), test set (query set)으로 나누어 사용한다. 이렇게 하는 이유는 training 시 few개의 train set을 보여주고 test set을 잘 맞추도록 하는 알고리즘을 사용하기 위해서다. few개의 데이터를 보여주는 것은 few-shot이라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적으로 &lt;a href=&quot;https://arxiv.org/pdf/1703.03400.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;model agnostic meta learning&lt;/a&gt;(MAML) 논문에서 가져온 fig2 그림을 많이 인용하여 설명한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;599&quot; width=&quot;630&quot; height=&quot;379&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4QuGC/btrfKBEqjIO/dABLmmwRFaBQFaaHIP3nwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4QuGC/btrfKBEqjIO/dABLmmwRFaBQFaaHIP3nwK/img.png&quot; data-alt=&quot;fig2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4QuGC/btrfKBEqjIO/dABLmmwRFaBQFaaHIP3nwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4QuGC%2FbtrfKBEqjIO%2FdABLmmwRFaBQFaaHIP3nwK%2Fimg.png&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;599&quot; width=&quot;630&quot; height=&quot;379&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;fig2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAML은 gradient-based meta learning의 대표 알고리즘이다. optimization 시 2개의 과정으로 나누어 업데이트하는 것이 특징이다. 첫 번째 과정에서 train set을 이용하여 각 task 별 업데이트를 진행하여 $\theta^{*}$ 을 얻는다. 이를 adaptation이라고 부른다. 다음으로 test set과 첫 번째 과정에서 얻은 $\theta^{*}$을 이용하여 $\theta$를 얻는다. 이를 meta-learning이라고 부른다. 이렇게 해주는 이유는 meta-test시 적은 양의 데이터를 넣어줬을 때 데이터를 잘 설명해주는 optima로 빠르게 adaptation 할 수 있는 좋은 initial point ($\theta$)를 찾기 위함이다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에는 multi-task learning과 meta-learning이 사실 차이가 거의 없고 multi-task learning으로도 few-shot setting에서 좋은 성능을 보인다고 주장하는 &lt;a href=&quot;https://arxiv.org/pdf/2106.09017.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Bridging multi-task learning and meta-learning&lt;/a&gt; 이라는 논문도 있다.&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <category>meta-learning</category>
      <category>multi-task-learning</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/41</guid>
      <comments>https://simpling.tistory.com/41#entry41comment</comments>
      <pubDate>Thu, 23 Sep 2021 11:10:30 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: multi-task learning using uncertainty to weigh losses for scene geometry and semantics</title>
      <link>https://simpling.tistory.com/40</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;&lt;a href=&quot;https://arxiv.org/pdf/1705.07115.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;multi-task learning using uncertainty to weigh losses for scene geometry and semantics&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;&quot; (CVPR 2018) - Gal et al.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;multi-task learning 시 loss는 여러 task에 대한 sum으로 주게 된다. 이때 loss를 주는 비율이 중요한데 보통은 hyper-parameter로 주어진다. 그런데 이 논문은 Uncertainty를 사용하여 weight를 learning 하게 해 줄 수 있는 방법을 제시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Multi-task learning은 여러 task를 한 번에 풀어내는 neural network를 만들어내므로 efficient 한 장점이 있으며 shared representation을 뽑을 수 있으므로 accuracy 향상을 가져오기도 한다. 한편 여러 task를 학습시키려면 figure 1에 나온 것처럼 loss를 각 task loss의 sum으로 표현해야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;317&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8Ud5V/btreLfKdWLN/XjTC6KPaTCXb6VkLXcTw7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8Ud5V/btreLfKdWLN/XjTC6KPaTCXb6VkLXcTw7K/img.png&quot; data-alt=&quot;figure 1.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8Ud5V/btreLfKdWLN/XjTC6KPaTCXb6VkLXcTw7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8Ud5V%2FbtreLfKdWLN%2FXjTC6KPaTCXb6VkLXcTw7K%2Fimg.png&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;317&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 1.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 loss의 sum을 똑같은 비율로 넣어서 학습할 수도 있겠지만 다르게 해서 넣을 수도 있다. 그렇게 되면 hyper-parameter가 task 개수만큼 많아지므로 좋지 않다. 그래서 논문은 uncertainty를 사용하여 각 task loss의 weight를 주려한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Uncertainty 및 Objective function&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;uncertainty에 대한 설명은 &lt;a href=&quot;https://simpling.tistory.com/28?category=380620&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;지난 글&lt;/a&gt;에서 자세히 해두었다. 하지만 이 논문에서는 추가적인 개념이 나오므로 Aleatoric uncertainty에 대해 더 자세히 보고 넘어가겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Aleatoric uncertainty는 데이터의 noise를 나타내는 지표라고 하였다. 대표적으로는 동전 던지기나 가위바위보 같이 데이터가 아무리 주어져도 예측하기 힘든 것들을 말한다. &lt;a href=&quot;https://simpling.tistory.com/28?category=380620&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;지난 글&lt;/a&gt;에서는 이미지 segmentation에서는 물체 사이의 경계 부분이 aleatoric uncertainty가 높음을 보았다. 이 논문에서는 aleatoric uncertainty를 2개로 나눌 수 있다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Data-dependent or Heteroscedastic uncertainty&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) Task-dependent or Homoscedastic uncertainty&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 uncertainty는 원래 알고 있던 개념을 그대로 따라 input data의 noise에 반응하고 model output으로 예측할 수 있는 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 uncertainty는 입력 데이터의 noise에 영향을 받지 않고 각 task 별로 다른 값을 가지게 되는 값이다. 그러므로 이 논문은 두 번째 uncertainty를 이용한다.&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;두 번째 uncertainty는 model output으로 predict 할 수 있는 값은 아니고 따로 learnable parameter로 두어 update 한다. mse를 사용하고 output distribution이 gaussian일 경우 식은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;182&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rlu4O/btreLgoTPic/7bFmDTmIJoJzLKwlOMVQfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rlu4O/btreLgoTPic/7bFmDTmIJoJzLKwlOMVQfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rlu4O/btreLgoTPic/7bFmDTmIJoJzLKwlOMVQfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frlu4O%2FbtreLgoTPic%2F7bFmDTmIJoJzLKwlOMVQfk%2Fimg.png&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;182&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$\sigma_{1}, \sigma_{2}$가 각 task별 uncertainty를 나타내는 learnable parameter이고 전체 loss를 minimize 할 때 함께 update 된다. 위의 loss 식은 본래 aleatoric uncertainty를 loss로 줄 때 식과 같다. 각 uncertainty가 크면 해당 task loss는 update에 영향을 덜 끼치게 된다 ($\frac {1} {2\sigma^{2}}$이 L(W)에 곱해지므로). 한편 $\sigma$가 무작정 커져서 Loss가 작아지는 것을 원하진 않으므로 뒤에 regularization term으로 $log\sigma$가 더해지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Experiments&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&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;흥미롭다. 저자들이 grid search로 찾은 optimal weights 보다 성능이 좋은 것은 물론이고 보통 사용하는 동일한 비율로 줬을 때의 loss 보다 훨씬 outperform 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;365&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkBTWJ/btreKI0gS4N/jPHzKwKVEn9CKCqL7ImMLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkBTWJ/btreKI0gS4N/jPHzKwKVEn9CKCqL7ImMLk/img.png&quot; data-alt=&quot;table 1.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkBTWJ/btreKI0gS4N/jPHzKwKVEn9CKCqL7ImMLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkBTWJ%2FbtreKI0gS4N%2FjPHzKwKVEn9CKCqL7ImMLk%2Fimg.png&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;365&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;table 1.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 결과를 보면 weight가 segmentation 쪽으로 치우쳐 있는 것을 볼 수 있다. 아마 segmentation loss가 다른 loss보다 작아서 더 커진 게 아닐까 싶다. 다시 생각해보면 동일한 크기로 loss 비율을 맞춰 주면 어느 정도 안정적인 성능을 낼 것 같다는 생각이 든다.&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>loss weights</category>
      <category>multi-task-learning</category>
      <category>uncertainty</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/40</guid>
      <comments>https://simpling.tistory.com/40#entry40comment</comments>
      <pubDate>Sun, 12 Sep 2021 22:12:23 +0900</pubDate>
    </item>
    <item>
      <title>Likelihood, Maximum likelihood estimation 이란?</title>
      <link>https://simpling.tistory.com/38</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 딥러닝 공부를 하다 보면 likelihood가 자주 등장한다. 기본적인 내용들을 다시 한번 remind 하기 위해 정리해둔다.&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;Likelihood를 식으로 표현하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ L(\theta|D) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$\theta$는 parameter이고 D는 data를 의미한다. 식을 그대로 해석해보면, 가능도는 관측값(D)이 주어졌을 때(given) 관측값이 $\theta$에 대한 확률분포 $P(\theta)$에서 나왔을 확률이다.&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;likelihood가 익숙하면서 안 익숙한(?) 이상한 느낌이 드는 이유는 likelihood와 비슷하게 생긴 $Pr(D|\theta)$라는 식을 자주 보았기 때문이다. 이 식은 '확률'을 나타내는데 중, 고등학교 과정에서 자주 봤었다. 확률은 가능도와 다르게 확률분포 $P(\theta)$가 주어졌을 때(given) Data가 이 분포에서 관측될 수 있는 빈도를 표현한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1591&quot; data-origin-height=&quot;752&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bno6SP/btrdqiO07PB/mJJx7JQZgcAKUxJi4UWK6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bno6SP/btrdqiO07PB/mJJx7JQZgcAKUxJi4UWK6K/img.png&quot; data-alt=&quot;정규분포&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bno6SP/btrdqiO07PB/mJJx7JQZgcAKUxJi4UWK6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbno6SP%2FbtrdqiO07PB%2FmJJx7JQZgcAKUxJi4UWK6K%2Fimg.png&quot; data-origin-width=&quot;1591&quot; data-origin-height=&quot;752&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;정규분포&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 정규 분포가 주어지고 데이터가 0~1$\sigma$ 사이로 관측될 확률은 34.1% 가 된다. 즉, 확률은 given distribution에서 데이터가 관측되게 될 범위의 area가 된다.&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;가능도와 확률의 차이는 명확하다. 확률은 주어진 확률분포에서 해당 관측값이 어느 정도 나올지를 표현하고 이 값은 distribution의 area를 통해 구한다. 반면 가능도는 관측 데이터가 있을 때 어떤 분포를 주고 그 분포에서 데이터가 나왔을 확률을 구하는 것이다. 가능도를 구하는 식은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ L(\theta|x) = P_{\theta} (X=x) = \prod^{n}_{k=1} P(x_{k}|\theta) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 가능도는 각 데이터 샘플에서 후보 분포 $P(\theta)$에 대한 y value(밀도)를 (데이터의 추출이 독립적이고 연달아 일어나는 사건이므로) 곱하여 계산한다. 직관적으로 생각했을 때 후보가 되는 분포가 데이터를 잘 설명한다면 likelihood는 당연히 높게 나올 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;249&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IvfC5/btrdwSafxZL/39UA22qqHv3ouV2LgYPQJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IvfC5/btrdwSafxZL/39UA22qqHv3ouV2LgYPQJk/img.png&quot; data-alt=&quot;데이터가 주어졌을 때 여러가지 후보 분포&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IvfC5/btrdwSafxZL/39UA22qqHv3ouV2LgYPQJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIvfC5%2FbtrdwSafxZL%2F39UA22qqHv3ouV2LgYPQJk%2Fimg.png&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;249&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;데이터가 주어졌을 때 여러가지 후보 분포&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 위의 그림처럼 파란색 데이터 분포를 설명하는 후보 분포가 1,2,3으로 주어졌다고 가정해보자. 이때 각 분포에 대한 likelihood를 구하면 데이터를 잘 설명하는 2번이 가장 큰 값을 가지게 될 것이다. 이렇게 가장 데이터를 잘 설명하는 분포를 likelihood를 통해 구할 수 있고 이런 방법을 Maximum Likelihood Estimation (MLE)라고 부른다.&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;다시 한번 MLE를 정의해보면 다음과 같다. 관측된 표본 데이터 집합을 X라고 했을 때 parameter $\theta$로 구성된 확률 밀도 함수(pdf)에서 $\theta$를 추정하는 방법이다. 이 $\theta$는 Likelihood $L(\theta|x)$를 maximize 함으로 찾을 수 있다. 보통은 파라미터 $\theta$에 대해 편미분 하여 그 값이 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;a href=&quot;https://ko.wikipedia.org/wiki/%EA%B0%80%EB%8A%A5%EB%8F%84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;wikipedia (likelihood)&lt;/a&gt;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <category>Likelihood</category>
      <category>maximum-likelihood</category>
      <category>MLE</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/38</guid>
      <comments>https://simpling.tistory.com/38#entry38comment</comments>
      <pubDate>Sun, 29 Aug 2021 10:49:23 +0900</pubDate>
    </item>
    <item>
      <title>Gaussian Process Regression</title>
      <link>https://simpling.tistory.com/37</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난 &lt;a href=&quot;https://simpling.tistory.com/21&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;gaussian process regression 글&lt;/a&gt;은 weight space view로 설명하여 어려운 느낌이 든다.&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Purpose&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gpr의 목적은 데이터(x, y)를 몇 개 가지고 있고 새로운 x가 있을 때 y를 구하고 싶은 것이 목적이다. 사실 이런 목적은 gpr 뿐 아니라 다른 방법으로도 달성할 수는 있다. linear regression 같은 것이 대표적이다. 하지만 gpr의 장점은 좀 더 복잡한 분포를 잡아낼 수 있다는 것이다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;How&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가지고 있는 데이터(x,y)를 가지고 새로운 x에 대해 y를 추론하는 게 목적이라면 기존 데이터를 어떻게 사용할 것인지 정해야 한다. gpr의 핵심은 기존 데이터들의 관계를 &lt;b&gt;gaussian&lt;/b&gt;과 &lt;b&gt;kernel&lt;/b&gt;을 이용하여 나타내고 새로운 x가 들어왔을 때도 그런 관계를 따른다고 생각하는 것이다.&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;우선 kernel을 알아야 한다. kernel은 (rough 하게 설명하면) 데이터 x와 x'의 관계를 나타내 주는 function이라고 이해하면 된다. 보통 식으로는 $K(x, x')$으로 나타낸다. function은 여러 가지가 될 수 있으며 대표적으로는 RBF kernel ($exp(-\frac {|x-x'|^{2}} {L^{2}})$)이 있다. kernel function은 복잡한 관계를 나타낼 수 있다는 장점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;417&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/skVMm/btrcMFYZOeC/Se1cxK8Iwy6K7zFmUNexJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/skVMm/btrcMFYZOeC/Se1cxK8Iwy6K7zFmUNexJk/img.png&quot; data-alt=&quot;다양한 gaussian 분포 (위키 참조)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/skVMm/btrcMFYZOeC/Se1cxK8Iwy6K7zFmUNexJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FskVMm%2FbtrcMFYZOeC%2FSe1cxK8Iwy6K7zFmUNexJk%2Fimg.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;417&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;다양한 gaussian 분포 (위키 참조)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gaussian 가정은 (식을 간단히 만드는데 유리하여) gaussian process regression을 유도할 때 여러번 사용된다. 먼저 linear regression에서의 weight distribution, 관측 데이터의 distribution이 gaussian이라고 가정하고 식을 유도한다. 관측 데이터 T에 대한 분포가 multivariate normal distribution이라는 가정으로 관측 데이터에 대한 gaussian 분포를 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ P(T) = N(T|0, (\beta I_{N})^{-1}+K) $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 식은 관측 데이터 T에 대한 gaussian distribution을 나타낸 것이다. $\beta$는 precision을 나타내고 K가 input x와 kernel function이 숨어져있는 행렬이다. 즉, input data에 대한 관계를 kernel로 나타낸 것이 관측 데이터의 multivariate gaussian distribution의 variance를 나타내는 데 사용되는 것이다.&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;이제 기존 데이터(x,y)를 가지고 distribution을 나타내는 데 성공했으니 새로운 x가 들어왔을 때 y를 유도하는 것을 알아야 한다. 확률 분포로 나타내면 기존 데이터가 $T_{N}$이고 새로운 input이 $t_{N+1}$일 때 $P(t_{N+1}|T_{N})$를 구하는 것이다. 이 또한 multivariate gaussian distribution이기 때문에 theorem을 사용하면 간단히 할 수 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Result&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 새로운 input $t_{N+1}$에 대한 distribution의 mean과 variance는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \mu_{t_{N+1}} = k^{T} cov_{N}^{-1}T_{N} $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \sigma^{2}_{t_{N+1}} = c-k^{T}cov_{N}^{-1}k $$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 k는 새로운 input과 기존 데이터(N개)의 관계를 kernel로 표현한 행렬이고 $cov_{N}$은 기존 데이터 간의 관계를 kernel로 표현한 행렬이다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Bayesian?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 새로운 input x에 대해 y를 구하는 과정과 결과를 살펴봤다. 그런데 gaussian process regression은 왜 bayesian 방법인가? 베이지안 방법은 prior를 통해 posterior의 분포를 추론하는 것이다. 그럼 여기서 prior는 무엇일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gaussian process (gp) prior는 다음과 같이 나타낼 수 있다. $$P(Y|X) = N(Y|0,K)$$ Y에 대한 확률 분포가 X에 dependent 하며, mean이 0이고 variance가 해당 X들로 만들어지는 kernel matrix일 때 gp prior 라고 한다. (X가 비슷하면 Y가 비슷한 부드러운 곡선을 정의한다) 이런 prior를 사용하여 gaussian process regression은 베이지안 방법이라 할 수 있다.&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;이 글은 gaussian process regression의 전체적인 그림을 보기 위한 글이라 생략을 많이 했다.&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;참조:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.edwith.org/bayesiandeeplearning/joinLectures/14426&quot;&gt;www.edwith.org/bayesiandeeplearning/joinLectures/14426&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1629615993381&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Bayesian Deep Learning 강좌소개 : edwith&quot; data-og-description=&quot;- 최성준&quot; data-og-host=&quot;www.edwith.org&quot; data-og-source-url=&quot;https://www.edwith.org/bayesiandeeplearning/joinLectures/14426&quot; data-og-url=&quot;http://www.edwith.org/bayesiandeeplearning&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/blLnNS/hyLjQESQFG/clRAMnQMlNGbj3bkLXch51/img.jpg?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080,https://scrap.kakaocdn.net/dn/khy4k/hyLjJyXSUF/xzXXzKmJvRoobTYj9UVQ1k/img.jpg?width=760&amp;amp;height=428&amp;amp;face=0_0_760_428&quot;&gt;&lt;a href=&quot;https://www.edwith.org/bayesiandeeplearning/joinLectures/14426&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.edwith.org/bayesiandeeplearning/joinLectures/14426&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/blLnNS/hyLjQESQFG/clRAMnQMlNGbj3bkLXch51/img.jpg?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080,https://scrap.kakaocdn.net/dn/khy4k/hyLjJyXSUF/xzXXzKmJvRoobTYj9UVQ1k/img.jpg?width=760&amp;amp;height=428&amp;amp;face=0_0_760_428');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Bayesian Deep Learning 강좌소개 : edwith&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;- 최성준&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.edwith.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=4vuweopUd_o&quot;&gt;https://www.youtube.com/watch?v=4vuweopUd_o&lt;/a&gt;&amp;nbsp;&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=4vuweopUd_o&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/eJH2X/hyLjXRwGzf/QjwzLuIZKv4MWSpmh30VE1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=748_216_846_324&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;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/4vuweopUd_o&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/베이지안</category>
      <category>bayesian</category>
      <category>gaussian-process</category>
      <category>gaussian-process-regression</category>
      <category>gpr</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/37</guid>
      <comments>https://simpling.tistory.com/37#entry37comment</comments>
      <pubDate>Sun, 22 Aug 2021 16:08:18 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: Learning towards Minimum Hyperspherical Energy</title>
      <link>https://simpling.tistory.com/36</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;&lt;a href=&quot;https://arxiv.org/abs/1805.09298&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Learning towards Minimum Hyperspherical Energy&lt;/a&gt;&quot; (2018, NIPS) - Liu et al.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 논문은 효율적인 neural network 학습을 위해 서로 다른 neuron이 나타내는 feature 사이의 distance가 증가하게 하고 그로 하여금 generalization 성능을 이끌어 내려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 Neural Network 관련 paper들을 보면 크면 클수록(over parameterization) 잘 된다라고 한다. 그런데 한편으로는 클수록&lt;span&gt;&amp;nbsp;&lt;/span&gt;correlation이 높은 neurons가 많아서 redundant 하다고도 한다. 그래서 큰 모델을 학습시키고 Pruning을 시켜 compression 하는 방법이나 efficient network를 찾는 방법을 사용한다. 이 논문에서는 training 할 때 neuron 간의 correlation을 낮춰 redundant한 neuron을 줄이고 generalization을 이끌어 내고자 한다.&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;논문의 제목에서도 알 수 있듯이 Hypershperical energy를 minimize 하여 목표를 달성하고자 한다. Energy는 아래 Formulation에서 정의하는 것을 보면 알 수 있고, 높은 energy를 가질수록 redunancy가 높아지고 낮은 energy일수록 neuron이 다양하고 유니폼하게 위치하여 낮은 energy를 가진다고 생각할 수 있다.&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;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Formulation&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Energy는 아래 1번식 처럼 표현한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;83&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbPy5U/btrcgOG1l1g/FU6M69oa7W8JzqKqcm2MJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbPy5U/btrcgOG1l1g/FU6M69oa7W8JzqKqcm2MJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbPy5U/btrcgOG1l1g/FU6M69oa7W8JzqKqcm2MJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbPy5U%2FbtrcgOG1l1g%2FFU6M69oa7W8JzqKqcm2MJk%2Fimg.png&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;83&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 layer에 N개의 neuron이 있고 각 weight는 d+1 dimension을 가질 때의 상황이다. $f_{s}$는 decreasing real-valued function이며 뭘 쓸지는 선택할 수 있는데 이 논문에서는 $f_{s}(z) = z^{-s} (s&amp;gt;0)$ 를 사용한다. $\hat{w_{i}}$ = $\frac {w_{i}} {||w_{i}||}$ (unit hypersphere에 projection된 neuron)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 식을 간단히 해석하면 각 neuron의 distance가 클수록 Energy는 감소하게 된다고 볼 수 있다 ($f_{s}$ 가 decreasing function 이므로).&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;Energy를 minimize 하는 식은 아래 2번식(s=0인경우),3번식(s&amp;gt;0인 경우) 과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;62&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btcyeI/btrb7zdzbCe/iRKpg4yfZpCNrNYHqMpQLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btcyeI/btrb7zdzbCe/iRKpg4yfZpCNrNYHqMpQLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btcyeI/btrb7zdzbCe/iRKpg4yfZpCNrNYHqMpQLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtcyeI%2Fbtrb7zdzbCe%2FiRKpg4yfZpCNrNYHqMpQLk%2Fimg.png&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;62&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;91&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kZVuc/btrb3nEEzdK/GoIY9KdM0Vb0K4Yvh7ZhP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kZVuc/btrb3nEEzdK/GoIY9KdM0Vb0K4Yvh7ZhP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kZVuc/btrb3nEEzdK/GoIY9KdM0Vb0K4Yvh7ZhP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkZVuc%2Fbtrb3nEEzdK%2FGoIY9KdM0Vb0K4Yvh7ZhP1%2Fimg.png&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;91&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Loss object는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;108&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rG5Zc/btrb3m6OJLS/aewkinSKMGpExAKKnJ2cv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rG5Zc/btrb3m6OJLS/aewkinSKMGpExAKKnJ2cv0/img.png&quot; data-alt=&quot;Loss function&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rG5Zc/btrb3m6OJLS/aewkinSKMGpExAKKnJ2cv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrG5Zc%2Fbtrb3m6OJLS%2FaewkinSKMGpExAKKnJ2cv0%2Fimg.png&quot; data-origin-width=&quot;1017&quot; data-origin-height=&quot;108&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Loss function&lt;/figcaption&gt;
&lt;/figure&gt;
&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;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;MHE Variants&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MHE의 변형으로 논문에서 제시한 것이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) Half-space MHE&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;figure2의 왼쪽 그림을 보면 그냥 MHE를 사용했을 때 neuron의 방향은 반대이나 (그래서 distance는 크지만) collinear한 관계가 되버린다. 이런 경우를 방지하기 위해 half-space MHE를 제시한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;237&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SHKRc/btrb9RxNxmv/ACjMhq9R9ZB26RUyF0YP11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SHKRc/btrb9RxNxmv/ACjMhq9R9ZB26RUyF0YP11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SHKRc/btrb9RxNxmv/ACjMhq9R9ZB26RUyF0YP11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSHKRc%2Fbtrb9RxNxmv%2FACjMhq9R9ZB26RUyF0YP11%2Fimg.png&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;237&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법은 간단한데, 애초에 반대방향의 neuron을 생성하고 MHE를 사용하는 것이다. 그러면 결과적으로 (원래 N개의 neuron이 존재하면) 2N개의 neuron을 얻게 될 것이고 이는 Figure 2의 오른쪽 그림처럼 correlation이 낮은 $\hat {W_{1}}, \hat {W_{2}}$를 얻을 수 있게된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 실제로 high-dimensional space 에서는 collinearity가 거의 일어나지 않으므로 그냥 MHE 방법도 잘 된다고 주장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) Angular MHE&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1)번 식에서는 원래 Euclidean distance로 neuron간의 거리를 구했는데 이번엔 (5)번 식처럼 arccos (angle)을 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;78&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byG3xL/btrb77U4zBF/ihnxr81pCqUCvr07x2sNh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byG3xL/btrb77U4zBF/ihnxr81pCqUCvr07x2sNh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byG3xL/btrb77U4zBF/ihnxr81pCqUCvr07x2sNh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyG3xL%2Fbtrb77U4zBF%2Fihnxr81pCqUCvr07x2sNh0%2Fimg.png&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;78&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 unit hypersphere에서 neuron 사이의 각도로 나타낸 거리가 커지게 만든다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Experiments&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흥미로운 실험들만 남겨둔다. Table2는 width가 커질 때 각 알고리즘 결과이고 Table3은 depth가 커질 때 결과이다. MHE를 썼을 때 Baseline 보다 network size가 작음에도 (width, depth 모두) 더 좋은 성능을 보이는 경우가 많았다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;125&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nK0ZB/btrcjapv4Z1/H4Ijf0sXX9ml8gW4IbRq6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nK0ZB/btrcjapv4Z1/H4Ijf0sXX9ml8gW4IbRq6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nK0ZB/btrcjapv4Z1/H4Ijf0sXX9ml8gW4IbRq6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnK0ZB%2Fbtrcjapv4Z1%2FH4Ijf0sXX9ml8gW4IbRq6K%2Fimg.png&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;125&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;160&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/65oO8/btrcecnR3vU/JGCKnotQz3YxkCZMK5UKc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/65oO8/btrcecnR3vU/JGCKnotQz3YxkCZMK5UKc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/65oO8/btrcecnR3vU/JGCKnotQz3YxkCZMK5UKc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F65oO8%2FbtrcecnR3vU%2FJGCKnotQz3YxkCZMK5UKc0%2Fimg.png&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;160&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서로 다른 classifier neuron에 대해서도 hyperspherical margin이 maximize 되도록 학습되어서 Class Imbalance 문제에서도 잘 작동했다. Figure4는 MNIST 데이터에서 0에 해당하는 데이터를 98% 날리고 학습시켰을 때 결과다. (화살표는 classifier neuron이고 각 색에 해당하는 것은 숫자다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;263&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl1z5Z/btrcf7fs6A9/B90zFgtTsNjWqBZlHtlFU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl1z5Z/btrcf7fs6A9/B90zFgtTsNjWqBZlHtlFU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl1z5Z/btrcf7fs6A9/B90zFgtTsNjWqBZlHtlFU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl1z5Z%2Fbtrcf7fs6A9%2FB90zFgtTsNjWqBZlHtlFU0%2Fimg.png&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;263&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽이 MHE를 안쓴 경우인데 남색(아마 0에 해당하는 듯) 부분 화살표를 잘 보면 연두색과 매우 가깝고 제대로 분류하지 못한 것을 볼 수 있다. 반면 MHE를 쓴 오른쪽은 남색도 clear 하게 분류한 것을 볼 수 있다.&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>class-imbalance</category>
      <category>efficient-neural-network</category>
      <category>Generalization</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/36</guid>
      <comments>https://simpling.tistory.com/36#entry36comment</comments>
      <pubDate>Sun, 15 Aug 2021 17:30:18 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: Sharpness-Aware Minimization for Efficiently Improving Generalization</title>
      <link>https://simpling.tistory.com/35</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2010.01412&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&quot;Sharpness-Aware Minimization for Efficiently Improving Generalization&quot;&lt;/a&gt; (2020, google research)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이번 논문은 flat minima를 찾아 Generalization 성능을 이끌어내는 알고리즘을 제안한 논문이다. Flat minimum의 loss는 주위 loss와 차이가 별로 나지 않을 것임을 안다. 이런 조건을 만족하도록 optimize 하는게 핵심이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존부터 loss landscape은 generalization 논문에서 자주 등장한다. 보통의 경우 landscape이 flat 할수록 general 한 성능을 보이고 sharp 할수록 그렇지 않다고 주장한다 (보통의 경우라 한 이유는 그 반대의 주장을 하는 논문도 있기 때문이다). 이는 직관적으로 말이 되는데 아래 &amp;lt;그림 1&amp;gt;과 같은 경우를 생각하면 된다. Tr은 Train set에 대한 loss landscape이며 Te는 Test set에 대한 loss landscape이다. 왼쪽은 flat 한 경우이고 오른쪽은 sharp 한 경우이다. Test set과 Train set이 달라서 landscape이 살짝 shift 되었다고 가정한다. flat 한 경우 test set에 대한 loss 값은 train set의 optimal loss와 많이 차이 나지 않지만 sharp 한 경우에는 많이 차이가 나게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XGEXp/btrbyHvpGzh/IuzIpMyZKuKnhGOkGvpo20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XGEXp/btrbyHvpGzh/IuzIpMyZKuKnhGOkGvpo20/img.png&quot; data-alt=&quot;그림 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XGEXp/btrbyHvpGzh/IuzIpMyZKuKnhGOkGvpo20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXGEXp%2FbtrbyHvpGzh%2FIuzIpMyZKuKnhGOkGvpo20%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;579&quot; height=&quot;146&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 보통 flat minima를 찾고 싶어 하고 이 논문에서도 그런 방법을 제시한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Objective Function&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p 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;1305&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KhGei/btrbtnre9to/ABeeGv4gsp5qKn7LtM6Iy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KhGei/btrbtnre9to/ABeeGv4gsp5qKn7LtM6Iy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KhGei/btrbtnre9to/ABeeGv4gsp5qKn7LtM6Iy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKhGei%2Fbtrbtnre9to%2FABeeGv4gsp5qKn7LtM6Iy1%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;1305&quot; height=&quot;197&quot; data-origin-width=&quot;1305&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Theorem 1 에서 training method를 유도한다. Data의 distribution이 D이고 거기서 (i.i.d condition에서) sampling 된 training set S 가 있을 때 Loss 간의 관계를 나타낸 것이다. Generalization이 극대화되기 위해서는 Data set D에 대한 Loss (즉 $L_{D}(w)$)가 minimize 돼야 한다 (test set을 잘 맞추는 게 목적이므로 너무 당연). 그래서 오른쪽 항을 minimize 하여 $L_{D}(w)$도 함께 minimize 하려고 하는데 오른쪽 항은 사실 sharpness와 관련된 식이다 (아래 식을 보면 그렇다).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSBLYI/btrbwibGUK0/Bfos6YiIFCH3l4otttWz0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSBLYI/btrbwibGUK0/Bfos6YiIFCH3l4otttWz0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSBLYI/btrbwibGUK0/Bfos6YiIFCH3l4otttWz0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSBLYI%2FbtrbwibGUK0%2FBfos6YiIFCH3l4otttWz0k%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;762&quot; height=&quot;87&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Theorem 1의 오른쪽 항을 위의 식처럼 표현 가능한데 대괄호 안의 항이 sharpness와 관련이 있게 된다. 설명하면 이렇다. ($\epsilon$은 perturbation 을 표현한다.) weight perturb (loss가 커지게 만드는)를 줬을 때의 loss와 그렇지 않았을 때의 loss 차이를 보는 것이므로 perturb에 민감하면 (loss landscape이 sharp 하면) 값이 커질 것이고 둔감하면 (loss landscape이 flat 하면) 값이 작아질 것이다. 이는 &amp;lt;그림 1&amp;gt;에서 생각해본 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 위의 식을 optimize 하면 결국 flat minima를 찾게 된다. 정확한 알고리즘은 밑에서 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Algorithm&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p 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;658&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXtfsL/btrbq4E39SH/j5KTBblkutrtOPtLdEl9Qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXtfsL/btrbq4E39SH/j5KTBblkutrtOPtLdEl9Qk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXtfsL/btrbq4E39SH/j5KTBblkutrtOPtLdEl9Qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXtfsL%2Fbtrbq4E39SH%2Fj5KTBblkutrtOPtLdEl9Qk%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;467&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;467&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에 나온 알고리즘 과정은 위와 같은데 쉽게 그림을 보면서 이해해보겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;470&quot; data-origin-height=&quot;383&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blv5sb/btrbEhphKTV/bhH88n4BF23zQ4rgOnIv91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blv5sb/btrbEhphKTV/bhH88n4BF23zQ4rgOnIv91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blv5sb/btrbEhphKTV/bhH88n4BF23zQ4rgOnIv91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fblv5sb%2FbtrbEhphKTV%2FbhH88n4BF23zQ4rgOnIv91%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;470&quot; height=&quot;383&quot; data-origin-width=&quot;470&quot; data-origin-height=&quot;383&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림 위의 숫자는 알고리즘이 진행되는 순서를 나타낸다. 첫번째로 $W_{t}$에서 loss가 maximize 되도록 만드는 perturb를 구하고 $W_{adv}$로 gradient ascent 한다. 두 번째로 $W_{adv}$에서 loss가 minimize 되도록 만드는 기울기를 구한다. 마지막으로 $W_{t}$에서 두 번째에서 구한 기울기로 gradient descent를 하면 알고리즘이 끝난다. 간단하면서도 직관적인 알고리즘인데 성능도 SOTA를 이뤘다 (논문 참조). 결과에서는 모델이 얼마나 Robust 하게 만들어졌는지를 테스트해보기도 하고 $\lambda_{max}$를 구해서 flat 한 정도도 찾아보며 검증을 많이 했는데 따로 첨부하지는 않는다. Robust 한 모델을 research 중이라면 한 번쯤 볼만한 논문인 것 같다.&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>Generalization</category>
      <category>Robust model</category>
      <category>Weight perturbation</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/35</guid>
      <comments>https://simpling.tistory.com/35#entry35comment</comments>
      <pubDate>Sun, 8 Aug 2021 18:32:26 +0900</pubDate>
    </item>
    <item>
      <title>Variational AutoEncoder란?</title>
      <link>https://simpling.tistory.com/34</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=LeVkjCuUdRs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;오토인코더의 모든 것(youtube) - 이활석&lt;/a&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;a href=&quot;https://hugrypiggykim.com/2018/09/07/variational-autoencoder%EC%99%80-elboevidence-lower-bound/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Variational AutoEncoder와 ELBO(blog) - Seon Guk&lt;/a&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/1312.6114.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&quot;Auto-Encoding Variational Bayes&quot;(2014) - Kingma et al.&lt;/a&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;a href=&quot;https://s3.us-west-2.amazonaws.com/secure.notion-static.com/cccff0e6-e337-412d-928a-c3ecbbcac4da/1906.02691.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;amp;X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20201204%2Fus-west-2%2Fs3%2Faws4_request&amp;amp;X-Amz-Date=20201204T075143Z&amp;amp;X-Amz-Expires=86400&amp;amp;X-Amz-Signature=71f9382f2a91be22bd97f6f396730143c00f9410f8a00984ebff293c51c1a864&amp;amp;X-Amz-SignedHeaders=host&amp;amp;response-content-disposition=filename%20%3D%221906.02691.pdf%22&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&quot;An Introduction to Variational AutoEncoders(2019)&quot; - Kingma et al.&lt;/a&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; &amp;nbsp;이활석님의 &lt;span style=&quot;color: #333333;&quot;&gt;명강의 &lt;/span&gt;'오토인코더의 모든 것' , VAE와 ELBO에 대해 슬라이드로 잘 정리한 블로그, Variational AutoEncoder(VAE)에 대한 논문을 참조하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp;VAE는 Autoencoder와는 다르게 latent variable을 Gaussian 분포 같이 잘 알려진 Prior 분포를 설정하고 거기에 맞출 수 있어서 이미지 등을 만들 때 편리한 생성 모델이다. 이를 이해하기 위한 기초 개념들이 중요한 것이 많아 정리한 것을 남긴다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;VAE 구조&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E7Lss/btqPfTKCSD6/ZCCxIoySo1N2UJNMOTN4UK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E7Lss/btqPfTKCSD6/ZCCxIoySo1N2UJNMOTN4UK/img.png&quot; data-alt=&quot;VAE 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E7Lss/btqPfTKCSD6/ZCCxIoySo1N2UJNMOTN4UK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE7Lss%2FbtqPfTKCSD6%2FZCCxIoySo1N2UJNMOTN4UK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;VAE 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위의 그림은 VAE의 과정을 표현한 것이다. 강아지 사진이 입력으로 들어가면 Encoder에서 데이터에 대한 분포를 나타내는데, 가우시안 분포를 가정하여 mean과 std로 출력한다. 이 분포에 대한 데이터를 전부 사용할 수 없으니 샘플링을 하게 되고 이때 Reparameterization trick을 사용한다. Reparameterization trick은 $\epsilon$을 N(0,1)에서 샘플링해서 &lt;span style=&quot;color: #333333;&quot;&gt;std에 곱해주고 mean과 더해주는 방법으로 샘플링을 직접 하는 것을 막는 방법이다. 이것&lt;span&gt;&lt;/span&gt;&lt;/span&gt;을 사용하지 않으면 출력된 mean과 std에 대한 가우시안 분포에서 직접 샘플링을 해야 하는데 그렇게 되면 deterministic하지 않기 때문에 역전파가 불가하다. 이에 대한 그림은 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5K5Ck/btqO8WvAG1i/z4LVZYhz00qU0MXcY9gLU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5K5Ck/btqO8WvAG1i/z4LVZYhz00qU0MXcY9gLU0/img.png&quot; data-alt=&quot;&amp;amp;quot;An Introduction to Variational AutoEncoders(2019)&amp;amp;quot; - Kingma et al.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5K5Ck/btqO8WvAG1i/z4LVZYhz00qU0MXcY9gLU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5K5Ck%2FbtqO8WvAG1i%2Fz4LVZYhz00qU0MXcY9gLU0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;&quot;An Introduction to Variational AutoEncoders(2019)&quot; - Kingma et al.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;샘플링한 Latent variable은 z라고 부르고 이것을 사용해 Decoder를 통과시켜 원래 데이터를 생성시키게 된다. AutoEncoder는 Manifold로 차원 축소를 잘 해내는 것이 목적이지만 Variational AutoEncoder는 latent variable z가 Gaussian distribution을 따른다고 가정하여 생성에 쓰고자 하는 것이 목적이다. z는 gaussian 분포이므로 나중에 굳이 Encoder를 사용하지 않고 뽑고 싶은 데이터에 대해 &lt;span style=&quot;color: #333333;&quot;&gt;gaussian 샘플링을 해주면 되므로 생성 모델에 적합하다. &lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Encoder - x를 잘 나타내는 z를 생성하는 sampling 함수 $q_{\phi}$&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; VAE는 데이터 셋에 있는 데이터들과 유사한 분포를 가지는 데이터를 &lt;b&gt;생성&lt;/b&gt;하는 것이 목적이다. 그런데 데이터 x를 잘 나타내는 함수가 필요하다. 이런 함수를 직접 구하진 못하므로 잘 알고있는 함수(ex. gaussian) $q_{\phi}$를 근사시키는 Variational Inference 방법을 적용한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;모든 x에 대해 z가 생성될 확률은 1이므로 $ \int q(z|x) dz = 1 $로 표현 가능하다. 그러므로 P(x)에 log를 취해서 식을 전개해보면 다음과 같이 표현된다.&lt;/p&gt;
&lt;p&gt;$$ log P(x) = log P(x) \int q(z|x) dz $$&lt;/p&gt;
&lt;p&gt;$$ = \int q(z|x) log P(x) dz $$&lt;/p&gt;
&lt;p&gt;베이즈 룰에 의해 $ log P(x) = log \frac {P(x|z) P(z)} {P(z|x)} = log P(x|z) + log P(z) - log P(z|x) $ 이므로 위의 식을 다음과 같이 전개한다.&lt;/p&gt;
&lt;p&gt;$$ = \int q(z|x) [log P(x|z) + log P(z) - log P(z|x)] dz $$&lt;/p&gt;
&lt;p&gt;$$ = \int q(z|x) log P(x|z) dz + \int q(z|x) (log P(z) - log P(z|x)) dz \pm \int q(z|x) log q(z|x) dz $$&lt;/p&gt;
&lt;p&gt;확률 밀도 함수 $ q(z|x) $ 를 따르는 x에 대한 P(x|z)의 기댓값은 q(z|x)를 따르는 샘플들로 근사할 수 있다. 이를 Monte Carlo Approximation이라고 하며 다음과 같이 나타낼 수 있다. $ \int q(z|x) log P(x|z) dz = E_{q(z|x)} [log P(x|z)] $ 이를 위의 식에 반영하면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ = E_{q(z|x)}[log P(x|z)] - \int q(z|x) logq(z|x) dz + \int q(z|x) log q(z|x) dz + \int q(z|x) log P(z) dz $$&lt;/p&gt;
&lt;p&gt;$$ + \int q(z|x) log q(z|x) dz - \int q(z|x) log P(z|x) dz $$&lt;/p&gt;
&lt;p&gt;이제 $ KL(p, q) = \int p(x) log p(x) dx - \int p(x) log q(x) dx $식을 이용하여 식을 바꿔주면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ = E_{q(z|x)} [log P(x|z)] - KL(q(z|x), P(z)) + KL(q(z|x),P(z|x)) \cdots (1)$$&lt;/p&gt;
&lt;p&gt;마지막 항의 P(z|x)는 x의 분포가 매우 복잡하여 나타내지 못하므로 구하지 못한다. 따라서 생략하여 표현하고 KL-divergence는 항상 0보다 큰 값을 가지므로 최종적으로 다음과 같이 표현할 수 있다.&lt;/p&gt;
&lt;p&gt;$$ log P(x) \ge E_{q(z|x)} [log P(x|z)] - KL(q(z|x),P(z)) $$&lt;/p&gt;
&lt;p&gt;데이터 x가 나올 확률 P(x)를 최대화하면 Network를 잘 학습시킨다고 할 수 있다. 위의 식을 앞으로 Evidence Lower Bound(ELBO)라고 부른다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다른 해석도 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhXUFA/btqPgH5pT2g/KRJJkxJCtF1UUnkwTXYw11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhXUFA/btqPgH5pT2g/KRJJkxJCtF1UUnkwTXYw11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhXUFA/btqPgH5pT2g/KRJJkxJCtF1UUnkwTXYw11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhXUFA%2FbtqPgH5pT2g%2FKRJJkxJCtF1UUnkwTXYw11%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;(1)식에서 마지막 항 $ KL(q_{\phi}(z|x), P(z|x)) $는 z가 x를 잘 표현하는 이상적인 sampling 함수 P와 $q_{\phi}$ 함수의 거리를 나타낸다. 이 두 함수의 차이를 줄이면(KL을 minimize 하면) 이상적 sampling 함수에 가까워지는 $q_{\phi}$를 얻게 되는데&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;P(z|x)는 x의 분포가 매우 복잡하여 구하지 못한다. 대신 위의 그림처럼 ELBO를 Maximize 하여 &lt;span style=&quot;color: #333333;&quot;&gt;간접적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;$KL(q(z|x), P(z|x))$를 minmize 하는 방법을 사용한다. &lt;/span&gt;이를 Variational Inference라고 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Decoder - z로부터 x를 잘 생성하는 함수 $g_{\theta}$&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;span style=&quot;color: #333333;&quot;&gt;Decoder에 &lt;/span&gt;z를 줬을 때 x가 나오게 나올 확률을 maximize 하게 해야 한다. 식으로는 $ E_{q_{\phi}(z|x)}[log (P(x|g_{\theta}(z))]$가 된다. 이는 Likelihood를 Maximize 하는 문제가 되어 풀 수 있다. ($q_{\theta}$를 통과한 값이 어떤 분포를 가정하냐에 따라 다른 loss function을 사용한다. gaussian(sigma=1인)이라면 mse, bernoulli 라면 cee를 사용한다(자세한 내용은 &lt;a href=&quot;https://simpling.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;를 참조))&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그런데 수식으로 보면 이미 ELBO안에 들어가 있다. 그러므로 최종 optimization 식은 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ argmin_{\phi, \theta} \sum_{i} -E_{q_{\phi}(z|x_{i})}[log(P(x_{i}|g_{\theta}(z)))] + KL(q_{\phi}(z|x_{i})|P(z)) $$&lt;/p&gt;
&lt;p&gt;첫 항은 Reconstruction Error로 x로부터 z를 생성하였고 z를 decoder에 넣었을 때 데이터 x를 얼마나 잘 생성해 냈는지를 의미한다.&lt;/p&gt;
&lt;p&gt;두 번째 항은 Regularization term으로 데이터 x가 Encoder를 통해 나온 z가 P(z)와 유사하게 분포하도록 만들어 준다. 이는 나중에 모델을 생성할 때 사용하는데 편리함을 준다. P(z)와 $q(z|x)$는 gaussian distribution을 가정하므로 KL-divergence를 쉽게 구할 수 있다(자세한 내용은 &lt;a href=&quot;https://simpling.tistory.com/33&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;를 참조).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Encoder $q_{\phi}$의 출력은 gaussian, Decoder $g_{\theta}$의 출력은 beroulli를 따른다고 가정하면 각각의 Error는 다음과 같이 계산된다.&lt;/p&gt;
&lt;p&gt;$$ Reconstruction Error : -\sum_{j=1}^{D} x_{i, j} log p_{i, j} + (1-x_{i, j}) log (p-p_{i, j}) $$&lt;/p&gt;
&lt;p&gt;$$ Regularization term : \frac {1} {2} \sum_{j=1}^{J}(\mu_{i, j}^{2} + \sigma_{i, j}^{2} - ln(\sigma_{i, j}^{2})-1)$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <category>ELBO</category>
      <category>VAE</category>
      <category>variational autoencoder</category>
      <category>오토인코더</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/34</guid>
      <comments>https://simpling.tistory.com/34#entry34comment</comments>
      <pubDate>Sun, 29 Nov 2020 10:04:10 +0900</pubDate>
    </item>
    <item>
      <title>KL-divergence with Gaussian distribution 증명</title>
      <link>https://simpling.tistory.com/33</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://stats.stackexchange.com/questions/7440/kl-divergence-between-two-univariate-gaussians&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://namu.wiki/w/%EA%B0%80%EC%9A%B0%EC%8A%A4%20%EC%A0%81%EB%B6%84&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://mathcs.clarku.edu/~djoyce/ma217/contexp.pdf&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://ko.wikipedia.org/wiki/%EC%A0%95%EA%B7%9C_%EB%B6%84%ED%8F%AC&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이번에는 두 개의 서로 다른 Gaussian 분포를 가정했을 때 KL-divergence&lt;span&gt;(Kullback&amp;ndash;Leibler divergence,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;KLD&lt;/b&gt;&lt;span&gt;)&lt;/span&gt;를 구하는 유도 과정을 정리한다. 위의 여러 링크들을 참고하였는데 중간중간 생략한 내용들이 많아 자세한 설명을 남겨둔다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 먼저 알아둬야 할 기초적인 내용을 정리해 보겠다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;1) Gaussian 분포&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;516&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0jcY1/btqOhPiNZmv/jRKBdEwmbZMLXvT6aH3g11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0jcY1/btqOhPiNZmv/jRKBdEwmbZMLXvT6aH3g11/img.png&quot; data-alt=&quot;가우시안 분포 (위키)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0jcY1/btqOhPiNZmv/jRKBdEwmbZMLXvT6aH3g11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0jcY1%2FbtqOhPiNZmv%2FjRKBdEwmbZMLXvT6aH3g11%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;516&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;가우시안 분포 (위키)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;가우시안 분포는 위의 그래프와 같이 mean과 variance에 따라 다른 모양을 가진다. 빨간색 그림처럼 mean=0, variance=1 인 경우를 특별히 표준 정규 분포라고 부른다.&lt;/p&gt;
&lt;p&gt;$mean : \mu, variance : \sigma^{2}$인 가우시안 분포를 함수로 나타내면 아래의 수식과 같다.&lt;/p&gt;
&lt;p&gt;$$ N(\mu, \sigma) = \frac {1} {\sqrt {2\pi \sigma^{2}}} e^{\frac {-(x-\mu)^{2}} {2 \sigma^{2}}} \cdots (1)$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2) 기댓값(평균값)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;밑에서 기댓값에 대한 내용이 나와 간단히 정리하고 넘어간다. 고등학교 통계학 때 배운 내용으로 매우 기초적인 것들이다. 기댓값은 평균값과 같은 의미로 사용되며 discrete random variable X에 대한 식은 다음과 같이 표현된다.&lt;/p&gt;
&lt;p&gt;$$ \mu = E(X) = \sum_{x} xf(x) $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;x&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;P(x)&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;1/4&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;1/2&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;1/4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이에 대한 간단한 예시로 위의 표와 같은 값을 갖는 x와 그에 대한 확률 P(x)가 있을 때 평균값은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;$$ \mu = 0 * \frac {1} {4} + 1 * \frac {1} {2} + 2 * \frac {1} {4} = 1 $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음으로 continuous random variable X에 대한 식은 다음과 같이 표현된다.&lt;/p&gt;
&lt;p&gt;$$ \mu = E(X) = \int_{-\infty}^{\infty} xf(x) dx \cdots (2) $$&lt;/p&gt;
&lt;p&gt;discrete 한 값을 계산하는 것에서 적분식으로 바꿔준 것으로 만약 [a, b] 구간을 벗어난 f(x) 값이 0이라면 다음과 같이 표현할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$ \mu = E(X) = \int_{b}^{a} xf(x) dx $$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(기댓값과 관련한 내용은 &lt;a href=&quot;https://mathcs.clarku.edu/~djoyce/ma217/contexp.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;를 참조)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3) 가우스 적분&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;유도 과정에서 가우스 적분이 필요하기 때문에 먼저 정리해둔다. (정확한 유도과정은 &lt;a href=&quot;https://namu.wiki/w/%EA%B0%80%EC%9A%B0%EC%8A%A4%20%EC%A0%81%EB%B6%84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;를 참조)&lt;/p&gt;
&lt;p&gt;$$ \int_{-\infty}^{\infty} e^{-x^{2}}dx = \sqrt {\pi} \cdots (3) $$&amp;nbsp;&lt;/p&gt;
&lt;p&gt;$$ \int_{-\infty}^{\infty} x^{n} e^{-ax^{2}}dx = \frac {2(n-1)!} {2^{(n+2)/2} a^{n/2}} \sqrt {\frac {\pi} {a}} (n:짝수) \cdots (4)$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$\cdot$ Kullback&amp;ndash;Leibler divergence with Gaussian distribution&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; KL-divergence(KLD)는 두 확률 분포 사이의 차이가 얼마나 나는지를 보기 위한 함수다. 두 확률분포 p, q에 대한 KLD를 식으로 표현하면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ D_{KL}(p||q) = \int p(x) log \frac {p(x)} {q(x)} dx $$&lt;/p&gt;
&lt;p&gt;$$ = \int p(x) log p(x) dx - \int p(x) log q(x) dx \ge 0 $$&lt;/p&gt;
&lt;p&gt;두 함수의 분포가 같아지면 $D_{KL} (p||q) = 0$이 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이제 p와 q가 Gaussian 분포를 따른다고 가정하고 식을 유도해 볼 것이다. p $ = N(\mu_{1}, \sigma_{1})&amp;nbsp; $,&amp;nbsp;q $ = N(\mu_{2}, \sigma_{2}) $&lt;/p&gt;
&lt;p&gt;$$ KL(p, q) = -\int p(x) log q(x) dx + \int p(x) log p(x) dx $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;1) $ \int p(x) log p(x) dx $ 계산&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;먼저 $\int p(x) log p(x) dx$에 대해 계산해본다. 편의상 $ Z = \frac {1} {\sqrt {2\pi \sigma^{2}}} $으로 나타낸다. p에 대한 분포이므로 $\sigma_{1}, \mu_{1} $에 대한 식이지만 여기서는 구분하지 않아도 되므로 생략한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(1)의 gaussian 함수를 p(x)에 넣으면 다음과 같이 정리된다.&lt;/p&gt;
&lt;p&gt;$$ \int p(x) log p(x) dx = \int Z e^{-\frac {(x-\mu)^{2}} {2 \sigma^{2} } } (- \frac {(x-\mu)^{2}} {2 \sigma^{2}} +log Z) dx $$&lt;/p&gt;
&lt;p&gt;이제 $\frac {x-\mu} {\sqrt {2}\sigma} = t, \frac {1} {\sqrt {2} \sigma} dx = dt$ 로 치환하면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ \int Ze^{-t^{2}} (-t^{2} + log Z ) \sqrt{2} \sigma dt $$&lt;/p&gt;
&lt;p&gt;Z를 다시 바꾸고 괄호를 풀면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ \frac {1} {\sqrt {\pi}} \int e^{-t^{2}} (-t^{2}) dt -\frac {log(2\pi \sigma^{2})} {2 \sqrt{\pi}} \int e^{-t^{2}} dt $$&lt;/p&gt;
&lt;p&gt;여기서 가우스 적분식 (3)과 (4)를 이용하면 최종적으로 다음과 같이 유도된다.&lt;/p&gt;
&lt;p&gt;$$ \int p(x) logp(x) dx = - \frac {1} {2} - \frac {1} {2} log(2 \pi \sigma_{1}^{2}) = -\frac {1} {2} (1+log(2\pi \sigma_{1}^{2})) $$&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;2) $ \int p(x) log q(x) dx $ 계산&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음으로 $ \int p(x) logq(x) dx $를 계산해본다. 먼저 (1)의 gaussian 함수를 q(x)에 넣어 정리한다.&lt;/p&gt;
&lt;p&gt;$$ - \int p(x)logq(x) dx = - \int p(x) log \frac {1} {\sqrt {2 \pi \sigma_{2}^{2}}} e ^{-\frac{(x-\mu_{2})^{2}} {2\sigma_{2}^{2}}} dx $$&lt;/p&gt;
&lt;p&gt;log안의 식을 분리하면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ - \int p(x) log \frac {1} {\sqrt {2\pi \sigma_{2}^{2}}} dx + \int p(x) \frac {(x-\mu_{2})^{2}} {2\sigma_{2}^{2}} dx $$&lt;/p&gt;
&lt;p&gt;$ \int p(x) dx = 1 $을 사용하여 첫 번째 항을 바꾸고 두 번째 항을 전개하면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ \frac {1} {2} log(2\pi \sigma_{2}^{2}) + \frac {\int p(x) x^{2} dx - \int 2 \mu_{2} x p(x) dx + \mu_{2}^{2} \int p(x) dx } {2 \sigma_{2}^{2}} $$&lt;/p&gt;
&lt;p&gt;이제 (2)의 식을 이용하여 오른쪽 항의 분자식을 바꿔주면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ \frac {1} {2} log (2\pi \sigma_{2}^{2}) + \frac {E_{1}(x^{2}) - 2 \mu_{2} E_{1}(x) + \mu_{2}^{2}} {2 \sigma_{2}^{2}} $$&lt;/p&gt;
&lt;p&gt;분산의 정의가 $ \sigma^{2} = E(x^{2}) - E^{2}(x) $이므로 $ E(x^{2}) = \sigma^{2} + E^{2}(x) $을 이용하여 식을 바꾸면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ \frac {1} {2} log(2 \pi \sigma_{2}^{2}) + \frac { \sigma_{1}^{2} +\mu_{1}^{2} - 2\mu_{2}\mu_{1} + \mu_{2}^{2} } { 2 \sigma_{2}^{2} } $$&lt;/p&gt;
&lt;p&gt;$$ = \frac {1} {2} log (2 \pi \sigma_{2}^{2}) + \frac {\sigma_{1}^{2}+(\mu_{1}-\mu_{2})^{2}} {2\sigma_{2}^{2}} $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;3) 정리&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이제 $\int p(x) logp(x) dx$와 $- \int p(x) log q(x) dx$를 합해서 식을 정리하면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ \therefore KL(p, q) = - \int p(x) log q(x) dx + \int p(x) log p(x) dx $$&lt;/p&gt;
&lt;p&gt;$$ = \frac {1} {2} log (2\pi \sigma_{2}^{2}) + \frac {\sigma_{1}^{2} + (\mu_{1} - \mu_{2})^{2}} {2\sigma_{2}^{2}} - \frac {1} {2} (1+log(2\pi \sigma_{1}^{2})) $$&lt;/p&gt;
&lt;p&gt;$$ = log \frac {\sigma_{2}} {\sigma_{1}} + \frac {\sigma_{1}^{2} + (\mu_{1} - \mu_{2})^{2})} {2\sigma_{2}^{2}} - \frac {1} {2} $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <category>gaussian</category>
      <category>KL-Divergence</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/33</guid>
      <comments>https://simpling.tistory.com/33#entry33comment</comments>
      <pubDate>Thu, 26 Nov 2020 11:27:12 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: SDE-Net: Equipping Deep Neural Networks with Uncertainty Estimates</title>
      <link>https://simpling.tistory.com/31</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&quot;&lt;a href=&quot;https://arxiv.org/abs/2008.10546&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SDE-Net: Equipping Deep Neural Networks with Uncertainty Estimates&lt;/a&gt;&quot; &lt;/b&gt;(2020, ICML) - Lingkai Kong et al.&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://en.wikipedia.org/wiki/Euler%E2%80%93Maruyama_method&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp;https://arxiv.org/abs/1806.07366&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://en.wikipedia.org/wiki/Euler_method&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://github.com/msurtsukov/neural-ode/blob/master/Neural%20ODEs.ipynb&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://github.com/Lingkai-Kong/SDE-Net&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이번 논문은 2018 nips에 올라온 Neural ordinary differential equations(Chen et al.)의 방법에 stochastic 한 과정을 더해 uncertainty를 추가하는 방법을 제시하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(이론과 함께 official pytorch 코드(&lt;span style=&quot;color: #333333;&quot;&gt;Regression을 수행하는 모델)&lt;/span&gt;를 참고하여 tensorflow 코드를 첨부하였습니다.)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp;기존에 uncertainty를 추정하는 방법들은 베이지안 방법이 주를 이루었다. 베이지안 방법은 prior를 도입하여 posterior 분포를 추정하여야 한다. 하지만 DNN의 parameters가 너무 많아 계산이 어렵다. 그래서 non-bayesian 방법들도 나왔는데 가장 유명한 것이 model ensembling 방법이다. 이 방법은 여러 DNNs를 학습시켜 예측의 다른 정도를 가지고 uncertainty를 얻는다. 이러한 방법은 여러 모델을 학습시켜야 하므로 computational cost가 크다. 또 다른 방법들은 aleatoric uncertainty(데이터에 내재된 불확실성)와 epistemic uncertainty(모델이 모르는 불확실성)를 구분하여 측정하지 못하는 문제를 가지고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이러한 문제들을 SDE-Net을 사용하여 해결한다. SDE-Net은 &lt;span style=&quot;color: #333333;&quot;&gt;drift net과 diffusion &lt;span style=&quot;color: #333333;&quot;&gt;net을 번갈아 가며 학습시킨다. &lt;/span&gt;&lt;/span&gt;drift net으로 예측의 정확성을 높이며 aleatoric uncertainty를 측정할 수 있고 , diffusion net으로 epistemic uncertainty를 측정하게 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Uncertainty에는 2가지 종류가 있다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Aleatoric Uncertainty&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- 데이터에 내재된 노이즈(3과 8을 구분하는 것 등)에 반응한다.&lt;/p&gt;
&lt;p&gt;- 데이터가 randomness 한 경우(동전 던지기 등)에 반응한다.&lt;/p&gt;
&lt;p&gt;- 데이터가 많아져도 줄어들지 않는다.&lt;/p&gt;
&lt;p&gt;- model의 output으로 직접 구한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Epistemic Uncertainty&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 모델이 모르는 부분(학습되지 않은 데이터)에서 반응한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 데이터를 많이 학습시킬수록 값이 작아진다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- sampling과 같은 방법으로 구한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Neural ordinary differential equations(Chen et al.)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 논문을 이해하기 위해서는 먼저 &lt;span style=&quot;color: #333333;&quot;&gt;Neural ordinary differential equations&lt;/span&gt;를 알아야 한다. 이 논문에서는 새로운 optimize방법을 제시하였다. ordinary differential equation을 이용하는 것인데 Euler method가 대표적이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;Euler method&lt;/u&gt;&lt;/b&gt;는 형태가 알려지지 않은 미지의 곡선을 찾으려고 할 때 사용하는 방법이다. 이 방법은 시작점과 해당 곡선의 미분 방정식을 알고 있다(모든 점에서의 기울기를 구할 수 있다)는 가정을 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;EX) 아래의 그림과 같이 A0가 시작점(초기값)이라고 가정하여 구해본다. A0에서의 기울기와 $\Delta t$를 곱하여 A0에 더하면 A1의 점을 구할 수 있다. 그렇게 구한 점도 곡선 위에 있다고 가정하고 같은 과정을 반복하면 A4까지 구할 수 있게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccQ7cd/btqNqCZtQXj/ee2LqybvHnvOSmcjKHwh10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccQ7cd/btqNqCZtQXj/ee2LqybvHnvOSmcjKHwh10/img.png&quot; data-alt=&quot;euler method&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccQ7cd/btqNqCZtQXj/ee2LqybvHnvOSmcjKHwh10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccQ7cd%2FbtqNqCZtQXj%2Fee2LqybvHnvOSmcjKHwh10%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;euler method&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이는 간단히 $ x_{t+1} = x_{t} + \Delta t \frac {dx} {dt} $ 로 구할 수 있다. $\frac{dx} {dt}$를 $f(x, t)$로 치환하면 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ x_{t+1} = x_{t} + \Delta x f(x,t) $$&lt;/p&gt;
&lt;p&gt;Neural Net을 dynamic system으로 생각하여 NN의 각 layer를 연속된 과정이라고 생각하면 ODE를 사용할 수 있다. Resnet의 residual block이 연속되어 존재한다면 다음과 같이 표현할 수 있다.&lt;/p&gt;
&lt;p&gt;$$h_{1} = f_{1}(x) + x$$&lt;/p&gt;
&lt;p&gt;$$h_{2} = f_{2}(h_{1}) + h_{1}$$&lt;/p&gt;
&lt;p&gt;$$h_{3} = f_{3}(h_{2}) + h_{2}$$&lt;/p&gt;
&lt;p&gt;$$h_{4} = f_{4}(h_{3}) + h_{3}$$&lt;/p&gt;
&lt;p&gt;위의 식을 일반화하여 나타내면 $h_{t+1} = h_{t} + f(h_{t}, \theta_{t})$이다. &lt;span style=&quot;color: #333333;&quot;&gt;만약 Euler method에서 $\Delta x$가 1이라면 위의 residual net의 식과 일치한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이는 어떤 하나의 곡선을 찾아나가는 과정으로 이해할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;논문에서는 Adjoint sensitivity method를 ODE solver로 사용하여 기울기를 구하고 오차를 줄이며 업데이트하는 방식을 사용하였다. (자세한 내용은 &lt;a href=&quot;http://%20https://arxiv.org/abs/1806.07366&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문&lt;/a&gt; 참조)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Time series model이 좀 더 직관적인데 그 과정은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lSjX9/btqNq0Z7V6D/InZyF4fAWrfb4DmK2nVxSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lSjX9/btqNq0Z7V6D/InZyF4fAWrfb4DmK2nVxSk/img.png&quot; data-alt=&quot;A generative latent function time-series model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lSjX9/btqNq0Z7V6D/InZyF4fAWrfb4DmK2nVxSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlSjX9%2FbtqNq0Z7V6D%2FInZyF4fAWrfb4DmK2nVxSk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;A generative latent function time-series model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;1. Enocder에서 posterior의 mean과 sigma를 추정하여 샘플링한다. $(z_{t_{0}}$ ~ $ N(z_{t_{0}} | \mu_{z_{t_{0}}} , \sigma_{z_{t_{0}}} ))$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2. ODE Solve를 이용하여 latent space에서의 latent trajectory를 얻는다. ($Z_{t_{0}} \sim Z_{t_{M}}$)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;3. 다른 Neural Net을 이용하여 latent trajectory를 data space로 mapping 한다. ($\hat{x}(t)$)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;4. 샘플링된 trajectory를 사용하여 ELBO를 maximize 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;간단히 말하면 시계열 데이터를 연속인 함수라고 생각하고 그것에 fitting 시켜나가는 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 방법의 장점은 다음과 같다.&lt;/p&gt;
&lt;p&gt;1. Faster testing time than RNN, but slower training time.&lt;/p&gt;
&lt;p&gt;2. Time series 예측이 더 정확하다.&lt;/p&gt;
&lt;p&gt;3. 새로운 optimizing의 영역을 열었다.&lt;/p&gt;
&lt;p&gt;4. 기울기 계산의 메모리가 적게 든다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Stochastic Differential Equation(SDE) &amp;amp; Brownian motion&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; ODE는 deterministic 하여 uncertainty를 추정하지 못한다. 따라서 stochastic 한 방법(SDE)을 사용한다. 거기에 더해 brownian motion&lt;span style=&quot;color: #333333;&quot;&gt;(액체나 기체 속에서 작은 입자들이 불규칙하게 움직이는 현상)&lt;/span&gt; term을 추가하여 epistemic uncertainty를 구한다. brownian motioin term을 추가해 epistemic uncertainty를 구하는 아이디어가 신선한 것 같다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Euler method에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;t를 $\Delta t$라고 표현하고 $\Delta t \to 0$이라면 위의 ResNet 식을 다음과 같이 표현할 수 있다.&lt;/p&gt;
&lt;p&gt;$$ dx_{t} = f(x_{t},t)dt $$&lt;/p&gt;
&lt;p&gt;이는 일반 ODE 식이고, brownian motion term을 추가한 SDE 식은 다음과 같다.&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;$$ dx_{t} = f(x_{t},t)dt + g(x_{t}, t) dW_{t}$$&lt;/p&gt;
&lt;p&gt;(f : drift net, g : diffusion net)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;$f(x_{t}, t)$는 예측을 잘 해내는 것이 목표이며 $g(x_{t}, t)$는 불확실성을 아는 것이 목표이다. 그러므로 training data가 충분하여 epistemic uncertainty가 낮으면 brownian motion의 variance는 낮을 것이고 training data가 부족하여 epistemic uncertainty가 높다면 brownian motion의 variance가 클 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Euler-Maruyama&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 원리적으로는 high-order numerical solver로 stochastic dynamics를 simulate 할 수 있지만 deep learning의 input data는 보통 high dimension을 가지므로 cost가 굉장하다. 따라서 여기서는 효율적 training을 위해 고정된 step size로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Euler-Maruyama&lt;/b&gt;라는 방법을 사용한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 방법은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Euler method를 ordinary differential equaion(ODE)&lt;/span&gt;에서 stochastic differential equation(SDE)으로 일반화시킨 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;$ dX_{t} = a(X_{t})dt + b(X_{t})dW_{t} $라는 stochastic differential equation을 가정한다. initial condition $X_{0} = x_{0}$이며 $W_{t}$는 Wiener process, [0, T]에서 일정 시간 간격으로 SDE를 해결하려고 한다. 그러면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;solution X에 대한 Euler-Maruyama 근사치는 다음과 같이 정의된 마르코프 체인 Y이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;$$ Y_{n+1} = Y_{n} + a(Y_{n})\Delta t + b(Y_{n}) \Delta W_{n} $$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;($\Delta t = T/N, Y_{0} = x_{0}, \Delta W$ : mean은 0 variance는 $\Delta t$인 i.i.d normal random variables )&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위의 내용을 코드로 표현한 것과 시뮬레이션 결과는 다음과 같다.(&lt;a href=&quot;https://en.wikipedia.org/wiki/Euler%E2%80%93Maruyama_method&quot;&gt;위키피디아 참조&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1605677877174&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np
import matplotlib.pyplot as plt

num_sims = 5  # Display five runs

t_init = 3
t_end = 7
N = 1000  # Compute 1000 grid points
dt = float(t_end - t_init) / N
y_init = 0

c_theta = 0.7
c_mu = 1.5
# sigma 값을 높이면 diffusion이 증가한다.
c_sigma = 1


def mu(y, t):
    &quot;&quot;&quot;Implement the Ornstein&amp;ndash;Uhlenbeck mu.&quot;&quot;&quot;  # = \theta (\mu-Y_t)
    return c_theta * (c_mu - y)


def sigma(y, t):
    &quot;&quot;&quot;Implement the Ornstein&amp;ndash;Uhlenbeck sigma.&quot;&quot;&quot;  # = \sigma
    return c_sigma


def dW(delta_t):
    &quot;&quot;&quot;Sample a random number at each call.&quot;&quot;&quot;
    return np.random.normal(loc=0.0, scale=np.sqrt(delta_t))


ts = np.arange(t_init, t_end + dt, dt)
ys = np.zeros(N + 1)

ys[0] = y_init

for _ in range(num_sims):
    for i in range(1, ts.size):
        t = (i - 1) * dt
        y = ys[i - 1]
        ys[i] = y + mu(y, t) * dt + sigma(y, t) * dW(dt)
    plt.plot(ts, ys)

plt.xlabel(&quot;time (s)&quot;)
h = plt.ylabel(&quot;y&quot;)
plt.show()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;327&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by41zA/btqNr844Qck/dwERwdaYOwRJekXORmQe6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by41zA/btqNr844Qck/dwERwdaYOwRJekXORmQe6k/img.png&quot; data-alt=&quot;sigma = 0.05&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by41zA/btqNr844Qck/dwERwdaYOwRJekXORmQe6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby41zA%2FbtqNr844Qck%2FdwERwdaYOwRJekXORmQe6k%2Fimg.png&quot; width=&quot;327&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;sigma = 0.05&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;347&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pxhpj/btqNq0TJ0sd/6rkoaKogf0q2d6qArb69hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pxhpj/btqNq0TJ0sd/6rkoaKogf0q2d6qArb69hk/img.png&quot; data-alt=&quot;sigma = 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pxhpj/btqNq0TJ0sd/6rkoaKogf0q2d6qArb69hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpxhpj%2FbtqNq0TJ0sd%2F6rkoaKogf0q2d6qArb69hk%2Fimg.png&quot; width=&quot;347&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;sigma = 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;실제 training시 사용하는 공식은 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ x_{k+1} = x_{k} + f(x_{k}, t;\theta_{f})\Delta t + g(x_{0};\theta_{g}) \sqrt {\Delta t} Z_{k} $$&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;($Z_{k} \sim N(0,1), \Delta t = T/N)$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;N은 SDE를 해결하는 step 수인데 neural net의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;layer depth로 이해할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;SDE-Net : Drift net(f) + Diffusion net(g)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RzV15/btqNpeZq1pL/3yALuYbALtwUAV8RnQCV50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RzV15/btqNpeZq1pL/3yALuYbALtwUAV8RnQCV50/img.png&quot; data-alt=&quot;SDE-Net&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RzV15/btqNpeZq1pL/3yALuYbALtwUAV8RnQCV50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRzV15%2FbtqNpeZq1pL%2F3yALuYbALtwUAV8RnQCV50%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;SDE-Net&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;u&gt;&lt;b&gt;Drift Net f&lt;/b&gt;&lt;/u&gt;는 좋은 예측 정확도를 학습하는 것에 목표를 둔다. 또한 Aleatoric uncertainty를 측정하는 것을 목표로 한다. Regression문제의 경우 mean과 variance를 출력하여 NLL로 학습시킨다&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;a href=&quot;https://arxiv.org/abs/1612.01474&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Simple and Scalable Predictive Uncertainty Estimation Using Deep Ensembles와&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #333333;&quot;&gt; 같은 방법)&lt;/span&gt;. Classification은 mean을 출력하여 cross entropy error로 학습시킨다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;u&gt;&lt;b&gt;Diffusion Net g&lt;/b&gt;&lt;/u&gt;는 epistemice uncertainty를 구하는 것에 목표를 둔다. In-distribution(&lt;span style=&quot;color: #333333;&quot;&gt;ID)&lt;/span&gt; data는 Brownian motion의 variance가 작아야 한다. 그래서 system state가 drift term에 의해 결정되며 output variance가 작아야 한다. 반면 Out-of-distribution(OOD) data는 Brownian motion의 variance가 커야 하며 system이 chaotic 해야 한다. 학습을 할 때 binary cross entropy error를 사용하여 fake(OOD)와 true(ID)를 잘 구별하도록 학습시킨다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;아래의 코드를 보면 이해가 더 쉽다. SDENet class를 보면 (training_diffusion이 아닌 경우) out이 layer_depth 만큼 반복되며 업데이트되는 것이 보인다&lt;span style=&quot;color: #333333;&quot;&gt;(이는 위의 Euler-Maruyama 방법을 사용한 것)&lt;/span&gt;. 여기서 다른 변수들은 모두 고정이고 random normal variables의 std 값이 diffusion term이 높은지 낮은지에 따라 결정되는 것을 알 수 있다.&lt;/p&gt;
&lt;p&gt;diffusion term은 sigmoid를 통과한 값에 sigma_max 값(이는 뒤에서 설명)을 곱해주므로 0~sigma_max의 variance 크기를 갖게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1605675473029&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Drift(Layer):
    def __init__(self):
        super(Drift, self).__init__(name=&quot;drift_net&quot;)
        self.fc = Dense(50)  # input : 50
        self.relu = ReLU()

    def call(self, t, x):
        out = self.relu(self.fc(x))
        return out


class Diffusion(Layer):
    def __init__(self):
        super(Diffusion, self).__init__(name=&quot;diffusion_net&quot;)
        self.relu = ReLU()
        self.fc1 = Dense(100)  # input : 50
        self.fc2 = Dense(1)  # input : 100

    def call(self, t, x):
        out = self.relu(self.fc1(x))
        out = self.fc2(out)
        out = tf.nn.sigmoid(out)
        return out  # batch,1
        

class SDENet(Model):
    def __init__(self, layer_depth):
        super(SDENet, self).__init__(name=&quot;SDE_Net&quot;)
        self.layer_depth = layer_depth
        self.downsampling_layers = Dense(50)  # batch, 50
        self.drift = Drift()  # batch, 1
        self.diffusion = Diffusion()
        self.fc_layers = Sequential(
            [ReLU(), Dense(2)]
        )  # input : 50, output : mean, variance
        self.deltat = 4.0 / self.layer_depth  # T:4, N:layer_depth
        self.sigma_max = 0.5  # sigma_max : scaling diffusion output

    def call(self, x, training_diffusion=False):
        out = self.downsampling_layers(x)
        if not training_diffusion:
            t = 0
            diffusion_term = self.sigma_max * self.diffusion(t, out)
            for i in range(self.layer_depth):
                t = 4 * (float(i)) / self.layer_depth
                out = (
                    out
                    + self.drift(t, out) * self.deltat
                    + diffusion_term
                    * tf.cast(tf.math.sqrt(self.deltat), &quot;float64&quot;)
                    * tf.random.normal(tf.shape(out), dtype=&quot;float64&quot;)
                )  # Euler-Maruyama method

            final_out = self.fc_layers(out)
            mean = final_out[:, 0]
            # sigma should be greater than 0.
            sigma = tf.math.softplus(final_out[:, 1]) + 1e-3
            return mean, sigma

        else:
            t = 0
            final_out = self.diffusion(t, out)
            return final_out
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Objective function for training&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Vnwsy/btqNx9aBlUf/L1uzK6lWDBGVqIvehiaFG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vnwsy/btqNx9aBlUf/L1uzK6lWDBGVqIvehiaFG0/img.png&quot; data-alt=&quot;objective function for training&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vnwsy/btqNx9aBlUf/L1uzK6lWDBGVqIvehiaFG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVnwsy%2FbtqNx9aBlUf%2FL1uzK6lWDBGVqIvehiaFG0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;objective function for training&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;(L: loss function, $P_{train}$: distribution for training data, $P_{OOD}$: OOD data, T: terminal time of the stochastic process)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;$ \min_{\theta_{f}}E_{x_{0} \sim P_{train}} E(L(x_{T})) $: training data로 Loss를 minimize 하며 학습시킨다.&lt;/p&gt;
&lt;p&gt;$ \min_{\theta_{g}}E_{x_{0} \sim P_{train}} g(x_{0};\theta_{g}) $: training data를 넣었을 때 diffusion net이 low diffusion을 출력하도록 학습시킨다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;$ \max_{\theta_{g}}E_{\hat {x}_{0} \sim P_{OOD}} g(\tilde {x}_{0};\theta_{g})$: out of distribution data를 넣었을 때 diffusion net이 high diffusion을 출력하도록 학습시킨다. (실제 학습 시에는 fake label을 주어 loss를 minimize 시킴)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;out of distribution data는 원래 값에 Gaussian noise를 더해준 값이 된다. $\tilde {x}_{0} = x_{0} + \epsilon$&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Uncertainty Quantification&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; SDE-Net이 학습된 후, sampling 하여 Uncertainty를 구한다. ($(x_{T})_{m=1}^{M}$)&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 이는 기존의 Ensembling 방법과 비슷해 보인다. 하지만 기존에는 여러 deterministic NNs를 학습시켜야 했지만 SDE는 하나의 NN만 학습시키면 된다,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;Aleatoric uncertainty&lt;/b&gt; : Regression의 경우&amp;nbsp; FC layer를 통해 출력되는 variance의 sampling 된 mean 값을 통해 구할 수 있다. Classification 문제는 entropy를 통해 구할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;Epistemic uncertainty&lt;/b&gt; : $x_{T}$에 대한 variance : $Var(x_{T})$ = $\frac {1} {M} \sum_{m=1}^{M} x_{T}^{2} - (\frac {1} {M} \sum_{m=1}^{M} x_{T})^{2}$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Theoretical Analysis&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 여기서 제안된 stochastic system의 solution인 $x_{t} (0 \leq t \leq T)$가 존재하고 unique 하다는 증명.&lt;/p&gt;
&lt;p&gt;C&amp;gt;0가 존재하면 다음을 만족한다.&lt;/p&gt;
&lt;p&gt;$$|| f(x, t;\theta_{f}) - f(y, t;\theta_{f})|| + ||g(x;\theta_{g} - g(y;\theta_{g})|| \leq C||x-y||$$&lt;/p&gt;
&lt;p&gt;($x, y \in R^{n}, t \geq 0$)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그러면 unique continuous and adapted process $(x_{t}^{x_{0}})_{t \geq 0}$가 존재한다. (t $ \geq 0 $)&lt;/p&gt;
&lt;p&gt;$$ x_{t}^{x_{0}} = x_{0} + \int_{0}^{t} f(x_{s}^{x_{0}}, t;\theta_{f})ds + \int_{0}^{t} g(x_{0};\theta_{g})dW_{s} $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위의 정리가 만족하려면 drift net f와 diffusion net&amp;nbsp; g는 uniformly Lipschitz 여야 한다(Lipschitz condition : 대부분 미분 가능하며 연속성이 보장되고 도함수가 유계인 함수). 이것은 ReLU나 sigmoid, Tanh 같은 Lipshitz nonlinearactivations를 Neural net에 쓰면 된다. 그러나 그냥 optimize를 하면 $g(x_{0};\theta_{g})$가 OOD데이터를 받을 때 infinity 한 값이 나올 수 있다. 따라서 $\sigma_{max}$라는 hyper-parameter를 추가하여 $g(x;\theta_{g})$ output value의 maximum값을 정해준다. 이것은 diffusion layer의 말단에 있는 sigmoid를 통과한 값에 $\sigma_{max}$를 곱해주는 식으로 구현한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Algorithm&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 학습 &lt;b&gt;Algorithm&lt;/b&gt;은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TJPy4/btqNthgrsrs/K3vUmpygHOO1qS4JYeYbx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TJPy4/btqNthgrsrs/K3vUmpygHOO1qS4JYeYbx0/img.png&quot; data-alt=&quot;algorithm&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TJPy4/btqNthgrsrs/K3vUmpygHOO1qS4JYeYbx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTJPy4%2FbtqNthgrsrs%2FK3vUmpygHOO1qS4JYeYbx0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;algorithm&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;1. training data를 활용하여 downsampling layer를 통과시켜 $X_{0}^{N_{M}}$를 얻는다.&lt;/p&gt;
&lt;p&gt;2. $X_{0}^{N_{0}}$로 Euler-Maruyama method를 활용하여 N번의 step을 통과시킨다. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;3. Fully connected layer를 통과시킨다.&lt;/p&gt;
&lt;p&gt;4. Loss를 구하고 down &lt;span style=&quot;color: #333333;&quot;&gt;sampling layer와&lt;span&gt; Fullyconnected layer, &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;drift net을 학습시킨다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;5. out-of-distribution data를 얻어 down sampling layer를 통과시켜 $\tilde {X}_{0}^{N_{M}}$을 얻는다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;6. $X_{0}^{N_{M}}$과 $\tilde{X}_{0}^{N_{M}}$을 diffusion net에 통과시켜 output을 얻는다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;7. 각각 true label과 fake label을 줘서 binary crossentropy로 diffusion net을 학습시킨다. (&lt;span style=&quot;color: #333333;&quot;&gt;diffusion net이 &lt;/span&gt;ID와 OOD를 구분하게 하는 학습)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;위와 같이 drift net과 diffusion net을 번갈아 가며 학습시킨다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코드로 나타내면 아래와 같다. 처음 기울기가 너무 커져 nan값이 나와 clip by norm 처리를 해주었다. 먼저 drift net, fc layer, down sampling layer를 학습시켜 준다. 그다음 diffusion layer를 in-distribution data와 out-of-distribution data로 번갈이 학습시켜 업데이트해준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1605680618961&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;real_label = 0
fake_label = 1

@tf.function
def train_net(x, y):
    with tf.GradientTape(persistent=True) as tape:
        mean, sigma = model(x, training_diffusion=False)
        loss = nll_loss(y, mean, sigma)

    drift_gradient = tape.gradient(loss, model.drift.trainable_variables)
    dsl_gradient = tape.gradient(loss, model.downsampling_layers.trainable_variables)
    fc_gradient = tape.gradient(loss, model.fc_layers.trainable_variables)

    drift_gradient = [(tf.clip_by_norm(grad, 100)) for grad in drift_gradient]
    dsl_gradient = [(tf.clip_by_norm(grad, 100)) for grad in dsl_gradient]
    fc_gradient = [(tf.clip_by_norm(grad, 100)) for grad in fc_gradient]

    optimizer_drift.apply_gradients(
        zip(drift_gradient, model.drift.trainable_variables)
    )
    optimizer_dsl.apply_gradients(
        zip(dsl_gradient, model.downsampling_layers.trainable_variables)
    )
    optimizer_fc.apply_gradients(zip(fc_gradient, model.fc_layers.trainable_variables))



@tf.function
def train_diffusion(real_x):
    with tf.GradientTape(watch_accessed_variables=False) as real_tape_diffusion:
        # only access to diffusion layer's parameters
        real_tape_diffusion.watch(model.diffusion.trainable_variables)
        real_y = tf.fill((real_x.shape[0], 1), real_label)
        real_pred = model(real_x, training_diffusion=True)
        real_loss = mse(real_y, real_pred)

    diffusion_gradient = real_tape_diffusion.gradient(
        real_loss, model.diffusion.trainable_variables
    )

    diffusion_gradient1 = [(tf.clip_by_norm(grad, 100)) for grad in diffusion_gradient]

    with tf.GradientTape(watch_accessed_variables=False) as fake_tape_diffusion:
        fake_tape_diffusion.watch(model.diffusion.trainable_variables)
        # fake std is 2 in official code, but in paper it is 4
        fake_x = (
            tf.cast(
                tf.random.normal((real_x.shape[0], 90), mean=0, stddev=2), &quot;float64&quot;
            )
            + real_x
        )
        fake_y = tf.fill((real_x.shape[0], 1), fake_label)
        fake_pred = model(fake_x, training_diffusion=True)
        fake_loss = mse(fake_y, fake_pred)

    diffusion_gradient = fake_tape_diffusion.gradient(
        fake_loss, model.diffusion.trainable_variables
    )

    diffusion_gradient2 = [(tf.clip_by_norm(grad, 100)) for grad in diffusion_gradient]

    diffusion_gradient = [
        grad1 + grad2 for grad1, grad2 in zip(diffusion_gradient1, diffusion_gradient2)
    ]

    optimizer_diffusion.apply_gradients(
        zip(diffusion_gradient, model.diffusion.trainable_variables)
    )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Experiments&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; SDE-Net과 비교하는 모델들은 다음과 같다.&lt;/p&gt;
&lt;p&gt;1) Threshold (Hendrucks &amp;amp; Gimple, 2017)&lt;/p&gt;
&lt;p&gt;2) MC-dropout (Gal &amp;amp; Ghahramani, 2016)&lt;/p&gt;
&lt;p&gt;3) DeepEnsemble (Lakshminarayanan et al., 2017) -&amp;gt; 5 neural net in ensemble&lt;/p&gt;
&lt;p&gt;4) Prior Network (PN) (Malinin &amp;amp; Gales, 2018)&lt;/p&gt;
&lt;p&gt;5) Bayes By Backpropagation (BBP) (Blundell et al., 2015)&lt;/p&gt;
&lt;p&gt;6) preconditioned Stochastic gradient Langevin dynamics (p-SGLD) (Li et al., 2016)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;SDE-Net은 10번의 sampling 사용.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;1. Out of distribution detection&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;- Classfication&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOlrnv/btqNpGBISpb/hXyPosIvfJahj8E1eoKgPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOlrnv/btqNpGBISpb/hXyPosIvfJahj8E1eoKgPK/img.png&quot; data-alt=&quot;table1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOlrnv/btqNpGBISpb/hXyPosIvfJahj8E1eoKgPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOlrnv%2FbtqNpGBISpb%2FhXyPosIvfJahj8E1eoKgPK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;table1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;MNIST, SVHN으로 각각 training 시키고 OOD를 넣었을 때 성능은 위의 table1과 같다. 단순 accuracy는 DeepEnsemble 모델이 제일 좋지만 parameters가 5배로(model을 5개 학습시킴) 들었음에도 SDE-Net과 차이가 크지 않다. 반면 TNR, AUROC, AUPR 등 모두 SDE-Net이 뛰어난 결과를 가져왔다. 특히 SVHN을 학습시키고 CIFAR를 OOD로 넣었을 때의 결과는 다른 모델들과 상당히 차이가 난다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;- Regression&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wtuhy/btqNqDdvV0g/qx9Z3S63hPi55oRtAPAHc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wtuhy/btqNqDdvV0g/qx9Z3S63hPi55oRtAPAHc0/img.png&quot; data-alt=&quot;table6&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wtuhy/btqNqDdvV0g/qx9Z3S63hPi55oRtAPAHc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwtuhy%2FbtqNqDdvV0g%2Fqx9Z3S63hPi55oRtAPAHc0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;table6&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Regression은 Year prediction MSD 데이터에 대해 학습하고 Boston Housing 데이터 셋을 OOD 데이터로 넣었다. 다른 모델들은 OOD 데이터에 정말 취약한 모습으로 보인다. 기본적으로 regression task는 연속적이고 한이 없기 때문에 uncertainty를 알아내기 굉장히 어렵기 때문이다. 하지만 SDE-Net은 상당히 좋은 결과를 내었다. diffusion net이 input data와 OOD데이터를 통해 직접적으로 학습하기 때문에 좋은 성능을 낸 것으로 보인다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;2. Misclassification Detection&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A8aGY/btqNCx3qTPW/hLoLpXk4fgOQFf1I4ugQWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A8aGY/btqNCx3qTPW/hLoLpXk4fgOQFf1I4ugQWK/img.png&quot; data-alt=&quot;table3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A8aGY/btqNCx3qTPW/hLoLpXk4fgOQFf1I4ugQWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA8aGY%2FbtqNCx3qTPW%2FhLoLpXk4fgOQFf1I4ugQWK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;table3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Misclassification detection 결과는 DeepEnsemble이 좋다. 하지만 SDE-Net과 별로 차이가 나지 않는 반면 computational cost는 높기 때문에 SDE-Net을 사용하는 것이 더 좋은 선택이 될 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;3. Adversarial Sample Detection&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; DNN은 데이터에 작은 adversarial perturbations를 준 adversarial examples에 굉장히 취약하다. 그래서 adversarial samples를 잘 detect 하는 것이 중요하다. SDE-Net은 따로 adversarial training을 하지는 않았지만 실험을 하였다. 여기서는 Fast Gradient-Sign Method(FGSM)과 Projected Gradient Descent(PGD) 방법으로 실험하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nuwSD/btqNCyH4ujm/Ksf8Y85o1fbEg6nv5YvyIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nuwSD/btqNCyH4ujm/Ksf8Y85o1fbEg6nv5YvyIk/img.png&quot; data-alt=&quot;figure 5 - FGSM&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nuwSD/btqNCyH4ujm/Ksf8Y85o1fbEg6nv5YvyIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnuwSD%2FbtqNCyH4ujm%2FKsf8Y85o1fbEg6nv5YvyIk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 5 - FGSM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;먼저 FGSM방법에 대한 결과가 figure 5에 나와있다. adversarial size $\epsilon$에 따른 detection 결과인데 MNIST의 경우 쉬운 task라 대부분의 모델들이 잘 수행하고 있다. 하지만 SVHN은 SDE-Net만 $\epsilon$값이 커지며 100%에 수렴하고 있는 것으로 보인다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T9f4z/btqNr76MGKf/CRYEuhaKZuKtffz4ZVdNak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T9f4z/btqNr76MGKf/CRYEuhaKZuKtffz4ZVdNak/img.png&quot; data-alt=&quot;figure 6 - PGD&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T9f4z/btqNr76MGKf/CRYEuhaKZuKtffz4ZVdNak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT9f4z%2FbtqNr76MGKf%2FCRYEuhaKZuKtffz4ZVdNak%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 6 - PGD&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;PGD방법에 대한 결과는 figure 6에 나와있다. MNIST의 경우 SDE-Net이 가장 outperform 한 결과를 내보였다. 하지만 SVHN은 DeepEnsemble을 제외한 나머지는 굉장히 좋지 못한 결과를 보였다. 이는 SVHN의 manifold가 high dimension을 가져 그럴 가능성이 높다고 한다. 그래서 이를 효율적이고 robust 하게 개선하는 것이 further work라고 소개한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;4. Active Learning&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp;사람이 많은 데이터를 labeling 하는 것은 cost가 많이 든다. 따라서 '모델이 labeling 된 약간의 데이터를 학습한 다음 labeling이 안된 데이터 중 좋은 데이터를 골라내게 하겠다'라는 아이디어가 active learning이다. 이때 uncertainty가 중요한 역할을 하게 된다. epistemic uncertainty가 높고 aleatoric uncertainty가 낮은 영역의 data를 뽑아내게 하면 학습이 잘 될 것이다. 그렇지 못한다면 overfitting이 되어 성능이 악화될 수도 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beys2Q/btqNx8XVwbg/P2702GMgZrKSRbJlSryTqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beys2Q/btqNx8XVwbg/P2702GMgZrKSRbJlSryTqK/img.png&quot; data-alt=&quot;figure 7 - active learning&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beys2Q/btqNx8XVwbg/P2702GMgZrKSRbJlSryTqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbeys2Q%2FbtqNx8XVwbg%2FP2702GMgZrKSRbJlSryTqK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 7 - active learning&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;active learning의 결과는 figure 7에 나와 있다. 처음에 50개의 데이터로 학습하고 각 epoch마다 50개의 데이터를 추가로 선택하여 학습을 진행한다. 총 100 epochs를 진행하였다.&lt;/p&gt;
&lt;p&gt;예상대로 SDE-Net이 굉장히 좋은 결과를 내고 있다. &lt;span style=&quot;color: #333333;&quot;&gt;uncertainty에 대한 측정이 좋았기 때문에 informative data를 잘 뽑아낸 것이다. 예상외로 MC-dropout도 상당히 좋은 결과를 얻었다. 반면 DeepEnsemble방법은 좋지 못한 결과를 내었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;cost는 많이 들지만 다른 task에서는 좋은 결과를 내었기 때문에 여기서도 괜찮을 것이라고 예상하였는데 의외였다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- Stochastic Differential Equation과 Brownian motion을 활용하여 Uncertainty를 추정하는 모델을 제시하였다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- 모델은 drift net과 diffusion net으로 나누어 학습을 하고 각각 accuracy와 epistemic uncertainty를 담당하게 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- Euler-Maruyama method를 사용하여 학습을 진행한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- 모델의 장점은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 1. 하나의 모델만 사용하여 학습에 대한 cost가 (ensembling 방법보다) 작다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 2. aleatoric uncertainty와 epistemic uncertainty를 구분할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 3. prior 분포를 특정할 필요가 없고 posterior 분포를 추정할 필요가 없어 효율적이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 4. classification과 regression 둘 다 수행 가능하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 5. OOD(out of distribution) detection, Misclassification Detection, Adversarial Sample Detection, Active Learning 모두에서 좋은 성능을 보인다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;pytorch를 활용한 &lt;/span&gt;Official code가 Github에 있어 Colab을 이용하여 train 시켜 보았을 때 논문에서 제시한 것과 비슷한 결과를 얻었습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Tensorflow로 변환한 파일도 따로 만들어 깃헙에 올려두었으나 성능이 torch와는 다르게 나왔습니다. 같은 구조를 만들었다고&lt;span style=&quot;color: #333333;&quot;&gt;(learning rate 조정을 하는 부분을 제외하고)&lt;/span&gt; 생각하였으나 다른 부분에 문제가 있는 것인지 모르겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Tensorflow를 활용한 깃헙 파일을 올려두었으니 혹시 문제를 아시는 분은 댓글로 남겨주시면 감사하겠습니다. (참고로 모델은 1 epoch의 훈련만 진행하였습니다.)&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그러므로 논문의 결과를 재현하고자 하면 pytorch 코드를 사용하는 것을 추천합니다. pytorch를 사용한 colab 파일 또한 깃헙에 따로 올려두었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;official code : &lt;a href=&quot;https://github.com/Lingkai-Kong/SDE-Net&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/Lingkai-Kong/SDE-Net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;깃헙 주소 : &lt;a href=&quot;https://github.com/Junghwan-brian/SDE-Net&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/Junghwan-brian/SDE-Net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>bayesian deep learning</category>
      <category>sde-net</category>
      <category>uncertainty</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/31</guid>
      <comments>https://simpling.tistory.com/31#entry31comment</comments>
      <pubDate>Sun, 15 Nov 2020 17:05:29 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: Learning Deep Features for Discriminative Localization</title>
      <link>https://simpling.tistory.com/30</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1512.04150&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;&quot;Learning Deep Features for Discriminative Localization&quot;&lt;/b&gt;&lt;/a&gt; &lt;span style=&quot;color: #333333;&quot;&gt;(CVPR 2015) - Bolei Zhou&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이번 논문은 오래됐지만 아직도 많이 인용되고 논문의 실험 결과로 자주 사용되는 Class Activation Maps (CAM)을 다룬 논문에 대한 리뷰이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;문제와 해결책&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 딥러닝 기술이 점점 정확도가 높아져가며 성능이 좋아졌지만 그것이 왜 그런 결과를 내는지는 알기 어려웠다. 이러한 것을 두고 딥러닝은 black box와 같다고 묘사를 하곤 한다. 그 안에서 무슨 일이 일어나는지 왜 그런 판단을 하는지 어렵기 때문이다.&amp;nbsp;이 어두컴컴한 상자에 빛을 내려준 기술 중 하나가 이 논문에서 제시한 &lt;b&gt;Class Activation Maps (CAM)&lt;/b&gt;이다. 기존의 CNN에서 사용이 되는 모델은 Convolution Layer가 여러 겹 쌓여있고 마지막에 Fully-connected layer로 이어져 분류를 시행하게 된다. 반면, &lt;span style=&quot;color: #333333;&quot;&gt;CAM 방법은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Convolution-Global average pooling-Softmax의&lt;/b&gt; 간단한 구조로 바꾸어 학습하게 된다. &lt;s&gt;(항상 좋은 논문들을 보면 정말 간단한 아이디어가 큰 변화를 가져온다는 생각이 든다.)&lt;/s&gt; 이 방법을 사용하면 모델이 어떤 판단을 내려 output을 낼 때 어디에 집중하여 보았는지 볼 수 있기 때문에 Explainable 한 결과를 낼 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Main Contribution : Class Activation Maps (CAM)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;&amp;nbsp; &lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;논문의 가장 중요한 핵심은 CAM이다. 이 CAM이 이루어지는 방식은 상당히 간단하다. 먼저 위에서 설명한 바와 같이 Convolution층 바로 다음 Global Average Pooling(GAP)을 붙이고 softmax를 붙이는 모델 구조를 만든다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKLqoZ/btqM64hPH6y/zpZ1SDDiocBkYAr2QnJfR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKLqoZ/btqM64hPH6y/zpZ1SDDiocBkYAr2QnJfR0/img.png&quot; data-alt=&quot;binary classification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKLqoZ/btqM64hPH6y/zpZ1SDDiocBkYAr2QnJfR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKLqoZ%2FbtqM64hPH6y%2FzpZ1SDDiocBkYAr2QnJfR0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;binary classification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;예를 들어&lt;span&gt; binary classification에서 &lt;/span&gt;&lt;/span&gt;Convolution층의 마지막 출력이 (width,height,channel) = (7,7,128)인 activation maps 가 있다고 하면 각 Channel 별로 모두 Global Average Pooling을 해주어 128개의 값이 나오면 softmax로 연결해주는 것이다. 위와 같이 [0,1]가 정답이라면 1 로가는 weights를 각 global average pooling을 한 마지막 activation maps에 곱해준다. 이렇게 하면 각 activation map과 weights를 곱하여 어디를 보고 판단을 했는지를 볼 수 있게 된다. 아래 그림은 이런 프로세스를 설명한 논문의 그림이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8tfAj/btqNaECrzqW/PPEMazKR6OKRAcEQbHk2p1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8tfAj/btqNaECrzqW/PPEMazKR6OKRAcEQbHk2p1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8tfAj/btqNaECrzqW/PPEMazKR6OKRAcEQbHk2p1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8tfAj%2FbtqNaECrzqW%2FPPEMazKR6OKRAcEQbHk2p1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위의 그림에서는 Australian terrier를 분류하므로 사람의 얼굴에 집중한 첫 번째 activation map의 $W_{1}$은 낮은 값일 것이고 개의 특징에 주목한 두 번째, n 번째 activation map에 연결된 $W_{2},W_{n}$은 높은 값을 가질 것으로 유추할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baVWed/btqNaFH8dXP/kqgaWVDVhmkIkDahyWlRm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baVWed/btqNaFH8dXP/kqgaWVDVhmkIkDahyWlRm0/img.png&quot; data-alt=&quot;Figure 4.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baVWed/btqNaFH8dXP/kqgaWVDVhmkIkDahyWlRm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaVWed%2FbtqNaFH8dXP%2FkqgaWVDVhmkIkDahyWlRm0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 4.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; CAM을 사용한 결과는 상당히 잘 나왔다. 이중에 흥미로웠던 결과가 Figure 4에 제시된 그림인데 각 class별로 같은 이미지를 인식할 때 다른 곳을 보았다는 것이다. 사람도 어떤 물체가 무엇인지 판단할 때 각 물체별 특성을 보고 판단하는 것과 같은 프로세스라 생각했다. 정답은 dome이지만 palace의 확률이 가장 높게 나왔는데 왜 그렇게 판단했는지를 알 수 있는 실험이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Weakly-supervised Object Localization&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUYsFg/btqM5eec37Y/Lvx1QGWwPlkXZA9fP0I3Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUYsFg/btqM5eec37Y/Lvx1QGWwPlkXZA9fP0I3Tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUYsFg/btqM5eec37Y/Lvx1QGWwPlkXZA9fP0I3Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUYsFg%2FbtqM5eec37Y%2FLvx1QGWwPlkXZA9fP0I3Tk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;논문에서는 단지 Explainable한 모델을 제시한 것에서 그치는 것이 아니라 object localization을 한 실험도 제시한다. 먼저 CAM 방법으로 &lt;span style=&quot;color: #333333;&quot;&gt;classification을 &lt;/span&gt;학습시킨 모델은 GAP를 사용하니 성능이 조금 저하되긴 했지만 경쟁력 있는 결과를 보여주었다. classification을 학습시킨 모델로 thresholding 방법을 사용하여 bounding box를 만드는 실험을 하였는데 놀랍게도 굉장히 좋은 성능을 보였다. table 2의 결과를 보면 기존의 bounding box를 annotation 하여 backpropagation 시킨 방법보다 더 좋은 성능을 보인다. 따로 학습을 하지 않았는데 이런 결과를 보여 재미있는 결과였다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sX7xz/btqM5UNjTEh/peQ8aTlKa0ERLiLezzbQ60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sX7xz/btqM5UNjTEh/peQ8aTlKa0ERLiLezzbQ60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sX7xz/btqM5UNjTEh/peQ8aTlKa0ERLiLezzbQ60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsX7xz%2FbtqM5UNjTEh%2FpeQ8aTlKa0ERLiLezzbQ60%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Experimental results&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; 이 외에도 논문에서는 정말 많은 실험 결과들을 제시한다. Fine-grained Recognition으로 200종의 새를 인식하는 문제에서 full image를 thresholding으로 crop하니 더 성능이 잘 나온다는 결과, Pattern Discovery로 장면에서 informative한 물체들을 인식하는 것에서 어디를 보고 판단했는지 알 수 있다는 결과 등 흥미로운 결과들이 있었다. 또 visual question answering에서 predictor가 문제에 대한 답을 무엇을 보고 맞혔는지 나타내는 것도 흥미로웠다. 이에 대한 결과는 Figure 12에 나와있다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/usjdT/btqM9rp64zQ/39ei2DvCabtTO8W9KLkfxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/usjdT/btqM9rp64zQ/39ei2DvCabtTO8W9KLkfxk/img.png&quot; data-alt=&quot;figure 12.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/usjdT/btqM9rp64zQ/39ei2DvCabtTO8W9KLkfxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FusjdT%2FbtqM9rp64zQ%2F39ei2DvCabtTO8W9KLkfxk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 12.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이번 논문에서는 CNN의 결과를 설명할 수 있는 CAM 방법을 제시하였다. Explainable model 뿐 아니라 직접 학습을 하지 않고 localization에서도 좋은 성능을 이끌어내어 weakly-supervised object localization 방법도 제시하였다. 이 논문을 통해 CNN이 우리가 생각하는 대로 잘 동작하고 있다는 것을 알 수 있게 되었다. 논문에서 나온 표현을 빌리면 CNN의 영혼을 잠시 보는 접근 방법을 제시하였다. 하지만 CAM은 Global Average Pooling을 사용해야 한다는 단점이 있었고 이를 해결한 것이 &lt;b&gt;grad-CAM&lt;/b&gt; 방법이다. 이에 대해서는 다음에 포스팅 할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>CAM</category>
      <category>class activation map</category>
      <category>CNN</category>
      <category>explainable model</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/30</guid>
      <comments>https://simpling.tistory.com/30#entry30comment</comments>
      <pubDate>Wed, 11 Nov 2020 08:33:59 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: Uncertainty-Aware Learning From Demonstration Using Mixture Density Networks with Sampling-Free Variance Modeling</title>
      <link>https://simpling.tistory.com/29</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&quot;Uncertainty-Aware Learning From Demonstration Using Mixture Density Networks with Sampling-Free Variance Modeling&quot;&lt;/b&gt;&lt;/span&gt; - Sunjun Choi (2017)&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://www.edwith.org/bayesiandeeplearning/joinLectures/14426&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이번 논문은 Mixture Density Network 구조를 이용하여 Sampling을 하지 않고 Uncertainty를 알 수 있는 모델링 방법을 제시하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;2가지 Uncertainty에 대해 비슷한 의미를 가진 용어가 많이 사용되는데 여기서 정리하고 시작한다.&lt;/p&gt;
&lt;p&gt;(Uncertainty를 variance로 혼용해서도 사용한다.)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Aleatoric Uncertainty = Unexplained Uncertainty = E [V(y|x, k)]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;특징&lt;/p&gt;
&lt;p&gt;- 데이터에 내재된 노이즈(3과 8을 구분하는 것 등)에 반응한다.&lt;/p&gt;
&lt;p&gt;- 데이터가 randomness 한 경우(동전 던지기 등)에 반응한다.&lt;/p&gt;
&lt;p&gt;- 데이터가 많아져도 줄어들지 않는다.&lt;/p&gt;
&lt;p&gt;- model의 output으로 직접 구한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Epistemic Uncertainty = Explained Uncertainty = V(E [y|x, k])&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;특징&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 모델이 모르는 부분(학습되지 않은 데이터)에서 반응한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 데이터를 많이 학습시킬수록 값이 작아진다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 충분한 데이터가 있으면 해결할 수 있어서 Explained uncertainty라고 한다.&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 본래 Sampling을 활용하여 구해서 Real time application에 적용하기 힘들었지만 이번 리뷰 논문에서 새로운 방법을 제안하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;기존 연구의 한계와 해결책&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 딥러닝을 여러 영역에서 적용시키며 잘못 예측하거나 시스템을 제대로 움직이지 않는 경우가 비극적 사건들을 일으키곤 한다. 그래서 Uncertainty를 예측하는 방법들이 제시되었다. Uncertainty는 2가지로 나눠 이해된다. 첫 번째는 데이터 자체에 내재되어있는 noise를 의미하는 &lt;b&gt;Aleatoric&lt;/b&gt; Uncertainty이다. 두 번째는 모델이 학습하지 않아 모르는 것을 의미하는 &lt;b&gt;Epistemic&lt;/b&gt; Uncertainty다. (이에 대해서는 기존에 리뷰한 &lt;span style=&quot;color: #666666;&quot;&gt;&quot;&lt;/span&gt;&lt;a href=&quot;https://simpling.tistory.com/entry/%EA%B0%84%EB%8B%A8-%EB%A6%AC%EB%B7%B0-What-Uncertainties-Do-We-Need-in-Bayesian-Deep-Learning-for-Computer-Vision&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;What Uncertainties Do We Need in Bayesian Deep Learning for Computer Vision&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&quot;에 자세히 나와있다.) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;기존 연구에서는 Uncertainty 추정으로 Monte Carlo Sampling 방법을 사용하였는데 이는 Real-time에 적합하지 않았다. 그래서 해당 논문에서는 Real time에 적합한 &lt;b&gt;Mixture density network(MDN) 구조를&lt;/b&gt; 제시한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Main contribution&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;b&gt;1. Sampling-free 한 uncertainty 방법으로 &lt;span style=&quot;color: #333333;&quot;&gt;Mixture density network(MDN) 구조를 제시하였다. 그 구조는 다음과 같다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMjfJH/btqMmpMHMw7/Ktgpvjf5L9ddveKkwVbFsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMjfJH/btqMmpMHMw7/Ktgpvjf5L9ddveKkwVbFsK/img.png&quot; data-alt=&quot;MDN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMjfJH/btqMmpMHMw7/Ktgpvjf5L9ddveKkwVbFsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMjfJH%2FbtqMmpMHMw7%2FKtgpvjf5L9ddveKkwVbFsK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;MDN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;모델의 output으로 $\hat {\pi}_{i} , \hat {\mu}_{i} , \hat {\sum}_{i}$을 K개 출력한다. 이는 다음 식으로 각각 probabilites, means, variances를 유도하는 데 사용된다.&lt;/p&gt;
&lt;p&gt;$$ \pi_{i} = \frac { exp(\hat {\pi}_{i} - max(\pi) } {\sum_{k=1}^{K} exp(\hat {\pi}_{k} - max(\pi))} $$&lt;/p&gt;
&lt;p&gt;$$ \mu_{i} = \hat {\mu}_{i} $$&lt;/p&gt;
&lt;p&gt;$$ \sum_{i} = \sigma_{max} diag (\rho (\hat {\sum}_{i})) $$&lt;/p&gt;
&lt;p&gt;(&lt;span style=&quot;color: #333333;&quot;&gt;sigmoid function&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;/span&gt;$\rho(x) = \frac {1} {1+exp(-x)}$, diag는 d-dimension vector를 d*d dimension diagonal matrix로 변환해주는 operator, max($\pi$)는 K개의 weights 중 maximum 값)&lt;/p&gt;
&lt;p&gt;이에 대해 직관적으로 이해하면 &lt;span style=&quot;color: #333333;&quot;&gt;$\pi_{i} , \mu_{i} , \sum_{i}$&lt;/span&gt;가 한 세트로 K개만큼 출력되는 데 이를 K명의 전문가들이 각각 자신의 의견을 낸다고 생각할 수 있다. $\pi_{i}$는 i번째 전문가의 영향력, $\mu_{i}$는 i번째 전문가의 예측, $\sum_{i}$는 i번째 전문가의 의견에 대한 확신(혹은 불확실성)이라고 할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp; 2. MDN으로부터 Explained Uncertainty와 Une&lt;span style=&quot;color: #333333;&quot;&gt;xplained Uncertainty를 구할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;MDN의 output parameters는 Gaussian mixture model(GMM)으로 구성되어 있다. GMM의 Total expectation은 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$E [y|x] = \sum_{i=1}^{K}\pi_{i}(x)\mu_{i}(x)$$&lt;/p&gt;
&lt;p&gt;GMM의 Total variance는 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ V(y|x) = \sum_{i=1}^{K}(\pi_{i}(x)\sum_{i}(x)) + \sum_{i=1}^{k}\pi_{i}(x) || \mu_{i}(x) - \sum_{k=1}^{K}\pi_{k}(x)\mu_{k}(x) || ^{2} \cdots (1) $$&lt;/p&gt;
&lt;p&gt;첫 번째 term은 model에서 나오는 variance에 가중치를 곱하고 더한 값이므로 데이터에 존재하는 noise를 포착하는 aleatoric uncertainty와 대응되며 이를 unexplained uncertainty라고 한다. 총 variance는 aleatoric uncertainty와 epistemic uncertainty와 같으므로(논문에 증명이 나옴) 두 번째 term이 모델이 모르는 것을 포착하는 epistemic uncertainty와 대응되며 explained uncertainty라고 한다. 이에 대해서는 뒤의 실험에서 증명한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Details&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; MDN를 훈련시킬 때의 Cost function은 negative log likelihood(NLL)을 사용한다. 가우시안 분포를 가정하며 mean은 $\mu$ , variance는 $\sum$이며 $\pi$만큼 곱하여 scaling을 한다. 모든 mixture에 대해 모두 더하여 Loss를 구한다. MDN을 학습시키고 가장 높은 mixture weight($\pi$)를 가진 mean과 variance를 고르면 Maximum-A-Posterior(MAP)를 구할 수도 있다.&lt;/p&gt;
&lt;p&gt;위의 (1) 번 식에서 각 mixture의 uncertainty를 분해할 수 있다. k번째 mixture의 variance는 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p&gt;$$ \sigma_{a}^{2} (x|k) + \sigma_{e}^{2}(x|k) = \sum_{k}(x) + \parallel \mu_{k}(x) - \sum_{j=1}^{K}\pi_{j}(x)\mu_{j}(x) \parallel ^{2}&amp;nbsp; $$&lt;/p&gt;
&lt;p&gt;($\sigma_{a}$ : Aleatoric uncertainty, $\sigma_{e}$ : Epistemic uncertainty)&lt;/p&gt;
&lt;p&gt;두 번째 term(explained, epistemic)은 k번째 전문가가(위의 전문가 예시를 다시 사용) 예측한 값과 다른 전문가들이 예측한 평균값과 얼마나 다른지를 나타낸다. 그러므로 마치 Sampling(혹은 Ensemble) 기법을 사용하여 각 예측 값이 얼마나 다른지 나타내는 epistemic uncertainty와 대응되는 값을 얻는다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Experimental result : Synthetic Examples&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 모델이 실제로 Uncertainty를 잘 나타내는지를 보기 위해 데이터가 부족할 때(1 사분면의 데이터를 없앰), noise가 심할 때(1사분면의 데이터에 noise를 섞음), output이 2개(함수 2개를 사용) 일 때의 상황을 만들어 실험을 하였다.&lt;/p&gt;
&lt;p&gt;Mixture의 개수는 10개를 사용하였다. 또한 &lt;span style=&quot;color: #666666;&quot;&gt;&quot;&lt;/span&gt;&lt;a href=&quot;https://simpling.tistory.com/entry/%EA%B0%84%EB%8B%A8-%EB%A6%AC%EB%B7%B0-What-Uncertainties-Do-We-Need-in-Bayesian-Deep-Learning-for-Computer-Vision&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;What Uncertainties Do We Need in Bayesian Deep Learning for Computer Vision&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&quot;의 방법도 함께 사용하여 비교하였다. 여기서는 50번의 Sampling을 하고 dropout rate을 0.8로 했다. 학습 layer는 2개이고 256개의 nodes를 사용하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;첫 번째 실험 결과는 Noise 한 데이터와 Absence 한 데이터에 대해 MDN방법과 기존의 방법을 비교하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;761&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVnDqy/btqMkm4muA0/FjuwYeeGiJfIN5CDdKr011/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVnDqy/btqMkm4muA0/FjuwYeeGiJfIN5CDdKr011/img.png&quot; data-alt=&quot;Fig 2.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVnDqy/btqMkm4muA0/FjuwYeeGiJfIN5CDdKr011/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVnDqy%2FbtqMkm4muA0%2FFjuwYeeGiJfIN5CDdKr011%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;761&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;(* E [V(y|x, k)]는 Unexplained uncertainty, V(E [y|x, k])는 Explained uncertainty를 나타낸다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;1. &lt;span style=&quot;color: #333333;&quot;&gt;Noise Data - a, c&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;1 사분면에 Noise를 섞은 데이터에 대한 Uncertainty 결과를 보면 Unexplained uncertainty와 Aleatoric uncertainty의 1사분면 값이 굉장히 높다. Aleatoric uncertainty와 Unexplained uncertainty는 데이터 자체에 있는 Noise를 잡아낸다는 것을 알 수 있다. Explained uncertainty나 Epistemic uncertainty는 기본적으로 데이터가 충분하여 (noise가 심함에도) uncertainty가 낮은 곳과 높은 곳이 섞여 있다. (&lt;span style=&quot;color: #333333;&quot;&gt;Explained uncertainty와 Epistemic uncertainty의 차이가 있지만 왜 그런지는 나와있지 않다. &lt;span style=&quot;color: #333333;&quot;&gt;MDN을 사용하는 방법이 기존의 sampling 방법보다 plot상으로 더 깔끔한(?) 결과를 만들어내는 듯하다. 사용한 HyperParameter가 mixture개수는 10개이고 Monte Carlo 수는 50이라 그럴 수도 있고 sampling시 사용되는 Dropout rate이 0.8로 매우 크고 적은 파라미터(256개 node 2개 layer)를 사용해서 그럴 수도 있다.&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;2. Absence Data - b, d&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;d의 결과를 보면 기존의 방법으로 Epistemic Uncertainty를 잡아내지 못한 것을 볼 수 있다. 반면 b의 결과는 데이터가 없는 1 사분면의 영역을 어느 정도 잡아낸 것으로 보인다. 특히 Explained uncertainty에서 더 잘 잡아냈다. 이것은 &lt;span style=&quot;color: #333333;&quot;&gt;Explained uncertainty와 &lt;span style=&quot;color: #333333;&quot;&gt;epistemic uncertainty가 관련이 있고 &lt;/span&gt;&lt;/span&gt;학습하지 않은 새로운 데이터가 들어오면 &lt;span style=&quot;color: #333333;&quot;&gt;epistemic uncertainty가&lt;/span&gt; 높게 나오&lt;span style=&quot;color: #333333;&quot;&gt;기 &lt;/span&gt;때문에 합리적인 결과이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 다음으로 prior에 따라 posterior 분포가 어떻게 변화하는지 보기 위해 $L_{2}$weight decay 방법을 사용하였다. Absence Data일 때 decay 크기를 크게 할 때 어떻게 변화하는지 아래의 그림 a~c에 나타나 있다. 또한 예측해야 하는 function이 2개일 때(각 mixture가 예측할 수 있는 것은 1개)의 Uncertainty도 확인하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;805&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHHcJj/btqMqeK24Up/3KZicKMBbP6n6iyebWCDP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHHcJj/btqMqeK24Up/3KZicKMBbP6n6iyebWCDP1/img.png&quot; data-alt=&quot;Fig 3.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHHcJj/btqMqeK24Up/3KZicKMBbP6n6iyebWCDP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHHcJj%2FbtqMqeK24Up%2F3KZicKMBbP6n6iyebWCDP1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;805&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;u&gt;1. Absence Data + weight decay - a, b, c&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;weight decay 크기가 커질수록 training data가 없는 영역에 대한 uncertainty가 증가하는 것을 볼 수 있다. 특히, Aleatoric uncertainty와 관련된 Unexplained uncertainty(E [V(y|x, k)])에 굉장히 효과적이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;2. Composition - d, e&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;e의 결과를 보면 한 개의 density network는 두 개의 함수를 모델링할 수 없어 reconstructed result가 엉뚱하게 나왔다. 반면 10개의 mixtures를 사용한 MDN의 결과는 정확하다. 여러개의 예측을 동시에 할 수 있기 때문에 두개의 함수를 fitting 시킬 수 있었다. 그래서 Unexplained uncertainty가 모두 낮은 것을 볼 수 있다. Explained uncertainty는 두 함수의 차이가 큰 부분에서 큰 값을 가진다. 두 함수의 값이 다르므로 여러 mixture들이 서로 다른 값을 예측했고 함수의 차이가 커질수록 예측한 값의 차이도 클 것이기 때문에 당연하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;Experimental result : Uncertainty-Aware Learning from Demonstrate to Drive&lt;/span&gt;&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 최종적으로 MDN을 활용하여 실제 driving dataset에 적용하는 실험을 하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AyRtv/btqMn496SRY/eNns4kY2oYZmgoiIEjeOBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AyRtv/btqMn496SRY/eNns4kY2oYZmgoiIEjeOBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AyRtv/btqMn496SRY/eNns4kY2oYZmgoiIEjeOBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAyRtv%2FbtqMn496SRY%2FeNns4kY2oYZmgoiIEjeOBk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;(위의 그림 중 첫 번째는 total variance를 나타내고, 두 번째와 세 번째는 각각 Explained variance, Unexplained variance를 나타낸다.)&lt;/p&gt;
&lt;p&gt;그림에서 점선으로 된 박스 영역의 위치는 같지만 Uncertainty가 다르게 나타난다. 2개 중 더 왼쪽에 있는 영역의 경우는 Unexplained variance가 높게 나오는데 이는 자동차를 피할 수 있는 여러 경우의 수가 있기 때문이다. 여러 경우 중 하나를 택해야 하므로 &lt;span style=&quot;color: #333333;&quot;&gt;Unexplained&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Uncertainty가 높다.&lt;/p&gt;
&lt;p&gt;오른쪽 영역은 E&lt;span style=&quot;color: #333333;&quot;&gt;xplained&lt;span&gt; variance가 높은데 이는 시뮬레이션 자동차가 앞에 자동차가 있으면 미리 피해버려서 다른 차 바로 뒤에서의 데이터가 없기 때문이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blKNkb/btqMpLo03iX/P0elk8RxfpLNXavp6xv2n1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blKNkb/btqMpLo03iX/P0elk8RxfpLNXavp6xv2n1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blKNkb/btqMpLo03iX/P0elk8RxfpLNXavp6xv2n1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblKNkb%2FbtqMpLo03iX%2FP0elk8RxfpLNXavp6xv2n1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp; 최종적으로 Explained uncertainty (UALfD)와 Une&lt;span style=&quot;color: #333333;&quot;&gt;xplained &lt;span style=&quot;color: #333333;&quot;&gt;uncertainty (UALfD2)를&lt;/span&gt; 각각 시뮬레이션 자동차의 운전 기준으로 사용하였다. uncertainty가 일정 threshold를 넘길 경우 safe mode를 하는 방법을 사용한다. 또한 MDN(k=1) 일 때, MDN(k=10) 일 때, baseline(FC layer), safe mode 일 때를 추가로 비교하였다. 결과는 위의 표와 같다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;가장 빠른 시간에 충돌 없이 들어온 것은 Explained uncertainty를 사용한 UALfD였다. une&lt;span style=&quot;color: #333333;&quot;&gt;xplained uncertainty를 사용한 UALfD2도 collision이 없었고 최종적으로 들어올 수 있었다(이는 safe mode와 유사하게 달렸기 때문일 것이다). 결과적으로 &lt;span style=&quot;color: #333333;&quot;&gt;Explained uncertainty가 안전과 속도를 모두 개선시켰다. RegNet과 MDN을 사용한 경우도 차이가 컸고 k=1과 k=10일 때의 차이도 굉장히 컸다. 이에 따라 MDN의 유용성도 보여주었다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;기존에는 model의 output으로 Aleatoric variance를 예측하고 (MC Dropout으로) Sampling을 하여 Epistemic variance를 얻었다. 이에 따라 Real-time Applications에서는 sampling 시간 때문에 &lt;span style=&quot;color: #333333;&quot;&gt;Epistemic variance를 구하기가 &lt;/span&gt;적합하지 않았다. 그것을 이번 논문에서 MDN 구조로 두 개의 variance를 함께 구하는 방법을 제시하였다. (Sampling-Free)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;MDN으로 Explained variance와 Unexplained variance를 구할 수 있었고 각각의 특성이 Epistemic, Aleatoric variance와 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Explained Uncertainty로 threshold를 정하여 Uncertainty-Aware Learning을 할 때 좋은 성능을 보여주었다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;아쉽게도 Regression에 대한 내용만 있고 Classification을 하는 방법은 소개하고 있지 않다.&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>aleatoric</category>
      <category>epistemic</category>
      <category>uncertainty</category>
      <category>베이지안 딥러닝</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/29</guid>
      <comments>https://simpling.tistory.com/29#entry29comment</comments>
      <pubDate>Mon, 2 Nov 2020 13:02:49 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: What Uncertainties Do We Need in Bayesian Deep Learning for Computer Vision</title>
      <link>https://simpling.tistory.com/28</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&quot;&lt;a href=&quot;https://arxiv.org/pdf/1703.04977.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;What Uncertainties Do We Need in Bayesian Deep Learning for Computer Vision&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;&quot;&amp;nbsp; (NIPS 2017) - Alex Kendal, Yarin Gal&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp;&amp;nbsp;https://www.edwith.org/bayesiandeeplearning/joinLectures/14426&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이번 논문은 Computer Vision 분야에서 Uncertainty를 다룬 논문이다. 사실 Computer Vision에 관심이 있지는 않지만 Uncertainty에 대해 새로운 방법을 제시하여 읽어보았다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;문제제기 및 해결책&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; 어플리케이션에서 AI가 흑인 여성 2명을 고릴라라고 판단한 사건이 있다. 이는 인종 차별 문제로 번져 문제가 되었다.(&lt;a href=&quot;https://www.usatoday.com/story/tech/2015/07/01/google-apologizes-after-photos-identify-black-people-as-gorillas/29567465/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;기사 링크&lt;/a&gt;) 또 자율주행 시스템이 하얀 트레일러를 하늘이라고 인식하여 사고를 내기도 하였다. 만약 둘 다 에러에 대한 더 높은 수준의 Uncertainty를 측정할 수 있었다면 그런 재앙은 피할 수 있었을 것이다. 그래서 본 논문에서는 2가지 Uncertainty를 사용하는 것을 제안한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;u&gt;&lt;b&gt;1. Aleatoric Uncertainty (Data Uncertainty)&lt;/b&gt;&lt;/u&gt; : 데이터에 내재되어 있는 에러에 대한 불확실성. (ex. sensor noise, motion noise 등) -&amp;gt; &lt;a href=&quot;https://simpling.tistory.com/entry/%EA%B0%84%EB%8B%A8-%EB%A6%AC%EB%B7%B0-Simple-and-Scalable-Predictive-Uncertainty-Estimation-Using-Deep-Ensembles&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;저번 글&lt;/a&gt;에서&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&quot;Simple and Scalable Predictive Uncertainty Estimation Using Deep Ensembles&quot;&lt;/b&gt;을 리뷰할 때 model의 output으로 mean과 variance를 예측했는데 그와 같은 방법을 사용한다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;u&gt;&lt;b&gt;2. Epistemic Uncertainty (Model Uncertainty)&lt;/b&gt;&lt;/u&gt; : 모델에 내재되어 있는 에러에 대한 불확실성. 즉, 모델의 weight 분포(prior)를 보게 되는데 논문에서는 MC dropout을 사용한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;627&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/df8Gbl/btqL7xdLT2r/GJsSZS1b093uKcn9wZw7y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/df8Gbl/btqL7xdLT2r/GJsSZS1b093uKcn9wZw7y1/img.png&quot; data-alt=&quot;각 Uncertainty의 특징&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/df8Gbl/btqL7xdLT2r/GJsSZS1b093uKcn9wZw7y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdf8Gbl%2FbtqL7xdLT2r%2FGJsSZS1b093uKcn9wZw7y1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;627&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;각 Uncertainty의 특징&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;위의 사진들은 Aleatoric Uncertainty와 Epistemic Uncertainty의 차이를 나타낸다. Input images에 대한 segmentation을 수행한 것인데, Aleatoric&lt;span style=&quot;color: #333333;&quot;&gt; Uncertainty의 경우 각 물체들의 경계 부분에서 높은 값을 가진다. 한편, &lt;span style=&quot;color: #333333;&quot;&gt;Epistemic Uncertainty는 Ground Truth와 Predict 한 것이 많이 차이가 나는 부분들이 높게 나온 것을 볼 수 있다. 논문에서는 두 개의 Uncertainty 방법을 함께 사용할 수 있는 새로운 방법을 제시하면서 모델의 성능을 개선하는 것을 보여주었다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Main Contribution&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &lt;b&gt;1. Epistemic Uncertainty와 Aleatoric Uncertainty에 대한 이해를 높여 주었고 Classification을 할 때 기존과 다른 새로운 접근 방법을 제시하였다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Epistemic Uncertainty를 알기 위해 Dropout variational inference를 사용하여 posterior를 추정하였다. Aleatoric Uncertainty는 input x에 대해 output y와 함께 variance를 추정하였다. 논문에서는 이 두 가지 Uncertainty를 합쳐서 함께 사용하도록 제안하였다. 그에 대한 &lt;u&gt;Regression&lt;/u&gt;에서의 Loss function은 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ L_{BNN}(\theta) = \frac {1} {D} \sum_{i} \frac {1} {2} \hat{\sigma_{i}} ^ {-2} ||y_{i} - \hat{y_{i}}||^{2} + \frac {1} {2} log \hat{\sigma_{i}}^{2}$$&lt;/p&gt;
&lt;p&gt;$\hat{y_{i}} 와 \hat{\sigma}$는 model의 output으로 구하는 값이고 각각 mean과 variance를 의미한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위의 식은 $\sigma$가 0이 되면 분모가 0이 되므로 다음과 같이 처리하여 계산한다.&lt;/p&gt;
&lt;p&gt;$$L_{BNN}(\theta) = \frac{1} {D} \sum_{i} \frac {1} {2} exp(-s_{i}) ||y_{i} - \hat{y_{i}}||^{2} + \frac {1} {2} s_{i}$$&lt;/p&gt;
&lt;p&gt;(&lt;span style=&quot;color: #333333;&quot;&gt;$ s_{i} = log \hat{\sigma_{i}}^{2}$)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;한편, &lt;u&gt;Classification&lt;/u&gt;의 경우는 위의 방법과 같이 구할 수가 없다. 따라서 Reparameterized trick을 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Image &lt;/span&gt;Segmentation을 진행할 때, Image의 각 pixel별로 softmax 값을 찾아야 한다. 그런데 여기서 모델의 output은 평균과 분산 값이다. 그러므로 평균에 대한 vector $f_{i}$, uncertainty에 대한 vector $\sigma_{i}$가 나온다. 각 픽셀 값에 대한 값은 $f_{i}, \sigma_{i}$를 각각 평균, 표준편차로 가지는 가우시안 분포에서 샘플링한 값이 된다. Network의 Parameter가 W일 때, 다음과 같이 나타낼 수 있다. $$ \hat{x_{i}}|W \sim N(f_{i}^{W}, (\sigma_{i}^{W}) ^ {2})$$&lt;/p&gt;
&lt;p&gt;하지만 이렇게 샘플링한 값은 모델의 output을 계속 바꾸기 때문에 미분이 불가능하여 역전파가 되지 않는다. 따라서 r&lt;span style=&quot;color: #333333;&quot;&gt;eparameterized trick을 사용한다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$ \hat{x_{i,t}} = f_{i}^{W} + \sigma_{i} ^ {W} \epsilon_{t} $$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$ (\epsilon_{t} \sim N(0, I)) $&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;N(0, l)를 따르는 가우시안 분포의 값 $\epsilon$을 $\sigma$와 matmul 하여 $f_{i}$에 더해준다. 이렇게 하면 역전파가 가능해지고 variance도 x에 더해지므로 모델 학습에 반영이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$ L_{x} = \sum_{i} log \frac {1} {T} \sum_{t} exp(\hat {x}_{i, t, c} - log \sum_{c'} exp(\hat {x}_{i, t, c'}))$$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;그 후 T번 반복하여 softmax값을 구한 후 평균을 취해주고 Loss (NLL) 값을 구한다. &lt;a href=&quot;https://simpling.tistory.com/27&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전&lt;/a&gt;에는 분류를 할 때 Brier Score와 Ensemble을 사용하여 Uncertainty를 구했지만 여기서는 MC Dropout과 Loss function을 적절히 구하여 사용하는 새로운 방법을 제시하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &lt;b&gt;2. Aleatoric Uncertainty방법으로 noisy 한 데이터는 덜 학습하게 하는 방법을 사용하여 모델의 퍼포먼스를 개선시켰다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;위의 식에서 $\sigma$가 2번 나오는데 각각의 역할을 이해하면 noisy한 데이터를 덜 학습하게 하는 방법을 이해할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;1) 분모 term $\sigma$의 역할&lt;/u&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: loss attenuation - $\sigma$ 값이 커지게 되면 $||y_{i} - \hat {y_{i}}|| ^ {2} $의 값이 작아진다. 따라서 Loss 값이 작아지므로 작은 값의 역전파가 일어나서 학습에 영향을 많이 못 미치도록 한다. 반대로 $\sigma$ 값이 작으면 반대로 역전파 값이 커져서 학습에 영향을 크게 해 준다. 즉, 확실한 정보(Uncertainty가 작은) 데이터에 대해서는 network를 크게 학습시키고 불확실한 정보(Uncertainty가 큰) 데이터에 대해서는 network를 작게 학습시킨다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;2) 더하는 $\sigma$의 역할&lt;/u&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: $\sigma$값이 무한대로 커져서 loss가 0이 되지 못하도록 하는 regularization term이다.&lt;/p&gt;
&lt;p&gt;즉, 모든 데이터가 불확실하다고 하지 못하게 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &lt;b&gt;3. 각 Uncertainty방법의 특징을 파악하고 모델의 퍼포먼스와 추론 시간을 비교하여 trade-offs를 조사하였다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCoXpL/btqMgtaA5z5/Eetw7qdAdF3zqgYsmrkah0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCoXpL/btqMgtaA5z5/Eetw7qdAdF3zqgYsmrkah0/img.png&quot; data-alt=&quot;데이터셋 변화에 따른 uncertainty 변화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCoXpL/btqMgtaA5z5/Eetw7qdAdF3zqgYsmrkah0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCoXpL%2FbtqMgtaA5z5%2FEetw7qdAdF3zqgYsmrkah0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;데이터셋 변화에 따른 uncertainty 변화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Train dataset이 적을 때와 클 때를 비교하였을 때, Aleatoric variance는 비슷한 값을 가지나 &lt;span style=&quot;color: #ee2323;&quot;&gt;Epistemic variance&lt;/span&gt;는 많은 변화가 일어난다. Epistemic variance의 경우 모델의 uncertainty를 나타내므로 학습을 많이 할수록 값이 줄어든다. &lt;span style=&quot;color: #333333;&quot;&gt;Train set과 다른 Test set을 실험하였을 때도 Epistemic variance값이 큰 값을 가졌는데 이 또한 train set과 다른 데이터가 들어오면 학습을 하지 않은 것이므로 큰 Uncertainty를 갖게 되는 것이다. 그러므로 &lt;span style=&quot;color: #333333;&quot;&gt;Epistemic variance는 이전까지 관찰되지 못한 데이터를 파악하는 것에 큰 도움이 되며 &lt;span style=&quot;color: #ee2323;&quot;&gt;Safety-critical&lt;/span&gt; 한 곳에 필요하다. 그리고 &lt;span style=&quot;color: #ee2323;&quot;&gt;데이터가 얼마 없는 곳&lt;/span&gt;에서 Uncertainty를 잘 줄 수 있다는 장점이 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;한편 &lt;span style=&quot;color: #006dd7;&quot;&gt;Aleatoric variance&lt;/span&gt;는 &lt;span style=&quot;color: #006dd7;&quot;&gt;데이터가 많아&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;Epistemic variance값이 잘 나오지 않는 경우 유용하며 Monte Carlo 기법을 사용하지 않아도 되므로 &lt;span style=&quot;color: #006dd7;&quot;&gt;Real-time&lt;/span&gt; 측정이 필요한 곳에 유용하다.&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Experiments&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6kKeT/btqMgspwWZH/x2KRkgPWJzJk2wzOdTuoDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6kKeT/btqMgspwWZH/x2KRkgPWJzJk2wzOdTuoDK/img.png&quot; data-alt=&quot;성능향상 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6kKeT/btqMgspwWZH/x2KRkgPWJzJk2wzOdTuoDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6kKeT%2FbtqMgspwWZH%2Fx2KRkgPWJzJk2wzOdTuoDK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;성능향상 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Semantic segmentation이나 Monocular depth regression에서 Aleatoric variance와 Epistemic variance를 모두 사용하여 학습시킬 때 대부분 성능 향상이 일어났다. 그리고 Aleatoric uncertainty의 경우가 Epistemic Uncertainty보다 잘 되는 경우가 많은데 이는 &lt;span style=&quot;color: #333333;&quot;&gt;loss attenuation으로 noisy 한 데이터에 대한 학습을 억제한 효과인 것 같다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVzeMT/btqMfiHrfHc/OnXBMvcWEu1wZDYxqDhZ20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVzeMT/btqMfiHrfHc/OnXBMvcWEu1wZDYxqDhZ20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVzeMT/btqMfiHrfHc/OnXBMvcWEu1wZDYxqDhZ20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVzeMT%2FbtqMfiHrfHc%2FOnXBMvcWEu1wZDYxqDhZ20%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;depth regression에 대한 결과를 보면 각 물체의 테두리에 해당하는 부분에서 aleatoric uncertainty가 높다. 이는 데이터 내에 존재하는 것으로 경계 부분에서 &lt;span style=&quot;color: #333333;&quot;&gt;depth regression을&lt;/span&gt; 어떻게 할지 헷갈려한다는 뜻이다. epistemic uncertainty는 ground truth와 대비하여 예측한 값이 차이가 많이 나는 부분의 값이 높은 것을 볼 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp; 논문에서는 Aleatoric Uncertainty와 Epistemic Uncertainty의 특성을 밝힌다.&lt;/p&gt;
&lt;p&gt;- Aletoric Uncertainty : Large data situations, Real-time applications&lt;/p&gt;
&lt;p&gt;- Epistemic Uncertainty : Safety-critical applications, Small datasets&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;기존까지 두 가지를 따로 사용하였으나 본 논문에서는 함께 측정하는 방법을 제안한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 모델의 output으로 mu와 sigma를 가진다. 적절한 Loss function과 sigma를 이용하여 Aleatoric uncertainty를 예측하고 MC Dropout을 이용하여 Epistemic uncertainty를 예측한다.&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;거기에 더해 Classification에서 사용할 수 있는 새로운 방법을 제시하여 실험에 성공한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- Reparametrized trick을 이용하여 sampling.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;T번 Sampling한 pixel y에 대한 total variance는 epistemic variance 와 a&lt;span style=&quot;color: #333333;&quot;&gt;leatoric variance를 더한&lt;/span&gt; 다음과 같다. $$ Var(y) \approx \frac {1} {T} \sum_{t=1}^{T} \hat{y_{t}}^{2} - (\frac {1} {T} \sum_{t=1}^{T} \hat{y_{t}})^{2} + \frac {1} {T} \sum_{t=1}^{T} \hat{\sigma_{t}}^{2} $$&lt;/p&gt;
&lt;p&gt;첫번째~두번째 term : Aleatoric Variance, 세번째 term : Epistemic Variance&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>aleatoric</category>
      <category>epistemic</category>
      <category>uncertainty</category>
      <category>베이지안 딥러닝</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/28</guid>
      <comments>https://simpling.tistory.com/28#entry28comment</comments>
      <pubDate>Wed, 28 Oct 2020 14:34:02 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: Simple and Scalable Predictive Uncertainty Estimation Using Deep Ensembles</title>
      <link>https://simpling.tistory.com/27</link>
      <description>&lt;blockquote data-ke-size=&quot;size26&quot; data-ke-style=&quot;style3&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/1612.01474&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;&lt;b&gt;&quot;Simple and Scalable Predictive Uncertainty Estimation Using Deep Ensembles&quot;&lt;/b&gt;&lt;/span&gt;&lt;/a&gt; (ICML 2017) - DeepMind&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;https://www.edwith.org/bayesiandeeplearning/joinLectures/14426&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;기존의 연구와 한계, 해결책&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 딥러닝이 발전하며 많은 발전을 이루었지만 아직 부족한 것들이 많이 있다. &lt;b&gt;Uncertainty&lt;/b&gt;를 구하는 일이 그중 하나다. 특히 의료, 금융, 자율주행 등의 task에서 overconfident 한 예측은 치명적인 결과를 이끌 수 있기 때문에 불확실성이 더욱 중요한 키워드가 되었다. 이 논문이 나오기 전에 uncertainty를 구하는 방법들은 대부분 베이지안과 관련이 되어 있었다. 베이지안 방법은 posterior 분포에 대한 mean값을 구하는 과정인데 실제로는 근사하는 방법을 사용한다.(&lt;a href=&quot;https://simpling.tistory.com/entry/%EB%B2%A0%EC%9D%B4%EC%A7%80%EC%95%88-%EB%94%A5%EB%9F%AC%EB%8B%9D-4-variational-inference&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;참조&lt;/a&gt;) 그에 대해 간단히 설명하면 다음과 같다. input을 모델에 넣어 output을 얻을 때, 파라미터를 잘 흔들어(sampling) 연산 시마다 output이 조금씩 달라져서 확률분포처럼 보이게 하는 것을 말한다. 대표적으로 MC Dropout, MC Batch Normalization 이 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;한계-해결책 1)&lt;/u&gt; &lt;/b&gt;베이지안 방법들은 훈련과정에서 많은 수정이 필요하여 computationally expensive 하며 여러 번 sampling 하는 과정이 필요하다. 그래서 논문에서는 하이퍼 파라미터 튜닝이 별로 필요하지 않고 병렬적으로 실행할 수 있으면서도 uncertainty 추정을 잘하는 non-bayesian방법을 제시한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;&lt;span style=&quot;color: #333333;&quot;&gt;한계-해결책 2) &lt;/span&gt;&lt;/u&gt;&lt;/b&gt;베이지안 방법들은 여러 결과를 함께 고려한다는 점이 Ensemble과 비슷하게 보인다. 하지만 Bayesian model averaging(soft model selection)의 경우는 posterior를 잘 근사하였다고 가정하기 때문에 그렇지 않을 경우 결과가 좋지 못하다. 반면 Ensemble(model combination)은 posterior를 잘 근사하지 못해도 좋은 결과를 내며 더욱 robust 한 모델을 얻을 수 있어 논문에서는 이 방법을 사용한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;Metrics - Scoring rules&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 논문에서는 Uncertainty를 측정하는 평가 방법으로 Scoring rules라는 개념을 소개하는데 이는 well-calibrate 된 예측에 대해 좋은 점수를 주고 그렇지 않으면 안 좋은 점수를 주는 지표라고 한다. 사실 대부분의 Neural Net에 대한 loss function은 적절한 scoring rules라고 한다. 여기서는 Brier Score(분류), NLL(회귀)을 사용한다. 추가적으로 Calibration Error도 나오는데 이는 &lt;a href=&quot;https://simpling.tistory.com/entry/%EB%B2%A0%EC%9D%B4%EC%A7%80%EC%95%88-%EB%94%A5%EB%9F%AC%EB%8B%9D-3-%EB%94%A5%EB%9F%AC%EB%8B%9D%EC%97%90-%EB%B2%A0%EC%9D%B4%EC%A7%80%EC%95%88-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글에&lt;/a&gt; 설명이 나와있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;텐서플로우를 사용하여 각각의 loss를 구하면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1603757271724&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import tensorflow as tf

# output : 분류에 대한 예측값
# label : 분류에 대한 정답값
Brier Score = tf.reduce_mean(tf.div(tf.reduce_sum(tf.square(tf.subtract(output, label)), axis = 1), num_label), axis = 0) 

# output_sig_pos : output으로 구한 sigma 값을 양수로 만든 값
# output_mu : output으로 구한 평균값
# label : 회귀에 대한 정답값
NLL = tf.reduce_mean(0.5*tf.log(output_sig_pos) + 0.5*tf.div(tf.square(label - output_mu),output_sig_pos)) + 5&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Main contribution&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; 논문에서 제시하는 (regression에 대한) &lt;b&gt;&lt;u&gt;학습 방법&lt;/u&gt;&lt;/b&gt;은 모델의 final output으로 &lt;b&gt;&lt;u&gt;mean과 variance를 구하는 것&lt;/u&gt;&lt;/b&gt;이다. 보통 Network의 output이 (regression일 경우) 하나의 mean 값을 구하게 된다. 하지만 여기서는 mean과 variance를 함께 구하여 모델의 예측 분포를 알 수 있도록 하였다. 상당히 간단하면서도 신선하다. 이때 사용하는 Loss function이 (Gaussian 분포를 가정한) &lt;b&gt;Negative log likelihood(NLL)&lt;/b&gt;이다. 논문에서 자주 비교하는 대상이 &lt;b&gt;Mean Squared Error(MSE)&lt;/b&gt;인데 MSE는 Proper scoring rule이 아니라 predictive uncertainty를 구하지 못한다고 한다. 즉, variance를 못 구한다는 의미다. 사실 MSE는 가우시안 분포를 가정하여 regression을 수행할 때 NLL로부터 유도될 수 있다(&lt;a href=&quot;https://simpling.tistory.com/entry/Mean-Squared-Error-VS-Cross-Entropy-Error&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;참조&lt;/a&gt;). 이 경우에는 variance가 constant로 무시되어 variance term이 사라지게 되었다. 하지만 직접적으로 NLL을 수행하면 그렇지 않을 수 있어 Scoring rule에 적합하다. 식으로 표현하면 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$ -log(p_{\theta}(y_{n}|x_{n})) = \frac { log (\sigma^{2}_{\theta}(x))} {2} + \frac {(y-\mu_{\theta}(x))^{2}}&amp;nbsp; {2\sigma^{2}_{\theta}(x)} + constant$$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 추가적으로 모델을 잘 학습시키는 방법으로 &lt;u&gt;&lt;b&gt;Ensemble과 Adversarial training&lt;/b&gt;&lt;/u&gt;을 제시하였다. 여기서 말하는 Ensemble 방법은 전체 데이터 셋에서 일부를 sampling하여 각각의 모델을 학습시켜 평균값을 내주는 것을 말한다. 실험 결과를 보면 Ensemble을 하지 않은 모델과 많은 차이가 나는 것을 확인할 수 있다. Classification은 Ensemble할 때 예측값을 평균내면 된다. Regression으로 여러 모델에 대한 Mean과 Variance를 Ensemble하는 것은 mixture of Gaussian distributions에 대한 Mean과 variance를 구하는 것 이다. 그 식은 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ \mu_{*}(x) = M^{-1}\sum_{m}\mu_{\theta_{m}}(x)$$&lt;/p&gt;
&lt;p&gt;$$ \sigma_{*}^{2} = M^{-1}\sum_{m}(\sigma^{2}_{\theta_{m}}(x) + \mu^{2}_{\theta_{m}}(x))-\mu^{2}_{*}(x) $$&lt;/p&gt;
&lt;p&gt;Adverarial training은 대체로 약간의 성능 개선을 이끌어 주었다. 이는 Goodfellow 교수님이 제시한 방법으로 데이터를 loss가 커지는 방향으로 perturbation 하여 실제 target의 공간을 더 열어주는 효과를 준다. 이는 예측 분포를 smooth 하게 해 줘서 더욱 robust 한 모델을 이끌어 내게 해준다. 수식은 다음과 같다. $$x' = x + \epsilon sign(\bigtriangledown_{x} l(\theta,x,y))$$&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Experimentsal reults&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #333333;&quot;&gt;실험 결과를 소개하기에 앞서 실험에서 MSE를 사용할 때, variance를 직접 구할 수 없으므로 empirical variance를 사용했다는 내용의 부록 결과를 소개한다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tiA2a/btqLRjmmaMW/jXFcANXqR5KmxEYlCDGff0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tiA2a/btqLRjmmaMW/jXFcANXqR5KmxEYlCDGff0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tiA2a/btqLRjmmaMW/jXFcANXqR5KmxEYlCDGff0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtiA2a%2FbtqLRjmmaMW%2FjXFcANXqR5KmxEYlCDGff0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;왼쪽의 결과는 variance를 예측하여 학습한 결과를 test set에 적용한 것으로 well-calibrated 되었다. 반면 오른쪽은 empirical variance을 사용한 것으로 uncertainty를 underestimate 하는 결과를 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;1. toyset으로 regression 한 결과&lt;/span&gt;&lt;span style=&quot;color: #000000; letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;709&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDCbFD/btqLTybYXqp/yicxln1YQrERDcSP5xV5zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDCbFD/btqLTybYXqp/yicxln1YQrERDcSP5xV5zk/img.png&quot; data-alt=&quot;Figure 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDCbFD/btqLTybYXqp/yicxln1YQrERDcSP5xV5zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDCbFD%2FbtqLTybYXqp%2Fyicxln1YQrERDcSP5xV5zk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;709&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;첫 번째 plot은 MSE로 훈련한 결과로 Uncertainty를 전혀 나타내지 못한다. 두 번째 plot은 1개의 모델을 NLL로 훈련한 결과로 약간의 variance를 나타내기 시작했다. 세 번째는 adversarial training을 추가한 결과로 그렇게 나은 성능을 보이진 않는 것 같다. 마지막은 5개의 모델을 앙상블 한 결과로 넓은 variance로 uncertainty를 추정하여 실제 분포를 추정해냈다. 이 실험으로 Ensemble과 Scoring rule(NLL)을 사용하는 것이 Uncertainty 추정에 좋다는 것을 알 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;2. probabilistic backpropagation , MC-dropout , Deep Ensembles 비교&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8Ia23/btqLRjGCg5D/9j4Ja7FtkgvKC1ie1hkVY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8Ia23/btqLRjGCg5D/9j4Ja7FtkgvKC1ie1hkVY1/img.png&quot; data-alt=&quot;table1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8Ia23/btqLRjGCg5D/9j4Ja7FtkgvKC1ie1hkVY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8Ia23%2FbtqLRjGCg5D%2F9j4Ja7FtkgvKC1ie1hkVY1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;table1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;RMSE를 사용하여 학습시키는 경우 논문에서 제시한 Deep Ensembles방법이 그다지 좋지 못하다. 하지만 NLL을 사용하면 대부분 더 좋은 결과를 얻음을 알 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;3. Ensemble 하는 모델을 늘려가며 여러 가지 방법을 MNIST 데이터셋과 SVHN에 적용하면 어떻게 달라지는지를 보았다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;854&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ARFlY/btqLQbB8x4Z/YvpFBvRccYaQ9TfKJIKGL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ARFlY/btqLQbB8x4Z/YvpFBvRccYaQ9TfKJIKGL1/img.png&quot; data-alt=&quot;figure 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ARFlY/btqLQbB8x4Z/YvpFBvRccYaQ9TfKJIKGL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FARFlY%2FbtqLQbB8x4Z%2FYvpFBvRccYaQ9TfKJIKGL1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;854&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;역시 Ensemble model은 그 수가 많아질수록 모든 지표에서 더 좋은 결과를 나타냄을 알 수 있다.(이를 보여주는 다른 실험도 있으나 생략) 또한 MC dropout방법보다 Deep Ensemble 방법을 사용하는 것이 성능이 좋다. Adversarial training 방법은 &lt;span style=&quot;color: #333333;&quot;&gt;augmenting with random direction&lt;span&gt; 보다 좋은 성능을 내지만 &lt;/span&gt;&lt;/span&gt;Ensemble 만큼의 효과가 크지는 않다. 오히려 augmenting with random direction 방법은 Ensemble만 사용할 때보다 안 좋은 결과를 내기도 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;4. Uncertainty Evaluation : known VS unknown classes&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;사실 논문의 핵심은 이 4번째 실험이다. 학습한 데이터를 잘 구분하면서도 이상한 데이터(out-of-distribution data)가 들어올 경우 uncertainty를 높이는 것이 모델의 핵심이기 때문이다. MNIST - Not MNIST와 SVHN - CIFAR10 (왼쪽이 train, 오른쪽이 test)에 대한 실험 결과이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYg7SP/btqLTyb0bFS/ukK8mvLqGfRGJppcTSpQDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYg7SP/btqLTyb0bFS/ukK8mvLqGfRGJppcTSpQDk/img.png&quot; data-alt=&quot;figure 3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYg7SP/btqLTyb0bFS/ukK8mvLqGfRGJppcTSpQDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYg7SP%2FbtqLTyb0bFS%2FukK8mvLqGfRGJppcTSpQDk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;figure 3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Entropy values로 측정을 하였는데 이 값이 높을수록 uncertainty 추정을 잘한 것이다. Known class(위의 그래프)에 대해서는 모든 모델이 좋은 성능을 보이고 있다. Unknwon class(아래의 그래프)는 Ensemble이 1개인 경우 entropy values가 낮지만 5개 이상의 ensemble 결과는 잘 나옴을 알 수 있다. 반면 MC-dropout은 uncertainty 추정이 Deep-Ensemble 모델보다 좋지 못하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;&amp;nbsp; &lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;논문의 핵심은 &lt;b&gt;2가지&lt;/b&gt;다. 첫 번째는 학습을 할 때, &lt;b&gt;Scoring rule(NLL,BS)&lt;/b&gt;을 사용하여 model의 불확실성을 구하는 것. 두 번째는 그것을&lt;b&gt; Ensemble&lt;/b&gt; 하여 정확도를 높이는 것. 이 방법을 사용하면 기존 베이지안 방법들보다 hyperparameter tuning에 적은 시간을 사용하며 MLP, CNN 등의 다양한 구조에 사용 가능하다. 뿐만 아니라 Uncertainty 추정에 좋은 결과를 보인다는 강한 강점이 있다. 하지만 model을 여러 개 학습시켜 Ensemble 하는 방법이라 &lt;span style=&quot;color: #333333;&quot;&gt;hyperparameter tuning에는 시간이 많이 걸리지 않을지라도 모델 학습 자체는 시간이 오래 걸릴 것이다. 또한 얼마 큼의 모델을 Ensemble 해야 하는지 결정하는 것도 명확하지 않다&lt;span style=&quot;color: #333333;&quot;&gt;. 그래서 논문의 마지막에는 using multiple heads, snapshot ensembles, swapout의 방법을 사용해보는 것이 흥미로울 것이라고 제시한다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>bayesian deep learning</category>
      <category>deep-ensemble</category>
      <category>uncertainty</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/27</guid>
      <comments>https://simpling.tistory.com/27#entry27comment</comments>
      <pubDate>Mon, 26 Oct 2020 20:08:24 +0900</pubDate>
    </item>
    <item>
      <title>베이지안 딥러닝 (4) - variational inference</title>
      <link>https://simpling.tistory.com/25</link>
      <description>&lt;p&gt;&amp;nbsp; 베이지안 딥러닝의 목적은 새로운 입력&lt;span style=&quot;color: #333333;&quot;&gt;(x*,y*)&lt;/span&gt;에 대한 Posterior를 추론하는 것이고 그에 대한 식은 다음과 같이 나타낼 수 있다. $$P(y_{*},x_{*}) = \int_{w}P(y|x_{*},w)P(w|x,y)dw$$&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://simpling.tistory.com/entry/%EB%B2%A0%EC%9D%B4%EC%A7%80%EC%95%88-%EB%94%A5%EB%9F%AC%EB%8B%9D-3-%EB%94%A5%EB%9F%AC%EB%8B%9D%EC%97%90-%EB%B2%A0%EC%9D%B4%EC%A7%80%EC%95%88-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;에서 본 바와 같이 posterior &lt;span style=&quot;color: #333333;&quot;&gt;$P(w|D)$를 구하기 어렵고 구했다해도 수많은 파라미터 w에 대해 적분을 해주는 것이 불가능하다. 그래서 다른 방법을 이용하여야 하는데 이때 사용하는 방법 중 하나가 variational inference이다. 간단히 말하면 우리가 알고 있는 어떤 분포 Q(w)를 Posterior &lt;span style=&quot;color: #333333;&quot;&gt;$P(w|D)$로 근사하는 것이다. 그렇다면 그 방법은 무엇인가? 이때 등장하는 것이 KL-divergence 와 Evidence Lower BOund(ELBO)이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; 우선 KL-divergence란 간단히 말해 어떤 두 분포 p와 q의 차이를 계산하는데 사용하는 함수다. 차이가 클수록 값이 커지고 유사할수록 작아진다. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이를 Variational inference와 함께 생각해보면 Q(w)를 P(w|D)로 근사시키기 위해서는 두 분포의 KL-divergence를 Minimize 하면 된다는 결론이 나온다. KL-divergence는 Entropy를 사용하여 다음과 같이 유도된다. (H(p)는 p의 엔트로피, 이산 분포의 경우를 가정)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;$$ H(p,q) = -\sum_{i}p_{i}log(q_{i})$$&lt;/p&gt;
&lt;p&gt;$$ = - \sum_{i}p_{i}log(q_{i}) - \sum_{i}p_{i}log(p_{i}) + \sum_{i}p_{i}log(p_{i})$$&lt;/p&gt;
&lt;p&gt;$$ = H(p) + \sum_{i}p_{i}log(p_{i}) - \sum_{i} p_{i}log(q_{i})$$&lt;/p&gt;
&lt;p&gt;$$ = H(p) + \sum_{i}p_{i}log(\frac {p_{i}} {q_{i}})$$&amp;nbsp;&lt;/p&gt;
&lt;p&gt;p와 q의 엔트로피는 p의 엔트로피에 추가적인 항을 더한 것이다. 그러므로 두 분포는 추가로 더해지는 항만큼의 차이가 있다는 뜻이다. 즉, p와 q의 차이는 $\sum_{i}p_{i}log(\frac {p_{i}} {q_{i}})$이며 이를 KL-divergence라고 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 하지만 KL-divergence는 $D_{KL}(q(w|\theta)||p(w|D))$로 Posterior를 구해야 하므로 직접 구하는 것은 어렵다. 그래서 이때 Evidence Lower Bound의 개념이 등장한다. 이는 log marginal likelihood로부터 식을 유도할 수 있는데 다음과 같다. $$lnP(D) = \int lnP(D)Q(w|\theta)dw$$&lt;/p&gt;
&lt;p&gt;$$ = \int Q(w|\theta) ln \frac {P(D)P(w|D)} {P(w|D)} dw$$&lt;/p&gt;
&lt;p&gt;$$ = \int Q(w|\theta) ln \frac {P(w,D)} {P(w|D)} dw $$&lt;/p&gt;
&lt;p&gt;$$ = \int Q(w|\theta) ln \frac {P(D|w)P(w)} {P(w|D)} dw $$&lt;/p&gt;
&lt;p&gt;$$ = \int Q(w|\theta) ln \frac {Q(w|\theta)P(D|w)P(w)} {Q(w|\theta)P(w|D)} dw $$&lt;/p&gt;
&lt;p&gt;$$ = \int Q(w|\theta) ln \frac {Q(w|\theta)} {P(w|D)} dw + Q(w|\theta)ln \frac {P(D|w)P(w)} {Q(w|\theta)}dw$$&lt;/p&gt;
&lt;p&gt;$$ = D_{KL}(Q(w|\theta)||P(w|D)) + F[Q]$$&lt;/p&gt;
&lt;p&gt;마지막 줄의 식에서 첫항이 KL-divergence를 나타내며 두 번째 항이 Variational Free Energy 혹은 Evidence Lower Bound(ELBO)라고 불린다. 즉, log marginal likelihood를 높이기 위해서는 KL-divergence를 줄이거나 ELBO를 높여야 하는데 KL-divergence는 구하기 힘드므로 대신 ELBO를 Maximize 하여 간접적으로 KL-divergence를 줄여 Q(w) 분포를 Posterior P(w)로 근사하는 문제로 풀게 된다. ELBO의 경우는 Likelihood와 Prior를 구하면 되므로 풀 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 정리하면, Posterior 분포에 근사하는 Q(w)를 구하려고 하는데 이를 Variational inference이라고 한다. 이는 KL-divergence를 Minimize 해서 구해야 하지만 직접 구하지 못하여 ELBO를 Maximize 하여 간접적으로 구한다. 이는 결과적으로 우리가 가진 데이터로 Neural network를 잘 튜닝하는 것을 의미한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참조 : &lt;a href=&quot;https://arxiv.org/ftp/arxiv/papers/1801/1801.07710.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Bayesian Neural Networks&lt;/a&gt;, Vikram Mullachery&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.edwith.org/bayesiandeeplearning/lecture/25280/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.edwith.org/bayesiandeeplearning/lecture/25280/&lt;/a&gt;&lt;a href=&quot;https://www.edwith.org/bayesiandeeplearning/joinLectures/14426&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.edwith.org/bayesiandeeplearning/joinLectures/14426&lt;/a&gt;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/베이지안</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/25</guid>
      <comments>https://simpling.tistory.com/25#entry25comment</comments>
      <pubDate>Tue, 20 Oct 2020 22:34:12 +0900</pubDate>
    </item>
    <item>
      <title>Challenges with Extreme Class-Imbalance and Temporal Coherence: A Study on Solar Flare Data</title>
      <link>https://simpling.tistory.com/24</link>
      <description>&lt;p&gt;&amp;nbsp; 이번 논문은 Class-Imbalance와 Temporal Cocherence 한 데이터를 다룰 때 어떤 방법들이 있으며 어떤 함정을 피해야 하는지를 소개한 논문이다. Solar Flare Data로 예시를 들며 설명을 하였는데 마침 플레어와 관련한 논문을 작성하기로 해서 본 논문이다. 실제로 플레어는 X-ray flux의 파장에 따라 등급을 나누는데 굉장히 Imbalance 하다. 강한 것부터 나열하면 X, M, C, B, N인데 갈수록 많아지는 구조이다. 또한 태양은 11년이라는 주기를 가지고 있어 각 연도별로 X등급이 나오는 비율도 다르다. 논문에서는 2009~2019까지의 데이터를 사용해 아래와 같은 그래프를 나타냈다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;756&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clyAKX/btqKRPgK8Tn/iHOcIorK45v6KFg2V9Ip61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clyAKX/btqKRPgK8Tn/iHOcIorK45v6KFg2V9Ip61/img.png&quot; data-alt=&quot;partition을 5개로 나누었다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clyAKX/btqKRPgK8Tn/iHOcIorK45v6KFg2V9Ip61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclyAKX%2FbtqKRPgK8Tn%2FiHOcIorK45v6KFg2V9Ip61%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;756&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;partition을 5개로 나누었다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjrdwk/btqKSg6gOnL/IHhSjqb2mBChU4jiiAmEMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjrdwk/btqKSg6gOnL/IHhSjqb2mBChU4jiiAmEMk/img.png&quot; data-alt=&quot;블균형한 데이터 분포&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjrdwk/btqKSg6gOnL/IHhSjqb2mBChU4jiiAmEMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbjrdwk%2FbtqKSg6gOnL%2FIHhSjqb2mBChU4jiiAmEMk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;블균형한 데이터 분포&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;X Class의 분포가 나머지에 비해 굉장히 적음을 알 수 있다. 논문 제목에서 Extreme이라는 단어를 사용한 것이 납득된다. 또한 논문 제목에서 눈에 띄는 키워드는 'Temporal Coherence'이다. 이는 '일시적인 연관성' 정도로 해석할 수 있겠는데 시공간적 데이터셋에서 일어나는 event에 대한 분류를 하려고 할 때 temporal coherence가 중요하다고 말한다. 이는 데이터가 공간적, 시간적 근접성 때문에 비슷한 특징을 나타내는 것을 의미한다. 예를 들어 태양 플레어의 경우에는 시간이 별로 지나지 않았을 때 자기장의 운동이 비슷할 것이므로 플레어가 일어나도 그 특성이 유사하다는 것이다. 이에 따라 같은 주기의 플레어는 잘 맞추어도 다른 주기의 test 셋은 잘 맞추지 못할 수 있다. 따라서 temporal coherence를 고려하여 train과 test를 진행해야 하며 이에 대한 실험은 뒤에 나온다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 논문에서는 Solar Flare Prediction에는 3가지 문제가 있다고 제시한다. 첫번째로는 위에서 봤듯이 &lt;b&gt;Extreme Class-Imbalance&lt;/b&gt; 문제이다. 두 번째로는 &lt;b&gt;Point-in-time vs Time Series Forecasting&lt;/b&gt;이라고 제시되어 있는데 플레어는 본질적으로 역동적 현상이고 진화적 경향(pre-flare와 post-flare)이 있기 때문에 single snapshot으로 보면 안 된다는 것이다. 그래서 time series로 진화적 경향을 고려하여야 하며 이것은 point-in-time 보다 다루기 어렵다고 한다. 세 번째로는 &lt;b&gt;Non-representative Datasets&lt;/b&gt;다. 태양은 주기를 가지고 변화하는데 하나의 태양 주기를 보고 train 하여 다음 주기를 맞추는 task는 효과적이지 않다. 왜냐하면 자기장의 활동이 지속적으로 변화하기 때문이다. 또한 수집된 좋은 데이터도 많지 않기 때문에 데이터가 대표성을 띄지 못하는 문제가 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 데이터셋은 &lt;b&gt;SWAN-SF&lt;/b&gt;를 사용한다. 이를 첫번째 이미지(Fig2)와 같이 5개의 partition으로 나누었다. 그 기준은 X , M Class가 대략적으로 유사하게 포함되도록 한 것이다. 그래서 태양 활동이 활발한 3번째 partition은 매우 짧은 것을 확인할 수 있다. 실험은 단순함을 위해 5개의 클래스가 아니라 XM, CBN 두 개의 클래스로 진행하였다. 모델은 모든 실험에서 &lt;b&gt;SVM&lt;/b&gt;을 사용하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 위에서 제시한 문제중 데이터 분석을 할 때 가장 많이 겪는 문제는 Imbalance일 것이다. 나도 상당히 많이 겪었는데 여기에는 간단한 두 개의 방법이 있다. &lt;u&gt;Undersampling, Oversampling&lt;/u&gt;이다. Undersampling은 많은 데이터가 사용되지 못한다는 단점이 있고 Oversampling은 overfitting 될 수 있다는 단점이 있다. 위에서 제시한 데이터 클래스에 대해 &lt;span style=&quot;color: #333333;&quot;&gt;Undersampling, Oversampling 하는 방법은 여러 개가 될 수 있다. binary클래스의 숫자를 맞추면서도 안에 섞인 C, B, N과 X, M 클래스까지 어떻게 맞춰줄 것이냐를 고려해야 하기 때문이다. 그래프로 표현하면 다음과 같다.&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;379&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bahzAR/btqKWWy6SKR/8nvWJbnShJiPKFD0oYRtgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bahzAR/btqKWWy6SKR/8nvWJbnShJiPKFD0oYRtgK/img.png&quot; data-alt=&quot;oversampling과 undersampling&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bahzAR/btqKWWy6SKR/8nvWJbnShJiPKFD0oYRtgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbahzAR%2FbtqKWWy6SKR%2F8nvWJbnShJiPKFD0oYRtgK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;379&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;oversampling과 undersampling&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; sampling 기법말고도 &lt;u&gt;Misclassification weight&lt;/u&gt;라는 방법을 제안한다. 우리는 minority class(여기서는 XM Class)를 잘 탐지해내는 것에 관심이 있으므로 minority class를 틀리는 것에 더 penalty를 주는 것이다. 이 논문에서는 weight를 조정하는 데 사용하는 식이 $w_{j}=\frac {n} {k*n_{j}}$이다. n은 total population, $n_{j}$는 j class에서의 populatioin, k는 class의 숫자이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;u&gt;Cross Validation&lt;/u&gt;과 &lt;u&gt;Data Normalization, Hyper-parameter tuning&lt;/u&gt;에 대한 내용과 실험결과도 있다. &lt;span style=&quot;color: #333333;&quot;&gt;Cross Validation은 핵심 내용이 데이터의 시공간적 특성을 고려하지 않은 random sampling을 하면 안 좋다는 것이다. 그 이유는 temporal (or spatial) coherence 때문이다. 그러한 경우에서는 overfitting을 일으킨다고 한다. 이를 피하기 위해서는 데이터셋의 다른 partitions로 train과 test를 해야 한다. 이에 대해서는 뒤의 실험 결과에 잘 나와있다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Data Normalization은 여기에서는 &lt;span style=&quot;color: #333333;&quot;&gt;zero-one normalization&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;을 진행하였다고 한다. 이때 &lt;span style=&quot;color: #333333;&quot;&gt;(min,max를 구하는 것을)&lt;/span&gt; &lt;/span&gt;각 partition별로&amp;nbsp;한 것과 전체 데이터셋으로 구한 것에 대한 차이를 확인하였다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 실험에 대한 지표로는 &lt;u&gt;TSS(True Skill Statistic)&lt;/u&gt;을 사용하였다. $TSS = TPR + TNR -1 (TPR = \frac {TP} {TP+FN} , TNR = \frac {TN} {TN+FP})$ 로 표현된다. 이는 양성, 음성인 것을 각각 얼마나 잘 골라냈는지를 나타낸다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 실험에서 Undersampling은 위의 fig2에서 제시한 US2 방법을 사용하였고 이는 binary class의 숫자뿐 아니라 그 안의 각 클래스별 숫자까지 모두 맞춰준 것이다. Oversampling은 OS3방법을 사용하였고 이는 X, M class를 1:1로 만들면서 C 클래스는 그대로 유지하고 B와 N은 undersampling 하였다. 참고로 sampling 방법은 train시에만 진행하고 test시에는 데이터를 그대로 사용한다. Mis-Classification Weights는 partition3을 예로 들었는데 minority-majority의 ratio 가 1:20 이어서 $w_{XM}=20, w_{CBN}=1$로 했다고 한다. 실험 결과를 보면 다른 sampling 기법들보다 좋은 결과를 내어 robust 한 forecast model을 만드는데 적합한 것으로 보인다. 실험 결과는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wQcVf/btqKVOBoET5/u7NKkBwZc0wN5qCEnppBs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wQcVf/btqKVOBoET5/u7NKkBwZc0wN5qCEnppBs1/img.png&quot; data-alt=&quot;실험결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wQcVf/btqKVOBoET5/u7NKkBwZc0wN5qCEnppBs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwQcVf%2FbtqKVOBoET5%2Fu7NKkBwZc0wN5qCEnppBs1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;실험결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 다음으로는 Cross Validation을 할 때 Train 셋과 Test 셋을 같은 partition으로 뽑았을 때(Unifold)와 다른 partition에서 뽑았을 때(Multifold)에 대한 실험 결과이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;422&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceB4di/btqKTE6SovG/CXdI36BMoL042IlUspRQR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceB4di/btqKTE6SovG/CXdI36BMoL042IlUspRQR0/img.png&quot; data-alt=&quot;cross validation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceB4di/btqKTE6SovG/CXdI36BMoL042IlUspRQR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceB4di%2FbtqKTE6SovG%2FCXdI36BMoL042IlUspRQR0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;422&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;cross validation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Unifold가 더 TSS가 높게 나오는데 이는 언뜻 보기에 더 좋다고 판단할 수 있으나 사실은 temporally coherent 데이터를 사용하였기 때문에 overfitting이 일어나서 그렇게 보이는 것이다. 그러므로 robust 한 모델을 만들기 위해서는 Multifold로 Cross Validation을 수행해야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 아래 그림은 Normalization을 Local영역에서 할 때와 Global 영역에서 할 때 각각의 TSS에 대한 그래프이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4hRru/btqK03X8UdW/71k8Jaq7riyNkXF0Qhi801/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4hRru/btqK03X8UdW/71k8Jaq7riyNkXF0Qhi801/img.png&quot; data-alt=&quot;normalization&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4hRru/btqK03X8UdW/71k8Jaq7riyNkXF0Qhi801/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4hRru%2FbtqK03X8UdW%2F71k8Jaq7riyNkXF0Qhi801%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;normalization&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Local 영역에서의 그래프는 큰 폭으로 성능이 바뀌게 된다. 이는 11년의 태양주기마다 지속적으로 자기장의 활동이 변하기 때문에 training과 testing partitions의 normalization을 일관성 없게 만들어서 그렇다. 반면 Global 한 Normalization은 변화가 적어 robust 한 양상이다. 하지만 어떤 데이터를 쓰느냐에 따라 Local normalization이 나을 수도 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;마지막으로 Oversampling을 할 때 sub-class balnace를 맞추느냐 아니냐에 따른 실험 결과를 제시한다. 이는 위의 fig4에서 OS3와 OS1에 해당한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btSf7T/btqKZnigLLM/TDwiBQoxnOabU0FKM4viHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btSf7T/btqKZnigLLM/TDwiBQoxnOabU0FKM4viHk/img.png&quot; data-alt=&quot;Oversampling with or without sub-class balnace&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btSf7T/btqKZnigLLM/TDwiBQoxnOabU0FKM4viHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtSf7T%2FbtqKZnigLLM%2FTDwiBQoxnOabU0FKM4viHk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Oversampling with or without sub-class balnace&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;두 방법은 비슷한 성능을 내지만 OS1이 좀 더 우위를 차지한다. 논문에는 OS1은 OS3보다 M-class instances를 X-class 보다 많이 형성하여 분류를 더 쉽게 만드는 데이터셋을 생성한다 라고 나와있다. 그래서 OS1이 더 나은 성능을 보일 것으로 예상하는 것은 당연하다고 한다. 같은 Oversampling이라도 다른 결과를 낼 수 있기 때문에 유사한 데이터셋으로 여러 model을 평가할 때는 같은 sampling 기법을 사용하는 것이 공정하다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Class-Imbalance와 Temporal coherence로 생기는 어려움을 해결하는 방법에 관한 논문이었는데 주제도 태양 플레어와 관련하여 도움이 많이 되었다. 방법은 기초적인 것이 많았지만 실험 결과들이 흥미로워 많은 insight를 얻을 수 있었다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참조 : &lt;a href=&quot;https://arxiv.org/pdf/1911.09061v1.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Challenges with Extreme Class-Imbalance and Temporal Coherence: A Study on Solar Flare Data, Azim Ahmadzadeh, 2019&lt;/a&gt;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/24</guid>
      <comments>https://simpling.tistory.com/24#entry24comment</comments>
      <pubDate>Thu, 15 Oct 2020 11:45:17 +0900</pubDate>
    </item>
    <item>
      <title>논문 리뷰: Averaging Weights Leads to Wider Optima and Better Generalization(SWA)</title>
      <link>https://simpling.tistory.com/23</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&quot;Averaging Weights Leads to Wider Optima and Better Generalization&quot;&lt;/b&gt;&lt;/span&gt; - Pavel Izmailov (2019)&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp;이번 논문은 Stochastic Weigths Averaging(SWA) 방법을 제시한 논문이다. 여러 캐글 대회에서 이 방법을 사용하여 우승을 하는 경우를 봐서 논문을 리뷰하게 되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; SWA는 기존의 SGD 보다 더 flatter 한 solution을 찾는 방법이라고 설명한다. 그래서 &lt;b&gt;generalization&lt;/b&gt;에 강하여 test 셋에서 훨씬 좋은 성능을 보인다. 방법 또한 간단하여 기존과 계산량 차이가 거의 없어 효과적이라 할 수 있다. &lt;u&gt;SWA는 SGD를 이용하여 optimization을 진행할 때 일정 주기마다 weight를 average하여 $w_{swa}$를 update 시키는 방법이다.&lt;/u&gt;(SnapShot Ensembles 방법 이다.) 논문에서 SWA는 &lt;b&gt;optimization&lt;/b&gt;과 &lt;b&gt;regularization&lt;/b&gt;과 관련있다고 한다. 여러 주기마다 weight를 update 시키는 것은 local solutions를 ensemble 하는 것과 같다고 이해할 수 있다. 따라서 어느 한쪽에 쏠리는 것을 막아 regularize를 수행하며 general 한 solution을 찾게 된다. &lt;span style=&quot;color: #333333;&quot;&gt;loss surface에서 대략적인 sampling을 하여 가중치를 업데이트 한다는 개념이 베이지안적 접근이라는 생각을 했다. 마지막 Discussion에도 이에 대한 내용이 나와 있다. Cyclical learning rate을 사용하면 SWA가 neural network weights에 대한 high posterior density를 탐험하는 것을 가능하게 한다. 이는 MCMC 방법과 유사하다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Algorithm&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; SWA를 수식으로 나타내면 아래 그림과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;311&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2fSL2/btqKRr0lpM2/6QQTED3myG87xWAPK7S1tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2fSL2/btqKRr0lpM2/6QQTED3myG87xWAPK7S1tk/img.png&quot; data-alt=&quot;SWA 수식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2fSL2/btqKRr0lpM2/6QQTED3myG87xWAPK7S1tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2fSL2%2FbtqKRr0lpM2%2F6QQTED3myG87xWAPK7S1tk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;311&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;SWA 수식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;개념만큼이나 &lt;span style=&quot;color: #333333;&quot;&gt;수식 또한 간단하다. &lt;/span&gt;SGD가 각 step마다 weight를 업데이트 시키는데 일정 주기마다 $w_{swa}$를 average값을 내어 업데이트시킨다는 것이 끝이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;Experimental result&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;b&gt;1)&lt;/b&gt; &lt;b&gt;논문에서 Learning rate를 중요하게 다루고 있는데 SWA를 사용할 때는 Constant 한 값과 Cyclical 한 값을 추천한다. 아래는 두 learning rate를 사용했을 때의 결과를 나타낸 그래프이다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKvXoR/btqKTFDmzJH/Vy2kjc8hkrKilFRsa43vJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKvXoR/btqKTFDmzJH/Vy2kjc8hkrKilFRsa43vJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKvXoR/btqKTFDmzJH/Vy2kjc8hkrKilFRsa43vJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKvXoR%2FbtqKTFDmzJH%2FVy2kjc8hkrKilFRsa43vJk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;왼쪽 두개는 Cyclical learning rate schedules을 사용한 것이고 오른쪽은 Constant learning rate schedules을 사용한 것이다. 우선 &lt;span style=&quot;color: #333333;&quot;&gt;Cyclical&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;learning rate schedules는 individual한 성능이 Constant learning rate 보다 일반적으로 더 정확하다. 하지만 Constant learning rate은 상대적으로 항상 큰 step으로 업데이트가 되어 Cyclical learning rate 보다 더 효과적인 탐험을 가능하게 한다는 장점이 있다. 따라서 어떤 task를 해결하냐에 따라 둘 다 사용하여 더 나은 것을 선택하는 것이 좋을 것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; &lt;b&gt;2) 이어서 Preactivation ResNet-164로 CIFAR-100를 학습할 때, 여러 Learning rate scheduels로 실험을 했다. 결과는 아래와 같다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;335&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHqJwn/btqKShJJmro/kNAzKk2jPFOoHOPjQpGS10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHqJwn/btqKShJJmro/kNAzKk2jPFOoHOPjQpGS10/img.png&quot; data-alt=&quot;여러 lr 실험&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHqJwn/btqKShJJmro/kNAzKk2jPFOoHOPjQpGS10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHqJwn%2FbtqKShJJmro%2FkNAzKk2jPFOoHOPjQpGS10%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;335&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;여러 lr 실험&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;가장 좋은 LR은 0.05였다. 일반적으로 0.05는 learning rate 치고 큰 편에 속하는데 이렇게 큰 learning rate을 사용하면 많은 탐색이 가능하며 SWA를 빠르게 수렴하도록 하는 좋은 결과를 낸다고 한다. 하지만 논문에서는 어떤 문제를 푸느냐에 따라 다르다고 하였으니 각 문제마다 hyperparmeter 탐색을 잘해야 할 것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; fixed learning rate으로 SWA를 사용한 실험에서 처음부터 SWA를 사용하여 학습을 시킨 모델보다 처음에는 그냥 SGD를 사용하고 중간부터 SWA를 사용한 모델이 16%정도 더 정확한 모델이 나왔다고 한다. 이렇게 &lt;u&gt;중간부터 SWA를 사용하면 더 빠르고 안정적이게 수렴한다고 한다.&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp; 3) &lt;span style=&quot;color: #333333;&quot;&gt;기존의 알고리즘들과 SWA를 ImageNet이나 CIFAR-10, CIFAR-100에 적용하여 성능을 비교하였는데 기존 SGD보다 항상 좋은 성능을 냈다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WPGO1/btqKTFwG4MH/4QV3ieSw7RQrURccNZiURk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WPGO1/btqKTFwG4MH/4QV3ieSw7RQrURccNZiURk/img.png&quot; data-alt=&quot;CIFAR-10, CIFAR-100으로 성능비교&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WPGO1/btqKTFwG4MH/4QV3ieSw7RQrURccNZiURk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWPGO1%2FbtqKTFwG4MH%2F4QV3ieSw7RQrURccNZiURk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;CIFAR-10, CIFAR-100으로 성능비교&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; 논문에서 &lt;a href=&quot;https://arxiv.org/abs/1802.10026&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Fast Geometric Ensembling(FGE)&lt;/a&gt;라는 알고리즘을 자주 언급하며 비교한다. 직접 읽어보진 않았지만 FGE는 weight space에서 가까운 포인트들을 생성하며 거기서 여러 Prediction을 내어 Ensembling 하는 알고리즘을 사용한다고 한다. 이에 따라 FGE는 계산량이 SWA보다 많을 수밖에 없다. 하지만 성능을 비교해봤을 때는 거의 비슷하며 CIFAR-10에서는 더 나은 결과를 내기도 하였다. 논문에서는 수식을 사용하여 prediction을 ensemble 하는 것과 weight를 ensemble 하는 것은 second order만큼의 작은 차이가 난다는 것도 증명하였다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #7e98b1;&quot;&gt;&lt;b&gt;개인 실험&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; 개인적으로 SWA를 사용해보고자 Pretrain 된 RESNET-50 모델을 CIFAR-10에 적용하여 성능을 비교하는 실험을 해보았다. 논문에서는 SGD만 사용하였지만 자주 사용하는 Adam도 성능이 잘 나오는지 궁금하여 같이 진행해 보았다. learning rate은 0.05를 사용하였다. train set은 5만 장, test set은 1만 장을 사용하였다. 총 5 epoch만 진행하였으며 $w_{swa}$는 10 step마다 업데이트하도록 하였다. tensorflow 2.3 version을 사용하였다. training에 대한 결과 그래프는 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;692&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LC0c9/btqKTGPS9qP/XybCYyo62vTcaWoJkD6qYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LC0c9/btqKTGPS9qP/XybCYyo62vTcaWoJkD6qYk/img.png&quot; data-alt=&quot;Training graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LC0c9/btqKTGPS9qP/XybCYyo62vTcaWoJkD6qYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLC0c9%2FbtqKTGPS9qP%2FXybCYyo62vTcaWoJkD6qYk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;692&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Training graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;test set에 대한 결과는 &lt;span&gt;adam:0.21, swa_adam:0.26, sgd:0.53, swa_sgd:0.56&lt;/span&gt; 이었다. 여러 번 실행을 하였을 때 SGD의 경우 swa가 더 잘 나오는 결과를 얻었다. 하지만 Adam은 training마다 결과가 잘 나올 때도 있고 그렇지 않을 때도 있었다. learning rate을 너무 크게 설정해서 그럴 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;혹시 개인적으로 돌리고 싶은 분들이 있다면 &lt;a href=&quot;https://github.com/Junghwan-brian/Colab/blob/main/SWA%EC%8B%A4%ED%97%98.ipynb&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;깃헙&lt;/a&gt;에 올려놨으니 colab을 사용하여 코드를 실행시키시면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/논문리뷰</category>
      <category>Generalization</category>
      <category>stochastic weight averaging</category>
      <category>swa</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/23</guid>
      <comments>https://simpling.tistory.com/23#entry23comment</comments>
      <pubDate>Wed, 14 Oct 2020 13:09:21 +0900</pubDate>
    </item>
    <item>
      <title>베이지안 딥러닝 (3) - 베이지안 딥러닝은 무엇인가?</title>
      <link>https://simpling.tistory.com/22</link>
      <description>&lt;p&gt;&amp;nbsp; Deep Learning에 베이지안을 사용하면 뭐가 좋은가? 불확실성에 대해 알 수 있다. 이에 대한 지표로 Expected Calibration Error (ECE)를 알면 좋다. 이번에 새롭게 알게 된 지표인데 상당히 유용한 것 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; Classification을 하게 될 때 softmax를 사용하게 된다. 이 softmax는 결과값에 대한 확률 값을 주게 되는데 일반적인 머신러닝 방법에서는(특히 데이터가 별로 없을 때) 그 값이 over-confident 하게 나온다. 쉽게 예를 들어보면 고양이와 강아지를 분류하는 모델인데 어떤 사진을 주었을 때, 결과에 대한 확률 값이 한쪽으로 쏠려서 높게 나온다는 이야기이다. 제대로 분류를 하여 잘 나온다면 괜찮겠지만 아리송한 경우에도 그 값이 높을 때는 문제가 된다. 한마디로 정말 당당히 틀리는 경우가 나올 수 있다는 것이다. 우리가 원하는 것은 80% 확률로 예측을 했을 때 실제 데이터에 대해 80% 정도로 맞추는 것이다. 이를 수식으로 나타내면 다음과 같다. $$P(\hat {Y}=y|\hat {P}=p) = p$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이에 대해 완벽한 경우 완벽히 calibration된 모델이라고 한다. 이 경우 확률을 정확히 믿을 수 있게 된다. 아래는 각 확률 값(x축)에 대해 실제 데이터의 분포 확률(y축)을 나타낸 그래프이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;421&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7vs6w/btqKGkgovBm/Bm63v1OChVRrCNucESsS6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7vs6w/btqKGkgovBm/Bm63v1OChVRrCNucESsS6k/img.png&quot; data-alt=&quot;calibration graph (출처: sklearn)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7vs6w/btqKGkgovBm/Bm63v1OChVRrCNucESsS6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7vs6w%2FbtqKGkgovBm%2FBm63v1OChVRrCNucESsS6k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;421&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;calibration graph (출처: sklearn)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;점선이 Perfectly calibrated된 경우인데 y=x를 그리고 있다. 이 선에 가까울수록 softmax로 나온 확률을 믿을만한 모델이다. 초록색 Support vector classification을 보면 초반에 확률 값이 낮을 때 실제 데이터 분포는 0에 가깝다. 즉 0~0.4 근처까지는 실제 맞추는 경우가 0%에 가깝다고 판단할 수 있고 오히려 &lt;span style=&quot;color: #333333;&quot;&gt;0.5 이상 부터는&lt;/span&gt; softmax 확률 대비 실제 분포의 확률 값이 더 높음으로 나온다. 이런 경우는 별로 탐탁지 않을 것이므로 ECE를 통해 평가를 하는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 우선 &lt;span style=&quot;color: #333333;&quot;&gt;calibration error를 구할 수 있어야 한다. &lt;/span&gt;calibration error는 아래의 수식과 같다. 이 수식은 위에서 봤던 perfect calibration model의 좌항과 우항의 차이 평균값이다.&lt;/p&gt;
&lt;p&gt;$$ E_{\hat {p}}[P(\hat {Y}=y|\hat {P}=p)-p]$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 최종적으로 Expected calibration error는 &lt;span style=&quot;color: #333333;&quot;&gt;calibration error를 실제 데이터 포인트에 대해 평가한 것이다. 이는&lt;/span&gt;&amp;nbsp;위의 그래프에서 perfectly calibrated와 실제 모델이 예측한 그래프의 차이에 대한 면적을 weighted sum 한 값이다. 수식은 다음과 같다.&lt;/p&gt;
&lt;p&gt;$$ \sum_{m=1}^{M} \frac {|B_{m}|} {n} |acc(B_{m}) - conf(B_{m})| $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 결과적으로 ECE를 잘 나오게 하는 것이 Bayesian의 목적이라고 할 수 있을 것 같다. 어떤 input에 대해 output을 내는데 확률 값이 정확하다면 이에 대한 불확실성을 알 수 있기 때문이다. 일반적인 머신러닝에서는 Likelihood를 최대화하는 Maximum-Likelihood(ML) 방법을 사용한다. 하지만 베이지안에서는 Prior로 Posterior를 찾는 방법을 쓴다. 단순히 Maximum-A-Posterior(MAP)를 찾는 것은 베이지안이 아니다. MAP는 over-confident 한 결과를 주기 때문에 uncertainty를 추정하기 힘들다. Bayesian Posterior는 MAP와 같이 최대가 되는 하나의 값을 찾는 것이 아니라 output에 대한 distribution을 추정하는 것이다. 예를 들어 아래 그림과 같은 Classification문제를 푼다고 가정한다. 이때 decision boundary distribution은 회색 선들로 나타낼 수 있다. &lt;span style=&quot;color: #333333;&quot;&gt;선이 진한 부분은 MAP를 이루는 부분이 될 것이며 선이 연해질수록 거기서 멀어지는 값이 된다. 이렇게 여러 분포를 알면 새로운 입력이 들어왔을 때, 적절한 output 확률 값을 구할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;328&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8cpIf/btqKDalaBpb/9frAQakvkuyK37PDIYjVY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8cpIf/btqKDalaBpb/9frAQakvkuyK37PDIYjVY0/img.png&quot; data-alt=&quot;Decision boundary distribution&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8cpIf/btqKDalaBpb/9frAQakvkuyK37PDIYjVY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8cpIf%2FbtqKDalaBpb%2F9frAQakvkuyK37PDIYjVY0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;328&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Decision boundary distribution&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;span style=&quot;color: #333333;&quot;&gt;Bayesian predict inference는 새로운 입력 $x^{*}$가 들어왔을 때 그에 대한 mean 값을 구하는 것이다. 식으로 보면 다음과 같다. $$\bar {y^{*}} = \int P(y^{*}|x^{*}, w) P(w|D) dw$$ 이때 P(w|D)는 Posterior로 식이 다음과 같다. &lt;/span&gt;$P(w|D) = \frac {P(D|w) P(w)} {P(D)} = \frac {P(D|w)P(w)} {\int P(D|w) P(D) dw}$. Posterior 분모 항의 Evidence는 구하는 게 어렵다. 만약 구했다고 해도 posterior를 구하기 위해서는 w에 대해 적분을 해줘야 하는데 w는 파라미터의 수가 많기(보통 딥러닝의 경우 파라미터를 수백만 개 이상 사용하므로) 때문에 적분이 힘들다. 따라서 Bayesian Model Averaging으로 근사를 한다. 근사식은 다음과 같다. $$ \bar {y^{*}} \sim \frac {1} {T} \sum_{w_{t} \sim q(w)} P(y^{*}|x^{*}, w_{t}) $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 간단히 정리하면 우리는 Posterior를 근사하는 q(w)를 구하고 싶은 것이다. 이때 weight를 sampling 하여 Average를 구하면 대략적 근사를 할 수 있다. 이 weights를 어떻게 sampling 하는가가 중요하게 작용한다. 이에 대한 주제가 Approximate Bayesian inference이다. 이에 대한 방법들로는 Bayes By Backprop(BBB), Markov Chain Monte Carlo method(MCMC), MC Dropout 등이 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참조 : &lt;a href=&quot;https://www.youtube.com/watch?v=Gm-TJ82vj6E&amp;amp;list=WL&amp;amp;index=9&amp;amp;t=421s&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.youtube.com/watch?v=Gm-TJ82vj6E&amp;amp;list=WL&amp;amp;index=9&amp;amp;t=421s&lt;/a&gt;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/베이지안</category>
      <category>bayesian</category>
      <category>Calibration</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/22</guid>
      <comments>https://simpling.tistory.com/22#entry22comment</comments>
      <pubDate>Mon, 12 Oct 2020 19:42:49 +0900</pubDate>
    </item>
    <item>
      <title>베이지안 딥러닝 (2) - Gaussian Process Regression (1)</title>
      <link>https://simpling.tistory.com/21</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Gaussian Process Regression(GPR)은 Non-parametric Bayesian regression 방법으로 Gaussian Process의 성질을 이용한다. 이를 이해하기 위해 먼저 Gaussian Process(GP)를 알아야 한다.&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;&amp;nbsp;GP는 처음 들어보는 것으로 낯설지만 어렵지 않은 개념이다. GP는 Random Process의 한 종류인데 Random Process는 시간(혹은 공간) 별로 표시된 확률변수의 조합이다. 직관적 이해를 돕기 위해 시간을 t 하나로 고정시키면 &lt;span style=&quot;color: #333333;&quot;&gt;Random Process는 Random Variable이 된다. 즉 하나의 시간별로 Random Variable이 있고 이것이 시간만큼 나열되어 있는 것이다. &lt;span style=&quot;color: #333333;&quot;&gt;Random Process X(t)인&amp;nbsp;&lt;/span&gt;$t_{1},t_{2}, ... , t_{k}$ 에 대해 랜덤 벡터 $X(t_{1}) , X(t_{2}), ... , X(t_{k})$ 가 jointly Gaussian을 만족하면 &lt;span style=&quot;color: #333333;&quot;&gt;Gaussian Process(GP)&lt;/span&gt; 이다. 이때 joint density는 다음과 같이 정의된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$ Mean : m(t) = E(X(t)) \in R^{n} $$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$ \cdot m(*) : mean function$$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$ Covariance : k(t,s) = cov(X(t),X(s)) \in R^{n \times n} $$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$ \cdot k(*,*) : covariance function $$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$ Notation : X(t) \sim gp(m(t),k(t,s)) $$&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말해 GP는 유한한 점들에 대한 다변량 정규분포를 의미한다.&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;&amp;nbsp; 이에 대한 예시로 X(t) = tA , where A ~ N(0,1) and t$\in$R 이 있다. t가 고정이면 상수 $\times$ A가 되고 A~N(0,1) 이므로 Random variable을 만족하며 A가 고정이면 시간에 대한 함수가 되므로 랜덤 프로세스의 조건을 만족한다. 이때,&amp;nbsp; Mean : m(t) = E(X(t)) = tE(A) = 0 가 되며 Covariance : k(t, s) = E(tAts) = ts 이므로 커널 함수가 ts인 GP가 성립된다.&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 style=&quot;color: #333333;&quot;&gt;&amp;nbsp; Weight space view를 이용해&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Gaussian Process Regression을 설명해보겠다. &lt;/span&gt;우선 간단한 Linear Regression에 대한 식 $f(x) = x^{T}W$ 을 생각해본다. 이 식은 x가 주어졌을 때 W를 찾는 것이다. y(x) = f(x) + $\varepsilon$ (where $\varepsilon \sim N(0,\sigma^{2}))$ 으로 n개의 Train data에 Noise가 섞였다고 가정한다. &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그랬을 때 &lt;span style=&quot;color: #333333;&quot;&gt;Likelihood는&lt;/span&gt; $$ P(y|x, w) = \prod_{i=1} ^ {n} P(y_{i}|x_{i},w) = \frac{1} {\sqrt{2\pi\sigma_{n}^{2}}} exp(-\frac{(y_{i}-y{i}^{T}w)^{2}} {2\sigma_{n}^{2}}) = \frac{1} {(2\pi\sigma^{2}_{n})^{\frac{2} {n}}} exp(-\frac{1} {2\sigma_{n}^{2}} ||y-X^{T}w||^{2})$$&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;&amp;nbsp; Bayesian은 단순히 Likelihood를 구하는 것이 아니다. Posterior distribution을 찾는 것이 그 목적이다. 따라서 파라미터에 대한 prior를 줘야 한다. 즉, weight에 대한 분포를 줘야 하는데 이때 Gaussian을 주게 된다. Gaussian을 주는 이유는 Conjugate Prior 때문이다. 낯선개념인데 간단하다. 내가 가지고 있는 Likelihood에 대한 Prior 꼴이 있다는 것이다. 이 Prior를 가정해야 Posterior을 계산할 수 있다. 그런데 이것을 만족하는 꼴이 별로 없으며 그중 하나가 &lt;span style=&quot;color: #333333;&quot;&gt;Gaussian&lt;/span&gt;이다. 위에서 Likelihood를 구할 때 가우시안을 가정하였으므로 Prior도 &lt;span style=&quot;color: #333333;&quot;&gt;Gaussian&lt;/span&gt; 분포를 따른다고 가정한다. 그래서 &lt;span style=&quot;color: #333333;&quot;&gt;Gaussian$\times$Gaussian = Gaussian을 도출한다. 이때 &lt;span style=&quot;color: #333333;&quot;&gt;Posterior는 다음과 같다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; $$P(w|y,x) = \frac{P(y|x,w) P(w)} {p(y|x)} \propto exp(\frac{1}{2\sigma^{2}_{n}}(y-x^{T}w)^{T}(y-x^{T}w)) exp(-\frac{1} {2} w^{T} \Sigma_{p}^{-1}w)$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ = exp(\frac{1} {2} (w-\bar{w})^{T}A(w-\bar{w})) (where , \bar{w}=\frac{1} {\sigma^{2}_{n}}A^{-1}xy , A=\frac{1}{\sigma^{2}_{n}}xx^{T}+\Sigma^{-1}_{p})$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\therefore P(w|y,x) = N(\bar{w},A^{-1})$$&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;&amp;nbsp; 슬프게도 단순히 Posterior를 구하는 것이 Bayesian solution이 아니다. 새로운 입력값에 대한 Posterior의 mean을 구하는 것이다. 여기까지 데이터에 대한 w의 분포를 구했다. 이제 새로운 입력 $x_{*}$이 들어왔을 때 Posterior mean을 구할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$P(f_{*}|x_{*},x,y) = \int P(f_{*}|x_{*},w)P(w|x,y)dw$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$N(\frac{1}{\sigma^{2}_{n}}x_{*}^{T}A^{-1}xy,x^{T}_{*}A^{-1}x_{*})$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 구한 것은 Linear regression에 대한 bayesian solution으로 Gaussian Process Regression을 구하기 위해서는 kernel trick을 써야 한다. 이는 입력을 다른 공간으로 보내서 Linear Regression을 해주는 방법이다. $f(x) = \phi(x)^{T}w$&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;kernel trick까지 이용하여 최종적으로 값을 구하면 $f_{*}$의 분포는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ f_{*}|x_{*}, x, y \sim N(m_{*},\Sigma_{*})$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ m_{*} = k(x_{*},x)(k(x,x)+\sigma_{n}^{2}l)^{-1}y$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ \Sigma_{*} = k(x_{*},x_{*})-k(x_{*},x)(k(x,x)+\sigma_{n}^{2}l)^{-1}k(x,x_{*})$$&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;&amp;nbsp; weight space view는 수식이 많아 어렵고 직관적이진 않은 것 같다. (좀 더 &lt;a href=&quot;https://simpling.tistory.com/37&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;쉽게 정리한 글&lt;/a&gt;을 참조하면 좋다.) 다시 한번 정리해보면, 간단한 Linear Regression에 대한 베이지안 솔루션을 구하고자 한다. 우선 Likelihood와 Prior(파라미터에 대한)를 Gaussian이라고 가정하여 Posterior를 구한다. 그러면 새로운 입력에 대한 Posterior의 mean 값을 구할 수 있게 된다. 마지막으로 kernel trick으로 GPR을 구할 수 있다. 하지만 GPR은 n개의 데이터가 있을 때 n*n의 역행렬을 구해야 해서 컴퓨터 연산량이 굉장히 크다. 그래서 빅데이터 시대에는 딥러닝에 뒤쳐지게 되었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;267&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccrsz6/btqOtFg0eB8/hW8ma5NAFQpuz0LJA0MME0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccrsz6/btqOtFg0eB8/hW8ma5NAFQpuz0LJA0MME0/img.png&quot; data-alt=&quot;gaussian process regression (wiki)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccrsz6/btqOtFg0eB8/hW8ma5NAFQpuz0LJA0MME0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fccrsz6%2FbtqOtFg0eB8%2FhW8ma5NAFQpuz0LJA0MME0%2Fimg.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;267&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;gaussian process regression (wiki)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진 참조 : &lt;a href=&quot;https://commons.wikimedia.org/wiki/File:Gaussian_Process_Regression.png&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;commons.wikimedia.org/wiki/File:Gaussian_Process_Regression.png&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강의 참조 : &lt;a href=&quot;https://www.edwith.org/bayesiandeeplearning/joinLectures/14426&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.edwith.org/bayesiandeeplearning/joinLectures/14426&lt;/a&gt;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/베이지안</category>
      <category>bayesian solution</category>
      <category>gaussian process</category>
      <category>gaussian process regression</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/21</guid>
      <comments>https://simpling.tistory.com/21#entry21comment</comments>
      <pubDate>Mon, 12 Oct 2020 18:07:25 +0900</pubDate>
    </item>
    <item>
      <title>베이지안 딥러닝 (1) - 기초 정리 (베이즈룰,ML,MAP)</title>
      <link>https://simpling.tistory.com/20</link>
      <description>&lt;p&gt;&amp;nbsp; 딥러닝에서 Uncertainty 추정에 관심을 갖다 보니 베이지안 딥러닝이 자주 보인다. 하지만 통계를 전공하지 않아 어려움이 많았다. 그래서 따로 기초부터 심화까지 정리를 하려고 한다. 우선 가장 기초인 베이즈 룰부터 시작한다. 베이즈 룰의 수식은 아래와 같다.&lt;/p&gt;
&lt;p&gt;$$P(B|A) = \frac{P(B \cap A)} {P(A)} = \frac{P(A \cap B)} {P(A)} = \frac{P(A|B) P(B)} {P(A)} $$&lt;/p&gt;
&lt;p&gt;*$(P(A \cap B) = P(A|B)P(B))$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이때 각각의 수식이 어떤 용어로 불리며 어떤 의미를 가지고 있는지를 잘 이해하고 있어야 뒤에 나오는 내용들을 이해하기 쉽다. 우선 $P(B|A)$ 는 구하고자 하는 값으로 Posterior Probability라고 하며 사후 확률이라고도 한다. 이 값을 바로 구하면 좋겠지만 대부분은 그러기 힘들다. 그래서 우리는 오른쪽에 나열된 식들의 값을 하나하나 구해서 사후 확률을 구하는 것이다. $\frac{P(A|B) P(B)} {P(A)}$ 의 식에서 $P(A|B)$ 는 Likelihood Probability 라고 하며 우도라고도 한다. 수식에서 보이는 것처럼 A와 B가 바뀐 상황에서의 조건부 확률 값이다. P(B)는 Prior Probability로 사전 확률이라고 하며 B에 대한 확률분포를 의미한다. P(A)는 Evidence라고 하며 A에 대한 확률분포를 의미한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이런 식으로 식만 보고 이해하기는 힘드므로 예시를 들어보는 것이 이해하는데 훨씬 도움이 된다. 내가 누군가와 싸웠는데 그 사람이 먼저 내게 사과를 하였다고 가정해본다. 이때 그 사람은 정말 내게 미안해서 사과를 한 것인가 궁금하다. 이에 대해 확률로 표현해보면 P(미안함|사과)이다. 반대로 사과는 했지만 미안하지 않은 경우는 P(안 미안함|사과)이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;331&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9CFct/btqKAz5enDM/KlUi983MknajOPNHI6rDOK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9CFct/btqKAz5enDM/KlUi983MknajOPNHI6rDOK/img.jpg&quot; data-alt=&quot;사과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9CFct/btqKAz5enDM/KlUi983MknajOPNHI6rDOK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9CFct%2FbtqKAz5enDM%2FKlUi983MknajOPNHI6rDOK%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;331&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;사과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;추가로 통계 조사 결과 미안한 사람이 상대에게 사과를 줄 확률이 40%이고 미안하지 않은 사람이 상대에게 사과를 줄 확률이 30%라고 가정한다. 이는 각각 P(사과|미안함) = 40% , P(사과|안 미안함) = 30%로 likelihood를 나타낸다. Posterior를 추정해보려고 하는데 Prior를 알지 못하므로 추정을 해보려고 한다. Prior는 싸웠을 때 미안해하는 사람에 대한 분포이다. 아마 사람이라면(?) 미안해할 확률이 높지 않을까 가정하여 70%라고 추정해본다. 이를 그림으로 나타내면 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/STuRh/btqLRUOOPSR/4Ls3qsb6ntUh9511AVq8DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/STuRh/btqLRUOOPSR/4Ls3qsb6ntUh9511AVq8DK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/STuRh/btqLRUOOPSR/4Ls3qsb6ntUh9511AVq8DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSTuRh%2FbtqLRUOOPSR%2F4Ls3qsb6ntUh9511AVq8DK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;즉, 우리가 구하는 Posterior &lt;span style=&quot;color: #333333;&quot;&gt;P(미안함|사과)&lt;/span&gt;는 $\frac {P(사과|미안함) * P(미안함)} {P(사과)} = \frac{0.28} {0.28+0.09} = 75 $% 가 된다.&amp;nbsp; 반대로 &lt;span style=&quot;color: #333333;&quot;&gt;Posterior&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;P(안 미안함|사과) = $\frac{0.09} {0.28 + 0.09} = 24$% 가 된다. 그러므로 &lt;span style=&quot;color: #333333;&quot;&gt;Maximum-A-Posterior(MAP)는 사과를 한 사람이 미안해한다고 결론 내린다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;만약 Prior를 가정하기 힘든 경우에는 &lt;span style=&quot;color: #333333;&quot;&gt;Maximum-Likelihood(ML)를 구해야 한다. 이는 간접적으로 더 높은 확률을 찾는 것으로 위의 경우에서는 &lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;P(사과|미안함) = 40% , P(사과|안 미안함) = 30%&lt;span&gt; 이다. 따라서 MAP와 마찬가지로 사과를 한 사람이 미안해한다고 결론지을 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 하지만 이 방법은 정확하지 않으며 Prior 확률이 같다는 가정을 하여 근사적 해를 구하는 것이다.&lt;/p&gt;
&lt;p&gt;MAP가 더 정확한 방법이지만 Prior Probability를 알거나 구해야 하므로 ML을 사용하는 게 더 나을 수 있다. 실제 Neural Network나 머신러닝을 사용하여 학습을 시킬 때는 보통 ML을 이용한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/베이지안</category>
      <category>딥러닝</category>
      <category>베이지안</category>
      <category>우도추정</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/20</guid>
      <comments>https://simpling.tistory.com/20#entry20comment</comments>
      <pubDate>Sun, 11 Oct 2020 16:14:28 +0900</pubDate>
    </item>
    <item>
      <title>Tensorflow&amp;amp;Keras - LSTM 개념 및 사용법 정리</title>
      <link>https://simpling.tistory.com/19</link>
      <description>&lt;p&gt;&amp;nbsp; LSTM 은 Long Short Term Memory의 줄임말로 주로 시계열 처리나 자연어 처리(현재는 잘 사용 안 하지만)를 사용하는 데 사용한다. LSTM을 처음 배울 때 헷갈렸던 것은 데이터의 '순환'에 대한 개념이었다. 흔히 아래와 같은 그림으로 LSTM을 나타낸다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;273&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y8CYQ/btqFhMPmfrt/Fd98EunokYbiiKkuVpsUG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y8CYQ/btqFhMPmfrt/Fd98EunokYbiiKkuVpsUG0/img.png&quot; data-alt=&quot;순환 신경망&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y8CYQ/btqFhMPmfrt/Fd98EunokYbiiKkuVpsUG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy8CYQ%2FbtqFhMPmfrt%2FFd98EunokYbiiKkuVpsUG0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;273&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;순환 신경망&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Input으로 x가 들어가면 여러번의 순환을 거쳐 output인 y가 나오는 구조이다. 이때 h는 그 중간다리 역할을 하는데 hidden state라고 한다. 위의 구조를 펼쳐서 보면 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6HAY5/btqFgxlkE6g/Qyg0QDrVZA4mlO6SvypXkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6HAY5/btqFgxlkE6g/Qyg0QDrVZA4mlO6SvypXkk/img.png&quot; data-alt=&quot;순환신경망을 펼쳐 보았을 때&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6HAY5/btqFgxlkE6g/Qyg0QDrVZA4mlO6SvypXkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6HAY5%2FbtqFgxlkE6g%2FQyg0QDrVZA4mlO6SvypXkk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;순환신경망을 펼쳐 보았을 때&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; Input 데이터인 x는 Sequence를 가지는 데이터가 되는데 위의 경우는 길이가 6인 데이터이기 때문에 총 6번의 input이 들어가게 된다.(예를 들면 단어가 6개인 문장) RNN 사이에 있는 화살표는 hidden state의 전달을 표현한다. 최종적으로 y값이 나오는 데는 hidden state와 연속적인 x의 입력에 의해 결정되게 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이런 모델의 구조는 사람의 기억과 이해 메커니즘을 연상케한다. 예를 들어&amp;nbsp; 어떤 글을 읽는다고 해보자. 우리는 한 단어를 읽을 때마다 이전 단어들을 읽으면서 이해했던 내용과 새로운 단어의 이해를 잘 조합하여 새로운 결론을 내게 된다. 이때 단어들이 x이고 단어들을 읽으면서 나오는 새로운 결론이 hidden state가 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; RNN은 보통 LSTM이나 GRU를 사용한다. LSTM은 input값을 받으면 hidden state와 cell state를 가지게 된다. cell state는 LSTM이 굴러가게 하는데 일종의 체인역할을 하며 기억을 오랫동안 유지할 수 있는 구조로 되어있다. hidden state는 위의 설명처럼 계층의 출력이 되며 다음 타임 스텝으로 정보를 넘기게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dEDkVL/btqFiOMKx6P/kiQIQ2Qlr5gBjGyNO6lWrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dEDkVL/btqFiOMKx6P/kiQIQ2Qlr5gBjGyNO6lWrk/img.png&quot; data-alt=&quot;LSTM 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dEDkVL/btqFiOMKx6P/kiQIQ2Qlr5gBjGyNO6lWrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdEDkVL%2FbtqFiOMKx6P%2FkiQIQ2Qlr5gBjGyNO6lWrk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;LSTM 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;Tensorflow에서 LSTM으로 cell state와 hidden state에 대한 출력을 바꾸는 변수로는 return_state와 return_sequences이다. 두 개의 변수는 boolean의 형태로 주어지게 되며 둘 다 false일 경우 아래와 같이 마지막 결괏값(마지막 hidden state) 값만 출력하게 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593596520923&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# lstm을 그냥 쓸 경우 최종 결과값만 도출한다.
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import LSTM
from numpy import array

inputs1 = Input(shape=(3, 1))
lstm1 = LSTM(1)(inputs1)
model = Model(inputs=inputs1, outputs=lstm1)

data = array([0.1, 0.2, 0.3]).reshape((1,3,1))

print(model.predict(data)) # [[0.04836999]]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; return_sequences = True로 설정할 경우 각 time step별 hidden state를 모두 출력하게 된다. 예를들어 위의 예시에서 처럼 길이가 6인 경우에는 총 6개의 hidden state값이 모두 나오는 것이다. 이렇게 출력을 하는 것은 보통 Attention을 사용하기 위함이다.&lt;/p&gt;
&lt;pre id=&quot;code_1593596668845&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# return_sequences = True를 한 경우에는 각 time step별 hidden state들이 출력된다.
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import LSTM
from numpy import array

inputs1 = Input(shape=(3, 1))
lstm1 = LSTM(1, return_sequences=True)(inputs1)
model = Model(inputs=inputs1, outputs=lstm1)

data = array([0.1, 0.2, 0.3]).reshape((1,3,1))

print(model.predict(data)) 
# [[[0.01184901]
#  [0.03267556]
#  [0.05920978]]]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp; return_state = True 를 한 경우에는 마지막 time step에서의 output(hidden state), hidden state와 cell state가 출력된다. 즉 마지막 output값이 2번 출력이 되고 cell state가 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593596819599&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# return_state = True 를 한 경우에는 마지막 time step에서의 output(hidden state),hidden state와 cell state가 출력된다.
# 즉 같은 값이 2번 출력된다.
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import LSTM
from numpy import array

inputs1 = Input(shape=(3, 1))
lstm1, state_h, state_c = LSTM(1, return_state=True)(inputs1)
model = Model(inputs=inputs1, outputs=[lstm1, state_h, state_c])

data = array([0.1, 0.2, 0.3]).reshape((1,3,1))

print(model.predict(data))
# [array([[0.00329698]], dtype=float32), array([[0.00329698]], dtype=float32), array([[0.00614673]], dtype=float32)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp; return_sequences와 return_state를 모두 True로 하게 되면 각 time step별 hidden state와 마지막 hidden state, 마지막 cell state 값이 출력된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1593596999073&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# return_sequences와 return_state 모두 True로 하게 되면 각 time step별 hidden state와 마지막 hidden state, 마지막 cell state 값이 출력된다.
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import LSTM
from numpy import array
# define model
inputs1 = Input(shape=(3, 1))
lstm1, state_h, state_c = LSTM(1, return_sequences=True, return_state=True)(inputs1)
model = Model(inputs=inputs1, outputs=[lstm1, state_h, state_c])
# define input data
data = array([0.1, 0.2, 0.3]).reshape((1,3,1))
# make and show prediction
print(model.predict(data))
#[array([[[0.01530219],
#        [0.04227088],
#        [0.07738266]]], dtype=float32), array([[0.07738266]], dtype=float32), array([[0.14669698]], dtype=float32)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; LSTM을 각 타임 스텝별로 분리해서 넣어주는 경우가 있을 수 있다. 그럴 때는 initial_state를 사용해야 한다.&lt;/p&gt;
&lt;p&gt;전체 sequence길이가 T이고 feature가 n이면 LSTM에 하나의 타임 스텝별로 넣기 때문에 input shape이 batch,1,n이 된다. 이런 식으로 T번 반복하여 넣으면 되는데 기존의 hidden state와 cell state를 전달해줘야 하므로 initial_state를 사용한다. 코드로 나타내면 다음과 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1605784886488&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class CustomLstm(keras.layers.Layer):
    def __init__(self):
        super(CustomLstm, self).__init__()
        self.initial_state = None
        self.lstm = LSTM(units, return_state=True,dropout=0.3)

    def call(self, data, training=False):
        for t in range(maxlen):
            # my hope: input_t = inputs[i, t, :]
            input_t = data[:, t, :]  # (batch,n)
            input_t = tf.expand_dims(input_t, 1)  # (batch,1,n)
            output_t, h, c = self.lstm(
                input_t, initial_state=self.initial_state, training=training)
            self.initial_state = h, c # 여기서 다음에 들어갈 initial state를 저장해 놓음.
            states.append(self.state)
            outputs.append(output_t) # 이렇게 모든 hidden state를 얻어서 반환할 수 있다.
        return states, outputs&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/Tensorflow&amp;amp;keras</category>
      <category>LSTM</category>
      <category>TensorFlow</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/19</guid>
      <comments>https://simpling.tistory.com/19#entry19comment</comments>
      <pubDate>Wed, 1 Jul 2020 18:50:37 +0900</pubDate>
    </item>
    <item>
      <title>Tensorflow - 다중 클래스 학습 평가 이론 및 구현</title>
      <link>https://simpling.tistory.com/18</link>
      <description>&lt;p&gt;&amp;nbsp; Classification을 할 때 평가에 Precision이나 Recall 등이 필요할 때가 있다. Binary는 바로 지원이 되어 사용하면 되지만 &lt;span style=&quot;color: #333333;&quot;&gt;Multi class의 경우는 따로 구현이 필요하다. 그에대한 Custom 함수를 &lt;a href=&quot;https://tykimos.github.io/2017/09/24/Custom_Metric/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;김태영님의 블로그&lt;/a&gt;를 참고하여 Tensorflow 2.2 version으로 만들어 보았다. 모든 구현은 Label이 One-hot 형태가 아닌 int형 데이터일 때를 가정하였다. One-hot인 경우는 추가적으로 argmax를 해주는 과정이 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCDYA1/btqFbCsIW33/3kWZIQZQR3WE0TPo6WZVZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCDYA1/btqFbCsIW33/3kWZIQZQR3WE0TPo6WZVZK/img.png&quot; data-alt=&quot;Binary Data&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCDYA1/btqFbCsIW33/3kWZIQZQR3WE0TPo6WZVZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCDYA1%2FbtqFbCsIW33%2F3kWZIQZQR3WE0TPo6WZVZK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Binary Data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 위와 같은 Binary + Imbalanced Data 가 있을 때 , 모델이 예측치로 모두 파란색 공을 뽑아내면 제대로 학습이 되지 않았음에도 정확도가 80%가 나오게 된다. 따라서 Recall이나 Precision의 평가방법이 필요하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzRdB/btqFcvmlWff/uG68YAgNxFodsjDrdkJVek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzRdB/btqFcvmlWff/uG68YAgNxFodsjDrdkJVek/img.png&quot; data-alt=&quot;노란색공을 양성이라 가정하며 모델이 위의 결과가 노란색공일 것이라고 예측한 것을 의미한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzRdB/btqFcvmlWff/uG68YAgNxFodsjDrdkJVek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkzRdB%2FbtqFcvmlWff%2FuG68YAgNxFodsjDrdkJVek%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;노란색공을 양성이라 가정하며 모델이 위의 결과가 노란색공일 것이라고 예측한 것을 의미한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Recall 같은 경우는 Imbalanced data에서 위와 같이 양성(노란색 공) 판정을 했을 때 아래의 그림과 같이 $ \frac{검출 양성 수} {전체 양성 수} =&amp;nbsp; \frac {1} {2}$ 이 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$(\frac{TP} {TP+FN})$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cd96Ve/btqFbldGPGu/OTAOA29zZWPzDxJf8krbxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cd96Ve/btqFbldGPGu/OTAOA29zZWPzDxJf8krbxK/img.png&quot; data-alt=&quot;검출 양성 수 / 전체 양성 수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cd96Ve/btqFbldGPGu/OTAOA29zZWPzDxJf8krbxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcd96Ve%2FbtqFbldGPGu%2FOTAOA29zZWPzDxJf8krbxK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;검출 양성 수 / 전체 양성 수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1593318336896&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 특정 클래스에 대한 재현율(TP/(TP+FN))
def single_class_recall(interesting_class_id):
    def recall(y_true, y_pred):
        class_id_true = tf.cast(y_true, tf.int64)
        class_id_pred = tf.math.argmax(y_pred, axis=-1)
        # 전체 양성수
        recall_mask = tf.cast(
            tf.math.equal(class_id_true, interesting_class_id), &quot;int32&quot;
        )
        # 검출 양성수
        class_recall_tensor = (
            tf.cast(tf.math.equal(class_id_true, class_id_pred), &quot;int32&quot;) * recall_mask
        )
        # 검출 양성수/전체 양성수
        class_recall = tf.cast(
            tf.math.reduce_sum(class_recall_tensor), &quot;float32&quot;
        ) / tf.cast(tf.math.maximum(tf.math.reduce_sum(recall_mask), 1), &quot;float32&quot;)
        return class_recall

    return recall&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Precision 은 아래 그림과 같이 $ \frac {실제 양성 수} {양성이라고 판정한 수} = \frac {1} {3} $ 이 된다.&lt;/p&gt;
&lt;p&gt;$(\frac{TP} {TP+FP})$&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTQodA/btqFaUgw9vk/5xPJbke3WeC4bCphvboCO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTQodA/btqFaUgw9vk/5xPJbke3WeC4bCphvboCO1/img.png&quot; data-alt=&quot;(판정한 것 중)실제 양성 수 / 양성이라고 판정한 수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTQodA/btqFaUgw9vk/5xPJbke3WeC4bCphvboCO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTQodA%2FbtqFaUgw9vk%2F5xPJbke3WeC4bCphvboCO1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;(판정한 것 중)실제 양성 수 / 양성이라고 판정한 수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1593318400019&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 특정 클래스에 대한 정밀도(TP/(TP+FP))
def single_class_precision(interesting_class_id):
    def prec(y_true, y_pred):
        class_id_true = tf.cast(y_true, tf.int64)
        class_id_pred = tf.math.argmax(y_pred, axis=-1)
        # 양성이라고 판정한 수(TP+FP)
        precision_mask = tf.cast(
            tf.math.equal(class_id_pred, interesting_class_id), &quot;int32&quot;
        )
        # 예측값중 실제 양성수(TP)
        class_prec_tensor = (
            tf.cast(tf.math.equal(class_id_true, class_id_pred), &quot;int32&quot;)
            * precision_mask
        )
        # 실제 양성수 / 양성이라고 판정한 수
        class_prec = tf.cast(
            tf.math.reduce_sum(class_prec_tensor), &quot;float32&quot;
        ) / tf.cast(tf.math.maximum(tf.math.reduce_sum(precision_mask), 1), &quot;float32&quot;)
        return class_prec

    return prec
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Recall이나 Precision 뿐만 아니라 F1Score 나 Critical Success Index (CSI) 도 사용할 때가 많은데 F1Score는 단순히&amp;nbsp;&lt;/p&gt;
&lt;p&gt;$ \frac {2*recall*precision} {recall+precision} $ 값이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;CSI는 아래 그림과 같이 $ \frac {검출 양성 수} {전체 양성 수 + 양성이라고 판정한 수} = \frac {1} {4} $&lt;span style=&quot;color: #333333;&quot;&gt;가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$(\frac{TP} {TP+FP+FN})$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJRzUZ/btqFaNWgOFg/PuSbLHKDEox7H0YlUcerT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJRzUZ/btqFaNWgOFg/PuSbLHKDEox7H0YlUcerT1/img.png&quot; data-alt=&quot;검출 양성 수 / (전체 양성 수 + 양성이라고 판정한 수)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJRzUZ/btqFaNWgOFg/PuSbLHKDEox7H0YlUcerT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJRzUZ%2FbtqFaNWgOFg%2FPuSbLHKDEox7H0YlUcerT1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;검출 양성 수 / (전체 양성 수 + 양성이라고 판정한 수)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1593318422374&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# critical success index - TP/(TP+FP+FN)
def single_class_csi(interesting_class_id):
    def csi(y_true, y_pred):
        class_id_true = tf.cast(y_true, tf.int64)
        class_id_pred = tf.math.argmax(y_pred, axis=-1)
        # 전체 양성수(TP+FN)
        real_positive = tf.cast(
            tf.math.equal(class_id_true, interesting_class_id), &quot;int32&quot;
        )
        # 양성이라고 판정한 수(TP+FP)
        pred_positive = tf.cast(
            tf.math.equal(class_id_pred, interesting_class_id), &quot;int32&quot;
        )
        # 검출 양성수(TP)
        true_positive = (
            tf.cast(tf.math.equal(class_id_true, class_id_pred), &quot;int32&quot;)
            * real_positive
        )
        tp_fp_fn = real_positive + pred_positive - true_positive
        # 검출 양성수/전체 양성수
        class_csi = tf.cast(tf.math.reduce_sum(true_positive), &quot;float32&quot;) / tf.cast(
            tf.math.maximum(tf.math.reduce_sum(tp_fp_fn), 1), &quot;float32&quot;
        )
        return class_csi

    return csi&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/Tensorflow&amp;amp;keras</category>
      <category>CSI</category>
      <category>Precision</category>
      <category>Recall</category>
      <category>학습평가</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/18</guid>
      <comments>https://simpling.tistory.com/18#entry18comment</comments>
      <pubDate>Sun, 28 Jun 2020 13:29:52 +0900</pubDate>
    </item>
    <item>
      <title>Auto Encoder란? - Manifold와 차원 축소</title>
      <link>https://simpling.tistory.com/16</link>
      <description>&lt;p&gt;&amp;nbsp; 이번 글에서는 Auto Encoder를 공부하면서 익힌 내용들을 정리한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; Auto Encoder는 Encoder와 Decoder의 구조로 되어있는데 PCA와 같은 차원 축소가 그 목적이었다. 그러므로 사실 핵심은 Encoder에서 Latent variable을 생성하는 것에 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C70FB/btqC48sUqT7/J1RffjoOR1LrHsCRfNrnkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C70FB/btqC48sUqT7/J1RffjoOR1LrHsCRfNrnkK/img.png&quot; data-alt=&quot;Auto-Encoder 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C70FB/btqC48sUqT7/J1RffjoOR1LrHsCRfNrnkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC70FB%2FbtqC48sUqT7%2FJ1RffjoOR1LrHsCRfNrnkK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Auto-Encoder 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; Latent Variable은 Input으로 넣은 Data의 차원을 축소시켜서 만든 벡터인데 언뜻 생각했을 때 정보가 많이 손실돼서 안 좋은 거 아닌가?라고 생각할 수 있다. 이를 이해하기 위해 차원의 저주를 먼저 알 필요가 있다.&lt;/p&gt;
&lt;p&gt;차원의 저주는 Data의 개수는 별로 없는데 이를 설명하려고 하는 변수의 차원은 클 때 일어난다. 예를 들어 데이터가 5개밖에 없는데 이를 설명하려는 길이 10인 벡터를 갖는 Parameter 개수가 1개(1-D), 2개(2-D), 3개(3-D) 일 때, 각각 $\frac{데이터}{차원}$과 차원에 대한 데이터 밀도값을 계산해보면 $\frac{5}{10^{1}}=50$%, $\frac{5}{10^{2}}=5$%, $\frac{5}{10^{3}}=0.5$%가 된다. 즉, 차원이 늘어갈수록 사용하는 공간대비 아는 정보에 대한 밀도가 희박해진다. 따라서 차원이 증가할수록 데이터 분석에 필요한 데이터 수가 기하급수적으로 늘어나게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이제, Mnist의 숫자 이미지를 생각해 볼 때, 이미지 크기가 28*28이므로 그것을 설명하는 파라미터는 784개이다. 그렇다면 임의의 분포로 각 픽셀에 데이터를 뿌릴 때 경우의 수는 굉장히 많을 테지만 한번쯤은 Mnist 데이터와 비슷한 숫자 이미지가 나오지 않을까?라고 생각할 수 있다. 하지만 꽤 많이 실행해봐도 Noise 가득한 형체 없는 이미지만이 나올 뿐이다. 여기서 가정을 할 수 있는데, 우리가 알고 있는 깨끗한 이미지들은 Normal하게 분포하지 않고 Dense 한 어떤 특정한 지역에 분포한다는 것이다. 그렇다면 우리는 Random 하게 그런 이미지들을 찾기가 힘들 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 위의 두 설명을 결합하면 Manifold 가정을 이끌어 낼 수 있다. 고차원의 데이터 밀도는 낮지만 이들의 집합을 포함하는 저차원의 SubSpace가 있다는 것이다. 그리고 이 저차원의 Manifold를 벗어나는 순간부터 급격히 밀도가 낮아져 이미지를 잘 설명하지 못하게 된다.&lt;/p&gt;
&lt;p&gt;(참고로 Manifold는 고차원의 데이터를 저차원으로 옮길 때 데이터를 잘 설명하는 집합의 모형이다. 또한 높은 차원에서 낮은 차원으로 변환하는 것을 Embedding 이라고 하며 그것에 대한 학습 과정을 Manifold Learning이라고 한다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 그러므로 Encoder에서는 Mainfold 가정을 통해 Input Data의 고차원 데이터는 희박한 밀도를 가지고 있으므로 저차원의 데이터로 만들어서 원래의 데이터를 잘 설명하는 Manifold를 찾는 것이 목적이다. 그렇다면 Decoder는 왜 존재하는가? 그 이유는 Decoder로 Latent Variable을 원래의 Data로 만들어 주게 되면 Label로 다시 input data를 사용할 수 있으므로 지도 학습이 가능해지기 때문이다. 지금은 Auto Encoder가 생성 모델로도 쓰이고 Denoising으로도 사용이 되는데 괜찮은 성능을 보인다.&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <category>auto encoder</category>
      <category>manifold</category>
      <category>차원축소</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/16</guid>
      <comments>https://simpling.tistory.com/16#entry16comment</comments>
      <pubDate>Sun, 29 Mar 2020 20:20:51 +0900</pubDate>
    </item>
    <item>
      <title>Mean Squared Error  VS  Cross Entropy Error</title>
      <link>https://simpling.tistory.com/15</link>
      <description>&lt;p&gt;DNN에서 Loss Function을 사용할 때 아래의 2가지 가정에 적합해야 한다.&lt;/p&gt;
&lt;p&gt;1) Train data에서의 Loss 총합은 개별 데이터 Loss의 합과 같아야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;$$L(\theta_{k}, D) = \sum_{i}L(\theta_{k} ,D_{i})$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;2) DNN 출력 값으로 Loss를 계산한다. (중간 단계에서의 값으로는 계산하지 않음.)&lt;/p&gt;
&lt;p&gt;$$\bigtriangledown L(\theta_{k},D) = \sum_{i}\bigtriangledown L(\theta_{k}, D_{i})$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Mean Squared Error(MSE)와 Cross Entropy Error(CEE)를 Loss Function으로 많이 사용하는 이유는 위의 두 조건을 만족하는 대표적 함수이기 때문이다. 이번 글에서 두 함수의 차이를 알아볼 것이고 각각 Regression, Classification에 적합함을 보일 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;각각의 Loss function 식은 다음과 같다. $$MSE=\frac {1} {n} \sum_{i}^{n} \frac {1} {2} (y_{i}-\tilde{y}_{i})^{2}$$&lt;/p&gt;
&lt;p&gt;$$CEE=-\sum_{i}y_{i}log(\tilde{y}_{i})$$&lt;/p&gt;
&lt;p&gt;(&lt;span style=&quot;color: #333333;&quot;&gt;$y_{i}$&lt;/span&gt;는 학습 데이터 정답의 i번째 요소, $\tilde{y}_{i}$는 학습 데이터 입력에 대한 예측값의 i번째 요소)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp; MSE의 경우는 식이 정답에서 예측한 값을 빼는 것으로 되어있어 직관적 이해가 쉽다. 하지만 CEE는 그렇지 않으므로 잠깐 알아보겠다. Cross Entropy에서 Entropy는 물리학을 배울 때 자주 나오는 단어인데 불확실성의 정도를 가리킨다. 그러므로 우리가 예측하기 힘들면 힘들수록 Entropy값은 커진다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 예를 들어, 국회의원 선거를 하는데 A후보와 B후보가 있다고 생각해보자. A후보의 지지율은 90%이고 B후보의 지지율이 10%라고 할 때,&lt;/p&gt;
&lt;p&gt;A후보가 이기는 경우: -log(P(A)) = -log(0.9) = 0.05&lt;/p&gt;
&lt;p&gt;B후보가 이기는 경우: -log(P(B)) = -log(0.1) = 1.0이다.&lt;/p&gt;
&lt;p&gt;Entropy는 놀람의 정보의 평균이므로 0.9*&lt;span style=&quot;color: #333333;&quot;&gt;0.05&lt;/span&gt;+ 0.1*&lt;span style=&quot;color: #333333;&quot;&gt;1.0&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;= 0.15이다.&lt;/p&gt;
&lt;p&gt;이번에는 A후보와 B후보의 지지율이 50:50이라고 생각해보겠다. 이때 각 후보의 Entropy는 0.30이다. 이때의 Entropy는 0.5*0.3 + 0.5*0.3 =&amp;nbsp; 0.3이다.&lt;/p&gt;
&lt;p&gt;계산 결과에서 보이듯 위에서 구한 값보다 아래의 경우가 Entropy가 더 높다. 즉, 확률 값이 비슷하여 예측이 힘들 때(결과가 불확실할 때) Entropy가 높게 나온다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;310&quot; height=&quot;217&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tVDH8/btqC21HQ8Nq/5AMtRG6aij9RrJKHhdWMP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tVDH8/btqC21HQ8Nq/5AMtRG6aij9RrJKHhdWMP0/img.png&quot; data-alt=&quot;손실의 정도를 구할 때 log를 사용하였으므로 $\tilde{y}_{i}$가 정답일 확률이 0에 가까울수록 Error값이 커지게 되고 1에 가까울수록 0에 가깝게 나타난다.&amp;amp;amp;nbsp;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tVDH8/btqC21HQ8Nq/5AMtRG6aij9RrJKHhdWMP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtVDH8%2FbtqC21HQ8Nq%2F5AMtRG6aij9RrJKHhdWMP0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;310&quot; height=&quot;217&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;손실의 정도를 구할 때 log를 사용하였으므로 $\tilde{y}_{i}$가 정답일 확률이 0에 가까울수록 Error값이 커지게 되고 1에 가까울수록 0에 가깝게 나타난다.&amp;nbsp;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; 한편, Classification을 수행하는 모델에서 CEE는 정답인&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt; 클래스에 대해서 오차를 계산한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;오차를 내는 과정에서 정답 클래스만 비교하지만, 다중 클래스 분류의 활성 함수인 softmax로 인해 다른 클래스에 대한 학습에도 영향을 준다. 위의 국회의원 예시처럼 각각의 -log(P(x)) 를 구하여 더하여 Error를 구해주는데 $\tilde{y}_{i}$ 가 0에 가까우면 가까울수록 Error는 기하급수로 커지게 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp; 두 손실 함수의 차이는 BackPropagation을 사용할 때 Loss Function에 대한 Activation Function의 미분 값을 사용하느냐에서도 나타난다. MSE의 경우 $\bigtriangledown_{a} C \odot \sigma'(Z^{L})$ 로 구하는데 CEE는 &lt;span style=&quot;color: #333333;&quot;&gt;$\sigma'(Z^{L})$항을 사용하지 않아 역전파시 기울기 손실이 덜하며 속도도 더 빠르다. 그러므로 &lt;b&gt;CEE는 역전파에 유리&lt;/b&gt;한 함수라고 할 수 있다. (하지만 중간 Layer에서는 활성 함수에 대한 미분 값을 사용하므로 결국 Gradient Vanishing이 일어나게 된다.)&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; Maximum-Likelihood의 관점에서 모델의 학습을 생각하면 정확한 $y$값을 찾는 것보다 &lt;span style=&quot;color: #333333;&quot;&gt;$y$를 평균으로 하는 분포에 의한 파라미터(평균, 표준편차)를 찾는다고 생각할 수 있다. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이때, 2가지 가정을 하는데 다음과 같다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;1) 모든 데이터가 각각 독립적이다.&amp;nbsp; &amp;nbsp;$P(y|f_{\theta}(x)) = \prod_{i}P_{D_{i}}(y|f_{\theta}(x_{i})$&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2) 각각의 데이터가 동일한 분포를 가진다. (ex) Gaussian분포 등등)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; x는 관측된 데이터로 고정되어 있고 y를 가장 잘 설명하는 파라미터 $\theta$ 를 찾고자 하는 것이므로 $\underset{\theta}{argmax} P(y|f_{\theta}(x))$로 나타낼 수 있다. 확률값은 0~1 사이의 값을 가지므로 계속해서 곱하면 빠르게 0으로 수렴하게 된다. 따라서 log를 사용하는데 log 특성상 곱이 덧셈으로 바뀌게 된다. 이렇게 되면 위에서 설명한 Loss function의 조건을 만족시키게 된다. 또한 모델 최적화를 할 때 Maximum을 구하는 것보다 Minimize를 많이 사용하므로 Negative-Likelihood를 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;$$Loss = -log \prod_{i}(P(y_{i}|f_{\theta}(x_{i})))&amp;nbsp; =&amp;gt;&amp;nbsp; -\sum_{i}log(P(y_{i}|f_{\theta}(x_{i})))$$&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;이때, Gaussian 분포와 Bernoulli 분포에 대한 수식을 다음과 같이 유도할 수 있다.&lt;/p&gt;
&lt;p&gt;$$ Gaussian-distribution $$&lt;/p&gt;
&lt;p&gt;$$ f_{\theta}(x_{i}) = \mu_{i} , \sigma_{i} = 1 $$&lt;/p&gt;
&lt;p&gt;$$ P(y_{i}|\mu_{i},\sigma_{i}) = \frac{1}{\sqrt{2\pi}\sigma_{i}}exp(-\frac{(y_{i}-\mu_{i})^2} {2\sigma_{i}^2}) $$&lt;/p&gt;
&lt;p&gt;$$ -log(P(y_{i}|\mu_{i})) \propto \frac{(y_{i}-\mu_{i})^2}{2} = \frac{(y_{i}-f_{\theta}(x_{i}))^2} {2}$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p&gt;$$ Bernoulli-distribution $$&lt;/p&gt;
&lt;p&gt;$$ f_{\theta}(x_{i}) = P_{i} $$&lt;/p&gt;
&lt;p&gt;$$ P(y_{i}|P_{i}) = P_{i}^{y_{i}}(1-P_{i})^{1-y_{i}} $$&lt;/p&gt;
&lt;p&gt;$$ -log(P(y_{i}|P_{i})) = - [y_{i} logP_{i}+(1-y_{i} log(1-P_{i})] $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 위 두식의 Loss는 각각 MSE , CEE 가 되는데 이에 따라 &lt;b&gt;연속적 분포를 갖는 데이터(Regression) 에는 MSE가 적합&lt;/b&gt;하고 &lt;b&gt;이산적 분포를 갖는 데이터(Classification) 에는 CEE가 적합&lt;/b&gt;하다고 생각할 수 있다. 하지만 딥러닝 특성상&lt;span style=&quot;color: #333333;&quot;&gt;(?)&lt;/span&gt; 반대의 결과도 나올 수 있으며 다른 Loss Function이 적합할 때도 많을 것이므로 처음 데이터를 사용할 때 참고하는 것이 좋을 것 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>머신러닝&amp;amp;딥러닝/기초정리</category>
      <category>CEE</category>
      <category>cross entropy</category>
      <category>Loss function</category>
      <category>MSE</category>
      <author>Like_Me</author>
      <guid isPermaLink="true">https://simpling.tistory.com/15</guid>
      <comments>https://simpling.tistory.com/15#entry15comment</comments>
      <pubDate>Sat, 28 Mar 2020 18:57:42 +0900</pubDate>
    </item>
  </channel>
</rss>