<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[ejkiwi.github.io]]></title><description><![CDATA[Obsidian digital garden]]></description><link>http://github.com/dylang/node-rss</link><image><url>site-lib/media/favicon.png</url><title>ejkiwi.github.io</title><link/></image><generator>Webpage HTML Export plugin for Obsidian</generator><lastBuildDate>Fri, 24 Jul 2026 08:22:23 GMT</lastBuildDate><atom:link href="site-lib/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Fri, 24 Jul 2026 08:22:22 GMT</pubDate><ttl>60</ttl><dc:creator/><item><title><![CDATA[키야~_~ 모각코 활동]]></title><description><![CDATA[관심 있는 분야의 논문을 하나 찾아서 주 1회 읽고 정리하자!]]></description><link>2026_하계_모각코/키야~_~-모각코-활동.html</link><guid isPermaLink="false">2026_하계_모각코/키야~_~ 모각코 활동.md</guid><pubDate>Fri, 24 Jul 2026 08:22:09 GMT</pubDate></item><item><title><![CDATA[20260701 모각코 활동 1회차]]></title><description><![CDATA[
Persona vector를 벡터 공간에서 조합·연산할 수 있음을 제시.
기존 성격 제어 방식(프롬프팅, 파인튜닝)의 한계 극복 시도: 정적이고 비용이 크며, 인간 특성의 동적·조합적 성질을 못 담아내니까... -&gt; activation space 상 personality vector를 직접 조작
성격 특성들이 모델 표현 공간에서 거의 직교(orthogonal)하는 방향으로 추출 가능 → 벡터 대수 연산(덧셈/조합)이 가능 문제의식: 기존의 대형 언어모델(LLM) 성격 제어 방식은 정적 프롬프트(prompt)나 비용이 많이 드는 파인튜닝(fine-tuning)에 의존하여, 인간 성격의 동적·조합적 특성을 제대로 반영하지 못함.
제안 방법: 본 논문은 훈련 없이(Training-free) LLM의 활성화 공간(activation space)에서 성격 벡터(personality vector)를 직접 조작하는 PERSONA 프레임워크를 제안함. 핵심 아이디어는 성격 특성이 모델의 표현 공간에서 추출 가능하고, 대략적으로 직교하는 벡터 방향으로 존재한다는 점임. 이 벡터들은 대수적 연산(곱셈, 덧셈, 뺄셈)이 가능함.
프레임워크 구성: PERSONA는 세 단계로 동작함. PERSONA-BASE: 대조적 활성화 분석(contrastive activation analysis)로 직교 성격 벡터 추출
PERSONA-ALGEBRA: 벡터 연산(강도 조절, 조합, 억제)으로 정밀 제어
PERSONA-FLOW: 추론 시점에서 대화 맥락에 따라 동적으로 성격 조합 및 조절 주요 성능: PersonalityBench 벤치마크에서 평균 9.60점(최대 10점)으로, 파인튜닝 상한선(9.61점)에 거의 근접한 성능을 훈련 없이 달성함. PERSONA-EVOLVE(동적 성격 적응 벤치마크)에서는 최대 91% win rate를 기록함.
의의: LLM의 성격이 수학적으로 조작 가능한 구조임을 보였으며, 해석 가능하고 효율적인 행동 제어의 새로운 방향을 제시함. 배경: 대형 언어모델(LLM)의 성격(personality) 제어는 의료, 교육, 사회 시뮬레이션 등 인간 중심 응용에서 매우 중요.
기존의 성격 제어 방식(프롬프트 엔지니어링, 파인튜닝)은 정적이고 비효율적이며, 인간 성격의 동적·조합적 특성을 반영하지 못함. 목적: 훈련 없이(Training-free) LLM의 활성화 공간(activation space)에서 성격 벡터를 직접 조작하여, 파인튜닝 수준의 성능과 동적·조합적 성격 제어를 동시에 달성하는 새로운 프레임워크(PERSONA)를 제안. 핵심 이론: 인간 성격은 Big Five(OCEAN) 모델(개방성, 성실성, 외향성, 친화성, 신경성)로 설명 가능. 심리학 분야에서의 이론적 정립을 들고 온거임 LLM의 내부 표현 공간에서도 각 성격 특성이 추출 가능한(대략적으로 직교하는) 벡터 방향으로 존재한다는 가정. ( 이걸 깔고 가는게 아니라 이걸 가설로 둔거임 ) activation layer에서 특정 벡터 방향으로 성격 특성이 존재한다는 뜻임
특정 벡터 방향으로 존재한다는게, 개방성 성실성 외향성 친화성 신경성이 각각 5가지의 방향으로 존재한다는 의미와 같음. 가설: 성격 특성은 LLM의 활성화 공간에서 추출 가능한 직교 벡터로 표현될 수 있을 것이다.
이 벡터들은 대수적 연산(스칼라 곱, 덧셈, 뺄셈)을 통해 성격 강도 조절, 조합, 억제가 가능할 것이다.
실시간 대화 맥락에 따라 동적으로 성격을 조합·조절할 수 있을것이다. 데이터 수집: Big Five 각 차원의 양극단(총 10개)에 대해, LLM이 해당 특성을 드러내거나 억제하도록 유도하는 프롬프트와 평가 질문을 자동 생성. 성격 벡터 추출: LLM의 응답 생성 시 내부 활성화(Residual Stream)를 수집.
특성 표현/억제 조건의 평균 활성화 차이로 성격 벡터 산출. 성격 제어: 추출된 벡터를 특정 계수로 활성화에 더해 성격 강도 조절, 여러 벡터의 합/차로 조합 및 억제 구현. 평가: 정적 성격 제어: PersonalityBench(외부 벤치마크, 약 90개 상황별 질문/특성)에서 성능 평가(8page).
동적 성격 제어: PERSONA-EVOLVE(800개 멀티턴 시나리오)에서 대화 맥락 변화에 따른 성격 일관성, 적합성, 진정성 평가(6~8page).
평가 방식: LLM 기반 자동 평가 및 인간 전문가 검증(18~21page). 목적: Big Five(OCEAN) 각 차원의 양극단(총 10개)에 해당하는 성격 벡터를 LLM의 activation space에서 추출
방법: 대조적 프롬프트(특성 표현/억제)와 평가 질문을 자동 생성
각 프롬프트 조건에서 모델의 응답을 생성하고, 특정 layer의 activation(잔차 스트림)을 수집
특성 표현/억제 조건의 평균 activation 벡터의 차이를 계산 → 해당 성격 특성의 방향(성격 벡터)으로 사용
벡터의 직교성(독립성) 및 효과성은 코사인 유사도, causal intervention 등으로 검증 예시 : 대조적 활성화 분석 방법 "big 5 중 일관성 성격을 추출해야겠다."
두 개의 프롬프트(대조적) 생성 -&gt; 긍정프롬프트 당신은 일관적이어야한다어쩌구 / 부정프롬프트 넌 창의적이어야한다 어쩌구
이 두 개를 주입
답변할때의 활성화 값 계산
두 프롬프트에 해당하는 답이 나올 때의 활성화 값 차이 로부터 순수한 성격만 발라냄
이러면 이제 일관성 이라는 방향벡터만 남는거임 5가지의 각 성격은 모두 직교하더라!!! llm의 내부 공간 속(수천차원에 달하는...) 개방성, 성실성, 외향성, 친화성, 신경성은 모두 직교하고있더라!!
대조적 활성화 분석을 하고 보니? 이렇던거임. 하나의 성격에서 대조되는 부분은 직교하는게 아니라 하나의 선상에서 서로 반대되는 부분에 존재하는 거. 개방성에서, 내향적/외향적은 같은 선 위에서 양끝에 존재하더라~ 목적: 추출된 성격 벡터를 수학적으로 조작하여 다양한 성격 조합 및 강도 조절 구현
방법: 스칼라 곱: 벡터에 계수를 곱해 성격 강도 조절 외향성 벡터에 2를 곱해서 주입하면, 성격 평가 점수도 딱 2배만큼 강해질 것 벡터 덧셈: 여러 성격 벡터를 더해 복합적 성격 조합 외향성 벡터와 동정심 벡터를 더해서 주입하면, 두 가지 성격이 모두 높게 측정될 벡터 뺄셈: 특정 성격 특성 억제 특정 벡터를 빼면, 다른 성격은 유지된 채 딱 그 성격만 줄어들 것 조작된 벡터를 activation에 더해 모델의 응답 성격을 실시간으로 변화시킴 목적: 대화 맥락에 따라 실시간으로 성격을 조합·조절하여 자연스러운 인격 변화 구현
방법: 각 대화 턴마다, 현재 맥락과 persona 설명을 바탕으로 각 성격 차원별로 조정 계수(–2~2)를 예측
예측된 계수만큼 성격 벡터를 조합해 composite steering vector를 생성
해당 벡터를 activation에 더해, 맥락에 맞는 성격으로 응답 생성
이 과정은 predict-then-steer 방식으로, 턴마다 반복됨
예를 들어서, 답변을 내뱉기 직전, 모델이 중간 추론 과정을 거쳐 현재 대화의 맥락을 분석한다는 거임.
예를 들어 상대방이 화가 난 상황이라면 "지금은 동정심(+1.0)을 높이고 외향성(-0.5)은 낮춰야겠다"라고 자체적으로 계수를 예측한 뒤에. 이렇게 계산된 조합 벡터를 모델 내부에 스티어링(주입)한 뒤, 그 설정값을 바탕으로 최종 답변을 생성한다는 거. 목적: 동적 성격 제어의 효과를 다중 시나리오에서 체계적으로 평가
방법: 100개 persona × 8개 시나리오(총 800개 멀티턴 대화)로 구성된 벤치마크
각 시나리오에서 성격 일관성, 역할 유지, 응답 진정성, 정보 충실도 등 다양한 지표로 평가
LLM 기반 자동 평가 및 인간 전문가 검증 병행 성격 벡터를 주입한 모델의 답변과 기본 모델의 답변을 쌍으로 보여줌
어떤 답변이 설정된 페르소나를 더 잘 유지했는지, 상황에 맞는 감정을 표현했는지 승률(win rate)을 계산하게 함
LLM 심판의 채점이 믿을 만한지 확인하기 위해 사람 전문가의 평가 결과와 비교하여 높은 일치율을 검증하는 과정도 거침 정적 성격 제어 PERSONA-BASE: 성격 추출한 그 벡터를 딱 고정해서 꽃아놓고 대화 시작부터 끝까지 그냥 처음 성격 그대로 유지하도록 한거임
LLaMA-3-8B-Instruct에서 평균 9.60점(최대 10점)으로, 파인튜닝(SFT) 상한선(9.61점)에 거의 근접 동적 성격 제어 PERSONA-FLOW: 정적으로 성격을 정해주긴 하지만, 상황에 따라서 특성을 조절하며 답하라고 조율하는 것.
성격 벡터의 대수적 성질 사용: 스칼라 곱(강도 조절), 덧셈(조합), 뺄셈(억제) 모두 예측 가능한 성격 변화 유도.
PERSONA-EVOLVE에서 최대 91% win rate(모델별 73.2~90.8%)로, 다양한 모델군에서 일관된 성격 유지와 맥락 적응력 입증. 안전성 영향: 위험 특성(예: self-interested)은 모델의 alignment로 인해 활성화 저항이 크고, 일부 특성(예: careless, inventive)은 안전성 저하 가능성 있음(24~25page, Table 14, 15). 한계: 일부 성격(예: 신뢰성, 침착성)은 이미 모델에 내재되어 있어 추가 조절 효과가 제한적(ceiling effect, 4page, Table 2).
안전성 alignment로 인해 위험 특성은 활성화가 어렵고, 반대로 일부 특성은 안전성 저하 가능성 존재(24~25page).
벡터 간 완전한 직교성은 아니며, 일부 상관관계가 존재하나 대수적 조합에는 큰 영향 없음(26page). 향후 연구 방향: 안전성 보장과 성격 제어의 동시 달성을 위한 alignment-aware steering 기법 개발 필요(25page).
다양한 문화적/언어적 배경에서의 성격 벡터 일반화 및 확장 연구.
실제 사용자와의 상호작용 기반 평가 및 응용 사례 확대. ]]></description><link>2026_하계_모각코/20260701-모각코-활동-1회차.html</link><guid isPermaLink="false">2026_하계_모각코/20260701 모각코 활동 1회차.md</guid><pubDate>Fri, 24 Jul 2026 08:21:22 GMT</pubDate></item><item><title><![CDATA[index]]></title><description><![CDATA[
<a data-href="백준" href="백준/백준.html" class="internal-link" target="_self" rel="noopener nofollow">백준</a>
<br><a data-href="2024_하계_모각코" href="2024_하계_모각코/2024_하계_모각코.html" class="internal-link" target="_self" rel="noopener nofollow">2024_하계_모각코</a>
<br><a data-href="2024 cnu 2차 학습동아리" href="2024-cnu-2차-학습동아리/2024-cnu-2차-학습동아리.html" class="internal-link" target="_self" rel="noopener nofollow">2024 cnu 2차 학습동아리</a>
<br><a data-href="2024-25_동계_모각코" href="2024-25_동계_모각코/2024-25_동계_모각코.html" class="internal-link" target="_self" rel="noopener nofollow">2024-25_동계_모각코</a>
<br><a data-href="2025_하계_모각코" href="2025_하계_모각코/2025_하계_모각코.html" class="internal-link" target="_self" rel="noopener nofollow">2025_하계_모각코</a>
<br><a data-href="2025-26_동계_모각코" href="2025-26_동계_모각코/2025-26_동계_모각코.html" class="internal-link" target="_self" rel="noopener nofollow">2025-26_동계_모각코</a>
<br><a data-href="2026_하계_모각코" href="2026_하계_모각코/2026_하계_모각코.html" class="internal-link" target="_self" rel="noopener nofollow">2026_하계_모각코</a>
<br><a data-href="git&amp;github" href="git&amp;github/git&amp;github.html" class="internal-link" target="_self" rel="noopener nofollow">git&amp;github</a>
<br><a data-href="AI_study" href="ai_study/ai_study.html" class="internal-link" target="_self" rel="noopener nofollow">AI_study</a>
사실이건아무것도작성한게없다...&gt;_&lt;
<br><a data-tooltip-position="top" aria-label="https://velog.io/@eonjikiwi/posts" rel="noopener nofollow" class="external-link is-unresolved" href="https://velog.io/@eonjikiwi/posts" target="_self">ejkiwi_velog</a>
]]></description><link>index.html</link><guid isPermaLink="false">index.md</guid><pubDate>Fri, 24 Jul 2026 08:11:51 GMT</pubDate></item><item><title><![CDATA[2026_하계_모각코]]></title><link>2026_하계_모각코/2026_하계_모각코.html</link><guid isPermaLink="false">2026_하계_모각코/2026_하계_모각코.md</guid><pubDate>Fri, 24 Jul 2026 08:06:59 GMT</pubDate></item><item><title><![CDATA[20260722 모각코 활동 4회차]]></title><description><![CDATA[개인 비서, 고객 서비스 봇 등 다양한 분야에 도입되고 있는 LLM 에이전트의 '대화형 프라이버시(Contextual Privacy)' 취약점을 평가하기 위한 새로운 감사 프레임워크를 제안"기존의 제일브레이킹(Jailbreaking)은 단순히 시스템을 망가뜨리는 것에 집중했지만, 최신 보안 위협은 이 논문처럼 대화 맥락 속에서 은근슬쩍 정보를 빼내는 것
방어자가 가지고 있는 정보가 단순히 뚫렸는지만 본 것이 아니라, 공격자 LLM이 탐색적 질문, 가상 상황 제시, 화제 전환, 권위 호소 등 어떤 언어적 기만술을 사용하여 방어자 LLM을 속이는지 그 전략 패턴을 이미 분석
대화 턴이 거듭될수록 공격자 LLM이 비밀 문서의 내용에 대해 어떻게 확신을 가져가는지를 그래프로 정리
기존의 LLM 보안 연구들은 주로 단일 턴(Single-turn) 기반의 탈옥(Jailbreaking) 공격에 집중해 왔으며, 대화형 agent가 문맥을 유지하며 장기적인 기억(Stateful memory)을 활용하는 환경에서의 프라이버시 누출 위험을 충분히 다루지 못 함.
저자들은 단순한 Explicit Leakage(직접적 노출)뿐만 아니라, 대화 과정에서 점진적으로 민감 정보를 수집하고 추론하는 Implicit Leakage(암묵적 노출)가 심각한 위협이 됨을 지적.CMPL은 공격자(Adversary U)와 애플리케이션 agent(Application Agent A) 간의 대화를 시뮬레이션하여 프라이버시 누출을 측정.
Application Agent (A): 태스크 설명 , 사용자 프로필 , 문맥적 프라이버시 지침 를 기반으로 동작하며, 대화 히스토리 를 상태로 유지
Adaptive Adversary (U): 전략가(Strategist ), 프롬프트 생성기(Prompt Generator ), 사이드채널 예측기(Side-channel Predictor )로 구성된 메타 에이전트. Strategist (): Chain-of-thought 추론을 통해 하위 목표(Sub-goal) 기반 계획을 세우거나 반응형(Reactive) 전략을 선택.
Predictor (): 대화 히스토리 를 바탕으로 목표 속성 를 추론하며, 자기 일관성 점수(Self-consistency score) 가 임계값 를 넘으면 최종 누출로 간주. Auditor (D): 대화가 명시적 정보(Explicit leakage)를 포함하는지 혹은 예측기 가 높은 신뢰도로 정답 를 맞췄는지(Implicit leakage)를 판단하여 누출 여부 를 결정.
공격 성공률(ASR)을 높이기 위해 제안된 적대적 agent는 다음 수식을 통해 공격 진행 상황을 평가.
여기서 은 대화 전후의 사후 확률과 사전 확률의 차이를 의미.
또한, 누출의 시간적 역학을 파악하기 위해 로컬 누출 가능성 등을 산출.
공격 효능: 제안된 적대적 공격은 SoTA 기반 공격보다 높은 성능을 보였으며, 일부 환경에서 최대 75%의 공격 성공률을 기록.
모델 스케일링: 공격자의 모델 크기가 커질수록(8B에서 70B으로) 누출 가능성이 급격히 증가하며, 반대로 애플리케이션 agent의 모델이 작을수록 프라이버시 취약성이 커지는 경향을 확인.
시간적 역학: 누출 확률은 대화 10~20턴 이후 정점에 도달한 뒤 점진적으로 감소하는 양상.
암묵적 누출의 위험성: 명시적인 정보 공개가 없더라도 대화 맥락을 통한 추론만으로도 개인의 정신 건강 상태 등 민감 정보를 높은 정확도로 유추할 수 있음을 입증.
본 연구는 대화형 agent의 프라이버시 보호가 단순한 단일 턴 필터링을 넘어, 문맥적 무결성(Contextual Integrity)을 고려한 장기적이고 적응적인 감사 시스템으로 진화해야 함을 강조. CMPL은 이러한 취약성을 진단하는 강력한 도구로서, 향후 더 견고한 AI agent 시스템을 설계하기 위한 벤치마크 역할.]]></description><link>2026_하계_모각코/20260722-모각코-활동-4회차.html</link><guid isPermaLink="false">2026_하계_모각코/20260722 모각코 활동 4회차.md</guid><pubDate>Fri, 24 Jul 2026 08:05:53 GMT</pubDate></item><item><title><![CDATA[20260708 모각코 활동 2회차]]></title><description><![CDATA[PLM(pretraining language model) 내부 표현에 성별·나이 같은 사회인구학적 정보가 실제로 인코딩되어 있는지를 probing 기법으로 분석한 연구
결과적으로 이러한 정보는 분명 존재하지만, 여러 층에 분산되어 있고 충분한 사전학습 데이터가 있어야 형성.
추가적으로, 일반적인 언어 이해 성능이 높은 모델이 사회인구학적 정보를 더 잘 학습하는 것은 아니라는 점(=일반 NLP 성능과 사회인구학적 지식은 별개의 능력이다!)을 보여주며, 사회적 맥락 이해는 여전히 현대 NLP의 중요한 미해결 과제임을 시사.왜 이 연구가 필요한지
사람은 상대방의 특성을 고려하며 언어를 사용하고, 언어에는 사회적인 특성이 자연스럽게 반영된다. 그래서 사회인구학 정보가 언어의 이해와 생성에 모두 중요하다
그러면 PLM도 사회인구학적 지식을 가지고있을까? probing을 통해서 알아볼 수 있겠다!! 기존에도 이런 방식으로 알아봤으니
다음에서 기존 연구 어디까지 왔는지 설명이어서 됨
→ 기존 연구는 어디까지 왔는지 근데 기존에는 낮은 수준의 구조적 지식 분석인거임 ( 이 논문이 쓰일 시점 2022 ) 낮은 수준 : 문법 구조
중간 수준 : 단어 의미
높은 수준 : 사회적 맥락( 사회성, 문화, 나이, 성별)
→ 무엇이 비어 있는지 모델의 상식 지식을 정량적으로 측정하는연구도 적음
"PLM이 사회인구학 정보를 배우는가?"를 체계적으로 분석한 연구가 없었다 데이터는 있는데도!!
→ 이 논문이 무엇을 했는지 이 문제를 처음 본격적으로 분석하겠다!
→ 제안 SOCIOPROBE라는 새로운 probing 프레임워크를 제안했다.
BERT, RoBERTa 등 여러 PLM을 비교
Classifier probing
MDL probing
둘 다 사용 → 결과 PLM은 사회인구학 정보를 실제로 학습
사회인구학 정보는 모델의 후반부 레이어(later layers)에서 주로 형성
일반적인 언어 이해 성능과는 별개의 능력이라는 점을 확인 GLUE 점수가 높다고 사회인구학 정보도 많이 배우는 것은 아니라는 것. 뭘 알고싶은가PLM은 사회인구학적 지식을 어느 정도 인코딩하고 있는가?
-&gt; 텍스트 도메인에 따라 다름
-&gt; 심지어, 좋은 언어모델(glue 점수 높은 거) != 사회 정보 잘 아는 거사회인구학적 지식을 배우려면 얼마나 많은 pretraining 데이터가 필요한가?
-&gt; 겁나많이 필요 많을수록 좋음
-&gt; 사회인구학적 지식은 오랜 학습이 필요함사회인구학 정보는 모델의 어디에 저장되어 있는가?
각 LAYER 하나 씩 Probing 함
-&gt; 대부분 뒤쪽 layer ( 물론 앞쪽도 존재 )
-&gt; 특정 layer에 있는게 아님 넓게 퍼져있음
다국어 모델에서는 사회인구학 정보의 위치가 달라지는가?
XLM-R처럼? : XLM-RoBERTa 다국어 로버타임 그래서스페인어같은건 단어 자체에 성별이 녹아있으니까,,, 다른 방식으로 저장되진 않을까 해서 추가 실험해본거임...
-&gt; 영어랑 다국어 모델 둘 다 비슷했음 추가 학습(STILTs)은 사회인구학 정보에 어떤 영향을 주는가?
STILTs : qa, ner, nli같은 작업으로 파인 튜닝(내가 찐으로 시키고 싶은 거) 하기 전에! 한 번 더 학습시킨다..? 이거 하면 좀 더 사회인구학 정보를 잘 담을 수 있을거라고 논문에서는 생각했던거임 그래서 이런 가설을 세우고 실험을 한거구
-&gt; 오히려 기본 정보 사라짐 : 오버라이팅 된 그 느낌 관련연구들이랑 비교해서 다른 점 어필
probing plm 뭔가 아직도 probing에 대해서는 논의도 많고..(논란도많고.. 이거 믿어도 됨? 같음..) 많은 연구가 나오는 듯? - 밑밥깔고감
so,,, 글서 너네가 태클걸거같으니까.. 여기 연구에서는 기본 probing과 mdl probing도 쓴댜
기존에는 영어 bert만 분석햇디만 이 논문 만들 시점,, xlm-r / clip같은 다국어 멀티모달 모델도 분석하기 시작되던 시기 ( 이 이야기는 왜 있는지 잘은 모르겠다 이거 ㄹ왜 끼운거지)
기존에는 걍 언어지식 얼마나 얻기인지인데
사회인구학 지식 알아보려고 했던게 이 연구의 킥임 ( 성별, 나이, 사회적특성 ) Sociodemographic Aspects 이런 사회인구학 지식이 plm이해하고 성능 높이는데 ㄹㅇ 중요한거라고!!
다른 연구들은 단순히 글만보고 무엇인지 맞추는(예측 작업) 연구를 하는거임 -&gt; 잉 이거 내가 하려는 거 아니니 이 논문은 오히려 예측 작업을 모델에 사회인구학 정보가 얼마나 저장되어 있는지 측정하는 도구(proxy)로 사용한다 이말이다..
직접 "모델 안에 성별 정보가 있다"를 볼 수는 없기 때문에, 성별 예측 성능을 대신 사용해 추론 다른 연구들은 편향을 탐지하고 제거하는 연구를 수행 의사는 남자 간호사는 여자 이런 편향 제거하겠다 이거임. -&gt; 이거 관련 논문이 이 논문고 ㅏ기존 시점에서 가장 비슷한 연구였음.
근데 얘들도 편향이 있다는 것만 확인하고?? 언제배우는지어느 layer인지어떻게저장되는지는 설명하지 못한다 이말이다,,,
이 논문에서는 PLM이 사회인구학적 지식을 포함하고 있음을 명확히 보여주며, 그 지식이 어떻게 획득되고 어디에 저장되는지를 제시해준다고!!! 실험방법, 실험, 결과
사회인구학적 정보는 언어 이해에서 매우 중요하지만, 지금까지 거의 연구되지 않았다. (앞 내용 요약)
SOCIOPROBE를 통해 PLM 내부에는 성별·나이 같은 사회인구학적 정보가 실제로 존재한다는 것을 확인했다.* 다만, 이 정보는 문법이나 의미 정보처럼 특정 레이어에 집중되어 있지 않고 여러 레이어에 분산(diffuse)되어 저장되어 있다. ( 실험 내용과 결론 ) 예를 들어서, 문법 정보 Layer 3에 집중되어 있음. 사회인구학 정보 Layer 6, 7, 8, 9, 10 등에 조금씩 퍼져 있음. 앞으로도 이런 연구 기대한다~~ 같은 말들
Probing(프로빙) 은 언어모델이 이미 학습한 정보가 내부 표현(hidden representation)에 들어 있는지 확인하는 실험 방법
"모델이 이 정보를 알고 있는가?"를 시험해 보는 방법인건데...~~
Hidden representation 위에 ㄹㅇ 간단한 분류기 하나를 붙이는거임 이 때 중요한 건 모델은 학습시키지 않음. 붙인 분류기를 학습시키는거임
왜냐면, 새로 학습시킨 걸 알고싶은게 아니라 기존에 알고있는 정보에 대한 판단인거기 때문 분류기가 의도한대로 잘 작동한다면 -&gt; 의도한 의미를 잘 알고있다고 판단하는거
여기 논문에서는 MDL Probing도 사용함
단순히 맞췄다! 를 넘어서 그 정보가 얼마나 쉽고 효율적으로 표현되어있는지를 평가하는고임
예 모델 A: 아주 간단한 분류기만으로 성별을 90% 정확도로 예측.
모델 B: 매우 복잡한 분류기를 써야 겨우 90% 정확도 달성.
둘 다 정확도는 같지만, 모델 A의 표현에는 성별 정보가 더 잘 정리되어 있다고 볼 수 있음. MDL은 이런 차이를 측정 정보이론 기반 probing이라고도 함. 정보량까지 보는거니까..
근데 왜 이렇게 두 개를 썼을까?
-&gt; 하나의 probing만 쓰면, 우연아냐? 할지도 모르니까. 논문 신뢰성 높일라고
일반 NLP 벤치마크사전학습이랑 파인튜닝 사이에 한 번 더 학습시키는 거]]></description><link>2026_하계_모각코/20260708-모각코-활동-2회차.html</link><guid isPermaLink="false">2026_하계_모각코/20260708 모각코 활동 2회차.md</guid><pubDate>Fri, 24 Jul 2026 08:01:48 GMT</pubDate></item><item><title><![CDATA[20260715 모각코 활동 3회차]]></title><description><![CDATA[여러 라운드의 역할 기반 상호작용에서
LLM이 어떻게 기만(거짓말) 하는지,
얼마나 정확하고 일관되게 동료의 기만을 탐지하는지,
이런 역학이 다중 턴에 걸쳐 어떻게 진화하는지를 다루는 벤치마크여기서의 기만 : 우리가 흔히 생각하는 '거짓말(Lying)'보다 훨씬 넓고 전략적인 개념
상대방이 오해하도록 교묘하게 판을 짜는 모든 행위
생략(판단에 중요한 내용을 쏙 빼놓고 말하기)
왜곡(사실 기반으로하되 겁나 과장하거나 축소)
주의분산(논점 흐리거나 다른 곳으로 시선 바꿔버리기)
날조(새빨간거짓말)
wolf게임 = 마피아게임
의심을 지수 평활법으로모델링함기만(deception)은 다중 에이전트 추론의 근본적인 과제이며, 효과적인 시스템은 정보를 전략적으로 숨기는 동시에 타인의 오해를 불러일으키는 행동을 탐지해야 합니다.
그러나 대부분의 평가는 기만을 정적인 분류 문제로 축소하여, 실제 기만적 역학의 상호작용적, 적대적, 종단적 특성을 간과하고 있습니다.
거대 언어 모델(LLM)은 설득력 있게 기만할 수 있지만, 동료의 기만을 탐지하는 능력은 여전히 취약합니다.
본 논문에서는 기만 생성과 탐지를 분리하여 측정할 수 있는, Werewolf(늑대인간) 게임 기반의 다중 에이전트 사회적 추론 벤치마크인 WOLF를 제시합니다.
WOLF는 역할 기반 에이전트(마을 주민, 늑대인간, 예언자, 의사)를 엄격한 밤낮 주기, 토론 차례, 다수결 투표가 포함된 프로그래밍 가능한 LangGraph 상태 머신에 내장합니다.
모든 발언은 별도의 분석 단위로 처리되며, 화자의 자기 평가 정직성과 타인의 동료 평가 기만성 점수가 포함됩니다.
기만은 표준화된 분류 체계(생략, 왜곡, 날조, 오도)를 통해 범주화되며, 의심 점수는 즉각적인 판단과 진화하는 신뢰 역학을 모두 포착하기 위해 종단적으로 평활화됩니다.
구조화된 로그는 프롬프트, 출력, 상태 전환을 보존하여 완전한 재현성을 보장합니다.
7,320개의 발언과 100번의 실행 결과, 늑대인간은 전체 차례의 31%에서 기만적인 발언을 생성했으며, 동료 탐지 성능은 71–73%의 정밀도와 52%의 전체 정확도를 기록했습니다.
늑대인간을 식별하는 정밀도는 더 높았으나, 마을 주민에 대한 위양성(false positive)이 발생하기도 했습니다.
늑대인간에 대한 의심은 라운드가 진행됨에 따라 52%에서 60% 이상으로 상승한 반면, 마을 주민과 의사에 대한 의심은 44–46% 수준에서 안정화되었습니다.
이러한 차이는 장기적인 상호작용이 진실한 역할에 대한 오류를 누적하지 않으면서도 거짓말쟁이에 대한 재현율을 향상시킨다는 점을 보여줍니다.
WOLF는 기만 평가를 정적 데이터셋 너머로 확장하여, 적대적 다중 에이전트 상호작용에서 기만 및 탐지 능력을 측정하기 위한 동적이고 통제된 테스트베드를 제공합니다.WOLF는 LLM의 기만 생성 및 탐지 능력을 평가하기 위한 다중 에이전트 사회적 추론 벤치마크입니다.
이 벤치마크는 프로그래밍 가능한 LangGraph 게임 루프 내에 역할 기반 에이전트를 포함하며, 모든 공개 발언은 자기 평가 및 동료 평가와 짝을 이루고 의심 점수는 시간이 지남에 따라 변화합니다.]]></description><link>2026_하계_모각코/20260715-모각코-활동-3회차.html</link><guid isPermaLink="false">2026_하계_모각코/20260715 모각코 활동 3회차.md</guid><pubDate>Fri, 24 Jul 2026 08:01:31 GMT</pubDate></item><item><title><![CDATA[20260130 모각코 활동 4회차]]></title><description><![CDATA[
SimCLRDataset: 동일 이미지에 augmentation 두 번 적용해 (view1, view2) 반환
SimCLRModel: 기존 ResNet18 backbone + Projection Head (MLP)
NTXentLoss + SimCLRTrainer 추가
(클로드가잔뜩도와줘서어찌저찌햇다다)
SimCLR은 동일 이미지에 서로 다른 Augmentation을 두 번 적용해 Positive Pair를 만든다.
__getitem__이 (view1, view2) 쌍을 반환하도록 해봤다.# src/dataset.py 에 추가
def get_simclr_transform(img_size: int = 32, s: float = 0.5) -&gt; transforms.Compose: color_jitter = transforms.ColorJitter( brightness=0.8 * s, contrast=0.8 * s, saturation=0.8 * s, hue=0.2 * s ) return transforms.Compose([ transforms.RandomResizedCrop(img_size, scale=(0.2, 1.0)), transforms.RandomHorizontalFlip(), transforms.RandomApply([color_jitter], p=0.8), transforms.RandomGrayscale(p=0.2), transforms.RandomApply( [transforms.GaussianBlur(kernel_size=3, sigma=(0.1, 2.0))], p=0.5 ), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) class SimCLRDataset(CIFAR10): def __init__( self, root: str, train: bool = True, transform=None, # get_simclr_transform() 결과를 주입 download: bool = True, ): super().__init__(root, train=train, transform=None, download=download) self.aug = transform # 두 번 각각 따로 적용 def __getitem__(self, index): img = Image.fromarray(self.data[index]) view1 = self.aug(img) view2 = self.aug(img) return view1, view2 # label 불필요 (self-supervised) def __len__(self): return len(self.data)
기존 Model(ResNet18)의 backbone을 인코더로 재사용하고,
그 위에 Projection Head (MLP) 를 추가한다.
Downstream에서는 Projection Head를 제거하고 backbone만 사용할 것이다다.# src/model.py 에 추가 class SimCLRModel(nn.Module): def __init__( self, embed_dim: int = 512, projection_dim: int = 128, num_classes: int = 10, ): super().__init__() self.embed_dim = embed_dim backbone = models.resnet18() backbone.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False) backbone.maxpool = nn.Identity() self.backbone = nn.Sequential(*list(backbone.children())[:-1]) self.projection_head = nn.Sequential( nn.Linear(embed_dim, embed_dim), nn.ReLU(inplace=True), nn.Linear(embed_dim, projection_dim), ) self.classifier = nn.Linear(embed_dim, num_classes) self.use_projection = True # Pretext: True / Downstream: False def forward(self, x): h = self.backbone(x).flatten(1) if self.use_projection: return self.projection_head(h) return self.classifier(h) def freeze_backbone(self): for param in self.backbone.parameters(): param.requires_grad = False @classmethod def from_checkpoint(cls, path, **kwargs): model = cls(**kwargs) model.load_state_dict(torch.load(path, map_location="cpu")) return model
NT-Xent Loss(Normalized Temperature-scaled Cross Entropy)를 구현하고,
Pretext 학습 전용 Trainer를 추가한다.# src/trainer.py 에 추가 import torch.nn.functional as F class NTXentLoss(nn.Module): def __init__(self, temperature: float = 0.5): super().__init__() self.temperature = temperature def forward(self, z1: torch.Tensor, z2: torch.Tensor) -&gt; torch.Tensor: B = z1.size(0) # L2 정규화 z1 = F.normalize(z1, dim=1) z2 = F.normalize(z2, dim=1) # (2B, 2B) 유사도 행렬 z = torch.cat([z1, z2], dim=0) # (2B, dim) sim = torch.mm(z, z.t()) / self.temperature # (2B, 2B) # 자기 자신(대각선) 마스킹 mask = torch.eye(2 * B, dtype=torch.bool, device=z.device) sim.masked_fill_(mask, float("-inf")) # Positive index: i번째의 positive는 i+B 또는 i-B 근데 이게 맞는지 모르겠다 labels = torch.cat([ torch.arange(B, 2 * B), # z1[i] → z2[i] torch.arange(0, B), # z2[i] → z1[i] ]).to(z.device) loss = F.cross_entropy(sim, labels) return loss class SimCLRTrainer: def __init__( self, model: SimCLRModel, device: torch.device = None, temperature: float = 0.5, ): self.model = model self.device = device or torch.device("cpu") self.model.to(self.device) self.criterion = NTXentLoss(temperature) def _train_one_epoch(self, loader, optimizer): self.model.train() self.model.use_projection = True total_loss = 0.0 for view1, view2 in tqdm(loader, desc="SimCLR Train", leave=False): view1 = view1.to(self.device) view2 = view2.to(self.device) z1 = self.model(view1) z2 = self.model(view2) loss = self.criterion(z1, z2) optimizer.zero_grad() loss.backward() optimizer.step() total_loss += loss.item() return total_loss / len(loader) @torch.no_grad() def _evaluate(self, loader): self.model.eval() self.model.use_projection = True total_loss = 0.0 for view1, view2 in loader: view1 = view1.to(self.device) view2 = view2.to(self.device) z1 = self.model(view1) z2 = self.model(view2) total_loss += self.criterion(z1, z2).item() return total_loss / len(loader) def train( self, train_loader, valid_loader, optimizer, epochs: int = 100, patience: int = 10, save_path: str = "./checkpoints/simclr/pretext", scheduler=None, ): save_dir = Path(save_path) save_dir.mkdir(parents=True, exist_ok=True) best_valid_loss = float("inf") patience_counter = 0 for epoch in range(1, epochs + 1): train_loss = self._train_one_epoch(train_loader, optimizer) valid_loss = self._evaluate(valid_loader) if scheduler: scheduler.step() print(f"[SimCLR] Epoch {epoch:03d} | Train Loss: {train_loss:.6f} | Valid Loss: {valid_loss:.6f}") if valid_loss &lt; best_valid_loss: best_valid_loss = valid_loss patience_counter = 0 ckpt_path = save_dir / f"epoch_{epoch:03d}_loss_{valid_loss:.6f}.pt" torch.save(self.model.state_dict(), ckpt_path) else: patience_counter += 1 if patience_counter &gt;= patience: print(f"[SimCLR] Early stopping at epoch {epoch}.") break
simclr: temperature: 0.5 projection_dim: 128 embed_dim: 512 pretext: lr: 3e-4 weight_decay: 1e-4 epochs: 100 patience: 10 save_path: "./checkpoints/simclr/pretext" scheduler: enabled: true type: "CosineAnnealingLR" T_max: 100 downstream: lr: 1e-4 weight_decay: 1e-4 epochs: 50 patience: 7 freeze_backbone: true save_path: "./checkpoints/simclr/downstream" scheduler: enabled: false
# experiments/train.py 에 추가 (기존 supervised / rotation 흐름 아래에 이어서 작성) from src.dataset import SimCLRDataset, get_simclr_transform
from src.model import SimCLRModel
from src.trainer import SimCLRTrainer, Trainer simclr_cfg = config["simclr"] simclr_aug = get_simclr_transform( img_size=config["data"]["img_size"][0], s=0.5
)
simclr_train_data = SimCLRDataset( root=config["data"]["root"], train=True, transform=simclr_aug,
)
simclr_valid_data = SimCLRDataset( root=config["data"]["root"], train=False, transform=simclr_aug,
) simclr_train_loader = DataLoader( simclr_train_data, batch_size=config["batch_size"]["unlabeled"], shuffle=True
)
simclr_valid_loader = DataLoader( simclr_valid_data, batch_size=config["batch_size"]["valid"]
) simclr_model = SimCLRModel( embed_dim=simclr_cfg["embed_dim"], projection_dim=simclr_cfg["projection_dim"],
)
simclr_trainer = SimCLRTrainer( simclr_model, device, temperature=simclr_cfg["temperature"]
) simclr_optimizer = torch.optim.AdamW( simclr_model.parameters(), lr=simclr_cfg["pretext"]["lr"], weight_decay=simclr_cfg["pretext"]["weight_decay"],
)
simclr_scheduler = build_scheduler(simclr_optimizer, simclr_cfg["pretext"]["scheduler"]) \ if simclr_cfg["pretext"]["scheduler"]["enabled"] else None simclr_trainer.train( train_loader=simclr_train_loader, valid_loader=simclr_valid_loader, optimizer=simclr_optimizer, epochs=simclr_cfg["pretext"]["epochs"], patience=simclr_cfg["pretext"]["patience"], save_path=simclr_cfg["pretext"]["save_path"], scheduler=simclr_scheduler,
) # 최적 체크포인트 로드
best_simclr_ckpt = min( Path(simclr_cfg["pretext"]["save_path"]).glob("*.pt"), key=lambda p: float(p.stem.split("_loss_")[-1])
)
simclr_model = SimCLRModel.from_checkpoint( best_simclr_ckpt, embed_dim=simclr_cfg["embed_dim"], projection_dim=simclr_cfg["projection_dim"],
) # Linear Probe 설정 (backbone 고정, classifier만 학습)
if simclr_cfg["downstream"]["freeze_backbone"]: simclr_model.freeze_backbone()
simclr_model.use_projection = False # classifier 모드로 전환 simclr_downstream_trainer = Trainer(simclr_model).to(device) simclr_downstream_optimizer = torch.optim.AdamW( filter(lambda p: p.requires_grad, simclr_model.parameters()), lr=simclr_cfg["downstream"]["lr"], weight_decay=simclr_cfg["downstream"]["weight_decay"],
) # 기존 labeled_loader / valid_loader 재사용
simclr_downstream_trainer.train( train_loader=labeled_loader, valid_loader=valid_loader, optimizer=simclr_downstream_optimizer, epochs=simclr_cfg["downstream"]["epochs"], is_pretext=False, patience=simclr_cfg["downstream"]["patience"], save_path=simclr_cfg["downstream"]["save_path"],
) print("--- SimCLR Model ---")
simclr_downstream_trainer.test(test_loader)
]]></description><link>2025-26_동계_모각코/20260130-모각코-활동-4회차.html</link><guid isPermaLink="false">2025-26_동계_모각코/20260130 모각코 활동 4회차.md</guid><pubDate>Mon, 23 Feb 2026 00:30:33 GMT</pubDate></item><item><title><![CDATA[20260213 모각코 활동 6회차]]></title><description><![CDATA[
MAEDataset: 패치 마스킹 후 (masked_img, original_img, mask) 반환
MAEModel: ViT 인코더(마스킹 안 된 패치만 처리) + 경량 디코더 구조
MAETrainer: 마스킹된 패치에 대한 MSE Loss
Rotation과 달리 MAE는 이미지를 패치로 나눈 뒤 일부를 마스킹하고 원본 픽셀을 복원하는 것이 목표!!
__getitem__이 (masked_img, original_img) 쌍을 반환하도록 했당# src/dataset.py 에 추가 class MAEDataset(CIFAR10): def __init__( self, root: str, train: bool = True, mask_ratio: float = 0.75, patch_size: int = 4, # CIFAR-10(32x32) 기준 → 8x8 = 64패치 transform=None, download: bool = True, ): super().__init__(root, train=train, transform=None, download=download) self.mask_ratio = mask_ratio self.patch_size = patch_size self.base_transform = transform # ToTensor + Normalize self.to_tensor = transforms.ToTensor() def _make_mask(self, num_patches: int) -&gt; torch.BoolTensor: """True인 위치 = 마스킹(제거)할 패치임임""" num_mask = int(num_patches * self.mask_ratio) mask = torch.zeros(num_patches, dtype=torch.bool) mask[torch.randperm(num_patches)[:num_mask]] = True return mask # shape: (num_patches,) def __getitem__(self, index): img = Image.fromarray(self.data[index]) # 원본 텐서 (복원 target) original = self.base_transform(img) # (C, H, W) # 마스킹된 텐서 생성 C, H, W = original.shape P = self.patch_size num_patches = (H // P) * (W // P) mask = self._make_mask(num_patches) # (num_patches,) # 패치 단위로 마스킹 (마스킹 위치를 0으로) masked = original.clone() idx = 0 for row in range(H // P): for col in range(W // P): if mask[idx]: masked[:, row*P:(row+1)*P, col*P:(col+1)*P] = 0.0 idx += 1 return masked, original, mask # mask는 loss 계산에 사용 def __len__(self): return len(self.data)
기존 Model(ResNet18)은 Downstream에서 그대로 재사용한다.
MAE Pretext 전용으로 ViT 인코더 + 작은디코더 구조를 추가했다.# src/model.py 에 추가 import math class PatchEmbed(nn.Module): def __init__(self, img_size=32, patch_size=4, in_channels=3, embed_dim=192): super().__init__() self.num_patches = (img_size // patch_size) ** 2 self.proj = nn.Conv2d(in_channels, embed_dim, kernel_size=patch_size, stride=patch_size) def forward(self, x): # x: (B, C, H, W) → (B, num_patches, embed_dim) return self.proj(x).flatten(2).transpose(1, 2) class MAEModel(nn.Module): """ - 인코더: 마스킹되지 않은 패치만 처리 - 디코더: 전체 패치 받아 픽셀 복원 """ def __init__( self, img_size: int = 32, patch_size: int = 4, in_channels: int = 3, encoder_dim: int = 192, encoder_depth: int = 6, encoder_heads: int = 3, decoder_dim: int = 96, decoder_depth: int = 2, decoder_heads: int = 3, ): super().__init__() self.patch_size = patch_size self.num_patches = (img_size // patch_size) ** 2 self.encoder_dim = encoder_dim self.patch_embed = PatchEmbed(img_size, patch_size, in_channels, encoder_dim) self.cls_token = nn.Parameter(torch.zeros(1, 1, encoder_dim)) self.enc_pos_embed = nn.Parameter( torch.zeros(1, 1 + self.num_patches, encoder_dim) ) encoder_layer = nn.TransformerEncoderLayer( d_model=encoder_dim, nhead=encoder_heads, dim_feedforward=encoder_dim * 4, batch_first=True, norm_first=True ) self.encoder = nn.TransformerEncoder(encoder_layer, num_layers=encoder_depth) self.enc_norm = nn.LayerNorm(encoder_dim) self.enc_to_dec = nn.Linear(encoder_dim, decoder_dim) self.mask_token = nn.Parameter(torch.zeros(1, 1, decoder_dim)) self.dec_pos_embed = nn.Parameter( torch.zeros(1, 1 + self.num_patches, decoder_dim) ) decoder_layer = nn.TransformerEncoderLayer( d_model=decoder_dim, nhead=decoder_heads, dim_feedforward=decoder_dim * 4, batch_first=True, norm_first=True ) self.decoder = nn.TransformerEncoder(decoder_layer, num_layers=decoder_depth) self.dec_norm = nn.LayerNorm(decoder_dim) self.pred_head = nn.Linear(decoder_dim, patch_size ** 2 * in_channels) self._init_weights() def _init_weights(self): nn.init.trunc_normal_(self.cls_token, std=0.02) nn.init.trunc_normal_(self.enc_pos_embed, std=0.02) nn.init.trunc_normal_(self.dec_pos_embed, std=0.02) nn.init.trunc_normal_(self.mask_token, std=0.02) def encode(self, x, mask): B = x.size(0) # cls token 추가 cls = self.cls_token.expand(B, -1, -1) x = torch.cat([cls, x], dim=1) # (B, 1+num_patches, dim) x = x + self.enc_pos_embed cls_x = x[:, :1, :] patch_x = x[:, 1:, :] # (B, num_patches, dim) visible = patch_x[~mask.unsqueeze(-1).expand_as(patch_x)].view(B, -1, self.encoder_dim) x_enc = torch.cat([cls_x, visible], dim=1) x_enc = self.encoder(x_enc) x_enc = self.enc_norm(x_enc) return x_enc def decode(self, x_enc, mask): B = x_enc.size(0) x_dec = self.enc_to_dec(x_enc) # 차원 축소 tokens = self.mask_token.expand(B, self.num_patches, -1).clone() num_visible = (~mask).sum(dim=1)[0].item() tokens[~mask] = x_dec[:, 1:1 + int(num_visible), :].reshape(-1, x_dec.size(-1)) cls_dec = x_dec[:, :1, :] full = torch.cat([cls_dec, tokens], dim=1) full = full + self.dec_pos_embed full = self.decoder(full) full = self.dec_norm(full) return self.pred_head(full[:, 1:, :]) # (B, num_patches, patch_size^2*C) def forward(self, x, mask): patches = self.patch_embed(x) # (B, num_patches, encoder_dim) x_enc = self.encode(patches, mask) pred = self.decode(x_enc, mask) return pred def get_encoder(self): return nn.Sequential(self.patch_embed, self.encoder, self.enc_norm)
MAE는 마스킹 패치에 대한 MSE Loss를 사용하므로 별도 Trainer를 추가했다...# src/trainer.py 에 추가
class MAETrainer: def __init__(self, model: MAEModel, device: torch.device = None): self.model = model self.device = device or torch.device("cpu") self.model.to(self.device) def _patchify(self, imgs: torch.Tensor, patch_size: int) -&gt; torch.Tensor: B, C, H, W = imgs.shape P = patch_size imgs = imgs.reshape(B, C, H // P, P, W // P, P) imgs = imgs.permute(0, 2, 4, 1, 3, 5).reshape(B, -1, P * P * C) return imgs def _compute_loss(self, pred, target, mask): loss = ((pred - target) ** 2).mean(dim=-1) # (B, num_patches) loss = (loss * mask.float()).sum() / mask.float().sum() return loss def _train_one_epoch(self, loader, optimizer): self.model.train() total_loss = 0.0 for masked_imgs, original_imgs, masks in tqdm(loader, desc="MAE Train", leave=False): masked_imgs = masked_imgs.to(self.device) original_imgs = original_imgs.to(self.device) masks = masks.to(self.device) # (B, num_patches) pred = self.model(masked_imgs, masks) target = self._patchify(original_imgs, self.model.patch_size) loss = self._compute_loss(pred, target, masks) optimizer.zero_grad() loss.backward() optimizer.step() total_loss += loss.item() return total_loss / len(loader) @torch.no_grad() def _evaluate(self, loader): self.model.eval() total_loss = 0.0 for masked_imgs, original_imgs, masks in loader: masked_imgs = masked_imgs.to(self.device) original_imgs = original_imgs.to(self.device) masks = masks.to(self.device) pred = self.model(masked_imgs, masks) target = self._patchify(original_imgs, self.model.patch_size) total_loss += self._compute_loss(pred, target, masks).item() return total_loss / len(loader) def train( self, train_loader, valid_loader, optimizer, epochs: int = 100, patience: int = 10, save_path: str = "./checkpoints/mae", scheduler=None, ): save_dir = Path(save_path) save_dir.mkdir(parents=True, exist_ok=True) best_valid_loss = float("inf") patience_counter = 0 for epoch in range(1, epochs + 1): train_loss = self._train_one_epoch(train_loader, optimizer) valid_loss = self._evaluate(valid_loader) if scheduler: scheduler.step() print(f"[MAE] Epoch {epoch:03d} | Train Loss: {train_loss:.6f} | Valid Loss: {valid_loss:.6f}") if valid_loss &lt; best_valid_loss: best_valid_loss = valid_loss patience_counter = 0 ckpt_path = save_dir / f"epoch_{epoch:03d}_loss_{valid_loss:.6f}.pt" torch.save(self.model.state_dict(), ckpt_path) else: patience_counter += 1 if patience_counter &gt;= patience: print(f"[MAE] Early stopping at epoch {epoch}.") break
# configs/config.yaml 에 추가 mae: patch_size: 4 # 32x32 이미지 → 8x8 = 64패치 mask_ratio: 0.75 encoder_dim: 192 encoder_depth: 6 decoder_dim: 96 decoder_depth: 2 pretext: lr: 1.5e-4 weight_decay: 0.05 epochs: 100 patience: 10 save_path: "./checkpoints/mae/pretext" scheduler: enabled: true type: "CosineAnnealingLR" T_max: 100 downstream: lr: 1e-4 weight_decay: 0.05 epochs: 50 patience: 7 save_path: "./checkpoints/mae/downstream" scheduler: enabled: false
곧 추가할 예정이다...!]]></description><link>2025-26_동계_모각코/20260213-모각코-활동-6회차.html</link><guid isPermaLink="false">2025-26_동계_모각코/20260213 모각코 활동 6회차.md</guid><pubDate>Mon, 23 Feb 2026 00:29:34 GMT</pubDate></item><item><title><![CDATA[20260206 모각코 활동 5회차]]></title><description><![CDATA[<a rel="noopener nofollow" class="external-link is-unresolved" href="https://arxiv.org/abs/2111.06377" target="_self">https://arxiv.org/abs/2111.06377</a>자기지도학습 - 이미지의 일부를 가리고 복원하는 방식으로 표현을 학습하는 방법"This paper shows that masked autoencoders (MAE) are scalable self-supervised learners for computer vision." 이 논문은 마스크 오토인코더(MAE)가 컴퓨터 비전에서 확장 가능한 자기지도학습 모델임을 보입니다. #MAE #maskedautoencoder #scalable 핵심 키워드는 "scalable" — SimCLR이 "simple"을 강조했다면, MAE는 "크게 키워도 잘 된다"는 확장성을 강조함"Our MAE approach is simple: we mask random patches of the input image and reconstruct the missing pixels." 우리의 접근법은 단순합니다: 입력 이미지의 랜덤 패치를 마스킹하고 빠진 픽셀을 복원합니다. NLP의 BERT와 유사한 발상 — BERT는 단어를 마스킹하고 예측, MAE는 이미지 패치를 마스킹하고 복원. 개념적으로는 단순하지만 구현에서 핵심적인 설계 선택들이 있음"First, we develop an asymmetric encoder-decoder architecture... Second, we find that masking a high proportion of the input image, e.g., 75%, yields a nontrivial and meaningful self-supervisory task." 두 가지 핵심 설계:
비대칭 인코더-디코더: 인코더는 보이는 패치만 처리 (마스크 토큰 없음), 디코더는 가볍게
높은 마스킹 비율(75%): 이미지 중복성이 높기 때문에, 쉬운 task가 되지 않으려면 많이 가려야 함
논문이 이 질문에 직접 답하는 게 인상적임. 세 가지 이유를 제시:아키텍처 차이 — 기존엔 CNN이 주류라 마스크 토큰 같은 개념을 삽입하기 어려웠음. ViT 등장으로 해결됨정보 밀도 차이 ← 이게 핵심!
언어: 단어 하나하나가 semantic하게 밀도 높음. 몇 개만 가려도 어려운 task
이미지: 공간적 중복성이 매우 높음. 옆 픽셀에서 쉽게 추측 가능
→ 해결책: 아주 많이 가리기 (75%)
디코더의 역할 차이
BERT 디코더: 의미 있는 단어를 예측 → 간단한 MLP로도 충분
MAE 디코더: 픽셀값을 복원 → 낮은 semantic 수준, 디코더 설계가 중요해짐
인코더 (무거움)
보이는 패치(25%)만 처리 → 마스크 토큰 없음
표준 ViT 구조 사용
포지셔널 임베딩 추가
디코더 (가벼움)
인코더 출력 + 마스크 토큰을 모두 받아서 처리
인코더보다 훨씬 작음 (FLOPs 기준 ~9% 수준)
Pre-training 때만 사용 → fine-tuning 시엔 버림
왜 이 설계가 효율적인가? 인코더가 전체 패치의 25%만 처리하니 연산량이 대폭 줄어듦. 논문 실험 기준 3× 이상 학습 속도 향상손실 함수는 MSE (Mean Squared Error) — 마스킹된 패치에 대해서만 계산 (BERT와 동일한 방식)흥미로운 변형: 패치별 정규화(normalized pixels)
각 패치의 픽셀값을 해당 패치의 평균/표준편차로 정규화해서 예측 target으로 사용
로컬 대비(local contrast)를 강화 → 실험 결과 성능 향상
토큰 기반 방법(BEiT 등)과 비교했을 때 픽셀 기반도 충분히 좋거나 더 나음 → 복잡한 tokenizer 없이도 잘 된다는 게 MAE의 강점마스킹 비율의 영향 (Figure 5)
fine-tuning: 40~80% 범위에서 전반적으로 잘 됨, 75%가 sweet spot
linear probing: 비율이 높을수록 꾸준히 향상. 75%가 최적
BERT의 15%와 대조적으로 이미지에선 왜 75%가 필요한지 직접 실험으로 보여줌
주요 성능 (Table 3)
ViT-H로 ImageNet-1K에서 87.8% top-1 달성 — IN1K 데이터만 사용한 방법 중 최고
supervised pre-training보다 transfer learning 성능도 좋음
학습 효율
BEiT보다 3.5× 빠름 (인코더에서 마스크 토큰 제거 덕분)
MoCo v3보다 적은 epoch에서 더 높은 성능
data augmentation 의존도 차이가 흥미로움. SimCLR은 crop+color distortion 조합이 없으면 성능이 크게 떨어지는데, MAE는 random masking 자체가 augmentation 역할을 하기 때문에 크게 의존하지 않음.MAE = "이미지의 75%를 가리고 복원하는 task를 통해, 라벨 없이도 지도학습을 능가하는 표현을 학습한다. 핵심은 비대칭 구조로 빠르게, 높은 마스킹 비율로 어렵게."
코드 구현 시 rotation 기반과의 가장 큰 차이는 task의 성격 — rotation은 분류(4-class), MAE는 픽셀 복원(regression+MSE)이라는 점, 그리고 아키텍처도 ViT 기반이어야 패치 단위 마스킹이 자연스럽다는 점이 구현에서 핵심 고려사항이 될 것 같음!]]></description><link>2025-26_동계_모각코/20260206-모각코-활동-5회차.html</link><guid isPermaLink="false">2025-26_동계_모각코/20260206 모각코 활동 5회차.md</guid><pubDate>Wed, 18 Feb 2026 06:35:20 GMT</pubDate></item><item><title><![CDATA[20260116 모각코 활동 2회차]]></title><description><![CDATA[
대상 원본: dAiv_ssl_rotation_resnet18.ipynb
리팩토링 결과물: src/, configs/, experiments/
기존 코드는 Jupyter Notebook 단일 파일(dAiv_ssl_rotation_resnet18.ipynb)에 데이터 로딩, 모델 정의, 학습 루프, 실험 실행이 모두 섞여있었다. 이를 모듈화된 Python 패키지 구조로 분리해보았다!!
데이터 / 모델 / 학습 로직을 독립 모듈로 분리
모든 하이퍼파라미터를 config.yaml 단일 파일에서 관리
기존 학습 로직 보존: 체크포인트 저장, Early Stopping 동작 변경 없음
SSL-paper-study/
└── dAiv_ssl_rotation_resnet18.ipynb &nbsp; # 모든 코드가 단일 노트북에 존재
SSL-paper-study/
├── src/
│ &nbsp; ├── __init__.py &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 패키지 공개 API 정의
│ &nbsp; ├── dataset.py &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # DataType, CIFAR10Dataset, get_transforms()
│ &nbsp; ├── model.py &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Model (ResNet18 기반)
│ &nbsp; └── trainer.py &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Trainer (scheduler 인자 추가)
├── configs/
│ &nbsp; └── config.yaml &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 전체 하이퍼파라미터 관리
├── experiments/
│ &nbsp; └── train.py &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 실험 실행 진입점
└── dAiv_ssl_rotation_resnet18.ipynb &nbsp; # 원본 유지 (수정 없음)
노트북의 DataType Enum과 CIFAR10Dataset 클래스를 그대로 옮기고, get_transforms() 함수를 새로 추가했다.이전된 내용 (변경 없음)
DataType Enum: LABELED_TRAIN, UNLABELED_TRAIN, UNLABELED_VALID, VALID, TEST
CIFAR10Dataset: seed=42 고정 분할, rotation label 자동 생성, transform 외부 주입 구조
신규 추가: get_transforms()def get_transforms( img_size: Tuple[int, int], mean: List[float], std: List[float], augment: bool = False,
) -&gt; transforms.Compose:
노트북의 Model 클래스를 변경 없이 그대로 이전했다.
ResNet18 backbone (CIFAR-10 적합 수정: conv1 3×3, maxpool → Identity)
is_pretext 플래그로 rotation_classifier / classifier 분기
Model.from_checkpoint() 클래스 메서드로 가중치 로드
노트북의 Trainer 클래스를 이전하고 train() 메서드에 scheduler 인자를 추가했다.변경 사항# 변경 전
def train(self, train_loader, valid_loader, optimizer, epochs, ...): # 변경 후
def train(self, train_loader, valid_loader, optimizer, epochs, ..., scheduler: Optional[torch.optim.lr_scheduler._LRScheduler] = None):
scheduler가 주어지면 매 epoch 종료 후 scheduler.step() 자동 호출:train_loss = self._train_one_epoch(...)
valid_loss, valid_acc = self._evaluate(...) if scheduler is not None: scheduler.step() # ← 추가
보존된 내용 (변경 없음)
_train_one_epoch() / _evaluate() 학습·평가 로직
patience 기반 Early Stopping
패키지 단독 임포트가 가능하도록 고쳤다.from .dataset import DataType, CIFAR10Dataset, get_transforms
from .model import Model
from .trainer import Trainer __all__ = ["DataType", "CIFAR10Dataset", "get_transforms", "Model", "Trainer"]
모든 하이퍼파라미터를 계층 구조로 관리한다. experiments/train.py에 하드코딩된 값은 없다.config.yaml
├── data &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: root, img_size, mean/std, split 비율
├── batch_size &nbsp; &nbsp;: labeled / unlabeled / valid
├── device &nbsp; &nbsp; &nbsp; &nbsp;: GPU 인덱스 (-1이면 CPU)
├── pretrained &nbsp; &nbsp;: HuggingFace Hub repo_id / file_name
├── supervised &nbsp; &nbsp;: lr, weight_decay, epochs, patience, save_top_k, save_path, scheduler
└── self_supervised
&nbsp; &nbsp; ├── pretext &nbsp; : (위와 동일 구조)
&nbsp; &nbsp; └── downstream: (위와 동일 구조)
각 학습 단계의 scheduler 블록 구조:scheduler: enabled: false # true로 변경하면 즉시 적용 type: "CosineAnnealingLR" T_max: 50 # 생성자에 그대로 전달되는 파라미터
노트북의 실험 순서를 그대로 유지하며 전체 실험을 실행하는 진입점 스크립트다.실행 흐름1. config.yaml 로드
2. device 설정
3. Dataset / DataLoader 생성
&nbsp; &nbsp;└─ labeled_loader만 augment=True, 나머지는 augment=False
4. Supervised 학습 (scheduler 포함)
5. SSL Pretext 학습 (HuggingFace Hub 사전학습 가중치 로드 → scheduler 포함)
6. SSL Downstream 학습 (Pretext 최적 체크포인트 로드 → scheduler 포함)
7. 두 모델 테스트 결과 출력
핵심: 동적 Scheduler 생성def build_scheduler(optimizer, sch_cfg): sch_cls = getattr(torch.optim.lr_scheduler, sch_cfg["type"]) kwargs = {k: v for k, v in sch_cfg.items() if k not in ("enabled", "type")} return sch_cls(optimizer, **kwargs)
type 필드만 교체하면 StepLR, OneCycleLR 등 어떤 scheduler로도 전환 가능하다.실행 방법# 프로젝트 루트에서 실행
python experiments/train.py
python experiments/train.py --config configs/config.yaml dAiv_ssl_rotation_resnet18.ipynb — 원본 노트북 무수정
CIFAR10Dataset의 seed=42 데이터 분할 로직
Trainer의 체크포인트 저장 / Early Stopping 동작
Model 아키텍처 (backbone, classifier, rotation_classifier)
]]></description><link>2025-26_동계_모각코/20260116-모각코-활동-2회차.html</link><guid isPermaLink="false">2025-26_동계_모각코/20260116 모각코 활동 2회차.md</guid><pubDate>Wed, 18 Feb 2026 06:30:25 GMT</pubDate></item><item><title><![CDATA[20260123 모각코 활동 3회차]]></title><description><![CDATA[SimcCLR논문 읽기.시각적 표현의 대조 학습을 위한 간단한 프레임워크<a rel="noopener nofollow" class="external-link is-unresolved" href="https://arxiv.org/pdf/2002.05709" target="_self">https://arxiv.org/pdf/2002.05709</a>자기지도학습 - 라벨 없이도 좋은 이미지 표현을 학습하기위한 방법들 중 한 방식으로서 나온 아이디어같은 이미지를 두 번 다르게 변형
같은 이미지에서 나온 두 버전 → 비슷하게
다른 이미지에서 나온 두 버전 → 다르게초록 분석
“This paper presents SimCLR: a simple framework for contrastive learning of visual representations.” 이 논문은 SimCLR을 제안합니다: 시각적 표현의 대조 학습을 위한 간단한 프레임워크
#SimCLR #contrastivelearning #simple 논문의 contribution은 “간단하면서도 효과적인” 방법!“We simplify recently proposed contrastive self-supervised learning algorithms without requiring specialized architectures or a memory bank.” 우리는 최근 제안된 대조 자기지도학습 알고리즘들을 단순화했으며, 특수한 구조나 메모리 뱅크가 필요없습니다.
기존 방법의 문제점 지적 ∙ Specialized architectures: 특별히 설계된 복잡한 네트워크 ∙ Memory bank: 이전 데이터를 저장하는 큰 메모리 (MoCo, InstDisc 등이 사용) - 이전에 계산한 feature들을 저장해두는 큰 저장소. 메모리 많이 먹고 구현 복잡함 ∙ SimCLR은 이런 거 없이도 잘 된다란 말임“In order to understand what enables the contrastive prediction tasks to learn useful representations, we systematically study the major components of our framework.” 대조 예측 과제가 유용한 표현을 학습하게 만드는 요인을 이해하기 위해, 우리는 프레임워크의 주요 구성 요소들을 체계적으로 연구했습니다.
∙ 이 논문의 방법론적 기여… 단순히 “이게 잘 되더라”가 아니라 → “왜 잘 되는지“ 분석
∙ “systematically study” = Ablation study (소거 실험)를 많이 했다는 뜻 → 이 논문의 강점! 각 구성요소의 영향을 실험으로 증명 ( Ablation study : )“We show that (1) composition of data augmentations plays a critical role…, (2) introducing a learnable nonlinear transformation… substantially improves…, and (3) contrastive learning benefits from larger batch sizes and more training steps…”
우리는 다음을 보였습니다:
1. 데이터 증강의 조합이 중요한 역할을 함
2. 학습 가능한 비선형 변환을 도입하면 성능이 크게 향상됨
3. 대조 학습은 큰 배치 크기와 더 많은 학습 단계로부터 이득을 봄
이 논문의 핵심 기여 3가지를 미리 요약! 발견 (1): 데이터 증강 ∙ “composition” = 여러 개를 조합하는 것 ∙ Critical role = 매우 중요함 ∙ 특히 crop + color distortion 조합 발견 (2): Projection head ∙ “nonlinear transformation” = MLP (비선형 신경망) ∙ “between representation and loss” = 표현 h와 손실 함수 사이에 삽입 ∙ Substantially improves = 엄청 좋아짐 (실제로 10%+ 향상) 발견 (3): 학습 설정 ∙ Larger batch sizes = 4096 이상 ∙ More training steps = 1000 epochs ∙ “compared to supervised learning” = 지도학습보다 더 필요함“By combining these findings, we are able to considerably outperform previous methods for self-supervised and semi-supervised learning on ImageNet.” 이러한 발견들을 결합하여, 우리는 ImageNet에서 자기지도학습과 준지도학습에 대한 이전 방법들을 크게 능가할 수 있었습니다. 평가 데이터셋 ImageNet (가장 널리 쓰이는 벤치마크)으로 두 가지 세팅에서 테스트: ∙ Self-supervised: 라벨 전혀 안 씀 ∙ Semi-supervised: 라벨 조금만 씀 (1%, 10%)
(구체적 성능) “A linear classifier trained on self-supervised representations learned by SimCLR achieves 76.5% top-1 accuracy, which is a 7% relative improvement over previous state-of-the-art, matching the performance of a supervised ResNet-50.” SimCLR이 학습한 자기지도 표현에 선형 분류기를 학습시키면 76.5% top-1 정확도를 달성하며, 이는 이전 최고 성능 대비 7% 상대적 향상이고, 지도학습 ResNet-50의 성능과 동등합니다. Linear evaluation 학습된 feature를 고정 (freeze)하고 그 위에 간단한 선형 분류기만 학습하는건데 Feature의 품질을 측정하는 표준 방법임 ∙ “matching supervised ResNet-50” ∙ 엄청난 의미! 라벨 없이도 지도학습과 같은 성능!(Semi-supervised 성능) “When fine-tuned on only 1% of the labels, we achieve 85.8% top-5 accuracy, outperforming AlexNet with 100× fewer labels.” 한글: 라벨의 1%만으로 fine-tuning 했을 때, 우리는 85.8% top-5 정확도를 달성하며, 이는 100배 적은 라벨로 AlexNet을 능가합니다. ∙ 1% labels = ImageNet의 1%만 라벨 사용 ∙ Top-5 accuracy = 상위 5개 예측 중 정답이 있으면 맞음 ∙ AlexNet: 100% 라벨 필요 ∙ SimCLR: 1% 라벨로 더 좋은 성능 ∙ 라벨링 비용을 100배 줄일 수 있다! 왜 AlexNet과 비교? ∙ AlexNet은 2012년 ImageNet 우승 모델이어가지고 딥러닝 역사에서 중요한 baseline이엇음.]]></description><link>2025-26_동계_모각코/20260123-모각코-활동-3회차.html</link><guid isPermaLink="false">2025-26_동계_모각코/20260123 모각코 활동 3회차.md</guid><pubDate>Wed, 18 Feb 2026 03:17:56 GMT</pubDate></item><item><title><![CDATA[대회 기록]]></title><description><![CDATA[기본 베이스라인
캘리브레이션: 양자화 시 가중치 손실을 최소화하기 위해 실제 데이터로
모델의 활성화 패턴을 분석하는 과정
SCHEME = "W4A16"의 의미? : - W = Weight(가중치), A = Activation(활성화), W4A16 = 가중치 4비트, 활성화 16비트
]]></description><link>lgaimers/대회-기록.html</link><guid isPermaLink="false">lgAimers/대회 기록.md</guid><pubDate>Wed, 11 Feb 2026 06:05:31 GMT</pubDate></item><item><title><![CDATA[20260110 모각코 활동 1회차]]></title><description><![CDATA[오늘의 목표 : 기존 작성 코드 분석하고 내가 뭘 해야할지 생각해보기핵심 특징:
Unlabeled 데이터의 경우 각 이미지를 0°, 90°, 180°, 270° 회전하여 4배로 증강
회전 각도(0-3)를 레이블로 사용하여 Pretext Task 학습
Labeled/Unlabeled 데이터 분할을 위한 캐싱 메커니즘으로 구현함
백본 (Backbone):
ResNet-18 기반
CIFAR-10에 맞게 첫 번째 Conv 레이어 수정 (kernel_size=3, stride=1)
MaxPool 레이어 제거
512차원 임베딩 출력
분류기 (Classifiers):
classifier: Downstream task용 10-way 분류기 (CIFAR-10 클래스)
rotation_classifier: Pretext task용 4-way 분류기 (회전 각도)
동작 방식:
is_pretext 플래그에 따라 사용할 분류기 결정
체크포인트에서 가중치 로드 기능 제공 (from_checkpoint)
주요 기능:
_train_one_epoch: 1 에포크 학습 수행
_evaluate: 검증/테스트 데이터로 평가
train: 전체 학습 루프 (early stopping, checkpoint 관리)
test: 최종 테스트 수행
체크포인트 관리:
검증 손실 기준으로 상위 K개 모델 저장 (save_top_k)
Early stopping (patience 파라미터)
학습 진행 상황을 tqdm으로 시각화 Labeled 데이터 (10%)만 사용
50 에포크 학습, learning rate = 1e-3
CIFAR-10 클래스 직접 예측
A. Pretext Task (회전 예측)
4. Unlabeled 데이터 (90%) 사용
5. 30 에포크 학습, learning rate = 1e-3
6. 이미지 회전 각도(0°, 90°, 180°, 270°) 예측
7. 백본 네트워크가 시각적 표현 학습B. Downstream Task (분류)
8. Pretext에서 학습한 백본 사용
9. Labeled 데이터 (10%)로 Fine-tuning
10. 30 에포크 학습, learning rate = 1e-4
11. CIFAR-10 클래스 예측
명확한 구조: 데이터, 모델, 학습이 잘 분리되어 있음
재사용 가능하게 함 : Dataset과 Trainer 클래스가 일반화되어 있음
효율적인 데이터 관리: 데이터 분할 일관성 보장
실용적인 기능: 체크포인트 관리, early stopping, 진행 상황 시각화 모듈화: dataset, model, trainer를 별도 파일로 분리
설정 파일: config.yaml 생성 및 적용
프로젝트 구조: src/, configs/, experiments/ 디렉토리 구성
데이터 증강: transform pipeline 개선
학습 안정화: learning rate scheduler 추가
아직 확장성과 유지보수성 측면에서 개선의 여지가 있어보인다! 2회차에서는 코드를 모듈화하고 설정 관리를 체계화하여 더 나은 구조로 발전시켜보면 좋을 거 같다.
이를 통해 앞으로 SimCLR, MAE 등 다양한 자기지도학습 방법론을 쉽게 추가하고 비교 실험할 수 있는 기반을 마련하는것이 내 목표이당]]></description><link>2025-26_동계_모각코/20260110-모각코-활동-1회차.html</link><guid isPermaLink="false">2025-26_동계_모각코/20260110 모각코 활동 1회차.md</guid><pubDate>Wed, 11 Feb 2026 05:48:58 GMT</pubDate></item><item><title><![CDATA[강의수강_chapter02]]></title><description><![CDATA[머신러닝 : 데이터로부터 패턴 파악, 학습
알고리즘이 학습과정에서의 피드백 받는 방식 supervised data + labels
overfitting 가능성
regression / classification semisupervised / selfsupervised pseudo-labeled data unsupervised unlabeled data reinforcement agent의 action -&gt; state + reward ( reward system )
trial and error
딥러닝 : 하나 이상의 hidden layer를 갖고 있는 neural network neural network : 행렬의 모임 ( feature들의 weight 만큼의 정보가 담겨있는 유의미한 행렬임 ) 이 neural network를 학습한다는 것 : 각 node를 연결하는 weight의 값을 얼마로 할당해줄까? 에 대한 것들을 찾아가는 과정임 loss -&gt; backpropagation으로 계속 업데이트해나가며 찾아감 단일 neural network -&gt; 이건 아무리 딥하게 쌓아도 그냥 linear한 함수가 되는거임 -&gt; non linear fuction이 꼬옥 필요한 이유. 비선형성이 추가되어야함 ( xor 문제 생각해보기! )
일반적인 neural network ( 비선형성이 추가됨 ) fully connected networkt : 앞 모든 뉴런들 - 다음 뉴런 모두 연결 그럼 prediction에서는? 우리가 하자고 했던 task에 맞추어 결과를 뽑아낼 수 있어야 함 - 확률 분포를 뽑아내야 함. softmax layer prediction을 통해 loss를 구하고, backpropagation 수행 tokenization
vocab size too big : 너무 많은 계산량
too small : 너무 많은 단어가 unk token이 되는것
word embedding bag of words : 고냥 제일 단순한 단어 매칭임 (one hot vector같은 고)
word2vec : 특정 단어A의 임베딩을 위해 주변 단어들을 이용해서 A를 예측하도록 하는 pseudo task를 정의하여 학습시킨 임베딩 방식 cbow : 주변 단어들을 통해 특정 단어를 예측하는 방식으로 vector값 업데이트
skip gram : 특정 단어를 통해 주변 단어를 예측하는 방식으로 vector값 업데이트
위와 같은 방식들의 최종(마지막) hidden layer가 각 단어의 word vector묶음마냥 표현이 되는 것 -&gt; word embedding vector
language model ( lstm 까지..! )
language model의 학습 단어 시퀀스에서 다음 단어의 확률 분포를 뽑는 과정 fixed language model : windows가 정해진(문맥의 단어 개수가 정해진 상황) 상황이 가정된 모델 -&gt; 전체 문맥을 봐야하는데 이러면 어떡함?
rnn : sequential data에 너무나도 자연스러운 형태임 이전 내용 계속 누적. 하나의 weight를 계속 공유하기 때문에 이러한 것이 가능함. 그러나 computation측면에서 많은 단점. 매 step(시퀀스에서 단어를 하나하나 가져올 때마다)마다 loss 계산, gradient 계산 하는 과정 이 때 이전 결과를 다음 입력으로 넣을수도,
정답 자체를 다음 입력으로 넣을수도 있음. lstm rnn : rnn에 gate, cell추가됨 forget gate : 얼마나 잊을것인가? -&gt; 이전 정보를 얼마 만큼만 보존하고 반영할 것인지를 -&gt; 이전 정보의 중요도 결정
input gate : 얼마나 입력할것인가? -&gt; 새로운 내용을 얼마만큼 반영할 것인지를 -&gt; 새 값의 가중치 결정
output gate : cell state에서 얼마나 출력할것인가? ( hidden sate 결정 )
cell state : 장기 기억 저장 벡터 값
C_t = (forget gate × C_{t-1}) + (input gate × C̃_t) : forget gate, input gate는 각각 순차적인 계산이 아니라 두 gate의 결과를 병렬로 계산 후 더하는 것 기존 seq2seq (encoder-decoder) 구조 모델
encoder rnn : input 문장 요약 / 이해
decoder rnn : encoder layer를 거친 마지막 hidden state를 다시 decoder rnn 입력으로 넣어, 순차으로 단어 예측
rnn이 가지는 기존 단점이 여전히 존재. encoder의 last hidden state만을 가지고 decoder의 입력으로 들어가기 때문에, encoder에서의 최근 정보만 강하게 기억, 초반 부분의 내용은 많이 잊게 됨 그럼 초기~최근 으로 갈수록 더 많이 기억하게 되는 구조를 사용하지 말아보자
중요한 부분에만 집중하도록 해보는 건? -&gt;attention encoder의 last hidden state를 쓰는 것이 아니라, context vector라는 것을 만들어서 사용해보기
context vector : encoder의 hidden state -&gt; attention weight 계산 -&gt; weighted sum - normalization (softmax)
attention weight encoder의 hidden state와 decoder의 hidden state의 연관성을 보자
여기서의 연관성 =&gt; dot product를 계산 후 socre 뽑아내기 rnn &lt;-&gt; transformer
rnn의 기존 문제점 : 한 번에 많은 sequence를 처리하기 힘들다, 병렬 처리가 불가능한 구조, 장기 의존성 문제
transformer : rnn과는 완전히 새롭고 다른 구조 -&gt; attention mechanism만 이용해서 만들어진 구조, 병렬 처리 가능, 애초에 모든 단어들이 fully connected하게 연결되어 처리됨
self attention
스스로 각 문장 안에서 각 단어끼리의 관계성(attention weight) 계산
계속 단어간의 표현(representation)의 상호작용을 일으키게 됨
query key value 단어의 representation을 projection 하여 query key value를 만드는 것에서 부터 시작함 기존 단어들에서부터 그대로 사영하여 query 하나를 만들어두고
기존 단어들에서부터 그대로 사영하여 key 하나를 만들어두고
기존 단어들에서부터 그대로 사영하여 value 하나를 만들어둠
결국 이 query key value는 하나의 입력에서부터 동일하게 나온 것들임 -&gt; "self" attention query와 key의 dot product 계산 -&gt; 확률 형태로 normalization : 문장 속 각 단어들간의 관계 (중요성)을 뽑아냄
앞에서 뽑아낸 중요성을 value vector와 곱함(weighted sum) -&gt; 단어의 새로운 representation을 만들기 =&gt; "self attention" positional embedding
rnn은 시퀀스를 처리할 때 단어 하나하나를 순차적으로 처리 -&gt; 시간의 순서가 반영됨
transformer는 병렬 처리되기 때문에 순차적(시간적)인 개념이 반영되지 않음. -&gt; positional embedding 사용multi head self attention
self attention을 여러번 나눠서 계산하는 것임
다양한 관점에서의 weight를 계산하여 그 결과를 합쳐나간다고 이해하면 됨 마지막에 concat해서 합침
실제 실험에서는 8개의 multi head를 사용함
이것 또한 동일하게 병렬 처리가 가능
각 head 별로 단어별 중요도가 다르게 나옴.
그 "다양한" 관점의 기준은 누가 정하는가? : 누가 정하는 것이 아님. 학습 과정에서 자동으로 정해지는 것. 각 헤드가 독립적인 가중치 행렬을 가지는데, 각 해드가 다른 패턴을 포착하도록 자동ㅡ로 학습됨. 우리는 이해하지 못하겠지만 attention layer의 신경망이 어떠한 "패턴"을 찾을것임.
근데 8개의 헤드가 각각 다른 패턴을 찾도록 하는것 encoder
multi head self attention + feed forward neural network의 반복 : input문장에 대한 representation 업데이트
decoder
encoder에서 생성된 representation -&gt; conditional 하게 문장 생성
encoder에서는 key와 value만 넘어오며, query는 decoder에서 계속 업데이트해나가는 방식임.
inference : 순차적으로 다음 단어 하나씩 예측하며 처리 지금까지 생성한 단어들"까지"만 보고 (masked self-attention)
다음 단어로 뭘 만들지를(query) 원문(encoder에서 생성된 representation) 참고하여
새 단어를 생성함(feed forward) greedy search : 매번 가장 높은 확률의 다음 단어를 선택하지만, 이는 최적의 선택이 아닐 수 있음. beam search : 매번 가장 높은 확률의 다음 단어를 선택하는 것이 아님. 여러 후보를 유함 word embedding의 pretrainingllm agent : 어떠한 특정환경과 상호작용할 수 있는 llm. 스스로 다음 절차를 생각해낼 수 있는 자율성과 반응성이라는 핵심 특징 존재.
short-term memory : 현재 대화 세션 내에서만 유지되는 즉각적인 문맥 정보로 대화의 최근 몇 턴을 기억하며 주로 컨텍스트 윈도우에 저장
long-term memory : 긴 대화 내용들을 저장해두고
toolformer :
MCP :
Reasoning :
planning :
ReAct : reason and act planning을 하면서 계속 답을 내는 형태
multi agent collaboration : supervised agent의 역할을 중심으로 ... AI 하드웨어와 GPU]]></description><link>lgaimers/강의수강_chapter02.html</link><guid isPermaLink="false">lgAimers/강의수강_chapter02.md</guid><pubDate>Fri, 16 Jan 2026 07:48:59 GMT</pubDate></item><item><title><![CDATA[회고]]></title><description><![CDATA[<a data-tooltip-position="top" aria-label="https://colab.research.google.com/drive/1n9Pjthb3W4q-MO891Ce_-y5Jh2uOw4uv?usp=sharing" rel="noopener nofollow" class="external-link is-unresolved" href="https://colab.research.google.com/drive/1n9Pjthb3W4q-MO891Ce_-y5Jh2uOw4uv?usp=sharing" target="_self">2024 cnu 2차 학습동아리 실습코드</a>24년 여름방학 모각코(모여서 각자 코딩) 활동에서 처음 만나 각자 인공지능 기초 공부를 진행했었는데, 이번에는 한 단계 더 나아가 실제로 음성 데이터를 다루는 인공지능 모델을 직접 구현해보자는 목표를 가지고 또 참여하게 되었다.
최종 목표: 여러 최적화 방법을 도입하여 성능을 높인 음성 분류 모델 구현
세부 목표: 음성 데이터 전처리 방법 익히기
CNN, ResNet 등 다양한 딥러닝 모델 실습
모델 성능 최적화 기법 학습 및 적용
최대한 높은 정확도 달성 원본 음성 → 전처리 → MFCC 변환 → Zero Padding → 모델 입력 CNN: 기본적인 합성곱 신경망
ResNet: Skip Connection으로 깊은 네트워크 학습 가능 데이터 증강
적절한 손실 함수와 옵티마이저 선택
정규화 기법 (Dropout, Batch Normalization)
하이퍼파라미터 튜닝 레이블 인코딩 문제 해결
과적합 문제 인식 및 대응 문제: 훈련 데이터에서는 잘 작동하지만 실제 정확도 3% 해결: 모델 구조 변경, 정규화 기법 적용, 하이퍼파라미터 조정 PyTorch 버전 호환성 문제 해결
레이블 인코딩 문제 문제: 문자열 레이블로 인한 훈련 오류
해결: 레이블 매핑 딕셔너리 생성하여 숫자로 변환 지금 생각해보면 예제 코드에 많이 의존했던 점이 아쉽다. 좀 더 스스로 구현해보고 싶었지만 역량이 많이 부족했던 것 같다.
실습 활동을 하면서 생각보다 오류가 많이 났고, 생각보다 스스로 그 오류를 해결할 수 있는 힘이 있음을 느낄 수 있었다. 그동안 인공지능 공부가 내가 하기에 엄청 어렵다는 생각에 주저했으나 그동안 내 의지의 문제였던 것 같다.]]></description><link>2024-cnu-2차-학습동아리/회고.html</link><guid isPermaLink="false">2024 cnu 2차 학습동아리/회고.md</guid><pubDate>Fri, 16 Jan 2026 07:12:08 GMT</pubDate></item><item><title><![CDATA[lgAimers]]></title><link>lgaimers/lgaimers.html</link><guid isPermaLink="false">lgAimers/lgAimers.md</guid><pubDate>Wed, 14 Jan 2026 01:28:19 GMT</pubDate></item><item><title><![CDATA[강의수강_chapter01]]></title><description><![CDATA[인공지능은 기본적으로 '낯선'지능이다
ai의 낯선 특징 3가지
자각 없는 수행 : 의식적 경험의 부재
이해할 수 없는 실패 : 진정한 이해의 부재
계산과 실재의 간극 : 몸이 없는 사이버 존재
우리의 기준과 동일한 기준으로 인공지능을 쉽게 이해할 순 없음. 공감이라는 측면에서만 보아도, 사실 단순한 감정 노동은 인간보다 인공지능이 훨씬 더 탁월함. 이런 측면에서 인간은 인간만의 "현명한" 공감능력을 길러야 함
ai 윤리 - ethics 고대의 '에토스'라는 개념으로 이해해야 함.
우리가 생각하는 공자, 맹자 뭐 그런 윤리라기보다는, 인공지능의 규범이라고 보면 됨.
인공지능을 만드는 각 테크기업들마다 지니고 있는 ai 규범들은 각각 다름.
그냥 막연하게 착하고 좋은것~ 을 논하는게 아니라는 것! 인공지능은 낯선 지능이라는 특성 때문에, 설계 단계에서부터 다양한 윤리(에토스)들을 추구하는 방식으로 논의되고 있음.
]]></description><link>lgaimers/강의수강_chapter01.html</link><guid isPermaLink="false">lgAimers/강의수강_chapter01.md</guid><pubDate>Tue, 13 Jan 2026 15:31:26 GMT</pubDate></item><item><title><![CDATA[20251216 모각코 활동 0회차]]></title><description><![CDATA[주제는! 자기지도학습 논문 구현 스터디이다.2025 2학기, 학술동아리에서 자기지도학습 강의를 진행했었다.
나름 공부해서 직접 rotation기반의 자기지도학습을 직접 구현하며 교육자료를 만들었지만!
끝나고 나니 부족한 부분도 많았고 아쉬운 부분이 한두개가 아니었다는 것~!
그 때 급하게 읽었던 논문 자료들도 제대로 다시 읽어보고, 코드도 대거 수정해서 보기 좋게 예쁘게 만들어보며 제대로 공부해보려 한다!이번 모각코 활동을 통해서
자기지도학습관련 논문들을 제대로 읽고, 이해하기
기존 교육자료 코드를 더 깔끔하고 확장 가능한 구조로 리팩토링
다양한 ssl방법론을 비교실험 할 수 있도록 개선
성능도 좀 더 높여보기
아래는 회차별 계획이다]]></description><link>2025-26_동계_모각코/20251216-모각코-활동-0회차.html</link><guid isPermaLink="false">2025-26_동계_모각코/20251216 모각코 활동 0회차.md</guid><pubDate>Sun, 28 Dec 2025 16:17:38 GMT</pubDate></item><item><title><![CDATA[강낭콩자반슨 모각코 활동]]></title><description><![CDATA[나의 모각코 활동 다짐 : 할수있는만큼 제대로 끝내자!목표
자기지도학습관련 논문들을 다시 제대로 읽고, 이해하기
기존 교육자료 코드를 더 깔끔하고 확장 가능한 구조로 리팩토링 (다양한 ssl방법론을 비교실험 할 수 있도록 개선할 것이다)
성능높이기
]]></description><link>2025-26_동계_모각코/강낭콩자반슨-모각코-활동.html</link><guid isPermaLink="false">2025-26_동계_모각코/강낭콩자반슨 모각코 활동.md</guid><pubDate>Sun, 28 Dec 2025 16:16:20 GMT</pubDate></item><item><title><![CDATA[뿌가각 모각코 활동]]></title><description><![CDATA[
뿌가각이란? 모여서각자코딩 뿌시기라는 뜻이다.
나의 모각코 활동 다짐 : 컴퓨터구조를 뿌시겠다!!!!!!]]></description><link>2025_하계_모각코/뿌가각-모각코-활동.html</link><guid isPermaLink="false">2025_하계_모각코/뿌가각 모각코 활동.md</guid><pubDate>Sun, 28 Dec 2025 14:19:22 GMT</pubDate></item><item><title><![CDATA[2025-26_동계_모각코]]></title><link>2025-26_동계_모각코/2025-26_동계_모각코.html</link><guid isPermaLink="false">2025-26_동계_모각코/2025-26_동계_모각코.md</guid><pubDate>Sun, 28 Dec 2025 14:17:05 GMT</pubDate></item><item><title><![CDATA[뭔차이지]]></title><description><![CDATA[층과 층 사이를 흐르는 텐서/벡터
보통 동그라미로 표현하는 그것임.
입력 데이터에서부터 입력 데이터의 변형된 상태...?들을 모두 칭하는 말..? 이라고해야하나...학습을 통해 업데이트되는 값들
진짜중요한녀석들! 핵심인거임. 심장인거임.입력을 변환하는 함수자주헷갈렸던 부분들... 이젠 혼동하지말고 잘 이해해보자!]]></description><link>ai_study/뭔차이지.html</link><guid isPermaLink="false">AI_study/뭔차이지.md</guid><pubDate>Sun, 28 Dec 2025 14:16:00 GMT</pubDate></item><item><title><![CDATA[궁금햇던것들 모음]]></title><description><![CDATA[
그냥 수학적으로 정의된 좌표계... 긍까 빈 도화지 같은 것. 학습을 통해 가중치 행렬이 “점(벡터)을 찍는 규칙”을 배워서, 그 규칙에 따라 latent space에 점을 찍을 수 있게 되는데,,,, 그렇게 해서?? 그 공간에 의미 있는 분포가 형성된다.
우리가 보는 PCA, t-SNE 그림은 고차원 latent space에 찍힌 점들을 2D/3D로 투영한 그림자일 뿐, 원본 공간을 직접 볼 수는 없음. Latent vector = hidden state = embedding 모두 같은 성격의 값: 입력이 들어왔을 때 모델이 계산해내는 고차원 벡터 표현. ( 압축한 값 )
이 벡터가 latent space 위의 **한 점(point)이 됨.
forward pass 중에 계산되며, 특별히 저장되지는 않고 다음 연산으로 넘어가 버림.
우리가 시각화할 때는 이 중간 값을 추출해서 저장한 뒤 차원 축소 기법(PCA 등)으로 찍는 거고!!! 가중치 행렬과의 관계 가중치 행렬 자체가 공간은 아님.
대신 입력을 latent space 안의 점으로 어디에 찍을지에 대한 규칙을 정의
학습이란, 이 가중치 행렬들을 조정해서 공간 위 점들의 패턴이 의미 있게 되도록 만드는 과정이다. 가중치 vs 파라미터 파라미터 = 학습 가능한 값 전체 가중치는 파라미터에 속함 잠재 벡터의 차원 -&gt; 잠재 공간에서 쓰는 축의 개수
2D latent space를 시각화했을 때, scatter plot의 한 점 한 점들이 2D latent vector에 해당한다.
사영은왜하는것이지?
-&gt; 우리 눈은 4차원부터는 그 공간을 시각화하여 표현하지 못한다.
-&gt; 4, 5, 6 ,,,, 차원의 잠재 벡터로 표현되어있는 벡터 공간을 시각화해서 보고싶으면 어떡해~
-&gt; 그 때는 차원을 줄이면 되지! 고차원을 저차원(1,2,3차원)으로 내리 꽃는 그 무드임 변수의 종류에 따라 탐색 공간 정의 가능
변수의 개수에 따라 탐색 공간 차원이 정해짐
이산 변수 (예: binary) 변수 하나 → 차원 1의 공간 예: {0, 1}
변수 두 개 → 차원 2의 공간 예: {0, 1}² = {(0,0), (0,1), (1,0), (1,1)}
변수 n개 → 차원 n의 이산 공간 예: {0, 1}ⁿ 연속 변수 (예: 실수) 변수 하나 → 차원 1의 공간 예: ℝ (실수직선)
변수 두 개 → 차원 2의 공간 예: ℝ² (평면)
변수 n개 → 차원 n의 연속 공간 예: ℝⁿ 단어를 숫자로 특징 표현.
vector_size를 지정해 단어를 특정 차원의 의미 벡터로 표현.
예: vector_size = 5, "이" → [0.1, -0.3, 0.5, 0.0, 0.2] n개의 단어 시퀀스를 입력으로 주고, 그 다음 단어를 예측하는 분류 문제로 처리함. 입력 예: "이", "것", "은" ( 이 때 "이","것","은" 은 각각 5차원 벡터 -&gt; 총3*5matrix 가 입력으로 들어감)
출력 예: "첫" 출력은 단어장 크기만큼의 확률 벡터 (예: softmax로 17차원 출력)
정답(GT)은 예측 단어가 단어장 내에서 위치하고 있는 인덱스 (예: "첫"은 7번 인덱스) 출력 시퀀스의 인덱스가 아님!!
정답 단어는 보통 정답 단어는 보통 one-hot 벡터로 표현되며, 실제 학습에서는 one-hot 벡터에서 1이 적혀있는 인덱스 번호만으로도 정답을 표현 함 예측 결과에 대한 loss 함수는 CrossEntropyLoss 사용 (softmax + log loss) 문장 앞부분처럼 앞에 단어가 부족할 때는 [START] 같은 특수 토큰으로 채움
예: 시퀀스 길이 = 3이면
[START], [START], "이" → 예측: "것" 각 단어의 벡터는 모델이 학습 과정에서 계속 업데이트됨
즉, 임베딩은 단순히 고정된 변환이 아니라 의미를 학습하는 파라미터(weight matrix)임 차원이 클수록 더 미묘하고 복잡한 의미를 표현할 수 있지만,
연산량 증가, 메모리 부담, 학습 시간 증가 등의 trade-off가 있음
일반적으로: Word2Vec: 100~300차원
BERT: 768차원
GPT-3: 최대 12,288차원까지도 사용 Transformer는 단어 순서를 알 수 없기 때문에 위치 정보(Position)를 따로 넣어줘야 함
이 위치 정보는 단어 임베딩 벡터와 같은 차원으로 만들어져 element-wise 덧셈 방식으로 추가함
예:
"이"의 임베딩 = [0.1, -0.3, 0.5, 0.0, 0.2]
위치 인코딩(Pos 0) = [0.01, 0.02, 0.03, 0.04, 0.05]
→ 최종 입력 벡터 = [0.11, -0.28, 0.53, 0.04, 0.25]
벡터 차원 수는 그대로 유지되며, 단어 의미 + 위치 정보가 하나의 벡터에 담김 벡터 전체는 의미를 잘 반영하지만,
각 인덱스가 “성별”이나 “감정” 같은 특정 의미를 갖는 건 보장되지 않음
이 차원별 의미를 해석하려는 것이 현재 활발한 연구 주제 중 하나임 예: probing task, interpretable embeddings, disentangled representations 등 Decoder만 사용
Encoder는 전체 입력을 한꺼번에 다 보고 처리 -&gt; gpt는 아니다~
앞 단어들만 보면서 오른쪽 단어를 예측하는! 순서대로 단어 예측하는 녀석
gpt의 출력은 ==다음 단어를 예측하는 Vocab size만큼의 확률 분포== (예: '것' 다음에 나올 단어가 '은'일 확률 등등) "나는 그것"까지 입력 -&gt; 그러면 GPT는 "그 다음 단어가 뭐일지" 예측해야 함. 이 때, GPT는 자기가 알고 있는 모든 단어(=어휘집, Vocabulary) 중에서~~ "것", "은", "이다", "합니다", "좋아해요" 같은 모든 후보 단어에 대해 확률을 계산해.
출력을 Linear를 통해 원하는 차원으로 맞추어 줌 Transformer는 결국 숫자 벡터(예: 768차원)를 출력해줌 : 복잡한 의미를 담은 벡터를 뽑아줄 수는 있지만? 그러나? 우리가 원하는 건... (예)Classification: 단일 문장 분류
(예)Entailment: 전제 → 가설 관계 추론
(예)Similarity: 두 문장의 유사도
(예)Multiple Choice: 지문과 보기들 중 정답 고르기
=&gt; 요런것들이기 때문에, 그 복잡한 벡터를 우리가 원하는 형태, 즉 정답 클래스 수로 가공해줘야한다! =&gt; Linear Layer 선형층
특수토큰 기계 번역<img alt="GPT1" src="https://ejkiwi.github.io/lib/media/GPT1.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"> Decoder만 쓰는 GPT가 어캐 번역을 하지.. 라고 생각할 수 있겟으나!! 입력 안에 번역해줘~ 라는 토큰이 들어온다면 가능할 수 잇다아~ Auto-regressive generation how are you &lt;to-fr&gt; : 입력 문장 (마지막 토큰&lt;to-fr&gt;이 작업 명령임)
Transformer-Decoder : 예측을 계산하는 모델 본체 Time step #1 지금까지의 입력을 보고, 첫 번째 단어의 위치인 Position 4 (즉, &lt;to-fr&gt; 바로 다음 위치)에 해당하는 단어를 예측.
"Comment"라는 단어 출력 Time step #2 현재 time step #1 에 해당하는 "Comment"까지 기억하고 있음.
그 다음 "allez-vous" 단어 예측, 출력 <br>
요약<img alt="GPT2" src="https://ejkiwi.github.io/lib/media/GPT2.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"> 입력 : 긴 문서 내용 (예: 위키피디아 문장들) + &lt;summarize&gt; 토큰 출력 : 그 문서에 대한 요약문 &lt;summarize&gt; = "요약해줘"라는 신호 Encoder만 사용
지피티니핑처럼 왼쪽 -&gt; 오른쪽 이렇게 한 방향만 바라보는 것이 아님.
양방향을 바라봄.
보통 한 단어를 768차원 벡터로 표현
pretraining
Masked language model : 토큰의 15%를 masking처리, 그 자리에 들어갈 적절한 단어를 예측하며 훈련받음 (예) Let’s stick to [MASK] in this skit → [MASK] = improvisation Next Sentence Prediction : 두 문장을 보고, 두 번째로 온 문장이 첫 번째 문장의 다음 문장이 진짜 맞을지!! 를 맞추며 훈련받음
FFNN + Softmax
FFNN : 완전 연결층 feed forward neural network
벡터 → 의미 있는 값(확률)
[MASK]위치를 예측한 출력 벡터 V가 있다구 치며는 V는 문맥을 이해한 벡터이지만, 이게 그래서 먼 단어인지는 알 수 없음.
이 때, FFNN을 통과 : FFNN: 768차원 → vocab 크기 (예: 30,000개) 모든 단어들(vocab) 중에서 어떤 게 가장 어울리는지 점수 매김 FFNN을 통과한 V를 Softmax 함수에 넣어서 확률로 바꿈 fine-tuning과 cls 토큰 [CLS]토큰 : 맨 앞 [CLS]의 출력 벡터는 전체 문장의 의미 요약 벡터가 됨. [CLS] 벡터를 기반으로 결과를 내는 출력층만 새로 추가
그 전체를 새로운 태스크에 맞게 재학습 =&gt; fine-tuning <br>
분류 작업에서의 fine-tuning<img alt="BERT1" src="https://ejkiwi.github.io/lib/media/BERT1.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"> <br>
Sentence Pair Classification<img alt="BERT2" src="https://ejkiwi.github.io/lib/media/BERT2.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"> 핑크벡터들 : 텍스트 토큰 단위들 입력 텍스트의 토큰화 결과 ( 아직 임베딩 안 됨 )
아직 숫자로 바뀌기 전 순수한 단어/기호 상태 노랑벡터들 : 입력 임베딩 벡터들 BERT 인코더에 들어가기 직전 입력 준비 완료!
Eᵢ : 단어에 대한 임베딩 Token Embedding + Segment Embedding + Position Embedding E[CLS]: [CLS] 토큰에 대한 입력 임베딩
E[SEP]: 문장 구분자에 대한 임베딩 Sentence 1 + [SEP] + Sentence 2 : [SEP]을 통해 두 문장을 하나로 연결 초록벡터들 : 출력 벡터들 BERT인코더를 거친 후 나온 최종 출력 벡터들
C : BERT 출력 중 [CLS]에 해당하는 벡터 (문장쌍 전체 의미 요약)
T₁, T₂, ..., T'ₘ: 각 토큰의 출력 벡터 → 문맥을 고려한 의미 벡터 노랑 벡터에서처럼 단어의 고립된 의미가 아니라, 주변 문맥을 보고 의미가 조정된 결과 🔤 핑크색 = "텍스트" 단어 🔢 노란색 = "벡터"로 바뀐 단어 (Embedding Layer 출력) 🧠 초록색 = 문맥 고려한 최종 의미 벡터 (Encoder 출력) <br>
Question Answering<img alt="BERT3" src="https://ejkiwi.github.io/lib/media/BERT3.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"> 입력 : [CLS] 질문 토큰들 [SEP] 지문(답) 토큰들 [SEP] Start/End Span : 입력이 들어왔을 때, 어디부터 어디까지가 답일까?를 고르는 것. 각 토큰별로.. 시작 위치일 확률 계산 하나
끝 위치일 확률 계산 하나
두 개의 linear layer 사용 softmax를 통해 확률 분포 만들기 -&gt; 가장 확률이 높은 시작/끝 고름 어디에서 학습할 것인가?
사용자의 데이터를 중앙 서버로 모아서 학습하지 않고, 개별 디바이스에서 모델을 학습하는 방식.
학습된 결과( 모델의 가중치나 업데이트 정보 )만 중앙 서버로 보내게 되는데, 이 때 중앙서버에서는 데이터를 취합 후 더 개선된 공통 모델을 생성하는 과정을 거침. 그리고 그 개선된 모델은 다시 사용자들에게 배포됨!!
관련 개념 ( 어디에서 학습할 것인가? ) 중앙 집중 학습 : 모든 데이터를 중앙 서버로 집합
분산 학습 : 모델 학습을 여러 서버에서 수행 후 결과를 병합
연합 전이 학습 : 연합학습 + 전이학습 -&gt; 서로 다른 기관 간 데이터를 공유하지 않고 협력 학습...?
스완슨 학습 : 블록체인 사용하여 중앙서버 없이 학습 어떻게 학습할 것인가?
특징을 자동으로 추출할 수 있도록 학습하는 과정을 뜻함. SELF FEATURE EXTRACT
데이터만 제공하면 그 데이터로부터 핵심 정보를 추출해낼 수 있고 기계 스스로 배워내는 학습 과정을 뜻함.
지도학습이될수도있구 비지도학습이될수도있구 자기지도학습이될수도있어 뭐 다.. 섞이는거지 어떻게 학습할 것인지에 대한 개념들이니까!!!!
관련 개념 ( 어떻게 학습할 것인가? ) 지도 학습 : 입력 데이터와 정답이 있는 상태 ( 사람이 직접 라벨을 떠먹여 줌. ) YES LABEL
비지도 학습 : 데이터의 라벨 없이 "패턴" 학습 ( 클러스터링 느낌 ) NO LABEL
자기지도 학습 : 데이터에서 일부 정보 숨기고 이를 예측하도록 학습 ( 데이터 자체에서 스스로 라벨을 "만들도록" 함 ) NO LABEL, GENERATE LABEL
전이 학습 : 미리 학습된 모델을 새로운 문제에 적용. RECYCLE 어떤 데이터를 다루는가?
domain : 특정 데이터 소스 또는 모델이 작동하는 환경 이미지 vs 음성
domain shifts : 훈련은 A사용자의 이메일로 스팸 필터링을 했다가, 실제 사용은 B사용자의 이메일로 스팸 필터링을 하는 것. task : 모델이 해결하거나 달성해야하는 문제 또는 목표 -&gt; 이 데이터를 가지고 무엇을 할 것인가?
domain adaptation?
diffusion model?
encoder-decoder -&gt; 입출력 크기를 같게.
가중치를 한 번 업데이트 할 때 동시에 사용하는 독립적인 데이터 샘플(llm에서는 문장의 개수)배치 1 [ 값1, 값2, 값3 ]
배치 2 [ 값1, 값2, 값3 ]
배치 3 [ 값1, 값2, 값3 ] ↓ ↓ ↓ 각 열마다 정규화 # Batch Norm 없을 때:
배치1(나는): [0.1, 100.0, 0.2]
배치2(너는): [0.2, 120.0, 0.3]
배치3(내가): [0.15, 110.0, 0.25]
# 문제: 차원2(100.0, 120.0, 110.0)가 너무 큰 값 → 이 차원에 "치중"됨
→ 이 차원의 "비중(가중치)"이 너무 큼
→ 다른 차원들의 영향력이 무시됨 # Batch Norm 후:
배치1(나는): [-1.0, -1.0, -1.0]
배치2(너는): [ 1.0, 1.0, 1.0]
배치3(내가): [ 0.0, 0.0, 0.0]
# 해결: 모든 차원이 비슷한 범위
→ 어떤 차원에도 "치중"되지 않음
→ 모든 차원의 "비중(가중치)"이 균형있게 됨
→ 모든 차원이 공평하게 기여함
배치1의 값1, 배치2의 값1, 배치3의 값
-&gt; 평균 0
-&gt; 분산1로
맞춰주는 것.배치 1 [ 값1, 값2, 값3 ] ← 이 3개를 정규화
배치 2 [ 값1, 값2, 값3 ] ← 이 3개를 정규화
배치 3 [ 값1, 값2, 값3 ] ← 이 3개를 정규화 ←─────────────→ 각 행마다 정규화 Word Embedding은 단순 숫자가 아니라 의미 표현 공간이라는 것!
Language Model이 분류 문제 구조로 작동한다는 것!
위치 인코딩 벡터는 단어 임베딩 벡터와 같은 차원으로 만들어져 element-wise 덧셈 방식으로 추가된다는 것! 임베딩 = "토큰을 숫자로 표현한 벡터" (discrete → dense vector // 고차원 -&gt; 저차원) 인코딩 = "어떤 정보(단어, 문장 등)를 벡터로 표현한 결과" (정보 구조 → 표현 벡터)
"위치"는 그 둘의 경계에 있는 예외 케이스라서 둘 다 쓰임... ( 위치 인코딩/임베딩 ) 단어 임베딩 벡터는 단순히 고정된 변환이 아니라 의미를 학습하는 파라미터라는 것!
layer norm batch norm은 텐서가 있다고 하면 세로로 정규화 하고
layer norm은 텐서가 있다고 하면 가로로 정규화 하는 느낌
(n, m) 텐서가 있다면...!
Batch Norm: 각 m 특성마다 n 샘플의 평균/분산으로 정규화
Layer Norm: 각 n개의 샘플마다 m 특성의 평균/분산으로 정규화 LLM의 임베딩 공간 =&gt; LATENT SPACE]]></description><link>ai_study/궁금햇던것들-모음.html</link><guid isPermaLink="false">AI_study/궁금햇던것들 모음.md</guid><pubDate>Sun, 28 Dec 2025 14:14:00 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/GPT1.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/GPT1.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[토큰이라...]]></title><description><![CDATA[Tokenization : 어디서 문장을 자를까? 정하기 모든 글자 하나 하나를 자르기 run, running, runs 같은 단어들은 run이라는 공통된 형태임을 안다
새로운 단어 생겨도 알 수 잇잔냐
원래보다 입력 길이가 길잖아
단어를 한개한개 자르니까 단어 자체 의미를 바로 알기는 힘드러 단어 단위로 자르기 단어 그 자체 의미가 보존되잖아
입력 시퀀스도 짤밪ㄶ아 -&gt; 계산량도 감소하구 속도도 빨라지구
단어 개많은 거 어캐 처리할것인데?
새로운 단어를 어캐 적응할건데? -&gt; UNK run runs running을 다 따로 해버리잖냐... 새 단어가 자주 등장하거나 다양한 입력을 다루려면 Character 단위가 좋고, 의미 단위를 명확히 다루고 싶으면 Word 단위가 좋은 것이다~~ UNK
한 번은 본 적 있는 단어라면 인덱스가 배정되어있을 것이야. 이녀석을 어떻게 숫자로 표현해야할지 알 수 있을 것이라구.. 근데???? 본 적 없는 단어는 뭐 알 수가 없잖냐!!!!!! 모델에 입력할수가 없다구.. 모델에 얘를 뭐 어캐 숫자로 바꾸어서 넣어줄건데!!! -&gt; 이 때는 &lt;UNK&gt;로 처리하면 되는 것이야.
자주 나오지 않는 특별 단어는 요래 처리를 하면 돼. 그래서 이 입력 자체를 버리지 않구 따로 처리할 수 있게 해주는 것이야. 그럼 모델이 돌다가 멈추지 않겟지??
보통&lt;UNK&gt;는 0과 1같은 특별한 ID 숫자 번호를 준댕
ㄱ근데 이 UNK가 너무 많아져버리면?? 이것이 이 UNK의 한계인것이야.
이게 너무 많으면 문장 의미 자체를 이해할 수 없게 되잖야.
어캐 해결해? -&gt;Subword Tokenization - Byte Pair Encoding 이 등장! Subword Tokenization
알 고 리 즘
희귀 단어처리 위해서요 - 자주 등장하는 글자 쌍을 합쳐나가기
처음에는 character단위로 시작
가장 많이 등장하는 글자 쌍 찾기
쌍 합쳐서 새 심볼 만들기
점점 더 큰 단위 만들기
~ 자연어를 컴퓨터에 넣으려면 전처리를 해야 하고, 그중 하나가 Tokenization이다.
~ 초기에 대표적으로 Word 단위 Tokenization을 사용했다.
~ 그런데 Word Tokenization 방식은 UNK(모르는 단어) 문제를 해결할 방법이 없었다.
~ 그래서 Character-level Tokenization도 시도했지만, ➔ 글자 단위는 의미를 포착하기 어렵고 시퀀스가 너무 길어져서 힘들었다.
~ 이 문제를 궁극적으로 해결하려고, "Subword Tokenization"이라는 새로운 방식이 등장했다!
~ 그래서, Subword Tokenization은 단순히 Word Tokenization에 딸려 있는 세부기법이 아니고, Word 방식, Character 방식과 나란히 독립적으로 존재하는 하나의 Tokenization 방법이다. 근데 이거 잘 쓸라면 첫 base vocab에 초ㅣ대한 다양한 글자가 이성야 할 거 아님?
근데 모든 unicode 다 넣기에는 개심각. 십삼만팔천개임@@@ 도롸이...
그래서 지피티니 투 같은 경우에는 처음 시작을 256개부터 시작해서... 현재는 삼만이천개~ 육만사천개 정도의 base vocab 임...자 근데 이것을.... 숫자로 바까야할것아님..
처음에는... 단어마다 고유 ID 배정하는 원 핫 벡터 방식을 사용함. ( 희소 표현 ) 30,000차원 벡터 중 3456번째만 1, 나머지는 0 너무 비효율적! (메모리 낭비 + 의미 없음) 그래서 그것 대신에Dense Vector(Word Embedding)로 변환하자는 아이디어가 생겻잖냐 "banking" → [0.12, -0.48, 0.23, ..., 0.04] (예: 768차원)
이 Vector가 바로 Word Vector(Word Embedding) 밀집되어 있고 (Dense)
의미를 담고 있다 (비슷한 의미면 가까운 벡터!)
word2vec word embedding 구현 방법 중 하나.
banking이라는 단어가 있으면, 그 단어 혼자 의미를 가지는 게 아니라, "항상 banking 근처에 어떤 단어들이 등장했는가" 를 보고 그 패턴을 벡터에 새긴다라는 마인드를 가진 방법이다...!!
<img alt="word2vec" src="https://ejkiwi.github.io/lib/media/word2vec.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">
저 사진에서.P(w문맥어(주변단어) | w중심어) 간의 확률을학습하는 과정 안에서 단어의 의미 벡터가 만들어 진 것.
주변 문맥으로 학습한 결과 =&gt; 단어 의미하는 의미 벡터 ( 얘는 주변 문맥을 잘 예측하는 방향으로 조정되었음. )
요즘에는 거의 Embedding을 학습하는 게 모델 학습 그 자체로서의 역할을 하도록 다른 모델에 포함시켜서 사용된다...!("Word2Vec은 단어를 의미 있는 벡터로 만드는 임베딩 학습기법이고, 이 결과를 다른 NLP Task를 수행하는 데 이용한다! -&gt; 지도학습! downstream task개념 기억나지?? downstream을 수행하기 위해서 다른 걸로 돌려버리잔아...!!!! ") 물론! rnn이면 시간 순서를 기억하니 ㄱㅊ 할지도.. 긏만???
self-attention과 transformer는 어캐할것이냐??
이녀석들은 모든것들을 한 번 에!!! 처리를한다고!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!그러면 뭐 apple이 love 앞ㅍ에나오ㅑㅅ는디뒤에나ㅗ왓는디저어캐아냐구그래서!! token의 위치 정보 또한 숫자로 표현해서 데이터로 가지고 잇어야해!!!
필요한 것
연속적으로 자연스럽게 변하는 값이 필요 ( 그냥 숫자 1 2 3 주면 부드럽게 순서 관계를 인식하기 어려움 )
멀어질수록 값이 달라지고 가까울수록 값이 비슷하게 나와야 함<br>
<img alt="positional_encoding1" src="https://ejkiwi.github.io/lib/media/positional_encoding1.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"> 짝수 차원에는 sin 함수를, 홀수 차원에는 cos 함수 사용.
잘 보면 sin과cos에 들어가는 녀석들이 매우 복잡함 각 차원(frequency)이 다 다르게 움직이고,
Sin, Cos도 교차로 쓰고
주기도 다르게 걸어놨음.
갱장히..갱장히...머...어찌저찌... 저찌저ㅉㅣ 해서 멀어질수록 값이 달라지고 가까울수록 값이 비슷하게 나오도록 함수를 설계하셧대요 그 이상은... 이해포기 <br><img alt="positional_encoding2" src="https://ejkiwi.github.io/lib/media/positional_encoding2.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">"단어가 문장에서 나오는 순서" 그대로 Y축에 1줄씩 차곡차곡 올라간 것...
그리고 y 축에는 단어 순서에 대한 의미를 가진 벡터가 들어감....
벡터 1번째 칸~ 128번째 칸 까지
단어를 의미 임베딩(Embedding)한다 (ex: students → [벡터]
단어 순서(Positional Encoding) 벡터를 만든다 (0번 단어용 벡터, 1번 단어용 벡터 등)
두 벡터를 더한다 (Element-wise Sum) 의미 + 순서 둘 다 반영된 최종 벡터 완성
Transformer Encoder로 넣는다|(Self-Attention 계산 시작!)
batch 1에서의 문장 하나[
[[나:임베딩값],[는:임베딩값],[빵:임베딩값],[이다:임베딩값]]-&gt; batch0
]
이 때의 shape : ( 1, 4, 임베딩dim )batch n에서의 문장 n개[
[[나:임베딩값],[는:임베딩값],[빵:임베딩값],[이다:임베딩값]], -&gt; batch0
[[빵:임베딩값],[좋아:임베딩값],[pad],[pad]], -&gt; batch1
[[너:임베딩값],[밥:임베딩값],[이니:임베딩값],[?:임베딩값]], -&gt; batch2
.
.
.
[[아니:임베딩값],[빵:임베딩값],[이다:임베딩값],[!:임베딩값]] -&gt; batch n
]
이 때의 shape : ( n, max_token:4, 임베딩dim )[
[[나:임베딩값],[는:임베딩값],[빵:임베딩값],[이다:임베딩값],[sep],
[빵:임베딩값],[좋아:임베딩값],[pad],[pad],[sep],
[너:임베딩값],[밥:임베딩값],[이니:임베딩값],[?:임베딩값],[sep],
[아니:임베딩값],[빵:임베딩값],[이다:임베딩값],[!:임베딩값]],
]
sep토큰을 쓸 때는 sep토큰을 처리하고, 다음 문장의 첫 번째 토큰을 입력받기 직전에 은닉 상태를 초기화해야 함(두 번째 문장이 마치 배치를 사용하는 상황에서의 다른 문장처럼 독립적인 상태에서 시작할 수 있도록 하기 위함)
문장의 길이를 seq_length라고 한다.
모델에 들어가는 아키텍처 기준으로는 max_token만큼의 길이가 들어감
[ [빵], [좋아], [pad], [pad] ] : seq_length2 max_token4 임베딩값 = [ 값1 , 값2 , .... , 값512 ]
각 토큰을 값 512개로 표현 -&gt;embedding dim이 512
내 생각대로, 당연하게도, linear layer는 마지막 임베딩값 기준으로 계산되는것이 맞음.각 배치마다 하나의 문장 넣은 경우
입력이 : ( 3, 4, 512 ) # 3개의 문장 # 각 4개토큰 # 각 토큰 512차원 표현[
[[나:임베딩값],[는:임베딩값],[빵:임베딩값],[이다:임베딩값]], -&gt; batch0
[[빵:임베딩값],[좋아:임베딩값],[pad],[pad]], -&gt; batch1
[[너:임베딩값],[밥:임베딩값],[이니:임베딩값],[?:임베딩값]], -&gt; batch2
]
batch 0의 토큰 0: [512차원] -&gt; Linear -&gt; [30000차원]
batch 0의 토큰 1: [512차원] -&gt; Linear -&gt; [30000차원]
batch 0의 토큰 2: [512차원] -&gt; Linear -&gt; [30000차원]
batch 0의 토큰 3: [512차원] -&gt; Linear -&gt; [30000차원]
batch 1의 토큰 0: [512차원] -&gt; Linear -&gt; [30000차원]
.
.
batch 2의 토큰 3: [512차원] -&gt; Linear -&gt; [30000차원]
... (총 3×4=12개 토큰 각각 처리-&gt; 물론 미니 배치를 쓰면 각 배치n개를 한번에 처리할 수 있음.) sep으로 여러개의 문장을 묶은 경우
입력이 : ( 1, 14, 512 ) # 3개의 문장 # 각 4개토큰 # 각 토큰 512차원 표현[
[[나:임베딩값],[는:임베딩값],[빵:임베딩값],[이다:임베딩값],[sep],
[빵:임베딩값],[좋아:임베딩값],[pad],[pad],[sep],
[너:임베딩값],[밥:임베딩값],[이니:임베딩값],[?:임베딩값]
]
토큰 0: [512차원] -&gt; Linear -&gt; [30000차원]
토큰 1: [512차원] -&gt; Linear -&gt; [30000차원]
.
.
토큰 14: [512차원] -&gt; Linear -&gt; [30000차원]
(총 1x(4+1sep+4+1sep+4)=14개 토큰 각각 처리) 둘 다 각 토큰의 표현을 512차원에서 30000차원으로 늘렸음.그리고 이 계산은 시간흐름 t마다 각 배치들이 모두 병렬 처리 됨.
t=1 -&gt; 배치0의 첫번째 + 배치1의 첫번째 + 배치2의 첫번째
t=2 -&gt; 배치0의 두번째 + 배치1의 두번째 + 배치2의 두번째
t=3 -&gt; 배치0의 세번째 + 배치1의 세번째 + 배치2의 세번째]]></description><link>ai_study/토큰이라....html</link><guid isPermaLink="false">AI_study/토큰이라....md</guid><pubDate>Sun, 28 Dec 2025 14:11:27 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/word2vec.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/word2vec.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[AI_study]]></title><link>ai_study/ai_study.html</link><guid isPermaLink="false">AI_study/AI_study.md</guid><pubDate>Thu, 11 Sep 2025 12:19:15 GMT</pubDate></item><item><title><![CDATA[활성화 함수들과 최적화 알고리즘과 손실함수]]></title><description><![CDATA[뉴런이 출력할 값을 변환 -&gt; 비선형성 추가 -&gt; 신경망은 복잡한 패턴 학습 가능<img alt="ReLU1" src="https://ejkiwi.github.io/lib/media/ReLU1.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">
입력이 0보다 크면 그대로 출력, 0 이하면 0 출력
비선형 함수로 딥러닝에서 가장 많이 사용됨
Gradient Vanishing 문제 완화 → 역전파 시 기울기가 0이 되는 문제가 적음
계산량이 적음 → 곱셈 연산 없이 비교만 하면 됨!
=================================
음수 입력은 항상 0으로 출력되기 때문에, 뉴런이 완전히 죽어버릴 수도 있음. 이걸 해결하기 위해 변형된 ReLU들이 등장 Leaky ReLU : x&lt;0일 때도 작은 기울기(α)를 유지. 보통 α = 0.01 정도로 설정
음수 영역을 조금이라도 학습할 수 있도록 함. PReLU : α를 고정된 값이 아니라 학습 가능하게 만든 것 <br><img alt="ReLU2" src="https://ejkiwi.github.io/lib/media/ReLU2.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"><br><img alt="sigmoid" src="https://ejkiwi.github.io/lib/media/sigmoid.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">
출력 범위: (0,1) 값이 0~1 사이로 정규화되어 확률처럼 해석할 수 있음 이진 분류(Binary Classification)에 사용 → YES/NO 같은 문제에서 확률을 예측할 때 유용 값 하나를 입력받아서(x) 하나의 값만 출력 ==================================
Gradient Vanishing 문제 시그모이드 함수는 미분하면 최대값이 0.25 역전파(Backpropagation)애서 기울기를 전파하고, 이를 이용해서 가중치를 업데이트하는데, 기울기가 너무 작아지면 가중치가 거의 업데이트되지 않아서 학습이 잘 안됨. 출력 값이 0이나 1에 가까워질수록 기울기가 0에 가까워짐 네트워크가 깊어질수록 학습이 어려움 → 그래서 최근에는 거의 안 쓴다. <br><img alt="softmax" src="https://ejkiwi.github.io/lib/media/softmax.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">
시그모이드의 자식
로지스틱 함수(시그모이드함수)의 다차원 일반화 다차원 일반화? : 여러개의 클래스에 적용 가능
여러 개의 입력값 (x1,x2,x3,...)을 받아서 각 클래스별 확률을 출력
출력 값의 총합이 항상 1 → 확률 분포처럼 해석 가능 각 클래스에 대한 상대적인 확률 계산 값이 클수록 확률이 높게 나옴 (ex: 고양이, 개, 말 중에서 하나를 예측) 다중 클래스 분류(Multi-class Classification)에 사용 여러 개의 클래스를 예측해야 할 때, 각각의 확률을 출력 ==================================
한 클래스의 확률이 높아지면, 나머지 확률이 급격히 줄어듦 큰 값이 들어오면 출력이 급격히 한쪽으로 치우칠 수 있음. Cross-Entropy Loss와 함께 사용해야 안정적인 학습 가능 단순한 MSE 같은 손실 함수를 쓰면 학습이 어렵다. <br><img alt="sigmoid_softmax" src="https://ejkiwi.github.io/lib/media/sigmoid_softmax.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"><br><img alt="Tanh1" src="https://ejkiwi.github.io/lib/media/Tanh1.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">
시그모이드의 자식
로지스틱(시그모이드) 함수를 평행이동하고 상수 곱한것과 동일
출력 범위: (-1,1) 시그모이드와 비슷하지만, 출력값이 영점을 중심으로 대칭
평균이 0에 가까워서 Gradient Vanishing 문제 완화 은닉층에서 주로 사용됨 시그모이드보다 더 나은 성능을 보임 =================================
여전히 Gradient Vanishing 문제 존재 값이 -1 또는 1에 가까워지면, 미분값이 0에 가까워짐
깊은 네트워크에서는 사용하기 어려움 → 요즘은 ReLU 계열을 더 많이 쓴다. <br><img alt="Tanh2" src="https://ejkiwi.github.io/lib/media/Tanh2.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">OPTIMIZER
손실 최소화를 위해 가중치 업데이트를 하는 데 사용
확률적 경사 하강법
가중치를 업데이트할 때, 전체 데이터가 아니라 일부만 사용 계산 속도를 빠르게 하기 위해 배치(Batch) 단위로 업데이트 SGD는 랜덤 샘플을 사용하기 때문에 최적값 주변에서 흔들리는 경향이 있음 이걸 해결하기 위해 Momentum, Nesterov Accelerated Gradient (NAG) 같은 기법 추가 ⚠️
지역 최소값(Local Minima)에 빠질 수 있음
학습 속도가 느릴 수 있음 기울기 방향이 항상 최선이 아니기 때문에 최적값에 도달하는데 오래 걸릴 수도 있음 진동(Loss값이 계속 크게 왔다 갔다 하는 현상) 발생 SGD 개선냥이
속도(velocity) 개념을 도입해서, 이전 기울기의 영향을 일부 유지
β(보통 0.9) 값이 클수록 이전 방향을 더 강하게 유지
기울기가 갑자기 바뀌더라도 부드럽게 이동 가능 → 진동(oscillation) 감소
⚠️
Overshooting 문제 : 너무 빠르게 이동가능해버려서 최적점을 지나칠수도있잖아! 라는 문제. Momentum 개선냥이
미리 계산한 위치에서 기울기를 보고 더 정확한 방향으로 이동 -&gt; 현 위치에서 앞으로의 위치도 미리 계산한 후 보정
Overshooting 문제 개선 SGD 개선냥이
각각의 파라미터에 대해 적응적인 학습률(learning rate) 적용
기울기가 크면 학습률을 줄이고, 기울기가 작으면 학습률을 증가 약간의 브레이크와 엑셀 느낌임.
학습률 ? : 가중치를 업데이트할 때 변화하는 크기를 결정하는 하이퍼파라미터. 모델이 얼마나 빠르게 또는 천천히 학습할지를 조절하는 중요한 요소 Gradient Vanishing 문제를 해결하는 데 도움 Momentum + RMSprop을 결합한 방식 모멘텀을 사용해서 빠르게 최적화하면서도, 적응적으로 학습률을 조정함
Momentum -&gt; 빠르게 최적화 가능
RMSprop -&gt; 적응적으로 학습률 조정 각각의 가중치에 대해 다른 학습률을 적용 변화가 큰 가중치는 학습률을 낮추고, 변화가 작은 가중치는 학습률을 높임 SGD보다 빠르게 수렴할 가능성이 높음 그래서 딥러닝에서 가장 많이 사용됨 ⚠️
메모리를 많이 사용 1차(moment)와 2차(moment) 모멘텀을 모두 저장해야 해서 SGD보다 메모리를 더 씀 일반화 성능이 떨어질 수 있다. 너무 빠르게 수렴해서 오히려 최적해를 잘 못 찾을 수도 있음 출력층에서 모델이 얼마나 잘못 예측했는지 평가하는 함수
모델의 예측값과 실제 정답(Label) 사이의 차이를 계산.
손실 함수의 값이 클수록 예측이 많이 틀린 것
손실 함수의 값이 **작을수록 예측이 잘 된 것
평균 제곱 오차
예측값 y^와 실제값 y의 차이를 제곱한 후 평균을 구함.
오차가 클수록 더 큰 패널티를 줌 (제곱이기 때문)
미분이 부드럽고, 계산이 쉬움. 예측 값과 실제값 사이의 평균 절대 차이를 측정하는 방법 mse + mae
오차가 작을 때는 MSE처럼 동작하고, 오차가 클 때는 MAE처럼 동작해서 이상치에 덜 민감
]]></description><link>ai_study/활성화-함수들과-최적화-알고리즘과-손실함수.html</link><guid isPermaLink="false">AI_study/활성화 함수들과 최적화 알고리즘과 손실함수.md</guid><pubDate>Thu, 11 Sep 2025 12:03:19 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/ReLU1.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/ReLU1.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[2025_하계_모각코]]></title><description><![CDATA[
<a data-href="뿌가각 모각코 활동" href="2025_하계_모각코/뿌가각-모각코-활동.html" class="internal-link" target="_self" rel="noopener nofollow">뿌가각 모각코 활동</a>
<br><a data-href="20250109 모각코 활동 1회차" href="2024-25_동계_모각코/20250109-모각코-활동-1회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250109 모각코 활동 1회차</a>
<br><a data-href="20250721 모각코 활동 2회차" href="2025_하계_모각코/20250721-모각코-활동-2회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250721 모각코 활동 2회차</a>
<br><a data-href="20250731 모각코 활동 3회차" href="2025_하계_모각코/20250731-모각코-활동-3회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250731 모각코 활동 3회차</a>
<br><a data-href="20250808 모각코 활동 4회차" href="2025_하계_모각코/20250808-모각코-활동-4회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250808 모각코 활동 4회차</a>
<br><a data-href="20250810 모각코 활동 5회차" href="2025_하계_모각코/20250810-모각코-활동-5회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250810 모각코 활동 5회차</a>
<br><a data-href="20250815 모각코 활동 6회차" href="2025_하계_모각코/20250815-모각코-활동-6회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250815 모각코 활동 6회차</a>
]]></description><link>2025_하계_모각코/2025_하계_모각코.html</link><guid isPermaLink="false">2025_하계_모각코/2025_하계_모각코.md</guid><pubDate>Sun, 17 Aug 2025 15:50:44 GMT</pubDate></item><item><title><![CDATA[20250815 모각코 활동 6회차]]></title><description><![CDATA[오늘의 목표 : 가상 메모리 공부하기프로그램이 실제 RAM보다 큰 메모리 공간을 쓸 수 있게 해주는 기술 (디스크를 메모리처럼 활용)
-&gt; 작은 RAM으로도 큰 프로그램을 실행할 수 있게 해준다!!
가상 메모리: 물리적 메모리보다 큰 메모리 공간을 프로그램에게 제공하는 기법
프로그램이 실제 물리 메모리 크기에 제약받지 않고 실행될 수 있도록 함
프로그램은 논리적 주소인 가상 주소를 사용하지만 실제 CPU는 당연히~ 물리적 주소에 접근을 하여야 한다. 이때 물리적 주소와 논리적 주소 사이에 상호 변환이 가능해야 하는데, 변환이 가능한 테이블을 운영체제가 제공해준다.
메모리 관리 하드웨어와 운영체제가 협력하여 구현 메모리 용량 확장: 물리 메모리보다 큰 프로그램 실행 가능
메모리 보호: 프로세스 간 메모리 영역 분리
메모리 공유: 여러 프로세스가 동일한 코드/데이터 공유 가능
프로그래밍 단순화: 연속된 메모리 공간 제공 가상 주소(Virtual Address): 프로그램이 사용하는 논리적 주소
물리 주소(Physical Address): 실제 메모리에서의 위치
가상 주소 → MMU(Memory Management Unit) → 물리 주소 하드웨어 구성요소
가상 주소를 물리 주소로 변환
페이지 테이블을 참조하여 변환 수행 페이지(Page): 가상 메모리를 일정한 크기로 나눈 단위 (보통 4KB)
프레임(Frame): 물리 메모리를 페이지와 같은 크기로 나눈 단위 가상 페이지 번호 → 물리 프레임 번호 매핑
각 프로세스마다 별도의 페이지 테이블 존재 Valid bit: 해당 페이지가 메모리에 있는지 표시
Protection bits: 읽기/쓰기/실행 권한
Reference bit: 최근에 접근했는지 표시
Modify bit: 페이지가 수정되었는지 표시
| Page Number (20비트) | Offset (12비트) | 가상 주소에서 페이지 번호와 오프셋 추출
페이지 테이블에서 해당 페이지 번호로 프레임 번호 찾기
Valid bit 확인
프레임 번호 + 오프셋 → 물리 주소 접근하려는 페이지가 물리 메모리에 없을 때
Valid bit가 0인 페이지에 접근할 때 하드웨어가 페이지 폴트 예외 발생
OS의 페이지 폴트 핸들러 실행
보조 저장장치(디스크)에서 해당 페이지 로드
페이지 테이블 업데이트
프로그램 재실행 물리 메모리보다 큰 프로그램 실행 가능
다중 프로그래밍 지원
메모리 보호 및 공유 기능
프로그래밍 편의성 증대 주소 변환 오버헤드
페이지 폴트로 인한 성능 저하
복잡한 메모리 관리
]]></description><link>2025_하계_모각코/20250815-모각코-활동-6회차.html</link><guid isPermaLink="false">2025_하계_모각코/20250815 모각코 활동 6회차.md</guid><pubDate>Sun, 17 Aug 2025 15:49:59 GMT</pubDate></item><item><title><![CDATA[20250808 모각코 활동 4회차]]></title><description><![CDATA[오늘의 목표 : 메모리 시스템 이해하기!<img alt="memory" src="https://ejkiwi.github.io/lib/media/memory.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">(위 사진의 input sources는 안 다룰것이댜)
용량: 32~64개 × 32/64비트 = 수백 바이트
속도: 1 클록 사이클
위치: CPU 내부
용도: 현재 작업 중인 데이터 용량: 16KB ~ 64KB
속도: 1-2 클록 사이클
위치: CPU 코어 내부
특징: 명령어 캐시(I-Cache)와 데이터 캐시(D-Cache)로 분리 용량: 256KB ~ 1MB
속도: 3-10 클록 사이클
위치: CPU 코어별 또는 공유
특징: 통합 캐시 (명령어 + 데이터) 용량: 8MB ~ 32MB
속도: 10-20 클록 사이클
위치: 여러 코어가 공유
특징: 코어 간 데이터 공유 역할 용량: 4GB ~ 128GB
속도: 100-300 클록 사이클
기술: DDR4, DDR5
특징: 휘발성, 프로그램 실행 공간 SSD: 빠르지만 비쌈 (마이크로초 단위)
HDD: 느리지만 저렴 (밀리초 단위)
특징: 비휘발성, 영구 저장 캐시 히트 (Cache Hit)
CPU → 캐시 확인 → 데이터 있음! → 빠른 반환 (1-10 사이클) 캐시 미스 (Cache Miss)
CPU → 캐시 확인 → 데이터 없음 → 메인 메모리 접근 → 캐시 업데이트 → 반환 (100-300 사이클) 캐시 라인 (Cache Line/Block) 캐시와 메모리 간 데이터 전송의 최소 단위
일반적으로 32바이트 ~ 128바이트
공간적 지역성 활용 태그 (Tag) 캐시 라인이 메모리의 어느 부분을 저장하고 있는지 식별
메모리 주소의 상위 비트들 유효 비트 (Valid Bit) 캐시 라인에 유효한 데이터가 있는지 표시
0: 무효, 1: 유효 캐시 교체 방식(정책) LRU (Least Recently Used) 가장 오래 사용되지 않은 블록을 교체 FIFO (First In First Out) 가장 먼저 들어온 블록을 교체 Random 무작위로 블록 선택 직접매핑 : 메모리의 각 블록이 캐시의 정확히 한 위치에만 매핑
완전 연관 매핑 : 메모리의 어떤 블록이라도 캐시의 어느 위치에나 저장 가능
집합 연관 매핑 : 캐시를 여러 집합(set)으로 나누고, 각 집합 내에서는 완전 연관
]]></description><link>2025_하계_모각코/20250808-모각코-활동-4회차.html</link><guid isPermaLink="false">2025_하계_모각코/20250808 모각코 활동 4회차.md</guid><pubDate>Sun, 17 Aug 2025 15:37:14 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/memory.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/memory.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[20250810 모각코 활동 5회차]]></title><description><![CDATA[오늘의 목표 : 저번에 공부하던 캐시 부분 이어서 더 공부하기, 파이프라인 개념 공부하기 자주 쓰는 데이터가 있어서, 이걸 임시로 저장해두고 우다다 쓰고 싶을 때.
캐시 없는 상황에서의 명령어 실행은? CPU의 대부분의 시간이 메모리를 기다리는 시간일 것이다( 명령어 가져오고(= 메모리 접근) 해석하고 실행하고 또 메모리접근해서 결과저장 ... ) 파이프라인이란? -&gt; 캐시 성능을 극대화 하기 위한 CPU 설계 기법 : 동시에 일을 하게 시키는 것임일1, 일2, 일3
시간1 -&gt; 일1 시작하자
시간2 -&gt; 일1 끝났다! 일2 시작하자
시간3 -&gt; 일2 끝났다!, 일3 시작하자
시간4 -&gt; 일3 끝났다!일1, 일2, 일3
시간1 -&gt; 일1 시작하자,
시간1~ -&gt; 일2 시작하자, 일1 하는중
시간1~ -&gt; 일3 시작하자, 일2 하는중, 일1 끝났다.
시간2 -&gt; 일3 하는중, 일2 끝났다.
시간2~ -&gt; 일3 끝났다.1. IF (Instruction Fetch): 명령어 가져오기
2. ID (Instruction Decode): 명령어 해석 + 레지스터 읽기
3. EX (Execute): ALU 연산 또는 주소 계산
4. MEM (Memory): 메모리 접근 (lw/sw만)
5. WB (Write Back): 결과를 레지스터에 저장 IF 단계: 명령어 캐시 접근
MEM 단계: 메모리 접근 없음
-&gt; 따라서 캐시의 미스가 영향을 미치는 부분은 IF에서만... 데이터 해저드 - 앞의 결과를 뒤에서 바로 써야 할 때 STALL, FORWARDING으로 해결가능
STALL: 뒤의 일을 잠시 대기시켰다가 앞에서 결과를 받고 그대로 사용
FORWARDING : MEM의 결과를 바로 EX로 전달하기 제어 해저드 - 분기할지 말지 모르겠을 때. 분기 결과를 알려면 EX 단계까지 가야하는데, 다음 명령어는 IF 단계에서 미리 가져와야 함. 근데?? 어떤 명령어를 가져올지 모르겠어!
항상 분기 안한다고 가정해서 순차적으로 계속 가져오거나 분기 예측기로 과거 패턴을 보고 예측하는 방식으로 해결 add $t0, $t1, $t2 IF: 명령어 캐시 접근 (히트/미스 가능)
MEM: 메모리 접근 없음 (캐시 무관)
영향: IF에서 캐시 미스 시만 스톨
lw $t0, 4($s0) IF: 명령어 캐시 접근
MEM: 데이터 캐시 접근
영향: 두 번의 캐시 접근! 둘 다 미스 가능성
sw $t0, 4($s0) IF: 명령어 캐시 접근
MEM: 데이터 캐시 쓰기
특이점: Write 정책에 따라 다름
]]></description><link>2025_하계_모각코/20250810-모각코-활동-5회차.html</link><guid isPermaLink="false">2025_하계_모각코/20250810 모각코 활동 5회차.md</guid><pubDate>Sun, 17 Aug 2025 15:30:31 GMT</pubDate></item><item><title><![CDATA[20250731 모각코 활동 3회차]]></title><description><![CDATA[오늘의 목표 : 프로세서 기초와 명령어 집합 공부하기일단 컴퓨터의 구조이다<img alt="cpu" src="https://ejkiwi.github.io/lib/media/cpu.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">
제어장치가 시키고, 연산장치가 일하고, 레지스터가 저장하는 느낌이다~_~역할
명령어를 해석하고 실행 순서를 제어
각 구성 요소에 제어 신호 전송
프로그램 카운터(PC) 관리
주요 기능
명령어 인출 (Fetch): 메모리에서 명령어 가져오기
명령어 해석 (Decode): 명령어의 의미 분석
실행 제어 (Execute): 필요한 제어 신호 생성
구성 요소
프로그램 카운터 (PC): 다음 실행할 명령어의 주소 저장
명령어 레지스터 (IR): 현재 실행 중인 명령어 저장
제어 신호 생성기: 각 구성 요소 제어
역할
모든 산술 연산과 논리 연산 수행
비교 연산 및 시프트 연산 담당
지원 연산
산술 연산: 덧셈, 뺄셈, 곱셈, 나눗셈
논리 연산: AND, OR, XOR, NOT
비교 연산: 같음, 크기 비교
시프트 연산: 좌시프트, 우시프트
플래그 레지스터
Zero Flag (Z): 결과가 0인지 표시
Carry Flag (C): 자리올림 발생 시
Overflow Flag (V): 오버플로 발생 시
Negative Flag (N): 결과가 음수인지 표시
역할
CPU에서 당장 사용할 데이터 보관
특징
CPU 내부의 고속 저장 공간
메모리보다 훨씬 빠른 접근 속도
제한된 개수 (보통 16~32개)
종류
범용 레지스터: 일반적인 데이터 저장
특수 목적 레지스터: 특정 용도로 사용 PC (Program Counter): 다음 명령어 주소
SP (Stack Pointer): 스택의 최상위 주소
LR (Link Register): 함수 호출 시 복귀 주소 정의
소프트웨어와 하드웨어 간의 인터페이스
프로그래머가 볼 수 있는 컴퓨터의 추상적 모델
CPU가 이해할 수 있는 명령어들의 집합
ISA가 정의하는 요소
명령어 집합: 사용 가능한 모든 명령어
레지스터: 개수, 크기, 용도
메모리 모델: 주소 지정 방식, 데이터 타입
예외 처리: 인터럽트, 예외 상황 처리
특징
오픈소스 ISA
모듈러 설계 (기본 + 확장)
학술 및 상업적 목적으로 자유 사용
32개의 범용 레지스터 (x0 ~ x31)특수 레지스터
x0 (zero): 항상 0 값, 쓰기 무시
pc: 프로그램 카운터 (명시적 접근 불가)
용도: 레지스터 간 연산 형식: op rd, rs1, rs2용도: 즉시값과 레지스터 연산, 로드 명령어 형식: op rd, rs1, imm 또는 op rd, imm(rs1)용도: 스토어 명령어 형식: op rs2, imm(rs1)용도: 조건부 분기 형식: op rs1, rs2, label용도: 상위 즉시값 로드 형식: op rd, imm용도: 무조건 점프 형식: op rd, label형식: addi x1, x2, 100
의미: 즉시값을 직접 사용
장점: 빠름
단점: 값의 크기 제한형식: add x1, x2, x3
의미: 레지스터 값 직접 사용
장점: 가장 빠름
특징: RISC의 기본 방식형식: lw x1, 8(x2)
의미: 베이스 레지스터 + 오프셋
용도: 배열, 구조체 접근
계산: 주소 = x2 + 8형식: beq x1, x2, label
의미: 현재 PC + 오프셋
용도: 분기 명령어
장점: 위치 독립적 코드1. 인출 (Fetch)IR ← Memory[PC]
PC ← PC + 4
2. 해석 (Decode)
명령어 형식 판별
필요한 레지스터 식별
제어 신호 생성
3. 실행 (Execute)
ALU 연산 수행
메모리 접근 (필요시)
결과 저장
4. 쓰기 (Write-back)
결과를 목적지 레지스터에 저장
플래그 업데이트
1. Fetch: IR ← Memory[PC], PC ← PC + 4
2. Decode: R-type, rs1=x2, rs2=x3, rd=x1, funct=ADD
3. Execute: ALU_result ← Register[x2] + Register[x3]
4. Write-back: Register[x1] ← ALU_result
]]></description><link>2025_하계_모각코/20250731-모각코-활동-3회차.html</link><guid isPermaLink="false">2025_하계_모각코/20250731 모각코 활동 3회차.md</guid><pubDate>Tue, 12 Aug 2025 17:24:13 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/cpu.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/cpu.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[20250718 모각코 활동 1회차]]></title><description><![CDATA[오늘의 목표
1.컴퓨터 구조 기본 개념과 디지털 논리 이해하기<img alt="computersystem" src="https://ejkiwi.github.io/lib/media/computersystem.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">중앙처리장치 (CPU)
명령어 실행과 연산을 담당하는 핵심 부품
제어장치(Control Unit)와 산술논리장치(ALU)로 구성
레지스터를 통해 임시 데이터 저장
메모리 시스템
주기억장치(RAM): 실행 중인 프로그램과 데이터 저장
보조기억장치(HDD, SSD): 영구적인 데이터 저장
캐시 메모리: CPU와 주기억장치 간의 속도 차이 보완
입출력 장치
입력장치: 키보드, 마우스, 터치스크린 등
출력장치: 모니터, 프린터, 스피커 등
입출력 제어기를 통해 CPU와 통신
소프트웨어는 계층적 구조로 구성시스템 소프트웨어
운영체제(OS): 하드웨어 자원 관리 및 사용자 인터페이스 제공
컴파일러: 고급 언어를 기계어로 번역
어셈블러: 어셈블리어를 기계어로 번역
응용 소프트웨어
사용자가 직접 사용하는 프로그램
워드프로세서, 웹브라우저, 게임 등 0과 1로만 구성된 수 체계
컴퓨터에서 모든 정보를 표현하는 기본 단위
예: 1011₂ = 1×2³ + 0×2² + 1×2¹ + 1×2⁰ = 11₁₀ 0~7의 숫자로 구성
이진수 3자리를 8진수 1자리로 변환 가능
예: 123₈ = 1×8² + 2×8¹ + 3×8⁰ = 83₁₀ 0~9, A~F로 구성 (A=10, B=11, C=12, D=13, E=14, F=15)
이진수 4자리를 16진수 1자리로 변환 가능
메모리 주소 표현에 주로 사용
예: A3F₁₆ = 10×16² + 3×16¹ + 15×16⁰ = 2623₁₀
10진수 → 2진수: 2로 나누어 나머지를 역순으로 배열 2진수 → 16진수: 4자리씩 묶어서 변환
1010 1100₂ = AC₁₆
AND 게이트
모든 입력이 1일 때만 출력이 1
진리표: A=0,B=0→0 | A=0,B=1→0 | A=1,B=0→0 | A=1,B=1→1
기호: D형 게이트 모양
OR 게이트
하나 이상의 입력이 1이면 출력이 1
진리표: A=0,B=0→0 | A=0,B=1→1 | A=1,B=0→1 | A=1,B=1→1
기호: 곡선형 게이트 모양
NOT 게이트 (인버터)
입력의 반대 값을 출력
진리표: A=0→1 | A=1→0
기호: 삼각형에 작은 원
XOR 게이트 (배타적 OR)
입력이 서로 다를 때만 출력이 1
진리표: A=0,B=0→0 | A=0,B=1→1 | A=1,B=0→1 | A=1,B=1→0
덧셈 회로에서 자리올림 없는 합 구현
NAND 게이트
AND 게이트의 출력을 NOT한 결과
범용 게이트: 모든 논리 함수 구현 가능
NOR 게이트
OR 게이트의 출력을 NOT한 결과
범용 게이트: 모든 논리 함수 구현 가능
교환 법칙 (Commutative Law)
A + B = B + A
A · B = B · A
결합 법칙 (Associative Law)
(A + B) + C = A + (B + C)
(A · B) · C = A · (B · C)
분배 법칙 (Distributive Law)
A · (B + C) = A·B + A·C
A + (B · C) = (A + B) · (A + C)
항등 법칙 (Identity Law)
A + 0 = A
A · 1 = A
보수 법칙 (Complement Law)
A + A' = 1
A · A' = 0
논리식의 부정을 간단히 하기 때문에 중요하다!(A + B)' = A' · B'
OR의 부정은 각각의 부정을 AND
(A · B)' = A' + B'
AND의 부정은 각각의 부정을 OR 출력이 현재 입력에만 의존
메모리 기능 없음
입력이 바뀌면 즉시 출력 변화
가산기 (Adder)
반가산기(Half Adder): 2개의 1비트 수를 더함 입력: A, B / 출력: Sum, Carry
Sum = A ⊕ B, Carry = A · B 전가산기(Full Adder): 이전 자리올림까지 고려 입력: A, B, Cin / 출력: Sum, Cout 디코더 (Decoder)
n비트 입력을 2ⁿ개의 출력선 중 하나를 선택
메모리 주소 디코딩에 사용
인코더 (Encoder)
2ⁿ개의 입력선 중 하나를 n비트로 인코딩
키보드 입력 처리에 사용
멀티플렉서 (Multiplexer, MUX)
여러 입력 중 하나를 선택하여 출력
선택신호에 따라 입력 경로 결정 출력이 현재 입력과 이전 상태에 의존
메모리 기능 보유
클록 신호에 동기화되어 동작 컴퓨터에서 모든 동작의 타이밍을 맞춰주는 기준 신호
컴퓨터 부품들이 언제 동작해야 하는지 알려주는 시간 기준 플립플롭 (Flip-Flop)
1비트 정보를 저장하는 기본 메모리 소자
클록 신호에 의해 상태 변화
카운터 (Counter)
클록 펄스를 계수하는 회로
업카운터, 다운카운터, 링카운터 등
레지스터 (Register)
여러 비트의 정보를 저장
시프트 레지스터: 데이터를 좌우로 이동
메모리
대용량 데이터 저장을 위한 순차 회로
RAM, ROM 등의 기본 구조
]]></description><link>2025_하계_모각코/20250718-모각코-활동-1회차.html</link><guid isPermaLink="false">2025_하계_모각코/20250718 모각코 활동 1회차.md</guid><pubDate>Tue, 12 Aug 2025 17:02:26 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/computersystem.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/computersystem.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[20250721 모각코 활동 2회차]]></title><description><![CDATA[오늘의 목표
1.데이터 표현(정수, 실수, 문자) 이해하기
2.산술 연산을 위한 회로 설계 공부특징
0 이상의 양수만 표현
n비트로 0부터 2ⁿ-1까지 표현 가능
모든 비트가 크기를 나타냄
예시 0000₂ = 0₁₀
0101₂ = 5₁₀
1111₂ = 15₁₀ 최상위 비트(MSB)가 부호 비트 (0=양수, 1=음수)
나머지 비트가 크기를 나타냄
문제점 : 0이 두 개 (+0, -0), 연산이 복잡
예시 (4비트) 0011₂ = +3₁₀
1011₂ = -3₁₀ 양수의 모든 비트를 반전시켜 음수 표현
문제점 : 여전히 0이 두 개 존재
예시 +3: 0011₂
-3: 1100₂ (0011의 모든 비트 반전) 현재 가장 널리 사용되는 방식계산 방법
양수의 1의 보수를 구함 (모든 비트 반전)
1을 더함 예시 +3: 0011₂
-3: 1100₂ + 1₂ = 1101₂ 0이 하나만 존재
덧셈/뺄셈 회로가 동일
범위: -2ⁿ⁻¹ ~ 2ⁿ⁻¹-1
8비트 2의 보수 범위: -128 ~ +127
표현 가능한 범위를 벗어나는 경우
부호 없는 정수: 자리올림이 발생하면 오버플로
부호 있는 정수: 부호가 바뀌면 오버플로
구성 요소
부호(Sign): 1비트 (0=양수, 1=음수)
지수(Exponent): 8비트 (단정도), 11비트 (배정도)
가수(Mantissa/Significand): 23비트 (단정도), 52비트 (배정도)
형식: S EEEEEEEE MMMMMMMMMMMMMMMMMMMMMMM
S: Sign bit (부호 비트) - 1비트
EEEEEEEE: Exponent (지수) - 8비트
MMMMMMMMMMMMMMMMMMMMMMM: Mantissa/Significand (가수) - 23비트
표현 방법
실수를 이진 소수로 변환
정규화 (1.xxxxx × 2ᵏ 형태)
지수에 바이어스(127) 더함
가수에서 정수부 1 제거 (암묵적 1) 예시: 12.75₁₀ 표현 12.75₁₀ = 1100.11₂
정규화: 1.10011 × 2³
지수: 3 + 127 = 130₁₀ = 10000010₂
가수: 10011000000000000000000₂
결과: 0 10000010 10011000000000000000000 0: 지수와 가수가 모두 0
무한대(∞): 지수가 모두 1, 가수가 0
NaN: 지수가 모두 1, 가수가 0이 아님 모든 실수를 정확히 표현할 수 없음
반올림 오차 발생 가능
예: 0.1₁₀을 이진수로 정확히 표현 불가
특징
7비트 코드 (0~127)
128개 문자 표현
영어 알파벳, 숫자, 특수문자, 제어문자
주요 코드
'0' ~ '9': 48 ~ 57 (30H ~ 39H)
'A' ~ 'Z': 65 ~ 90 (41H ~ 5AH)
'a' ~ 'z': 97 ~ 122 (61H ~ 7AH)
공백: 32 (20H)
줄바꿈(LF): 10 (0AH)
확장 ASCII
8비트 사용 (0~255)
추가 128개 문자 (특수문자, 외국어 문자)
배경
ASCII로는 전 세계 모든 문자 표현 불가
다국어 지원 필요
특징
전 세계 모든 문자를 하나의 코드 체계로 통합
현재 약 150,000개 문자 수록
코드 포인트: U+0000 ~ U+10FFFF
인코딩 방식
UTF-8: 가변 길이 (1~4바이트), ASCII 호환
UTF-16: 가변 길이 (2~4바이트)
UTF-32: 고정 길이 (4바이트)
UTF-8의 장점
ASCII와 완전 호환
인터넷에서 가장 널리 사용
영어는 1바이트, 한글은 3바이트로 효율적 CPU의 핵심 구성 요소
산술 연산(+, -, ×, ÷)과 논리 연산(AND, OR, NOT) 수행
비교 연산과 시프트 연산도 담당
입력
A, B: 피연산자 (보통 32비트 또는 64비트)
제어 신호: 수행할 연산 지정
캐리 입력(Cin): 이전 연산의 자리올림
출력
결과(Result): 연산 결과
플래그(Flags): 연산 상태 정보 Zero Flag (Z): 결과가 0일 때
Carry Flag (C): 자리올림 발생 시
Overflow Flag (V): 오버플로 발생 시
Negative Flag (N): 결과가 음수일 때 제어 신호 예시 (4비트)
0000: A AND B
0001: A OR B
0010: A + B
0110: A - B
0111: A &lt; B인지 비교
기능: 2개의 1비트 수를 더함 입력: A, B 출력: Sum, Carry논리식
Sum = A ⊕ B (XOR)
Carry = A · B (AND)
진리표기능: 2개의 1비트 수와 이전 자리올림을 더함 입력: A, B, Cin 출력: Sum, Cout논리식
Sum = A ⊕ B ⊕ Cin
Cout = A·B + Cin·(A ⊕ B)
구현 방법
반가산기 2개를 연결하여 구성 가능
원리: A - B = A + (-B) = A + B의 2의 보수구현 방법
B의 모든 비트를 반전 (1의 보수)
가산기의 캐리 입력에 1을 넣음
A와 처리된 B를 가산기로 더함
장점
덧셈기 회로를 그대로 활용
별도의 뺄셈 회로 불필요
구조
덧셈기에 XOR 게이트 추가
제어 신호로 덧셈/뺄셈 선택
동작
Sub = 0: 덧셈 모드 (B는 그대로 전달)
Sub = 1: 뺄셈 모드 (B는 반전되어 전달, Cin = 1)
시프트-덧셈 방법
승수의 각 비트를 검사
1이면 피승수를 더하고, 0이면 건너뜀
매번 피승수를 왼쪽으로 시프트
부스 알고리즘 (Booth's Algorithm)
부호 있는 정수의 효율적인 곱셈
연속된 1을 하나의 덧셈과 뺄셈으로 처리
복원 나눗셈 (Restoring Division)
피제수에서 제수를 빼봄
결과가 음수면 복원하고 몫에 0
결과가 양수면 몫에 1
나머지를 왼쪽으로 시프트하고 반복
]]></description><link>2025_하계_모각코/20250721-모각코-활동-2회차.html</link><guid isPermaLink="false">2025_하계_모각코/20250721 모각코 활동 2회차.md</guid><pubDate>Tue, 29 Jul 2025 09:25:39 GMT</pubDate></item><item><title><![CDATA[2025 cnu 동계 학습동아리 (복습)]]></title><link>2025-cnu-동계-학습동아리-(복습)/2025-cnu-동계-학습동아리-(복습).html</link><guid isPermaLink="false">2025 cnu 동계 학습동아리 (복습)/2025 cnu 동계 학습동아리 (복습).md</guid><pubDate>Tue, 29 Jul 2025 08:02:18 GMT</pubDate></item><item><title><![CDATA[통통이들 학습 동아리 활동]]></title><description><![CDATA[비록 미적짱은 되지 못했지만 확통짱은 될 수 있을것이야... \( •̀ ω •́ )/ ]]></description><link>2025-cnu-동계-학습동아리-(복습)/통통이들-학습-동아리-활동.html</link><guid isPermaLink="false">2025 cnu 동계 학습동아리 (복습)/통통이들 학습 동아리 활동.md</guid><pubDate>Tue, 29 Jul 2025 08:02:08 GMT</pubDate></item><item><title><![CDATA[Class-Balanced Loss Based on Effective Number of Samples _ 김언지]]></title><link>ai_study/class-balanced-loss-based-on-effective-number-of-samples-_-김언지.html</link><guid isPermaLink="false">AI_study/Class-Balanced Loss Based on Effective Number of Samples _ 김언지.pdf</guid><pubDate>Mon, 12 May 2025 16:55:17 GMT</pubDate></item><item><title><![CDATA[버전 관리]]></title><description><![CDATA[눈에 보이는 디렉터리.
파일 수정, 저장 등의 작업을 하는 디렉터리.버전으로 만들어질 파일이 대기하는 곳 ( = staging area )( 저장소 )
스테이지에서 대기하고 있던 파일들을 버전으로 만들어 저장하는 곳.로컬 저장소
내 컴퓨터 안에서 관리되는 git저장소
( 내가 작업하고 잇는 공간 ex -&gt; 저번에 다이브 홈피 만들 때 인텔리제이에서 작업햇자나 그 공간임 )원격 저장소( git push 하면 올라가는 그 곳 )를 의미함.
" 내가 포크fork 하여 클론clone 한 원격 저장소 "
내 로컬 저장소와 연결된 저장소를 뜻함.
내가 푸시push 하는 원격 저장소를 뜻함.
내 포크fork 라고 해도 됨.
원본 저장소를 의미함
" 내가 포크fork한 레포의 원본 제작자 저장소 "
어떤 프로젝트를 포크fork 했을 때, 내 레포지토리의 원본이 되는 저장소를 뜻함.
원본 프로젝트의 저장소를 뜻하는것임.
새로운 버전 생성
스테이지 -&gt; 저장소로컬에서 원격 저장소로 변경 사항을 업로드.
로컬에서 작업한 것을 원격 저장소와 동기화 하는 것.두 개의 브랜치를 하나로 합치는 것.
0. ex)
develop 브랜치로 이동
브랜치 merge ( 여기까지는 로컬에서만 반영 )
merge 완료 후 push해서 원격에도 반영
만약 시현언니와 내가 홈페이지의 같은 부분을 서로 다르게 수정했다면 어떻게 될까??? -&gt; git은 어떤 코드가 맞는지 판단할만큼 똑똑이가 아니다.
-&gt; 고로 내 코드가 덮어씌워지거나 시현언니의 코드가 덮어씌워질 수 있다 이말이다!!
git status를 통해 충돌 난 파일을 확인하자
수동으로 충돌 해결 후 수정해야한다. ( 구분선 으로 충돌된 두 코드를 확인할 수 있을것 )
최종 수정본 다시 git에 반영 pull origin을 통해 항상 최신 상태를 유지하자.
작업 시 브랜치를 너무 오래 따로 두지 말고, 자주 동기화하자.
다른 사람이 작업하는 부분은 피해서 작업하자.
한 디렉터리 안에서 버전 관리를 하지 않을 파일이나 디렉터리가 있을 시, .gitignore파일을 안에다가 파일이나 디렉터리이름 또는 파일 확장자를 입력해두면 입력해둔 것들을 버전 관리에서 제외할 수 있다.내 로컬 저장소에서 origin이나 upstream 레포의 최신 변경사항 가져오기원격 저장소의 최신 변경 사항 로컬 브랜치에 반영로컬 브랜치를 원격 저장소 상태로 초기화협업을 위한 브랜치 관리 방법론최종 배포를 위한 브랜치개발용 브랜치 - 실제 작업
develop에서 수정한 후 main으로 병합해야 한다.develop에서 갈라져 나온 브랜치
기능 개발이 목적develop에서 갈라져 나온 브랜치
이번 출시 버전 준비가 목적버그 수정하는 브랜치
develop브랜치로 이동
새로운 기능 추가를 위해 feature 브랜치 생성 ( 그냥 바로 develop 브랜치에서 수정해도 되긴 함)
변경 사항을 커밋하고 develop에 병합 ( 그냥 바로 develop 브랜치에서 수정해도 되긴 함)
develop 브랜치를 main으로 병합
git 저장소 안에 또 다른 git 저장소를 포함하는 기능
하나의 프로젝트에서 다른 프로젝트를 독립적인 버전 관리 상태로 유지하고 싶을 때...!!! 사용한다다다다다다다
??? 경험해본 적 없어서 아직 모르겟ㄸ]]></description><link>git&amp;github/버전-관리.html</link><guid isPermaLink="false">git&amp;github/버전 관리.md</guid><pubDate>Wed, 19 Feb 2025 07:31:49 GMT</pubDate></item><item><title><![CDATA[난이걸여태몰랏어]]></title><description><![CDATA[사용하고 싶은 문서의 경로로 이동한 후에, 그곳에서 git 명령어를 사용하면 되는것이었다!!!!
터미널에서 경로 이동
Git 초기화 ( 말이 그냥 초기화지 그냥 Git을 사용할 준비를 하는 것. )
git init
사용할 파일 준비 : 작업할 파일이나 문서를 저장소에 추가
커밋
]]></description><link>git&amp;github/난이걸여태몰랏어.html</link><guid isPermaLink="false">git&amp;github/난이걸여태몰랏어.md</guid><pubDate>Wed, 19 Feb 2025 07:29:36 GMT</pubDate></item><item><title><![CDATA[2024-25_동계_모각코]]></title><description><![CDATA[
<a data-href="파샤샥 모각코 활동" href="2024-25_동계_모각코/파샤샥-모각코-활동.html" class="internal-link" target="_self" rel="noopener nofollow">파샤샥 모각코 활동</a>
<br><a data-href="20250109 모각코 활동 1회차" href="2024-25_동계_모각코/20250109-모각코-활동-1회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250109 모각코 활동 1회차</a>
<br><a data-href="20250117 모각코 활동 2회차" href="2024-25_동계_모각코/20250117-모각코-활동-2회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250117 모각코 활동 2회차</a>
<br><a data-href="20250126 모각코 활동 3회차" href="2024-25_동계_모각코/20250126-모각코-활동-3회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250126 모각코 활동 3회차</a>
<br><a data-href="20250202 모각코 활동 4회차" href="2024-25_동계_모각코/20250202-모각코-활동-4회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250202 모각코 활동 4회차</a>
<br><a data-href="20250209 모각코 활동 5회차" href="2024-25_동계_모각코/20250209-모각코-활동-5회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250209 모각코 활동 5회차</a>
<br><a data-href="20250215 모각코 활동 6회차" href="2024-25_동계_모각코/20250215-모각코-활동-6회차.html" class="internal-link" target="_self" rel="noopener nofollow">20250215 모각코 활동 6회차</a>
]]></description><link>2024-25_동계_모각코/2024-25_동계_모각코.html</link><guid isPermaLink="false">2024-25_동계_모각코/2024-25_동계_모각코.md</guid><pubDate>Sat, 15 Feb 2025 17:03:58 GMT</pubDate></item><item><title><![CDATA[20250215 모각코 활동 6회차]]></title><description><![CDATA[오늘의 목표 : 프로젝트 결과 발표와 활동 마무리 리스트, 튜플, 집합, 딕셔너리 기본 데이터들의 구조이다
데이터를 저장하고 정리할 때 사용된다.
순서가 있는 데이터 모음은 리스트
순서가 있는 데이터 모음이지만 수정이 불가능한 튜플
중복과 순서 둘 다 없는 데이터 모음은 집합
키 - 값 쌍의 데이터 모음은 딕셔너리 연산자, 조건문, 반복문, 함수 데이터를 처리하거나 조작할 때 필수적으로 사용된다.
수학적 계산이나 논리적 비교를 위해서 연산자를 사용하고
특정 조건에 따라 동작을 실행하기 위해 조건문을 사용하고
같은 작업을 여러 번 실행하기 위해 반복문을 사용한다.
함수는 반복적인 작업을 하나로 묶어서 재사용할 수 있해주는 도구이다. 넘파이 수치 데이터를 더욱 빠르고 효율적으로 다룰 수 있게 해는 파이썬 라이브러리이다.
넘파이의 배열은 리스트보다 훨씬 굿굿이다. ( 벡터와 행렬 연산에 강력함 )
기계학습 모델에서 데이터를 입력할 때 넘파이에서의 배열을 주로 사용함. 판다스 데이터 분석에 최적화된 라이브러리이다. ( 데이터 정리와 분석 )
DataFrame : 2차원 테이블 형태로 데이터를 쉽게 다룰 수 있게 해줌.
주로 데이터 전처리에서 많이 사용. 기계학습 데이터로부터 패턴을 학습해서 예측하는 과정. ]]></description><link>2024-25_동계_모각코/20250215-모각코-활동-6회차.html</link><guid isPermaLink="false">2024-25_동계_모각코/20250215 모각코 활동 6회차.md</guid><pubDate>Sat, 15 Feb 2025 17:02:59 GMT</pubDate></item><item><title><![CDATA[20250109 모각코 활동 1회차]]></title><description><![CDATA[오늘의 목표 : 연산자, 조건문, 반복문, 함수 복습
연산자 : 어떤 연산을 나타내는 기호
피연산자 : 연산의 대상이 되는 숫자나 변수를 의미 거듭제곱(지수)는 높은 우선순위를 가짐
거듭제곱 표현 시 왼쪽부터 계산됨..!! abc (&lt;-방향)
지수자리에는 실수도 들어올 수 있다 부울BOOL형 T F의 값을 가짐
붙어있는 그 자체로 하나임.
참 거짓 값을 갖게 된 비교연산자 덩어리들을 변수에집어넣을수도 있음. 부울BOOL형 T F의 값을 가짐 붙어있는 그 자체로 하나임.
비트 단위연산자에도 적용 가능 숫자를 2진수로 변환해서 비트 단위로 연산하는 연산자
? 시프트 ?
비트를 왼쪽 또는 오른쪽으로 이동시키는 것.
왼쪽 시프트 : 비트를 왼쪽으로 밀고 오른쪽에 0을 채워넣음 (값이 두 배)
오른쪽 시프트 : 비트를 오른쪽으로 밀고 왼쪽에 0을 채워넣음(값이 절반) 0제외 모든 수 : T
0 : F
문자 : T
공백문자 "" : F
None : F 횟수 제어 반복(for문) : 반복 횟수 지정
조건 제어 반복(while문) : 특정 조건 만족시 계속 반복 range(start=0,stop,step=1) : start와step은 따로 지정하지 않으면 0과 1로 지정. 반드시 지정해야하는 값은 stop값. T =turtle.Turtle() -&gt; T라는 변수로 거북이 객체를 생성
T.shape("turtle") -&gt; 거북이 객체 T에 shape()라는 명령을 내림 이 때 shape()는 메소드
t.forward(100) -&gt; 거북이 객체 T에&nbsp; forward()라는 명령을 내림 이 때 forward()는 메소드
print('helloworld')&nbsp; -&gt; 'helloworld'라는 문자열을 출력하기 위한 명령을 내리는 print()함수.
함수 : 여러 개의 매개변수를 가질 수 있고, 이 매개변수를 통해 일을 함. 객체가 없더라도 일을 할 수 있고, print()처럼 단독으로 사용 가능. 함수()
메소드 : 매개변수 가질 수 있음. 클래스의 일부로 메소드가 존재하며( 아마 메소드가 클래스의 일부로서 존재한다는 뜻 같음 ) 객체가 있어야 일을 할 수 있음. 객체.메소드() 느낌으로 사용해야함 코드의 재사용성 증가
가독성 향상
유지보수 용이 a='abcde'=&gt;문자열 문자열 안에 있는 개별 문자들을 추출하는 작업이 기본적. (문자열을 문자로 분해) 문자열은 인덱스로 접근 가능 인덱스(0~)/음수인덱스(-1~) 슬라이싱 : [이상:미만] 문자열 리스트 변환 : list('a') 문자열을 단어로 나누는 작업 a.split() -&gt; 띄어쓰기를 기준으로 구분
a.split('.') -&gt;&nbsp; '.' 을 기준으로 구분
=&gt; 즉, split()의 괄호 안에는 기준이 들어가는 거임. 단어들을 다시 붙이는 작업 ''.join(문자들) -&gt; 문자들이 붙음
'-'.join(문자들) -&gt; 문자들이 -을 사용하여 붙여짐. 문자열의 출현 횟수 계산 a.count('찾고싶은녀석') 문자열이 무엇으로 시작/끝 이 나는지 확인 a.startswith() =&gt; 시작 . 부울형으로 결과가 나옴
a.endswith() =&gt; 끝 . 부울형 결과 나옴 ]]></description><link>2024-25_동계_모각코/20250109-모각코-활동-1회차.html</link><guid isPermaLink="false">2024-25_동계_모각코/20250109 모각코 활동 1회차.md</guid><pubDate>Sat, 15 Feb 2025 15:46:11 GMT</pubDate></item><item><title><![CDATA[20250209 모각코 활동 5회차]]></title><description><![CDATA[오늘의 목표 : 기계학습 구현import pandas as pd import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.tree import DecisionTreeClassifier from sklearn.tree import plot_tree
# 데이터 다운로드 wine = pd.read_csv('https://bit.ly/wine_csv_data')
# 데이터 구조 확인 print(wine.head()) # 처음 5개의 샘플 print(wine.info()) # 데이터프레임의 각 열의 데이터 타입과 누락된 데이터 확인 print(wine.describe()) # 통계 ( 평균, 표준편차, 최소, 최대, 중간값, 1사분위수, 3사분위수 ) alcohol sugar pH class
0 9.4 1.9 3.51 0.0
1 9.8 2.6 3.20 0.0
2 9.8 2.3 3.26 0.0
3 9.8 1.9 3.16 0.0
4 9.4 1.9 3.51 0.0
&lt;class 'pandas.core.frame.DataFrame'&gt;
RangeIndex: 6497 entries, 0 to 6496
Data columns (total 4 columns):
Column Non-Null Count Dtype 0 alcohol 6497 non-null float64
1 sugar 6497 non-null float64
2 pH 6497 non-null float64
3 class 6497 non-null float64
dtypes: float64(4)
memory usage: 203.2 KB
None
alcohol sugar pH class
count 6497.000000 6497.000000 6497.000000 6497.000000
mean 10.491801 5.443235 3.218501 0.753886
std 1.192712 4.757804 0.160787 0.430779
min 8.000000 0.600000 2.720000 0.000000
25% 9.500000 1.800000 3.110000 1.000000
50% 10.300000 3.000000 3.210000 1.000000
75% 11.300000 8.100000 3.320000 1.000000
max 14.900000 65.800000 4.010000 1.000000# 판다스 데이터 프레임 -&gt; 넘파이 배열 data = wine[['alcohol', 'sugar', 'pH']].to_numpy() target = wine['class'].to_numpy()
# 데이터 나누기 train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2, random_state=42)
# 나눈 데이터 형태 확인 print(train_input.shape, test_input.shape)
(5197, 3) (1300, 3)# 데이터 전처리 ss = StandardScaler() ss.fit(train_input) train_scaled = ss.transform(train_input) test_scaled = ss.transform(test_input)
lr = LogisticRegression() lr.fit(train_scaled, train_target) print(lr.score(train_scaled, train_target)) print(lr.score(test_scaled, test_target)) print(lr.coef_, lr.intercept_) # 로지스틱 회귀가 학습한 계수와 절편
0.7808350971714451 0.7776923076923077 <a data-href="0.51268071 1.67335441 -0.68775646" href=".html" class="internal-link" target="_self" rel="noopener nofollow">0.51268071 1.67335441 -0.68775646</a> [1.81773456]`dt = DecisionTreeClassifier(random_state=42) dt.fit(train_scaled, train_target) print(dt.score(train_scaled, train_target)) print(dt.score(test_scaled, test_target))
0.996921300750433
0.8592307692307692# 훈련 결과 시각화 plt.figure(figsize=(10,7)) plot_tree(dt) plt.show()
<br><img alt="wine_plot1" src="https://ejkiwi.github.io/lib/media/wine_tree1.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 자세히 살펴보기 plt.figure(figsize=(10,7)) plot_tree(dt, max_depth=1, filled=True, feature_names=['alcohol', 'sugar', 'pH']) plt.show()
<br><img alt="wine_plot2" src="https://ejkiwi.github.io/lib/media/wine_tree2.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 가지치기 dt = DecisionTreeClassifier(max_depth=3, random_state=42) dt.fit(train_scaled, train_target) print(dt.score(train_scaled, train_target)) print(dt.score(test_scaled, test_target))
0.8454877814123533
0.8415384615384616# 가지치고 난 뒤의 훈련 시각화 plt.figure(figsize=(20,15)) plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH']) plt.show()
<br><img alt="wine_plot3" src="https://ejkiwi.github.io/lib/media/wine_tree3.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 전처리 하기 전의 데이터들로 다시 훈련해보기 -&gt; 결과는 같을 것. dt = DecisionTreeClassifier(max_depth=3, random_state=42) dt.fit(train_input, train_target) print(dt.score(train_input, train_target)) print(dt.score(test_input, test_target))
0.8454877814123533
0.8415384615384616# 시각화 -&gt; 데이터를 전처리 하고 난 뒤에 훈련 한 것과 같은 트리를 갖지만, 특성값을 표준점수로 바꾸지 않았기 때문에 이해하기 더욱 쉬움. plt.figure(figsize=(20,15)) plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH']) plt.show()
<br><img alt="wine_plot4" src="https://ejkiwi.github.io/lib/media/wine_tree4.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 특성 중요도 print(dt.feature_importances_)
[0.12345626 0.86862934 0.0079144 ]]]></description><link>2024-25_동계_모각코/20250209-모각코-활동-5회차.html</link><guid isPermaLink="false">2024-25_동계_모각코/20250209 모각코 활동 5회차.md</guid><pubDate>Mon, 10 Feb 2025 10:21:55 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/wine_tree1.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/wine_tree1.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[파샤샥 모각코 활동]]></title><description><![CDATA['파사삭' == '파이썬 파사삭'나의 모각코 활동 다짐 : 파이썬의 짱이 되겠다!!!!!!팀 모각코 계획]]></description><link>2024-25_동계_모각코/파샤샥-모각코-활동.html</link><guid isPermaLink="false">2024-25_동계_모각코/파샤샥 모각코 활동.md</guid><pubDate>Mon, 10 Feb 2025 08:46:23 GMT</pubDate></item><item><title><![CDATA[20250202 모각코 활동 4회차]]></title><description><![CDATA[오늘의 목표 : Pandas 공부와 타이타닉 데이터 분석
판다스(Pandas) : 파이썬에서의 데이터 분석과 처리를 위해 사용되는 라이브러리.
엑셀, CSV, SQL 같은 다양한 형식의 데이터를 쉽게 다룰 수 있음.
numpy기반으로 만들어져 빠르고 효율적임.
Series (1차원 데이터)
리스트나 배열과 비슷하지만, 인덱스를 가질 수 있음.
data = pd.Series([10, 20, 30, 40], index=['A', 'B', 'C', 'D'])
DataFrame (2차원 데이터)
표 형태의 데이터 구조로, 행과 열로 구성됨.
data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [25, 30, 35], 'Score': [85, 90, 95]}
데이터 불러오기.read_csv('파일경로.csv') # CSV 파일 불러오기
.read_excel('파일경로.xlsx') # 엑셀 파일 불러오기
.info() # 데이터 요약 정보
.describe() # 수치형 데이터 통계 요약 (이 때, include = 'object' 라는 파라미터를 넣어주면, 범주형 변수에 대한 통계정보를 볼 수 있음. )
.shape # (행, 열) 크기 확인
.columns # 컬럼(열) 이름 확인
.dtypes # 데이터 타입 확인 .isnull().sum() # 결측치(NaN) 개수 확인
.head() # 상위 5개 행 출력
.tail() # 하위 5개 행 출력
.dropna() # 결측치가 하나라도 있는 행 삭제
.
.
.
등등...
# 필요한 모듈 불러오기 import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 데이터 불러오기 df = sns.load_dataset('titanic') # 데이터 기본 정보 확인 print(df.info()) print(df.isnull().sum()) # 결측치 확인 # 결측치 처리 (결측치가 하나라도 있는 행은 그냥 없애버릴것이다~!) df = df.dropna() df = df.reset_index(drop=True) # 인덱스 정리
결과&lt;class 'pandas.core.frame.DataFrame'&gt;
RangeIndex: 891 entries, 0 to 890
Data columns (total 15 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 survived 891 non-null int64 1 pclass 891 non-null int64 2 sex 891 non-null object 3 age 714 non-null float64 4 sibsp 891 non-null int64 5 parch 891 non-null int64 6 fare 891 non-null float64 7 embarked 889 non-null object 8 class 891 non-null category 9 who 891 non-null object 10 adult_male 891 non-null bool 11 deck 203 non-null category 12 embark_town 889 non-null object 13 alive 891 non-null object 14 alone 891 non-null bool dtypes: bool(2), category(2), float64(2), int64(4), object(5)
memory usage: 80.7+ KB
None
survived 0
pclass 0
sex 0
age 177
sibsp 0
parch 0
fare 0
embarked 2
class 0
who 0
adult_male 0
deck 688
embark_town 2
alive 0
alone 0
dtype: int64
print(df.describe()) print(df.describe(include = 'object')) # 범주형 변수에 대한 통계정보
결과 survived pclass age sibsp parch fare
count 182.000000 182.000000 182.000000 182.000000 182.000000 182.000000
mean 0.675824 1.192308 35.623187 0.467033 0.478022 78.919735
std 0.469357 0.516411 15.671615 0.645007 0.755869 76.490774
min 0.000000 1.000000 0.920000 0.000000 0.000000 0.000000
25% 0.000000 1.000000 24.000000 0.000000 0.000000 29.700000
50% 1.000000 1.000000 36.000000 0.000000 0.000000 57.000000
75% 1.000000 1.000000 47.750000 1.000000 1.000000 90.000000
max 1.000000 3.000000 80.000000 3.000000 4.000000 512.329200 sex embarked who embark_town alive
count 182 182 182 182 182
unique 2 3 3 3 2
top male S man Southampton yes
freq 94 115 87 115 123
# 성별에 따른 생존률 print(df.groupby('sex')['survived'].mean() * 100) # 객실 등급에 따른 생존률 print(df.groupby('pclass')['survived'].mean() * 100) # 연령대별 생존률 print(df.groupby('age')['survived'].mean() * 100)
결과sex
female 93.181818
male 43.617021
Name: survived, dtype: float64 pclass
1 67.515924
2 80.000000
3 50.000000
Name: survived, dtype: float64 age
0.92 100.000000
1.00 100.000000
2.00 33.333333
3.00 100.000000
4.00 100.000000 ... 64.00 0.000000
65.00 0.000000
70.00 0.000000
71.00 0.000000
80.00 100.000000
Name: survived, Length: 63, dtype: float64
corr_data = df.select_dtypes(include=['number']).corr() # 숫자형 데이터만 추출하여 상관관계 분석 # 상관관계 시각화 plt.figure(figsize=(10, 6)) sns.heatmap(corr_data, annot=True, cmap='coolwarm', fmt=".2f", linewidths=0.5) plt.title("heatmap - titanic data") plt.show()
<img alt="titanic1" src="https://ejkiwi.github.io/lib/media/titanicplot_1.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 주요 변수들간의 상관관계 시각화 sns.pairplot(df[['survived', 'age', 'sibsp', 'fare']]) plt.show()
<br><img alt="titanic2" src="https://ejkiwi.github.io/lib/media/titanicplot_2.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">]]></description><link>2024-25_동계_모각코/20250202-모각코-활동-4회차.html</link><guid isPermaLink="false">2024-25_동계_모각코/20250202 모각코 활동 4회차.md</guid><pubDate>Sun, 02 Feb 2025 16:50:57 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/titanicplot_1.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/titanicplot_1.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[20250126 모각코 활동 3회차]]></title><description><![CDATA[오늘의 목표 : 넘파이, 차트 공부 및 구현 (넘파이와 맷플롯립과 짱친되기)Numerical Python : 파이썬에서 수치 계산을 빠르고 효율적으로 수행할 수 있도록 해주는 라이브러리.
( ?라이브러리 : 자주 쓰이는 코드들을 묶어놓은 도구상자. ex - PyTorch는 AI 모델을 만들 때 쓰는 도구상자같은것... )
빠른 연산 : C로 구현되어 있어 배열 연산 속도가 매우 빠르다
다차원 배열 지원 복잡한 데이터 표현이 가능해진다 ( 이미지 3D : 높이.너비.채널, 동영상 4D : 프레임 수.높이.너비.채널)
효율적인 연산이 가능해짐 -&gt; 100개의 2D이미지를 처한다고 쳤을 때, 일반 Python 리스트로는 구조가 복잡해지고 느려짐. 하지만 다차원 배열을 사용하면 연산이 단순하고 빨라짐. 다양한 함수
배열 연산이 간편 : 반복문 없이 배열 전체에 대해 한 번에 연산 수행 가능 ( 벡터화 연산 )
import numpy as np ( 보통은 np라는 이름으로 불러옴 )
# 1D 배열
a = np.array([1, 2, 3]) # 2D 배열
b = np.array([[1, 2, 3], [4, 5, 6]]) # 0으로 채워진 배열
c = np.zeros((3, 3)) # 1로 채워진 배열
d = np.ones((2, 4)) # 임의의 숫자로 초기화된 배열
e = np.full((2, 2), 7) # 연속된 숫자로 이루어진 배열
f = np.arange(0, 10, 2) # [0, 2, 4, 6, 8] # 균등 분할된 값
g = np.linspace(0, 1, 5) # [0. , 0.25, 0.5 , 0.75, 1.]
<img alt="배열 생성" src="https://ejkiwi.github.io/lib/media/numpy01.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">arr = np.array([[1, 2, 3], [4, 5, 6]]) print(arr.shape) # 배열 형태 (2, 3)
print(arr.ndim) # 차원 개수 (2D 배열이면 2)
print(arr.size) # 전체 요소 개수 (6)
print(arr.dtype) # 데이터 타입 (int32, float64 등)
<br><img alt="배열 속성 확인" src="https://ejkiwi.github.io/lib/media/numpy02.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 특정 요소 접근
print(arr[0, 1]) # 0번째 행, 1번째 열 (2) # 행, 열 슬라이싱
print(arr[1, :]) # 1번째 행 전체 [4, 5, 6]
print(arr[:, 2]) # 모든 행의 2번째 열 [3, 6, 9] # 범위 슬라이싱
print(arr[0:2, 1:3]) # 첫 두 행의 1~2번째 열 [[2, 3], [5, 6]]
<br><img alt="배열 인덱싱과 슬라이싱" src="https://ejkiwi.github.io/lib/media/numpy03.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">x = np.array([1, 2, 3])
y = np.array([4, 5, 6]) # 요소별 연산
print(x + y) # [5, 7, 9]
print(x * y) # [4, 10, 18]
print(x ** 2) # [1, 4, 9] # 스칼라와 연산
print(x + 10) # [11, 12, 13]
<br><img alt="배열 연산" src="https://ejkiwi.github.io/lib/media/numpy04.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">arr = np.array([3, 1, 4, 2]) # 합, 평균, 표준편차, 최댓값, 최솟값
print(np.sum(arr)) # 10
print(np.mean(arr)) # 2.5
print(np.std(arr)) # 표준편차
print(np.max(arr)) # 4
print(np.min(arr)) # 1 # 오름차순 정렬
print(np.sort(arr)) # [1, 2, 3, 4]
# 내림차순 정렬
print(np.sort(arr)[::-1]) # [4, 3, 2, 1]
<br><img alt="그 외 유용한 함수" src="https://ejkiwi.github.io/lib/media/numpy05.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">arr = np.array([[1, 2], [3, 4]]) # 배열 형태 변경
reshaped = arr.reshape(4, 1)
print(reshaped)
# [[1]
# [2]
# [3]
# [4]] # 전치 (Transpose)
print(arr.T)
# [[1 3]
# [2 4]] # 1차원으로 펼치기
flattened = arr.flatten()
print(flattened) # [1, 2, 3, 4]
<br><img alt="배열 변환" src="https://ejkiwi.github.io/lib/media/numpy06.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">Python에서의 데이터 시각화를 위한 라이브러리
다양한 시각화 제공 : 간단한 선 그래프, 막대 그래프, 히스토그램부터 복잡한 3D 그래프까지 다양한 시각화를 제공함.
보통 matplotlib.pyplot 모듈을 통해 그래프를 그림.
보통 import matplotlib.pyplot as plt plt라는 이름으로 불러옴.
# 데이터 x = [0, 1, 2, 3, 4, 5] y = [0, 2, 4, 6, 8, 10] # 선 그래프 시각화 plt.plot(x, y, label="y = 2x", color="blue", linestyle="--", marker="o") plt.title("Line Plot Example") # 그래프 제목 plt.xlabel("X-axis") # x축 이름 plt.ylabel("Y-axis") # y축 이름 plt.legend() # 범례 추가 plt.show() # 시각화
<br><img alt="선 그래프" src="https://ejkiwi.github.io/lib/media/matplotlib01.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 데이터 x = [1, 2, 3, 4, 5] y = [5, 7, 6, 8, 7] sizes = [100, 200, 300, 400, 500] # 산점도 시각화 plt.scatter(x, y, s=sizes, color="green", alpha=0.6) plt.title("Scatter Plot Example") # 제목 plt.xlabel("X-axis") # x축 이름 plt.ylabel("Y-axis") # y축 이름 plt.show() # 시각화
<br><img alt="산점도 그래프" src="https://ejkiwi.github.io/lib/media/matplotlib02.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 데이터 categories = ['A', 'B', 'C', 'D'] values = [3, 7, 8, 5] # 막대 그래프 시각화 plt.bar(categories, values, color="orange") plt.title("Bar Plot Example") # 제목 plt.xlabel("Categories") # x축 이름 plt.ylabel("Values") # y축 이름 plt.show() # 시각화
<br><img alt="막대 그래프" src="https://ejkiwi.github.io/lib/media/matplotlib03.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 데이터 data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 8, 9, 10] # 히스토그램 시각화 plt.hist(data, bins=5, color="purple", alpha=0.7) plt.title("Histogram Example") # 제목 plt.xlabel("Value Ranges") # x축 이름 plt.ylabel("Frequency") # y축 이름 plt.show() # 시각화
<br><img alt="히스토그램" src="https://ejkiwi.github.io/lib/media/matplotlib04.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 데이터 data = [ [2, 3, 5, 6, 8], # Group 1 [1, 4, 4, 5, 9], # Group 2 [3, 5, 7, 7, 10] # Group 3 ] # 박스 플롯 시각화 plt.boxplot(data, tick_labels=['Group 1', 'Group 2', 'Group 3']) ## tick_labels -&gt; 이전에는 labels로 쓰임 plt.title("Box Plot Example") # 제목 plt.ylabel("Values") # y축 이름 plt.show()
<br><img alt="박스 그래프" src="https://ejkiwi.github.io/lib/media/matplotlib05.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 데이터 labels = ['Apples', 'Bananas', 'Cherries', 'Mangoes'] sizes = [35, 25, 20, 20] # 파이 차트 시각화 plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140, colors=['red', 'yellow', 'pink', 'brown']) plt.title("Pie Chart Example") # 제목 plt.show() # 시각화
<br><img alt="원형 차트" src="https://ejkiwi.github.io/lib/media/matplotlib06.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 데이터 x = [1, 2, 3, 4, 5] y1 = [1, 2, 4, 8, 16] y2 = [1, 1, 2, 3, 5] # 면적 그래프 시각화 plt.fill_between(x, y1, color="skyblue", alpha=0.5, label="Area 1") plt.fill_between(x, y2, color="lightgreen", alpha=0.7, label="Area 2") plt.title("Area Plot Example") # 제목 plt.xlabel("X-axis") # x축 이름 plt.ylabel("Y-axis") # y축 이름 plt.legend() # 범례 추가 plt.show() # 시각화
<br><img alt="면적 그래프" src="https://ejkiwi.github.io/lib/media/matplotlib07.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 데이터 x = [1, 2, 3, 4, 5] y1 = [2, 4, 6, 8, 10] y2 = [1, 3, 5, 7, 9] # 다중 그래프 시각화 plt.subplot(1, 2, 1) # ( 1행 2열 )plt.plot(x, y1, color="blue", marker="o") # 첫 번째 그래프 plt.title("Graph 1") # 첫 그래프 이름 plt.subplot(1, 2, 2) plt.plot(x, y2, color="red", linestyle="--") # 두 번째 그래프 plt.title("Graph 2") # 두 번째 그래프 이름 plt.tight_layout() # 간격 조정 plt.show() # 시각화
<br><img alt="다중 그래프" src="https://ejkiwi.github.io/lib/media/matplotlib08.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"># 데이터 categories = ['A', 'B', 'C'] group1 = [3, 5, 7] group2 = [4, 6, 8] # 스택형 막대 그래프 시각화 plt.bar(categories, group1, label="Group 1", color="lightblue") plt.bar(categories, group2, bottom=group1, label="Group 2", color="orange") # 스택 쌓기 plt.title("Stacked Bar Plot Example") # 제목 plt.xlabel("Categories") # x축 이름 plt.ylabel("Values") # y축 이름 plt.legend() # 범례 추가 plt.show() # 시각화
<br><img alt="스택형 막대 그래프" src="https://ejkiwi.github.io/lib/media/matplotlib09.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">]]></description><link>2024-25_동계_모각코/20250126-모각코-활동-3회차.html</link><guid isPermaLink="false">2024-25_동계_모각코/20250126 모각코 활동 3회차.md</guid><pubDate>Sun, 26 Jan 2025 08:15:20 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/numpy01.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/numpy01.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[20250117 모각코 활동 2회차]]></title><description><![CDATA[오늘의 목표 : 자료구조 개념과 종류(리스트, 튜플, 집합, 딕셔너리) 공부 및 구현 여러가지 자료를 저장할 수 있는 데이터 구조체 &nbsp;[ , , ]
요소(value) : 리스트 내 데이터를 의미
인덱스(index) : 리스트 내 데이터의 주소
순서가 있는 데이터 구조 수정 가능 (mutable).
중복된 값을 허용.
my_list = [1, 2, 3, 4] # 리스트 생성
my_list.append(5) # 값 추가
my_list[0] = 10 # 값 수정
print(my_list) # [10, 2, 3, 4, 5]
수정이 불가능한, 여러가지 자료를 저장할 수 있는 데이터 구조체 ( , , )
순서가 있는 데이터 구조.
수정 불가능 (immutable).
중복된 값을 허용.
반복문에서 리스트보다 빠름
딕셔너리의 키가 될 수 있음
리스트와 튜플 서로 변환 가능
*&lt;주의&gt; 요소가 1개인 튜플은 요소의 끝에 반드시 쉼표(,) 추가
my_tuple = (1, 2, 3, 4) # 튜플 생성
# my_tuple[0] = 10 # 수정 불가능 (오류 발생)
print(my_tuple[1]) # 2
고유한 값들을 순서 없이 저장할 수 있는 데이터 구조체 { , , }
순서가 없는 데이터 구조 ( = 인덱스 접근 불가 )
중복된 값을 허용하지 않음.
수학의 집합 연산 가능 (합집합, 교집합 등).
리스트와 집합&nbsp;서로 변환 가능
my_set = {1, 2, 3, 3} # 중복된 값은 자동 제거
my_set.add(4) # 값 추가
print(my_set) # {1, 2, 3, 4}
키key를 기반으로 값value을 저장할 수 있는 데이터 구조체 { key:value, key:value, ..., key:value }
키-값 (key-value) 쌍으로 데이터를 저장.
키는 중복될 수 없으나, 값은 중복 가능.
순서는 유지
key는 변수로 지정 가능
my_dict = {"name": "Alice", "age": 25} # 딕셔너리 생성
my_dict["age"] = 26 # 값 수정
my_dict["city"] = "Seoul" # 새 키-값 추가
print(my_dict) # {'name': 'Alice', 'age': 26, 'city': 'Seoul'}
]]></description><link>2024-25_동계_모각코/20250117-모각코-활동-2회차.html</link><guid isPermaLink="false">2024-25_동계_모각코/20250117 모각코 활동 2회차.md</guid><pubDate>Fri, 17 Jan 2025 15:14:09 GMT</pubDate></item><item><title><![CDATA[명령어]]></title><description><![CDATA[
on branch main : 현재 main 브랜치에 존재함.
No commits yet : 아직 커밋한 파일이 없음.
nothing to commit : 현재 커밋할 파일이 없다.
working tree clean : 작업 트리도 수정 사항 없이 깨끗하다.
untracked files : 아직 한 번도 버전 관리가 안 된 파일 ( 한 번도 커밋되어본 적 없고 스테이지에도 올라오지 않은 파일 ) tracked files : 한 번 커밋하기 시작한 파일 ( 계속 추적해서 변경사항이 존재하게 됨 ) Changes to be committed : 앞으로 커밋될 것. new file : 새로운 파일
modified : 수정되었다. "warning: LF will be eplaced by CRLF in ~" 이라는 경고메시지가 나타나는데, 스테이징이 안 된것은 아님.
( 윈도우의 줄 바꿈 문자와 리눅스의 줄 바꿈 문자는 다름 -&gt; 윈도우에서 문서를 저장하면 줄이 바뀌는 자리에 눈에 보이지 않는 CR문자와 LF문자가 삽입됨 -&gt; 깃에서는 텍스트 문서의 CRLF문자를 LF문자로 자동 변환해서 커밋할 것이라는 의미임 ) -m : 커밋 메시지 추가( "-m" 을 입력하고 그 뒤에 메시지 입력 )
-a : git add를 함께 진행하겠음을 의미.
-am : git add를 하고, 커밋 메시지 추가 커밋 해시 ( (HEAD -&gt; MAIN) : 최신 버전이라는 뜻 )
작성자
버전 만든 날짜
커밋 메시지 -- stat : 커밋과 관련한 파일까지 함께 살펴보기 : 삭제됨 : 추가됨 ]]></description><link>git&amp;github/명령어.html</link><guid isPermaLink="false">git&amp;github/명령어.md</guid><pubDate>Sun, 05 Jan 2025 08:42:52 GMT</pubDate></item><item><title><![CDATA[git&github]]></title><link>git&amp;github/git&amp;github.html</link><guid isPermaLink="false">git&amp;github/git&amp;github.md</guid><pubDate>Sun, 05 Jan 2025 06:55:01 GMT</pubDate></item><item><title><![CDATA[백준]]></title><description><![CDATA[
<a data-href="문제 1011" href="백준/문제-1011.html" class="internal-link" target="_self" rel="noopener nofollow">문제 1011</a>
<br><a data-href="문제 14369" href="백준/문제-14369.html" class="internal-link" target="_self" rel="noopener nofollow">문제 14369</a>
<br><a data-href="문제 1931" href="백준/문제-1931.html" class="internal-link" target="_self" rel="noopener nofollow">문제 1931</a>
]]></description><link>백준/백준.html</link><guid isPermaLink="false">백준/백준.md</guid><pubDate>Sat, 04 Jan 2025 15:33:19 GMT</pubDate></item><item><title><![CDATA[백준 풀이]]></title><description><![CDATA[🌱<a data-tooltip-position="top" aria-label="https://solved.ac/profile/eonjikiwi" rel="noopener nofollow" class="external-link is-unresolved" href="https://solved.ac/profile/eonjikiwi" target="_self">백준 프로필</a>🌱열심히 풀었던 문제들/ 왕큰 깨달음을 얻었던 문제들을 정리해놓았다!!!!!!!!!!!!!]]></description><link>백준/백준-풀이.html</link><guid isPermaLink="false">백준/백준 풀이.md</guid><pubDate>Sat, 04 Jan 2025 15:28:47 GMT</pubDate></item><item><title><![CDATA[2024 cnu 2차 학습동아리]]></title><description><![CDATA[<a data-tooltip-position="top" aria-label="https://colab.research.google.com/drive/1n9Pjthb3W4q-MO891Ce_-y5Jh2uOw4uv?usp=sharing" rel="noopener nofollow" class="external-link is-unresolved" href="https://colab.research.google.com/drive/1n9Pjthb3W4q-MO891Ce_-y5Jh2uOw4uv?usp=sharing" target="_self">2024 cnu 2차 학습동아리 실습코드</a>]]></description><link>2024-cnu-2차-학습동아리/2024-cnu-2차-학습동아리.html</link><guid isPermaLink="false">2024 cnu 2차 학습동아리/2024 cnu 2차 학습동아리.md</guid><pubDate>Thu, 02 Jan 2025 09:04:05 GMT</pubDate></item><item><title><![CDATA[문제 1931]]></title><description><![CDATA[회의실 배정입력 : 첫째 줄에 회의의 수 N(1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N+1 줄까지 각 회의의 정보가 주어지는데 이것은 공백을 사이에 두고 회의의 시작시간과 끝나는 시간이 주어진다. 시작 시간과 끝나는 시간은 231-1보다 작거나 같은 자연수 또는 0이다.
출력 : 첫째 줄에 최대 사용할 수 있는 회의의 최대 개수를 출력한다.import sys
input = sys.stdin.readline case = []
for _ in range(int(input())): a = list(map(int,input().split())) case.append(a)
case.sort(key=lambda x: (x[0], x[1])) CASE = []
cAse = set()
c = len(cAse)
for _ in case: #어차피 시작시간도 같은데 끝시간이 더 긴건 필요업냠냠냠냠냠,,.. cAse.add(_[0]) if _[1] == _[0]: #시작하자마자끝나는건필요해... CASE.append(_) elif len(cAse) != c: #정렬한 뒤, 저장하는거니까... 시작시각이 같은 회의들 중 일찍끝나는것만 필요 c = len(cAse) CASE.append(_) result = 1
now = case[0]
for _ in case[1::]: if now[1] &gt; _[1]: #now보다 지금 _의 끝 시작이 더 작다? -&gt; 이녀석은 더 효율적인 회의임 얘 선택해야해.. 근데 회의 카운트 수를 높일 수는 없음. now = _ #그냥 now를 더 좋은 회의로 바꾸는거임. 3 100, 4 5인 경우에 해당.. elif now[1] &lt;= _[0]: #근데..? _의 시작시간이..? now의 끝나는 시작과 같다? -&gt; 이건 바로 회의 수 추가mood ~~ 완전 그 느낌임... if _[0] == _[1]: #시작시각과 끝 시각이 같은 경우. result += 1 #무조건 추가 else: result += 1 #추가하고 now = _ #현재 회의 바꾸고... print(result) 푼 방식은.. 주석과같다...~_~
]]></description><link>백준/문제-1931.html</link><guid isPermaLink="false">백준/문제 1931.md</guid><pubDate>Thu, 02 Jan 2025 08:57:47 GMT</pubDate></item><item><title><![CDATA[문제 14369]]></title><description><![CDATA[전화번호 수수께끼(Small)입력 : 첫 줄에 테스트케이스의 개수 T가 주어진다. 각 테스트케이스에는 상대방이 제시한 스트링 S가 주어진다. S는 영어 대문자로만 이루어져 있다.
1≤&nbsp;T&nbsp;≤ 100이고, S의 길이는 3 이상 20 이하이다. 모든 테스트케이스에는 유일한 해답이 있다.
출력 : 각 줄에 테스트케이스 번호 x와 전화번호 y를 Case # x: y의 형태로 출력한다.첫 시도 -&gt; 시간초과ZERO = [1,0,0,0,0,0,1,1,0,0,0,0,0,0,1]
ONE = [1,0,0,0,0,1,1,0,0,0,0,0,0,0,0]
TWO = [0,0,0,0,0,0,1,0,0,1,0,0,1,0,0]
THREE =[2,0,0,1,0,0,0,1,0,1,0,0,0,0,0]
FOUR = [0,1,0,0,0,0,1,1,0,0,1,0,0,0,0]
FIVE = [1,1,0,0,1,0,0,0,0,0,0,1,0,0,0]
SIX = [0,0,0,0,1,0,0,0,1,0,0,0,0,1,0]
SEVEN =[2,0,0,0,0,1,0,0,1,0,0,1,0,0,0]
EIGHT =[1,0,1,1,1,0,0,0,0,1,0,0,0,0,0]
NINE = [1,0,0,0,1,2,0,0,0,0,0,0,0,0,0]
NUMBER = [ ["0",ZERO], ["1", ONE], ["2", TWO], ["3", THREE], ["4", FOUR], ["5", FIVE], ["6", SIX], ["7", SEVEN], ["8", EIGHT], ["9",NINE] ]
ALPHABET = ['E', 'F', 'G', 'H', 'I', 'N', 'O', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Z'] def CASE(TEXT, ALPHABET = ALPHABET): result = [] for i in ALPHABET: result.append(TEXT.count(i)) return result def CLEAR_NUMBER(NUMBER = NUMBER, case = []): number = [] #전처리 for i in NUMBER: detect = 0 for j in range(15): if i[1][j] &gt; case[j]: detect = 1 break if detect == 0: number.append(i) case = [y-x for x,y in zip(i[1], case)] return number, case def ANSWER(case, number = NUMBER): answer = [] case = CASE(case) while True: if case == [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]: break number, case = CLEAR_NUMBER(number, case) for i in number: answer.append(i[0]) return answer answer = []
for i in range(int(input())): case = input() a = "" for j in sorted(ANSWER(case)): a += j answer.append(a) m = 1
for i in answer: print("Case "+"#"+str(m)+": "+i) m += 1
'E', 'F', 'G', 'H', 'I', 'N', 'O', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Z' 를 차례대로 묶어서, 해당 알파벳이 있으면 1, 없으면 0을 매겨주었다. 그리고 주어진 case에서, 해당되는 알파벳 부분을 전체에서 빼주는 작업을
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 이 될 때까지 반복해서
정답을 찾는 방법으로 작성했다.
CLEAR_NUMBER 함수는 NUMBER 리스트를 순회하면서 각 숫자의 패턴과 case를 비교하는데, 매 숫자마다 15개의 값을 비교하고, 이를 매번 갱신하며 반복적으로 수행하는 점이 시간을 많이 잡아먹었고.. case가 0으로 수렴하는 과정에서 반복 횟수가 많아지고, 내부적으로 CLEAR_NUMBER를 여러 번 호출하므로 시간이 크게 소요되어서 시간초과가 났을 것이다.
네 번째 시도from collections import Counter DIGITS = [ ["0", "Z", "ZERO"], ["2", "W", "TWO"], ["4", "U", "FOUR"], ["6", "X", "SIX"], ["8", "G", "EIGHT"], ["3", "H", "THREE"], ["5", "F", "FIVE"], ["7", "V", "SEVEN"], ["1", "O", "ONE"], ["9", "I", "NINE"],
] def solve_case(case): case_count = Counter(case) result = [] for digit, unique_char, word in DIGITS: count = case_count[unique_char] if count &gt; 0: result.extend([digit] * count) for char in word: case_count[char] -= count return "".join(sorted(result)) # 입력 처리
t = int(input())
answers = []
for i in range(t): case = input().strip() answers.append(f"Case #{i + 1}: {solve_case(case)}") print("\n".join(answers))
그냥 아예 각 알파벳이 고유하게 가지고 있는 문자열을 비교해서 빼주는 방식으로 진행했다.
["1", "O", "ONE"] 같은 경우 "O"가 "ZERO"에도 있고 "TWO"에도 있고 "FOUR" 에도 있기 때문에 문제가 될 거 같지만 애당초 "ZERO"는 유일한 "Z"에 의해 다 걸러지게 되고, 마찬가지로 "TWO"는 "W"에, "FOUR"는 "U"에 걸러지게 되므로 상관 없다.
from collections import Counter를 사용해서 시간을 줄였다.
]]></description><link>백준/문제-14369.html</link><guid isPermaLink="false">백준/문제 14369.md</guid><pubDate>Thu, 02 Jan 2025 08:54:49 GMT</pubDate></item><item><title><![CDATA[문제 1011]]></title><description><![CDATA[Fly me to the Alpha Centauri입력 : 입력의 첫 줄에는 테스트케이스의 개수 T가 주어진다. 각각의 테스트 케이스에 대해 현재 위치 x 와 목표 위치 y 가 정수로 주어지며, x는 항상 y보다 작은 값을 갖는다. (0 ≤ x &lt; y &lt; 231)
출력 : 각 테스트 케이스에 대해 x지점으로부터 y지점까지 정확히 도달하는데 필요한 최소한의 공간이동 장치 작동 횟수를 출력한다.case = []
for i in range(int(input())): d, e = map(int,input().split()) case.append([d, e, e-d]) result = []
for i in case: r = 0 count = 0 m = 0 while True: m += 1 r += m count += 1 if i[2] &lt;= r: result.append(count) break r += m count += 1 if i[2] &lt;= r: result.append(count) break for i in result: print(i) r: 누적 이동 거리
count: 이동 횟수
m: 현재 단계에서 한 번에 이동할 수 있는 거리
이동 거리는 1부터 시작하며, 매 단계마다 1, 2, 3, ... 식으로 증가.(같은 거리만큼 두 번 반복)
11 22 33 44 55 66 77 88 99 1010 1111 1212 1313 1414 ,,, -&gt; 개수 12 34 56 78 910 ,,,, -&gt; 횟수의 수 구간의 크기가 순서대로 1부터 20까지 있다고 하면, 그 구간에 따른 정답은 -&gt; 1 2 33 44 555 666 7777 8888이 됨. * (예) 구간의 크기가 8이면 정답은 5가 됨. / 구간의 크기가 10이면 정답은 6이 됨.
]]></description><link>백준/문제-1011.html</link><guid isPermaLink="false">백준/문제 1011.md</guid><pubDate>Thu, 02 Jan 2025 08:39:47 GMT</pubDate></item><item><title><![CDATA[2024_하계_모각코]]></title><description><![CDATA[
<a data-href="모.구.모.구 모각코 활동" href="2024_하계_모각코/모.구.모.구-모각코-활동.html" class="internal-link" target="_self" rel="noopener nofollow">모.구.모.구 모각코 활동</a>
<br><a data-href="20240707 모각코 활동 1회차" href="2024_하계_모각코/20240707-모각코-활동-1회차.html" class="internal-link" target="_self" rel="noopener nofollow">20240707 모각코 활동 1회차</a>
<br><a data-href="20240709 모각코 활동 2회차" href="2024_하계_모각코/20240709-모각코-활동-2회차.html" class="internal-link" target="_self" rel="noopener nofollow">20240709 모각코 활동 2회차</a>
<br><a data-href="20240716 모각코 활동 3회차" href="2024_하계_모각코/20240716-모각코-활동-3회차.html" class="internal-link" target="_self" rel="noopener nofollow">20240716 모각코 활동 3회차</a>
<br><a data-href="20240723 모각코 활동 4회차" href="2024_하계_모각코/20240723-모각코-활동-4회차.html" class="internal-link" target="_self" rel="noopener nofollow">20240723 모각코 활동 4회차</a>
<br><a data-href="20240730 모각코 활동 5회차" href="2024_하계_모각코/20240730-모각코-활동-5회차.html" class="internal-link" target="_self" rel="noopener nofollow">20240730 모각코 활동 5회차</a>
<br><a data-href="20240806 모각코 활동 6회차" href="2024_하계_모각코/20240806-모각코-활동-6회차.html" class="internal-link" target="_self" rel="noopener nofollow">20240806 모각코 활동 6회차</a>
<br><a data-href="20240813 모각코 활동 7회차" href="2024_하계_모각코/20240813-모각코-활동-7회차.html" class="internal-link" target="_self" rel="noopener nofollow">20240813 모각코 활동 7회차</a>
]]></description><link>2024_하계_모각코/2024_하계_모각코.html</link><guid isPermaLink="false">2024_하계_모각코/2024_하계_모각코.md</guid><pubDate>Sun, 01 Dec 2024 08:02:21 GMT</pubDate></item><item><title><![CDATA[모.구.모.구 모각코 활동]]></title><description><![CDATA[팀 모각코 목표 : 1. 절대 포기하지 않기, 2. 모르는 거 그냥 넘어가지 않기나의 모각코 활동 다짐 : 활동 계획을 완벽히 마무리 할 수 있도록 노력하겠습니다!나의 모각코 활동 계획
7월 7일 모각코 활동 동안 공부할 주제 전체적으로 톺아보기, 팀원들과 친해지기 7월 9일, 7월 16일 파이토치 사용 익히기
선배님 프로젝트의 레포지토리에 있는 코드 분석해보며 공부하기 7월 23일, 7월 30일, 8월 6일, 8월 13일 CNN 구조 공부하기
RESNET 구조 공부하기 모각코 팀블로그
<a data-tooltip-position="top" aria-label="https://jolly-exoplanet-ef1.notion.site/1868305015324f9f84670142f4029fb7" rel="noopener nofollow" class="external-link is-unresolved" href="https://jolly-exoplanet-ef1.notion.site/1868305015324f9f84670142f4029fb7" target="_self">모.구.모.구_팀블로그</a>]]></description><link>2024_하계_모각코/모.구.모.구-모각코-활동.html</link><guid isPermaLink="false">2024_하계_모각코/모.구.모.구 모각코 활동.md</guid><pubDate>Tue, 26 Nov 2024 17:34:04 GMT</pubDate></item><item><title><![CDATA[20240813 모각코 활동 7회차]]></title><description><![CDATA[오늘의목표
RESNET 실습 - CIFAR10 이미지 분류
양자화 공부#필요한 모듈 불러오기 import torch
import torch.nn as nn #다양한 종류의 레이어 제공 -&gt; 모델 만들기 도우미!
import torch.nn.functional as F #활성화 함수, 손실함수 등을 함수 형태로 제공.
import torch.backends.cudnn as cudnn
모델링#BasicBlock 클래스 정의 class BasicBlock(nn.Module): # nn.Module 상속받기 def __init__(self, in_planes, planes, stride = 1): super(BasicBlock, self).__init__() #BasicBlock의 부모클래스인 nn.Module의 __init__함수를 먼저 호출해서 사용. #conv1과 conv2 설정 #2D 컨볼루션 레이어 설정 self.conv1 = nn.Conv2d(in_planes, planes, kernel_size = 3, stride = stride, padding = 1, bias = False) # in_planes 입력채널 수 / planes 출력채널 수 / kernel_size 3*3 필터(커널) 사용 / stride (커널로 훑을 때의 보폭) 기본값은 1 / padding 패딩의 크기 1 / bias = False 바이어스(출력값을 조절하기 위해 사용되는 값) 를 사용하지 않겠다. -&gt; 바로 다음 줄의 코드(배치정규화)에서 바이어스의 역할을 해주기 때문에 여기에선 사용하지 않는다. #배치 정규화 설정 self.bn1 = nn.BatchNorm2d(planes) # planes 배치정규화를 적용할 채널의 수. 앞의 출력 채널의 수와 동일해야함(당연함) #2D 컨볼루션 레이어 설정 self.conv2 = nn.Conv2d(planes, planes, kernel_size = 3, stride = 1, padding = 1, bias = False) #배치 정규화 설정 self.bn2 = nn.BatchNorm2d(planes) # shortcut 설정 -&gt; `H(x) = R(x) + x`에서의 x를 위한 작업 self.shortcut = nn.Sequential() # nn.Sequential : pytorch에서 여러 레이어들을 순서대로 쌓을 때 사용하는 도구 # x를 그대로 더할 수 있는 경우 if stride != 1: #stride의 값이 1인경우(입력과 출력의 채널 수가 다른 경우 = x를 그대로 더할 수 없는 경우) self.shortcut = nn.Sequential( nn.Conv2d(in_planes, planes, kernel_size = 1, stride = stride, bias = False), nn.BatchNorm2d(planes) ) # nn.Sequential을 사용해서 Conv2d와 BatchNorm레이어들을 이어줬음 #순전파 함수 # __init__에서 설정해뒀던 거 실제로 사용하는 부분. def forward(self,x): out = F.relu(self.bn1(self.conv1(x))) #conv1 거치고, relu함수 거치기 out = self.bn2(self.conv2(out)) #그다음 conv2 거치기 out += self.shortcut(x) # resnet의 핵심인 skip connection : H(x) = R(x) + x
#ResNet 클래스 정의 class ResNet(nn.Module): def __init__(self, block, num_blocks, num_classes = 10): super(ResNet, self).__init__() #ResNet의 부모클래스인 nn.Module의 __init__함수를 먼저 호출해서 사용. self.in_planes = 64 # 입력 채널 수 64 # 2D 컨볼루션레이어 설정 self.conv1 = nn.Conv2d(3, 64, kernel_size = 3, stride = 1, padding = 1, bias = False) # 입력채널 수 3 / 출력채널 수 64 / kernel_size 3*3 필터(커널) 사용 / stride (커널로 훑을 때의 보폭) 1 / padding 패딩의 크기 1 / bias = False 바이어스(출력값을 조절하기 위해 사용되는 값) 를 사용하지 않겠다. # 배치정규화 설정 self.bn1 = nn.BatchNorm2d(64) # 배치정규화를 위해 사용할 채널 수 = 이전 채널에서의 출력 채널 수 = 64 # 레이어블록 설정(각 블록은 앞서 정의한 BASIC BLOCK으로 구성될거임. 인자 block 자리에, BasicBlock이 들어갈거니까아아아~~) # _make_layer() : (블록의 종류, 출력 채널 수, 쌓을 블럭의 수, 레이어의 첫 블럭에서 사용할 stride의 값) self.layer1 = self._make_layer(block, 64, num_blocks[0], stride = 1) # self.layer2 = self._make_layer(block, 128, num_blocks[1], stride = 2) self.layer3 = self._make_layer(block, 256, num_blocks[2], stride = 2) # self._make_layer()에서 self는 현재 클래스의 인스턴스를 가리킴. # 클래스 예측값 계산 self.linear = nn.Linear(512, num_classes) # 입력 채널 수 512, 출력 채널 수 num_classes # _make_layer 함수 설정 def _make_layer(self, block, planes, num_blocks, stride): strides = [stride] + [1] * (num_blocks -1) # stride 값 설정 # 첫 번째 블록의 stride는 지정된 값을 사용하고 이후 블럭들은 stride = 1이 된다. layers = [] # 블럭을 담을 빈 리스트 생성 for stride in strides: layers.append(block(self.in_planes, planes, stride)) # 입력 채널 수 self.in_planes, 출력 채널 수 planes, 스트라이드 값 stride self.in_planes = planes # 채널 수 변경해주기(다음 레이어를 위해) return nn.Sequential(*layers) # 생성한 블록들을 하나의 레이어로 묶어서 반환. # 순전파 함수 # __init__ 설정해뒀던거랑 _make_layer 함수 만든 거 실제로 사용하는 부분. def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.layer1(out) out = self.layer2(out) out = self.layer3(out) out = self.layer4(out) out = F.avg_pool2d(out, 4) # 풀링층 out = out.view(out.size(0),-1) # 텐서의 차원 변경 out = self.linear(out) #완전 연결층 return out
# ResNet 18 함수 정의 def ResNet18(): return ResNet(BasicBlock, [2,2,2,2])
데이터 불러오기import torchvision
import torchvision.transforms as transforms transform_train = transforms.Compose([
&nbsp; &nbsp; transforms.RandomCrop(32, padding=4),
&nbsp; &nbsp; transforms.RandomHorizontalFlip(),
&nbsp; &nbsp; transforms.ToTensor(),
]) transform_test = transforms.Compose([
&nbsp; &nbsp; transforms.ToTensor(),
]) train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True, num_workers=2)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=100, shuffle=False, num_workers=2) 학습시키기device = 'cuda'
net = ResNet18()
net = net.to(device)
learning_rate = 0.1
file_name = 'resnet18_cifar10.pth'
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=learning_rate, momentum=0.9, weight_decay=0.0002) def train(epoch):
&nbsp; &nbsp; print('\n[ Train epoch: %d ]' % epoch)
&nbsp; &nbsp; net.train()
&nbsp; &nbsp; train_loss = 0
&nbsp; &nbsp; correct = 0
&nbsp; &nbsp; total = 0 &nbsp; &nbsp; for batch_idx, (inputs, targets) in enumerate(train_loader):
&nbsp; &nbsp; &nbsp; &nbsp; inputs, targets = inputs.to(device), targets.to(device)
&nbsp; &nbsp; &nbsp; &nbsp; optimizer.zero_grad() &nbsp; &nbsp; &nbsp; &nbsp; outputs = net(inputs)
&nbsp; &nbsp; &nbsp; &nbsp; loss = criterion(outputs, targets)
&nbsp; &nbsp; &nbsp; &nbsp; loss.backward() &nbsp; &nbsp; &nbsp; &nbsp; optimizer.step()
&nbsp; &nbsp; &nbsp; &nbsp; train_loss += loss.item()
&nbsp; &nbsp; &nbsp; &nbsp; _, predicted = outputs.max(1) &nbsp; &nbsp; &nbsp; &nbsp; total += targets.size(0)
&nbsp; &nbsp; &nbsp; &nbsp; current_correct = predicted.eq(targets).sum().item()
&nbsp; &nbsp; &nbsp; &nbsp; correct += current_correct
&nbsp; &nbsp; &nbsp; &nbsp; if batch_idx % 100 == 0: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('\nCurrent batch:', str(batch_idx))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('Current batch average train accuracy:', current_correct / targets.size(0))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('Current batch average train loss:', loss.item() / targets.size(0)) &nbsp; &nbsp; print('\nTotal average train accuarcy:', correct / total)
&nbsp; &nbsp; print('Total average train loss:', train_loss / total) def test(epoch):
&nbsp; &nbsp; print('\n[ Test epoch: %d ]' % epoch)
&nbsp; &nbsp; net.eval()
&nbsp; &nbsp; loss = 0
&nbsp; &nbsp; correct = 0
&nbsp; &nbsp; total = 0 &nbsp; &nbsp; for batch_idx, (inputs, targets) in enumerate(test_loader):
&nbsp; &nbsp; &nbsp; &nbsp; inputs, targets = inputs.to(device), targets.to(device)
&nbsp; &nbsp; &nbsp; &nbsp; total += targets.size(0) &nbsp; &nbsp; &nbsp; &nbsp; outputs = net(inputs)
&nbsp; &nbsp; &nbsp; &nbsp; loss += criterion(outputs, targets).item() &nbsp; &nbsp; &nbsp; &nbsp; _, predicted = outputs.max(1)
&nbsp; &nbsp; &nbsp; &nbsp; correct += predicted.eq(targets).sum().item() &nbsp; &nbsp; print('\nTotal average test accuarcy:', correct / total)
&nbsp; &nbsp; print('Total average test loss:', loss / total) &nbsp; &nbsp; state = {
&nbsp; &nbsp; &nbsp; &nbsp; 'net': net.state_dict()
&nbsp; &nbsp; }
&nbsp; &nbsp; if not os.path.isdir('checkpoint'):
&nbsp; &nbsp; &nbsp; &nbsp; os.mkdir('checkpoint')
&nbsp; &nbsp; torch.save(state, './checkpoint/' + file_name)
&nbsp; &nbsp; print('Model Saved!') import time def adjust_learning_rate(optimizer, epoch):
&nbsp; &nbsp; lr = learning_rate
&nbsp; &nbsp; if epoch &gt;= 50:
&nbsp; &nbsp; &nbsp; &nbsp; lr /= 10
&nbsp; &nbsp; if epoch &gt;= 100:
&nbsp; &nbsp; &nbsp; &nbsp; lr /= 10
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for param_group in optimizer.param_groups:
&nbsp; &nbsp; &nbsp; &nbsp; param_group['lr'] = lr start_time = time.time() for epoch in range(0, 150):
&nbsp; &nbsp; adjust_learning_rate(optimizer, epoch)
&nbsp; &nbsp; train(epoch)
&nbsp; &nbsp; test(epoch)
&nbsp; &nbsp; print('\nTime elapsed:', time.time() - start_time) 양자화 공부
양자화 : 실수형 변수(floating-point type)를 정수형 변수(integer or fixed point)로 변환하는 과정
양자화 하는 이유 : 인공지능 모델에 큰 비트수의 자료형을 사용 -&gt; 학습 과정에서 계산량과 필요한 메모리 크기 등이 커지게 됨. -&gt; 학습을 시키기 위해 많은 리소스가 필요해지고, 추론도 오래 걸리는 문제가 발생. 양자화를 통하여 효과적인 모델 최적화를 할 수 있는데, float 타입을 int형으로 줄이면서 용량을 줄일 수 있고 bit 수를 줄임으로써 계산 복잡도도 줄일 수 있음
Pipeline
-HuggingFace의 가장 기본 기능으로, 자연어 처리 작업, inference(추론)을 빠르게 할 수 있게 해준다.
-(hugging face에 대한 내용은 처음 보낸 코랩 파일 가장 위에 있으니 더 알아보고싶으시면 참고하시면 됩니다!)
-pretrained model(사전학습 모델)을 사용하는 가장 쉬운 방법.
-사전학습모델이란 : 예를 들어 텍스트 유사도 예측 모델을 만들기 위해서, 감정 분석 문제를 학습했던 모델의 가중치를 활용하는 방법. 즉, 감정 분석 문제를 학습하면서 얻은 언어에 대한 이해를 텍스트 유사도 문제를 학습하는 데 활용하는 방식이다.
pipeline(task, model, config, tokenizer, feature_extractor, framework, revision, use_fast, use_auth_token, model_kwargs, pipeline_class, kwargs) 매개변수 설명**
-task : 어떤 작업을 할것인가? -&gt; 여기에서는 'text-generation' 텍스트 생성 작업을 할거임. ( 그 외 question-answering, translation 등등이 있음 ) 이건 pipeline을 사용할 때 꼭 지정해주어야 함. 나머지것들은 기본으로 지정된 것들이 있기 때문에 따로 필요한 경우만 지정해주면 됨.
-model : 어떤 모델을 사용할것인가? -&gt; 여기에서는 "meta-llama/Meta-Llama-3-8B-Instruct" 라는 hugging face에서 미리 가져온 모델을 사용.
-device map : 모델이 어디서(GPU 또는 CPU) 실행되어야할까? -&gt; 여기에서는 "auto" 로, 현재 기기에서 사용가능한 장소를 자동으로 감지하고, GPU가 있다면 이를 우선적으로 사용
-model_kwargs : 추가로 전달할 매개변수(예를 들어 특정 설정을 변경하는 경우 사용) -&gt; 여기에서는 {"quantization_config": quantization_config} 이라는 quantization(양자화) 에 대한 설정을 포함하구 있음.#준비
!pip install bitsandbytes # 양자화 기법을 사용할 수 있게 해주는 파이썬 모듈 다운로드
!pip install -U bitsandbytes
from transformers import pipeline, BitsAndBytesConfig # BitsAndBytesConfig 허깅페이스에서 양자화를 위한 라이브러리 #허깅페이스 로그인("meta-llama/Meta-Llama-3-8B-Instruct"를 사용하기 위함)
from huggingface_hub import login
login("내 TOKEN") #양자화 옵션 설정
#4bit로 되어있긴 하지만, 8bit도 가능. quantization_config = BitsAndBytesConfig(load_in_4bit=True) &nbsp;# You can also try load_in_8bit
pipe = pipeline("text-generation", "meta-llama/Meta-Llama-3-8B-Instruct", device_map="auto", model_kwargs={"quantization_config": quantization_config}) #양자화 한 후 실행
chat = [
&nbsp; &nbsp; {"role": "system", "content": "You are a sassy, wise-cracking robot as imagined by Hollywood circa 1986."},
&nbsp; &nbsp; {"role": "user", "content": "Hey, can you tell me any fun things to do in New York?"}
]
response = pipe(chat, max_new_tokens=512)
print(response[0]['generated_text'][-1]['content'])
chat.append(
&nbsp; &nbsp; {"role": "user", "content": "Wait, what's so wild about soup cans?"}
)
response = pipe(chat, max_new_tokens=512)
print(response[0]['generated_text'][-1]['content']) ]]></description><link>2024_하계_모각코/20240813-모각코-활동-7회차.html</link><guid isPermaLink="false">2024_하계_모각코/20240813 모각코 활동 7회차.md</guid><pubDate>Wed, 25 Sep 2024 07:11:10 GMT</pubDate></item><item><title><![CDATA[20240806 모각코 활동 6회차]]></title><description><![CDATA[오늘의목표
CNN 실습 - MNIST 이미지 분류 ( RESNET은 7회차에 진행할 예정 )import torch #pytorch 가져오기
데이터 가져오기#데이터셋불러오고 텐서로 바꿔주기 from torchvision import datasets #데이터셋 불러오고 from torchvision.transforms import ToTensor #텐서로 바꿔주기 #datasets에서 MNIST 가져와서 훈련데이터와 테스트데이터 가져와주기. #datasets.MNIST(root - 데이터가 저장될 경로, train - train이 true 이면 train data이고 false면 test data, download - 데이터 없으면 인터넷에서 다운로드해줌 , transform - transform을 ToTensor로 지정해주지 않으면 텐서의 형식이 아닌, PIL이미지로 데이터가 가져와지게 된다) train_data = datasets.MNIST( &nbsp; &nbsp; root = "data", &nbsp; &nbsp; train = True, #train data를 다운로드 &nbsp; &nbsp; transform = ToTensor(), &nbsp; &nbsp; download = True ) test_data = datasets.MNIST( &nbsp; &nbsp; root = 'data', &nbsp; &nbsp; train = False, #test data를 다운로드 &nbsp; &nbsp; transform = ToTensor() )
데이터 확인하기#학습데이터 확인 print(train_data) print(train_data.data.size()) # 데이터셋의 이름은 MNIST # 데이터의 수는 60000개 # 훈련데이터 # StandardTransform(데이터셋에 일관되게 적용되는 변환의 표준을 정의) -&gt; Transform: ToTensor() #이미지 데이터들을 모두 일관되게 텐서 형태로 변환하겠다는 것을 의미. #테스트데이터 확인 print(test_data) print(test_data.data.size()) #데이터의 수가 10000 인 것과 테스트데이터라는 것을 제외하면 나머지 속성은 학습데이터와 동일함.
#데이터 시각적으로 확인 import matplotlib.pyplot as plt #시각적 확인을 위해 matplotlib을 사용. fig, ax = plt.subplots() # fig -&gt; 데이터가 담기는 프레임 / ax -&gt; 실제 데이터가 그려지는 캔버스 ax.imshow(train_data.data[0], cmap='gray') #데이터의 모습 #이미지 위에 각 픽셀 값을 표시해서 나타내보기 for i in range(train_data.data[0].shape[0]): # i와j는 텍스트를 표시할 위치를 지정하기 위함. &nbsp; for j in range(train_data.data[0].shape[1]): &nbsp; &nbsp; c = 1 if train_data.data[0][i, j].item() &lt; 125 else 0 # 이미지의 각 픽셀 값( train_data.data[0][i,j].item() )이 125보다 작으면 c = 1 흰색을 사용, 크면 c = 0 검정 사용. &nbsp; &nbsp; ax.text(j, i, str(train_data.data[0][i, j].item()), color=(c, c, c), ha='center', va='center', fontsize=5) # text()를 사용하여 이미지 위에 텍스트 그리기 plt.title("%i" % train_data.targets[0]) plt.show
<img alt="mnist_1" src="https://ejkiwi.github.io/lib/media/MNIST.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">데이터 준비하기from torch.utils.data import DataLoader
# DataLoader -&gt; &nbsp;데이터를 미니배치 형태로 만들어서 우리가 실제로 학습할 때 이용할 수 있도록 함.
#DataLoader(dataset 데이터 , batch_size=1 한 번의 배치 안에 있는 샘플 사이즈, shuffle=False 데이터셋을 섞어서 데이터가 학습되는 순서를 바꿈, num_workers=0 동시에 처리하는 프로세서의 수. 하나 더 추가하면 20%정도 속도가 빨라짐.)
#배치 학습 -&gt; 전체 데이터를 n등분 하여 학습. loaders = { &nbsp; &nbsp; 'train' : torch.utils.data.DataLoader(train_data, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; batch_size=100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shuffle=True, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num_workers=1), &nbsp; &nbsp; 'test' : torch.utils.data.DataLoader(test_data, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;batch_size=100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;shuffle=True, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;num_workers=1) } loaders
CNN 모델 설정하기class CNN(torch.nn.Module): &nbsp; def __init__(self): &nbsp; &nbsp; super(CNN, self).__init__() &nbsp; &nbsp; self.layer1 = torch.nn.Sequential( &nbsp; &nbsp; &nbsp; &nbsp; torch.nn.Conv2d(1, 16, kernel_size=5, stride=1, padding=2), #컨볼루션 레이어(합성곱층) #1차원(1개채널) 데이터를 받아 16개의 feature(16개의채널)로 나누겟다!!임. &nbsp; &nbsp; &nbsp; &nbsp; torch.nn.ReLU(), #ReLU층 &nbsp; &nbsp; &nbsp; &nbsp; torch.nn.MaxPool2d(kernel_size=2, stride=2)) #풀링층 &nbsp; &nbsp; self.layer2 = torch.nn.Sequential( &nbsp; &nbsp; &nbsp; &nbsp; torch.nn.Conv2d(16, 32, kernel_size=5, stride=1, padding=2), &nbsp; &nbsp; &nbsp; &nbsp; torch.nn.ReLU(), &nbsp; &nbsp; &nbsp; &nbsp; torch.nn.MaxPool2d(kernel_size=2, stride=2))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; # layer 1, layer2 층까지는 이미지를 형상으로 분할하고 분석하는 부분
&nbsp; &nbsp; &nbsp; &nbsp; # 다음 fc 층에서는 이미지를 분류 예측하는 부분.
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.fc = torch.nn.Linear(32 * 7 * 7, 10, bias=True) #32*7*7만큼의 입력을 linear레이어에 의해 계산되게 해서... 10개의 출력( MNIST 이미지를 0부터 9까지 분류해야하기때문 )이 나오도록 함. &nbsp; &nbsp; torch.nn.init.xavier_uniform_(self.fc.weight) # 신경망의 가중치를 초기화 ( 신경망의 가중치를 학습 전에 적절한 값으로 설정하는 과정 ) &nbsp; &nbsp; # __init__에서는 필요한 레이어들을 정의내렸다고 볼 수 있음.
&nbsp; &nbsp; # 아래 forward(얘가 실제적인 모델의 형태가 됨)에서 사용한다. &nbsp; def forward(self, x): #순전파 #순전파만 지정해주어도 pytorch에서는 역전파 과정을 매우 쉽게 할 수 있도록 해준다. &nbsp; &nbsp; out = self.layer1(x) &nbsp; &nbsp; out = self.layer2(out) &nbsp; &nbsp; out = out.view(out.size(0), -1) # view() 함수는 텐서의 크기를 변경하는 데 사용 # 데이터를 완전 연결(fc) 층에 전달하기 위해 2차원 또는 3차원 텐서를 1차원 벡터로 평탄화 하는 과정이 필요함.
&nbsp; &nbsp; out = self.fc(out) &nbsp; &nbsp; return out
model = CNN() model
CNN(
(layer1): Sequential(
(0): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(layer2): Sequential(
(0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(fc): Linear(in_features=1568, out_features=10, bias=True)
)학습하기learning_rate = 0.01 # 파라미터를 얼마나 업데이트할 것인지를 결정. 학습률, step size. 너무 크지도 작지도 않아야 함. loss_func = torch.nn.CrossEntropyLoss() # 모델 예측과 실제값 간의 차이를 측정하는 손실함수. optimizer = &nbsp;torch.optim.Adam(model.parameters(), lr=learning_rate) # 손실함수를 통해 나온 을 최소화하기 위해 가중치를 업데이트하는 방법 training_epochs = 10 # 전체 데이터셋을 몇 번 반복할 것인지 결정.
# 반복의 횟수는 epoch과 batch의 크기에 따라 결정 total_batch = len(loaders['train']) for epoch in range(training_epochs): &nbsp; avg_cost = 0 &nbsp; for X, Y in loaders['train']: &nbsp; &nbsp; optimizer.zero_grad() # 학습에서, 역전파를 거칠 때 마다 각 .grad 값에 변화도가 저장이 되는데, 이어지는 다음 학습에서 .grad의 값을 0으로 초기화시켜주지 않으면 이전에 저장된 변화도 값이 다음 학습에 영향을 주기 때문에 원하는 방향으로 학습하기 힘들다. 그래서zero_grad를 통해 .grad 의 값들을 0으로 초기화시켜준다. &nbsp; &nbsp; pred = model(X) #순전파 &nbsp; &nbsp; cost = loss_func(pred, Y) #손실함수계산 &nbsp; &nbsp; cost.backward() #역전파 &nbsp; &nbsp; optimizer.step() # 역전파 단계에서 수집된 변화도로 매개변수를 조정 &nbsp; &nbsp; avg_cost += cost / total_batch &nbsp; print('[Epoch: {:&gt;4}] cost = {:&gt;.9}'.format(epoch + 1, avg_cost))
&nbsp; # `epoch + 1` 값을 최소 4칸의 너비로 오른쪽 정렬하여 출력
&nbsp; # `avg_cost` 값을 최소 9자리까지 나타내어 오른쪽 정렬하여 출력 print('Learning Finished....&gt;_&lt;')
[Epoch: 1] cost = 0.0461711548
[Epoch: 2] cost = 0.0472225286
[Epoch: 3] cost = 0.0413064063
[Epoch: 4] cost = 0.0417594947
[Epoch: 5] cost = 0.0395734794
[Epoch: 6] cost = 0.0441303253
[Epoch: 7] cost = 0.0408433564
[Epoch: 8] cost = 0.043582622
[Epoch: 9] cost = 0.0441764817
[Epoch: 10] cost = 0.0412645154
Learning Finished....&gt;_&lt;]]></description><link>2024_하계_모각코/20240806-모각코-활동-6회차.html</link><guid isPermaLink="false">2024_하계_모각코/20240806 모각코 활동 6회차.md</guid><pubDate>Wed, 07 Aug 2024 13:56:13 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/MNIST.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/MNIST.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[20240730 모각코 활동 5회차]]></title><description><![CDATA[오늘의목표
1.cnn공부 - 합성곱 계층에서의filter, Padding에 대해 더 알아보기.
2.resnet공부 - Residual Block과 Skip-Connection 에 대해 더 깊이 알아보기합성곱 계층에서의 filter
CNN에서 filter는 커널(n * m의 행렬)와 같은 의미이다. (mask라고도 불린다.)
filter를 사용하는 이유는 사진에서 feature(특징)를 뽑아내기 위함이다.
입력 데이터의 전체 이미지에서, filter를 통해 천제 이미지를 순환하며, 특정 filter모양과 일치할수록 더 큰 값을 가지게 될 것인데, 이는 전체 이미지서 특정 filter와 유사한 모양을 가진 부분에 대한 feature들만 얻게 된다는 것을 의미한다. =&gt; 특정 filter에 부합하는 feature정보를 얻는 과정.
Padding
cnn구조에서, 합성곱층을 지나게 되면, 합성곱 연산으로 인해서 Feature Map의 크기는 입력데이터보다 크기가 작아지게 된다. 이렇게 크기가 작아지는것을 피하기 위해서 Padding 이라는 방법을 사용할 수 있다.
zero padding : 입력 데이터(이미지) 주위를 0으로 둘러주는 padding의 방법이다.
<img alt="zero padding" src="https://ejkiwi.github.io/lib/media/zero_Padding.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"> P : padding layer의 수
n : 이미지의 크기가 n * n
f : 커널의 크기(filter의 크기)가 f * f
(n+2p) * (n+2p) : 패딩된 이미지의 크기
((n + 2p – f + 1) * (n + 2p – f + 1)) : 합성곱층을 지난 출력 이미지의 크기 padding이 필요한 이유 이미지 데이터의 축소를 막을 수 있다. - 여러번의 계산을 거쳐야 하는데 초반부터 이미지가 너무 작아져버린다면 학습을 별로 하지 못하고 끝나버릴 수 있기 때문에 padding을 통해 이미지의 크기를 조절해줘야한다.
모서리에 있는 중요한 정보를 충분히 활용할 수 있다. - padding을 사용하지 않는 경우, 모서를 학습할 기회가 적어지게 된다. 만약 중요한 정보가 모서리쪽에 있다면, 모델의 성능이 떨어지기 때문에 padding을 사용하여 모서리의 정보들도 충분히 학습할 수 있도록 해주어야 한다.<br>
<img alt="패딩과 모서리~" src="https://ejkiwi.github.io/lib/media/CNN_Padding_Edge.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved"> Valid Padding과 Same Padding : 각각 순서대로 패딩하지 않는 것, 입력데이터와 출력데이터가 동일하도록 하는 패딩을 뜻한다.
Residual Block 과 Skip-Connection
Residual Block은 층이 깊어지더라도 성능이 뒤떨어지지 않게 하기 위해 제시된 것.
Residual 은 "잔여" 라는 뜻을 가지고 있는데, x를 입력 H(x)를 x의 분포로 가정하면 residual은 최종으로 구하고자 하는 H(x)와 x의 차이로 볼 수 있다.
즉, Residual = R(x) = H(x) - x 가 되며 H(x) = R(x) + x 로 정리가능하다. <br><img alt="residualblock" src="https://ejkiwi.github.io/lib/media/residual%20block.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">
위 신경망층에서는 F(x)r가 R(x)의 역할을 하기 때문에 Residual Block이라 불리게 된다.
Residual Block은 그레디언트 소실 문제를 약화시키고, 이에 따라 신경망의 깊이가 깊어져도 성능이 떨어지지 않게 되는 것.
그레디언트 소실 문제 신경망을 학습시는 과정에서 -&gt; 역전파 알고리즘을 통해 출력층에서 입력층으로 손실함수에 대한 그레디언트를 전파하고, 경사 하강법을 통해 이 그레디언트를 사용하여 각 파라미터를 수정하는 단계를 거치게 됨.
이 때 신경망의 하위층으로 진행될수록 그레디언트가 점점 작아지게 되는 문제가 그레디언트 소실 문제이다.
residual block에서는 x, x+1, x+2 층이 있다고 할 때, x+2층은 x+1층뿐만 아니라 x로부터도 정보를 받을 수 있게 된다. 따라서 역전파 알고리즘이 실행될 때 그레디언트가 작아지는것을 어느정도 막아주는 효과가 발생한다.
이러한 residual block의 방식을 하나의 합성곱층을 기준으로 살펴보았을 때,
한 층의 입력값을 출력값과 합쳐서 다음 층으로 넘겨주는 방식이 그 층의 입력값이 해당 층을 통과하지 않고 다음 층으로 넘어가는 것과 같기 때문에 Skip Connection이라 부르게 되는 것이다.
즉, Residual Block의 핵심은 Skip Connection이라 할 수 있다. ]]></description><link>2024_하계_모각코/20240730-모각코-활동-5회차.html</link><guid isPermaLink="false">2024_하계_모각코/20240730 모각코 활동 5회차.md</guid><pubDate>Wed, 31 Jul 2024 12:40:41 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/zero_Padding.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/zero_Padding.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[20240716 모각코 활동 3회차]]></title><description><![CDATA[오늘의 목표
1.파이토치 공부하기 - 실습해보기
2.선배님의 프로젝트 코드 절반 분석하기 - resnet 부분파이토치 실습import torch #파이토치 불러오기
from torch import nn #토치에서 nn 불러오기 #텐서 형태로 train데이터 가져오기
x_train = torch.Tensor([1,2,3,4,5,6]).view(6,1)
y_train = torch.Tensor([3,6,9,12,15,18]).view(6,1) #MyNeuralNetwork 클래스 만들기. nn.Module이 부모클래스가 됨.
class MyNeuralNetwork(nn.Module):
&nbsp; def __init__(self):
&nbsp; &nbsp; super().__init__()
&nbsp; &nbsp; self.linear_relu_stack = nn.Sequential(nn.Linear(1,1)) &nbsp; def forward(self, x):
&nbsp; &nbsp; logits = self.linear_relu_stack(x)
&nbsp; &nbsp; return logits #모델
model = MyNeuralNetwork()
#손실함수
loss_function = nn.MSELoss()
#옵티마이저
optimizer = torch.optim.SGD(model.parameters(),lr=1e-2) nums_epoch = 2000 #학습시키기
for epoch in range(nums_epoch + 1):
&nbsp; prediction = model(x_train)
&nbsp; loss = loss_function(prediction, y_train) &nbsp; optimizer.zero_grad()
&nbsp; loss.backward()
&nbsp; optimizer.step() &nbsp; if epoch % 100 == 0:
&nbsp; &nbsp; print('epoch = ', epoch, 'current loss = ', loss.item())
#예측하기
x_test = torch.Tensor([8,9,10,11]).view(4,1)
pred = model(x_test)
pred
선배님의 프로젝트 코드from huggingface_hub import hf_hub_download
import wespeaker
from huggingface_hub import hf_hub_download
huggingface_hub 라이브러리를 통해서 hf_hub_download함수를 가져와준다.
hf_hub_download함수를 통해서 모델을 다운로드 할 수 있다.
기본적으로, 함수에는 repo_id와 repo_type을 인자로 넘겨준다. (revision - 특정 버전의 파일을 다운로드 하고 싶을 시. / local_dir 특정 위치에 저장하고 싶을 시.)
import wespeaker
wespeaker을 가져와준다. def get_resnet152(): model_id = "Wespeaker/wespeaker-voxceleb-resnet152-LM" model_name = model_id.replace("Wespeaker/wespeaker-", "").replace("-", "_") root_dir = hf_hub_download(model_id, filename=model_name+".onnx").replace(model_name+".onnx", "") import os if not os.path.isfile(root_dir+"avg_model.pt"): os.rename(hf_hub_download(model_id, filename=model_name+".pt"), root_dir+"avg_model.pt") if not os.path.isfile(root_dir+"config.yaml"): os.rename(hf_hub_download(model_id, filename=model_name+".yaml"), root_dir+"config.yaml") resnet = wespeaker.load_model_local(root_dir) #print("Compile model for the NPU") #resnet.model = intel_npu_acceleration_library.compile(resnet.model) def resnet152(ado, sample_rate=None): if isinstance(ado, str): return resnet.recognize(ado) else: return recognize(resnet, ado, sample_rate) resnet152.__dict__['register'] = lambda *args, **kwargs: resnet.register(*args, **kwargs) return resnet152
분석
def get_resnet152():
get_resnet 152 라는 이름의 함수를 정의model_id = "Wespeaker/wespeaker-voxceleb-resnet152-LM"
model_id라는 변수에 "Wespeaker/wespeaker-voxceleb-resnet152-LM"를 지정. 아마 모델 아이디에 모델의 이름을 저장한 것일 것.moldelname = model.id.replace("Wespeaker/wespeaker-",").replace("-", " ")
model_name이라는 변수를 만들어서, model_id를 약간 변형시킨 이름으로 지정해줌. "voxceleb_resnet152_LM"이 될 것.root_dir = hf_hub_download(model_id, filename = model_name+" .onnx").replace(model_name+" .onnx", "")
hf_hub_download : huggingface_hub 라이브러리를 통해서 가져왔던 함수. 함수를 사용해서 모델 파일을 다운로드하고, 다운로드한 파일을 root_dir에 저장함.import os
os 모듈을 가져옴
os 모듈 : 파일 및 디렉토리 작업, 프로세스 및 스레드 관리, 시스템 정보와 관련한 작업들을 수행할 수 있는 모듈이다.if not os.path.isfile(root_dir+"avg_model.pt"):
os.rename(hf_hub_download(model_id, filename=model_name+".pt"), root_dir+"avg_model.pt")
만약 avg_model.pt이름을 가진 파일이 없다면, 모델의 pt파일을 다운로드 한 뒤 이름을 avg_model.pt로 바꾸어서 root_dir 변수에 저장함.
os.path.isfile(path) : path가 파일인 경우 true를 리턴, 아니면 false를 리턴.
os.rename : 파일 또는 폴더의 이름을 간단히 변경할 수 있다.if not os.path.isfile(root_dir+"config.yaml"):
os.rename(hf_hub_download(model_id, filename=model_name+".yaml"), root_dir+"config.yaml")
앞 코드와 같은 느낌인데, 만약 config.yaml파일이 없으면 모델의 yaml파일을 다운로드 한 뒤 이름을 바꾸어서 root_dir변수에 저장함.resnet = wespeaker.load_model_local(root_dir)
resnet이라는 변수를 지정해줄건데, wespeaker 라이브러리의 load_model_local 함수를 사용할거임. 이 때 root_dir에 있는 파일들을 불러오게 됨.def resnet152(ado, sample_rate=None):
if isinstance(ado, str):
return resnet.recognize(ado)
else:
return recognize(resnet, ado, sample_rate) resnet152라는 함수를 정의해주는데, 이 함수는 입력으로 ado를 받음.
instance(객체, 타입) : isinstance함수는 지정된 객체(여기에서는 ado)가 지정된 타입이면 true를 반환하고 아니면 false를 반환한다.
ado가 문자열이라면 resnet.recognize(ado)를 리턴하고
그렇지 않다면 recognize(resnet, ado, sample_rate)을 리턴함.(recognize함수는 이전에 지정해둔 함수이다.)def recognize(model, pcm, sample_rate): q = extract_embedding(model, pcm, sample_rate) best_score = 0.0 best_name = '' for name, e in model.table.items(): score = model.cosine_similarity(q, e) if best_score &lt; score: best_score = score best_name = name del score gc.collect() return {'name': best_name, 'confidence': best_score}
resnet152.__dict__['register'] = lambda *args, **kwargs: resnet.register(*args, **kwargs)
resnet152라는 함수에 register라는 기능을 추가(대체?)
lambda함수를 통해서 resnet152에서 register메서드를 사용하려고 할 때, resnet객체의 register 메서드를 가져와서 사용하게 된다.
args, kwargs : 몇 개의 인자를 받아야 할지 정할 수 없을 때 args와 kwargs(keyword arguments)를 파라미터로 써줌. args 앞에 붙는 * 는 여러개의 인자를 묶어서 하나의 튜플로 묶어주고 이를 args에 할당해준다. kwargs 앞에 붙는 ** 는 여러개의 키워드 아규먼트들을 묶어서 딕셔너리로 만들어준다. return resnet152
get_resnet152라는 함수는 resnet152를 반환함.resnet152 = get_resnet152()
print("INFO: ResNet152 Ready -", resnet152)
분석
resnet152 = get_resnet152()
get_resnet152함수를 가져와서 resnet152함수에 저장함
print("INFO: ResNet152 Ready -", resnet152)
모델이 준비되었다는 메시지를 출력한 뒤, resnet152를 출력함.]]></description><link>2024_하계_모각코/20240716-모각코-활동-3회차.html</link><guid isPermaLink="false">2024_하계_모각코/20240716 모각코 활동 3회차.md</guid><pubDate>Tue, 30 Jul 2024 04:01:59 GMT</pubDate></item><item><title><![CDATA[20240723 모각코 활동 4회차]]></title><description><![CDATA[오늘의목표
1.cnn공부 - 정의와 구조 살펴보기
2.resnet공부 - 정의와 구조 살펴보기딥 러닝 : 심층 신경망을 주로 다루는 ai분야. 심층 신경망은 신경망을 여러 계층으로 구성한 것.
기존 신경망의 큰 단점 : 입력 데이터의 구조 고려 안 함. -&gt; 이미지와 같은 공간적 구조를 가지는 데이터 다루기 적합하지 않음.
기존 신경망에서의 단점(공간적 구조 데이터 다루기 어려움)을 극복하기 위해 cnn 등장CNN
합성곱 신경망
-2차원 구조를 고려하는 신경망
-가중치와 바이어스로 이루어진 뉴런으로 구성
- 입력데이터를 받고, 처리한 후 특정한 결과를 출력함.
-입력 계층에 들어온 미가공 이미지 데이터에 해당하는 클래스를 예측하는 것이 목적.
-예측된 클래스는 출력 계층의 결과 값 형태(클래스 점수 변환됨)로 출력됨.
-계층의 종류
1. 입력층
- 미가공 이미지 데이터를 받음.
2. 합성곱층
- 합성곱 연산을 수행함.
- 커널(n m의 행렬)로 이미지(높이 너비)를 처음부터 끝까지 겹쳐 훑는다. 겹쳐지는 부분의 각 이미지와 원소의 값을 곱해서 모두 더한 값을 출력함.
- 스트라이드 : 커널이 입력을 훑는데, 이 때의 보폭을 뜻함.
- 이 때 출력되는 것(입력으로부터 커널을 사용하여 합성곱 연산을 통해 나온 결과)은 '출력 특성 맵(output feature map)' 이라 함.
- CNN에서는 합성곱 계층의 입출력 데이터를 특성 맵(feature map) 이라 함.
- <img alt="cnn 연산 방법" src="https://ejkiwi.github.io/lib/media/cnn1.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">
3.ReLU층
- 인공신경망에서 사용되는 활성화함수 f(x) = max(0, x) -&gt; 입력값이 0보다 크면 그 값을 그대로 출력하고, 0 이하면 0을 출력.
4. 풀링층
- 특성 맵을 다운샘플링하여 특성 맵의 크기를 줄임.
- 합성곱 연산과 유사함 (커널과 스트라이드 개념이 존재)
- 최대풀링 : 커널과 겹치는 영역 안에서 최대값을 추출
- 평균풀링 : 커널과 겹치는 영역 안에서 평균값을 추출RESNET
CNN의 한 종류
-신경망의 깊이가 깊어짐에 따라 발생하는 훈련 문제를 해결하기 위해 '잔여학습'이라는 개념을 도입함.
- 훈련 문제 : 기존 모델들은 레이어를 깊게 쌓을수록 더 성능이 좋아질 것이라고 예상했지만 실제로는 20층 이상부터 성능이 낮아지는 현상이 발생.
- 잔여학습 : 스킵연결(입력값이 일정층들을 건너뛰어서 출력에 더할 수 있게 하는 역할) -&gt; 기존신경망은 k번째 층과 (i+1)번째 층의 연결로 이루어져있는데, resnet은 (i+r)층의 연결을 허용(shortcut connection).<br>
- <img alt="ResNet 구조" src="https://ejkiwi.github.io/lib/media/resnet.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">
-최대 152개 층까지 쌓을 수 있게 됨.<br>
<img alt="cnn2" src="https://ejkiwi.github.io/lib/media/cnn2.png" referrerpolicy="no-referrer" target="_self" class="is-unresolved">]]]></description><link>2024_하계_모각코/20240723-모각코-활동-4회차.html</link><guid isPermaLink="false">2024_하계_모각코/20240723 모각코 활동 4회차.md</guid><pubDate>Tue, 23 Jul 2024 13:38:23 GMT</pubDate><enclosure url="https://ejkiwi.github.io/lib/media/cnn1.png" length="0" type="image/png"/><content:encoded>&lt;figure&gt;&lt;img src="https://ejkiwi.github.io/lib/media/cnn1.png"&gt;&lt;/figure&gt;</content:encoded></item><item><title><![CDATA[20240707 모각코 활동 1회차]]></title><description><![CDATA[오늘의 목표
1.모각코 활동 동안 공부할 주제 전체적으로 톺아보기
2.팀원들과 친해지기파이토치
python을 바탕으로 제작된, 딥러닝과 인공지능 분야에서 주로 활용되는 라이브러리
pytorch의 연산은 tensor를 기본으로 하여 작동
tensor : 파이토치의 기본 데이터 타입. 배열이나 행렬과 유사한 구조(다차원 배열)이다.
파이토치를 기반으로 구성된 모델은 학습을 위한 그래디언트를 자동으로 계산한다. -&gt; 자동 미분
그래디언트 : 벡터 미분의 결과 (=함수의 기울기, 각 변수에 대한 변화율)
선배님의 프로젝트
<a data-tooltip-position="top" aria-label="https://github.com/b-re-w/2024-1_BPL_STalk_Model_Research" rel="noopener nofollow" class="external-link is-unresolved" href="https://github.com/b-re-w/2024-1_BPL_STalk_Model_Research" target="_self">2024-1_BPL_STalk_Model_Research</a>
CNN 모델
2차원 데이터 (이미지 등)의 패턴을 인식하고 분석하는 데 사용되는 딥러닝 모델.
여러개의 층으로 구성됨.
인간의 시신경 구조를 모방한 구조임
이미지의 RESNET 모델
CNN 모델에 잔차 연결 개념을 도입한 것.
잔차 연결 : 각 층의 출력을 다음 층으로 직접 보내는 대신에, 입력을 더한 뒤 다음 층으로 전달하는 연결.
]]></description><link>2024_하계_모각코/20240707-모각코-활동-1회차.html</link><guid isPermaLink="false">2024_하계_모각코/20240707 모각코 활동 1회차.md</guid><pubDate>Mon, 15 Jul 2024 07:48:10 GMT</pubDate></item><item><title><![CDATA[20240709 모각코 활동 2회차]]></title><description><![CDATA[오늘의 목표
1.파이토치 공부하기 - youtube에 있는 파이토치 설명 강좌(<a rel="noopener nofollow" class="external-link is-unresolved" href="https://youtube.com/playlist?list=PLS8gIc2q83Oit-utRso2iblvt00fZOw85&amp;si=i0CZi4e5g_dVJ3dx" target="_self">https://youtube.com/playlist?list=PLS8gIc2q83Oit-utRso2iblvt00fZOw85&amp;si=i0CZi4e5g_dVJ3dx</a>) 1,2,3강 들으며 공부
2.선배님의 프로젝트 코드 절반 분석하기 - whisper 부분파이토치
al분야에서 google tensorflow와 함께 딥러닝 모델을 구축하고 학습하는 데 가장 많이 사용되고 있는 오픈 소스 기반의 딥러닝 프레임워크임.
오픈소스 : 개방형 협업을 장려하는 소프트웨어 개발 모델
프레임워크 : 소프트웨어 개발에 있어 하나의 뼈대와 같은 역할을 하는 것으로, 목적에 필요한 것을 고민할 필요 없이 이용할 수 있도록 일괄로 가져다 쓰도록 만들어 놓은 구조화된 틀임.
텐서 : 파이토치의 기본 데이터 타입
배열이나 행렬과 유사한 자료 구조이다
일반적으로는 1차원 - 벡터 , 2차원 - 행렬, 3차원 이상 - 벡터 이지만, 파이토치에서는 입력과 출력 그리고 학습에 필요한모든 데이터들을 모두 텐서 데이터타입으로 정의하고 있다.
텐서의 속성으로는 모양,자료형,저장되는 위치가 있다
보통 저장되는 위치는 cpu인데, gpu를 사용할 수 있다면, .to("cuda")를 사용해서 텐서를 gpu로 이동시킬 수 있다. gpu : 컴퓨터 그래픽을 처리하는 장치로 그래픽 카드를 구성하는 가장 중요한 핵심 요소. 1.파이썬의 리스트 데이터로부터 직접 텐서를 만들 수 있다.
- listdata = [[10,20],[30,40]] tensor1 = torch.Tensor(listdata)`
2.파이썬의 넘파이 데이터로부터 직접 텐서를 만들 수도 있다.(넘파이로만들어진건 보통 int로 생성되기때문에 원래 데이터가 float의 형태인 경우, 캐스팅해주는 작업이 필요하기도 하다.)
3.파이썬의 랜덤 데이터로부터 직접 텐서를 만들 수도 있다.
- tensor3 = torch.rand(2,2) -&gt; rand()메서드는 0~1사이의 균일 분포 랜덤값을 생성함 ( randn()메서드는 정규분포를 가지는 랜덤값을 생성 )
텐서를 넘파이로 바꿀 수도 있다.
- tensor.numpy()
인덱싱과 슬라이싱이 가능하다
elment-wise product 연산 matrix multiplication 연산 (행렬곱)
텐서를 합칠 수 있다. Tensor Concatenate (dim=0 세로, dim=1 가로)
파이토치 딥러닝 모델 구조 :
1.데이터정의
- 기본 데이터타입인 TENSOR로 생성해야함.
- TensorDataset(x_train,y_train) : 텐서 데이터셋 생성
- DataLoader(dataset, batch_size, shuffle) : 미니 배치 학습과 데이터 셔플, 멀티 프로세싱 등을 간단하게 수행할 수 있음.
- 미니 배치 학습 : 전체 데이터를 n등분 하여 각각의 학습 데이터를 배치 방식으로 학습시키는 것.
- 데이터 셔플 : train데이터와test데이터 간의 동일한 분포를 가지도록 섞어는 것.
- 멀티 프로세싱 : 여러 작업을 별도의 프로세스를 생성 후 병렬처리를 하는 과정을 거치기 때문에 더 빠르게 결과를 얻을 수 있다.
2.모델구축
- nn.Module을 상속받는 class를 생성하여 정의하는 것이 일반적이다.
- 클래스 속 __init__함수에서 계층(신경망 모델을 구성하는)을 정의.
- 클래스 속 forward 함수에서 신경망에 데이터 전달하기를 수하고, 결과값을 리턴함
3.피드포워드
- 모델 학습을 위해서는 피드 포워드 계산값과 정답의 차이 계산이 필요 -&gt; 이 계산을 위해서는 손실함수와 옵티마이저가 필요함.
- 손실함수 : MSE 등
- 옵티마이저 : SDG, ADAM
4.손실함수계산
- nn.MSELoss(model(x_train),y_train) : 피드포워드 계산 값과 정답과의 오차 계산.
- 이 때, model에 데이터를 전달하면 model 클래스 안에 있는 forward()함수자동으로 forward()함수를 호출하기 때문에 우리가 따로 호출해줄 필요가 없다.
5.모델학습
-역전파 코드 : 학습이 진행됨에 따라서 모델 파라미터(가중치와 바이어스)를 업데이트하면서 최적화 시킨다
- optimizer.zero.grad()
- loss.backward()
- optimizer.step() 모델(model) : 각 층을 포함하고 있는 인공신경망 그 자체 (이를 레고처럼 순차적으로 쌓기 -&gt; CNN, RNN 등 다양한 모델 구축 가능) 3&gt;4&gt;5의 반복 -&gt; 딥러닝 학습
손실함수가 최소가 될 때까지 모델 파라미터(가중치, 바이어스) 값을 찾아감. 선배님 프로젝트 분석 - whisper
1.from faster_whisper import WhisperModel
2.def get_whisper() : 3. model_size = "medium" #@param ['tiny', 'base', 'small', 'medium', 'large', 'large-v2', 'large-v3'] 4. compute_type = "int8" #@param ['float16', 'int8']
5. return WhisperModel(model_size, device=DEVICE, cpu_threads=12, compute_type=compute_type).transcribe1: faster_whisper 에서 WhisperModel 모듈 불러오기
2: get_whisper 라는 이름의 함수 설정하기
3: model_size는 "medium"이다. model_size가 가질 수 있는 옵션으로는 "tiny","base","small","medium","large","large-v3" 이 있다. -&gt; model_size는 모델의 크기를 뜻한다.
4: compute_type은 "int8"이다. compute_type이 가질 수 있는 옵션으로는 "float16","int8"이 있다. -&gt; compute_type은 계산 유형을 뜻한다.
5: WhisperModel은 4가지의 매개변수를 사용하는데, 여기에서 model_size는 앞서 정한 크기와 같고, device는 모델이 실행될 장치를 지정한다. cpu_threads는 CPU의 스레드 수를 뜻한다. compute_type또한 앞서 정한 계산 유형과 같다. 이 때 .transcribe는 모델의 음성 인식 기능을 호출해서 음성을 텍스트로 변환해준다.]]></description><link>2024_하계_모각코/20240709-모각코-활동-2회차.html</link><guid isPermaLink="false">2024_하계_모각코/20240709 모각코 활동 2회차.md</guid><pubDate>Mon, 15 Jul 2024 06:27:57 GMT</pubDate></item></channel></rss>