<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Share_My_Note</title>
        <link>https://velog.io/</link>
        <description>Vision_NLP</description>
        <lastBuildDate>Mon, 15 Jul 2024 14:24:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Share_My_Note</title>
            <url>https://images.velog.io/images/noooooh_042/profile/597b3431-ba8a-4aa0-9b80-c66bb049ea03/s.PNG</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Share_My_Note. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/noooooh_042" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[산술부호화(Arithmetic coding)]]></title>
            <link>https://velog.io/@noooooh_042/%EC%82%B0%EC%88%A0%EB%B6%80%ED%98%B8%ED%99%94Arithmetic-coding</link>
            <guid>https://velog.io/@noooooh_042/%EC%82%B0%EC%88%A0%EB%B6%80%ED%98%B8%ED%99%94Arithmetic-coding</guid>
            <pubDate>Mon, 15 Jul 2024 14:24:36 GMT</pubDate>
            <description><![CDATA[<p>산술 부호화는 주어진 메시지를 더 작은 비트 시퀀스로 압축하는 엔트로피 부호화 방법 중 하나
이 방법은 메시지 전체를 하나의 숫자로 표현하여, 기호의 빈도에 따라 효율적으로 데이터를 압축합니다. </p>
<ol>
<li>기호의 확률</li>
</ol>
<ul>
<li><p>메시지를 구성하는 각 기호의 출현 확률을 계산한다.</p>
<ul>
<li>이 확률은 기호의 빈도를 기반으로 하며, 기호가 자주 나타날수록 낮은 비트 수로 표현될 수 있다. 예를 들어, 문자열 &quot;ABABAC&quot;에서 각 기호의 확률은 다음과 같이 계산된다.</li>
</ul>
<p>P(A) = 3/6 = 0.5
P(B) = 2/6 ≈ 0.333
P(C) = 1/6 ≈ 0.167</p>
</li>
</ul>
<ol start="2">
<li>구간 할당</li>
</ol>
<ul>
<li><p>초기 구간 [0, 1) 내에서 각 기호의 확률에 비례하여 구간을 할당합니다. </p>
<ul>
<li><p>앞서 계산한 확률을 바탕으로 구간을 할당하면 다음과 같다.</p>
<p>  &#39;A&#39;는 [0, 0.5)
  &#39;B&#39;는 [0.5, 0.833)
  &#39;C&#39;는 [0.833, 1)</p>
</li>
</ul>
</li>
</ul>
<ol start="3">
<li><p>산술 부호화 과정</p>
<p>초기화
초기 구간을 [0, 1)로 설정함.
이는 전체 메시지를 표현할 수 있는 범위임.</p>
<p>메시지 인코딩 </p>
<ul>
<li>메시지의 각 기호에 대해 다음 단계를 반복</li>
<li>현재 구간을 기호의 확률에 따라 세분화</li>
<li>현재 구간을 해당 기호의 하위 구간으로 업데이트</li>
</ul>
</li>
</ol>
<ol start="4">
<li><p>예제: &quot;AB&quot; 인코딩 과정
 기호 &#39;A&#39;, &#39;B&#39;, &#39;C&#39;의 확률이 각각 0.5, 0.333, 0.167이라고 가정하고, 메시지 &quot;AB&quot;를 인코딩함.</p>
<p> 4.1 초기 구간 설정</p>
<ul>
<li>초기 구간: [0, 1)</li>
</ul>
<p> 4.2 첫 번째 기호 &#39;A&#39; 처리</p>
<ul>
<li>&#39;A&#39;의 구간은 [0, 0.5)</li>
<li>현재 구간을 [0, 0.5)로 업데이트</li>
</ul>
<p> 4.3 두 번째 기호 &#39;B&#39; 처리
 &#39;B&#39;의 구간은 [0.5, 0.833) //
   현재 구간 [0, 0.5) 내에서 &#39;B&#39;가 차지하는 비율을 계산:
   하위 구간 [0.25, 0.4165)
   계산 과정 : [0 + 0.5 x 0.5, 0 + 0.5 x 0.833) = [0.25, 0.4165)
   최종 구간은 [0.25, 0.4165)임.
 이 구간 내의 어떤 숫자 (예: 0.25)를 부호화된 값으로 사용함</p>
</li>
<li><p>복호화 과정
복호화는 부호화의 역과정으로, 부호화된 값을 사용하여 원래 메시지를 복원함
 초기 구간을 [0, 1)로 설정하고, 부호화된 값을 포함하는 하위 구간을 찾음
 하위 구간에 따라 기호를 결정하고, 현재 구간을 그 기호의 구간으로 업데이트.
 이 과정을 반복하여 원래 메시지를 복원함.
 예를 들어, 부호화된 값이 0.25라면:
 초기 구간: [0, 1)
 값 0.25가 포함된 첫 번째 하위 구간은 [0, 0.5) → 기호 &#39;A&#39;
 구간을 [0, 0.5)로 업데이트
 값 0.25가 포함된 두 번째 하위 구간은 [0.25, 0.4165) → 기호 &#39;B&#39;
 복호화된 메시지는 &quot;AB&quot;임.</p>
</li>
<li><p>장점과 단점</p>
</li>
</ol>
<ul>
<li>장점<ul>
<li>높은 압축률: 기호의 출현 확률에 따라 최적화된 압축을 제공하여 효율적임</li>
<li>유연성: 고정된 코드 길이가 없기 때문에 다양한 데이터에 적용 가능함</li>
<li>실시간 압축: 스트림 데이터 압축에 적합하여 실시간으로 데이터를 압축할 수 있음</li>
</ul>
</li>
<li>단점<ul>
<li>복잡성: 구현이 상대적으로 복잡하며, 특히 부동소수점 연산의 정확도가 중요함.</li>
<li>성능 문제: 매우 긴 메시지에 대해 성능이 떨어질 수 있으며, 부동소수점 연산의 정밀도에 따라 오류가 발생할 수 있음.</li>
</ul>
</li>
</ul>
<ol start="6">
<li>결론
산술 부호화는 높은 압축률을 제공하는 강력한 데이터 압축 기법임. 기호의 확률에 따라 구간을 분할하여 메시지를 효율적으로 압축하는 이 방법은 무손실 압축을 위해 다양한 분야에서 사용됨. 구현의 복잡성에도 불구하고, 이미지 압축(JPEG), 비디오 압축(MPEG), 텍스트 압축 등 다양한 응용 분야에서 널리 활용됨.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dzip(deepzip v2)]]></title>
            <link>https://velog.io/@noooooh_042/Dzipdeepzip-v2</link>
            <guid>https://velog.io/@noooooh_042/Dzipdeepzip-v2</guid>
            <pubDate>Sat, 28 May 2022 09:03:28 GMT</pubDate>
            <description><![CDATA[<h1 id="인공-지능-기반-범용-압축-모델-dzip">인공 지능 기반 범용 압축 모델 Dzip</h1>
<ul>
<li>Deepzip의 두번째 버전인 Dzip
첫번째 버전 출처 : <a href="https://github.com/mohit1997/DeepZip">https://github.com/mohit1997/DeepZip</a>
두번째 버전 출처 : <a href="https://github.com/mohit1997/Dzip-torch">https://github.com/mohit1997/Dzip-torch</a></li>
</ul>
<h2 id="abstract">abstract</h2>
<ul>
<li>확률적 데이터 모델링을 따르는 예측 기반 인코딩(무손실 압축 모델)</li>
<li>Dzip은 예측을 위한 신경망과 산술 코딩으로 모델링한 시퀀셜 데이터 압축기이다.</li>
<li>Dzip은 하이브리드 아키텍처를 가지고 있는데 적응형과 세미-적응형(반적응형) 학습을 기반으로 한다.</li>
<li>기존의 신경망 기반의 압축기들과는 달리, Dzip은 추가적인 학습 데이터가 필요하지 않고 특정 데이터에 제한되지 않는다.</li>
<li>Gzip(평균 29% 크기 감소), 7zip(평균 12% 크기 감소)와 같은 범용 압축기보다 뛰어났으며, 특수 압축기와 비슷한 성능을 보여준다.</li>
<li>Dzip의 한계는 인코딩/디코딩 속도가 느리다는 것이다.</li>
<li>코드 출처 : <a href="https://github.com/mohit1997/Dzip-torch">https://github.com/mohit1997/Dzip-torch</a></li>
</ul>
<h2 id="dzip-모델의-기여">Dzip 모델의 기여</h2>
<ul>
<li>입력 파일을 바이트 스프림으로 다루며 추가적인 학습 데이터 셋이 필요하지 않다.</li>
<li>기존 신경망 기반 압축기와 다르게 알파벳 크기에 관계없이 모든 데이터를 압축할 수 있는 독자적인 압축기이다.</li>
<li>하이브리드 학습(적응형 및 세미 적응형) 접근 방식 사용한다.</li>
<li>여러 도메인의 데이터를 압축해보았는데 Gzip보다 평균 29%, LSTM-Compress보다 33%, 7zip 보다 12%, BSC 보다 8% 개선됨을 확인하였다.</li>
<li>state-of-art인 신경망 기반 압축기 CMIX와 NNCP 비교하면, Dzip이 CMIX보다 3~4배 빠르고 NNCP보다 4배 빠른 동시에 비슷한 성능을 보여준다. </li>
<li>특정 합성 데이터셋(엔트로피)에서 다른 압축기들보다 뛰어난 성능을 보여준다.</li>
</ul>
<h2 id="배경">배경</h2>
<ul>
<li>예측 모델 다음에 산술 코더로 구성된 통계적 코딩 접근법이다.</li>
<li>알파벳 <em>S</em> 로 데이터 스트림 S^N = {S1, S2, S3 ... SN} 을 무손실 압축한다.</li>
<li>확률 모델의 목적은 시퀀스 S^N에 대해, r 번째 Sr 부호의 조건부 확률 분포를 추정하는 것이다.</li>
<li>Sr은 이전까지 관찰된 K 부호를 기반 P(Sr | Sr-1 ... Sr-K) 확률 추정이다.</li>
<li>이 확률 추정과 Sr은 산술 코더 블록으로 들어가며 반복적으로 상태가 업데이트된다.</li>
<li>이러한 접근법은 압축된 사이즈의 크기와 크로스 엔트로피 로스(cross entropy loss)가 같아지게 된다.
<img src="https://velog.velcdn.com/images/noooooh_042/post/6bfea961-bc30-46e8-83c6-93135880acc2/image.png" alt=""></li>
<li>위 식에서 |S|는 알파벳 사이즈이며, y, y&#39;는 원핫 인코딩된 정답값과 예측된 확률값이며 N은 시퀀스 길이이다.</li>
<li>확률을 추정하는 모델은 크로스 엔트로피 로스(cross entropy loss)를 최소화하기 위해 학습된다. 확률을 추정하는 모델을 학습시키는 3가지 방식이 있다.</li>
</ul>
<h3 id="확률-추정-모델-학습-방법">확률 추정 모델 학습 방법</h3>
<ul>
<li><p>정적(static) : 외부 훈련 데이터를 가지고 훈련되어지고 압축과 압축 해제에 사용된다. 성능은 모델의 일반화 능력에 의존한다. 이 접근법은 비슷한 훈련 데이터가 가능한 경우에만 사용된다.</p>
</li>
<li><p>적응형(adaptive) : 압축과 압축 해제가 시퀀스에 적응하며 업데이트되는 랜덤으로 초기화된 모델이다. 이 접근법은 학습하는 데이터의 유효성을 요구하지 않으며 작은 모델에서는 잘 작동한다. 그러나 큰 모델에서는 변화하는 통계에 빠르게 적응하기 어렵다.</p>
</li>
<li><p>세미 적응형(반적응형:semi-adaptive) : 입력 시퀀스를 기반으로 학습되고 학습 절차에 멀티 패스가 포함한다. 학습된 모델의 파라미터들은 압축된 파일에 포함된다. 최소 설명 길이(Minimum description length)원칙에 따라 정확한 모델과 모델의 파라미터를 저장하는데 필요한 비트 사이의 트레이드 오프가 있다. 모델이 클수록 압축이 향상될 수 있지만, 소규모 데이터 세트의 경우 모델 자체의 크기가 커질 수 있어 압축이 저하될 수 있다.(압축 데이터에 압축 모델 파라미터 포함되어 있기 때문) </p>
</li>
</ul>
<h1 id="방법">방법</h1>
<p><img src="https://velog.velcdn.com/images/noooooh_042/post/e11a3620-e7cd-4889-b50c-f9db92df8b7f/image.png" alt=""></p>
<ul>
<li>세미 적응형과 적응형 학습 방법을 사용하여 하이브리드 학습 방식이라고 할 수 있다.</li>
<li>bootstrap 모델은 RNN 학습을 기반으로 하며 세미 적응형 방식을 사용한다.</li>
<li>supporter 모델은 미리 정의된 의사 랜덤 매개변수로 초기화된 큰 신경망이다.</li>
<li>bootstrap 모델의 압축 성능 향상을 위한 모델이다.</li>
<li>bootstrap과 supporter 모델의 출력은 최종 예측을 위해 결합된다.</li>
<li>combined 모델의 파라미터는 인코딩 도중 적응형으로 업데이트된다.</li>
</ul>
<h2 id="모델-아키텍처">모델 아키텍처</h2>
<p><img src="https://velog.velcdn.com/images/noooooh_042/post/720e019e-0eb0-47d0-9cdd-0975b4b9a251/image.png" alt=""></p>
<p><strong>bootstrap 모델</strong></p>
<ul>
<li>bootstrap 모델의 아키텍처는 모델 사이즈와 예측 능력 사이 트레이트 오프를 유지할 수 있도록 디자인되었다.</li>
<li>임베딩 레이어와 biGRU 레이어 다음에 선형 레이어와 밀집 레이어가 온다.</li>
<li>기본(default)으로 16(m)번째 타임 스텝 후 biGRU 레이어의 출력들은 하나의 벡터로 쌓이(stacked)고 평탄화(flattened)됨.</li>
<li>16(m)번째 출력은 다음 레이어의 파라미터를 줄이는 데 도움이되며 장기 의존성을 학습할 수 있도록한다.</li>
<li>작은 bottleneck dense 레이어는 아키텍처의 깊이를 증가시킨다.</li>
<li>레이어 출력은 스케일화 되지 않은 확률(log)이며 logits_b이다. </li>
<li>dense layer가 장기 의존성을 학습하기 때문에 합성 데이터에서 좋은 성능을 보여준다.</li>
<li>입력 vocabulary 사이즈에 의해 자동으로 layer width가 결정된다. </li>
<li>vocabulary 사이즈는 다양하며 임베딩 벡터 차원은  8 ~ 16, biGRU의 은닉 상태는 8 ~ 128 차원, dense layer의 width는 16 ~ 256 이다. </li>
<li>위 하이퍼 파라미터는 경험적으로 얻어진 결과이다.</li>
</ul>
<p><strong>supporter 모델</strong></p>
<ul>
<li>supporter 모델의 아키텍처는 bootstrap 모델보다 데이터에 빠르게 적응하고 더 나은 확률 추정을 제공하기 위해 만들어졌다.</li>
<li>입력이 임베딩 레이어로 구성되며 3개의 sub-NNs 구성되어있다. </li>
<li>첫번째 sub-NN은 선형으로 빠르게 학습하며, 두번째는 2개의 dense layer, 세번째는 residual block을 사용하여 복잡한 패턴을 학습할 수 있다.</li>
<li>ReLU를 모든 dense layer와 residual layer에 사용하였다.</li>
<li>각 sub-NNs 출력은 선형 layer를 통해 vocabulary 차원과 같아지며 모두 더해진 최종 출력은 logis_s이다.</li>
<li>dense layer와 residual layer는 vocabulary 사이즈에 따라 자동적으로 1024 또는 2048 로 정해진다.(github 참고)</li>
</ul>
<p><strong>combined 모델</strong></p>
<ul>
<li>combined 모델은 boostrap의 출력 logits_b와 supporter의 출력 logits_s를 공식에 의해 최종 logits_c로 만든다.
<img src="https://velog.velcdn.com/images/noooooh_042/post/4c25a971-e1b6-44a3-a669-288f71ea2797/image.png" alt=""></li>
<li>람다(ㅅ)는 학습 파라미터로 시그모이드 활성화 함수를 통해 0과 1사이 값을 갖는다.</li>
<li>학습을 통해 더 나은 모델에 가중치를 더 주며 학습되며 최종 출력 logits_c는 softmax 활성화 함수에 의해 확률이 출력된다.</li>
</ul>
<h2 id="모델-학습">모델 학습</h2>
<ul>
<li>Dzip 모델의 첫번째로 입력 데이터의 vocabulary 사이즈를 선택한다.</li>
<li>vocabulary 사이즈에 의해 boostrap과 supporter 모델의 하이퍼 파라미터가 자동을 지정된다.</li>
<li>모델은 8 에폭, 배치사이즈 2048, 그래디언트 클립핑, 아담 옵티마이저(learning rate 0.005)를 사용한다.</li>
<li>작은 데이터 셋에는 bootstrap 모델의 충분한 학습을 위해서 에폭을 증가시켜도 된다.</li>
<li>훈련 후, 모델은 무손실 압축기 BSC에 의해 압축된 파일의 일부로 저장되어진다.</li>
</ul>
<p><strong>combined 모델(Hybrid)</strong></p>
<ul>
<li>이 모델은 학습된 boostrap 모델과 랜덤으로 파라미터가 초기화된 supporter 모델을 사용한다.</li>
<li>bootstrap 모델의 파라미터는 고정되며 인코딩, 디코딩 동안 supporter 모델은 최적화된다.</li>
<li>한 번에 하나의 부호를 인코딩하는 시간이 매우 느리기 때문에 시퀀스를 64개의 동일한 사이즈로 나누고 하나의 배치에서 각 부분에 대해 확률을 생성하는 공통 모델을 사용한다.</li>
<li>원핫 벡터로 y를 인코딩 후 아래 손실 함수를 통해서 모델을 최적화 한다.
<img src="https://velog.velcdn.com/images/noooooh_042/post/17a61450-6adb-45a2-9282-bc132113431d/image.png" alt=""></li>
<li>f는 softmax이며 CE는 cross entropy이다.</li>
<li>가중치 업데이트는 (각 파트의)20개의 부호를 인코딩(또는 디코딩) 후 수행된다.</li>
<li>learning rate 를 낮게(0.005)를 유지하여 발산을 방지한다.</li>
<li>모델을 업데이트하기 위해서 아담 옵티마이저(B1 = 0, B2 = 0.999)이다.</li>
</ul>
<p><strong>Only bootstrap 모델</strong></p>
<ul>
<li>시퀀스는 1024개의 부분으로 나눠지고 각 부분의 첫 K 부호는 균일한 확률을 사용하여 인코딩된다. </li>
<li>이 모드에서 사용된 배치 사이즈는 1024이며, 64인 combined 모델 접근 방식과 반대된다.</li>
<li>bootstrap 모델로 부터 얻어진 확률 추정을 사용하여 각 부분에서 K + 1 번째 부호를 인코딩한다.( 각 부분에 대한 확률은 하나의 배치에서 끝난다 )</li>
<li>이 절차는 모든 부분들이 인코딩될때까지 반복된다.</li>
<li>시퀀스 길이는 인코딩된 파일의 일부로 저장되고 디코딩은 대칭적으로 수행된다.</li>
</ul>
<h2 id="결과">결과</h2>
<p><strong>real 데이터셋 압축 결과</strong>
<img src="https://velog.velcdn.com/images/noooooh_042/post/d827d6f6-2249-4181-931f-0198f5077a0c/image.png" alt=""></p>
<p><strong>합성 데이터셋 압축 결과</strong>
<img src="https://velog.velcdn.com/images/noooooh_042/post/d7949e4c-5aad-4db6-81cc-3201be1b7f71/image.png" alt=""></p>
<h3 id="only-bootstrap-모델과-combined-model-사이의-트레이드-오프">only bootstrap 모델과 combined model 사이의 트레이드 오프</h3>
<p><img src="https://velog.velcdn.com/images/noooooh_042/post/558bbe50-2832-4738-a146-63dd25bbe515/image.png" alt=""></p>
<ul>
<li><p>(real 데이터셋 기준)combined model이 only bootstrap 모델보다 평균 0.055 bpc 성능이 좋았음 
<img src="https://velog.velcdn.com/images/noooooh_042/post/467a74a5-b681-4a56-a5e7-ef3059c015a5/image.png" alt=""></p>
</li>
<li><p>only bootstrap 모델이 combined 모델보다 평균 1.5 ~ 4배 빨랐다.</p>
</li>
<li><p>또한 only bootstrap 모델이 Gzip, 7zip, BSC, LSTM-Compress 보다 성능이 좋다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[순환 신경망 RNN]]></title>
            <link>https://velog.io/@noooooh_042/%EC%88%9C%ED%99%98-%EC%8B%A0%EA%B2%BD%EB%A7%9D-RNN</link>
            <guid>https://velog.io/@noooooh_042/%EC%88%9C%ED%99%98-%EC%8B%A0%EA%B2%BD%EB%A7%9D-RNN</guid>
            <pubDate>Wed, 16 Feb 2022 12:01:52 GMT</pubDate>
            <description><![CDATA[<h1 id="순환-신경망recurrent-neural-network">순환 신경망(Recurrent Neural Network)</h1>
<h2 id="이론">이론</h2>
<ul>
<li>RNN(Recurrent Neural Network)은 은닉층의 노드에서 활성화 함수를 통해 나온 결과값을 출력층으로 보내면서 다시 은닉층 노드의 다음 계산의 입력으로 보내는 특징을 가지고 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/3f31d1a1-aeb8-454e-9364-2bed7c082fbd/%EC%BA%A11.JPG" alt=""></p>
<ul>
<li>x는 입력층의 입력 벡터이고 y는 출력층의 출력 벡터이다.</li>
<li>RNN 은닉층에서 활성화 함수를 통해 결과를 내보내는 역할을 하는 노드를 셀(cell)이라고 한다.</li>
<li>이전 값을 기억하려고 하는 일종의 메모리 역할을 하기 때문에 RNN cell 또는 메모리 셀이라고도 한다.</li>
<li>은닉층의 메모리 셀은 각각의 시점(time step)에서 바로 이전 시점에서의 은닉층의 메모리 셀에서 나온 값을 자신의 입력으로 사용한다.</li>
<li>현재 시점을 변수 t라고 할때, 현재 시점 t에서의 메모리 셀이 갖고있는 값은 과거의 메모리 셀들의 값에 영향을 받았다고 할 수 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/218b6d1f-526b-4988-91a9-48ee0786aebb/%EC%BA%A12.JPG" alt=""></p>
<ul>
<li>메모리 셀이 출력층 방향 또는 다음 시점인 t+1의 자신에게 보내는 값을 은닉 상태(hidden state) 한다.</li>
<li>t 시점의 메모리 셀은 t-1 시점의 메모리 셀이 보낸 은닉 상태값을 t 시점의 은닉 상태 계산을 위한 입력값으로 사용하게 된다.</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/1060df4f-58ee-40a2-be76-9da368fc149a/%EC%BA%A13.JPG" alt=""></p>
<ul>
<li>MLP는 대표적인 순방향 신경망(Feedfoward neural network)로써 입력에서 출력층 방향으로 연산이 되는 구조이다.</li>
<li>RNN은 순환 신경망으로써 현재의 상태(state)가 이전 상태(state)를 사용하는 순환되는 연산있는 구조이다.</li>
</ul>
<h2 id="코드">코드</h2>
<ul>
<li>Keras에는 세 개의 내장 RNN 레이어와 RNN 셀이 있다.
셀은 RNN 레이어의 for 루프 내부이다. keras.layers.RNN 레이어 내에 셀을 래핑하면 RNN(LSTMCell(10))과 같은 시퀀스 배치를 처리할 수 있는 레이어를 얻을 수 있다.
예를 들면 RNN(LSTMCell(10))은 LSTM(10)과 동일한 결과를 낼 수 있다.<ol>
<li>keras.layers.SimpleRNN</li>
<li>keras.layers.GRU</li>
<li>keras.layers.LSTM</li>
<li>keras.layers.SimpleRNNCell</li>
<li>keras.layers.GRUCell</li>
<li>keras.layers.LSTMCell</li>
</ol>
</li>
</ul>
<ul>
<li>tensorflow에 있는 예시코드를 수정했습니다. (MNIST 숫자 맞추기)</li>
<li><a href="https://www.tensorflow.org/guide/keras/rnn?hl=ko">https://www.tensorflow.org/guide/keras/rnn?hl=ko</a></li>
<li>입력 시퀀스로 MNIST 숫자의 행 시퀀스(각 픽셀 행을 하나의 타임스텝으로 취급)를 사용하고 숫자의 레이블을 예측하는 실습<pre><code class="language-python">import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
mnist = keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
sample, sample_label = x_train[0], y_train[0]
input_dim = 28
units = 64
output_size = 10 # label 은 0 부터 9 까지 임.
model = keras.layers.RNN(keras.layers.SimpleRNNCell(units), input_shape=(None, input_dim))
model = keras.models.Sequential([model, keras.layers.BatchNormalization(), keras.layers.Dense(output_size),])
model.set_weights(model.get_weights())
model.compile(  loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
  optimizer=&quot;sgd&quot;,
  metrics=[&quot;accuracy&quot;],
)
model.fit(
  x_train, y_train, validation_data=(x_test, y_test), batch_size=batch_size, epochs=1
)
model.summary()
predict_num = model.predict(np.expand_dims(sample,axis=0))
print(&quot;예측한 숫자 : {}, 정답 숫자 : {}&quot;.format(predict_num.argmax(), sample_label))
print(&quot;성능 평가&quot;)
model.evaluate(x_test,y_test)</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TCP/IP]]></title>
            <link>https://velog.io/@noooooh_042/TCPIP</link>
            <guid>https://velog.io/@noooooh_042/TCPIP</guid>
            <pubDate>Fri, 11 Feb 2022 12:03:41 GMT</pubDate>
            <description><![CDATA[<h1 id="tcpip">TCP/IP</h1>
<ul>
<li><p>보통 하나로 부르지만 TCP와 IP는 별개이다. 네트워크의 경우 계층이 정의되어있고 각 계층마다 하는 역할과 책임지는 영역이 나눠져있다.</p>
</li>
<li><p>TCP를 알기전에 네트워크 계층을 이해해보자.</p>
</li>
</ul>
<h2 id="네트워크-계층-osi-7">네트워크 계층 (OSI 7)</h2>
<ul>
<li><p>OSI 7 계층은 국제표준화기구(International Standard Organization, ISO)에서 1984년에 발표한 네트워크 표준 모델이다.</p>
</li>
<li><p>정보통신업체 사이의 장비 호환성을 위해서 1984년 국제표준화기구에서 발표한 표준 프로토콜이다.
<img src="https://images.velog.io/images/noooooh_042/post/7ce1f252-04d2-46e0-97ef-8b1ef8a53099/TCPIP.JPG" alt="TCP/IP"></p>
</li>
<li><p>OSI 7 계층에서 하위로 갈수록 하드웨어에 가까워지고, 상위 계층으로 갈 수록 소프트웨어에 가깝다.</p>
</li>
</ul>
<ol>
<li><p>1 layer (Physical Layer) : 시스템의 물리적 전기적 표현을 나타내는 층위이다. 케이블 종류, 무선 주파수 링크, 핀, 전압 등의 물리적인 요건을 의미한다.</p>
</li>
<li><p>2 layer (Data Link Layer) : 직접적으로 연결된 두 개의 노드 사이의 데이터 전송을 가능하게 한다.</p>
</li>
<li><p>3 layer (Network Layer) : 네트워크의 핵심인 라우팅(데이터가 가야할 길을 찾는 기능)의 대부분이 3 layer에서 작동한다. 여러 대의 라우터들을 바탕으로 데이터를 패킷 단위로 잘게 쪼개어 전송한다. </p>
</li>
<li><p>4 layer (Transport Layer) : 보내고자 하는 데이터의 용량과 속도, 목적지를 처리한다. 전송 계층에서 가장 대표적인 프로토콜은 전송 제어 프로토콜(TCP)이다. TCP는 인터넷 프로토콜(IP) 위에 구축되기 때문에 TCP/IP로 알려져있다.</p>
</li>
<li><p>5 layer (Session Layer) : 실제 네트워크 연결이 이뤄지며 두 대의 기기가 대화하기 위해서는 하나의 세션이 열려야한다. 세션 계층에는 프로세스간의 통신을 제어하고, 통신 과정이 진행될 때 동기화를 유지하는 역할을 한다.</p>
</li>
<li><p>6 layer (Presentation Layer) : 응용프로그램 형식을 네트워크 형식으로 변환하거나 그 반대의 경우가 일어나는 계층이다. 데이터를 안전하게 주고 받기 위해 암호화하고 복호화하는 과정이 일어난다.</p>
</li>
<li><p>7 layer (Application Layer) : 사용자가 네트워크에 접근할 수 있도록 인터페이스를 제공하며 사용자에게 가장 직접적으로 보이는 부분이다. 구글 크롬 같은 브라우저가 어플리케이션 계층에 속한다.</p>
</li>
</ol>
<h2 id="ip-internet-protocol">IP (Internet Protocol)</h2>
<ul>
<li>각 패킷의 주소 부분을 처리해 패킷들이 목적지에 정확하게 도달하도록 하는 일을 담당한다.</li>
</ul>
<h3 id="ip의-특징">IP의 특징</h3>
<ol>
<li>신뢰성(에러제어) 및 흐름제어 기능이 전혀 없다.</li>
<li>비연결성 데이터그램 방식을 채택하고 있으며 패킷의 완전한 전달(소실,중복,지연,순서바뀜 등이 없게하는 것)을 보장하지 않는다.</li>
<li>IP 헤더 내 수신 및 발신 주소를 포함하고, IP 헤더 내 바이트 전달 순서는 최상위 바이트(MSB)를 먼저 보낸다.</li>
<li>모든 상위 계층 프로토콜(TCP,UDP,ICMP,IGMP 등)이 IP 데이터그램에 실려서 전송된다.</li>
</ol>
<h2 id="tcp-transmission-control-protocol">TCP (Transmission Control Protocol)</h2>
<ul>
<li>통신하고자 하는 양쪽 단말(endpoint)이 통신할 준비가 되었는지, 데이터가 제대로 전송되었는지 등을 점검한다.</li>
<li>TCP(Trasmission Control Protocol)는 연결 지향 프로토콜으로서 클라이언트와 서버가 연결된 상태에서 데이터를 주고받는 프로토콜을 의미한다.</li>
<li>클라이언트가 연결 요청(SYN 데이터 전송)을 하고, 서버가 연결을 수락하면 통신 선로가 고정되고, 모든 데이터는 고정된 통신 선로를 통해서 순차적으로 전달된다.</li>
<li>신뢰성 있는 데이터의 전송을 위해 확인작업을 거치는데 TCP는 패킷을 성공적으로 전송하면(ACK) 라는 신호를 날리고 만약에 ACK 신호가 제 시간에 도착하지 않으면 Timeout이 발생하여 패킷 손실이 발생한 패킷을 다시 전송한다.</li>
</ul>
<h3 id="tcp의-특징">TCP의 특징</h3>
<ol>
<li>연결형 (connnection-oriented) 서비스로 연결이 성공해야 통신이 가능하다.</li>
<li>데이터의 경계를 구분하지 않는다. (바이트 스트림 서비스)</li>
<li>데이터의 전송 순서를 보장한다. (데이터의 순서 유지를 위해 각 바이트마다 번호를 부여)</li>
<li>신뢰성있는 데이터를 전송한다. (Sequence Number, Ack Number를 통한 신뢰성 보장)</li>
<li>데이터 흐름 제어(수신자 버퍼 오버플로우 방지) 및 혼잡 제어(패킷 수가 과도하게 증가하는 현상 방지)</li>
<li>연결의 설정(3-way handshaking)과 해제(4-way handshaking)</li>
<li>전이중(Full-Duplex), 점대점(Point to Point) 서비스</li>
<li>UDP보다 전송속도가 느리다.</li>
</ol>
<h3 id="3-way-handshake-방식-syn-ack">3 way handshake 방식 (SYN, ACK)</h3>
<p><img src="https://images.velog.io/images/noooooh_042/post/be50ca7c-ead3-47ee-8676-afa83e90e539/hand.JPG" alt=""></p>
<ul>
<li>서로의 통신을 위한 관문(port)을 확인하고 연결하기 위하여 3번의 요청/응답 후에 연결되는 과정이다.</li>
</ul>
<h4 id="연결-과정">연결 과정</h4>
<ol>
<li>Client에서 Server에 연결 요청을 하기위해 SYN 데이터를 보낸다.</li>
<li>Server에서 해당 포트는 LISTEN 상태에서 SYN 데이터를 받고 SYN_RCV로 상태가 변경된다.</li>
<li>요청을 정상적으로 받았다는 대답(ACK)와 Client도 포트를 열어달라는 SYN 을 같이 보낸다.</li>
<li>Client에서는 SYN+ACK 를 받고 ESTABLISHED로 상태를 변경하고 서버에 ACK 를 전송한다.</li>
<li>ACK를 받은 서버는 상태가 ESTABLSHED로 변경된다. 그리고 서로의 포트가 ESTABLISHED 되면서 연결이 되게 된다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[어파인 변환과 투시 변환]]></title>
            <link>https://velog.io/@noooooh_042/%EC%96%B4%ED%8C%8C%EC%9D%B8-%EB%B3%80%ED%99%98%EA%B3%BC-%ED%88%AC%EC%8B%9C-%EB%B3%80%ED%99%98</link>
            <guid>https://velog.io/@noooooh_042/%EC%96%B4%ED%8C%8C%EC%9D%B8-%EB%B3%80%ED%99%98%EA%B3%BC-%ED%88%AC%EC%8B%9C-%EB%B3%80%ED%99%98</guid>
            <pubDate>Thu, 27 Jan 2022 15:03:42 GMT</pubDate>
            <description><![CDATA[<h1 id="어파인-변환">어파인 변환</h1>
<p>어파인 변환 : 영상을 평행 이동시키거나 회전, 크기 변환, 전단 변환 등을 통해 만들 수 있는 변환을 통칭한다.</p>
<p>영상에서 어파인 변환을 적용할 경우, 직선은 그대로 직선으로 나타나고, 직선 간의 길이 비율과 평행 관계가 그대로 유지된다. 어파인 변환에 의해 직사각형 영상은 평행 사변형 형태로 변환될 수 있다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/9bebfb48-58e2-481d-8f40-70d0796eb842/%EA%B7%B8%EB%A6%BC1.png" alt=""></p>
<p>어파인 변환은 여섯 개의 파라미터를 이용한 수식으로 정의할 수 있다. 어파인 변환에 의해 입력 영상의 좌표가 (x, y)가 결과 영상의 좌표(x’, y’)으로 이동하는 결과는 다음과 같은 어파인 변환 행렬로 표현된다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/63ddf26b-6d5d-4e97-ab22-4c56f91026e5/%EA%B7%B8%EB%A6%BC2.png" alt=""></p>
<p>어파인 변환 행렬을 알기 위해서는 적어도 3개의 점을 알아야한다. 그리고 어파인 변환은 점 세 개의 이동관계만 정의할 수 있다.</p>
<h1 id="예시-코드">예시 코드</h1>
<pre><code class="language-python">
from __future__ import print_function
import cv2 as cv
import numpy as np

src = cv.imread(cv.samples.findFile(&#39;lena.jpg&#39;))
if src is None:
    print(&#39;Could not open or find the image:&#39;, args.input)
    exit(0)
srcTri = np.array( [[0, 0], [src.shape[1] - 1, 0], [0, src.shape[0] - 1]] ).astype(np.float32)
dstTri = np.array( [[0, src.shape[1]*0.33], [src.shape[1]*0.85, src.shape[0]*0.25], [src.shape[1]*0.15, src.shape[0]*0.7]] ).astype(np.float32)
warp_mat = cv.getAffineTransform(srcTri, dstTri)
warp_dst = cv.warpAffine(src, warp_mat, (src.shape[1], src.shape[0]))
# Rotating the image after Warp
center = (warp_dst.shape[1]//2, warp_dst.shape[0]//2)
angle = -50
scale = 0.6
rot_mat = cv.getRotationMatrix2D( center, angle, scale )
warp_rotate_dst = cv.warpAffine(warp_dst, rot_mat, (warp_dst.shape[1], warp_dst.shape[0]))
cv.imshow(&#39;Source image&#39;, src)
cv.imshow(&#39;Warp&#39;, warp_dst)
cv.imshow(&#39;Warp + Rotate&#39;, warp_rotate_dst)
cv.waitKey()
</code></pre>
<h2 id="input-image">input image</h2>
<p><img src="https://images.velog.io/images/noooooh_042/post/3579d1c5-08c4-494a-80b3-af5d9643d4c5/%EA%B7%B8%EB%A6%BC5.JPG" alt=""></p>
<h2 id="output-image">output image</h2>
<p><img src="https://images.velog.io/images/noooooh_042/post/b10f1c5a-c343-412e-843a-7ad58637632a/%EA%B7%B8%EB%A6%BC6.JPG" alt="">
<a href="https://docs.opencv.org/3.4/d4/d61/tutorial_warp_affine.html">https://docs.opencv.org/3.4/d4/d61/tutorial_warp_affine.html</a></p>
<h1 id="투시-변환">투시 변환</h1>
<p>투시 변환(perspective transform) : 직사각형 형태의 영상을 임의의 볼록 사각형 형태로 변경할 수 있는 변환이다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/792964e1-26f2-47f1-b990-d697e93e96ea/%EA%B7%B8%EB%A6%BC3.png" alt=""></p>
<p>투시 변환은 grid의 평행 상태가 유지되지 않기 때문에 결과 영상의 형태가 임의의 사각형으로 나온다.</p>
<p>점 하나의 이동관계로부터 x 좌표에 대한 방정식 하나와 y 좌표에 대한 방정식 하나를 얻을 수 있기 때문에 점 네개의 이동 관계로부터 여덟 개의 방정식을 얻을 수 있게 된다.</p>
<p>이 여덟 개의 방정식으로부터 투시 변환을 표현하는 파라미터 정보를 계산할 수 있다.</p>
<p>투시 변환은 보통 3 x 3 크기의 실수 행렬로 표현한다.</p>
<p>투시 변환은 여덟 개의 파라미터로 표현할 수 있지만, 좌표 계산의 편의상 아홉 개의 원로를 갖는 3 x 3 행렬을 사용한다. </p>
<p>입력 영상의 픽셀 좌표 (x, y)가 투시 변환을 표현하는 행렬에 의해 이동하는 결과 영상 픽셀 좌표 (x’, y’)는 다음과 같이 계산된다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/9ebb4eae-babd-41a0-b3d5-67a99a9ca256/%EA%B7%B8%EB%A6%BC4.png" alt=""></p>
<p>행렬 수식에서 입력 좌표와 출력 좌표를 (x, y, 1), (wx’, wy’, w) 형태로 표현한 것을 동차 좌표계(homogeneous coordinates)라고 하며, 좌표 계산의 편의를 위해 사용하는 방식이다.</p>
<p>w는 결과 영상의 좌표를 표현할 때 사용되는 비례 상수이다.</p>
<h1 id="예시-코드-1">예시 코드</h1>
<pre><code class="language-python">
import numpy as np
import cv2

# read input
img = cv2.imread(&quot;sudoku.jpg&quot;)

# specify desired output size 
width = 350
height = 350

# specify conjugate x,y coordinates (not y,x)
input = np.float32([[62,71], [418,59], [442,443], [29,438]])
output = np.float32([[0,0], [width-1,0], [width-1,height-1], [0,height-1]])

# compute perspective matrix
matrix = cv2.getPerspectiveTransform(input,output)

print(matrix.shape)
print(matrix)

# do perspective transformation setting area outside input to black
imgOutput = cv2.warpPerspective(img, matrix, (width,height), cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0,0,0))
print(imgOutput.shape)

# save the warped output
cv2.imwrite(&quot;sudoku_warped.jpg&quot;, imgOutput)

# show the result
cv2.imshow(&quot;result&quot;, imgOutput)
cv2.waitKey(0)
cv2.destroyAllWindows()

</code></pre>
<h2 id="input-image-1">input image</h2>
<p><img src="https://images.velog.io/images/noooooh_042/post/79afd962-cc78-49ca-a9ef-d54633328e87/%EA%B7%B8%EB%A6%BC7.JPG" alt=""></p>
<h2 id="output-image-1">output image</h2>
<p><img src="https://images.velog.io/images/noooooh_042/post/8b82eba1-31f4-47ee-ad3e-532d7d05233f/%EA%B7%B8%EB%A6%BC8.JPG" alt="">
<a href="https://stackoverflow.com/questions/63954772/perspective-transform-in-opencv-python">https://stackoverflow.com/questions/63954772/perspective-transform-in-opencv-python</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[강화학습 (Markov Decision Process)]]></title>
            <link>https://velog.io/@noooooh_042/%EA%B0%95%ED%99%94%ED%95%99%EC%8A%B5-MDP</link>
            <guid>https://velog.io/@noooooh_042/%EA%B0%95%ED%99%94%ED%95%99%EC%8A%B5-MDP</guid>
            <pubDate>Sun, 23 Jan 2022 08:44:56 GMT</pubDate>
            <description><![CDATA[<h1 id="강화학습-기초">강화학습 기초</h1>
<h2 id="1-강화학습의-기본-구조">1. 강화학습의 기본 구조</h2>
<ul>
<li>Agent(에이전트)가 Environment(환경)와 상호작용하며 강화학습의 목표는 Environment(환경)에서 Agent가 최대 reward를 얻을 수 있도록 Agent(에이전트)를 학습하는 것이다.</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/e3c3f2c3-f7dd-4799-87a6-881a7088be95/%EC%BA%A1.png" alt="캡"></p>
<ul>
<li><p>Agent(에이전트) : 주어진 문제 상황에서 행동하는 주체이다.</p>
</li>
<li><p>Environment(환경) : 문제 세팅 그 자체를 의미하며 Agent가 취할 수 있는 행동, 그에 따른 보상 등 게임 자체의 모든 규칙이 Environment(환경)이 된다. </p>
<ul>
<li>강화학습에서는 Environment(환경)을 Markov property(마르코프 특성)으로 가정한다.</li>
</ul>
</li>
<li><p>Agent가 Environment(환경)에서 Action(행동)을 하기 위한 의사 결정 과정을 수학적으로 풀기 위해서 마르코프 결정 과정(Markov Decision Process)으로 모델링한다. </p>
</li>
</ul>
<h2 id="2-마르코프-결정-과정markov-decision-process">2. 마르코프 결정 과정(Markov Decision Process)</h2>
<ul>
<li><p>마르코프 결정 과정(Markov Decision Process)은 (S, A, P, R, γ) 로 표현되며 마르코프 프로세스(Markov Process)의 확장된 형태이다.</p>
<ul>
<li><p>S(state) : 현재 시점에서 상태(상황)이 어떤지 나타내는 값들의 집합.</p>
</li>
<li><p>A(action) : Agent가 취할 수 있는 선택지(행동)를 나타내는 값들의 집합이다.</p>
</li>
<li><p>P(probability) : 상태(S)에서 다른 상태(S&#39;)로 전이될 확률(상태 이행 확률)을 의미한다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/07fd27f7-d050-4921-a89d-637c07ba1b68/%EC%BA%A114.JPG" alt=""></p>
</li>
<li><p>R(reward) : Agent가 환경으로부터 현재 상태에서 다음 상태로 진행될 때마다 받는 상태의 가치를 스칼라 값으로 정량화하였다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/fd36aa23-511f-4f77-9fc1-e97b10d84e61/%EC%BA%A115.JPG" alt=""></p>
</li>
<li><p>γ(discount factor) : 가까운 미래와 먼 미래에 얻을 수 있는 R(reward)의 정도를 조절하는 변수이다.</p>
</li>
</ul>
</li>
<li><p>π(policy) : policy(정책)은 Agent(에이전트)가 이전 상태(S)에서 다음 상태(S&#39;)로 행동(A)을 이동시키는 방식이다.</p>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/a9c6d5f8-775a-43bc-bde0-76818818dbfc/%EC%BA%A116.JPG" alt=""></p>
<ul>
<li>최적 정책의 목표는 누적 보상을 많이 받을 수 있는 정책을 찾는 것이다.</li>
</ul>
<ul>
<li><p>마르코프 프로세스(Markov Process)는 마르코프 특성(Markov property)을 지니는 이산 시간(discrete time) 확률 과정(stochastic process)이다.</p>
</li>
<li><p>이산 시간 확률 과정(discrete time stochastic process): 시간(time interval)이 이산적(discrete)이고 현재의 상태(state)가 이전 상태(state)에만 영향을 받는 확률 과정이다. (이때 확률은 상태 이행 확률이다.)</p>
</li>
<li><p>마르코프 특성(Markov property)이란 과거 상태들(S1, S2,..., St−1)과 현재 상태(St)가 주어졌을때, 미래 상태(St+1)는 과거 상태와는 독립적으로 현재 상태에 의해서만 결정되는 것을 말한다.</p>
</li>
<li><p>마르코프 프로세스(Markov Process)는 상태(S)와 상태 이행 확률(P)로 구성되며, P는 상태 S에서 S’으로 전이될 확률을 나타낸다.</p>
</li>
<li><p>마르코프 프로세스(Markov Process)는 시간 t에서의 상태는 t−1에서의 상태에만 영향을 받는다라고 말할 수 있다.</p>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/4959960f-3afb-4914-85d2-992e5d859432/%EA%B0%AD2.png" alt=""></p>
<h2 id="3-마르코프-보상-프로세스markov-reward-process">3. 마르코프 보상 프로세스(Markov Reward Process)</h2>
<ul>
<li><p>마르코프 프로세스(Markov Process)에서는 각 상태별 전이될 확률(P)이 주어져 있지만 이전 상태(S)에서 다음 상태(S&#39;)로 가치 평가가 없다.</p>
</li>
<li><p>보상(reward)과 감가율(discount factor)을 추가하며 보상(reward)는 가치를 정량화하고 감가율(discount factor)는 보상(reward)의 정도를 조절한다.</p>
</li>
<li><p>Agent(에이전트)는 가치함수(value function)을 활용하여 보상(reward)이 최대인 상태(S)를 찾는다.</p>
</li>
</ul>
<h3 id="31-상태-가치-함수state-value-function">3.1 상태 가치 함수(state value function)</h3>
<ul>
<li>현재 상태(S)에서 다음 상태(S&#39;)들의 집합으로 보상(reward)에 대한 기댓값이 정해지는 데 각 상태(S&#39;)를 평가하는 것이 상태 가치 함수(state value fuction)이다.</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/6c435667-01b2-4365-b203-57f97db34bbc/%EC%BA%A15.JPG" alt=""></p>
<ul>
<li>Gt(누적 보상 함수)는 시간 t 이후로부터 얻을 수 있는 보상의 합을 의미하고 감가율(γ)을 통해 다음과 같이 정의한다.</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/623ce100-57ec-4a91-8081-a1e260799b39/%EC%BA%A14.png" alt=""></p>
<ul>
<li><p>감가율(γ)이 0에 가까워지면 근시안적인 평가를 하게되어 가까운 미래만 고려하게 된다.</p>
</li>
<li><p>감가율(γ)이 1에 가까워지면 먼 미래까지 평가하게 되어 거의 모든 보상값을 고려하게 된다.</p>
</li>
<li><p>감가율(γ)은 미래의 보상은 현재의 보상보다 가치가 낮음을 의미하고 감가율을 조정하여 가치의 정도를 조정할 수 있다.</p>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/62a6b28c-bdaf-465e-8f43-3f1ec5b383d1/%EC%BA%A113.JPG" alt=""></p>
<ul>
<li>정책 π에 의해서 행동들이 결정되고 결정된 행동들에 의해서 상태들도 정해진다. 상태 가치 함수는 현재 상태 s에서 정책 π를 따랐을 때의 가치를 반환한다.</li>
</ul>
<h3 id="32-상태-행동-가치-함수action-state-value-function">3.2 상태 행동 가치 함수(action state value function)</h3>
<ul>
<li><p>상태 가치 함수(state value function)을 통해서 더 높은 가치를 갖는 다음 상태(S&#39;)를 선택하여 현재 상태(S)를 이동시킨다.</p>
</li>
<li><p>상태 행동 가치 함수는 이전 상태(S)에서 행동(A)를 수행했을 때 다음 상태(S&#39;)에 대한 가치를 반환한다.</p>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/15e547ca-8827-4c98-9e91-dd7bbdc7d0f0/%EC%BA%A16.JPG" alt=""></p>
<p><img src="https://images.velog.io/images/noooooh_042/post/5fdeb9e0-8d51-4600-a936-9e1845e3d50c/%EC%BA%A112.JPG" alt=""></p>
<ul>
<li><p>상태 행동 가치 함수는 Q - value를 구하기 위해 사용된다.</p>
</li>
<li><p>정책 π에 의해서 행동들이 결정되고 결정된 행동들에 의해서 상태들도 정해진다. 현재 상태 s에서 정책 π를 따라 행동 a를 수행했을 때의 가치의 기댓값이 반환(Q-value)된다.</p>
</li>
</ul>
<h3 id="33-벨만-방정식bellman-equation">3.3 벨만 방정식(Bellman equation)</h3>
<ul>
<li><p>가치함수로부터 기댓값을 계산하려면 앞으로 받을 모든 보상에 대해 고려해야지만 물리적으로 계산하기 무리가 있다.</p>
</li>
<li><p>벨만 방정식을 사용하면 여러 번의 연속적인 계산으로 가치함수의 참 값을 알아낸다.(가치함수 업데이트)</p>
</li>
<li><p>벨만 방정식은 상태 가치 함수와 상태 행동 가치 함수의 관계를 나타내는 방정식이다.</p>
</li>
<li><p>벨만 기대 방정식(Bellman expectation equation) : 현재 상태의 가치함수와 다음 상태의 가치함수 사이의 관계를 식으로 나타낸 것이다.</p>
<ul>
<li><p>상태 가치 함수
<img src="https://images.velog.io/images/noooooh_042/post/4a6b795b-24df-4689-85be-8541a35bab52/%EC%BA%A19.JPG" alt=""></p>
</li>
<li><p>상태 행동 가치 함수</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/defefacb-0b4a-49ff-9930-f1cd52dfcff0/%EC%BA%A17.JPG" alt=""></p>
<ul>
<li><p>벨만 최적 방정식(Bellman optimality equation) : 최적 가치 함수를 현재 상태의 최적 가치 함수와 다음 상태의 최적 가치 함수 사이의 관계로 나타낸 것이다.</p>
<ul>
<li><p>최적 가치 함수 : 현재 상태에서 앞으로 가장 많은 보상을 받을 <strong>정책</strong>을 따랐을 때의 가치함수이다. 즉, 현재 환경에서 취할 수 있는 가장 높은 값의 보상 총합이다.</p>
</li>
<li><p>최적 상태 가치
<img src="https://images.velog.io/images/noooooh_042/post/f8ba2011-2a4e-45fc-8189-272cb308de8a/%EC%BA%A110.JPG" alt=""></p>
</li>
<li><p>최적 상태 행동 가치
<img src="https://images.velog.io/images/noooooh_042/post/0b1cc967-2b14-46cb-aed9-0f4f76f1104c/%EC%BA%A111.JPG" alt=""></p>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[객체지향 프로그래밍]]></title>
            <link>https://velog.io/@noooooh_042/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@noooooh_042/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Wed, 19 Jan 2022 12:49:46 GMT</pubDate>
            <description><![CDATA[<h1 id="객체-지향-프로그래밍-object-oriented-programmingoop">객체 지향 프로그래밍 object-oriented programming(OOP)</h1>
<ul>
<li><p>프로그램 설계 방법론으로 프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수 많은 객체(object)라는 기본 단위로 나누고 이들을 상호 작용으로 서술하는 방식</p>
</li>
<li><p>큰 문제를 작게 쪼개는 것이 아니라, 먼저 작은 문제들을 해결할 수 있는 객체들을 만든 뒤, 이 객체들을 조합해서 큰 문제를 해결하는 상향식(bottom-up) 해결법을 도입. 이 객체라는 것을 일단 한번 독립성, 신뢰성이 높게 만들어 놓기만 하면 그 이후에는 그 객체를 수정없이 재사용할 수 있으므로 개발 기간과 비용이 대폭 줄어들게 된다.</p>
</li>
</ul>
<h2 id="1-특성">1. 특성</h2>
<ul>
<li><p><strong>캡슐화(encapsulation)</strong> : 변수와 함수를 하나의 단위로 묶는 것을 의미한다. 즉, 데이터의 번들링(bundling)이다. 대개 프로그래밍 언어에서 이 번들링은 클래스를 통해서 구현되고, 해당 클래스의 인스턴스 생성을 통해 클래스 안에 포함된 멤버 변수와 메소드에 쉽게 접근할 수 있다.</p>
</li>
<li><p><strong>정보 은닉(information hiding)</strong> : 프로그램의 세부 구현을 외부로 드러나지 않도록 특정 모듈 내부로 감추는 것이다. 내부 구현은 감추고 모듈 내에서의 응집도를 높이며, 외부로 노출을 최소화하여 모듈간의 결합도를 떨어뜨려 유연함과 유지보수성을 높이는 개념이다. 많은 객체 지향 언어에서 사용되는 클래스를 기준으로 보면, 클래스 외부에서는 바깥으로 노출된 특정 메소드에만 접근이 가능하며 클래스 내부에서 어떤 식으로 처리가 이루어지는지는 알지 못하도록 설계한다.</p>
<ul>
<li>public : 클래스의 외부에서 사용가능.</li>
<li>protected : 다른 클래스에게는 노출되지 않지만, 상속받은 자식 클래스에게는 노출</li>
<li>private : 클래스 내부에서만 사용되며 외부로 노출되지 않음</li>
</ul>
</li>
<li><p><strong>상속(inheritance)</strong> : 상속은 자식 클래스가 부모 클래스의 특성과 기능을 그대로 물려받은 것이다. 기능의 일부분을 변경해야할 경우 자식 클래스에서 상속받은 그 기능만을 수정해서 다시 정의하게 되는데, 이러한 작업을 오버라이딩(overriding)이라고 한다. 상속은 캡슐화를 유지하면서도 클래스의 재사용이 용이하도록 해준다.</p>
</li>
<li><p><strong>다형성(polymorphism)</strong> : 하나의 변수, 또는 하나의 변수가 상황에 따라 다른 의미로 해석</p>
<ul>
<li><p>서브타입 다형성(subtype polymorphism) : 기초 클래스 또는 어떤 인터페이스를 구현하는 상위 클래스를 생성하고, 해당 클래스를 상속받는 다수의 하위 클래스들을 만들어 상위 클래스의 포인터나 참조변수 등이 하위클래스의 객체를 참조하게 하는 것이다.이 때 각각의 하위 클래스는 상위 클래스의 메소드 위에 자신의 메소드를 덮어쓰는 메소드 오버라이딩(method overriding)을 수행하며, 상위 클래스의 참조변수가 어떤 하위 클래스의 객체를 참조하느냐에 따라 호출되는 메소드가 달라진다.</p>
</li>
<li><p>매개변수 다형성(parametric polymorphism) : 타입을 매개변수로 받아 새로운 타입을 되돌려주는 기능이다. 타입 매개변수를 정의한 클래스 혹은 메소드는 사용할 때 매개변수에 타입을 지정하게 되며, 컴파일 시 지정한 타입에 따라 해석된다.</p>
<ul>
<li>템플릿(template) : C++에서 사용하는 개념으로, 타입 매개변수를 입력한 타입으로 치환한 코드를 생성하는 방식이다. 타입 뿐 아니라 변수도 입력할 수 있으며, 객체 내부에서 연산이나 함수 호출을 할 수 있지만, 해당 연산이나 함수가 정의되지 않은 타입을 매개변수로 넣으면 컴파일 에러가 발생하며 컴파일이 느려지고 파일이 커진다.</li>
<li>제네릭(generic) : Java와 C# 등에 도입된 개념으로, 지정한 타입 매개변수에 해당하는 타입만을 사용하겠다고 약속하는 방식이다. 타입 매개변수가 특정 객체를 상속할 경우 상속하는 객체의 함수는 호출할 수 있지만 그렇지 않을 경우 타입 매개변수로 지정된 객체의 멤버에는 접근할 수 없다.</li>
</ul>
</li>
<li><p>임시 다형성(ad hoc polymorphism)</p>
<ul>
<li>함수 오버로딩(function overloading) : C++과 C#, Java에서는 함수 오버로딩을 통해 동일한 이름의 함수를 매개변수에 따라 다른 기능으로 동작하도록 할 수 있다. 함수 오버로딩을 너무 많이 사용하면 전체적인 코드의 유지보수가 어려워지므로, 템플릿 또는 제네릭으로 대체하는 것이 일반적이다.</li>
<li>연산자 오버로딩(operator overloading) : C++, C# 등에서는 연산자를 오버로딩해서 기본 연산자가 해당 클래스에 맞는 역할을 수행하게 하는 것이 가능하다. Java에서는 연산자의 오버로딩이 불가능하다.</li>
</ul>
</li>
<li><p>강제 다형성(coercion polymorphism)</p>
<ul>
<li>묵시적 형 변환(implicit type coercion) : &#39;double a = 30;&#39;이라는 식이 실행되면 int형 값 30은 double로 묵시적 형 변환이 이루어진다. double은 int보다 크기가 큰 자료형이므로, 이러한 형 변환을 자료형 승급(type promotion)이라고 한다. C++의 변환 생성자에 의한 형 변환도 묵시적 변환에 속하며, 이를 막으려면 생성자 앞에 explicit 키워드를 추가해야 한다.</li>
<li>명시적 형 변환(explicit type coercion) : &#39;double a = (double)30;&#39;이라는 식은 위와 동일한 결과를 내지만, (double)을 통해 int형 값 30이 double형으로 변환됨을 명시적으로 표현하였다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="2-장점과-단점">2. 장점과 단점</h2>
<h3 id="1-장점">1. 장점</h3>
<ul>
<li><p>프로그램을 유연하게 변경하고 용이하게 만든다.</p>
</li>
<li><p>프로그램의 개발과 보수를 간편하게 만든다.</p>
</li>
<li><p>직관적인 코드 분석을 가능하게 한다.</p>
<p>=&gt; 강한 응집력(strong cohesion)과 약한 결합력(weak coupling)을 지향한다.</p>
<ul>
<li><p>응집력(cohesion) : 프로그램의 한 요소가 특정 목적을 위해 밀접하게 연관된 기능들이 모여서 구현되어 있고, 지나치게 많은 일을 하지 않으면 그것을 응집력이 높다고 표현한다.</p>
</li>
<li><p>결합력(coupling) : 프로그램 코드의 한 요소가 다른 것과 얼마나 강력하게 연결되어 있는지, 얼마나 의존적인지를 나타내는 정도</p>
</li>
</ul>
</li>
</ul>
<h3 id="2-단점">2. 단점</h3>
<ul>
<li><p>처리 속도가 상대적으로 느림</p>
</li>
<li><p>객체가 많아지면 용량이 커짐</p>
</li>
<li><p>설계 시 많은 시간과 노력이 필요</p>
<p>=&gt; </p>
<ul>
<li>기능을 묶으면 결국 함수 호출이 추가로 들어가거나 계산식 중간에 포인터 연산 등이 필요해지며, 멤버 함수 같은 경우 어느 객체의 함수인지 지정해야 하기 때문에 추가 포인터 크기와 연산 비용이 들어간다.</li>
<li>메모리 할당을 배열로 하지 못하게 되니 따로따로 생성하게 되는데 이렇게 각각의 객체의 생성과 파괴가 반복되면 메모리 단편화라는 문제가 생기게 된다</li>
<li>객체 하나하나를 따로 나누는데 주력하다보니 서로 비슷한 처리를 하는 코드가 서로를 건드릴 수 없게 되었고 이를 해결하기 위해 getter(접근자: 값을 반환하는 메소드), setter(설정자: 필드에 값을 저장하는 메소드)사용이 너무 많아졌다. 이 과정에서 캡슐화가 깨지고 그냥 public으로 공개한 경우나 마찬가지인 상태가 되어 의미가 퇴색</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로세스와 쓰레드]]></title>
            <link>https://velog.io/@noooooh_042/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%93%B0%EB%A0%88%EB%93%9C</link>
            <guid>https://velog.io/@noooooh_042/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%93%B0%EB%A0%88%EB%93%9C</guid>
            <pubDate>Sun, 16 Jan 2022 10:04:27 GMT</pubDate>
            <description><![CDATA[<p>출처 : <a href="https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html">https://gmlwjd9405.github.io/2018/09/14/process-vs-thread.html</a></p>
<p>멀티코어를 가진 CPU가 보편적이기 때문에 멀티 코어를 활용할 수 있어야한다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/48244a3a-5fd9-478e-af75-91d5ca013de8/%EC%BA%A1%EC%B2%98.JPG" alt=""></p>
<h2 id="프로세스process">프로세스(Process)</h2>
<ul>
<li>프로세스는 사용 중인 파일, 데이터, 프로세서의 상태, 메모리 영역 주소공간, 스레드 정보, 전역 데이터가 저장된 메모리 부분 등 수 많은 자원을 포함하는 개념. 종종 스케쥴링의 대상이 되는 작업이라고 불리기도 한다.</li>
<li>프로세스는 각각 독립된 메모리 영역( Code, Data, Stack, Heap의 구조)을 할당 받는다.</li>
<li>기본적으로 프로세스당 최소 1개의 스레드(메인 스레드)를 가지고 있다.</li>
<li>각 프로세스는 별도의 주소 공간에서 실행되며, 한 프로세스는 다른 프로세스의 변수나 자료 구조에 접근할 수 없다.</li>
<li>한 프로세스가 다른 프로세스의 자원에 접근하려면 프로세스 간의 통신(IPC, inter-process communication)을 가지고 있어야한다.<ul>
<li>EX) 파이프, 파일, 소켓 등을 이용한 통신 방법</li>
</ul>
</li>
</ul>
<h2 id="프로세스-스케쥴링">프로세스 스케쥴링</h2>
<ul>
<li>프로세스가 생성되어 실행될 때 필요한 시스템의 여러 자원을 해당 프로세스에게 할당하는 작업을 뜻하며, 대기 시간은 최소화하고 최대한 공평하게 처리하는 것을 목적으로 한다.</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/0dd3559e-2a87-4f7a-88f2-78e7c22fb80e/%EC%BA%A1%EC%B2%98.2JPG.JPG" alt=""></p>
<h2 id="스레드thread">스레드(Thread)</h2>
<ul>
<li>스레드는 프로세서 내에서 각각 Stack만 따로 할당 받고 Code, Data, Heap 영역은 공유한다.</li>
<li>스레드는 한 프로세스 내에서 동작되는 여러 실행 흐름으로, 프로세스 내의 주소 공간이나 자원들(힙 공간 등)을 같은 프로세서 내에 스레드 끼리 공유하면서 실행된다.</li>
<li>같은 프로세스 안에 있는 여러 스레드들은 같은 힙 공간을 공유한다. 반면에 프로세스는 다른 프로세스의 메모리에 직접 접근할 수 없다.</li>
<li>각 각의 스레드는 별도의 레지스터와 스택을 갖고 있지만, 힙 메모리는 서로 읽고 쓸 수 있다.<ul>
<li>레지스터 : 메모리로 연산의 결과를 보내고 영구적으로 저장할 데이터를 하드디스크에 저장해야하는 등의 명령을 처리하기 위해서 주소와 명령을 저장할 수 있는 기억 공간이 레지스터이다. 연산 속도가 메모리보다 수십 수백 배 빠르다.</li>
</ul>
</li>
</ul>
<h2 id="쓰레드와-프로세스의-차이점">쓰레드와 프로세스의 차이점</h2>
<ul>
<li>프로세스는 완벽히 독립적이기 때문에 메모리 영역(Code, Data, Heap, Stack)을 다른 프로세스와 공유하지 않지만, 쓰레드는 해당 쓰레드를 위한 스택을 생성할 뿐 그 이외 Code, Data, Heap 영역을 공유한다.</li>
</ul>
<h3 id="메모리맵">메모리맵</h3>
<p><img src="https://images.velog.io/images/noooooh_042/post/6edfeba1-8670-46f3-bf81-e98d5302c76e/%EC%BA%A1%EC%B2%983.JPG" alt=""></p>
<ul>
<li><p>정적 할당 영역</p>
<p>  text(Code) 영역 : 작성한 코드가 들어가며 상수, 컴파일된 기계어가 들어간다. 프로그램이 끝날 때까지 메모리에 계속 적재되어있는다.</p>
<p>  Data 영역 : 전역 변수, static 변수, 배열, 구조체 등이 저장되며 초기화된 데이터는 data에 저장, 초기화되지 않은 데이터는 bss에 저장된다. </p>
</li>
<li><p>동적 할당 영역</p>
<p>  Heap 영역 : 프로그래머가 동적으로 사용하는 영역으로 malloc, free, new, delete 에 의해 할당되고 반환된다. </p>
<ul>
<li><p>런타임 시 크기가 결정된다.</p>
<p>Stack 영역 : 지역변수, 매개변수, 리턴 값 등이 저장되어 있고 함수 호출 시 생성되고, 함수가 종료되면 시스템에 반환된다. 프로그램이 자동을 사용하는 임시 메모리 영역이다.</p>
</li>
<li><p>컴파일 시 크기가 결정된다.</p>
</li>
</ul>
</li>
</ul>
<h2 id="멀티-프로세스">멀티 프로세스</h2>
<ul>
<li>하나의 응용 프로그램을 여러개의 프로세스로 구성하여 각 프로세스가 하나의 작업을 처리하도록 하는 것</li>
</ul>
<h3 id="멀티-프로세스의-문제점">멀티 프로세스의 문제점</h3>
<ul>
<li>두 개의 프로세스는 완전히 독립된 두 개의 프로그램 실행을 위해 사용되기 때문에 컨텍스트 스위칭(프로세스의 상태 정보를 저장하고 복원하는 일련의 과정)으로 인한 성능 저하가 발생<ul>
<li>Context Switching : CPU에서 여러 프로세스를 돌아가면서 작업을 처리하는 과정. 구체적으로는 동작 중인 프로세스가 대기를 하면서 프로세스의 상태(Context)를 보관하고 대기하고 있던 다음 순서의 프로세스가 동작하면서 이전에 보관했던 프로세스의 상태를 복구하는 작업</li>
</ul>
</li>
<li>Context Switching 과정에서의 오버헤드 : Context Switching 과정에서 캐쉬 메모리 초기화 등 무거운 작업이 진행되고 많은 시간이 소모되는 등의 오버헤드가 발생</li>
<li>프로세스는 각각의 독립된 메모리 영역을 할당받았기 때문에 프로세스 사이에서 공유하는 메모리가 없어, Context Switching가 발생하면 캐쉬에 있는 모든 데이터를 모두 리셋하고 다시 캐쉬 정보를 불러와야 한다.</li>
</ul>
<h2 id="멀티-쓰레딩">멀티 쓰레딩</h2>
<ul>
<li>하나의 응용프로그램을 여러 개의 스레드로 구성하고 각 스레드로 하여금 하나의 작업을 처리하도록 하는 것</li>
<li>시스템 자원 소모 감소: 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.</li>
<li>시스템 처리량 증가: 스레드 간 데이터를 주고 받는 것이 간단해지고 시스템 자원 소모가 줄어들게 된다. 스레드 사이의 작업량이 작아 Context Switching이 빠르다.</li>
<li>간단한 통신 방법으로 인한 프로그램 응답 시간 단축 : 스레드는 프로세스 내의 Stack 영역을 제외한 모든 메모리를 공유하기 때문에 통신의 부담이 적다.</li>
<li>여러개의 스레드들이 하나의 메모리를 공유한다.<ul>
<li>Code 영역을 공유하기 때문에 두 개 이상의 쓰레드가 자신이 포함된 프로세스의 Code 영역에 있는 함수를 호출할 수 있다.</li>
<li>Data영역과 Heap 영역을 공유하기 때문에 전역 변수와 동적 할당된 메모리 공간을 공유할 수 있고, 이를 통해 쓰레드 간 통신을 할 수 있지만 동시에 메모리에 접근하기 때문에 주의해야한다.</li>
</ul>
</li>
<li>쓰레드는 하나의 프로그램 내에서 여러 개의 실행 흐름을 두기 위한 모델이다.</li>
<li>쓰레드는 메모리를 공유하기 때문에 컨텍스트 스위칭에 걸리는 시간이 프로세스보다 짧다<ul>
<li>쓰레드에는 실제로 공유되는 데이터가 있고 아닌 데이터가 있다.<ul>
<li>Program Counter : 쓰레드 별로 main 함수를 독립적으로 가지고 있고, 함수 호출도 독립적으로 진행되기 때문에 쓰레드별로 Program Counter 값은 달라야한다. (Program Counter는 실행해야 할 명령어의 위치를 가리키는 레지스터)</li>
<li>Stack Pointer와 Frame Pointer : 쓰레드는 독립적인 스택을 가지기 때문에 스택 정보를 가지고 있는 Stack Pointer와 Frame Pointer는 공유되지 않는다.</li>
<li>범용적으로 사용가능한 레지스터 : 시스템을 어떻게 디자인 하느냐에 따라 달라지는 것이기 때문에 일반적으로 공유된다고 할 수 없다.</li>
<li>Cache 메모리 : 프로세스 사이에서 공유하는 메모리가 하나도 없기 때문에 컨텍스트 스위칭이 발생하면 캐시에 있는 모든 데이터를 모두 리셋하고 다시 캐시 정보를 불러와야한다. 하지만 쓰레드는 캐시 정보를 비울 필요가 없기 때문에 프로세스와 쓰레드의 컨텍스트 스위칭 속도 차이가 발생한다.<ul>
<li>cache 메모리란? CPU에서 한 번 이상 읽어들인 메인 메모리의 데이터를 저장하고 있다가 CPU가 다시 그 메모리에 저장된 데이터를 요구할 때 메인 메모리를 통하지 않고 바로 값을 전달하는 용도로 사용된다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="멀티-프로세스-대신-멀티-스레드를-사용하는-이유">멀티 프로세스 대신 멀티 스레드를 사용하는 이유</h2>
<p><img src="https://images.velog.io/images/noooooh_042/post/bfd69ac4-d8a3-4dd2-95a6-248e7c59f1bd/%EC%BA%A1%EC%B2%984.JPG" alt=""></p>
<ul>
<li>프로그램을 여러개 키는 것보다 하나의 프로그램 안에서 여러 작업을 해결한다.</li>
<li>자원의 효율성 증대<ol>
<li>멀티 프로세스로 실행되는 작업을 멀티 스레드로 실행할 경우, 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.<ul>
<li>프로세스 간의 Context Switching시 단순히 CPU 레지스터 교체 뿐만 아니라 RAM과 CPU 사이의 캐쉬 메모리에 대한 데이터까지 초기화되므로 오버헤드가 크기 때문</li>
</ul>
</li>
<li>스레드는 프로세스 내의 메모리를 공유하기 때문에 독립적인 프로세스와 달리 스레드 간 데이터를 주고 받는 것이 간단해지고 시스템 자원 소모가 줄어들게 된다.</li>
</ol>
</li>
<li>처리 비용 감소 및 응답 시간 단축<ol>
<li>프로세스 간의 통신(IPC)보다 스레드 간의 통신의 비용이 적으므로 작업들 간의 통신의 부담이 줄어든다.<ul>
<li>스레드는 Stack 영역을 제외한 모든 메모리를 공유하기 때문</li>
</ul>
</li>
<li>프로세스 간의 전환 속도보다 스레드 간의 전환 속도가 빠르다.<ul>
<li>Context Switching시 스레드는 Stack 영역만 처리하기 때문</li>
</ul>
</li>
</ol>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[특징점 매칭]]></title>
            <link>https://velog.io/@noooooh_042/%ED%8A%B9%EC%A7%95%EC%A0%90-%EB%A7%A4%EC%B9%AD</link>
            <guid>https://velog.io/@noooooh_042/%ED%8A%B9%EC%A7%95%EC%A0%90-%EB%A7%A4%EC%B9%AD</guid>
            <pubDate>Tue, 09 Nov 2021 12:29:40 GMT</pubDate>
            <description><![CDATA[<p>특징점 매칭은 특징점을 검출하고 특징점 주변의 정보(기술자)를 통해서 매칭한다.</p>
<h1 id="descriptor--기술자-">Descriptor ( 기술자 )</h1>
<blockquote>
<p>기술자는 서로 다른 영상에서 특징점이 어떤 연관성을 가졌는지 구분하게 하는 역할을 한다.
기술자는 검출된 특징점 근방의 영상을 표현하는 실수 또는 이진 벡터이다. 영상의 방향, 밝기, 크기, 색상 등을 표현한다.
기술자는 특징 벡터로 표현하는데 행은 특징점의 개수, 열은 특징점 알고리즘에 의해 다르게 정의된다.
<img src="https://images.velog.io/images/noooooh_042/post/ddeccef0-4304-4b83-8d32-47767a9bc4f8/image-20211107183527136.png" alt="기술자"></p>
<p>위의 경우 KAZE 특징 검출 방법으로 3159개의 특징점을 검출하였고 64개로 특징점을 표현하였다. 특징점의 자료형은 float32이다.
이러한 특징점을 표현하는 기술자는 2가지 방식이 있는데 실수 기술자와 이진 기술자가 있다.</p>
</blockquote>
<h2 id="실수-기술자">실수 기술자</h2>
<blockquote>
<p>실수 기술자는 실수값으로 기술자를 표현하며 실수 자료형을 사용하여 특징점 주변의 정보를 저장한다.
실수 기술자를 사용하는 알고리즘은 SIFT, SURF, KAZE 등이 있으며 보통 NORM_L2 를 사용하여 유사도를 판단한다.
<img src="https://images.velog.io/images/noooooh_042/post/4ebb8a03-68fc-489b-8c1a-9608768c4df8/image-20211108205848281.png" alt="실수기술자"></p>
<p>특징점 부근의 적절한 크기의 부분 영상을 추출한다. 이 부분 영상을 16 x 16으로 분할하고 그레디언트 방향 성분에 대한 히스토그램을 계산한다.
방향 히스토그램을 4 x 4 단위로 모아서 8개 방향으로 표현한다.</p>
</blockquote>
<h2 id="이진-기술자">이진 기술자</h2>
<blockquote>
<p>이진 기술자는 보통 uint8 자료형을 이용하여 비트 단위로 영상 특징 정보를 저장한다. 
이진 기술자를 사용하는 알고리즘은 AKAZE, ORB, BRIEF 등이 있으며 NORM_HAMMING 를 사용하여 유사도를 판단한다.
<img src="https://images.velog.io/images/noooooh_042/post/c25aab58-4cfa-48c5-b110-da0f5ae9e565/image-20211108210827357.png" alt="이진기술자"></p>
<p>특징점 주변 부분 영상에 미리 정의해둔 점을 비교한다.
1번 2번 3번 점의 영상 밝기를 비교해서 0과 1로 표현한다. ( ex) [ 1 0 1 ] ) </p>
</blockquote>
<h2 id="특징-매칭-feature-matching-">특징 매칭( Feature Matching )</h2>
<blockquote>
<ol>
<li>BFMatcher ( Brute-Force Matcher )</li>
<li>FLannBasedMatcher ( Fast Library for Approximate Nearest Neighbors Matching )</li>
</ol>
</blockquote>
<p>특징 매칭이란 </p>
<p>서로 다른 두 이미지에서 특징점과 특징 디스크럽터를 비교해서 비슷한 객체끼리 짝짓는 것이다.</p>
<p>특징 매칭기는 두 개의 디스크립터를 서로 비교하여 매칭해주는 함수를 갖는다. 3개의 함수가 있는데 match, knnMatch, radiusMatch 이다. 이 함수들은 첫번째 파라미터인 queryDescriptors를 기준으로 두번째 파라미터인 trainDescriptors에 맞는 매칭을 찾아서 반환한다.</p>
<p>match는 queryDescriptors 한개당 최적의 매칭을 이루는 trainDescriptors를 찾아 결과로 반환한다. 그러나 최적 매칭을 찾지 못하는 경우도 있기 때문에 반환되는 매칭 결과 개수가 queryDescriptors의 개수보다 적을 수도 있다.</p>
<p>knnMatch 는 queryDescriptors 한 개당 k개의 최근접 이웃 개수만큼 trainDescriptors에서 찾아 반환한다. k 개의 최근접 이웃 개수만큼이란 가장 비슷한 k개만큼 매칭값을 반환한다는 뜻이다. </p>
<p>위 함수의 반환 결과는 DMatch 객체로 매칭 결과를 표현한다. </p>
<p>queryIdx : queryDecriptors의 인덱스</p>
<p>trainIdx : trainDescriptors의 인덱스</p>
<p>imgIdx : trainDescriptor의 이미지 인덱스</p>
<p>distance : 유사도 거리</p>
<p>queryIdx와 trainIdx로 두 이미지의 어느 지점이 서로 매칭되었는지 알 수 있다. 또한 distance로 얼마나 가까운 거리인지도 알 수 있다.</p>
<p><strong>거리측정 알고리즘</strong>
<img src="https://images.velog.io/images/noooooh_042/post/ca6b5ab7-389a-4da7-bc01-dab1c5f7ec8f/image-20211108200319173.png" alt="거리">
세가지 유클리드 거리 측정법과 두가지 해밍 거리 측정법 중에 선택할 수 있다. </p>
<p>SIFT와 SURF 디스크립터 검출기의 경우 NORM_L1, NORM_L2가 적합하고 </p>
<p>ORB 디스크럽터 검출기의 경우 NORM_HAMMING이 적합하다. NORM_HAMMING2의 경우ORB의 WTA_K가 3 혹은 4일 때 적합하다.</p>
<h2 id="bfmatcher--brute-force-matcher-">BFMatcher ( Brute-Force Matcher )</h2>
<p>기준 이미지의 특징점 하나와 또 다른 이미지의 특징점들을 모두 비교해 가장 유사한 것이 동일한 특징점이라고 판별한다.</p>
<h2 id="flannfast-library-for-approximate-nearest-neighbors-matching">FLANN(Fast Library for Approximate Nearest Neighbors Matching)</h2>
<p>BFMatcher는 모든 디스크럽터를 전수 조사하므로 이미지 사이즈가 클 경우 속도가 굉장히 느리다. 하지만 FLANN은 모든 디스크럽터를 전수 조사하기 보다 이웃하는 디스크럽터끼리 비교한다. 이웃하는 디스크럽터를 찾기 위해 FLANN 알고리즘 함수에 인덱스 파라미터와 검색 파라미터를 전달해 줘야한다.</p>
<p>인덱스 파라미터로 indexParams를, 검색파라미터로 searchParams를 전달받는다.</p>
<p>인덱스 파라미터</p>
<ul>
<li><p>FLANN_INDEX_LINEAR : 선형 인덱싱, BFMatcher와 동일</p>
</li>
<li><p>FLANN_INDEX_KDTREE : KD - 트리 인덱싱 ( tree=4 : 트리의 개수 ( 16을 권장 ) )</p>
</li>
<li><p>FLANN_INDEX_KMEANS : K - 평균 트리 인덱싱 ( branching=32 : 트리 분기 개수, iterations=11: 반복 횟수, centers_init=0: 초기 중심점 방식 )</p>
</li>
<li><p>FLANN_INDEX_COMPOSITE=3:  KD-트리, K-평균 혼합 인덱싱 ( trees=4: 트리 개수, branching=32: 트리 분기 새수, iterations=11: 반복 횟수, centers_init=0: 초기 중심점 방식 )</p>
</li>
<li><p>FLANN_INDEX_LSH=6: LSH 인덱싱 (t able_number: 해시 테이블 수, key_size: 키 비트 크기, multi_probe_level: 인접 버킷 검색 )</p>
</li>
<li><p>FLANN_INDEX_AUTOTUNED=255:자동 인덱스 ( target_precision=0.9: 검색 백분율, build_weight=0.01: 속도 우선순위, memory_weight=0.0: 메모리 우선순위, sample_fraction=0.1: 샘플 비율 )</p>
</li>
</ul>
<p>검색파라미터 </p>
<ul>
<li>checks=32 검색할 후보수</li>
<li>eps=0.0</li>
<li>sorted=True 정렬해서 반환</li>
</ul>
<h2 id="특징점-알고리즘-성능-비교">특징점 알고리즘 성능 비교</h2>
<p><img src="https://images.velog.io/images/noooooh_042/post/6c9c53e6-752c-4d65-be3d-cfdae5934227/image-20211108212016153.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[특징점 추출]]></title>
            <link>https://velog.io/@noooooh_042/%ED%8A%B9%EC%A7%95%EC%A0%90-%EC%B6%94%EC%B6%9C</link>
            <guid>https://velog.io/@noooooh_042/%ED%8A%B9%EC%A7%95%EC%A0%90-%EC%B6%94%EC%B6%9C</guid>
            <pubDate>Sun, 07 Nov 2021 08:52:00 GMT</pubDate>
            <description><![CDATA[<h1 id="특징점-추출-알고리즘">특징점 추출 알고리즘</h1>
<blockquote>
<ol>
<li>Harris corner [ 1988 ]</li>
<li>SIFT [ 2004 ]</li>
<li>FAST [ 2006 ]</li>
</ol>
</blockquote>
<p>영상 특징점이란?</p>
<p>영상에서 물체를 추적하거나 인식할 때, 영상과 영상을 매칭할 때 가장 일반적인 방법은 영상에서 주요 특징점을 뽑아서 매칭하는 것이다. 특징점을 영어로는 보통 keypoint 또는 interesting point라고 부른다.</p>
<p>영상에서 좋은 특징점은?</p>
<ol>
<li>물체의 형태나 크기, 위치가 변해도 쉽게 식별이 가능할 것</li>
<li>카메라의 시점, 조명이 변해도 영상에서 해당 지점을 쉽게 찾아낼 수 있을 것</li>
</ol>
<p>이러한 조건을 만족시키는 특징점은 코너점이다.</p>
<h2 id="harris-corner">Harris Corner</h2>
<p>영상에서 코너를 찾는  기본적인 아이디어는 영상에서 작은 윈도우를 조금씩 이동시켰을 때, 코너점의 경우는 모든 방향으로 영상의 변화가 커진다. </p>
<p><img src="https://images.velog.io/images/noooooh_042/post/9aed9e0e-7435-4407-8b7f-c7fc957a571a/image-20211107163455529.png" alt=""></p>
<p>동작 원리</p>
<p>작은 윈도우를 수평, 수직, 좌대각선, 우대각선 4개 방향으로 1픽셀씩 이동시켰을 때 영상 변화량(SSD) E을 계산한 후, E들 중의 최소값을 해당 픽셀의 영상 변화량 값으로 설정, 이 최소값들 중 극대가 되는 지점을 코너점으로 함</p>
<p>특징</p>
<ul>
<li>영상의 평행이동, 회전 변화에 불변</li>
<li>affine 변화(카메라 각도에 의한 기하학 왜곡, 형태 변형 ) , 조명의 변화에도 어느 정도 강인하다.</li>
<li>영상 크기 변화에는 영향을 받는다. ( 적용할 때는 다양한 스케일을 고려해야할 수도 있다. )</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/59af282c-062b-460f-b321-3af2b24ff955/image-20211107164948169.png" alt=""></p>
<p><strong>스케일 ( Scale )</strong></p>
<p>영상인식, 컴퓨터 비전에서 스케일은 중요한 문제.</p>
<p>영상에서 물체의 특징을 계산할 때 어떤 스케일을 보느냐에 따라 전혀 다른 결과가 나올 수 있기 때문이다.</p>
<p>위와 같이 영상 코너 검출에서 큰 스케일에서는 명확히 코너점으로 인식되겠지만, 작은 스케일에서는 완만한 곡선 또는 직선으로 인식될 것이다. </p>
<ul>
<li>스케일을 이미지 크기로 생각하기 쉬우나 서로 다른 개념이다. <ul>
<li>이미지 크기 : 이미지의 픽셀 수나 물리적인 width와 height </li>
<li>Scale : 이미지의 설명 ( 산의 모양을 본다면 scale이 큰 것이고 나뭇잎의 모양을 본다면 scale이 작은 것 )</li>
</ul>
</li>
</ul>
<h2 id="sift">SIFT</h2>
<p>SIFT는 기존의 Harris 코너가 영상의 스케일 변화에 민감한 문제를 해결하기 위하여 DoG( Difference of Gaussian )를 기반으로 이미지 내에서 뿐만 아니라 스케일 축으로도 코너성이 극대인 점을 찾는다.</p>
<p><strong>이미지 피라미드( Image Pyramid )</strong></p>
<p><img src="https://images.velog.io/images/noooooh_042/post/fbe786f3-e233-42de-ba47-98f49af5eff6/image-20211107170532546.png" alt=""></p>
<p>스케일에 불변하는 특징점을 찾기위해 고안된 방법</p>
<p>입력 이미지의 크기를 단계적으로 변화(축소)시켜 가면서 필요한 분석 작업을 한다.</p>
<p>ex ) 영상에서 보행자를 검출하는 경우, 이미지 피라미드를 생성한 후 각 스케일 영상에서 고정된 크기의 윈도우를 이동시켜 가면서 윈도우 내 영역이 보행자인지 여부를 판단.</p>
<p>SIFT에서 특징점을 추출하기 위해서 Laplacian 함수값을 사용한다. 각 영상 스케일마다 Laplacian 값을 계산하되 그 값이 이미지 내에서 뿐만 아니라 스케일 축으로도 극대( 또는 극소 )인 점들의 특징점으로 선택한다.</p>
<ul>
<li>Laplacian 계산은 이미지 밝기 변화에 대한 2차 미분값으로 계산되며, 영상 밝기 변화가 일정한 곳에서는 0에 가까운 값, 밝기가 급격한 곳에서는 높은 값(절대값)을 나타낸다.</li>
</ul>
<p>실제 SIFT에서는 속도문제로 인해 Laplacian을 직접 계산하지 않고 DoG( Difference of Gaussian )를 이용하여 각 스케일별로 Laplacian을 근사적으로 계산한다. </p>
<p><strong>DoG ( Difference of Gaussian )</strong></p>
<p>입력 영상에서 Gaussian 필터를 점진적으로 적용하여 블러링시킨 이미지들에서 인접 이미지들간의 차 영상을 의미하며 이론적으로 LoG(Laplacian of Gaussian) 필터를 적용한 것과 거의 동일한 결과를 갖는다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/e00b340b-efb2-4c09-9f67-27d14bf85419/image-20211107171909533.png" alt=""></p>
<p>그렇게 얻어진 DoG 피라미드에서 극대 또는 극소점을 찾으면 SIFT의 특징점이 된다.</p>
<h2 id="fast">FAST</h2>
<p>극도의 빠름을 추구한 특징점 추출 방법</p>
<p>속도에 최적화된 설계 기술임에도 특징점의 품질( repeatability : 다양한 영상 변화에서도 동일한 특징점이 반복되어 검출되는 정도 ) 또한 기존 방법을 상회한다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/1ac263c8-87bf-4b19-bc86-e051f05770ea/image-20211107172230921.png" alt=""></p>
<p>FAST에서는 P를 중심으로하는 반지름 3인 원 상의 16개의 픽셀값을 보고 판단한다. P 값보다 일정값 이상( &gt;P+t ) 밝은 픽셀들이 n개 이상 연속되어 있거나 일정값 이상 어두운 픽셀(&lt; p - t )들이 n개 이상 연속되어 있으면 P를 코너점으로 판단한다. </p>
<p>FAST 알고리즘은 n을 몇 개 잡느냐에 따라서 FAST-9, FAST-10... 과 같이 다양한 버전이 가능하다.</p>
<p>어떤 점 P가 코너점인지 여부를 판단하기 위해 decision tree를 이용한다. 픽셀의 밝기값이 P보다 휠씬 밝은 경우, P보다 휠씬 어두운 경우, P와 유사한 경우 3가지 값으로 분류하고 원주상의 픽셀 밝기 분포를 16차원의 ternary 벡터로 표현한다. 이를 decision tree에 입력하여 코너점 분류한다.</p>
<p><strong>non-maximal suppression</strong></p>
<p>FAST 알고리즘은 어떤 점 P가 코너점으로 검출된 경우 P와 인접한 주변 점들도 같이 코너점으로 검출되는 경우가 많아지는 문제점이 있다. 이 문제를 해결하기 위해 코너성이 극대점만 남기고 나머지는 제거하는 방법이 non-maximal suppression이다.</p>
<p>FAST 알고리즘의 성능</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/9a7f36be-c9a8-406b-906f-63e4f9d8e313/image-20211107173856310.png" alt=""></p>
<p>FAST - 9의 성능이 가장 좋으며 기존 방식에 비해 10배 이상의 속도 증가를 가져온다. </p>
<p><img src="https://images.velog.io/images/noooooh_042/post/05e307aa-8228-4b0b-b4a6-87dba6a6a82a/image-20211107174017752.png" alt=""></p>
<p>특징점의 품질(repeatability) 또한 기존 방법들을 상회하는 결과를 보여준다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[pytorch DataLoader]]></title>
            <link>https://velog.io/@noooooh_042/pytorch-DataLoader</link>
            <guid>https://velog.io/@noooooh_042/pytorch-DataLoader</guid>
            <pubDate>Thu, 12 Aug 2021 07:26:22 GMT</pubDate>
            <description><![CDATA[<h1 id="파이토치-dataloader">파이토치 DataLoader</h1>
<p>튜토리얼을 기반으로 적어보는 사용자 정의 DataLoader
출처 : <a href="https://tutorials.pytorch.kr/beginner/basics/data_tutorial.html">https://tutorials.pytorch.kr/beginner/basics/data_tutorial.html</a></p>
<p>기본형</p>
<pre><code class="language-python">import os
import pandas as pd
from torchvision.io import read_image

class CustomImageDataset(Dataset):
    def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
        self.img_labels = pd.read_csv(annotations_file)
        self.img_dir = img_dir
        self.transform = transform
        self.target_transform = target_transform

    def __len__(self):
        return len(self.img_labels)

    def __getitem__(self, idx):
        img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
        image = read_image(img_path)
        label = self.img_labels.iloc[idx, 1]
        if self.transform:
            image = self.transform(image)
        if self.target_transform:
            label = self.target_transform(label)
        return image, label</code></pre>
<h2 id="__init__">__init__</h2>
<blockquote>
<pre><code class="language-python">def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
    self.img_labels = pd.read_csv(annotations_file)
    self.img_dir = img_dir
    self.transform = transform
    self.target_transform = target_transform</code></pre>
</blockquote>
<pre><code>&gt; \_\_init\_\_ 함수는 Dataset 객체가 생성(instantiate)될 때 한 번만 실행된다. 여기서는 이미지와 주석 파일(annotation_file)이 포함된 디렉토리와 (다음 장에서 자세히 살펴볼) 두가지 변형(transform)을 초기화한다.
&gt; 주요 목적은 데이터셋의 디렉토리를 가져오는 역할을 하기 위해서 만들어진다.
&gt; 가지고 있는 데이터의 디렉토리 정보가 담긴 csv,txt,json 등이 없을 경우 직접 함수를 구현해야한다.
&gt; camvid 데이터셋을 load 하는 함수를 구현하였다.
&gt; ```python
    def __init__(self, path, image_set, transforms=None):
        assert image_set in (&#39;train&#39;, &#39;val&#39;, &#39;test&#39;), &quot;image_set is not valid!&quot;
        self.data_dir_path = path
        self.image_set = image_set
        self.transforms = transforms
        self.createIndex()
    def createIndex(self):
        self.img_list = []
        self.segLabel_list = []
        self.exist_list = []
        img_list = os.listdir(os.path.join(self.data_dir_path,self.image_set))
        self.img_list = [os.path.join(self.data_dir_path,self.image_set,file_name) for file_name in img_list]
        #print(self.img_list)
        self.segLabel_list = os.listdir(os.path.join(self.data_dir_path,self.image_set+&quot;annot&quot;))
        self.segLabel_list = [os.path.join(self.data_dir_path,self.image_set+&quot;annot&quot;,file_name) for file_name in self.segLabel_list]
        for imgs in self.segLabel_list:
            imgs = cv2.imread(imgs)
            lis_id = [0]*12 # 클래스 개수 
            for num in np.unique(imgs[:,:,0].flatten()):
                lis_id[num] = 1
            self.exist_list.append(lis_id)</code></pre><blockquote>
<ol>
<li>데이터셋의 경로를 가지고 온 후 train, test, valid 를 구분해준다.</li>
<li>def createIndex(self) 함수를 만들어 데이터의 특성에 맞게 데이터를 불러올 수 있도록 해준다. ( __getitem__ )</li>
</ol>
<ul>
<li>self.img_list는 이미지의 모든 경로를 저장하는 list이다.</li>
<li>self.segLabel_list 세그먼트된 이미지 경로를 저장하는 list이다.</li>
<li>self.exist_list 세그먼트된 이미지에 어떤 클래스가 있는지 저장하는 list이다.</li>
<li>self.exist_list 경우 학습할 때 이미지에 어떤 클래스가 저장되어 있는지가 필요했기 때문에 따로 만들어준 list이다.</li>
<li>segLabel_list안에 클래스가 몇 개 있는지 찾고 one_hot_encoding 하였다.</li>
</ul>
</blockquote>
<h2 id="__len__">__len__</h2>
<blockquote>
<pre><code class="language-python">def __len__(self):
    return len(self.img_labels)</code></pre>
</blockquote>
<pre><code>&gt; \_\_len\_\_ 함수는 데이터셋의 샘플 개수를 반환한다. 데이터 개수를 표현할 수 있는 list만 있으면 사용할 수 있다.
&gt; ```python 
def __len__(self):
    return len(self.img_list)</code></pre><h2 id="__getitem__">__getitem__</h2>
<blockquote>
<pre><code class="language-python">def __getitem__(self, idx):
    img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
    image = read_image(img_path)
    label = self.img_labels.iloc[idx, 1]
    if self.transform:
        image = self.transform(image)
    if self.target_transform:
        label = self.target_transform(label)
    sample = {&quot;image&quot;: image, &quot;label&quot;: label}
    return sample</code></pre>
</blockquote>
<pre><code>&gt; \_\_getitem\_\_ 함수는 주어진 인덱스 idx 에 해당하는 샘플을 데이터셋에서 불러오고 반환합니다. 인덱스를 기반으로, 디스크에서 이미지의 위치를 식별하고, read_image 를 사용하여 이미지를 텐서로 변환하고, self.img_labels 의 csv 데이터로부터 해당하는 정답(label)을 가져오고, (해당하는 경우) 변형(transform) 함수들을 호출한 뒤, 텐서 이미지와 라벨을 Python 사전(dict)형으로 반환합니다.
&gt; idx를 통해서 데이터를 가져오는데 sample 딕셔너리를 통해서 한꺼번에 가져온다.
&gt; idx를 가져올 때는 batch 개수에 맞춰서 가져오고 옵션에 따라 무작위로 가져갈 수 있다.
&gt; ```python
def __getitem__(self, idx):
    img = cv2.imread(self.img_list[idx])
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    segLabel = cv2.imread(self.segLabel_list[idx])[:, :, 0]
    exist = np.array(self.exist_list[idx])
    sample = {&#39;img&#39;: img,
              &#39;segLabel&#39;: segLabel,
              &#39;exist&#39;: exist,
              &#39;img_name&#39;: self.img_list[idx]}
    if self.transforms is not None:
        sample = self.transforms(sample)
    return sample</code></pre><blockquote>
<p>idx를 통해서 데이터를 가져가기 때문에 __init__ 에서 변수들을 list 형태로 만든것이다.</p>
</blockquote>
<h2 id="collate">collate</h2>
<blockquote>
<p>batch_size =2일 때, [sample1, sample2] 이렇게 list형식으로 input이 들어온다. batch로 묶일 모든 데이터를 잘 묶어주는(collate) 함수이다.</p>
<p>```python
@staticmethod
def collate(batch):
    if isinstance(batch[0][&#39;img&#39;], torch.Tensor):
        img = torch.stack([b[&#39;img&#39;] for b in batch])
    else:
        img = [b[&#39;img&#39;] for b in batch]
    if batch[0][&#39;segLabel&#39;] is None:
        segLabel = None
        exist = None
    elif isinstance(batch[0][&#39;segLabel&#39;], torch.Tensor):
        segLabel = torch.stack([b[&#39;segLabel&#39;] for b in batch])
        exist = torch.stack([b[&#39;exist&#39;] for b in batch])
    else:
        segLabel = [b[&#39;segLabel&#39;] for b in batch]
        exist = [b[&#39;exist&#39;] for b in batch]
    samples = {&#39;img&#39;: img,
               &#39;segLabel&#39;: segLabel,
               &#39;exist&#39;: exist,
               &#39;img_name&#39;: [x[&#39;img_name&#39;] for x in batch]}
    return samples</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[CNN 다수 채널의 합성곱]]></title>
            <link>https://velog.io/@noooooh_042/CNN-%EB%8B%A4%EC%88%98-%EC%B1%84%EB%84%90%EC%9D%98-%ED%95%A9%EC%84%B1%EA%B3%B1</link>
            <guid>https://velog.io/@noooooh_042/CNN-%EB%8B%A4%EC%88%98-%EC%B1%84%EB%84%90%EC%9D%98-%ED%95%A9%EC%84%B1%EA%B3%B1</guid>
            <pubDate>Wed, 04 Aug 2021 10:15:16 GMT</pubDate>
            <description><![CDATA[<h1 id="다채널-합성곱-연산">다채널 합성곱 연산</h1>
<blockquote>
<p>CNN의 합성곱을 설명하는 블로그에 가보면 1채널 이미지, 3채널 이미지에 대해서 convolution 연산을 설명하고 있다. </p>
<p>초기 입력 convolution에 대한 이해는 가지만 다양한 모델을 보게되면 여러층을 쌓아서 convolution을 하기 때문에 중간 단계의 convolution에 대해서 감이 안잡히는 경우가 있었다. </p>
<p>그래서 다채널의 합성곱 연산에 대해서 적어보게 되었다.</p>
</blockquote>
<h2 id="3차원-텐서의-합성곱-연산">3차원 텐서의 합성곱 연산</h2>
<blockquote>
<p>일단 다수의 채널을 가진 입력 데이터를 가지고 합성곱(conv) 연산을 한다고 하면 커널의 수도 입력 채널의 수 만큼 있어야한다. 즉, 입력 채널 수와 커널의 채널의 수는 같다. 그래서 합성곱 연산을 채널마다 수행하고 그 결과를 모두 더하여 특성맵을 얻게된다.
<img src="https://images.velog.io/images/noooooh_042/post/db0463c1-d914-43b4-9b6e-1bbf6e943692/Screenshot%20from%202021-08-04%2018-54-50.png" alt=""></p>
<p>3개의 채널을 가진 입력 데이터와 3개의 채널을 가진 커널의 합성곱
<strong>여기서 주의할 점은 위 연산에서 사용되는 커널은 3개의 커널이 아니라 3개의 채널을 가지는 1개의 커널이라는 점이다.</strong></p>
</blockquote>
<h2 id="3차원-텐서의-합성곱-연산-1">3차원 텐서의 합성곱 연산</h2>
<blockquote>
<p>일반화를 위해 사용하는 각 변수가 의미하는 바는 아래와 같다.
<img src="https://images.velog.io/images/noooooh_042/post/e6d228ad-3b09-4f1c-8c7d-d4f432586d55/Screenshot%20from%202021-08-04%2018-59-03.png" alt="">
다음은 3차원 텐서의 합성곱 연산 ( 위에서 봤던 내용 )
<img src="https://images.velog.io/images/noooooh_042/post/032459df-5d95-4538-b433-2e97ad0aaaf1/Screenshot%20from%202021-08-04%2019-00-04.png" alt=""></p>
<p>다수의 입력 데이터의 채널의 수와 커널의 채널의 수가 같고 커널의 개수는 1개이다.
커널의 수가 1개일 경우 특징맵은 1개가 나오게 되는 것이 특징이다.
그렇다면 다수의 커널을 사용할 경우, 특성맵의 크기가 어떻게 바뀔까?
<img src="https://images.velog.io/images/noooooh_042/post/1959a132-e6ea-4098-aa6c-126a6bfea86b/Screenshot%20from%202021-08-04%2019-02-11.png" alt="">
합성곱 연산에서 다수의 커널을 사용할 경우, 다수의 커널 수가 특성맵의 채널 수와 같아지게 된다.</p>
<p>이를 이해했다면 커널의 크기와 입력 데이터의 채널 수(Ci)와 특성 맵(출력 데이터)의 채널 수(Co)가 주어졌을 때, 가중치 매개변수의 총 개수를 구할 수 있다</p>
<p>가중치는 커널의 원소들이므로 하나의 커널의 하나의 채널은 Ki×Ko 개의 매개변수를 가지게 된다.</p>
<p>그런데 합성곱 연산을 하려면 커널은 입력 데이터의 채널 수와 동일한 채널 수를 가져야 한다. </p>
<p>따라서 <strong>하나의 커널이 가지는 매개변수의 수는 Ki× Ko× Ci 이고 커널이 총 Co개가 있어야 된다.</strong></p>
<p>가중치 매개변수의 총 수 : <strong>Ki× Ko× Ci× Co</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[opencv_pixel_2]]></title>
            <link>https://velog.io/@noooooh_042/opencvpixel2</link>
            <guid>https://velog.io/@noooooh_042/opencvpixel2</guid>
            <pubDate>Tue, 13 Jul 2021 17:41:17 GMT</pubDate>
            <description><![CDATA[<h1 id="히스토그램">히스토그램</h1>
<blockquote>
<p>히스토그램은 어떤 데이터가 얼마나 많은지를 나타내는 도수 분포표를 그래프로 나타낸 것</p>
<p>히스토그램을 사용하면 데이터의 분포 상태를 한눈에 쉽게 알아볼 수 있다. 
화소의 분포를 나타내는 지표이기 때문에 이 분포를 이해하면 이미지, 영상의 특성을 판단할 수 있는 유용한 도구가 될 수 있다.</p>
</blockquote>
<h2 id="단일-채널의-히스토그램">단일 채널의 히스토그램</h2>
<blockquote>
<p>단일 채널 8비트 행렬의 히스토그램
8비트 행렬이기 때문에 값의 범위가 0 ~ 255 사이
흑백 이미지 ( 오늘도 아이유 )<img src="https://images.velog.io/images/noooooh_042/post/ce0e777b-0465-4129-b214-781576156ea0/0714iu.PNG" alt="">
<img src="https://images.velog.io/images/noooooh_042/post/37bea61a-c7f6-45c3-85e2-3a5e80331626/hist.PNG" alt="">
히스토그램에는 흰색 분포가 많은 것을 알수 있다. </p>
<pre><code class="language-python">import numpy as np 
import cv2 
import seaborn as sns
image = cv2.imread(&quot;0714_iu.jpeg&quot;,cv2.IMREAD_GRAYSCALE)
if image is None : raise Exception(&quot;image None&quot;)
cv2.imshow(&quot;image&quot;,image)
cv2.waitKey()
cv2.destroyAllWindows()
print(sns.histplot(image.flatten(),legend=None))</code></pre>
</blockquote>
<pre><code>
## 3채널( 컬러 )의 히스토그램
&gt; ![](https://images.velog.io/images/noooooh_042/post/95dafbaa-74fc-4ec1-9cc4-93e1fcaaf99a/0714_iu3.PNG)
&gt; ![](https://images.velog.io/images/noooooh_042/post/83761e4a-0556-48d1-81c3-1f17f7e42e68/color_hist.PNG)
&gt; 컬러 히스토그램
&gt; 

## 히스토그램 스트레칭
&gt; 명암도 이미지에서 이미지가 선명하고 깨끗해보이려면 어두운 부분에서 밝은 부분까지 고르게 분포해야함
&gt; 그렇지 않고 특정 밝기만 있다면 이미지가 전체적으로 선명하지 않아보인다.
&gt; 
&gt; 이런 이미지의 히스토그램을 보면 분포가 좁게 나타난다.![](https://images.velog.io/images/noooooh_042/post/a99924b2-7b11-477c-b104-575769e3ed1c/iu_4_or.PNG)
&gt;![](https://images.velog.io/images/noooooh_042/post/25da5cd1-3fd9-4081-8e08-1265aa6433d4/iu_4.PNG)
&gt; 
&gt; 이렇게 히스토그램의 분포가 좁아서 영상의 대비가 좋지 않은 이미지의 화질을 개선할 수 있는 알고리즘은 히스토그램 스트레칭이다.
&gt;
&gt; 명암 분포가 좁은 히스토그램을 좌우로 잡아당겨 고른 명암 분포를 가진 히스토그램이 되게 하는 것이다.
&gt; 
&gt; 히스토그램의 가장 낮은 화소값과 가장 높은 화소값을 잡아당긴다.
&gt; 
&gt; 낮은 화소는 0으로 높은 화소는 255로 당기는 것이다.
&gt; 
&gt; 새 화소값 = (화소값 - low) / (high - low ) x 255
&gt; ![](https://images.velog.io/images/noooooh_042/post/1c0c14ce-2e0a-43a8-b451-d13fa01bdf62/iu4_4.PNG)
&gt; ![](https://images.velog.io/images/noooooh_042/post/15ec13ad-5f23-460f-8087-554fb09a5f67/hist_4.PNG)
&gt; 
&gt; ```python
image = cv2.imread(&quot;0714_iu4.png&quot;,cv2.IMREAD_GRAYSCALE)
if image is None : raise Exception(&quot;image None&quot;)
image_flat = image.flatten()
low = 25
high = 80
idx = np.arange(0,256)
idx = (idx - low) / (high - low) *255
idx[0:int(low)] = 0
idx[int(high+1):] = 255
dst = cv2.LUT(image,idx.astype(&#39;uint8&#39;))
cv2.imshow(&quot;dst&quot;,dst)
cv2.imshow(&quot;image&quot;,image)
cv2.waitKey()
cv2.destroyAllWindows()</code></pre><blockquote>
<p>어두운 부분이 사라지고 선명해진 것을 확인할 수 있다.
코드에서 low와 high 값을 min, max 함수로 찾았는데 0과 248이 나와서 결과가 좋지 않았음
히스토그램을 보고 직접 low와 high를 지정해서 좋은 결과 산출</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[opencv_pixel_1]]></title>
            <link>https://velog.io/@noooooh_042/opencvpixel1</link>
            <guid>https://velog.io/@noooooh_042/opencvpixel1</guid>
            <pubDate>Mon, 12 Jul 2021 16:39:58 GMT</pubDate>
            <description><![CDATA[<h1 id="화소-처리">화소 처리</h1>
<h2 id="1-이미지의-밝기">1. 이미지의 밝기</h2>
<blockquote>
<p>이해하기 쉽게 흑백 이미지를 예로 들어서 이미지의 밝기 처리를 해본다.
opencv GRAYSCALE 
흑백이미지 한 픽셀의 데이터 사이즈를 보통 uint8로 정의하는데 0 ~ 255 범위를 갖게된다. 
다음은 화소값의 변화에 따른 이미지의 밝기 변화이다.
<img src="https://images.velog.io/images/noooooh_042/post/1181d6f1-9fe6-46b1-a91a-13d640de7a02/gray_1.PNG" alt=""></p>
<pre><code class="language-python">import numpy as np
import cv2
image1 = np.zeros((50,512),np.uint8)
image2 = np.zeros((50,512),np.uint8)
rows,cols = image1.shape[:2]
for i in range(rows):
    for j in range(cols):
        image1.itemset( (i, j ), j//2)
        image2.itemset( (i, j ), j//20*10)
cv2.imshow(&quot;image1&quot;,image1)
cv2.imshow(&quot;image2&quot;,image2)
cv2.waitKey(0)
cv2.destroyAllWindows()</code></pre>
</blockquote>
<pre><code>
### 1.1 이미지 화소값
&gt; 관심영역의 이미지 값을 직접 확인해보면.... ( IU )
&gt; ![](https://images.velog.io/images/noooooh_042/post/1cb6762d-2fa3-4168-b134-471198477909/iu1.PNG)
&gt; ![](https://images.velog.io/images/noooooh_042/post/3191a4f3-8400-4138-abf9-1f4d08aad760/roi.PNG)
&gt; 머리 부분에 관심영역이 있는데 검은 머리라서 pixel 값이 낮게 나왔다. 반면에 배경부분은 밝기 때문에 pixel값이 높게 나왔다.

## 2. 이미지 화소값 연산으로 밝기 변경
&gt; opencv는 밝기를 조절하는 방법이 2가지 있다.
&gt; 1. saturation ( cv2.add(), cv2.subtract() )
&gt; 2. modulo ( + , - )
&gt; saturation 방식은 화소를 더해주거나 빼줬을 때 최소 0, 최대 255 값으로 변경된다.
&gt; modulo 방식은 0 보다 작아지면 255 , 255 보다 커지면 0으로 바뀌어 계산된다.
&gt; ```python
import cv2 
image = cv2.imread(&quot;iu2.jpg&quot;,cv2.IMREAD_GRAYSCALE)
if image is None: raise Exception(&quot;이미지 x&quot;)
image_shape_y,image_shape_x = image.shape[:2]
image = cv2.resize(image,(image_shape_x//4,image_shape_y//4))
dst1 = cv2.add(image,100)
dst2 = cv2.subtract(image,100)
cv2.imshow(&quot;original&quot;,image)
cv2.imshow(&quot;bright_image&quot;,dst1)
cv2.imshow(&quot;dark_image&quot;,dst2)
cv2.waitKey(0)
cv2.destroyAllWindows()</code></pre><blockquote>
<p><img src="https://images.velog.io/images/noooooh_042/post/4e9ec093-5a3d-4765-84a5-9f9dc26d8d31/iu3.PNG" alt="">
=&gt; saturation 방식 밝기 조절 ( 원본, cv2.subtract, cv2.add )
: 밝기에 따라 느낌이 다르다~</p>
</blockquote>
<h2 id="3-명암-대비">3. 명암 대비</h2>
<blockquote>
<p>명암 대비란 상이한 두 가지 색이 경계에서 서로 영향을 미쳐 그 차이가 가 강조되어 나타나는 현상
낮은 명암 대비 이미지는 전체적으로 이미지가 어둡거나 밝다. ( 사물이나 배경 구분이 어렵다.)</p>
<pre><code class="language-python">noimage = np.zeros(image.shape[:2], image.dtype)
avg = cv2.mean(image)[0]/2.0
dst1 = cv2.scaleAdd(image,0.5,noimage)
dst2 = cv2.scaleAdd(image,2.0,noimage)
dst3 = cv2.addWeighted(image,0.5,noimage,0,avg)
dst4 = cv2.addWeighted(image,2.0,noimage,0,-avg)</code></pre>
</blockquote>
<pre><code>![](https://images.velog.io/images/noooooh_042/post/6819280e-d0e9-4ee9-9bfa-df5677dd8e33/iu4.PNG)
&gt; avg는 명암 대비 효과를 높이기 위해서 이미지의 전체 평균의 절반값을 계산한다. 
&gt; dst1은 scaleAdd를 사용하여 명암대비 0.5배
&gt; dst2는 scaleAdd를 사용하여 명암대비 2배
&gt;  곱셈만으로 명암대비를 조절하면 이미지가 전체적으로 어두워지거나 밝아진다. (dst2 , dst1)
&gt; 
&gt; 
&gt; dst3와 dst4는 명암대비를 조절하면서 이미지의 화소값의 평균값을 추가로 이용한다. 
&gt; cv2.addWeighted(이미지1,이미지1가중치,이미지2,이미지2가중치,결과에 추가적으로 더할 값)
&gt; dst3는 이미지의 명암을 0.5배 곱한 후 평균의 절반을 더해주었다.
&gt; dst4는 이미지의 명암을 2배 곱한 후 평균의 절반을 빼주었다.
&gt; 그 결과 전반적으로 밝고 밝은 부분은 더 밝게 어두운 부분은 어둡게 되며 전체적으로 이미지가 또렷해졌다.

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[앙상블]]></title>
            <link>https://velog.io/@noooooh_042/%EC%95%99%EC%83%81%EB%B8%94</link>
            <guid>https://velog.io/@noooooh_042/%EC%95%99%EC%83%81%EB%B8%94</guid>
            <pubDate>Sun, 04 Jul 2021 07:59:56 GMT</pubDate>
            <description><![CDATA[<h1 id="앙상블-학습">앙상블 학습</h1>
<blockquote>
<ol>
<li>앙상블 학습이란</li>
<li>과반수 투표 분석</li>
<li>배깅 분석</li>
<li>랜덤 포레스트 분석</li>
<li>부스팅 분석</li>
</ol>
</blockquote>
<h2 id="1-앙상블-학습이란">1. 앙상블 학습이란</h2>
<h3 id="목적">목적</h3>
<ul>
<li>여러 분류기( 모델 )를 하나의 메타 분류기로 연결( 통합한다는 의미가 강하다) 하여 개별 분류기보다 더 좋은 일반화 성능을 달성</li>
</ul>
<h3 id="방법">방법</h3>
<ul>
<li>여러 분류 알고리즘 사용 : 다수결 투표</li>
<li>하나의 분류 알고리즘 이용 : 배깅(bagging), 부스팅 (boosting)</li>
</ul>
<h3 id="종류">종류</h3>
<ul>
<li>투표 : 동일한 훈련세트</li>
<li>배깅 : 훈련 샘플에서 알고리즘 마다 별도의 훈련 세트 추출<ul>
<li>랜덤포레스트 : 의사결정 나무</li>
</ul>
</li>
<li>부스팅 : 샘플을 뽑을 때 잘못 분류된 data 50%를 재학습, 또는 가중치 이용</li>
</ul>
<h3 id="과반수-투표">과반수 투표</h3>
<ul>
<li>방법<ul>
<li>동일한 훈련세트로 모델 구축</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/6d89ec4c-6cac-45fe-8b7d-85f65b451894/image-20200928182452647.png" alt=""></p>
<blockquote>
<p> 최종 예측은 각 훈련 모델에서 예측한 값들을 모으고 투표하여 다수결로 결정한다.</p>
<p> 훈련 세트는 하나만 이용한다. </p>
<p> 여러 모델에 하나의 데이터를 적용해본다.</p>
</blockquote>
<h3 id="배깅">배깅</h3>
<ul>
<li>방법<ul>
<li>훈련 샘플에서 알고리즘 마다 별도의 훈련 세트를 추출해서 모델 구축 </li>
<li>부트스트랩 실시: 데이터로 부터 복원 추출을(중복 허용)을 이용</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/c2e2b3d4-6240-494b-870b-fbc641694f73/image-20200928183139929.png" alt=""></p>
<blockquote>
<p><strong>하나의 분류 모델</strong>이지만 <strong>여러 개의 옵션</strong>을 준다.</p>
<p>여러 개의 샘플을 모델에 넣고 돌려 결과값을 얻어내고 다수의 결과값을 가지고 모델을 만들어감</p>
<p>하나의 데이터 샘플에서 몇 개를 뽑아서 샘플 데이터를 만든다.</p>
<p>분류 모델을 다양하게 쓸 수 있다. (DT, LR...)</p>
<p>DicisionTree와 관련되어있다.</p>
</blockquote>
<h3 id="랜덤포레스트">랜덤포레스트</h3>
<ul>
<li>방법<ul>
<li>배깅의 일종</li>
<li>단일 분류 알고리즘(DT) 사용</li>
<li>포레스트 구축 : 무작위로 예측 변수 선택하여 모델 구축</li>
<li>결과 결합 : 투표(분류) , 평균화 (예측)</li>
<li>나무구조로 표현 ( X ) -&gt; 변수의 중요도 제공 </li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/4fe04988-a423-4f0d-aff1-1c719205d4c5/image-20200928184245156.png" alt=""></p>
<blockquote>
<p>트리에서 숲!</p>
<p>여러개의 트리들에 들어가는 요인들이 바뀐다. -&gt; 다양한 모델 -&gt; 통합 -&gt; BEST</p>
<p>예측률은 높일 수 있으나 설명력이 약하다. 왜 그렇게 나오고 어떤 의미가 있나? - 앙상블 목적 자체가 정확도를 높이는 거다.</p>
<p>중요한 변수를 골라낼 수 있지만 어떤 규칙에 의해 어떻게 만들어 졌다고 골라내기 어렵다 =&gt; 통합 모델을 만들어내기 때문</p>
</blockquote>
<h3 id="부스팅">부스팅</h3>
<ul>
<li>방법<ul>
<li>샘플 뽑을 때 잘못 분류된 data 50%를 재학습</li>
<li>AdaBoost : 전체 훈련 샘플 사용하고, 잘못 분류된 data에 가중치</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/1d989817-7022-4ca0-8a75-3a3634ba5b2d/image-20200928184706373.png" alt=""></p>
<blockquote>
<p>데이터 반을 재활용하는 방법</p>
<p>가장 정확도가 높게 나오는 것은 부스팅  but 실제 시스템에서 사용하기에 복잡하고 어렵다... ( 잘못된 것에 가중치를 준다. )</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[연관규칙]]></title>
            <link>https://velog.io/@noooooh_042/%EC%97%B0%EA%B4%80%EA%B7%9C%EC%B9%99</link>
            <guid>https://velog.io/@noooooh_042/%EC%97%B0%EA%B4%80%EA%B7%9C%EC%B9%99</guid>
            <pubDate>Sun, 04 Jul 2021 07:58:23 GMT</pubDate>
            <description><![CDATA[<h1 id="연관-규칙">연관 규칙</h1>
<h3 id="1-useful-result">1. Useful Result</h3>
<blockquote>
<p>마케팅 전략상 유용한 결과가 나온 경우</p>
<p>ex) 주말을 위해, 목요일 소매점에 기저귀를 사러 온 아빠들은 맥주도 함께 구매 -&gt; 주말에 football을 보면서 마심</p>
</blockquote>
<h3 id="2-trivial-result">2. Trivial Result</h3>
<blockquote>
<p>기존의 마케팅 전략에 의해 연관성이 높게 나온 경우</p>
<p>ex) 정비 계약을 맺은 소비자들은 많은 설비를 구매 -&gt; 정비 계약은 대개의 경우 따로 맺어지는 것이 아니라, 많은 설비 구입시 함께 제시</p>
</blockquote>
<h3 id="3-inexplicable-result">3. Inexplicable Result</h3>
<blockquote>
<h4 id="의미를-발견하기-위해-많은-고민이-필요한-경우">의미를 발견하기 위해 많은 고민이 필요한 경우</h4>
<p>ex) 새로 철물점을 개업하면, 대개 화장실 문고리를 많이 구매 -&gt; 어떤 의미가 있는지 고민 필요</p>
</blockquote>
<h3 id="2-연관성-규칙-생성-과정">2. 연관성 규칙 생성 과정</h3>
<h4 id="1단계--지지도support">1단계 : 지지도(support)</h4>
<blockquote>
<p>빈발(frequent) 항목 집합들에 기초하여 후보 규칙들의 집합 결정</p>
<p>단일 항목 집합, 2개 항목집합, 3개 항목집합</p>
<p>통계적 유의성 ( statistic significance)</p>
<p>전체적인 거래 규모에 대한 값</p>
<p><strong>값이 클수록 자주 발생하는 거래 ( 한 항목 거래 건수 / 총 항목 거래 건수)</strong></p>
<p>지지도에 의해 결정</p>
<p>대표 알고리즘 : *<em>apriori *</em>알고리즘</p>
<p>-&gt; A와 B가 동시에 장바구니에 담길 확률 = support</p>
</blockquote>
<h3 id="-ariori-알고리즘-원리">* ariori 알고리즘 원리</h3>
<p><img src="https://images.velog.io/images/noooooh_042/post/1fed5959-ec21-4b32-baa7-f83bd7cad314/image-20200919111833405.png" alt=""></p>
<h3 id="-ariori-알고리즘-설명">* ariori 알고리즘 설명</h3>
<ul>
<li>Database를 통해 모든 항목을 포함한 집합군 검색 {A, B, C, D, E}</li>
<li>앞의 표에서 최소지지도 2</li>
<li>단일항목 지지도 계산 -&gt; L1에서 {D} 제거</li>
<li>{D} 를 제외한 2개 항목 집합군을 생성한 후 지지도 계산 -&gt; L2에서 {A, B}, {A, E} 제거</li>
<li>3개 항목 집합군 생성 -&gt; {A, B, C}, {A, B, E}, {A, C, E} 는 {A, B} = 1, {A, C} = 1, {A,E} = 1 이므로 후보군에서 제외</li>
</ul>
<h4 id="2단계--신뢰도-confidence">2단계 : 신뢰도 (confidence)</h4>
<blockquote>
<p>규칙의 불확실성을 평가하기 위해서 신뢰도 사용</p>
<p>연관 규칙의 강도 ( rule strength )</p>
<p>선행항목 A를 포함하는 거래 중에서 후행항목 B가 포함된 거래의 비율</p>
<p>A를 구매한 경우, 이 중에서 얼마나 항목 B를 구매할 것인지를 의미</p>
<p><strong>값이 클수록 A 구매시 B 구매율이 높음</strong></p>
<p>최소 기준 신뢰도 값을 설정</p>
<p>-&gt; A가 구매됬을 때 B를 구매하면 어떤 연관성이 있을까 = confidence</p>
</blockquote>
<h4 id="3단계--향상도-lift">3단계 : 향상도 (lift)</h4>
<blockquote>
<p>상대적 관련성은 실제 거래 발생 확률을 각 아이템의 거래가 독립적일 경우에 비해 그 거래가 동시에 발생할 예상기대확률로 나눈것</p>
<p>항목 B가 임의로 구매될 확률에 비해 항목 A를 구매한 후에 항목 B를 구매할 확률의 비율</p>
<p>항목 A와 B의 구매 패턴이 독립적인지, 서로 상관성이 있는지 파악</p>
<p>향상도 &gt; 1</p>
<p>향상도 : 임의로 조합된 규칙과의 비교를 통해 해당 규칙이 얼마나 실제적인 연관성을 가지고 있는지 파악</p>
<p>*<em>Lift (A=&gt;B) = c (A=&gt;B) / s (A=&gt;B) *</em></p>
<p>​                <strong>= 항목 A가 구매된 이후 항목 B가 구매될 확률 / 항목 B가 구매될 확률</strong></p>
</blockquote>
<table>
<thead>
<tr>
<th>Lift</th>
<th>의미</th>
<th>예</th>
</tr>
</thead>
<tbody><tr>
<td>&lt;1</td>
<td>두 품목이 서로 음의 상관관계</td>
<td>지사제와 변비약</td>
</tr>
<tr>
<td>1</td>
<td>두 품목이 서로 독립적인 관계</td>
<td>과자와 후추</td>
</tr>
<tr>
<td>&gt;1</td>
<td>두 품목이 서로 양의 상관관계</td>
<td>빵과 버터</td>
</tr>
</tbody></table>
<h4 id="의미-파악">의미 파악</h4>
<p>연관규칙</p>
<blockquote>
<p>{맥주 -&gt; 콜라} : 지지도 = 50 , 신뢰도 = 1.00 향상도 1.50</p>
<p>지지도 : 맥주와 콜라를 동시에 구매한 사람은 전체 구매 중 절반이다. (50%)</p>
<p>신뢰도 : 맥주를 구매한 사람들은 모두 콜라도 같이 구매한다.(100%)</p>
<p>향상도 : 맥주 구매 시 콜라를 구매하게 될 가능성은 그냥 콜라를 구매할 때보다 1.5배나 높아진다.</p>
</blockquote>
<h3 id="2-고려사항">2. 고려사항</h3>
<ul>
<li>신뢰도 값이 크면 좋지만 신뢰도가 크다고 최선의 연관성 규칙이라고 볼 수는 없음<ul>
<li>두 항목의 기본적인 구매율이 어느 정도 수준이 되어야만 의미가 있음</li>
<li>즉, 지지도가 어느 정도 수준에 도달해야만 한다.</li>
</ul>
</li>
</ul>
<ul>
<li>신뢰도와 지지도는 자주 구매되는 항목에 대해서는 연관성 때문이 아니라 우연히 높게 나올 수도 있음<ul>
<li>Lift 확인</li>
</ul>
</li>
</ul>
<ul>
<li>신뢰도가 높을 경우에는 X =&gt; Y 에서 항목 Y의 확률이 커야지 이 연관성 규칙이 의미가 있음<ul>
<li>Lifit 값이 1보다 커야 유용한 정보가 됨</li>
</ul>
</li>
</ul>
<h3 id="3-연관-규칙-장점과-단점">3. 연관 규칙 장점과 단점</h3>
<h4 id="1-장점">1. 장점</h4>
<ul>
<li>수 많은 품목 간에 유의한 연관성을 갖는 구매 패턴을 찾아주고, 이를 바탕으로 또 다른 연구 가설을 탐지할 수 있는 가능성 제공</li>
<li>자료구조와 계산과정이 간단하며, 결과가 명확하고 이해하기 쉬움</li>
<li>사전에 특별한 분석 방향이나 목적이 없는 경우, 비 목적성 데이터 마이닝 분석기법으로 매우 효과적임</li>
</ul>
<h4 id="2-단점">2. 단점</h4>
<ul>
<li>연관 규칙에서 얻어지는 결과가 상당히 많기 때문에 실무적인 활용도가 떨어질 수 있음</li>
<li>항목의 수를 결정하기 어려움ㄴ</li>
<li>드물게 발생하는 항목에 대해서 처리가 어려움</li>
<li>DBMS 등과 같은 전산화 작업이 없을 시는 동일한 거래를 추적하기가 어려움</li>
<li>항목의 수가 증가하면 계산시간이 급격히 증가</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[의사결정나무]]></title>
            <link>https://velog.io/@noooooh_042/%EC%9D%98%EC%82%AC%EA%B2%B0%EC%A0%95%EB%82%98%EB%AC%B4</link>
            <guid>https://velog.io/@noooooh_042/%EC%9D%98%EC%82%AC%EA%B2%B0%EC%A0%95%EB%82%98%EB%AC%B4</guid>
            <pubDate>Sun, 04 Jul 2021 07:52:12 GMT</pubDate>
            <description><![CDATA[<h2 id="의사결정나무-decision-tree">의사결정나무( Decision tree)</h2>
<ul>
<li>의사결정규칙(decision rule)을 나무 구조로 도표화하여 <strong>분류</strong>(classification)와 <strong>예측</strong>(prediction)을 수행하는 분석 방법</li>
</ul>
<h3 id="주요-방법">주요 방법</h3>
<ul>
<li>Tree and rule 구조<ul>
<li>규칙(rule)은 나무 무델로 표현</li>
<li>결과는 규칙으로 표현</li>
</ul>
</li>
<li>재귀적 분할 <ul>
<li>나무 만드는 과정 -&gt; 계속 쪼개지게 한다.</li>
<li>그룹이 최대한 동질하도록 반복적으로 레코드 하위 그룹으로 분리</li>
</ul>
</li>
<li>가지치기<ul>
<li>생성된 나무를 자르는 과정 (정교화)</li>
<li>과적합을 피하기 위해 필요없는 가지를 간단히 정리</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/f57edfce-0f68-45db-ac10-f0ee44b63bee/image-20200923222929061.png" alt=""></p>
<h2 id="decision-tree-특징">Decision Tree 특징</h2>
<h3 id="재귀적-분할-알고리즘">재귀적 분할 알고리즘</h3>
<ul>
<li>CART( Classication And Regression Tree)</li>
<li>C4.5</li>
<li>CHAID (Chi - square Automatic Interation Detection)</li>
</ul>
<h3 id="불순도impurity-알고리즘">불순도(Impurity) 알고리즘</h3>
<ul>
<li>지니 지수</li>
<li>엔트로피 지수(Entropu Index), 정보 이익(Information Gain)</li>
<li>카이제곱 통계량</li>
</ul>
<h4 id="분류나무의-장점">분류나무의 장점</h4>
<ul>
<li>지도학습(분류 및 예측)의 데이터 마이닝 기법</li>
<li>적용 결과에 의해 if - then으로 표현되는 규칙이 생성</li>
<li>규칙의 이해가 쉽고 SQL과 같은 DB 언어로 표현</li>
<li>좋은 해석력으로 널리 쓰임</li>
<li>많은 분야에서는 결정을 내리게 된 이유를 설명하는 능력이 중요함(해석력)<ul>
<li>예 : 은행의 대출 심사 결과 부적격 판정이 나온 경우 고객에게 부적격 이류를 설명해야함</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/0e963aa1-2ff4-434c-882b-a80b8e0b57a0/image-20200925003425585.png" alt=""></p>
<p>어느 규칙이 가장 중요한 규칙인지 알아야 함</p>
<p>규칙(rule)을 어디까지 쓸지 정해야 한다. </p>
<h4 id="분류나무-classification-tree">분류나무 (Classification Tree)</h4>
<ul>
<li><p>목표변수 : 범주형(categorical target) - 좋음, 나쁨</p>
</li>
<li><p>예측변수 : 범주형, 수치형 가능 --&gt; 표준화 안시켜도 된다.  /// 보통 수치형 데이터는 표준화를 시켜야함</p>
</li>
<li><p>재귀적 분할 (Recursive pariting)</p>
<ul>
<li>그룹이 최대한 동질(순수)하도록 반복적으로 레코드를 하위그룹으로 분리 (순수: 하나의 그룹에 같은 class만 존재)</li>
</ul>
</li>
<li><p>가지치기 (pruning the tree)</p>
<ul>
<li>과적합을 피하기 위해 필요없는 가지를 간단히 정리</li>
</ul>
</li>
<li><p>분류 알고리즘과 순수도 지표 ( 얼마만큼 그룹을 정확하게 나눠줄 수 있는지 숫자로 표현 )</p>
<ul>
<li>CART : 지니 지수(Gini index)</li>
<li>C4.5 : 엔트로피 지수(Entropy index), 정보 이익, 정보이익비율</li>
<li>CHAID : 카이제곱 통계량(Chi - Square static)</li>
</ul>
</li>
<li><p>끝마디 : 소속집단</p>
</li>
<li><p>경향(랭킹)도 가능</p>
</li>
</ul>
<h4 id="회기나무-regression-tree">회기나무 (Regression Tree)</h4>
<ul>
<li><p>잘 안쓰인다. ( 회기분석, 인공지능 등이 더 잘 분석하기 때문 )</p>
</li>
<li><p>목표변수 : 연속 변수(Continuous Variables) - 총구매액, 매출액 -&gt; 값을 예측</p>
</li>
<li><p>분류 알고리즘 </p>
<ul>
<li>CART  F통계량 -분산의 감소량</li>
</ul>
</li>
<li><p>끝마디 : 집단의 평균</p>
</li>
<li><p>목표변수의 평균에 기초하여 분리</p>
</li>
<li><p>분리의 경계점 근방에서는 예측 오류가 클 가능성</p>
<ul>
<li>예측일 경우 회기나무보다 신경망 또는 회귀분석이 더 좋음</li>
</ul>
</li>
</ul>
<h4 id="의사결정-나무의-구성-원리">의사결정 나무의 구성 원리</h4>
<ul>
<li>일정기준(나무의 최종 node 수 , 자료 수, 나무의 깊이)에 의해 나무의 모양이 결정</li>
<li>의사결정 트리의 가지 분리방법(split), 잘라내기(Prune) 방법에 따라 CHAID, CART, C4.5, QUEST 등 여러가지 알고리즘이 사용</li>
<li>분리기준 : 순수도(Purity), 불순도(Impurity) 기준</li>
<li>정지규칙 : 더 이상 분리가 일어나지 않고 현재의 마디가 끝마디가 되도록하는 규칙</li>
<li>잘라내기 : 지나치게 많은 마디를 가지는 의사결정나무는 새로운 자료에 적용될 때 예측 오차가 매우 클 가능성</li>
</ul>
<h4 id="의사결정나무분석의-과정">의사결정나무분석의 과정</h4>
<ol>
<li><p>나무 모델 생성</p>
<ul>
<li>재귀적 분할 방법을 이용하여 나무모델 생성</li>
<li>CART(Gini) , C4.5(Entropy) , CHAID (Chi-square) 이용</li>
</ul>
</li>
<li><p>과적합 문제 해결 (가지치기)</p>
<ul>
<li>나무모델 생성하면서 최적모델일 때 stop : CHAID</li>
<li>완전 나무모형 생성 후 가지치기 : CART,C4.5<ul>
<li>학습 데이터만 C4.5</li>
<li>학습데이터(나무생성) -&gt; 검증 데이터(가지치기) : CART</li>
</ul>
</li>
</ul>
</li>
<li><p>검증</p>
</li>
</ol>
<ul>
<li>교차 타당성을 이용한 의사결정 나무 평가</li>
</ul>
<ol start="4">
<li>해석 및 예측</li>
</ol>
<p><img src="https://images.velog.io/images/noooooh_042/post/5209bd2f-65b0-4a35-b3ac-1ecd0d5d248c/image-20200925011308304.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모델 최적화]]></title>
            <link>https://velog.io/@noooooh_042/%EB%AA%A8%EB%8D%B8-%EC%B5%9C%EC%A0%81%ED%99%94</link>
            <guid>https://velog.io/@noooooh_042/%EB%AA%A8%EB%8D%B8-%EC%B5%9C%EC%A0%81%ED%99%94</guid>
            <pubDate>Sun, 04 Jul 2021 07:47:49 GMT</pubDate>
            <description><![CDATA[<h1 id="최적화">최적화</h1>
<h2 id="교차-검정--cross-validation">교차 검정 ( Cross Validation)</h2>
<ul>
<li>모델의 성능을 검증하기 위한 방법<ul>
<li>홀드아웃 검정</li>
<li>K-fold 검정</li>
</ul>
</li>
</ul>
<ul>
<li><p>홀드아웃 검정</p>
<ul>
<li>훈련 데이터 / 테스트 데이터를 나눈다.</li>
<li>훈련 데이터로 모델을 만든다.</li>
<li>테스트 데이터로 성능 평가
<img src="https://images.velog.io/images/noooooh_042/post/46c8a232-b508-407b-9b7d-2d1d2922eb51/image-20200927182816635.png" alt=""></li>
</ul>
</li>
<li><p>문제점 </p>
<ul>
<li>모델을 변경하는 방법론</li>
<li>최적화 파라미터를 찾기 어렵다. ( max_depth...) 일일이 대입해야한다.</li>
</ul>
</li>
</ul>
<ul>
<li><p>K-fold 검정
<img src="https://images.velog.io/images/noooooh_042/post/08613654-5a87-4c8d-b391-e4eb87bd3747/image-20200927182854529.png" alt=""></p>
</li>
<li><p>방식 </p>
<ul>
<li>훈련 데이터를 나눈 후 10% 정도를 나눠서 테스트 데이터로 사용 -&gt; 10번 반복<ul>
<li>훈련의 검증용 ( 다 만든 후 모델 검증용이 아니다. )</li>
</ul>
</li>
<li>나머지 30% ( 처음에 test / train 나눈 거 ) 최종 테스트</li>
</ul>
</li>
</ul>
<p>--- &gt; 더 엄격한 방법</p>
<ul>
<li>중간에 훈련 모델을 검증할 필요 -&gt; 모델 변경 여부 확인 <ul>
<li>주로 파라미터 검증할 때 사용</li>
<li>최종 모델을 구할 때 파라미터를 조정 ( max_depth 값을 여러번 변경 )<ul>
<li>하나의 데이터를 가지고 쓰는 것이 아니고 Cross Validation 데이터를 가지고 바꿔가면서 검증</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="2가지-방법">2가지 방법</h3>
<ol>
<li><p>모델 구축 후 교차 검증을 한다. </p>
</li>
<li><p>기본 모델을 검증한 다음 최적화를 위해 한번 돌려준다. </p>
<ul>
<li>기존 모델과 최적화된 모델을 비교 </li>
</ul>
</li>
</ol>
<ul>
<li>파이프라인 모델 만들기<ul>
<li>파이프라인을 이용하여 최적 모델 만들기</li>
<li>기본 모형은 아무 옵션이 없는 모델로 부터 시작</li>
<li>파라미터 옵션 확인 : pipe_tree.get_params().keys()</li>
</ul>
</li>
</ul>
<ul>
<li><p>과적합 문제</p>
<ul>
<li>검증 곡선으로 과대적합과 과소 적합 조사<ul>
<li>과대 적합 : 파라미터가 많음 -&gt; 파라미터 축소</li>
<li>과소적합 : 파라미터가 적음 -&gt; 파라미터 추가</li>
</ul>
</li>
</ul>
</li>
<li><p>학습 곡선 </p>
<ul>
<li>샘플 데이터의 수에 따른 정확도 변화</li>
</ul>
</li>
<li><p>검증 곡선 </p>
<ul>
<li>하이퍼 파라미터에 따른 정확도 변화
<img src="https://images.velog.io/images/noooooh_042/post/1ed39ea7-79f5-42dc-bc9f-a404c34e8a8b/image-20200927191151040.png" alt=""></li>
</ul>
</li>
</ul>
<ul>
<li>하이퍼 파라미터 튜닝 ( 가장 마지막 )<ul>
<li>그리드 서치를 사용한 머신러닝 모델 세부 튜닝</li>
<li>기계학습 모델의 성능을 결정하는 하이퍼 파라미터 튜닝</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[과대,과소적합]]></title>
            <link>https://velog.io/@noooooh_042/%EA%B3%BC%EB%8C%80%EA%B3%BC%EC%86%8C%EC%A0%81%ED%95%A9</link>
            <guid>https://velog.io/@noooooh_042/%EA%B3%BC%EB%8C%80%EA%B3%BC%EC%86%8C%EC%A0%81%ED%95%A9</guid>
            <pubDate>Sun, 04 Jul 2021 07:45:41 GMT</pubDate>
            <description><![CDATA[<h1 id="과소-과대-적합">과소 과대 적합</h1>
<h3 id="과적합overfitting">과적합(overfitting)</h3>
<ul>
<li>학습용 데이터에 완전히 적합</li>
<li>학습용 집합에서 잡음(noise)도 모형화하기 때문에 평가용 집합에서 전체 오차는 일반적으로 증가</li>
</ul>
<h3 id="모델-개발의-목적">모델 개발의 목적</h3>
<ul>
<li>학습용 Data에서는 높은 성과 =&gt; 평가용 Data에서는 낮은 성과 ( x )</li>
<li>현재 데이터의 설명 =&gt; 미래 데이터 예측 ( O )
<img src="https://images.velog.io/images/noooooh_042/post/da7ce6b2-c26a-4503-accb-30ff91ce2d50/image-20200926190758874.png" alt=""></li>
</ul>
<h2 id="과적합-문제">과적합 문제</h2>
<h3 id="과소적합--높은-편향-">과소적합 ( 높은 편향 )</h3>
<ul>
<li>훈련, 검증 정확도 모두 낮음</li>
<li>데이터가 작거나 많이 돌리지 않았다.</li>
</ul>
<h3 id="과대-적합높은-분산">과대 적합(높은 분산)</h3>
<ul>
<li>훈련 데이터에 비해 모델이 너무 복잡할 경우</li>
<li>너무 많이 훈련을 돌려 훈련 데이터에만 맞아지는 경우</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/81687074-1635-4a16-ad5f-343106e82e80/image-20200926190938232.png" alt=""></p>
<ul>
<li><p>학습곡선 (Learning Curve)</p>
<ul>
<li>샘플 데이터의 수에 따른 정확도 변화</li>
</ul>
</li>
<li><p>검증 곡선 (Validation Curve)</p>
<ul>
<li>하이퍼 파라미터에 따른 정확도</li>
</ul>
</li>
</ul>
<h2 id="과적합-방지">과적합 방지</h2>
<h3 id="성장-멈추기-stopping-tree-growth">성장 멈추기 (stopping Tree Growth)</h3>
<ul>
<li>나무 모델을 성장시키면서 특정 조건에서 성장을 중단</li>
<li>나무모델의 깊이 : 복잡도 파라미터</li>
<li>노드 내의 최소 관측치의 수</li>
<li>불순도의 최소 감소량<ul>
<li>CHAID 에서 사용</li>
<li>나무모델 생성시에 통계적으로 유의하지 않으면 종료</li>
<li>가지치기 사용하지 않고 종료</li>
</ul>
</li>
</ul>
<p>=================&gt;&gt;&gt; 하지만 잘 안쓰인다.</p>
<h3 id="가지치기--pruning-the-tree">가지치기 ( Pruning the Tree)</h3>
<ul>
<li>나무 모델 생성 후 필요없는 가지 제거</li>
<li>성장을 멈추기 보다 더 성능 우수</li>
<li>C4.5 : 학습 데이터를 이용하여 나무 모델 성장과 가지치기에 사용</li>
<li>CART : 학습 데이터는 나무모델 성장에, 검증 데이터는 가지치기에 사용</li>
</ul>
<p>====&gt; 처음부터 다 한 후 가지치기로 골라낸다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[confusion matrix]]></title>
            <link>https://velog.io/@noooooh_042/confusion-matrix</link>
            <guid>https://velog.io/@noooooh_042/confusion-matrix</guid>
            <pubDate>Sun, 04 Jul 2021 07:17:52 GMT</pubDate>
            <description><![CDATA[<h2 id="정오-행렬-confusion-matrix">정오 행렬 (confusion matrix)</h2>
<ul>
<li><p>대칭적 상대적인 표현들</p>
<ul>
<li>정확도(Accuracy) vs 오류율(Error Rate)  </li>
<li>TPR (True Positive Rate) vs FPR ( False Positive Rate)</li>
<li>민감도 vs 특이도</li>
<li>재현율 vs 정밀도</li>
</ul>
<h2 id="정오-분류표로-검정">정오 분류표로 검정</h2>
</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/eaac73b9-5f5a-4213-8866-ef8d8dd6711d/image-20200925213241366.png" alt=""></p>
<h3 id="정확도-vs-오류율">정확도 vs 오류율</h3>
<ul>
<li><p>정확도  : 클래스 0과 1 모두를 정확하게 분류</p>
</li>
<li><p>오류율 : 클래스 0과 1 모두를 정확하게 분류하지 못함
<img src="https://images.velog.io/images/noooooh_042/post/5376a24b-fa81-4da0-8ac5-070c9d4bb63c/image-20200925215118913.png" alt="">
<img src="https://images.velog.io/images/noooooh_042/post/2f71f86f-7a35-4c0a-a729-6a1242085b0f/image-20200925215140049.png" alt=""></p>
</li>
<li><p>정확도는 맞춘 갯수 / 총 갯수 </p>
</li>
<li><p>오류율은 틀릿 갯수 / 총 갯수</p>
</li>
</ul>
<p>0 : Negative 
1 : Positive</p>
<p>중요한 변수는 1로 놓고 본다. </p>
<ul>
<li>TN ( True Negative ) / TP (True Positive)</li>
<li>PN ( Predict Negative) / PP (Predict Positive)</li>
</ul>
<h3 id="정오-행렬-confusiin-matrix">정오 행렬 (Confusiin matrix)</h3>
<ul>
<li><strong>TPR</strong> ( True Positive Rate ) : <strong>실제</strong> Class 1 중 잘 맞춘 것  == <strong>민감도</strong> == <strong>재현율</strong><ul>
<li>우리가 관심있는 것을 잘 맞췄는가( 실제값 중에서 잘 맞춘것 )</li>
</ul>
</li>
<li><strong>FPR</strong> ( False Positive Rate ) : <strong>실제</strong> Class 0 중 못 맞춘 것<ul>
<li>내가 관심이 없는 것 중에 못 맞춘 것 ( 실제 값 중에 못 맞춘 것 )</li>
</ul>
</li>
<li><strong>특이도</strong> (Specificity) : <strong>실제</strong> Class 0중에 잘 맞춘것 ( = 1- FPR)<ul>
<li>내가 관심이 없는 것 중에 잘 맞춘 것</li>
</ul>
</li>
<li><strong>정밀도</strong>( Precision ) : <strong>예측</strong> Class 1 중 잘 맞춘 것<ul>
<li>내가 예측한 것 중에 잘 맞춘 것</li>
</ul>
</li>
<li><strong>F1</strong> : <strong>실제</strong> 잘 맞춘 것 + <strong>예측</strong> 잘 맞춘 것  ( 재현율 up and 정밀도 up )</li>
</ul>
<p><img src="https://images.velog.io/images/noooooh_042/post/ceb83c24-0985-4a93-a3fb-e5b4f5ffddf2/image-20200925220524554.png" alt=""></p>
<p>&gt; 나중에 실제값 중에 잘 맞췄나 예측값 중에 잘 맞췄나에 따라 모델을 결정할 수도 있다.</p>
<p><img src="https://images.velog.io/images/noooooh_042/post/6fef1b13-181e-40b0-859b-fc352e1dc20c/image-20200925220859302.png" alt="">
<img src="https://images.velog.io/images/noooooh_042/post/bbd463fc-d424-474d-8cad-cf8d9561723a/image-20200925220917948.png" alt="">
<img src="https://images.velog.io/images/noooooh_042/post/b8d784a5-75af-431e-861d-65e01ca08d1b/image-20200925221139988.png" alt="">
<img src="https://images.velog.io/images/noooooh_042/post/553c7c90-c51c-47c1-a5f5-38887740b650/image-20200925221714588.png" alt=""></p>
<h3 id="roc-그래프">ROC 그래프</h3>
<p><img src="https://images.velog.io/images/noooooh_042/post/2d3c74b0-dca3-4fe7-8814-398021cdf76e/image-20200925223234497.png" alt=""></p>
<p>&gt; 검정색 선이 기준선 : 반만 맞춘것 ( 모델을 안돌려도 50%는 맞춘다. )
&gt; 기준선 보다 얼마만큼 잘 맞추느냐 -&gt; 그래프가 파란색 처럼 좌상향이 되야 잘 맞추는거 ( TPR &gt; FPR 경우 )</p>
]]></description>
        </item>
    </channel>
</rss>