<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>천천히 꾸준히 조용히</title>
    <link>https://13months.tistory.com/</link>
    <description>천천히 꾸준히 조용히..
i3months 블로그</description>
    <language>ko</language>
    <pubDate>Fri, 10 Apr 2026 05:39:15 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>i3months</managingEditor>
    <image>
      <title>천천히 꾸준히 조용히</title>
      <url>https://tistory1.daumcdn.net/tistory/4775559/attach/1d8003f60bce4c3d85d7c4c06bf1ab80</url>
      <link>https://13months.tistory.com</link>
    </image>
    <item>
      <title>[StackUp] 종합설계 프로젝트 브레인스토밍 발표</title>
      <link>https://13months.tistory.com/825</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2002&quot; data-origin-height=&quot;1172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPlf6u/dJMcagLLyeh/dtd5kIGjBCfE7ROMpTotBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPlf6u/dJMcagLLyeh/dtd5kIGjBCfE7ROMpTotBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPlf6u/dJMcagLLyeh/dtd5kIGjBCfE7ROMpTotBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPlf6u%2FdJMcagLLyeh%2Fdtd5kIGjBCfE7ROMpTotBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2002&quot; height=&quot;1172&quot; data-origin-width=&quot;2002&quot; data-origin-height=&quot;1172&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;저희 팀의 종합설계 주제는 &quot;멀티모달 AI 를 활용한 챗봇 개발&amp;rdquo;이고,&amp;nbsp;&lt;br /&gt;이 주제를 바탕으로 IT 직군을 위한 모의 면접 경험을 제공하는 서비스를 개발하고 있습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2018&quot; data-origin-height=&quot;1166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yyMin/dJMcagLLyeB/XBG0y9X6SlP8CCLG8HMl51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yyMin/dJMcagLLyeB/XBG0y9X6SlP8CCLG8HMl51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yyMin/dJMcagLLyeB/XBG0y9X6SlP8CCLG8HMl51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyyMin%2FdJMcagLLyeB%2FXBG0y9X6SlP8CCLG8HMl51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2018&quot; height=&quot;1166&quot; data-origin-width=&quot;2018&quot; data-origin-height=&quot;1166&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;이번 발표 주제는 브레인스토밍 입니다.&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;저희 팀은 프로젝트에서 어떤 기능이 필수적으로 개발되어야 하는지와,&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;그 기능을 어떻게 구현할지에 대해 브레인스토밍을 진행했습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2014&quot; data-origin-height=&quot;1162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOvdNk/dJMcaflL6Qu/OCxT8zHEtyKxP009OVIb8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOvdNk/dJMcaflL6Qu/OCxT8zHEtyKxP009OVIb8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOvdNk/dJMcaflL6Qu/OCxT8zHEtyKxP009OVIb8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOvdNk%2FdJMcaflL6Qu%2FOCxT8zHEtyKxP009OVIb8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2014&quot; height=&quot;1162&quot; data-origin-width=&quot;2014&quot; data-origin-height=&quot;1162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;우선 저희 프로젝트의 큰 주제는 면접입니다.&amp;nbsp;&lt;br /&gt;면접 중에서도 IT 직군을 위한 면접이니, 어떤 기능이 필요할지에 대해서 회의를 진행했습니다.&lt;br /&gt;보이시는 화면은 회의 내용을 정리한 기록입니다.&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2028&quot; data-origin-height=&quot;1162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1okRT/dJMcaflL6Rz/bxrkjLEShOfJ1014p56dNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1okRT/dJMcaflL6Rz/bxrkjLEShOfJ1014p56dNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1okRT/dJMcaflL6Rz/bxrkjLEShOfJ1014p56dNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1okRT%2FdJMcaflL6Rz%2FbxrkjLEShOfJ1014p56dNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2028&quot; height=&quot;1162&quot; data-origin-width=&quot;2028&quot; data-origin-height=&quot;1162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;굉장히 많은 아이디어가 나왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;기술면접, 인성면접을 분리해서 서비스를 제공하자는 의견이 있었고,&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;카메라를 연동해서 시선처리 및 표정 변화를 분석하자는 의견이 있었고,&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;질문 별로 꼬리질문을 AI를 활용해 생성하고 이 질문을 바탕으로 면접을 진행하자는 의견도 있었습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;슬라이드에 기록한 내용들 뿐만 아니라 굉장히 많은 아이디어가 있었습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2014&quot; data-origin-height=&quot;1166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZVTiw/dJMcagZgwqs/JL0KcCvLgF9DKdWufiyBlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZVTiw/dJMcagZgwqs/JL0KcCvLgF9DKdWufiyBlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZVTiw/dJMcagZgwqs/JL0KcCvLgF9DKdWufiyBlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZVTiw%2FdJMcagZgwqs%2FJL0KcCvLgF9DKdWufiyBlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2014&quot; height=&quot;1166&quot; data-origin-width=&quot;2014&quot; data-origin-height=&quot;1166&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;우선 아이디어를 모으는 것도 필요하지만, 아이디어를 잘 정리하는것도 중요합니다.
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;저희는 브레인스토밍 과정에서 나온 아이디어를 네 가지 핵심 기능으로 압축했습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;면접 진행 전의 사전 준비,&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;면접 세션 시작,&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;실시간 면접 프로세스,&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;면접 히스토리 관리&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;이렇게 네 가지 핵심 기능으로 프로젝트를 새롭게 정의했습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2040&quot; data-origin-height=&quot;1188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lww7j/dJMcabczPcz/WYG2SK3eOdkLPdKeEf9Oj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lww7j/dJMcabczPcz/WYG2SK3eOdkLPdKeEf9Oj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lww7j/dJMcabczPcz/WYG2SK3eOdkLPdKeEf9Oj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLww7j%2FdJMcabczPcz%2FWYG2SK3eOdkLPdKeEf9Oj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2040&quot; height=&quot;1188&quot; data-origin-width=&quot;2040&quot; data-origin-height=&quot;1188&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;저 핵심 기능 정의를 바탕으로 페이퍼 프로토타입을 간단하게 작성했습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;바로 서비스의 화면을 바탕으로 그리는 것 보다는, 서비스를 추상화 한 구현 단위를 기준으로 생각했습니다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2022&quot; data-origin-height=&quot;1188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4sTWl/dJMcaibKqEL/o0KQivO4r9J7UtSVAWbD1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4sTWl/dJMcaibKqEL/o0KQivO4r9J7UtSVAWbD1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4sTWl/dJMcaibKqEL/o0KQivO4r9J7UtSVAWbD1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4sTWl%2FdJMcaibKqEL%2Fo0KQivO4r9J7UtSVAWbD1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2022&quot; height=&quot;1188&quot; data-origin-width=&quot;2022&quot; data-origin-height=&quot;1188&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;이후, 지금까지 정리한 내용을 바탕으로 유저 플로우를 정리했습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;사전 준비 과정에서는 사용자가 이력서 및 깃허브 리포지토리를 선택하고, 그 내용들을 마크다운으로 요약 및 저장하는 과정을 담고 있습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;면접 세션이 시작된 후에는 사전 준비 과정에서 만들어진 파일들이 어떻게 사용되는지를 나타냅니다.&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2034&quot; data-origin-height=&quot;1170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIcphW/dJMcafe2CpH/tYSHFCO0woaFyqSWsSkQ11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIcphW/dJMcafe2CpH/tYSHFCO0woaFyqSWsSkQ11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIcphW/dJMcafe2CpH/tYSHFCO0woaFyqSWsSkQ11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIcphW%2FdJMcafe2CpH%2FtYSHFCO0woaFyqSWsSkQ11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2034&quot; height=&quot;1170&quot; data-origin-width=&quot;2034&quot; data-origin-height=&quot;1170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;실시간 면접이 진행될 때는 카메라와 마이크 권한을 얻고 웹소켓이 실행됩니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;사용자의 응답과 모습이 웹소켓을 통해 실시간 서버로 전송되고, 실시간 서버는 AI 서버에게 STT를 요청합니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;이후 AI 서버는 음성을 분석해 사용자의 이력서와 포트폴리오 기반의 꼬리질문을 생성하고, 생성된 질문은 실시간 서버를 통해 사용자에게 전달됩니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;면접이 종료된 이후에는 영상 녹화를 종료하고 S3에 해당 비디오 및 기타 파일을 업로드합니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;이후 AI 서버를 통해 면접 피드백을 생성하고 사용자에게 제공합니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1990&quot; data-origin-height=&quot;1134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdsRTb/dJMb99TnHLz/V8M6bkNP09fOWukXmkuz1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdsRTb/dJMb99TnHLz/V8M6bkNP09fOWukXmkuz1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdsRTb/dJMb99TnHLz/V8M6bkNP09fOWukXmkuz1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdsRTb%2FdJMb99TnHLz%2FV8M6bkNP09fOWukXmkuz1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1990&quot; height=&quot;1134&quot; data-origin-width=&quot;1990&quot; data-origin-height=&quot;1134&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;어떻게 구현할지에 대한 청사진으로, 소프트웨어 아키텍처를 작성했습니다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;다만, 이번 발표 주제가 브레인스토밍인만큼 자세한 설명은 생략하고 이후 4.20에 진행될 스프린트에서 상세 내용을 발표하겠습니다.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  기록</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/825</guid>
      <comments>https://13months.tistory.com/825#entry825comment</comments>
      <pubDate>Tue, 31 Mar 2026 16:55:58 +0900</pubDate>
    </item>
    <item>
      <title>[Embedded] Cortex-M4 Processor</title>
      <link>https://13months.tistory.com/822</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 시스템은 일반 PC와 다르게 하나의 기능에 최적화 되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 설계부터가 다름.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 시스템에서는 주변의 아날로그 환경과 상호작용하는 입출력 신호가 굉장히 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2202&quot; data-origin-height=&quot;1206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vK9Cw/dJMcajasFFf/kJWo7SzU3JTyEWtvolkRNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vK9Cw/dJMcajasFFf/kJWo7SzU3JTyEWtvolkRNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vK9Cw/dJMcajasFFf/kJWo7SzU3JTyEWtvolkRNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvK9Cw%2FdJMcajasFFf%2FkJWo7SzU3JTyEWtvolkRNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;615&quot; height=&quot;337&quot; data-origin-width=&quot;2202&quot; data-origin-height=&quot;1206&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flash는 프로그램을 저장하고, SDRAM은 실행 중 데이터를 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPIO는 디지털 I/O를 처리하고, ADC/DAC와 UART는 통신을 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 모든 구성요소들이 하나의 System On a Chip으로 집적된 형태로 구성됨. SoC가 하나의 프로세서라고 보면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SRAM (Static RAM)&lt;/b&gt; 은 전원이 공급될 때는 데이터가 계속 유지되니 주기적인 리프레쉬가 불필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;속도가 가장 중요한 영역에 배치됨.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SDRAM (Synchronous DRAM)&lt;/b&gt; 은 데이터를 유지하기 위해 주기적으로 Refresh를 해줘야함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DRAM은 비동기 방식으로 동작하지만, SDRAM은 클럭 신호에 동기화되어 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대용량 고 대역폭이 필요한 곳에 배치됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Flash Memory&amp;nbsp;&lt;/b&gt;는 전원이 없어도 전하가 유지되니 Non-Volatile하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;UART (Universial Asynchronous Receiver/Transmitter)&lt;/b&gt; 는 임베디드 시스템에서 가장 보편적으로 사용되는 직렬 통신 프로토콜으로, 사전에 합의된 Baud Rate로 데이터를 주고받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세서도 여러 종류가 있음&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU (Central Processor Unit) :&lt;/b&gt; 명령어 처리 중심의 프로세서로 특정 작업을 잘 수행한다기보다는 범용적인 작업을 처리함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DSP (Digital Signal Processor) :&lt;/b&gt; 아날로그 신호를 디지털로 변환해 필터링하거나 신호변환을 처리함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GPU (Graphic Processing Unit) :&lt;/b&gt; 원래는 게임 화면 영상처리 전용 프로세서로 개발됐는데 지금은 AI 가속기로 사용됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;NPU (Neuromorphic Processing Unit) :&lt;/b&gt; AI를 가속시키는 용도의 뉴럴넷 전용 프로세서. TPU도 NPU의 일부임.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MCU (Microcontroller Unit) :&lt;/b&gt; 제어 목적을 위한 소형 프로세서. Cortex M4도 MCU 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연한 말이지만 센서가 수집하는 데이터는 연속적인 성격을 가지지만, 컴퓨터은 이산 데이터만 처리할 수 있으니 변환이 필요함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘은 GPU나 NPU처럼 특정 성격을 가진 칩이 등장하고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPU도 사실은 게임 전용으로 개발됐기에 AI에 완전히 fit하지는 않음. 그래서 엔비디아에서는 트랜스포머를 가속 할 수 있는 회로를 따로 만들어서 판매하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPU 아키텍처는 덧셈 곱셈 연산만 잘해서 범용성이 떨어지니, 센서 I/O나 시스템 부팅처럼 범용적인 작업은 CPU가 담당하고 특정 도메인에서 필요한 연산은 GPU가 담당하는 방식으로 구성된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 Cortex M4 프로세서는 RISC 방식으로 설계됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CISC와 다르게 RISC는 단순한 명령어를 빠르게, 많이 처리할 수 있어 파이프라인 설계가 쉽고 임베디드 시스템에 적합하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핸드폰이나 임베디드 시스템은 개인 PC와 다르게 배터리로 동작하니, 전력을 많이 먹는 CISC보다는 저전력에 유리한 RISC를 사용하는 편이 합리적임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 단순한 구조 기반에 Add-On 방식으로 기능을 붙이는것도 굉장히 쉽고..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 디바이스들도 웬만하면 SoC 방식으로 RISC + a로 설계되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;칩 하나에 다 때려박으면서 최적화도 기가막히게 하는..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ARM Holdings는 Apple과 Acorn과 VLSI가 만든 회사로, 설계도만 만들어서 반도체 회사에게 라이센스 장사를 하는 회사.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 설계도를 삼성, 퀄컴같은 팹리스 회사에게 팔아넘기는 식으로 돈을 벌고있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ARM은 애초에 RISC방식으로 설계된 회사라서 언급.. (Acorn RISC Machines)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RISC-V는 ARM이 수익을 너무 추구해서 새로 도입됐지만, 여전히 ARM의 시장 점유율이 너무 크긴 하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 ARM은 임베디드 프로세서의 신임&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;1256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djlUMw/dJMcagdNdFW/YY8XjAKZwrmWtOoSHfRWA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djlUMw/dJMcagdNdFW/YY8XjAKZwrmWtOoSHfRWA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djlUMw/dJMcagdNdFW/YY8XjAKZwrmWtOoSHfRWA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjlUMw%2FdJMcagdNdFW%2FYY8XjAKZwrmWtOoSHfRWA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;533&quot; data-origin-width=&quot;1422&quot; data-origin-height=&quot;1256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cortex는 A / R / M 계열으로 제품군이 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cortex-Application : 스마트폰이나 태블릿 같은 고성능 앱을 실행할 때 사용됨.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cortex-RealTime : 자동차, SSD 컨트롤러같은 실시간 제어를 다룰 때 사용됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MCortex-Microcontroller : 저전력 제어, 임베디드 MCU를 다룰 때 사용됨.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;1222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRW7Jq/dJMcaaSbTxm/g64yaOKDF1cE4eOKO12ibk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRW7Jq/dJMcaaSbTxm/g64yaOKDF1cE4eOKO12ibk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRW7Jq/dJMcaaSbTxm/g64yaOKDF1cE4eOKO12ibk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRW7Jq%2FdJMcaaSbTxm%2Fg64yaOKDF1cE4eOKO12ibk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;540&quot; height=&quot;601&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;1222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cortex-M4는 MCU + DSP + FPU가 하나로 합쳐진 구조로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MCU :&lt;/b&gt; 저전력, 인터럽트 처리 등 일반 마이크로컨트롤러의 모든 기능을 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DSP :&lt;/b&gt; 뭐 말 그대로.. 신호처리 알고리즘에 사용된다. Single-Cycle MAC 이나 Barrel Shifter 같은..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FPU :&lt;/b&gt; 32비트 부동소수점 연산을 하드웨어로 처리한다. 이게 없으면 float 연산을 소프트웨어로 처리해야 함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 시대에서는 Precision 개념이 점점 더 중요해지고 있음. 그러니 FPU가 좀 중요해짐..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Filter가 곧 Convolution 연산이다. 사실 CNN도 DSP의 필터 연산과 구조가 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 시스템을 설계한다면 인터럽트가 정말 정말 중요하고, 인터럽트를 기반으로 코드를 작성해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;할 일 없으면 Sleep, SSE 처럼 이벤트가 발생할 때만 깨어나도록 하고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 설계하는게 Energy Efficient 하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터럽트로 CPU를 깨울 때는 Clock Pulse를 사용함. Pulse를 올렸다가 내렸다가 반복하는 식.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Clock 속도를 높이면 CPU를 깨우는거고.. Clock 속도를 낮추면 꺼져있다는거고.. 이런식으로 파워 소모를 거의 안 하도록 설계함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Polling 방식을 임베디드 시스템에서 사용한다면 CPU가 계속 풀파워로 돌게 되니 비효율적임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MXjCb/dJMcad2m4ms/RjcWnexI7c1vHIezGWCndK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MXjCb/dJMcad2m4ms/RjcWnexI7c1vHIezGWCndK/img.png&quot; data-origin-width=&quot;2058&quot; data-origin-height=&quot;688&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.8568%; margin-right: 10px;&quot; data-widthpercent=&quot;46.4&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MXjCb/dJMcad2m4ms/RjcWnexI7c1vHIezGWCndK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMXjCb%2FdJMcad2m4ms%2FRjcWnexI7c1vHIezGWCndK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2058&quot; height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bX1bXM/dJMcafeUpIC/K8bU3SXpFymON1CyOyZAI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bX1bXM/dJMcafeUpIC/K8bU3SXpFymON1CyOyZAI1/img.png&quot; data-origin-width=&quot;1334&quot; data-origin-height=&quot;386&quot; data-is-animation=&quot;false&quot; style=&quot;width: 52.9804%;&quot; data-widthpercent=&quot;53.6&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bX1bXM/dJMcafeUpIC/K8bU3SXpFymON1CyOyZAI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbX1bXM%2FdJMcafeUpIC%2FK8bU3SXpFymON1CyOyZAI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1334&quot; height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prefetch 버퍼가 3개의 명령어를 미리 읽어두기에, CPU가 현재 명령어를 실행하는 동안 다음 명령어를 해석하고 다음 명령어를 메모리에서 가져올 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 그림 보면 어떻게 동작하는지 보임. 1 Cycle in N Instruction이 된다는것.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 분기가 없는 순차적 코드에서는 Cycle Per Instruction = 1 을 달성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prefetch 버퍼는 word 3개를 저장하는데, 메모리를 끌어다가 사용하는 경우 CPI &amp;gt; 1 가 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에서 값을 읽어오는 명령은 Execute 단계에서 주소 계산 -&amp;gt; 메모리 접근 -&amp;gt; 데이터 가져오기 순서대로 이루어진다. 핵심은 메모리 접근 자체가 추가 사이클을 먹는것.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분기문은 사이클을 더 먹을 수 밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분기 명령어가 Execute에 들어가야 어디로 점프할지가 결정되니 파이프라인을 비우고 정리해 줘야 함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 분기가 없는 순차 코드는 CPI = 1이 되지만 분기가 등장하면 사이클 낭비가 생긴다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어 집합은 &lt;b&gt;Thumb-2&lt;/b&gt;를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cortex-A 계열은 ARM 32-bit Instruction Set Architecture를 사용하는데, 모든 명령어가 32비트를 사용하고 조건부 실행해야 해 임베디드 시스템에서는 적합하지 않음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thumb 16-bit를 사용하면 ARM 32bit를 16bit로 압축해서 코드 밀도를 향상시킬 수 있지만, 성능은 잘 안 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cortex-M 계열에서 사용하는 Thumb-2는 16비트와 32비트를 혼합해서 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 시스템에서는 메모리를 정말 잘 최적화하고 아껴써야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 ADD 명령어 하나를 실행할 때도 컴파일 했을 때 4바이트 인 것 보다는 2바이트인게 훨씬 좋으니까.. 컴파일 옵션에서 Thumb-2를 사용한다면 원래 32비트짜리를 16비트로 사용할 수 있으니 메모리를 절약할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 이러면 해석가능한 명령어의 수가 줄어들고, 접근 가능한 레지스터의 수도 줄어든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 32비트 명령어를 일부에서는 사용한다는 컨셉의 Thumb 2를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세서는 명령어를 가져올 때 첫 16비트를 보고 해당 명령어가 16비트인지 32비트인지 판단함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;1208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/70DKU/dJMcajuMia2/3DJTYGueeP0kduutgPNbJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/70DKU/dJMcajuMia2/3DJTYGueeP0kduutgPNbJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/70DKU/dJMcajuMia2/3DJTYGueeP0kduutgPNbJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F70DKU%2FdJMcajuMia2%2F3DJTYGueeP0kduutgPNbJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;555&quot; height=&quot;433&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;1208&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;R0 ~ R7 레지스터는 16비트 Thumb 명령어도 접근할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 자주 쓰이는 레지스터지만, 16비트 명령어는 인코딩 공간이 작아서 3비트밖에 표현할 수 없어 R0 ~ R7까지만 접근 가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;R8 ~ R12 레지스터는 32비트 명령어로만 접근할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;R13 레지스터는 Stack Pointer로, CONTROL 레지스터 비트 1에 따라 두 가지 스택 포인터를 선택한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Main Stack Pointer로 사용되거나 Process Stack Pointer로 사용됨.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;R14 레지스터는 Link Register로 서브루틴을 호출했을 때 복귀 주소를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;R15 레지스터는 다음에 실행할 명령어의 주소를 저장한다. 다만!! 리셋했을 때는 0x0000_0004 에서 시작함!!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제에서 다 다뤘던거 같긴 함&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science/Embedded Software</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/822</guid>
      <comments>https://13months.tistory.com/822#entry822comment</comments>
      <pubDate>Wed, 18 Mar 2026 16:50:10 +0900</pubDate>
    </item>
    <item>
      <title>[Data Science] Decision Tree &amp;amp; Regularization</title>
      <link>https://13months.tistory.com/821</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Decision Tree는 데이터를 분류하기 위해 Y/N 으로 구성된 트리 구조로 이어붙인 모델. 아이디어는 굉장히 단순함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이걸 어떻게 학습시키는지가 문제..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2208&quot; data-origin-height=&quot;966&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mgiRG/dJMcagx28WU/A6bFIbx9qrUTQwnXwfSNO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mgiRG/dJMcagx28WU/A6bFIbx9qrUTQwnXwfSNO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mgiRG/dJMcagx28WU/A6bFIbx9qrUTQwnXwfSNO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmgiRG%2FdJMcagx28WU%2FA6bFIbx9qrUTQwnXwfSNO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;684&quot; height=&quot;299&quot; data-origin-width=&quot;2208&quot; data-origin-height=&quot;966&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Training ML 모델 중 제일 많이 사용되는 모델으로, 딥러닝 모델처럼 Training Data를 완벽하게 설명할 수 있도록 학습된다는 공통점이 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 일단 오버피팅으로 만들고 Training과 Validate가 비슷해지도록 조작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델을 처음부터 적당히 학습시키려고 하면 어디에서 멈춰야 하는지에 대한 기준이 없음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 일단 Training Set을 제대로 설명하는 복잡한 모델을 만들고, Validation Set 성능을 보면서 Complexity를 줄여나가는 식으로..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝에서는 Early Stopping, Dropout 등으로 구현되고 Decision Tree에서는 Prunning, max_depth 제한으로 구현된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;depth를 조작할 때는 Validation Accuracy를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;depth가 커지면 Training Accuracy는 계속 오르지만 Validation Accuracy는 점점 떨어지고, 그 떨어지는 지점이 최적 depth.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prunning은 서브트리 전체를 Leaf 노드로 교체했을 때 Validation 성능이 비슷하다면 더 단순한 쪽을 선택한다는 것.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 뒤에 설명할 Random Forest 방식이 훨씬 편함..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 분기점에서 Feature를 기준으로 데이터를 둘로 나누고, 더 이상 나눌 수 없거나 종류가 하나만 남는 경우 그게 리프 노드가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 질문을 선택해야지 데이터가 잘 분리될까?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 계산할 때는 Entropy개념을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드 하나에 여러 클래스가 섞여있다면 엔트로피가 높고 클래스가 하나밖에 없다면 엔트로피가 0이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 Weighted Entropy를 계산해 이 값이 가장 작은 split을 선택한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cP8pAR/dJMcaaLotyA/kVOD2BwwOqmxi6fN6ouK90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cP8pAR/dJMcaaLotyA/kVOD2BwwOqmxi6fN6ouK90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cP8pAR/dJMcaaLotyA/kVOD2BwwOqmxi6fN6ouK90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcP8pAR%2FdJMcaaLotyA%2FkVOD2BwwOqmxi6fN6ouK90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;452&quot; height=&quot;178&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나눠진 두 자식 노드의 엔트로피를 각 노드의 비율로 가중평균 값을 계산함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저거만 보고도 유추할 수 있듯 그리디하게 눈앞에서 가장 좋은 split을 고르기에 Training Data의 노이즈까지 학습하게 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Feature간에 클래스가 잘 나뉘지 않는 경우 경계선이 매우 복잡해지고.. 이 복잡한 경계선은 Test Data에 fit하지 않게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오버피팅을 막기 위한 방식으로 여러가지가 있음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Random Forest&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완전히 자라난 Decision Tree는 Training Data에 맞춰서 Overfit 되고, 데이터를 조금만 바꿔도 완전히 다른 트리가 나타난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 Overfit된 트리 여러 개를 조합한다면 편향이 작고 분산도 낮아지지 않을까?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 아이디어를 Bagging이라고 부름. (Bootstrap AGGregatING)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 데이터에서 복원추출로 T개의 데이터셋을 생성하고, 각 데이터셋으로 Decision Tree를 구축한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예측 할 때는 T개의 Decision Tree의 결과를 다수결로 계산하는 식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bagging 으로는 제일 처음에 강한 Feature가 분리 기준으로 선택되니 트리가 서로 비슷해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 매 split마다 전체 Feature 중 무작위로 m개만 후보로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 각 Decision Tree가 다른 방식으로 오버피팅되고 다양성이 확보됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Gradient Boosting&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bagging은 트리를 병렬로 만들어 다수결로 예측하는 방식이고, Boosting은 순차적으로 약점을 보완하는 방식이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 모델의 잔차를 다음 모델에게 전달해 오차를 줄이는 방식임.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수학적으로는 Gradient Descent와 동일한 방식임.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Residual은 곧 MSE 손실과 비슷하기에..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 Learning Rate를 결정할 때도 Gradient Descent에서 사용한 방식을 그대로 활용할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 트리를 더할 때 Learning Rate 만큼만 반영하는 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gradient Boosting은 Theta가 아니라 예측값 자체를 직접 업데이트한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 잔차 방향으로 예측값을 조금씩 개선하는 방식임.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Weak Learner를 모아서 강력한 모델 하나를 구축하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델을 평가하고 하이퍼파라미터를 튜닝할 때는 Test Set을 여러 번 쓰면 안됨.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test Set 정보는 절대 절대 모델이 학습하면 안된다. 그러니 &lt;b&gt;K-Fold Cross Validation&lt;/b&gt;을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1680&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n2HrW/dJMcagkwola/b6oBfVuvI8Tspi1jKxd82K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n2HrW/dJMcagkwola/b6oBfVuvI8Tspi1jKxd82K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n2HrW/dJMcagkwola/b6oBfVuvI8Tspi1jKxd82K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn2HrW%2FdJMcagkwola%2Fb6oBfVuvI8Tspi1jKxd82K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;723&quot; height=&quot;360&quot; data-origin-width=&quot;1680&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 성능은 K번 Val 성능의 평균으로 측정되고, 이 값을 기준으로 모델을 선택하고 하이퍼파라미터를 튜닝한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터가 정말 충분하다면 이걸 굳이 안해도 되지만.. 데이터가 적으면 해줘야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 Accuracy를 모사하기 위해 전체 데이터를 k개의 fold로 나누고 성능 확인 후 각 모델의 성능을 측정해 평균 측정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 머신러닝을 한다는 건, 데이터 분포가 있다는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 데이터를 볼 수 없으니 모델을 가지고 테스트 한다는건데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 강조해보면 모델 튜닝에 Test Set이 노출되는건 절대로 막아야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Validation을 테스트처럼 써야하는데 이걸 지키지 않는 논문들도 많다고 한다..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 관측하는 모든 데이터에는 항상 노이즈가 섞여서 들어온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 노이즈는 무작위성을 가지기에 데이터셋을 뽑을 때 마다 y값이 달라짐.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJB6Dl/dJMcaflDGL8/Z7D3erzVmxl3mdjiyFzgZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJB6Dl/dJMcaflDGL8/Z7D3erzVmxl3mdjiyFzgZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJB6Dl/dJMcaflDGL8/Z7D3erzVmxl3mdjiyFzgZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJB6Dl%2FdJMcaflDGL8%2FZ7D3erzVmxl3mdjiyFzgZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;645&quot; height=&quot;394&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터셋이 2차식 형태를 띄고, 함수도 2차식 형태를 띈다면 잘 맞출 수 있지만, 더 낮은 차원을 사용하거나 더 높은 차원을 사용한다면 Variance가 너무 낮거나 또 너무 높아질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 데이터를 무작위로 뽑으면 Theta도 무작위이고, 함수도 무작위로 결정된다는게 중요함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 같은 입력에 대해서도 예측값이 학습마다 달라질 수 있다는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 기반으로 다시 개념을 정의해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Model Bias&lt;/b&gt; : 여러 번 학습했을 때 예측값의 평균이 실제값에서 얼마나 체계적으로 벗어나는가?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Model Variance&lt;/b&gt; : 학습 데이터가 조금 달라졌을 때 예측값이 얼마나 흔들리는가?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Model Risk&lt;/b&gt; : 모델 예측값과 실제 관측값 사이의 평균 제곱 오차.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순할수록 Bias가 높고, 복잡할수록 Variance가 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 성능 지표로 Bias와 Variance를 동시에 반영하는 Model Risk를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2088&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjmWFE/dJMcadBg9TI/hsVkXKYih7aoNjHf35GUv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjmWFE/dJMcadBg9TI/hsVkXKYih7aoNjHf35GUv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjmWFE/dJMcadBg9TI/hsVkXKYih7aoNjHf35GUv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjmWFE%2FdJMcadBg9TI%2FhsVkXKYih7aoNjHf35GUv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;725&quot; height=&quot;156&quot; data-origin-width=&quot;2088&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식을 잘 정리해보면 Model Risk가 절대 조작할 수 없는 Irreducible Error, Bias, Variance로 구성됨을 확인할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Variance를 줄이려면 모델을 단순하게 만들어야 하는데 이러면 Bias가 올라가고.. Bias를 줄이려면 모델을 복잡하게 만들어야 하는데 이러면 Variance가 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2336&quot; data-origin-height=&quot;862&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BInQm/dJMcacvHCrk/khKEz5HCXfeQC6uRcgtbNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BInQm/dJMcacvHCrk/khKEz5HCXfeQC6uRcgtbNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BInQm/dJMcacvHCrk/khKEz5HCXfeQC6uRcgtbNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBInQm%2FdJMcacvHCrk%2FkhKEz5HCXfeQC6uRcgtbNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;648&quot; height=&quot;239&quot; data-origin-width=&quot;2336&quot; data-origin-height=&quot;862&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 최적의 Point를 찾아야 함. 그게 그래프에서의 최소 지점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적의 Complexity를 찾은 후에는 저걸 직접 제어할 수 있어야 함. Regularization을 수행 할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Parameter가 너무 커지지 않도록 Q값을 도입한다. Q가 작으면 모델이 단순해지고, Q가 크면 복잡해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;952&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvn2Ln/dJMcaibB2vh/tbHUsfJNq44F279StZvWi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvn2Ln/dJMcaibB2vh/tbHUsfJNq44F279StZvWi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvn2Ln/dJMcaibB2vh/tbHUsfJNq44F279StZvWi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbvn2Ln%2FdJMcaibB2vh%2FtbHUsfJNq44F279StZvWi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;634&quot; height=&quot;104&quot; data-origin-width=&quot;952&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1928&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yNBeC/dJMcafsogfC/CPOYqnT7onTZtryswkQzN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yNBeC/dJMcafsogfC/CPOYqnT7onTZtryswkQzN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yNBeC/dJMcafsogfC/CPOYqnT7onTZtryswkQzN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyNBeC%2FdJMcafsogfC%2FCPOYqnT7onTZtryswkQzN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;216&quot; data-origin-width=&quot;1928&quot; data-origin-height=&quot;636&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Regularization이 없을 때의 OLS Theta Hat은 Loss를 완전히 최소화하는 지점에 위치해 파라미터 값이 굉장히 크다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델이 Training Data에 완전히 맞추기 때문.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 파라미터 합이 Q보다 작아야 한다는 Regularization을 걸어버리면 원래의 최솟값이 되는 지점은 제약 밖에 위치하기에 도달할 수 없고, 제약 영역 안에서 Loss가 가장 작은 Theta를 찾아야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;L1 에서는 제약 영역이 다이아몬드 형태로 이루어지고 L2 에서는 제약 영역이 원형으로 이루어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원형에서는 등고선이 곡선 위에서 만나니 모든 Feature가 유지된다 정도만 알면 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다이아몬드 형태에서는? Theta가 0이 될 가능성이 있어 Feature가 사라질 수도 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2142&quot; data-origin-height=&quot;786&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yc4qr/dJMcabcrE1Z/3iCpzThASjnwP1s4pQPhvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yc4qr/dJMcabcrE1Z/3iCpzThASjnwP1s4pQPhvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yc4qr/dJMcabcrE1Z/3iCpzThASjnwP1s4pQPhvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyc4qr%2FdJMcabcrE1Z%2F3iCpzThASjnwP1s4pQPhvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;250&quot; data-origin-width=&quot;2142&quot; data-origin-height=&quot;786&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;L1이든 L2든 제약식을 사용할 때는 특정 영역 밖으로 나가면 안된다는 식을 풀어야 하기에 최적화하기 힘들다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 제약식을 페널티식으로 변형하면 최솟값을 찾는 문제로 바뀌게 되고, Gradient Descent를 그대로 사용할 수 있어 최적화하기 편함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Q값이나 lambda값은 모델의 일부가 아닌 하이퍼파라미터일 뿐이니 마찬가지로 Validation Accuracy를 보고 결정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science/Data Science</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/821</guid>
      <comments>https://13months.tistory.com/821#entry821comment</comments>
      <pubDate>Sat, 14 Mar 2026 13:23:46 +0900</pubDate>
    </item>
    <item>
      <title>[Data Science] Regression &amp;amp; Classification</title>
      <link>https://13months.tistory.com/820</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머신러닝에서 이미 공부한 내용이지만 간단하게 훑어보고 넘어가자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2672&quot; data-origin-height=&quot;930&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccjU14/dJMcafzaTCQ/dkDWFiBtAK42TC6QpwSAHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccjU14/dJMcafzaTCQ/dkDWFiBtAK42TC6QpwSAHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccjU14/dJMcafzaTCQ/dkDWFiBtAK42TC6QpwSAHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccjU14%2FdJMcafzaTCQ%2FdkDWFiBtAK42TC6QpwSAHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;713&quot; height=&quot;248&quot; data-origin-width=&quot;2672&quot; data-origin-height=&quot;930&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Regression 에서 Model은 그냥 함수로 생각하면 됨. Constant Model은 평균값을 뱉어내는 함수로 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저기서 Theta는 Parameter로, 데이터를 통해 추정하는 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중력가속도 g도 사실 계산을 통해 얻은 값이니 Parameter라고 볼 수 있음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수식에서 x y 값은 그냥 주어지는 값이니까 Parameter가 아니다. 저기서는 x y 값이 Constant.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Theta에 hat이 붙어있으면 Estimated Parameter로 Best Fit한 Parameter라고 보면 됨.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;hat이 붙어있지 않으면 Model Parameter.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델링 과정은 크게 4가지로 구분된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Choose a Model&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Constant Model은 항상 같은 값을 출력할거고.. Linear Model은 직선 형태고.. Polynomial Model은 곡선 형태일거고..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인 지식이나 데이터 시각화를 참고해서 적절한 모델을 선택한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Choose a Loss Function&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Loss Function은 Theta hat이 얼마나 틀렸는지를 측정하는 함수.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, Model을 판단하는 Metric을 의미한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 맞추면 낮은 값을, 잘 못 맞췄으면 높은 값을 부여해 모델을 평가함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Loss는 틀린 정도를 의미하기에 작을수록 좋은 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 가지 Loss Function이 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DOzFJ/dJMcaiJnqWb/cnuunwgFQeYWmkoiZKqqWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DOzFJ/dJMcaiJnqWb/cnuunwgFQeYWmkoiZKqqWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DOzFJ/dJMcaiJnqWb/cnuunwgFQeYWmkoiZKqqWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDOzFJ%2FdJMcaiJnqWb%2FcnuunwgFQeYWmkoiZKqqWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;562&quot; height=&quot;198&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;490&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;L2 Loss (MSE), L1 Loss (MAE) ...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;L2 Loss는 오차를 제곱하기에 이상치에 매우 민감하고, L1 Loss는 절댓값이라 이상치의 영향이 상대적으로 작다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Training Data로 오차를 최소화하는 Theta Hat을 결정하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Validation Data로 Loss Function, 모델 구조, HyperParameter 튜닝 등을 결정하고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test Data로 최종 성능을 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경험상 MSE를 사용하면 큰 문제가 없다고 함.. 여러 Loss를 혼합해서 사용할 때는 Absolute Loss를 사용하는 편.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Fit the Model&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fitting은 Loss Function을 최소화하는 Theta Hat을 찾는 과정이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까도 말했듯 Loss Function의 입력은 Theta이고, x y 는 Constant.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최소화 할 때는 당연히 미분해서 0이 되는 지점을 찾는 방식을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. Evaluate Model Performance&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Evaulation은 학습된 모델이 얼마나 잘 Fitting 됐는지 확인하는 작업이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSE에 루트를 씌운 RMSE를 쓰면 원래 데이터와 단위가 같아져 해석이 편함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평균적으로 예측값이 원래 값보다 얼마나 벗어났는지를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Residual을 구하고 시각화하면 모델의 문제점을 파악할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시각화 했을 때 무작위로 잘 퍼져있다면 잘 Fitting 됐음을 의미하고, 특정 패턴이 보이면 모델이 데이터 구조를 잘 못 잡고 있는것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터는 실제 패턴과 노이즈로 구성되고, 잔차는 모델이 못 잡은 부분과 노이즈로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 패턴이 있다는 건 아직 잡지 못한 구조가 남아있다는거임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Simple Linear Regression은 Feature&lt;/b&gt;가 1개고, &lt;b&gt;Multiple Linear Regression&lt;/b&gt;은 Feature가 여러 개로 구성된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 Feature가 여러 개라고 해도 Theta에 대해서는 여전히 Linear하기에 Linear Regression.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4단계로 구성되는건 똑같은데, 수식이 행렬로 바뀌면서 기하학적 해석만 조금 달라짐.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Loss Function은 L2 Loss의 제곱으로 표현할 수 있고, Fitting에서는 Subspace와 Projection이 적용되어 수식이 조금 달라짐.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 오버피팅이 발생할 수 있으니 Feature가 늘어날수록 모델이 무조건 좋아지지는 않는다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 계산은 모두 비선형적으로 연결되어있고, 단순하게 최적화 할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 &lt;b&gt;Gradient Descent&lt;/b&gt;를 사용함. 오차의 최소를 찾아가는 방식으로, 이미지 보면 직관적으로 이해할 수 있음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2592&quot; data-origin-height=&quot;936&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2TmOP/dJMcagx2VaT/Qvu07TMU9LsCqBvknG3Kuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2TmOP/dJMcagx2VaT/Qvu07TMU9LsCqBvknG3Kuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2TmOP/dJMcagx2VaT/Qvu07TMU9LsCqBvknG3Kuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2TmOP%2FdJMcagx2VaT%2FQvu07TMU9LsCqBvknG3Kuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;683&quot; height=&quot;247&quot; data-origin-width=&quot;2592&quot; data-origin-height=&quot;936&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Global 값을 찾을 수는 없다. Local Minimum을 찾는게 다임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기울기에 비례해서 움직이되, Learning Rate로 스케일을 조절함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Learning Rate Scheduling 을 사용해서 알파 값을 조작하는데.. 이거 관련해서는 휴리스틱하게 찾아가는 편.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Convex 하다면 Local 값이 Global 값임을 보장할 수 있지만, Non-Convex 하더라도 충분히 성능이 좋기에 그 부분이 크게 중요하지는 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Parameter가 여러 개면 각각 편미분하고 동시에 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Batch Gradient Descent에서 Theta를 한 번 업데이트 하려면 n개 데이터 전부의 Gradient를 모두 더해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n이 100만이면? 업데이트 한 번 할때 100만번 계산해야 하는 것.. 너무 너무 비효율적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 &lt;b&gt;Mini Batch Stochastic Gradient Descent&lt;/b&gt;를 사용함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 Mini Batch는 데이터를 잘라내고 각 set마다 Theta를 업데이트 하는데 사용하는 방식이고, Stochastic은 잘라낸 덩어리를 순서대로 자르지 않고 무작위로 섞어서 구성하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 노이즈가 있을텐데 학습이 제대로 될까?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 된다고 함.. 오히려 Non-Convex 에서 Local Minimum을 탈출하는데 도움이 될 때도 있고 ..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linear Regression은 연속적인 숫자를 예측한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카테고리를 예측해야 할 때는 Classification을 사용하는데, Regression으로 Classification을 수행하기 위해 Regression 값을 0~1 사이의 확률값으로 변환해서 Classification에 사용한다. 그리고 이걸 &lt;b&gt;Logistic Regression&lt;/b&gt; 이라고 부름.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 Regression이나 Classification이나 계산 구조는 같음. 출력이 실수인지 카테고리인지만 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확률값 변환만 해주면 그냥 같은 문제.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 확률값으로 변환함?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Odds&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;p가 확률이라고 치면 Odds를 p / (1-p) 로 정의할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 값의 범위는 0 ~ 무한&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Logit (Log-Odds)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Odds 에다가 로그 씌우면 됨. 이러면 범위가 -무한 ~ +무한으로 바뀐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Sigmoid (Logit의 역함수)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;p 에 대해서 식을 풀어주면 0 ~ 1 사이 확률을 반환하는 이쁜 함수가 나옴&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수를 활용하면 Real Value를 통해 확률값을 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2618&quot; data-origin-height=&quot;1388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/binZza/dJMcafeTBGg/xpN6uXjJKlHefnwKxkXs10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/binZza/dJMcafeTBGg/xpN6uXjJKlHefnwKxkXs10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/binZza/dJMcafeTBGg/xpN6uXjJKlHefnwKxkXs10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbinZza%2FdJMcafeTBGg%2FxpN6uXjJKlHefnwKxkXs10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;325&quot; data-origin-width=&quot;2618&quot; data-origin-height=&quot;1388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 피쳐 받고 계산하고.. Non Linear한 시그모이드를 거쳐서 확률값을 뱉는 과정임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Loss Function으로는 MSE 대신 Cross-Entropy Loss를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sigmoid와 MSE를 조합하면 Loss Surface가 Non-Convex 하게 되니 Gradient Descent로 Global 값을 찾는게 어려워진다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애초에 CE Loss 자체는 Convex하고, n개를 평균낸 Empirical Risk도 Convex 상태를 유지함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2386&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yXdIp/dJMcadBgz4v/geppyrv7ky3hOdD1iiU9Gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yXdIp/dJMcadBgz4v/geppyrv7ky3hOdD1iiU9Gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yXdIp/dJMcadBgz4v/geppyrv7ky3hOdD1iiU9Gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyXdIp%2FdJMcadBgz4v%2Fgeppyrv7ky3hOdD1iiU9Gk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2386&quot; height=&quot;224&quot; data-origin-width=&quot;2386&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;y가 1일 때는 p가 0에 가까울수록 loss가 폭발적으로 커진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;틀렸을 때 강하게 페널티를 준다는 것.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 CE Loss를 최소화하는건 결국 MLE와 수학적으로 동치임. (식정리 잘 해보면 알 수 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 데이터가 주어졌을 때 이 데이터가 나올 확률을 최대화하는 Theta를 찾는게 결국 Cross Entropy Loss를 최소화하는 Theta를 찾는거랑 같은 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 데이터가 Linear Separable하면 Theta를 무한히 키울수록 Loss가 계속 작아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 최솟값이 없으니 학습이 안됨..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linear Separable 하다는거는 데이터를 분류하는 하나의 선이 있다는건데, Separable 데이터에서는 Theta가 클수록 Sigmoid가 Step Function처럼 변한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 Loss를 최소화하는 Theta가 무한이라는거임; 그 값에 도달할 수 없으니 Gradient Descent가 멈추지 않고 Theta를 키우면서 발산하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 Loss 값에 가중치 제곱합을 추가하는 L2 Regularization을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1978&quot; data-origin-height=&quot;804&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cT56AW/dJMcah4O2Ea/41zT1lQljNTWEpNKpJzHnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cT56AW/dJMcah4O2Ea/41zT1lQljNTWEpNKpJzHnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cT56AW/dJMcah4O2Ea/41zT1lQljNTWEpNKpJzHnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcT56AW%2FdJMcah4O2Ea%2F41zT1lQljNTWEpNKpJzHnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;663&quot; height=&quot;269&quot; data-origin-width=&quot;1978&quot; data-origin-height=&quot;804&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Theta가 너무 커지더라도 Regularization 항이 페널티를 주기에 Theta 크기가 제한된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델을 평가할 때 Accuracy만 보는건 문제가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스팸메일 분류할 때 스팸 5개 정상95개 데이터에서 전부 정상이라고만 해도 Accuracy가 95%가 나옴.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 Confusion Matrix 그려서 Precision, Recall, ROC Curve, AUC 를 사용해 모델을 종합적으로 평가함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수식 외우지 말고 이해하기&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Accuracy는 전체 중 제대로 맞춘거의 비율으로 단순하지만 데이터가 불균형하면 뻥튀기 가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Precision은 예측 양성에서 제대로 맞춘거의 비율으로 얼마나 신뢰할 수 있는지를 의미.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Recall은 실제 양성에서 제대로 맞춘거의 비율으로 숨어있는 양성을 얼마나 잘 맞췄는지를 의미.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;F1 Score는 TN을 안쓰니 클래스 불균형 상태에서는 Accuracy 대신 F1 Score를 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science/Data Science</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/820</guid>
      <comments>https://13months.tistory.com/820#entry820comment</comments>
      <pubDate>Sat, 7 Mar 2026 19:55:47 +0900</pubDate>
    </item>
    <item>
      <title>[Fault Detection] Synergy of Environmental Sensing and Voltage Control: A Dual-Factor Analysis of DRAM RowHammer</title>
      <link>https://13months.tistory.com/815</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RowHammer는 DRAM row 근처를 집중적으로 때릴 때 해당 row에 Bit-Flip이 발생하는 취약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 연구는 Hardware Counter Performance 지표만 사용해서 Bit-Flip을 관찰했다면, 이번 논문에서는 하드웨어 외부 환경인 온도를 함께 관찰한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공장에서 돌아가는 엣지 디바이스들은 외부 환경이 중요할거니까.. HPC 데이터 외에도 외부 환경 데이터를 읽어야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;꼭 공장이 아니더라도 무거운 연산을 수행하다 보면 시스템 온도를 변화시킬 수 있고, 이 온도는 해커의 공격으로 활용될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, Bit-Flip을 온도 센서로 활용하는거임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 논문은 IoT 디바이스에서 DRAM의 온도를 감시하는 새로운 RowHammer 공격인 SpyHammer를 제안한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 DRAM 모델마다 RowHammer 공격과 온도 간의 상관관계가 서로 다름.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SK Hynix, Micron에서 제조한 DRAM은 온도가 올라가면 BER이 증가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 Samsung에서 제조한 DRAM은 온도가 올라가면 오히려 BER이 감소한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7PRcQ/dJMcafeuYbe/p2pDuK7ZivkiJNB4dgQbtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7PRcQ/dJMcafeuYbe/p2pDuK7ZivkiJNB4dgQbtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7PRcQ/dJMcafeuYbe/p2pDuK7ZivkiJNB4dgQbtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7PRcQ%2FdJMcafeuYbe%2Fp2pDuK7ZivkiJNB4dgQbtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;580&quot; height=&quot;540&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제조사마다 상관관계의 방향이 다르고 절대적인 에러 개수가 칩마다 다르지만, 같은 모델에 대해 온도가 n도 변할 때 BER이 변하는 정도를 그래프로 시각화하면 똑같이 나타남을 확인할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 공격자는 DRAM과 똑같은 모델을 구매해서 테스트해보고 그래프를 그려본다면 시스템의 에러 변화만 보고 온도를 측정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SpyHammer는 에러가 났는지 안 났는지에 집중하는게 아니라, 에러의 개수와 온도의 관계를 측정하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DRAM Bender를 사용해 온도를 조절하고, 간섭을 제거해 모든 에러가 RowHammer때문에 터지는 환경을 구축함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;50도에서 95도까지 1도 단위로 테스트 했을 때 온도 변화를 측정해보면 아래와 같이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4PVz9/dJMcaiWwoJB/R642lfFdaxr3nuoBVZQTJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4PVz9/dJMcaiWwoJB/R642lfFdaxr3nuoBVZQTJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4PVz9/dJMcaiWwoJB/R642lfFdaxr3nuoBVZQTJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4PVz9%2FdJMcaiWwoJB%2FR642lfFdaxr3nuoBVZQTJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;585&quot; height=&quot;472&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제조사별로 온도와 BER간의 상관관계를 보여준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삼성 말고는 온도가 증가함에 따라 Bit-Flip Per Row 도 증가함을 확인할 수 있음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;766&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b63yE2/dJMcabXqosM/6HbmpKi9gxBY76G7Kz5mRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b63yE2/dJMcabXqosM/6HbmpKi9gxBY76G7Kz5mRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b63yE2/dJMcabXqosM/6HbmpKi9gxBY76G7Kz5mRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb63yE2%2FdJMcabXqosM%2F6HbmpKi9gxBY76G7Kz5mRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;555&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;766&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DRAM 모듈을 48개의 영역으로 쪼개서 테스트해보면 DRAM의 어느 부분을 때려도 온도와 에러의 상관관계가 동일하게 나타남을 알 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 DRAM이면 다 적용할 수 있다는거임.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oxPik/dJMcahQSC4m/dyiVt2E6XKmSDC7t1wdF61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oxPik/dJMcahQSC4m/dyiVt2E6XKmSDC7t1wdF61/img.png&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;812&quot; data-is-animation=&quot;false&quot; style=&quot;width: 47.5694%; margin-right: 10px;&quot; data-widthpercent=&quot;48.13&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oxPik/dJMcahQSC4m/dyiVt2E6XKmSDC7t1wdF61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoxPik%2FdJMcahQSC4m%2FdyiVt2E6XKmSDC7t1wdF61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;814&quot; height=&quot;812&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uOwoC/dJMcahQSC4l/ghyT0YHZyBxpaVzfkGkMU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uOwoC/dJMcahQSC4l/ghyT0YHZyBxpaVzfkGkMU1/img.png&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;796&quot; data-is-animation=&quot;false&quot; style=&quot;width: 51.2678%;&quot; data-widthpercent=&quot;51.87&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uOwoC/dJMcahQSC4l/ghyT0YHZyBxpaVzfkGkMU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuOwoC%2FdJMcahQSC4l%2FghyT0YHZyBxpaVzfkGkMU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;860&quot; height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 온도와 공격자가 추측한 온도의 차이를 관찰해보면, 정규분포와 비슷한 형태를 확인할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 오차가 0일 확률이 가장 높은 것.. DRAM의 특성을 미리 알고 있다면 오차 없이 온도를 예측할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SpyHammer의 목표는 DRAM의 Bit-Flip을 온도계로 사용해 DRAM의 온도를 추정하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &quot;RowHammer 공격을 수행했더니 에러가 n개 발생했다&quot;라는 정보를 사용해 그 디바이스의 온도를 예측한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 큰 주제는 외부 환경 + HPC 지표로 Fault Detection 모델을 구현하는거니까, 온도 말고도 다른 요인을 고려할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 전압을 고려해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Wordline은 전선으로 생각해면 됨. 워드라인 전압 (Vpp)는 전선에 가해주는 전압을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RowHammer로 DRAM의 특정 row를 계속 때리면 해당 row의 Wordline 전압을 저전압과 고전압 사이에서 번갈아 변화시킬 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Wordline 전압이 흔들리면 해당 row와 인접한 row에서 간섭이 발생해 Bit-Flip으로 이어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 논문에서는 Vpp를 낮춰서 Bit-Flip을 줄이자는 접근을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제조사는 DRAM을 만들 때 최악의 상황을 가정해 Guardband를 넉넉하게 잡으니 이걸 조금만 깎아서 RowHammer 방어에 사용한다는 전략을 사용함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vpp를 낮추면 인접한 row에 가해지는 강도 자체가 약해지기에 RowHammer를 통한 Bit-Flip 성공률이 낮아질 수 밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DRAM 테스트 플랫폼인 SoftMC를 수정해서 테스트 인프라를 구축함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UxNHX/dJMcadnnacs/lggdO8UvLuf1CIE22Spbk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UxNHX/dJMcadnnacs/lggdO8UvLuf1CIE22Spbk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UxNHX/dJMcadnnacs/lggdO8UvLuf1CIE22Spbk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUxNHX%2FdJMcadnnacs%2FlggdO8UvLuf1CIE22Spbk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;660&quot; height=&quot;228&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전압이 낮아질수록 Bit-Flip이 감소한다. 2.5V가 정상 전압이고, 왼쪽으로 갈수록 전압이 낮아짐.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BER을 정규화해서 2.5V일 때 1.0만큼의 에러가 발생했다면 Vpp를 낮출수록 에러가 낮아짐을 확인할 수 있음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kKnwy/dJMcaiCedj2/kl7jyWIpU05cSNlR5QskB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kKnwy/dJMcaiCedj2/kl7jyWIpU05cSNlR5QskB1/img.png&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;512&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.7863%; margin-right: 10px;&quot; data-widthpercent=&quot;50.37&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kKnwy/dJMcaiCedj2/kl7jyWIpU05cSNlR5QskB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkKnwy%2FdJMcaiCedj2%2Fkl7jyWIpU05cSNlR5QskB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1518&quot; height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlYdsU/dJMcadVcEgU/tjFCzmqJs3neBAV2WsC8x0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlYdsU/dJMcadVcEgU/tjFCzmqJs3neBAV2WsC8x0/img.png&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;380&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.0509%;&quot; data-widthpercent=&quot;49.63&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlYdsU/dJMcadVcEgU/tjFCzmqJs3neBAV2WsC8x0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlYdsU%2FdJMcadVcEgU%2FtjFCzmqJs3neBAV2WsC8x0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1110&quot; height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전압이 낮아질수록 강도가 낮아지니 Bit-Flip을 발생시키기 위해 RowHammer로 더 많이 때려야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, Vpp를 너무 낮추면 부작용이 생길 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전압을 낮추면 트랜지스터가 문을 천천히 열기에 대기시간이 길어진다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.5V 에서 2.0V 까지는 Guardband 덕분에 아무런 에러가 발생하지 않지만, 2.0V보다 더 낮추면 시스템이 데이터를 읽지 못하는 Read Fault 상태에 빠진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;참고문헌&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;1. SpyHammer:&amp;nbsp;Understanding&amp;nbsp;and&amp;nbsp;Exploiting&amp;nbsp;RowHammer&amp;nbsp;under&amp;nbsp;Fine-Grained&amp;nbsp;Temperature&amp;nbsp;Variations&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2210.04084&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/2210.04084&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Understanding&amp;nbsp;RowHammer&amp;nbsp;Under&amp;nbsp;Reduced&amp;nbsp;Wordline&amp;nbsp;Voltage:&amp;nbsp;An&amp;nbsp;Experimental&amp;nbsp;Study&amp;nbsp;Using&amp;nbsp;Real&amp;nbsp;DRAM&amp;nbsp;Devices&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://arxiv.org/abs/2206.09999&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/2206.09999&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  공부</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/815</guid>
      <comments>https://13months.tistory.com/815#entry815comment</comments>
      <pubDate>Sat, 14 Feb 2026 02:24:53 +0900</pubDate>
    </item>
    <item>
      <title>[2025 동계 모각코] 6주차 - Claude Code와 AI Agent</title>
      <link>https://13months.tistory.com/814</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 모임 시간&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2026.01.16 14:00 ~ 17:00 (Zoom)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3156&quot; data-origin-height=&quot;1844&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnaS5i/dJMcagLvFEk/sZRtkTpTCvJxW7SJjxoi0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnaS5i/dJMcagLvFEk/sZRtkTpTCvJxW7SJjxoi0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnaS5i/dJMcagLvFEk/sZRtkTpTCvJxW7SJjxoi0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnaS5i%2FdJMcagLvFEk%2FsZRtkTpTCvJxW7SJjxoi0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3156&quot; height=&quot;1844&quot; data-origin-width=&quot;3156&quot; data-origin-height=&quot;1844&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 진행 내용&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발을 처음 공부한건 2022년 3월부터고, 회사생활을 처음 시작한 건 2023년 정도.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM의 기술적 기반은 2017년에 등장했지만, 내가 LLM을 쓸만하다고 인지한 시기는 2023년 하반기이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 AI 동향을 보면 2023년에 비해 성능이 비약적으로 좋아졌으니.. 기술에 발전에 따라 내 생각도 바꿔야 함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 작성하거나 소프트웨어 아키텍처를 설계하는 작업은 AI가 잘 하니까..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭘 하고 싶은지를 명확하게 작성해주는게 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code 등 AI Agent를 사용할 때도 마찬가지.. 이런 Agent들은 speckit같은 도구를 제공해 사용자가 뭘 원하는지를 쉽게 문서화할 수 있도록 도와준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agent가 작업을 시작하기 전 spec을 참고하니 코드 작성 시 지켜야 할 규칙, FSD 및 DDD 같은 프로젝트 폴더 구조 등을 명시해두면 좋음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 가 어떻게 구현할지를 해결해주니 무엇을, 왜 해결할지를 결정하는게 더 중요해졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 의미에서 도메인 지식이 중요함. IT 지식만 가지고는 다른 도메인의 문제를 해결하는게 힘들다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 공부를 시작했을 때 부터 생각했던건데.. IT 분야는 다른 도메인과 엮일 때 가장 빛난다고 생각함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금융, 반도체, 여행 등 여러 도메인이 있고.. 내가 흥미를 가지는 도메인 하나와 IT를 결합해서 산업의 여러 문제를 해결하는걸 목표로..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  모각코</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/814</guid>
      <comments>https://13months.tistory.com/814#entry814comment</comments>
      <pubDate>Thu, 12 Feb 2026 03:29:45 +0900</pubDate>
    </item>
    <item>
      <title>[Fault Injection] 라즈베리파이 Bit-Flip을 HPC로 잡아내기 - 1</title>
      <link>https://13months.tistory.com/811</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목표는 A Micro Architectural Events Aware Real-Time Embedded System Fault Injector 논문 구현하기.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 모델을 학습시켜서 Edge Device가 공격받는 경우를 인지하는 시스템을 구축해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 모델을 학습시키기 위해 두 가지 데이터가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 정상 상태의 HPC 데이터 (collect_ptrace_normal.py)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Bit-Flip으로 결함이 발생한 상태의 HPC 데이터 (collect_native_fault.py)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스코드는 &lt;a href=&quot;https://github.com/i3months/playground&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt; 참고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하드웨어는 라즈베리파이 4를 사용함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768290991882&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pi@raspberrypi:~ $ sudo apt update
Hit:1 http://deb.debian.org/debian bookworm InRelease
Hit:2 http://deb.debian.org/debian-security bookworm-security InRelease
Hit:3 http://deb.debian.org/debian bookworm-updates InRelease
Hit:4 https://deb.nodesource.com/node_18.x nodistro InRelease
Hit:5 http://archive.raspberrypi.com/debian bookworm InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
394 packages can be upgraded. Run 'apt list --upgradable' to see them.
pi@raspberrypi:~ $ sudo apt install -y linux-perf
..

pi@raspberrypi:~ $ perf --version
perf version 6.12.47
pi@raspberrypi:~ $&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 내부 상태를 들여다봐야 하니까.. perf를 설치해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;perf는 PMU에 접근해 하드웨어 이벤트를 읽어온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커널 수준에서 동작하기에 시스템 성능에 영향을 주지 않으면서 데이터를 수집할 수 있음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;1218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XZCGo/dJMcajuaQbW/SH4pZTsN6d5JPsYmoD2myk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XZCGo/dJMcajuaQbW/SH4pZTsN6d5JPsYmoD2myk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XZCGo/dJMcajuaQbW/SH4pZTsN6d5JPsYmoD2myk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXZCGo%2FdJMcajuaQbW%2FSH4pZTsN6d5JPsYmoD2myk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;606&quot; height=&quot;642&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;1218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;perf list 명령어로 하드웨어가 어떤 이벤트를 감지할 수 있을 지 확인해보자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 지표 중 cycles / instructions / cache-misses / branch-misses 네 가지를 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 네 가지 지표는 Bit-Flip이 발생했을 때 가장 민감하게 반응하는 핵심 지표로, 모델을 학습시킬 때도 저 네 가지 지표만 사용할 예정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768803869334&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
 * 벤치마크는 Marvin 논문 그대로 사용함 
 */

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;time.h&amp;gt;

#define BENCHMARK_BASICMATH 1
#define BENCHMARK_QSORT 2
#define BENCHMARK_SHA 3

#ifndef BENCHMARK
#define BENCHMARK BENCHMARK_BASICMATH
#endif

#if BENCHMARK == BENCHMARK_BASICMATH

double basic_math_compute(int n) {
    double result = 0.0;
    
    for (int i = 1; i &amp;lt;= n; i++) {
        double x = (double)i;
        double sqrt_approx = x / 2.0;
        for (int j = 0; j &amp;lt; 10; j++) {
            sqrt_approx = (sqrt_approx + x / sqrt_approx) / 2.0;
        }
        
        double angle = (double)i / 1000.0;
        double sin_approx = angle;
        double term = angle;
        for (int j = 1; j &amp;lt; 10; j++) {
            term *= -angle * angle / ((2*j) * (2*j + 1));
            sin_approx += term;
        }
        
        result += sqrt_approx + sin_approx;
    }
    
    return result;
}

int main() {
    printf(&quot;Starting Basic Math Benchmark\n&quot;);
    
    volatile double result = basic_math_compute(10000);
    
    printf(&quot;Result: %.6f\n&quot;, result);
    return 0;
}

// ============================================
// Quick Sort Benchmark
// ============================================
#elif BENCHMARK == BENCHMARK_QSORT

void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}

int partition(int arr[], int low, int high) {
    int pivot = arr[high];
    int i = (low - 1);
    
    for (int j = low; j &amp;lt;= high - 1; j++) {
        if (arr[j] &amp;lt; pivot) {
            i++;
            swap(&amp;amp;arr[i], &amp;amp;arr[j]);
        }
    }
    swap(&amp;amp;arr[i + 1], &amp;amp;arr[high]);
    return (i + 1);
}

void quickSort(int arr[], int low, int high) {
    if (low &amp;lt; high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

int main() {
    printf(&quot;Starting Quick Sort Benchmark\n&quot;);
    
    int n = 10000;
    int* arr = (int*)malloc(n * sizeof(int));
    
    srand(42);  
    for (int i = 0; i &amp;lt; n; i++) {
        arr[i] = rand() % 10000;
    }
    
    quickSort(arr, 0, n - 1);
    
    int sorted = 1;
    for (int i = 0; i &amp;lt; n - 1; i++) {
        if (arr[i] &amp;gt; arr[i + 1]) {
            sorted = 0;
            break;
        }
    }
    
    printf(&quot;Result: %s\n&quot;, sorted ? &quot;Sorted correctly&quot; : &quot;Sort failed&quot;);
    
    free(arr);
    return 0;
}

// ============================================
// SHA-like Hash Benchmark
// ============================================
#elif BENCHMARK == BENCHMARK_SHA

unsigned int rotate_left(unsigned int value, int shift) {
    return (value &amp;lt;&amp;lt; shift) | (value &amp;gt;&amp;gt; (32 - shift));
}

void sha_like_hash(const unsigned char* data, int len, unsigned int hash[5]) {
    hash[0] = 0x67452301;
    hash[1] = 0xEFCDAB89;
    hash[2] = 0x98BADCFE;
    hash[3] = 0x10325476;
    hash[4] = 0xC3D2E1F0;
    
    for (int i = 0; i &amp;lt; len; i++) {
        unsigned int temp = rotate_left(hash[0], 5) + hash[4] + data[i];
        hash[4] = hash[3];
        hash[3] = hash[2];
        hash[2] = rotate_left(hash[1], 30);
        hash[1] = hash[0];
        hash[0] = temp;
    }
}

int main() {
    printf(&quot;Starting SHA-like Hash Benchmark\n&quot;);
    
    int data_size = 100000;
    unsigned char* data = (unsigned char*)malloc(data_size);
    for (int i = 0; i &amp;lt; data_size; i++) {
        data[i] = (unsigned char)(i % 256);
    }
    
    unsigned int hash[5];
    sha_like_hash(data, data_size, hash);
    
    printf(&quot;Hash: %08x %08x %08x %08x %08x\n&quot;, 
           hash[0], hash[1], hash[2], hash[3], hash[4]);
    
    free(data);
    return 0;
}

#endif&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;벤치마크는 논문과 유사하게 QuickSort / SHA / BasicMath / 단순반복문을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;준비해 둔 py 파일을 실행시키면 4가지 csv 데이터를 얻을 수 있음. (하나는 정상, 나머지는 Bit-Flip)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Marvin 논문은 Xilinx Zynq 기반 하드웨어를 사용해 XSCT를 통해 Fault Injection을 구현하지만, 라즈베리파이 4 에서는 XSCT를 사용할 수 없으니 GDB를 사용해서 Fault Injection을 구현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애초에 Marvin의 핵심이 Fault 결과를 분류하고 로깅하는 방법론이니.. Bit-Flip의 발생 자체에 집중해야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 라즈베리파이 4에서 GDB로 Bit-Flip을 유도할 때는 GDB 내부에서 perf를 실행할 수 없어서 HPC 측정이 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 perf stat은 자식 프로세스 전체를 측정하는데, GDB가 벤치마킹 중 하나를 실행하면 perf는 GDB와 벤치마크 모두를&amp;nbsp; 측정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 HPC에 디버깅 심볼 로드, 브레이크포인트 설정, 명령어 파싱 등 모든 작업이 포함됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Marvin 논문에서는 XSCT로 외부에서 JTAG를 통해 레지스터를 조작하는 방식이라 XSCT의 오버헤드가 HPC에 포함되지 않음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 Marvin을 구현하려면 GDB 말고 Ptrace를 사용해 프로세스 외부에서 레지스터를 조작하는 방식으로 구현해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GDB를 사용할 때는 측정 도구의 오버헤드가 너무 커서 실제 Bit-Flip 효과를 가리니 Ptrace 방식을 사용하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bit-Flip 을 발생시킬 때의 타이밍, 대상 레지스터 등을 잘 고려해서 데이터를 수집해야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 생각했는데 실제로 Ptrace 방식으로 Bit-Flip을 유도하고 데이터를 시각해봤는데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상 데이터랑 차이가 크지 않았음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1508&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MTpDq/dJMcabJKY3C/4kFKZcdpUxdiKwE6Xxw8Y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MTpDq/dJMcabJKY3C/4kFKZcdpUxdiKwE6Xxw8Y1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MTpDq/dJMcabJKY3C/4kFKZcdpUxdiKwE6Xxw8Y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMTpDq%2FdJMcabJKY3C%2F4kFKZcdpUxdiKwE6Xxw8Y1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;642&quot; height=&quot;356&quot; data-origin-width=&quot;1508&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 시작 시점에만 Bit-Flip이 발생하게 되면 HPC 로 잡아낼 수 없음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Marvin 논문을 보면 프로그램 실행 중간에 Bit-Flip을 발생시키는데, Ptrace로는 이게 힘들다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 라즈베리파이에 GPIO 써서 JTAG 디버거를 연결하든지 해야함..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 힘들면 프로그램 코드 자체에 Bit-Flip을 삽입해두는 방법도 있다. 이 방법으로 다시 트라이해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1498&quot; data-origin-height=&quot;820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YShvi/dJMb99SHmoU/CglFuVLrSAmrnKokedmNy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YShvi/dJMb99SHmoU/CglFuVLrSAmrnKokedmNy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YShvi/dJMb99SHmoU/CglFuVLrSAmrnKokedmNy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYShvi%2FdJMb99SHmoU%2FCglFuVLrSAmrnKokedmNy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;729&quot; height=&quot;399&quot; data-origin-width=&quot;1498&quot; data-origin-height=&quot;820&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제대로 된 데이터를 수집하려면.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 계산 중간에 Fault Injection을 수행하고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 실제로 사용하고 있는 변수를 Bit-Flip 하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 그 변수가 덮어쓰여지지 않아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLFI 에서도 LLVM IR 수준에서 Bit-Flip 을 발생시키니까 사실상 코드 수준에서 공격하는거랑 마찬가지.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이 방법으로 논문을 작성하는건 힘드니까.. 다른 방법을 생각해보기..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 여기까지의 시행착오를 정리..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. GDB를 사용해 레지스터를 직접 수정하는 경우&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1769161054619&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gdb --batch                    
-ex 'break main'               
-ex 'run'                      
-ex 'next'                     # 3줄 실행
-ex 'next'
-ex 'next'
-ex 'set $x0 = $x0 ^ (1&amp;lt;&amp;lt;5)'  # bit-flip
-ex 'continue'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GDB 자체가 너무 무거워서 제대로 측정할 수 없다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상 상태에서는 30M cycles / GDB를 돌리면 1.2B cycles가 측정됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉.. cycles이 Bit-Flip 때문에 늘어났는지 GDB 때문에 늘어났는지 알 수 없음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Ptrace를 사용해 Bit-Flip을 유도하는 경우&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 System Call인 Process Trace을 사용함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1769161393785&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fork()                         // 자식 프로세스 생성
ptrace(PTRACE_TRACEME)         // 부모가 자식 프로세스를 추척
execl(target_program)          // 자식 프로세스가 프로그램 실행
waitpid()                      // 대기
PTRACE_GETREGSET               // 부모가 레지스터 읽음
regs[0] ^= (1 &amp;lt;&amp;lt; 5)            // 부모가 Bit-Flip 수행
PTRACE_SETREGSET               // 
PTRACE_CONT&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 시작 직후에 Bit-Flip이 발생해버려서 실제 계산 전에 정상 값으로 덮어써진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 HPC 지표에는 아무 변화가 없음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이론상 Bit-Flip 발생 시점을 조작하면 되는데.. 조작할 때의 오버헤드가 너무 커서 GDB와 같은 문제가 발생함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  기록</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/811</guid>
      <comments>https://13months.tistory.com/811#entry811comment</comments>
      <pubDate>Tue, 3 Feb 2026 16:18:26 +0900</pubDate>
    </item>
    <item>
      <title>[2025 동계 모각코] 5주차 - Fault Injection Detector</title>
      <link>https://13months.tistory.com/812</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 모임 시간&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2026.01.23 14:00 ~ 17:00 (Zoom)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3170&quot; data-origin-height=&quot;1784&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boA1YX/dJMcafrSjYf/1H3eUk87AKySkZzXz57lE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boA1YX/dJMcafrSjYf/1H3eUk87AKySkZzXz57lE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boA1YX/dJMcafrSjYf/1H3eUk87AKySkZzXz57lE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboA1YX%2FdJMcafrSjYf%2F1H3eUk87AKySkZzXz57lE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3170&quot; height=&quot;1784&quot; data-origin-width=&quot;3170&quot; data-origin-height=&quot;1784&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 진행 내용&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연구실 인턴 생활을 마무리하고 2월에 예정된 글로벌인재 프로그램에서 진행할 논문 주제에 대해 공부하고 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 주제는 Fault Injection이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 디바이스에 강한 전압이나 충격을 가해서 Bit-Flip을 유발할 수 있는데, Bit-Flip 발생 시 Hardware Performance Counter 패턴이 달라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 패턴 차이를 학습해서 Bit-Flip을 감지하는 프로젝트를 진행하고 이걸 바탕으로 논문을 작성하는게 목표.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문을 작성하면서 가장 중요한 건, 이전에 내가 하려던 연구와 동일한 연구가 있는지와 내가 하려는 연구가 학술적 가치, 연구적 가치가 있는지 확인하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 사전 조사가 굉장히 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 점에서는 연구와 개발이 굉장히 유사하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 없던 걸 만들어야 하고, 유사한 주제를 다루더라도 이전 프로젝트에 비해 내가 진행하는 프로젝트가 가지는 이점을 설명할 수 있어야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 논문은 학술지니까.. 연구실 소속이라면 지도교수님에게 논문 작성 주제를 추천받거나 주제 선정에 도움을 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발은 아예 얘기가 다르다. 기획이 매우 중요하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 만드려고 하는 서비스가 어떤 문제를 해결할 수 있을지? 그리고 내가 목표로 하는 시장의 규모가 어느정도인지?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경쟁사는 어떤 곳이 있는지? 경쟁사와 비교했을 때 내 서비스가 얼마나 독창적인지? 등..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자는 불만이 많아야 한다고 생각함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불만을 통해 문제를 정의하고, 그 문제를 해결하는 서비스를 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 불편해서 만드는거니까.. 개발에 대한 동기도 충분하고, 프로젝트도 엎지 않고 진행할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  모각코</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/812</guid>
      <comments>https://13months.tistory.com/812#entry812comment</comments>
      <pubDate>Sun, 25 Jan 2026 17:36:51 +0900</pubDate>
    </item>
    <item>
      <title>[RAG] Parametric Memory to Self-Reflection</title>
      <link>https://13months.tistory.com/806</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 모델이 지식을 저장하는 방식은 크게 두 가지로 정의됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Parametric Memory&lt;/b&gt; - 모델 학습으로 가중치 내부에 저장된 지식으로, 하드코딩된 데이터라고 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Non-Parametric Memory&lt;/b&gt; - 모델 외부에 존재하는 지식으로, 웹으로 치면 DB라고 보면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 지식이 나올 때 마다 모델을 매번 새로 학습시키는건 오버헤드가 너무 크고, 수십억개로 구성된 가중치 파라미터에 의존하다 보니 답변을 역추적하기가 힘들다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1592&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs4TdH/dJMcac9Epa7/K9HexfnDCygPjpBJiTZABk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs4TdH/dJMcac9Epa7/K9HexfnDCygPjpBJiTZABk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs4TdH/dJMcac9Epa7/K9HexfnDCygPjpBJiTZABk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs4TdH%2FdJMcac9Epa7%2FK9HexfnDCygPjpBJiTZABk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;717&quot; height=&quot;215&quot; data-origin-width=&quot;1592&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 LLM은 지식이 모델의 가중치에만 의존한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 말한 문제들을 해결하기 위해 두 가지 Memory를 결합한 구조를 사용함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Query Encoder는 질문을 벡터로 변환하고, 질문 벡터와 가장 유사한 상위 K개의 문서를 빠르게 찾아온다. (MIPS)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 질문 x와 찾아온 문서 z를 함께 입력받아 최종 답변인 y를 생성하는 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 MIPS 가 벡터DB라고 생각하면 됨.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색을 담당하는 Retriver와 생성을 담당하는 Generator를 하나로 연결해 답변이 틀리면 검색을 잘못했는지, 답변을 잘못 생성했는지를 함께 학습해서 더 높은 수준의 최적화를 구현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Neural Network 기반인 Query Encoder를 사용하기에 미분할 수 있어 최종 답변의 오차가 Retriver까지 전파되어 학습이 가능함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문 x에 대해 문서 z가 여러개 나올 수 있는데, 이 때는 Marginalization을 사용해 각 문서 z가 주어졌을 때 정답 y가 나올 확률을 모두 계산해서 합산한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고싶은건 질문 x가 주어졌을 때 답변 y가 나올 확률인데, RAG에서는 x와 y에 문서 z가 끼어든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 z가 여러개라면 어떤 문서가 진짜 정답을 가지고 있는지 확신할 수 없기에 각각의 기여도를 합산하는 방식을 사용함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RAG-Sequence&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문장 하나를 완성할 때 까지는 단일 문서의 맥락을 유지한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 문서로 만든 문장의 전체 확률 / 2번 문서로 만든 문장 전체의 확률 .. 이렇게 모든 확률을 구하고 합산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RAG-Token&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단어를 생성할 때 마다 문서를 매번 합산한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 단어를 뱉을 때 문서의 의견을 종합하고, 그 다음 단어를 뱉을 때도 문서의 의견을 종합한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LIMIT 1로 맨 위에꺼만 가져올 수도 있겠지만.. 첫 번째 문서가 무조건 성능이 좋은 문서라는 보장은 없음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 문서를 확률적으로 합산하면 결과가 다음 답변에 얼마나 기여했는지가 수치로 남으니 학습에 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습 중에 문서 인코더가 변하면 모든 문서의 벡터를 새로 계산해서 인덱스를 다시 빌드해야하니..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서 인코더와 인덱스는 업데이트하지 않고 고정하고, 질문 인코더와 생성기만 학습시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 재학습 없이 인덱스 교체만으로 지식을 업데이트 하는 것. 이 부분으로 기존 LLM의 한계를 극복한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 RAG는 질문이 어렵든 쉽든 문서 K개를 무조건 가져와서 답변을 생성하는데 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 정보를 가져와서 답변 생성에 활용하는건 좋은데, 이러면 오히려 불필요한 정보 때문에 오답을 낼 확률을 높히고 유연성을 떨어뜨림.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 Self-RAG를 사용해 모델이 외부 지식이 필요할 때만 문서에 쿼리하는 구조를 사용함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;reflection tokens을 도입해 지금 가져온 문서가 질문과 연관되는지, 내가 쓴 문장이 문서 내용과 일치하는지를 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7Asmv/dJMcafyAuAo/Y2jqtxNJYfEREsDwmIKWFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7Asmv/dJMcafyAuAo/Y2jqtxNJYfEREsDwmIKWFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7Asmv/dJMcafyAuAo/Y2jqtxNJYfEREsDwmIKWFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7Asmv%2FdJMcafyAuAo%2FY2jqtxNJYfEREsDwmIKWFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;689&quot; height=&quot;376&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 문맥을 보고 검색이 필요한 시점인지를 판단해 Retrieve 토큰을 생성하고, 문서 K개를 병렬로 처리해 답변 후보를 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 생성된 답변에 Critique Token을 붙여 점수를 매기고 가장 신뢰도가 높은 최종 답변을 선택함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 LLM은 저런 행동을 할 수 없음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 Retrive를 뱉지도 않고 틀린지 맞는지 Critique 점수를 매기는 법도 모른다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 저 동작이 가능하려면 Fine-Tuning이 선행되어야 함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Critic은 Fine-Tuning에 필요한 데이터를 만드는 역할을 한다. (이 부분은 검색이 필요하고, 이 답변은 5점짜리고.. 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM 자체를 Fine-Tuning 하는거지, LLM 외부나 내부에 다른 모델을 Fine-Tuning 해서 배치하는게 아님.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 RAG가 Static하게 무조건 탐색하는 방식을 사용했다면 Self-RAG는 Dynamic하게 필요할 때만 검색한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델이 뱉는 상태코드를 먼저 정의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RETRIEVE&lt;/b&gt; : 현재 문맥에서 외부 DB 조회가 필요한지?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ISREL&lt;/b&gt; : 가져온 문저가 질문을 해결하는데 실질적인 도움이 되는지?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ISSUP&lt;/b&gt; : 생성된 답변이 문서에 기록된 사실과 일치하는지?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ISUSE&lt;/b&gt; : 생성된 답변이 사용자의 질문에 얼마나 유용한지?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 4가지 토큰 기반의 데이터를 GPT-4를 활용해 데이터를 수집한다. 이 데이터를 가지고 Critic 모델을 만들 예정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 저 Critic 모델을 Critique Token을 달아줄 수 있는 채점기로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트 데이터에 Critic 모델을 돌려 [Retrieval] [ISREL] 토큰을 텍스트 사이사이에 삽입하고, Generator에게 데이터를 통째로 입력.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델은 어느 타이밍에 [Retrieval]을 뱉을지, 문서를 읽고 어떤 Critique 토큰을 뱉을지 학습한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉.. GPT-4 로 Generator를 학습시키면 좋은데, API 비용이 비싸니 Critic 모델을 만들어 사용하는 것.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서는 학습 시 데이터 15만개를 사용하는데, 15만개를 전부 GPT-4에게 시키면 비용 감당이 안됨,,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPT-4 -&amp;gt; Critic -&amp;gt; Generator 까지 학습했다면 이제 Self-RAG 모델을 돌려볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습이 끝나면 이제 앞서 말했던 Dynamic한 동작이 시작된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점수 계산 시에는 ISREL, ISSUP 토큰을 사용한다. 시스템은 이 토큰들의 확률값을 보고 점수를 계산함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토큰 값을 조작할 수 있으니 도메인별로 모델의 특성을 커스텀 할 수 있는 것도 장점.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디테일한 부분을 물어보면 잘 대답할 수 있지만, 전체적인 질문에 대한 답변은 힘들다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문과 비슷한 Chunk만 몇 개 가져오기에 문서 전체 토큰의 문맥을 유지할 수 없고.. 요약할 수도 없다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 GraphRAG가 도입됐다. 데이터를 단순하게 자르지 않고, Graph를 도입해 지식의 관계를 정립함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트에서 Node를 뽑아내고, 그 사이의 관계를 이어준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM은 완성된 그래프를 미리 요약하고, 답변을 생성할 때 활용함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SvV9g/dJMcaa47xFv/08kdzk3QA9YzcQnbA7nQ70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SvV9g/dJMcaa47xFv/08kdzk3QA9YzcQnbA7nQ70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SvV9g/dJMcaa47xFv/08kdzk3QA9YzcQnbA7nQ70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSvV9g%2FdJMcaa47xFv%2F08kdzk3QA9YzcQnbA7nQ70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;327&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 방식을 Vector RAG라고 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VectorRAG는 텍스트 임베딩으로 벡터 공간에서 가까운 정보를 검색하는데, 이건 Local Similarity에 의존함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GraphRAG는 데이터를 큰 단위로 요약해서 전체 맥락을 기억한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Leiden이나 Louvain 같은 커뮤니티 탐지 알고리즘을 사용해 그래프를 구성하는 노드를 하나의 커뮤니티로 묶어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프 탐색이 목적이 아니라, 그래프를 계층적인 커뮤니티 요약본으로 변환하는게 목적.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서를 적당한 크기로 자르고, LLM이 Chunk에서 노드와의 관계를 뽑아낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 추출된 정보로 그래프 인덱스를 만들고 앞서 말한 알고리즘으로 커뮤니티를 구성한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 각 커뮤니티의 내용을 LLM으로 미리 요약함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문이 들어오면 관련 있는 커뮤니티의 요약본을 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Map - Reduce 방식으로, 각 요약본에서 부분 답변을 만들고 그 답변들을 합쳐 최종 답변을 만들어낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gemini나 GPT 같은 서비스 수준의 LLM은 RAG가 기본적으로 구현되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니까, GPT나 Gemini 모델 자체는 Parametric Memory만 가진 상태로 학습 데이터 Cut-Off 시점 이후의 정보는 모름.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 웹이나 API를 통해 접근하는 GPT와 Gemini는 Retriever가 붙어있는 시스템으로 서빙된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 요즘 자바취업전망 어떠냐고 물어보면 시스템 내부의 라우터가 판단해서 외부 데이터를 쿼리해서 모델에게 던지고, 모델은 그 데이터까지 함께 입력받아서 출력을 만들어 내는 것. - 그냥 RAG 개념이 그대로 사용되고 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 RAG는 모델이 한 번에 읽을 수 있는 양이 작아서 탄생한 기술.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 크기가 커지면 한 번에 다 때려박을 수 있지 않나?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Attention 연산 복잡도는 입력 길이 N 에 대해 N^2 이니 한 번 질문할 때 마다 발생하는 API 비용이 기하급수적으로 늘어날 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 비용과 속도를 고려할 때 아직까지는 RAG를 배제할 수 없음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAG도 어떻게 보면 VRAM을 효과적으로 쓴다는 측면이긴 함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VRAM에 안 올리고 저렴하고 용량이 큰 Vector DB에 데이터를 저장하고 필요할 때만 로드하는 방식이니까.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 VRAM 공간이 무한이라 모든 단어를 다 올릴 수 있다고 해도, 모든 걸 다 읽는게 항상 좋지는 않음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N이 커질수록 특정 단어에 집중하는 점수가 낮아질 수 밖에 없다. (Attention is All you need)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터구조 이론을 그대로 따라가게 되는..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 실전에서 내가 거대 기업을 이기려면, 특정 영역에 집중해야 하고 RAG를 잘 사용한다면 가능성이 있어 보임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Specific Data는 내가 알아서 수집하고, 그 데이터와 Gemini / GPT api를 쓸지 아님 로컬 모델 파인튜닝을 할지는 고려해 봐야 하고..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 RAG를 구현할 때는 논문을 내가 직접 구현하기보다는 ChromaDB 같은 벡터디비 서비스를 사용하거나 LangChain에서 Retriever를 호출하거나.. 상용 라이브러리를 사용하는 방식을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;참고문헌&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;1. Retrieval-Augmented&amp;nbsp;Generation&amp;nbsp;for&amp;nbsp;Knowledge-Intensive&amp;nbsp;NLP&amp;nbsp;Tasks&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;a href=&quot;https://arxiv.org/abs/2005.11401&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/2005.11401&lt;/a&gt;&amp;nbsp;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;2. Self-RAG:&amp;nbsp;Learning&amp;nbsp;to&amp;nbsp;Retrieve,&amp;nbsp;Generate,&amp;nbsp;and&amp;nbsp;Critique&amp;nbsp;through&amp;nbsp;Self-Reflection&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;a href=&quot;https://arxiv.org/abs/2310.11511&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/2310.11511&lt;/a&gt;&amp;nbsp;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;3. From Local to Global: A Graph RAG Approach to Query-Focused Summarization&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;a href=&quot;https://arxiv.org/abs/2404.16130&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://arxiv.org/abs/2404.16130&lt;/a&gt;&amp;nbsp;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  공부</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/806</guid>
      <comments>https://13months.tistory.com/806#entry806comment</comments>
      <pubDate>Sun, 18 Jan 2026 15:53:47 +0900</pubDate>
    </item>
    <item>
      <title>[2025 동계 모각코] 4주차 - RAG와 LoRA</title>
      <link>https://13months.tistory.com/805</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 모임 시간&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2026.01.16 14:00 ~ 17:00 (Zoom)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3204&quot; data-origin-height=&quot;1830&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bx216I/dJMcabwcC9N/sr6S8rQsKXlyBa6xjHuj21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bx216I/dJMcabwcC9N/sr6S8rQsKXlyBa6xjHuj21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bx216I/dJMcabwcC9N/sr6S8rQsKXlyBa6xjHuj21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbx216I%2FdJMcabwcC9N%2Fsr6S8rQsKXlyBa6xjHuj21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3204&quot; height=&quot;1830&quot; data-origin-width=&quot;3204&quot; data-origin-height=&quot;1830&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 진행 내용&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;엣지 디바이스에서 LLM을 돌리는 연구를 진행하면서.. 돌아가는 LLM의 성능을 개선하기 위해 RAG와 LoRA 등 다양한 방법론을 함께 공부하고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컴퓨팅 리소스가 제한된 환경에서 LLM을 돌려야 하니.. 고려할 부분이 상당히 많다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서버 통신 없이 처리해야 하니, 디바이스의 VRAM을 최대한 활용해야 함.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;1324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W3JU7/dJMcagLdkuz/zxOplkstTkdpwSKlv3fWB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W3JU7/dJMcagLdkuz/zxOplkstTkdpwSKlv3fWB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W3JU7/dJMcagLdkuz/zxOplkstTkdpwSKlv3fWB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW3JU7%2FdJMcagLdkuz%2FzxOplkstTkdpwSKlv3fWB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;602&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;1324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RAG는 벡터디비에 내 데이터베이스를 구축해두고 LLM이 답변을 생성할 때 참고하도록 하는 기술.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 RAG를 기반으로 여러 응용이 있다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Self-RAG로 답변 과정을 스스로 검토해 답변의 근거를 생각해내고,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Graph-RAG로 정보 간의 관계를 인식할 수 없었던 기존 RAG의 한계를 극복한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;운영체제 / 네트워크 / 컴퓨터구조 / 컴퓨터시스템 등 컴퓨터과학 전공지식이 어느정도 있으면 어떤 종류의 논문이든지 어느정도 읽을만 한듯..&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;오히려 학부 수준의 전공공부를 마쳤다면 공부할 때 논문을 꼭 봐야 한다고 생각함.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;강의를 찾아 듣는 것 보다 논문을 통해 공부하고 스터디하는게 훨씬 나을듯..&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  모각코</category>
      <author>i3months</author>
      <guid isPermaLink="true">https://13months.tistory.com/805</guid>
      <comments>https://13months.tistory.com/805#entry805comment</comments>
      <pubDate>Sun, 18 Jan 2026 13:27:50 +0900</pubDate>
    </item>
  </channel>
</rss>