<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>alpha_gorani.log</title>
        <link>https://velog.io/</link>
        <description>함께 성장할 수 있는 AI Engineer가 되고 싶습니다 </description>
        <lastBuildDate>Wed, 05 Jun 2024 09:42:03 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>alpha_gorani.log</title>
            <url>https://velog.velcdn.com/images/running_learning/profile/e9637ddd-4e69-4e49-b052-2ca43fcbd7c7/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. alpha_gorani.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/running_learning" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[만들면서 배우는 생성 AI] 8장 - 확산 모델(diffusion model)]]></title>
            <link>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-8%EC%9E%A5-%ED%99%95%EC%82%B0-%EB%AA%A8%EB%8D%B8diffusion-model</link>
            <guid>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-8%EC%9E%A5-%ED%99%95%EC%82%B0-%EB%AA%A8%EB%8D%B8diffusion-model</guid>
            <pubDate>Wed, 05 Jun 2024 09:42:03 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>2020년에 획기적인 확산 모델 논문이 나왔다. 이름하여 DDPM! (denoising diffusion probablistic model의 줄임말)
최근 생성 모델링에서 핫한(?) diffusion 모델의 주요 논문이다.
이번 포스팅에서 diffision 모델이 무엇이고 그 기본 원리와 이를 작동하게 하기 위한 모델의 구성 요소에 대해 알아보자!</p>
</blockquote>
<h1 id="1-denoising-diffusion-model">1. Denoising diffusion model</h1>
<p>Denoising diffusion model을 직영하면 잡음 제거 확산 모델이다. 이 모델의 핵심 아이디어는 다음과 같다.</p>
<p>연속해서(여러 번의 과정으로) 매우 조금씩 이미지에서 잡음을 제거하도록 모델을 훈련시키는 것이다.
그렇게 되면 이론적으로 완전히 랜덤한 잡음에서 훈련 세트의 이미지와 같은 이미지를 얻을 수 있다.
Denoising diffision 모델 학습에는 크게 <strong>두 가지의 과정</strong>이 필요하다.</p>
<p><strong>1. 정방향 확산 과정 (diffusion process)
2. 역방향 확산 과정 (denoising process)</strong></p>
<p>이에 대해 조금 더 자세히 알아보자.</p>
<h1 id="2-정방향-확산-과정-diffusion-process">2. 정방향 확산 과정 (diffusion process)</h1>
<p>Forward process라고도 불리는 정방향 확산 과정은 원본 이미지에 noise를 점진적으로 적용하는 과정이다.
이때의 noise는 가우시안 노이즈로 평균이 0이고 분산이 1인 노이즈이다.
원본 이미지에 가우시안 노이즈를 조금씩 1000번 적용했다고 해보자.
그러면 1000번째로 적용한 이미지는 가우시안 노이즈와 거의 동일할 것이다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/5ccb8419-772c-490c-92b0-6aae2cdc53e2/image.png" alt=""></p>
<p>이를 식 $$q=(x_t|x_{t-1})$$ 로 표현한다.
$$x_{t-1}$$ 에서 가우시안 잡음(소량)을 추가한 $$x_t$$의 분포라고 볼 수 있을 것이다.</p>
<p>이를 수학적으로 표현하면 다음과 같다.
$x_t = \sqrt{1-\beta} x_{t-1} + \sqrt{\beta} I$ </p>
<p>갑자기 $\beta, I$ 가 나와서 헷갈릴 수 있지만 하나하나 보면 이해하기 쉽다.
우선 위에서 언급한 것처럼 정방향 패스에서는 원본 이미지에 소량의 가우시안 노이즈를 넣어 완벽한 가우시안 노이즈 분포를 만들어 내고 싶다.
따라서 $x_t = a<em>x_{t-1} + b</em>noise$ 가 될 것이다.
여기서 a,b는 스케일 값 (얼만큼의 이전 이미지를 포함할지(a), 가우시안 노이즈를 포함할지(b)) 이다.</p>
<p>따라서 가우시안 노이즈 $I$를 소량 적용할 $\sqrt{\beta}$가 적용되는 것이다. </p>
<p><strong>그렇다면 왜 $\sqrt{\beta}$와 $\sqrt{1-\beta}$를 스케일 값으로 만들었을까?</strong> (여기서 $\sqrt{\beta}$는 상수이다.)
결론적으로는 이런 식을 통해 T가 클 때,$x_t$는 표준 가우스 분포에 가깝다는 식이 도출되기 때문이다.</p>
<p>*<em>유도하기 위해서는 $var(ax)=a^2</em>var(x)$ 와
$var(x+y)=var(x)+var(y)$의 성질(공식)을 알아야 한다. 
**</p>
<p>$x_{t-1}$을 평균이 0 분산이 1로 하였기 때문에 위의 첫 번째 공식에 따라
$\sqrt{1-\beta} x_{t-1}$의 분산은 $1 - \beta$가 되고, 
$\sqrt{\beta}I$의 분산은 $\beta$가 된다.</p>
<p>이 둘을 더하게 되면 (= $x_t$ 분포 유도) 
평균이 0이고 분산이 1 ($1 - \beta + \beta$ = 1)인 또 다른 새로운 분포를 얻게 되는 것이다. </p>
<p><strong>즉 원본 이미지에 소량의 가우시안 분포를 추가하면서 항상 $x_t$를 표준 가우스 분포와 거의 동일하다는 게 만들겠다는 아이디어이다.</strong></p>
<p>다행히도 q를 t번 적용하지 않고 원본 이미지에서 $x_t$로 한 번에 갈 수 있다.
(위의 식에서 대입만 하면 도출되는 있는 식이지만 직접 전개하기에 너무 길고 복잡하기 때문에 생략)
따라서 정방향 확산 방향의 과정 q는 아래의 식과 같이 표현할 수 있다.
<img src="https://velog.velcdn.com/images/running_learning/post/80108e91-8d7d-4a44-8e5d-05ec507d73e3/image.png" alt="">
라고 가정하면
<img src="https://velog.velcdn.com/images/running_learning/post/a0260776-304e-4dc8-a3c9-74b685c0fa2a/image.png" alt="">
이 식이 만족한다.</p>
<h3 id="2-1-diffusion-schedule">2-1 Diffusion schedule</h3>
<p>이렇게 되면 $\beta$에 대해서도 궁금할 것이다. 
앞서 말한 것처럼 $\beta$는 어떠한 상수인데 이를 어떻게 정해야 하는 것일까?
이를 확산 스케줄 혹은 베타 스케줄이라고 부른다.
<strong>각 타인 스텝 t에 따라 다른 $\beta$값을 선택할 수 있다. 
$\beta$값이 t에 따라 변하는 방식을 확산 스케줄이라고 부른다</strong>.</p>
<p>다양한 확산 스케줄이 있다. 아래의 그림에서처럼 linear, sigmoid, quadratic 한 스케줄링뿐만 아니라 cosine(+offset cosine) 스케줄링까지 사용하여 t번의 확산을 하게 된다.
<img src="https://velog.velcdn.com/images/running_learning/post/a984c67c-49e6-4b0b-b37a-afdc28d4929b/image.png" alt=""></p>
<p>위의 그림에서 알 수 있듯이 각 스케줄링에 따라 잡음의 추가 과정에서 얼마나 바뀌는지 알 수 있다.</p>
<p>논문에서는 선형적인 스케줄링 방법을 사용했으나(0.0001 ~ 0.02 범위에서 선형적으로 증가) 시그모이드나 코사인 스케줄링을 사용하면 보다 $\beta$값이 느리게 상승하게 되므로 더욱 점진적인 노이즈 추가가 가능해진다.
이는 훈련의 효율성과 생성 품질을 향상하는 역할을 한다.</p>
<h1 id="3역방향-확산-과정reverse-process">3.역방향 확산 과정(reverse process)</h1>
<p>정방향 확산 과정을 통해 우리는 원본 이미지에 잡음을 점진적으로 추가했다.
정방향 확산 과정에서는 학습할 파라미터가 없다. 실제로 베타 스케줄링은 학습 파라미터가 아니다.</p>
<p><strong>반면 역방향 확산 과정에서는 정방향 확산 과정을 되돌릴 수 있는 신경망을 구축한다.</strong>
$q(x_{t-1}|x_t)$의 분포를 근사화하는 신경망을 구축하는 것이다.
이 신경망은 랜덤한 잡음(가우시안 노이즈)을 샘플링하고 역방향 확산 과정을 &#39;여러 번&#39; 적용하여 새로운 이미지를 생성하게 한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/b181fc25-21d5-4616-b22b-3527bf5ac2bd/image.png" alt=""></p>
<p>역방향 확산 신경망은 어떠한 타임 스텝 t에서 원본 이미지 $x_0$로부터 추가된 잡음 $\epsilon$을 예측한다.
(t 시점의 이미지는 원본 이미지에 얼만큼의 잡음이 추가되어 있는 가를 예측)</p>
<p><strong>해당 신경망의 학습을 위해서는 원본 이미지에 정방향 확산을 적용시켜 $x_t$의 이미지와 잡음 비율 $\beta$를 신경망에 전달하여 $\epsilon$을 예측하게 되는 것이다.
따라서 loss는 예측한  $\epsilon$와 실제  $\epsilon$의 오차와 관련된 loss function을 쓰면 된다.
여기서는 제곱 오차를 사용했다.</strong></p>
<p>$$loss =  \epsilon^2(실제 노이즈) - \epsilon_\theta^2(예측 노이즈)$$</p>
<p>또한 잡음 제거 모델로 Unet을 사용했다.
Unet의 구조는 다음과 같다.
(조금 더 자세한 Unet 구조 설명은 논문 리뷰를 통해 하겠다.)</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/737425ff-33c9-4936-a243-25b3e3b36403/image.png" alt=""></p>
<p>Unet은 $x_t$의 분산과 이미지를 입력으로 받아 같은 해상도(size)의 $\epsilon$을 출력한다.</p>
<h3 id="3-1-모델에서-샘플링하기">3-1 모델에서 샘플링하기</h3>
<p>Unet이 학습을 잘해서 입력에 대한 $\epsilon$을 잘 예측하면 우리는 비로소 훈련 이미지 세트로부터 이미지를 샘플링할 수 있다.</p>
<p>먼저 모델이 예측한 $\epsilon$를 사용하여 $x_0$를 추정한다. 
그 후 추정한 $x_0$에서 $\epsilon$를 t-1까지만 재적용하여 새로운 $x_{t-1}$을 추정한다.</p>
<p>이 과정을 반복하면 조금씩 점진적으로 $x_0$에 대한 추정치로 돌아갈 수 있다.
아래의 그림을 참고하면 이해하기 쉽다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/90fcb244-7d7b-4cb4-9686-6c64d481ed25/image.png" alt=""></p>
<p>여기서 재적용할 단계는 타임스텝 t(정방향 확산 단계에서 정함)와 같을 필요가 없다고 한다.
다만 알아둬야 하는 것은 단계가 많아질 수록 이미지 생성 품질이 높아진다는 것과 이미지 생성에 대한 시간이 선형적으로 증가한다는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/d9590f64-3b07-48ff-9fed-62687c7be5d0/image.png" alt=""></p>
<p>실제 훈련과정의 각 에폭에서 샘플링한 이미지를 보면 에폭이 증가할수록 훈련이 잘 되어 잡음(노이즈)을 잘 예측하고 이를 denoising 함으로써 보다 그럴싸한 이미지가 샘플링되는 것을 볼 수 있다.</p>
<p>이번 장에 대한 실습 코드는 깃허브에 올려 참고하면 좋을 것 같다.
<a href="https://github.com/3n952/generative_ai/blob/main/diffusion.ipynb">8장 실습 code</a></p>
<hr>
<blockquote>
<p>reference
[1]diffusion 설명 영상, http://%20https//<a href="http://www.youtube.com/watch?v=jaPPALsUZo8&amp;t=463s">www.youtube.com/watch?v=jaPPALsUZo8&amp;t=463s</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[만들면서 배우는 생성 AI] 6장 - 노멀라이징 플로 모델 (normalizing flow model)]]></title>
            <link>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-6%EC%9E%A5-%EB%85%B8%EB%A9%80%EB%9D%BC%EC%9D%B4%EC%A7%95-%ED%94%8C%EB%A1%9C-%EB%AA%A8%EB%8D%B8-normalizing-flow-model</link>
            <guid>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-6%EC%9E%A5-%EB%85%B8%EB%A9%80%EB%9D%BC%EC%9D%B4%EC%A7%95-%ED%94%8C%EB%A1%9C-%EB%AA%A8%EB%8D%B8-normalizing-flow-model</guid>
            <pubDate>Wed, 05 Jun 2024 09:07:49 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이번 포스팅에서 변수 변환을 활용하여 데이터 분포를 직접 모델링하는 노멀라이징 플로 모델에 대해 알아보자!</p>
</blockquote>
<p><strong>Normalizing flow 모델</strong>은 데이터를 간단한 분포에 매핑할 수 있다.
하지만 매핑 함수에 제약이 어느정도 있기 때문에 이를 고려할 필요가 있다.
<strong>어떠한 제약</strong>이 있는 지, 그리고 <strong>이를 해결한 모델</strong>은 어떤 것이 있는지 공부해보자.</p>
<h1 id="1-normalizing-flow">1. Normalizing flow</h1>
<p>노멀라이징 플로는 VAE와 개념이 유사하다.
VAE가 인코더를 학습하여 복잡한 분포와 샘플링이 가능한 간단한 분포 사이를 매핑하고 디코더를 학습하여 단순한 분포에서 복잡한 분포로 매핑하는 것과 같이,
노멀라이징 플로도 마찬가지로 간단한 분포로의 매핑과 복잡한 분포로의 매핑이 이뤄진다.</p>
<p>하지만 신경망은 일반적으로 반전 가능하지 않다.
따라서 노멀라이징 플로 모델은 딥러닝 모델로 복잡한 분포와 단순한 분포를 서로 반전 가능하도록 하는 과정을 만든다.
이 과정을 <strong>변수 변환(change of variables)</strong>이라고 한다.</p>
<p>간단한 2차원 예제로 변수 변환의 개념을 이해해 보자.
2차원 위에 정의된 확률 분포 Px(x)가 있다고 가정하자.
<img src="https://velog.velcdn.com/images/running_learning/post/1bac32f1-4004-4ed3-8ee1-f053a087d468/image.png" alt=""></p>
<p>이 함수를 분포의 영역으로 적분하면 1이 되어 잘 정의된 확률 분포가 된다.
(x1 = [1, 4], x2 =[0, 2])</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/78c64b51-b854-4068-b57f-d179e58fd3eb/image.png" alt=""></p>
<p>이 분포에 scaling + translation을 적용하여 단위 정사각형 Z에 대해 정의한다고 하면, 
x = (x1, x2) 는 새로운 변수 z = (z1, z2)에 매핑되어야 한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/071d9af4-789f-4eb6-94a9-3c36812740a3/image.png" alt=""></p>
<p>이 함수를 분포의 영역으로 적분하면 1이 되어 잘 정의된 확률 분포가 된다.
(x1 = [1, 4], x2 =[0, 2])</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/5f2cfcd2-23cc-447e-af67-8aaeeeb8b441/image.png" alt=""></p>
<p>이 분포에 scaling + translation을 적용하여 단위 정사각형 Z에 대해 정의한다고 하면, x = (x1, x2)는 새로운 변수 z = (z1, z2)에 매핑되어야 한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/21bcb254-8722-4f54-8542-032dc86632db/image.png" alt=""></p>
<p>이 매핑 함수가 다음과 같다면 모든 z를 이에 해당하는 x로 다시 매핑할 수 있는 함수 g가 존재한다.
이를 통해 두 확률 분포 사이의 공간을 일관되게 매핑할 수 있게 된다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/2f35665b-7c5f-4c13-a221-c2e253c960a7/image.png" alt=""></p>
<p>*<em>이러한 변수 변환이 확률 분포 px(x)에 얼마나 영향을 미치는 지 알아야 한다.
*</em> g에 대한 방정식을 Px(x)에 대입하여 z로 정의되는 함수 Pz(z)로 변환하면 이를 알 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/cad34657-9387-4084-a71e-d38a23a29681/image.png" alt=""></p>
<p>이 식을 단위 면적에 대해 적분하면 1/6이 되므로 유효한 확률 분포라고 볼 수 없게 된다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/327a06ad-1e3b-4a85-8023-0b80626ab691/image.png" alt=""></p>
<p>따라서 새로운 확률 분포 pz(z)에 대한 상대적인 면적 변화에 해당하는 정규화 계수가 곱해져야 적분 결과를 1로 만들 수 있을 것이다.
정규화 계수는 다행이도 야코비 행렬식의 절댓값으로 대체된다고 한다.</p>
<p><strong>이제서야 이 두가지를 가지고 변수 변환 과정을 하나의 방정식으로 표현할 수 있다.</strong></p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/42d5696b-eda8-4b3e-9d61-9409169acdd9/image.png" alt=""></p>
<p>|det()|의 식이 야코비 행렬에 대한 값(정규화 계수의 역할)이다.
<strong>결과적으로 노멀라이징 플로 모델은 변수 변환 함수 f가 반전 가능하며, 행렬식을 쉽게 계산할 수 있는 신경망을 활용해야 변수 변환 방정식을 적용할 수 있다는 것이다.</strong></p>
<h1 id="2-realnvp">2. RealNVP</h1>
<p>노멀라이징 플로 모델로 복잡한 데이터 분포를 간단한 가우스 분포로 변환하는 신경망의 모델이다.
즉, 역변환이 가능하고 야코비 행렬을 쉽게 계산하게 했다는 것이다.
RealNVP를 이해하려면 커플링 층을 이해하면 된다.</p>
<h3 id="21-coupling-layer-커플링-층">2.1 coupling layer 커플링 층</h3>
<p>커플링 층은 입력의 각 원소에 대해서 스케일 계수와 이동 계수를 만든다.
<img src="https://velog.velcdn.com/images/running_learning/post/4ad94a61-1b0d-429b-89c2-11b85f395598/image.png" alt=""></p>
<p>데이터가 커플링 층에 전달 될 때 마스킹 되는 방식은 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/fc6aa4e2-9be5-4eef-b4a6-9b49a19395e7/image.png" alt=""></p>
<p>처음 d차원이 처음 커플링 층에 주입되면 남은 D-d차원은 마스킹이 된다.
즉 s, t에 대한 값이 마스킹 후보가 되는 것이다.
그 다음 입력의 나머지 절반인 D-d가 역 마스킹되어 처음 d차원이 마스킹 되어 커플링 층을 통과한다.
<strong>이렇게 하는 이유는 야코비 행렬 구조를 하삼각 행렬로 만들어 내기 위함</strong>이다.
<img src="https://velog.velcdn.com/images/running_learning/post/40c8063b-1a5b-4e94-8a68-127bdaf57211/image.png" alt=""></p>
<p>커플링 층에 대한 야코비 행렬 구조는 위의 행렬과 같다.
이를 표현하면 다음과 같다.
<img src="https://velog.velcdn.com/images/running_learning/post/ef3053c0-706b-4541-81a6-635d7277b22c/image.png" alt=""></p>
<p>대각선 위쪽 원소가 모두 0이 되므로 하삼각 행렬이 만들어진다.
하삼각 행렬의 행렬식은 단순히 대각 원소의 곱과 같으므로 대각 아래에 대한 복잡한 도함수와 관련이 없어 계산에 용이하다.
이런식으로 커플링층을 쌓고 마스킹을 뒤집으면 앞서 언급한 &#39;변환 함수 f가 반전 가능하며, 행렬식을 쉽게 계산할 수 있는 신경망&#39;이 완성되는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/73f8104c-2ca3-41d1-82ab-5164547106da/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[만들면서 배우는 생성 AI] 5장- 자기회귀 모델(autoregressive model)]]></title>
            <link>https://velog.io/@running_learning/5%EC%9E%A5.-%EC%9E%90%EA%B8%B0%ED%9A%8C%EA%B7%80-%EB%AA%A8%EB%8D%B8autoregressive-model</link>
            <guid>https://velog.io/@running_learning/5%EC%9E%A5.-%EC%9E%90%EA%B8%B0%ED%9A%8C%EA%B7%80-%EB%AA%A8%EB%8D%B8autoregressive-model</guid>
            <pubDate>Tue, 04 Jun 2024 09:32:56 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>자기회귀 모델은 생성 문제를 순차적인 과정으로 다뤄 단순화한다.
앞 장에서 살펴본 VAE, GAN과는 달리 잠재 확률 변수를 사용하지 않고 시퀀스에 있는 이전 값을 바탕으로 예측을 만든다.
따라서 데이터 생성 분포를 근사하는 것 보다는 명시적으로 이를 모델링 한다는 점에서 차이가 있다.
이번 포스팅에서 생성 모델링 문제를 &#39;순차적&#39;으로 다루는 자기회귀 모델에 대해 알아보자.</p>
</blockquote>
<h1 id="1-lstm">1. LSTM</h1>
<p>LSTM은 순환 신경망의 한 종류이다. 순환 신경망에는 순차적인 데이터(텍스트 데이터, 시계열 데이터 등)을 처리하는 순환 층(셀)이 있고, 특정 타임 스텝에서 셀의 출력이 다음 타임 스텝의 입력으로 사용된다.
재귀적으로 되먹이는 구조를 가지는 네트워크이기 때문에 recurrent neural netwrok, RNN으로 쓰인다.</p>
<p>처음 RNN은 장기 의존성(long-short term memory )의 문제를 가지고 있었다.
현재 타임 스텝에서 멀리 떨어진 타임 스텝에서의 셀의 출력이 현재 타임 스텝에 전혀 영향을 미치지 못하는 것을 의미한다.
그 원인은 그레이디언트 소실 문제이며, 따라서 긴 시퀀스에서는 사용하기 어렵다는 단점이 있었다.</p>
<p>이 문제를 해결하고자 나온 모델이 LSTM이다.
LSTM의 셀은 RNN의 그레이디언트 소실 문제를 해결하여 긴 타임 스텝 동안 시퀀스를 훈련시킬 수 있었다.
LSTM의 어떤 구조가 이를 가능하게 했는 지 알아보자.</p>
<h3 id="11-lstm-셀">1.1 LSTM 셀</h3>
<p>LSTM의 셀은 이전 은닉 상태  h𝘵₋₁ 와 현재의 단어 임베딩 𝑿𝘵 가 주어졌을 때 새로운 은닉 상태 h𝘵를 출력한다.
아래의 그림 5-6을 보면서 이해해보자.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/82cd54cc-cc35-493a-a20c-da194678f218/image.png" alt=""></p>
<p>하나의 LSTM 셀은 셀 상태(C𝘵)를 관리한다. 셀 상태는 현재 시퀀스의 상태에 관한 내용을 담고 있다고 보면 된다.
셀 상태 C𝘵 와 은닉 상태 h𝘵를 업데이트 하면서 LSTM의 셀이 매 시퀀스마다 작동한다.</p>
<p>그림 5-6을 보면 은닉 상태와 셀 상태의 업데이트가 어떻게 이뤄지는 지와 그 흐름에 대해 알 수 있다.
셀 상태와 은닉 상태는 다음과 같은 단계를 거쳐 업데이트 된다.</p>
<blockquote>
<ol>
<li>이전 타임 스텝의 은닉 상태 h𝘵₋₁ 는 현재 단어 임베딩 𝑿𝘵 와 연결 되어(연결된 벡터 V) 삭제 게이트로 전달(이전 셀 상태 C𝘵₋₁ 를 얼마나 유지할 지 결정)</li>
<li>벡터 V는 입력 게이트로 전달 (이전 셀 상태 C𝘵₋₁ 에 얼마나 새로운 정보를 추가할 지 결정)</li>
<li>벡터 V는 완전 연결층으로 전달 되어 벡터 ć𝘵를 생성(셀이 저장하려는 새로운 정보를 담기)</li>
<li>4번 식을 통해 C𝘵를 만드는 과정(이전 셀 상태의 일부분을 삭제하고 새로운 정보를 더해 업데이트)</li>
<li>벡터 V는 가중치 행렬 Wo, 편향 bo가 시그모이드로 넘어간다. 출력 게이트로도 넘어감</li>
<li>업데이트된 셀 상태 C𝘵가 6번 식에 의해 새로운 은닉 상태 h𝘵를 생성</li>
</ol>
</blockquote>
<h1 id="2-pixelcnn">2. PixelCNN</h1>
<p>텍스트 데이터가 아닌 이미지, 영상 데이터에서도 자기회귀 모델을 사용할 수 있다.
같은 아이디어로 이전 픽셀을 기반으로 다음 픽셀의 likelihood를 예측해 픽셀 단위로 이미지를 생성하는 모델이다.
<strong>PixelCNN</strong>이 그 모델 중 하나이다.</p>
<p>자기회귀 모델은 시퀀스 데이터가 필요하다. 하지만 이미지 데이터에는 순서가 지정되어 있지 않다.
일반적인 CNN은 모든 픽셀을 동등하게 처리하여 어떤 픽셀도 이미지의 시작이나 끝으로 판단하지 않는다.
우리가 픽셀에 순서를 정해줘야 한다.
일반적으로 픽셀의 순서는 왼쪽 위에서 오른쪽 아래로 행을 따라 이동하고 그 다음 열을 따라가는 개념이다.
순서가 지정된 픽셀을 필터가 해당 픽셀 앞부분만 보고 판단해야한다.
이를 통해 다음 픽셀의 값을 예측하면서 한번에 한 픽셀씩 이미지를 생성해내는 것이다.</p>
<p><strong>PixelCNN에서 중요한 것은 이미지를 자기회귀 방식으로 생성한다는 아이디어와 이를 효과적으로 구현하기 위해 masked convolution layer, residual block의 개념을 도입</strong>했다는 것이다. (최초로 도입한 것은 아님)</p>
<p>이를 하나씩 살펴보면서 개념을 이해해보자!</p>
<h3 id="21-masked-convolution-layer마스크드-합성곱-층">2.1 Masked convolution layer(마스크드 합성곱 층)</h3>
<p>앞서 말했듯 우리가 생성하고자 하는 현재 픽셀의 앞부분만 보고 해당 픽셀을 예측해야한다. 이렇게 하기 위해서 필요한게 masked convolution layer이다. 필터를 마스킹하여(conv연산을 할 때) 이를 구현한다.
이렇게 하면 1과 0으로 구성된 mask에 필터 가중치 행렬을 곱하여 현재 픽셀 뒤에 있는 모든 픽셀의 값이 0이 된다.</p>
<p>각 픽셀의 층 출력이 해당 픽셀 앞에 있는 픽셀 값에서 추론되어야하기 때문에 중앙 픽셀이 마스킹 된 mask A와, 중앙 픽셀이 마스킹되어 있지 않은 mask B가 있다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/f8eb4910-b66e-4356-b50b-81d0280744fb/image.png" alt=""></p>
<p><strong>두 종류의 마스크가 있는 이유</strong>는 초기 masked conv layer에서는 중앙 픽셀이 신경망이 예측해야 할 픽셀 값이기 때문이고, 후속 masked conv layer에서 예측된 중앙 픽셀 값을 바탕으로 그 다음 픽셀이 예측되어야 하기 때문이다.</p>
<h3 id="22-residual-block-잔차-블록">2.2 Residual block (잔차 블록)</h3>
<p>잔차 블록은 신경망의 나머지 부분에 출력이 전달되기 전의 입력과 더해지는 층의 블록을 의미한다.
이를 skip connection이라고 하는데, 간단히 표현하면 y = x + f(x)와 같은 꼴이다.(x가 입력, f(x)가 층의 출력)
잔차 블록 층은 gradient vanishing 문제를 해결하여 원활한 모델의 학습을 도와 일반화의 성능을 높인다.</p>
<p><strong>PixelCNN에서 residual block은 다음과 같다.</strong>
conv + masked conv + conv를 통과한 layer의 출력을 layer의 입력과 더한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/3486fb62-ec21-44d8-9312-54052ed27fb5/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ROS2] 개념 및 용어 정리]]></title>
            <link>https://velog.io/@running_learning/ROS2-%EA%B0%9C%EB%85%90-%EB%B0%8F-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@running_learning/ROS2-%EA%B0%9C%EB%85%90-%EB%B0%8F-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 29 May 2024 10:33:41 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>ROS 2에서 robotic system을 구현하는 데 필요한 몇 가지의 개념이 있다.
ROS 2 tutorial에서 공부한 내용을 바탕으로 정리해 보자!</p>
</blockquote>
<h1 id="1-node노드">1. Node(노드)</h1>
<p>ROS graph는 ROS 2에서의 모든 데이터를 동시에 처리하는 네트워크를 일컫는다.
ROS graph에서 실행가능한 모든 파일은 연결되어야 하고, 이를 매핑하고 시각화할 줄도 알아야 한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/aef22fb2-a842-4bba-aa46-29367fc72368/image.png" alt=""></p>
<p>위의 영상을 보면 전반적인 ROS system의 흐름을 보여준다. (ROS graph)
이는 Node와 Node들 사이에 데이터가 오가면서 이뤄진다.</p>
<p>여기서 Node는 로봇의 바퀴를 제어한다던지 측정 데이터를 publishing 한다던지와 같은 single, modular의 목적을 가지고 있어야 한다.
각각의 Node는 topic, service, action, parameter를 통해 다른 노드와 데이터를 주거나 받을 수 있다.
따라서 Node는 데이터의 내용을 수행하는 한 단위의 프로세서라고 이해했다. 즉, ROS2가 동작하는 하나의 단위.
(ex. node가 2개 있다면 node 1은 카메라 센서로 이미지 받기 node 2는 로봇 바퀴 제어하기)</p>
<p>추가적으로 ROS 2에서 Node는 c++, python과 같은 executable이 하나 이상 포함되어 있다고 한다.
결국 ROS에서는 Node들 사이에 주고받는 데이터가 서로 다른 특징을 가지고 다른 노드로 오가게 되는데
여기서 &#39;서로 다른 특징을 가지는 방식&#39;이 <strong>Topic, service, parameter, action</strong>이 된다.</p>
<h1 id="2-topic토픽">2. Topic(토픽)</h1>
<p>ROS 2는 복잡한 system을 여러 modular nodes로 나눈다.
node 간의 message 교환을 위해 bus 역할을 하는 topic이 필요하다.</p>
<p>topic은 publisher - subscriber model로 구성되어 있다.
Publisher는 데이터를 발생 (Publish)하는 노드이다.
Subscriber는 Publisher가 Topic에 쓴 Message를 받거나 읽는 노드이다.</p>
<p><strong>이 두 노드 사이의 비동기식 단방향 메세지 통신을 topic</strong>이라고 한다.
지속적으로 센서 데이터를 생성해 내고 이를 받아 처리하는 경우에 적합한 형태이다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/e2cd1ef4-a4e6-47b2-a726-35a43c2c9545/image.png" alt=""></p>
<p>노드가 여러 데이터를 pub 할 수도 있고 동시에 topic을 sub 할 수도 있다.
이때 topic은 point-to-point일 필요는 없다. 
1:1, 1:다, 다:다 모든 경우가 가능하다고 한다</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/d669c3dc-3be0-4ae0-ae53-9e2d0fb63150/image.png" alt=""></p>
<h1 id="3-service서비스">3. Service(서비스)</h1>
<p><img src="https://velog.velcdn.com/images/running_learning/post/83ace9ea-8134-4c3c-82e6-57322b7087af/image.png" alt=""></p>
<p><strong>service는 server와 client사이에서 Request와 Respond가 호출되는 동기식 양방향 메세지 통신 방법이다.</strong>
서비스는 토픽과 달리 특별한 상황에서 호출할 때만 데이터가 통신된다.
즉, 특정 목적의 작업에 해당되는 서비스를 일회성으로 요청하는 것이다.</p>
<h1 id="4-action액션">4. Action(액션)</h1>
<p><strong>Action은 서버와 클라이언트 간의 비동기식 양방향 메세지 통신이다.</strong>
요청 후에 응답까지 오랜 시간이 걸리고 중간 결과 값이 필요할 때 사용하는 장기적인 실행 작업이다.
또한 service와 topic을 기반으로 구축되는데, 이때 goal service, feedback topic, result service의 세 부분으로 이뤄진다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/3a431222-bc3a-4c84-8743-78e4b03ae970/image.png" alt=""></p>
<h1 id="5-parameter파라미터">5. Parameter(파라미터)</h1>
<p>node의 구성하는 값이다. 즉 노드에서 사용하는 파라미터를 의미한다.
매개변수를 노드 설정이라고 판단할 수 있다.
노드는 매개변수를 정수, 부동 소수점, boolean, 문자열 등등으로 저장할 수 있다고 한다.
이는 파라미터 서버에서 관리하고 프로그램이 동작하는 도중에 실시간으로 변경 가능하다.
(ex. 모터가 돌아가는 최대 최소 속도의 값 파라미터)</p>
<hr>
<blockquote>
<p>reference
[1] ros2 tutorial, <a href="https://docs.ros.org/en/foxy/Tutorials.html">https://docs.ros.org/en/foxy/Tutorials.html</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[만들면서 배우는 생성 AI] 4장 - 생성적 적대 신경망(GAN) ]]></title>
            <link>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-4%EC%9E%A5-%EC%83%9D%EC%84%B1%EC%A0%81-%EC%A0%81%EB%8C%80-%EC%8B%A0%EA%B2%BD%EB%A7%9DGAN</link>
            <guid>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-4%EC%9E%A5-%EC%83%9D%EC%84%B1%EC%A0%81-%EC%A0%81%EB%8C%80-%EC%8B%A0%EA%B2%BD%EB%A7%9DGAN</guid>
            <pubDate>Wed, 29 May 2024 09:26:06 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>4장의 Generative adversarial network에 대하여 학습해 보자.
GAN의 어떠한 구조적 특징을 가지고 있는지, 이에 대한 문제점은 무엇이 있는지 파악한 다음,이를 와서스테인 GAN과 WGAN이 어떻게 해결하고자 하는지 알아보자!</p>
</blockquote>
<h1 id="1-gan의-두-네트워크-구조">1. GAN의 두 네트워크 구조</h1>
<p>GAN은 General Adversarial Network의 약자로 생성적 적대 신경망이라고 부른다. 이를 해석해 보면 &quot;적대적인 두 신경망으로 결과를 생성한다.&quot;라고 볼 수 있다.</p>
<p>어떤 아이디어가 이를 가능하게 할까?
이를 이해하기 위해서는 우선 GAN의 구조에 대해 알 필요가 있다.</p>
<p>GAN은 생성자(generator)와 판별자(discriminator)가 서로를 이기려고 하는 과정을 통해 의미 있는 샘플을 생성하는 것이다.(서로 적대적 관계라고 생각하면 된다.)</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/22f28813-cc62-47b6-96d4-4dde1c11cf3e/image.png" alt=""></p>
<p>간략하게 표현하면 그림 4-2와 같은 구조를 가지고 있다.</p>
<p>생성자는 랜덤함 잡음으로부터 원래 데이터셋에서 샘플링한 것과 같은 샘플을 추출하는 것에 관심이 있고, 판별자는 원래 데이터 셋에서 샘플링한 것인지 생성자가 만든 위조품인지 예측하는 것에 관심이 있다.</p>
<p>따라서 생성자는 최대한 &#39;진짜&#39;(원래 데이터셋에서 샘플링한 것) 같은 샘플을 만들어야 하고,판별자는 생성자가 만든 이미지가 진짜인지 아닌지 잘 파악해야 한다.</p>
<p>이러한 과정에서 생성자는 더 &#39;진짜&#39;같은 샘플을 만들어 낼 것이고 판별자는 더 &#39;진짜&#39;같아진 이미지를 더 잘 구분한다. 이 과정이 반복되면서 결국 생성자가 더 더 &#39;진짜&#39;같은 샘플을 만들어내게 하는 것이 GAN의 목표이다.</p>
<h1 id="2-dcgan심층-합성곱-gan">2. DCGAN(심층 합성곱 GAN)</h1>
<p>위의 구조를 차용하여 심층 합성곱 GAN이 등장했다.
이를 통해 보다 사실적인 이미지를 생성하는 것에 성공했다.(그 당시에..)</p>
<p>앞서 언급한 것과 같이 DCGAN은 생성자 network와 판별자 network가 필요하다.
생성자는 Autoencoder의 decoder부분과 같은 역할을 한다.
반면 판별자는 image classification의 역할을 수행한다.
따라서 생성자는 Transposed conv 연산을 수행하여 원본과 같은 크기의 결과를 출력할 것이고, 판별자는 conv 연산을 통해 feature map을 1*1 크기로 조정하고 이를 Flatten 하여 0~1 사이의 결과를 출력하게 된다.</p>
<p>코드 예시는 다음과 같다.</p>
<pre><code class="language-python">#discriminator - 판별자 역할 block : image classification과 동일

discriminator_input = layers.Input(shape=(IMAGE_SIZE, IMAGE_SIZE, CHANNELS))
x = layers.Conv2D(64, kernel_size=4, strides=2, padding=&quot;same&quot;, use_bias=False)(
    discriminator_input
)
x = layers.LeakyReLU(0.2)(x)
x = layers.Dropout(0.3)(x)
x = layers.Conv2D(
    128, kernel_size=4, strides=2, padding=&quot;same&quot;, use_bias=False
)(x)
x = layers.BatchNormalization(momentum=0.9)(x)
x = layers.LeakyReLU(0.2)(x)
x = layers.Dropout(0.3)(x)
x = layers.Conv2D(
    256, kernel_size=4, strides=2, padding=&quot;same&quot;, use_bias=False
)(x)
x = layers.BatchNormalization(momentum=0.9)(x)
x = layers.LeakyReLU(0.2)(x)
x = layers.Dropout(0.3)(x)
x = layers.Conv2D(
    512, kernel_size=4, strides=2, padding=&quot;same&quot;, use_bias=False
)(x)
x = layers.BatchNormalization(momentum=0.9)(x)
x = layers.LeakyReLU(0.2)(x)
x = layers.Dropout(0.3)(x)
x = layers.Conv2D(
    1,
    kernel_size=4,
    strides=1,
    padding=&quot;valid&quot;,
    use_bias=False,
    activation=&quot;sigmoid&quot;,
)(x)
discriminator_output = layers.Flatten()(x)

discriminator = models.Model(discriminator_input, discriminator_output)
discriminator.summary()</code></pre>
<pre><code class="language-python"># Generator - 생성자 역할 block : VAE decoder부분과 동일

generator_input = layers.Input(shape=(Z_DIM,))
x = layers.Reshape((1, 1, Z_DIM))(generator_input)
x = layers.Conv2DTranspose(
    512, kernel_size=4, strides=1, padding=&quot;valid&quot;, use_bias=False
)(x)
x = layers.BatchNormalization(momentum=0.9)(x)
x = layers.LeakyReLU(0.2)(x)
x = layers.Conv2DTranspose(
    256, kernel_size=4, strides=2, padding=&quot;same&quot;, use_bias=False
)(x)
x = layers.BatchNormalization(momentum=0.9)(x)
x = layers.LeakyReLU(0.2)(x)
x = layers.Conv2DTranspose(
    128, kernel_size=4, strides=2, padding=&quot;same&quot;, use_bias=False
)(x)
x = layers.BatchNormalization(momentum=0.9)(x)
x = layers.LeakyReLU(0.2)(x)
x = layers.Conv2DTranspose(
    64, kernel_size=4, strides=2, padding=&quot;same&quot;, use_bias=False
)(x)
x = layers.BatchNormalization(momentum=0.9)(x)
x = layers.LeakyReLU(0.2)(x)
generator_output = layers.Conv2DTranspose(
    CHANNELS,
    kernel_size=4,
    strides=2,
    padding=&quot;same&quot;,
    use_bias=False,
    activation=&quot;tanh&quot;,
)(x)
generator = models.Model(generator_input, generator_output)
generator.summary()</code></pre>
<h3 id="2-1-dcgan의-훈련-과정">2-1. DCGAN의 훈련 과정</h3>
<p>GAN은 두 가지 네트워크의 구조뿐만 아니라 서로 다른 네트워크가 어떻게 학습하는지 훈련 과정을 아는 것이 핵심이다.
판별자가 진짜라고 생각하도록 하는 생성자의 샘플링이 필요하다.
이를 위해서는 다음과 같은 훈련 과정이 이뤄진다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/ac07427d-4250-44d6-8a5d-0c6c3c29d11b/image.png" alt=""></p>
<p>우선 판별자는 진짜 샘플을 구분해야 하므로 훈련 세트의 샘플과 생성자의 출력을 합쳐서 훈련 세트를 통해 학습이 이뤄진다.</p>
<p>image classification과 같이 &#39;진짜&#39;의 샘플은 1, &#39;가짜 &#39; 샘플은 0으로 라벨링이 되어 지도 학습으로 훈련이 된다.
반면 생성자는 판별자가 수행한 작업(생성된 이미지에 점수를 부여하고 높은 점수를 낸 이미지로 최적화하는 것)이 필요한 데, 학습 과정 중에 생성자 자신이 만든 &#39;가짜&#39;이미지를 판별자에 전달하여 그 샘플에 대한 점수를 얻는다. 진짜 샘플로 만드는 게 목표이므로 1로 라벨링이 된다. </p>
<p>두 네트워크의 경우 손실 함수로 이진 크로스 엔트로피를 사용한다.
<strong>여기서 중요한 점은 한 번에 두 네트워크의 가중치가 업데이트되는 것이 아니라, 두 네트워크가 번갈아 업데이트되는 것이 중요하다.</strong>
예를 들어 생성자 네트워크를 훈련할 때 판별자 네트워크도 훈련이 된다면, 판별자가 생성자가 대충 만들어도 &#39;진짜&#39;라고 판단하도록 조정되기 때문이다.
우리의 목표는 &#39;진짜&#39; 같은 샘플링을 하는 생성자를 만드는 것이지 &#39;가짜&#39;같은 샘플을 &#39;진짜&#39;라고 판단하는 판별자가 아니다.</p>
<p>train step을 통해 훈련 루프를 구현해 보면 더욱 직관적으로 파악할 수 있다.</p>
<pre><code class="language-python">def train_step(self, real_images):
        # 잠재 공간에서 랜덤 포인트 샘플링
        batch_size = tf.shape(real_images)[0]
        random_latent_vectors = tf.random.normal(
            shape=(batch_size, self.latent_dim)
        )

        # 가짜 이미지로 판별자 훈련하기
        with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
            # 여기서부터 
            generated_images = self.generator(
                random_latent_vectors, training=True
            )
            real_predictions = self.discriminator(real_images, training=True)
            fake_predictions = self.discriminator(
                generated_images, training=True
            )

            real_labels = tf.ones_like(real_predictions)
            real_noisy_labels = real_labels + NOISE_PARAM * tf.random.uniform(
                tf.shape(real_predictions)
            )
            fake_labels = tf.zeros_like(fake_predictions)
            fake_noisy_labels = fake_labels - NOISE_PARAM * tf.random.uniform(
                tf.shape(fake_predictions)
            )

            d_real_loss = self.loss_fn(real_noisy_labels, real_predictions)
            d_fake_loss = self.loss_fn(fake_noisy_labels, fake_predictions)
            d_loss = (d_real_loss + d_fake_loss) / 2.0

            g_loss = self.loss_fn(real_labels, fake_predictions)
            # 여기까지

        gradients_of_discriminator = disc_tape.gradient(
            d_loss, self.discriminator.trainable_variables
        )
        gradients_of_generator = gen_tape.gradient(
            g_loss, self.generator.trainable_variables
        )

        self.d_optimizer.apply_gradients(
            zip(gradients_of_discriminator, discriminator.trainable_variables)
        )
        self.g_optimizer.apply_gradients(
            zip(gradients_of_generator, generator.trainable_variables)
        )

        # 메트릭 업데이트
        self.d_loss_metric.update_state(d_loss)
        self.d_real_acc_metric.update_state(real_labels, real_predictions)
        self.d_fake_acc_metric.update_state(fake_labels, fake_predictions)
        self.d_acc_metric.update_state(
            [real_labels, fake_labels], [real_predictions, fake_predictions]
        )
        self.g_loss_metric.update_state(g_loss)
        self.g_acc_metric.update_state(real_labels, fake_predictions)

        return {m.name: m.result() for m in self.metrics}</code></pre>
<p>그럼에도 불구하고 DCGAN은 <strong>한계</strong>가 명확하다.</p>
<p><strong>1. 훈련의 어려움</strong>
&#39;판별자가 생성자보다 훨씬 뛰어난 경우 / 생성자가 판별자보다 훨씬 뛰어난 경우&#39; 모두 각 손실 함수의 그레이디언트가 0에 수렴하여 전혀 훈련되지 않는 문제가 생긴다.</p>
<p><strong>2. 손실 함수의 낮은 유용성</strong>
DCGAN은 생성자의 손실이 작을수록 생성된 이미지의 품질이 더 좋을 것이라고 생각된다.
하지만 생성자는 판별자에 의해서만 평가되고 판별자는 계속 향상되기 때문에 생성자의 손실과 이미지 품질 사이의 연관성이 부족하고,
이는 훈련 과정을 모니터링하는 데 어렵게 한다.
실제로 에폭이 증가함에 따라 이미지 품질이 좋아지지만 생성자 손실은 증가하는 모습을 보인다.</p>
<p><strong>3. 다양한 하이퍼파라미터</strong> 
간단한 GAN도 튜닝해야 할 하이퍼파라미터가 상당히 많다.
구조의 크기, 배치 정규화, 드롭아웃, 잠재 공간 크기 등의 하이퍼파라미터를 고려해야 한다.
작은 하이퍼파라미터의 변화에도 민감하기 때문에 모델의 안정성을 높이고 민감한 하이퍼파라미터를 조정할 수 있어야 한다.</p>
<h1 id="3--wasserstein-gan-with-gradient-penalty---gan의-한계손실-함수이-낮은-유용성-해결법-제시">3.  Wasserstein GAN with gradient penalty - GAN의 한계(손실 함수이 낮은 유용성) 해결법 제시</h1>
<p>안정적인 GAN의 훈련을 위해 다음 두 가지 속성을 고려한 GAN의 훈련법을 고안했다.</p>
<ol>
<li>생성자가 수렴하는 것과 샘플의 품질을 연관 짓는 의미 있는 손실 측정 방법</li>
<li>최적화 과정의 안정성 향상</li>
</ol>
<p>이진 크로스 엔트로피 대신 Wasserstein loss를 사용하면 더욱 안정적인 손실 함수의 수렴이 가능하다고 한다.
어떻게 이게 가능한지 알아보자.</p>
<h3 id="3-1-wasserstein와서스테인-loss란">3-1 Wasserstein(와서스테인) loss란?</h3>
<p>와서스테인 손실함수는 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/105efa55-dbcb-4afc-b7e5-af12cab95b87/image.png" alt=""></p>
<p>이것이 원래의 이진 크로스 엔트로피와 비교하여 어떠한 점이 GAN 학습의 안정적인 수렴을 도와주는지 알아보자.
이진 크로스 엔트로피 손실함수는 식 4-1과 같다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/2bdf85a8-1a9c-4a0f-bd4e-f425f6b06e05/image.png" alt=""></p>
<p>GAN의 판별자를 훈련하기 위해 진짜 이미지에 대한 예측 𝛲ᵢ = 𝐷(𝑥ᵢ)와 𝑦ᵢ = 1을 비교하고, 생성된 이미지에 대한 예측 𝛲ᵢ = 𝐷(G(zᵢ))와 𝑦ᵢ = 0을 비교하여 손실을 계산한다.
따라서 이를 최소화 하는 식은 식 4-2와 같이 나타낼 수 있다.
<img src="https://velog.velcdn.com/images/running_learning/post/b3d2b096-81ad-446e-85e5-2c54115cf070/image.png" alt=""></p>
<p>이에 따라 판별자 손실을 최소화하기 위해서는 𝐸x<del>px[logD(x)] + 𝐸z</del>pz[log(1 - D(G(z)))]가 최대가 되어야 한다.</p>
<p>각 항을 살펴보면, 𝐸x~px[logD(x)] 는 판별자가 실제 데이터 x를 실제로 판단한 확률의 로그 스케일에 대한 확률 가중 평균을 의미한다.</p>
<p>𝐸z~pz[log(1 - D(G(z)))]는 생성자가 만들어낸 가짜 데이터 G(z)를 가짜라고 판단한 확률의 로그스케일에 대한 확률 가중 평균을 의미한다. 이는 진짜는 진짜로, 가짜는 가짜로 판단하도록 판별자를 학습시키는 요인이 된다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/4a450d3c-f904-4554-8421-153d8a0c290f/image.png" alt=""></p>
<p>반면 생성자를 훈련하기 위해 생성된 이미지에 대한 예측 𝛲ᵢ = 𝐷(G(zᵢ))와 𝑦ᵢ = 1을 비교하여 손실을 계산한다.
이에 따라 생성자 손실을 최소화하기 위해서는 𝐸z~pz[log(D(G(z)))] 가 최대가 되어야 한다.
즉, 판별자 모델이 가짜 데이터 G(z)를 실제 데이터로 오인할 확률을 최대화하는데 중점을 둔다.
이는 판별자가 생성된 가짜 데이터를 얼마나 실제 데이터와 유사하다고 판단하는지를 측정하게 한다.</p>
<p>다시 와서스테인 손실로 돌아오자.
우선 와서스테인 손실은 타깃값을 1과 0 대신 타겟값으로 𝑦ᵢ =1, 𝑦ᵢ ​=−1을 사용한다.
또한 판별자의 마지막 층에서 시그모이드 활성화 함수를 제거하여 
[0,1] 범위의 출력을 [-∞, ∞]의 범위로 늘린다.
확률이 아닌 점수의 개념을 반환한다.</p>
<p><strong>따라서 와서스테인 손실 함수에 따라
판별자는 진짜 이미지에 대한 예측 𝛲ᵢ = 𝐷(𝑥ᵢ)와 𝑦ᵢ = 1을 비교하고
생성된 이미지에 대한 예측 𝛲ᵢ = 𝐷(G(zᵢ))와 𝑦ᵢ = -1을 비교하지만,
생성자는 진짜 이미지에 대한 예측 𝛲ᵢ = 𝐷(𝑥ᵢ)와 𝑦ᵢ = 1을 비교하여 손실을 계산한다는 점에서 BCE와 차이가 생긴다.</strong></p>
<p>판별자, 생성자 함수의 최소화는 다음과 정의된다.</p>
<p>&lt;판별자 최소화&gt;
<img src="https://velog.velcdn.com/images/running_learning/post/e70cad3b-d231-491b-955a-f88cb4bdbd3b/image.png" alt="">
&lt;생성자 최소화&gt;
<img src="https://velog.velcdn.com/images/running_learning/post/c54ae775-11f1-4ff7-8fee-ee7d7d315a58/image.png" alt=""></p>
<p>이는 판별자는 진짜 이미지와 생성된 이미지에 대한 예측 사이의 차이를 최대화하는 것에 관심이 있으며,</p>
<p>생성자는 판별자로부터 가능한 한 높은 점수를 받는 이미지를 생성하는 것에 관심이 있게 된다.</p>
<h3 id="3-2-립시츠-제약">3-2 립시츠 제약</h3>
<p>판별자의 마지막 층에 시그모이드 활성 함수를 사용하여 [0,1]의 출력 범위를 가지지 않고 이를 없애 [-∞, ∞]의 출력 범위를 갖게 하는 이유는 뭘까?</p>
<p>일반적으로 신경망에서 손실 함수 및 가중치가 큰 값을 가지는 것은 파라미터 업데이트에 문제가 된다.
따라서 이 큰 값의 출력 범위를 어느 정도 제한해줘야 한다.
제한에 앞서 판별자는 1-립시츠 연속 함수를 따라야 한다고 한다.</p>
<p>하나의 이미지를 하나의 예측으로 변환하는 함수가 D라고 했을 때,
임의의 두 입력 이미지 x1, x2에 대해 다음 부등식을 만족할 때 이 함수를 1-립시츠라고 한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/6ab44bc2-8708-4bb6-a42a-305a47fde2d4/image.png" alt=""></p>
<p>분모의 값은 두 이미지 픽셀의 평균적인 절댓값 차이를 의미하고
분자의 값은 판별자 예측 간의 절댓값 차이를 의미한다.
이미지 사이의 판별자의 예측이 변화하는 비율이 1이어야 함을 의미한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/35fda5ac-d71d-4f72-a586-6a881fc34889/image.png" alt=""></p>
<h3 id="3-3-그레이디언트-페널티-손실">3-3 그레이디언트 페널티 손실</h3>
<p>그레이디언트 노름이 1에서 벗어날 경우 모델에 불이익을 주는 그레이디언트 페널티항을 판별자 손실 함수에 포함시켜 립시츠 제약 조건을 직접 강제하게 했다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/0f0c0aa6-5696-4022-b8f8-a520d8188659/image.png" alt=""></p>
<p>그림 4-12를 보면 진짜 이미지와 가짜 이미지에 대한 와서스테인 손실과 더불어 그레이디언트 페널티 손실이 추가되어 전체의 손실 함수를 구성하는 것을 볼 수 있다.
여기서 그레이디언트 패널티 손실은 입력 이미지에 대한 예측의 그레이디언트 노름과 1 사이의 차이를 제곱한 것이라고 한다.</p>
<h1 id="4--cgan---conditional-gan">4.  CGAN - conditional GAN</h1>
<p>기존의 GAN과 달리 출력을 제어할 수 있는 CGAN에 대해 알아보자.
<img src="https://velog.velcdn.com/images/running_learning/post/1f9fd7ec-afd7-4c6b-a254-b024e2722913/image.png" alt=""></p>
<p>표준 GAN과 CGAN의 주요한 차이점은 CGAN에서 레이블과 관련된 추가 정보를 생성자와 판별자에게 전달한다는 것이다.
생성자에서는 이 정보를 원핫 인코딩 된 벡터로 잠재 공간 샘플에 단순히 추가하고,판별자에서는 레이블 정보를 RGB 이미지에 추가 채널로 추가한다.</p>
<p>그렇다면 CGAN의 출력 제어는 어떻게 동작할까?
특정 원핫 인코딩된 레이블을 생성자의 입력에 전달하면 된다.
예를 들어 금발의 얼굴은 [0,1], 금발이 아닌 얼굴은 [1,0]에 벡터를 전달하면 된다.
이는 GAN이 개별 특성이 서로 분리되도록 잠재공간의 포인트를 구성할 수 있다는 증거가 된다.</p>
<p>아래의 그림 4-17을 보면 이해하기 쉽다.
<img src="https://velog.velcdn.com/images/running_learning/post/4c1907ee-15e5-43b9-9fc2-0f9846482b38/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Paper Review] YOLACT: Real-time Instance Segmentation]]></title>
            <link>https://velog.io/@running_learning/Paper-Review-YOLACT-Real-time-Instance-Segmentation-97dto17e</link>
            <guid>https://velog.io/@running_learning/Paper-Review-YOLACT-Real-time-Instance-Segmentation-97dto17e</guid>
            <pubDate>Tue, 02 Apr 2024 07:51:39 GMT</pubDate>
            <description><![CDATA[<p>이번 포스팅에서는 ICCV 2019에 나온 YOLACT 논문을 리뷰할 예정이다.</p>
<p>해당 논문은 &#39;실시간&#39;으로 이미지를 instance segmentation 문제를 해결하는 방법을 제시한다.</p>
<p><a href="https://arxiv.org/abs/1904.02689">YOLACT Paper link</a></p>
<blockquote>
<p>Bolya, Daniel, et al. &quot;Yolact: Real-time instance segmentation.&quot; 
Proceedings of the IEEE/CVF international conference on computer vision. 2019.</p>
</blockquote>
<h1 id="abstract">Abstract</h1>
<p>이 논문에서는 &#39;real-time instance segmentation&#39;을 위한 fully-convolution model을 제시한다.</p>
<p>이를 가능하게 하기 위해서 instance segmentation task를 두 개의 하위 작업으로 나눠 병렬로 수행한다.</p>
<ul>
<li><p>Prototype mask set 생성</p>
</li>
<li><p>각 instance mask의 coefficients 예측</p>
</li>
</ul>
<p>이에 대한 내용은 추후에 설명하도록 하겠다.
여기서는 두 가지의 병렬 task로 instance segmentation을 한다는 정도만 알면 될 것 같다.</p>
<h1 id="instroduction">Instroduction</h1>
<p>2-stage detection 모델인 Mask RCNN, FCIS와 같은 접근 방식은 Faster R-CNN 및 R-FCN을 기반으로 발전해 왔다.</p>
<p>하지만 2-stage 방식 detection은 &#39;속도&#39;(speed)보다 &#39;성능&#39;(performance)에 중점을 두고 있다.
속도의 측면에서 보완하고자 1-stage 방식의 detection 모델인 SSD, YOLO와 같은 모델이 실시간으로 detection 할 수 있게 했다.
그러나 object detection보다 intance segmentation가 더 어려운 task이기 때문에 정말 똑같은 방식으로 &#39;실시간&#39;의 성능을 고도화할 순 없다.</p>
<p>그 이유는 다음과 같다.
2-stage 기반의 instance segmentation은 feature localization에 의존하여 mask를 생성해 낸다.
feature의 일부를 바운딩 박스 영역으로 pooling(=re-pooling)하고 이를 mask predictor에 입력으로 통과시킨다.
이 방법은 sequential하기 때문에 가속화하여 속도를 높이기 어렵다.</p>
<p>물론 FCIS와 같이 이러한 단계를 병렬로 수행하는 단계별 방법도 있지만, localization 이후에 많은 후처리 과정이 필요하기 때문에 속도를 높이는 것은 어렵다고 한다.</p>
<p>본 연구에서는 이러한 점을 고려하면서 2-stage의 한계를 극복하는 방식으로 빠르고 단계적인 인스턴스 세그멘테이션 모델을 제공한다.
<img src="https://velog.velcdn.com/images/running_learning/post/24a2d0f5-7e97-4e24-afde-ba53de5e18cd/image.png" alt=""></p>
<p>실제로 본 논문에서 제시한 YOLACT 모델의 성능은 figure 1과 같다.
COCO dataset 기준으로 Mask mAP가 30을 상회하면서 동시에 30 FPS를 넘는 추론 능력을 보여준다.
이는 인간이 느끼기에 실시간이라고 판단되는 기준인 30 FPS를 넘기 때문에 목표를 달성했다고 볼 수 있다.</p>
<h1 id="yolactthe-proposed-method">YOLACT(The proposed method)</h1>
<p>앞서 언급한 것처럼 YOLACT 저자들은 Faster R-CNN에서 Mask R-CNN로 발전시킨 것(object detect측면에서)과 같이 mask branch를 추가하여 실시간의 성능을 고도화하고자 한다.</p>
<p>다만 위의 발전 방식과 다른 점은 explicit feature localization step이 따로 없다는 것이다.
다음 Figure 2를 보고 YOLACT의 구조를 파악하고 어떻게 문제를 해결하고 자하는 지 그 흐름을 이해해 보자.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/a25a1475-a0c6-4a5d-95ff-4c08517607b5/image.png" alt=""></p>
<p>Input image로부터 특징을 추출하기 위해 Feature Backbone을 거치면, 어떠한 형태의 특징을 가지는 Feature map이 만들어진다.
그중 C5에 해당하는 feature map을 활용하여 P5로 대응시키고 이를 up / down - sampling 한다.
Upsampling 과정에서 P4와 C4, P3와 C3을 선형 결합한다. 이때 만들어진 P3 ~ P7의 조합으로 Protonet과 Prediction Head에 사용되는 것이다.</p>
<blockquote>
<p><strong>왜 Feature pyramid를 사용할까?</strong>
다양한 크기와 해상도를 가지는 Feature map을 만들고 이를 결합하면 다양한 receptive field를 고려할 수 있기 때문에 
다양한 크기의 객체 특히 작은 객체의 특징을 잡아내는 데 유용하게 사용된다. 
즉, robust 한 segmentation 성능을 내기 위해서이다.</p>
</blockquote>
<p>드디어 Abstract에서 언급한 두 가지 병렬 작업(parallel task)에 대해 알아볼 시간이다.</p>
<p>하나는 1) FCN(fully convolutional network)를 사용한 Prototype masks set 생성하기이고,
다른 하나는 2) &#39;mask coeffiecients&#39;의 벡터를 예측하기이다.
위의 figure 2에서 prediction head와 protonet의 파트로 나눠지는 부분이 이에 해당한다.</p>
<p>이 두 가지를 병렬적으로 수행될 수 있는 경우는 <strong>mask의 spatially coherent 성질</strong>을 이용할 수 있어야 하는 경우이다.
<strong>spatially coherent의 성질</strong>은 쉽게 말해서 서로 가까운 픽셀은 같은 instance일 가능성이 높다는 것을 의미한다.
그러나 spatially coherent의 성질을 활용하는 데 기존의 task에 문제가 있다.</p>
<p>원래 one-stage detector는 각 anchor에 대해 class와 box coefficients를 
fc-layer의 출력으로 생성한다.
하지만 fc-layer는 mask에 대하여 spatially coherent한 것을 활용하지 못한다.(localization의 정보 없이 class와 box coefficient를 계산하기 때문에)
그렇다고 two-stage의 localization(ex. RoI-Align)을 사용하면 속도 페널티가 크다.</p>
<p>따라서 본 논문은 fc-layer의 출력으로 semantic vector를, conv-layer의 출력으로 mask coefficients와 prototype mask를 생성하여 활용하고자 한다.</p>
<p>결과적으로 이 둘이 독립적으로 계산되기 때문에, computation overhead는 이 둘을 합치는 과정에서 생긴다.
이것을 matrix multiplication으로 해결하기 때문에 속도 문제를 해결할 수 있다고 한다.</p>
<p>각 파트에 대해 좀 더 자세히 알아보자.</p>
<h2 id="1-prototype-generation">1. Prototype Generation</h2>
<p>Figure 2에서 Protonet에 해당하는 부분이다.
<strong>Protonet은 전체 이미지에 대한 K개의 prototype mask set을 예측한다.
k개의 channel이 각각의 k개의 mask로 대응되는 꼴이다.</strong>
아래의 figure 3을 보면 138 * 138 * k(개)의 mask set이 생성된 것이다.</p>
<p>이를 backbone feature layer에 연결하는데, figure 2의 P3에 해당한다.
FPN(Feature Pyramid Network)를 사용하고 그 후 입력 이미지에 대하여 1/4 크기로 up-sampling 한다.
(550 * 550 input size -&gt; 138 * 138 feature map size )
FPN의 깊은 layer를 활용한 고해상도의 feature map을 통해 작은 객체에 대해 고품질의 mask를 생성할 수 있다.
<img src="https://velog.velcdn.com/images/running_learning/post/651fd2c8-e278-4769-a94b-7015456811da/image.png" alt=""></p>
<p>또한 Protonet의 출력을 unbound 하게 만드는 게 중요하다고 강조한다.
큰 confident를 가지는 값에 대하여 large, overpowering activation(명확할 수록 더 커지는 활성화 값)하게 하기 위해 
Protonet출력에 Relu나 비선형이 아닌(nonlinearity)의 함수를 사용하는 것으로 이를 해결했다고 한다.</p>
<h2 id="2-mask-coefficients">2. Mask Coefficients</h2>
<p>일반적으로 anchor-based detector는 prediction head에 2개의 branch를 사용한다.</p>
<ol>
<li>c개의 class confidence를 예측</li>
<li>bounding box 좌표계(4개)를 위한 regressor 예측</li>
</ol>
<p>본 논문은 Mask coefficients를 예측하기 위해 위의 1,2 branch와 병렬적으로 다른 하나의 branch를 추가하여 k개의 prototype의 mask coefficients를 예측한다.</p>
<p>따라서 일반적인 anchor-based detector에서 anchor당 4+c(4a + ca)개의 계수를 생성하는 것 대신에 4 + c + k(ca + 4a + ka)개의 계수를 생성하게 된다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/ebd1bfad-e4ad-48fa-ae25-f2d42707f085/image.png" alt=""></p>
<p>Figure 4를 보면 왼쪽(기존 anchor-based)은 Pᵢ 로부터 class(1번에 해당)와 box(2번에 해당) branch를 가지지만 오른쪽(본 논문 제시)은 class와 box에 병렬적으로 더하여 mask의 branch를 생성하는 것을 볼 수 있다.</p>
<h2 id="3-mask-assembly">3. Mask Assembly</h2>
<p>최종적으로 instance mask를 생성하기 위해서 prototype branch와 mask coefficients branch를 결합해야 한다.</p>
<p>mask coefficient를 계수로 한 선형 결합을 통해 이를 가능하게 한다.
final mask 생성을 위해 비선형 함수인 sigmoid를 사용한다고 한다.
즉, 아래의 식(1)과 같이 두 branch의 단일 행렬 곱과 simoid를 통한 instance mask를 생성한다.
<img src="https://velog.velcdn.com/images/running_learning/post/e165393c-3ff6-47d8-9a4e-47c66203a7ab/image.png" alt=""></p>
<p>P는 prototype mask의 H * W * K 크기의 행렬이고, C는 인스턴스에 대한 mask coefficients의 N * K (N은 NMS 결과 남아있는 class들의 수) 크기의 행렬이다.</p>
<h3 id="31-losses">3.1 Losses</h3>
<p>본 논문은 모델 훈련에 사용할 손실 함수로 Classification Loss, Box regression Loss, Mask Loss 3가지를 사용한다.
각각 weight을 1 / 1.5 / 6.125로 두기 때문에 Mask loss에 대해 더 민감하게 적용되도록 구성했다.</p>
<p>Classification과 Box regression Loss에 대해서는 &#39;SSD: Single shot multibox detector&#39;의 논문에서 사용한 것을 차용했다고 한다.
(SSD 논문 리뷰에서 다뤄보자!)
Mask Loss는 pixel-wise binary cross entropy를 사용했다고 한다.</p>
<h3 id="32-cropping-masks">3.2 Cropping Masks</h3>
<p>본 논문은 evaluation 단계에서 최종 마스크를 예측된 bounding box로 자른다.
반면 Training 단계에서는 예측된 bounding box 대신에 Ground truth bounding box로 자른다.
Mask Loss를 Ground truth bounding box 영역으로 나누어 Prototype mask에서 작은 객체를 보존한다고 한다.
(이게 어떻게 가능한 건지는 아직 이해를 못 해서 더 공부해야 할 것 같다..)</p>
<h2 id="4-emergent-behavior">4. Emergent Behavior</h2>
<p>instance segmentation에서 FCNs를 사용하여 translation invariance의 성질을 가진 것과 달리 본 논문의 task에서는 translation variance가 필요하기 때문에 조금 다른 접근법을 사용했다. (mask별 나타나는 activation이 달라야 할 것이다.)</p>
<blockquote>
<p>Translation invariance란?
쉽게 말해, Conv layer의 연산 과정에서 input의 위치가 달라져도 output이 동일한 값을 갖는 것을 의미한다.
가령 고양이 구분 task에서 고양이가 이미지의 어떤 곳에 위치하더라도 Convnet은 Translation invariance의 성질로 고양이로 구분할 수 있어야 한다.</p>
</blockquote>
<p>FCIS나 Mask R-CNN에서 적용한 방법은 translation variance를 explicitly 하게 추가한다.
(re-pooling, second stage에 mask branch 적용 -&gt; localizing instance X )</p>
<p>반면 본 논문에서는 final mask를 predicted bounding box로 자르는 과정을 제외하면 explicitly하게 추가하여 translation variance를 추가하지 않았다.
대신 서로 다른 Prototypes의 activation을 통해 localizing instance 하는 방법에 대해 학습했다고 보는 것 같다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/286afd06-91d6-41e7-a589-83a8eff0c83a/image.png" alt=""></p>
<p>Figure 5에서 이를 확인해 볼 수 있다.</p>
<p>우선 이미지 A(빨간 픽셀로만 이뤄진 이미지)가 padding 없이 FCN을 통과하면 모두 같은 값을 가질 것이다.
padding을 각 layer마다 추가해 준다면 각 layer를 지날 때마다 픽셀이 이미지의 가장자리로부터 얼마나 떨어졌는지 알 수 있다.
이것이 <strong>본질적으로 Translation variant를 가지고 있다</strong>고 볼 수 있으며, 이를 활용하는 게 본 논문이다.</p>
<p>Figure 5를 보면 6개(k = 6)의 Prototype mask가 각 이미지(a<del>f)에 대하여 생긴 것을 볼 수 있다.
각각의 prototype은 이미지의 특정 partitions를 활성화하는 것으로 보인다.
이러한 partition map(1</del>3)을 결합하여 같은 semantic class에 대해서 instance를 구분할 수 있다고 한다.
(심지어 겹치는 부분도 구별한다고 합니다.)</p>
<p>예를 들어 <strong>이미지 d에서 prototype 2에서 3을 빼준다면 녹색 우산을 activation 한 것과 같게 된다</strong>.</p>
<p>또한 Prototype은 compressible(압축가능)하다.
Protonet이 prototype을 하나로 결합하는 경우, mask coefficient branch가 어떤 prototype이 어떤 상황에서 필요한 지를 학습할 수 있게 한다.</p>
<p>따라서 무작정 K를 증가시키는 것은 mask coefficient가 network에서 학습면서 올바르게 생성되어 그 균형을 이루는 것에 방해가 될 것이다. (실제로는 K를 무작정 증가시키는 것은 별 효과가 없다고 한다.)</p>
<h1 id="results">Results</h1>
<p><img src="https://velog.velcdn.com/images/running_learning/post/50514d9e-0bf8-4342-ad05-9cc5f8cb54dc/image.png" alt=""></p>
<p>Table 1을 보면 MS COCO 셋 기준으로 YOLACT모델을 다른 모델의 성능 지표와 비교하였다.
속도 측면(FPS, Time)에서 큰 경쟁 우위가 있다는 점에서 의미가 있다.
더욱이 다른 모델들끼리의 성능 지표는 AP기준(AP50, 75의 차이를 보면) 비슷한 간격을 두고 성능이 측정된다. </p>
<p>반면 YOLACT-550(550은 이미지 사이즈)와 Mask R-CNN을 비교해 보면 AP50은 
약 9.5 정도 차이가 나지만 AP75는 약 6.6 정도 차이 난다는 점에서 IOU threshhold를 높일수록 성능 차이가 줄어든다는 것을 시사하고 있는 것 같다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/93bea9fa-5c23-4535-b1cd-60f9ac949239/image.png" alt=""></p>
<p>Figure 7을 보면 mask의 quality 부분에서도 YOLACT의 좋은 성능을 볼 수 있다.
이를 가능하게 한 것은 138 * 138 크기의 비교적 큰 final mask size와 
원본 feature로부터 생성한 mask를 꼽는다.
큰 객체에 대하여 FCIS와 Mask R-CNN와 비교하여 더 좋은 quality를 내고 있다.
가령 사람의 팔 부분을 보면 그 경계를 더욱 세밀하게 따르는 mask를 생성하는 것을 볼 수 있다.
(FCIS, Mask R-CNN은 주위에 noise가 있는 모습이 관찰된다.)</p>
<blockquote>
<p>References
[1] YOLACT 논문: Bolya, Daniel, et al. &quot;Yolact: Real-time instance segmentation.&quot; 
Proceedings of the IEEE/CVF international conference on computer vision. 2019.
[2] translation invariance: <a href="https://ganghee-lee.tistory.com/43">https://ganghee-lee.tistory.com/43</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Mac M1] ROS2 + Gazebo 설치하기]]></title>
            <link>https://velog.io/@running_learning/Mac-M1-ROS2-Gazebo-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@running_learning/Mac-M1-ROS2-Gazebo-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 02 Apr 2024 07:36:45 GMT</pubDate>
            <description><![CDATA[<p>로봇 시뮬레이션을 위해 ROS2와 Gazebo를 다운받으려는데 자꾸 오류가 났다.
UTM으로 ubuntu 22.04버전을 다운 받아 가상 머신에서 docker로 ROS2를 실행해 보았으나,
Gazebo를 설치하고 실행하는 과정에서 계속 오류가 났었다..</p>
<p>ARM chip에서 ubuntu22.04와 gazebo의 호환성에서 발생한 것 같은데 확실하진 않다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/18e7278b-4a79-4a4c-80b9-3f60096ec86a/image.png" alt=""></p>
<p><del>외않데..?ㅂㄷㅂㄷ</del></p>
<p>그래서 그냥 로컬에 직접 설치하여 이를 해결했다.
이번 포스팅에서는 Mac M1칩 환경에서 ROS2를 로컬에 직접 설치하는 방법에 대해 소개한다.
설치 단계는 크게 다음과 같다. </p>
<blockquote>
<ol>
<li>homebrew installation</li>
<li>conda environment installation</li>
<li>ROS2 installation using Robostack</li>
<li>gazebo installation</li>
</ol>
</blockquote>
<h2 id="1install-homebrew">1.Install Homebrew</h2>
<p>Homebrew는 Mac OS에서 소프트웨어의 설치 및 업데이트에 용이하고 이를 통해 프로그래밍 언어, 라이브러리 등을 쉽게 설치할 수 있게 하는 패키지매니지 tool이다. </p>
<p>더욱이 homebrew는 Apple(또는 Linux)에서 제공하지 않는 유용한 패키지 관리자를 설치한다는 점에서 유용하게 쓰인다.</p>
<p>우선 터미널 창을 열어 다음 커맨드를 실행한다.</p>
<pre><code>$ /bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;</code></pre><p>이를 통해 homebrew가 설치된다.
homebrew 메인 페이지에 그대로 쓰여있어 이를 복사+붙여 넣기 해도 된다.
<a href="https://brew.sh/">Homebrew homepage</a></p>
<p>만약 터미널 창에 Next step란에 Run ~~ Commands in your terminal이라고 뜨면 그걸 그대로 복붙 해서 터미널에서 실행하면 된다.
그 후 터미널에 다음 커맨드를 실행한다.</p>
<pre><code>$ brew doctor</code></pre><h2 id="2install-conda-environment">2.Install Conda environment</h2>
<p>ROS2 실행을 위한 conda 환경을 설정해주어야 한다.
Anaconda 보다 가벼운 Miniconda나 Miniforge를 사용하는 것을 추천한다.</p>
<p>Mac m1 환경에서 Miniconda를 설치하는 방법은 아래 사이트에서 친절하게 설명해 주기 때문에 그대로 따라 하기만 하면 된다.</p>
<p><a href="https://docs.anaconda.com/free/miniconda/index.html">Miniconda Quick command install</a></p>
<p>(주의: 아래 그림처럼 &#39;Mac OS&#39;를 선택했는지 확인할 것.)
<img src="https://velog.velcdn.com/images/running_learning/post/57aa1212-fb6a-4e4f-92e8-57e63a13b4e5/image.png" alt=""></p>
<p>conda가 정상적으로 설치되어 실행된다면 터미널 창에 줄마다 맨 앞에 &#39;(base)&#39;라는 문구가 나온다.</p>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/running_learning/post/3f66d785-9c7f-4f42-b4f8-fa5668f0d109/image.png" alt=""></th>
<th><img src="blob:https://velog.io/795bae8c-9750-42ef-8ac9-f7279228a3b7" alt=""></th>
</tr>
</thead>
</table>
<h2 id="3install-ros2-using-robostack">3.Install ROS2 using Robostack</h2>
<p>Robostack 홈페이지에 다음과 같이 설명되어 있다.</p>
<blockquote>
<p>Welcome to RoboStack - a bundling of the Robot Operating System (ROS) by Open Robotics for Linux, Mac and Windows using the Conda package manager. We provide ROS packages for ROS1 Noetic and ROS2 Humble (as well as unsupported Melodic/Foxy/Galactic packages), as well as a variety of ROS related plugins for Jupyter notebooks.</p>
</blockquote>
<p>다양한 OS platform에서 제공되며 Conda 환경에서 쉽게 ROS를 실행할 수 있게 한다고 한다.</p>
<p>Conda가 설치되었다면, (base)환경에서 아래의 코드 블록을 실행한다.</p>
<pre><code>$ conda install mamba -c conda-forge</code></pre><p>다음과 같은 주의사항이 있다고 한다. 아마 Ros 설치 중에 오류가 난다면 이와 관련된 오류가 될 것이다.
<img src="https://velog.velcdn.com/images/running_learning/post/6c5a226a-cf9c-4516-ae0d-0c98a0d5e3d1/image.png" alt=""></p>
<p>Mamba를 설치했다면 Conda 가상환경을 만들어주자.</p>
<pre><code># ex) conda create -n robot_env
$ conda create -n &quot;가상환경 이름&quot;</code></pre><p>가상환경 설치가 끝났다면 설치된 가상환경을 활성화시켜 주자.</p>
<pre><code># ex) conda activate robot_env
$ conda activate &quot;앞에서 지은 가상환경 이름&quot;</code></pre><p>이렇게 해주면 앞에 있던 &#39;(base)&#39;가 &#39;(가상환경 이름)&#39;으로 바뀔 것이다. 가상환경을 잘 활성화시켰다는 의미!
그 후 conda environment configuration에 conda-forge와 robostack 채널을 추가하고, default 채널은 지워줘야 한다.
<strong>이때 주의할 것은 가상환경이 잘 활성화되어있는지 파악하는 것이다!</strong></p>
<pre><code># this adds the conda-forge channel to the new created environment configuration 
$ conda config --env --add channels conda-forge

# and the robostack channel
$ conda config --env --add channels robostack-staging

# remove the defaults channel just in case, this might return an error if it is not in the list which is ok
$ conda config --env --remove channels defaults</code></pre><p>이제 드디어 ROS2를 설치할 수 있게 되었다.
ROS2 설치 커맨드는 다음과 같다.</p>
<pre><code># Install ros-humble into the environment (ROS2)
$ conda install ros-humble-desktop</code></pre><p>그 후 초기화를 위해 가상환경을 deactivate 했다가 다시 활성화시켜주자.</p>
<pre><code># deactivate 먼저
condaa deactivate

# 다시 가상환경 activate
conda activate &quot;가상환경 이름&quot;</code></pre><p>그 후 가상환경 내에서 ROS Package를 관리해 주고 도와주는 tool을 설치해 준다.</p>
<pre><code>$ conda install compilers cmake pkg-config make ninja colcon-common-extensions catkin_tools rosdep</code></pre><p>이렇게 되면 ROS2 설치가 끝났다!!
잘 설치되었는지 확인하기 위해서 Rviz를 실행시켜 보자.</p>
<pre><code>$ rviz2</code></pre><p>성공적으로 설치가 완료되었다면 다음과 같이 RViz가 새 창으로 열리게 된다.
(Rviz는 로봇 시뮬레이션을 위한 3D 시각화 툴이라고 생각하면 된다)</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/466acc49-71c2-45d0-aa75-cea3b9b606b0/image.png" alt=""></p>
<h2 id="4-install-gazebo">4. Install Gazebo</h2>
<p>Gazebo는 오픈 소스로 제공되는 가상 시뮬레이션 툴이다. </p>
<p>이를 통해 사용자 원하는 로봇을 가상 시뮬레이션에 삽입한 후, 삽입된 로봇과 사용자가 작성한 프로그램이 메시지를 주고받으며 동작하는 모습을 확인할 수 있게 해 준다. 이는 ROS와 별게 프로그램이기 때문에 따로 설치해 주도록 하자.</p>
<p>다행히도 한 줄만으로 간단하게 Gazebo를 설치할 수 있다고 한다.
(그러나 아래의 커맨드로 간단하게 설치하는 것은 OS X 10.11 이상 버전에서 작동한다고 하니, 그 이전 버전인 경우 default standard library와 rebuilding dependencies를 바꿔야 한다고 합니다.. 참고하시길..)</p>
<p>별개의 프로그램이기 때문에 ROS설치를 위해 가상환경에서 벗어나야 한다.
우선 deactivate를 해주자. </p>
<pre><code>$ conda deactivate</code></pre><p>그럼 당연히 (base) 환경으로 바뀔 것이다.
이제 gazebo를 설치해 주자.</p>
<pre><code>$ curl -ssL http://get.gazebosim.org | sh</code></pre><p>이거 설치하는데 시간이 걸린다. 미뤘던 방 청소를 하고 오자..
설치가 끝났다면  실행이 되는지 보기 위해 (base) 환경에서 gazebo를 실행해 주자.</p>
<pre><code>$ gazebo</code></pre><p>설치가 성공적으로 되었다면 다음과 같은 화면이 뜬다!
<img src="https://velog.velcdn.com/images/running_learning/post/0a06ce13-aeea-4f7e-bb44-8d530734d2e2/image.png" alt=""></p>
<p>이제 드디어 로봇 개발을 위한 기본적인 환경 설정이 끝났다.. 화이팅..</p>
<blockquote>
<p>References
[1] 참고영상: <a href="https://www.youtube.com/watch?v=GEgVpdZj3tY">https://www.youtube.com/watch?v=GEgVpdZj3tY</a>
[2] gazebo tutorial: <a href="https://classic.gazebosim.org/tutorials?tut=install_on_mac">https://classic.gazebosim.org/tutorials?tut=install_on_mac</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[ROS(robot operating system)의 등장 배경]]></title>
            <link>https://velog.io/@running_learning/ROSrobot-operating-system%EC%9D%98-%EB%93%B1%EC%9E%A5-%EB%B0%B0%EA%B2%BD</link>
            <guid>https://velog.io/@running_learning/ROSrobot-operating-system%EC%9D%98-%EB%93%B1%EC%9E%A5-%EB%B0%B0%EA%B2%BD</guid>
            <pubDate>Tue, 02 Apr 2024 07:12:18 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>최근 로봇에 AI를 접목시키는 것에 관심이 생겼다. 이와 관련된 공부를 하다가 ROS와 ROS 2에 대해 알아야 했다.
인공지능 공부하는 데 파이썬을 알아야 하는 것과 같은 느낌이 들었다.
그렇다고 ROS 2가 프로그래밍 언어 자체는 아니다. 
따라서 이번 포스팅에서는 ROS 2를 사용하기 전에 그 등장 배경에 대해 간략하게 알아보도록 하겠다.</p>
</blockquote>
<p>비대면적 서비스가 활발해짐에 따라 다양한 기술이 산업에 적용되었다.
특히 코로나 이후 인공지능, 로보틱스 등이 빠르게 발전하고 있다.
최근 기사를 보면 로봇이 치킨도 튀기고, 요리도 하는 경우도 있으며 심지어 배달까지 하는 로봇까지 개발되고 상용화 과정에 있다고 한다.
실제로 식당에 가보면 로봇이 테이블로 직접 서빙해 주는 경우를 본 적이 있기도 하다.</p>
<p>그렇다면 이러한 로봇 서비스를 개발하기 위해서 어떻게 해야할까?
어떤 서비스 로봇을 만들지에 따라 달라지겠지만 매우 다양한 작업(분야)이 필요하다.
기구 설계, 임베디드, 시뮬레이션, 웹 연동, 컴퓨터 비전 등등.. 의 작업이 필요하다.
더욱이 AI기술이 발달함에 따라 인공지능이 로봇에도 적용되고 있다.
이렇게 만든 로봇이 인간에게 있어 이롭게 하기 위해서는 안전하고 강인해야 한다.이를 위해 수많은 테스트의 과정이 지속적으로 필요하다.</p>
<p><strong>그럼 로봇을 하나 만드는 데 저 모든 분야를 직접 다 다룰 줄 알아야 할까?</strong>
그 분야에 대해 아는 것은 중요하지만 직접 다룰 줄 아는 것은 또 다른 얘기이다.</p>
<p>가령 내가 AI engineer인데 누군가 만들어 놓은 
open source의 임베디드, 웹 프로그램으로 내가 만든 로봇 전용 AI 알고리즘을 로봇에 적용하여 테스트해 볼 수 있을 것이다.
이때 <strong>&#39;누군가 만들어 놓은 로봇용 개발 프로그래밍 tool&#39;</strong>의 역할을 하는 것이 바로 ROS이다.</p>
<h2 id="rosrobot-operating-system">ROS(Robot Operating System)</h2>
<p><a href="https://www.ros.org/">ROS homepage</a></p>
<p>위의 ROS 홈페이지에 접속하면 ROS를 다음과 같이 정의 및 설명하고 있다.</p>
<blockquote>
<p>The Robot Operating System (ROS) is a set of software libraries and tools that help you build robot applications. From drivers to state-of-the-art algorithms, and with powerful developer tools, ROS has what you need for your next robotics project. And it&#39;s all open source.</p>
</blockquote>
<p>즉, *<em>로봇 개발을 위한 라이브러리이자 플랫폼인 것이다. *</em>
ROS가 로봇 프로그래밍에 제공하는 기능 및 역할은 크게 다음과 같다.</p>
<ol>
<li>기존의 open-source를 제공</li>
<li>다양한 툴 제공 ex) 디버깅 툴로서 콘솔의 출력이 아닌 시각화 툴을 제공
(RViz, RQt)</li>
</ol>
<p>ROS의 기본적인 이해를 돕는 블로그가 있어 첨부하도록 하겠다.
<a href="https://velog.io/@7cmdehdrb/whatIsROS">ROS의 이해</a></p>
<h2 id="ros2">ROS2</h2>
<p>ROS가 뭔지 알고 나면 ROS2는 ROS를 배워야 알 수 있을 것만 같다.
하지만 그건 아니다. 물론 이론적인 배경은 알 필요가 있지만 ROS를 다룰 줄 몰라도 ROS 2는 다룰 수 있다.</p>
<p>그렇다면 기존의 ROS를 사용하지 않고 ROS2를 사용하는 배경은 무엇일까?
기존의 ROS는 다음과 같은 문제가 있었다.</p>
<ul>
<li>실시간성 보장 x</li>
<li>보안에 취약</li>
<li>Python 2를 사용</li>
</ul>
<p>이러한 부분을 보완하고자 등장한 것이 ROS 2이다.
ROS와 ROS 2의 아키텍처를 시각화하면 다음과 같다.
<img src="https://velog.velcdn.com/images/running_learning/post/8340e4d7-fa10-4e7b-9cc3-5e7fba98aea2/image.png" alt=""></p>
<p>아래 사이트에서 ROS2 설계에 대한 철학도 엿볼 수 있다.
<a href="https://design.ros2.org/">design ros2.org</a></p>
<p>이러한 배경에서 처음 로봇을 공부하려는 사람은 ROS 2를 바로 공부해도 된다고 한다.</p>
<p>추후의 포스팅에서 더욱 다양한 AI 로봇에 대한 내용을 다루겠지만 ROS 2를 어떻게 세팅하고 사용하는지 위주로 올리도록 하겠다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[만들면서 배우는 생성 AI] 3장 - 변이형 오토인코더(VAE)]]></title>
            <link>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-2%EC%9E%A5-%EB%94%A5%EB%9F%AC%EB%8B%9D</link>
            <guid>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-2%EC%9E%A5-%EB%94%A5%EB%9F%AC%EB%8B%9D</guid>
            <pubDate>Tue, 26 Mar 2024 06:24:20 GMT</pubDate>
            <description><![CDATA[<h2 id="1-오토-인코더autoencoder">1. 오토 인코더(Autoencoder)</h2>
<p>Autoencoder는 다음과 같은 구조로 이루어져 있다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/43e8ea36-671a-4fb4-b709-ed477337a6f1/image.png" alt=""></p>
<p>단순하게 입력에 대한 인코딩과 디코딩 작업을 수행하도록 훈련된 신경망이다.
오토 인코더에서 중요한 개념은 딱 세 가지이다. 
<strong>1. 인코더(encoder)
2. 잠재 공간(latent space)
3. 디코더(decoder)</strong></p>
<p>먼저 인코더는 이미지 같은 고차원 입력 데이터를 저차원 임베딩 벡터로 압축하는 역할을 한다.</p>
<p>쉽게 말해서 픽셀값으로 이루어져 있는 입력 데이터를 어떠한 이미지적 특징(ex. 사람의 눈, 고양이의 귀, 질감 등등)을 가지도록 차원을 축소시키는 것을 의미한다. 28 * 28 크기의 이미지의 픽셀은 총 784개이다. 픽셀값 기준으로 784차원으로 표현된 이 이미지를 어떠한 특징의 저차원으로 축소시키겠다는 의미로 받아들일 수 있다.</p>
<p>인코더를 통해 나온 저차원 임베딩 벡터는 잠재 공간 안에 존재한다.
임베딩은 원본 이미지를 저차원 잠재 공간으로 압축한 것이기 때문이다.
이 잠재 공간에서 임의의 포인트를 선택하여 디코더에 통과시키면 새로운 이미지가 생성되는 것이다.
원래의 이미지를 재구성하는 데 이미 가지고 있는 이미지와 동일하지 않으면서 재구성하는 데 필요하다.</p>
<p>디코더는 잠재 공간의 한 포인트를 유효한 이미지로 변환하는 방법을 학습하여, 새로운 이미지를 생성하는 역할을 한다.
이러한 구조를 통해 새로운 이미지를 만들어 낼 수 있는 것이다.</p>
<p>하지만 이에 문제가 있다. 
잠재 공간의 한 포인트에 직접 매핑되기 때문에 빈 공간에 대한 이미지 생성 품질이 극히 안 좋아질 것이다.
오토인코더가 이미지를 인코딩할 때 비슷한 이미지끼리 그룹이 생길 것이고 그룹간의 사이에서 생성한 이미지가 좋을 것이라고 기대하기 어려워진다.</p>
<p>이를 해결하고자 나타난 것이 <strong>변이형 오토인코더(Variational AutoEncoder: VAE)</strong>이다.</p>
<h2 id="2-변이형-오토인코더vae">2. 변이형 오토인코더(VAE)</h2>
<p>오토인코더가 이미지를 잠재 공간의 한 포인트에 직접 매핑하는 것 대신, 변이형 오토인코더는 이미지를 잠재 공간에 있는 포인트 주변의 다변량 정규분포에 매핑한다.</p>
<p>즉, 변이형 오토인코더는 잠재 공간의 &#39;확률적 분포&#39;를 학습하여 이산적으로 매핑되어 이미지 생성 성능이 낮아지는 문제를 해결한다는 것이다.</p>
<p>평균이 <strong>µ</strong>이고 표준 편차가 𝞼인 정규 분포에서 포인트 Z를 샘플링하는 데 다음과 같은 공식이 사용된다.</p>
<blockquote>
<p><strong><em>Z = µ + 𝞼𝟄</em></strong></p>
</blockquote>
<p>이를 위해 인코더는 각 입력을 평균 벡터(µ역할)와 분산 벡터(𝞼역할)에 매핑하면 된다.
이때 잠재 공간에서 차원 간 상관관계가 없다고 가정하기 때문에 차원 간 공분산을 신경 쓸 필요가 없다고 한다.
또한 분산의 값은 항상 양수여야 하기 때문에 분산의 로그에 매핑하도록 하는 것에 주의해야 한다.</p>
<p>즉, 인코더는 입력 이미지를 받아 잠재 공간의 다변량 정규 분포를 정의하는 2개의 벡터로 인코딩하는 역할을 한다.</p>
<p>2개의 벡터는 다음과 같다.</p>
<ul>
<li>z_mean = 분포의 평균 벡터</li>
<li>z_log_var =  차원별 분산의 로그 값</li>
</ul>
<p>위의 샘플링 공식에 의하여</p>
<blockquote>
<p>Z = z_mean + exp(z_log_var * 0.5) * epsilon</p>
</blockquote>
<p>과 같이 대입할 수 있다.
이 때 epsilon은 표준 정규 분포에서 샘플링된다. epsilon ~ N(0,I)</p>
<p>디코더 부분은 오토인코더와 동일하다.
지금까지의 내용으로 변이형 오토인코더의 구조를 보면 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/d664d49d-1394-4982-a653-82036032d793/image.png" alt=""></p>
<p>변이형 오토인코더와 오토인코더가 가지는 차이는 손실함수에서도 차이가 있다.</p>
<p>오토인코더는 인코더와 디코더를 통과한 출력과 원본 이미지의 차이인 Reconstuction loss만 계산했다.
하지만 변이형 오토인코더는 인코더가 가지는 정규 분포와 표준 정규 분포와 얼마나 다른지 측정해야 하므로 Kullback - leibler divergence(KL divergence)를 더하여 사용한다.</p>
<p>쿨백 라이블러를 사용하는 이유에 대해 개괄적으로 설명하면, KL divergence는 샘플을 표준 정규 분포에서 크게 벗어나는 z_mean, z_log_var 변수로 인코딩하는 네트워크에 벌칙을 가하는 역할을 하기 때문이다.</p>
<p>이는 reconstuction이미지가 원본과 잘 맞는지도 판단하면서 인코딩 과정에서 z_mean, z_log_var가 표준 정규 분포를 따르게 함으로써 정규 분포에 매핑되도록 하는 역할을 하는 것이다.</p>
<p><a href="https://github.com/3n952/generative_ai">autoencoder, VAE 실습 코드 깃허브 주소</a></p>
<blockquote>
<p>References
[1] 논문: Variational Autoencoder(VAE) (Kingma et al. 2014), <a href="https://arxiv.org/abs/1312.6114">https://arxiv.org/abs/1312.6114</a>
[2] VAE 영상 자료: <a href="https://youtu.be/rNh2CrTFpm4">https://youtu.be/rNh2CrTFpm4</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[만들면서 배우는 생성 AI] 2장 - 딥러닝]]></title>
            <link>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-2%EC%9E%A5-%EB%94%A5%EB%9F%AC%EB%8B%9D-hfs031zl</link>
            <guid>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-2%EC%9E%A5-%EB%94%A5%EB%9F%AC%EB%8B%9D-hfs031zl</guid>
            <pubDate>Tue, 26 Mar 2024 06:09:22 GMT</pubDate>
            <description><![CDATA[<h2 id="1-딥러닝용-데이터">1. 딥러닝용 데이터</h2>
<p>딥러닝 학습에 필요한 데이터는 매우 다양하다.
이미지, 텍스트, 오디오 뿐만 아니라 영상과 같은 비정형 데이터가 있다.
그렇다면 <strong>정형 / 비정형 데이터</strong>는 무엇이 다를까?</p>
<p>기존의 많은 머신러닝 알고리즘은 테이블 형태의 정형 데이터를 입력으로 받는다.
엑셀로 표현된 데이터가 대표적인 정형 데이터이다.
각 데이터 샘플의 특성이 열로 표현되고 이 특성이 출력에 어떻게 영향을 미치는 지 모델이 학습을 한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/0af5330a-6368-49be-8af5-d97173d51a81/image.png" alt=""></p>
<p>반면 비정형 데이터는 특성의 열로 구성할 수 없는 데이터를 의미한다.
이미지의 픽셀, 음성의 진동수, 텍스트의 문자 하나에는 정보가 거의 없어 이를 표현하는 것은 비효율적이다.
가령 어떤 이미지의 234번째 픽셀이 황토색이라면 이것이 황토색 집인지 강아지의 털인지 구분할 수가 없다.
다만 이러한 픽셀이 모여 공간적인 정보가 담긴 고수준의 특성을 구성하게 한다면 이미지 task에 적합한 데이터가 될 것이다.</p>
<h2 id="2-신경망의-학습">2. 신경망의 학습</h2>
<p>딥러닝의 심층 신경망은 층(layer)을 연속으로 쌓아 구성한다.
층은 유닛을 가지며, 이전 층의 유닛과 가중치로 연결된다.
데이터의 입력은 심층 신경망의 층을 거치며 출력을 내는 정방향 계산을 수행한다.
정방향 계산으로 나온 출력(예측)의 성능을 향상시키기 위해 역전파를 수행하면서 가중치를 업데이트 한다.
이를 통해 궁극적으로 딥러닝 네트워크가 더 좋은 예측을 하게 되는 것이다.
<a href="https://sanmldl.tistory.com/49">전반적인 딥러닝 학습 과정</a></p>
<p>그렇다면 이미지와 텍스트가 가지는 의미(공간, 문자)를 딥러닝은 어떻게 학습하여 표현할 수 있을까? 신경망의 가장 유용한 핵심 속성은 입력 데이터에서 특성을 스스로 학습하는 능력이라고 할 수 있다.
후속 층의 유닛은 이전 층의 저수준 특성을 결합하여 원본 입력의 정교한 의미(사람을 얼굴 모양 -&gt; 눈 모양 -&gt; 웃고있다)를 표현한다.
각 유닛에 무엇을 찾아야 하는지 등의 개념을 인간이 개입해서 알려줄 필요가 없다.</p>
<p>예를 들어 &#39;사람이 웃고 있는 지 예측하는 심층 신경망&#39;이 있다면 각 층에서 다음과 같이 고수준부터 저수준 특성까지 잡는 경우를 보자.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/45c7fb0a-df43-4f41-8d47-88060a0eccf8/image.png" alt=""></p>
<ol>
<li>유닛 A(갈색 유닛)는 입력 픽셀의 개별 채널에 대한 값을 받는다.</li>
<li>유닛 B는 입력값을 결합하여 edge와 같은 저수준 특성을 추출한다.</li>
<li>유닛 C는 저수준 특성을 결합하여 치아의 출현과 같은 고수준 특성을 추출한다.</li>
<li>유닛 D는 고수준 특성을 결합하여 원본 이미지에 있는 사람이 웃고 있을 때 가장 큰 값을 출력한다.</li>
</ol>
<h2 id="3-합성곱-신경망">3. 합성곱 신경망</h2>
<p>이미지 데이터의 공간 구조를 잘 파악하기 위해서는 합성곱 신경망(conv net)을 사용해야한다.</p>
<p>이와 관련된 포스팅으로 이해해보자!
<a href="https://sanmldl.tistory.com/28">합성곱 연산의 이해</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[만들면서 배우는 생성 AI] 1장 - 생성 모델링]]></title>
            <link>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-1%EC%9E%A5-%EC%83%9D%EC%84%B1-%EB%AA%A8%EB%8D%B8%EB%A7%81</link>
            <guid>https://velog.io/@running_learning/%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%83%9D%EC%84%B1-AI-1%EC%9E%A5-%EC%83%9D%EC%84%B1-%EB%AA%A8%EB%8D%B8%EB%A7%81</guid>
            <pubDate>Wed, 06 Mar 2024 02:14:48 GMT</pubDate>
            <description><![CDATA[<p>생성형 AI를 구현하기 위한 기본서로 &#39;만들면서 배우는 생성 AI&#39;라는 책을 공부하고 리뷰하도록 한다.</p>
<h2 id="1-생성-모델링이란">1. 생성 모델링이란?</h2>
<p>생성 모델링이란 거시적으로 다음과 같이 정의할 수 있다고 한다.</p>
<blockquote>
<p>주어진 데이터 셋과 유사한 데이터를 정의하도록 
모델을 훈련하는 머신러닝의 한 분야.</p>
</blockquote>
<p>이게 무슨 의미인지 이해해보자. 
말의 이미지가 들어있는 데이터 셋(주어진 데이터 셋)에서 모델을 훈련하면, 말 이미지와 유사한 말(과 같은) 이미지를 샘플링하여 원래의 말 이미지와는 다른 이미지를 만들어 낸다는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/d943af41-513f-4e0a-b0e0-a8ba1853093a/image.png" alt=""></p>
<p>가령 이미지 생성 task는 픽셀 값으로 모델이 훈련하기 때문에 훈련 데이터에서 픽셀 값의 분포 및 조합을 학습할 것이다. 이렇게 학습된 모델의 결과를 샘플링하여 새로운 데이터를 만들어내는 것이다.</p>
<p>그렇다면 모델이 학습한 결과가 계속 같을 수 있다는 문제가 생길 수 있다.
이를 위해 샘플링시 개별 샘플에 영향을 미칠 랜덤한 요소를 추가해줌으로써 이를 해결해준다. 
즉, A 이미지는 훈련 데이터 셋에 있을 확률(말의 이미지), B 이미지(말이 아닌 이미지)는 그렇지 않을 확률을 따르는 알려지지 않은 확률분포를 가진다고 가정한다.</p>
<p>생성형 AI 모델은 이러한 확률 분포를 가장 가깝게 표현하도록 학습된다.
그 후 샘플링을 통해 새롭고 다른 샘플을 생성한다.</p>
<h3 id="11-생성-모델링-vs-판별-모델링">1.1 생성 모델링 vs 판별 모델링</h3>
<p>생성 모델링과 판별 모델링은 훈련 데이터의 분포를 가장 잘 따르도록 학습된다는 점에서는 공통점이 있다. 하지만 그 방식과 목적에서 차이가 있다.</p>
<p>우선, 판별 모델링의 예시는 image classification이 있다. 
이를 통해 고흐의 작품의 진위여부를 판단할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/2837af6f-1d44-4349-a89b-0cc2a4822c94/image.png" alt=""></p>
<p>위 그림을 보면 훈련 데이터에서 image - label 한 쌍이 있으면 모델이 이를 학습하여 새로운 image가 입력되었을 때 label의 확률을 구한다.
따라서 판별 모델링에서는 label이 있어야 한다.
이미지가 모델의 input으로 들어와 Conv layer를 통과하면서 고흐가 그린 그림의 색깔, 형태, 질감을 학습한다. 학습된 표현이 fully-connected layer를 지나 label과 매칭되면서 확률을 표현하게 된다.</p>
<p>반면 생성 모델링은 주어진 이미지의 레이블을 예측하는 것이 아니기 때문에, 레이블이 필요가 없다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/76c8b83d-03a4-4ab0-b278-9e7b2a0ee46a/image.png" alt=""></p>
<p>이전에 설명한 것과 같은 흐름대로 생성 모델링이 이뤄지는 것을 확인할 수 있다.
그림에서도 알 수 있듯이 판별 모델링과 생성 모델링은 차이가 있다.
각각의 수학적 정의를 살펴보자.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/cfd599b6-e797-4b44-97f7-cd8d9c48d8fb/image.png" alt=""></p>
<p>결국 생성 모델링과 다르게 판별 모델링에서는 고흐의 그림처럼 생긴 그림을 모방할 수 없는 것이다.</p>
<h3 id="12-첫번째-생성-모델">1.2 첫번째 생성 모델</h3>
<p>생성 모델을 이해하려면 생성 모델링이 어떠한 작동 플로우를 가지고 있는지 알 필요가 있다. 
2차원의 생성 모델링을 통해 생성 모델을 이해해 보았다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/bdebf70c-2c95-4f03-a5c7-5b9df35350fb/image.png" alt=""></p>
<p>그림 1-4에 있는 점을 데이터 포인트라고 하고 이 포인트들의 집합을 X라고 한다.
이 포인트 집합 X에 대한 규칙을 $$p_{data}$$라고 한다.
해당 규칙으로 2차원 공간의 다른 포인트 X = ($$x_{1}$$, $$x_{2}$$)를 매핑하는 것이 이번 생성 모델링의 목표이다.</p>
<p>집합 X에 대하여 어떤 모델을 임의로 정할 수 있을 것이다. 
가령 다음 그림 1-5와 같다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/75e83a39-8bea-4506-b51b-d2a989f14b16/image.png" alt=""></p>
<p>단순하게 $$p_{data}$$를 통해 $$p_{model}$$을 결정했다.
주황색 상자가 $$p_{model}$$이 될 것이다.
주황색 상자 안의 어떠한 점을 추정하더라도 우리는 $$p_{data}$$로 학습된 $$p_{model}$$의 분포로부터 샘플링하게 되는 것이다.</p>
<p><strong>위의 과정을 프레임워크로 표현하면 다음과 같다.</strong>
<img src="https://velog.velcdn.com/images/running_learning/post/7eb49876-12de-49c7-a0f2-c089c1fc07e3/image.png" alt=""></p>
<p>우리가 정한 $$p_{model}$$이 바람직한 속성을 유지하는지 파악해보자.
실제 데이터 생성 분포 $$p_{data}$$는 다음과 같다. 
<img src="https://velog.velcdn.com/images/running_learning/post/9b60710e-76dc-4c28-9c3b-0a783325ca56/image.png" alt=""></p>
<p>그림 1-6을 보면 $$p_{model}$$은 $$p_{data}$$를 너무 단순하게 표현한 것으로 보인다. 데이터의 특성을 제대로 고려하지 못한 모델일 가능성이 크다. 
실제로는 대륙의 좌표를 의미하지만 주황상자 $$p_{model}$$은 대륙이 아닌 해양에 점이 찍힐 수도 있는 것이다. 이는 우리가 생성한 데이터가 실제 데이터를 잘 흉내내지 못한다고 볼 수 있다.
<strong>따라서 포인트 A,B,C 중 C만이 어느정도 정확하게 $$p_{data}$$를 샘플링 했다고 할 수 있다.</strong></p>
<h3 id="121-표현-학습">1.2.1 표현 학습</h3>
<p>딥러닝은 고차원의 데이터의 특성을 학습하여 결과를 도출한다. 
이는 고차원 데이터의 표현을 학습한다는 의미이다. </p>
<p>그렇다면 표현 학습(representative learning)은 무엇일까?
<strong>표현 학습이란 표현을 출력으로 사상(mapping, 대응)하는 방법뿐만 아니라 표현 자체까지도 인공지능 시스템이 기계 학습 알고리즘으로 배우게 하는 것이다.</strong></p>
<p>이 말을 조금 쉽게 이해해보자.
딥러닝을 조금 공부해본 사람이면 DNN의 구조를 알 것이다. 
classification task에서 각 feature가 input으로 들어오면 DNN에서 이를 가공하여 n-space로 표현하게 되고, 이후 linear classifier가 classification을 수행하게 된다.
가령 height, weight의 feature 값으로 인간과 고릴라를 구분하려고 한다면 이 때의 height, weight를 가공한 어떠한 space는 비교적 괜찮은 <strong>표현</strong>이 될 수 있다.</p>
<p>이를 이미지에 적용시켜보면 약간 달라진다. 자동차를 구분하는 task가 주어졌다고 하자. 이를 구분하기 위해서 픽셀 값(=h / w와 같은 의미)을 feature로 DNN에 학습하게 된다면 자동차를 잘 구분하지 못할 것이다. 
이는 자동차를 잘못 <strong>표현</strong>되어 학습된 것을 의미한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/65854989-1dbe-4608-bb2c-2470d14bf547/image.png" alt=""></p>
<p>이를 해결한 것이 CNN이다. CNN을 통해 이미지(자동차)가 가지는 어떠한 특징들을 특정 feature map으로 <strong>표현</strong>함으로써(ex 자동차 전체의 모양, 자동차 바퀴 위치 등등) 이미지가 자동차인지 아닌지 구분할 수 있게 된다.
위의 사진을 보면 특징 검출(feature extractor)가 데이터를 task에 맞게 <strong>표현</strong>을 하는 역할을 한다고 보면 된다.</p>
<h2 id="2-핵심-확률-이론">2. 핵심 확률 이론</h2>
<p>앞에서 살펴 보았듯이 생성 모델링은 확률 분포의 통계적 모델링과 관련이 매우 깊다.
따라서 생성 모델을 이해하기 위해서는 기본적인 확률 이론에 대해 공부할 필요가 있다.</p>
<ul>
<li>핵심 용어 5가지 </li>
</ul>
<ol>
<li><p><strong>표본 공간</strong>: 샘플 x가 가질 수 있는 모든 값의 집합</p>
</li>
<li><p><strong>확률 밀도 함수</strong>: 데이터 포인트 x를 0~1사이의 숫자로 매핑하는 함수 , p(x)</p>
</li>
<li><p><strong>parameter modeling(모수 모델링)</strong>: $$p_{model}(x)$$를 찾기 위해 유한한 개수의 파라미터 <em>Ɵ</em>를 사용해 기술할 수 있는 밀도 함수 $$p_{Ɵ}(x)$$의 한 종류</p>
</li>
<li><p><strong>likelihood(가능도)</strong>: 파라미터 집합 <em>Ɵ</em> 의 가능도(Likelihood)는 𝑳(<em>Ɵ</em> | x)이다. 이는 관측된 포인트 x가 주어졌을 때 <em>Ɵ</em> 의 타당성을 측정한다. (𝑳(<em>Ɵ</em> | x) = $$p_{Ɵ}(x)$$ )</p>
</li>
<li><p><strong>MLE(최대 가능도 추정)</strong></p>
</li>
</ol>
<p>확률 이론에 대한 보다 자세한 내용은 아래의 링크를 참고해주세요!
<a href="https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-3%EC%A3%BC%EC%B0%A8-2">확률이론 - 아이펠 3주차</a></p>
<blockquote>
<p>References
[1] representative learning, <a href="https://89douner.tistory.com/339">https://89douner.tistory.com/339</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Paper Review] Image style transfer using CNN]]></title>
            <link>https://velog.io/@running_learning/Paper-Review-Image-style-transfer-using-CNN</link>
            <guid>https://velog.io/@running_learning/Paper-Review-Image-style-transfer-using-CNN</guid>
            <pubDate>Tue, 05 Mar 2024 10:56:16 GMT</pubDate>
            <description><![CDATA[<p>이번 포스팅에서는 CVPR 2016에 나온 style transfer 논문을 리뷰할 예정이다.</p>
<p>해당 논문은 우리가 원하는 이미지를 원하는 그림 스타일(화풍)에 적용하는 방법을 제시한다.</p>
<p>paper: <a href="https://openaccess.thecvf.com/content_cvpr_2016/html/Gatys_Image_Style_Transfer_CVPR_2016_paper.html">https://openaccess.thecvf.com/content_cvpr_2016/html/Gatys_Image_Style_Transfer_CVPR_2016_paper.html</a></p>
<h3 id="abstract">Abstract</h3>
<p>앞서 말했듯 본 논문은 이미지의 특성을 사용하여 style transfer를 수행하는 방법을 제안한다. 이때, 이미지의 특성을 추출하기 위해 CNN구조를 사용하여 명시적인 high level information을 활용한다.
결과적으로 content 정보와 style 정보를 분리하여 재결합할 수 있는  artistic style의 neural network 알고리즘을 만들었다.
이 말은 A라는 이미지에서는 content 정보를, B라는 이미지에서는 style 정보를 추출하여 (분리하여) 재결합(recombine)하겠다는 의미이다. </p>
<p>쉽게 정리하면, CNN을 통해 이미지로부터 content / style 정보를 각각 추출하여 content에 style을 적용하는 style transfer를 수행한다.</p>
<h3 id="introduction">Introduction</h3>
<p>이전에 스타일 변환에 대한 연구는 texture transfer 연구로 시작되었다. 
원본 이미지에 texture를 합성하는 것으로 이뤄졌는데, 괄목할만한 결과를 보였지만, 역시 fundamental한 한계점이 명확하다고 한다.
그것은 low level의 image feature를 사용했다는 점이다.
따라서 high level의 feature를 사용하기 위해 CNN을 사용했다.
잘 학습된 CNN으로 high level의 feature를 활용하면, content와 style을 잘 나타낼 수 있음을 Figure 1에서 보여준다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/3426503a-cdd2-40d9-9940-3668797d6618/image.png" alt=""></p>
<p>Figure 1에서 보이듯이, content Representations는 input image가 CNN을 통과하면서 나타난 feature map의 각 층에서의 집합으로 표현된다. 
본 논문은 이를 활용하여 content와 style에 동시에 적용하도록 한다.</p>
<ul>
<li><strong>Content Reconstructions</strong>
기존의 VGG network를 구성하는 conv layer를 통과한 feature map을 사용한다. 본 논문에서는 (a)~(e)까지의 content 변환을 수행하는 데 사용된 layer는 각각 conv1_2(a), conv2_2(b), ..., conv_5_2(e)라고 한다.
깊은 층의 feature map을 사용할수록, 즉 (a)-&gt;(e)방향으로 갈수록 디테일한 픽셀 정보는 소실되지만, high level의 특징은 잘 보존된다.</li>
</ul>
<ul>
<li><strong>Style Reconstructions</strong>
input image의 화풍을 재현 및 구현하기 위해서 해당 이미지의 texture 정보를 capture 하려고 했다. 
texture 정보는 각각의 다른 feature map 끼리의 correlation을 구해 계산된다.
이 때도 역시 conv layer를 통과한 feature map을 사용하는데, content에서 사용된 feature map과 다른 점은 
층이 깊어질수록, 중복하여 사용했다는 점이다.
예를 들어, (a)에서는 conv_1, (b)에서는 conv1_1 과 conv2_1, ..., (e)에서는 conv1_1, conv2_1, conv3_1, conv4_1, conv5_1이 사용된다.</li>
</ul>
<h3 id="deep-image-representations">Deep Image representations</h3>
<p>방금 나타난 content, style reconstruction이 어떻게 수행될 수 있는지 설명하는 파트이다.
설명하기 앞서 해당 논문의 backbone network와 어떠한 기법과 tool로 모델링을 했는지 알려준다.
각 reconstruction을 위해 필요한 feature map은
16 conv + 5 pooling layer로 구성된 19개 layers를 가진 VGG network를 사용한다.</p>
<p>이미지와 위치에 대한 평균 activation이 1이 되도록 normalize를 한다.
feature map을 풀링하거나 정규화하지 않고 linear activation fuction을 조절해 output은 바뀌지 않는다.
FCN을 사용하지 않았고 Caffe framework으로 개발했으며 성능이 더 좋았던 average pooling을 사용했다고 한다.</p>
<p><strong>2.1 Content representation</strong>
network의 각 층은 non-linear filter를 쌓았으므로, image x는 CNN의 각 층을 통과하면서 이미지에 대응되는 filter들에 의해 인코딩 된다. </p>
<p>한 layer에 N​ℓ의 filter가 N​ℓ개의 Mℓ size의 feature map을 형성한다. 
따라서 layer ℓ은 다음과 같은 matrix를 store 할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/0a045b58-ee07-44e1-9939-352a5436cccd/image.png" alt=""></p>
<p>이는 layer ℓ의 activation값을 의미한다.
이미지 정보를 visualize하기 위해 white noise image를 original Image에 대응되는 feature와 맞도록 gradient descent를 실행한다.
다음 식(1)을 보면, 이게 무엇을 의미하는지 더욱 직관적으로 와닿는다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/69533840-574b-40db-bce6-4d55fdfd8219/image.png" alt=""></p>
<p>p​는 원본 이미지, x는 생성된 이미지라고 하면, P​ℓ과 F​ℓ을 각각 layer ​ℓ에서 각각 얻어진 feature representations이다.
이 두 feature representations 사이의 squared-error loss를 정의한 식이 식(1)이다.(content loss)</p>
<p>즉, 정리하자면, original 이미지와 white noise로 생성된 각각의 feature map끼리 squared-error를 최소화하여 각 feature map의 pixel값들을 비슷하게 만들겠다는 의미이다.
target image(여기서는 original image)와 X₁의 white noise image로 Xiters를 구하자는 아이디어.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/2138576f-f3a0-4819-be7a-da1f65316330/image.png" alt=""></p>
<p><strong>2.2 Style representation</strong>
Image의 style(화풍)은 추출할 image의 texture 정보를 활용한다.
앞서 언급한 것처럼 feature space(map)을 사용하는데,
각기 다른 filter response(= feature map을 사용했다)들에 대해 correlations를 구하여 이를 가능하게 했다.
feature correlations는 layer ℓ에 대한 각각의 feature map을 vectorize 하고 그 값끼리 내적 하여 구했다.</p>
<p>이러한 feature map끼리의 correlations를 Gram matrix라고 명칭했다. 
본 논문은 이 Gram matrix를 style representation이라고 한다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/202c12c0-892c-44e3-b5f7-58a94cb0c6a6/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/80303fab-03ef-48c8-99c9-75935775f4a9/image.png" alt=""></p>
<p>위 content representation과 마찬가지로, original과 white noise image가 특정 layer을 통과한 feature map의 correlation을 구하여 squared-error loss를 구하고 이 값이 최소가 되도록 한다.(= style loss) 
따라서 total loss = content loss + style loss가 된다.</p>
<p>논문에서 제안한 전체적인 task의 flow는 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/d7a98267-2494-4cc7-a80c-4b840dce928d/image.png" alt=""></p>
<p>이 전반적인 알고리즘을 이해한다면 해당 논문에 대한 아이디어와 구현 방식에 대해 이해했다고 볼 수 있을 것이다.
다만 추가된 내용은 total loss에서 각 loss에 대한 가중치 𝛂, 𝛃가 추가되었다는 점이다.
상대적으로 어떠한 loss를 더 많이 반영할지를 조절하게 해주는 hyper parameter이다.</p>
<p><strong>2.3 Style transfer</strong></p>
<p>그림 A의 화풍을 사진 P에 적용된 것을 보여준다.
feature representation의 distance를 최소화하면 style transfer가 잘 수행됨을 나타낸다. 학습 시 L-BFGS optimizer를 사용하였다고 한다.
그 결과는 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/06736c23-87ba-46b5-9a3f-37629ae51b6b/image.png" alt=""></p>
<h3 id="results">Results</h3>
<p>본 논문의 key finding은 CNN network로 contetn와 style이 잘 분리되었다는 것이다.
이를 활용하여 새로운 image를 만드는데 독립적인 representation을 사용했다.
이를 증명하기 위해 results에서 Neckar river in Tubingen, Germany의 사진과 artwork를 합성하여 보여준다.</p>
<p>이때 유의할 점은, 스타일 합성을 위한 content representation은 conv4_2의 layer의 출력 feature를 사용했으며,
style representation은 conv1_1, conv2_1, conv3_1, conv4_1, and conv5_1의 layer의 출력을 복합적으로 사용했다.
각 층에 대해 동일한 가중치로 feature를 사용했다고 한다. (wl = 1/5 in those layers, wl = 0 in all other layers)</p>
<p><strong>3.1 Trade-off between content and style matching</strong></p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/981bcc7d-522a-4d19-99dd-e17f752b4e9e/image.png" alt=""></p>
<p>합성이 완벽하게 수행될 수는 없다.
따라서 total loss를 정의할 때, 어떠한 loss에 상대적인 가중을 둘 지 정하는 것이 중요하다. content에 가중을 두면 style이 잘 합성되지 않으며, 반대의 경우 content가 잘 나타나지 않는 모습을 보인다.</p>
<p>Figure 4를 보면 content/style의 비율을 나타내는 데,
왼쪽 상단의 경우 style이 content의 10,000배 가중되는 파라미터(𝛃 = 10000 * 𝛂 )를 가질 때의 결과를 보여준다.
이는 content와 style 간의 trade-off 관계를 잘 나타내준다.</p>
<p><strong>3.2 Effect of different layers of the Convolutional Neural Network</strong></p>
<p>또 다른 중요한 요소는 layer의 어떤 층을 사용하여 feature를 활용할 것인지와 관련있다.(layer 설정과 관련된 내용)</p>
<p>style representation은 Neural Network의 여러 layer에서 multi-scale로 표현되는데 각 layer들은 local scale을 결정하고 그에 따라서 다른 결과가 나타난다.
higher layer까지 이용하게 된다면 더 큰 규모의 local image structure를 보존할 수 있고, 스타일 정보를 적절하게 바꿀 수 있다.</p>
<p>즉, higher layer의 출력까지 중복하여 사용한다면 더 자연스럽고 부드럽게 시각적인 변환을 보일 수 있는 style representation을 만들 수 있는 것이다. 따라서 본 논문은 conv1_1~conv5_1의 레이어들의 style features를 사용했다고 한다.</p>
<p>마찬가지로 content representation에 대해서도 같은 실험을 수행한 결과, lower layer에 대해서는 fine structure를 보존하는 반면 higher layer를 사용하면 detail 한 pixel정보가 유실되는 것을 볼 수 있다.
Figure 5를 보면 이를 직관적으로 확인할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/1c9061b2-391f-4097-9bac-7b483dd7db28/image.png" alt=""></p>
<p><strong>3.3 Initialisation of  gradient descent</strong></p>
<p>grdient descent를 진행할 때, 초기의 이미지를 어떻게 설정하느냐에 따라 결과가 바뀐다는 것을 실험으로 보여줬다.
<img src="https://velog.velcdn.com/images/running_learning/post/de46e9a1-19c1-4618-b0b1-5c09d895a735/image.png" alt=""></p>
<p>A는 content 이미지로부터 초기값을 설정한 경우이고 
B는 style 이미지로 초기화하여 style transfer를 수행했을 때의 결과이다.
C는 각가의 다른 random noise로 출발한 결과이다. 이 모든 결괏값이 다 다름을 알 수 있다.</p>
<p><strong>3.4 Photorealistic style transfer</strong>
그림이 아닌 사진끼리의 style transfer도 잘 수행하는 모습을 보인다는 것을 실험으로 보여준다. 밤에 찍은 뉴욕사진과 낮에 찍은 런던 사진을 1 : 100 수준으로 합성했더니 잘 합성된 것을 보여준다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/48714698-b7fa-4b84-969e-018388d87777/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모두의 연구소 - 아이펠 리서치 과정 15주차]]></title>
            <link>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-15%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-15%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 05 Mar 2024 10:13:32 GMT</pubDate>
            <description><![CDATA[<h1 id="15주차">15주차</h1>
<p>Going deeper가 끝나고 slow paper로 넘어가는 주이다.
slow paper는 논문 하나를 잡고 토론하여 이해하는 방식으로 학습이 진행된다. 마지막에 퀴즈를 품으로써 학습에 대한 정도를 파악할 수 있었다.
논문 작성하는 방법에 대한 가이드를 배우기도 했다.</p>
<p>이번주 slow paper에서는 style transfer에 대해 공부하는 시간을 가졌다.
논문 하나 보고 이해하는 데에도 시간이 오래 걸리는 데 필요한 논문을 계속 공부하고 봐야한 다는 것도 놀라운데, 더욱 놀라운 것은 새로운 개념을 딥러닝에 적용시킨 논문 저자들이 정말 대단하다고 생각하게 되었다.</p>
<blockquote>
<h2 id="15주차-paper">15주차 paper</h2>
</blockquote>
<ol>
<li>Style transfer using CNN</li>
</ol>
<p>paper: <a href="https://openaccess.thecvf.com/content_cvpr_2016/html/Gatys_Image_Style_Transfer_CVPR_2016_paper.html">https://openaccess.thecvf.com/content_cvpr_2016/html/Gatys_Image_Style_Transfer_CVPR_2016_paper.html</a></p>
<p>해당 논문은 다른 화풍의 그림을 실제 사진에 적용하여 마치 화풍의 스타일이 사진에 적용된 것 같은 결과를 도출한다.</p>
<p>보다 자세한 내용은 아래의 링크 paper review 시리즈에 작성하도록 하겠다.
<a href="https://velog.io/@running_learning/Paper-Review-Image-style-transfer-using-CNN">https://velog.io/@running_learning/Paper-Review-Image-style-transfer-using-CNN</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모두의 연구소 - 아이펠 리서치 과정 14주차]]></title>
            <link>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-14%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-14%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 05 Mar 2024 10:03:14 GMT</pubDate>
            <description><![CDATA[<h1 id="14주차">14주차</h1>
<p>Going deeper의 마지막 주차이다.
하루에 한 노드씩 보기가 슬슬 버거워 질 때 즈음 going deeper가 
마무리 돼서 다행이라고 생각했다.</p>
<p>CV에서 사용되는 대부분의 task는 다뤄본 것 같아서 나름 뿌듯하기도 했다.
그럼에도 해당 task를 완벽하게 다룰 줄 모르기 때문에 더욱더 공부해야 겠다고 다짐했다.</p>
<blockquote>
<h2 id="14주차-task">14주차 task</h2>
</blockquote>
<ol>
<li>행동 스티커 만들기 - keypoint detection</li>
<li>multi-modal 생성형 AI - Stable diffusion</li>
</ol>
<p>keypoint detection이라고 하면, 말 그대로 keypoint를 탐지하는 것이다.
예를 들어 human pose estimation(관절) 등이 있다.</p>
<p>다음으로 multi-modal은 AI에서는 다양한 데이터 형식을 의미한다. 
즉, text to image, image to text 등과 같이 다른 데이터 형식으로 모델의 결과를 보여주는 것을 의미한다.  </p>
<p>이번 Going deeper에서는 이 두 task에 대해 다뤄보았다.</p>
<h3 id="1-행동--스티커-만들기---keypoint-detection">1. 행동  스티커 만들기 - keypoint detection</h3>
<p>이번 프로젝트의 목표는 사람의 행동을 추정하는 것이다.
Human pose estimation(HPE) task이다.
HPE는 크게 2가지로 나뉜다.</p>
<ul>
<li>2D HPE </li>
<li>3D HPE</li>
</ul>
<p>2D HPE는 2D에서 2차원 좌표(x,y)를 찾는 것이고, 
3D HPE는 2D에서 3차원 좌표(x,y,z)를 찾는 것이다.
이번 포스팅에서는 2D HPE를 기준으로 다룬다.</p>
<p>이를 다루는 방법은 <strong>top-down, bottom-up</strong> 이렇게 두 가지가 있다.
<img src="https://velog.velcdn.com/images/running_learning/post/81c0b3d8-1c1e-4df1-a633-cfd8d5fc1419/image.png" alt=""></p>
<p><strong>top-down</strong> 방식은 모든 사람의 정확한 keypoint를 찾기위해 object detection을 사용한다. 이후 detect된 객체를 crop한 이미지내에서 keypoint를 찾아내어 표현한다.
다만 detector가 선행되어야 하고 모든 사람마다 detection 알고리즘을 적용 해야하기 때문에 사람이 많이 등장할 때는 느리다는 단점이 있다.</p>
<p><strong>bottom-up</strong> 방식은 detector가 없고 keypoint를 먼저 검출한다. 예를 들어 손목에 해당하는 모든 점들을 검출하는 식이다. 이후 한 사람에 대한 keypoint를 clustering해서 표현한다.
이는 detector가 필요없기 때문에 다수의 사람이 영상에 등장하더라도 속도가 크게 저하되지 않는다는 장점이 있다. 다만 clustering 방식에서 top-down에 비해 keypoint 검출 범위가 넓어지기 때문에 성능면에서 크게 저하된다는 단점이 있다.</p>
<p>얼마나 정확해야 하는지, 데이터에 사람이 얼마나 구성되어 있는지 등에 따라서 필요한 알고리즘을 사용한다.
detection에 대해 배워봤으니, top-down방식을 사용하여 HPE를 수행해보았다!
이를 수행하기 위해 <strong>Stacked Hourglass Network</strong> 모델을 사용했다.</p>
<p>Stacked Hourglass Network 이전에도 pose estimation을 위한 모델은 다양하게 등장했고 발전해왔다. 다만 이번 포스팅에서는 Stacked Hourglass Network만 다루도록 하겠다.</p>
<h3 id="stacked-hourglass-network"><strong>Stacked Hourglass network</strong></h3>
<p>StackedHourglassNetwork의 기본 구조는 모래시계 같은 모양으로 만들어져 있다. Convlayer와 pooling으로 이미지(또는 feature)를 인코딩하고upsampling layer를 통해 feature map의 크기를 키우는 방향으로decoding한다.featuremap 크기가 작아졌다 커지는 구조여서 hourglass 라고 표현한다(모래시계 형태).</p>
<p>기존방법들과의 가장 큰 차이점은 다음과 같다.</p>
<ol>
<li>feature map upsampling </li>
<li>residual connection</li>
</ol>
<p>pooling으로 image의 global feature를 찾고 upsampling으로 local feature를 고려하는 아이디어가 hourglass의 핵심이다.
이전에 downsampling 되는 feature map을 upsample layer에서 residual connet함으로서 이를 가능하게 했다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/4c05d6f9-77cb-4dde-a125-0d2d0b2dadd7/image.png" alt=""></p>
<p>자세한 코드는 아래 깃허브 링크를 참고해주세요!
<a href="https://github.com/3n952/aiffel_6/blob/main/GD08/GD08_main.ipynb">human pose estimation</a></p>
<h3 id="2-multi-modal-생성형-ai---stable-diffusion">2. multi-modal 생성형 AI - Stable diffusion</h3>
<p>멀티모달 생성형 AI는 요즘 매우 인기있고 핫한 인공지능 분야이다. 지금 AI 열풍을 불러온 장본인이기도 하다. text to image, image to video 등등의 멀티모달 생성형 AI가 계속해서 등장하고 발전하고 있는 중이다. 
그 중에서 이번에는 stable diffusion 모델을 사용하여 text to image 모델을 사용해보고 적용해보는 시간을 가졌다.</p>
<p>해당 내용은 지금 계속 공부중이므로 나중에 기회가 되면 보다 세부적인 내용으로 정리하도록 하겠다.</p>
<p>깃허브 링크: <a href="https://github.com/3n952/aiffel_6/blob/main/GD09/GD09_main.ipynb">stable diffusion 실습</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모두의 연구소 - 아이펠 리서치 과정 13주차]]></title>
            <link>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-13%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-13%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Thu, 28 Dec 2023 09:01:01 GMT</pubDate>
            <description><![CDATA[<h1 id="13주차">13주차</h1>
<p>Going deeper의 2부가 시작됐다..
12주차에 <strong>처음이자 마지막으로 있는 아이펠 방학</strong>을 지나고 맞이하는 2부여서
더 힘겹지만 열심히하려고 노력했다.</p>
<p>방학 때는 아이펠 내에서 취업에 대한 준비를 위해 개인적으로 찾아볼 수 있는 과제를 준다. 과제 수행을 위한 레퍼런스를 제공하여 취업에 대해 작게나마 고민하는 시간을 갖을 수 있어 좋았다.  방학 숙제의 개념으로 제공되지만 안해도 처벌(?)은 없다.
나는 개인적으로 잘 쉬어야 잘 공부한다는 마인드여서 실컷 놀고 왔다 ㅎㅎ</p>
<blockquote>
<h2 id="13주차-task">13주차 task</h2>
</blockquote>
<ol>
<li>End to End OCR</li>
<li>멀리 있는 사람도 스티커를 붙여주자 - Face detection</li>
</ol>
<p>두 가지 task 모두 object detection의 개념이 공통적으로 들어가기 때문에 object detection 파트를 공부하는 것이 cv에서 큰 도움이 되는 것을 다시금 느끼게 되었다. object detection을 위한 다양한 모델이 제시되었지만 나는 one-stage 모델인 yolo 계열의 모델을 주로 공부했다! 나중에 기회가 되면 따로 포스팅을 해보겠다..</p>
<h3 id="1-end-to-end-ocr">1. End to End OCR</h3>
<p><strong>이미지로부터 text detection + recognition을 한 번에 수행하는 모델을 구현하는 것이 이번 프로젝트의 목표이다.</strong></p>
<ul>
<li><p>text detection은 문장 단위 및 단어 단위의 text의 위치를 찾는 것이다.
따라서 기존의 객체 탐지를 위해 사용했던 object detection, segmentation 기법이 사용된다.
다양한 기법들이 text detection을 위해 사용되었지만 이를 일일히 소개하진 않고 <strong>&#39;EASR:An Efficient and Accurate Scene Text Detector&#39;</strong>라는 논문에서 소개된 표로 대충 이러한 게 있었구나 정도로 이해하면 된다.
<img src="https://velog.velcdn.com/images/running_learning/post/e33232d0-11a6-4cea-98a0-0aa5af355af6/image.png" alt="">
정리하자면, 단어 단위와 글자 단위의 탐지 기법이 조금 다른데</p>
</li>
<li><p><em>단어 단위의 탐지*</em>는 단어에 대한 bbox 추출을 위해 object detection의 Regression(anchor로 bounding box regression 수행)기반이, </p>
</li>
<li><p><em>글자 단위 탐지*</em>에는 글자 영역에 대한 segmentation 기반의 방법론을 사용한다고 한다.
최근에는 CRAFT, Pyramid mask Text detector 등의 모델을 사용하여 text detection을 수행한다고 한다.</p>
</li>
<li><p>text recognition은 찾은 위치에 대한 text가 무엇인지 인식하는 것을 의미한다. 인식하는 것을 구현하기 위해서는 우선 unsegmented data에 대해 이해할 필요가 있다. unsegmented data는 말 그대로 segmentation이 되어있지 않은 데이터를 의미한다. 
가령 이미지에서 &quot;you&quot;라는 단어는 &quot;y&quot;,&quot;o&quot;,&quot;u&quot;로 segmentation이 가능하여 각각 라벨링이 되어 있다면, 이는 segmented data가 될 것이다. 반대의 경우가 unsegmented data가 된다. 즉, 전체적인 라벨은 알지만 sequence를 이루는 부분들은 모르는 경우를 의미한다.(= segment되어 있지 않은 하위 데이터들 끼리 sequence를 이룬다.)
이러한 unsegmented data를 위해 CNN + RNN 모델을 같이 사용하는 방법을 고안해냈다. CNN은 강력한 image feature extractor이지만 추출된 특징으로 찾은 text가 무엇을 의미하는 지는 알 수가 없다. 반면 RNN은 강력한 sequence learner이지만, 데이터를 미리 segment 시켜야 하고, 아웃풋을 label sequence로 변환하는 사후 처리가 필요하다.</p>
</li>
<li><p><em>따라서 이 두 가지를 고려하여 추출된 feature를 map-to-sequence를 통해 sequence 형태의 feature로 변환한 후 다양한 길이의 input을 처리할 수 있는 RNN으로 넣는 CRNN 모델을 사용했다.*</em></p>
</li>
</ul>
<p>이 외에도 CTC loss를 사용하여 unsegmented data에 대해 어떤 문자일 확률이 높은지 추정하게 한다. <a href="https://www.cs.toronto.edu/~graves/icml_2006.pdf">CTC</a></p>
<p>Github: <a href="https://github.com/3n952/aiffel_6/tree/main/GD06">https://github.com/3n952/aiffel_6/tree/main/GD06</a></p>
<h3 id="2-멀리-있는-사람도-스티커를-붙여주자---face-detection">2. 멀리 있는 사람도 스티커를 붙여주자 - Face detection</h3>
<p><strong>이미지로부터 사람의 얼굴을 인식하고 특정 부위에 적용할 스티커를 탐지된 얼굴에 적용시켜보자는 것이 이번 프로젝트의 목표이다.</strong></p>
<p>one-stage object detection 모델을 위주로 face detection에 적합한 모델을 선정하기 위해, yolo와 ssd 모델 구조에 대해 공부하는 시간이 되었다.</p>
<p>Github: <a href="https://github.com/3n952/aiffel_6/blob/main/GD07/GD07_main.ipynb">https://github.com/3n952/aiffel_6/blob/main/GD07/GD07_main.ipynb</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모두의 연구소 - 아이펠 리서치 과정 12주차]]></title>
            <link>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-12%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-12%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Fri, 01 Dec 2023 01:35:39 GMT</pubDate>
            <description><![CDATA[<h1 id="12주차">12주차</h1>
<p>드디어 Going deeper의 1부가 끝나는 주이다. 그래서 해당 내용을 기반으로 새로운 task를 주는데 이를 아이펠에서는 DLthon이라고 부른다. 
어떤 major를 선택했는지에 따라 주제가 다르지만, CV에서는 segmentation task를 수행했다. </p>
<p>지난번에 main quest로 했던 motorcycle night ride dataset을 활용하여 semantic segmantation을 하는 task이기 때문에 크게 어렵지는 않았다. 
하지만 3일간 주어진 시간에 팀원들과 효율적으로 과제를 수행하는 것은 참 어려웠다. 오히려 이번 기회에 짧게나마 팀원들과 팀 스케줄 짜는 것, 협업하는 것 등에 대한 감을 잡을 수 있었던 것 같아 좋았다.</p>
<blockquote>
<h3 id="12주차-내용">12주차 내용</h3>
</blockquote>
<ol>
<li>DLthon - motorcycle night ride</li>
</ol>
<ul>
<li>DLthon github
<a href="https://github.com/3n952/aiffel_6/tree/main/DLthon">https://github.com/3n952/aiffel_6/tree/main/DLthon</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모두의 연구소 - 아이펠 리서치 과정 11주차]]></title>
            <link>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-11%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-11%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sat, 18 Nov 2023 09:01:42 GMT</pubDate>
            <description><![CDATA[<h1 id="11주차">11주차</h1>
<p>지난 주와 같이 Going Deeper라는 session으로 CV의 task를 다양하게 경험해 보고 공부하는 시간이 되었다. 논문을 가볍게 공부하고 이를 task에 적용하는 모델을 짜보는 것이 실습의 주요 목표가 되었지만, 나는 개인적으로 스스로의 힘으로 모델을 짜보기는 커녕 object detection ~ segmenation의 task의 model이 학습하는 전반적인 과정을 이해하기 힘들어서 따로 이해하는 데에 시간을 많이 할애했다.</p>
<p>개념이 어려워지다 보니 스스로 학습에 집중하지 못하는 모습을 보면서 반성을 하게 되는 주가 되기도 했다. 앞으로 어려운 내용이 계속해서 나올텐데 이런 태도로 학습한다면 
이도 저도 아니게 될 것 같아, 주말동안 마음을 다 잡고 
사소한 생활 패턴부터 학습 plan까지 큰 틀을 잡고 동기 부여하는 시간을 가졌다. </p>
<p><strong>화이팅..!</strong></p>
<blockquote>
<h3 id="going-deeper">Going Deeper</h3>
</blockquote>
<ol>
<li><p>node 10~12</p>
</li>
<li><p>node 13~15</p>
</li>
<li><p>Going Deeper node 10~12</p>
</li>
</ol>
<ul>
<li>Object Detection: 자율주행 보조 시스템
github: <a href="https://github.com/3n952/aiffel_6/tree/main/GD04">https://github.com/3n952/aiffel_6/tree/main/GD04</a></li>
</ul>
<ol start="2">
<li>Going Deeper node 13~15</li>
</ol>
<ul>
<li>Segmentation: 도로 영역 찾기
github: <a href="https://github.com/3n952/aiffel_6/tree/main/GD05">https://github.com/3n952/aiffel_6/tree/main/GD05</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모두의 연구소 - 아이펠 리서치 과정 10주차]]></title>
            <link>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-10%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-10%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sat, 18 Nov 2023 08:27:14 GMT</pubDate>
            <description><![CDATA[<h1 id="10주차">10주차</h1>
<p>대망의 10주차는 <del>기다리고 기다리던</del> Going Deeper 노드를 시작하는 주이다. 
Going deeper에서 자신의 전공 (ex. CV / NLP)을 선택하여 특정 분야에 대해 
공부할 수 있기 때문에 이 사실이 기대가 됐던 것 같다.</p>
<p>고잉디퍼는 다음과 같이 진행된다.
<strong>1. 2일에 한 프로젝트를 진행
2. 프로젝트 수행을 위한 2개 분량의 노드를 공부 및 실습하고 프로젝트를 진행하는 형식</strong></p>
<p>이틀에 한 프로젝트..? &quot;개꿀이잖아?&quot; 라고 생각했었다..
매일 프로젝트 제출을 하거나 챕터를 끝내야 한 우리로서는 
개꿀이라고 생각했지만 막상 해보니 개꿀이 아니다 ...</p>
<blockquote>
<h3 id="going-deeper">Going Deeper</h3>
<p>*<em>node 3개당 하나의 프로젝트 수행 *</em></p>
</blockquote>
<ol>
<li>node 1~3 -&gt; project 1</li>
<li>node 4~6 -&gt; project 2</li>
<li>node 7~9 -&gt; project 3</li>
</ol>
<ol>
<li>Going deeper node 1~3</li>
</ol>
<ul>
<li>backbone network의 ablation study
github: <a href="https://github.com/3n952/aiffel_6/tree/main/GD01">https://github.com/3n952/aiffel_6/tree/main/GD01</a></li>
</ul>
<ol start="2">
<li>Going deeper node 4~6</li>
</ol>
<ul>
<li>data augmentation: CutMix, Mixup 기법 사용
github: <a href="https://github.com/3n952/aiffel_6/tree/main/GD02">https://github.com/3n952/aiffel_6/tree/main/GD02</a></li>
</ul>
<ol start="3">
<li>Going deeper node 7~9</li>
</ol>
<ul>
<li>Class Activation Map: CAM, Grad-CAM
github: <a href="https://github.com/3n952/aiffel_6/tree/main/GD03">https://github.com/3n952/aiffel_6/tree/main/GD03</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모두의 연구소  - 아이펠 리서치 과정 8주차 ]]></title>
            <link>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-8%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-8%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Wed, 01 Nov 2023 14:32:57 GMT</pubDate>
            <description><![CDATA[<h1 id="8주차">8주차</h1>
<p>8주차는 지난 주에 시작한 &quot;케창딥&quot;을 계속해서 공부하는 주차였다.
하루에 한 챕터씩 공부를 하여 다음 날 퀘스트를 봐야한다.
한 챕터에 해당하는 양이 은근 많고, 챕터가 진행될 수록 내용이 어려워지기 때문에 이해하는 데에 시간이 더더욱 많이 걸렸다...</p>
<blockquote>
<h2 id="케라스-창시자에게-배우는-딥러닝">케라스 창시자에게 배우는 딥러닝</h2>
<p>chapter 4 ~ 8</p>
</blockquote>
<h3 id="chapter-4-신경망-시작하기-분류--회귀">chapter 4. 신경망 시작하기: 분류 / 회귀</h3>
<p>4장에서는 신경망이 어떻게 구성되는 지에 대해 간단하게
예제를 통해 알아보게 되었다.
이전 &quot;Exploration&quot;노드나, &quot;딥러닝 한 번에 끝내기&quot; 노드에서 
한 번씩은 했거나 적어도 데이터 셋은 한 번 이상은 봤다.</p>
<p>IMDB, Reusters, Boston housing dataset을 이용하여 
<strong>영화 감성 분류(이진 분류), 뉴스 토픽 분류(다중 분류), 주택 가격 예측(회귀)</strong> 의 문제를 
해결하는 task가 주어진다. 
각 문제들은 분류, 회귀 문제에서 아주 클래식하고 기본적인 문제이기 때문에
이를 토대로 딥러닝에 첫 걸음을 내딛는데에 큰 도움이 될 것 같다!</p>
<p>각각에 대해 설명과 코드를 깃허브에 올려뒀다!
<a href="https://github.com/3n952/DL_study/tree/main/keras_deep">케창딥 리뷰 깃허브 </a></p>
<h3 id="chapter-5-머신-러닝의-기본-요소">chapter 5. 머신 러닝의 기본 요소</h3>
<p> 5장은 머신 러닝에서 중요한 최적화, 일반화에 대해 다루는 챕터였다.
 <strong>최적화</strong>란 훈련 데이터에서 최고의 성능을 얻기 위해 train되는 과정을 의미한다. 
 반면 <strong>일반화</strong>는 훈련된 모델에서 사용되지 않은 즉, 새로운 데이터에 대해서 얼마나 좋은 성능으로 예측하는지를 의미한다.</p>
<p> 케창딥의 표현을 빌리자면 
 <strong>&quot;머신 러닝은 최적화와 일반화 사이에서 줄다리기를 하는 것과 같다&quot;</strong> 라고 한다. </p>
<p> 결국 머신 러닝의 목표는 일반화의 성능을 높이는 것이지만 일반화 성능만 높이는 기법은 없다. 다만, 훈련 데이터에서 학습된 모델으로 새로운 데이터를 맞추는 일을 할 뿐이다. 여기서 <strong>과소적합과 과대적합</strong>의 개념이 등장한다.</p>
<p> <strong>과소적합</strong>은 모델이 아직 개선될 여지가 있는 상태에서 학습이 끝난 것을 의미하고, <strong>과대적합</strong>은 너무 훈련 데이터에 꼭 맞도록 모델이 학습한 경우를 의미한다. 아래의 그림을 보면 이해하기가 직관적으로 이해할 수 있다.</p>
<p> <img src="https://velog.velcdn.com/images/running_learning/post/0cae804f-0c05-4d4b-b4cd-83ed277dd665/image.png" alt=""></p>
<p>줄다리기라는 표현을 한 것이 여기서 드러난다.
best fit의 부분(sweet spot)을 보면, 
<strong>training error가 낮아</strong>지면서, <strong>test error가 높아지기 시작</strong>하는 지점임을 알 수 있다.</p>
<p>어떠한 요소가 과대적합을 유발하는 것일까?</p>
<ol>
<li>잡음 섞인 데이터 - 이상치 다루기</li>
<li>불확실한 특성 - 입력으로 들어오는 특성의 불확실성
<em>ex) 바나나 -&gt; 덜 익은 바나나 / 다 익은 바나나는 무슨 기준으로 나눌까?</em></li>
<li>드문 특성과 가짜 상관관계 - 드문 특성이 있거나, 가짜 상관관계가 있는 데이터가 입력으로 들어오면 그 특성과 상관관계가 훈련에 크게 기여하게 된다.</li>
</ol>
<p>이를 해결하고자 <strong>특성 선택(feature selection)</strong>을 수행한다.</p>
<p>일반화의 본질은 <strong>매니폴드 가설</strong>에서 시작된다. 
매니폴드 가설 공간에서 <strong>데이터 보간</strong>(interpolation)을 통해
우리가 예측한 값들이 적절히 매핑될 수 있도록 하는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/fdf688a6-f7cf-40cf-b0f6-0a579f6b3c68/image.png" alt=""></p>
<p>그렇다면 딥러닝 모델의 평가는 어떻게 할 수 있을까?
정답은 <strong>훈련, 검증, 테스트 세트로 데이터 세트를 분할</strong> 하는 것이다.
일반화 성능을 신뢰있게 측정하기 위해 훈련 데이터는 훈련에만 사용하고, 
최종적으로는 테스트 데이터로 이를 검증하는 것이다.</p>
<p>검증 세트는 테스트 데이터의 역할을 학습 iter마다 
수행할 수 있도록 하는 데이터 세트이다.
하지만 검증 세트를 통해 성능을 파악하고 이를 토대로 모델 튜닝을 하다보면 <strong>정보 누설(information leak)</strong>의 문제가 발생한다.
정보 누설로 인해 검증 세트에 대해 
어느정도 과대적합이 되는 모습을 보일 수 있는 것이다.
<strong>이를 해결하고자, 홀드 아웃 검증이 나타났다.</strong></p>
<p><strong>k-fold cross validation</strong>이 홀드 아웃 검증이 가장 대표적이다.
<img src="https://velog.velcdn.com/images/running_learning/post/a7897cda-1669-4e0a-a1e8-bfca1af8c0e7/image.png" alt=""></p>
<p>이렇게 최적의 성능을 보이게 하기 위해서 다음과 전반적으로 같은 방법이 필요하다.</p>
<p>-훈련 성능 향상-</p>
<ol>
<li>파라미터 튜닝</li>
<li>모델 구조에 대한 더 나은 가정</li>
<li>모델 용량 늘리기</li>
</ol>
<p>-일반화 성능 향상-</p>
<ol>
<li><p>데이터 큐레이션</p>
</li>
<li><p>특성 공학</p>
</li>
<li><p>조기종료</p>
</li>
<li><p>모델 규제 : L1, L2 / dropout</p>
<h3 id="chapter-6-일반적인-머신-러닝-워크플로">chapter 6. 일반적인 머신 러닝 워크플로</h3>
<p>머신 러닝 프로젝트를 기획하고 실행할 때, 어떠한 것들을 염두해 두어 중점 사항으로 체크해야 하는 지에 대해 잘 설명해준다. 천천히 읽기만 해도 이해가 되는 부분이 많기 때문에 이를 잘 정리한 블로그를 첨부하고 마무리하겠다!
<a href="https://sanmldl.tistory.com/51">chapter 6 blog</a></p>
</li>
</ol>
<h3 id="chapter-7-케라스-완전-정복">chapter 7. 케라스 완전 정복</h3>
<p>케라스 모델을 만드는 다양한 방법에 대해 공부하는 챕터였다.</p>
<ol>
<li>sequential api</li>
<li>functional api</li>
<li>subclassing api</li>
</ol>
<p>이것들은 이론적인 것들 보다는 코드를 직접 보면서 이해하는 것이 중요했다.
이에 대한 코드를 깃허브에 정리했다.
<a href="https://github.com/3n952/DL_study/tree/main/keras_deep">케창딥 리뷰 깃허브 </a></p>
<h3 id="chapter-8-컴퓨터-비전을-위한-딥러닝">chapter 8. 컴퓨터 비전을 위한 딥러닝</h3>
<p>8장에서는 합성곱 신경망으로 컴퓨터 비전(CV) 관련 문제를 설명하고,
그 예시를 보여준다.
합성곱 신경망 즉 convnet에서 합성곱 연산이 갖는 의미가 무엇일까?
간단하게 요약하면 다음과 같을 것이다.</p>
<p><strong>1. 합성곱 연산을 통해 학습된 패턴은 평행 이동 불변성을 가진다.
2. 합성곱 연산 기반의 network는 공간적 계층 구조를 학습할 수 있다.</strong></p>
<p><strong>평행 이동 불변성</strong>을 쉽게 설명하면, 어떠한 패턴을 갖는 특징은 다른 위치에서 나타나도 이를 인식할 수 있게하는 성질을 의미한다. Fully connected layer에서는 새로운 위치에서의 패턴은 새로운 패턴으로 인식하기 때문에 평행 이동 불변성이 없다고 할 수 있다.</p>
<p><strong>공간적 계층 구조</strong>는 네트워크의 밑단부터 시작해서 깊어질수록 합성곱 신경망이 표현하는 범위가 계층 구조를 갖는 다는 것을 의미한다. 예를 들어 사람의 이미지에서 밑단에서 사람 얼굴의 선, 모양, 질감과 같은 패턴을 학습하면, 더욱 깊어지면서 얼굴의 눈, 코, 입의 패턴을 인식하는 것과 같다.</p>
<p>케창딥에서는 고양이를 예시로 들었다. 아래의 그림을 보면 직관적으로 이해하기 쉽다.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/f9fb0e9e-bbba-4c54-a10f-2fc99858b8ff/image.png" alt=""></p>
<p>그렇다면 합성곱 연산의 계산 과정은 어떻게 될까?
합성곱 연산의 계산 과정을 이해하기 위해서는 몇가지 요소의 개념을 알 필요가 있다.</p>
<ul>
<li>filter(필터)</li>
<li>feature map(특성 맵)</li>
<li>padding(패딩)</li>
<li>stride(스트라이드)</li>
</ul>
<p>이를 기반으로 합성곱 연산에 대해 설명한 블로그 포스팅을 첨부하겠다!
<a href="https://sanmldl.tistory.com/28">합성곱 연산</a></p>
<p>이 개념을 바탕으로 사전 훈련된 모델을 사용하여 얼마나 효율적으로 모델 예측을 수행할 지에 대한 예시가 코드와 함께 설명되어 있다.
이 부분은 개념적인 것도 중요하지만 코드를 보는 것이 이해하기에 훨~씬 용이하다고 판단 되어 깃허브 주소를 올리도록 하겠다!
<a href="https://github.com/3n952/DL_study/tree/main/keras_deep">convnet model training code repo</a></p>
<blockquote>
<p>출처</p>
</blockquote>
<ol>
<li>과대적합, 과소적합 그래프: 
<a href="https://heytech.tistory.com/125">https://heytech.tistory.com/125</a></li>
<li>데이터 보간 예시 그림:
<a href="https://velog.io/@xuio/TIL-Data-Manifold-%ED%95%99%EC%8A%B5%EC%9D%B4%EB%9E%80">https://velog.io/@xuio/TIL-Data-Manifold-%ED%95%99%EC%8A%B5%EC%9D%B4%EB%9E%80</a></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[모두의 연구소 - 아이펠 리서치 과정 7주차]]></title>
            <link>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-7%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@running_learning/%EB%AA%A8%EB%91%90%EC%9D%98-%EC%97%B0%EA%B5%AC%EC%86%8C-%EC%95%84%EC%9D%B4%ED%8E%A0-%EB%A6%AC%EC%84%9C%EC%B9%98-%EA%B3%BC%EC%A0%95-7%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 23 Oct 2023 06:38:01 GMT</pubDate>
            <description><![CDATA[<h1 id="7주차">7주차</h1>
<p>7주차는 <strong>&quot;딥러닝 한 번에 끝내기&quot;</strong> 라는 노드를 2일만에 끝내고, <strong>&quot;케라스 창시자에게 배우는 딥러닝&quot;</strong> (이하 케창딥) 이라는 딥러닝 책을 공부하기 시작하는 주이다. </p>
<p><strong>&quot;딥러닝 한 번에 끝내기&quot;</strong> 노드는 이틀만에 딥러닝 학습을 개괄적으로 다룬다. 개인적으로 크게 도움이 된 느낌은 아니였다. 그 이유는 이미 fundamental과 exploration 노드를 경험한 이후에 해당 노드가 진행되는데 그 내용이 비교적 부실하다고 생각했기 때문이다. 그래도 딥러닝 내용을 전반적으로 복습, 리마인드하는 것은 좋았다.</p>
<p>이후 <strong>&quot;케창딥&quot;</strong>은 이번 주에 chapter 2개 분량에 대해 공부를 했다. 
케라스 API내부의 각각의 모듈이 <strong>&quot;코드적으로&quot;</strong> 어떻게 구성되어 있고 어떠한 역할을 하는 지, 그 기초적인 내용에 대해 알 수 있어서 <del>학습에 흥미가(사실 없음) 있었다</del>.
개인적으로 케창딥이 2회독째 인데, 첫 번째로 볼 때와는 다르게 보이는 것이 많아진 느낌이여서 나름(?) 뿌듯했다.</p>
<blockquote>
<h3 id="딥러닝-한-번에-끝내기">딥러닝 한 번에 끝내기</h3>
</blockquote>
<ol>
<li>텐서의 표현과 연산</li>
<li>딥러닝 구조와 모델 학습</li>
<li>규제</li>
<li>가중치 초기화와 배치 정규화</li>
<li>간단한 딥러닝 프로젝트</li>
</ol>
<blockquote>
<h3 id="케라스-창시자에게-배우는-딥러닝">케라스 창시자에게 배우는 딥러닝</h3>
</blockquote>
<ol>
<li>Chapter 2. 신경망의 수학적 구성 요소</li>
<li>Chapter 3. keras와 tensorflow 소개</li>
</ol>
<h3 id="1-딥러닝-한-번에-끝내기">1. 딥러닝 한 번에 끝내기</h3>
<h4 id="11-텐서의-표현과-연산">1.1 텐서의 표현과 연산</h4>
<p>딥러닝 기반의 학습이 이뤄질 때 keras, pytorch 모두 data container로서 tensor를 사용한다. tensor의 rank와 dimension을 이해하고 각 경우의 shape를 공부했다. 
<strong>ex) rank 1 tensor =&gt; vector</strong></p>
<p>아래의 그림을 참고하자!
<img src="https://velog.velcdn.com/images/running_learning/post/5cc53db4-148d-41e4-9cd2-34a5828adff1/image.png" alt="tensor per rank"></p>
<p>이를 텐서 표현으로 나타내기 위해서 
상수는 tf.constant(), 변수는 tf.Variable()을 사용하여 나타낸다. 
기본적으로 변하지 않는 값 즉, 상수로 tensor를 표현하지만 우리는 학습을 통해 가중치를 업데이트 하는 것이 필요하므로, 이 때 변수 tf.Variable()을 사용해준다. 
실제로 tf.contant()의 요소를 바꾸거나 수정할 수 없다!</p>
<p>텐서 표현을 위해서 텐서 객체를 만들 때, 텐서의 요소와 데이터 타입을 정해줄 필요가 있다. 데이터 타입은 아래의 표에서 확인하자.</p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/81afb5df-114c-40b3-afd7-5ffd8ca103a4/image.png" alt=""></p>
<p>또한 각 텐서끼리의 여러가지 연산을 지원한다. 
위의 내용을 예시 코드와 표를 보고 이해해보자. </p>
<pre><code class="language-python">#rank 2 tensor
t = tf.constant([[1, 2, 3],[4,5,6]]) 
print(t)
print(tf.rank(t))

# dtype 지정
f16 = tf.constant(2., dtype=tf.float16)
print(f16)

#텐서 타입 변환. tf.cast()
f32 = tf.cast(f16, tf.float32)
print(f32)

#텐서 형상 변환. tf.reshape()
x = tf.constant([[1], [2], [3]])
print(x)
print(x.shape)

y = tf.reshape(x, [1, 3])
print(y)
print(y.shape)

#텐서 전치 tf.transpose()
print(y)
print(tf.transpose(y))
print(y.shape)</code></pre>
<h4 id="12-딥러닝-구조와-모델-학습">1.2 딥러닝 구조와 모델 학습</h4>
<p>케라스에서 제공하는 API들의 구성도를 살펴보면, 크게 Model API와 Layer API가 있고 필요한 모듈들을 Modules API를 호출해서 사용하는 구조이다.
구성도는 다음과 같이 이해할 수 있다.
<img src="https://velog.velcdn.com/images/running_learning/post/2ef624b5-25e6-4fac-a3e6-9548f406a1b4/image.png" alt="케라스 구성도"></p>
<ul>
<li>Layer API
케라스의 Layer API를 사용하여 모델의 층을 쉽고 편하게 구성할 수 있다.
가장 기본이 되는(범용성이 큰) 것은 Input, Dense, Flatten, Activation 객체를 만들 때 사용하는 것이다. 
이는 직접 코드로 보는 것이 이해하기가 수월하다고 생각한다.
각각을 코드로 구현하면 다음과 같다.<pre><code class="language-python">import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
</code></pre>
</li>
</ul>
<p>#input 객체
keras.Input(shape=(28, 28), dtype=tf.float32)</p>
<p>#Dense 객체
layers.Dense(10, activation=&#39;relu&#39;, name=&#39;Dense Layer&#39;)</p>
<p>#Flatten 객체
inputs = keras.Input(shape=(28, 28, 1))
layer = layers.Flatten(input_shape=(28, 28, 1))(inputs)</p>
<p>#Activation 객체
layer = layers.Activation(&#39;sigmoid&#39;)
layer = layers.LeakyReLU()</p>
<p>```</p>
<ul>
<li>모델 학습: 손실 함수, 옵티마이저, 학습
딥러닝 모델을 학습시킬 때 손실 함수, 옵티마이저가 필요하다.
손실 함수와 옵티마이저에 어떤 것들이 있고 무슨 역할을 하는 지 알게되었다.
일일히 설명하기에는 스압!주의가 될 것이기 때문에, model의 구조를 정의하고 compile시에 손실 함수와 옵티마이저를 적용시키는 것만 기억하자!</li>
</ul>
<p><img src="https://velog.velcdn.com/images/running_learning/post/7223b64c-00ba-4a41-bf03-b3090f4fbb66/image.png" alt="학습 flow"></p>
<pre><code>              데이터 입력 -&gt; 모델 생성 -&gt; 모델 학습 -&gt; 예측 결과</code></pre><h4 id="13-규제">1.3 규제</h4>
<p>딥러닝 한 번에 끝내기는 과대 적합(overfitting)을 방지하기 위해 
다양한 규제 방법을 소개해준다. </p>
<ol>
<li>파라미터 수를 적절히 조절하기(층 깊이, 수 증가/감소)</li>
<li>L1/L2 regularization</li>
<li>Dropout</li>
</ol>
<p>L1/L2에서 중요한 개념은 손실 함수에 파라미터의 L1 / L2의 값을 더해줌으로써 손실함수이 최소화되는 방향만 고려하는 것이 아니라,
추가적으로 파라미터 값이 크게 안 커지도록 하는 방향을 추가해주는 것이다.
L2규제가 이상치에 더욱 robust하게 작용한다고 한다..!</p>
<p>-L1 regularization loss
<img src="https://velog.velcdn.com/images/running_learning/post/fd31aa9c-6584-436d-8bac-628b1001918d/image.png" alt=""></p>
<p>-L2 regularization loss
<img src="https://velog.velcdn.com/images/running_learning/post/7d657dcb-2ae7-40ed-894c-ab936528fb36/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/running_learning/post/05ddf18c-95e2-426f-bb01-70f787656165/image.png" alt=""></p>
<p>dropout은 순전파 방향에서 활성화 할 노드의 개수나 층을 설정하는 것이다.
이를 통해 과적합을 막는 것이다.
<img src="https://velog.velcdn.com/images/running_learning/post/59c86e25-dd72-438e-b237-1c72a4afeb5e/image.png" alt=""></p>
<p>각 규제가 어떻게 작용하길래 과적합을 방지하는 것인지는 따로 포스팅을 할 예정이다.</p>
<h4 id="14-가중치-초기화와-배치-정규화">1.4 가중치 초기화와 배치 정규화</h4>
<p>가중치 초기화는 말 그대로 가중치의 초기화에 대한 것을 건드리는 것을 의미한다.</p>
<p>만약 가중치의 값이 일부 값으로 치우치게 된다고 생각해보자.
순전파 방향으로 노드를 지나가는 동안 활성화 함수를 통과한 값들도 치우치게 되고, 결국 표현할 수 있는 신경망의 수가 적어지는 문제가 발생한다.
활성화 함수에 따라 추정되는 값들의 분포를 보면 이해하기가 쉽다.
가령 다음과 같은 표로 이해할 수 있을 것이다.
<img src="https://velog.velcdn.com/images/running_learning/post/f183846c-79b8-447c-87e8-2c8623fb14e0/image.png" alt=""></p>
<p>결과적으로는 모델의 활성화 값이 골고루 분포 되는 것이 중요하다.</p>
<h4 id="15-간단한-딥러닝-프로젝트">1.5 간단한 딥러닝 프로젝트</h4>
<p>딥러닝 한 번에 끝내기 실습을 총망라하여 세 가지의 아주아주 간단한 프로젝트를 진행하였다.</p>
<p>github repo:
<a href="https://github.com/3n952/aiffel_6/tree/main/10_project">간단한 딥러닝 프로젝트</a></p>
<hr>
<h3 id="2-케라스-창시자에게-배우는-딥러닝">2. 케라스 창시자에게 배우는 딥러닝</h3>
<h4 id="chapter-2-신경망의-수학적-구성-요소">Chapter 2. 신경망의 수학적 구성 요소</h4>
<p>신경망에서 사용하는 텐서와 그 연산에 대해서 공부하는 챕터였다.
특히 개인적으로 텐서 연산의 도함수로 그레이디언트를 계산할 때, 
TF 내에서 어떻게 코드적으로 처리하는 지 궁금했는데 이게 어느정도 해결이 된 것 같다.(tf.GradientTape())</p>
<p>추가적으로 텐서 연산의 기하학적 해석에 대해 그루 분들과 다양한 얘기를 나누면서 모델이 어떻게 데이터 포인터를 설명하고자 하는 지 상상할 수 있게 되었다..!
<del>(맞게 상상하는 지는 모름 ㅋㅋ)</del></p>
<h4 id="chapter-3-keras와-tensorflow-소개">Chapter 3. keras와 tensorflow 소개</h4>
<p>텐서 객체를 생성하고 케라스 API에서 내부적으로 어떤 일이 일어나는 지 파악하는 챕터였다. 
간단하게 정리하자면 핵심은 keras에 다양한 모듈이 있는데, 
<strong>모델의 층 객체를 기준으로 layer 클래스가 가중치를 어떻게 저장하고, 어떻게 입출력의 크기를 추론하는 지</strong>에 대해 알 수 있었다는 것이다.</p>
<p>챕터2,3에서 실습한 코드는 아래 레포에 올려뒀다.
<a href="https://github.com/3n952/DL_study/tree/main/keras_deep">https://github.com/3n952/DL_study/tree/main/keras_deep</a></p>
<blockquote>
<h3 id="references">references</h3>
</blockquote>
<ol>
<li>가중치 초기화 figure(작은 난수) 
<a href="https://velog.io/@cha-suyeon/DL-%EA%B0%80%EC%A4%91%EC%B9%98-%EC%B4%88%EA%B8%B0%ED%99%94Weights-Initialization">https://velog.io/@cha-suyeon/DL-%EA%B0%80%EC%A4%91%EC%B9%98-%EC%B4%88%EA%B8%B0%ED%99%94Weights-Initialization</a></li>
</ol>
]]></description>
        </item>
    </channel>
</rss>