<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>insung_na.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sat, 29 Jul 2023 04:48:39 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>insung_na.log</title>
            <url>https://velog.velcdn.com/images/insung_na/profile/798d72d3-0eb2-40ca-96c6-a7e5fddd7927/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. insung_na.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/insung_na" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[6강. 파일입출력]]></title>
            <link>https://velog.io/@insung_na/6%EA%B0%95.-%ED%8C%8C%EC%9D%BC%EC%9E%85%EC%B6%9C%EB%A0%A5</link>
            <guid>https://velog.io/@insung_na/6%EA%B0%95.-%ED%8C%8C%EC%9D%BC%EC%9E%85%EC%B6%9C%EB%A0%A5</guid>
            <pubDate>Sat, 29 Jul 2023 04:48:39 GMT</pubDate>
            <description><![CDATA[<h1 id="1-파일-스트림stream">1. 파일 스트림(Stream)</h1>
<h2 id="스트림">스트림</h2>
<ul>
<li>파일, 네트워크 등에서 데이터를 바이트 단위로 읽고 쓰는 클래스</li>
<li>Stream class는 상위 기본 클래스<ul>
<li>FileSteam</li>
<li>MemoryStream</li>
<li>NetworkStream</li>
<li>SqllFileStream</li>
</ul>
</li>
<li><code>using System.IO</code>로 선언</li>
</ul>
<h2 id="filestream">FileStream</h2>
<ul>
<li>파일 입출력을 다루는 기본 클래스</li>
<li>byte[]  배열로 데이터를 읽거나 저장함
-&gt; 형변환이 요구됨</li>
<li>StreamWriter / StreamReader</li>
<li>BinaryWriter / BinaryReader<pre><code class="language-cs">public FileStream(
  string path,        //경로
  FileMode mode,        //Append, Create, CreateNew, Open, OpenOrCreate, Truncate
  FileAccess access    //Read, ReadWrite, Write
)</code></pre>
</li>
</ul>
<h2 id="텍스트-파일-처리">텍스트 파일 처리</h2>
<ul>
<li>StreamWriter, StreamReader</li>
<li>텍스트 파일 특징<ul>
<li>기본단위: 1바이트</li>
<li>아스키코드: 기반</li>
</ul>
</li>
<li>C# 인코딩: 아스키코드 -&gt; 유니코드</li>
</ul>
<h3 id="streamwriter">StreamWriter</h3>
<ul>
<li>파일쓰기</li>
<li><code>public class StreamWriter : TextWriter</code><blockquote>
<p>상속구조</p>
<ul>
<li>System.Object<ul>
<li>System.MarshalByRefObject<ul>
<li>System.IO.TextWriter<ul>
<li>System.IO.StreamWriter</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</li>
</ul>
<pre><code class="language-cs">static void Main(string[] args)
{
    //실행파일이 존재하는 Debug 디렉토리에 생성됨
    FileStream fs = new FileStream(&quot;test.txt&quot;, FileMode.Create);
    StreamWriter sw = new StreamWriter(fs);
    //파일 입출력 처리
    sw.WriteLine(12);
    sw.WriteLine(3.14f);
    sw.Write(&quot;Hello World&quot;);
    sw.Close();

    //아래와 같이 사용 시 Close() 메서드 사용 불필요, 자동 Close() 실행
    //단순 쓰기용으로 사용한다면 FileStream 불필요, &quot;파일명&quot;만 작성해도 실행가능
    using (StreamWriter sw2 = new StreamWriter(new FileStream(&quot;test2.txt&quot;, FileMode.Create)))
    {
        //파일 입출력 처리
    }
}</code></pre>
<h3 id="streamreader">StreamReader</h3>
<ul>
<li>파일읽기</li>
<li><code>public class StreamReader : TextReader</code><blockquote>
<p>상속구조</p>
<ul>
<li>System.Object<ul>
<li>System.MarshalByRefObject<ul>
<li>System.IO.TextReader<ul>
<li>System.IO.StreamReader</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</li>
</ul>
<pre><code class="language-cs">static void Main(string[] args)
{
    //단순 읽기용으로 사용한다면 FileStream 불필요, &quot;파일명&quot;만 작성해도 실행가능
    FileStream fs = new FileStream(&quot;test.txt&quot;, FileMode.Open, FileAccess.Read);
    StreamReader sr = new StreamReader(fs);
    //파일 입출력 처리
    var value = int.Parse(sr.ReadLine());
    var value2 = float.Parse(sr.ReadLine());
    var str1 = sr.ReadLine();
    sr.Close();

    Console.WriteLine(&quot;{0}, {1}, {2}&quot;, value, value2, str1);
}</code></pre>
<h3 id="string-데이터-분리">string 데이터 분리</h3>
<ul>
<li>string.Split 활용<pre><code class="language-cs">string str = &quot;C언어: 90 C#언어: ,100 컴퓨터.구조: 70&quot;;
</code></pre>
</li>
</ul>
<p>var str_Element = str.Split(&#39;,&#39;, &#39;.&#39;, &#39; &#39;);
foreach(var element in str_Element)
    Console.WriteLine(element);</p>
<hr>
<p>C언어:
90
C#언어:</p>
<p>100
컴퓨터
구조:
70
계속하려면 아무 키나 누르십시오 . . .</p>
<pre><code>
### 바이너리 파일 읽고 쓰기
- 위와 동일한 형식으로 진행
- 쓰기모드
```cs
using (BinaryWriter bw = new BinaryWriter(new FileStream(&quot;test.dat&quot;, FileMode.Create)))
{
    //파일 입력 처리
    bw.Write(12);
    bw.Write(3.14f);
    bw.Write(&quot;Hello World&quot;);
}</code></pre><ul>
<li>읽기모드
<code>BinaryReader(Stream, Encoding, Boolean)</code><ul>
<li>Stream: 타겟(FileStream)</li>
<li>Encoding: 인코딩 설정(default = UTF-8)</li>
<li>Boolean: 객체 소멸 시 입력스트림 닫기 여부(default=false)<pre><code class="language-cs">int var1;
float var2;
string str1;
</code></pre>
</li>
</ul>
</li>
</ul>
<p>using (BinaryReader br = new BinaryReader(File.Open(&quot;test.data&quot;, FileMode.Open)))
{
    //파일 입력 처리
    var1 = br.ReadInt32();
    var2 = br.ReadSingle();
    str1 = br.ReadString();
}
Console.WriteLine(&quot;{0} {1} {2}&quot;, var1, var2, str1);</p>
<hr>
<p>12 3.14 Hello World</p>
<pre><code># 2. 직렬화(Serialize)
## 직렬화
- 기존의 StreamWriter/StreamReader(바이너리 포함)
  -&gt; 기본 데이터형만 저장 및 읽기 가능
- BinaryFormatter 네임스페이스
  - 구조체, 클래스 저장 및 읽기를 지원함

```cs
[Serializable]
Struct A    //클래스도 사용가능
{
    //파라미터 입력
}</code></pre><pre><code class="language-cs">public void Serialize(
    Stream serializationStream,
    object graph
)

//Deserialize은 object형임으로 기본형으로 형변환 필요
public object Deserialize(
    Stream serializationStream
)</code></pre>
<h2 id="역직렬화deserialize">역직렬화(deserialize)</h2>
<ul>
<li>직렬화 대상에서 제외<pre><code class="language-cs">[Serializable]
class TestClass
{
  int nValue;
  [NonSerialize]
  string strMessage;
  //내용
}</code></pre>
</li>
</ul>
<h3 id="직렬화와-역직렬화-예시">직렬화와 역직렬화 예시</h3>
<ul>
<li><p>직렬화 시도 후 직렬화된 데이터 읽기는 정상적으로 출력됨</p>
</li>
<li><p>역직렬화로 직렬화가 되지 않은 데이터 읽기는 공백으로 출력됨</p>
<pre><code class="language-cs">static void 직렬화()
{
  DATA[] Data = new DATA[2];
  Data[0].var1 = 1;
  Data[0].var2 = 0.5f;
  Data[0].str1 = &quot;Test1&quot;;
  Data[1].var1 = 2;
  Data[1].var2 = 1.5f;
  Data[1].str1 = &quot;Test2&quot;;

  using (FileStream fs1 = new FileStream(&quot;test.dat&quot;, FileMode.Create))
  {
      BinaryFormatter bf = new BinaryFormatter();
      bf.Serialize(fs1, Data);
  }

  DATA[] ResultData;

  using (FileStream fs2 = new FileStream(&quot;test.dat&quot;, FileMode.Open))
  {
      BinaryFormatter bf2 = new BinaryFormatter();
      ResultData = (DATA[])bf2.Deserialize(fs2);
  }

  for(int i=0;i&lt;2;i++)
      Console.WriteLine(&quot;{0} {1} {2} {3}&quot;, 
          ResultData[i].var1, ResultData[i].var2, ResultData[i].str1, 1);
}</code></pre>
</li>
</ul>
<hr>
<p>1 0.5  1
2 1.5  1</p>
<pre><code>
## 컬렉션의 직렬화
- 같은 데이터형의 임의의 메모리 또는 연속적인 메모리를 다룰 수 있도록 하는 클래스
- ArrayList, List&lt;T\&gt;
- 제네릭(&lt;&gt;)을 이용한 직렬화
```cs
[Serializable]
struct Data
{
    public int data;
    public string str;
    public Data(int data1, string str1)
    {
        data = data1;
        str = str1;
    }
}

static void 제네릭을_이용한_직렬화()
{
    List&lt;Data&gt; ResultList;
    List&lt;Data&gt; DataList = new List&lt;Data&gt;();
    DataList.Add(new Data(7, &quot;test1&quot;));
    DataList.Add(new Data(12, &quot;test2&quot;));
    DataList.Add(new Data(19, &quot;test3&quot;));

    using (FileStream fs1 = new FileStream(&quot;test.dat&quot;, FileMode.Create))
    {
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(fs1, DataList);
    }

    using (FileStream fs2 = new FileStream(&quot;test.dat&quot;, FileMode.Open))
    {
        BinaryFormatter bf2 = new BinaryFormatter();
        ResultList = (List&lt;Data&gt;)bf2.Deserialize(fs2);
    }

    for (int i=0;i&lt;ResultList.Count;i++)
        Console.WriteLine(&quot;{0} {1}&quot;, ResultList[i].data, ResultList[i].str);
}</code></pre><h1 id="3-정리">3. 정리</h1>
<table>
<thead>
<tr>
<th align="center">입출력 단위</th>
<th align="center">클래스</th>
<th align="center">사용빈도</th>
</tr>
</thead>
<tbody><tr>
<td align="center">바이트</td>
<td align="center">File, FileStream + BitConverter</td>
<td align="center">1</td>
</tr>
<tr>
<td align="center">텍스트</td>
<td align="center">StreamWriter, StreamReader + FileStream</td>
<td align="center">3</td>
</tr>
<tr>
<td align="center">이진</td>
<td align="center">BinaryWriter, BinaryReader + FileStream</td>
<td align="center">5</td>
</tr>
<tr>
<td align="center">구조체와 클래스</td>
<td align="center">[Serializable] + BinaryFormatter</td>
<td align="center">6</td>
</tr>
<tr>
<td align="center">구조체와 클래스</td>
<td align="center">[Serializable] + 컬랙션 + BinaryFormatter</td>
<td align="center">6</td>
</tr>
</tbody></table>
<h1 id="4-reference">4. Reference</h1>
<ul>
<li><a href="https://www.youtube.com/watch?v=5YfRoWZQZZc&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=16">나우캠퍼스-6강-1부</a>, <a href="https://www.youtube.com/watch?v=5YfRoWZQZZc&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=17">2부</a>, <a href="https://www.youtube.com/watch?v=5YfRoWZQZZc&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=18">3부</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[5강. 배열]]></title>
            <link>https://velog.io/@insung_na/5%EA%B0%95.-%EB%B0%B0%EC%97%B4</link>
            <guid>https://velog.io/@insung_na/5%EA%B0%95.-%EB%B0%B0%EC%97%B4</guid>
            <pubDate>Fri, 28 Jul 2023 08:24:34 GMT</pubDate>
            <description><![CDATA[<h1 id="1-1차원배열">1. 1차원배열</h1>
<ul>
<li>기본 개념<ul>
<li>같은 데이터형 + 변수명 + 순차적인 메모리 나열</li>
</ul>
</li>
<li>참조형<ul>
<li>new를 통해 생성</li>
</ul>
</li>
<li>Array객체로부터 파생된 참조형</li>
<li>foreach 사용가능<h2 id="형식">형식</h2>
<ul>
<li><code>데이터형[] 배열명;</code></li>
<li><code>int[] array_name;</code></li>
<li><code>int[] array = new int[] {1,2,3};</code></li>
</ul>
</li>
<li>Array.Length: 길이 확인</li>
</ul>
<h1 id="2-2차원-및-다차원-배열">2. 2차원 및 다차원 배열</h1>
<ul>
<li>행과 열, 면은 콤마(,)로 구분<h2 id="형식-1">형식</h2>
<ul>
<li><code>데이터형[차원 수 + 1 만큼 &#39;,&#39; 입력] 배열명;</code></li>
<li><code>int[,] array_name;</code></li>
<li><code>int[,,] array_name;</code><pre><code class="language-cs">for (int i = 0; i &lt; 3; i++)
for (int j = 0; j &lt; 2; j++)
    Console.Write(정수이차원배열1[i, j]);</code></pre>
</li>
</ul>
</li>
</ul>
<h1 id="3-가변-배열">3. 가변 배열</h1>
<ul>
<li>배열 길이가 유동적인 배열<h2 id="형식-2">형식</h2>
<ul>
<li><code>데이터형[][] 배열명;</code></li>
<li><code>int[][] array_name;</code></li>
</ul>
</li>
<li>사용 예시<pre><code class="language-cs">int[][] array = new int[3][];
array[0] = new int[] { 1, 2 };
array[1] = new int[] { 3, 4, 5 };
array[2] = new int[] { 6, 7, 8, 9 };
</code></pre>
</li>
</ul>
<p>int[][] array2 = 
{
    new int[]{1,2,3 },
    new int[]{2,3,4},
    new int[]{3,4,5},
};</p>
<p>foreach(var i in array2) // 배열 받아오기
    foreach (var j in i) // 배열에서 데이터 받아오기 또는 for문에 i.Length를 사용
        Console.WriteLine(j); // 데이터 출력하기</p>
<p>int[][][] array3D =
            {
                new int[][] // 2D array at index 0
                {
                    new int[]{1, 2, 3}, // Row 0
                    new int[]{4, 5, 6}, // Row 1
                    new int[]{7, 8, 9}  // Row 2
                },
                new int[][]
                {
                    new int[]{1, 2 }
                },
                new int[][]
                {
                    new int[]{11, 12 },
                    new int[]{12, 13 },
                    new int[]{13, 14 },
                    new int[]{14, 15, 16 }
                }
            };</p>
<pre><code>        for (int i = 0; i &lt; array3D.Length; i++)
        {
            for (int j = 0; j &lt; array3D[i].Length; j++)
            {
                Console.Write($&quot;{i}행 {j}열:&quot;);
                for (int k = 0; k &lt; array3D[i][j].Length; k++)
                {
                    Console.Write(array3D[i][j][k]);
                    Console.Write(&#39; &#39;);
                }
                Console.WriteLine();

            }
        }</code></pre><pre><code># 4. 배열을 인수로 전달
- 배열과 함수는 참조형이기 때문에 값이 변경된다
## 형식
```cs
int[] array = {1,2,3,4};

void func(int[] arr)
{
    //함수 내용
    //참조형이기 때문에 array를 수정하면
    //원본 array도 수정된다
}
func(array);</code></pre><h1 id="5-배열을-리턴하는-함수">5. 배열을 리턴하는 함수</h1>
<ul>
<li>배열을 리턴하는 의미<ul>
<li>배열이 참조하는 객체의 주소값을 리턴하는 것<h2 id="형식-3">형식</h2>
<pre><code class="language-cs">함수(매개변수)
{
  //함수 내용 실행
return Array
}
var 받기 = 함수(매개변수)</code></pre>
</li>
</ul>
</li>
</ul>
<h1 id="6-배열의-메서드">6. 배열의 메서드</h1>
<h2 id="초기화-메서드">초기화 메서드</h2>
<ul>
<li><code>Array.Clear(타겟_배열, 시작_인덱스, 초기화_길이);</code><ul>
<li><code>Array.Clear(numbers, 2, 4);</code> 인덱스 2부터 5까지 0으로 초기화<h2 id="배열-복사-메서드">배열 복사 메서드</h2>
</li>
</ul>
</li>
<li><code>public Object Clone();</code></li>
<li>object형이기 때문에 unboxing이 필요<pre><code class="language-cs">int[] nArray1 = {1,2,3,4};
int[] nCloneArray = (int[])nArray1.Clone();</code></pre>
</li>
</ul>
<h1 id="7-reference">7. Reference</h1>
<ul>
<li><a href="https://www.youtube.com/watch?v=Fc2uogIYb-k&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=13">나우캠퍼스-5강-1부</a>, <a href="https://www.youtube.com/watch?v=Fc2uogIYb-k&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=14">2부</a>, <a href="https://www.youtube.com/watch?v=Fc2uogIYb-k&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=15">3부</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[4강. C# 기본 문법]]></title>
            <link>https://velog.io/@insung_na/4%EA%B0%95.-C-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@insung_na/4%EA%B0%95.-C-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Thu, 27 Jul 2023 07:18:03 GMT</pubDate>
            <description><![CDATA[<h1 id="1-연산자">1. 연산자</h1>
<h2 id="단항연산자">단항연산자</h2>
<ul>
<li>+, -, !, ~, ++, -- 등</li>
<li>!는 bool형에서만 사용</li>
</ul>
<h2 id="산술연산자">산술연산자</h2>
<ul>
<li>*, /, %, +, -</li>
<li>string에서는 +로 문자열 연결 가능</li>
<li>참고사항<ul>
<li>수치형 + &quot;문자열&quot; = &quot;문자열&quot;</li>
<li>&quot;문자열&quot; + &quot;문자열&quot;은 메모리를 많이 차지한다<ul>
<li>문자열은 <code>참조 형식</code>으로 위의 방식을 사용하면 <code>Heap</code>에 3개의 문자열이 메모리를 차지하게 된다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="시프트-연산자와-관계연산자">시프트 연산자와 관계연산자</h2>
<ul>
<li>&lt;&lt;, &gt;&gt;, &lt;=, &gt;=, &gt;, &lt;, ==, !=</li>
</ul>
<h2 id="is-연산자">is 연산자</h2>
<ul>
<li>형식 호환을 조사하는 연산자</li>
<li><code>변수 is 클래스형|데이터형;</code></li>
<li><code>object</code>와 하위의 다른 데이터형(int, float)는 호환O</li>
<li>동일 계층의 데이터형(int, float)끼리는 호환X<pre><code class="language-cs">if (objVar is int)
  Console.WriteLine(&quot;UnBoxing 호환O&quot;);</code></pre>
</li>
</ul>
<h2 id="as-연산자">as 연산자</h2>
<ul>
<li>형변환과 변환조사</li>
<li>캐스트 연산자의 역할, 불변환은 null리턴</li>
<li><code>결과형 = 참조형, 언박싱, 박싱 as 변환형</code><pre><code class="language-cs">string str2 = objVar as string;
//objVar를 string형으로 변경할 수 있으면 (string)objVar가 str2에 저장됨
//형변환을 못하면 null 저장</code></pre>
</li>
</ul>
<h2 id="비트논리연산자">비트&amp;논리연산자</h2>
<h3 id="비트연산자">비트연산자</h3>
<ul>
<li>&amp;, |, ~, ^</li>
<li>and, or, not, xor<h3 id="논리연산자">논리연산자</h3>
</li>
<li>&amp;&amp;, ||, !</li>
<li>and, or, not</li>
</ul>
<h2 id="null-병합-연산자">null 병합 연산자</h2>
<ul>
<li>??: null 조사</li>
<li><code>c = A ?? B</code><ul>
<li>A가 null이 아니면 A를 C에 대입</li>
<li>A가 null이면 B를 C에 대입</li>
</ul>
</li>
</ul>
<h1 id="2-제어문">2. 제어문</h1>
<h2 id="if--else">if ~ else</h2>
<pre><code class="language-cs">if (조건1)
    Console.WriteLine(&quot;첫번째내용&quot;);
else if (조건2)
    Console.WriteLine(&quot;두번째내용&quot;);
else
    Console.WriteLine(&quot;세번째내용&quot;);</code></pre>
<h2 id="switch-case-break">switch, case, break</h2>
<ul>
<li>정수, 문자상수, 문자열 가능</li>
<li>모든 case와 default에는 <em>break가 반드시 있어야 함</em><pre><code class="language-cs">switch(데이터)
{
  case 1:
      Console.WriteLine(&quot;첫번째내용&quot;);
      break;
  case &#39;1&#39;:
      Console.WriteLine(&quot;두번째내용&quot;);
      break;
  default:
      Conosole.WriteLine(&quot;세번째내용&quot;);
      break;
}</code></pre>
</li>
</ul>
<h1 id="3-반복문">3. 반복문</h1>
<h2 id="for변수조건증감">for(변수;조건;증감)</h2>
<pre><code class="language-cs">for (int i = 0; i &lt; 10; i++)
    Console.WriteLine(&quot;{0}번째 반복시행 중&quot;, i);</code></pre>
<h2 id="foreach변수-in-컨테이너형">foreach(변수 in 컨테이너형)</h2>
<ul>
<li>읽기전용 함수<pre><code class="language-cs">forreach(int i in 정수배열)
  Console.WriteLine(i)</code></pre>
<h2 id="while-반복문">while 반복문</h2>
</li>
<li><code>while(조건){내용}</code>, <code>do{내용}while(조건)</code></li>
</ul>
<h1 id="4-점프문">4. 점프문</h1>
<ul>
<li>goto, continue, return, break<h2 id="goto">goto</h2>
</li>
<li>해당 키워드의 위치로 이동한다</li>
<li>과거부터 문법해석과 디버깅을 방해하기 때문에 많이 사용하지 말라고 한다</li>
<li>하지만 다중 반복문 등에서 한 번에 빠져나올 수 있는 경우는 사용을 권장한다<pre><code class="language-cs">start:
Console.WriteLine(&quot;현재 숫자: &quot; + number);
number++;
</code></pre>
</li>
</ul>
<p>if (number &lt;= 5)
    goto start;</p>
<pre><code>
# 5. 예외처리문
## try~catch
```cs
try
{
    //예외가 발생할 수 있는 코드
}
catch(예외처리객체 e)
{
    //예외발생 시 실행코드
}</code></pre><h3 id="참고사항">참고사항</h3>
<ul>
<li>try문 안에서 초기화한 변수를 try문 밖에서 사용할 수 없다<ul>
<li><code>int m; try{m=12;} ... Console.Write(m);</code>은 오류 발생</li>
<li><blockquote>
<p><code>int m=0; try{m=12;} ... Console.Write(m);</code>은 사용 가능</p>
</blockquote>
</li>
</ul>
</li>
<li>System.Exception의 파생객체만 사용가능<ul>
<li>OverFlowException</li>
<li>FormatException</li>
<li>DivideByZeroException</li>
<li>FileNotFoundException</li>
<li>IndxOutOfRangeException</li>
</ul>
</li>
</ul>
<h2 id="trycatchfinally">try<del>catch</del>finally</h2>
<ul>
<li>finally: 예외 발생과 상관없이 항상 실행되는 구문</li>
<li>예외처리에 실패하면 프로그램이 바로 종료, 정지, 문제가 발생하는데 finally구문으로 해당 실행을 강제할 수 있다<ul>
<li>ex. SQL을 활용하고 나서 finally에 sql 종료구문 추가</li>
<li>ex. 영상처리 중 웹캠 종료</li>
</ul>
</li>
</ul>
<h2 id="throw">throw</h2>
<ul>
<li>예외 상황을 임의로 바생시키는 역할</li>
</ul>
<h1 id="6-정리">6. 정리</h1>
<ul>
<li>대부분의 연산자는 C,C++언어와 같음</li>
<li>C#에서 새롭게 등장한 연산자<ul>
<li>is, as, null</li>
</ul>
</li>
<li>반복문<ul>
<li><code>for</code>, <code>while</code>, <code>do~while</code>, <code>foreach</code>(=python의 for)</li>
</ul>
</li>
<li>예외처리문<ul>
<li><code>try~catch~finally</code>(=python의 try<del>exception</del>finally)</li>
<li><code>throw</code>(=python의 raise)</li>
</ul>
</li>
</ul>
<h1 id="7-reference">7. Reference</h1>
<ul>
<li><a href="https://www.youtube.com/watch?v=ze7yCaKmzgk&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=11">나우캠퍼스-4강-1부</a>, <a href="https://www.youtube.com/watch?v=ze7yCaKmzgk&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=12">2부</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[3강. 데이터형]]></title>
            <link>https://velog.io/@insung_na/3%EA%B0%95.-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%98%95</link>
            <guid>https://velog.io/@insung_na/3%EA%B0%95.-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%98%95</guid>
            <pubDate>Wed, 26 Jul 2023 09:28:57 GMT</pubDate>
            <description><![CDATA[<h1 id="1-데이터형">1. 데이터형</h1>
<h2 id="기본-데이터형">기본 데이터형</h2>
<ul>
<li>C#의 데이터형 object로부터 파생된 객체</li>
<li><code>CTS</code>(Common Type System)에서 정의된 객체</li>
</ul>
<h3 id="정수형">정수형</h3>
<blockquote>
</blockquote>
<table>
<thead>
<tr>
<th align="center">키워드</th>
<th align="center">클래스</th>
<th align="center">용량</th>
</tr>
</thead>
<tbody><tr>
<td align="center">byte</td>
<td align="center">System.Byte</td>
<td align="center">1 byte</td>
</tr>
<tr>
<td align="center">sbyte</td>
<td align="center">System.SByte</td>
<td align="center">1 byte</td>
</tr>
<tr>
<td align="center">short</td>
<td align="center">System.Int16</td>
<td align="center">2 byte</td>
</tr>
<tr>
<td align="center">ushort</td>
<td align="center">System.UInt16</td>
<td align="center">2 byte</td>
</tr>
<tr>
<td align="center">int</td>
<td align="center">System.Int32</td>
<td align="center">4 byte</td>
</tr>
<tr>
<td align="center">uint</td>
<td align="center">System.UInt32</td>
<td align="center">4 byte</td>
</tr>
<tr>
<td align="center">long</td>
<td align="center">System.Int64</td>
<td align="center">8 byte</td>
</tr>
<tr>
<td align="center">ulong</td>
<td align="center">System.UInt64</td>
<td align="center">8 byte</td>
</tr>
</tbody></table>
<h3 id="실수형">실수형</h3>
<ul>
<li>C#의 float는 클래스가 <code>System.Single</code> 이다.</li>
</ul>
<blockquote>
</blockquote>
<table>
<thead>
<tr>
<th align="center">키워드</th>
<th align="center">클래스</th>
<th align="center">용량</th>
</tr>
</thead>
<tbody><tr>
<td align="center">float</td>
<td align="center">System.Single</td>
<td align="center">4 btyte</td>
</tr>
<tr>
<td align="center">double</td>
<td align="center">System.Double</td>
<td align="center">8 btyte</td>
</tr>
<tr>
<td align="center">decunak</td>
<td align="center">System.Decimal</td>
<td align="center">16 btyte</td>
</tr>
</tbody></table>
<h3 id="문자열형">문자(열)형</h3>
<ul>
<li>C#의 문자형(char)는 <code>2 byte</code> 이고 <code>&#39;&#39;</code>로 정의한다.<ul>
<li><code>char 문자 = &#39;굿&#39;;</code></li>
</ul>
</li>
<li>문자열형은 <code>&quot;&quot;</code>로 정의한다<ul>
<li><code>string a = &quot;Hello World&quot;;</code></li>
</ul>
</li>
<li>문자열 출력 추가내용<ul>
<li>&#39;&#39; 출력 방법<ul>
<li>@&quot;C:\aaa\aaa\aaa.exe&quot;</li>
<li>&quot;C:\aaa\aaa\aaa.exe&quot;</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<table>
<thead>
<tr>
<th align="center">키워드</th>
<th align="center">클래스</th>
<th align="center">용량</th>
</tr>
</thead>
<tbody><tr>
<td align="center">char</td>
<td align="center">System.Char</td>
<td align="center">2 byte</td>
</tr>
<tr>
<td align="center">string</td>
<td align="center">System.String</td>
<td align="center">-</td>
</tr>
</tbody></table>
<h3 id="bool-형">bool 형</h3>
<blockquote>
</blockquote>
<table>
<thead>
<tr>
<th align="center">키워드</th>
<th align="center">클래스</th>
<th align="center">용량</th>
</tr>
</thead>
<tbody><tr>
<td align="center">bool</td>
<td align="center">System.Boolean</td>
<td align="center">1 byte</td>
</tr>
</tbody></table>
<h3 id="var-키워드">var 키워드</h3>
<ul>
<li>대입되는 데이터에 따라 데이터형 결정</li>
<li>ex. <code>foreach(var i in Array){내용;}</code></li>
<li>사용할 수 없는 예<ul>
<li>null값 초기화, 매개변수X</li>
<li>only 지역변수, 클래스 멤버X</li>
<li>연속적으로 초기화하는 경우<ul>
<li>ex. var m = 10, n = 20;<h4 id="var-vs-object">var vs object</h4>
</li>
</ul>
</li>
</ul>
</li>
<li>var를 사용해서 데이터형이 지정되면 변경 불가능</li>
<li>object는 변경가능, 하지만 boxing &amp; unboxing이 필요함<ul>
<li>boxing&amp;unboxing 정리파트 이후에 작성예정</li>
</ul>
</li>
</ul>
<h1 id="2-변환">2. 변환</h1>
<ul>
<li><code>기본데이터형.ToString()</code>  &lt;=&gt; <code>기본데이터형.Parse()</code></li>
<li>Convert.ToInt32()</li>
<li>Convert.ToSingle()</li>
<li><code>Convert.ToXXXXX()</code></li>
</ul>
<h1 id="3-표준-입력">3. 표준 입력</h1>
<h2 id="표준-입력">표준 입력</h2>
<ul>
<li>참조 : <a href="https://learn.microsoft.com/ko-kr/dotnet/api/system.consolekeyinfo?view=net-7.0">표준입력-공식문서</a></li>
<li><code>Console.ReadKey()</code></li>
<li><code>public static ConsoleKeyInfo ReadKey(bool intercept)</code><ul>
<li>true: 화면출력안함</li>
<li>false: 화면출력(default)</li>
</ul>
</li>
<li>ConsoleKeyInfo<ul>
<li>키의 문자와 Shift, Alt, Ctrl 등 보조키 상태 포함</li>
</ul>
</li>
<li>ConsoleKeyInfo.Key: 입력된 키 위치 확인</li>
<li>ConsoleKeyInfo.KeyChar: 대소문자 구분 키 확인<pre><code class="language-cs">//ConsoleKeyInfo는 구조체 형식
</code></pre>
</li>
</ul>
<p>Console.WriteLine(&quot;ESC를 누르면 종료합니다&quot;);
ConsoleKeyInfo KeyInfo;
do
{
    KeyInfo = Console.ReadKey(true); //안보이게 설정
    if (KeyInfo.Key == ConsoleKey.A) //A입력시 실행
        Console.WriteLine(&quot;A를 입력했습니다&quot;);
  // ESC를 누르면 종료
} while (KeyInfo.Key != ConsoleKey.Escape); </p>
<pre><code>
# 4. 사용자 지정형
- struct, enum, class, interface 중 class와 interface는 나중에 배움으로 생략
## struct
- 제한사항
  - 구조체에 선언된 const, static 변수만 초기화 가능
  - 구조체 안에 선언할 수 있는 생성자는 매개변수가 반드시 있어야 함
  - 구조체를 같은 구조체에 대입하게 되면 값이 복사
  - 구조체는 `값 형식`이고 클래스는 `참조 형식`
  - 값 형식이므로 선언만으로 사용 가능
    - new를 사용하면 생성자가 호출되어 기본값으로 초기화 됨
  - 구조체 또는 클래스에 상속X
  - 인터페이스를 상속하여 메서드 구현 가능

```cs
접근지정자 struct 구조체명
{
    // 멤버, 속성, 메서드
}</code></pre><h2 id="enum">enum</h2>
<ul>
<li>상수를 문자열로 대치하여 선언</li>
<li>enum 열거형 명칭 {문자열1, 문자열2};<ul>
<li>문자열1=10으로 설정하면 다음 데이터는 1씩 증가</li>
<li><code>enum Days {Sun, Mon, ..., Sat};</code></li>
</ul>
</li>
<li>기본은 int형이지만 char형을 제외한 형식 지정가능<ul>
<li><code>enum Days:byte{Sun=0, Mon, Tue, ... , Sat};</code></li>
</ul>
</li>
<li>열거형 변수가 아닌 변수에 열거형 값을 대입할 때는 데이터형을 명시할 것</li>
</ul>
<h1 id="5-값-형식과-참조-형식">5. 값 형식과 참조 형식</h1>
<h2 id="스택stack">스택(Stack)</h2>
<ul>
<li>고정된 크기(정적)의 메모리</li>
<li>데이터를 쌓아올리는 구조의 메모리</li>
<li>데이터 처리 방식 : <code>Last-In-First-Out(=후입선출)</code></li>
</ul>
<h3 id="값-형식">값 형식</h3>
<ul>
<li>메모리에 값을 담는 데이터 형식</li>
<li>스택에 할당(즉, 자동으로 제거됨)<ul>
<li><code>지역변수가 stack에 할당됨</code>, 메서드 호출이 완료되면 <code>스택 메모리가 자동으로 회수</code>되고 값이 제거됨</li>
</ul>
</li>
<li>기본데이터 형식과 구조체가 여기에 해당됨</li>
</ul>
<h2 id="큐queue">큐(Queue)</h2>
<ul>
<li>C#에서 큐의 사용은 선택적<ul>
<li><code>System.Collections.Queue</code></li>
</ul>
</li>
<li>데이터 처리 방식 : First-In-Fist-Out(=선입선출)</li>
</ul>
<h2 id="힙heap">힙(Heap)</h2>
<ul>
<li>유동적 크기(동적)의 메모리</li>
<li>자유롭게 데이터를 저장할 수 있는 메모리</li>
</ul>
<h3 id="참조-형식">참조 형식</h3>
<ul>
<li><code>heap</code>에 데이터를 저장하고 해당하는 메모리를 참조하는 방식</li>
<li>처음 변수만 선언하면 값 형식과 달리 메모리가 할당되지 않음</li>
<li>힙에 할당(<code>가비지 콜렉터에 의해 제거됨</code>)</li>
<li>배열, 클래스, 인터페이스, 델리게이트, 문자열, Object 등이 여기에 해당</li>
</ul>
<h4 id="boxingunboxing">Boxing&amp;Unboxing</h4>
<ul>
<li>Boxing<ul>
<li>값 형식 -&gt; 참조 형식으로 변환하는 것</li>
<li>stack -&gt; heap<pre><code class="language-cs">int num = 42;
object boxedNum = num; // Boxing</code></pre>
</li>
</ul>
</li>
<li>UnBoxing<ul>
<li>Boxing된 데이터를 값 형식으로 변환하는 것</li>
<li>heap -&gt; stack<pre><code class="language-cs">object boxedNum = 42;
int num = (int)boxedNum; // Unboxing</code></pre>
</li>
</ul>
</li>
</ul>
<h1 id="6-정리">6. 정리</h1>
<ul>
<li>기본 데이터형과 CTS 형식을 익혀둔다.</li>
<li>데이터형에 관한 검증 코드를 작성해보자.</li>
<li>값 형식과 참조 형식의 차이점을 이해하자.</li>
</ul>
<blockquote>
</blockquote>
<table>
<thead>
<tr>
<th align="center">구분</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">값 형식</td>
<td align="center">기본 데이터형, struct, enum</td>
</tr>
<tr>
<td align="center">참조 형식</td>
<td align="center">class, interface, delegate, array, string</td>
</tr>
</tbody></table>
<h1 id="7-reference">7. Reference</h1>
<ul>
<li><a href="https://www.youtube.com/watch?v=fxEPhGcYns8&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=6">나우캠퍼스-3강-1부</a>, <a href="https://www.youtube.com/watch?v=fxEPhGcYns8&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=7">2부</a>, <a href="https://www.youtube.com/watch?v=fxEPhGcYns8&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=8">3부</a>, <a href="https://www.youtube.com/watch?v=fxEPhGcYns8&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=9">4부</a>, <a href="https://www.youtube.com/watch?v=io4YrVFCCV0&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=10">5부</a></li>
<li>이것이 C#이다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2강. C# 프로그래밍의 기본 구조]]></title>
            <link>https://velog.io/@insung_na/2%EA%B0%95.-C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@insung_na/2%EA%B0%95.-C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Tue, 25 Jul 2023 13:27:55 GMT</pubDate>
            <description><![CDATA[<h1 id="1-솔루션과-프로젝트-생성">1. 솔루션과 프로젝트 생성</h1>
<h2 id="솔루션과-프로젝트">솔루션과 프로젝트</h2>
<ul>
<li>프로젝트<ul>
<li>C#에서 필요로 하는 여러 파일에 대한 정보 및 컴파일 옵션 정보 등 포함</li>
</ul>
</li>
<li>솔루션<ul>
<li>다수의 프로젝트를 하나의 솔루션 안에서 다룰 수 있음</li>
</ul>
</li>
</ul>
<h2 id="단일-프로젝트-생성">단일 프로젝트 생성</h2>
<ul>
<li>파일 -&gt; 새로 만들기 -&gt; 프로젝트 -&gt; 콘솔 앱(.NET Framework) 선택</li>
</ul>
<h1 id="2-c-프로그램-시작">2. C# 프로그램 시작</h1>
<h2 id="기본구조">기본구조</h2>
<h3 id="자동-생성-코드">자동 생성 코드</h3>
<pre><code class="language-cs">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace nowcampus_2_ConsoleApp
{
    internal class Program
    {
        static void Main(string[] args)
        {
        }
    }
}
</code></pre>
<h3 id="코드-구분">코드 구분</h3>
<ul>
<li>using 부분 -&gt; 프롤로그</li>
<li>namespace 부분 -&gt; 프로그램 몸체</li>
</ul>
<h3 id="프롤로그">프롤로그</h3>
<ul>
<li>using<ul>
<li>클래스의 네임스페이스를 선언하는 역할</li>
<li>네임스페이스 명시 없이 클래스 사용</li>
</ul>
</li>
</ul>
<h3 id="main">Main</h3>
<ul>
<li>C#은 하나 이상의 클래스 정의는 필수</li>
<li>소스코드가 실행되는 몸체</li>
<li>static 메서드<ul>
<li>클래스로부터 객체를 생성하지 않고 직접 [클래스명. 메서드명] 형식으로 호출하는 메서드</li>
</ul>
</li>
</ul>
<h3 id="mainstring-args">Main(string[] args)</h3>
<ul>
<li>프로그램 실행시 추가적으로 입력되는 부분이 args에 배열로 순서대로 입력됨</li>
<li>ex. <code>프로그램_실행 Hello world</code>로 입력 시 <code>args[0]=&#39;Hello&#39;</code>, <code>args[1]=&#39;world&#39;</code>가 할당됨</li>
</ul>
<h1 id="3-표준-출력">3. 표준 출력</h1>
<h2 id="표준-출력">표준 출력</h2>
<ul>
<li><code>Console.Write()</code><ul>
<li>내용을 줄바꿈 없이 출력</li>
</ul>
</li>
<li><code>Console.WriteLine()</code><ul>
<li>내용 출력 후 줄바꿈(=Console.WriteLine(&quot;\n&quot;)</li>
</ul>
</li>
<li>메서드 원형(Overloading 지원)<ul>
<li>public static void Write(bool value);</li>
<li>public static void Write(string format, Object arg0);</li>
<li>public static void WriteLine(bool value);</li>
<li>public static void WriteLine(string format, Object arg0);</li>
</ul>
</li>
</ul>
<h2 id="출력-형식">출력 형식</h2>
<ul>
<li>Console.Write(변수 or 데이터); -&gt; 데이터 1개 입력</li>
<li>Console.Write(&quot;{0} {1}&quot;, 변수1, 변수2); -&gt; 인덱스 지정</li>
<li>Console.Write($&quot;{변수1} {변수2}&quot;); -&gt; 위치 직접 지정<pre><code class="language-cs">Console.WriteLine(&quot;Hello World&quot;);
Console.WriteLine(&quot;{0} {1}&quot;, &quot;Hello&quot;, &quot;World&quot;);
Console.WriteLine($&quot;{&quot;Hello World&quot;}&quot;);</code></pre>
</li>
</ul>
<hr>
<p>Hello World
Hello World
Hello World</p>
<pre><code>
## 표준 숫자 서식 문자열
- C : 통화($, \ 등) 표시
- D : 10진수 정수
- E : 지수형 형태 출력
- F : 부동 소수점 출력
  - `$&quot;{13.234234:f3}&quot; = 13.234`
- G : 기본 출력
- N : 콤마 출력
- P : % 단위로 출력
- X : 16 진수 출력

```cs
Console.WriteLine(&quot;{0:C} {1:P} {0:X}&quot;, 123, 123.45);
-----------------------------------------------------
₩123 12,345.00% 7B</code></pre><p>참고 : <a href="https://learn.microsoft.com/ko-kr/dotnet/standard/base-types/standard-numeric-format-strings">MSDN-표준 숫자 서식 문자열</a></p>
<h1 id="4-c-키워드">4. C# 키워드</h1>
<h2 id="c-키워드">C# 키워드</h2>
<ul>
<li>총 77개</li>
<li>C 키워드(26개)<ul>
<li>break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, return, short, sizeof, static, struct, switch, typeof, void, while</li>
</ul>
</li>
<li>C++ 키워드(19개)<ul>
<li>bool, catch, class, false, finally, namespace, new, private, protected, explicit, operator, public, this, throw, true, try, using, virtual, volatile</li>
</ul>
</li>
<li>C# 키워드(32개)<ul>
<li>abstract, as, base, byte, checked, decimal, delegate, event, fixed, foreach, in, interface, internal, implicit, is, lock, null, object, out, override, params, readonly, ref, sbute, sealed, string, uint, ulong, unchecked, unsafe, ushort, volatile</li>
</ul>
</li>
</ul>
<h1 id="5-정리">5. 정리</h1>
<ul>
<li>C# 프로그래밍 구조를 이해하고 네임스페이스와 클래스의 관계를 이해</li>
<li>표준 출력인 Console.Write, Console.WriteLine()을 사용해보고 MSDN에서 다양한 출력 형식을 살펴보자</li>
</ul>
<h1 id="6-reference">6. Reference</h1>
<ul>
<li><a href="https://www.youtube.com/watch?v=47u8Q06qyw8&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=4">나우캠퍼스-2강-1부</a>, <a href="https://www.youtube.com/watch?v=47u8Q06qyw8&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=5">2부</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[1강. 닷넷프레임워크와 C#언어]]></title>
            <link>https://velog.io/@insung_na/1%EA%B0%95%EB%8B%B7%EB%84%B7%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EC%99%80-C%EC%96%B8%EC%96%B4</link>
            <guid>https://velog.io/@insung_na/1%EA%B0%95%EB%8B%B7%EB%84%B7%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EC%99%80-C%EC%96%B8%EC%96%B4</guid>
            <pubDate>Tue, 25 Jul 2023 06:08:20 GMT</pubDate>
            <description><![CDATA[<h1 id="1-net-framewrok">1. .Net Framewrok</h1>
<h2 id="운영체제와-닷넷-프레임워크">운영체제와 닷넷 프레임워크</h2>
<ul>
<li>과거에 각 운영체제에 닷넷 프레임워크를 추가해서 사용했으나</li>
<li>닷넷 프레임워크가 운영체제 안으로 들어가서 대부분의 OS에서 사용가능</li>
</ul>
<h2 id="구성요소">구성요소</h2>
<ul>
<li>클래스 라이브러리와 CLR(Common Langugage Runtime)
<img src="https://velog.velcdn.com/images/insung_na/post/6ef47292-569c-423c-bff5-db5126eb130b/image.png" alt=""></li>
</ul>
<h3 id="클래스-라이브러리">클래스 라이브러리</h3>
<ul>
<li>BCL(Basic Class Library): 기본 클래스</li>
<li>Window Form: 윈도우 응용 프로그램 제작을 위한 클래스 라이브러리</li>
<li>ASP.NET: 웹 클래스 라이브러리</li>
<li>ADO.NET: 데이터베이스 클래스 라이브러리</li>
</ul>
<h3 id="clrcommon-language-runtime">CLR(Common Language Runtime)</h3>
<ul>
<li>컴파일된 C# 코드(.exe)를 실행하는 역할</li>
<li>MSIL, IL, Common Intermediate Language, CIL, 중간언어<ul>
<li>닷넷 프레임워크의 장점은 대부분의 기기에서 사용가능한 것이다</li>
<li>코드를 컴파일하면 생성되는 코드로 각 CPU와 OS에 맞는 코드를 생성함</li>
</ul>
</li>
</ul>
<blockquote>
<p>*용어 알기</p>
</blockquote>
<ul>
<li>*.exe, *.dll을 실행파일이 아닌 <em><strong>어셈블리</strong></em> 라고 한다</li>
</ul>
<h2 id="cts와-cls">CTS와 CLS</h2>
<h3 id="common-type-system">Common Type System</h3>
<ul>
<li>공통 데이터형과 형식 정의<ul>
<li>int =&gt; System.Int32</li>
<li>float =&gt; System.Single</li>
</ul>
</li>
</ul>
<h3 id="common-lanuguage-specifiaction">Common Lanuguage Specifiaction</h3>
<ul>
<li>공통 언어 사양 정의</li>
<li>닷넷 언어가 지켜야 할 최소 코드 규칙</li>
</ul>
<hr>
<h1 id="2-c-언어에-대한-개요">2. C# 언어에 대한 개요</h1>
<h2 id="c-언어">C# 언어</h2>
<ul>
<li>C# 언어 = C++ 언어 기반 + java 장점</li>
<li>사용범위<ul>
<li>XML, Web, Network, 데이터베이스, 게임, IoT 등</li>
</ul>
</li>
<li>C#은 포인터를 거의 사용하지 않는다<ul>
<li>객체 생성 new는 있지만 해제는 없다</li>
<li>메모리 관리는 Garbage Collector가 담당</li>
</ul>
</li>
</ul>
<h2 id="c-프로그램-실행-과정">C# 프로그램 실행 과정</h2>
<p><img src="https://velog.velcdn.com/images/insung_na/post/f6993ef9-2d82-4533-b4df-e445b385deef/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/53059f1e-8de1-4479-bf68-070fb8d70a76/image.png" alt=""></p>
<hr>
<h1 id="3-정리">3. 정리</h1>
<ul>
<li>닷넷 프레임워크의 구성 요쇼와 역할 이해<ul>
<li><code>BCL</code>, <code>IL</code>, <code>CLR</code>, <code>JIT</code>, <code>CTS</code> 등...</li>
</ul>
</li>
<li>컴파일부터 실행까지의 과정을 이해</li>
<li>인문학 서작 읽기 추천<ul>
<li>사고력 키우기</li>
</ul>
</li>
</ul>
<h1 id="4-닷넷-환경의-컴파일-과정">4. 닷넷 환경의 컴파일 과정</h1>
<h2 id="jitjust-in-time-컴파일">JIT(Just-In-Time) 컴파일</h2>
<ul>
<li>C/C++로 작성된 프로그램은 정적인 네이티브 코드(.exe, .dll)를 생성해 배포하기 때문에 빠르다</li>
<li>Java, C#과 같은 언어들은 컴파일러가 생성한 <code>IL</code> 코드를 가지고 있다가 프로그램 실행 시에 <code>CLR</code> 코드를 해석해서 동적인 네이티브 코드를 생성하게 된다</li>
<li>이러한 가상머신에 의한 런타임 컴파일 방식을 <code>JTL</code> 컴파일 이라고 한다</li>
<li>그렇기 때문에 첫 수행이 아주 느리고, 이후 수행부터는 빠른 속도를 갖게 된다</li>
</ul>
<h2 id="aotahead-of-time-컴파일">AOT(Ahead-Of-Time) 컴파일</h2>
<ul>
<li><code>JIT</code> 컴파일 방식의 느린 속도를 해결하기 위해 만들어진 컴파일 방식</li>
<li>목표 시스템의 기계어와 무관하게 중간 언어 형태로 배포된 후 목표 시스템에서 <code>인터프리터</code>나 <code>JIT</code> 컴파일 등 기계여 번역을 통해 <em><strong>실행되는 중간 언어를 미리 목표 시스템에 맞는 기계어로 번역하는 방식</strong></em></li>
</ul>
<h1 id="5-references">5. References</h1>
<ul>
<li><a href="https://www.youtube.com/watch?v=PKxm0vkoWgo&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=2">나우캠퍼스-1강-1부</a>, <a href="https://www.youtube.com/watch?v=CKzBAwkkB-c&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=3">2부</a></li>
<li><a href="https://rito15.github.io/posts/cs-dotnet-compile/">https://rito15.github.io/posts/cs-dotnet-compile/</a></li>
<li><a href="https://ko.wikipedia.org/wiki/AOT_%EC%BB%B4%ED%8C%8C%EC%9D%BC">https://ko.wikipedia.org/wiki/AOT_%EC%BB%B4%ED%8C%8C%EC%9D%BC</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[C# 오리엔테이션]]></title>
            <link>https://velog.io/@insung_na/C-%EC%98%A4%EB%A6%AC%EC%97%94%ED%85%8C%EC%9D%B4%EC%85%98</link>
            <guid>https://velog.io/@insung_na/C-%EC%98%A4%EB%A6%AC%EC%97%94%ED%85%8C%EC%9D%B4%EC%85%98</guid>
            <pubDate>Tue, 25 Jul 2023 04:28:29 GMT</pubDate>
            <description><![CDATA[<h1 id="1-c을-공부하는-이유">1. C#을 공부하는 이유</h1>
<ul>
<li>나는 메카트로닉스 학과의 졸업을 앞두고 있으며 머신비전 분야에 관심이 있다.</li>
<li>제로베이스 데이터 취업 스쿨을 통해서 Python 기반으로 전반적인 데이터 분석, AI모델링에 대해 학습했다.</li>
<li>머신비전 분야에 대해서 확인해보니, 주로 사용하는 언어들은 C++, C#이고 python은 보이지 않았다.</li>
<li>C++과 C# 둘 중 무엇을 공부해야 할까 고민하다가 python의 클래스와 굉장히 흡사한 C#을 공부하기로 결정하였다.</li>
<li>PC, PLC 제어 분야로 먼저 취업한 친구에게 듣기로 GUI을 HMI에서 C#으로 모두 바꾸어서 다시 공부해야 한다는 얘기를 듣고 더욱 C#을 공부해야겠다고 다짐했다.</li>
<li>학과에서 PLC를 배웠는데, MX-Component와 C#을 이용하면 컨트롤이 매우 쉽다는 것을 이미 경험해서 알고 있다.</li>
</ul>
<h1 id="2-학습-플랫폼-선택">2. 학습 플랫폼 선택</h1>
<ul>
<li>나는 원래 충남인력개발원의 &quot;<strong><em>OPC-UA 기반 스마트제조 지능형 MES 프로젝트</em></strong>&quot;를 통해서 머신비전 뿐만 아니라 MES에 대한 전반적인 것과 C#, 제조분야의 Python을 이용한 데이터분석까지 학습하려 했으나 인원미달로 _<strong>폐강</strong>_되었다...</li>
<li>전공 때 C를 배웠고, 개인적으로 C++ 조금 학습했고, 부트캠프에서 Python을 배워서 기본은 갖춰져있어서 책으로 독학하려 했는데, 조금 힘들다...</li>
<li>혼자 책으로 하는 것이 재미도 좀 떨어지고, 심심하다는 생각에 다른 부트캠프를 찾아보았으나 C#부트캠프의 장소(주로 부산...)와 시간들이 나에게 맞지 않아서, <strong><em>나우캠퍼스의 공개 영상을 통해서 C#에 대한 것을 학습하고자 한다.</em></strong></li>
</ul>
<h1 id="3-c-활용분야">3. C# 활용분야</h1>
<p><img src="https://velog.velcdn.com/images/insung_na/post/8fb72fbd-06a0-4db8-8c74-e9c869afe00d/image.png" alt=""></p>
<h1 id="4-강의-내용">4. 강의 내용</h1>
<ul>
<li>C# 언어 기초 문법</li>
<li>WindowForm 프로그래밍</li>
<li>데이터베이스 프로그래밍(Feat. MS-SQL)</li>
</ul>
<h1 id="5-희망-취업처">5. 희망 취업처</h1>
<ul>
<li>제조분야 데이터 분석</li>
<li>자동화 머신비전, 머신러닝</li>
</ul>
<h1 id="6-reference">6. Reference</h1>
<ul>
<li><a href="https://www.youtube.com/watch?v=Urw1N7tntkA&amp;list=PLOKPEzlY4JKQNiHEQ4SDBxAFo9RDod8Tm&amp;index=1">나우캠퍼스-오리엔테이션</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Object Detection]]></title>
            <link>https://velog.io/@insung_na/Object-Detection</link>
            <guid>https://velog.io/@insung_na/Object-Detection</guid>
            <pubDate>Sat, 17 Jun 2023 10:31:30 GMT</pubDate>
            <description><![CDATA[<p>학습영상: <a href="https://www.youtube.com/watch?v=Adi0Iasehj8&amp;list=PLZp_s5JzDY_Zi9-DeUbSCKFe6pxpuNh7A&amp;index=1&amp;t=9134s">메타코드-딥러닝 강의 컴퓨터 비전 인식모델 개발 2편</a>
출처: 메타코드M</p>
<hr>
<h1 id="object-detection">Object Detection</h1>
<ul>
<li>사진 속의 모든 객체를 인지하는 문제</li>
<li>클래스분류(Classification) + 위치탐색(Localization)</li>
<li>Boundry Box를 생성해서 객체의 클래스와 위치를 표기<ul>
<li>4개의 좌표 생성(상자의 중심점과 폭, 높이 or 상자의 좌상단과 우상단 좌표)</li>
<li>YOLO: center_x, center_y, width, height</li>
</ul>
</li>
</ul>
<h2 id="single-object">Single Object</h2>
<ul>
<li>이미지에 단일 대상이 존재하는 단일 객체 탐지
<img src="https://velog.velcdn.com/images/insung_na/post/1e22ab5f-5e35-4088-85f5-c850a933c3e9/image.png" alt=""></li>
</ul>
<h2 id="sliding-window">Sliding window</h2>
<ul>
<li>Single Object에서 Multiple Object를 수행하는 경우, 한 이미지에 여러 객체가 존재하는데 이를 하나의 객체로 취급하여 올바른 클래스 분류를 수행할 수 없게 됨</li>
<li>해결책: 이미지 내에서 일부 window를 생성하고 그 안에서 Object Detection를 수행<ul>
<li>단점: 많은 윈도우를 생성하므로 계산이 너무 많다(고비용, 저속도)</li>
</ul>
</li>
</ul>
<h2 id="region-proposal-selective-search">Region Proposal: Selective Search</h2>
<ul>
<li>초기에 작은 영역들을 생성한 후, 이를 색깔, 질감, 크기, 위치 등의 특징을 사용하여 유사한 영역들을 합쳐가며 큰 영역 생성</li>
<li>이러한 계층적인 결합과정을 통해 객체와 배경의 경계를 찾아내고, 객체가 있을 가능성이 있는 영역(Region of Interest, ROI, 관심영역)을 제안</li>
</ul>
<h2 id="모델-형태">모델 형태</h2>
<h3 id="one-stage-detector">One-Stage Detector</h3>
<ul>
<li>Clasification과 Regional Proposal을 동시에 수행하는 방법</li>
<li>비교적 빠르지만 정확도가 낮음</li>
<li>YOLO계열, SSD
<img src="https://velog.velcdn.com/images/insung_na/post/46a63592-9255-456b-b88d-91f0c56f2427/image.png" alt="">출처: <a href="https://pseudo-lab.github.io/Tutorial-Book/chapters/object-detection/Ch1-Object-Detection.html#id3">가짜연구소</a></li>
</ul>
<h3 id="two-stage-detector">Two-Stage Detector</h3>
<ul>
<li>Clasification과 Regional Proposal을 순차적으로 수행하는 방법</li>
<li>비교적 느리지만 정확도가 높음</li>
<li>RCNN계열
<img src="https://velog.velcdn.com/images/insung_na/post/a1e3c094-b7a5-41c0-be17-885a1e17bcf9/image.png" alt="">출처: <a href="https://pseudo-lab.github.io/Tutorial-Book/chapters/object-detection/Ch1-Object-Detection.html#id3">가짜연구소</a></li>
</ul>
<h1 id="r-cnn-계열-모델">R-CNN 계열 모델</h1>
<p><img src="https://velog.velcdn.com/images/insung_na/post/42204c24-bf02-43c4-9cdf-a3ef5a7c91a3/image.png" alt=""></p>
<h2 id="rcnn">RCNN</h2>
<ul>
<li>기존 이미지에서 Region Proposal 생성(약 2000개)</li>
<li>영역을 warp(crop, resize) 작업수행</li>
<li>CNN으로 feature map 생성</li>
<li>Regressor로 bounding box 조정, SVM으로 class 예측<ul>
<li>클래스 수:예측 수 + 1, (background 분류를 위해 +1)</li>
</ul>
</li>
<li>단점<ul>
<li>이미지변형이나 손실, 후보영역만큼 CNN을 수행하므로 고비용, 저속도
<img src="https://velog.velcdn.com/images/insung_na/post/6d5cf403-070f-487e-b901-1d11984122a0/image.png" alt=""></li>
</ul>
</li>
</ul>
<h2 id="fast-rcnn">Fast RCNN</h2>
<ul>
<li>CNN으로 먼저 feature map을 생성, region proposal을 수행</li>
<li>MaxPooling 등을 활용해서 ROI에 적용(=RoI Pooling Layer)</li>
<li>RoI Pooling으로 Feature vector 생성</li>
<li>FC Layer를 거쳐서 Softmax를 통해 분류, Regressor로 bounding box 조정
<img src="https://velog.velcdn.com/images/insung_na/post/09745665-5efb-4c3a-92f1-7f0ba6ef4f06/image.png" alt=""></li>
</ul>
<h2 id="faster-rcnn">Faster RCNN</h2>
<ul>
<li>Selective Search 부분을 딥러닝으로 바꾼 Region Proposal Network(RPN) 사용</li>
<li>Feature map에서 CNN 연산시 sliding-window가 찍은 지점마다 Anchor-box로 후보영역을 예측<ul>
<li>Anchor-box: 미리 지정해놓은 여러 개의 비율과 크기의 Bounding-box</li>
</ul>
</li>
<li>RPN에서 얻은 후보영역을 IoU순으로 정렬하여 Non-Maximum Suppression(NMS) 알고리즘을 통해 최종 후보영역을 선택</li>
<li>RoI Pooling을 거치고 이후 Fast R-CNN과 동일하게 진행</li>
</ul>
<h1 id="yolo">YOLO</h1>
<p><img src="https://velog.velcdn.com/images/insung_na/post/38b53f2b-7261-4024-8dcf-be8755cfbbab/image.png" alt=""></p>
<h2 id="학습절차">학습절차</h2>
<ul>
<li>입력 이미지를 처음부터 grid로 나누고 각 grid별로 bounding box와 class를 예측, box별 confidence도 함께 예측</li>
<li>각 셀은 5*B+C의 데이터 수를 가지고 있음</li>
<li>각 cell마다 B=2개의 bbox를 예측해, 7*7*B개의 class score vector를 얻고 Nonmaximum suppression(NMS)로 정제함</li>
<li>object마다 하나의 bbox를 갖도록 함
<img src="https://velog.velcdn.com/images/insung_na/post/1c41c489-79b2-40d4-9ca5-d1382033745f/image.png" alt=""><img src="https://velog.velcdn.com/images/insung_na/post/2acad374-0239-477f-89c3-7bca1c6b8a2b/image.png" alt=""><img src="https://velog.velcdn.com/images/insung_na/post/92429755-6ce7-478c-9bcd-c6e63f59480b/image.png" alt=""></li>
</ul>
<h2 id="non-maximum-suppression-nms">Non maximum suppression (NMS)</h2>
<ul>
<li>동일한 객체에 대해 겹치는 정도(IOU; Intersection Of Union)가 높은 순서대로 정렬함.</li>
<li>Score가 가장 높은 경계상자를 기준으로 Threshold를 설정해 후보군을 줄임.
<img src="https://velog.velcdn.com/images/insung_na/post/a991a366-9acf-43bb-ad42-71d169b4c734/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[딥러닝 기초]]></title>
            <link>https://velog.io/@insung_na/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EB%A6%AC%EB%A7%88%EC%9D%B8%EB%93%9C1</link>
            <guid>https://velog.io/@insung_na/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EB%A6%AC%EB%A7%88%EC%9D%B8%EB%93%9C1</guid>
            <pubDate>Wed, 14 Jun 2023 10:16:12 GMT</pubDate>
            <description><![CDATA[<p>학습영상: <a href="https://www.youtube.com/watch?v=Adi0Iasehj8&amp;list=PLZp_s5JzDY_Zi9-DeUbSCKFe6pxpuNh7A&amp;index=1&amp;t=0s">메타코드-딥러닝 강의 컴퓨터 비전 인식모델 개발 1편</a>
출처: 메타코드M</p>
<hr>
<h1 id="ai">AI</h1>
<ul>
<li>인간의 학습 능력, 추론능력, 지각능력 등을 인공적으로 구현한 컴퓨터 시스템</li>
</ul>
<h2 id="ml">ML</h2>
<ul>
<li>컴퓨터에게 인간의 능력을 학습시키는 알고리즘</li>
<li>주로 정형 데이터</li>
</ul>
<h2 id="dl">DL</h2>
<ul>
<li>여러 비선형 변환기법의 조합을 통해 높은 수준의 추상화를 시도하는 기계학습 알고리즘의 집합</li>
<li>주로 비정형 데이터</li>
</ul>
<h3 id="mldl-프레임워크">ML/DL 프레임워크</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/0ae7bbaf-5fb0-40d6-934a-854cf7734084/image.png" alt=""></p>
<h3 id="neural-network">Neural Network</h3>
<ul>
<li>$z = \sum{x_{i}{w_{i}}} + bias$</li>
<li>활성화 함수 $\sigma(z)$을 통해서 비선형화</li>
<li>참값과 예측값을 비교하여 loss 계산</li>
<li>optimizer 적용
<img src="https://velog.velcdn.com/images/insung_na/post/3e29ca15-83ad-4279-aa37-a77044e031f7/image.png" alt=""></li>
</ul>
<h3 id="activation-function">Activation Function</h3>
<ul>
<li>역할 : 비선형화</li>
<li>주로 ReLU 사용
<img src="https://velog.velcdn.com/images/insung_na/post/1833c72c-0897-4702-85a6-cf0b01aee429/image.png" alt=""></li>
</ul>
<h1 id="optimizer">Optimizer</h1>
<ul>
<li>loss를 최소화 하는 weights를 구하는 optimizer
<img src="https://velog.velcdn.com/images/insung_na/post/6d7f6a88-ed8a-4ea3-8a27-683360eff047/image.png" alt=""></li>
</ul>
<h2 id="gradient-descent">Gradient Descent</h2>
<ul>
<li>Loss Function이 아래로 볼록한 형태가 이상적인 경우이고, 이 때, weights를 최적화하기 가장 좋다</li>
<li>Loss function을 미분하여 weights를 갱신한다</li>
<li>Learning rate가 너무 큰 경우, 진동이 발생</li>
<li>반대로 너무 작은 경우, 굉장히 긴 시간의 학습이 필요
<img src="https://velog.velcdn.com/images/insung_na/post/76094789-6bd8-4683-a28e-ce31db36f19e/image.png" alt=""><img src="https://velog.velcdn.com/images/insung_na/post/99e6c76a-c511-417b-af97-aef413c61ca7/image.png" alt=""></li>
</ul>
<h2 id="stochastic-gradient-descent-sgd">Stochastic Gradient Descent (SGD)</h2>
<ul>
<li>기존의 GD는 모든 기울기를 계산했었다</li>
<li>SGD는 확률적으로 기울기를 계산한다</li>
</ul>
<h2 id="momentum">Momentum</h2>
<ul>
<li>기울기 일부를 누적하여 관성을 추가함<pre><code>velocity = momentum * velocity - learning_rate * gradient
w = w + velocity</code></pre></li>
</ul>
<h2 id="root-mean-square-propagation-rmsprop">Root Mean Square Propagation (RMSProp)</h2>
<ul>
<li>AdaGrad는 처음에 크게 학습하고, 점점 작게 학습하는데 과거의 기울기를 제곱하기 때문에 갱신값이 점차 0으로 수렴하는 문제가 있었다</li>
<li>RMSProp은 기하급수적으로 감소하는 평균 제곱 기울기를 사용</li>
<li>각 매개변수의 학습률을 이전 기울기의 평균 제곱근(RMS)으로 나누어 큰 기울기에서는 학습률을 낮추고 작은 기울기에서는 높임<pre><code>cache = decay_rate * cache + (1 - decay_rate) * gradient^2
w = w - (learning_rate / sqrt(cache + epsilon)) * gradient</code></pre></li>
</ul>
<h2 id="adaptive-moment-estimation-adam">Adaptive Moment Estimation (Adam)</h2>
<ul>
<li>Momentum과 RMSProp의 결합</li>
<li>적응형 학습 속도 및 관성, 효율적인 수렴</li>
<li>딥러닝에서 주로 사용하는 optimizer<pre><code>m = beta1 * m + (1 - beta1) * gradient
v = beta2 * v + (1 - beta2) * gradient^2
m_hat = m / (1 - beta1^t)
v_hat = v / (1 - beta2^t)
w = w - (learning_rate / (sqrt(v_hat) + epsilon)) * m_hat</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ZB 데이터스쿨 11기]18주차 학습노트]]></title>
            <link>https://velog.io/@insung_na/ZB-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%8A%A4%EC%BF%A8-11%EA%B8%B018%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5%EB%85%B8%ED%8A%B8</link>
            <guid>https://velog.io/@insung_na/ZB-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%8A%A4%EC%BF%A8-11%EA%B8%B018%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5%EB%85%B8%ED%8A%B8</guid>
            <pubDate>Mon, 08 May 2023 06:56:44 GMT</pubDate>
            <description><![CDATA[<h1 id="📌18주차-학습노트">📌18주차 학습노트</h1>
<h1 id="컴퓨터-비전이란">컴퓨터 비전이란?</h1>
<ul>
<li>컴퓨터를 이용하여 정지 영상 또는 동영상으로부터 의미있는 정보를 추출하는 방법을 연구하는 학문</li>
<li>사람이 눈으로 사물을 보고 인지하는 작업을 컴퓨터가 수행하게 하는 학문</li>
</ul>
<h2 id="computer-vision과-image-processing">Computer Vision과 Image Processing</h2>
<ul>
<li>Computer vision<ul>
<li>컴퓨터로 이미지와 영상으로부터 정보를 추출하고 분석하는 분야</li>
</ul>
</li>
<li>Image Processing<ul>
<li>컴퓨터 비전을 위해 영상을 입력받아 화질 개선 등의 전처리를 의미</li>
</ul>
</li>
</ul>
<h3 id="컴퓨터-비전-응용-분야">컴퓨터 비전 응용 분야</h3>
<ul>
<li>영상의 화질 개선</li>
<li>내용 기반 영상 검색</li>
<li>얼굴 검출 및 인식</li>
<li>의료영상처리</li>
<li>광학 문자 인식</li>
<li>머신 비전</li>
<li>인공지능 서비스</li>
</ul>
<h3 id="영상데이터">영상데이터</h3>
<ul>
<li><p>영상이란?</p>
<ul>
<li>픽셀이 바둑판 모양의 격자에 나열되어 있는 형태(2차원 행렬)</li>
<li>pixel : 영상 기본 단위
<img src="https://user-images.githubusercontent.com/118172599/235609500-a6433170-5069-4e5e-9154-964085b5a02e.png" alt="image"></li>
</ul>
</li>
<li><p>영상의 좌표계</p>
<ul>
<li>이미지는 가로 x 세로로 표기</li>
<li>행렬은 세로 x 가로로 표기</li>
<li>헷갈릴 수 있으니 주의
<img src="https://velog.velcdn.com/images/insung_na/post/51da4d00-ee03-45cb-bc68-6cec47781cf0/image.png" alt=""></li>
</ul>
</li>
<li><p>Grayscale Image</p>
<ul>
<li>흑백사진, 색상 채널 1개</li>
<li>밝기 정보를 256단계로 표현</li>
<li>용량 : width x heigth [Bytes]
<img src="https://velog.velcdn.com/images/insung_na/post/8bcbf8b0-e0e9-47f6-b819-054a706e10e3/image.png" alt=""></li>
</ul>
</li>
</ul>
<ul>
<li><p>Truecolor Image</p>
<ul>
<li>컬러사진, 색상채널 3개</li>
<li>RGB 성분을 각각 256단계로 표현($256^3=16,777,216$)</li>
<li>용량 : width x heigth x 3[Bytes]
<img src="https://velog.velcdn.com/images/insung_na/post/1f8ec04a-3920-4fe6-923e-6606a060216f/image.png" alt=""></li>
</ul>
</li>
<li><p>하나의 픽셀이 3개의 요소를 갖는 경우(C++)</p>
</li>
<li><p>픽셀이 3차원 행렬로 구성되는 경우(Python)
<img src="https://user-images.githubusercontent.com/118172599/235613123-ed7c45d3-92a9-4ea2-8485-4d7508d86f3e.png" alt="image"></p>
</li>
</ul>
<h2 id="기본-이미지-출력python">기본 이미지 출력(python)</h2>
<h3 id="cv-module">cv module</h3>
<pre><code class="language-python">import cv2
import sys

img1 = cv2.imread(&quot;./data/cat.bmp&quot;)  # 데이터 읽기
img2 = cv2.imread(&quot;./data/cat.bmp&quot;, cv2.IMREAD_GRAYSCALE)  # 데이터 읽기
if img1 is None or img2 is None:
    print(&quot;Image load Failed!!&quot;)    # 이미지를 못 찾으면 출력
    sys.exit()

cv2.namedWindow(&quot;Truecolor&quot;, flags=cv2.WINDOW_NORMAL) # &quot;Truecolor&quot; 창 생성
cv2.imshow(&quot;Truecolor&quot;, img1)       # &quot;Truecolor&quot; 창에 img1 보여주기
cv2.namedWindow(&quot;Grayscale&quot;)        # &quot;Grayscale&quot; 창 생성
cv2.imshow(&quot;Grayscale&quot;, img2)       # &quot;Grayscale&quot; 창에 img2 보여주기

cv2.imwrite(&quot;cat_grayscale.png&quot;, img2) # &quot;cat_grayscale.png&quot;로 img2를 저장

while cv2.waitKey() == ord(&quot;q&quot;):    # &quot;q&quot; 입력대기
    break

cv2.destroyAllWindows()             # 모든 창 종료</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/c4575329-09e0-4df0-93c4-07e2a2ae9aae/image.png" alt=""></p>
<h3 id="matplotlib으로-출력하기">Matplotlib으로 출력하기</h3>
<ul>
<li>컬러 영상 출력하기</li>
<li>OpenCV는 BGR순서</li>
<li>plt는 RGB순서
-&gt; cv2.cvtColor() 함수로 색상 순서 변경 필요<pre><code class="language-python">import cv2
import matplotlib.pyplot as plt
</code></pre>
</li>
</ul>
<p>imgBGR = cv2.imread(&#39;cat_truecolor.png&#39;)
imgRGB = cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB)
imgGRAY = cv2.imread(&#39;cat_truecolor.png&#39;, cv2.IMREAD_GRAYSCALE)</p>
<p>plt.figure(figsize=(12, 3))</p>
<h1 id="bgr">BGR</h1>
<p>plt.subplot(131)
plt.axis(&quot;off&quot;)
plt.imshow(imgBGR)
plt.title(&quot;imgBGR&quot;)</p>
<h1 id="rgb">RGB</h1>
<p>plt.subplot(132)
plt.axis(&quot;off&quot;)
plt.imshow(imgRGB)
plt.title(&quot;imgRGB&quot;)</p>
<h1 id="gray">GRAY</h1>
<p>plt.subplot(133)
plt.axis(&quot;off&quot;)
plt.imshow(imgGRAY, cmap=&quot;gray&quot;)
plt.title(&quot;imgGRAY&quot;)</p>
<p>plt.show()</p>
<pre><code>![](https://velog.velcdn.com/images/insung_na/post/150b4610-e7fa-4d47-b221-9e4953c96909/image.png)


## ROI와 마스크 연산
- 관심 영역(ROI)
    - Region of Interest
    - 영상에서 특정 연산을 수행하고자 하는 영역
- 마스크 연산
    - OpenCV에서는 이미지합성을 할 때, 마스크 영상의 0이 아닌 부분을 입력영상에서 추출해서 출력영상과 합성을 한다.
    - 배경과 대상을 구분하는 마스크 영상을 활용
    - 마스크 영상은 `cv2.CV_8UC1`타입이어야 한다
    - 픽셀 값이 0이 아닌 위치에서만 연산이 수행됨

### 마스크 연산 함수
- `cv2.copyTo(src, mask, dst=None) -&gt; dst`
  - src : 입력영상, `cv2.CV_8UC3`
  - mask : 마스크 영상, `cv2.CV_8U`
    - 0이 아닌 픽셀에 대해서만 복사연산 수행
  - dst : 출력영상, `cv2.CV_8UC3`
  - 연산 수행 시 각 인자의 크기가 동일해야 함

### 마스크 영상을 이용한 영상 합성(Python)
```python
import sys
import cv2


# 마스크 영상을 이용한 영상 합성
src = cv2.imread(&#39;./data/airplane.bmp&#39;, cv2.IMREAD_COLOR)
mask = cv2.imread(&#39;./data/mask_plane.bmp&#39;, cv2.IMREAD_GRAYSCALE)
dst = cv2.imread(&#39;./data/field.bmp&#39;, cv2.IMREAD_COLOR)

if src is None or mask is None or dst is None:
    print(&#39;Image load failed!&#39;)
    sys.exit()

# mask에서 값이 0이 아닌 부분을 src에서 복사해서 dst에 합성
# cv2.copyTo() 실행 시에 모든 요소의 크기가 같아야 함
cv2.copyTo(src, mask, dst)
# dst[mask &gt; 0] = src[mask &gt; 0]

cv2.imshow(&#39;src&#39;, src)
cv2.imshow(&#39;mask&#39;, mask)
cv2.imshow(&#39;dst&#39;, dst)
cv2.waitKey()
cv2.destroyAllWindows()</code></pre><p><img src="https://velog.velcdn.com/images/insung_na/post/57bfd82d-c88d-4fcb-a354-dd7c51a35395/image.png" alt=""></p>
<h2 id="도형그리기">도형그리기</h2>
<pre><code class="language-python">import numpy as np
import cv2

img = np.full((400, 400, 3), 255, np.uint8)
#img = cv2.imread(&#39;cat.bmp&#39;)

cv2.line(img, (50, 50), (200, 50), (0, 0, 255), 5)
cv2.line(img, (50, 60), (150, 160), (0, 0, 128))

cv2.rectangle(img, (50, 200, 150, 100), (0, 255, 0), 2)
cv2.rectangle(img, (70, 220), (180, 280), (0, 128, 0), -1)

cv2.circle(img, (300, 100), 30, (255, 255, 0), -1, cv2.LINE_AA)
cv2.circle(img, (300, 100), 60, (255, 0, 0), 3, cv2.LINE_AA)

pts = np.array([[250, 200], [300, 200], [350, 300], [250, 300]])
cv2.polylines(img, [pts], True, (255, 0, 255), 2)

text = &#39;Hello? OpenCV &#39; + cv2.__version__
cv2.putText(img, text, (50, 350), cv2.FONT_HERSHEY_SIMPLEX, 0.8, 
            (0, 0, 255), 1, cv2.LINE_AA)

cv2.imshow(&quot;img&quot;, img)
cv2.waitKey()
cv2.destroyAllWindows()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/edcd7ae6-6500-4e04-92de-8e8c85642e6a/image.png" alt=""></p>
<h2 id="카메라-출력-및-영상저장">카메라 출력 및 영상저장</h2>
<pre><code class="language-python">import sys
import cv2


cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print(&quot;Camera open Failed!&quot;)
    sys.exit()

w = round(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)

fourcc = cv2.VideoWriter_fourcc(*&quot;DIVX&quot;) # *&#39;DIVX&#39; == &#39;D&#39;, &#39;I&#39;, &#39;V&#39;, &#39;X&#39;
delay = round(1000 / fps)

out = cv2.VideoWriter(&#39;./data/output.avi&#39;, fourcc, fps, (w, h))    # 프레임 단위 영상저장

if not out.isOpened():
    print(&#39;File open Failed!&#39;)
    cap.release()
    sys.exit()

while True:
    ret, frame = cap.read()

    if not ret:
        break

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)    # 흑백
    edge = cv2.Canny(gray, 100, 255)                # 외곽선
    gray_color = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR) # 저장을 위해 BGR로 변환

    out.write(gray_color)    # 흑백 저장

    cv2.imshow(&#39;frame&#39;, frame)
    cv2.imshow(&#39;gray&#39;, gray)
    cv2.imshow(&#39;gray_color&#39;, gray_color)
    cv2.imshow(&#39;edge&#39;, edge)

    if cv2.waitKey(delay) == 27:
        break

cap.release()
out.release()
cv2.destroyAllWindows()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/5b410f5a-20c2-45b3-995d-2b578b0b9af2/image.png" alt=""></p>
<h2 id="명함검출">명함검출</h2>
<p><img src="https://velog.velcdn.com/images/insung_na/post/76b66ae3-830e-4e6b-8fb2-eb5f599e3a8e/image.png" alt=""></p>
<h3 id="명함-검출python">명함 검출(Python)</h3>
<pre><code class="language-python">import sys
import cv2


# 영상 불러오기
src = cv2.imread(&#39;./data/namecard1.jpg&#39;)

if src is None:
    print(&#39;Image load failed!&#39;)
    sys.exit()

# 입력 영상을 그레이스케일 영상으로 변환
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

# 자동 이진화
_, src_bin = cv2.threshold(src_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

# 외곽선 검출 및 명함 검출
contours, _ = cv2.findContours(src_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

for pts in contours:
    # 너무 작은 객체는 무시
    if cv2.contourArea(pts) &lt; 1000:
        continue

    # 외곽선 근사화
    approx = cv2.approxPolyDP(pts, cv2.arcLength(pts, True)*0.02, True)

    # 사각형으로 근사화되면 외곽선 표시
    if len(approx) == 4:
        cv2.polylines(src, [approx], True, (0, 255, 0), 2, cv2.LINE_AA)

cv2.imshow(&#39;src&#39;, src)
cv2.waitKey()
cv2.destroyAllWindows()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/9d8c5f56-21c3-4c77-a666-86599f99b395/image.png" alt=""></p>
<h3 id="명함-똑바로-펴기">명함 똑바로 펴기</h3>
<ul>
<li>데이터 : 강사님의 명함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/insung_na/post/39214b8e-0765-415f-ad25-fd2abed31b1b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/4f5a927b-d494-476c-8f9c-873587b10d47/image.png" alt=""></p>
<h4 id="수동으로-펴기">수동으로 펴기</h4>
<pre><code class="language-python">import sys
import numpy as np
import cv2


# 영상 불러오기
src = cv2.imread(&#39;namecard1.jpg&#39;)

if src is None:
    print(&#39;Image load failed!&#39;)
    sys.exit()

# 출력 영상 설정
w, h = 720, 400
srcQuad = np.array([[324, 308], [760, 369], [718, 611], [231, 517]], np.float32)
dstQuad = np.array([[0, 0], [w-1, 0], [w-1, h-1], [0, h-1]], np.float32)
dst = np.zeros((h, w), np.uint8)

pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)
dst = cv2.warpPerspective(src, pers, (w, h))

cv2.imshow(&#39;src&#39;, src)
cv2.imshow(&#39;dst&#39;, dst)
cv2.waitKey()
cv2.destroyAllWindows()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/bff26114-38e0-4157-bb43-9653448ac52f/image.png" alt=""></p>
<h4 id="자동으로-펴기">자동으로 펴기</h4>
<pre><code class="language-python">import sys
import numpy as np
import cv2

# approx 좌표 순서 지정
def reorderPts(pts):
    idx = np.lexsort((pts[:, 1], pts[:, 0]))  # 칼럼0 -&gt; 칼럼1 순으로 정렬한 인덱스를 반환
    pts = pts[idx]  # x좌표로 정렬

    if pts[0, 1] &gt; pts[1, 1]:
        pts[[0, 1]] = pts[[1, 0]]

    if pts[2, 1] &lt; pts[3, 1]:
        pts[[2, 3]] = pts[[3, 2]]

    return pts


# 영상 불러오기
src = cv2.imread(&#39;./data/namecard2.jpg&#39;)

if src is None:
    print(&#39;Image load failed!&#39;)
    sys.exit()

# 출력 영상 설정
w, h = 720, 400
srcQuad = np.array([[0, 0], [0, h], [w, h], [w, 0]], np.float32)
dstQuad = np.array([[0, 0], [0, h], [w, h], [w, 0]], np.float32)
dst = np.zeros((h, w), np.uint8)

# 입력 영상을 그레이스케일 영상으로 변환
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

# 자동 이진화
_, src_bin = cv2.threshold(src_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

# 외곽선 검출 및 명함 검출
contours, _ = cv2.findContours(src_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

for pts in contours:
    # 너무 작은 객체는 무시
    if cv2.contourArea(pts) &lt; 1000:
        continue

    # 외곽선 근사화
    approx = cv2.approxPolyDP(pts, cv2.arcLength(pts, True)*0.02, True)

    # 사각형으로 근사화되면 외곽선 표시
    if len(approx) == 4:
        #cv2.polylines(src, [approx], True, (0, 255, 0), 2, cv2.LINE_AA)
        corners = approx.reshape(4, 2).astype(np.float32)
        srcQuad = reorderPts(corners)


pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)
dst = cv2.warpPerspective(src, pers, (w, h))

cv2.imshow(&#39;src&#39;, src)
cv2.imshow(&#39;dst&#39;, dst)
cv2.waitKey()
cv2.destroyAllWindows()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/b3812a36-1617-4239-850e-9a873742531d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/8db2c95e-cacb-4e2a-ab3b-53972ae76549/image.png" alt=""></p>
<h2 id="딥러닝모델을-활용한-얼굴검출">딥러닝모델을 활용한 얼굴검출</h2>
<ul>
<li>미리 학습된 딥러닝모델을 사용함
<img src="https://velog.velcdn.com/images/insung_na/post/7aa91443-2de8-4233-8e0b-87b7a80acc4b/image.png" alt=""></li>
</ul>
<h3 id="영상에서-얼굴-찾기">영상에서 얼굴 찾기</h3>
<h4 id="opencv-dnn-얼굴-검출기-입력">OpenCV DNN 얼굴 검출기 입력</h4>
<ul>
<li>입력 영상 크기: 300x300</li>
<li>픽셀 값 범위: 0 ~ 255</li>
<li>색상 채널 순서: BGR</li>
<li>평균 픽셀 값: (104, 177, 123)</li>
</ul>
<h4 id="opencv-dnn-얼굴-검출기-출력">OpenCV DNN 얼굴 검출기 출력</h4>
<ul>
<li>shape=(1, 1, 200, 7), dtype=float32</li>
<li>detect = out[0, 0, :, :]</li>
</ul>
<pre><code class="language-python">import sys
import numpy as np
import cv2


model = &#39;./data/opencv_face_detector/res10_300x300_ssd_iter_140000_fp16.caffemodel&#39;
config = &#39;./data/opencv_face_detector/deploy.prototxt&#39;
#model = &#39;opencv_face_detector/opencv_face_detector_uint8.pb&#39;
#config = &#39;opencv_face_detector/opencv_face_detector.pbtxt&#39;

# 카메라 열기
cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print(&#39;Camera open failed!&#39;)
    sys.exit()

# 모델 불러오기
net = cv2.dnn.readNet(model, config)

if net.empty():
    print(&#39;Net open failed!&#39;)
    sys.exit()

while True:
    # 카메라 읽기
    ret, frame = cap.read()

    # 이미지 좌우 반전
    frame = cv2.flip(frame, 1)

    if not ret:
        break

    # 2차원 -&gt; 4차원 이미지 생성
    blob = cv2.dnn.blobFromImage(frame, 1, (300, 300), (104, 177, 123))

    # 모델에 이미지 입력
    net.setInput(blob)

    # 모델 실행
    out = net.forward()
    detect = out[0, 0, :, :]

    (h, w) = frame.shape[:2]

    for i in range(detect.shape[0]):
        confidence = detect[i, 2]
        if confidence &lt; 0.5:    # 예측값이 0.5 이하면 무시
            break

        # 바운딩 박스의 좌표
        x1 = int(detect[i, 3] * w)
        y1 = int(detect[i, 4] * h)
        x2 = int(detect[i, 5] * w)
        y2 = int(detect[i, 6] * h)

        # 바운딩 박스 그리기
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0))

        # 예측값 출력
        label = f&#39;Face: {confidence:4.2f}&#39;
        cv2.putText(frame, label, (x1, y1 - 1), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 1, cv2.LINE_AA)

    cv2.imshow(&#39;frame&#39;, frame)

    if cv2.waitKey(1) == 27:  # ESC누르면 종료
        break

cap.release()
cv2.destroyAllWindows()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/f6dc0ac1-e127-49d9-bc91-42e58d0d249f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/7f8565db-6305-45f3-b5a5-53ccc7757307/image.png" alt=""></p>
<h3 id="얼굴-모자이크처리">얼굴 모자이크처리</h3>
<ul>
<li>촬영을 하다보면 타인의 개인정보(얼굴, 자동차 번호판, 주민번호 등)을 습득하게 된다.</li>
<li>개인정보를 보호하기 위해 이를 모자이크 처리할 필요성이 있다
<img src="https://velog.velcdn.com/images/insung_na/post/a8cc6826-d477-42d5-9b13-22d1efd5d340/image.png" alt=""></li>
</ul>
<pre><code class="language-python">import sys
import numpy as np
import cv2

model = &#39;./data/opencv_face_detector/res10_300x300_ssd_iter_140000_fp16.caffemodel&#39;
config = &#39;./data/opencv_face_detector/deploy.prototxt&#39;
#model = &#39;opencv_face_detector/opencv_face_detector_uint8.pb&#39;
#config = &#39;opencv_face_detector/opencv_face_detector.pbtxt&#39;

# 카메라 열기
cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print(&#39;Camera open failed!&#39;)
    sys.exit()

# 모델 불러오기
net = cv2.dnn.readNet(model, config)

if net.empty():
    print(&#39;Net open failed!&#39;)
    sys.exit()

while True:
    # 카메라 읽기
    ret, frame = cap.read()

    # 이미지 좌우 반전
    frame = cv2.flip(frame, 1)

    if not ret:
        break

    # 2차원 -&gt; 4차원 이미지 생성
    blob = cv2.dnn.blobFromImage(frame, 1, (300, 300), (104, 177, 123))

    # 모델에 이미지 입력
    net.setInput(blob)

    # 모델 실행
    out = net.forward()
    detect = out[0, 0, :, :]

    (h, w) = frame.shape[:2]

    for i in range(detect.shape[0]):
        confidence = detect[i, 2]
        if confidence &lt; 0.5:    # 예측값이 0.5 이하면 무시
            break

        # 바운딩 박스의 좌표
        x1 = int(detect[i, 3] * w)
        y1 = int(detect[i, 4] * h)
        x2 = int(detect[i, 5] * w)
        y2 = int(detect[i, 6] * h)

        face_img = frame[y1:y2, x1:x2]
        fh, fw = face_img.shape[:2]

        # 모자이크 처리
        face_img2 = cv2.resize(face_img, (0, 0), fx=1./16, fy=1./16)
        cv2.resize(face_img2, (fw, fh), dst=face_img, interpolation=cv2.INTER_NEAREST)
        #frame[y1:y2, x1:x2] = cv2.resize(face_img2, (fw, fh), interpolation=cv2.INTER_NEAREST)


        # 바운딩 박스 그리기
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0))

        # # 예측값 출력
        label = f&#39;Face: {confidence:4.2f}&#39;
        cv2.putText(frame, label, (x1, y1 - 1), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 1, cv2.LINE_AA)

    cv2.imshow(&#39;frame&#39;, frame)

    if cv2.waitKey(1) == 27:  # ESC누르면 종료
        break

cap.release()
cv2.destroyAllWindows()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/914ce683-b61b-490d-9145-fcf914660ef6/image.png" alt=""></p>
<h1 id="📌자연어-처리">📌자연어 처리</h1>
<h2 id="transformer">Transformer</h2>
<ul>
<li>Attention 기법을 활용하여 CNN, RNN을 사용하지 않는 자연어 처리 모델</li>
<li>GPT : Transformer의 Decoder를 아키텍처를 활용</li>
<li>BERT : Transformer의 Encoder를 아키텍처를 활용</li>
</ul>
<h2 id="자연어처리-task">자연어처리 task</h2>
<ul>
<li>감정 분석<ul>
<li>ex. 맛있는 사과를 먹었다</li>
</ul>
</li>
<li>기계어번역<ul>
<li>ex. 나는 사과를 먹었다 -&gt; I ate an apple</li>
</ul>
</li>
<li>QA<ul>
<li>ex. 지문을 읽고, 질문에 대답</li>
</ul>
</li>
<li>마스크 필링<ul>
<li>ex. 나는 X를 먹었다 -&gt; X에 들어갈 수 있는 단어 찾기</li>
</ul>
</li>
</ul>
<h2 id="transformer-architecture">Transformer Architecture</h2>
<h3 id="positional-encoding">Positional Encoding</h3>
<ul>
<li>transformer는 병렬 처리이므로 성능이 향상되었으나 RNN에서 가능했던 순서처리가 불가능해짐</li>
<li>이를 해결하기 위해 positional encoding 사용</li>
<li>각 토큰의 입력 임베딩에 위치 인코딩을 추가함으로써 Transformer 모델은 병렬 처리 구조에도 불구하고 토큰의 순차적 순서를 유지할 수 있게 됨</li>
</ul>
<h3 id="multi-head-attention">Multi head attention</h3>
<ul>
<li>Self-Attention 메커니즘을 이용한 자연어 처리 향상 모듈</li>
<li>입력벡터로 query, key, value 벡터를 받음</li>
<li>이를 활용하여 attention score를 계산하고 단어별 중요도를 결정할 수 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/insung_na/post/128fc534-3132-489b-9c2d-8e34a637e70b/image.png" alt=""></p>
<h3 id="성능향상을-위한-기술">성능향상을 위한 기술</h3>
<ul>
<li>Skip Connection<ul>
<li>한 계층의 출력을 다른 계층의 출력에 직접 추가하는 연결</li>
<li>Vanishing Gradient를 완화하기 위해 사용한 방법</li>
</ul>
</li>
<li>Layer Normalization<ul>
<li>각 계층의 출력 정규화</li>
<li>입력 변동의 영향을 줄이고 네트워크의 전반적인 안정성과 성능 향상</li>
</ul>
</li>
</ul>
<h3 id="기존-모델과-성능비교">기존 모델과 성능비교</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/ec24bcca-2ffd-45de-b618-599af1d0f11b/image.png" alt=""></p>
<h3 id="요약">요약</h3>
<ul>
<li>기계번역 task에서 기존의 연구들 보다 성능적으로 우수</li>
<li>병렬적으로 처리가 가능한 모델 -&gt; time complexity 감소</li>
<li>이후에 사용되는 Bert, GPT 모델에서 일반화에 강점이 있다는 것이 확인</li>
</ul>
<h2 id="transformer-process">Transformer Process</h2>
<p><img src="https://velog.velcdn.com/images/insung_na/post/befb9ee9-a009-4919-844c-d7af2363411c/image.png" alt=""></p>
<ul>
<li><ol>
<li>input 임베딩 + Position Encoding (Encoder)</li>
</ol>
</li>
<li><ol start="2">
<li>Q, K, V 생성</li>
</ol>
</li>
<li><ol start="3">
<li>Multi-Head Attention 사용</li>
</ol>
</li>
<li><ol start="4">
<li>Skip-Connection + Layer Normalization</li>
</ol>
</li>
<li><ol start="5">
<li>Self-attention 반복수행</li>
</ol>
</li>
<li><ol start="6">
<li>Encoder의 출력값을 Decoder가 받아서 학습을 진행</li>
</ol>
</li>
<li><ol start="7">
<li>Linear모델과 softmax을 통해서 최종결과(확률)를 도출</li>
</ol>
</li>
</ul>
<h2 id="hugging-face">Hugging Face</h2>
<ul>
<li><a href="https://github.com/huggingface/transformers">https://github.com/huggingface/transformers</a></li>
<li>NLP분야의 스타트업</li>
<li>다양한 트랜스포머 모델(transformer.models)과 학습 스크립트(transformer.Trainer)를 제공하는 모듈</li>
<li>개발자가 자연어 처리 애플리케이션과 서비스를 빠르고 효율적으로 구축하고 배포할 수 있도록 함</li>
</ul>
<h3 id="사용법">사용법</h3>
<ul>
<li><p>사용할 Task, Libraries 등 또는 Filter을 설정하고 원하는 모델을 찾기</p>
</li>
<li><p>모델 포스팅 글에서 사용법 확인하고 적용하기
<img src="https://velog.velcdn.com/images/insung_na/post/6f8d36b3-8f99-44e9-a297-a9605711517b/image.png" alt=""><img src="https://velog.velcdn.com/images/insung_na/post/51dba9f8-e956-45ff-b166-9b25139564e9/image.png" alt=""><img src="https://velog.velcdn.com/images/insung_na/post/2f604077-bb17-4ef3-afbd-0b989c4392ff/image.png" alt=""></p>
</li>
<li><p>사이트에서도 간편실행가능
<img src="https://velog.velcdn.com/images/insung_na/post/89c8b49f-3240-4474-93fd-bb0937181962/image.png" alt=""></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Hugging Face: Use Model]]></title>
            <link>https://velog.io/@insung_na/Hugging-Face-Training</link>
            <guid>https://velog.io/@insung_na/Hugging-Face-Training</guid>
            <pubDate>Mon, 08 May 2023 06:23:57 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다</p>
</blockquote>
<h1 id="1-zip_dataset_load">1. zip_dataset_load</h1>
<h2 id="squad_it">SQuAD_it</h2>
<h4 id="data-download--unzip">Data download &amp; unzip</h4>
<pre><code class="language-python">!wget https://github.com/crux82/squad-it/raw/master/SQuAD_it-train.json.gz
!wget https://github.com/crux82/squad-it/raw/master/SQuAD_it-test.json.gz

!gzip -dkv SQuAD_it-*.json.gz</code></pre>
<h3 id="데이터-불러오기">데이터 불러오기</h3>
<pre><code class="language-python">!pip install datasets
!pip install transformers
from datasets import load_dataset

data_files = {&quot;train&quot;: &quot;./SQuAD_it-train.json&quot;, &quot;test&quot;: &quot;./SQuAD_it-test.json&quot;}
squad_it_dataset = load_dataset(&quot;json&quot;, data_files=data_files, field=&quot;data&quot;)
squad_it_dataset
-------------------------------------------------------------------
DatasetDict({
    train: Dataset({
        features: [&#39;paragraphs&#39;, &#39;title&#39;],
        num_rows: 442
    })
    test: Dataset({
        features: [&#39;paragraphs&#39;, &#39;title&#39;],
        num_rows: 48
    })
})</code></pre>
<h2 id="drugscom_raw">drugsCom_raw</h2>
<h3 id="데이터-로드">데이터 로드</h3>
<pre><code class="language-python">!wget &quot;https://archive.ics.uci.edu/ml/machine-learning-databases/00462/drugsCom_raw.zip&quot;
!unzip drugsCom_raw.zip
data_files = {&quot;train&quot;: &quot;drugsComTrain_raw.tsv&quot;, &quot;test&quot;:&quot;drugsComTest_raw.tsv&quot;}
drug_dataset = load_dataset(&quot;csv&quot;, data_files=data_files, delimiter=&quot;\t&quot;)
drug_dataset
-----------------------------------------------------------------
DatasetDict({
    train: Dataset({
        features: [&#39;Unnamed: 0&#39;, &#39;drugName&#39;, &#39;condition&#39;, &#39;review&#39;, &#39;rating&#39;, &#39;date&#39;, &#39;usefulCount&#39;],
        num_rows: 161297
    })
    test: Dataset({
        features: [&#39;Unnamed: 0&#39;, &#39;drugName&#39;, &#39;condition&#39;, &#39;review&#39;, &#39;rating&#39;, &#39;date&#39;, &#39;usefulCount&#39;],
        num_rows: 53766
    })
})</code></pre>
<h3 id="전처리">전처리</h3>
<pre><code class="language-python">drug_dataset = drug_dataset.rename_column(  # 칼럼명 변경
    original_column_name=&quot;Unnamed: 0&quot;, new_column_name=&quot;patient_id&quot;
)
drug_dataset
-------------------------------------------------------------------
DatasetDict({
    train: Dataset({
        features: [&#39;patient_id&#39;, &#39;drugName&#39;, &#39;condition&#39;, &#39;review&#39;, &#39;rating&#39;, &#39;date&#39;, &#39;usefulCount&#39;],
        num_rows: 161297
    })
    test: Dataset({
        features: [&#39;patient_id&#39;, &#39;drugName&#39;, &#39;condition&#39;, &#39;review&#39;, &#39;rating&#39;, &#39;date&#39;, &#39;usefulCount&#39;],
        num_rows: 53766
    })
})</code></pre>
<h4 id="데이터-소문자화">데이터 소문자화</h4>
<pre><code class="language-python">def lowercase_condition(example):
  return {&quot;condition&quot;: example[&quot;condition&quot;].lower()}

drug_dataset = drug_dataset.filter(lambda x: x[&quot;condition&quot;] is not None) # Nonetype 제거
drug_dataset.map(lowercase_condition) # 데이터를 소문자로 변경</code></pre>
<h4 id="리뷰-길이-제한">리뷰 길이 제한</h4>
<pre><code class="language-python">def compute_review_length(example):
  return {&quot;review_length&quot;: len(example[&quot;review&quot;].split())}

drug_dataset = drug_dataset.map(compute_review_length)
drug_dataset = drug_dataset.filter(lambda x: x[&quot;review_length&quot;] &gt; 30) # 리뷰가 너무 긴 데이터는 필터링
print(drug_dataset.num_rows)
-----------------------------------------------
{&#39;train&#39;: 138514, &#39;test&#39;: 46108}</code></pre>
<h3 id="1-batch">1 batch</h3>
<pre><code class="language-python">import html

new_drug_dataset = drug_dataset.map(
    lambda x: {&quot;review&quot;: [html.unescape(o) for o in x[&quot;review&quot;]]}, batched=True
)
new_drug_dataset
-------------------------------------------------------------------------
DatasetDict({
    train: Dataset({
        features: [&#39;patient_id&#39;, &#39;drugName&#39;, &#39;condition&#39;, &#39;review&#39;, &#39;rating&#39;, &#39;date&#39;, &#39;usefulCount&#39;, &#39;review_length&#39;],
        num_rows: 138514
    })
    test: Dataset({
        features: [&#39;patient_id&#39;, &#39;drugName&#39;, &#39;condition&#39;, &#39;review&#39;, &#39;rating&#39;, &#39;date&#39;, &#39;usefulCount&#39;, &#39;review_length&#39;],
        num_rows: 46108
    })
})</code></pre>
<h3 id="autotokenizer">AutoTokenizer</h3>
<pre><code class="language-python">from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained(&quot;bert-base-cased&quot;)

def tokenize_and_split(examples):
  return tokenizer(
      examples[&quot;review&quot;],
      truncation=True,
      max_length=128,
      return_overflowing_tokens=True  # 길이를 넘어가는 토큰 반환 여부
  )
len(drug_dataset[&quot;train&quot;][0][&#39;review&#39;].split()) # 전체 문장을 띄어쓰기로 분할한 수
----------------------
141</code></pre>
<pre><code class="language-python">result = tokenize_and_split(drug_dataset[&quot;train&quot;][0])
[len(inp) for inp in result[&quot;input_ids&quot;]]       # max length 내부와 초과한 대상
--------------------------
[128, 49]</code></pre>
<h1 id="2-model">2. Model</h1>
<pre><code class="language-python">from transformers import AutoTokenizer

checkpoint = &quot;distilbert-base-uncased-finetuned-sst-2-english&quot;  # 사용할 모델
tokenizer = AutoTokenizer.from_pretrained(checkpoint)           # 모델의 tokenizer 로딩

raw_inputs = [
    &quot;I&#39;ve been waiting for a HuggingFace course my whole life.&quot;,
    &quot;I hate this so much!&quot;,
]

inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors=&quot;pt&quot;)  # input을 숫자로 토큰화
inputs[&quot;input_ids&quot;]
-----------------------------------------------------------------------------------
tensor([[  101,  1045,  1005,  2310,  2042,  3403,  2005,  1037, 17662, 12172,
          2607,  2026,  2878,  2166,  1012,   102],
        [  101,  1045,  5223,  2023,  2061,  2172,   999,   102,     0,     0,
             0,     0,     0,     0,     0,     0]])</code></pre>
<pre><code class="language-python">inputs[&quot;attention_mask&quot;]    # 문장길이를 맞추기 위해 0으로 패딩
-------------------------------------------------------------
tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])</code></pre>
<h2 id="분류모델">분류모델</h2>
<pre><code class="language-python">from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)
model.config.id2label
---------------------------------------------
{0: &#39;NEGATIVE&#39;, 1: &#39;POSITIVE&#39;}</code></pre>
<pre><code class="language-python">outputs = model(**inputs)
outputs
-----------------------------------------------------------------------
SequenceClassifierOutput(loss=None, logits=tensor([[-1.5607,  1.6123],
        [ 4.1692, -3.3464]], grad_fn=&lt;AddmmBackward0&gt;), hidden_states=None, attentions=None)</code></pre>
<h4 id="지문에-대한-긍정-부정-분류">지문에 대한 긍정 부정 분류</h4>
<ul>
<li>첫번째 문장은 긍정</li>
<li>두번째 문장은 부정<pre><code class="language-python">import torch
</code></pre>
</li>
</ul>
<p>predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
predictions</p>
<hr>
<p>tensor([[4.0195e-02, 9.5981e-01],
        [9.9946e-01, 5.4418e-04]], grad_fn=<SoftmaxBackward0>)</p>
<pre><code>
## BertModel Config Modify
### Config 불러오기
```python
from transformers import BertConfig, BertModel

config = BertConfig()   # default 파라미터
config
----------------------------------------------------
BertConfig {
  &quot;attention_probs_dropout_prob&quot;: 0.1,
  &quot;classifier_dropout&quot;: null,
  &quot;hidden_act&quot;: &quot;gelu&quot;,
  &quot;hidden_dropout_prob&quot;: 0.1,
  &quot;hidden_size&quot;: 768,
  &quot;initializer_range&quot;: 0.02,
  &quot;intermediate_size&quot;: 3072,
  &quot;layer_norm_eps&quot;: 1e-12,
  &quot;max_position_embeddings&quot;: 512,
  &quot;model_type&quot;: &quot;bert&quot;,
  &quot;num_attention_heads&quot;: 12,
  &quot;num_hidden_layers&quot;: 12,
  &quot;pad_token_id&quot;: 0,
  &quot;position_embedding_type&quot;: &quot;absolute&quot;,
  &quot;transformers_version&quot;: &quot;4.28.1&quot;,
  &quot;type_vocab_size&quot;: 2,
  &quot;use_cache&quot;: true,
  &quot;vocab_size&quot;: 30522
}</code></pre><h3 id="모델에-config-적용">모델에 config 적용</h3>
<pre><code class="language-python">model = BertModel(config)
model
------------------------------------------------------
BertModel(
  (embeddings): BertEmbeddings(
    (word_embeddings): Embedding(30522, 768, padding_idx=0)
    (position_embeddings): Embedding(512, 768)
    (token_type_embeddings): Embedding(2, 768)
    (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
    (dropout): Dropout(p=0.1, inplace=False)
  )
  (encoder): BertEncoder(
    (layer): ModuleList(
      (0-11): 12 x BertLayer(
        (attention): BertAttention(
          (self): BertSelfAttention(
            (query): Linear(in_features=768, out_features=768, bias=True)
            (key): Linear(in_features=768, out_features=768, bias=True)
            (value): Linear(in_features=768, out_features=768, bias=True)
            (dropout): Dropout(p=0.1, inplace=False)
          )
          (output): BertSelfOutput(
            (dense): Linear(in_features=768, out_features=768, bias=True)
            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
            (dropout): Dropout(p=0.1, inplace=False)
          )
        )
        (intermediate): BertIntermediate(
...
  (pooler): BertPooler(
    (dense): Linear(in_features=768, out_features=768, bias=True)
    (activation): Tanh()
  )
)</code></pre>
<h3 id="config-수정해보기">Config 수정해보기</h3>
<pre><code class="language-python">config.hidden_size = 48    # 786 -&gt; 48
model = BertModel(config)
model
-----------------------------------------------------------
BertModel(
  (embeddings): BertEmbeddings(
    (word_embeddings): Embedding(30522, 48, padding_idx=0)
    (position_embeddings): Embedding(512, 48)
    (token_type_embeddings): Embedding(2, 48)
    (LayerNorm): LayerNorm((48,), eps=1e-12, elementwise_affine=True)
    (dropout): Dropout(p=0.1, inplace=False)
  )
  (encoder): BertEncoder(
    (layer): ModuleList(
      (0-11): 12 x BertLayer(
        (attention): BertAttention(
          (self): BertSelfAttention(
            (query): Linear(in_features=48, out_features=48, bias=True)
            (key): Linear(in_features=48, out_features=48, bias=True)
            (value): Linear(in_features=48, out_features=48, bias=True)
            (dropout): Dropout(p=0.1, inplace=False)
          )
          (output): BertSelfOutput(
            (dense): Linear(in_features=48, out_features=48, bias=True)
            (LayerNorm): LayerNorm((48,), eps=1e-12, elementwise_affine=True)
            (dropout): Dropout(p=0.1, inplace=False)
          )
        )
        (intermediate): BertIntermediate(
...
  (pooler): BertPooler(
    (dense): Linear(in_features=48, out_features=48, bias=True)
    (activation): Tanh()
  )
)</code></pre>
<h2 id="model-저장하기">model 저장하기</h2>
<pre><code class="language-python">model.save_pretrained(&quot;./test&quot;)</code></pre>
<h1 id="3-tokenizer">3. Tokenizer</h1>
<h2 id="tokenizer가-적절하지-못하면">tokenizer가 적절하지 못하면</h2>
<ul>
<li>tokenzier의 사용모델(환경)에 적절한 것을 사용하여야 한다</li>
<li>ex. A데이터셋을 기반으로 학습하였는데 B데이터셋을 사용한 경우</li>
<li>인식하지 못하면 &#39;[UNK]&#39;</li>
<li>자주 사용하는 접두어, 접미어를 학습한 경우 &#39;##&#39;같은 것이 생성됨<pre><code class="language-python">tokenizer = AutoTokenizer.from_pretrained(&quot;bert-base-cased&quot;)
sequence = &quot;Using a Transformer network is simple&quot;
tokens = tokenizer.tokenize(sequence)
</code></pre>
</li>
</ul>
<h2 id="printtokens">print(tokens)</h2>
<p>[&#39;Using&#39;, &#39;a&#39;, &#39;Trans&#39;, &#39;##former&#39;, &#39;network&#39;, &#39;is&#39;, &#39;simple&#39;]</p>
<pre><code>- 토큰화가 적합하지 않으면 의미없는 토큰으로 분리될 수 있음
```python
sequence = &quot;Using a Transformer network is manual, KT-12312&quot;
tokens = tokenizer.tokenize(sequence)

print(tokens)
--------------------------------------------
[&#39;Using&#39;, &#39;a&#39;, &#39;Trans&#39;, &#39;##former&#39;, &#39;network&#39;, &#39;is&#39;, &#39;manual&#39;, &#39;,&#39;, &#39;K&#39;, &#39;##T&#39;, &#39;-&#39;, &#39;123&#39;, &#39;##12&#39;]</code></pre><h3 id="convert와-decode">Convert와 Decode</h3>
<pre><code class="language-python">ids = tokenizer.convert_tokens_to_ids(tokens)
ids
-------------------------------------------------
[7993, 170, 13809, 23763, 2443, 1110, 9506, 117, 148, 1942, 118, 13414, 11964]</code></pre>
<pre><code class="language-python">tokenizer.decode(ids)
------------------------------------------
&#39;Using a Transformer network is manual, KT - 12312&#39;</code></pre>
<h1 id="4-training">4. Training</h1>
<ul>
<li>dataloader -&gt; model -&gt; optimizer -&gt; loss -&gt; training<pre><code class="language-python">from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch
</code></pre>
</li>
</ul>
<p>checkpoint = &#39;distilbert-base-uncased-finetuned-sst-2-english&#39;          # 사용할 모델명
tokenizer = AutoTokenizer.from_pretrained(checkpoint)                   # 모델의 토큰화
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)  # 모델 로딩</p>
<p>sequence = &quot;I&#39;ve been waiting for a HuggingFace course my whole life.&quot;  # text</p>
<p>tokens = tokenizer.tokenize(sequence)   # text -&gt; token
ids = tokenizer.convert_tokens_to_ids(tokens) # token -&gt; ids</p>
<p>inputs_ids = torch.tensor([ids])
print(&quot;input IDs:\n&quot;, inputs_ids, end=&quot;\n\n&quot;)</p>
<p>output = model(inputs_ids)
print(&quot;Logits:&quot;, output.logits, end=&quot;\n\n&quot;)</p>
<p>predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
print(&quot;Predicts:\n&quot;, predictions)</p>
<hr>
<p>input IDs:
 tensor([[ 1045,  1005,  2310,  2042,  3403,  2005,  1037, 17662, 12172,  2607,
          2026,  2878,  2166,  1012]])</p>
<p>Logits: tensor([[-2.7276,  2.8789]], grad_fn=<AddmmBackward0>)</p>
<p>Predicts:
 tensor([[4.0195e-02, 9.5981e-01],
        [9.9946e-01, 5.4418e-04]], grad_fn=<SoftmaxBackward0>)</p>
<pre><code>
### 다중 데이터셋 학습
```python
batched_ids = [
    [200, 200, 200],
    [200, 200, tokenizer.pad_token_id],
]

attention_mask = [
    [1, 1, 1],
    [1, 1, 0],
]

outputs = model(torch.tensor(batched_ids), attention_mask=torch.tensor(attention_mask))
print(outputs.logits)
-------------------------------------------------
tensor([[ 1.5694, -1.3895],
        [ 0.5803, -0.4125]], grad_fn=&lt;AddmmBackward0&gt;)</code></pre><h2 id="데이터-로드-1">데이터 로드</h2>
<pre><code class="language-python">from datasets import load_dataset
from transformers import AutoTokenizer, DataCollatorWithPadding

raw_datasets = load_dataset(&quot;glue&quot;, &quot;mrpc&quot;) # 데이터셋 로딩
checkpoint = &quot;bert-base-uncased&quot;            # 불러올 모델명
tokenizer = AutoTokenizer.from_pretrained(checkpoint)   # 모델 토큰화 로딩</code></pre>
<pre><code class="language-python">raw_datasets[&#39;train&#39;].features
-------------------------------------------------------
{&#39;sentence1&#39;: Value(dtype=&#39;string&#39;, id=None),
 &#39;sentence2&#39;: Value(dtype=&#39;string&#39;, id=None),
 &#39;label&#39;: ClassLabel(names=[&#39;not_equivalent&#39;, &#39;equivalent&#39;], id=None),
 &#39;idx&#39;: Value(dtype=&#39;int32&#39;, id=None)}</code></pre>
<h3 id="전처리-1">전처리</h3>
<pre><code class="language-python">def tokenize_function(example):
    return tokenizer(example[&quot;sentence1&quot;], example[&quot;sentence2&quot;], truncation=True)

tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)  # 토큰화

data_collator = DataCollatorWithPadding(tokenizer=tokenizer)    # 토큰화 자동패딩

tokenized_datasets = tokenized_datasets.remove_columns([&quot;sentence1&quot;, &quot;sentence2&quot;, &quot;idx&quot;])   # 불필요칼럼제거
tokenized_datasets = tokenized_datasets.rename_column(&quot;label&quot;, &quot;labels&quot;)    # 칼럼명 수정
tokenized_datasets.set_format(&quot;torch&quot;)    # 형식 &quot;torch&quot;로 변환
tokenized_datasets[&quot;train&quot;].column_names
-------------------------------------------------------------
[&#39;labels&#39;, &#39;input_ids&#39;, &#39;token_type_ids&#39;, &#39;attention_mask&#39;]</code></pre>
<h3 id="데이터-로더-생성">데이터 로더 생성</h3>
<pre><code class="language-python">from torch.utils.data import DataLoader

train_dataloader = DataLoader(
    tokenized_datasets[&quot;train&quot;], shuffle=True, batch_size=8, collate_fn=data_collator
)
test_dataloader = DataLoader(
    tokenized_datasets[&quot;validation&quot;], batch_size=8, collate_fn=data_collator
)

for batch in train_dataloader:
    break
{k: v.shape for k, v in batch.items()}
-------------------------------------------------------
{&#39;labels&#39;: torch.Size([8]),
 &#39;input_ids&#39;: torch.Size([8, 66]),
 &#39;token_type_ids&#39;: torch.Size([8, 66]),
 &#39;attention_mask&#39;: torch.Size([8, 66])}</code></pre>
<h2 id="모델링">모델링</h2>
<ul>
<li>True or False 이므로 num_labels=2<pre><code class="language-python">from transformers import AutoModelForSequenceClassification
</code></pre>
</li>
</ul>
<p>model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)</p>
<pre><code>### 스케쥴러
```python
from transformers import get_scheduler

num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)
lr_scheduler = get_scheduler(
    &quot;linear&quot;,
    optimizer=optimizer,
    num_warmup_steps=0,
    num_training_steps=num_training_steps
)
print(num_training_steps)
-----------------------------------------------
1377</code></pre><h3 id="cuda-설정">CUDA 설정</h3>
<ul>
<li>실습환경: 코랩<pre><code class="language-python">import torch
</code></pre>
</li>
</ul>
<p>is_cuda = &quot;cuda&quot; if torch.cuda.is_available() else &quot;cpu&quot;
device = torch.device(is_cuda)
model.to(device)
device</p>
<hr>
<p>device(type=&#39;cuda&#39;)</p>
<pre><code>
## 모델 학습
```python
from tqdm import tqdm

progress_bar = tqdm(range(num_training_steps))

model.train()
for epoch in range(num_epochs):
    for batch in train_dataloader:
        batch = {k: v.to(device) for k, v in batch.items()}
        outputs = model(**batch)
        loss = outputs.loss
        loss.backward()

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(1)
-----------------------------------------------------------------
100%|██████████| 1377/1377 [01:06&lt;00:00, 21.74it/s]</code></pre><h2 id="모델-평가">모델 평가</h2>
<pre><code class="language-python">from datasets import load_metric

metric = load_metric(&quot;glue&quot;, &quot;mrpc&quot;)
model.eval()
for batch in test_dataloader:
    batch = {k: v.to(device) for k, v in batch.items()}
    with torch.no_grad():
        outputs = model(**batch)

    logits = outputs.logits
    predictions = torch.argmax(logits, dim=-1)
    metric.add_batch(predictions=predictions, references=batch[&quot;labels&quot;])

metric.compute()
-----------------------------------------------------------
{&#39;accuracy&#39;: 0.8578431372549019, &#39;f1&#39;: 0.8989547038327526}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Hugging Face: Tasks]]></title>
            <link>https://velog.io/@insung_na/Hugging-Face-Tasks</link>
            <guid>https://velog.io/@insung_na/Hugging-Face-Tasks</guid>
            <pubDate>Mon, 08 May 2023 05:50:47 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다</p>
</blockquote>
<h1 id="huggingface">HuggingFace</h1>
<ul>
<li><a href="https://github.com/huggingface/transformers">https://github.com/huggingface/transformers</a></li>
<li>NLP분야의 스타트업</li>
<li>다양한 트랜스포머 모델(transformer.models)과 학습 스크립트(transformer.Trainer)를 제공하는 모듈</li>
<li>개발자가 자연어 처리 애플리케이션과 서비스를 빠르고 효율적으로 구축하고 배포할 수 있도록 함</li>
</ul>
<h2 id="pipeline">Pipeline</h2>
<ul>
<li>특정 작업을 수행하거나 특정 목표를 달성하기 위해 선형 또는 순차적 방식으로 연결된 일련의 프로세스</li>
<li>preprocess -&gt; 모델 -&gt; post process 생성</li>
<li>최초 실행시 모델 다운로드</li>
<li>pipeline(task, model, config, tokenizer, ...)<ul>
<li>task : 내가 원하는 작업(ex. &#39;sentiment-analysis&#39;, &#39;zero-shot-classification&#39;, ...)</li>
<li>model : 사용모델 (Default=task에 적절한 모델 할당)<pre><code>!pip install transformers
!pip install datasets
</code></pre></li>
</ul>
</li>
</ul>
<p>from transformers import pipeline</p>
<pre><code>## 감정분석
- 해당 문장이 긍정인지 부정인지 판별
```python
classifier = pipeline(&#39;sentiment-analysis&#39;)
classifier.model
classifier(&quot;I&#39;ve been waiting for a HuggingFace course my whole life.&quot;)
-------------------------------------------------------
[{&#39;label&#39;: &#39;POSITIVE&#39;, &#39;score&#39;: 0.9598049521446228}]</code></pre><h2 id="zero-shot-분류">Zero-shot 분류</h2>
<ul>
<li>Zero-shot-Learning : 모델이 이전에 본 적이 없는 개체나 개념을 인식하도록 훈련되는 기계 학습</li>
<li>Zero-shot-Classification : 해당 클래스에 대한 명시적인 훈련 없이 이전에 본 적이 없는 클래스 분류<pre><code class="language-python">classifier = pipeline(&quot;zero-shot-classification&quot;)   # Default Model = facebook/bart-large-mnli
classifier(
  &quot;This is a course about the transformers library&quot;,          # 문제
  candidate_labels = [&quot;education&quot;, &quot;politics&quot;, &quot;business&quot;],    # 정답보기
)</code></pre>
</li>
</ul>
<hr>
<p>{&#39;sequence&#39;: &#39;This is a course about the transformers library&#39;,
 &#39;labels&#39;: [&#39;education&#39;, &#39;business&#39;, &#39;politics&#39;],
 &#39;scores&#39;: [0.9192408919334412, 0.060778193175792694, 0.01998087950050831]}</p>
<pre><code>```python
classifier(
    &quot;This is a course about the transformers library&quot;,          # 문제
    candidate_labels = [&quot;course&quot;, &quot;library&quot;, &quot;game&quot;, &quot;This&quot;],    # 정답보기
)
----------------------------------------------------------------
{&#39;sequence&#39;: &#39;This is a course about the transformers library&#39;,
 &#39;labels&#39;: [&#39;course&#39;, &#39;library&#39;, &#39;This&#39;, &#39;game&#39;],
 &#39;scores&#39;: [0.732907235622406,
  0.19588284194469452,
  0.06776876002550125,
  0.003441136097535491]}</code></pre><h2 id="생성모델">생성모델</h2>
<ul>
<li>문제로 주어진 문장을 기반으로 그 다음 문장을 생성<pre><code class="language-python">generator = pipeline(&quot;text-generation&quot;)    # Default Model = gpt2
generator(&quot;In this course, we will teach you how to &quot;)</code></pre>
</li>
</ul>
<hr>
<p>[{&#39;generated_text&#39;: &#39;In this course, we will teach you how to \xa0create simple, beautiful, dynamic design diagrams, and how to create them with a variety of basic software tools. We will make use of our favorite tools like Sketch, L.A. Sketch&#39;}]</p>
<pre><code>### 세부조정
- num_return_sequences : 문장갯수
- max_length : 문장 길이
```python
generator(&quot;In this course, we will teach you how to &quot;, num_return_sequences=5, max_length=20)
---------------------------------------------------------------------
[{&#39;generated_text&#39;: &#39;In this course, we will teach you how to \xa0communicate with fellow listeners.\n2&#39;},
 {&#39;generated_text&#39;: &#39;In this course, we will teach you how to \xa0install the new web application for PHP 5&#39;},
 {&#39;generated_text&#39;: &#39;In this course, we will teach you how to \xa0understand the most basic \xa0of&#39;},
 {&#39;generated_text&#39;: &#39;In this course, we will teach you how to \xa0compete with the enemy. By taking&#39;},
 {&#39;generated_text&#39;: &#39;In this course, we will teach you how to \xa0explicitly use the\xa0cargo&#39;}]</code></pre><pre><code class="language-python">list_ = [&quot;In this course, we will teach you how to &quot;, &quot;This is a course about the transformers library&quot;]

for sentence in list_:
    print(generator(sentence, num_return_sequences=1, max_length=20))
--------------------------------------------------------------------------------------------
[{&#39;generated_text&#39;: &#39;In this course, we will teach you how to \xa0help others get involved in social media.&#39;}]
[{&#39;generated_text&#39;: &#39;This is a course about the transformers library.\n\nThis is part of the Meej&#39;}]</code></pre>
<h3 id="huggingface-사이트에-있는-모델사용">HuggingFace 사이트에 있는 모델사용</h3>
<ul>
<li>사용할 Task, Libraries 등 또는 Filter을 설정하고 원하는 모델을 찾기</li>
<li>모델 포스팅 글에서 사용법 확인하고 적용하기
<img src="https://user-images.githubusercontent.com/118172599/236658858-5cf4ef58-7005-42f8-8a0e-9682d1ff3d3d.png" alt="image">
<img src="https://user-images.githubusercontent.com/118172599/236659078-0704a318-e5eb-4799-ae90-3367ab3f7ae0.png" alt="image">
<img src="https://user-images.githubusercontent.com/118172599/236659099-61f98aea-1231-4b11-8a31-59160d0ae7d4.png" alt="image"></li>
</ul>
<pre><code class="language-python">generator = pipeline(&quot;text-generation&quot;, model=&quot;huggingtweets/dril&quot;)
generator(&quot;My dream is &quot;, num_return_sequences=5)
-------------------------------------------------------------------------------------------------
[{&#39;generated_text&#39;: &#39;My dream is ive invented. ive invented what is basically the most popular movie ever made and I need over $10,000 to make it go away. Thank you.&#39;},
 {&#39;generated_text&#39;: &#39;My dream is ive been to be the next &quot;Powerball jack&quot;&#39;},
 {&#39;generated_text&#39;: &#39;My dream is ive come to the realization that i have the power of unlimited consciousness. I would get a brain if i could simply convince all the guys in the house where i live to stop smoking pot that i can still tell the difference between a man and a woman and I would become completely Normal&#39;},
 {&#39;generated_text&#39;: &quot;My dream is ive gotten over 1000 jobs. That&#39;s what my self believes. Ive fucked over 1000 people&quot;},
 {&#39;generated_text&#39;: &#39;My dream is \ue001� That the \ue003� of humanity \ue006nh is To See The \ue006nht That Is As The \ue001� Of My Dream.&#39;}]</code></pre>
<ul>
<li>사이트에서도 실행가능
<img src="https://user-images.githubusercontent.com/118172599/236659251-a18e9e83-462c-4deb-ae82-124ca4e85ddf.png" alt="image"></li>
</ul>
<h2 id="mask-filling">Mask Filling</h2>
<ul>
<li><code>&lt;mask&gt;</code>에 들어갈 단어 맞추기<pre><code class="language-python">unmasker = pipeline(&quot;fill-mask&quot;)    # Default Model = distilroberta-base
unmasker(&quot;This coures will teach you all about &lt;mask&gt; models&quot;, top_k=5)</code></pre>
</li>
</ul>
<hr>
<p>[{&#39;score&#39;: 0.040895454585552216,
  &#39;token&#39;: 745,
  &#39;token_str&#39;: &#39; building&#39;,
  &#39;sequence&#39;: &#39;This coures will teach you all about building models&#39;},
 {&#39;score&#39;: 0.03127061203122139,
  &#39;token&#39;: 30412,
  &#39;token_str&#39;: &#39; mathematical&#39;,
  &#39;sequence&#39;: &#39;This coures will teach you all about mathematical models&#39;},
 {&#39;score&#39;: 0.025371771305799484,
  &#39;token&#39;: 774,
  &#39;token_str&#39;: &#39; role&#39;,
  &#39;sequence&#39;: &#39;This coures will teach you all about role models&#39;},
 {&#39;score&#39;: 0.01844116672873497,
  &#39;token&#39;: 265,
  &#39;token_str&#39;: &#39; business&#39;,
  &#39;sequence&#39;: &#39;This coures will teach you all about business models&#39;},
 {&#39;score&#39;: 0.015211271122097969,
  &#39;token&#39;: 3034,
  &#39;token_str&#39;: &#39; computer&#39;,
  &#39;sequence&#39;: &#39;This coures will teach you all about computer models&#39;}]</p>
<pre><code>## 그룹 엔티티
- 학습되지 않은 단어의 클래스 찾기
- Sylvain: Person, Hugging Face: Organization, Brooklyn: Location
```python
ner = pipeline(&quot;ner&quot;, grouped_entities=True) # Default Model = dbmdz/bert-large-cased-finetuned-conll03-english
ner(&quot;My name is Sylvain and I work at Hugging Face in Brooklyn.&quot;)
--------------------------------------------------------------------------------
[{&#39;entity_group&#39;: &#39;PER&#39;,
  &#39;score&#39;: 0.9981694,
  &#39;word&#39;: &#39;Sylvain&#39;,
  &#39;start&#39;: 11,
  &#39;end&#39;: 18},
 {&#39;entity_group&#39;: &#39;ORG&#39;,
  &#39;score&#39;: 0.9796019,
  &#39;word&#39;: &#39;Hugging Face&#39;,
  &#39;start&#39;: 33,
  &#39;end&#39;: 45},
 {&#39;entity_group&#39;: &#39;LOC&#39;,
  &#39;score&#39;: 0.9932106,
  &#39;word&#39;: &#39;Brooklyn&#39;,
  &#39;start&#39;: 49,
  &#39;end&#39;: 57}]</code></pre><h2 id="qna">QnA</h2>
<ul>
<li>Query text : 나는 집에 들어갔다. 그런데 배고파서 햄버거를 먹었다</li>
<li>Question : 누가 햄버거를 먹었나?</li>
<li>Answer : 나<pre><code class="language-python">question_answer = pipeline(&quot;question-answering&quot;) # Default Model = distilbert-base-cased-distilled-squad
question_answer(
  question=&quot;what&#39;s my name?&quot;,
  context=&quot;My name is Sylvain and I work at Hugging Face in Brooklyn.&quot;,
)</code></pre>
</li>
</ul>
<hr>
<p>{&#39;score&#39;: 0.9988495111465454, &#39;start&#39;: 11, &#39;end&#39;: 18, &#39;answer&#39;: &#39;Sylvain&#39;}</p>
<pre><code>## summary
- 한계점 : 긴 문장에서 일부분을 추출해서 요약
```python
summarizer = pipeline(&quot;summarization&quot;) # Default Model = sshleifer/distilbart-cnn-12-6
summarizer(
    &quot;&quot;&quot;
    National Commercial Bank (NCB), 
    Saudi Arabia’s largest lender by assets, 
    agreed to buy rival Samba Financial Group for $15 billion in the biggest banking takeover this year.
    NCB will pay 28.45 riyals ($7.58) for each Samba share, according to a statement on Sunday, 
    valuing it at about 55.7 billion riyals. NCB will offer 0.739 new shares for each Samba share, 
    at the lower end of the 0.736-0.787 ratio the banks set when they signed an initial framework 
    agreement in June.The offer is a 3.5% premium to Samba’s Oct. 8 closing price of 27.50 riyals and 
    about 24% higher than the level the shares traded at before the talks were made public. Bloomberg 
    News first reported the merger discussions.The new bank will have total assets of more than $220 billion, 
    creating the Gulf region’s third-largest lender. The entity’s $46 billion market capitalization nearly matches 
    that of Qatar National Bank QPSC, which is still the Middle East’s biggest lender with about $268 billion of 
    assets.
    &quot;&quot;&quot;
)
---------------------------------------------------------------------------------------------------------------------------
[{&#39;summary_text&#39;: &quot; Saudi Arabia&#39;s largest lender National Commercial Bank agrees to buy rival Samba Financial Group for $15 billion . NCB will pay 28.45 riyals ($7.58) for each Samba share, valuing it at about 55.7 billion . The new bank will have total assets of more than $220 billion, creating the Gulf region’s third-largest lender .&quot;}]</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[GPT&BERT]]></title>
            <link>https://velog.io/@insung_na/GPTBERT</link>
            <guid>https://velog.io/@insung_na/GPTBERT</guid>
            <pubDate>Sat, 06 May 2023 14:00:04 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다</p>
</blockquote>
<h1 id="few-zero-short-learning--transfer-learning">Few, Zero short learning &amp; Transfer learning</h1>
<h2 id="자연어-데이터의-불완전성">자연어 데이터의 불완전성</h2>
<ul>
<li>특정 자연어 Task를 해결하기 위해서는 다양한 Label이 요구됨. 특히, format도 매우 복잡함</li>
<li>input data는 굉장히 많은데 label이 적음</li>
<li>수많은 텍스트 데이터들이 레이블이 없이 존재함(ex. 의료 데이터셋)</li>
</ul>
<h3 id="pre-training">pre-training</h3>
<ul>
<li>레이블이 지정되지 않은 데이터 세트에서 훈련하여 심층 신경망의 매개변수를 초기화하는 기술</li>
</ul>
<h3 id="fine-tunning">Fine tunning</h3>
<ul>
<li>사전 학습된 모델을 새로운 문제에 적용하기 위해 일부 가중치를 조절하는 학습 과정</li>
</ul>
<h3 id="transfer-learning">Transfer learning</h3>
<ul>
<li>일본어-영어, 한국-일본어 간의 번역 데이터는 많으나 한국-영어 데이터는 적을 경우</li>
<li>영어-&gt;일본어 데이터셋에서 문맥 벡터를 잘 뽑아내는 모델을 학습한 후 영어-&gt;한국어 데이터셋에 적용</li>
</ul>
<h2 id="few-shot-zero-shot-learning">Few shot, zero shot learning</h2>
<ul>
<li>Query image :  추론할 입력 데이터</li>
<li>Training set : 모델이 학습하는 데이터 셋</li>
<li>Support set : 추론해야 하는 셋<ul>
<li>support set의 종류 수를 way, 사진 수를 shot으로 표현함
<img src="https://velog.velcdn.com/images/insung_na/post/b18f1e36-f36f-4b6e-9702-9ca73f8683fa/image.png" alt=""></li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/insung_na/post/30436f33-adec-48fe-8508-b74a81073378/image.png" alt=""></p>
<h1 id="gpt-1">GPT-1</h1>
<ul>
<li>Gpt1, Bert, Gpt2, Gpt3 순으로 연구됨</li>
<li>Generative Pre-Training</li>
<li>비지도학습 기반의 pre-training과 지도학습 기반의 fine-tunning을 결합한 semi-supervised learning</li>
<li>그래서 다양한 자연어 task에서 fine-tunning만으로도 좋은 성능을 보이는 범용적인 자연어 representation을 학습하는 것</li>
<li>2 stage로 구성되어 있으며 <strong>transformer의 decoder 구조</strong>를 사용함</li>
<li>기존 RNN 대비 좋은 성능을 보였으며 일반화 성능 확인</li>
</ul>
<h2 id="stage1-pre-training">Stage1: pre-training</h2>
<ul>
<li>문장 $u$가 구성되어 있고 서브단어 $u_i$로 각 확률들을 계산</li>
<li>$h_0$=초기화, $W_e$=워드 임베딩, $U$=단어(쿼리), $W_p$=포지션 임베딩
<img src="https://velog.velcdn.com/images/insung_na/post/56bcbf09-3d56-4f25-abde-77bbb71a40e9/image.png" alt=""></li>
</ul>
<h2 id="stage2-fine-tuning">Stage2: fine-tuning</h2>
<ul>
<li>$x$=문장의 토큰들, $y$=label
<img src="https://velog.velcdn.com/images/insung_na/post/2ca37570-00ae-47bb-a24c-4ea9460b3458/image.png" alt=""></li>
</ul>
<h2 id="task-specific-input-transformations">Task-specific input transformations</h2>
<ul>
<li>기존: Task specific 구조에 기반한 학습, 구조에 종속되기 때문에 task가 변할 때 마다 많은 커스터마이즈를 요구</li>
<li>GPT-1 : Pre-training model 적용될 수 있도록 input구조를 convert
<img src="https://velog.velcdn.com/images/insung_na/post/64bedd85-9979-4905-8276-334c64cdb050/image.png" alt=""></li>
</ul>
<h3 id="gpt-1의-성능">GPT-1의 성능</h3>
<ul>
<li><p>LM -&gt; 큰 데이터셋 에서는 좋은 결과 but 작은 데이터셋에서는 아님
<img src="https://velog.velcdn.com/images/insung_na/post/bcab9009-1dd7-49c5-97ce-92a5aefb9396/image.png" alt=""></p>
</li>
<li><p>Layer 가 증가함에 따라 정확도가 높아지는 것을 확인</p>
</li>
<li><p>LSTM과 비교하여 다양한 task에서 일반화 성능 확인
<img src="https://velog.velcdn.com/images/insung_na/post/18c26934-2a54-42c9-bd22-fb658f0401e3/image.png" alt=""></p>
</li>
</ul>
<h1 id="bert">BERT</h1>
<ul>
<li>Bidirectional Encoder Representations from Transformer</li>
<li>Wiki &amp; book data 와 같은 대용량 unlabeled data로 pre-training 시킨 후, 특정 task 에 transfer learning 을 함</li>
<li>GPT와의 차이? -&gt; unidirectional(GPT) vs bidirectional(BERT)</li>
<li>GPT와는 달리 새로운 네트워크를 붙이지 않고 fine-tunning 만을 진행함</li>
<li>GPT-1 : Unsupervised pre-training -&gt; BERT : Masked Language Model(MLM) &amp; Next sentence prediction</li>
<li>Next sentence prediction <ul>
<li>문장간 관계를 알아내기 위한 task, 두 문장이 실제 corpus 에서 이어져 있는지 아닌지 확인</li>
<li>50% 는 실제 이어져 있는 문장</li>
</ul>
</li>
<li>Pre-training 프로세스는 GPT-1과 같음</li>
</ul>
<h2 id="bert와-gpt">BERT와 GPT</h2>
<p><img src="https://velog.velcdn.com/images/insung_na/post/c8d900c9-349d-4d2e-9c16-10e6a23f2f72/image.png" alt=""></p>
<h2 id="mask-language-modelmlm">Mask Language Model(MLM)</h2>
<ul>
<li>[MASK] 비율 : 15%</li>
<li>Tokenization : Wordpiece</li>
<li>LM 의 left-to-right 와는 달리, [MASK] 를 추론하는 task 수행</li>
<li>Fine tunning 에는 사용되지 않음
<img src="https://velog.velcdn.com/images/insung_na/post/5947a3ec-9cba-4c17-a4e1-ba8f9208ae37/image.png" alt=""></li>
</ul>
<h3 id="mask-생성-과정">MASK 생성 과정</h3>
<ul>
<li>80% : token 을 [MASK]로 변환</li>
<li>10% : token 을 임의의 단어로 변경</li>
<li>10% : 원래의 단어 token 으로 둠</li>
</ul>
<p>Pre-trained 되는 transformer encode의 입장에서는 contextual representation 학습</p>
<h3 id="bert의-input">BERT의 input</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/9f915622-5994-4533-8538-fd360b6577c5/image.png" alt=""></p>
<h3 id="bert의-fine-tuning">BERT의 fine-tuning</h3>
<ul>
<li>Sequence-level classification <ul>
<li>[CLS] token 의 output 사용</li>
<li>CLS output 에 W matrix 를 곱해주고 softmax를 취해 준다.</li>
</ul>
</li>
<li>Span-level, token-level prediction
<img src="https://velog.velcdn.com/images/insung_na/post/40a4d5db-0249-4861-ada5-97ba3a7d0931/image.png" alt=""></li>
</ul>
<h2 id="bert의-성능">BERT의 성능</h2>
<h3 id="glue">GLUE</h3>
<ul>
<li>다양한 task를 모아놓아 종합적인 자연어 이해 능력 테스트가 가능한 벤치마크</li>
<li>BERT는 대부분의 task에 SOTA(State-of-the-art)</li>
<li>특히 데이터 크기가 작아도 fine-tunning 후에는 좋은 성능
<img src="https://velog.velcdn.com/images/insung_na/post/7e58ec07-df5c-4354-8642-8d053ff860f2/image.png" alt=""></li>
</ul>
<h3 id="squad">SQuAD</h3>
<ul>
<li>GLUE는 sequence classification </li>
<li>SQuAD 는 질문 과 지문이 주어지고, substring 인 정답 찾기</li>
<li>질문 A, 지문 B 지문에서 substring 찾기 문제</li>
<li>Start vector와 end vector의 dot product를 하여 찾기
<img src="https://velog.velcdn.com/images/insung_na/post/d9b371ad-fcc5-4a29-98b6-f28d6974762c/image.png" alt="">
<img src="https://velog.velcdn.com/images/insung_na/post/81f82e79-0be4-4500-a21b-299bbb58dbff/image.png" alt=""></li>
</ul>
<h3 id="swag">SWAG</h3>
<ul>
<li>Grounded common-sense inference</li>
<li>문장이 주어지고, 가장 잘 이어지는 문장 찾기</li>
<li>주어진 문장 A, 가능한 문장들 B
<img src="https://velog.velcdn.com/images/insung_na/post/f12d3716-fc0a-42e9-8264-fbc6e8c75efa/image.png" alt=""></li>
</ul>
<h3 id="conll-2003">CoNLL-2003</h3>
<ul>
<li>각각의 단어가 어떤 형식인지</li>
<li>Person, Organization, Location …</li>
<li>토큰마다 classifier 붙이기
<img src="https://velog.velcdn.com/images/insung_na/post/62515ca9-2603-4294-92e3-00709153d91a/image.png" alt=""></li>
</ul>
<h3 id="ablation-studies">Ablation studies</h3>
<ul>
<li><p>Pre-train 을 하나라도 제거하면 성능 감소가 일어남</p>
</li>
<li><p>No NSP -&gt; 자연어 추론 계열(NLI)에서 성능 감소 폭 큼</p>
</li>
<li><p>MLM 대신 LTR -&gt; 성능이 매우 감소함
<img src="https://velog.velcdn.com/images/insung_na/post/d3c181c1-8ce7-4862-9d0f-4bdfbd30f8fe/image.png" alt=""></p>
</li>
<li><p>모델 사이즈가 커질수록 성능 향상</p>
</li>
<li><p>MLM이 많은 training이 필요하지만 성능향상 확인
<img src="https://velog.velcdn.com/images/insung_na/post/b31e9a72-f41b-42cb-8cb7-6ed9a287dfb5/image.png" alt=""></p>
</li>
</ul>
<h1 id="gpt-2">GPT-2</h1>
<p><img src="https://velog.velcdn.com/images/insung_na/post/82e4e58e-0c5b-41a6-bd7f-91eb48dcf72f/image.png" alt=""></p>
<ul>
<li><p>Fine-tunning 없이도 우리는 가능하게 하고 싶다. </p>
</li>
<li><p>모델 자체는 GPT-1과 크게 차이 없음</p>
</li>
<li><p>Zero shot learning </p>
<ul>
<li>Model이 바로 downstream task에 적용함 (few shot: 몇 번 보고 적용함 )</li>
</ul>
</li>
<li><p>WebText 데이터을 구축</p>
<ul>
<li>이 대용량 데이터셋에 LM 모델을 학습했을 때 supervision 없이도 다양한 task 처리</li>
</ul>
</li>
<li><p>Byte pair Encoding을 활용 하여 Out of Vocabulary 문제 해결</p>
</li>
</ul>
<h2 id="zero-shot-적용방법">Zero shot 적용방법</h2>
<ul>
<li>문장의 긍/부정 -&gt; what do you think about this sentence ? 같은 질문 추가</li>
<li>문장 요약 -&gt; What is the summary of … ? 추가</li>
<li>번역 -&gt; what is translated sentence in Korean? 추가</li>
</ul>
<h2 id="byte-pair-encoding">Byte pair Encoding</h2>
<h3 id="word-piece-model-bert">Word Piece model (BERT)</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/3714398e-42f0-48c4-8dd1-03acc2697965/image.png" alt=""></p>
<ul>
<li>Jet은 자주 등장하지 않아서 J et 로 나눔</li>
<li>모든 단어 시작에는 _ </li>
</ul>
<h3 id="byte-pair-encodingbpe">Byte-pair encoding(BPE)</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/734d7b75-3b6d-4ac5-8c92-8380ca99b07c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/1f8ae267-8474-4c6e-99a4-19780f2c73bf/image.png" alt=""></p>
<h3 id="gpt-2의-성능">GPT-2의 성능</h3>
<ul>
<li>Zero shot 임에도 불구하고 8개중 7개에서 SOTA</li>
<li>특히, PTB,Wikitext-2 와 같은 적은 데이터셋에서 좋은 성능
<img src="https://velog.velcdn.com/images/insung_na/post/293be309-cac4-45d2-bb28-8a3024996ace/image.png" alt=""></li>
</ul>
<h1 id="gpt-3">GPT-3</h1>
<ul>
<li>GPT-2 대비 Self-attention layer를 굉장히 많이 쌓아 parameter 수를 대폭 늘림</li>
<li>GPT-2에서 사용하는 Zero shot learning framework의 확장</li>
</ul>
<h2 id="shot-learing">shot learing</h2>
<p><img src="https://velog.velcdn.com/images/insung_na/post/dd84aba1-2a9a-42b0-b144-ce66d78e5521/image.png" alt=""></p>
<h2 id="transformer">Transformer</h2>
<ul>
<li>Transformer : 예측 K값 이전의 모든 입력 데이터을 예측에 활용<ul>
<li>입력 데이터의 크기가 크면 계산량이 매우 많아짐</li>
</ul>
</li>
<li>Sparse Transformers : 입력 데이터의 일부분만 활용<ul>
<li>계산 효율성을 높이고, 불필요한 계산을 줄일 수 있음</li>
<li>GPT3가 strided와 fixed 사용
<img src="https://velog.velcdn.com/images/insung_na/post/194fc9e9-b676-4e92-8af2-8c926d1518db/image.png" alt=""></li>
</ul>
</li>
</ul>
<h1 id="전체-요약">전체 요약</h1>
<p><img src="https://velog.velcdn.com/images/insung_na/post/7041c887-72a2-4f38-b350-9cca123c2557/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Transformer 관련 연구]]></title>
            <link>https://velog.io/@insung_na/Transformer-%EA%B4%80%EB%A0%A8-%EC%97%B0%EA%B5%AC</link>
            <guid>https://velog.io/@insung_na/Transformer-%EA%B4%80%EB%A0%A8-%EC%97%B0%EA%B5%AC</guid>
            <pubDate>Sat, 06 May 2023 08:31:19 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다</p>
</blockquote>
<h1 id="관련연구-computer-vision">관련연구: Computer Vision</h1>
<h2 id="visual-transformervit">Visual Transformer(ViT)</h2>
<ul>
<li>AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE, ICLR 2021</li>
<li>Vit는 Transformer를 사용하여 이미지 인식에 적용한 연구</li>
<li>컴퓨터 비전 분야에서는 Convolution 연산을 이용한 방법이 아직까지 대중적</li>
</ul>
<h3 id="inductive-bias귀납편향">Inductive bias(귀납편향)</h3>
<ul>
<li>데이터가 공간적으로 변화해도 불변하는 것</li>
<li>ViT는 귀납편향없이 성능향상을 보임
<img src="https://velog.velcdn.com/images/insung_na/post/98267214-63a6-4853-b716-ca7610ea5571/image.png" alt=""></li>
</ul>
<h3 id="key-idea">Key idea</h3>
<ul>
<li>positional encoding에서 이미지를 분할하고 분할 대상을 각각의 토큰으로 판단하여 수행
<img src="https://velog.velcdn.com/images/insung_na/post/09e336f7-e49e-49ee-91d7-d762d4113ef7/image.png" alt=""></li>
</ul>
<h3 id="vit-forwarding">Vit Forwarding</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/a53b189b-4ea3-4f05-a562-10d9e717adcc/image.png" alt=""></p>
<h3 id="타모델과-비교">타모델과 비교</h3>
<ul>
<li>JFT300M dataset으로 pretrain 시키고 테스트<ul>
<li>이미지 약 3억개 사용(용량 : 18PB)</li>
</ul>
</li>
<li>자동으로 low-level의 특성을 학습하는 embedding filter</li>
<li>Positional embdding 이후의 이미지와 패치와의 유사도</li>
<li>Attention이 얼마나 먼 패치를 할당하고 있는지 (receptive field와 유사)
<img src="https://velog.velcdn.com/images/insung_na/post/23974853-3461-4474-8ad4-48fc25f9f95f/image.png" alt=""></li>
</ul>
<p><img src="https://velog.velcdn.com/images/insung_na/post/7930004e-8dda-4237-a106-c56a4120fbae/image.png" alt=""></p>
<h2 id="detr">DETR</h2>
<ul>
<li>End-to-End Object Detection with Transformers, ECCV 2020</li>
<li>Object Detection 문제를 direct set prediction으로 푸는 모델</li>
<li>기존의 Detection 에서 생기는 non-maximum suppression (NMS) 문제를 해결</li>
<li>Transformer 기반의 prediction</li>
</ul>
<h3 id="nms-problem">NMS Problem</h3>
<ul>
<li>기존 방법은 non-maximum suppression (NMS) 문제를 해결하기 위해 post processing 필요</li>
<li>DETR은 transformer 를 활용한 end-to-end 방식</li>
</ul>
<p><img src="https://velog.velcdn.com/images/insung_na/post/b6015c46-a9ff-4358-95a0-393914d77465/image.png" alt=""></p>
<h3 id="detr-모델-절차">DETR 모델 절차</h3>
<ul>
<li>CNN을 입력받아서 positional Encoding 수행</li>
<li>Encoder을 거치고 Decoder 수행</li>
<li>Decoder에서 대상에 대해서 하나의 Bounding box가 할당되도록 birpartite mathing 사용
<img src="https://velog.velcdn.com/images/insung_na/post/118fec88-3b5e-4852-a81f-2e4149ffae4a/image.png" alt=""></li>
</ul>
<h3 id="bipartite-matching">bipartite matching</h3>
<ul>
<li>NMS 해결 -&gt; 각각의 실제 레이블에 대해서 하나만 할당</li>
<li>오브젝트가 없다면 확률을 계산하지 않고</li>
<li>오브젝트가 있다면 바운딩 박스의 확률을 계산하고 최적의 박스를 찾는다
<img src="https://velog.velcdn.com/images/insung_na/post/4e5d934f-3032-4142-86f2-869d1f62715b/image.png" alt="">
<img src="https://velog.velcdn.com/images/insung_na/post/8dd6ffee-d2b1-4115-9559-f5043055124e/image.png" alt=""></li>
</ul>
<h3 id="python-code">Python Code</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/6611efb9-bf63-4bab-b564-310dcda2f274/image.png" alt=""></p>
<hr>
<h1 id="관련연구-시계열-데이터">관련연구: 시계열 데이터</h1>
<h2 id="bets">BETS</h2>
<ul>
<li>Informer: Beyond Efficient Transformer for Long Sequence TimeSeriesForecasting (AAAI&#39;21 Best Paper)</li>
<li>기존의 시계열 데이터 처리는 LSTM을 많이 사용</li>
<li>BETS는 일반적으로 훨씬 긴 시계열을 예측하는 시계열 데이터</li>
<li>Transformer 의 attention layer 는 matrix 연산임 -&gt; 계산인 size의 제곱만큼 증가</li>
</ul>
<p><img src="https://velog.velcdn.com/images/insung_na/post/fd3606cc-d143-42e6-aa0a-7862014a5de5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/0f768f82-c363-4392-840a-8cf2c27bd903/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/84dcec53-675e-42b0-868c-fc07184d1598/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Transformer]]></title>
            <link>https://velog.io/@insung_na/Transformer</link>
            <guid>https://velog.io/@insung_na/Transformer</guid>
            <pubDate>Sat, 06 May 2023 07:18:30 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다</p>
</blockquote>
<h1 id="transformer">Transformer</h1>
<h2 id="transformer-architecture">Transformer Architecture</h2>
<h3 id="positional-encoding">Positional Encoding</h3>
<ul>
<li>transformer는 병렬 처리이므로 성능이 향상되었으나 RNN에서 가능했던 순서처리가 불가능해짐</li>
<li>이를 해결하기 위해 positional encoding 사용</li>
<li>각 토큰의 입력 임베딩에 위치 인코딩을 추가함으로써 Transformer 모델은 병렬 처리 구조에도 불구하고 토큰의 순차적 순서를 유지할 수 있게 됨</li>
</ul>
<h3 id="multi-head-attention">Multi head attention</h3>
<ul>
<li>Self-Attention 메커니즘을 이용한 자연어 처리 향상 모듈</li>
<li>입력벡터로 query, key, value 벡터를 받음</li>
<li>이를 활용하여 attention score를 계산하고 단어별 중요도를 결정할 수 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/insung_na/post/128fc534-3132-489b-9c2d-8e34a637e70b/image.png" alt=""></p>
<h3 id="성능향상을-위한-기술">성능향상을 위한 기술</h3>
<ul>
<li>Skip Connection<ul>
<li>한 계층의 출력을 다른 계층의 출력에 직접 추가하는 연결</li>
<li>Vanishing Gradient를 완화하기 위해 사용한 방법</li>
</ul>
</li>
<li>Layer Normalization<ul>
<li>각 계층의 출력 정규화</li>
<li>입력 변동의 영향을 줄이고 네트워크의 전반적인 안정성과 성능 향상</li>
</ul>
</li>
</ul>
<h3 id="기존-모델과-성능비교">기존 모델과 성능비교</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/ec24bcca-2ffd-45de-b618-599af1d0f11b/image.png" alt=""></p>
<h3 id="요약">요약</h3>
<ul>
<li>기계번역 task에서 기존의 연구들 보다 성능적으로 우수</li>
<li>병렬적으로 처리가 가능한 모델 -&gt; time complexity 감소</li>
<li>이후에 사용되는 Bert, GPT 모델에서 일반화에 강점이 있다는 것이 확인</li>
</ul>
<h1 id="positional-encoding-1">Positional Encoding</h1>
<h2 id="필요한-이유">필요한 이유</h2>
<ul>
<li>기존의 RNN 기반의 방법 경우, context 벡터를 추출해서 사용함</li>
<li>이러한 추출을 하기 위해서는 문장의 단어들을 순차적으로 처리해야 했음</li>
<li>디코더도 마찬가지로 순차적으로 처리되었고 문장의 순서를 고려하게 됨</li>
<li>반면 Transformer 의 입력 Q 의 경우 행렬 연산을 통해 입력 벡터로 변환되어 Multi-head attention 모듈에 들어감</li>
<li>문장의 순서에 대한 정보를 넣어줄 필요성이 생김
<img src="https://velog.velcdn.com/images/insung_na/post/3f4f3de9-7da4-4a28-9114-dfd886b79884/image.png" alt=""></li>
</ul>
<p><img src="https://velog.velcdn.com/images/insung_na/post/368e95c8-8de2-4b9c-a873-17ba17e47330/image.png" alt=""></p>
<h2 id="어떻게-부여해야-하는가">어떻게 부여해야 하는가</h2>
<ul>
<li>단어 순서대로 숫자 카운팅 -&gt; 숫자가 너무 빨리 커져서 weight 학습이 어려우므로 X</li>
<li>카운팅 후 정규화 -&gt; weight 학습은 안정적이지만, 단어가 추가되면 같은 값 할당 불가능하므로 X</li>
<li>단어 순서대로 벡터표현 -&gt; 단어 순서끼리의 거리가 달라지므로 X</li>
<li>Sinusodial Encoding 사용<ul>
<li>i=depth, p=position</li>
<li>삼각함수 sin, cos 사용</li>
<li>rotaion matrix로 인해 적절한 상대거리를 얻게 됨
<img src="https://velog.velcdn.com/images/insung_na/post/78a2c6ab-5434-4445-8186-61198270ce99/image.png" alt="">
<img src="https://velog.velcdn.com/images/insung_na/post/e1234a82-833b-493b-9062-3dc8aa1d313b/image.png" alt="">Reference : <a href="https://skyjwoo.tistory.com/entry/positional-encoding%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80">skyjwoo의 position_encoding 포스팅</a></li>
</ul>
</li>
</ul>
<h3 id="python-code">Python Code</h3>
<pre><code class="language-python">def positional_encoding(max_position, d_model, min_freq=1e-4):
    position = np.arange(max_position)
    freqs = min_freq**(2*(np.arange(d_model)//2)/d_model)
    pos_enc = position.reshape(-1,1)*freqs.reshape(1,-1)
    pos_enc[:,::2] = np.cos(pos_enc[:, ::2])    # 짝수만 cos
    pos_enc[:, 1::2] = np.sin(pos_enc[:, 1::2]) # 홀수만 sin
    return pos_enc</code></pre>
<h1 id="multi-head-self-attention">Multi-head Self-attention</h1>
<h2 id="설명">설명</h2>
<ul>
<li><p>Query, Key, Value attention을 기반으로 Scaled Dot-pordict attention을 사용함
<img src="https://velog.velcdn.com/images/insung_na/post/8327bce2-22db-4211-9bbf-49e06852dc59/image.png" alt=""></p>
</li>
<li><p>기존의 attention 기법의 경우 Key와 Query만 존재</p>
</li>
<li><p>그러나 Transformer의 attention의 경우 Value까지 존재</p>
</li>
<li><p>문장을 이해할 때 단어들은 서로 영향을 끼치며 그 강도는 다르다</p>
</li>
<li><p>단어에 대한 벡터(Q)는 주어진 단어들에 대해서 유사한 정도(K)만큼 고려하고 각 주어진 단어들은 V만큼의 중요도를 갖는다</p>
</li>
</ul>
<h3 id="attention">Attention</h3>
<h4 id="k번째-단어만-고려하여-q-v-k-계산">k번째 단어만 고려하여 Q, V, K 계산</h4>
<p><img src="https://velog.velcdn.com/images/insung_na/post/94d6c036-faf3-4af0-97ee-f89239e9bd0c/image.png" alt=""></p>
<h4 id="i-love-you라는-문장으로-예시를-들면-input-linear-embedding을-통해-각-단어에-대한-qkv-행렬로-변환한다">&quot;I love you&quot;라는 문장으로 예시를 들면 input linear embedding을 통해 각 단어에 대한 Q,K,V 행렬로 변환한다</h4>
<p><img src="https://velog.velcdn.com/images/insung_na/post/bf2327fe-1e19-49c5-a7a3-8908e0b3e98a/image.png" alt=""></p>
<h4 id="softmax을-q-k에-대해-적용한다">softmax을 Q, K에 대해 적용한다</h4>
<ul>
<li>Query 로 단어를 주었을 때</li>
<li>이 단어와 유사한 Key 값을 더욱더 attention 을 주고</li>
<li>이 key 값의 중요도에 따라서 Value 값을 준다. 
<img src="https://velog.velcdn.com/images/insung_na/post/bfa4c5f7-ea05-44fc-b6ab-344222a2f9d2/image.png" alt=""></li>
</ul>
<h4 id="softmaxqk결과에-v를-곱해서-attention--획득">softmax(Q,K)결과에 V를 곱해서 Attention  획득</h4>
<ul>
<li>Attention 매트릭스가 Query의 차원수와 동일해짐</li>
<li>계속해서 같은 차원으로 Self-attention 수행이 가능하게 된다
<img src="https://velog.velcdn.com/images/insung_na/post/c79157e7-adc2-4d1e-be81-7aa28c87cd92/image.png" alt=""></li>
</ul>
<h3 id="mask-matrix">Mask Matrix</h3>
<ul>
<li><p>$QK^T$에 mask값으로 0에 가까운 값을 주어서 특정 단어는 무시할 수 있도록 함
<img src="https://velog.velcdn.com/images/insung_na/post/75b7794a-c125-4afe-91c0-52d4532f80ae/image.png" alt=""></p>
</li>
<li><p>처음 쿼리의 차원수 head의 개수만큼 나눠주기 때문에 최종적으로 입력의 차원수와 같게 된다
<img src="https://velog.velcdn.com/images/insung_na/post/f2963c40-2dcf-4e5e-8283-7837e1a8add7/image.png" alt=""></p>
</li>
</ul>
<h3 id="python-code-1">Python Code</h3>
<ul>
<li>reference : <a href="https://github.com/ndb796/Deep-Learning-Paper-Review-and-Practice/blob/master/code_practices/Attention_is_All_You_Need_Tutorial_(German_English).ipynb">참조한 깃허브</a><pre><code class="language-python">import torch
import torch.nn as nn
</code></pre>
</li>
</ul>
<p>class MultiHeadAttentionLayer(nn.Module):
    def <strong>init</strong>(self, hidden_dim, n_heads, dropout_ratio, device):
        super().<strong>init</strong>()</p>
<pre><code>    assert hidden_dim % n_heads == 0

    self.hidden_dim = hidden_dim # 임베딩 차원
    self.n_heads = n_heads # 헤드(head)의 개수: 서로 다른 어텐션(attention) 컨셉의 수
    self.head_dim = hidden_dim // n_heads # 각 헤드(head)에서의 임베딩 차원

    self.fc_q = nn.Linear(hidden_dim, hidden_dim) # Query 값에 적용될 FC 레이어
    self.fc_k = nn.Linear(hidden_dim, hidden_dim) # Key 값에 적용될 FC 레이어
    self.fc_v = nn.Linear(hidden_dim, hidden_dim) # Value 값에 적용될 FC 레이어

    self.fc_o = nn.Linear(hidden_dim, hidden_dim)

    self.dropout = nn.Dropout(dropout_ratio)

    self.scale = torch.sqrt(torch.FloatTensor([self.head_dim])).to(device)

def forward(self, query, key, value, mask = None):

    batch_size = query.shape[0]

    # query: [batch_size, query_len, hidden_dim]
    # key: [batch_size, key_len, hidden_dim]
    # value: [batch_size, value_len, hidden_dim]

    Q = self.fc_q(query)
    K = self.fc_k(key)
    V = self.fc_v(value)

    # Q: [batch_size, query_len, hidden_dim]
    # K: [batch_size, key_len, hidden_dim]
    # V: [batch_size, value_len, hidden_dim]

    # hidden_dim → n_heads X head_dim 형태로 변형
    # n_heads(h)개의 서로 다른 어텐션(attention) 컨셉을 학습하도록 유도
    Q = Q.view(batch_size, -1, self.n_heads, self.head_dim).permute(0, 2, 1, 3)
    K = K.view(batch_size, -1, self.n_heads, self.head_dim).permute(0, 2, 1, 3)
    V = V.view(batch_size, -1, self.n_heads, self.head_dim).permute(0, 2, 1, 3)

    # Q: [batch_size, n_heads, query_len, head_dim]
    # K: [batch_size, n_heads, key_len, head_dim]
    # V: [batch_size, n_heads, value_len, head_dim]

    # Attention Energy 계산
    energy = torch.matmul(Q, K.permute(0, 1, 3, 2)) / self.scale

    # energy: [batch_size, n_heads, query_len, key_len]

    # 마스크(mask)를 사용하는 경우
    if mask is not None:
        # 마스크(mask) 값이 0인 부분을 -1e10으로 채우기
        energy = energy.masked_fill(mask==0, -1e10)

    # 어텐션(attention) 스코어 계산: 각 단어에 대한 확률 값
    attention = torch.softmax(energy, dim=-1)

    # attention: [batch_size, n_heads, query_len, key_len]

    # 여기에서 Scaled Dot-Product Attention을 계산
    x = torch.matmul(self.dropout(attention), V)

    # x: [batch_size, n_heads, query_len, head_dim]

    x = x.permute(0, 2, 1, 3).contiguous()

    # x: [batch_size, query_len, n_heads, head_dim]

    x = x.view(batch_size, -1, self.hidden_dim)

    # x: [batch_size, query_len, hidden_dim]

    x = self.fc_o(x)

    # x: [batch_size, query_len, hidden_dim]

    return x, attention</code></pre><pre><code>
# Layer Normalization
## Batch norm vs Layer norm
- Batch nrom : sample들의 feature별 평균과 분산 -&gt; batch size에 따라서 성능변화가 심함
Layer nrom : 각 batch에 대해서 feature들의 평균과 분산
![](https://velog.velcdn.com/images/insung_na/post/c310d474-4e5e-4fa8-b1bb-adb81dfd6060/image.png)
![](https://velog.velcdn.com/images/insung_na/post/fc35700a-3197-487e-a073-1a60b1e3c210/image.png)

### Python Code
```python
class LayerNorm(nn.Module):
    def __init__(self, d_model, eps=1e-8):
        super(LayerNorm, self).__init__()
        self.gamma = nn.Parameter(torch.ones(d_model))
        self.beta = nn.Parameter(torch.zeros(d_model))
        self.eps = eps

    def forward(self, x):
        mean = x.mean(-1, keepdim=True)
        std = x.std(-1, keepdim=True)
        return self.gamma * (x - mean) / (std + self.eps) + self.beta</code></pre><h1 id="final-summary">Final Summary</h1>
<p><img src="https://velog.velcdn.com/images/insung_na/post/befb9ee9-a009-4919-844c-d7af2363411c/image.png" alt=""></p>
<ol>
<li>input 임베딩 + Position Encoding (Encoder)</li>
<li>Q, K, V 생성</li>
<li>Multi-Head Attention 사용</li>
<li>Skip-Connection + Layer Normalization</li>
<li>Self-attention 반복수행</li>
<li>Encoder의 출력값을 Decoder가 받아서 학습을 진행</li>
<li>Linear모델과 softmax을 통해서 최종결과(확률)를 도출</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ZB 데이터스쿨 11기]17주차 학습노트]]></title>
            <link>https://velog.io/@insung_na/ZB-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%8A%A4%EC%BF%A8-11%EA%B8%B017%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5%EB%85%B8%ED%8A%B8</link>
            <guid>https://velog.io/@insung_na/ZB-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%8A%A4%EC%BF%A8-11%EA%B8%B017%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5%EB%85%B8%ED%8A%B8</guid>
            <pubDate>Fri, 05 May 2023 14:14:42 GMT</pubDate>
            <description><![CDATA[<h1 id="📌17주차-학습내용-요약">📌17주차 학습내용 요약</h1>
<h2 id="딥러닝-역사">딥러닝 역사</h2>
<p><img src="https://user-images.githubusercontent.com/118172599/235621770-44359d7b-eec0-4a50-9857-af51e8e4bb56.png" alt="image"></p>
<h2 id="ml-vs-dl">ML vs DL</h2>
<p><img src="https://velog.velcdn.com/images/insung_na/post/fc8ad4af-9eba-4424-8f07-9f889cce4c50/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/3c51cefc-6c40-4012-8b2d-dec9899ec67a/image.png" alt=""></p>
<h2 id="딥러닝-구성">딥러닝 구성</h2>
<p><img src="https://velog.velcdn.com/images/insung_na/post/00ee43b2-107e-49e4-9f15-75f50a47ed47/image.png" alt=""></p>
<h1 id="딥러닝">딥러닝</h1>
<h2 id="뉴런">뉴런</h2>
<p><img src="https://user-images.githubusercontent.com/118172599/234757945-2ed036ab-3a4f-4e5d-b331-b3d0245224b6.png" alt="image"></p>
<ul>
<li>구성요소 : 입력, 가중치, 활성화함수, 출력</li>
<li>가중치를 업데이트</li>
<li>처음에는 초기화를 통해 랜덤값을 넣고, 학습을 통해 가중치를 수렴시킴</li>
</ul>
<h2 id="레이어와-망net">레이어와 망(net)</h2>
<p><img src="https://user-images.githubusercontent.com/118172599/234758143-32ca2003-019f-4912-bda0-a0c830f0144b.png" alt="image"></p>
<ul>
<li>뉴런이 모여서 layer를 구성하고, 망(net)이 됨</li>
</ul>
<h2 id="딥러닝-1">딥러닝</h2>
<p><img src="https://user-images.githubusercontent.com/118172599/234758269-0cf9ea26-3816-438b-b77b-2daba5a4b743.png" alt="image"></p>
<ul>
<li>신경망이 깊어(많아)지면 깊은 신경망 Deep Learning이 됨</li>
</ul>
<h1 id="cnn">CNN</h1>
<p><img src="https://velog.velcdn.com/images/insung_na/post/1f96dea1-7e82-4531-9ec1-b845bb2df202/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/4a0b3390-77f8-4f7c-a1bd-317e032cdbbe/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/942f334d-534d-4dd4-8c82-56a5f546b6a4/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/ed6e3c26-7d92-4031-99ac-2d74ccb824e6/image.png" alt=""></p>
<h2 id="dropout">Dropout</h2>
<p><img src="https://velog.velcdn.com/images/insung_na/post/9e63992b-27e5-4654-a39e-11ca2c2d931a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/74c57f6e-b2d8-425e-89a3-26ab7d3ba88d/image.png" alt=""></p>
<h2 id="역전파">역전파</h2>
<ul>
<li>XOR문제의 해결을 위해 등장한 역전파</li>
<li>출력층부터 delta를 계산해서 은닉층으로 전달한다
<img src="https://velog.velcdn.com/images/insung_na/post/ca189115-bfae-4cd9-a875-fc7ce08b692e/image.png" alt=""></li>
</ul>
<h3 id="연쇄법칙chain-rule">연쇄법칙(Chain Rule)</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/c864776d-81fb-4d49-bce2-fd1706697174/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/1718b84a-a58c-4c19-b553-da32546dc122/image.png" alt=""></p>
<h2 id="활성함수">활성함수</h2>
<h3 id="softmax">softmax</h3>
<ul>
<li>$softmax(x_i) = e^{x_i} / \sum_{j=1}^{n} e^{x_j}$</li>
<li>입력받은 값을 출력으로 0~1사이의 값으로 모두 정규화하며 출력 값들의 총합은 항상 1이 되는 특성을 가진 함수</li>
</ul>
<h3 id="relu">ReLU</h3>
<ul>
<li>$f(x) = max(0, x)$</li>
<li>+/-가 반복되는 신호에서 -흐름을 차단<h3 id="sigmoid의-한계">sigmoid의 한계</h3>
<img src="https://user-images.githubusercontent.com/118172599/234776620-9a70fed7-c8ac-4113-93ff-c0b6d9799368.png" alt="image"></li>
</ul>
<p><img src="https://user-images.githubusercontent.com/118172599/234776364-a427e968-4181-4ad5-a43b-83c881d478a3.png" alt="image"></p>
<p><img src="https://user-images.githubusercontent.com/118172599/234776712-26611708-168c-437a-8c74-44824456e801.png" alt="image"></p>
<h4 id="vanishing-gradient-problem">Vanishing Gradient problem</h4>
<p><img src="https://user-images.githubusercontent.com/118172599/234776823-18f643d5-e993-483b-b37f-019b427fe3b0.png" alt="image"></p>
<h4 id="relu-1">ReLU</h4>
<ul>
<li>Rectified Linear Units</li>
<li>은닉층은 대부분 ReLU를 사용</li>
</ul>
<p><img src="https://user-images.githubusercontent.com/118172599/234776948-a113d677-823d-482c-b383-12e3d2fa51ae.png" alt="image"></p>
<h4 id="softmax-1">softmax</h4>
<ul>
<li>카테고리들 중 확률이 가장 높은 대상을 정답으로 판단</li>
</ul>
<p><img src="https://user-images.githubusercontent.com/118172599/234777058-1a837440-7d88-47e7-98b3-440547df3f61.png" alt="image"></p>
<h3 id="활성화-함수-미분값">활성화 함수 미분값</h3>
<p><img src="https://velog.velcdn.com/images/insung_na/post/19acb6d3-4b44-4fb2-9a15-68dabe250af6/image.png" alt=""></p>
<h2 id="옵티마이저">옵티마이저</h2>
<p><img src="https://velog.velcdn.com/images/insung_na/post/fd446dc2-b774-48d5-8e85-9c34b82ccaf0/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Pytorch_basic]]></title>
            <link>https://velog.io/@insung_na/Pytorchbasic</link>
            <guid>https://velog.io/@insung_na/Pytorchbasic</guid>
            <pubDate>Fri, 05 May 2023 13:21:09 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다</p>
</blockquote>
<h1 id="1-pytorch_basic">1. Pytorch_basic</h1>
<pre><code class="language-python">import torch
x = torch.tensor(3.5)</code></pre>
<h4 id="기울기-계산">기울기 계산</h4>
<pre><code>x = torch.tensor(3.5, requires_grad=True)

print(x)
y = (x-1) * (x-2) * (x-3)

print(y)
y.backward()    # 미분계산
x.grad          # x의 기울기
---------------------------------------------------
print(x) : tensor(3.5000, requires_grad=True)
print(y) : tensor(1.8750, grad_fn=&lt;MulBackward0&gt;)
x.grad : tensor(5.7500)</code></pre><h2 id="연쇄법칙chain-rule">연쇄법칙(Chain Rule)</h2>
<p><img src="https://user-images.githubusercontent.com/118172599/235351400-6c309dd3-ad25-4d88-b014-f8a942840f74.png" alt="image"></p>
<p><img src="https://user-images.githubusercontent.com/118172599/235351404-3f9ebf9d-2ebc-4853-8936-0b5bd87afae0.png" alt="image"></p>
<pre><code>a = torch.tensor(2., requires_grad=True)
b = torch.tensor(1., requires_grad=True)

x = 2*a + 3*b
y = 5*a*a + 3*b**3
z = 2*x + 3*y
z.backward()    # 미분실행
a.grad          # a의 미분값
-----------------------------------
tensor(64.)</code></pre><h1 id="2-보스턴-집값-예측">2. 보스턴 집값 예측</h1>
<pre><code class="language-python">import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt</code></pre>
<h2 id="데이터-로드">데이터 로드</h2>
<pre><code class="language-python">from sklearn.datasets import fetch_openml
import pandas as pd

X, y = fetch_openml(&#39;boston&#39;, return_X_y=True, parser=&#39;auto&#39;, version=1)
df = X
df[&#39;TARGET&#39;] = y
df.tail()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/d7e1e597-13ce-4213-8efe-c82a18ba0a84/image.png" alt=""></p>
<h2 id="칼럼-선정">칼럼 선정</h2>
<pre><code class="language-python">import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
cols = [&quot;TARGET&quot;, &quot;INDUS&quot;, &quot;RM&quot;, &quot;LSTAT&quot;, &quot;NOX&quot;, &quot;DIS&quot;]
data = torch.tensor(df[cols].values).float()
data.shape
-----------------------------------------------------------
torch.Size([506, 6])</code></pre>
<h2 id="특성과-라벨로-분리">특성과 라벨로 분리</h2>
<pre><code class="language-python">x = data[:, 1:]
y = data[:, :1]

print(x.shape, y.shape)
--------------------------------
torch.Size([506, 5]) torch.Size([506, 1])</code></pre>
<h2 id="하이퍼파라미터">하이퍼파라미터</h2>
<pre><code class="language-python">n_epochs = 2000
learning_rate = 1e-3
print_interval = 100</code></pre>
<h2 id="모델-학습">모델 학습</h2>
<pre><code>model = nn.Linear(x.size(-1), y.size(-1))

# SGD(stochastic gradient descent, 확률적 경사하강법)
optimizer = optim.SGD(model.parameters(), lr=learning_rate)

for i in range(n_epochs):
    y_hat = model(x)
    loss = F.mse_loss(y_hat, y)

    optimizer.zero_grad()   # optimizer 초기화
    loss.backward()     # 미분

    optimizer.step()    # 파라미터 업데이트

    if (i+1)%print_interval==0:
        print(&quot;Epoch %d: loss=%.4e&quot; %(i+1, loss))
-----------------------------------------------------
Epoch 100: loss=4.4202e+01
Epoch 200: loss=3.7470e+01
...
Epoch 1900: loss=2.8987e+01
Epoch 2000: loss=2.8986e+01</code></pre><h2 id="모델-학습결과">모델 학습결과</h2>
<pre><code class="language-python">df = pd.DataFrame(torch.cat([y, y_hat], dim=1).detach_().numpy(), columns=[&quot;y&quot;, &quot;y_hat&quot;])
sns.pairplot(df, height=5)
plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/1144dabd-f363-40d7-ae67-25b2ca9fbc76/image.png" alt=""></p>
<h1 id="3-유방암-예측">3. 유방암 예측</h1>
<pre><code class="language-python">import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()

# print(cancer.DESCR)</code></pre>
<h2 id="데이터-정리">데이터 정리</h2>
<pre><code class="language-python">df = pd.DataFrame(cancer.data, columns=cancer.feature_names)
df[&#39;class&#39;] = cancer.target
df.tail()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/74ccb17d-c5b2-433a-bd24-bedce2c58e17/image.png" alt=""></p>
<h2 id="칼럼-선정-1">칼럼 선정</h2>
<pre><code class="language-python">cols = [&#39;mean radius&#39;, &#39;mean texture&#39;,
        &#39;mean smoothness&#39;, &#39;mean compactness&#39;, &#39;mean concave points&#39;,
        &#39;worst radius&#39;, &#39;worst texture&#39;,
         &#39;worst smoothness&#39;, &#39;worst compactness&#39;, &#39;worst concave points&#39;,
         &#39;class&#39;]

for c in cols[:-1]:
    sns.histplot(df, x=c, hue=cols[-1], bins=50, stat=&quot;probability&quot;)
    plt.show()    # 이미지 다수 생략</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/24b95d80-b5e7-4606-a369-69205666e0dc/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/26cae222-33de-4eec-b19f-bdf36ddb43b1/image.png" alt=""></p>
<h2 id="데이터-분리">데이터 분리</h2>
<pre><code class="language-python">data = torch.from_numpy(df[cols].values).float()

x = data[:, :-1]
y = data[:, -1:]

print(x.shape, y.shape)
-----------------------------------------------------
torch.Size([569, 10]) torch.Size([569, 1])</code></pre>
<h2 id="하이퍼파라미터-1">하이퍼파라미터</h2>
<pre><code class="language-python">n_epochs = 200000
learning_rate = 1e-2
print_interval = 10000</code></pre>
<h2 id="모델링">모델링</h2>
<pre><code class="language-python">class MyModel(nn.Module):
    def __init__(self, input_dim, output_dim):
        super(MyModel, self).__init__()
        self.input_dim, self.output_dim = input_dim, output_dim
        self.linear = nn.Linear(input_dim, output_dim)
        self.act = nn.Sigmoid()

    def forward(self, x):
        y = self.act(self.linear(x))

        return y</code></pre>
<pre><code class="language-python">model = MyModel(input_dim=x.size(-1),
                output_dim=y.size(-1))
crit = nn.BCELoss() # Binary Cross Entropy

optimizer = optim.SGD(model.parameters(), lr=learning_rate)</code></pre>
<h2 id="모델-학습-1">모델 학습</h2>
<pre><code class="language-python">for i in range(n_epochs):
    y_hat = model(x)
    loss = crit(y_hat, y)

    optimizer.zero_grad()
    loss.backward()

    optimizer.step()

    if (i+1)%print_interval==0:
        print(f&quot;Epoch {i+1}: loss={loss.item():.4f}&quot;)
---------------------------------------------------------
Epoch 10000: loss=0.2796
Epoch 20000: loss=0.2299
...
Epoch 190000: loss=0.1167
Epoch 200000: loss=0.1156</code></pre>
<h2 id="모델-학습결과-1">모델 학습결과</h2>
<pre><code class="language-python">correct_cnt = (y == (y_hat &gt; .5)).sum()
total_cnt = float(y.size(0))

print(&quot;Accuracy: %.4f&quot; %(correct_cnt/total_cnt))
---------------------------------------------------
Accuracy: 0.9649</code></pre>
<pre><code class="language-python">df = pd.DataFrame(torch.cat([y, y_hat], dim=1).detach().numpy(), columns=[&quot;y&quot;, &quot;y_hat&quot;])
sns.histplot(df, x=&quot;y_hat&quot;, hue=&quot;y&quot;, bins=50, stat=&quot;probability&quot;)
plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/714af961-da74-47e3-97b6-ba691b8b53a6/image.png" alt=""></p>
<h1 id="4-mnist">4. MNIST</h1>
<pre><code class="language-python">import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms

import matplotlib.pyplot as plt
%matplotlib inline</code></pre>
<h2 id="set-cuda">Set Cuda</h2>
<pre><code class="language-python">device = torch.device(&quot;cuda&quot; if torch.cuda.is_available() else &quot;cpu&quot;)
print(&quot;Current device is&quot;, device)
----------------------------------------------------------------------
Current device is cpu</code></pre>
<h2 id="datasets-load">Datasets Load</h2>
<pre><code class="language-python">import os
# os.listdir(&quot;../data&quot;)
train_data = datasets.MNIST(root=&quot;../data&quot;,   # data save path
                            train=True,       # train data
                            download=True,    # download on
                            transform=transforms.ToTensor())

test_data = datasets.MNIST(root=&quot;../data&quot;,    # data save path
                            train=False,      # test data
                            transform=transforms.ToTensor())

print(&quot;number of training data: &quot;, len(train_data))
print(&quot;number of test data: &quot;, len(test_data))
-----------------------------------------------------------------
number of training data:  60000
number of test data:  10000</code></pre>
<h2 id="data-check">Data Check</h2>
<pre><code class="language-python">image, label = train_data[0]
image.shape, image.squeeze().shape
# 첫번째 차원이 channel
------------------------------------------------
(torch.Size([1, 28, 28]), torch.Size([28, 28]))</code></pre>
<pre><code class="language-python">plt.imshow(image.squeeze().numpy(), cmap=&quot;gray&quot;)
plt.title(&quot;label : %s&quot; %label)
plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/c397d774-cd8d-4564-b7ee-faed62f6b5e4/image.png" alt=""></p>
<h2 id="mini-batch-configure">Mini batch configure</h2>
<pre><code class="language-python">batch_size = 50
learning_rate = 0.0001
epoch_num = 15

train_loader = torch.utils.data.DataLoader(dataset = train_data,
                                           batch_size=batch_size,
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset = test_data,
                                           batch_size=batch_size,
                                           shuffle=True)

first_batch = train_loader.__iter__().__next__()
print(&quot;{:15s} | {:&lt;25s} | {}&quot;.format(&quot;name&quot;, &quot;type&quot;, &quot;size&quot;))
print(&quot;{:15s} | {:&lt;25s} | {}&quot;.format(&quot;Num of Batch&quot;, &quot;&quot;, len(train_loader)))
print(&quot;{:15s} | {:&lt;25s} | {}&quot;.format(&quot;first_batch&quot;, str(type(first_batch)), len(first_batch)))
print(&quot;{:15s} | {:&lt;25s} | {}&quot;.format(&quot;first_batch[0]&quot;, str(type(first_batch[0])), first_batch[0].shape))
print(&quot;{:15s} | {:&lt;25s} | {}&quot;.format(&quot;first_batch[1]&quot;, str(type(first_batch[1])), first_batch[1].shape))
-----------------------------------------------------------------------------------------------------------
name            | type                      | size
Num of Batch    |                           | 1200
first_batch     | &lt;class &#39;list&#39;&gt;            | 2
first_batch[0]  | &lt;class &#39;torch.Tensor&#39;&gt;    | torch.Size([50, 1, 28, 28])
first_batch[1]  | &lt;class &#39;torch.Tensor&#39;&gt;    | torch.Size([50])</code></pre>
<h2 id="modeling">Modeling</h2>
<ul>
<li><p>nn.Linear(3136, 1000)으로 설정되어 있다</p>
</li>
<li><p>(28,28) -&gt; MaxPooling2d 2번 -&gt; (7,7) 여기에 channel_cnt를 곱함</p>
</li>
<li><p>하지만 연결계층의 입력크기는 일반적으로 특징을 잘 포착할 수 있을 만큼 크게 선택됨</p>
</li>
<li><p>입력크기 너무 크면 과적합, 작으면 정보를 모두 포착하지 못해서 올바른 학습불가</p>
</li>
<li><p>따라서 시행착오를 통해서 최적의 입력크기를 찾아야한다</p>
<pre><code class="language-python">class CNN(nn.Module):
  def __init__(self):
      super(CNN, self).__init__()
      self.conv1 = nn.Conv2d(1, 32, 3, 1, padding=&quot;same&quot;)
      self.conv2 = nn.Conv2d(32, 64, 3, 1, padding=&quot;same&quot;)
      self.dropout = nn.Dropout2d(0.25)

      self.fc1 = nn.Linear(3136, 1000)
      self.fc2 = nn.Linear(1000, 10)

  def forward(self, x):
      x = self.conv1(x)
      x = F.relu(x)
      x = F.max_pool2d(x,2)

      x = self.conv2(x)
      x = F.relu(x)
      x = F.max_pool2d(x,2)

      x = self.dropout(x)
      x = torch.flatten(x,1)

      x = self.fc1(x)
      x = F.relu(x)
      x = self.fc2(x)
      output = F.log_softmax(x, dim=1)

      return output</code></pre>
<pre><code class="language-python">model = CNN().to(device)
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
criterion = nn.CrossEntropyLoss()</code></pre>
<h2 id="model-learning">Model Learning</h2>
<pre><code class="language-python">from time import time
</code></pre>
</li>
</ul>
<p>model.train()
i = 1
for epoch in range(epoch_num):
    start_time_each_epoch = time()
    for data, target in train_loader:
        data = data.to(device)
        target = target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        if i%1000==0:
            print(&quot;Time: %.3f\tTrain Step: %d\tLoss: %.3f\t&quot; %(time() - start_time_each_epoch, i, loss.item()))
        i+=1</p>
<hr>
<p>Time: 81.436    Train Step: 1000    Loss: 0.191<br>Time: 69.932    Train Step: 2000    Loss: 0.033<br>Time: 53.119    Train Step: 3000    Loss: 0.014<br>Time: 52.150    Train Step: 4000    Loss: 0.132<br>Time: 22.078    Train Step: 5000    Loss: 0.192<br>Time: 136.500    Train Step: 6000    Loss: 0.178<br>Time: 114.181    Train Step: 7000    Loss: 0.048<br>Time: 90.783    Train Step: 8000    Loss: 0.018<br>Time: 68.979    Train Step: 9000    Loss: 0.020<br>Time: 43.789    Train Step: 10000    Loss: 0.005<br>Time: 20.056    Train Step: 11000    Loss: 0.055<br>Time: 97.013    Train Step: 12000    Loss: 0.000<br>Time: 78.883    Train Step: 13000    Loss: 0.027<br>Time: 62.891    Train Step: 14000    Loss: 0.005<br>Time: 47.510    Train Step: 15000    Loss: 0.003<br>Time: 31.382    Train Step: 16000    Loss: 0.000<br>Time: 15.918    Train Step: 17000    Loss: 0.001<br>Time: 95.073    Train Step: 18000    Loss: 0.018</p>
<pre><code>## Model Eval
```python
model.eval()
correct = 0

for data, target in test_loader:
    data = data.to(device)
    target = target.to(device)
    output = model(data)
    prediction = output.data.max(1)[1]
    correct += prediction.eq(target.data).sum()

print(&quot;Test set: Accuracy: %.2f&quot; %(100.*correct / len(test_loader.dataset)))
------------------------------------------------------------------------------
Test set: Accuracy: 99.08</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[OX분류하기]]></title>
            <link>https://velog.io/@insung_na/OX%EB%B6%84%EB%A5%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@insung_na/OX%EB%B6%84%EB%A5%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 05 May 2023 12:59:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다</p>
</blockquote>
<h1 id="ox-classification">OX Classification</h1>
<h2 id="1-개요">1. 개요</h2>
<ul>
<li>딥러닝 기초 이진분류에 대해 학습한다</li>
<li>데이터셋 : OX Images</li>
<li><em>데이터셋을 얻지 못했다</em><ul>
<li>결과는 학습자료를 보고, 코드만 입력하면서 학습한다<h2 id="2-데이터-수집">2. 데이터 수집</h2>
</li>
</ul>
</li>
<li>데이터셋 없음</li>
<li>코드만 입력<h2 id="3-데이터-전처리">3. 데이터 전처리</h2>
</li>
<li>이미지 불러오기(실행X)</li>
<li>train_test별로 크기 조정</li>
<li>이미지 제네레이터<h3 id="3-1-이미지-조정">3-1. 이미지 조정</h3>
<pre><code class="language-python">from glob import glob
</code></pre>
</li>
</ul>
<p>train_raw_path = &quot;./train_raw/O/*.&quot;
train_raw_O_list = glob(train_raw_path)
train_raw_O_list</p>
<pre><code>![](https://velog.velcdn.com/images/insung_na/post/883f5585-307b-4bf5-b111-969bf07eb34a/image.png)

#### img_resize
![](https://velog.velcdn.com/images/insung_na/post/84a4afa1-0a65-4ae0-943b-e627edfe5ea3/image.png)

```python
# !pip install scikit-image
from skimage.transform import rescale, resize
from skimage import color
from skimage.io import imread, imsave
import matplotlib.pyplot as plt
import numpy as np

def img_resize(img):
    img = color.rgb2gray(img)
    return resize(img, (28,28))</code></pre><h4 id="train_o">train_O</h4>
<pre><code class="language-python">from tqdm.notebook import tqdm

def convert_train_O():
    train_raw_O_list = glob(train_raw_path)
    for each in tqdm(train_raw_O_list):
        img = imread(each)
        img_resized = img_resize(img)
        save_name = &quot;./train/O/&quot; + each.split(&quot;/&quot;)[-1][:-4] + &quot;.png&quot;    # rename
        imsave(save_name, np.round(img_resized*255).astype(int))

convert_train_O()</code></pre>
<h4 id="train_x">train_X</h4>
<pre><code class="language-python">from tqdm.notebook import tqdm

train_raw_path = &quot;./train_raw/X/*.&quot;
def convert_train_X():
    train_raw_X_list = glob(train_raw_path)
    for each in tqdm(train_raw_X_list):
        img = imread(each)
        img_resized = img_resize(img)
        save_name = &quot;./train/X/&quot; + each.split(&quot;/&quot;)[-1][:-4] + &quot;.png&quot;    # rename
        imsave(save_name, np.round(img_resized*255).astype(int))

convert_train_X()</code></pre>
<h4 id="test_o">test_O</h4>
<pre><code class="language-python">from tqdm.notebook import tqdm

test_raw_path = &quot;&quot;
def convert_test_O():
    test_raw_O_list = glob(test_raw_path)
    for each in tqdm(test_raw_O_list):
        img = imread(each)
        img_resized = img_resize(img)
        save_name = &quot;./test/O/&quot; + each.split(&quot;/&quot;)[-1][:-4] + &quot;.png&quot;    # rename
        imsave(save_name, np.round(img_resized*255).astype(int))

convert_test_O()</code></pre>
<h4 id="test_x">test_X</h4>
<pre><code class="language-python">from tqdm.notebook import tqdm

test_raw_path = &quot;&quot;
def convert_test_X():
    test_raw_X_list = glob(test_raw_path)
    for each in tqdm(test_raw_X_list):
        img = imread(each)
        img_resized = img_resize(img)
        save_name = &quot;./test/X/&quot; + each.split(&quot;/&quot;)[-1][:-4] + &quot;.png&quot;    # rename
        imsave(save_name, np.round(img_resized*255).astype(int))

convert_test_X()</code></pre>
<h3 id="3-2-image_generator">3-2. Image_generator</h3>
<pre><code class="language-python">import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator
import keras

np.random.seed(13)
train_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(&quot;./train&quot;, target_size=(28,28), batch_size=3, class_mode=&quot;categorical&quot;)

test_datagen = ImageDataGenerator(rescale=1./255)

test_generator = test_datagen.flow_from_directory(&quot;./test&quot;, target_size=(28,28), batch_size=3, class_mode=&quot;categorical&quot;)</code></pre>
<h2 id="4-모델링">4. 모델링</h2>
<pre><code class="language-python">model = Sequential()
model.add(Conv2D(32, kernel_size=(3,3), activation=&quot;relu&quot;, input_shape=(28,28,3)))
model.add(Conv2D(64, kernel_size=(3,3), activation=&quot;relu&quot;))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(128, activation=&quot;relu&quot;))
model.add(Dense(2, activation=&quot;softmax&quot;))

model.compile(loss=&quot;categorical_crossentropy&quot;, optimizer=&quot;adam&quot;, metrics=[&quot;accuracy&quot;])

hist = model.fit_generator(train_generator, steps_per_epoch=15, epochs=50, validation_data=test_generator, validation_steps=5)
plt.figure(figsize=(12,6))
plt.plot(hist.history[&quot;loss&quot;], label=&quot;loss&quot;)
plt.plot(hist.history[&quot;val_loss&quot;], label=&quot;val_loss&quot;)
plt.plot(hist.history[&quot;accuracy&quot;], label=&quot;accuracy&quot;)
plt.plot(hist.history[&quot;val_accuracy&quot;], label=&quot;val_accuracy&quot;)
plt.legend()
plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/1da1aa68-1fad-4b8d-baeb-1eedabc5dbc0/image.png" alt=""></p>
<h2 id="5-모델-평가">5. 모델 평가</h2>
<pre><code class="language-python">scores = model.evalute(test_generator, steps=5)

print(&quot;%s: %.2f%%&quot; %(model.metrics_names[1], scores[1]*100))    # 100.0%</code></pre>
<pre><code class="language-python">model.predict(test_generator)
n = 1

def show_prediction_result(n):
    img = imread(test_generator.filepaths[n])
    pred = model.predict(np.expand_dims(color.gray2rgb(img), axis=0))
    title = &quot;Predict : &quot; + str(np.argmax(pred))
    plt.imshow(img/255., cmap=&quot;gray&quot;)
    plt.title(title)
    plt.show()

show_prediction_result(n)
show_prediction_result(40)</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/6e0f3408-b9e7-4cd7-934c-867692890090/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/insung_na/post/d5eda09f-a19c-4374-8a83-ce0e13b4a029/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Find Mask Man]]></title>
            <link>https://velog.io/@insung_na/Find-Mask-Man</link>
            <guid>https://velog.io/@insung_na/Find-Mask-Man</guid>
            <pubDate>Fri, 05 May 2023 12:42:07 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다</p>
</blockquote>
<h1 id="find-mask-man">Find Mask man</h1>
<ul>
<li>출처 : <a href="https://www.kaggle.com/datasets/ashishjangra27/face-mask-12k-images-dataset">https://www.kaggle.com/datasets/ashishjangra27/face-mask-12k-images-dataset</a><h2 id="module-import">Module Import</h2>
<pre><code class="language-python">import numpy as np
import pandas as pd
import os
import glob
import matplotlib.pyplot as plt
import seaborn as sns
import tensorflow as tf
from tensorflow.keras import Sequential, models, layers, models
from tensorflow.keras.layers import Flatten, Dense, Conv2D, MaxPool2D
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix</code></pre>
<h2 id="data-collecting">Data collecting</h2>
<h3 id="데이터-경로와-목록-저장">데이터 경로와 목록 저장</h3>
<pre><code class="language-python">path = &quot;../data/Face Mask Dataset/&quot;
dataset = {&quot;image_path&quot;:[], &quot;mask_status&quot;:[], &quot;where&quot;:[]}
</code></pre>
</li>
</ul>
<p>for where in os.listdir(path):
    for status in os.listdir(path + &quot;/&quot; + where):
        for image in glob.glob(path + &quot;/&quot; + where + &quot;/&quot; + status + &quot;/&quot; + &quot;*.png&quot;):
            dataset[&quot;image_path&quot;].append(image)
            dataset[&quot;mask_status&quot;].append(status)
            dataset[&quot;where&quot;].append(where)</p>
<p>dataset = pd.DataFrame(dataset)
dataset.head()</p>
<pre><code>![](https://velog.velcdn.com/images/insung_na/post/6bcadb20-a8fe-422d-bf4b-0813048e75af/image.png)

### 데이터 확인
```python
print(&quot;With Mask:&quot;, dataset.value_counts(&quot;mask_status&quot;)[0])
print(&quot;Without Mask:&quot;, dataset.value_counts(&quot;mask_status&quot;)[1])

sns.countplot(x=dataset[&quot;mask_status&quot;])
-----------------------------------------
With Mask: 5909
Without Mask: 5883</code></pre><p><img src="https://velog.velcdn.com/images/insung_na/post/dfc3dca4-448f-4d0b-9ea4-2e3ee33ca393/image.png" alt=""></p>
<pre><code class="language-python">import cv2

plt.figure(figsize=(15,10))
for i in range(9):
    random = np.random.randint(1, len(dataset))
    plt.subplot(3, 3, i+1)
    plt.imshow(cv2.imread(dataset.loc[random, &quot;image_path&quot;]))
    plt.title(dataset.loc[random, &quot;mask_status&quot;], size=15)
    plt.xticks([]); plt.yticks([])
plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/86b1f4e1-6f8c-4730-9f68-3051fa619e3d/image.png" alt=""></p>
<pre><code class="language-python">train_df = dataset[dataset[&quot;where&quot;]==&quot;Train&quot;]
test_df = dataset[dataset[&quot;where&quot;]==&quot;Test&quot;]
valid_df = dataset[dataset[&quot;where&quot;]==&quot;Validation&quot;]

plt.figure(figsize=(15, 5))
plt.subplot(131)
sns.countplot(x=train_df[&quot;mask_status&quot;])
plt.title(&quot;Train Dataset&quot;, size=10)

plt.subplot(132)
sns.countplot(x=test_df[&quot;mask_status&quot;])
plt.title(&quot;test Dataset&quot;, size=10)

plt.subplot(133)
sns.countplot(x=valid_df[&quot;mask_status&quot;])
plt.title(&quot;Validation Dataset&quot;, size=10)</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/5d248183-f9b6-4571-bd1c-649931f604c0/image.png" alt=""></p>
<h2 id="data-preprocessing">Data preprocessing</h2>
<h3 id="인덱스-초기화">인덱스 초기화</h3>
<pre><code class="language-python">train_df = train_df.reset_index(drop=True)
train_df.head()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/2ae33529-cb00-4d66-a75b-5b3a1ab02532/image.png" alt=""></p>
<h3 id="이미지-전처리">이미지 전처리</h3>
<pre><code class="language-python">data = []
image_size = 150

for i in range(len(train_df)):
    # Converting the image into grayscale
    img_array = cv2.imread(train_df[&quot;image_path&quot;][i], cv2.IMREAD_GRAYSCALE)

    # Resizing the array
    new_image_array = cv2.resize(img_array, (image_size, image_size))

    # Encoding the image with the label
    if train_df[&quot;mask_status&quot;][i] == &quot;WithMask&quot;:
        data.append([new_image_array, 1])
    else:
        data.append([new_image_array, 0])

np.random.shuffle(data)    # 순서를 학습하지 못하도록 shuffle</code></pre>
<h3 id="전처리-데이터-확인">전처리 데이터 확인</h3>
<pre><code class="language-python">fig, ax = plt.subplots(2, 3, figsize=(10,6))

for row in range(2):
    for col in range(3):
        image_index = row * 100 + col

        ax[row, col].axis(&quot;off&quot;)
        ax[row, col].imshow(data[image_index][0], cmap=&quot;gray&quot;)

        if data[image_index][1] == 0:
            ax[row, col].set_title(&quot;Without Mask&quot;)
        else:
            ax[row, col].set_title(&quot;With Mask&quot;)</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/d897e817-3df0-4012-91e2-7fe33dff1e03/image.png" alt=""></p>
<h2 id="modeling">Modeling</h2>
<h3 id="모델-학습">모델 학습</h3>
<pre><code class="language-python">X = []
y = []
for image in data:
    X.append(image[0])
    y.append(image[1])

X = np.array(X)
y = np.array(y)

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=13)
model = models.Sequential([
    layers.Conv2D(32, kernel_size=(5,5), strides=(1,1), padding=&quot;same&quot;, activation=&quot;relu&quot;, input_shape=(150,150,1)),
    layers.MaxPooling2D(pool_size=(2,2), strides=(2,2)),
    layers.Conv2D(64, kernel_size=(2,2), padding=&quot;same&quot;, activation=&quot;relu&quot;),
    layers.MaxPooling2D(pool_size=(2,2)),
    layers.Dropout(0.25),
    layers.Flatten(),
    layers.Dense(1000, activation=&quot;relu&quot;),
    layers.Dense(1, activation=&quot;sigmoid&quot;)              
])

model.compile(optimizer=&quot;adam&quot;, loss=tf.keras.losses.BinaryCrossentropy(), metrics=[&quot;accuracy&quot;])

X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], X_train.shape[2], 1)
X_val = X_val.reshape(X_val.shape[0], X_val.shape[1], X_val.shape[2], 1)
history = model.fit(X_train, y_train, epochs=4, batch_size=32)
---------------------------------------------------------------------------------------------------
Epoch 1/4
250/250 [==============================] - 317s 1s/step - loss: 25.5447 - accuracy: 0.8960
Epoch 2/4
250/250 [==============================] - 393s 2s/step - loss: 0.0632 - accuracy: 0.9758
Epoch 3/4
250/250 [==============================] - 379s 2s/step - loss: 0.0300 - accuracy: 0.9894
Epoch 4/4
250/250 [==============================] - 391s 2s/step - loss: 0.0185 - accuracy: 0.9933</code></pre>
<h4 id="colab-gpu-사용시-학습속도">Colab GPU 사용시 학습속도</h4>
<p><img src="https://user-images.githubusercontent.com/118172599/235179966-4c4b29f9-3aec-4a22-b8d3-e0bfd0bdb648.png" alt="image"></p>
<h2 id="모델-평가">모델 평가</h2>
<h3 id="모델-성능-확인">모델 성능 확인</h3>
<pre><code class="language-python">model.evaluate(X_val, y_val)
-----------------------------------------------------------------------------------------
63/63 [==============================] - 16s 253ms/step - loss: 0.1214 - accuracy: 0.9660
[0.12140300869941711, 0.9660000205039978]</code></pre>
<pre><code class="language-python">prediction = (model.predict(X_val) &gt; 0.5).astype(&quot;int32&quot;)

print(classification_report(y_val, prediction))
print(confusion_matrix(y_val, prediction))
----------------------------------------------------------------------------------------
63/63 [==============================] - 14s 222ms/step
              precision    recall  f1-score   support

           0       0.96      0.97      0.97      1032
           1       0.97      0.96      0.96       968

    accuracy                           0.97      2000
   macro avg       0.97      0.97      0.97      2000
weighted avg       0.97      0.97      0.97      2000

[[1001   31]
 [  37  931]]</code></pre>
<h3 id="틀린데이터-확인">틀린데이터 확인</h3>
<pre><code class="language-python">wrong_result = []

for n in range(y_val.shape[0]):
    if prediction[n] != y_val[n]:
        wrong_result.append(n)

len(wrong_result)
-------------------------------------------------
68</code></pre>
<pre><code class="language-python">import random

samples = random.choices(population=wrong_result, k=6)

plt.figure(figsize=(14, 12))

for idx, n in enumerate(samples):
    plt.subplot(2, 3, idx+1)
    plt.imshow(X_val[n].reshape(150, 150),interpolation=&quot;nearest&quot;)
    plt.title(prediction[n])
    plt.axis(&quot;off&quot;)</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/10e0dc28-86b7-445a-872c-2b8198e813c4/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CNN Feature Maps]]></title>
            <link>https://velog.io/@insung_na/CNN-Feature-Maps</link>
            <guid>https://velog.io/@insung_na/CNN-Feature-Maps</guid>
            <pubDate>Fri, 05 May 2023 12:27:00 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다</p>
</blockquote>
<h1 id="cnn_feature_maps">CNN_Feature_Maps</h1>
<h2 id="사용-데이터-및-모델">사용 데이터 및 모델</h2>
<h3 id="mnist-load">MNIST Load</h3>
<pre><code class="language-python">import tensorflow as tf

mnist = tf.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

X_train = X_train.reshape((60000, 28, 28, 1))
X_test = X_test.reshape((10000, 28, 28, 1))</code></pre>
<h3 id="simple-modeling">Simple Modeling</h3>
<pre><code class="language-python">from tensorflow.keras import layers, models

model = models.Sequential([
    layers.Conv2D(3, kernel_size=(3, 3), strides=(1,1), padding=&quot;same&quot;, activation=&quot;relu&quot;, input_shape=(28,28,1)),
    layers.MaxPooling2D(pool_size=(2,2), strides=(2,2)),
    layers.Dropout(0.25),
    layers.Flatten(),
    layers.Dense(1000, activation=&quot;relu&quot;),
    layers.Dense(10, activation=&quot;softmax&quot;)              
])

model.summary()
--------------------------------------------------------------------
Model: &quot;sequential&quot;
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 28, 28, 3)         30        

 max_pooling2d (MaxPooling2D  (None, 14, 14, 3)        0         
 )                                                               

 dropout (Dropout)           (None, 14, 14, 3)         0         

 flatten (Flatten)           (None, 588)               0         

 dense (Dense)               (None, 1000)              589000    

 dense_1 (Dense)             (None, 10)                10010     

=================================================================
Total params: 599,040
Trainable params: 599,040
Non-trainable params: 0
_________________________________________________________________</code></pre>
<h4 id="layer-조회">layer 조회</h4>
<pre><code class="language-python">model.layers
--------------------------------------------------------------------
[&lt;keras.layers.convolutional.conv2d.Conv2D at 0x1428ca6d310&gt;,
 &lt;keras.layers.pooling.max_pooling2d.MaxPooling2D at 0x1428d08ead0&gt;,
 &lt;keras.layers.regularization.dropout.Dropout at 0x1428e790150&gt;,
 &lt;keras.layers.reshaping.flatten.Flatten at 0x1428e7b2a90&gt;,
 &lt;keras.layers.core.dense.Dense at 0x1428e7b3690&gt;,
 &lt;keras.layers.core.dense.Dense at 0x1428e793a10&gt;]</code></pre>
<p>아직 학습하지 않은 Conv 레이어의 weigths</p>
<pre><code class="language-python">conv = model.layers[0]
conv_weights = conv.weights[0].numpy()
conv_weights.mean(), conv_weights.std()
------------------------------------------
(0.012864082, 0.23187771)</code></pre>
<h4 id="weights-분포도">weights 분포도</h4>
<pre><code class="language-python">import matplotlib.pyplot as plt

plt.hist(conv_weights.reshape(-1, 1))
plt.xlabel(&quot;weights&quot;)
plt.ylabel(&quot;count&quot;)
plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/c5a4974b-42a7-4e23-80e4-0aef4e8b17c2/image.png" alt=""></p>
<h3 id="학습-전-conv-filter">학습 전 conv filter</h3>
<pre><code class="language-python">fig, ax = plt.subplots(1, 3, figsize=(15, 5))
for i in range(3):
    ax[i].imshow(conv_weights[:,:,0,i], vmin=-0.5, vmax=0.5)
    ax[i].axis(&quot;off&quot;)

plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/ee74dcad-d18f-43c9-8b4f-133cace1018d/image.png" alt=""></p>
<h4 id="모델-학습">모델 학습</h4>
<pre><code class="language-python">model.compile(optimizer=&quot;adam&quot;, loss=&quot;sparse_categorical_crossentropy&quot;, metrics=[&quot;accuracy&quot;])
hist = model.fit(X_train, y_train, epochs=5, verbose=1, validation_data = (X_test, y_test))</code></pre>
<h3 id="학습-후-conv-filter">학습 후 conv filter</h3>
<pre><code class="language-python">fig, ax = plt.subplots(1, 3, figsize=(15, 5))
for i in range(3):
    ax[i].imshow(conv_weights[:,:,0,i], vmin=-0.5, vmax=0.5)
    ax[i].axis(&quot;off&quot;)

plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/193ea889-4f7a-4d43-95ff-2b791e574cf2/image.png" alt=""></p>
<h2 id="featuremaps">FeatureMaps</h2>
<h3 id="featuremaps에-사용할-데이터">FeatureMaps에 사용할 데이터</h3>
<pre><code class="language-python">plt.imshow(X_train[0], cmap=&quot;gray&quot;)</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/65225613-8204-42ef-9114-aa2672668e51/image.png" alt=""></p>
<h3 id="featuremaps-생성">FeatureMaps 생성</h3>
<pre><code class="language-python">inputs = X_train[0].reshape(-1, 28, 28, 1)
conv_layer_output = tf.keras.Model(model.input, model.layers[0].output)

feature_maps = conv_layer_output.predict(inputs)</code></pre>
<h3 id="feature_maps">feature_maps</h3>
<pre><code class="language-python">def draw_feature_maps(n):
    inputs = X_train[n].reshape(-1, 28, 28, 1)
    feature_maps = conv_layer_output.predict(inputs)

    fig, ax = plt.subplots(1,4, figsize=(15,5))
    ax[0].imshow(feature_maps[0,:,:,0], cmap=&quot;gray&quot;)

    for i in range(1, 4):
        ax[i].imshow(feature_maps[0,:,:,i-1])
        ax[i].axis(&quot;Off&quot;)
    plt.show()

draw_feature_maps(1)</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/0f3ab7b3-aedd-4126-bddc-e58b4e2e3620/image.png" alt=""></p>
<pre><code class="language-python">draw_feature_maps(4)</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/a753c1f8-30e5-4378-a3c8-431bc1b01a1a/image.png" alt=""></p>
<h3 id="채널-증가">채널 증가</h3>
<ul>
<li>입력 수 3 -&gt; 8<pre><code class="language-python">from tensorflow.keras import layers, models
</code></pre>
</li>
</ul>
<p>model1 = models.Sequential([
    layers.Conv2D(8, kernel_size=(3,3), strides=(1,1), padding=&quot;same&quot;, activation=&quot;relu&quot;, input_shape=(28,28,1)),
    layers.MaxPooling2D(pool_size=(2,2), strides=(2,2)),
    layers.Dropout(0.25),
    layers.Flatten(),
    layers.Dense(1000, activation=&quot;relu&quot;),
    layers.Dense(10, activation=&quot;softmax&quot;)<br>])</p>
<p>model1.compile(optimizer=&quot;adam&quot;, loss=&quot;sparse_categorical_crossentropy&quot;, metrics=[&quot;accuracy&quot;])
hist = model1.fit(X_train, y_train, epochs=5, verbose=1, validation_data = (X_test, y_test))</p>
<hr>
<p>Epoch 1/5
1875/1875 [==============================] - 46s 24ms/step - loss: 0.1633 - accuracy: 0.9499 - val_loss: 0.0579 - val_accuracy: 0.9810
Epoch 2/5
1875/1875 [==============================] - 45s 24ms/step - loss: 0.0680 - accuracy: 0.9784 - val_loss: 0.0442 - val_accuracy: 0.9856
Epoch 3/5
1875/1875 [==============================] - 47s 25ms/step - loss: 0.0460 - accuracy: 0.9854 - val_loss: 0.0403 - val_accuracy: 0.9876
Epoch 4/5
1875/1875 [==============================] - 50s 26ms/step - loss: 0.0350 - accuracy: 0.9884 - val_loss: 0.0353 - val_accuracy: 0.9881
Epoch 5/5
1875/1875 [==============================] - 52s 28ms/step - loss: 0.0270 - accuracy: 0.9909 - val_loss: 0.0422 - val_accuracy: 0.9870</p>
<pre><code>
### feature_maps
```python
conv_layer_output = tf.keras.Model(model1.input, model1.layers[0].output)

def draw_feature_maps(n):
    inputs = X_train[n].reshape(-1, 28, 28, 1)
    feature_maps = conv_layer_output.predict(inputs)

    fig, ax = plt.subplots(1,9, figsize=(15,5))
    ax[0].imshow(feature_maps[0,:,:,0], cmap=&quot;gray&quot;)

    for i in range(1, 9):
        ax[i].imshow(feature_maps[0,:,:,i-1])
        ax[i].axis(&quot;Off&quot;)
    plt.show()

draw_feature_maps(1)</code></pre><p><img src="https://velog.velcdn.com/images/insung_na/post/3879e9b8-eea2-4ce6-91a4-977434892ae1/image.png" alt=""></p>
<pre><code class="language-python">draw_feature_maps(9)</code></pre>
<p><img src="https://velog.velcdn.com/images/insung_na/post/efda9891-765c-4f15-a4a4-52f5721ddfe1/image.png" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>