<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>tobigs1516_image</title>
        <link>https://velog.io/</link>
        <description>2021 투빅스 15, 16기 이미지 세미나입니다</description>
        <lastBuildDate>Wed, 01 Dec 2021 08:20:38 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>tobigs1516_image</title>
            <url>https://images.velog.io/images/tobigs1516_image/profile/6d95b84d-2ff4-4111-bf9f-7e4f4c8cfaaa/투빅이.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. tobigs1516_image. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/tobigs1516_image" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Vision Transformer(ViT) (AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE)]]></title>
            <link>https://velog.io/@tobigs1516_image/Vision-Transformer</link>
            <guid>https://velog.io/@tobigs1516_image/Vision-Transformer</guid>
            <pubDate>Wed, 01 Dec 2021 08:20:38 GMT</pubDate>
            <description><![CDATA[<h2 id="abstract">Abstract</h2>
<ul>
<li>Transformer는 자연어처리 분야를 완전히 장악한 표준 모델이 되었으나 컴퓨터 비전에서는 Transformer의 활용이 제한적이었다.</li>
<li>비전에 self attention을 적용하려는 이전 연구들은 convolutional network와 함께 사용하거나 convolutional network의 전체 구조에서 몇몇 요소들만 대체하는 식으로 사용되었다.</li>
<li>ViT는 CNN에 의존하지 않고 순수한 transformer가 image patch의 시퀀스에 다이렉트로 적용되어 image 분류 task에서 좋은 성능을 보일 수 있음을 밝혔다.</li>
<li>큰 데이터셋에 pre-trained 시킨 후 작거나 중간의 image recognition 벤치마크 데이터셋에 전이 학습을 할 때 ViT는 기존 CNN SOTA 모델들보다 계산량은 줄고 좋은 성능을 보였다.</li>
</ul>
<h2 id="introduction">Introduction</h2>
<ul>
<li>컴퓨터비전에서는 아직까지 convolutional 구조가 지배적이다.</li>
<li>Convolutional layer를 전부 self-attention으로 바꾼 연구도 있었는데 이론적으로는 효율적이었으나 현대 하드웨어 가속기 GPU를 활용하지 못한다는 단점이 있었고 그만큼 어텐션을 컴퓨터 비전에 적용하는 것은 어려운 일이었다.</li>
<li>이번 연구에서는 최소한의 수정으로 표준 transformer에 이미지를 직접 적용하였다. 이미지를 패치로 분할하고 패치의 선형 임베딩 시퀀스를 트랜스포머 인코더의 입력으로 넣는다. 이미지 패치는 NLP에서 토큰(단어)와 같은 방식으로 처리된다.</li>
<li>다시 말해, NLP 시점에서 보면 인풋 이미지가 문장, 패치가 문장을 구성하는 각각의 단어라고 할 수 있다.</li>
<li>하지만 ImageNet과 같은 중간 크기의 데이터셋에 대해 학습할 때는 ResNet과 같은 모델들에 비해 정확도가 떨어졌다. 왜냐하면 CNN이 가지고 있는 inductive bias가 Transformer에는 부족하기 때문에 충분하지 못한 양의 데이터로 학습시킬 경우 모델의 일반화 성능이 좋지 않았다.</li>
</ul>
<blockquote>
<p><strong>Inductive bias란?</strong></p>
</blockquote>
<ul>
<li>새로운 데이터에 대해 좋은 성능을 내기 위해 모델에 사전적으로 주어지는 가정</li>
<li>SVM: Margin 최대화, CNN: Locality (지역적인 정보), RNN: Sequentiality (순차적인 정보)</li>
<li>CNN은 2차원의 지역적인 특성을 유지하며 레이어를 통과하며 지역적인 정보를 중요하게 여기며 모델을 학습한다.</li>
<li>반면 Transformer는 데이터를 1차원으로 만든 후 self attention을 통해 layer를 학습하기 때문에 2차원의 지역적인 정보가 유지가 되지 않으므로 CNN에 비해 inductive bias가 적다. 다만 모델의 자유도가 CNN보다 높아 데이터로부터 더 많은 것을 학습할 수 있다.</li>
</ul>
<h2 id="method">Method</h2>
<h3 id="vit-모델-구조">ViT 모델 구조</h3>
<ul>
<li>오리지널 Transformer의 구조를 가능한한 그대로 사용하였고 이를 통해 쉽게 확장 가능한 NLP Transforemr의 구조와 효율적인 구현을 바로 사용할 수 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/hannapark56/post/17cb699f-2d51-442c-88ed-21ca232704e9/image.png" alt=""></p>
<h4 id="transformer-encoder의-input">Transformer encoder의 Input</h4>
<ul>
<li>Transformer는 input으로 1차원 토큰 임베딩 시퀀스를 받기 때문에 2D의 이미지를 사용하기 위해 H X W X C의 이미지를 N X (P X P X C) 인 이미지 패치들로 변환해야 한다.</li>
<li>여기서 P는 패치의 크기이고, N = HW/(P*P) 은 패치의 수이며 시퀀스 길이를 의미한다.</li>
<li>2차원인 patch를 1차원으로 flatten 시키고 linear projection을 통해 D차원 벡터로 매핑시킨다. 이 projection 결과가 patch embeddings이다.</li>
<li>이미지 분류를 위해 임베딩된 패치들의 맨 앞에 class token을 추가한다. (class embedding)</li>
<li>각 시퀀스의 순서를 나타내는 position embedding을 추가한다.</li>
<li>이렇게 총 3개의 임베딩 벡터들로 이루어진 시퀀스가 transformer의 encoder의 input으로 입력된다.</li>
</ul>
<h4 id="transformer-encoder">Transformer Encoder</h4>
<ul>
<li>트랜스포머 인코더는 MSA(Multi head self-attention)와 MLP(Mulit layer perceptron) 블록들로 구성된다. LN(Layer Norm)은 모든 블록에 사용되며 블록 이후에는 residual connection이 적용된다.</li>
</ul>
<p><img src="https://images.velog.io/images/hannapark56/post/585b955e-ecab-4c03-9b80-30480f8c526e/image.png" alt=""></p>
<ul>
<li>Transformer의 Encoder의 입력에 해당하는 부분이다. Xclass는 class token, Xp는 각각의 이미지 패치들, E는 linear projection의 가중치라서 XpE는 patch embedding이다. Epos는 positional embedding이다.
<img src="https://images.velog.io/images/hannapark56/post/4cd64f38-ddd3-40ab-ae59-5822b41112e8/image.png" alt=""></li>
<li>Transformer encoder의 수식이다. 이전 입력값 z(l-1)에 학습을 안정성을 위해 layer norm을 적용한 후 Multi-head attention을 적용한다. 그리고 z(l-1)을 더해줌으로 skip connection을 해준다.
<img src="https://images.velog.io/images/hannapark56/post/fd3941dc-aaf8-4115-b418-262fe2d716d5/image.png" alt=""></li>
<li>Multi-head attention 결과로 얻은 값을 layer norm을 적용한 후 MLP을 해준다. 
<img src="https://images.velog.io/images/hannapark56/post/2a2b01f9-8f45-4fc2-9771-291f58483c70/image.png" alt=""></li>
<li>z0L은 class token의 최종 output이다. 이를 layer norm을 적용한 후 y를 얻는다. 이후 y를 MLP 헤드에 넣어 이미지의 class를 예측한다.</li>
</ul>
<h4 id="hybrid-architecture">Hybrid Architecture</h4>
<ul>
<li>Raw 이미지 패치 대신 CNN의 중간 feature map에서 input sequence를 형성할 수 있다. Patch embedding projection E는 CNN의 feature map으로부터 추출된 패치들에 적용되고 classification token과 positional embedding은 위와 동일하게 추가된다.</li>
</ul>
<h3 id="fine-tuning-and-higher-resolution">Fine-tuning and Higher Resolution</h3>
<ul>
<li>ViT는 기존 이미지 인식 모델과 동일하게 거대한 양의 데이터셋으로 사전 학습하고 파인튜닝하는 단계를 거친다. 웬만한 거대한 데이터셋을 사용하지 않으면 좋은 성능을 기대하기 어렵다. ViT는 구글 내부 이미지 6억장을 사용하여 사전학습을 했다고 한다.</li>
<li>파인 튜닝시에는 pre-trained prediction head를 제거하고 0으로 초기화된 D*K 차원의 feedforward layer를 추가한다. 여기서 K는 downstream task의 class의 개수이다.</li>
<li>또한, 사전학습 때보다 더 높은 resolution으로 파인 튜닝하는 것이 종종 도움이 된다. 그리고 패치의 크기는 사전학습과 파인튜닝에서 동일하다. 파인튜닝시에 resolution이 더 높기 때문에 파인튜닝 때는 패치의 수가 증가한다.</li>
<li>ViT는 패치의 수(시퀀스의 길이) N을 얼마든지 늘릴 수 있으나 길이가 늘어날 경우 사전학습된 모델의 positional embedding은 의미가 없을 수 있다. 이를 보완하기 위해 이럴 때는 2차원 구조를 사용하여 positional embedding을 조정한다.</li>
</ul>
<h2 id="experiments">Experiments</h2>
<h3 id="comparision-to-state-of-the-art">Comparision To State Of The Art</h3>
<p><img src="https://images.velog.io/images/hannapark56/post/1fe6eb9c-a688-4a04-afb5-188261351866/image.png" alt=""></p>
<ul>
<li>ViT 모델은 BERT에 사용되는 구성을 기반으로 하였으며, Base와 Large model은 BERT에서 그대로 차용했고 Huge 모델은 저자들이 추가했다.</li>
<li>VIT-L/16의 의미는 Large 모델을 사용했고 패치의 사이즈가 16*16 이라는 뜻이다.</li>
</ul>
<p><img src="https://images.velog.io/images/hannapark56/post/d57db2a8-c98a-4a69-a775-03b86250ed14/image.png" alt=""></p>
<ul>
<li>위쪽이 pre-trained에 사용한 데이터와 모델이고 왼쪽이 fine-tuning에 사용한 데이터셋이다. 해당 연구가 진행된 시점 기준으로 EfficintNet으로 학습시킨 Noisty Student가 ImageNet의 SOTA였고 다른 데이터셋에서는 ResNet으로 학습시킨 BiT-L이 SOTA였다.</li>
<li>TPUv3-core-days는 쉽게 말해 해당 모델을 학습시키기 위해 사용되는 자원의 양이다. ViT가 기존 모델보다 효율적으로 사전 학습이 가능함을 알 수 있고 성능은 기존 모델과 거의 비슷하거나 우수함을 알 수 있다.<h3 id="pre-training-data-requirements">Pre-Training Data Requirements</h3>
<img src="https://images.velog.io/images/hannapark56/post/fd06e807-4703-4f27-83ca-6e06fe886c4a/image.png" alt=""></li>
<li>ViT는 pre-trained 데이터셋이 작다면 성능이 좋지 않다. ImageNet에 학습시켰을 때는 BiT의 성능이 ViT보다 좋았고 JFT와 같은 거대한 데이터셋으로 pre-traiend 학습시켰을 때 비로소 ViT 성능이 BiT를 넘었다. (참고로 회색 영역은 BiT-50와 BiT-152의 성능 구간) <strong>(Figure 3)</strong></li>
<li>JFT 데이터셋을 샘플링해서 pre-trained 시킨 결과 샘플 데이터가 작으면 ResNet이 few-shot evaluation에서 더욱 우수했고 샘플 데이터가 커지면 ViT의 성능이 ResNet을 넘었다. <strong>(Figure 4)</strong></li>
</ul>
<h3 id="scaling-study">Scaling Study</h3>
<p><img src="https://images.velog.io/images/hannapark56/post/14720fd7-5c69-4257-aca9-74bb59edd968/image.png" alt=""></p>
<ul>
<li>ViT, ResNet, Hybrid 각 모델의 performance 대비 pre-training cost를 비교하였는데 ViT가 ResNet보다 효율적이다. 왜냐하면 동일한 성능 달성을 위해 ResNet보다 2~4배 정도 적은 컴퓨팅 자원을 사용하였기 때문이다.</li>
<li>Hybrid는 적은 계산 비용에서는 ViT의 성능을 넘었는데 계산 비용이 커질수록 성능 차이가 사라진다.</li>
<li>ViT은 모델이 커지면 성능이 어느정도 포화되었던 ResNet과 달리 포화되지 않기 때문에 추후 더 좋은 성능 향상을 기대할 수 있다.</li>
</ul>
<h2 id="reference">Reference</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=D72_Cn-XV1g">https://www.youtube.com/watch?v=D72_Cn-XV1g</a></li>
<li><a href="https://www.youtube.com/watch?v=QkwNdgXcfkg&amp;t=1s">https://www.youtube.com/watch?v=QkwNdgXcfkg&amp;t=1s</a></li>
<li><a href="https://www.youtube.com/watch?v=bgsYOGhpxDc&amp;t=1908s">https://www.youtube.com/watch?v=bgsYOGhpxDc&amp;t=1908s</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[DeepPose: Human Pose Estimation via Deep Neural Networks]]></title>
            <link>https://velog.io/@tobigs1516_image/DeepPose</link>
            <guid>https://velog.io/@tobigs1516_image/DeepPose</guid>
            <pubDate>Wed, 01 Dec 2021 06:31:13 GMT</pubDate>
            <description><![CDATA[<h3 id="introduction">Introduction</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/b4dead7e-ffd8-481e-8533-c75accd97e81/image.png" alt="">Deep Pose는 DNN 기반의 Pose Estimation(사람의 관절 위치를 찾는 task) 방법을 제안하며, 해당 task 최초로 DNN을 적용하여 SOTA를 달성하였다. 그 뿐만 아니라, 당시에는 딥러닝을 주로 Classification task에만 사용하였는 데 Regression task에서도 훌륭히 적용할 수 있음을 증명하였다. </p>
<blockquote>
<p><strong>Pose Estimation task에서 CNN이 적합한 이유</strong>
    1. 관절 위치 예측 시 이미지의 맥락을 파악하여 예측 할 수 있다. 따라서, 관절들 사이의 상관 관계를 학습할 수 있다.
    2. 기존 방식은 관절 별 특징 검출(Feature Representation)과 검출기(Detector)를 만든 다음 조합하는 방식이었다면, CNN을 통해 단일 신경망으로 모든 관절 위치를 예측할 수 있다.</p>
</blockquote>
<h3 id="deep-learning-model-for-pose-estimation">Deep Learning Model for Pose Estimation</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/d16bd5dc-6e9f-489a-9606-4613b5915f1c/image.png" alt="">Input Image가 CNN을 통과하면, 각 관절 별로 x, y 좌표 2개씩 k개의 관절에 대해서 예측 값을 도출하며 이는 총 2k 차원의 벡터를 의미한다. 
<img src="https://images.velog.io/images/yoonj98/post/4ed37078-e5f6-4523-b0ec-507ebc3726f1/image.png" alt=""></p>
<blockquote>
<ul>
<li>x : Image data</li>
</ul>
</blockquote>
<ul>
<li>y : Ground truth pose vector</li>
<li>K : 신체 관절 수</li>
<li>y_i : i번째 관절의 x, y 좌표 (이미지 내 절대 좌표)</li>
</ul>
<p>이때, 벡터 y_i는 i번째 관절의 x, y 좌표를 담은 2차원 벡터이며, 벡터 y는 2차원 벡터 k개를 쭉 펼쳐서 이어 붙인 2k 차원의 벡터이다.</p>
<p>y_i 벡터는 i번째 관절의 x, y 좌표와 중심점 간의 차를 구하고, 각각을 너비와 높이로 나눠 주어 normalize하여 사용한다.
<img src="https://images.velog.io/images/yoonj98/post/31bb0e6d-1888-448b-bf09-cb621e913a7e/image.png" alt=""></p>
<blockquote>
<ul>
<li>b = (b_c, B_w, B_h) : 사람 신체에 대한 bounding box</li>
</ul>
</blockquote>
<ul>
<li>b_c : bounding box의 중심</li>
<li>b_w : bounding box의 너비</li>
<li>b_h: bounding box의 높이</li>
</ul>
<p>예를 들어, Bounding Box (x, y, w, h) = (120, 150, 200, 300)이고 머리에 대한 좌표가 (120, 370)이라면 normalize된 좌표는 $(\frac{1}{200}(120-120)$, $\frac{1}{300}(370-300))$ = (0, 0.73)이다.</p>
<p>해당 normalize 과정을 Pose Vector 모두에 적용해주면 다음과 같은 normalized pose vector를 얻을 수 있다. 
<img src="https://images.velog.io/images/yoonj98/post/ff220686-120e-4e8b-91a3-9f06ebcef5ce/image.png" alt=""></p>
<p>이렇게 normalize된 값을 통해 학습하여 예측 값을 도출할 수 있다. 그렇다면, 예측 값을 원래 이미지에 찍어주기 위해서는 normalize에 대한 역 연산을 진행해야하며 수식은 다음과 같다. </p>
<p><img src="https://images.velog.io/images/yoonj98/post/a4441ec9-21b5-4828-96ac-8743923c83e6/image.png" alt="">즉, Input image와 파라미터를 통해 CNN이 normalize된 예측 값을 도출하고 이를 다시 역으로 적용하면 관절 예측 벡터인 y*를 구할 수 있다. </p>
<blockquote>
<ul>
<li>x : Input Image</li>
</ul>
</blockquote>
<ul>
<li>φ : CNN 모델을 통과시키는 함수</li>
<li>θ : 학습되는 파라미터</li>
</ul>
<p>다만, 이런 방식(Initial Stage)의 경우 큰 이미지를 보고 예측한 결과 값이기 때문에 정교함이 떨어질 수 있다. 따라서, 이를 보완하기 위한 아이디어는 예측 좌표를 기반으로 bounding box를 다시 그리고 crop하여 다시 CNN 모델을 통과하는 Cascasde 방식(Stage S)이다. </p>
<p><em>앞서 Pose Vector에 대해 진행한 Normalize는 crop 전 이미지 내 좌표이기 때문에 이후 과정에서 원활히 사용하기 위함이다.</em></p>
<h3 id="cascade-of-pose-regressors">Cascade of Pose Regressors</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/ad8dae3b-f747-4626-8b29-7ba3d2bb9601/image.png" alt=""></p>
<p>앞서, 설명한 바와 같이 예측 좌표를 기반으로 bounding box를 다시 그리고 crop하여 다시 CNN 모델을 통과시켜 정교화된 좌표 예측값을 구할 수 있다. 이는 식으로 표현하면 다음과 같다. </p>
<p><img src="https://images.velog.io/images/yoonj98/post/d0db7bdf-7847-4f9c-8e20-2ce4be71828b/image.png" alt=""></p>
<p>이때, 모든 좌표들에 대해서 새로운 바운딩 박스를 그리며, σ*diam(ys)라는 수식에 의해서 크기가 결정된다. </p>
<blockquote>
<ul>
<li>diam(ys) : 이전에 예측한 좌표들에서 왼쪽 어깨와 오른쪽 엉덩이 좌표 간의 거리</li>
</ul>
</blockquote>
<ul>
<li>σ : diam(ys)를 키워주는 파라미터, 따로 수식적으로 구하기 보단 임의의 상수 (2, 3...)을 입력해준다.</li>
</ul>
<h3 id="training">Training</h3>
<h4 id="과정">과정</h4>
<ol>
<li>Stage 1 모형을 학습하여 Input Image 속 관절의 대략적인 위치를 파악한다.</li>
<li>관절 별로 Stage t 모형에 새로운 Bounding Box를 입력해 예측 값을 산출하고 이를 S번 반복한다. ($S &gt;= t &gt;= 2$)</li>
</ol>
<h4 id="metric--percent-of-detected-joints-pdj">Metric : Percent of Detected Joints (PDJ)</h4>
<ol>
<li>몸통의 길이를 계산한다. </li>
<li>(특정 임계값 * 길이)가 반지름인 원을 생성한다. </li>
<li>예측 위치가 원 내부에 있는 지 여부를 확인한다. </li>
<li>예측 결과에 대한 PDJ (= 원 내부에 있는 경우/전체 관절수)를 계산한다.</li>
</ol>
<h3 id="result">Result</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/9304c30c-b970-4109-830e-b3c95c0f5ace/image.png" alt="">
Stage 1만 진행하는 것보다 관절별 모델 학습 시 탐지 성능이 증가함을 확인할 수 있다</p>
<h3 id="한계점">한계점</h3>
<ol>
<li><p>관절과 관절 간의 공간적 상관관계 정보를 고려하지 않기 때문에, 이미지 상으로 보이지 않는 관절들을 예측하기 어렵다.</p>
</li>
<li><p>Input Image에 대한 crop을 반복하고, 각 단계별로 별개의 CNN을 학습시키는 방식에는 비효율적인 계산 과정이 존재한다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Visualizing and Understanding Convolutional Networks]]></title>
            <link>https://velog.io/@tobigs1516_image/Visualizing-and-Understanding-Convolutional-Networks</link>
            <guid>https://velog.io/@tobigs1516_image/Visualizing-and-Understanding-Convolutional-Networks</guid>
            <pubDate>Wed, 24 Nov 2021 09:41:08 GMT</pubDate>
            <description><![CDATA[<h3 id="abstract">Abstract</h3>
<p>본 논문은 AlexNet과 같은 우수한 성능을 보인 large convolutional network가 왜 학습 수행이 잘되는지, 그리고 좋은 성능을 만드는지에 대해 다룹니다.
CNN아키텍쳐를 구성하는 각각의 layer부터 최종 classifier까지 입력된 이미지로부터 어떻게 특징이 추출되고, 학습되는지를 시각화하여 분석하는 방법을 제시합니다. 또한 이러한 시각화 분석을 통해 기존 AlexNet대비 성능 향상을 이루게 됩니다.</p>
<h3 id="1-introduction">1. Introduction</h3>
<p>1990년대 LeCun의 연구를 통해서 CNN이 손글씨 인식이나 face detection등의 task에서 우수한 성능을 보인 것이 소개되었습니다. </p>
<p>2012년에는 AlexNet이 PASCAL VOC 데이터셋에 대하여 차등모델에 비해 약 10%나 향상된 정확도를 보였는데, 이러한 극적인 성능 향상으로 다음 3가지 요인을 뽑을 수 있습니다.</p>
<ol>
<li>레이블링된 수백만 개의 샘플들로 구성된 굉장히 큰 규모의 학습 데이터셋 제공이 가능해짐<ol start="2">
<li>강력한 GPU파워가 제공되어, 굉장히 큰 규모의 모델의 학습들이 보급됨</li>
<li>Dropout과 같은 모델을 Regulazation하는 좋은 전략들이 연구됨
이러한 진보적인 발전에 비해, 복잡한 모델들이 어떻게 behavior하고 어떻게 좋은 성능을 얻는지, 내부적으로 어떻게 동작하는지에 대한 insight가 굉장히 부족했습니다.</li>
</ol>
</li>
</ol>
<p>그래서 본 논문에서는 모델의 모든 layer에 대한 각각의 feature map들을 자극하는 입력을 드러내기 위한 시각화 기법을 연구했고, 시각화는 학습 동안에 발생되는 feature의 진화를 관측할 수 있게 해주며 모델의 잠재적인 문제를 진단할 수 있게 해주었습니다.</p>
<p>이들이 제안하는 시각화 기법은 Zeiler가 제안한 Deconvolution Network를 사용하여 입력 픽셀 공간에 feature activation을 투영시키는 방법입니다. 분류를 하는데 어느 부분이 중요한 역할을 하는데 알기 위해 입력 이미지의 일부를 가리고 분류기의 출력이 이에 얼마나 민감하게 변화하는지를 분석하는 연구를 수행했습니다.</p>
<h3 id="11-related-work">1.1 Related Work</h3>
<h4 id="visualization">Visualization</h4>
<p>현실에서 네트워크에 대한 직관을 얻기 위해서 시각화를 많이 수행하나, 대부분이 pixel공간으로 투영이 가능한 첫번째 레이어로 제한된 연구였습니다.</p>
<p>상위 레이어를 시각화하는 방법 중 하나는 unit의 activation을 최대화 하기 위해 이미지 공간의 gradient descent를 수행하여 각 unit의 최적의 stimuli를 찾아내는 것입니다.(careful initialization이 요구되며, unit invariance에 대해 어떠한 정보도 제공받지 못한다는 단점이 있습니다.)</p>
<blockquote>
<ul>
<li>unit invariance란?
패턴인식의 관점에서 ideal한 feature란 robust하고, selective한 feature를 말합니다. hidden layer의 각각의 Unit들은 특징을 감지하는 feature detector라고 볼 수 있고, 이는 hidden unit이 표현하는 feature가 현재 입력에 존재하는 경우 강하게 반응하고, 현재 입력에 부재하는 경우 약하게 반응하는 경향을 보이는 것을 의미합니다.
즉, invariant한 뉴런이라는 것은 입력이 특정 변환들을 거치게 되더라도 해당 feature의 high response를 유지하는 것을 의미합니다.
(예를 들면, 어떤 뉴런이 얼굴의 특징을 탐지하는 뉴런이라고 할 때, 얼굴이 Rotate되더라도 response를 잘 해내는 것이라고 할 수 있습니다.)</li>
</ul>
</blockquote>
<p>상위 레이어를 시각화하는 또 다른 연구로, 주어진 unit의 Hessian이 최적의 reponse를 중심으로 수치적으로 연산되는 방법을 보여주는 연구가 있었습니다. 이를 통해 invariance함에 대해 insight를 제공했지만, 상위 레이어에 대한 invariance함이 너무 극도로 복잡하여 단순한 2차 근사로는 계산해내기 굉장히 어렵다는 문제가 있었습니다.</p>
<p>본 논문에서는 학습 데이터셋에 대하여 어떤 패턴이 feature map을 activate시키는지 보이기 위해, invariance를 non-parametric한 관점에서 제공한 기법을 연구하였습니다.</p>
<h3 id="2-approach">2. Approach</h3>
<p>본 논문에서는 AlexNet을 기반으로 모델을 구현했습니다.</p>
<p> CNN의 동작을 이해하기 위해 중간의 hidden layer들의 feature activity에 대한 해석이 필요하고, 이를 위해 이러한 activity들을 input space로 다시 mapping시키는 Deconvolutional Network에 기반한 기법을 보였습니다. </p>
<p>Deconvnet은 convet과 같은 component(filtering, pooling등)을 사용하지만 역으로 수행하는 네트워크로, pixel이 feature로 mapping되는 과정의 반대과정이라고 생각하면 됩니다. cnn의 maxpooling대신 unpooling이, activation대신 rectification, conv대신 deconv을 수행하게 됩니다.</p>
<p><img src="https://images.velog.io/images/lm_minjin/post/ee202141-df75-4bc4-958c-d6c3ffe26b40/image.png" alt=""></p>
<h4 id="unpooling">Unpooling</h4>
<p>Convnet에서 Maxpooling연산은 주변에서 가장 강한 자극만을 다음 단계로 전달합니다. 그렇게 때문에, 다음 단계에서 어느 신호가 가장 강한 자극을 가지고 있었는지를 파악할 수 있는 방법이 없었습니다. 이에 본 논문에서는 switch라는 개념을 도입하게 됩니다. <strong>switch는 Maxpooling 전에 가장 강한 자극의 위치 정보를 저장</strong>해놓는 것으로, 역으로 풀링을 시행할 때 switch정보를 활용하여 가장 강한 자극의 위치를 찾아갈 수 있게 됩니다.</p>
<p><img src="https://images.velog.io/images/lm_minjin/post/ea3d64b1-0b40-4825-9071-73efc57f2c76/image.png" alt=""></p>
<h4 id="rectification">Rectification</h4>
<p>본 논문에서 사용한 활성화함수는 relu함수로써, feature map들이 활성화 함수를 거치고 나면 항상 positive한 상태를 보장받습니다.</p>
<p>사실 relu를 한 번 거치고 나면, 양수인 부분은 그대로이기 때문에 상관이 없지만, 음수 부분은 0이 되어버려 살릴 수 있는 방법이 없는데, 본 논문에서는 음수 부분은 우리가 원하는 stimulus를 찾는데엔 영향을 끼치지 않아 문제가 되지 않았다고 합니다.</p>
<h4 id="filtering">Filtering</h4>
<p>Convnet은 이전 layer로부터 feature map을 컨볼루션 하기 위해 학습된 필터를 사용합니다. 이를 역연산 하기 위해 deconvnet은 같은 filter들의 trasposed된 버전을 사용합니다. 이 연산은 수학적으로 가역이 가능한 연산이기 때문에 문제가 될 것은 없습니다.
<img src="https://images.velog.io/images/lm_minjin/post/1933d0b3-fd69-45e6-8e5c-32b29aaa9091/image.png" alt=""></p>
<p>*참고하면 좋은 글 : <a href="https://medium.com/apache-mxnet/transposed-convolutions-explained-with-ms-excel-52d13030c7e8">https://medium.com/apache-mxnet/transposed-convolutions-explained-with-ms-excel-52d13030c7e8</a></p>
<h3 id="3-training-details">3. Training Details</h3>
<ul>
<li>ImageNet 데이터셋의 분류 수행을 위하여 AlexNet모델을 사용
(단, 3,4,5번째 레이어의 sparse connection을 dense coonnection으로 대체)</li>
<li>AlexNet모델은 ImageNet 2012데이터셋을 기반으로 학습
(1.3m개의 이미지, 1000개 클래스)</li>
<li>입력 크기는 256x256으로 먼저 cropping을 수행한 후, 224x224로 sub cropping을 수행</li>
<li>128 minibatch size를 기반으로 SGD로 학습, learning rate은 0.01로 두고 annealing을 함</li>
<li>학습하는 도중 첫번째 레이어의 시각화를 해보면 일부가 donimate하는 것을 확인할 수 있음
==&gt; 이를 해결하기 위해 convolutional layer의 각 filter를 renormalize함</li>
<li>70 epoch이후 학습을 멈춤</li>
</ul>
<p>이렇게 deconv과정을 거치면, 원본과 같지는 않더라도 feature가 input space에 어떻게 맵핑되는지 알 수 있습니다.
또한, 여기서 더 나아가 이를 이용해 어떤 구조가 최적의 구조인지 결정할 수 있습니다.</p>
<h3 id="4-convnet-visualization">4. Convnet Visualization</h3>
<p>deconvnet을 사용하여 ImageNet의 validation set에 대하여 feature activation을 시각화 하였습니다.</p>
<h4 id="feature-visualization">Feature Visualization</h4>
<p><img src="https://images.velog.io/images/lm_minjin/post/5a25ca09-1073-4ebb-bb5f-771f2507e77b/image.png" alt="">
그림을 살펴보면 layer 1에서는 색, edge, corner와 같은 low level의 feature들을 추출하는 것을 알 수 있습니다. layer 3을 보면 layer 1,2와 달리 좀 더 high level의 feature, 사물의 texture나 어느 정도의 물체를 추출할 수 있다는 것을 알 수 있습니다. layer가 깊어질수록 더 세밀한 특징들을 잡아낸다는 것을 알 수 있습니다.
이를 보며 특징이 제대로 포착됐는지를 확인할 수 있습니다.</p>
<p><img src="https://images.velog.io/images/lm_minjin/post/0943f015-17e4-4db8-b8e9-b213d352249a/image.png" alt="">
각각의 feature를 학습하는데에 1,2,5,10,20,30,40,64 epoch이 소요되었다고 합니다. 확실히 epoch이 커짐에 따라 특징을 제대로 추출해낸다는 것을 알 수 있습니다.
<img src="https://images.velog.io/images/lm_minjin/post/0e5bb2b6-a456-4779-bee7-126a593f3b43/image.png" alt=""></p>
<ul>
<li>invariance = 불변성, 함수의 입력이 바뀌어도 출력은 그대로 유지되어 바뀌지 않는 것</li>
</ul>
<p>그림에서 행의 a는 사진을 translation했을 때, b는 scale했을 때, c는 rotation했을 때를 의미합니다. a,b,c2와 a,b,c3는 layer 1과 layer 7에서 원본과 변형된 이미지의 feature vector사이의 Euclidean distrance를 나타낸 그래프이고, a,b,c4는 각 이미지에 변형됨에 따라 각 이미지를 옳게 분류할 확률을 나타냅니다.</p>
<p>layer 1에서는 작은 변화에도 민감하게 변화하지만, layer 7에서는 불변성이 얻어지는 것을 확인할 수 있습니다.</p>
<p><img src="https://images.velog.io/images/lm_minjin/post/6d0c9a2f-c405-45f3-b3bc-4146b6e5073b/image.png" alt="">
본 연구에서는 시각화를 통해 보다 더 좋은 모델을 만드려고 했고, 그러한 탐색 과정을 통해 input단에서 첫번째 레이어로 넘어갈 때 AlexNet에서는 사용한 11x11 필터 대신 7x7 필터를 사용하는 것이 낫다는 것을 알게 되었습니다.</p>
<p>b가 기존의 AlexNet의 첫번째 레이어에서 추출한 특징들이고, c가 본 연구의 첫번째 레이어에서 추출한 필터들입니다. 작은 stride와 필터 크기로 더 distinctive한 특징들과 적은 죽은 특징들을 추출해낸다는 것을 알 수 있습니다. d는 기존 AlexNet의 2번째 레이어에서 추출한 특징이고, e는 본 연구의 2번째 레이어의 특징들입니다. 역시 본 연구에서 만든 모델이 더 선명하게 특징을 추출하는 것을 볼 수 있습니다. </p>
<p><img src="https://images.velog.io/images/lm_minjin/post/ff461fb6-79d9-44c6-b1bf-b6ee6a9f8faa/image.png" alt="">
마지막으로, 본 논문의 저자들은 cnn이 물체의 위치까지 정확히 파악을 해준다는 것을 알 수 있었습니다. 이를 확인하기 위해 물체의 일부를 회색 박스로 가려서 학습을 진행하였고, 물체를 가리면 이를 제대로 분류해낼 가능성이 급격히 떨어지는 것을  역으로 확인해내는 방법을 사용했습니다.</p>
<p>b와 c는 layer 5에서 가장 강한 feature map의 heatmap과 projection을 나타낸 것이고, d와 e는 classifier의 출력값을 나타낸 것입니다.</p>
<p>b는 가리는 부분에 따라서 layer 5의 activation이 어떻게 달라지는지를 보여주는데, 강아지 사진을 보면 회색 박스가 강아지의 얼굴을 가리면 activation이 떨어지는 것을 확인할 수 있습니다. c에서 검은 사각형으로 표시된 부분은 가장 강한 activation을 input space에 맵핑시켰을 때를 보여줍니다. 
d는 classifier의 출력에 대해 이미지의 특정 부분을 가렸을 때 이미지를 제대로 분류하는지 확률적으로 나타낸 것입니다. 마지막으로 e는 가리는 영역에 따라 분류가 어떻게 달라지는지를 보여줍니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CycleGAN: Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks]]></title>
            <link>https://velog.io/@tobigs1516_image/CycleGAN</link>
            <guid>https://velog.io/@tobigs1516_image/CycleGAN</guid>
            <pubDate>Wed, 24 Nov 2021 02:14:02 GMT</pubDate>
            <description><![CDATA[<h3 id="기존의-gan">기존의 GAN</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/47a91184-9ae8-497a-8fcb-d304743e798d/image.png" alt="">
기존의 GAN의 경우 완벽히 한 쌍을 이루는 데이터만을 이용해 학습이 가능하였다. 하지만, 완벽히 같은 조건을 지니는 데이터를 구하기에는 어려운 부분이 존재한다. 이러한 점을 해결한 논문이 바로 CycleGAN이다. 말 그림을 얼룩말 그림으로 바꾸기 위해서는 똑같은 배경의 얼룩말 사진을 학습시켜야 했다면 CycleGAN의 경우 어떤 이미지든 얼룩말이 있는 이미지가 있다면 학습을 시킬 수 있다.</p>
<hr>
<h3 id="abstract">Abstract</h3>
<p>Image-To-Image Translation은 pair image를 활용해 input과 output을 매핑하는 것이 목표인 task이다. 하지만 앞서 설명했듯이 완벽히 한 쌍을 이루는 train 이미지를 구하는 일은 쉽지 않기 때문에, CycleGAN은 <strong>pair 없이 X라는 도메인으로부터 얻은 이미지를 타깃 도메인 Y로 바꾸는 방법</strong>을 활용한다. 즉, 한 이미지 집합의 고유한 특징들을 포착하고 이 특성을 다른 이미지 집합으로 전이시키는 것이다. </p>
<p>해당 논문의 목표는 <strong>Adversarial loss</strong>를 활용하여, G(X)로부터의 이미지 데이터 분포와 Y로부터의 이미지 데이터 분포를 구분할 수 없도록, G : X → Y를 학습시키는 것이다. 이러한 매핑은 제약이 적으므로 F : Y → X와 같은 역방향 매핑도 동시에 진행했으며, F(G(X))가 X와 유사해지도록 강제하는 <strong>cycle consistency loss</strong>를 도입했다. </p>
<p>이러한 방법을 적용하여 Cycle GAN을 활용하였을 때, 다음과 같은 결과물을 얻을 수 있었다. </p>
<p><img src="https://images.velog.io/images/yoonj98/post/c7095834-dd6a-4d9f-a534-bf7a99bd5b81/image.png" alt=""></p>
<h3 id="introduction">Introduction</h3>
<p>CycleGAN은 unpair한 이미지로 학습을 하기 위해, 도메인 간 모종의 관계가 존재한다고 가정하였다. y_hat과 y를 구분하도록 적대적으로 학습된 모델을 사용하여 이미지 y와 구분되지 않는 아웃풋 y hat = G(X)를 산출하는 G : X → Y를 학습시켰다. </p>
<p>다만, 해당 방식의 translation은 각각의 input x와 y가 의미있는 방식으로 짝지어지는 것을 보장하지 않으며, 종종 mode-collapse (어떤 input 이미지든 모두 같은 output 이미지로 매핑하면서 최적화에 실패하는 것)로 이끌곤 한다.</p>
<p>이러한 이슈를 해결하기 위해 tranlsation이 cycle consistent (주기적 일관성)이어야 한다는 속성을 이용하였다. 여기서, 주기적인 일관성은 영어로 된 문장을 불어로 번역했다면 해당 불어 문장을 영어로 번역 시 본래의 영어 문장이 도출되어야 함을 의미한다. </p>
<p>따라서, G와 F를 동시에 학습하고, F(G(X)) ≈ x, G(F(y)) ≈ y이게 만드는 cycle consistency loss를 추가함으로써, cycle consistency loss와 adversarial losses를 X와 Y에 적용된 전체 목적함수가 완성됐다.</p>
<h3 id="formulation">Formulation</h3>
<p>앞서 언급했듯이 본 논문의 목표는 주어진 도메인 X와 Y를 매핑하는 함수를 학습하는 것이다. </p>
<p><img src="https://images.velog.io/images/yoonj98/post/d3da83bd-c5c4-41df-84b7-83415cb5229b/image.png" alt=""></p>
<p>기본적으로 CycleGAN은 2개의 GAN을 필요로 한다. X에서 Y의 이미지를 만들어주는 Generator와 이 이미지가 진짜인지 판단하는 Discriminator, 그리고 반대의 경우까지 고려하기 때문이다.</p>
<blockquote>
<p>해당 논문에서 제안하는 모델을 구축하기 위한 Component는 다음과 같다. </p>
</blockquote>
<ul>
<li>Generator G : X → Y mapping</li>
<li>Generator F : Y → X mapping</li>
<li>Discriminator Dy : 실제 도메인 Y의 이미지 y와 G가 생성한 y_hat=G(x)을 구분</li>
<li>Discriminator Dx : 실제 도메인 X의 이미지 x와 F가 생성한 x_hat=F(y)을 구분</li>
</ul>
<h4 id="adversarial-loss">Adversarial Loss</h4>
<p>함수 G : X → Y와 Dy에 대해서는 아래와 같은 목적함수를 적용한다. 
<img src="https://images.velog.io/images/yoonj98/post/b058c5ef-18ac-4f24-8581-cdf6a1b9c9cc/image.png" alt=""></p>
<p>여기서, G는 위의 함수를 최소화를, Dy는 최대화시키고자 하며 이는 다음과 같이 나타낼 수 있다. 
<img src="https://user-images.githubusercontent.com/69336270/139573205-56fba68b-9078-4032-b97d-f75a795e842a.png" alt="image"></p>
<p>마찬가지로, 함수 F : Y → X와 Dx에 대해서도 유사한 adversarial losses를 적용하면 이는 다음과 같이 나타낼 수 있다. 
<img src="https://user-images.githubusercontent.com/69336270/139573209-14007f23-3d00-4c46-ab07-3cd10aebda9a.png" alt="image"></p>
<h4 id="cycle-consistency-loss">cycle consistency loss</h4>
<p> Unpaired data는 각 이미지간의 대응 관계가 너무 많기 때문에 만들어진 이미지가 실제 이미지와 pair라고 확정지을 수 없다. 이는 mapping의 제약이 적다는 것을 의미이며 결국 mode collapse로 이어질 수 있다. </p>
<p> 이러한 문제로 인해 Adversarial losses 단독으로는 매핑 함수의 제대로 된 학습을 보장하기 어렵다. 따라서, 가능한 매핑 함수의 공간을 줄이기 위해 아래의 그림 (b), (c)와 같이 매핑 함수는 cycle-consistent 해야 한다.</p>
<p><img src="https://user-images.githubusercontent.com/69336270/139570780-54265770-8f1c-44f6-a27e-1c954c3403da.png" alt="image"></p>
<p>이러한 행동은 cycle consistency loss를 이용해 유도할 수 있으며, 수식은 다음과 같다. 각각 생성해낸 이미지를 다시 원본으로 복구할때, 원본과 그 복구값과의 거리를 구하는 것이다.</p>
<p><img src="https://user-images.githubusercontent.com/69336270/139570827-262f57a0-6612-4165-a47a-fe942e1ac427.png" alt="image"></p>
<p>Cycle consistency loss가 유도한 결과는 다음과 같으며, 재건된 이미지 F(G(X))가 input 이미지 x와 유사함을 확인할 수 있다. </p>
<p><img src="https://user-images.githubusercontent.com/69336270/139570841-f702bc82-9a1f-4060-8d79-5b24c0afb569.png" alt="image"></p>
<h3 id="full-objective">Full objective</h3>
<p>전체 목적 함수는 다음과 같다. 
<img src="https://user-images.githubusercontent.com/69336270/139570886-e69d9095-98bf-4eb5-9a76-bfcdf846e7b0.png" alt="image"></p>
<p>λ는 두 함수(= 위 식에서의 첫 번째 항과 두 번째 항)의 상대적인 중요도에 따라 결정되며, 본 논문의 풀고자 하는 목표는 다음과 같다.</p>
<p><img src="https://user-images.githubusercontent.com/69336270/139570918-c0c0ee60-99f0-48e2-918b-6848beefebd7.png" alt="image"></p>
<p>즉, X → Y GAN의 Adversarial Loss와, Y → X GAN의 Adversarial Loss를 더하고, 각각 다시 원본으로 복구하는 cycle consistency loss 값을 더해준 값이 최종  Loss값이며, 이를 최소화하는 방향으로 G와 F를 학습하는 것이다.</p>
<h3 id="implementation">Implementation</h3>
<h4 id="training-details">Training details</h4>
<p>모델 학습 과정을 안정화시키기 위해 두 가지 기술을 적용했다. </p>
<ol>
<li><p>$L_{GAN}$의 negative log likelihood 함수를 least-squares loss로 대체했다는 점이다. 해당 loss가 학습 과정에서 더욱 안정적이고 좋은 품질의 결과를 도출했다. </p>
</li>
<li><p>모델의 진동을 줄이기 위해 discriminator를 최신의 generator가 생성한 하나의 이미지를 이용하기보다는 지금까지 생성된 이미지들을 사용했다는 점이다. 이를 위해 이전에 생성된 이미지 50개를 저장할 수 있는 버퍼를 이용했다.</p>
</li>
</ol>
<h3 id="result">Result</h3>
<h4 id="evaluation">Evaluation</h4>
<p>pix2pix와 같은 데이터 셋과 평가 지표 (metrics)를 사용하여 몇 가지 baseline과 양적, 질적 두 기준 모두로 비교했다. 도시 풍경 데이터셋에서의 semantic label ↔ photo task와 Google map으로부터의 aerial photo(공중사진) ↔ 지도 태스크를 포함하며, loss function에 대한 연구도 진행했다.</p>
<h4 id="evalution-metrics">Evalution metrics</h4>
<p>이때, 사용된 평가 지표는 총 3가지이다. </p>
<ol>
<li><p>AMT perceptual studies
사람을 대상으로 한 실험으로, 참가자들에게는 실제 사진 혹은 가짜 이미지를 보여준 후 그들이 진짜라고 생각하는 것을 선택하게 했다.</p>
</li>
<li><p>FCN score
perceptual studies가 얼마나 그래픽이 실제 같은지를 테스트하는 데에 있어서는 매우 좋은 기준이지만, 사람을 대상으로 한 실험이 필요하지 않은 automatic한 양적 기준을 위해 우리는 &#39;FCN score&#39;를 채택했다. </p>
</li>
<li><p>Semantic segmentation metrics
사진을 라벨링 하는 성능을 평가하기 위해 우리는 per-pixel 정확도(accuracy)와 IOU를 포함하는 기본적인 평가지표를 이용했다.</p>
</li>
</ol>
<h4 id="comparison-against-baselines">Comparison against baselines</h4>
<p>CoGAN, SimGAN, pix2pix와 같은 다양한 다른 모델과 CycleGAN에게 같은 태스크를 시킨 후, 결과를 비교했을 때의 결과이다. 
<img src="https://user-images.githubusercontent.com/69336270/139572511-efe8b052-adc9-49be-90b3-346f49d746f8.png" alt="image"></p>
<h3 id="application">Application</h3>
<p><img src="https://user-images.githubusercontent.com/69336270/139572559-be98a529-0370-4ca7-9365-f678372f2aa0.png" alt="image">다음은 CycleGAN을 통해 pair가 없는 task에 대해 모델을 적용한 결과이다. 이때, 등장한 $L_{idnetity}$란 인풋과 아웃풋의 색 구성을 보존하기 위해 추가된 loss로, 그림이 아닌 사진이 인풋으로 들어왔을 때는 사진 자기 자신을 아웃풋으로 산출하도록 generator를 regularize한다. 이를 통해 generator가 종종 낮의 그림을 해질녘의 사진으로 바꾸는 것과 같은 문제를 해결할 수 있다. </p>
<h3 id="limitations-and-discussion">Limitations and Discussion</h3>
<p>다만, CycleGAN 역시 모든 task에서 긍정적인 결과만을 도출한 것은 아니다. </p>
<p>CycleGAN은 주로 분위기나 색상을 바꾸는 것으로 스타일을 학습하여 다른 이미지를 생성한다. 따라서, 기하학적인 모양을 변경하는 데는 어려움이 있다. 또한, 데이터셋의 분포가 불안정하면 이미지를 제대로 생성할 수 없다.</p>
<p><img src="https://user-images.githubusercontent.com/69336270/139572645-f0b0c593-e14b-47ef-8fc2-83cad3597ca2.png" alt="image">다음 그림을 보면, 사과를 오렌지로 바꿀 때 단순히 색상만 변경됨을 확인할 수 있다. 또한, 사람을 태운 말을 얼룩말로 바꿀 때 사람까지 얼룩말로 바뀌었는 데 이는 학습한 데이터에서 사람이 얼룩말을 탄 이미지가 단 1장이었기 때문이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[FaceNet]]></title>
            <link>https://velog.io/@tobigs1516_image/FaceNet</link>
            <guid>https://velog.io/@tobigs1516_image/FaceNet</guid>
            <pubDate>Wed, 17 Nov 2021 05:44:33 GMT</pubDate>
            <description><![CDATA[<h1 id="abstract--introduction">Abstract &amp; Introduction</h1>
<ul>
<li>각각의 얼굴 이미지를 128차원으로 임베딩하여 이미지에 대한 feature를 구한 후 유클리드 공간에서 임베딩 간 거리를 구한다. </li>
<li>즉, 각 이미지의 임베딩 결과의 거리를 이미지 간 유사도로 사용하여 Face Recognition과 Clustering을 하는 모델이다.</li>
<li>기존 얼굴 인식 접근 방법은 CNN을 사용하여 classification layer를 학습한 후 중간 단계 레이어의 출력값을 사용하였는데, FaceNet은 triplet loss를 통해 임베딩 자체를 다이렉트로 최적화하여 CNN을 훈련한다.</li>
<li>임베딩을 계산한 후 다이렉트하게 task를 해결하는데, Face Verification(두 사람이 같냐 다르냐?)은 두 임베딩 사이의 거리에 threshold를 주어 해결하며, Face Recognition(새로 들어온 이 사람이 누구냐?)은 K-NN Classification을, Clustering은 K-means 또는 Agglomerative clustering을 사용하여 해결한다.</li>
</ul>
<h1 id="triplet-loss를-이용한-metric-learning">Triplet Loss를 이용한 Metric Learning</h1>
<p><img src="https://images.velog.io/images/hannapark56/post/1d8fd3e5-daf2-4f8e-a311-e879a6c2b7cb/image.png" alt=""></p>
<ul>
<li>Anchor(기준 이미지), Positive(기준과 같은 사람 이미지), Negative(기준과 다른 사람 이미지)를 한 쌍의 데이터로 입력 받는다.</li>
<li>동일한 네트워크에 위의 3개의 이미지를 인풋으로 받아 각 이미지의 임베딩을 구한다. 여기서 임베딩의 이미지는 이미지의 특징을 잘 담고 있는 임베딩이다.</li>
</ul>
<p><img src="https://images.velog.io/images/hannapark56/post/412b9b7d-c370-4c72-8c9c-e1803e84eb73/image.png" alt=""></p>
<ul>
<li>위의 식에서 앞의 항은 같은 사람의 두 이미지에 대한 임베딩의 거리를 구한 것이며, 뒤의 항은 다른 두 사람의 이미지의 임베딩의 거리를 구한 것이다. </li>
<li>여기서 핵심은 같은 사람의 이미지의 임베딩은 가깝게, 다른 사람의 이미지의 임베딩은 멀게 학습시키는 것이다.</li>
<li>α는 positive와 negative사이의 margin을 의미한다.</li>
</ul>
<p><img src="https://images.velog.io/images/hannapark56/post/c96f02cf-1af8-4160-bee5-e9565a991c0d/image.png" alt=""></p>
<ul>
<li>Loss는 위의 식과 같다. 즉 위의 Loss를 최소화하는 방식으로 네트워크를 훈련시킨다.</li>
</ul>
<h1 id="triplet-selection">Triplet Selection</h1>
<p><img src="https://images.velog.io/images/hannapark56/post/412b9b7d-c370-4c72-8c9c-e1803e84eb73/image.png" alt=""></p>
<ul>
<li>Triplet 데이터를 잘 뽑는 것은 매우 중요한데, 많은 triplets가 위의 식을 쉽게 만족할 것이며 이는 학습이 제대로 진행되지 않는다는 문제가 발생한다.</li>
<li>이를 해결하기 위해 거리가 최대한 먼 positive (hard positive), 거리가 최대한 가까운 negative (hard negative)를 골라 위의 식을 만족하지 않는 triplet을 만들어야 한다.</li>
</ul>
<p><img src="https://images.velog.io/images/hannapark56/post/62ae8e27-4009-4bf5-9786-e516ce864fbe/image.png" alt=""></p>
<ul>
<li>전체 데이터셋에서 argmin과 argmax를 계산하는 것은 불가능하다. 또한, 이런 방식은 hard positive, hard negative로 잘못 라벨링된 이미지나 poor한 이미지가 선택될 가능성이 많기 때문에 좋지 않은 학습 과정이 될 수 있다.</li>
<li>이를 해결하기 위해 각 사람마다 40개의 이미지를 수집하여 하나의 mini batch에 담는다. Hard postive는 mini batch내의 모든 anchor-positive을 사용하며, hard negative는 아래의 식을 만족시키는 이미지를 선택한다.</li>
</ul>
<p><img src="https://images.velog.io/images/hannapark56/post/9564592e-fb9a-4166-85f6-63b6f3ccc3db/image.png" alt=""></p>
<ul>
<li>위의 식을 만족하여 얻은 negative를 semi-hard라고 부르며, margin α 보다 크지 않은 negative를 선택하는 것이다.</li>
</ul>
<h1 id="deep-convolutional-networks">Deep Convolutional Networks</h1>
<ul>
<li>SGD, AdaGrad, margin α는 0.2를 사용하여 CNN을 학습한다.</li>
<li>두 종류의 네트워크를 사용하였는데, 가장 성능이 잘 나온 네트워크(NN2, Inception 224x224)의 구조는 다음과 같다.
<img src="https://images.velog.io/images/hannapark56/post/db40f011-d6e5-458b-988c-effd7a8ca08a/image.png" alt=""></li>
</ul>
<h1 id="performance-on-lfw">Performance on LFW</h1>
<ul>
<li>이미지를 얼굴 크기에 맞게 잘라주는 과정만 했을 때 98.87%의 정확도를 보였고, 추가적인 alignment를 했을 때 99.63%의 정확도를 보였다.</li>
<li>다음 이미지는 FaceNet이 잘못 맞춘 이미지이다. 
<img src="https://images.velog.io/images/hannapark56/post/9433bfe5-3ba7-4836-8f7c-d5f957bba5dc/image.png" alt=""></li>
<li>사람의 육안으로도 쉽게 구분하기 어려운 이미지이며, 이를 통해 FaceNet의 성능이 꽤나 좋은 것을 확인할 수 있다.</li>
</ul>
<h3 id="face-clustering">Face Clustering</h3>
<ul>
<li>FaceNet이 동일 인물을 Clustering한 결과이다.</li>
</ul>
<p><img src="https://images.velog.io/images/hannapark56/post/f99a0e95-3a83-4c18-8211-8dc60068b156/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Neural Style Transfer]]></title>
            <link>https://velog.io/@tobigs1516_image/Neural-Style-Transfer</link>
            <guid>https://velog.io/@tobigs1516_image/Neural-Style-Transfer</guid>
            <pubDate>Wed, 17 Nov 2021 05:33:34 GMT</pubDate>
            <description><![CDATA[<h1 id="what-is-neural-style-transfer">What is neural Style Transfer?</h1>
<p><img src="https://images.velog.io/images/kimkj38/post/bf8d6121-9cc2-4faf-978d-818a3ee285b7/image.png" alt=""></p>
<ul>
<li>원본 이미지에 특정 스타일을 입혀 새로운 형태의 이미지를 생성하는 것</li>
<li>대표적으로 Pix2pix, CycleGAN 등의 논문들이 있다</li>
</ul>
<h1 id="what-are-deep-convnets-learning">What are deep ConvNets learning?</h1>
<p><img src="https://images.velog.io/images/kimkj38/post/6f9a2569-3be2-40f0-9c25-4b7b49c83f82/image.png" alt="">
신경망에서 학습하는게 대체 무엇인가?
-&gt; 훈련 세트가 신경망을 거칠 때 각 레이어에서 유닛의 활성값을 최대화하는 이미지를 시각화하자</p>
<p><img src="https://images.velog.io/images/kimkj38/post/63072e63-9597-4583-8b8c-394c08c82e17/image.png" alt=""></p>
<ul>
<li>위 그림은 첫번째 은닉층에서 유닛들의 활성화를 최대로하는 이미지를 가져온 모습이다.</li>
<li>(a)는 좌상단에서 우하단을 향하는 대각선을, (b)에서는 좌하단에서 우상단을 향하는 대각선을, (c)는 왼쪽이 초록색인 세로 모서리, (d)는 주황색을 탐지하는 유닛이라고 볼 수 있다.</li>
<li>얕은 레이어에서는 선, 코너 등과 같이 단순한 형태의 이미지를 탐지할 수 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/kimkj38/post/04e67e0e-e0b7-47c9-b2ac-105119e3fc63/image.png" alt=""></p>
<ul>
<li>레이어가 깊어짐에 따라 탐지할 수 있는 이미지의 수준이 고도화된다.</li>
<li>두번째 레이어에서는 여러개의 세로선 혹은 눈과 같은 blob 형태의 이미지들을 확인할 수 있으며 세번째 레이어에서는 차의 바퀴와 같은 객체의 일부를, 마지막 레이어에서는 객체 자체를 인식할 수 있게 된다.</li>
</ul>
<h1 id="cost-function">Cost function</h1>
<p><img src="https://images.velog.io/images/kimkj38/post/af77050b-d3b3-4880-a4af-84b73a2cd6c9/image.png" alt=""></p>
<blockquote>
<p>$J(G) = \alpha J_{content}(C,G) + \beta J_{style}(S,G)$</p>
</blockquote>
<ul>
<li>Style Transfer에서의 생성이미지는 Content $C$와 Style $S$ 이 둘 모두와 유사해야 하기 때문에 비용함수도 두 개로 구성된다.</li>
<li>가중치 $\alpha, \beta$로 두 개의 비용함수의 비중을 조절할 수 있다.</li>
<li>생성이미지는 처음에는 랜덤하게 픽셀을 부여하여 노이즈 형태로 나타나지만 $C, S$와 유사해지도록 학습함으로써 점점 그럴듯한 모양의 이미지를 생성해낸다.</li>
</ul>
<h2 id="content-cost-function">Content cost function</h2>
<p><img src="https://images.velog.io/images/kimkj38/post/b033880d-ba93-4bbd-86af-83bb76e2a590/image.png" alt=""></p>
<ul>
<li>VGG 등과 같은 사전학습된 ConvNet을 사용하여 생성이미지와 content 이미지의 차이를 최소화하도록 만든다.</li>
<li>layer $l$을 이용하여 비용함수를 계산하며, 이 때 $l$은 너무 깊지도 얕지도 않은 layer가 되어야 한다.</li>
<li>얕은 레이어에서의 비교로 학습하면 생성 이미지가 content image와 거의 일치하는 픽셀값들을 가질 것이며, 깊은 레이어에서의 비교로 학습하면 생성이미지가 content image와 크게 다를 것이다.</li>
</ul>
<h2 id="style-cost-function">Style cost function</h2>
<p><img src="https://images.velog.io/images/kimkj38/post/7d5ea608-d260-4e19-a182-f8fa0b0930e5/image.png" alt=""></p>
<ul>
<li>style이란 각 채널들 사이에 분포하는 활성값들의 상관관계를 의미한다</li>
<li>위 그림에서 수직선을 나타내는 채널과 주황색을 나타내는 채널을 비교할 때 상관관계가 높다면 수직선이 있을 때 주황색을 나타냄을 의미하고 상관관계가 낮다면 두 특징은 함께 나타날 필요가 없음을 의미한다.
<img src="https://images.velog.io/images/kimkj38/post/42f02134-95fc-4736-94af-190b33a66092/image.png" alt=""></li>
</ul>
<blockquote>
<ul>
<li>$G_{kk&#39;}^{<a href="S">l</a>} = \sum\limits_{i=1}^{n_H^{[l]}}\sum\limits_{j=1}^{n_W^{[l]}}a_{ijk}^{<a href="S">l</a>}a_{ijk&#39;}^{<a href="S">l</a>}$</li>
</ul>
</blockquote>
<ul>
<li><p>$G_{kk&#39;}^{<a href="G">l</a>} = \sum\limits_{i=1}^{n_H^{[l]}}\sum\limits_{j=1}^{n_W^{[l]}}a_{ijk}^{<a href="G">l</a>}a_{ijk&#39;}^{<a href="G">l</a>}$</p>
</li>
<li><p>위 식은 채널 $k$와 $k&#39;$의 상관관계를 의미하며 Gram matrix라고 부른다.
<img src="https://images.velog.io/images/kimkj38/post/cf918684-b372-4d82-a8b3-f87cc17eee59/image.png" alt=""></p>
</li>
<li><p>최종적인 Style cost function은 위와 같으며 생성이미지와 Style image의 스타일(각 채널 간의 상관관계)의 차이값을 최소화하도록 만든다.</p>
</li>
<li><p>이 때, 앞에 붙는 정규화 상수는 Cost function에서 $\beta$가 곱해지기 때문에 중요하지 않다.</p>
</li>
</ul>
<h1 id="1d-and-3d-generalization">1D and 3D generalization</h1>
<h2 id="1d">1D</h2>
<p><img src="https://images.velog.io/images/kimkj38/post/3a8b4a49-f364-4f4a-9cf3-b933bbae0458/image.png" alt=""></p>
<ul>
<li>1D로의 변환은 단지 너비와 높이가 없이 일렬로 값들이 나열된다는 차이점 뿐이다.</li>
<li>(14x14x3)의 2D 이미지가 (5x5x3)의 필터를 거쳐 (10x10x16)의 output으로 나오는 연산은 (14x1)의 1D 정보가 (5x1)의 필터를 거쳐 (10x16)의 output으로 나오는 연산과 동일하다.</li>
</ul>
<h2 id="3d">3D</h2>
<p><img src="https://images.velog.io/images/kimkj38/post/97749ec8-2f52-44a5-83eb-089e3ee932df/image.png" alt=""></p>
<ul>
<li>3D의 예시로 CT 촬영을 들 수 있다.</li>
<li>CT는 몸의 각 단면을 스캔하는 것으로 너비, 높이 외에 깊이에 대한 정보가 추가된다.</li>
<li>따라서, 필터도 3차원으로 구성되며 (14x14x14x1)의 이미지가 (5x5x5x1)의 필터를 거쳐 (10x10x10x16)의 output을 출력하는 예를 들 수 있다.</li>
</ul>
<h1 id="reference">Reference</h1>
<ul>
<li><a href="https://www.edwith.org/ai218/joinLectures/138363?isDesc=false">https://www.edwith.org/ai218/joinLectures/138363?isDesc=false</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Face Recognition]]></title>
            <link>https://velog.io/@tobigs1516_image/Face-Recognition</link>
            <guid>https://velog.io/@tobigs1516_image/Face-Recognition</guid>
            <pubDate>Wed, 10 Nov 2021 09:39:40 GMT</pubDate>
            <description><![CDATA[<h2 id="what-is-face-recognition">What is face recognition</h2>
<h3 id="face-verification-vs-face-recognition">Face verification vs face recognition</h3>
<p>Verification(1:1)</p>
<ul>
<li>input image, name/ID</li>
<li>output whether the input image is that of the claimed person
 얼굴 검증 문제는 입력 이미지와 어떤 사람의 이름 또는 ID가 주어지면, 시스템이    그 사람인지를 검증하는 것입니다.</li>
</ul>
<p>Recognition(1:k)</p>
<ul>
<li>Has a database of K persons</li>
<li>Get an input image</li>
<li>output ID if the image is any of the K persons(or &quot;not recognized&quot;)
 만약, 한 사람에 대해 실수할 확률이 1%일 때 DB에 100명이 있으면, 얼굴 인식      은 실수할 확률이 100배가 됨. 즉, 100명의 DB에서 얼굴 인식이 잘 작동하기       위해선 각각의 사람에 대해 맞출 확률이 99%보다 더 높아야 함.</li>
</ul>
<p>즉, 얼굴 검증 문제보다 얼굴 인식 문제가 더 어렵다!
앞으로 살펴 볼 내용은 구성 요소로서 얼굴 검증 시스템을 만드는 것. 정확도가 충분히 높으면 이를 인식 시스템에 활용할 수 있다.</p>
<h2 id="one-shot-learning">One shot learning</h2>
<p>원샷 학습 문제에선 하나의 예시를 통해서만 사람을 인식해야 함.
(대부분의 얼굴 인식 시스템이 이것이 필요. 보통 DB엔 직원 혹은 팀원의 사진이 하나밖에 없기 때문!)</p>
<p><img src="https://images.velog.io/images/lm_minjin/post/42bb1775-438f-4e54-882a-156be480f533/image.png" alt="">
접근 방법 중 하나는 출력 시 직원과 모르는 사람이라는 클래스를 추가해서 학습시키는 것. 
하지만 이는 신경망을 훈련시키기에 충분하지 않기도 하고, 새로운 사람이 입사하게 되면 소프트맥스 유닛을 추가해서 다시 훈련 시켜야 함.</p>
<h3 id="learning-a-similiarity-function">Learning a &quot;similiarity&quot; function</h3>
<p>이 방법 대신 유사도 함수를 학습시키는 방법이 있다. 
이는 신경망으로 하여금 두 이미지의 유사도를 구하는 함수를 학습시킴.
<img src="https://images.velog.io/images/lm_minjin/post/d1f5d586-a253-4acf-bc5a-e751f1aa5627/image.png" alt=""></p>
<ul>
<li>유사도 함수 : d(img1, img2) = 두 이미지의 차이</li>
<li>어떤 기준치 보다 크면 두 이미지가 서로 많이 다른 것이고, 작으면 비슷한 것
=&gt; 이는 얼굴 검증 문제를 다루는 방식!
이 방식을 활용할 경우, DB에 새로운 사람을 추가해도 그대로 잘 작동한다!</li>
</ul>
<h2 id="siamese-network">Siamese Network</h2>
<p>: 두 개의 입력에 대해 독립적으로 두 개의 합성곱 신경망을 실행한 뒤 비교하는 아이디어
<img src="https://images.velog.io/images/lm_minjin/post/f86c7936-0e46-4bfb-b66f-08f678a2476e/image.png" alt=""></p>
<ul>
<li>하나의 이미지를 신경망에 넣어서 얻은 FC의 결과를 &quot;x1의 인코딩&quot;이라고 하자. 즉, 해당 이미지를 어떤 작은 차원의 벡터로 표현한 것.</li>
<li>다른 사진과 비교하기 위해서, 이 이미지의 FC 결과인 &quot;x2의 인코딩&quot;을 구함. 만약 두 인코딩 벡터가 해당 이미지를 잘 표현하고 있다면, 두 벡터 사이의 거리 d를 구할 수 있다.<ul>
<li>여기서 거리는 두 벡터 사이의 norm으로 정의.<ul>
<li>d(x1, x2) = IIf(x1) - f(x2)II</li>
</ul>
</li>
</ul>
</li>
<li>따라서 두 개의 입력에 대해 독립적으로 두 개의 합성곱 신경망을 실행한 뒤, 비교하는 아이디어를 샴 네트워크라고 한다! (두 신경망은 같은 파라미터를 가짐.)</li>
<li>샴 네트워크의 학습 방법<ol>
<li>두 네트워크에 두 사진을 입력으로 넣고, 합성곱 신경망으로 인코딩을 시킴.</li>
<li>만약에 두 사람이 비슷한 사람이라면, 인코딩 사이의 거리 값은 작아야 함.</li>
<li>만약에 두 사람이 다른 사람이라면, 인코딩 사이의 거리 값은 커야 함.</li>
<li>위 조건을 만족시키도록 학습 시킴.<h2 id="triplet-loss">Triplet loss</h2>
<h3 id="learning-objective">Learning Objective</h3>
삼중항 손실 함수는 항상 하나의 이미지를 기준으로, 같은 사람인 것을 뜻하는 &quot;긍정 이미지&quot;와 다른 사람인 &quot;부정 이미지&quot;의 거리를 구한다. 즉, 한 번에 3개의 이미지를 보게 됨!
<img src="https://images.velog.io/images/lm_minjin/post/706cd82c-58ca-4b6c-804c-d8a6d5b4d737/image.png" alt=""></li>
</ol>
</li>
<li>기준이 되는 이미지를 A, 긍정 이미지를 P, 부정 이미지를 N으로 두자.
우리의 목적은 A와 P와의 거리가 항상 A와 N사이의 거리보다 작거나 같게 만드는 것!<h3 id="loss-function">Loss function</h3>
<img src="https://images.velog.io/images/lm_minjin/post/23a79e13-6f77-4fa7-ad4d-1e58a307b5f1/image.png" alt=""></li>
</ul>
<p>이는 아래와 같이 변형할 수 있음.
<img src="https://images.velog.io/images/lm_minjin/post/b31419de-14c5-4963-8800-dbe2508431f5/image.png" alt="">
위의 식을 만족하는 자명한 방법 중에 하나는 두 거리가 모두 0이 되는 것. 따라서 신경망이 무조건 0을 반환하지 않게 하기 위해, 신경망으로 하여금 모든 인코딩이 같지 않다는 것을 알려줘야 함.</p>
<p>따라서, 목적 함수를 약간 수정함.
<img src="https://images.velog.io/images/lm_minjin/post/f2758378-bfe8-4196-8f6b-cb15811d16c7/image.png" alt="">
(alpha는 하이퍼파라미터. 마진이라고 불리기도 함. 마진의 역할을 두 거리의 값이 차이가 충분한 거리를 갖게 만드는 것. 왜냐면 A와 P의 거리에 알파를 더한 값보다 A와 N의 거리가 같거나 크게 만드니까!)</p>
<p>단일 손실함수는 아래와 같음.
<img src="https://images.velog.io/images/lm_minjin/post/e5aa6a6a-a84d-4f79-a655-b994746b4b14/image.png" alt="">
(여기서 max함수의 역할은 거리의 차이값이 얼마나 음수인지는 신경쓰지 않게 하기 위함! =&gt; 즉, A와 P와의 거리가 A와 N과의 거리보다 작을 경우엔 신경 쓰지 않음. 맞게 계산된 거니까!)
즉, 이 목적 함수는 A와 P와의 거리가 A와 N과의 거리보다 충분히 작아서(마진만큼), max( ...  , 0)을 했을 때 0이 도출되도록 함.</p>
<p>전체 손실 함수는 아래와 같음.
<img src="https://images.velog.io/images/lm_minjin/post/5fd92347-db4e-4c4d-8678-b2ec5626a2b1/image.png" alt="">
만약 천 명의 사람에 대한 만 개의 이미지 훈련 세트가 있다면 만 개의 사진을 사용해서 삼중항을 만들고, 삼중항에 대해 정의도니 비용 함수에 경사 하강법을 적용해서 신경망을 훈련시켜야 함.
삼중항 데이터셋을 정의하기 위해서 A와 P의 쌍들이 필요함. 같은 사람에 대한 쌍! 따라서 시스템을 훈련시키기 위해서 같은 사람에 대한 많은 이미지의 데이터셋이 필요하다. 그래서, 예시로 천 명의 사람에 대해 만 개의 이미지를 예로 든 것.
이를 적용해서 시스템을 훈련시킨 다음에 얼굴 인식 시스템의 원샷 학습 문제에 적용할 수 있다!</p>
<h3 id="choosing-the-triplets-apn">Choosing the triplets A,P,N</h3>
<p>어떻게 삼중항을 생성할 수 있을까?
훈련 세트인 A, P, N을 무작위로 고르면 제약식을 쉽게 달성하게 됨. 왜냐면, 무작위로 뽑힌 두 장의 사진에서 확률적으로 A,N이 A,P보다 훨씬 다를 것이기 때문. 즉, d(A,N)이 d(A,P)+alpha보다 클 확률이 높다(N은 A와 다른 사람이니까!).
따라서, 훈련 세트를 만들 때 학습하기 어렵게 만들어야 함.</p>
<ul>
<li>d(A,P)가 d(A,N)과 비슷하면 어렵게 만드는 효과를 얻을 수 있음.<ul>
<li>대부분의 경우에 제약식을 만족하지 않게 훈련 세트를 만드는 것은 경사 하강법이 더 효율적으로 일을 하게 함.
==&gt; 랜덤으로 고르지 말고, A와 유사한 N을 찾아서 삼중항으로 만들자!</li>
</ul>
</li>
</ul>
<h3 id="triplet-selection추가">Triplet Selection(추가)</h3>
<p><em>참고 : <a href="https://deep-learning-study.tistory.com/681">https://deep-learning-study.tistory.com/681</a></em>, <em><a href="https://omoindrot.github.io/triplet-loss">https://omoindrot.github.io/triplet-loss</a></em></p>
<p>논문에서는 hard negative, hard positive method를 제안함. 학습하기 어려운 positive와 negative sample을 추출하여 모델이 어려운 환경에서 학습되도록 함. 학습 초기에는 hard example 방법이 모델의 불안정함을 유발하므로 초기에는 all positive sample로 학습을 진행함.
<img src="https://images.velog.io/images/lm_minjin/post/3622e095-450d-4ebf-9a0c-6f07aa9c3810/image.png" alt=""></p>
<ul>
<li>easy triplets : triplets which have a loss of 0, because d(a,p) + margin &lt; d(a,n)</li>
<li>hard triplets :  triplets where the negative is closer to the anchor than the positive, i.e. d(a,n) &lt; d(a,p)</li>
<li>semi-hard triplets : triplets where the negative is not closer to the anchor than the positive, but which still have positive loss. i.e. d(a,p) &lt; d(a,n) &lt; d(a,p) + margin</li>
</ul>
<p>hard positive sample은 다음의 조건을 만족하는 sample을 의미.
<img src="https://images.velog.io/images/lm_minjin/post/574b5b32-5918-4086-bbc9-2dd6438b0e04/image.png" alt="">
위 수식을 보면, anchor와 positive사이의 embedding거리가 최대인 sample을 의미. 일정 임계점 거리 이상이면 negative로 분류되는데, negative로 분류되기 전까지의 거리가 최대인 sample을 의미</p>
<p>hard negative sample은 다음의 조건을 만족.
<img src="https://images.velog.io/images/lm_minjin/post/624f477b-74f9-45c8-ba33-9a3e9c68d521/image.png" alt="">
negative sample이 되는 임계점에 가까운 negative sample은 hard negative sample임. 
모델이 positive인지 negative인지 판별하기 어려운 sample로 학습한다면 더 좋은 성능을 나타낸다.
즉, mini-batch안에서 가장 큰 d(a,p)과 가장 작은 d(a,n)의 조합을 선택해서 모델을 좀 더 좋게 학습시킬 수 있음.</p>
<h2 id="face-verification">Face Verification</h2>
<h3 id="learning-the-similarity-functioon">Learning the similarity functioon</h3>
<p>샴 네트워크를 훈련시키는 다른 방법은 인코딩들의 차이를 로지스틱 회귀 유닛에 입력해서 예측을 하면 됨! (같은 사람일 경우 1, 다른 사람일 경우 0)
<img src="https://images.velog.io/images/lm_minjin/post/b1f4a94f-4420-4100-b9fc-c4568a5ab5c5/image.png" alt=""></p>
<p>샴 네트워크의 훈련 방법
<img src="https://images.velog.io/images/lm_minjin/post/a62f841c-134b-4853-91b0-6818867accfa/image.png" alt=""></p>
<ul>
<li>로지스틱의 역할은 두 인코딩과의 차를 이용하여 두 이미지가 같은 사람인지 아닌지 판단하는 것. 두 인코딩간의 차이는 여러가지 방식으로 구할 수 있음.(둘의 차를 제곱해서 각각의 합으로 나눌 수도 있음 - 카이 제곱 방식)</li>
<li>훈련 세트도 한 쌍의 이미지로 만듦. 같은 사람일 경우 라벨을 1로 지정하고, 다를 경우 0으로 만듭니다.
<img src="https://images.velog.io/images/lm_minjin/post/5f94beb3-65b3-46d0-b382-6ff63fcabdfd/image.png" alt="">
=&gt; 이렇게 이진 분류로 학습을 할 경우, DB에 있는 이미지는 미리 임베딩 값을 계산하고, 새로운 이미지에 대해서만 인코딩 값을 계산해 미리 계산된 인코딩과 비교.
만약 직원 DB가 아주 큰 경우 모든 직원에 대해 매번 인코딩을 계산할 필요가 없으므로, 계산량을 상당히 줄일 수 있다.
(이 방식은 위와 같은 샴 신경망과 삼중항 손실 함수를 사용하여 인코딩을 학습하는 경우 모두 적용 가능.)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[SSD: Single Shot MultiBox Detector]]></title>
            <link>https://velog.io/@tobigs1516_image/SSD-Single-Shot-MultiBox-Detector</link>
            <guid>https://velog.io/@tobigs1516_image/SSD-Single-Shot-MultiBox-Detector</guid>
            <pubDate>Wed, 10 Nov 2021 08:47:47 GMT</pubDate>
            <description><![CDATA[<h1 id="introduction">Introduction</h1>
<ul>
<li>기존 연구들은 bouding box들을 뽑아내고 특징을 추출한 뒤 classifier를 거치는 과정을 거쳤다.</li>
<li>하지만 이러한 과정들은 연산량이 매우 크며, 실시간으로 응용하기에는 느리다는 단점이 있다.</li>
<li>본 논문에서는 속도를 크게 개선하며 정확도 또한 유지하는 네트워크를 제안한다.</li>
</ul>
<blockquote>
<p><strong>&lt;SSD의 특징&gt;</strong></p>
</blockquote>
<ul>
<li>classification과 localization을 위해 작은 컨볼루션 필터를 사용한다.</li>
<li>각기 다른 비율을 가진 객체들을 검출하기 위해 구별된 필터를 사용한다.</li>
<li>다양한 크기의 객체들을 검출하기 위해 여러 feature map으로부터 위의 필터를 이용하여 output을 도출한다.
(VOC2007 데이터셋으로 test한 결과 59FPS/74.3% mAP로 7FPS/74.3% mAP인 Faster-RCNN과 45FPS/63.4% mAP인 YOLO에 비해 높은 성능)</li>
</ul>
<h2 id="model">Model</h2>
<p><img src="https://user-images.githubusercontent.com/76815825/117246200-292ba700-ae77-11eb-8c84-cec0b44670d0.png" alt="image"> </p>
<p>Base network로 <strong>VGG16</strong>을 활용하였다. <strong>3개의 FC layer 중 2개만 Convolution layer로 대체하여 사용</strong>하였으며 뒤에 auxiliary structure를 덧붙였다. <strong>추가된 레이어</strong>를 살펴보면 $p$개의 채널을 가진 <strong>m x n feature map에 $(3 \times 3 \times p)$의 필터를 적용</strong>하여 <strong>class score와 좌표값을 예측</strong>할 수 있다.   </p>
<p>자세히 보면 다음과 같다. </p>
<p><img src="https://user-images.githubusercontent.com/76815825/117247241-e1a61a80-ae78-11eb-87e7-1fcdd5c69d95.png" alt="image"> </p>
<p>Pascal 데이터셋을 예로 설명하면, 
3x3x(bouding box의 개수x(Class의 개수+좌표값(x,y,w,h))) = 3x3x(6x(21+4))가 <strong>Classifier</strong>가 된다. 결과는 그림의 우측과 같이 <strong>각 bounding box별로 좌표값과 class score</strong>가 나오는 것을 볼 수 있다. </p>
<p>SSD에서는 클래스 별로 <strong>8732개의 bounding box</strong>가 나오게 되는데 도출 과정은 다음과 같다. </p>
<blockquote>
<ul>
<li>conv4_3로부터 38x38x(4x(Classes+4)) = 5776x(Classes+4)  </li>
</ul>
</blockquote>
<ul>
<li>conv7로부터 19x19x(6x(Classes+4)) = 2166x(Classes+4) </li>
<li>conv8_2로부터 10x10x(6x(Classes+4)) = 600x(Classes+4) </li>
<li>conv9_2로부터 5x5x(6x(Classes+4)) = 150x(Classes+4) </li>
<li>conv10_2로부터 3x3x(4x(Classes+4)) = 36x(Classes+4) </li>
<li>conv11_2로부터 1x1x(4x(Classes+4)) = 4x(Classes+4) </li>
<li><blockquote>
<p>8732x(Classes+4)</p>
</blockquote>
</li>
</ul>
<h1 id="default-boxes--aspect-ratio">Default boxes &amp; Aspect ratio</h1>
<p>모델에서 볼 수 있듯이 Default boxes는 <strong>feature map에 따라 4개 혹은 6개</strong>가 만들어진다. 이 때 생성되는 박스들은 각각 <strong>다른 비율</strong>을 가지며 Default box라고 부른다. Fater-RCNN의 anchor box와 유사한 개념이지만 서로 다른 feature map에 적용한다는 점에서 다르다.</p>
<p>  <img src="https://user-images.githubusercontent.com/76815825/117317985-fe683f80-aec4-11eb-81da-b8b08ad477d1.png" alt="image"></p>
<ul>
<li><p>$S_{min} = 0.2$, $S_{max} = 0.9$, $m=6$(feature map의 개수)으로 $k$에 따라 1~6이 대입되어($k=1$일 때 $S_{min},$ $k=6$일 때 $S_{max}$) <strong>각 feature map마다 다른 scale($s_k$)</strong>을 가지게 된다. </p>
</li>
<li><p><strong>비율은 $a_r$에 의해 정해진다.</strong> 예를 들어 $a_r = 2$인 경우 $w,h$는 2:1의 비율을 가진다.</p>
</li>
<li><p>6개의 bounding boxes를 뽑을 때는 $a_r$의 5개 원소를 모두 사용하며, 추가적으로 <strong>더 작은 크기의 1:1 비율인 $s_k^{&#39;}=\sqrt{s_ks_{k+1}}$</strong>가 사용된다. <strong>4개를 뽑을 때는 3과 1/3이 제외</strong>된다.</p>
</li>
</ul>
<p><img src="https://user-images.githubusercontent.com/76815825/117321456-1a211500-aec8-11eb-9b77-c46013753f12.png" alt="image">  </p>
<p>위 그림이 Default boxes에 대한 설명을 직관적으로 보여준다.  </p>
<ul>
<li><p><strong>작은 객체(고양이)는 resolution이 큰 feature map(8x8)</strong>에 의해 인식이 되며 <strong>큰 객체(강아지)는 resolution이 작은 feature map(4x4)</strong>에 의해 인식이 됨을 알 수 있다.</p>
</li>
<li><p>1부터 6까지의 k의 값을 대입했을 때 $s_k$ = [0.2, 0.34, 0.48, 0.62, 0.76, 0.9]가 되는데 이 값이 <strong>default box의 크기를 결정하는 input image와의 비율</strong>임을 생각하면 그림과 맞아떨어짐을 다시 한 번 이해할 수 있다.  </p>
</li>
<li><p>300픽셀 이미지의 0.2는 60픽셀로 <strong>작은 default box</strong>이므로 세밀한 정보를 잡아내는 <strong>큰 feature map</strong>에서 사용되며 반대로 0.9일 경우에는 <strong>default box의 크기가 270</strong>이므로 <strong>작은 feature map</strong>에서 사용된다.</p>
</li>
</ul>
<h1 id="matching-strategy">Matching strategy</h1>
<p>학습을 하기 위해서는 수많은 default box들이 각각 어떤 Ground Truth box에 대응되는지 매칭해주는 과정이 필요하다. 이 때 <strong>GT와의 IOU</strong>를 활용하며 <strong>0.5 이상인 박스들을 전부 positive</strong>로 분류한다. 반대로 IOU가 <strong>0.5 미만인 박스들은 배경</strong>이라고 생각을 하여 <strong>negative</strong>로 분류한다.</p>
<h1 id="loss-function">Loss function</h1>
<p> <img src="https://user-images.githubusercontent.com/76815825/117318216-2bb4ed80-aec5-11eb-8f84-0d53821174ed.png" alt="image"></p>
<p> SSD의 loss function은 <strong>classification loss와 localization loss 합</strong>으로 이루어져있다. $\alpha$는 둘의 가중치를 조절하는 값으로 디폴트 값은 1이다.</p>
<blockquote>
<ul>
<li>$N$: $l$과 $g$의 IOU가 0.5 이상인 박스의 수 </li>
</ul>
</blockquote>
<ul>
<li>$x$: default box<ul>
<li>$c$: 클래스</li>
<li>$l$: bbox의 좌표</li>
<li>$g$: GT의 좌표</li>
</ul>
</li>
</ul>
<h2 id="localization-loss">Localization Loss</h2>
<p><img src="https://images.velog.io/images/kimkj38/post/c7efa71b-b472-4711-ace6-64e7239b2d19/image.png" alt=""></p>
<ul>
<li>$x^k_{ij}$: $k$클래스에 대해 $i$번째 default box와 $j$번째 GT가 매칭되면(IOU&gt;=0.5) 1, 아니면 0. 즉, <strong>매칭된 박스에 대해서만 localization loss를 계산</strong>한다. </li>
<li>$l_i^m$은 예측 </li>
<li>Default box에서 좌표(cx,cy,w,h)의 조정값을 빼주어 <strong>smooth L1 loss</strong>를 구한다.</li>
<li>4개의 값에 대해 오차를 구하기 때문에 <strong>커질 수 밖에 없는 값을 줄여주는 효과</strong>가 있으며 L1 Loss는 미분 불가능한 지점이 있어 역전파할 때 문제가 있어 smooth L1 loss를 사용한다.</li>
</ul>
<p><img src="https://images.velog.io/images/kimkj38/post/7747c7ff-266a-4b67-b17d-27ed1ba64688/image.png" alt=""></p>
<p>Default box는 localization loss를 통해 좌표값이 세밀하게 조정되며 수식은 다음과 같다.</p>
<p><img src="https://images.velog.io/images/kimkj38/post/100884e7-8c33-4484-a3e5-d78bdd7279a8/image.png" alt=""></p>
<p>$x, y, w, h$는 각각 $x, y$좌표(위치), width(너비), height(높이)를 의미하며, $P_{x,y,w,h}$는 Default box, $G$는 Ground Truth(실제값)이다. </p>
<p>아래의 식에서는</p>
<blockquote>
<p>$\phi_5(P^i)$: CNN에서 학습된 $P^i$에 해당하는 특징 벡터
$\hat{w}_*$: 특징벡터를 4차원 벡터로 만들어주는 Linear layer의 학습되는 가중치
$\lambda$: regularization을 위한 상수</p>
</blockquote>
<p>$w_<em>$를 통해 $d_{</em>}(P) = w_{*}^{T}\phi_{5}(P)$라는 transformation 함수를 정의할 수 있으면 $\hat{G}$를 추정할 수 있다.</p>
<p>(1),(2),(3),(4)의 <strong>$\hat{G}$은 $G$와 최대한 가까워질 추정량</strong>을 의미하므로 이 식을 변형시킨 (6),(7),(8),(9)의 
<strong>$t$($d$의 치환)는 최종적으로 결정되는 함수</strong>라고 할 수 있다.  </p>
<p>따라서, <strong>$t$와 $d$의 차이를 최소화시켜주는 loss function</strong>이 적용되어 Bounding Box의 위치, 크기가 조정된다.</p>
<h2 id="confidence-loss">Confidence Loss</h2>
<p><img src="https://user-images.githubusercontent.com/76815825/117318726-a7169f00-aec5-11eb-8b50-9a86f7817ea0.png" alt="image"> </p>
<p><strong>Confidence Loss</strong>는 매칭된 박스와 매칭되지 않은 박스에 대해 모두 cross entropy loss를 구한다. </p>
<h1 id="hard-negative-minining">Hard Negative Minining</h1>
<p>SSD의 default box는 8000여개나 되지만 실질적으로 우리가 인식하고자 하는 객체의 수는 10개도 안 되는 경우가 일반적이므로 <strong>대부분의 box들은 배경</strong>을 나타낸다. 따라서 배경 클래스에 대한 데이터만 과도하게 많은 <strong>imbalance</strong> 문제가 발생한다. 이를 해결하기 위해 SSD에서는 <strong>loss가 높은(background인데 background class라 판단하는 확률이 작은) 데이터만 sorting하여 positive data의 3배만 사용하는 기법</strong>을 쓴다.  </p>
<h2 id="results">Results</h2>
<p><img src="https://user-images.githubusercontent.com/76815825/117329099-42f8d880-aecf-11eb-9089-787ee685d5cf.png" alt="image"></p>
<p>결과 중에 눈에 띄었던 것은 <strong>작은 물체에 대한 성능이 유독 떨어진다</strong>는 것인데 추후에 나온 분석으로는 <strong>작은 물체를 첫 feature map에서 detect하기 때문</strong>이라고 한다. 이를 보완하기 위해 RetinaNet에서는 왕복하는 방식을 통해 작은 물체에 대한 성능을 높였다.  </p>
<p>SSD에서는 <strong>augmentation</strong>을 통해 이와 같은 문제를 개선하였다. Random crop을 통해 &quot;zoom in&quot;하여 더 큰 객체의 데이터를 만들기도 하고 반대로 &quot;zoom out&quot;한 후 남는 공간은 평균 픽셀값으로 채워 작은 객체의 데이터를 만들기도 하였다. 그 외에도 randomly sample patch, horizontally flipped 등의 방법이 활용된다.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=ej1ISEoAK5g">https://www.youtube.com/watch?v=ej1ISEoAK5g</a></li>
<li><a href="https://yeomko.tistory.com/20">https://yeomko.tistory.com/20</a></li>
<li><a href="https://taeu.github.io/paper/deeplearning-paper-ssd/">https://taeu.github.io/paper/deeplearning-paper-ssd/</a></li>
<li><a href="https://www.youtube.com/watch?v=MLDo1R5XKk4">https://www.youtube.com/watch?v=MLDo1R5XKk4</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Object Detection]]></title>
            <link>https://velog.io/@tobigs1516_image/Object-Detection</link>
            <guid>https://velog.io/@tobigs1516_image/Object-Detection</guid>
            <pubDate>Wed, 03 Nov 2021 09:53:55 GMT</pubDate>
            <description><![CDATA[<p>object detection을 이해하기 위해선, object localization의 이해가 선행되어야 합니다.</p>
<h2 id="object-localization">Object localization</h2>
<h3 id="what-is-localization-and-detection">What is localization and detection?</h3>
<ul>
<li>lmage classification은 알고리즘이 주어진 사진을 보고 무엇인지 라벨링</li>
<li>object localization은 라벨링뿐만 아니라 그 물체의 위치 주변에 경계 상자(bounding box)를 집어넣거나, 빨간 직사각형을 그리는 것까지 포함</li>
<li>detection은 사진 속에 존재하는 여러 물체들을 모두 감지하고 위치를 알아내는 것이라고 할 수 있습니다.
<img src="https://images.velog.io/images/lm_minjin/post/cd63e616-422a-4647-ac71-fb1c68004f62/image.png" alt=""></li>
</ul>
<h3 id="classfication-with-localization">Classfication with localization</h3>
<p>localization은 결과값으로 image label + 경계 상자를 표현하는 4가지 값을 산출합니다.
경계 상자는 다음과 같이 4개의 값으로 표현됩니다.
<img src="https://images.velog.io/images/lm_minjin/post/b63a02f3-547f-49bb-98f8-40b25618df42/image.png" alt=""></p>
<ul>
<li>b_x : 박스의 중심 위치, x 좌표</li>
<li>b_y : 박스의 중심 위치, y 좌표</li>
<li>b_h : 전체 이미지에서의 높이의 비중</li>
<li>b_w : 전체 이미지에서의 길이의 비중</li>
</ul>
<p>Example)
<img src="https://images.velog.io/images/lm_minjin/post/75d11640-2994-4ff4-97f5-6c09929aee8a/image.png" alt=""></p>
<ul>
<li>현재 사진 속 물체가 자동차이므로, 라벨링 값으로 2 산출.</li>
<li>사진의 왼쪽 상단을 (0,0), 오른쪽 하단을 (1,1)이라고 한다면, 자동차가 대략 가운데, 하단 부분에 위치하므로 b_x = 0.3, b_y = 0.7을, 전체 이미지에서 너비가 대략 30%, 폭이 40%를 차지한다고 하면, b_h와 b_w값으로 0.3, 0.4를 산출.</li>
</ul>
<p>classfication with localization에선 output이 다음과 같은 형식을 지닙니다.
<img src="https://images.velog.io/images/lm_minjin/post/1bbed2e9-630d-4c0a-b901-02dc18b7128d/image.png" alt=""></p>
<ul>
<li>object probablity(P_c) : 물체의 존재 여부의 확률. 물체가 배경으로 분류될 경우 감지하고자 하는 물체가 없는 것이므로 0으로 표현.</li>
<li>bouncding box : 경계 상자의 위치</li>
<li>classes : 0과 1로 구성된 해당하는 object class의 라벨</li>
</ul>
<p>손실 함수는 물체가 있는지 없는지에 따라서 나뉩니다. 예를 들어 3개의 클래스를 분류하는 문제에서, 제곱오차를 손실 함수로 사용한다면 다음과 같습니다.
<img src="https://images.velog.io/images/lm_minjin/post/cd362a6c-b146-40ae-88d9-e3ef675a2a80/image.png" alt="">
즉, 물체가 있을 경우 모든 요소에 대한 제곱 오차를 더해 손실을 계산하지만, 물체가 없을 경우 p_c항 외의 다른 요소는 무관하므로 p_c에 대한 손실만 계산합니다.</p>
<h2 id="landmark-detection">Landmark detection</h2>
<p>앞선 예시에서는 자동차의 위치 정보를 표현하기 위해 4가지 값으로 사용했습니다. 하지만 단순히 직사각형으로 물체의 위치를 표현하는 것이 아니라, 사람의 눈꼬리, 입 모양 등과 같이 위치를 좀 더 자세히 인식하고 싶다면 어떻게 할까요?
<img src="https://images.velog.io/images/lm_minjin/post/dc887134-7e6c-4278-b874-bcdde494b6d6/image.png" alt="">
다음과 같이 핵심이 되는 위치, 특징점의 좌표를 포함하는 라벨링 훈련 세트를 만들어서 모델을 학습시킬 수 있습니다.</p>
<ul>
<li>여러개의 특징점을 포함하는 레이블 훈련 세트를 만들어 신경망으로 하여금 어디에 특징점들이 있는지 말할 수 있게 학습 시킬수 있습니다.</li>
<li>다만 훈련 시키려고 하는 모든 이미지에서 사람이 지정한 특징점의 정의는 같아야합니다.(특징점1은 왼쪽 눈꼬리 위치, 특징점2는 오른쪽 눈꼬리 위치, ...)</li>
</ul>
<h2 id="object-detection">Object Detection</h2>
<p>자동차 인식 알고리즘을 개발한다고 하면 먼저 레이블 훈련 세트를 만들어야 합니다. 이미지 x는 긍정 샘플로, 모두 자동차입니다. 이 훈련 세트로 학습해, 이미지의 대부분이 자동차인지 아닌지에 따라 0 또는 1의 값이 나오게 됩니다. 이 합성공 신경망을 훈련한 후에 이를 슬라이딩 윈도 검출에 사용할 수 있습니다.
<img src="https://images.velog.io/images/lm_minjin/post/6b4f1ed3-4160-4376-8b50-9e43350536ed/image.png" alt=""></p>
<h3 id="sliding-windows-detection">Sliding windows detection</h3>
<ol>
<li>특정 윈도 크기 설정</li>
<li>윈도 사이즈로 잘려진 이미지를 입력값으로 분류 시행</li>
<li>윈도를 슬라이드하며 이미지 전체에 대해 시행</li>
<li>윈도 크기를 바꿔 1-3의 과정을 반복
<img src="https://images.velog.io/images/lm_minjin/post/8868e08e-1934-45ec-b9d8-10d7f9a4da0d/image.png" alt=""></li>
</ol>
<ul>
<li>이 방법의 단점은 많은 영역을 잘라내어, 이미지의 모든 곳을 한번씩 훑어야하기 때문에 아주 큰 계산 비용이 듭니다.</li>
<li>또한, 윈도 크기를 너무 작게하거나, 스트라이드를 늘리게 되면 성능 저하, 즉 정확하게 물체를 못잡아 낼 수도 있습니다.
합성곱을 사용하면 이 방법을 효율적으로 구현해낼 수 있습니다.<h2 id="convolutional-implementation-sliding-windows">Convolutional Implementation Sliding Windows</h2>
<h3 id="turning-fc-layers-convolutional-layer">Turning FC layers convolutional layer</h3>
<img src="https://images.velog.io/images/lm_minjin/post/e0acdc3c-25b9-4fff-b073-efe3d287ad04/image.png" alt="">(위가 기존 완전 연결층이고, 아래가 합성곱 완전 연결층)</li>
<li>기존(위) 에 것과 비교하면 합성곱층(아래)은 최대 풀링 이후 모든 차원을 1차원으로 만드는 대신, 합성곱 연산을 하게 됩니다.</li>
<li>5 x 5 x 16크기의 feature map에 5 x 5 x 16크기의 필터를 400개 사용하면, 1 x 1 x 400이 됩니다.</li>
<li>이는 수학적으로 완전 연결층 연산과 동일합니다. 결과값으로 도출된 400개의 각 값이 5 x 5 x 16 크기의 필터에 대한 임의의 선형함수를 구성하고 활성화함수를 통과하기 때문입니다.
즉, FC layer부분을 convolution을 통해 구현할 수 있습니다.</li>
</ul>
<p>슬라이딩 윈도 검출에서는 아래와 같이 활용합니다.
<img src="https://images.velog.io/images/lm_minjin/post/86332e25-65bc-47f8-89b5-2aa8b94cb0fe/image.png" alt=""></p>
<ul>
<li>4 개의 윈도를 슬라이딩 하면서 검출하게 된다고 예시를 들어봅시다.(단, 1 x 1에서 입체 부분은 생략)</li>
<li>합성곱 신경망의 input이 14 x 14 x 3 크기의 이미지라면, 테스트 세트 이미지는 16 x 16 x 3이 됨. </li>
<li>마지막을 완전 연결층이 아닌 합성곱층을 사용하면 아래처럼 4개의 윈도에 해당하는 구역이 생깁니다.</li>
<li>이는 합성곱층을 4번 통과하지 않고 한 번에 4개의 윈도에 대한 분류를 할 수 있어 계산 비용이 많이 줄어듭니다. 따라서 효율적인 계산을 할 수 있게 됩니다.</li>
</ul>
<p>하지만, 이 방법도 픽셀 상의 문제로 경계 상자가 물체와 정확하지 일치하지 않는다는 단점이 존재합니다. 이를 해결하기 위해 YOLO(you Onle Look Once)알고리즘을 사용합니다.</p>
<h2 id="predict-bounding-boxes">Predict Bounding Boxes</h2>
<p>우선 훈련 셋을 만들기 위해 output 레이블 y를 정의합니다. YOLO 알고리즘은 두 객체의 중간 점을 취한 다음, 중간 점을 포함하는 영역에 이 객체를 해당하는 것입니다. 그렇게 되면 아래와 같은 사진의 결과 레이블이 나온다. 보라색 레이블은 object가 없는 영역의 결과 행렬이고 초록색 레이블은 object가 있는 영역의 결과 행렬이다. 
<img src="https://images.velog.io/images/lm_minjin/post/9638574f-97b4-497c-8633-e84fde17c25a/image.png" alt=""></p>
<ul>
<li>각 격자셀에 대해 해당하는 라벨값이 있습니다. 만약에 물체가 격자 셀 내에 존재 하게 된다면 격자 셀 내에서 해당하는 물체의 위치 중심값을 b_x, b_y로 설정하게 됩니다. 만약에 물체가 격자 셀 내에 없다면, 물체의 존재 여부는 0이 되고, 나머지 경계상자 값은 관심이 없으니 임의의 값으로 설정하게 됩니다.</li>
<li>따라서 최종적으로 출력은 3 x 3 x 8 크기의 형태입니다. 각 8 차원의 벡터가 격자셀에 맞게 쌓여 있는 모습입니다. 이를 라벨링 된 볼륨과 오차를 구한뒤 역전파를 통해 학습 시키게 됩니다.</li>
<li>테스트시 이미지를 넣으면 3 x 3 x 8 형태의 출력을 얻고, 물체 존재 여부가 1인 벡터의 경계상자 값만 불러와서 그리게 됩니다. </li>
<li>실제로는 더 큰 격자 셀들을 활용하게 됩니다. </li>
<li>경계 상자 값 중 중심값 b_x, b_y은 0과 1사이의 값을 가집니다. 하지만 경계상자의 높이와 넓이 비중은 1보다 클 수도 있습니다.</li>
</ul>
<p>간단하게 말하자면 객체의 중간 점을 포함하는 그리드 셀 하나에 해당 객체를 할당하는 방법으로 라벨링하면 정확한 object의 bounding box를 얻어낼 수 있다는 것입니다.
이 알고리즘은 그리드 셀 하나에 하나 이하의 객체가 할당될 경우엔 문제가 생기지 않습니다.</p>
<h2 id="intersection-over-unioniou">Intersection Over Union(IOU)</h2>
<p>합집합 위의 교집합(이하 IOU)를 통해서 물체 감지 알고리즘의 평가에 사용 할 수 있습니다.
보라색이 알고리즘이 도출한 경계 상자이고, 빨간색이 참 값의 경계 상자라고 하면, 이는 좋은 결과일까요 나쁜 결과일까요?
<img src="https://images.velog.io/images/lm_minjin/post/6f954ea4-8f47-4f58-94cb-3ecb095e7de9/image.png" alt="">
IOU는 참 값인 경계 상자(True Bounding Box)와 알고리즘이 도출한 경계 상자(Predicted Bounding Box) 간의 교집합의 크기를 합집합의 크기로 나눈 값입니다. 즉, IOU가 클 수록 우리는 알고리즘이 도출한 경계 상자가 옳다고 판단하게 됩니다.
<img src="https://images.velog.io/images/lm_minjin/post/1b55f2a2-5eb9-4ef7-8533-cc64752c4d5b/image.png" alt=""></p>
<ul>
<li>IOU는 0과 1사이의 값을 가집니다. 즉, 1이 되면 완전 겹치고, 0이 되면 겹치지 않는 것입니다. 이론적 이유는 없지만 보통 관습으로 0.5 보다 크면 맞다고 판단 할 것입니다. IOU가 높을 수록 더 엄격한 기준이라고 할 수 있습니다.</li>
<li>이는 localization와 accuracy를 매핑하는 한 가지 방법입니다. 알고리즘이 물체를 올바르게 탐지하고 localization한 횟수를 세면 됩니다. 물체가 맞게 localization 되었는지는 IOU를 사용하면 됩니다.</li>
</ul>
<h2 id="non-max-suppression">Non-max Suppression</h2>
<ul>
<li>알고리즘이 같은 물체를 여러번 감지하는 경우도 있을 것입니다. 하지만 우리는 하나의 물체는 한번 감지하기를 원합니다. 이를 Non-max Suppression를 통해서 해결할 수 있습니다.</li>
<li>Non-max Suppression는 알고리즘이 각 물체를 한 번씩만 감지하게 보장합니다.
물체를 감지한 경계상자들 중에서 감지 확률(p_c)이 최대인 상자를 고른 후, 해당 경계 상자와의 IOU를 구해서 높은 IOU를 가진 상자들을 제거(같은 물체를 탐지한 근처 경계 상자들을 제거)하는 방법이 Non-max Suppression입니다.
구체적으로 하나의 물체를 감지하는 예시를 살펴봅시다.
<img src="https://images.velog.io/images/lm_minjin/post/b60cb98b-81bf-453e-84db-a36a64085101/image.png" alt=""></li>
<li>감지된 모든 경계 상자중, 감지 확률이 0.6 이하인 경계 상자를 버립니다.</li>
<li>감지 확률이 제일 높은 경계상자를 기준으로 잡습니다.</li>
<li>해당 상자와 높은 IOU를 가지는 경계 상자를 버립니다.</li>
<li>1개가 남을때 까지 2~3 과정을 계속 반복합니다.
즉, Non-max Suppression은 확률의 최댓값을 도출하고, 최댓값의 아닌 것들은 억제한다는 의미입니다.
만약에 2개 이상의 클래스가 있을 경우, 각 클래스에 대해 독립적으로 Non-max Suppression를 해야합니다.</li>
</ul>
<h2 id="anchor-boxes">Anchor Boxes</h2>
<ul>
<li>현재까지 배운 물체 감지 알고리즘의 최대 단점은 각각의 격자 셀이 오직 하나의 물체만 감지 할 수밖에 없다는 것입니다(예를 들어, 구름과 해가 겹쳐져 있는 경우, 해당 격자 셀은 둘 중 하나만 예측 했을 것). 이를 해결하기 위해 앵커 박스를 사용합니다.</li>
<li>경계 박스를 직접적으로 예측 하는 대신 미리 크기가 정해진 앵커 박스를 여러 개 만들어 사용합니다.
<img src="https://images.velog.io/images/lm_minjin/post/359d6dff-de37-404b-8dad-f400d501ab8c/image.png" alt=""></li>
<li>이전에는 각 격자셀에서 해당 물체에 대한 결과값(물체의 존재 여부, 중심점, 경계 상자 값 그리고 클래스)이 존재했지만, 앵커 박스를 사용하게 되면 앵커 박스의 개수만큼 결과값이 늘어나야 합니다.</li>
<li>아래 두 가지 예시를 보겠습니다. 물체가 겹쳐있는 경우(좌측)와 하나만 있는 경우(우측) 을 살펴보면, 결과값이 이전에 비해 늘어난걸 알 수 있습니다.
<img src="https://images.velog.io/images/lm_minjin/post/5a231efb-caeb-484e-91d5-d65db098a6a1/image.png" alt=""></li>
<li>위쪽 8개 요소가 앵커 박스 1에 대한 것이고, 아래쪽 8개 요소가 앵커 박스 2에 대한 것입니다.</li>
<li>두 물체 다 존재하는 경우 (좌측) 두 앵커박스에 해당물체의 존재여부 값은 1이 되며, 각각의 중심값, 경계 상자값, 클래스 값이 존재하게 됩니다.</li>
<li>하나의 물체 (우측) 만 존재하는 경우의 이미지는 첫번째 앵커박스에 해당 물체의 존재 여부 값이 0이 되고, 나머지 앵커 1에 해당되는 값들은 임의로 되어도 상관 없습니다.</li>
<li>앵커박스는 사람이 정할 수도 있고 자동으로 정하는 알고리즘도 있습니다.</li>
<li>다만 사전에 정한 앵커 박스의 수 보다 하나의 셀에 겹치는 물체의 수가 많을 경우 앵커 박스의 수만큼만 물체를 인식할 수 있다는 단점이 존재합니다. </li>
<li>또한, 두 물체가 같은 셀에 존재하고, 같은 앵커 박스를 갖는 경우 역시 제대로 인식하지 못합니다.</li>
<li>하지만 격자가 작으면 작을수록, 두 물체가 같은 중심점을 가질 확률은 낮습니다.<h2 id="yolo-algorithm">YOLO algorithm</h2>
지금까지 배운 내용으로 YOLO 물체 감지 알고리즘을 구성해봅시다. 
3개의 물체를 검출하는 알고리즘을 훈련시킨다고 생각해봅시다.
<img src="https://images.velog.io/images/lm_minjin/post/ed373a8e-2afe-4359-8448-fea714e5e971/image.png" alt=""></li>
<li>우선 y값의 크기는 격자 셀이 3x3, 앵커 박스가 2개, 클래스가 3개이므로 3 x 3 x 2 x 8이 됩니다.</li>
<li>파란색 격자의 y값을 보면, 앵커 박스1과 2에서 물체를 인식하지 못했기 때문에 p_c값이 0이 됩니다.</li>
<li>초록색 격자의 y값을 보면, 자동차를 인식할 수 있는데 이 자동차는 앵커 박스 2와 좀 더 유사하다고 생각하면 위쪽의 p_c값은 0, 아래의 p_c값은 1이 됩니다.</li>
</ul>
<p>YOLO 물체 감지 알고리즘은 다음과 같은 순서로 진행됩니다.</p>
<ol>
<li>각각의 격자 셀에 대하여, 경계 상자를 도출합니다.
(앵커 박스의 수만큼 경계 상자가 도출됨.)
<img src="https://images.velog.io/images/lm_minjin/post/b6d5bbae-84bb-43b1-919a-1f943540f2ee/image.png" alt=""></li>
<li>낮은 확률의 경계 상자를 제거합니다.
<img src="https://images.velog.io/images/lm_minjin/post/86569bf1-2d06-43ac-a33d-7fc87e4c4d4b/image.png" alt=""></li>
<li>각각의 class(보행자, 자동차, 오토바이 등)에 대해 non-max suppression을 이용하여 최종 결과를 도출합니다.
<img src="https://images.velog.io/images/lm_minjin/post/f8078376-d6ac-4b6b-9de1-b1f448fda347/image.png" alt=""></li>
</ol>
<h2 id="region-proposal--r-cnn">Region Proposal : R-CNN</h2>
<p>sliding window 아이디어를 생각해보면, 물체가 있든 없든 이미지의 모든 영역에 대해 물체 감지를 실행합니다. 이러한 알고리즘의 하나의 약점은 명확하게 물체가 없는 많은 지역들을 감지한다는 것입니다.
그래서 R-CNN을 사용하여 component classifier를 실행할 몇 개의 지역만을 고른다.
<img src="https://images.velog.io/images/lm_minjin/post/f06f09ab-9bab-48aa-af61-0f0e4cd917b6/image.png" alt="">
segmentation algorithm을 이용하여 영역을 분할하고, 해당 영역의 경계 상자에 대해서만 분류기를 실행한다.</p>
<h4 id="r-cnn에서-물체가-있을-법한-영역을-찾는-방법--selective-search">R-CNN에서 &quot;물체가 있을 법한&quot; 영역을 찾는 방법 : Selective search</h4>
<p><img src="https://images.velog.io/images/lm_minjin/post/f16abe9a-23ef-43ff-a568-3ac54904947d/image.png" alt=""></p>
<ol>
<li><p>색상, 질감, 영역크기 등.. 을 이용해 non-object-based segmentation을 수행한다. 이 작업을 통해 좌측 제일 하단 그림과 같이 많은 small segmented areas들을 얻을 수 있다.</p>
</li>
<li><p>Bottom-up 방식으로 small segmented areas들을 합쳐서 더 큰 segmented areas들을 만든다.</p>
</li>
<li><p>(2)작업을 반복하여 최종적으로 2000개의 region proposal을 생성한다.</p>
</li>
</ol>
<p>이 과정을 pseudo code로 살펴보면 다음과 같습니다.
<img src="https://images.velog.io/images/lm_minjin/post/613802c2-9d11-447c-844f-efb4120e0cec/image.png" alt="">
R : 선택된 초기 영역들
S : 영역들간의 유사도 집합</p>
<p>각각의 영역들에 대한 유사도 초기화
While(반복) </p>
<ol>
<li>가장 유사도가 높은 영역 i,와 j 선택</li>
<li>선택된 영역을 t로 병합</li>
<li>i와 j가 연관된 다른 유사도 집합들은 제거</li>
<li>병합된 t영역과 나머지 영역들간의 유사도 재정의</li>
<li>새로운 유사도 집합에 합쳐진 영역을 추가 포함</li>
<li>하나의 영역이 될때 까지 반복</li>
</ol>
<p>** 유사도 측정방법
[0,1] 사이로 정규화된 4가지 요소(색상, 재질, 크기, 채움-Fill)들의 가중합으로 계산합니다. </p>
<h3 id="faster-algorithms">Faster algorithms</h3>
<p>R-CNN은 아직 꽤 느리기 때문에 이 알고리즘의 속도를 높이기 위한 여러 알고리즘이 있습니다.</p>
<ul>
<li>R-CNN : 어떤 알고리즘을 통해 지역을 제안하고 분류합니다. 각각의 지역은 결과값으로 label과 bounding box를 도출합니다.</li>
<li>Fast R-CNN : 기본적인 R-CNN 알고리즘에 합성곱 슬라이딩 윈도 구현을 더한 것. 원래 R-CNN은 한 번에 하나의 지역을 분류하지만, fast R-CNN에서는 합성곱 슬라이딩 윈도를 통해 모든 지역을 한 번에 분류할 수 있습니다. 하지만, 여전히 지역 제안을 위한 클러스터링 단계가 느리다는 단점이 있습니다.</li>
<li>Faster R-CNN : 지역과 영역들을 제안하는 데에 분할 알고리즘 대신 신경망을 사용해 fast R-CNN보다 조금 더 빠릅니다. 하지만 YOLO보단 느립니다.</li>
</ul>
<h4 id="mask-cnn">Mask-CNN</h4>
<p><a href="https://herbwood.tistory.com/20">https://herbwood.tistory.com/20</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Practical advice for using ConvNets]]></title>
            <link>https://velog.io/@tobigs1516_image/Practical-advice-for-using-ConvNets</link>
            <guid>https://velog.io/@tobigs1516_image/Practical-advice-for-using-ConvNets</guid>
            <pubDate>Wed, 03 Nov 2021 06:55:02 GMT</pubDate>
            <description><![CDATA[<h2 id="using-open-source-implementations">Using open-source implementations</h2>
<p>많은 연구자들이 Github와 같이 인터넷에 코드를 공유
기반을 삼고 싶은 논문을 찾게 된다면 온라인에서 오픈 소스를 찾으면 된다.
-&gt; 처음부터 코드를 짜는 것 보다 속도가 빠름</p>
<h2 id="transfer-learning">Transfer Learning</h2>
<p>이미지넷과 같은 큰 데이터 세트를 학습해 고성능의 연구를 거친 모델의 가중치를 가지고 와서 우리의 신경망에 재구성해 사용하는 것</p>
<p>신경망의 오픈 소스를 다운 받을 때 코드만 받는 것이 아니라 가중치도 함께 받아야 한다.</p>
<h3 id="1-데이터셋이-작을-때">1. 데이터셋이 작을 때</h3>
<p><img src="https://images.velog.io/images/hannapark56/post/3e2c7e67-0fae-4fd0-9bfa-ee445d1c9232/image.png" alt=""></p>
<p>뒷단의 소프트맥스 레이어를 없애고 우리의 문제에 맞는 소프트맥스 유닛을 만든다. 
-&gt; 위의 문제의 경우 1000개의 class의 결과를 출력하는 것이 아니라 3개의 class 만 출력
앞단의 층들은 가중치는 고정(freeeze)하고 소프트맥스 층의 가중치만 훈련</p>
<p>빠르게 훈련하는 법: 
고정된 레이어는 훈련시키지 않기 때문에 하나의 고정 함수가 발생해서 이미지 X를 특정 활성값으로 전달, 즉 미리 활성값을 계산하여 저장하면 계산 시간을 줄일 수 있음</p>
<h3 id="2-더-큰-데이터셋이-있을-때">2. 더 큰 데이터셋이 있을 때</h3>
<p><img src="https://images.velog.io/images/hannapark56/post/df5b984a-9f42-43cd-93b1-e092f21f9d3e/image.png" alt=""></p>
<p>몇개의 레이어만 동결시키고 이후의 층들을 학습
마찬가지로 출력층의 클래스는 다르기 때문에 변경하여 학습</p>
<p>데이터가 많을수록 동결 레이어의 수는 줄고 훈련시킬 레이어의 개수는 늘어나게 됨</p>
<h3 id="3-아주-큰-데이터셋">3. 아주 큰 데이터셋</h3>
<p>무작위 초기화가 아닌 기존 오픈소스 네트워크의 가중치를 초기화 값으로 설정하고 네트워크 전체를 다시 훈련</p>
<h2 id="data-augmentation">Data Augmentation</h2>
<p>데이터가 부족할 때 데이터 양을 늘리고 성능을 올리는 방법</p>
<p><img src="https://images.velog.io/images/hannapark56/post/9a2d43d9-7f0e-4b05-811f-3e552f2f52d5/image.png" alt=""></p>
<h3 id="mirroring">Mirroring</h3>
<p>데이터를 대칭시킴</p>
<h3 id="random-cropping">Random Cropping</h3>
<p>데이터의 일부분을 자름</p>
<p>이 외에도 Data Augmentation으로 Rotation, Shearing, Local Warping이 있음</p>
<p><img src="https://images.velog.io/images/hannapark56/post/20952ad5-cc56-440b-a7a6-45e4d81950b6/image.png" alt=""></p>
<h3 id="color-shifting">Color shifting</h3>
<p>학습 알고리즘이 햇빛 등에 의한 색의 변화에 더 잘 반응할 수 있도록 해줌
RGB 각 채널에 서로 다른 수를 더한다. 예를 들면, 빨강 파랑이 더해지면 이미지가 보라색에 가까워짐
실제로는 위의 예시처럼 큰 변화가 아닌 RGB에 아주 작은 변화만 줌</p>
<p>RGB 표본을 만드는 방법: 
색 변형을 하는 방법 중 하나가 PCA -&gt; PCA 색 확대</p>
<h3 id="데이터-변형-구현-방법">데이터 변형 구현 방법</h3>
<p><img src="https://images.velog.io/images/hannapark56/post/e7ca1aa9-a243-4379-b3fc-334e33b7c8e1/image.png" alt=""></p>
<p>CPU 스레드를 통해 데이터를 디스크에서 불러오는 동시에 데이터를 변형시킴으로써 배치를 형성</p>
<p>참고: <a href="https://github.com/albumentations-team/albumentations">Albumentations: library for image augmentation</a></p>
<h2 id="컴퓨터-비전-시스템을-구축하기-위한-팁-the-state-of-computer-vision">컴퓨터 비전 시스템을 구축하기 위한 팁 (The state of computer vision)</h2>
<h3 id="data-vs-hand-engineering">Data vs. hand-engineering</h3>
<p><img src="https://images.velog.io/images/hannapark56/post/95af928b-9709-4145-9629-b40106f7c326/image.png" alt=""></p>
<p>데이터의 양이 많으면 -&gt; 간단한 네트워크 구조 사용 + 수작업이 적음
데이터의 양이 적으면 -&gt; 복잡한 알고리즘 + 수작업이 많음</p>
<p>데이터가 적으면 Hand engineered features, network architecture, other components 등에 집중하며 전이 학습도 많은 도움이 됨. 
데이터의 부재로 컴퓨터 비전에서 복잡한 네트워크 구조가 많이 등장함</p>
<h3 id="tips-for-doing-well-on-benchmarkswinning-competitions">Tips for doing well on benchmarks/winning competitions</h3>
<h4 id="ensembling">Ensembling</h4>
<p>여러개의 신경망을 사용하여 독립적으로 훈련 시킨 후 평균을 내는 것
시간 지연 발생 및 메모리 많이 필요</p>
<h4 id="multi-crop-at-test-time">Multi-crop at test time</h4>
<p><img src="https://images.velog.io/images/hannapark56/post/3d629be2-317b-4685-9f89-cfd2260ef672/image.png" alt=""></p>
<p>테스트 이미지에 적용되는 Data augmentation의 한 종류
테스트 이미지를 여러 버전으로 크로핑하여 classify 후 평균을 내서 결과를 얻는다.</p>
<p>위의 예시의 경우 이미지 원본에서 중간 부분, 모서리 4부분 cropping, 대칭된 이미지에서도 동일하게 중간 부분, 모서리 4부분 cropping
-&gt; 10개의 이미지를 classify 후 평균을 내줌</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[UNet]]></title>
            <link>https://velog.io/@tobigs1516_image/UNet</link>
            <guid>https://velog.io/@tobigs1516_image/UNet</guid>
            <pubDate>Wed, 27 Oct 2021 09:53:14 GMT</pubDate>
            <description><![CDATA[<h1 id="introduction">Introduction</h1>
<ul>
<li>그동안 객체 인식 분야에서 컨볼루션 네트워크를 활용한 수많은 모델들이 있었지만 <strong>train dataset과 네트워크의 크기에 영향</strong>을 받아 실질적인 사용이 제한적이었다.</li>
<li>따라서, 본 논문에서는 <strong>적은 데이터로도 학습이 가능한 여러가지 기법들을 소개</strong>한다.</li>
<li>본 논문은 <strong>biomedical 이미지</strong>에 대해 중점적으로 다루며 픽셀 단위의 분류가 필요하므로 <strong>segmentation</strong>으로 연결된다.</li>
<li><strong>FCN의 구조를 수정, 확장</strong>하여 더 적은 데이터로부터 더 정확한 예측을 가능하게 하였다.</li>
<li><blockquote>
<p><strong>contracting path에서의 feature map을 upsampling에서의 feature map에 더해주어 정보를 전달</strong>한다.</p>
</blockquote>
</li>
</ul>
<blockquote>
<p><strong>&lt;기존 연구의 단점&gt;</strong></p>
</blockquote>
<ul>
<li>sliding window방식으로 patch를 뽑아 <strong>각 patch별로 네트워크</strong>를 거치며, <strong>중복</strong>되는 부분들이 많아 느리다.</li>
<li><strong>큰 patch</strong>를 사용할 경우 max pooling이 늘어나 <strong>localiztion의 성능이 떨어지고</strong>, <strong>작은 patch</strong>를 사용할 경우 <strong>context를 많이 담을 수 없다</strong>는 trade-off가 있다.</li>
</ul>
<h1 id="architecture">Architecture</h1>
<p><img src="https://images.velog.io/images/kimkj38/post/5917bd14-9fec-4051-9450-484a9d41bcd5/image.png" alt=""></p>
<h2 id="contracting-path">Contracting path</h2>
<ul>
<li>그림의 좌측에 해당하는 부분으로 일반적인 컨볼루션 네트워크를 활용한 <strong>DownSampling</strong> 과정이다. <strong>의미정보(Context information)</strong>를 추출한다.</li>
<li>Unpadding <strong>3x3 필터</strong>를 활용하여 feature map의 크기가 감소하며 <strong>max pooling</strong>도 함께 활용한다.</li>
<li>DownSampling을 할 때마다 <strong>채널의 수를 2배 증가</strong>시킨다.</li>
</ul>
<h2 id="expansive-path">Expansive path</h2>
<ul>
<li>그림의 우측에 해당하는 부분으로 <strong>Upsampling</strong> 과정이다. <strong>위치정보(Localization)</strong>를 추출한다.</li>
<li><strong>2x2 Deconvolution 레이어</strong>를 활용하며 <strong>채널수를 반씩 줄여나간다.</strong></li>
<li>contracting path에서의 feature map과 <strong>concatenation</strong>을 하여 <strong>expansive path의 의미정보를 전달</strong>한다.</li>
<li>최종적으로 $W \times H \times Class$로 출력한다.<h1 id="methods">Methods</h1>
<h2 id="upsampling-larger-channels">Upsampling larger channels</h2>
<img src="https://images.velog.io/images/kimkj38/post/10a66515-e857-445e-af04-a31aa20c4cbd/image.png" alt="">
UNet에서는 <strong>upsampling 시에도 높은 채널수</strong>를 유지하였다. 이를 통해 context information을 높은 해상도에서도 이어 받을 수 있다. </li>
</ul>
<h2 id="mirroring-extrapolate">Mirroring extrapolate</h2>
<p><img src="https://images.velog.io/images/kimkj38/post/0c78f83d-df5c-4b69-8ec2-71f67fcd48d7/image.png" alt="">
UNet에서 사용하는 Biomedical 이미지들의 특성상 테두리에 있는 부분도 동일하게 중요하다. 따라서 본 논문에서는 <strong>테두리의 정보도 활용하기 위해 미러링을 통해 패딩</strong>을 해주었다. 미러링 패딩을 쓰면 <strong>테두리의 픽셀들을 반사시킨 형태로 채워</strong>주게 되는데 biomedical 분야에서 주로 등장하는 <strong>세포가 대칭구도</strong>를 이루는 경우가 많기 때문으로 추측된다고 한다.</p>
<h2 id="overlap-tile-strategy">Overlap-tile strategy</h2>
<p><img src="https://images.velog.io/images/kimkj38/post/0ec2c8a5-3b6b-46c2-94d3-dd8656aaf228/image.png" alt="">
패딩을 이용하며 output 사이즈가 input 사이즈에 비해 작기 때문에 <strong>겹치는 부분이 존재하도록 patch를 구성해야 원본 크기의 output을 얻을 수 있다.</strong> 위 그림에서 파란색 patch를 input으로 넣으면 노란색 output이, 빨간색 patch를 input으로 넣으면 초록색 output이 나와 연결되는 것을 알 수 있다.</p>
<h2 id="weight-loss">Weight Loss</h2>
<p><img src="https://images.velog.io/images/kimkj38/post/7986f004-b205-4153-8d20-78031dd0f532/image.png" alt="">
<img src="https://images.velog.io/images/kimkj38/post/786c8dc5-9f7b-4e20-85f8-b830f028e508/image.png" alt="">
Segmentation에서는 <strong>동일 클래스의 객체를 구분하기 어렵다는 문제</strong>가 있는데 본 논문에서는 <strong>weighted loss</strong>를 통해 해결하였다. UNet의 loss function은 위와 같이 pixel-wise cross entropy loss로 계산하며 <strong>경계와 가까운 픽셀들에는 높은 가중치$(w(x))$</strong>를 부여하여 학습을 세밀하게 할 수 있도록 만들어주었다.</p>
<blockquote>
<p>$K$: 클래스의 수
$l$: ${1, ..., K}$, 실제 라벨 집합
$p_k(x)$: 픽셀 $x$가 k클래스일 확률(softmax)</p>
</blockquote>
<p><img src="https://images.velog.io/images/kimkj38/post/49b8b558-3c17-4729-b962-6e8a6c483dc8/image.png" alt="">
가중치($w(x)$)는 위와 같이 계산된다. 그림(d)에서 볼 수 있듯이 경계에 있을수록 높은 값을 가진다.</p>
<blockquote>
<p>$w_c$: weight map to balance the class frequencies.
$w_0$: 하이퍼파라미터로 논문에서는 10으로 설정
$\sigma$: 하이퍼파라미터로 논문에서는 5로 설정
$d_1(x)$: 픽셀 $x$에서 가장 가까운 셀과의 거리
$d_2(x)$: 픽셀 $x$에서 두번째로 가까운 셀과의 거리</p>
</blockquote>
<h2 id="data-augmentation">Data Augmentation</h2>
<p><img src="https://images.velog.io/images/kimkj38/post/65b10e43-3d69-4ac9-b0ba-c0ee94e3300b/image.png" alt="">
본 논문에서는 Data augmentation을 적절히 활용하여 객체의 불변하는 고유한 특성들을 잘 뽑아낼 수 있게 만들었다. <strong>Rotation, Shift, Elastic distortion</strong> 등을 활용하였으며 특히 <strong>Elastic distortion은 픽셀별로 이미지가 다른 방향으로 뒤틀리게 만드는 방법</strong>으로 성능 향상에 효과적이다. Biomedical data의 경우 살아있는 것을 관찰한 데이터이기 때문에 <strong>순간순간의 미세한 변형을 주어 자연스러운 변화에 강건한 모델</strong>을 만들 수 있도록 한다.</p>
<h1 id="experiments">Experiments</h1>
<h3 id="em-segmentation-challenge">EM Segmentation challenge</h3>
<p><img src="https://images.velog.io/images/kimkj38/post/a675a313-2ff4-4310-a9d0-949f0b46ae2a/image.png" alt="">
30개의 세포 구조 Training 데이터셋과 Ground truth segmentation map(객체와 배경을 0,1로 분류)이 제공된다. 해당 데이터셋에서 <strong>가장 낮은 warping error</strong>를 보여 적은 데이터셋으로 좋은 성능을 보이고 있음을 증명한다.</p>
<h3 id="isbi-cell-tracking-challening">ISBI cell tracking challening</h3>
<p><img src="https://images.velog.io/images/kimkj38/post/6769f82c-774a-4cc5-b46b-a5cae7477bfc/image.png" alt="">
<img src="https://images.velog.io/images/kimkj38/post/3e1df8a1-293b-4987-b24f-a7159fd9a186/image.png" alt="">
세포 분류 대회에서 제공되는 데이터로 (a),(b)가 &#39;PhC-U373&quot; (c),(d)가 &#39;DIC-HeLa&#39;이다. 두 데이터셋에서 모두 UNet이 <strong>가장 높은 IOU score</strong>를 기록하였으며 2등과의 격차가 굉장히 큰 것을 볼 수 있다.</p>
<h1 id="reference">Reference</h1>
<ul>
<li><a href="https://arxiv.org/abs/1505.04597">https://arxiv.org/abs/1505.04597</a></li>
<li><a href="https://joungheekim.github.io/2020/09/28/paper-review/">https://joungheekim.github.io/2020/09/28/paper-review/</a></li>
<li><a href="https://www.hj-chung.com/post/elastic-distortion/">https://www.hj-chung.com/post/elastic-distortion/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[FCN (Fully-Convolution Network for semantic segmentation) 리뷰]]></title>
            <link>https://velog.io/@tobigs1516_image/FCN-Fully-Convolution-Network-for-semantic-segmentation-review</link>
            <guid>https://velog.io/@tobigs1516_image/FCN-Fully-Convolution-Network-for-semantic-segmentation-review</guid>
            <pubDate>Wed, 27 Oct 2021 06:16:27 GMT</pubDate>
            <description><![CDATA[<p>FCN(Fully-Convolution Network for semantic segmentation) 리뷰</p>
<p>2021년 10월 기준으로 26376회의 인용. semantic segmentation의 포문을 연 논문이라고 할 수 있습니다.</p>
<p>뒤이어 등장하는 모델들도 FCN의 한계점을 지적하며 이를 보완한 모델을 제시하기 때문에 FCN을 이해하는 것이 매우 중요합니다.</p>
<h1 id="abstract">Abstract</h1>
<ul>
<li>fully convolutional network는 input size에 영향을 받지 않는다.</li>
<li>image classification network를 fine-tuning하여 사용할 수 있다.</li>
<li>skip connection 아키텍쳐를 추가했다.</li>
</ul>
<p>abstract에서는 위의 3가지 정도의 요점을 이야기하고 있습니다.</p>
<p>앞으로는 FCN 구조의 핵심과 관련된 부분을 살펴보도록 하겠습니다.</p>
<h1 id="semantic-segmentation">Semantic Segmentation</h1>
<p>semantic segmentation task를 우선 이해해봅시다. 
<code>semantic</code>은 의미 <code>segmentation</code>은 분할입니다. 이미지의 물체 종류별로 구분짓는 것입니다.</p>
<p>아래는 segmentation이 된 예시입니다.
<img src="https://images.velog.io/images/ann9902/post/0dea164f-25fe-4793-8311-6e6a4969148e/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/ann9902/post/dcadf475-08b7-40cc-864a-82d7d17b1ebe/image.png" alt="">
Image Classification이 이미지 전체를 분류하는 것이라면<br>semantic segmentation는 <code>픽셀 단위로 분류</code>하는 것입니다. </p>
<h1 id="fcn의-구조">FCN의 구조</h1>
<p><img src="https://images.velog.io/images/ann9902/post/18b8f282-64fc-441e-8112-524b7e4c51b3/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/ann9902/post/d464e79b-cfbb-42ed-89f6-1843f68fa8cb/image.png" alt="">
<a href="https://eda-ai-lab.tistory.com/518">이미지 출처</a></p>
<blockquote>
<p>FCN은 Classification backbone + upsampling 이라고 간단하게 말할 수 있습니다. </p>
</blockquote>
<p>기존의 image classificaiton model에서 classification을 하는 뒷단의 dense layer를 제거하고 upsampling을 하는 layer를 추가하여 </p>
<p>input과 동일한 h, w를 가지고, 각 픽셀의 class를 나타내는 class 개수만큼의 채널을 가지는 ouput이 만들어집니다. </p>
<ul>
<li>input : (3, w, h)</li>
<li>ouput : (class_num, w, h)</li>
</ul>
<h1 id="fc-layer-vs-fully-conv-layer">FC-layer vs Fully Conv layer</h1>
<p>FCN에서 classification FC-layer를 Fully convolution layer으로 대체하였습니다. </p>
<p><img src="https://images.velog.io/images/ann9902/post/d4b281fa-c30a-4055-9692-310920f26e5b/%EC%A0%9C%EB%AA%A9%20%EC%97%86%EB%8A%94%20%ED%94%84%EB%A0%88%EC%A0%A0%ED%85%8C%EC%9D%B4%EC%85%98%20(1).png" alt=""></p>
<p>이는 아래와 같은 장점을 가집니다.</p>
<ul>
<li>input size에 독립적이다.</li>
<li>공간 정보를 손실하지 않는다.</li>
</ul>
<p>FC-layer는 input size에 따라 고정된 노드수를 갖기 때문에 input size가 변하면 network 구조도 변경되어야 합니다.</p>
<p>하지만 Fully convolution layer는 kernel을 이용하기 때문에 구조의 변경이 필요하지 않습니다.</p>
<p>위의 그림에서 FC-layer는 flatten을 하면서 공간정보를 잃어버리는 반면 Fully convolution layer는 1x1 conv를 사용하여 공간정보를 유지하면서 shape을 바꿀 수 있습니다.</p>
<p><img src="https://images.velog.io/images/ann9902/post/210987bf-c91e-45f8-991b-43c2e0253a4c/image.png" alt="">
*논문의 Adapting classifiers for dense prediction 참고</p>
<h1 id="transposed-convolution">Transposed convolution</h1>
<h2 id="transposed-convolution-1">Transposed convolution</h2>
<p><img src="https://images.velog.io/images/ann9902/post/57c83c52-62f1-4a2b-be73-9db64dd9af26/image.png" alt="">
<a href="https://miro.medium.com/max/1400/1*faRskFzI7GtvNCLNeCN8cg.png">출처</a>
transposed convolution은 위와 같이 learnable한 kernel을 적용한 conv를 진행하여 upsampling을 하는 것입니다.</p>
<h2 id="transposed-convolution과-deconvolution">Transposed convolution과 deconvolution</h2>
<p>많은 논문에서 deconvolution를 transposed convolution과 동일하게 사용하는데, 이는 엄밀히 말하면 틀린 표현입니다. </p>
<p>두 연산을 아래와 같은 차이점을 가집니다.</p>
<ul>
<li>transposed convolution은 input을 그대로 복원하지 않습니다.</li>
<li>kernel이 학습됩니다.</li>
</ul>
<p>convolution의 역연산을 뜻하는 deconvolution과 다릅니다.</p>
<p><code>transposed</code>라는 이름이 붙은 이유가 존재합니다. </p>
<p>input : 4x4, output : 2x2, kernel : 3x3 , stride = 1, padding = 0인 convolution연산을 행렬로 나타내면 아래와 같습니다.<br><img src="https://images.velog.io/images/ann9902/post/cbf3333e-6ec8-4521-8645-f1708d07ca16/image.png" alt=""></p>
<p>convolution matrix를 transposed해서 원래의 output과 곱해주면 원래의 input size크기의 output이 나오게됩니다. </p>
<p><img src="https://images.velog.io/images/ann9902/post/92274e74-7965-42fd-8843-5aec63796cbc/image.png" alt=""></p>
<p>이때 transposed convolution의 output은 원래의 input과 동일하지 않습니다. </p>
<p>*논문의 Upsampling is backwards strided convolution부분 참고</p>
<h1 id="skip-connection">Skip connection</h1>
<p><img src="https://images.velog.io/images/ann9902/post/d119f265-dfb4-4057-907e-14f65c271e81/image.png" alt=""></p>
<p>본 논문에서는 앞단에서의 여러번 pooling이 적용되기 전의 정보를 뒷단에 더해줍니다. </p>
<p>pooling layer를 5번 거친 마지막 feature map의 2배 키워서 </p>
<p>pool4의 feature map과 더한 후 (1/16)</p>
<p>이를 2배 키워서 pool3의 feature map과 더합니다.(1/8)</p>
<p>원래의 사이즈로 복원해야하므로 이를 다시 8배 키워줍니다.</p>
<p>정보의 손실이 있기전의 정보를 뒷단에 더해줌으로써 성능의 향상을 이룰 수 있었습니다.</p>
<h1 id="성능">성능</h1>
<p><img src="https://images.velog.io/images/ann9902/post/2d5b5a55-f51c-468b-a52b-8ad7952ebef3/image.png" alt="">
VGG backbone의 성능이 가장 좋았다고 합니다.</p>
<p><img src="https://images.velog.io/images/ann9902/post/2c6b6420-db81-439d-85a6-02b756d41e32/image.png" alt="">
skip connection을 적용한 결과이고, 8s가 가장 좋음을 볼 수 있습니다.</p>
<p><img src="https://images.velog.io/images/ann9902/post/dbab1f4a-f0f3-4a41-96d5-5033d6b97e6d/image.png" alt="">
당시 SOTA모델에 비해 20%정도의 성능 향상을 이뤘습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Convolutional Neural Networks]]></title>
            <link>https://velog.io/@tobigs1516_image/Convolutional-Neural-Networks</link>
            <guid>https://velog.io/@tobigs1516_image/Convolutional-Neural-Networks</guid>
            <pubDate>Mon, 18 Oct 2021 04:10:36 GMT</pubDate>
            <description><![CDATA[<h1 id="c4w1l02-computer-vision">C4W1L02 Computer vision</h1>
<h3 id="fully-connected-layer-convolution-layer">Fully-connected layer, Convolution layer</h3>
<p>1000x1000x3 크기의 input, 1000개의 hidden node를 가지는 fc-layer를 생각해보면 3billion(30억)개의 parameter가 생긴다. </p>
<p>이는 과적합을 유도하기 쉽다.</p>
<p>이를 해결할 수 있는 것이 Convolution network이다.
convolution network는 인풋에 동일한 가중치(filter)를 슬라이딩하면서 적용한다. 이는 parameter의 숫자를 훨씬 줄여줄 수 있다. 
<img src="https://images.velog.io/images/ann9902/post/9fbf1247-8c82-45c4-8a5c-e6653ce344b9/image.png" alt=""></p>
<h1 id="c4w1l02-edge-detection-examples">C4W1L02 Edge Detection Examples</h1>
<h3 id="vertical-edge-detection">vertical edge detection</h3>
<p>convolution network에서 vertical edge를 추출하려면 어떻게 해야할까?
아래와 같이 1, 0, -1 로 이루어진 filter를 사용하면 된다. 이 필터가 어떻게 vertical edge를 잘 잡아낼 수 있는 것일까? </p>
<p>직접 계산해보면 아래와 같다.
아래의 예시의 input은 한쪽은 밝고, 다른 한쪽은 어둡다.
이를 1, 0, -1 로 이루어진 필터와 합성곱하면 input에서 가운데 경계선 부근이 추출됌을 볼 수 있다.</p>
<p>경계선에 비해 꽤 넓은 범위로 추출된 것 같지만 이는 매우 작은 인풋이라 그런것이고 더 큰 이미지에 적용한다면 정밀하게 추출될 수 있다.
<img src="https://images.velog.io/images/ann9902/post/9a4edea6-1f1f-4756-8775-1a05302f614a/image.png" alt=""></p>
<hr>
<h1 id="c4w1l03-more-edge-detection">C4W1L03 More Edge Detection</h1>
<h3 id="vertical-and-horizontal-edge-detection">Vertical and Horizontal Edge Detection</h3>
<p>밝은 부분 -&gt; 어두운 부분의 edge는 양수로,
어두운 부분 -&gt; 밝은 부분의 edge는 음수로 나오게 된다. </p>
<p>방향성을 고려하지 않는다면 결과에 절댓값을 씌어줄 수도 있다.
<img src="https://images.velog.io/images/ann9902/post/a0c77ea5-7eee-4e62-a3a3-70032765d05f/image.png" alt=""></p>
<p>horizontal edge를 추출하려면 위의 vertical filter와 같은 원리로 아래와 같이 구성하면 된다.
초록색 박스부분에선 input에서 10에서 0으로 바뀌는 경계선 부분에 해당하기 때문에 feature map에서 30이 나오고,</p>
<p>보라색 박스부분에선 input에서 0에서 10으로 바뀌는 경계선 부분에 해당하기 때문에 feature map에서 -30이 나온다.</p>
<p>노란색 박스부분에선 input에서 대체적으로 10에서 0으로 바뀌지만 다른 한쪽에 10 포함되어 있기 때문에 30보다 작은 10이라는 숫자가 나오게 된다. </p>
<p><img src="https://images.velog.io/images/ann9902/post/5a01c6fd-4de1-4655-9332-db8d440672a3/image.png" alt=""></p>
<h3 id="learning-to-detect-edges">Learning to detect edges</h3>
<p>앞선 예시에서의 vertical filter, horizontal filter 모두 하나의 예시이다. </p>
<p>아래의 sobel filter, schor filter 처럼 중간에 큰값을 줘서 중간 픽셀을 더 집중할 수도 있다.</p>
<p>하지만 이런 수작업으로 만든 특정 filter보다, </p>
<blockquote>
<p>filter를 파라미터로하여 역전파를 통해 학습하는 것은 아주 다양한 edge를 검출해낼 수 있게한다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/ann9902/post/93028741-cd0b-4b2f-8ee7-3a02f33f3e27/image.png" alt=""></p>
<p>Q. 정사각형 input이 아니라 직사각형 input을 넣는 경우도 있는가?
<a href="https://stackoverflow.com/questions/50540580/can-i-use-rectangle-images-with-a-convolution-neural-network-in-keras">참고링크</a>
있다. 정사각형 input을 사용하는 것은 계산의 편리함을 위해서이다.
만약 input이 224x320라면 pooling layer를 적용함에따라 224x320, 112x160, 56x80, 28x40, 14x20, 7x10 와 같이 변화할 것이다.  </p>
<h1 id="c4w1l04-padding">C4W1L04 Padding</h1>
<h3 id="padding">padding</h3>
<p>convolution layer에서 패딩이 필요한 이유는 두가지이다.</p>
<ol>
<li>convolution연산을 할 수록 feature map의 크기는 작아진다. 여러 layer를 거치고 난 후에는 아주 작은 map만 남게된다.</li>
<li>가장자리의 input은 결과에 사용되는 횟수가 적다.
아래 그림에서 초록색 픽셀은 한번만 연산되는 반면 빨간색 픽셀은 여러번 연산되는 것을 볼 수 있다.
<img src="https://images.velog.io/images/ann9902/post/d8ec3c9c-f80d-4801-abd3-229d82e1c832/image.png" alt=""></li>
</ol>
<h3 id="valid-and-same-convolutions">Valid and Same convolutions</h3>
<ul>
<li>valid
no padding.
input : n x n
filter : f x f
output : n-f+1 x  n-f+1</li>
</ul>
<ul>
<li>same
input shape == output shape
input : n x n
filter : f x f
output : n+2p-f+1 x n+2p-f+1</li>
</ul>
<p>위의 식에 따라서 input shape과 output shape이 같으려면 p = (f-1)/2 가 된다.</p>
<p>따라서 filter가 홀수라면 위의 식에 따른 padding을 적용시 conv연산을 하더라도 동일한 크기를 유지할 수 있다.</p>
<p>이는 filter의 크기를 짝수로 쓰지 않는 이유와도 관련이 있다.</p>
<ol>
<li>filter가 짝수라면 padding이 왼쪽과 오른쪽이 비대칭적으로 적용이 되어야 한다.</li>
<li>filter가 짝수라면 중앙을 나타내는 픽셀이 없어서 계산을 할 때 애매하다.</li>
</ol>
<p>짝수 filter가 성능에 큰 영향을 주진 않지만 적용할 때 깔끔해지지 않기 때문에 관습적으로 사용하지 않는다고 한다.
<img src="https://images.velog.io/images/ann9902/post/6f2f78ad-e770-4486-952c-e70c956a5b96/image.png" alt=""></p>
<h1 id="c4w1l05-strided-convolutions">C4W1L05 Strided Convolutions</h1>
<h3 id="strided-convolution">Strided convolution</h3>
<p>convolution에서 stride가 2라면 아래 그림처럼 2칸씩 옮기며 연산을 진행한다.
따라서 앞서 output shape이 (n+2p-f) + 1 이었다면 stride가 적용된다면 </p>
<p>(n+2p-f)/s + 1 가 된다.</p>
<p>그런데 만약 이 값이 정수가 아니라면 내림을 해준다. 내림을 한다는 의미는 아래 그림에서 파란 박스처럼 input 영역을 벗어나게 되는 경우는 연산을 하지 않는다는 것이다. 
<img src="https://images.velog.io/images/ann9902/post/1ebdc660-d510-4d93-a0ad-05fade3632f5/image.png" alt=""></p>
<p>Q. stride를 크게 줄수록 정보의 손실이 일어나지 않는가?
맞다. 정보의 손실이 일어난다. 하지만 손실이 허용될 때가 있다. 예를 들어 대부분이 까맣고 일부분만 하얀 밤하늘의 별과 같은 이미지가 있다고 하면 stride를 작게주어 세밀하게 학습하는 것보다 stride를 크게 줘서 학습을 해도 feature는 잘 추출될 수 있을 것이다.</p>
<h3 id="technical-note-on-cross-correlation-vs-convolution">Technical note on cross-correlation vs convolution</h3>
<p>딥러닝을 공부하다보면 우리가 흔히 말하는 convolution이라는 것이 사실 convolution이 아니라고 하는 것 을 볼 수 있다.</p>
<p>사실 수학, 신호처리에서 말하는 convolution은 곱하는 연산과 더하는 연산을 해준다음, 그것을 가로, 세로로 뒤집는 미러링 과정을 진행한다. 미러링 과정을 통해 결합법칙이 성립하게 해주기에 이 과정이 중요하다고 한다.</p>
<blockquote>
<p>딥러닝에서는 미러링 과정을 생략하여도 학습에 아무런 문제가 없기 때문에 미러링을 생략한 형태의 convolution을 관습적으로 convolution이라고 부른다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/ann9902/post/6defd248-bbad-4a28-9b2f-2aa5f165ed19/image.png" alt=""></p>
<h1 id="c4w1l06-convolutions-over-volumes">C4W1L06 Convolutions Over Volumes</h1>
<h3 id="convolution-on-rgb-images">Convolution on RGB images</h3>
<p>covolution을 텐서에 적용하는 방법은 아래 그림과 같다.
input channel수와 동일한 수의 channel을 가지는 filter로 합성곱을 하면 된다. 결과로는 1차원의 map이 나오게 된다.</p>
<p><img src="https://images.velog.io/images/ann9902/post/c4a8346a-010e-49be-be42-1186500dbbb6/image.png" alt=""></p>
<p>이때 filter를 아래 그림의 첫번째처럼 구성하게되면 R채널의 수직 성분을 추출할 것이고,
두번째처럼 구성하게되면 색깔에 상관없이 수직 성분을 추출할 것이다.
<img src="https://images.velog.io/images/ann9902/post/2ca8732d-d6f0-47f8-a08e-a43598f4f4a3/image.png" alt=""></p>
<h3 id="multiple-filters">Multiple filters</h3>
<p>필터를 여러개 적용한다면 필터의 개수만큼 다양한 종류의 특징이 추출될 것이다.</p>
<p>Classification 모델을 보면 channel을 많이 뽑고 보는 모델들이 있는데 이러한 이유로 다양한 feature들이 뽑힐 수 있어 성능의 향상이 있지 않았나 싶다.</p>
<p>여러개 필터를 적용한다면 output의 channel은 필터의 개수와 동일해질 것이다.
<img src="https://images.velog.io/images/ann9902/post/a71662a2-82dc-436b-b6bb-e6235de2699f/image.png" alt=""></p>
<h1 id="c4w1l07-one-layer-of-a-convolutional-net">C4W1L07 One Layer of a Convolutional Net</h1>
<p>이 장에서는 하나의 레이어에서 다음 레이어로 넘어갈 때 연산이 어떻게 진행되는지 설명한다.</p>
<p>필터를 적용한 결과에 activation func, bias를 추가하면 ouput의 한 채널이 완성된다. 
이 과정을 filter의 개수만큼 진행하면 된다.</p>
<p><img src="https://images.velog.io/images/ann9902/post/0c7a731f-569c-4ab6-b7f4-53a122a895ce/image.png" alt="">
아래와 같은 표현이 등장하는데, [] 안에 들어가는 숫자는 몇번째 layer 인지를 나타내는 것이다. </p>
<p><img src="https://images.velog.io/images/ann9902/post/bcf14fac-e9f5-419f-aa1e-dea072d47a96/image.png" alt=""></p>
<h1 id="c4w1l09-pooling-layers">C4W1L09 Pooling Layers</h1>
<h3 id="max-pooling">Max pooling</h3>
<p>필터가 적용되는 영역에서 가장 큰 수만 뽑히는 연산이다.
pooling이 적용될때 output size를 계산하는 방법은 convolution할 때와 같다.</p>
<p>pooling layer에서의 hyperparameter는 f(filter), s(stride)이다. 2, 2로 두는 경우가 많다고 한다.
(n -f)/s + 1 이다. (channel은 conv연산에서는 filter의 개수였다면 pooling에서는 인풋의 채널과 같다)</p>
<p>pooling layer는 단순 연산만 하기에 학습하는 parameter가 없다. 
<img src="https://images.velog.io/images/ann9902/post/ab264470-29dc-4093-8ca4-8e14d708daaf/image.png" alt=""></p>
<p>pooling에서는 padding을 거의 쓰지 않는다고한다.
(그런데 테두리 부분에 max가 존재하는 경우라면 padding을 추가해주는 것이 좋지 않을까?)</p>
<h3 id="average-pooling">Average pooling</h3>
<p>거의 사용하지 않는다고 한다.</p>
<p>pooling의 목적이 특징을 극대화하려고 하는 것이기에 평균을 구해서 특징을 완화시키는 것은 도움이 안될 것 같다.</p>
<p>레이어 하단부에서 MAP(mean average pooling)가 사용되는 경우는 있다.</p>
<p>map는 grad cam에서도 사용된다.</p>
<h1 id="c4w1l10-cnn-example">C4W1L10 CNN Example</h1>
<h3 id="neural-network-example">Neural Network example</h3>
<h4 id="lenet-5">LeNet-5</h4>
<ul>
<li>input : 32 x 32 x 3</li>
<li>conv + pooling , FC-layer , softmax</li>
</ul>
<h4 id="convolution-모델의-패턴">convolution 모델의 패턴</h4>
<ul>
<li>층이 깊어질수록 H, W 는 작아지고 channel은 늘어난다.</li>
<li>conv - pooling 이 반복된 후 FC layer, softmax 가 이어지는 형태</li>
</ul>
<p>Q. 왜 처음부터 채널의 수를 많이 뽑지않고 뒤로 갈수록 늘릴까?
초반에는 H, W가 크기에 연산량의 제약상 효율적으로 feature를 추출하기위해 그런것이라고 예상된다.</p>
<p><img src="https://images.velog.io/images/ann9902/post/3e97a52c-1fa1-4333-bc18-6a19713eb315/image.png" alt="">
*층의 개수를 셀때는 conv+pooling을 하나의 레이어로 명칭한다.(하나의 convention)</p>
<p>아래는 LeNet-5의 구조이다.
<img src="https://images.velog.io/images/ann9902/post/b31ba5aa-17cb-4460-8155-c6b1dbb3a22f/image.png" alt=""></p>
<p>여기서 알 수 있는 것은</p>
<ul>
<li>activation size가 점진적으로 줄어든다. 너무 빠르게 감소하면 성능에 악영향을 줄 수 있다.</li>
<li>conv layer가 dense layer에 비해 현저히 적은 파라미터를 가진다.</li>
</ul>
<p>Q. 위의 사진의 parameter에서 channel을 생략한 것 같다.
맞다. 위의 사진에서 parameter를 계산할 때 필터의 channel을 1로 두고 계산하고 있는데, CONV1기준으로 정확하게 계산하면</p>
<p>((5x5x3)+1)x8 = 608 이 된다.
<img src="https://images.velog.io/images/ann9902/post/1fea6a79-4dd7-4b60-97dd-ceca9e849dc5/image.png" alt=""></p>
<h1 id="c4w1l11-why-convolutions">C4W1L11 Why Convolutions</h1>
<h2 id="why-convolutions">Why convolutions</h2>
<h3 id="parameter-sharing">Parameter sharing</h3>
<p>한 이미지 내에서 동일한 필터를 공유한다. </p>
<h3 id="sparsity-of-connection">Sparsity of connection</h3>
<p>아래 그림에서 output의 초록색 부분은 input의 초록색 박스 부분과만 연결된다. 빨간색 박스도 이와 같다. 이러한 특성으로 희소한 conneciton을 가지게 된다. 
위의 두가지 특성으로 적은 파라미터수, 오버피팅 방지를 할 수 있다. 
<img src="https://images.velog.io/images/ann9902/post/850dc001-4d7d-4d6a-9dfc-3214bc241ba3/image.png" alt=""></p>
<h3 id="translation-invariance">translation invariance</h3>
<p>동일한 filter를 적용하기 때문에 이미지내 물체의 위치가 달라지더라도 특징을 포착해낼 수 있다.</p>
<p>위의 이유가 convolution이 효과적인 이유이다.</p>
<h2 id="putting-it-together">Putting it together</h2>
<p>model의 예측치가 나오면 이의 오차를 합한 후에 training set 크기(m)로 나눠주면 cost가 나온다.</p>
<p>이 cost를 backpropagation하여 각 conv layer가 가지는 w, b를 업데이트하면된다.</p>
<p><img src="https://images.velog.io/images/ann9902/post/1bebd666-0d68-47d2-a664-5dd6b64956f1/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Deep Convolutional Models: Case Studies]]></title>
            <link>https://velog.io/@tobigs1516_image/Deep-Convolutional-Models-Case-Studies</link>
            <guid>https://velog.io/@tobigs1516_image/Deep-Convolutional-Models-Case-Studies</guid>
            <pubDate>Wed, 13 Oct 2021 09:06:43 GMT</pubDate>
            <description><![CDATA[<p>작성자 : 동국대학교 통계학과 <a href="https://github.com/yoonj98">이윤정</a></p>
<blockquote>
<h3 id="contents">Contents</h3>
</blockquote>
<ol>
<li>왜 케이스 스터디를 하나요?</li>
<li>고전적인 네트워크들</li>
<li>ResNets</li>
<li>왜 ResNets이 잘 작동할까요?</li>
<li>Network 속의 Network</li>
<li>Inception 네트워크의 아이디어</li>
<li>Inception 네트워크</li>
</ol>
<hr>
<h1 id="deep-convolutional-models-case-studies">Deep Convolutional Models: Case Studies</h1>
<p>이번 강의에서는 합성곱 신경망의 사례와 구조에 대해 배울 수 있습니다. </p>
<h2 id="왜-케이스-스터디를-하나요">왜 케이스 스터디를 하나요?</h2>
<p>Computer Vision에서는 앞선 강의에서 배운 padding, pooling 그리고 fully connected layer를 통해 Convolution Neural Network을 구축하는 것이 가장 중요합니다. 이때, 한 task에서 잘 동작하는 CNN 구조는 다른 task에서도 유용하게 동작하기 때문에 CNN을 구축하기 위해서는 신경망 구조를 살펴보아야 합니다. </p>
<h2 id="고전적인-네트워크들">고전적인 네트워크들</h2>
<h3 id="1-lenet-5">1. LeNet-5</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/e6d97942-480f-4cfa-b186-c8cca6274754/image.png" alt="">LeNet-5의 목적은 손글씨 인식입니다. 그 중 흑백으로 된 손글씨를 인식하기 위해 input channel이 1입니다. 또한, <strong>conv pool ... conv pool ... fc fc output</strong>의 구성을 보임을 알 수 있습니다. 다만, 해당 모델을 구상하는 당시에는 padding을 사용하지 않는 경향이 있었습니다. 그렇기 때문에 층이 깊어질수록 높이와 너비는 줄어드는 반면, 채널의 수는 늘어나는 경향을 지닙니다. 그 뿐만 아니라, 해당 모델을 구상하는 당시에는 Relu activation function이 아닌 Sigmoid와 tanh activation function을 사용하였습니다. </p>
<h3 id="2-alexnet">2. AlexNet</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/e6f88b4c-83de-45cf-b5e9-23ba704bcdf9/image.png" alt="">AlexNet의 목적은 이미지를 1000개에 해당하는 클래스로 분류하는 것 입니다. 이때, 논문에서 Input Image는 224x224x3이지만, 실제로 계산해보면 227x227x3이 타당하므로 그림을 보면 input size가 227x227x3입니다.  </p>
<p>Input Image 227x227x3에 대해 11x11, 5x5, 3x3 커널을 사용하였으며 5개의 convolutional layer와 3개의 dense layer로 이루어져 있습니다. AlexNet은 LeNet-5와 유사한 구조지만 parameter 수에서 가장 큰 차이를 보입니다. LeNet의 경우 6만개의 parameter를 갖는다면 AlexNet의 경우 6천만개의 parameter를 갖습니다. 또한, AlexNet은 Relu activation function을 사용했습니다. </p>
<h3 id="3-vgg-16">3. VGG-16</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/64023f50-ac4f-4c3d-abc0-fd171207f72d/image.png" alt="">VGG-16은 수많은 parameter를 갖는 대신, 모든 합성곱 연산이 3x3 filter를 가지고 padding 크기는 2, stride는 1을 사용하는 동일합성곱 연산입니다. 
<img src="https://images.velog.io/images/yoonj98/post/9628eb28-c6b7-4537-92b0-4921777b53aa/image.png" alt="">이렇게 3x3 filter를 중첩하여 쌓는 이유는 3개의 3x3 convolutional layer를 중첩하면 1개의 7x7 convolutional layer와 receptive field가 같아지지만, activation function을 더 많이 사용할 수 있어 더 많은 비선형성을 얻을 수 있으며, parameter 수도 줄어드는 효과를 얻을 수 있기 때문입니다. (3x3x3=27 &lt; 7x7=49) 그럼에도 불구하고, parameter 수가 많으므로 네트워크의 크기가 커진다는 단점이 있습니다. </p>
<blockquote>
<ul>
<li>동일합성곱 연산 : 이전 layer의 높이와 너비를 같게 만드는 padding을 갖는 연산</li>
<li>receptive field : 각 단계의 입력 이미지에 대해 하나의 필터가 커버할 수 있는 이미지 영역의 일부</li>
</ul>
</blockquote>
<h2 id="resnets">ResNets</h2>
<p>vanishing gradient와 exploding gradient 문제로 인해 고전적인 네트워크들은 아주 깊은 신경망을 학습하지 못하였습니다. 그러만, ResNet은 <strong>Skip Connection</strong>을 통해 이러한 문제를 해결하였습니다. </p>
<h3 id="1-resnet의-main-path">1. ResNet의 Main Path</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/682677f3-a18d-40b6-acc3-e47e5ec22b55/image.png" alt="">예를 들어, 2개의 layer가 존재할 때 다음과 같이 존재하는 모든 층을 지나는 일련의 연산 과정을 main path라고 부릅니다. 따라서, $a^{[l]}$의 정보가 $a^{[l+2]}$로 흐르기 위해서는 다음과 같은 연산 과정을 거쳐야 합니다. 이때, Relu activation function을 통해 비선형성을 적용해줄 수 있습니다.</p>
<h3 id="2-skip-connection-short-cut">2. Skip Connection (Short Cut)</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/c76ee143-f381-4f25-8643-52798d8b7224/image.png" alt="">많은 layer를 걸쳐 backpropagation될 때 vanishing gradient 문제가 발생하므로, ResNet은 gradient가 몇 개의 layer를 건너 뛰어 연결될 수 있는 short cut을 사용했습니다. 이를 통해 $a^{[l]}$의 정보를 변하지 않고 더 깊은 layer에 전달할 수 있습니다.</p>
<h3 id="3-residual-block">3. Residual Block</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/82daf2a1-fffa-4619-8530-efbee3a22d83/image.png" alt="">$a^{[l]}$를 더해서 다시 activation function에 넣는 부분까지를 residual block이라고 부르며, ResNet은 여러 개의 residual block으로 구성됩니다.</p>
<blockquote>
<h4 id="왜-res잔차net인가요">왜 Res(잔차)Net인가요?</h4>
<p><img src="https://images.velog.io/images/yoonj98/post/721b3512-a566-4c98-9059-cb1967899095/image.png" alt="">기존의 신경망은 입력값 x를 타겟값 y로 매핑하는 함수 H(x)를 얻는 것이 목적입니다. 그러나 ResNet은 F(x)+x를 최소화하는 것을 목적으로 합니다. 이때, x는 현시점에서 변할 수 없는 값이므로 F(x)를 0에 가깝게 만드는 것이 목적이 됩니다. 
F(x)가 0이 되면 출력과 입력이 모두 x로 같아지게 됩니다. F(x)=H(x)-x이므로 F(x)를 최소로 해준다는 것은 H(x)-x를 최소로 해주는 것과 동일한 의미를 지닙니다. 여기서 H(x)-x를 잔차(residual)라고 합니다. 즉, 잔차를 최소로 해주는 것이므로 ResNet이라고 칭합니다.</p>
</blockquote>
<h2 id="왜-resnets이-잘-작동할까요">왜 ResNets이 잘 작동할까요?</h2>
<p><img src="https://images.velog.io/images/yoonj98/post/bb9d2a06-f0e3-4dbb-88a1-3e53f0deeaf3/image.png" alt="">
Plain 모델의 경우 layer의 개수를 늘릴 수록 훈련 오차가 감소하다가 다시 증가하는 경향을 보였습니다. 반면, ResNet의 경우 layer의 개수를 늘릴 수록 훈련 오차가 꾸준히 감소하는 경향을 보입니다.
<img src="https://images.velog.io/images/yoonj98/post/5c2a99e3-2f0b-43df-ad88-66baf976805c/image.png" alt="">Skip Connetion을 통한 출력값 $a^{[l+2]}$= $g(z^{[l+2]}+a^{[l]}) = g(W^{[l+2]}a^{[l+2]}+b^{[l+2]}+a^{[l]})$입니다. 이때, $W^{[l+2]}$와 $b^{[l+2]}$의 값이 극도로 작아져 0에 가까워진다면 $a^{[l+2]}=g(a^{[l]})=a^{[l]}$로 항등식이 되며, Relu activation function로 인해 양수 값만 존재하게 됩니다. </p>
<p>이처럼, 양수인 경우 항등 함수인 Relu로 학습이 되면 $a^{[l+2]}=a^{[l]}$이므로 적어도 성능 저하는 발생하지 않습니다. 다만, 다음과 같이 전개되기 위해서는 $z^{[l+2]}$와 $a^{[l]}$이 같은 차원을 가져야 합니다. 따라서, 동일합성곱 연산을 하거나 차원을 같게 만들어주는 행렬 $W_s$를 곱해줍니다.</p>
<p><img src="https://images.velog.io/images/yoonj98/post/1567c0f3-ca3c-46ec-8da2-b7061c5c0435/image.png" alt="">그림을 자세히 보면 output feature map의 개수가 변함에 따라  Shortcut이 실선이 아니라 점선을 이용하는 것을 알 수 있습니다. Output feature map의 개수가 2배로 커질 때 마다 feature map의 가로, 세로 size는 절반으로 줄여주는 방식을 이용하고 있으며, 이 때는 pooling 대신 stride를 2로 갖는 convolution 연산을 이용하는 점이 특징입니다. 이 경우, Shortcut에서도 feature map size를 줄여주어야 하기 때문에 projected shortcut을 이용합니다. 이러한 shortcut 구조를 통해 vanishing gradient에 강인한 학습을 수행할 수 있게됩니다.</p>
<blockquote>
<h4 id="simple-shortcut-vs-projected-shortcut">simple shortcut VS projected shortcut</h4>
<p><img src="https://images.velog.io/images/yoonj98/post/0cfeb73c-c161-4f89-8b54-1697075294f6/image.png" alt="">shortcut을 적용할때 $F(x)+x$에서 F(x)는 convolution filter를 통과하였습니다. 이때, filter 수가 증가하게 되면 차원 수가 높아지기 때문에 x의 차원을 높여줘야 합니다. 따라서 차원이 증가한 경우 1x1 convolution을 사용하는 projected shortcut을 통해 x의 차원을 증가시킵니다.</p>
</blockquote>
<h2 id="network-속의-network">Network 속의 Network</h2>
<p>1x1 합성곱은 1x1 크기를 가지는 Filter를 사용한 Convolution Layer입니다. 1x1 합성곱은 channel이 1개일 때는 유용해보이지 않지만, 여러 개의 channel을 가지고 있을 때에는 3가지 특징을 지닙니다. </p>
<h3 id="1-channel-수-조절">1. Channel 수 조절</h3>
<p>pooling을 통해서 높이와 너비는 줄일 수 있지만, channel은 줄일 수 없습니다. 이때, channel을 줄일 수 있는 방법은 1x1 convolution입니다. 1x1 convolution 연산을 위해 필요한 필터는 (1 x 1 x #channel x #filter)입니다. 여기서, #channel은 입력의 channel 수와 동일해야 하고 #filter는 원하는 출력의 channel 수로 지정해야 합니다.</p>
<p><img src="https://images.velog.io/images/yoonj98/post/f68130e6-d4fc-4c18-8fd9-2c5ae712e910/image.png" alt="">28x28x192의 input이 32개의 1x1 필터와 합성곱을 하여 28x28 x32의 output이 됩니다. 이는 input channel의 수만큼 유닛을 입력으로 받아 이들을 하나로 묶는 연산과정 통해 output channel의 수만큼 출력을 하는 작은 신경망 네트워크로 간주할 수 있습니다. (: <strong>네트워크 안의 네트워크</strong>)</p>
<h3 id="2-연산량-조절">2. 연산량 조절</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/c1730f87-2ef4-43bc-acb5-817cee7fa703/image.png" alt="">깊이 128의 입력 데이터로 깊이 128의 출력 데이터를 만들기 위해 3x3 convolution을 적용하면 3∗3∗128∗128=147,456개의 파라미터 수를 가집니다. 이때, 1x1 convolution을 통해 깊이를 32로 줄인 다음 3x3 convolution으로 깊이 128의 출력 데이터를 만든다고 한다면 1∗1∗128∗32+3∗3∗32∗128 = 4096+36,864 = 40,960개의 parameter를 가져 연산량 조절을 할 수 있음을 확인할 수 있습니다.</p>
<h3 id="3-비선형성-부여">3. 비선형성 부여</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/18768f22-183e-4ccf-a75d-d30cb5c543c0/image.png" alt="">1x1 convolution이 수행하는 작업은 여기에 있는 36가지 위치(높이와 너비의 곱에 의한 픽셀 갯수)를 각각 살펴보고 32개의 숫자(channel)와 필터의 32개 숫자 사이에 요소 간 곱셈을 하는 것입니다. 그리고 나서 ReLU 비선형성을 적용합니다.</p>
<h2 id="inception-네트워크의-아이디어">Inception 네트워크의 아이디어</h2>
<p><img src="https://images.velog.io/images/yoonj98/post/6776e03f-a396-4354-b584-b24e857eb388/image.png" alt="">인셉션 네트워크의 아이디어는 filter의 크기나 pooling을 결정하는 대신 한 layer 안에서 여러 종류의 filter를 사용해 네트워크가 스스로 조합을 학습하게 만드는 것입니다.</p>
<p><img src="https://images.velog.io/images/yoonj98/post/68607c5a-5201-4fde-aea7-5e081a2b5f1a/image.png" alt="">다만, 특정한 filter size에 국한된 것이 아니라는 점은 다양성을 띄지만 계산 비용에 있어서 문제가 발생합니다. 단순 5x5 필터를 사용한 연산 과정에서 계산해야 할 parameter 개수는 28x28x64x5x5x128 = 약 1억 6천만개이기 때문입니다. </p>
<p>이러한 문제점을 해결하기 위해서 1x1 Convolution을 활용하게 됩니다. 동일한 사이즈의 입력 데이터를 1x1 Convolution을 사용한 후, 5x5 Convolution을 사용한 연산 결과를 보면 단순 convolution 연산 결과인 28x28x64와 동일한 사이즈입니다. 이때, 연산 과정에서 계산해야할 parameter 개수는 총 4천 480만개입니다. 학습에 필요한 계산 비용이 크게 줄어든 것을 알 수 있습니다. </p>
<p>여기서 사용된 1 x 1 합성곱 층을 <strong>병목 층</strong>이라고도 합니다. 병목층을 사용시 표현의 크기가 줄어들어 성능에 영향을 지장을 줄지 걱정 될 수도 있는데, 적절하게 구현시 표현의 크기를 줄임과 동시에 성능에 큰 지장 없이 많은 수의 계산을 줄일수 있습니다.</p>
<h2 id="inception-네트워크-googlenet">Inception 네트워크 (GoogLeNet)</h2>
<p><img src="https://images.velog.io/images/yoonj98/post/08c11885-61d0-4209-87cd-1c0bbc049a1b/image.png" alt="">GoogLeNet은 상술한 바와 같이 22개 층으로 구성되어 있습니다. 파란색 블럭의 층수를 세보면 22개 층임을 알 수 있습니다. </p>
<h3 id="1-1x1-convolution">1. 1x1 Convolution</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/8989986d-97c6-4543-8ae1-967411a0cbaa/image.png" alt="">GoogLeNet에서 1x1 convolution은 feature map의 개수를 줄이는 목적으로 사용됩니다. feature map의 개수가 줄어들면 그만큼 연산량이 줄어듭니다.</p>
<h3 id="2-inception-module">2. Inception Module</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/f1f6f691-5fdc-4bd5-8b79-f6dc1f0cd48c/image.png" alt="">GoogLeNet은 총 9개의 인셉션 모듈을 포함하고 있습니다. 인셉션 모듈을 하나 확대해서 자세히 살펴봅시다. </p>
<p><img src="https://images.velog.io/images/yoonj98/post/02ced411-1505-4310-ab07-e16c9b413d24/image.png" alt="">GoogLeNet에 실제로 사용된 모듈은 1x1 convolution이 포함된 (b) 모델입니다. 아까 살펴봤듯이 1x1 convolution은 feature map의 개수를 줄여주는 역할을 합니다. 노란색 블럭으로 표현된 1x1 convolution을 제외한 (a) 모델을 살펴보면, 이전 층에서 생성된 feature map을 1x1 convolution, 3x3 convolution, 5x5 convolution, 3x3 max pooling해준 결과 얻은 feature map을 모두 함께 쌓아줍니다. </p>
<p>AlexNet, VGGNet 등 이전 CNN 모델들은 한 층에서 동일한 사이즈의 filter를 이용해서 convolution을 해줬던 것과 차이가 있습니다. 따라서 좀 더 다양한 종류의 특성이 도출되며, 1x1 convolution이 포함되었으므로 연산량 역시 감소하게 됩니다.</p>
<blockquote>
<h4 id="왜-여러-크기의-filter를-사용하나요">왜 여러 크기의 filter를 사용하나요?</h4>
<p><img src="https://images.velog.io/images/yoonj98/post/cd77556c-7e17-4d2a-8d5f-94e8e57fa259/image.png" alt="">자동차가 있는 두 이미지에 (3,3) 크기의 filter를 하나만 사용해 이미지의 특징을 찾아봅시다. 그림에서도 볼 수 있듯이 같은 물체일지라도 서로 다른 비율로 위치할 경우 한 종류의 필터를 사용하는 것이 효율적이지 않다는 것을 생각할 수 있습니다. 이러한 아이디어에 따라 GogLeNet은 다른 크기의 필터를 가진 인셉션 모듈 9개가 입력 이미지의 서로 다른 영역의 특징을 찾아 축적합니다.</p>
</blockquote>
<h3 id="3-global-average-pooling">3. Global Average Pooling</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/1a6c7aa3-22fe-4f72-9a06-6dfed85930d6/image.png" alt="">AlexNet, VGGNet 등에서는 fully connected layer(FC)들이 망의 후반부에 연결되어 있습니다. 그러나 GoogLeNet은 FC 방식 대신에 global average pooling이란 방식을 사용합니다. global average pooling은 전 층에서 산출된 feature map들을 각각 평균낸 것을 이어서 1차원 벡터를 만들어주는 것입니다. 1차원 벡터를 만들어줘야 최종적으로 이미지 분류를 위한 softmax 층을 연결해줄 수 있기 때문입니다. 만약 전 층에서 1024장의 7x7의 feature map이 생성되었다면, 1024장의 7x7 feature map 각각 평균내주어 얻은 1024개의 값을 하나의 벡터로 연결해주는 것입니다.</p>
<h3 id="4-auxiliary-classifier">4. Auxiliary Classifier</h3>
<p><img src="https://images.velog.io/images/yoonj98/post/ceb497c1-916f-4bc7-9979-85e732c5b9d2/image.png" alt="">네트워크의 깊이가 깊어지면 깊어질수록 vanishing gradient 문제를 피하기 어려워집니다. 가중치를 훈련하는 과정에 backpropagation를 활용하는데, 이 과정에서 가중치를 업데이트하는데 사용되는 gradient가 점점 작아져서 0이 되어버리기 때문입니다. 따라서 네트워크 내의 가중치들이 제대로 훈련되지 않는 문제가 발생합니다.</p>
<p>이 문제를 극복하기 위해서 GoogLeNet에서는 네트워크 중간에 두 개의 보조 분류기(auxiliary classifier)를 달아주었습니다. 보조 분류기의 구성을 살펴보면, 5x5 평균 pooling (stride 3) -&gt; 128개 1x1 convolution -&gt; 1024 FC layer -&gt; 1000 FC layer -&gt; softmax 순입니다.</p>
<h2 id="결론">결론</h2>
<p><img src="https://images.velog.io/images/tobigs1516_image/post/77a28fc4-28bd-42a3-88fe-1af95cfce64f/image.png" alt="">LeNet-5를 제외한 오늘 배운 모델들의 Imagenet 데이터셋에 대한 상위 5개의 정확도와 parameter의 수입니다.</p>
<ul>
<li>AlexNet과 ResNet-152는 둘 다 약 6천만 개의 parameter를 가지고 있지만 상위 5개 정확도에는 약 10%의 차이가 있습니다. 그러나 ResNet-152를 훈련하려면 많은 계산이 필요합니다. (AlexNet의 약 10배) 이는 더 많은 훈련 시간이 필요함을 의미합니다.</li>
<li>VGGNet은 ResNet-152에 비해 더 많은 매개변수와 FLOP을 가질 뿐만 아니라 정확도도 떨어집니다. 감소된 정확도로 VGGNet을 훈련하는 데 더 많은 시간이 걸립니다.</li>
<li>AlexNet 교육은 Inception 교육과 거의 같은 시간이 걸립니다. 향상된 정확도(약 9%)로 메모리 요구 사항이 10배 감소합니다.</li>
</ul>
<hr>
<h2 id="reference">reference</h2>
<p><a href="https://www.boostcourse.org/ai218/joinLectures/138359?isDesc=false">https://www.boostcourse.org/ai218/joinLectures/138359?isDesc=false</a>
<a href="https://bskyvision.com/">https://bskyvision.com/</a>
<a href="https://hoya012.github.io/blog/deeplearning-classification-guidebook-1/">https://hoya012.github.io/blog/deeplearning-classification-guidebook-1/</a>
<a href="https://techblog-history-younghunjo1.tistory.com/132">https://techblog-history-younghunjo1.tistory.com/132</a>
<a href="https://ganghee-lee.tistory.com/41">https://ganghee-lee.tistory.com/41</a>
<a href="https://ardino.tistory.com/44">https://ardino.tistory.com/44</a></p>
]]></description>
        </item>
    </channel>
</rss>