<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title></title>
    <link>https://eremo2002.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 6 Jul 2026 00:07:54 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>eremo2002</managingEditor>
    <item>
      <title>[2019 ICCV] Real Image Denoising With Feature Attention</title>
      <link>https://eremo2002.tistory.com/124</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://openaccess.thecvf.com/content_ICCV_2019/papers/Anwar_Real_Image_Denoising_With_Feature_Attention_ICCV_2019_paper.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://openaccess.thecvf.com/content_ICCV_2019/papers/Anwar_Real_Image_Denoising_With_Feature_Attention_ICCV_2019_paper.pdf&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Abstract&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Deep CNN은 공간적으로 invariant noise를 포함한 이미지에서 성능이 잘 나오지만 real noise에는 제한적이고 multiple stage 모델링이 필요하다.&lt;/li&gt;
&lt;li&gt;본 논문에서는 denoising 알고리즘의 practicability를 높이기 위해 RIDNet이라는 single-stage blind real image denoising network를 제안한다.&lt;/li&gt;
&lt;li&gt;RIDNet은 residual on residual structure 구조를 통해 low-frequency information이 잘 전달하고 channel attention을 적용하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미지를 획득하는 과정에서 noise corruption은 불가피하게 발생하고 이는 이미지의 visual quality를 저하시키기 때문에 이미지에서 noise 정보를 제거하는 것이 중요합니다. practical denoising 알고리즘이라면 noise의 표준편차 정보를 모르더라도 공간적으로 variant, invariant noise를 잘 처리할 수 있어야 합니다. 그러나 현재 SOTA 모델들의 경우 이러한 부분에서 거리가 있기에 practical denoising 알고리즘이라고 보기엔 무리가 있습니다. 따라서 저자는 synthetic noise나 real noise에 관계 없이 noise를 잘 처리할 수 있는 efficient single CNN 모델을 새롭게 제안합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여기서 synthetic noise는 AWGN를 의미합니다. 즉, synthetic noise는 잘 제거하지만 real noise를 제거하지 못하는 알고리즘은 practical 하다고 보기 어렵습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;본 논문의 주요 contribution은 다음과 같습니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;real image denoising을 위한 two-stage CNN 모델을 제안합니다. 단, one stage model만으로도 SOTA를 달성했습니다.&lt;/li&gt;
&lt;li&gt;denoising에서 feature attention을 처음으로 적용하였습니다.&lt;/li&gt;
&lt;li&gt;기존 모델들이 단순히 레이어를 연속적으로 쌓아 depth는 깊어지지만 성능향상엔 크게 도움이 안되었지만 저자는 module 수를 늘려 성능향상을 이끌어 냈습니다.&lt;/li&gt;
&lt;li&gt;synthetic image dataset, real image noise dataset에서 SOTA를 달성하였습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;CNN Denoiser&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;논문에서 제안하는 모델은 크게 3가지 module로 구성됩니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;feature extraction&lt;/li&gt;
&lt;li&gt;feature learning residual on the residual module&lt;/li&gt;
&lt;li&gt;reconstruction&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;463&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl631a/btrH2f71FGY/9s3emMkrJyEi1jLgDAqvYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl631a/btrH2f71FGY/9s3emMkrJyEi1jLgDAqvYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl631a/btrH2f71FGY/9s3emMkrJyEi1jLgDAqvYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl631a%2FbtrH2f71FGY%2F9s3emMkrJyEi1jLgDAqvYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;463&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;463&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;feature extraction module은 입력 이미지로부터 feature를 추출하는 첫 번째 conv layer를 의미합니다.&lt;/li&gt;
&lt;li&gt;feature extraction module에서 추출된 feature는 feature learning residual the residual module로 입력됩니다. feature learning residual the residual module은 논문에서 제안하는 enhancement attention module(EAM)이라고 보면 됩니다.&lt;/li&gt;
&lt;li&gt;EAM의 output은 reconstruction module로 입력되어 input image와 동일한 size의 output을 만들어냅니다.&lt;/li&gt;
&lt;li&gt;feature extraction, reconstruction이라는 나름대로 의미 있는(?) 네이밍을 사용했지만 실제론 그저 모델의 가장 첫번째 conv layer, 가장 마지막 conv layer를 의미합니다. 모델의 핵심은 EAM이라고 보면 될 것 같습니다.&lt;/li&gt;
&lt;li&gt;Loss 함수는 L1을 사용하였습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;123&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQQq9i/btrH0dczmuR/VzgisKe2CgT7XX6DtNXpRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQQq9i/btrH0dczmuR/VzgisKe2CgT7XX6DtNXpRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQQq9i/btrH0dczmuR/VzgisKe2CgT7XX6DtNXpRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQQq9i%2FbtrH0dczmuR%2FVzgisKe2CgT7XX6DtNXpRK%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;123&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;123&quot;/&gt;&lt;/span&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;&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;EAM에 대해서 좀 더 살펴보겠습니다.&lt;/li&gt;
&lt;li&gt;우선 아래 EAM에서 residual block이 여러 개 반복되는 걸 볼 수 있는데 이러한 residual on the residual architecture 구조를 통해 네트워크의 depth가 깊어지더라도 denoising 성능향상이 가능하다고 말합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mKyEI/btrH2glyVrS/215ySXMCwvMnLfr2JBffl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mKyEI/btrH2glyVrS/215ySXMCwvMnLfr2JBffl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mKyEI/btrH2glyVrS/215ySXMCwvMnLfr2JBffl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmKyEI%2FbtrH2glyVrS%2F215ySXMCwvMnLfr2JBffl1%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;953&quot; height=&quot;267&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;저자는 EAM의 first part를 merge-and-run unit이라고 부릅니다. (검은색 box로 표시된 부분) 여기서 input feature는 두 path로 나뉘어 입력되며 두 path에서 서로 다른 dilation을 적용하고 concat합니다. 이를 통해 object 크기에 robust하도록 receptive field를 다양하게 가져가겠다는 의도를 알 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bruNu3/btrH0QA3XRr/nheP2oRemcackE1JwwOjN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bruNu3/btrH0QA3XRr/nheP2oRemcackE1JwwOjN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bruNu3/btrH0QA3XRr/nheP2oRemcackE1JwwOjN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbruNu3%2FbtrH0QA3XRr%2FnheP2oRemcackE1JwwOjN1%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;953&quot; height=&quot;267&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이후 2개의 conv layer로 구성된 residual block으로 입력되고 이후 3개의 conv layer로 구성된 enhanced residual block으로 입력됩니다. (검은색 box로 표시한 부분)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;enhanced residual block의 마지막 conv layer는 1x1 conv를 사용하여 feature를 flatten하기 위해 사용한다고 말하는데 이 부분은 잘 이해가 되지 않았습니다. 원래 resnet의 residual block에서 1x1 conv를 사용하는 목적은 element-wise addition 연산이 가능하도록 channel size를 맞춰주는 용도로 사용하는데 RIDNet의 EAM 안에서 feature map의 channel size는 모두 같기 때문에 channel 크기를 맞춰주는 용도는 아닌 거 같고요. 개인적인 생각으로는 1x1 conv가 f.c layer와 비슷한 역할을 하기 때문에 channel attention을 사용하기 전에 channel axis에 따라 feature extraction을 한 번 더 수행하려는 목적이 아닌가 하는 생각이 듭니다. 정확한 의도는 잘 모르겠습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;385&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKFNbG/btrH1Akcv7u/wM22vPnQJZZErOJpmHSyr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKFNbG/btrH1Akcv7u/wM22vPnQJZZErOJpmHSyr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKFNbG/btrH1Akcv7u/wM22vPnQJZZErOJpmHSyr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKFNbG%2FbtrH1Akcv7u%2FwM22vPnQJZZErOJpmHSyr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;385&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;385&quot;/&gt;&lt;/span&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그림에서 볼 수 있는 것처럼 전체 아키텍처에서는 EAM을 4개만 사용합니다. 단순히 residual module을 반복하는 것만으로는 성능향상이 되지 않아 Long Skip Connection을 사용하게 됩니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;feature extractor module의 feature를 가져와서 final EAM output feature와 연결&lt;/li&gt;
&lt;li&gt;input image와 reconstruction module의 output feature를 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(input image + reconstruction module&amp;rsquo;s output feature)를 사용하는 이유는 denoised image를 학습하기 보다 residual(noise) 정보를 학습시키려는 의도이며 noise의 sparse representation으로 인해 original image를 학습시키는 것보다 더 빠른 학습이 가능하게 됩니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;denoised feature에 noisy image를 더해줌으로써 noise의 sparse representation을 의도함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1347&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vR8CZ/btrHZqp7r5G/OpV27qd5fakrhIkLkjKxn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vR8CZ/btrHZqp7r5G/OpV27qd5fakrhIkLkjKxn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vR8CZ/btrHZqp7r5G/OpV27qd5fakrhIkLkjKxn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvR8CZ%2FbtrHZqp7r5G%2FOpV27qd5fakrhIkLkjKxn1%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;1347&quot; height=&quot;267&quot; data-origin-width=&quot;1347&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;denoising method에서 channel feature는 equal 하게 처리되는 경우가 많은데 이는 적절하지 않다고 말합니다. 즉 이미지에 존재하는 핵심 content를 학습하기 위해 channel feature 사이의 relationship에 대한 attention을 부여합니다. channel attention은 다른 image recognition task에서도 많이 활용되는 기법입니다.&lt;/li&gt;
&lt;li&gt;일반적으로 이미지는 low-frequency region과 high-frequency region으로 구성되어 있는데 conv layer는 local information만 추출하므로 global contextual 정보를 추출하는 건 불리합니다. 따라서 global average pooling을 통해 이미지 전체에 대한 정보를 압축하고 복원하는 과정을 통해 channel dependency를 계산하여 input feature에 곱해줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbPIs3/btrH0cY1wUL/4UJA8fE0n9BBwkQmXx8VSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbPIs3/btrH0cY1wUL/4UJA8fE0n9BBwkQmXx8VSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbPIs3/btrH0cY1wUL/4UJA8fE0n9BBwkQmXx8VSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbPIs3%2FbtrH0cY1wUL%2F4UJA8fE0n9BBwkQmXx8VSK%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;689&quot; height=&quot;251&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Experiments&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정량적 지표를 몇 가지 살펴보겠습니다. 우선 논문에서 제안하는 LSC, SSC, LC, FA를 모두 사용했을 때 성능이 가장 높게 나왔습니다. (사실 사람이 구분하기엔 어려울정도의 미세한 차이가 아닐까 합니다..)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1676&quot; data-origin-height=&quot;315&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6YFgw/btrH0R070TW/zT6fL9a9aAhjJoEBtcTSvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6YFgw/btrH0R070TW/zT6fL9a9aAhjJoEBtcTSvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6YFgw/btrH0R070TW/zT6fL9a9aAhjJoEBtcTSvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6YFgw%2FbtrH0R070TW%2FzT6fL9a9aAhjJoEBtcTSvK%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;1676&quot; height=&quot;315&quot; data-origin-width=&quot;1676&quot; data-origin-height=&quot;315&quot;/&gt;&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Noise level이 좀 더 증가하더라도 기존 모델대비 향상된 성능을 보여줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1706&quot; data-origin-height=&quot;323&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DNn61/btrHZeXKp21/ZTtbXFD8RIMkApUOv8RBnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DNn61/btrHZeXKp21/ZTtbXFD8RIMkApUOv8RBnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DNn61/btrHZeXKp21/ZTtbXFD8RIMkApUOv8RBnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDNn61%2FbtrHZeXKp21%2FZTtbXFD8RIMkApUOv8RBnK%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;1706&quot; height=&quot;323&quot; data-origin-width=&quot;1706&quot; data-origin-height=&quot;323&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pMWEH/btrH1zZSVBn/zAlv5JxqmlxX7TIVHmmvxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pMWEH/btrH1zZSVBn/zAlv5JxqmlxX7TIVHmmvxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pMWEH/btrH1zZSVBn/zAlv5JxqmlxX7TIVHmmvxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpMWEH%2FbtrH1zZSVBn%2FzAlv5JxqmlxX7TIVHmmvxk%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;638&quot; height=&quot;465&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도자기의 윗부분 패턴은 다른 모델들에 비해 denoising도 잘 되고 패턴 복원도 잘 되었지만 아래쪽에 있는 지그재그 패턴은 아예 사라져버리는 문제가 있습니다. sigma 값을 좀 줄여서 약한 noise를 주면 패턴이 뭉게지지 않을 수도 있을 거 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEnZ8y/btrHZshdSUy/hcTHUUKfS7ytHFuRSkTEYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEnZ8y/btrHZshdSUy/hcTHUUKfS7ytHFuRSkTEYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEnZ8y/btrHZshdSUy/hcTHUUKfS7ytHFuRSkTEYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEnZ8y%2FbtrHZshdSUy%2FhcTHUUKfS7ytHFuRSkTEYK%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;747&quot; height=&quot;595&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&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;&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;&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;real-world noisy image의 경우 다른 모델들이 over-smoothing 되거나 별 주위에 있는 noise를 잘 제거하지 못하지만 RIDNet은 detail한 정보, structure 정보는 살리면서도 noise를 잘 제거한다고 하는데 저는 눈으로는 봐서는 잘 모르겠습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1691&quot; data-origin-height=&quot;645&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPkRaC/btrH0tsAGA2/GeVs0kkRxPspx1R6m5TBKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPkRaC/btrH0tsAGA2/GeVs0kkRxPspx1R6m5TBKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPkRaC/btrH0tsAGA2/GeVs0kkRxPspx1R6m5TBKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPkRaC%2FbtrH0tsAGA2%2FGeVs0kkRxPspx1R6m5TBKK%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;829&quot; height=&quot;316&quot; data-origin-width=&quot;1691&quot; data-origin-height=&quot;645&quot;/&gt;&lt;/span&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;&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 이미지는 그나마 잘 보이는 거 같습니다. 강아지 얼굴쪽에 있는 noise들이 다른 모델들에 비해 훨씬 잘 제거가 되었고 글러브 표면에 있는 noise 역시 잘 제거가 되었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;434&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caTPXR/btrH0OXxtmE/Z25cr3WLdHfFEuEKOrCESk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caTPXR/btrH0OXxtmE/Z25cr3WLdHfFEuEKOrCESk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caTPXR/btrH0OXxtmE/Z25cr3WLdHfFEuEKOrCESk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaTPXR%2FbtrH0OXxtmE%2FZ25cr3WLdHfFEuEKOrCESk%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;742&quot; height=&quot;395&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;434&quot;/&gt;&lt;/span&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;&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;본 논문에서는 synthetic noise, real-world noise를 제거하기 위한 새로운 CNN을 제안하였습니다. 논문에서 사용한 LSC, SSC, SC, CA 등의 테크닉을 통해 low-frequency 정보가 네트워크에 잘 전달될 수 있게 하였으며 EAM이라는 새로운 구조의 모듈을 제안한 것이 가장 핵심인 것 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ML &amp;amp; DL/Paper Review</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/124</guid>
      <comments>https://eremo2002.tistory.com/124#entry124comment</comments>
      <pubDate>Sat, 23 Jul 2022 00:07:17 +0900</pubDate>
    </item>
    <item>
      <title>numpy를 이용한 Convolution 2D 구현</title>
      <link>https://eremo2002.tistory.com/123</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;pytorch, tensorflow 등의 딥러닝 라이브러리를 사용하지 않고 딥러닝 모델을, backpropagation weight update까지 수행하는 파이프라인을 만들기 위해 필요한 내용들을 정리하고자 함&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;여기선 python numpy를 이용하여 Convolution 2D 연산을 수행하는 함수를 구현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;pytorch, tensorflow의 Conv2D를 보면 인자로 받는 값들이 굉장히 많은데 우선은 kernel, padding, stride 정도만 사용하기로 함&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;&amp;nbsp;&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;입력으로 사용할 (3, 5, 5) 크기의 numpy array를 생성한다. (channel-first format)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;output은 Conv2D 함수의 리턴 값으로 Conv2D 함수의 인자로는 image, out_channel, kernel, padding, strides를 받는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;image : 입력 array&lt;/li&gt;
&lt;li&gt;out_channels : output array의 채널 크기 = kernel 개수&lt;/li&gt;
&lt;li&gt;kernel : kernel 크기&lt;/li&gt;
&lt;li&gt;padding : zero-padding&lt;/li&gt;
&lt;li&gt;strides : strides&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1631551106132&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;image = np.random.random((3, 5, 5))
output = Conv2D(image, 6, (3, 3), padding=1, strides=1)

def Conv2D(image, out_channels, kernel, padding=0, strides=1):
	pass&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;output array의 사이즈를 계산하기 위해 입력 image의 channel, height, width 정보를 각 변수에 저장&lt;/li&gt;
&lt;li&gt;(image_channel, kernel[0], kernel[1]) 크기의 kernel을 생성한다. kernel의 channel은 입력 feature의 channel과 동일해야함&lt;/li&gt;
&lt;li&gt;convolution연산의 output 크기를 사전에 계산하여 해당 크기에 맞는 zero array를 생성해둔다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1631551410463&quot; class=&quot;python&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def Conv2D(image, out_channels, kernel, padding=0, strides=1):
    '''
    input = (C, H, W)
    kernel = (k, k)
    ouptput = (out_channels, output_height, output_width)
    '''
    image_channel, image_height, image_width = image.shape[0], image.shape[1], image.shape[2]

    kernel_channel, kernel_height, kernel_width = image_channel, kernel[0], kernel[1]
    kernel = np.random.random((image_channel, kernel_height, kernel_width))    
    
    output_height = int(((image_height - kernel_height + 2 * padding) / strides) + 1)
    output_width= int(((image_width - kernel_width + 2 * padding) / strides) + 1)
    output_channel = out_channel
    
    output = np.zeros((output_channels, output_height, output_width))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;zero padding을 사용하는 경우, zero padding이 추가된 사이즈에 해당하는 imagePadded를 생성&lt;/li&gt;
&lt;li&gt;imagePadded array에서 zero 값이 되어야 하는 부분을 제외한 나머지는 부분은 입력 image array의 값으로 할당&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1631551765030&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if padding != 0:
        imagePadded = np.zeros((image_channel, image_height + padding * 2, image_width + padding * 2))
        imagePadded[:, padding:(-1*padding), padding:(-1*padding)] = image&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;반복문을 통해 convolution 연산을 수행&lt;/li&gt;
&lt;li&gt;convolution feature map은 filter 개수만큼 생성되므로 channel 축까지 고려하여 3중 for문을 사용함&lt;/li&gt;
&lt;li&gt;한 필터마다 생성하는 convolution 결과를 output_per_channel에 저장하고 그 값을 output[z, :, :] = output_per_channel로 output array의 각 채널에 할당함&lt;/li&gt;
&lt;li&gt;sliding window 과정 중 연산 범위를 벗어나지 않도록 for문 내 if문 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1631551887764&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for z in range(0, output_channel):
        output_per_channel = np.zeros((output_height, output_width))
        
        for y in range(0, output_height):
            if (y*strides + kernel_height) &amp;lt;= imagePadded.shape[1]:

                for x in range(0, output_width):                
                    if (x*strides + kernel_width) &amp;lt;= imagePadded.shape[2]:
                        output_per_channel[y][x] = np.sum(imagePadded[:,
                                                               y*strides : y*strides + kernel_height,
                                                               x*strides : x*strides + kernel_width] * kernel).astype(np.float32)
        output[z, :, :] = output_per_channel&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실행 예제 코드
&lt;pre id=&quot;code_1631552348157&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;'''
impelement Convolution 2D using numpy

- used channel-first format =&amp;gt; (Channel, Height, Width)

references
https://datascience-enthusiast.com/DL/Convolution_model_Step_by_Stepv2.html
https://medium.com/analytics-vidhya/2d-convolution-using-python-numpy-43442ff5f381
'''

import numpy as np
np.set_printoptions(linewidth=np.inf)

def Conv2D(image, out_channels, kernel, padding=0, strides=1):
    '''
    input = (C, H, W)
    kernel = (k, k)
    ouptput = (out_channels, output_height, output_width)
    '''
    image_channel, image_height, image_width = image.shape[0], image.shape[1], image.shape[2]

    kernel_channel, kernel_height, kernel_width = image_channel, kernel[0], kernel[1]
    kernel = np.random.random((image_channel, kernel_height, kernel_width))    
    
    output_height = int(((image_height - kernel_height + 2 * padding) / strides) + 1)
    output_width= int(((image_width - kernel_width + 2 * padding) / strides) + 1)
    output_channel = out_channels
    
    output = np.zeros((output_channel, output_height, output_width))

    # create zero-padded input
    if padding != 0:
        imagePadded = np.zeros((image_channel, image_height + padding * 2, image_width + padding * 2))
        imagePadded[:, padding:(-1*padding), padding:(-1*padding)] = image
    
    print('='*50)
    print('imagePadded')
    print(f'imagepadded shape : {imagePadded.shape}')
    print(imagePadded)

    # convolution 2D
    for z in range(0, output_channel):
        output_per_channel = np.zeros((output_height, output_width))
        
        for y in range(0, output_height):
            if (y*strides + kernel_height) &amp;lt;= imagePadded.shape[1]:

                for x in range(0, output_width):                
                    if (x*strides + kernel_width) &amp;lt;= imagePadded.shape[2]:
                        output_per_channel[y][x] = np.sum(imagePadded[:,
                                                               y*strides : y*strides + kernel_height,
                                                               x*strides : x*strides + kernel_width] * kernel).astype(np.float32)
        output[z, :, :] = output_per_channel
    
    print('='*50)
    print('output')
    print(f'output shape : {output.shape}')
    print(output)
    print('='*50)

    return output


image = np.random.random((3, 5, 5))
output = Conv2D(image, 6, (3, 3), padding=1, strides=1)​&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Python</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/123</guid>
      <comments>https://eremo2002.tistory.com/123#entry123comment</comments>
      <pubDate>Tue, 14 Sep 2021 02:02:28 +0900</pubDate>
    </item>
    <item>
      <title>Sigmoid, Softmax in semantic segmentation</title>
      <link>https://eremo2002.tistory.com/122</link>
      <description>&lt;p&gt;semantic segmentation을 공부하면서 최종 output feature map에 어떤 activation function을 취해야 하는지 헷갈렸던 내용을 정리합니다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;final output feature map의 사이즈는 (C, H, W)이고 아래와 같은 값이 나왔다고 가정하겠습니다.&lt;/li&gt;
&lt;li&gt;여기선 dog, cat, person, backgorund 4가지 클래스가 있고 각 채널은 특정 클래스에 대응됩니다.&lt;/li&gt;
&lt;/ul&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/n0mio/btqWjpKQJpd/4D30jHDK26ylVfJGkFGhYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n0mio/btqWjpKQJpd/4D30jHDK26ylVfJGkFGhYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n0mio/btqWjpKQJpd/4D30jHDK26ylVfJGkFGhYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn0mio%2FbtqWjpKQJpd%2F4D30jHDK26ylVfJGkFGhYK%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;&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;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Sigmoid를 취하게 되면 각 element마다 0~1사이의 값으로 출력됩니다. element 단위로 계산되기 때문에 각 픽셀에 대한 독립적인 확률값을 구할 수 있습니다.&lt;/li&gt;
&lt;/ul&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/bDYFqy/btqV8Fgz6GF/EKdsVNE7sIJCZbKwuIZzeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDYFqy/btqV8Fgz6GF/EKdsVNE7sIJCZbKwuIZzeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDYFqy/btqV8Fgz6GF/EKdsVNE7sIJCZbKwuIZzeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDYFqy%2FbtqV8Fgz6GF%2FEKdsVNE7sIJCZbKwuIZzeK%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;&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;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나의 이미지에 하나의 라벨만 존재하는 image classification 문제의 경우 softmax를 취하고 가장 큰 값을 예측 클래스로 사용합니다.&lt;/li&gt;
&lt;li&gt;semantic segmentation 또한 분류 단위가 이미지에서 픽셀 단위로 바뀌었을 뿐 개념은 같습니다. 이런 상황에서&amp;nbsp; (0, 1)에 위치한 픽셀은 cat으로 봐야하는지, background로 봐야하는지 애매합니다.&lt;/li&gt;
&lt;li&gt;여기선 background의 값이 더 크기 때문에 background로 판단할 수 있겠지만 두 픽셀 값의 차이가 거의 없는 경우 어떤 클래스로 판단해야 하는지 애매합니다.&lt;/li&gt;
&lt;li&gt;일반적인 semantic segmentation task에서 하나의 픽셀은 하나의 클래스에만 대응되기 때문에 sigmoid를 사용하게 되면 이러한 문제에 직면할 수 있습니다. (도메인에 따라 semantic segmentation task에서 하나의 픽셀이 여러 라벨을 갖는 multi-label classification 문제도 존재합니다.)&lt;/li&gt;
&lt;/ul&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/dDcH0M/btqV8GfpkTm/COnM4UZGSdashKKUcz0cc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDcH0M/btqV8GfpkTm/COnM4UZGSdashKKUcz0cc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDcH0M/btqV8GfpkTm/COnM4UZGSdashKKUcz0cc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDcH0M%2FbtqV8GfpkTm%2FCOnM4UZGSdashKKUcz0cc1%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;&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;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이번엔 sigmoid대신 softmax를 취하는 경우를 보겠습니다.&lt;/li&gt;
&lt;li&gt;pytorch에선 softmax를 취할 때 어떤 축을 기준으로 계산할건지 파라미터를 줄 수 있습니다.&lt;/li&gt;
&lt;li&gt;만약 채널 축을 기준으로 softmax를 취하게 되면 같은 위치에 있으면서 다른 채널에 존재하는 element들의 합이 1이 되도록 계산합니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&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/uwdrw/btqWBzSDY4M/WXqkTjMkNC8UMvltOjFZBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uwdrw/btqWBzSDY4M/WXqkTjMkNC8UMvltOjFZBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uwdrw/btqWBzSDY4M/WXqkTjMkNC8UMvltOjFZBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuwdrw%2FbtqWBzSDY4M%2FWXqkTjMkNC8UMvltOjFZBk%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;&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;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 채널에서 같은 위치에 있는 값들을 더했을 때 1이 됩니다.&lt;/li&gt;
&lt;/ul&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/cxKUKu/btqWBBbQ7pQ/V6Lgtm4N9Fd5YVAF8HmtW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxKUKu/btqWBBbQ7pQ/V6Lgtm4N9Fd5YVAF8HmtW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxKUKu/btqWBBbQ7pQ/V6Lgtm4N9Fd5YVAF8HmtW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxKUKu%2FbtqWBBbQ7pQ%2FV6Lgtm4N9Fd5YVAF8HmtW1%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;&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/oX9gi/btqWsIiLYKK/HNpkqFufP73R1wk62ZTDZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oX9gi/btqWsIiLYKK/HNpkqFufP73R1wk62ZTDZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oX9gi/btqWsIiLYKK/HNpkqFufP73R1wk62ZTDZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoX9gi%2FbtqWsIiLYKK%2FHNpkqFufP73R1wk62ZTDZ1%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;&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;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&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;(0, 0)에서 가장 큰 확률 값은 cat 클래스에 해당하므로 (0, 0)은 cat으로 분류하게 됩니다.&lt;/li&gt;
&lt;/ul&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/cv57Cr/btqV8FHwO2l/sgUlkasb0JmbJQpXeLwaB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cv57Cr/btqV8FHwO2l/sgUlkasb0JmbJQpXeLwaB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cv57Cr/btqV8FHwO2l/sgUlkasb0JmbJQpXeLwaB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcv57Cr%2FbtqV8FHwO2l%2FsgUlkasb0JmbJQpXeLwaB0%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;&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;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 예시에선 채널 축을 기준으로 softmax를 취했는데 height로 취하게 되면 어떻게 계산되는지 보겠습니다.&lt;/li&gt;
&lt;li&gt;height를 기준으로 하면 각 채널마다 독립적으로 계산되며, matrix의 각 column마다 합이 1이 되도록 합니다.&lt;/li&gt;
&lt;/ul&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/cwJS1p/btqWGK7nFO3/XqsgskXESp0nmUKukKHze1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwJS1p/btqWGK7nFO3/XqsgskXESp0nmUKukKHze1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwJS1p/btqWGK7nFO3/XqsgskXESp0nmUKukKHze1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwJS1p%2FbtqWGK7nFO3%2FXqsgskXESp0nmUKukKHze1%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;&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/VE2p7/btqWBA44gnN/zqZoZ09kEPVApQ6P6PA0cK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VE2p7/btqWBA44gnN/zqZoZ09kEPVApQ6P6PA0cK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VE2p7/btqWBA44gnN/zqZoZ09kEPVApQ6P6PA0cK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVE2p7%2FbtqWBA44gnN%2FzqZoZ09kEPVApQ6P6PA0cK%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;&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;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이번에는 width 축을 기준으로 softmax를 취하는 경우입니다.&lt;/li&gt;
&lt;li&gt;채널마다 독립적으로 계산되고, matrix의 각 row마다 합이 1이 되도록 계산합니다.&lt;/li&gt;
&lt;/ul&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/Wp8HO/btqWBAKLvV8/6XrualSNGzVoCiFHqT2pBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wp8HO/btqWBAKLvV8/6XrualSNGzVoCiFHqT2pBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wp8HO/btqWBAKLvV8/6XrualSNGzVoCiFHqT2pBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWp8HO%2FbtqWBAKLvV8%2F6XrualSNGzVoCiFHqT2pBk%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;&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/bgIuKO/btqWzt6duWG/hprLZlC62NuaJBCKXcZfK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgIuKO/btqWzt6duWG/hprLZlC62NuaJBCKXcZfK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgIuKO/btqWzt6duWG/hprLZlC62NuaJBCKXcZfK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgIuKO%2FbtqWzt6duWG%2FhprLZlC62NuaJBCKXcZfK0%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;&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;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아래 내용은 SegNet의 section 3의 내용입니다.&lt;/li&gt;
&lt;li&gt;마지막 문장에서 픽셀마다 독립적인 확률값을 계산하기 위해 softmax를 취한다고 했는데 그러면 sigmoid를 취했을 때 결과랑 똑같은 거 아닌가? 라는 생각을 했습니다.&lt;/li&gt;
&lt;li&gt;제가 해당 내용을 잘못 받아들였던 이유는 feature map이 softmax, sigmoid를 거쳤을 때 어떤 결과가 나오는지 그 차이점을 잘못 이해하고 있었기 때문입니다.&lt;/li&gt;
&lt;/ul&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/XKgvy/btqWsJhL0pm/N3dKznK5wp0ULHGao8zIL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XKgvy/btqWsJhL0pm/N3dKznK5wp0ULHGao8zIL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XKgvy/btqWsJhL0pm/N3dKznK5wp0ULHGao8zIL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXKgvy%2FbtqWsJhL0pm%2FN3dKznK5wp0ULHGao8zIL0%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;&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;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;픽셀 단위로 독립적인 softmax를 취했을 때, 아래와 같이 각 픽셀마다 0~1 사이의 확률 값이 나온다고 생각했습니다.&lt;/li&gt;
&lt;li&gt;sigmoid를 사용해도 각 픽셀마다 0~1 사이의 확률 값이 나오기 때문에 결과적으로 차이가 없다고 생각했습니다.&lt;/li&gt;
&lt;/ul&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/b0mN44/btqWxf1HZUa/XRjlIxSN78qBHIoBdCUd8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0mN44/btqWxf1HZUa/XRjlIxSN78qBHIoBdCUd8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0mN44/btqWxf1HZUa/XRjlIxSN78qBHIoBdCUd8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0mN44%2FbtqWxf1HZUa%2FXRjlIxSN78qBHIoBdCUd8k%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;&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그러나 각 픽셀마다 softmax를 취하게 되면 하나의 원소만 존재하므로 출력값은 항상 1이 됩니다.&lt;/li&gt;
&lt;/ul&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/b889bX/btqV8GT2qSw/9zwnKkJ0edfrtd3HbzUK4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b889bX/btqV8GT2qSw/9zwnKkJ0edfrtd3HbzUK4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b889bX/btqV8GT2qSw/9zwnKkJ0edfrtd3HbzUK4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb889bX%2FbtqV8GT2qSw%2F9zwnKkJ0edfrtd3HbzUK4K%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;&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;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;따라서, k개의 클래스가 존재하는 semantic segmentation task에선 (K, H, W) 최종 output feature map에 채널 축을 기준으로 softmax를 사용해야합니다.&lt;/li&gt;
&lt;/ul&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/cnJouQ/btqWsJhMlBm/w8t9k5GuFYIHmDDCHRk6N0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnJouQ/btqWsJhMlBm/w8t9k5GuFYIHmDDCHRk6N0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnJouQ/btqWsJhMlBm/w8t9k5GuFYIHmDDCHRk6N0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnJouQ%2FbtqWsJhMlBm%2Fw8t9k5GuFYIHmDDCHRk6N0%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;&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/qFxiV/btqWzuqwB4E/ZaKYqKSkDo1eL87sdXTt0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qFxiV/btqWzuqwB4E/ZaKYqKSkDo1eL87sdXTt0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qFxiV/btqWzuqwB4E/ZaKYqKSkDo1eL87sdXTt0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqFxiV%2FbtqWzuqwB4E%2FZaKYqKSkDo1eL87sdXTt0K%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;&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;
&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/MBrwO/btqWxfgjA4o/zitsUyWCUDiuIGsf2kBNzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MBrwO/btqWxfgjA4o/zitsUyWCUDiuIGsf2kBNzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MBrwO/btqWxfgjA4o/zitsUyWCUDiuIGsf2kBNzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMBrwO%2FbtqWxfgjA4o%2FzitsUyWCUDiuIGsf2kBNzK%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;&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/euuuWP/btqV8HegrZI/QyJvGc8pWC7zkKBUyHHnXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/euuuWP/btqV8HegrZI/QyJvGc8pWC7zkKBUyHHnXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/euuuWP/btqV8HegrZI/QyJvGc8pWC7zkKBUyHHnXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeuuuWP%2FbtqV8HegrZI%2FQyJvGc8pWC7zkKBUyHHnXK%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;&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;
&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그런데 pytorch를 사용한 구현체들을 보면 softmax를 사용하지 않습니다.&lt;/li&gt;
&lt;li&gt;softmax를 사용해야 하는 것이 맞는데, 왜 대다수의 pytorch 구현체들은 softmax layer가 존재하지 않는지 이해할 수 없었습니다.&lt;/li&gt;
&lt;/ul&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;a href=&quot;https://github.com/usuyama/pytorch-unet/blob/master/pytorch_unet.py&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnlbr1/btqWn2hybWZ/ksbXUQtmMxnUPiAX7SnXN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbnlbr1%2FbtqWn2hybWZ%2FksbXUQtmMxnUPiAX7SnXN0%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;/a&gt;&lt;figcaption&gt; https://github.com/usuyama/pytorch-unet/blob/master/pytorch_unet.py &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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 부분에 대한 갈증은 pytorch document에서 crossentropyloss를 확인하고서야 해소할 수 있었습니다.&lt;/li&gt;
&lt;li&gt;pytorch에선 cross entropy loss에 softmax 결과를 포함하고 있기 때문에 모델 구현 단계에서 굳이 softmax layer를 사용하지 않아도 됩니다.&lt;/li&gt;
&lt;/ul&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/cIqSmj/btqWjpD7KMP/WwyKHGxN7B3UIX2w9RV4b1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIqSmj/btqWjpD7KMP/WwyKHGxN7B3UIX2w9RV4b1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIqSmj/btqWjpD7KMP/WwyKHGxN7B3UIX2w9RV4b1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIqSmj%2FbtqWjpD7KMP%2FWwyKHGxN7B3UIX2w9RV4b1%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;&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>ML &amp;amp; DL/이것저것..</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/122</guid>
      <comments>https://eremo2002.tistory.com/122#entry122comment</comments>
      <pubDate>Tue, 9 Feb 2021 11:34:23 +0900</pubDate>
    </item>
    <item>
      <title>SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation</title>
      <link>https://eremo2002.tistory.com/120</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/1511.00561.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;arxiv.org/pdf/1511.00561.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Abstract&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;SegNet이라는 pixel-wise segmentation 모델을 제안한다.&lt;/li&gt;
&lt;li&gt;SegNet은 encoder-decoder로 아키텍처로 encoder는 f.c layer를 제외한 VGG16을 사용하고 decoder는 학습 파라미터가 필요 없는 un-maxpooling을 이용하여 upsampling한다.&lt;/li&gt;
&lt;li&gt;decoder에서 upsampling 된 feature map은 convolution layer를 통해 dense feature map으로 만든다.&lt;/li&gt;
&lt;li&gt;SegNet은 memory &amp;amp; accuracy 사이의 trade-off에서 FCN, DeepLab-LargeFOV, DeconvNet 보다 좋은 퍼포먼스를 낸다.&lt;/li&gt;
&lt;li&gt;제안하는 SegNet 아키텍처가 road scene segmentation, SUN RGB-D indoor scene segmentation task에서 더 좋은 성능을 낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;max pooling, sub-sampling 연산을 수행하다보면 coarse feature map이 만들어지게 된다. coarse feature map은 pixel-wise prediction을 해야하는 segmentation task에서 정보가 부족하기 때문에 좋은 output을 내지 못한다.&lt;/p&gt;
&lt;p&gt;SegNet은 이러한 low resolution feature로부터 input 이미지와 동일한 크기로 정확한 boundary localization이 가능한 아키텍처를 만들고자 제안되었다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;SegNet은 road scene segmentation task를 풀고자 하였으며, 해당 task는 appearance(road, building), shape(cars, pedestrians), spatial-relationship (context, road &amp;amp; side-walk) 같은 정보를 이해하는 것이 중요하다. 대다수의 픽셀은 크기가 큰 building, road class에 해당하기 때문에 class간의 boundary를 잘 구분할 수 있어야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;도로와 보도는 비슷한 점이 있지만 엄연히 다른 class이기 때문에 두 class간의 경계를 잘 구분하는 것이 중요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;우선, SegNet 구조는 아래 그림 2와 같으며 encoder 구조는 VGG16에서 f.c layer를 제외한 것과 동일하다. f.c layer를 제외한 이유는 SegNet이 메모리 사용량, 계산량 등 computation cost 측면에서 강점을 가지기 위해 f.c layer를 제외하였다. decoder의 경우 encoder의 mirrored 구조로 볼 수 있으며 upsampling을 위해 un-maxpooling을 사용하였다. DeconvNet과 비슷하지만 un-maxpooling 이후 일반 conv layer를 이용하여 feature를 추출했다는 점에서 차이가 있다.&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/doiyeG/btqVdeYwpSw/6WKvuXNrOYqeqtz4C1AP1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/doiyeG/btqVdeYwpSw/6WKvuXNrOYqeqtz4C1AP1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/doiyeG/btqVdeYwpSw/6WKvuXNrOYqeqtz4C1AP1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdoiyeG%2FbtqVdeYwpSw%2F6WKvuXNrOYqeqtz4C1AP1K%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;SegNet의 main idea라 할 수 있는 un-maxpooling의 장점은 3가지로 추려볼 수 있다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;boundary delineation(묘사) 측면에서 improve&lt;/li&gt;
&lt;li&gt;upsampling을 위해 deconvolution layer를 사용하지 않기 때문에 별도의 학습 파라미터가 없고 전체 모델은 여전히 end-to-end 학습이 가능하다.&lt;/li&gt;
&lt;li&gt;다른 encoder-decoder 구조에 응용할 수 있고 modification이 용이하다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Architecture&lt;/h1&gt;
&lt;p&gt;SegNet의 encoder-decoder는 각각 13개의 convolution layer로 구성되어 있고 encoder는 VGG16 구조를 따르기 때문에 encoder의 경우 pre-trained weight 활용이 가능하다. encoder에서 f.c layer를 제외한 이유는 VGG에서 대다수의 파라미터가 f.c layer에 존재하지만 f.c layer가 그만큼 중요한 역할을 하는 것도 아니고 메모리 사용량도 줄일 수 있기 때문에 f.c layer를 제외하였다. f.c layer만 제외하더라도 약 9배의 파라미터가 줄어들게 된다. 레이어 구조는 conv &amp;rarr; BN &amp;rarr; ReLU, stride가 2인 2x2 max pooling을 사용하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;convolution, pooling으로 feature map의 사이즈가 줄어들게 되면 디테일한 boundary 정보가 사라지게 되며 이러한 문제는 pixel 단위로 예측해야 하는 segmentation에서는 더욱 심각해진다. 이러한 문제를 해결하기 위해 feature map의 representation power는 살리면서 upsampling하는 것이 중요한데 SegNet에서는 un-maxpooling과 convolution을 이용하여 이러한 문제를 해결하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;만약 메모리 자원에 대한 제한이 없으면 encoder에서 만들어지는 모든 feature map을 저장해놨다가 skip connection을 이용해 decoder에서 나온 feature와 결합하는 것도 하나의 방법이 되겠지만 메모리는 제한적이기 때문에 현실적으론 어렵다. 그래서 max-pooling layer의 indices 정보를 이용한 un-maxpooling을 사용하는 것이 훨씬 효율적이다.&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/bur7XU/btqVugNeD6m/r1Xr2VU0mhLlW1KmOkM730/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bur7XU/btqVugNeD6m/r1Xr2VU0mhLlW1KmOkM730/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bur7XU/btqVugNeD6m/r1Xr2VU0mhLlW1KmOkM730/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbur7XU%2FbtqVugNeD6m%2Fr1Xr2VU0mhLlW1KmOkM730%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;K(클래스 개수)개의 채널을 가진 decoder의 최종 output은 trainable softmax classifier로 입력되어 pixel 마다 독립적으로 확률값을 계산한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Decoder Variants&lt;/h2&gt;
&lt;p&gt;본 논문에서는 SegNet 구조를 조금씩 변형하여 성능을 비교한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;SegNet-basic&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;기존의 SegNet과 동일하며 layer 개수만 줄인 버전으로 4개의 encoder, 4개의 decoder를 사용한다.&lt;/li&gt;
&lt;li&gt;wide context 정보를 추출하기 위해 모든 convolution layer에서 7x7 kernel을 사용하며 decoder에 bias, relu를 사용하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;FCN-basic&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;encoder 구조는 SegNet-basic과 동일하고 decoder는 FCN에서 사용했던 구조를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SegNet-Basic-SingleChannelDecoder&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SegNet-Basic과 동일한 구조&lt;/li&gt;
&lt;li&gt;decoder filter가 single 채널을 갖도록 함&lt;/li&gt;
&lt;li&gt;이렇게 하는 이유? 학습 파라미터 수를 줄일 수 있고 인퍼런스 속도 향상&lt;/li&gt;
&lt;li&gt;여기서 single channel이라는 것으로 봤을 때, depthwise convolution을 사용했다는 것으로 보임&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;FCN-Basic-NoAddition&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FCN에서 skip connection 제외&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Bilinear-Interpolation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FCN-Basic-NoAddition모델에서 upsampling layer를 fixed bilinear interpolation weight 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;SegNet-Basic-EncoderAddition&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;채널 크기가 64인 모든 feature map을 가져와서 decoder feature map과 add&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;FCN-Basic-NoDimReduction&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;encoder에서 채널 차원축소 x&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Training&lt;/h2&gt;
&lt;p&gt;학습 데이터셋 : CamVid road scene&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;367 train images, 233 test images&lt;/li&gt;
&lt;li&gt;11 classes (road, building, cars, pedestrians, signs, poles, side-walk ...)&lt;/li&gt;
&lt;li&gt;weight init : He&lt;/li&gt;
&lt;li&gt;optimizer : SGD&lt;/li&gt;
&lt;li&gt;lr : 0.1(momentum = 0.9)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;sky, road, building 처럼 크기가 큰 클래스의 경우 이미지에서 차지하고 있는 픽셀 수가 다른 클래스에 비해 많기 때문에 loss에 끼치는 영향도 클래스마다 달라지게 된다. class balancing이 필요하며 논문에서는 median frequency balancing을 사용하였다. 학습 데이터셋에서 특정 클래스가 차지하고 있는 비중에 따라 loss함수 계산 시 weight를 다르게 부여함 (클래스마다 비중 계산은 픽셀 수를 기준으로 계산한 것으로 보임)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;sky, building, road 같이 크기가 큰 클래스의 경우 1보다 작은 값의 weight를 사용하고 크기가 작은 클래스의 경우 1보다 큰 값의 weight를 사용하여 loss function 계산 시 class balancing이 유지되도록 함&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;validation score가 가장 좋은 weight를 test에 사용함&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Analysis&lt;/h2&gt;
&lt;p&gt;정량적 평가 척도로 총 3가지 metric을 사용함&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;global accuracy&lt;/p&gt;
&lt;p&gt;데이터셋 전체의 픽셀 수에서 올바르게 분류된 픽셀의 수&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;class average accuracy&lt;/p&gt;
&lt;p&gt;각 클래스마다 accuracy를 계산한 뒤, 평균낸 것&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;boundary F1 Score&lt;/p&gt;
&lt;p&gt;boundary에 대한 예측이 중요하기 때문에 mIoU보다 정성적 평가에 더 적합하기 때문에 mIoU 대신 BF1 score를 사용함&lt;/p&gt;
&lt;p&gt;score = 2 * precision * recall / (recall + precision)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;metric 참고자료&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mathworks.com/help/vision/ref/evaluatesemanticsegmentation.html&quot;&gt;https://www.mathworks.com/help/vision/ref/evaluatesemanticsegmentation.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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/ccS6Mt/btqVtaGu2v5/njEdMEAAvHKaTn8ux3uH01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccS6Mt/btqVtaGu2v5/njEdMEAAvHKaTn8ux3uH01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccS6Mt/btqVtaGu2v5/njEdMEAAvHKaTn8ux3uH01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccS6Mt%2FbtqVtaGu2v5%2FnjEdMEAAvHKaTn8ux3uH01%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;upsampling에서 bilinear-interpolation을 사용한 경우 성능 저조함&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;학습 파라미터를 이용하여 upsampling하는 FCN-Basic기반 모델이나, upsampling 이후 feature를 더 추출하는 모델(SegNet-Basic 기반 variant)들이 bilinear-interpolation 보다 더 좋은 성능을 보여줌 결과적으로 decoder 또한 학습 가능한 구조를 사용하는 것이 더 좋다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;SegNet-Basic과 FCN-Basic은 둘다 성능이 잘 나오는 편, 그러나 인퍼런스 시 SegNet은 max-pooling indices를 사용하기 때문에 메모리 사용량이 더 적음. SegNet 메모리 사용량이 1이라고 했을 때 FCN은 11배 이상의 메모리를 사용함&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;메모리 사용량 측면에선 SegNet-Basic이 더 효과적인데 인퍼런스 속도는 FCN-Basic이 더 빠르다. SegNet decoder의 경우 각 decoder layer에서 64개의 feature map을 사용하지만 FCN-Basic의 경우 각 decoder layer에서 feature map dimension reduction으로 인해 인퍼런스 속도는 FCN-Basic이 더 빠르다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;실험결과를 전체적으로 요약해보면,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;encoder feature map 전체를 저장하는 것이 BF(boundary F1 score) 성능이 가장 좋다. 여기서 feature map 저장은 skip connection을 위해 저장하는 것&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;인퍼런스 시 메모리 사용량이 제한된 경우, decoder에서 un-maxpooling을 사용하면 성능을 올릴 수 있음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Larger decoders increase performance&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Benchmarking&lt;/h1&gt;
&lt;p&gt;SegNet을 2가지 scene segmentation dataset에서 평가함&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;road scene segmentation&lt;/li&gt;
&lt;li&gt;indoor scene segmentation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Road Scene Segmentation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;class간 boundary 부분에서 SegNet이 다른 모델들보다 더 정교하게 boundary를 구분하고 small 객체도 잘 잡는다.&lt;/li&gt;
&lt;li&gt;DeepLab-LargeFOV의 경우 크기가 작은 클래스는 제대로 segmentation하지 못했지만 그래도 competitive한 결과를 보여줌&lt;/li&gt;
&lt;li&gt;FCN with deconv의 경우 고정된 bilinear upsampling을 사용한 FCN보다 더 better한 결과를 보여줌&lt;/li&gt;
&lt;li&gt;DeconvNet의 경우 모델 자체가 굉장히 크고 학습이 비효율적이며 small class 객체는 segmentation하지 못함..&lt;/li&gt;
&lt;/ul&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/bM69Cl/btqVe66L386/91k5Eie3Hh5Bp7mk93cobk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bM69Cl/btqVe66L386/91k5Eie3Hh5Bp7mk93cobk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bM69Cl/btqVe66L386/91k5Eie3Hh5Bp7mk93cobk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbM69Cl%2FbtqVe66L386%2F91k5Eie3Hh5Bp7mk93cobk%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;&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;SegNet을 non deep-learning method와 비교한 결과로 확실히 딥러닝을 사용하는 것이 더 의미 있는 성능을 보여줌&lt;/p&gt;
&lt;p&gt;그런데 CamVid dataset은 데이터가 그렇게 많지 않은 데이터셋인데 여기에 추가 데이터셋으로 학습시켜놓고 딥러닝 모델이 더 좋다! 라고 주장하는 건 좀... 학습은 CamVid trainset만 사용해서 학습시키고 비교하는 게 맞지 않나...&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/byQcRm/btqVuhSUJVS/VmpXxDR4ZQczVwSiXrMqO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byQcRm/btqVuhSUJVS/VmpXxDR4ZQczVwSiXrMqO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byQcRm/btqVuhSUJVS/VmpXxDR4ZQczVwSiXrMqO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyQcRm%2FbtqVuhSUJVS%2FVmpXxDR4ZQczVwSiXrMqO1%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;&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/bR1qfm/btqVswXlNtU/aCxtfBiXWF7sgt5P2Hwrx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR1qfm/btqVswXlNtU/aCxtfBiXWF7sgt5P2Hwrx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR1qfm/btqVswXlNtU/aCxtfBiXWF7sgt5P2Hwrx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR1qfm%2FbtqVswXlNtU%2FaCxtfBiXWF7sgt5P2Hwrx1%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;SUN RGB-D Indoor Scenes&lt;/h2&gt;
&lt;p&gt;SUN RGB-D 데이터셋은 실내 이미지에서 37개 클래스를 segmentation한 데이터셋 (실내 환경 같은 데이터는 증강현실 쪽에서 흥미롭게 사용되는 데이터셋이라고 함)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;5285 train images&lt;/li&gt;
&lt;li&gt;5050 testing images&lt;/li&gt;
&lt;li&gt;class : wall, floor, ceiling, table, chair, sofa ...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;객체의 shape, size, pose가 굉장히 다양하고 부분적인 occlusion도 존재하기 때문에 꽤나 challenge한 task임. 본 논문에서는 이미지의 depth 정보는 제외하고 RGB 정보만 사용&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;SegNet qualitative result(정성적 결과)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SegNet은 view가 달라지더라도 크기가 큰 객체들은 잘 잡아냄 다른 모델들보다 reasonable한 결과를 보여줌&lt;/li&gt;
&lt;li&gt;It is also useful to segment decorative objects such as paintings on the wall for AR tasks. 라고 주장하는데 전혀 그렇지 않아보임&lt;/li&gt;
&lt;li&gt;특히 세 번째 컬럼 이미지의 경우 굉장히 난잡한 prediction이 만들어지는데, 이는 주방에 존재하는 객체들이 라벨링되지 않았기 때문에 발생하는 결과&lt;/li&gt;
&lt;/ul&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/bhf1Cz/btqVkLnsN50/nYXK2Mre7UzdP57EELoY81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhf1Cz/btqVkLnsN50/nYXK2Mre7UzdP57EELoY81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhf1Cz/btqVkLnsN50/nYXK2Mre7UzdP57EELoY81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbhf1Cz%2FbtqVkLnsN50%2FnYXK2Mre7UzdP57EELoY81%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;&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;Quantitative result(정량적 평가)&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 딥러닝 모델들이 mIoU, BF 성능 저조함(이 결과는 데이터셋 특성상 어쩔 수 없는 거 같다.)&lt;/li&gt;
&lt;li&gt;SegNet의 G, C, BF 성능은 다른 모델들보다 훨씬 우수한 결과를 보임 (물론 &amp;gt;140K에서..)&lt;/li&gt;
&lt;li&gt;iteration이 적을 때도 성능이 더 잘 나온다 (수렴이 빠르다?)&lt;/li&gt;
&lt;/ul&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/boHbzg/btqVtcdhMv7/B0OIVX5PQYTUF3gHUkCyh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boHbzg/btqVtcdhMv7/B0OIVX5PQYTUF3gHUkCyh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boHbzg/btqVtcdhMv7/B0OIVX5PQYTUF3gHUkCyh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboHbzg%2FbtqVtcdhMv7%2FB0OIVX5PQYTUF3gHUkCyh0%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사이즈가 큰 클래스의 경우 reasonable한 성능을 보여주지만 사이즈가 작은 클래스의 경우 성능이 매우 저조함&lt;/li&gt;
&lt;li&gt;클래스 수가 많고 이미지에서 사이즈가 작은 객체 또한 많기 때문에 성능이 잘 나오지 않는다.&lt;/li&gt;
&lt;/ul&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/b2rShP/btqVtbrRA7o/lk88PI7uXkTk8RkZ48Mwuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2rShP/btqVtbrRA7o/lk88PI7uXkTk8RkZ48Mwuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2rShP/btqVtbrRA7o/lk88PI7uXkTk8RkZ48Mwuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2rShP%2FbtqVtbrRA7o%2Flk88PI7uXkTk8RkZ48Mwuk%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;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Discussion and Future Work&lt;/h1&gt;
&lt;p&gt;딥러닝 기반의 모델들이 성능이 좋은 이유는 대규모 데이터셋으로 큰 model을 학습시키기 때문에 성능이 잘 나온다. 그러나 딥러닝 모델을 deploy하거나 임베디드 device에 포팅해야 하는 경우 메모리, 연산 속도와 같은 요소도 굉장히 중요하다. 또한 학습시간에 비례해서 성능이 지속적으로 증가하는 것도 아니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;효율성 측면에서 메모리 사용량, 연산 속도를 고려해야 실시간 application으로 활용이 가능할 것이다. 기존 모델들은 이러한 측면을 고려하지 않았던 것 같음. 따라서 모델을 경량화하면서 reasonable한 성능을 내는 모델을 만드는 것이 중요하며 이러한 측면을 고려해서 SegNet을 설계함&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;일반적인 PASCAL VOC, MS-COCO 데이터셋의 경우 test 이미지에 존재하는 클래스 수가 많지 않지만, Scene segmentation의 경우 test 이미지에서 등장하는 클래스 수가 더 많고 indoor scene segmentation은 high variability 특성 때문에 더 challenge하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;road, indoor scene segmentation을 위한 효율적인 아키텍처 SegNet을 제안하였다.&lt;/li&gt;
&lt;li&gt;SegNet은 메모리 사용량 연산 속도 측면에서 다른 모델보다 훨씬 효율적이다.&lt;/li&gt;
&lt;li&gt;encoder에서 모든 feature map을 저장하는 아키텍처의 경우 성능은 우수하지만 메모리 사용량이 많아지는 단점이 있다. 그러나 SegNet은 un-maxpooling을 사용하여 메모리 사용량을 줄이면서 성능도 개선하였다.&lt;/li&gt;
&lt;/ul&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;h1&gt;My opinion&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;일단 저널 논문이라 그런지 컨퍼런스 논문보다 텍스트가 굉장히 많음..&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Table 1에서 train accuracy를 같이 제공해준 점이 좋았음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;segmentation 모델을 메모리 사용량, 연산 속도 측면을 고려하여 아키텍처를 설계했다는 점에서 의미 있는 시도&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;모델 구조가 심플하고 DeconvNet이랑 크게 다르지 않다. 그림도 명확해서 아키텍처를 이해하는데 어려움은 없었음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;본인들이 강하게 주장하는 메모리 사용량, 인퍼런스 속도를 고려했을 때, SegNet이 정말 dramatic한 성능 개선을 했다고 느껴지진 않음.. 인퍼런스 시 메모리 사용량이나 연산 시간이 효율적이라고 하는데 Table 6을 보면 DeepLab-LargeFOV보다 GPU inference memory만 좋고 나머지 지표는 다 밀림&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;객관적이지 못한 실험&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이전 논문인 FCN, DeconvNet에선 Pascal VOC로 실험했는데 왜 여기선 Pascal VOC로 안했는지 의문임. Pascal VOC 데이터셋에서 성능이 안 나와서 일부러 scene segmentation 쪽으로 전환하고 그쪽에 의미부여를 한 건 아닌가 하는 생각이 듦&lt;/li&gt;
&lt;li&gt;비교 모델인 FCN, DeconvNet, DeepLab-LargeFOV은 논문에서 사용하는 Road scene segmentation, indoor scene segmentation 데이터셋으로 성능 평가를 한 적이 없음. 그러면 결국 저자가 기존 모델을 튜닝해서 해당 데이터셋으로 평가했다는 건데 그러면 이게 과연 객관적인 실험이라고 할 수 있을까?&lt;/li&gt;
&lt;li&gt;Table 2에서 왜 SegNet은 large dataset을 사용하는지..?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;un-maxpooling을 사용해서 메모리 사용량을 줄였다고 주장하는데 차라리 encoder network를 VGG가 아닌 다른 경량화된 network를 활용했다면 어땠을까&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;스터디원분들 의견&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FCN, DeconvNet, bilinear interpolation 등 여러 모델이나 테크닉 등에 대한 비교가 많음, 제안하는 모델에 집중하기 보다 추가적인 실험이 굉장히 많았음&lt;/li&gt;
&lt;li&gt;제안하는 방법, 컨트리뷰션에 비해 설명이 너무 장황하다. 같은 말 너무 반복함&lt;/li&gt;
&lt;li&gt;해당 저널에 실릴 정도의 논문인가?&lt;/li&gt;
&lt;li&gt;활용도는 높아 보이지 않지만 논문에서 언급해주는 개념들을 공부해보기 좋음&lt;/li&gt;
&lt;li&gt;DeconvNet의 연장선이지만 DeconvNet과 큰 차이가 없다.&lt;/li&gt;
&lt;li&gt;DeconvNet과 비슷하지만 약간의 차이로도 성능이 개선될 수 있다.&lt;/li&gt;
&lt;li&gt;제안하는 방법이 fancy하기 보다 억지로 분량을 늘리려는 느낌을 많이 받음&lt;/li&gt;
&lt;li&gt;road scene segmentation이라는 새로운 데이터셋에서 평가했다는 점&lt;/li&gt;
&lt;li&gt;도로, 차량, 사람 등 객체들간의 관계를 이해하는 것이 중요하다고 언급했는데 이에 대한 해석이 부족함&lt;/li&gt;
&lt;li&gt;decoder단에서 튜닝하기 위한 노력은 좋으나 제안하는 방법이 그만한 메리트가 있는가&lt;/li&gt;
&lt;li&gt;u-net의 history를 알고 가는 점&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>ML &amp;amp; DL/Paper Review</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/120</guid>
      <comments>https://eremo2002.tistory.com/120#entry120comment</comments>
      <pubDate>Mon, 1 Feb 2021 19:59:27 +0900</pubDate>
    </item>
    <item>
      <title>Learning Deconvolution Network for Semantic Segmentation</title>
      <link>https://eremo2002.tistory.com/119</link>
      <description>&lt;p&gt;&lt;a href=&quot;http://www.cv-foundation.org/openaccess/content_iccv_2015/papers/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.cv-foundation.org/openaccess/content_iccv_2015/papers/&lt;/a&gt;&lt;a href=&quot;http://Noh_Learning_Deconvolution_Network_ICCV_2015_paper.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Noh_Learning_Deconvolution_Network_ICCV_2015_paper.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Abstract&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Deep deconvolution network라는 모델을 제안하여 semantic segmentation 문제를 해결&lt;/li&gt;
&lt;li&gt;VGG-16 모델을 가져와서 top layer부분을 튜닝하고 deconvolution, upooling layer를 추가함 이를 통해 픽셀단위의 정교한 prediction이 가능함&lt;/li&gt;
&lt;li&gt;객체 구조의 디테일한 특징과 multiple scale까지 핸들링이 가능하며 PASCAL VOC dataset에서 72.5%의 accuracy 달성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;FCN기반 모델들은 다음과 같은 한계점을 가지고 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1. 고정된 receptive field를 사용하므로 객체의 크기가 receptive field보다 점점 작아지거나 커졌을 때 prediction mask가 제대로 그려지지 않을 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;고정된 receptive field를 사용하는 FCN은 아래와 같이 객체 크기에 따라 잘못된 output을 만들어낼 수 있다. (a)의 경우, bus가 receptive field보다 크기가 훨씬 크기 때문에 bus가 가지고 있는 전체적인 특징을 보지 못하고 제한된 local 정보만 추출하게 된다. (b)의 경우 객체의 크기가 너무 작아서 background로 인식해버리는 문제가 발생한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;FCN에서는 dense prediction을 위해 skip architecture을 적용하여 이를 개선하고자 했다. 그러나 고정된 receptive field를 사용하는 문제에서 skip architecture는 근본적인 해결책이라고 보기 어렵다. skip architecture는 boundary detail과 semantic 정보 사이의 trade-off 정도로 볼 수 있다.&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/c4tes2/btqVdMsbB3z/SXgViUy1foZhgZWj0fyqg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4tes2/btqVdMsbB3z/SXgViUy1foZhgZWj0fyqg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4tes2/btqVdMsbB3z/SXgViUy1foZhgZWj0fyqg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4tes2%2FbtqVdMsbB3z%2FSXgViUy1foZhgZWj0fyqg1%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;2. deconvolution layer에 입력되는 coarse map은 local 정보도 많이 부족하고 dense하지 않다. 또한 16x16 feature map을 single bilinear interpolation layer만 사용해서 original input size와 동일한 size로 맞춰주기 때문에 객체의 detail structure 정보를 제대로 복원하지 못한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;본 논문에서는 이러한 limitation을 극복하기 위해 기존과 다른 방법을 적용하였으며 주요 contribution은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;deconvolution, unpooling, ReLU로 구성된 deep deconvoltuion network를 제안한다. 기존에는 semantic segmentation task에서 deep deconvolution network를 사용하지 않았다는 점에서 더욱 의미가 있다.&lt;/li&gt;
&lt;li&gt;객체의 크기와 detail한 정보를 잘 추출하고 복원하기 위한 방법으로 object proposal을 이용하여 instance-wise segmentation을 수행하고 semantic segmentation result와 combine한다.&lt;/li&gt;
&lt;li&gt;PASCAL VOC dataset에서 높은 성능을 냈고 FCN 모델과 앙상블 했을 때 best accuracy를 달성했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;System Architecture&lt;/h1&gt;
&lt;p&gt;본 논문에서 제안하는 deep deconvolution network의 구조는 아래 그림과 같다. 크게 convolution network, deconvolution network로 나눌수 있으며, 각 network가 encoder-decoder 역할을 수행하는 것과 비슷한 구조다. 다시 말해, convolution network는 입력 이미지로부터 feature를 추출하는 feature extractor 역할을 수행하고 deconvolution network는 입력 사이즈와 동일한 크기로 object segmentation map을 생성하는 역할을 수행한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;VGG16 모델을 가져와서 fully-connected layer를 convolution layer로 대체하였다. 여기까진 FCN 구조와 같고 deconvolution network는 convolution network의 mirrored 버전으로 unpolling, deconvolution layer를 통해 feature size를 동일한 크기로 복원해나간다.&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/bGIMgs/btqVdM6MxWG/y6TqvrCpSZa0Crz8AVXrYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGIMgs/btqVdM6MxWG/y6TqvrCpSZa0Crz8AVXrYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGIMgs/btqVdM6MxWG/y6TqvrCpSZa0Crz8AVXrYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGIMgs%2FbtqVdM6MxWG%2Fy6TqvrCpSZa0Crz8AVXrYK%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;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Unpooling&lt;/h3&gt;
&lt;p&gt;일반적으로 pooling은 noise값을 필터링하여 feature의 크기를 줄이기 위해 사용된다. pooling의 단점 중 하나는 spatial information 정보가 손실되는 단점이 있다. 2x2 filter를 사용하는 max pooling의 경우 4가지 값 중 가장 큰 값을 가져오게 되는데 pooling을 수행하고 난 뒤에 각 element 값은 기존의 입력 matrix에서 어느 위치에 해당하는 값인지 알 수가 없다. 특히나 공간정보가 손실된다는 점은 semantic segmentation task에서 더욱 critical한 문제가 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;따라서 deconvolution network에서는 pooling의 역연산인 unpooling 연산을 통해 feature의 original size를 복원한다. pooling layer를 거친 값이 기존 matrix에서 어느 위치에 존재했는지 그 값을 기억하고 있으면 동일한 위치의 값으로 복원할 수 있기 때문에 위치정보가 손실되는 문제를 해결할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;384&quot; width=&quot;468&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H67Zz/btqU52KjwNv/iCZsaQxXWnyTxG6Q7m5x1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H67Zz/btqU52KjwNv/iCZsaQxXWnyTxG6Q7m5x1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H67Zz/btqU52KjwNv/iCZsaQxXWnyTxG6Q7m5x1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH67Zz%2FbtqU52KjwNv%2FiCZsaQxXWnyTxG6Q7m5x1k%2Fimg.png&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;384&quot; width=&quot;468&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;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Deconvolution&lt;/h3&gt;
&lt;p&gt;unpooling layer가 size를 복원하긴 하지만 max 값이 아닌 값들은 0으로 채우기 때문에 결국에는 sparse activation map이 된다. 논문에서는 이 sparse activation map을 deconvolution layer를 통해 dense하게 만들어준다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;convolution layer는 multiple input activation을 하나의 single activation으로 만들어내지만 deconvolution layer는 하나의 single input activation을 여러 개의 multiple output으로 만들어낸다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Q) 따지고 보면 convolution도 하나의 single input activation을 여러 개의 multiple output으로 만들어내는 건 마찬가지 같은데..?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;222&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AxZTR/btqU4YBlDP7/Koco62YUC4tj5T8XxVXF20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AxZTR/btqU4YBlDP7/Koco62YUC4tj5T8XxVXF20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AxZTR/btqU4YBlDP7/Koco62YUC4tj5T8XxVXF20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAxZTR%2FbtqU4YBlDP7%2FKoco62YUC4tj5T8XxVXF20%2Fimg.png&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;222&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;unpooling과 마찬가지로 deconvolution layer 또한 feature size를 upsampling한다. 논문에서는 unpooling layer output과 동일한 size로 맞춰주기 위해 deconvolution layer output을 동일한 사이즈로 crop했다고 한다.&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/cAaSyX/btqU7b760Oj/uRs1LeCpCvRuDbwVWxS8k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAaSyX/btqU7b760Oj/uRs1LeCpCvRuDbwVWxS8k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAaSyX/btqU7b760Oj/uRs1LeCpCvRuDbwVWxS8k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAaSyX%2FbtqU7b760Oj%2FuRs1LeCpCvRuDbwVWxS8k0%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;ul&gt;
&lt;li&gt;Q) deconvolution layer에서 upsampling이 되는 게 맞는지? 코드에서는 deconvolution layer에서는 upsampling이 안되는 거 같음. 그러면 굳이 deconvolution layer가 아니라 unpooling+conv 조합을 쓰는 것과 무엇이 다른지?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;deocnovlution layer의 필터는 입력 object의 shape을 복원하기 위해 학습된다. 따라서 deconvolution network 역시 hierarchical 구조로 레이어를 쌓게 되면 서로 다른 level의 shape detail 정보를 추출할 수 있게 된다. deconvolution network에서 low-level layer는 객체의 전반적인 shape을 추출하고, 클래스를 구분짓는 fine detail 정보들은 high-level layer에서 추출된다. 이러한 방식으로 deconvolution network는 semantic segmentation을 위한 class-specific shape 정보를 잘 뽑아낼 수 있는 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Analysis of Deconvolution Network&lt;/h3&gt;
&lt;p&gt;FCN의 경우 coarse feature를 가져와서 dense prediction하기 때문에 detail 한 정보를 제대로 추출하지 못한다. 물론 skip architecture를 적용하여 어느정도 보완하긴 했지만 deconvolution network처럼 feature reconstruction을 제대로 하기엔 부족한 점이 많다. deconvolution network의 경우 당장 사용하는 uppooling layer, deconvolution layer 개수만 봐도 알수 있듯이 FCN과 reconstruction 성능이 차이날 수밖에 없다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;아래 그림 4는 deconvolution network에서 각 layer output을 시각화한 결과다. 빨간색으로 box친 b, d, f, h, j는 deconvolution layer output이고 c, e, g, i는 unpooling layer output이다. 각 레이어를 거듭하면서 추출되는 feature가 coarse &amp;rarr; fine으로 바뀌는 것을 볼 수 있다. 즉, lower layer에서는 객체의 전반적인 형상(location, shape, region)을 추출하게 되고 higher layer에서는 좀 더 복잡한 패턴이 추출된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;또한, unpooling layer의 경우 pooling layer에서 계산된 위치값을 기억하여 복원하기 때문에 위치정보가 손실되지 않으면서 dense한 output을 만들어내기 때문에 객체의 detailed structure 정보를 효과적으로 reconstruction할 수 있다. 이와 반대로 deconvolution layer는 class-specific shape 정보를 잘 추출하는 역할을 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;논문에서 unpooling layer는 example-specific structure를, deconv layer는 class-specific shape을 뽑아낸다고 한다. 내가 생각해본 example-specific structure와 class-specific shape 두 키워드의 차이는 다음과 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;입력 이미지에서 자전거를 다른 방향에서 찍더라도 자전거가 가지고 있는 고유한 feature는 여전히 존재한다. 따라서 deconvolution layer는 자전거의 방향이 다르더라도 자전거가 가지고 있는 고유한 특징들을 잘 뽑아낼 수 있을 것이다. 따라서 자전거라는 class가 갖는 feature를 잘 추출하기 때문에 class-specific shape이라는 용어를 사용한 것이고, 반대로 unpooling layer의 경우 학습을 통해 feature를 추출하는 레이어가 아니고 주어진 input을 잘 reconstruction하는 것이 목표기 때문에 example-specific라는 용어를 사용한 것이다.&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/HX3XC/btqU94gwFij/C1ScwyimE2WeB66wF6zKO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HX3XC/btqU94gwFij/C1ScwyimE2WeB66wF6zKO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HX3XC/btqU94gwFij/C1ScwyimE2WeB66wF6zKO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHX3XC%2FbtqU94gwFij%2FC1ScwyimE2WeB66wF6zKO0%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;deconvolution layer와 unpooling을 사용하기 때문에 coarse feature map만 사용하는 FCN보다 정교한 output을 만들어낸다.&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/dHET7s/btqVbXgVez3/mAVFpuemOzOnuLZHmAqdtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dHET7s/btqVbXgVez3/mAVFpuemOzOnuLZHmAqdtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dHET7s/btqVbXgVez3/mAVFpuemOzOnuLZHmAqdtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdHET7s%2FbtqVbXgVez3%2FmAVFpuemOzOnuLZHmAqdtK%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;System Overview&lt;/h2&gt;
&lt;p&gt;제안하는 알고리즘은 원래 semantic segmentation task를 풀기 위한 것이 목적이지만 semantic segmentation을 instance-wise segmentation 문제로 재해석해서 해결하고자 하였다. 기존 이미지에 여러 개의 객체가 존재할 시 객체가 존재하는 영역을 crop하여 sub-image로 만든다. 하나의 이미지에서 여러 개의 sub-image가 만들어질 수 있고 이러한 sub-image의 prediction을 모두 통합하여 semantic segmentation 결과를 얻는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;하나의 이미지를 통째로 입력하는 것보다 instance 단위로 잘라서 prediction하게 되면 다양한 scale의 객체를 핸들링할 수 있고 객체의 detail한 feature를 추출할 수 있다는 장점이 있다. 또한 search space를 감소시켜 training complexity를 줄일 수 있다. 그러나 여전히 고정된 receptive field를 사용하게 됐을 때 뒤따라오는 단점은 존재한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Training&lt;/h1&gt;
&lt;p&gt;논문에서 제안하는 네트워크는 꽤나 deep한 구조를 가지기 때문에 파라미터 또한 많이 존재한다. 네트워크 크기에 비해 PASCAL VOC dataset의 데이터 규모가 상대적으로 작기 때문에 네트워크를 제대로 학습하는 것이 쉽지 않다. 즉, 오버피팅이 일어날 확률이 높아진다. 논문에서는 네트워크를 효과적으로 학습하기 위해 다음과 같은 Batch Normalization, Two-stage training 방법을 적용하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Batch Normalization&lt;/h2&gt;
&lt;p&gt;internal-covariate-shift는 딥러닝 네트워크를 학습하기 어렵게 만드는 요인 중 하나이다. covariate-shift는 학습에 사용하는 데이터의 분포와 test 시 사용하는 데이터의 분포가 다른 현상을 의미한다. internal-covariate-shift란 네트워크에 존재하는 각 layer들의 입력 분포가 일정하지 않아 학습이 어려워지는 문제를 의미한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BN에 대한 자세한 설명 참고&amp;nbsp;&lt;a href=&quot;http://sanghyukchun.github.io/88/&quot;&gt;http://sanghyukchun.github.io/88/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;본 논문에서는 BN을 통해 internal-covariate-shift 현상을 줄여 네트워크를 최적화 하였으며 Conv &amp;rarr; BN, Deconv &amp;rarr; BN의 구조를 사용하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Two-stage Training&lt;/h2&gt;
&lt;p&gt;BN을 사용한다 하더라도 semantic segmentation task 자체가 search space도 워낙 커서 네트워크를 최적화하기가 쉽지 않다. 본 논문에서는 two-stage training method를 사용하여 모델을 학습시켰다. two-stage training이란 처음에는 easy example들로 학습시킨 후에 challenging example을 이용하여 fine-tuning하는 방법이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;First stage training&lt;/p&gt;
&lt;p&gt;easy example을 만들기 위해 GT annotation에서 객체가 중앙에 오도록 crop한다. 이렇게 객체의 위치나 사이즈를 조절함으로써 적은 training 데이터로도 semantic segmentation의 search space를 상당히 줄일 수 있다고 한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Second stage training&lt;/p&gt;
&lt;p&gt;second stage는 좀더 challenging example을 만들어낸다. object proposal(객체가 있을법한 위치에 bounding box를 그림)방법을 이용하여 이미지를 crop한다. 여기서 GT segmentation 영역과 IoU 값이 50% 이상인 sample만 사용한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Two-stage training을 통해 testing 시 misalignment 문제를 좀 더 robust하게 만들 수 있다고 한다. 물론 학습 과정이 좀 더 challenging해지는 건 어쩔 수 없다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Inference&lt;/h1&gt;
&lt;p&gt;인퍼런스 과정은 개개의 instance들을 segmentation한 뒤 이 값을 combine하여 사용한다. 일단 입력 이미지가 들어오면 객체가 있을 법한 후보군을 충분히 생성하고 각 후보군(sub-image)이 네트워크에 입력되어 나온 결과를 모두 aggregate하여 최종적으로 semantic segmentation output을 만들어낸다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Aggregating Instance-wise Segmentation Maps&lt;/h2&gt;
&lt;p&gt;입력 이미지에서 생성된 proposal들은 misalignment, 불필요한 background 정보 등을 포함할 수 있기 때문에 부정확한 prediction이 생성될 수 있다. 따라서 이러한 노이즈를 surpass할 수 있도록 aggregation해야 한다. proposal 생성 방법은 edge-box 라는 기법을 이용한다. edge-box란 말 그대로 edge를 기반으로 객체가 있을 법한 위치를 찾아내는 방법이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;여기선 컨셉정도만 이해하고 Edge Box에 대한 자세한 내용은 논문을 읽어봐야 될 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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/HvO4t/btqVbuF1BXp/tWCXQ51ZRndo0OJeJ8V8a0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HvO4t/btqVbuF1BXp/tWCXQ51ZRndo0OJeJ8V8a0/img.png&quot; data-alt=&quot;https://pdollar.github.io/files/papers/ZitnickDollarECCV14edgeBoxes.pdf&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HvO4t/btqVbuF1BXp/tWCXQ51ZRndo0OJeJ8V8a0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHvO4t%2FbtqVbuF1BXp%2FtWCXQ51ZRndo0OJeJ8V8a0%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;https://pdollar.github.io/files/papers/ZitnickDollarECCV14edgeBoxes.pdf&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;i 번째 proposal에 대한 WxHxC output score map이 나왔을 때 해당 score map에 zero-padding을 추가하여 original image와 동일한 사이즈로 만들어준다. 각 proposal에서 나온 모든 score map을 모두 더하거나 혹은 max값만 취하여 aggregating한다. (1), 또는 (2)번 수식을 사용한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(여기서 G_i는 output score map에 zero-padding을 추가한 것)&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/cHDsVJ/btqVbWWCpT7/TiGafdrqKJlw0IyZ7DPfiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHDsVJ/btqVbWWCpT7/TiGafdrqKJlw0IyZ7DPfiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHDsVJ/btqVbWWCpT7/TiGafdrqKJlw0IyZ7DPfiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHDsVJ%2FbtqVbWWCpT7%2FTiGafdrqKJlw0IyZ7DPfiK%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;최종 output은 aggregating map에 softmax를 취한 뒤, fully-connected CRF를 통해 pixel-wise labeling을 만들어낸다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Ensemble with FCN&lt;/h2&gt;
&lt;p&gt;논문에서 제안하는 모델과 FCN을 ensemble하여 더 좋은 퍼포먼스를 낼 수 있다. 두 모델을 앙상블한 이유는 FCN의 경우 객체의 전체적인 shape을 잘 추출할 수 있다는 장점이 있고 deconvolution network의 경우 객체의 fine-detail 정보를 잘 추출하기 때문이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;각 모델에서 나온 두 개의 output의 평균 값을 구한 뒤 CRF를 적용하여 final map을 만들어낸다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Experiments&lt;/h1&gt;
&lt;p&gt;정량적 평가 결과로 DeconvNet과 FCN을 앙상블한 뒤 CRF를 적용한 모델의 성능이 가장 우수했다. CRF를 적용했을 때 1% 가량 정확도가 더 개선되었다.&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/bUtKQu/btqVbuF1Fce/WJGVUoXCsniDBvAIHNJEek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUtKQu/btqVbuF1Fce/WJGVUoXCsniDBvAIHNJEek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUtKQu/btqVbuF1Fce/WJGVUoXCsniDBvAIHNJEek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUtKQu%2FbtqVbuF1Fce%2FWJGVUoXCsniDBvAIHNJEek%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;아래 그림 6은 instance-wise prediction을 적용했을 때 결과를 보여준다. 입력 이미지에 다양한 스케일의 객체가 존재할 때 proposal 수를 늘릴수록 작은 크기의 객체 또한 잘 잡아내는 것을 볼 수 있다.&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/csN9pK/btqU94OqbFi/ZP2kK5wX1a1WRU4k69Qvo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csN9pK/btqU94OqbFi/ZP2kK5wX1a1WRU4k69Qvo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csN9pK/btqU94OqbFi/ZP2kK5wX1a1WRU4k69Qvo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsN9pK%2FbtqU94OqbFi%2FZP2kK5wX1a1WRU4k69Qvo0%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;각 모델의 정성적 결과는 아래 그림과 같다. (a)에선 대체로 Deconvnet의 경우 FCN보다 fine segmentation 결과를 보여주고 multi-scale object 또한 잘 분할하는 모습을 보여준다. FCN의 경우 고정된 receptive field를 사용하기 때문에 객체 크기가 너무 크거나 작은 경우 정확도가 상당히 떨어지는 결과를 보여준다.&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/bV5A2q/btqVdeJfbrv/BjsyOjGUvUqElekn1UJLBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bV5A2q/btqVdeJfbrv/BjsyOjGUvUqElekn1UJLBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bV5A2q/btqVdeJfbrv/BjsyOjGUvUqElekn1UJLBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbV5A2q%2FbtqVdeJfbrv%2FBjsyOjGUvUqElekn1UJLBk%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;아래 그림 (b)의 경우 DeconvNet의 결과에 노이즈가 생기는 걸 볼 수 있는데 proposal이 misalign 되거나 배경에 너무 치우쳤을 때 발생하게 된다. &amp;rarr; 양질의 proposal을 사용하지 않을 시 이러한 노이즈가 낄 수밖에 없는 것 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그러나, DeconvNet+FCN 앙상블 모델의 경우 노이즈가 발생하지 않으며 multi-scale 객체가 존재하더라도 정확한 segmentation이 가능한 걸 볼 수 있다.&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/dQUVhO/btqU4YOW254/iES3IQkFFDpsCjRTdkNfNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQUVhO/btqU4YOW254/iES3IQkFFDpsCjRTdkNfNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQUVhO/btqU4YOW254/iES3IQkFFDpsCjRTdkNfNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQUVhO%2FbtqU4YOW254%2FiES3IQkFFDpsCjRTdkNfNK%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;FCN, DeconvNet의 개별 모델에서 잘못된 labeling map이 그려졌음에도 불구하고 두 모델을 앙상블 했을 때 오히려 개선된 결과를 보여준다. 나아가 여기에 CRF를 적용하게 되면 더 정확한 segmentation map이 만들어진다.&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/bWe26P/btqVbuF1JiW/EgzkwUrVBB1IDmkoxRKLkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWe26P/btqVbuF1JiW/EgzkwUrVBB1IDmkoxRKLkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWe26P/btqVbuF1JiW/EgzkwUrVBB1IDmkoxRKLkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWe26P%2FbtqVbuF1JiW%2FEgzkwUrVBB1IDmkoxRKLkK%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;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;본 논문에서는 deconvolution network라는 novel semantic segmentation 알고리즘을 제안하였다. deconvolution layer를 통해 dense하고, precise한 segmentation mask를 그릴 수 있게 된다. 또한 FCN에서 문제가 되었던 fixed size receptive field문제를 instance-wise prediction을 통해 해결하였으며 이미지에 다양한 스케일의 객체가 존재하더라도 이를 잘 핸들링할 수 있게 된다. 제안하는 모델을 FCN과 앙상블 했을 때 성능이 더욱 개선되었으며 PASCAL VOC segmentation task에서 SOTA를 달성하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;My opinion&lt;/h1&gt;
&lt;p&gt;딥러닝 기반의 semantic segmentation 모델 중 초석이 되는 FCN의 단점을 개선하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;FCN의 fixed receptive field 문제를 지적하였고 이러한 문제를 instance-wise prediction를 통해 객체 크기에 구애받지 않고 multi-scale object image에서도 핸들링이 가능하다. 또한 FCN이 객체의 정교한 shape, detail한 부분에서 성능이 떨어지는 문제를 unpooling layer + deconvolution layer를 결합한 deconvnet으로 보완하였다. 모델의 구조만 봤을 땐 크게 어렵지 않기 때문에 쉽게 응용이 가능할 것 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그러나 고정된 receptive field를 갖는 문제는 커널 사이즈를 다양하게 설정해서 해결하면 어땠을까 하는 생각이 든다.&lt;/p&gt;
&lt;p&gt;왜냐하면 논문에서 적용한 proposal 테크닉을 일반 유저가 활용하기엔 쉽지 않다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;deconv layer말고 그냥 conv layer써도 되지 않나? (후속 논문들에선 그냥 conv만 써서 성능이 많이 올라감, deconv layer를 사용했다는 점에서 의의가 있는듯)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;스터디원분들의 의견&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;실험 테이블에 FCN+CRF를 보여줬으면 어땠을까?&lt;/li&gt;
&lt;li&gt;deconvnet에서 나온 feature map을 시각화해서 해석해준 점이 좋았다.&lt;/li&gt;
&lt;li&gt;two-stage learning에서 object proposal에 대한 내용이 부족했다.&lt;/li&gt;
&lt;li&gt;FCN+DeconvNet 앙상블해서 성능을 올렸으면, deconvnet에서도 충분히 skip connection을 적용해도 됐을텐데 왜 안 썼을까?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;References&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/@sunnerli/simple-introduction-about-hourglass-like-model-11ee7c30138&quot;&gt;https://medium.com/@sunnerli/simple-introduction-about-hourglass-like-model-11ee7c30138&lt;/a&gt;&lt;/p&gt;</description>
      <category>ML &amp;amp; DL/Paper Review</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/119</guid>
      <comments>https://eremo2002.tistory.com/119#entry119comment</comments>
      <pubDate>Fri, 29 Jan 2021 23:46:39 +0900</pubDate>
    </item>
    <item>
      <title>Fully Convolutional Networks for Semantic Segmentation</title>
      <link>https://eremo2002.tistory.com/118</link>
      <description>&lt;h1&gt;&lt;span style=&quot;color: #333333;&quot;&gt;ASCAL &lt;span style=&quot;color: #333333;&quot;&gt;c segmentation task에서 SOTA를 달성하였다.&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Abstract&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;convolution layer만 사용하는 FCN(Fully Convolutional Network)을 제안하였고, pixel 단위의 예측을 해야하는 semantic segmentation task에서 SOTA를 달성하였다.&lt;/li&gt;
&lt;li&gt;AlexNet, VGG, GoogLeNet 구조를 fully convolutional network 형태로 튜닝하고, transfer learning을 이용하였다.&lt;/li&gt;
&lt;li&gt;또한, skip connection구조로 low-level feature, high-level feature를 결합하여 보다 정교한 segmentation output을 낼 수 있었다.&lt;/li&gt;
&lt;li&gt;제안하는 FCN은 PASCAL VOC segmentation task에서 SOTA를 달성하였다. (기존 모델대비 약 20%의 성능 향상)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;CNN은 classification, detection 등 다양한 recognition task에서 뛰어난 성능을 보여주고 있다. segmentation task에선 coarse feature를 통해 pixel-wise prediction을 위한 fine feature를 잘 생성해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;본 논문에서는 'coarse'라는 키워드를 지속적으로 사용한다. 이 단어는 '굵은', '거친'이라는 의미를 가지고 있으며 'fine'과 반대의 의미를 지닌다. coarse feature가 처음엔 low-level feature를 의미하는 줄 알았는데 그게 아니고 CNN의 conv, pooling layer를 통해 resolution이 충분히 작아진 feature를 의미한다.&lt;/li&gt;
&lt;li&gt;일반적으로 classification task에선 coarse feature를 벡터로 만들어 classifier의 입력으로 넣어 분류를 수행하지만 pixel 단위의 prediction을 수행해야 하는 segmentation task에선 coarse feature를 다시 input image size와 비슷한 크기로 up-sampling해주는 작업이 필요하다. 그래야 더욱 정교한 pixel-wise prediction이 가능하기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;본 논문에서 제안하는 fully convolutional network(FCN)는 pixel-wise prediction을 위한 최초의 end-to-end 모델이자 pre-training 모델을 사용하였다. 기존에 fully convolutional 형태의 network들이 존재하긴 했지만 이러한 모델들은 랜덤하게 crop된 image patch를 입력으로 넣는 patchwise training을 사용하였고 fully conv 모델에서는 patchwise training이 더 비효율적이다. FCN은 patchwise training을 사용하지 않고 이미지 전체를 하나의 입력으로 사용하였다.&lt;/p&gt;
&lt;p&gt;밑에서 설명하겠지만 coarse feature를 다시 up-sampling하는 과정에서 정보가 손실될 수 있다. 이러한 문제를 방지하기 위해, skip connection 구조를 사용하여 좀 더 다양한 feature spectrum을 다루고자 하였다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;deep feature &amp;harr; shallow feature&lt;/li&gt;
&lt;li&gt;coarse &amp;harr; fine&lt;/li&gt;
&lt;li&gt;semantic &amp;harr; appearance&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Fully convolutional networks&lt;/h1&gt;
&lt;p&gt;기본적으로 convolution 연산은 translation invariance하다. 이는 레이어를 거듭하여 feature size가 down sampling되더라도 위치 정보는 변하지 않는다. 예를 들어, 이미지 왼쪽 상단에 고양이가 있었을 때 convolution layer를 여러 번 거쳐 resolution이 줄어들더라도 여전히 왼쪽 상단에 고양이에 대한 정보가 남아있다.&lt;/p&gt;
&lt;p&gt;또한, FCN은 fully-connected layer를 사용하지 않기 때문에 고정된 입력 size를 사용해야 하는 제한에서 벗어날 수 있다. 일반적인 classification network에선 충분히 추출된 feature map을 vector로 변환한 뒤 classifier의 입력으로 사용한다. 이미 네트워크를 정의하면서 vector의 크기 또한 정의되었기 때문에 반드시 입력 이미지 크기가 고정되어야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;연산량, 파라미터가 너무 많고 고정된 입력 사이즈를 받아야 한다는 점에서 fully-connected layer가 갖는 문제는 명확하다. 이러한 문제로 인해 Global Average Pooling(GAP)을 사용하는 모델들이 많다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Adapting classifiers for dense prediction&lt;/h3&gt;
&lt;p&gt;LeNet AlexNet, VGG 등 fully-connected layer를 사용하는 유명 모델들은 대부분 입력 사이즈를 고정된 크기로 받아 공간적인 정보가 사라진 non-spatial output을 출력하게 된다.&lt;/p&gt;
&lt;p&gt;fully-connected layer가 공간정보를 잃어버리는 특징이 있지만 다른 관점에서 생각해봤을 때, convolution kernel의 사이즈가 입력 region 전체를 커버하는 크기로 conv 연산을 수행하는 것으로 해석할 수도 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fully-connected layer를 f.c layer와 비슷한 효과를 낼 수 있는 conv layer로 대체하여 고정된 입력 크기를 받는 문제에서 벗어나고자 함&lt;/li&gt;
&lt;li&gt;고정된 입력 사이즈를 받아야 하는 문제를 해결함과 동시에 출력 output feature map의 크기 또한 입력 사이즈와 동일하게 생성할 수 있다. 입력의 height, width값이 500x500이였으면 출력도 500x500이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Shift-and-stitch is filter rarefaction&lt;/h3&gt;
&lt;p&gt;input shift and output interlacing trick은 coarse output에서 dense prediction feature를 생성하기 위한 방법 중 하나이며 OverFeat에서 소개되었다. 해당 trick은 일종의 up-sampling 방법이라고 볼 수 있는데 interpolation을 사용하지 않고 up-sampling을 수행한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;5x5 input에 zero-padding, shift연산을 수행하여 translate된 4개의 입력을 만들어낸 후 각 입력에 대해 2x2 max-pooling 연산을 수행한다. 첫 번째(red)를 보면 output의 크기가 3x3가 나오게 되고, 다른 output을 보면 3x2, 2x3, 2x2 등의 output이 나오게 된다. 어느 방향으로 shift 연산 했는지에 따라 output 사이즈가 달라지게 된다.&lt;/p&gt;
&lt;p&gt;shift 방향에 따라 output 크기가 3x3가 아닌 경우 sliding window 연산이 더 적게 수행된다. 왜 sliding window를 끝까지 수행하지 않는지 이해가 잘 안되었는데 아래 예제에선 결과적으로 입력 크기와 동일한 5x5를 만들어 내기 위해선 3x3, 3x2, 2x3, 2x2 output이 필요하다. output을 어떻게 stitching 할 것인지에 따라 3x3, 3x3, 3x3, 3x3 output을 가지고도 5x5를 만들어 낼 수 있을 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;어쨌든 이러한 4개의 output을 combine하여 오른쪽 아래 그림과 같이 입력 사이즈와 동일한 5x5 output을 생성한다.&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/Qq5R1/btqVbWWBYnR/yz2GKnSFSpe4ETgdvekIN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qq5R1/btqVbWWBYnR/yz2GKnSFSpe4ETgdvekIN0/img.png&quot; data-alt=&quot;https://stackoverflow.com/questions/40690951/how-does-shift-and-stitch-in-a-fully-convolutional-network-work&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qq5R1/btqVbWWBYnR/yz2GKnSFSpe4ETgdvekIN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQq5R1%2FbtqVbWWBYnR%2Fyz2GKnSFSpe4ETgdvekIN0%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;https://stackoverflow.com/questions/40690951/how-does-shift-and-stitch-in-a-fully-convolutional-network-work&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;본 논문에서는 convolution layer의 filter와 stride 값에 따라 shift-and-stitch trick과 유사한 결과를 낼 수 있다고 한다. 그러나 결과적으로 해당 trick을 적용하지 않는다. 추후 소개되는 skip connection 구조가 더욱 효과적이기 때문이다.&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;h3&gt;Upsampling is backwards strided convolution&lt;/h3&gt;
&lt;p&gt;coarse output에서 dense prediction을 만들어내기 위해 upsampling이 필요하다. interpolation으로 upsampling을 수행할 수 있지만 본 논문에선는 deconvolution이라는 layer를 사용하여 upsampling을 수행한다. deconvolution은 convolution의 역연산으로 가중치가 있기 때문에 end-to-end 방식으로 학습이 가능하며 비선형 함수를 통해 비선형성 또한 증가시킬 수 있는 장점이 있다. 논문에서는 deconvolution을 통해 빠르고 효과적인 dense prediction이 가능해졌다고 말한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;deconvolution&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Decovnolution은 convolution의 역연산&lt;/li&gt;
&lt;li&gt;5x5 input이 있을 때 3x3 kernel을 사용하면 2x2 output을 만들어낸다. 2x2 ouput을 다시 기존의 5x5 input과 동일한 값으로 복원하고자 할 때 사용한다.&lt;/li&gt;
&lt;li&gt;단순히 spatial size만 동일하게 upsampling하는 것이 아니라 기존의 input pixel 값과 동일한 값을 만들어내야 한다. 따라서 convolution 연산에 사용되었던 kernel과 동일한 kernel을 사용해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Transposed convoltuion&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;deconvolution과 유사하지만 명백한 차이점이 있다.&lt;/li&gt;
&lt;li&gt;output을 input과 동일한 크기로 upsampling한다는 점에서는 같다.&lt;/li&gt;
&lt;li&gt;그러나 기존의 input pixel 값과 동일한 값을 만들어낼 필요는 없다. 따라서 convolution 연산에 사용되었던 kernel과 다른 kernel이 사용된다.&lt;/li&gt;
&lt;li&gt;tranpose라는 의미는 아래 예로 보면 더욱 명확하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;우선 일반적인 convolution의 matrix 연산은 아래와 같이 수행된다.&lt;/p&gt;
&lt;p&gt;4x4 input은 16x1 vector로 만들어주고 3x3 kernel은 4x16 sparse matrix로 변환하여 계산한다.&lt;/p&gt;
&lt;p&gt;stride로 인한 값을 0으로 채워주기 때문에 sparse matrix라고 한다.&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/cuHsKr/btqU53Cs2N3/J6BpyAKkdl3vbcpB0evZ80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuHsKr/btqU53Cs2N3/J6BpyAKkdl3vbcpB0evZ80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuHsKr/btqU53Cs2N3/J6BpyAKkdl3vbcpB0evZ80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuHsKr%2FbtqU53Cs2N3%2FJ6BpyAKkdl3vbcpB0evZ80%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;&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;기존의 convolution 연산에서 3x3 kernel을 4x16 sparse matrix로 변환해서 사용하였다. 그러나 transposed convolution은 4x16 sparse matrix가 아닌 16x4 sparse matrix를 사용한다. 그래서 이름이 &quot;&lt;b&gt;transposed&quot;&lt;/b&gt; &lt;b&gt;convolution&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/bpJNkT/btqVbvyaBKt/H8eAcpuRNg93sJsvKamnVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpJNkT/btqVbvyaBKt/H8eAcpuRNg93sJsvKamnVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpJNkT/btqVbvyaBKt/H8eAcpuRNg93sJsvKamnVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpJNkT%2FbtqVbvyaBKt%2FH8eAcpuRNg93sJsvKamnVk%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;본 논문에서는 deconvoltuion이라는 단어를 사용하는데 구체적으로 따지면 deconvolution은 아니고 transposed convolution이다. ML, DL 쪽에선 초창기 deconvolution과 transposed convolution을 명확히 구분하지 않고 혼용하여 사용했기 때문에 논문에서도 이러한 혼용이 있는 거 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Patchwise training is loss sampling&lt;/h3&gt;
&lt;p&gt;patchwise training이란 하나의 이미지에서 객체가 존재하는 위치를 crop하여 하나의 patch로 만든 뒤 모델에 입력하는 training 방식이다. patchwise training을 사용하는 이유는 이미지에 필요없는 정보들이 존재할 수 있고 하나의 이미지에서 서로 다른 객체가 존재하는 경우 redundancy가 발생하기 때문이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;고양이와 관련된 feature를 추출해야 하는데 어쩔 수 없이 car가 있는 영역까지 보게 되는 문제&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;patch를 어떤 방식으로 만들어낼 것인지에 따라 다양하겠지만 patch간에 overlap이 일어나지 않는다면 patchwise training과 whole image training이 동일하다. 만약 100x100의 입력 이미지가 있을 때 이를 10x10 grid로 분할하면, 10x10 크기의 patch를 100개 만들어낼 수 있다. 100개의 patch를 모두 조합하면 결국 100x100 이미지가 된다. 이 경우 patch를 뽑아낼 때 overlapping을 적용하지 않은 경우이고, 만약 overlapping을 허용하여 patch를 뽑아내게 되면 더 많은 수의 patch가 만들어진다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;patch를 overlap되지 않게 추출한다고 해도 patchwise training과 whole image training이 동일하다고 말하는 건 조금 동의하기 어렵다. patch들을 전부 모으면 결국 하나의 원본 image가 되겠지만 개별 patch에서 feature를 뽑아내는 것과 image 전체를 보고 feature를 뽑아내는 것에는 명백한 차이가 있기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;patchwise training의 장점은 class imbalance 문제를 완화할 수 있지만 spatial correlation 정보가 부족해지는 단점이 있다. spatial correlation이 부족하다는 것은 결국 이미지의 일부(patch)를 볼 것이냐 이미지 전체를 볼 것이냐의 차이를 말한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;해당 section의 제목이 patchwise training is loss sampling인 이유는 내가 이해한 바로 하나의 이미지를 100개의 patch로 분할하여 각 patch마다 모델에 입력했을 때 100개의 prediction이 나오게 되고 100개의 loss 값이 계산된다. 그럼 여기서 background 같은 중요치 않은 patch들이 존재할 수 있고 object가 포함된 중요한 patch들이 포함되는 경우도 있을 것이다. 따라서 각 patch마다 계산된 loss값을 모두 다 더해서 사용하는 게 아니라 각 loss마다 weight를 주거나 중요한 patch에서 계산된 loss값만 샘플링해서 사용하겠다는 것으로 이해하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;결과적으로 본 논문에선 patchwise training을 사용하지 않았다. 실험에서 whole image training이 dense prediction을 위한 training 속도 측면에서 더 효과적이고 효율적이었다고 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Segmentation Architecture&lt;/h1&gt;
&lt;h2&gt;From classifier to dense FCN&lt;/h2&gt;
&lt;p&gt;AlexNet, VGG, GoogLeNet를 FCN 방식으로 튜닝하였다. GoogLeNet의 경우 네트워크의 중간중간 softmax layer가 존재하는데 해당 layer를 제외하고 final loss layer만 사용하였다. PASCAL VOC dataset의 class 개수를 맞추기 위해 1x1 conv를 사용하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;실험 결과론 VGG가 가장 높은 성능을 보여주었고 GoogLeNet의 경우 segmentation task와 적합하지 않은 모델로 보임&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/bxt0OY/btqVbXnGycc/fXXEtDDY0bHqRwJtYsa8ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxt0OY/btqVbXnGycc/fXXEtDDY0bHqRwJtYsa8ek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxt0OY/btqVbXnGycc/fXXEtDDY0bHqRwJtYsa8ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbxt0OY%2FbtqVbXnGycc%2FfXXEtDDY0bHqRwJtYsa8ek%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;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;Combining what and where&lt;/h2&gt;
&lt;p&gt;입력 이미지가 pooling layer를 거치면서 아래와 같은 비율로 사이즈가 줄어든다. 결과적으로 pool5까지 거치게 되면 feature의 크기는 입력 이미지의 1/32이 된다. (224x224 &amp;rarr; 7x7)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;32배 작아진 feature를 가지고 32배 upsampling 하게 되면 디테일한 정보들이 많이 없는 상태에서 과도하게 크기를 늘리게 때문에 정확한 prediction이 어렵다. 그래서 논문에선 사이즈를 차근차근 증가시키고 coarse feature에서 부족했던 정보를 pool3, pool4에서 가져와서 결합한 뒤 채우겠다는 것이다. coarse feature는 상대적으로 global feature를 담고 있기 때문에 local feature가 부족하고 부족한 local feature를 이전 레이어의 feature에서 가져오겠다는 것&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;conv6: 7x7x512 &amp;rarr; 7x7x4096&lt;/li&gt;
&lt;li&gt;conv7: 7x7x4096 &amp;rarr; 7x7x21&lt;/li&gt;
&lt;/ul&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/ekNAHX/btqVde3ypGq/w56zA4x72j8jLkcjdU9k1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ekNAHX/btqVde3ypGq/w56zA4x72j8jLkcjdU9k1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ekNAHX/btqVde3ypGq/w56zA4x72j8jLkcjdU9k1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FekNAHX%2FbtqVde3ypGq%2Fw56zA4x72j8jLkcjdU9k1K%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;ul&gt;
&lt;li&gt;pool3, pool4에서 가져온 featuer를 2x conv7, 4x conv7과 결합하기 위해선 채널 사이즈를 맞춰주어야 한다. 채널 사이즈 매칭은 1x1 conv를 이용함&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이러한 upsampling을 몇번 수행할 것인지에 따라 FCN-32, FCN-16, FCN-8 3가지 버전의 모델이 만들어지게 된다. 당연히 FCN-8이 더 많은 feature combining을 이용하기 때문에 성능이 높다. upsampling을 더 수행하면 FCN-4, FCN-2도 만들 수 있겠지만 FCN-8까지만 만들었다.&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/doWoj3/btqVbueXPvj/pL8ouYs3MnJJ6tM94ltKF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/doWoj3/btqVbueXPvj/pL8ouYs3MnJJ6tM94ltKF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/doWoj3/btqVbueXPvj/pL8ouYs3MnJJ6tM94ltKF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdoWoj3%2FbtqVbueXPvj%2FpL8ouYs3MnJJ6tM94ltKF0%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Experimental framework&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;optimizer: SGD, momentum: 0.9&lt;/li&gt;
&lt;li&gt;batch size: 20&lt;/li&gt;
&lt;li&gt;learning rate의 경우 각 모델마다 고정된 값을 사용함
&lt;ul&gt;
&lt;li&gt;AlexNet: 1e-3&lt;/li&gt;
&lt;li&gt;VGG16: 1e-4&lt;/li&gt;
&lt;li&gt;GoogLeNet: 1e-5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;실험에서 patch sampling 방식과 full image 방식을 비교하였는데 sampling 방식이 loss 수렴 속도도 늦고 학습 속도도 더 오래 걸린다. 결과적으로 full image 방식을 사용하여 학습하였다.&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/cgbfXZ/btqU94nmbfH/jb2OLwTgVDfK5wh88aIiY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgbfXZ/btqU94nmbfH/jb2OLwTgVDfK5wh88aIiY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgbfXZ/btqU94nmbfH/jb2OLwTgVDfK5wh88aIiY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgbfXZ%2FbtqU94nmbfH%2Fjb2OLwTgVDfK5wh88aIiY0%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;data augmentaton으로 randomly mirroring, jittering, translating 을 사용하였다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;image mirroring은 flip이라고 생각하면 됨&lt;/li&gt;
&lt;li&gt;jittering은 이미지 픽셀 값 자체를 변화(?)시킨 일종의 노이즈 추가로 보인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Result&lt;/h1&gt;
&lt;p&gt;본 논문에서는 4가지 metric을 사용하여 평가한다.&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/LJ937/btqVdNxQmkj/0p5WODxCoHqKepRaZ14l0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LJ937/btqVdNxQmkj/0p5WODxCoHqKepRaZ14l0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LJ937/btqVdNxQmkj/0p5WODxCoHqKepRaZ14l0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLJ937%2FbtqVdNxQmkj%2F0p5WODxCoHqKepRaZ14l0k%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;&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;/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/rpnso/btqU92Qx9fE/kFDvXtZcK4KUiLycY7Axc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rpnso/btqU92Qx9fE/kFDvXtZcK4KUiLycY7Axc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rpnso/btqU92Qx9fE/kFDvXtZcK4KUiLycY7Axc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frpnso%2FbtqU92Qx9fE%2FkFDvXtZcK4KUiLycY7Axc0%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;&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/B6e8v/btqVdeWLxcr/vawD8kK5yLbtiOsLaP1jik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B6e8v/btqVdeWLxcr/vawD8kK5yLbtiOsLaP1jik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B6e8v/btqVdeWLxcr/vawD8kK5yLbtiOsLaP1jik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB6e8v%2FbtqVdeWLxcr%2FvawD8kK5yLbtiOsLaP1jik%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;&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/lYKi9/btqVbv51fCL/Gqu1kx2NKBK9c3x4TLsI00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lYKi9/btqVbv51fCL/Gqu1kx2NKBK9c3x4TLsI00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lYKi9/btqVbv51fCL/Gqu1kx2NKBK9c3x4TLsI00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlYKi9%2FbtqVbv51fCL%2FGqu1kx2NKBK9c3x4TLsI00%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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;각 실험 table에서 다른 모델과 비교했을 때 FCN 구조가 SOTA를 달성하였다.&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;아래 prediction 결과를 봤을 때 굉장히 작은 부분까지 정교하게 예측하기엔 어려워 보인다. 특히 4번째 row를 봤을 때 구명조끼를 사람으로 잘못 인식한 결과를 보여주었다.&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/q0LUA/btqU94nmb7S/2O0E4iO9CUnBBe16TQ8351/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q0LUA/btqU94nmb7S/2O0E4iO9CUnBBe16TQ8351/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q0LUA/btqU94nmb7S/2O0E4iO9CUnBBe16TQ8351/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq0LUA%2FbtqU94nmb7S%2F2O0E4iO9CUnBBe16TQ8351%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;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;modern classification model을 fcn 방식으로 재구성하여 semantic segmentation task를 풀고자 하였다.&lt;/p&gt;
&lt;p&gt;향후 multi-resolution layer 같은 아키텍처 튜닝을 통해 더욱 성능을 개선할 것으로 보고 이와 동시에 모델 구조 또한 심플하게 구축한다면 학습, 인퍼런스 속도 또한 개선할 수 있다.&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;my opinion&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;기존 classification model을 응용하여 semantic segmentation task를 해결한 모델로 semantic segmentation 대표 모델 중 하나로 꼽히는 중요한 논문이다.&lt;/li&gt;
&lt;li&gt;고정된 입력 사이즈를 해결하고, 효과적인 upsampling, skip connection 등의 여러 technique을 결합하여 SOTA를 달성했다는 점 그럼에도 모델 구조 자체가 복잡하지 않고 심플함&lt;/li&gt;
&lt;li&gt;이미지의 작고 디테일한 영역까지 정교하게 segmentation하기 어려워 보이고 인간보다 높은 segmentation 성능을 내려면 아직 갈 길이 멀다.&lt;/li&gt;
&lt;li&gt;fully connected layer를 convolution으로 변환하는 conv6 layer의 경우 7x7 kernel을 사용하는 것보다 1x1 kernel을 사용하는 것이 파라미터 수, 연산량 측면에서 더 효율적일 것 같다는 생각이 듦&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>ML &amp;amp; DL/Paper Review</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/118</guid>
      <comments>https://eremo2002.tistory.com/118#entry118comment</comments>
      <pubDate>Fri, 29 Jan 2021 23:29:59 +0900</pubDate>
    </item>
    <item>
      <title>Densely Connected Convolutional Networks</title>
      <link>https://eremo2002.tistory.com/116</link>
      <description>&lt;h1&gt;Abstract&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;feed forward 방식으로 레이어를 연결한 DenseNet이라는 새로운 아키텍처를 제안한다.&lt;/li&gt;
&lt;li&gt;이전 레이어의 모든 feature map이 다음 레이어로 입력된다.&lt;/li&gt;
&lt;li&gt;DenseNet은 gradient vanishing, strengthen feature propagation, encourage feature reuse, reduce the number of parameters 측면에서 큰 장점을 갖는다.&lt;/li&gt;
&lt;li&gt;DenseNet은 less computation으로 STOA를 달성함&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CNN이 깊어지면서 feature information, gradient가 많은 레이어를 지나가면서 vanish되는 문제가 발생함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이러한 문제를 해결하기 위해 ResNet, Highway Networks, FractalNet 등등.. 많은 네트웍들이 제안되었지만 이러한 approach들이 가지고 있는 한 가지 특징은 early layer에서 later layer로 가는 short path를 사용했다는 점&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그러나 본 논문에서는 기존의 short path pattern을 distill하고 네트워크의 레이어 사이에서 information flow가 원활히 이루어지도록 각 레이어를 모두 연결한 connectivity pattern을 사용함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;각 레이어는 이전의 모든 레이어에서 나온 feature map을 입력으로 받으며, 자신의 output feature map을 이후에 있는 모든 레이어에 전달하는 구조&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;321&quot; height=&quot;270&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmY7tN/btqDzEe5iil/ZQTLrfbJCvwJWkpPwKpdD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmY7tN/btqDzEe5iil/ZQTLrfbJCvwJWkpPwKpdD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmY7tN/btqDzEe5iil/ZQTLrfbJCvwJWkpPwKpdD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmY7tN%2FbtqDzEe5iil%2FZQTLrfbJCvwJWkpPwKpdD0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;321&quot; height=&quot;270&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;ul&gt;
&lt;li&gt;
&lt;p&gt;ResNet에선 feature map끼리 summation했지만 DenseNet에선 feature concat&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;L번째 레이어는 이전 레이어에서 온 L개의 input을 입력으로 받게 되고 자신의 feature map을 자기 뒤에 있는 L-l개의 레이어에 전달해줌. 따라서 네트워크에 총 L개의 레이어가 존재할 때 L(L+1)/2개의 connection이 존재하게 됨&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이러한 dense connectivity pattern은 traditional CNN보다 파라미터 수가 적으며 중복된 feature map을 재학습할 필요가 없어진다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;또한 DenseNet의 구조는 information flow를 개선하여 네트워크에서 gradient가 사라지는 문제를 방지하여 학습이 쉬워진다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Related Work&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Highway Network는 bypassing path를 통해 100개 이상의 레이어를 사용하는 deep model에서도 학습이 효과적으로 이루어지게 함&lt;/li&gt;
&lt;li&gt;다양한 task에서 뛰어난 성능을 보여준 ResNet에서 레이어를 1202개까지 늘렸을 때 오히려 성능이 떨어졌음. stochastic depth에서는 ResNet-1202를 학습하면서 랜덤하게 특정 레이어를 dropping시켜 성공적으로 학습하였음. 이 결과로 1202개 레이어에서 모든 레이어가 반드시 필요한 것이 아니며 이렇게 많은 레이어를 사용하는 것은 redundancy가 커지게 되는 문제가 있다는 것을 말해줌&lt;/li&gt;
&lt;li&gt;다양한 approach들이 있지만, DenseNet은 레이어를 deep하게 쌓거나 wide한 아키텍처로 인해 representational power가 떨어지는 것이 아닌 네트워크 내에서 feature reuse를 통해 condensed된 모델을 만들어 파라미터 수를 줄이고 쉽게 학습할 수 있는 방향을 선택함&lt;/li&gt;
&lt;li&gt;다른 레이어들에서 학습된 feature map을 서로 concat하는 것은 variation을 증가시킴.&lt;/li&gt;
&lt;li&gt;Inception에서도 다른 레이어서 나온 feature를 연결하는 구조를 취하는데, DenseNet이 훨씬 심플하며 효율적인 구조임&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;DenseNets&lt;/h1&gt;
&lt;h3&gt;Dense Connectivity&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Denotement&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;x_{0} = single image&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;non-linear transormation(BN, ReLU, Pooling, Conv 등..)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;399&quot; height=&quot;82&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zqd73/btqDyMEIGsz/ZzocVqawb7Ei3lkWdQYDE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zqd73/btqDyMEIGsz/ZzocVqawb7Ei3lkWdQYDE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zqd73/btqDyMEIGsz/ZzocVqawb7Ei3lkWdQYDE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzqd73%2FbtqDyMEIGsz%2FZzocVqawb7Ei3lkWdQYDE0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;399&quot; height=&quot;82&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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ResNet은 skip connection에서 온 feature와 non-linear transformation feature끼리 summation하지만 이러한 방식은 네트워크에서 information flow가 지연될 수 있음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;레이어 간의 information flow를 improve하기 위해 resnet과 다른 dense connectivity를 제안함&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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/ba1lYK/btqDA6vxzb1/1X0DM2PBY9GgmhAVUN8Cn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba1lYK/btqDA6vxzb1/1X0DM2PBY9GgmhAVUN8Cn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba1lYK/btqDA6vxzb1/1X0DM2PBY9GgmhAVUN8Cn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba1lYK%2FbtqDA6vxzb1%2F1X0DM2PBY9GgmhAVUN8Cn1%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;ul&gt;
&lt;li&gt;x0, x1, ...xl-1은 0번째 레이어부터 l-1번째 레이어의 feature map을 모두 concat한 feature map. 이러한 dense connectivity 구조를 취하기 때문에 제안하는 네트워크 아키텍처의 이름을 DenseNet이라 부름&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Composite function&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;composite function H_l을 BN, ReLU, 3x3 conv 순서대로 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Pooling layers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;concatenation operation은 feature map의 width, height dimension이 일치해야 함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DenseNet의 dense connectivity는 dense block내에서 이루어지며 spatial size를 down-sampling하기 위해 dense block 사이에 transition layer를 추가함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;transition layer는 BN, 1x1 conv, 2x2 avg pooling&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;722&quot; height=&quot;140&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVgtYX/btqDCYwK66R/HUgeQKaH5kKbWhh47liliK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVgtYX/btqDCYwK66R/HUgeQKaH5kKbWhh47liliK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVgtYX/btqDCYwK66R/HUgeQKaH5kKbWhh47liliK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVgtYX%2FbtqDCYwK66R%2FHUgeQKaH5kKbWhh47liliK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;722&quot; height=&quot;140&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;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Growth rate&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;input layer의 feature map을 제외하고 convolution layer에서 만들어지는 feature map의 채널 수를 조절하기 위한 하이퍼파라미터 growth rate&lt;/li&gt;
&lt;li&gt;각 레이어에서 k개의 feature map을 만들어내도록 함. 모든 conv layer에서 사용되는 필터의 개수를 k개로 고정시킴. DenseNet에선 이전 레이어의 모든 feature map을 concat하기 때문에 뒤로 갈수록 feature map의 채널 수가 많아짐.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Bottleneck layers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;각 레이어에서 채널 수가 k개인 output feature map을 만들어냄. k가 작은 값이더라도 레이어가 쌓일 수록 채널 수가 굉장히 많아지기 때문에 채널 수를 조절하기 위한 bottleneck layer를 사용&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;467&quot; height=&quot;260&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IgWYf/btqDzk89MV7/K4EZXSo1Q2CXnLd7c4I0Pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IgWYf/btqDzk89MV7/K4EZXSo1Q2CXnLd7c4I0Pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IgWYf/btqDzk89MV7/K4EZXSo1Q2CXnLd7c4I0Pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIgWYf%2FbtqDzk89MV7%2FK4EZXSo1Q2CXnLd7c4I0Pk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;467&quot; height=&quot;260&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;ul&gt;
&lt;li&gt;
&lt;p&gt;1x1 conv에서 채널 수가 growth rate*4인 feature map을 만들고 3x3 conv에서는 growth rate만큼 채널 수를 가지는 feature를 뽑음&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;493&quot; height=&quot;274&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/sY3Mo/btqDDYQyyVb/sRgWPpVobx3ae5rslSykP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sY3Mo/btqDDYQyyVb/sRgWPpVobx3ae5rslSykP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sY3Mo/btqDDYQyyVb/sRgWPpVobx3ae5rslSykP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsY3Mo%2FbtqDDYQyyVb%2FsRgWPpVobx3ae5rslSykP1%2Fimg.png&quot; width=&quot;493&quot; height=&quot;274&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;ul&gt;
&lt;li&gt;
&lt;p&gt;bottleneck layer에서 BN-ReLU-Conv(1x1)-BN-ReLU-Conv(3x3)를 사용하는 버전을 DenseNet-B라고 부름. DenseNet-B(Bottleneck)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Compression&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;model의 compactness를 improve하기 위해 transition layer에서 feature map size를 조절함.&lt;/li&gt;
&lt;li&gt;dens block에서 m개의 feature map이 나왔다면 transition layer에선 &amp;theta;m개의 output feature map을 generate함&lt;/li&gt;
&lt;li&gt;&amp;theta;값은 0 &amp;lt; &amp;theta; &amp;le; 1이며, &amp;theta;=1인 경우 feature map의 채널 수는 바뀌지 않음&lt;/li&gt;
&lt;li&gt;&amp;theta; &amp;lt; 1인 버전을 DenseNet-C(Compression)라고 하며, 실험에선 &amp;theta;=0.5로 설정함&lt;/li&gt;
&lt;li&gt;DenseNet-B와 DenseNet-C를 합친 버전을 DenseNet-BC라 부름&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Implementation Details&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;이미지넷을 제외한 모든 데이터셋에서는 dense block이 3개인 DenseNet을 사용하였으며 모든 dense block 안에서 반복되는 레이어 수는 같음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;first dense block으로 들어가기 전에 input image는 3x3 convolution layer를 한번 거침&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;마지막 dense block하고 나서 global average pooling 및 softmax classifier로 연결&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;실험에 사용하는 DenseNet-BC는 4개의 Dense Blcok으로 구성, {L = 100, k = 12}, {L = 250, k = 24}, {L = 190, k = 40}&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;625&quot; height=&quot;289&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9yzh3/btqDA6oEvhJ/tDPUGI2kT9196bOUEkezBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9yzh3/btqDA6oEvhJ/tDPUGI2kT9196bOUEkezBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9yzh3/btqDA6oEvhJ/tDPUGI2kT9196bOUEkezBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9yzh3%2FbtqDA6oEvhJ%2FtDPUGI2kT9196bOUEkezBk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;625&quot; height=&quot;289&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;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Experiments&lt;/h1&gt;
&lt;h3&gt;Classification Result on CIFAR and SVHN&lt;/h3&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;595&quot; height=&quot;376&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVtBkc/btqDzDHqbpZ/3mpBM2sDwKoQ3yi5AxvWFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVtBkc/btqDzDHqbpZ/3mpBM2sDwKoQ3yi5AxvWFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVtBkc/btqDzDHqbpZ/3mpBM2sDwKoQ3yi5AxvWFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVtBkc%2FbtqDzDHqbpZ%2F3mpBM2sDwKoQ3yi5AxvWFk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;595&quot; height=&quot;376&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;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DenseNet-BC (L=190, k=40) 모델이 CIFAR-10, CIFAR100 datasest에서 SOTA를 달성함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SVHN dataset에서도 ResNet 보다 더 좋은 성능을 보여줌&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SVHN dataset에서 Depth가 250인 모델이 100인 모델보다 성능이 떨어지는 결과를 보임. 이는 SVHN classification이 상대적으로 easy한 task이기 때문에 deep model이 training set에 오버피팅 된 것으로 보임&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;bottleneck layer와 compression을 사용하지 않은 일반 DenseNet에서 depth와 k가 커질수록 성능이 개선되는 결과를 보임. 이는 DenseNet 구조가 bigger and deeper model에서 증가된 representational power를 잘 utilize할 수 있기 때문&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;파라미터 수를 비교했을 때 ResNet이나 FractalNet보다 더 적은 파라미터로 높은 성능을 달성함. 이는 파라미터 측면에서도 DenseNet이 효율적이고 특히 DenseNet-BC를 사용하면 파라미터를 더욱 효율적으로 줄일 수 있음&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;아래 Fig 4, right C10+ dataset에 대한 training, test loss&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;615&quot; height=&quot;207&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dw1KKJ/btqDzk89Ocj/7gRCspgbpLWcBTBFqWF5D1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dw1KKJ/btqDzk89Ocj/7gRCspgbpLWcBTBFqWF5D1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dw1KKJ/btqDzk89Ocj/7gRCspgbpLWcBTBFqWF5D1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdw1KKJ%2FbtqDzk89Ocj%2F7gRCspgbpLWcBTBFqWF5D1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;615&quot; height=&quot;207&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;ul&gt;
&lt;li&gt;
&lt;p&gt;Middle) 같은 수준의 accuracy를 달성한 지점에서 DenseNet은 ResNet보다 1/3가량 더 적은 파라미터만 사용했음에도 불구하고 같은 성능을 냄&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DenseNet-BC (L=100, k=12)는 1001개의 레이어를 사용한 ResNet-1001보다 90%적은 파라미터만 사용하였음에도 불구하고 비슷한 test error 결과를 보임&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DenseNet의 효율적인 파라미터 사용이 오버피팅되는 문제를 방지해주는 효과가 있음&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;
&lt;p&gt;ImageNet Classification에서 DenseNet의 depth와 growth rate을 바꿔가며 ResNet과 비교&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;651&quot; height=&quot;193&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/oRDZB/btqDyFsgoIH/TTvJR2mHtPmLhhqJwQRo41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oRDZB/btqDyFsgoIH/TTvJR2mHtPmLhhqJwQRo41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oRDZB/btqDyFsgoIH/TTvJR2mHtPmLhhqJwQRo41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoRDZB%2FbtqDyFsgoIH%2FTTvJR2mHtPmLhhqJwQRo41%2Fimg.png&quot; width=&quot;651&quot; height=&quot;193&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;ul&gt;
&lt;li&gt;
&lt;p&gt;공정한 비교를 위해 데이터 pre-processing, optimization setting 등을 똑같이 세팅하여 실험&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ResNet과 비슷한 성능을 내는 수준에서 비교했을 때, 파라미터나 연산량이 훨씬 효율적임&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Discussion&lt;/h1&gt;
&lt;h3&gt;Implicit Deep Supervision.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;DenseNet이 잘 되는 이유는 각 레이어들이 shorter connection으로 loss function으로부터 additional supervision을 갖기 때문&lt;/li&gt;
&lt;li&gt;다시 말해, DenseNet은 &quot;deep supervision&quot;과 같은 역할을 수행할 수 있음.
&lt;ul&gt;
&lt;li&gt;deep supervision이란 Deep 뉴럴넷에서 classifier를 여러 개 두어 성능을 올리는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Deeply-supervised nets(DSN)에서 모든 히든 레이어에 classifier를 추가하여 intermediate layer들이 discriminative feature를 더욱 잘 학습하게 만들기 때문&lt;/li&gt;
&lt;li&gt;DenseNet은 classifier가 transition layer를 통해 모든 레이어에 supervision을 전달해주기 때문에 deep supervision과 비슷한 역할을 하며 singe classifier만 사용하기 less complicate하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Stochastic vs. deterministic connection.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;stochastic depth regularization이란 네트워크에서 레이어를 일정하게 drop하는 기법으로 dropout과 비슷하게 일정 확률로 특정 레이어를 drop시켜 주위에 있는 다른 레이어와 연결되게 만드는 것&lt;/li&gt;
&lt;li&gt;이러한 connectivity pattern이 DenseNet과 비슷한 면이 있음. 궁극적으론 차이가 있지만 랜덤하게 끊어진 레이어가 다른 레이어들에 연결되는 패턴이 DenseNet의 dense connectivity 패턴과 비슷하기 때문&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Feature Reuse.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Target layer(l), Source layer(s)가 있을 때, (ℓ, s)는 레이어 l이 이전 레이어 s에서 나온 정보를 얼마나 많이 사용하는지 나타냄&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;예를 들어, (12, 1), (12, 2), (12, 3)처럼 target layer와 source layer의 거리가 먼 경우 상대적으로 값이 작지만 (12, 9), (12, 10), (12, 11)은 값이 큼&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The color of pixel encodes the average L1 norm of the weights connecting convolutional layer s to ℓ&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;389&quot; height=&quot;301&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UCD1Q/btqDBA4dQgT/22a6HalUK3nq3lD8BXXlK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UCD1Q/btqDBA4dQgT/22a6HalUK3nq3lD8BXXlK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UCD1Q/btqDBA4dQgT/22a6HalUK3nq3lD8BXXlK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUCD1Q%2FbtqDBA4dQgT%2F22a6HalUK3nq3lD8BXXlK1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;389&quot; height=&quot;301&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;ul&gt;
&lt;li&gt;
&lt;p&gt;early layer에서 추출된 feature가 deep layer에 잘 전달됨&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;transition layer도 이전 dense block에서 추출된 feature를 잘 살려서 다음 레이어에 전달하는 것으로 보아 information flow가 원활히 이루어짐&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dense Block 2, 3에서 첫번째 레이어들은 transition layer output에 영향을 미치는 정도가 낮아 transition layer는 redundant feature를 다루게 되는 경향이 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Classification layer는 전반적으로 entire dense block의 feature를 사용하지만 classification layer와 인접한 레이어의 weight가 밝은 것으로 보아 classifier는 high-level feature에 더 집중하는 경향이 있음&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Dense connectivity 구조를 적용한 DenseNet이라는 새로운 CNN아키텍처를 제안함&lt;/li&gt;
&lt;li&gt;DenseNet의 레이어가 수백개가 되더라도 학습에 문제가 없었고 DenseNet의 파라미터가 증가할수록 overfitting이나 degradation 문제없이 accuracy가 증가함&lt;/li&gt;
&lt;li&gt;fewer parameters and less computation으로 SOTA를 달성함&lt;/li&gt;
&lt;li&gt;제안하는 simple connectivity rule로 DenseNet은 identity mapping, deep supervision, diversified depth등 여러 특성을 integrate함.&lt;/li&gt;
&lt;li&gt;이를 통해 네트워크 전체에서 feature reuse를 할 수 있고 성능을 높일 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;References&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=-W6y8xnd--U&quot;&gt;https://www.youtube.com/watch?v=-W6y8xnd--U&lt;/a&gt;&lt;/p&gt;</description>
      <category>ML &amp;amp; DL/Paper Review</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/116</guid>
      <comments>https://eremo2002.tistory.com/116#entry116comment</comments>
      <pubDate>Wed, 22 Apr 2020 00:19:25 +0900</pubDate>
    </item>
    <item>
      <title>Deep Residual Learning for Image Recognition</title>
      <link>https://eremo2002.tistory.com/115</link>
      <description>&lt;h1&gt;Abstract&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Deep neural net은 학습시키기 어렵다는 문제가 있다. 그러나 본 논문에서는 residual learning framework을 통해 깊은 신경망도 잘 학습시킬 수 있다.&lt;/li&gt;
&lt;li&gt;제안하는 residual network는 optimize가 쉽고 상당히 깊은 depth를 가지는 뉴럴넷에서도 성능을 낼 수 있다.&lt;/li&gt;
&lt;li&gt;VGG보다 8배 많은 152개의 레이어를 사용했음에도 성능이 좋았다. (레이어 수는 훨씬 많지만 실제 Complexity 측면에선 오히려 ResNet이 VGG보다 lower complexity)&lt;/li&gt;
&lt;li&gt;Classification뿐만 아니라 detection, localization, segmentation등 다양한 task에서 SOTA를 달성했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;1. Introduction&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Deep 뉴럴넷은 low/mid/high level의 enrich feature를 만들어낼 수 있다는 점에서 좋은 성능을 보여주고 있다. 따라서 신경망의 depth는 매우 중요한 요소라 할 수 있다.&lt;/li&gt;
&lt;li&gt;그렇다면 레이어를 많이 쌓아올리는 것은 네트워크를 더 쉽게 학습시킨다고 볼 수 있을까?
&lt;ul&gt;
&lt;li&gt;Degradation(gradient vanishing, gradient exploding)이라는 문제가 있다.
&lt;ul&gt;
&lt;li&gt;Gradient vanishing은 gradient값이 너무 작아서 네트워크를 제대로 학습시키지 못하는 문제를 말한다. 이 문제는 입력값에 비해 출력값이 너무 작은 space로 맵핑될 때 발생할 수 있으며 레이어가 깊어질수록 발생하는 문제이다. activation function으로 sigmoid or tanh 함수를 사용할 때 발생할 수 있음&lt;/li&gt;
&lt;li&gt;Gradient exploding은 gradient vanishing과 반대로 gradient 값이 너무 커져서 발산해버리는 문제&lt;/li&gt;
&lt;li&gt;Layer를 더 많이 사용했는데 degradation으로 인해 오히려 error가 더 높음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;404&quot; height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F41Yc/btqDCZoURC2/kjRdYZGu7c0IXCbvK11x71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F41Yc/btqDCZoURC2/kjRdYZGu7c0IXCbvK11x71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F41Yc/btqDCZoURC2/kjRdYZGu7c0IXCbvK11x71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF41Yc%2FbtqDCZoURC2%2FkjRdYZGu7c0IXCbvK11x71%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;404&quot; height=&quot;212&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;네트워크의 depth를 늘리는 것은 이러한 degradation 문제를 일으킨다. degradation문제는 모델의 오버피팅으로 인해 발생하는 것이 아니라 레이어를 더 많이 쌓아올려 모델의 training error가 더 커지게 만든다. 즉 degradation은 training 과정에서 네트워크를 최적화하기 어렵게 만든다고 볼 수 있다.&lt;/li&gt;
&lt;li&gt;shallower 모델과 deeper 모델을 가정했을 때 deeper model에 제안하는 identity mapping 레이어를 추가하면 deeper model의 성능이 shallower model보다 더 높아질 수 있다.&lt;/li&gt;
&lt;li&gt;따라서 본 논문에서는 degradation problem을 해결하기 위한 deep residual learning framework를 제안한다.&lt;/li&gt;
&lt;/ul&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;320&quot; height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/deFQ1I/btqDzkgVqYA/mXsxmmSTWRxZvK457b8mI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/deFQ1I/btqDzkgVqYA/mXsxmmSTWRxZvK457b8mI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/deFQ1I/btqDzkgVqYA/mXsxmmSTWRxZvK457b8mI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdeFQ1I%2FbtqDzkgVqYA%2FmXsxmmSTWRxZvK457b8mI1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;320&quot; height=&quot;170&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;x는 input, F(x)는 일반적인 Conv, BN, relu 같은 레이어를 거친 것을 의미한다. F(x)에 shortcut connection으로 x를 더해주어 F(x)가 아닌 F(x)+x를 다음 레이어로 전달한다. 여기서 shortcut connection이란 하나 이상의 레이어를 skipping하는 걸 말한다.&lt;/li&gt;
&lt;li&gt;Deep residual net은 단순하게 레이어만 쌓아올린 plain network보다 최적화가 쉽고 성능이 더 높다. 또한 네트워크의 depth가 증가하더라도 좋은 performance를 낼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;3. Deep Residual Learning&lt;/h1&gt;
&lt;h3&gt;Residual Learning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;기존의 뉴럴넷은 아래 왼쪽 그림과 같이 레이어를 쌓아 입력 x값이 target값 y를 잘 맵핑하는 H(x)를 찾는 것이 목표였다.&lt;/li&gt;
&lt;/ul&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;290&quot; height=&quot;239&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsaDdC/btqDDvgLvUP/GDYZpyskzAi6QWtkzFhLZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsaDdC/btqDDvgLvUP/GDYZpyskzAi6QWtkzFhLZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsaDdC/btqDDvgLvUP/GDYZpyskzAi6QWtkzFhLZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsaDdC%2FbtqDDvgLvUP%2FGDYZpyskzAi6QWtkzFhLZ0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;290&quot; height=&quot;239&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;ul&gt;
&lt;li&gt;
&lt;p&gt;그러나 Residual block에선 H(x)가 F(x) + x가 된다. (여기서 F(x)는 weight layer와 ReLu를 의미한다.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Residual block에서 x는 F(x)와 element-wise add연산이 이루어지기 때문에 x는 변하지 않는 값으로 볼 수 있다. 만약 H(x) = F(x) + x에서 F(x)가 0이라면 H(x) = x가 되고 입력값과 출력값이 같아지게 된다. 그러므로 F(x)가 0에 가까울만큼 매우 작은 값이라면 H(x)는 입력 x와 매우 비슷하다고 볼 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;따라서 ResNet에선 적절한 H(x)를 찾는 것이 아니라 적절한 residual function F(x) = H(x) - x를 찾는 것이 목표가 된다. 여기서 H(x) - x를 residual(잔차)라 부르며 이 값이 최소가 되도록 학습하기 때문에 Residual learning이라 부른다. 또한 이러한 element-wise add연산은 추가적인 파라미터를 필요로 하지 않기 때문에 Complexity를 증가시키지도 않는다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;따라서 학습의 방향이 어느정도 정해져있고(?) back-propagation 과정에서 기울기가 사라지지 않기 때문에 gradient vanishing 문제를 방지할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;논문에서 제안하는 residual block은 아래 수식 (1)과 같이 정의할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;여기서 x, y는 input, output이며 function F는 Conv, relu Conv를 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;254&quot; height=&quot;82&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o7JqG/btqDAC2s0Sk/jOtp7YUrKGbPGgPkR0cc40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o7JqG/btqDAC2s0Sk/jOtp7YUrKGbPGgPkR0cc40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o7JqG/btqDAC2s0Sk/jOtp7YUrKGbPGgPkR0cc40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo7JqG%2FbtqDAC2s0Sk%2FjOtp7YUrKGbPGgPkR0cc40%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;254&quot; height=&quot;82&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;한가지 주의해야할 점은 F + x는 element-wise addition 연산이기 때문에 dimension이 일치해야 한다. dimension이 일치하지 않는 경우 linear projection을 사용하여 dimension을 맞춰준다.&lt;/li&gt;
&lt;/ul&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;298&quot; height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6CRVF/btqDDYptSVN/G6yMITjq2KQVB49M2g9rjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6CRVF/btqDDYptSVN/G6yMITjq2KQVB49M2g9rjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6CRVF/btqDDYptSVN/G6yMITjq2KQVB49M2g9rjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6CRVF%2FbtqDDYptSVN%2FG6yMITjq2KQVB49M2g9rjK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;298&quot; height=&quot;45&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Network Architectures&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;네트워크 간 비교에서 VGG19, Plain net, ResNet34를 비교한다.&lt;/li&gt;
&lt;li&gt;Residual block에서 element-wise add 연산은 dimension이 서로 일치해야 하기 때문에 채널 수가 다른 경우 1x1 conv를 통해 채널 수를 맞춰준 뒤 add연산한다.&lt;/li&gt;
&lt;li&gt;ResNet의 shortcut connection은 identity mapping으로 element-wise add연산을 수행하기 때문에 dimension이 일치해야 한다. 아래 그림에서 실선은 일반적인 shortcut connection이고 점선의 경우 dimension이 일치하지 않기 때문에 dimension을 증가시켜 연산한다.&lt;/li&gt;
&lt;li&gt;dimension을 증가시키기 위한 방법으로 2가지를 고려해볼 수 있음
&lt;ol&gt;
&lt;li&gt;zero padding을 이용하여 dimension을 맞춰줌 (이 경우 추가적인 파라미터는 없음)&lt;/li&gt;
&lt;li&gt;1x1 convolution을 이용하여 dimension을 맞춰줌. (shortcut connection으로 오는 x에 1x1 conv를 사용하여 dimension matching하는 걸 projection shortcut이라 부름)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&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/dmWPrX/btqDCbC3h4V/4wPsSG1lsuYt1medVvWGRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmWPrX/btqDCbC3h4V/4wPsSG1lsuYt1medVvWGRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmWPrX/btqDCbC3h4V/4wPsSG1lsuYt1medVvWGRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdmWPrX%2FbtqDCbC3h4V%2F4wPsSG1lsuYt1medVvWGRk%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;/figure&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;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ResNet 아키텍처 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;628&quot; height=&quot;227&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;325&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0FHBO/btqDCajXQwl/1jE30KFstXTz8gDkl2vbSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0FHBO/btqDCajXQwl/1jE30KFstXTz8gDkl2vbSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0FHBO/btqDCajXQwl/1jE30KFstXTz8gDkl2vbSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0FHBO%2FbtqDCajXQwl%2F1jE30KFstXTz8gDkl2vbSk%2Fimg.png&quot; width=&quot;628&quot; height=&quot;227&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;325&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;0&quot; data-origin-height=&quot;0&quot; width=&quot;470&quot; height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9V8RS/btqDA5KddsM/Xa1OKQb1wKLanZxxcJKpWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9V8RS/btqDA5KddsM/Xa1OKQb1wKLanZxxcJKpWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9V8RS/btqDA5KddsM/Xa1OKQb1wKLanZxxcJKpWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9V8RS%2FbtqDA5KddsM%2FXa1OKQb1wKLanZxxcJKpWK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;470&quot; height=&quot;232&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;4. Expriments&lt;/h1&gt;
&lt;h3&gt;Plain Networks.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ImageNet error, 얇은선 = training error, 굵은 선 = validation error&lt;/li&gt;
&lt;li&gt;Plain Network의 경우(아래 그림 왼쪽) 레이어를 더 많이 사용했을 경우 error가 더 높았다.&lt;/li&gt;
&lt;li&gt;그러나 논문에서 제안하는 Residual block을 적용했을 경우 레이어가 더 많은 모델의 성능이 더 높은 것을 확인할 수 있다.&lt;/li&gt;
&lt;li&gt;이 실험에서 plain network의 성능이 안 좋은 이유는 degradation문제가 아니고 단지 제안하는 solution을 적용했을 때 잘 작동한다는 것을 보여주는 결과임&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;628&quot; height=&quot;219&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SvOxA/btqDyNKAS41/ETUSJ40vuW0tkF6K6ucdd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SvOxA/btqDyNKAS41/ETUSJ40vuW0tkF6K6ucdd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SvOxA/btqDyNKAS41/ETUSJ40vuW0tkF6K6ucdd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSvOxA%2FbtqDyNKAS41%2FETUSJ40vuW0tkF6K6ucdd1%2Fimg.png&quot; width=&quot;628&quot; height=&quot;219&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;308&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;h3&gt;Residual Networks.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;3가지 major observation&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ResNet-18보다 ResNet-34가 training error도 낮고 validation data에 대해서 일반화가 더 잘되는 걸 볼 수 있다. 이는 ResNet이 degradation 문제를 잘 잡아주고 네트워크의 depth를 늘렸을 때도 좋은 성능을 얻을 수 있다는 걸 의미한다.&lt;/li&gt;
&lt;li&gt;plain-34, ResNet-34를 비교했을 때 ResNet의 성능이 더 높으며 이는 residual learning이 deep 모델에서 잘 작동하며 효과적임&lt;/li&gt;
&lt;li&gt;plain-18, ResNet-18을 비교했을 때 성능면에서 크게 차이가 나지 않는다. 그러나 ResNet의 수렴이 훨씬 빨랐다. ResNet의 최적화가 더 빠르고 쉽다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;496&quot; height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6I7Hg/btqDDZaQ4rk/3fBslCB2jsZhTf6JjQWB1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6I7Hg/btqDDZaQ4rk/3fBslCB2jsZhTf6JjQWB1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6I7Hg/btqDDZaQ4rk/3fBslCB2jsZhTf6JjQWB1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6I7Hg%2FbtqDDZaQ4rk%2F3fBslCB2jsZhTf6JjQWB1k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;496&quot; height=&quot;156&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Identity vs. Projection Shortcuts.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;short connection으로 element-wise add연산을 할 때는 dimension이 일치해야 한다. dimension이 일치하지 않는 경우 이를 맞춰주기 위해 linear projection을 사용한다. Table 3에서 ResNet-A, B, C는 서로 다른 유형의 linear projection을 사용하였다.&lt;/p&gt;
&lt;p&gt;A. zero-padding shortcut: dimension을 늘리기 위한 경우에 사용&lt;/p&gt;
&lt;p&gt;B. projection shortcut: dimension을 늘리기 위한 경우에만 사용하고 나머지 shortcut에선 일반적인 identity mapping 사용&lt;/p&gt;
&lt;p&gt;C. 모든 shortcut을 projection (모든 shortcut connection이 projection shortcut이라는 뜻인듯)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;405&quot; height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cri4mn/btqDzjoOgtZ/LVTVY1u3jL4oVuJK7jeboK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cri4mn/btqDzjoOgtZ/LVTVY1u3jL4oVuJK7jeboK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cri4mn/btqDzjoOgtZ/LVTVY1u3jL4oVuJK7jeboK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcri4mn%2FbtqDzjoOgtZ%2FLVTVY1u3jL4oVuJK7jeboK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;405&quot; height=&quot;298&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A, B, C 모두 plain-34보단 성능이 좋다.&lt;/li&gt;
&lt;li&gt;B는 A보다 조금 더 better하다. A의 zero-padded dimension, 즉 0으로 채워진 부분은 residual learning이 아니기 때문&lt;/li&gt;
&lt;li&gt;C는 B보다 조금 좋긴하지만 projection shortcut에 의해 추가적인 파라미터가 발생한다는 단점이 있다. 따라서 projection shortcut은 더 이상 사용하지 않는다.&lt;/li&gt;
&lt;li&gt;Identity shortcut은 parameter free하다는 점도 중요함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Deeper Bottleneck Architectures.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Deeper Network의 경우 오른쪽과 같은 bottleneck design을 적용한 residual block을 사용한다.&lt;/li&gt;
&lt;li&gt;여기서 1x1을 사용하는 이유는 cost를 줄이기 위해 dimension을 줄이고 이후 element-wise add 연산을 위해 다시 dimension을 맞춰주기 위해 사용한다.&lt;/li&gt;
&lt;li&gt;이러한 구조가 projection shortcut 구조보다 더 효율적임&lt;/li&gt;
&lt;/ul&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;372&quot; height=&quot;188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cldVSy/btqDzjPRhKy/f9CRfK8stSbwdhRbEIoIG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cldVSy/btqDzjPRhKy/f9CRfK8stSbwdhRbEIoIG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cldVSy/btqDzjPRhKy/f9CRfK8stSbwdhRbEIoIG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcldVSy%2FbtqDzjPRhKy%2Ff9CRfK8stSbwdhRbEIoIG1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;372&quot; height=&quot;188&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;ul&gt;
&lt;li&gt;ResNet의 레이어를 101, 152개 사용했을 때도 VGG와 비교했을 때 오히려 lower complexity&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;CIFAR-10 and Analysis&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;다른 모델들과 비교했을 때&lt;/li&gt;
&lt;li&gt;ResNet-110은 evaluation을 5번 한 거라서 평균, 표준편차까지 기록됨&lt;/li&gt;
&lt;/ul&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;347&quot; height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8aL50/btqDA45wj7M/zxsWy3iBqekycZKguxyFv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8aL50/btqDA45wj7M/zxsWy3iBqekycZKguxyFv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8aL50/btqDA45wj7M/zxsWy3iBqekycZKguxyFv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8aL50%2FbtqDA45wj7M%2FzxsWy3iBqekycZKguxyFv0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;347&quot; height=&quot;314&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ResNet이 plain network보다 error rate이 낮음&lt;/li&gt;
&lt;li&gt;레이어를 1200개까지 늘려봤는데 training error는 비슷한데 testing error가 더 높게 나옴&lt;/li&gt;
&lt;li&gt;CIFAR-10은 상대적으로 small dataset이기 때문에 레이어를 1202개까지 사용할 필요가 없다고 봄&lt;/li&gt;
&lt;/ul&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;707&quot; height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDuqmC/btqDA5wxeXT/jrUOfkHX7Vd3GjJDwMvGM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDuqmC/btqDA5wxeXT/jrUOfkHX7Vd3GjJDwMvGM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDuqmC/btqDA5wxeXT/jrUOfkHX7Vd3GjJDwMvGM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDuqmC%2FbtqDA5wxeXT%2FjrUOfkHX7Vd3GjJDwMvGM0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;707&quot; height=&quot;176&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Object Detection on PASCAL and MS COCO&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Table 7에선 Faster R-CNN의 backbone을 VGG16에서 ResNet-101로 바꿨을 때 결과. VGG보다 ResNet을 썼을 때 mAP가 더 높음&lt;/li&gt;
&lt;li&gt;Table 8은 COCO validation 결과로 VGG보다 더 높은 성능을 보임&lt;/li&gt;
&lt;li&gt;mAP@.5는 IoU를 0.5로 했을 때 mAP를 의미함&lt;/li&gt;
&lt;li&gt;mAP@[.5, .95]는 IoU를 0.5부터 0.95까지 0.05씩 증가시켜 총 10개 케이스에 대한 IoU를 구하고 이를 평균낸 값&lt;/li&gt;
&lt;/ul&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;369&quot; height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPljCo/btqDDXRD5WC/ADKl0wsAhonP6g1sCHBhI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPljCo/btqDDXRD5WC/ADKl0wsAhonP6g1sCHBhI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPljCo/btqDDXRD5WC/ADKl0wsAhonP6g1sCHBhI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPljCo%2FbtqDDXRD5WC%2FADKl0wsAhonP6g1sCHBhI1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;369&quot; height=&quot;231&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Object Detection Improvements&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;p&gt;Object detection의 성능을 높이기 위해 3가지 technique을 적용함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Box refinement&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Faster-RCNN에서 final output은 regressed box이며 이 box는 proposal box와 different하다. 따라서 regressed box로부터 새로운 feature를 pooling하여 새로운 classification score와 regressed box값을 도출함. 총 300개의 new prediction을 구하고 IoU가 0.3인 Non-Maximum suppression을 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Global context&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;global context를 combine하는 것. 이미지가 주어졌을 때 global Spatial Pyramid Pooling을 적용. pooled feature가 RoI layers로 들어간 뒤 global context feature를 뽑아내고 global feature를 classification, box regression layer로 입력함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Multi-scaling testing&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;testing에서만 multi-scaling을 적용함. 학습된 모델로 image pyramid에서 {200, 400, 600, 800, 1000} 크기의 feature를 추출. 인접한 사이즈의 feature를 2개 선택하여 RoI pooling과 이후 레이어들을 거친 뒤, maxout을 사용하여 merge함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;baseline model보다 box refinement, context, multi-scale testing을 적용했을 때 성능이 개선됨&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;class별로 AP를 계산했을 때 거의 모든 class에서 성능 개선이 이루어짐&lt;/li&gt;
&lt;/ul&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;664&quot; height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dscfeZ/btqDBA4dG6F/9Y5a3yY6jvjGFTylxgTPv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dscfeZ/btqDBA4dG6F/9Y5a3yY6jvjGFTylxgTPv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dscfeZ/btqDBA4dG6F/9Y5a3yY6jvjGFTylxgTPv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdscfeZ%2FbtqDBA4dG6F%2F9Y5a3yY6jvjGFTylxgTPv1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;664&quot; height=&quot;403&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&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;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://bskyvision.com/644&quot;&gt;https://bskyvision.com/644&lt;/a&gt;&lt;/p&gt;</description>
      <category>ML &amp;amp; DL/Paper Review</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/115</guid>
      <comments>https://eremo2002.tistory.com/115#entry115comment</comments>
      <pubDate>Wed, 22 Apr 2020 00:11:25 +0900</pubDate>
    </item>
    <item>
      <title>Going Deeper with Convolutions</title>
      <link>https://eremo2002.tistory.com/114</link>
      <description>&lt;h1&gt;Abstract&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Inception이라는 새로운 Deep CNN 아키텍처를 제안한다.&lt;/li&gt;
&lt;li&gt;image classification, detection에서 SOTA를 달성했다.&lt;/li&gt;
&lt;li&gt;네트워크 안의 computing resource가 효율적으로 이뤄지도록 개선하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;제안하는 GoogLeNet은 ILSVRC-2014에서 AlexNet보다 12배 적은 파라미터 개수로 훨씬 좋은 성능을 냄&lt;/li&gt;
&lt;li&gt;efficient deep neural networks을 제안한다.&lt;/li&gt;
&lt;li&gt;여기서 &quot;deep&quot;이란 단어의 의미는 2가지를 갖는다.
&lt;ul&gt;
&lt;li&gt;Inception module이라는 새로운 모듈을 제안한다.&lt;/li&gt;
&lt;li&gt;말 그대로 네트워크의 depth 증가를 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Related Work&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;최근 CNN을 설계하는데 있어서 레이어를 더 깊게 쌓아 올리는 구조가 하나의 트렌드가 되고 있다.&lt;/li&gt;
&lt;li&gt;일반적으로 연속된 conv layer를 사용하며 추가적으로 normalization or max-pooling 레이어를 추가한다.&lt;/li&gt;
&lt;li&gt;&quot;Robust object recognition with cortex-like mechanisms&quot;에서는 multiple scale을 다루기 위해 서로 다른 사이즈의 고정된 Gabor filter series를 사용하였다.&lt;/li&gt;
&lt;li&gt;본 논문에서는 이러한 방법을 참고하여 네트워크를 설계하였지만 Inception 모델의 모든 필터는 학습된다는 점에서 차이가 있다.&lt;/li&gt;
&lt;li&gt;Network in Network는 뉴럴넷의 representational power를 끌어올리기 위한 방법 중 하나로 1x1 conv를 사용하여 depth를 증가시킨다.&lt;/li&gt;
&lt;li&gt;그러나 Inception에서 1x1 conv는 2가지 목적을 갖는다.
&lt;ol&gt;
&lt;li&gt;computational bottlenecks을 줄이기 위한 dimension reduction module로 사용한다.&lt;/li&gt;
&lt;li&gt;네트워크의 depth를 증가시킬뿐만 아니라 performance penalty없이 네트워크의 width 또한 조절할 수 있다. 여기서 네트워크의 width란 각 레이어의 unit 수를 의미한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Motivation and High Level Considerations&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;네트워크의 depth, width를 늘리는 것은 성능을 향상시킬 수 있는 쉬운 방법 중 하나지만 2가지 문제점을 가지고 있다.
&lt;ol&gt;
&lt;li&gt;네트워크가 커질수록 파라미터수가 증가하게 되며 이는 네트워크가 training set에 오버피팅될 수 있는 문제가 된다.&lt;/li&gt;
&lt;li&gt;네트워크가 커질수록 computational resource가 증가하게 된다. computational resource는 무한하지 않으므로 computational resource가 efficient distribution될 수 있도록 해야 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;위와 같은 문제를 해결하는 근본적인 방법은 sparsity를 더 증가시키는 것이다. 즉, f.c layer를 sparse한 layer로 대체하고, convolution layer도 더 sparse하게 바꾸는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Architectural Details&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;네트워크 내에서 sparsity를 높이고 Dense한 Matrix 연산을 통해 컴퓨터가 효율적으로 연산하게 한다.&lt;/li&gt;
&lt;li&gt;네트워크의 sparse 구조가 더 성능이 높다. (Dropout), 그러나 컴퓨터의 연산은 Dense할수록 빠르다는 특징이 있다. 두가지 특징을 잘 고려하여 설계한 것이 Inception module&lt;/li&gt;
&lt;/ul&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;583&quot; height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdS529/btqDCZoUNrn/tLhS4TnlOuIz0NK8OjQ4SK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdS529/btqDCZoUNrn/tLhS4TnlOuIz0NK8OjQ4SK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdS529/btqDCZoUNrn/tLhS4TnlOuIz0NK8OjQ4SK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdS529%2FbtqDCZoUNrn%2FtLhS4TnlOuIz0NK8OjQ4SK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;583&quot; height=&quot;192&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&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; width=&quot;457&quot; height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coXDwE/btqDACnS9ME/SrIX0yedYGZOMBFEj4Ahj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coXDwE/btqDACnS9ME/SrIX0yedYGZOMBFEj4Ahj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coXDwE/btqDACnS9ME/SrIX0yedYGZOMBFEj4Ahj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoXDwE%2FbtqDACnS9ME%2FSrIX0yedYGZOMBFEj4Ahj0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;457&quot; height=&quot;246&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;ul&gt;
&lt;li&gt;위와 같은 구조에서 computational cost가 너무 커진다는 문제가 있음 이를 보완하기 위해 3x3, 5x5 conv 이전에 1x1 conv를 사용하여 channel 수를 조절하도록 함&lt;/li&gt;
&lt;/ul&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;505&quot; height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kAnvW/btqDCa5hkz6/A5Skgdu5Ia0zTGdPHEj5F1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAnvW/btqDCa5hkz6/A5Skgdu5Ia0zTGdPHEj5F1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAnvW/btqDCa5hkz6/A5Skgdu5Ia0zTGdPHEj5F1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAnvW%2FbtqDCa5hkz6%2FA5Skgdu5Ia0zTGdPHEj5F1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;505&quot; height=&quot;287&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;GoogLeNet&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;activation function으로 ReLU&lt;/li&gt;
&lt;li&gt;#3x3 reduce, #5x5 reduce는 해당 컨볼루션 연산을 하기 전에 1x1 convolution을 먼저 사용한 것&lt;/li&gt;
&lt;li&gt;전체 레이어는 22개로 구성(pooling 포함하면 27개), block 내부까지 일일이 다 계산하면 대략 100개&lt;/li&gt;
&lt;li&gt;f.c layer만 사용하는 게 아니라 average pooling도 사용, top-1 acc 개선됨&lt;/li&gt;
&lt;/ul&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;680&quot; height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vBr7Q/btqDBzRK3du/SxOIRTKRKC9GBhdrn0JFx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vBr7Q/btqDBzRK3du/SxOIRTKRKC9GBhdrn0JFx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vBr7Q/btqDBzRK3du/SxOIRTKRKC9GBhdrn0JFx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvBr7Q%2FbtqDBzRK3du%2FSxOIRTKRKC9GBhdrn0JFx0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;680&quot; height=&quot;466&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&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; width=&quot;795&quot; height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qwvwO/btqDA5Dm2xv/YJSFHsrlSdIzfIPADxeDi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qwvwO/btqDA5Dm2xv/YJSFHsrlSdIzfIPADxeDi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qwvwO/btqDA5Dm2xv/YJSFHsrlSdIzfIPADxeDi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqwvwO%2FbtqDA5Dm2xv%2FYJSFHsrlSdIzfIPADxeDi1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;795&quot; height=&quot;183&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;ul&gt;
&lt;li&gt;auxiliary classifier를 네트워크 중간에 삽입하여, lower stage에서도 back-propagation이 잘 이루어지도록 함&lt;/li&gt;
&lt;li&gt;Inception에서는 네트워크가 매우 깊기 때문에 Gradient Vanishing 같은 문제가 발생할 수 있다. 이러한 문제를 방지하기 위해 네트워크 중간에 2개의 auxiliary classifier를 두어 네트워크 중간에서도 Back propagation을 하였다.&lt;/li&gt;
&lt;li&gt;전체 loss 계산시 auxiliary classifier에서 나온 loss는 0.3을 곱하여 더해진다.&lt;/li&gt;
&lt;li&gt;inference 시 auxiliary classifier는 사용하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Experiments&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;training과 testing에서 아래와 같이 진행함&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Training
&lt;ul&gt;
&lt;li&gt;동일한 GoogLeNet 모델 7개를 만들어서 독립적으로 트레이닝한 뒤 앙상블 기법을 사용함&lt;/li&gt;
&lt;li&gt;7개 모델 모두 같은 initialization, learning rate policy을 사용함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Testing
&lt;ol&gt;
&lt;li&gt;이미지를 4가지 scale로 resizing함 256, 288, 320, 352&lt;/li&gt;
&lt;li&gt;left, center, right square를 구함&lt;/li&gt;
&lt;li&gt;위에서 구한 square에서 다시 top, center bottom 방향으로 square를 구함&lt;/li&gt;
&lt;li&gt;center와 4개의 corner 위치에서 224x224로 cropping함&lt;/li&gt;
&lt;li&gt;horizontal flip&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;위와 같은 data augmentation을 거치면 이미지 하나에서 총 4x3x6x2 = 144개의 이미지를 얻을 수 있음&lt;/li&gt;
&lt;li&gt;최종 softmax 확률값은 multiple crop들의 평균&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Classification performance, GoogLeNet이 SOTA를 달성함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2012년에 제안된 SuperVision보다 error rate을 절반이상 줄임&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/enY8B1/btqDACnTbqR/gfddP24PudWqXXe7l7kcik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/enY8B1/btqDACnTbqR/gfddP24PudWqXXe7l7kcik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/enY8B1/btqDACnTbqR/gfddP24PudWqXXe7l7kcik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FenY8B1%2FbtqDACnTbqR%2FgfddP24PudWqXXe7l7kcik%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;391&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&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;ul&gt;
&lt;li&gt;모델의 개수, crop수를 다르게 하여 비교한 결과&lt;/li&gt;
&lt;li&gt;단일 모델의 경우 top-1 validation error rate이 제일 낮은 모델을 선택함&lt;/li&gt;
&lt;/ul&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;357&quot; height=&quot;215&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PURzF/btqDDYptNtb/D1sadTZC2vXd9e6ZDkKvMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PURzF/btqDDYptNtb/D1sadTZC2vXd9e6ZDkKvMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PURzF/btqDDYptNtb/D1sadTZC2vXd9e6ZDkKvMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPURzF%2FbtqDDYptNtb%2FD1sadTZC2vXd9e6ZDkKvMK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;357&quot; height=&quot;215&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;h1&gt;Conclusions&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;optimal sparse 구조를 통해 뉴럴넷의 성능을 개선시킴&lt;/li&gt;
&lt;li&gt;shallower and narrower 모델에 비해 computational cost가 크게 증가하지 않았음에도 불구하고 높은 성능을 냄&lt;/li&gt;
&lt;li&gt;object detection에서 context, bounding box regression을 수행하지 않아도 좋은 성능을 냄&lt;/li&gt;
&lt;li&gt;제안하는 sparser architecture는 feasible, useful idea&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;References&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.oreilly.com/library/view/learning-tensorflow/9781491978504/ch04.html&quot;&gt;https://www.oreilly.com/library/view/learning-tensorflow/9781491978504/ch04.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://sike6054.github.io/blog/paper/second-post/&quot;&gt;https://sike6054.github.io/blog/paper/second-post/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kangbk0120.github.io/articles/2018-01/inception-googlenet-review&quot;&gt;https://kangbk0120.github.io/articles/2018-01/inception-googlenet-review&lt;/a&gt;&lt;/p&gt;</description>
      <category>ML &amp;amp; DL/Paper Review</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/114</guid>
      <comments>https://eremo2002.tistory.com/114#entry114comment</comments>
      <pubDate>Wed, 22 Apr 2020 00:00:07 +0900</pubDate>
    </item>
    <item>
      <title>Very Deep Convolutional Networks for Large-Scale Image Recognition</title>
      <link>https://eremo2002.tistory.com/113</link>
      <description>&lt;h1&gt;Abstract&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;CNN의 depth가 accuracy에 어떤 영향을 미치는지 investigate&lt;/li&gt;
&lt;li&gt;네트워크의 depth를 늘렸을 때 significant한 성능 향상이 이루어짐&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;최근 Computer vision의 다양한 문제에서 CNN이 높은 성능을 보여주고 있다.&lt;/li&gt;
&lt;li&gt;해당 논문에서는 CNN 아키텍처를 설계하는 데 있어서 depth의 중요성에 초점을 맞춘다.&lt;/li&gt;
&lt;li&gt;다른 파라미터들은 그대로 두고 3x3 Conv 레이어만 늘리면서 CNN의 depth에 따라 성능이 어떻게 달라지는지 확인한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;ConvNet Configuration&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;3x3 conv를 사용한다. Why?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;256&quot; height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbV2XO/btqDDvHQfUb/2SpMbYjr6NaVlKBnuVeOFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbV2XO/btqDDvHQfUb/2SpMbYjr6NaVlKBnuVeOFk/img.png&quot; data-alt=&quot;&amp;amp;amp;nbsp; &amp;amp;amp;nbsp;&amp;amp;amp;nbsp;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbV2XO/btqDDvHQfUb/2SpMbYjr6NaVlKBnuVeOFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbV2XO%2FbtqDDvHQfUb%2F2SpMbYjr6NaVlKBnuVeOFk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;256&quot; height=&quot;231&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;left, right, up, down, center 방향을 모두 capture할 수 있는 가장 작은 사이즈의 커널이기 때문&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1x1 conv를 사용하는 버전도 있음 1x1 conv에서 채널 수를 변경하지 않으며, 입력 channel의 linear transformation으로 볼 수 있음&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;padding, stride를 1로 주어, 모든 conv layer에서 spatial resolution이 보존됨&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;spatial size는 2x2 max pooling(stride=2)에서 줄어듦&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;마지막 conv, max-pool 레이어 이후 3개의 f.c레이어 사용 4096, 4096, 1000&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;activation function ReLU사용,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Local Response Normalization 사용x&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LRN레이어가 이미지넷 데이터셋에서 성능 향상이 되지 않음&lt;/li&gt;
&lt;li&gt;메모리 사용량이랑 computation time 증가시키는 단점 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Architecture&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;layer가 많은 네트워크일지라도 파라미터 수 차이가 크게 나지 않는다.&lt;/li&gt;
&lt;/ul&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;626&quot; height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ca45S5/btqDDYC0Pnx/35M1gSeK5rdNvTii69bciK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ca45S5/btqDDYC0Pnx/35M1gSeK5rdNvTii69bciK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ca45S5/btqDDYC0Pnx/35M1gSeK5rdNvTii69bciK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fca45S5%2FbtqDDYC0Pnx%2F35M1gSeK5rdNvTii69bciK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;626&quot; height=&quot;560&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;0&quot; data-origin-height=&quot;0&quot; width=&quot;484&quot; height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9rpVK/btqDCbwjDnm/Fd2P0rpWSIfPCj28pyaF6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9rpVK/btqDCbwjDnm/Fd2P0rpWSIfPCj28pyaF6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9rpVK/btqDCbwjDnm/Fd2P0rpWSIfPCj28pyaF6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9rpVK%2FbtqDCbwjDnm%2FFd2P0rpWSIfPCj28pyaF6k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;484&quot; height=&quot;73&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;Discussion&lt;/h2&gt;
&lt;p&gt;VGG의 네트워크 구조가 기존의 ImageNet 2012, 2014 sota였던 AlexNet, ZF-Net와 다른 점이 무엇인가?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;11x11, 7x7의 large receptive field를 사용했던 것에 비해 상대적으로 매우 작은 크기의 3x3 receptive filed를 사용하였다.&lt;/li&gt;
&lt;li&gt;5x5 conv는 3x3 conv 두 번 사용한 것과 같은 receptive filed를 가지며, 7x7 conv는 3x3 conv를 세 번 사용한 것과 같은 receptive filed를 가진다.&lt;/li&gt;
&lt;/ul&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;251&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/99rpy/btqDzjWHReI/vtjGcLxmifCU0SzPWWWkb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/99rpy/btqDzjWHReI/vtjGcLxmifCU0SzPWWWkb1/img.png&quot; data-alt=&quot;https://www.researchgate.net/figure/The-receptive-field-of-each-convolution-layer-with-a-3-3-kernel-The-green-area-marks_fig4_316950618&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/99rpy/btqDzjWHReI/vtjGcLxmifCU0SzPWWWkb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F99rpy%2FbtqDzjWHReI%2FvtjGcLxmifCU0SzPWWWkb1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;328&quot; height=&quot;251&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;https://www.researchgate.net/figure/The-receptive-field-of-each-convolution-layer-with-a-3-3-kernel-The-green-area-marks_fig4_316950618&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;그럼 그냥 5x5, 7x7 한 번만 쓰면 되지 뭐하러 3x3 여러번 사용하는가?
&lt;ul&gt;
&lt;li&gt;비선형 함수를 더 많이 사용하여 decision function이 더 discriminative해진다&lt;/li&gt;
&lt;li&gt;1x1 conv를 사용하는 것 역시 receptive filed에 영향을 주지 않고 비선형성을 증가시킬 수 있는 방법이라 할 수 있음&lt;/li&gt;
&lt;li&gt;파라미터 수를 줄일 수 있다.
&lt;ul&gt;
&lt;li&gt;input &amp;amp; output 채널 수가 같은 3x3 conv를 3번 사용했을 때 파라미터 수는 3x(3x3xCxC)가 된다.&lt;/li&gt;
&lt;li&gt;동일한 조건으로 7x7 conv를 한번 사용했을 때 파라미터 수는 7x7xCxC가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;rArr; Small size의 conv filter를 사용하는 conv layer를 여러 개 쌓는 것이 성능을 향상시킬 수 있다.&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Evaluation&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;single scale을 사용한 evaluation으로 train image와 test image의 size가 고정되어 동일한 경우&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;649&quot; height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bekDMy/btqDCZJa5ka/DuAEsQmRJsjI79RpaszKk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bekDMy/btqDCZJa5ka/DuAEsQmRJsjI79RpaszKk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bekDMy/btqDCZJa5ka/DuAEsQmRJsjI79RpaszKk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbekDMy%2FbtqDCZJa5ka%2FDuAEsQmRJsjI79RpaszKk1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;649&quot; height=&quot;282&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;ul&gt;
&lt;li&gt;
&lt;p&gt;Local Response Normalization을 사용했을 때 오히려 error rate이 더 높았다. 이로 인해, 모델 B부터는 LRN을 적용하지 않았다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;네트워크의 depth가 깊어질수록(layer 수 증가) 성능이 향상되었다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;C(use 1x1), D(only 3x3)는 같은 depth를 가지지만 D가 성능이 더 높았다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;additional non-linearity가 성능 향상이 더 도움이 되기 때문&lt;/li&gt;
&lt;li&gt;1x1보다는 3x3가 spatial context 잘 capture할 수 있기 때문에 더 중요하게 작용함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;19개의 레이어를 사용했을 때 error rate saturate되었음, 그러나 더 large한 dataset의 경우 depth가 더 깊은 모델을 사용하는 것이 유리할 수 있음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;기존 모델 B에서 3x3 conv 2개를 5x5 1개로 바꿔봤음, 그러나 오히려 error가 더 높게 나옴. 즉, small filter를 사용하는 것이 더 outperform&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;training image에 scale jittering을 사용했을 때 성능이 더 높았음&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;scale jittering이란 이미지의 크기를 256 or 384 같은 고정된 크기로 조절하거나 [256; 512] 같은 특정 범위의 사이즈로 조절한 뒤 CNN의 입력 사이즈(224x224)에 맞게 무작위로 cropping하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;
&lt;p&gt;이번에는 test image에 scale jittering을 사용하여 multi scale image에 대한 evaluation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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/QfVuh/btqDzC9pjUH/erevpSYeh2t3sb0rLKC6N1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QfVuh/btqDzC9pjUH/erevpSYeh2t3sb0rLKC6N1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QfVuh/btqDzC9pjUH/erevpSYeh2t3sb0rLKC6N1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQfVuh%2FbtqDzC9pjUH%2FerevpSYeh2t3sb0rLKC6N1%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;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;train image와 test image간의 scale이 너무 차이나면 오히려 성능이 떨어질 수 있으므로 크게 차이나지 않는 범위에서 scale을 조정함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;train image = Q, test image = S이며 Q=S라고 했을 때, Q = {S-32, S, S+32}의 3가지 scale로 test image의 사이즈를 조절함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Table 4에서 볼 수 있는 것처럼 multiple scale test image를 사용했을 때 성능이 증가함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Table 4에서 모델 D의 마지막 결과를 보면 training &amp;amp; testing 과정에서 scale jittering을 적용한 것이 가장 성능이 좋았음. 왜냐하면 네트워크가 testing에서 들어오는 다양한 scale의 이미지를 트레이닝 과정에서 학습할 수 있기 때문&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;지금까지의 실험에선 단일 모델을 가지고 평가했지만 이번에는 여러 모델의 output을 combine하여 평가함. combine 과정은 단순하게 각 class에 대한 확률값을 평균내어 사용함&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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/xaEoh/btqDACIb3Vl/aZYiDONJ4zFboQrkgki9K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xaEoh/btqDACIb3Vl/aZYiDONJ4zFboQrkgki9K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xaEoh/btqDACIb3Vl/aZYiDONJ4zFboQrkgki9K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxaEoh%2FbtqDACIb3Vl%2FaZYiDONJ4zFboQrkgki9K1%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;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Table 5에서 second row를 보면 scale jittering이 서로 다른 D 모델 3개를 조합함. 그 결과 단일 모델로 D를 사용했을 때 25.9%, 8.0%의 error를 냈던 결과에 비해 25.3%, 7.8%로 더 높은 성능을 냄&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;7개의 모델을 combine 했을 때 error rate이 더 줄어듦&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;7개의 모델이 내는 예측 값을 단순하게 평균낸 것이 아니라 각 모델마다 가중치를 두고 반영함. 어떤 모델의 신뢰도가 더 높은지 평가하는 기준은 top-5 validation error를 보고 판단함. 모델 C보다는 모델 E가 성능이 좀 더 좋다고 보기 때문에 모델 C와 E의 가중치를 서로 다르게 두는 것.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;
&lt;p&gt;ILSVRC-2014 classification result&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;663&quot; height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg8f5Y/btqDBAb0BPO/lk3YYg3O0NgNlreoUNsit1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg8f5Y/btqDBAb0BPO/lk3YYg3O0NgNlreoUNsit1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg8f5Y/btqDBAb0BPO/lk3YYg3O0NgNlreoUNsit1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg8f5Y%2FbtqDBAb0BPO%2Flk3YYg3O0NgNlreoUNsit1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;663&quot; height=&quot;318&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;ul&gt;
&lt;li&gt;제안하는 네트워크가 single net 기준으로 SOTA&lt;/li&gt;
&lt;li&gt;이전 우승자들의 성능을 모두 이김&lt;/li&gt;
&lt;li&gt;winner인 GoogleNet과 비교했을 때도 competitive하며 다른 method보다는 outperform&lt;/li&gt;
&lt;li&gt;VGG Net을 설계할 때 classic한 CNN 아키텍처에서 시작한 것이 아니라 네트워크의 depth를 어디까지 증가시킬 수 있느냐에 관점을 두고 설계함&lt;/li&gt;
&lt;li&gt;VGG 1 net에서 test error 없는 이유: 시간부족으로 인해 best performance single network를 deadline까지 제출하지 못 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Localization&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;classification task가 아닌 localization task에 적용했을 때의 결과&lt;/li&gt;
&lt;li&gt;localization이란? 이미지 내에 1개의 object만 존재하며 bounding box로 object의 위치를 localization해야하고 해당 이미지가 어떤 class인지 prediction하는 문제&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Localization ConvNet&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;기존에 class score를 예측했던 last &lt;a href=&quot;http://f.cl&quot;&gt;f.c&lt;/a&gt; layer가 bounding box location을 예측하도록 바꿔야 함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;classification task에서 제일 성능이 좋았던 아키텍처 D를 사용함&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;classification CNN과의 가장 큰 차이점은 logistic regression objective(분류 문제를 푸는 모델)를 Euclidean loss로 변경. (Ground-truth와 예측 bounding box 사이의 loss를 구하기 위해)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2개의 localization model을 사용하였으며 각각 256x256, 384x384 size로 트레이닝 함. classification model에서 사용된 pre-trained 모델을 사용하기 때문에 별도의 training scale jittering은 사용하지 않음&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;모든 layer를 fine-tuning하는 것과 2개의 first two f.c layer만 fine-tuning하는 두가지 방법을 고려함. 마지막 f.c layer는 랜덤하게 초기화하고 train from scratch&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;
&lt;p&gt;SCR(single-class regression), PCR(per-class regression)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;579&quot; height=&quot;149&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CJuUs/btqDzkgVaW7/EUKMAlbHOghy8KcBxUmyhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CJuUs/btqDzkgVaW7/EUKMAlbHOghy8KcBxUmyhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CJuUs/btqDzkgVaW7/EUKMAlbHOghy8KcBxUmyhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCJuUs%2FbtqDzkgVaW7%2FEUKMAlbHOghy8KcBxUmyhk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;579&quot; height=&quot;149&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;ul&gt;
&lt;li&gt;
&lt;p&gt;first two f.c layer를 fine-tuning하는 것보다 모든 레이어를 fine-tuning하는 것이 더 좋음&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;
&lt;p&gt;multiple scale image로 학습하고 테스트 하는 것이 더 성능이 높다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;451&quot; height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUuIEj/btqDCaxpBR4/Sae4YcltrKTLqwTSodA901/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUuIEj/btqDCaxpBR4/Sae4YcltrKTLqwTSodA901/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUuIEj/btqDCaxpBR4/Sae4YcltrKTLqwTSodA901/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUuIEj%2FbtqDCaxpBR4%2FSae4YcltrKTLqwTSodA901%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;451&quot; height=&quot;154&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;&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;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;localization task에서 VGG를 다른 모델과 비교&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;530&quot; height=&quot;133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4xuWU/btqDyOo2KCi/AiCxgLmhemykuVNm2EiB6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4xuWU/btqDyOo2KCi/AiCxgLmhemykuVNm2EiB6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4xuWU/btqDyOo2KCi/AiCxgLmhemykuVNm2EiB6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4xuWU%2FbtqDyOo2KCi%2FAiCxgLmhemykuVNm2EiB6K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;530&quot; height=&quot;133&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;ul&gt;
&lt;li&gt;
&lt;p&gt;top-5 test error가 25.3%로 최고 성능을 달성함.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;
&lt;p&gt;다양한 image classification 데이터셋에서 SOTA를 찍었던 모델들과의 성능 비교&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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;645&quot; height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfOvrO/btqDyNDCd1u/eHZRsoIKMEpX2M1SHLbw21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfOvrO/btqDyNDCd1u/eHZRsoIKMEpX2M1SHLbw21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfOvrO/btqDyNDCd1u/eHZRsoIKMEpX2M1SHLbw21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfOvrO%2FbtqDyNDCd1u%2FeHZRsoIKMEpX2M1SHLbw21%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;645&quot; height=&quot;213&quot; onerror=&quot;this.onerror=null; this.src='//t1.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;ul&gt;
&lt;li&gt;*(asterisk) 달린 모델은 class 2000개짜리 ILSVRC dataset으로 pre-training시킨 모델&lt;/li&gt;
&lt;li&gt;기존 모델들과 비교했을 때 VOC-2007, VOC-2012, Caltech-256 dataset에서 기존 SOTA를 달성했던 모델보다 더 높은 성능을 보여주었으며 Caltech-101 dataset의 경우에도 competitive한 결과를 보여줌&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;large scale image classification에서 기존의 CNN보다 레이어를 더 깊게 쌓아 성능을 향상시킴(2위)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Object localization challenge에서도 SOTA&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;네트워크의 depth는 classification accuracy에 beneficial한 요소이며 visual representation 측면에서도 매우 중요함&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ML &amp;amp; DL/Paper Review</category>
      <author>eremo2002</author>
      <guid isPermaLink="true">https://eremo2002.tistory.com/113</guid>
      <comments>https://eremo2002.tistory.com/113#entry113comment</comments>
      <pubDate>Tue, 21 Apr 2020 23:54:08 +0900</pubDate>
    </item>
  </channel>
</rss>