📍 시험 장소 및 일정

  • 시험일: 2026년 5월 17일 (일)
  • 시험장: 인천 바이오과학고등학교
  • 입실: 09:30 / 시험 시작: 10:00

🎯 ADSP를 딴 이유

학교에 CS포인트 제도가 있어서 IT 자격증을 취득하면 장학금으로 전환할 수가 있는데 이번년도 취득한것만 해당이 돼서 이미 취득해 놓은 정보처리기사,SQLD는 해당이 안되어 자격증을 찾다가 공기업에도 도움이 되면서도 제일 만만해 보였던 ADsP를 고르게 되었다. 그런데 4학년이다 보니 졸업작품·사이드 프로젝트·수업을 병행하면서 자연스럽게 우선순위가 밀려 결국 시험 3일 전에야 책을 펼쳤다.


📚 공부 방법

개념서는 거의 보지 않고 밀리의 서재에서 문제집 한 권을 골라 기출 위주로 공부했다. 유튜브 인강과 기출 해설 해놓은 블로그가 도움이 많이 되었다. 데이터 사이언스 수업에서 쌓은 배경지식도 도움이 됐다. 총 순 공부 시간은 3일 동안 약 10시간 정도 된 것 같다.

과목공부 방법체감 난이도
1과목 기출 4~5개년 무난
2과목 기출 4~5개년 무난
3과목 개념서 부분 정독 → 기출 복습 어려움

1,2과목은 전공자라면 시간을 많이 할애 하지 않아도 될 것 같았다. 기출문제를 풀다 보니 유형이 정해져 있었다. 하지만 3과목은 1과목, 2과목에 비해 비중이 제일 크고 범위도 넓었다.  그나마 데이터 사이언스 과목에서 배웠던 내용들이 좀 포함 되어 있어서 그나마 괜찮았지만  R언어와 낯선 통계 용어가 많아서 끝까지 자신이 없었다. 결국 "1·2과목에서 점수를 최대한 확보해서 3과목을 커버하자" 전략으로 시험장에 들어갔다.

💡 기출 5개년 반복이 단기간 준비에는 가장 효율적이었다.


📊 시험 결과

시험을 다 풀고 남은 시간에 확신 없는 답들만 추려 셀프 채점해보니 60~70점 사이가 나왔다. 그래도 혹시 몰라 다시 재검토 하면서 시험시간 끝나기 5분전까지 풀다가 시험장을 나왔다.

그리고 오늘 사전 점수 결과가 나왔고 66점으로 합격!

혹시 몰라 걱정 많이 했는데 5만 원 접수비도 안 날리고 CS점수까지 얻을 수 있게 됐다.


💬 총평

기출 5개년 + 관련 수업 배경지식이 있다면 전공자는 시간을 많이 할애하지 않아도 될 것 같다는 생각이 들었다. 다만 3과목(R, 통계 용어)은 시간 여유가 있을 때 개념을 먼저 훑는 걸 추천한다.

 

실습 3주차, 이번 주는 현대 AI의 근간이 된 Transformer(트랜스포머) 아키텍처를 논문을 이해하는 것을 목표로 삼았습니다. 단순히 라이브러리를 사용하는 것을 넘어, 내부 연산의 흐름과 설계 의도를 파고든 기록을 남깁니다.

1. Transformer: 왜 'Attention'만으로 충분한가?

기존 NLP의 표준이었던 RNN(Recurrent Neural Networks)은 문장을 단어 단위로 한 단계씩 순차적으로 처리했습니다. 하지만 이러한 방식은 두 가지 치명적인 병목 현상을 야기했습니다.

❶ 순차적 연산의 한계 (Sequential Bottleneck)

RNN은 t 시점의 연산을 하기 위해 t-1 시점의 결과가 반드시 필요합니다. 이는 최신 GPU의 강점인 병렬 연산(Parallel Computing)을 원천적으로 차단하여, 모델이 커질수록 학습 시간이 기하급수적으로 늘어나는 결과를 초래했습니다.

❷ 정보 소실 (Vanishing Gradient & Long-term Dependency)

문장이 길어질수록 앞부분의 정보가 뒷부분까지 전달되지 못하고 흐릿해지는 문제가 있었습니다. LSTM과 GRU가 이를 보완하려 했으나, 수백 단어 이상의 긴 문맥(Context)을 완벽히 유지하기엔 역부족이었습니다.

❸ 트랜스포머의 해법: "모든 단어를 동시에 보라"

트랜스포머는 '순서'라는 개념을 연산 순서에서 분리해냈습니다.

  • Self-Attention: 문장 내의 모든 단어 쌍(Pair) 간의 관계를 한 번에 계산합니다. "The animal didn't cross the street because it was too tired"라는 문장에서 'it'이 무엇을 가리키는지 찾을 때, RNN처럼 앞의 단어를 다 거쳐오는 것이 아니라 'it'과 'animal'의 유사도를 즉각적으로 계산해버리는 방식입니다.
  • Positional Encoding: 순차 연산을 없애면서 사라진 '단어의 위치 정보'를 보완하기 위해 도입되었습니다. 단어 임베딩에 사인(Sine)과 코사인(Cosine) 함수 기반의 고유 위치 값을 더해주어, 모델이 "이 단어는 문장의 앞에 있다"는 것을 수학적으로 인지하게 만듭니다.

결과적으로, 트랜스포머는 모든 정보를 한 번에(Global Context) 보면서도 병렬 처리가 가능해졌고, 이를 통해 훨씬 거대한 데이터를 빠른 속도로 학습할 수 있게 되었습니다. 이것이 바로 논문 제목이 "Attention이면 충분하다(Attention Is All You Need)"인 이유입니다.


2. 핵심 메커니즘: Scaled Dot-Product Attention

트랜스포머의 성능은 결국 "입력 데이터 중 어디에 집중(Attention)할 것인가"를 수학적으로 얼마나 잘 표현하느냐에 달려 있습니다. 그 수식이 바로 아래의 공식입니다.

이 수식이 왜 이렇게 설계되었는지, 각 구성 요소의 역할을 깊이 있게 분석해 보았습니다.

❶ Query, Key, Value의 역할극

단순히 데이터를 넣는 것이 아니라, 데이터를 세 가지 목적에 맞게 투영(Projection)합니다.

  • Query (질문): "현재 내가 처리 중인 이 단어와 관련된 정보가 어디에 있지?"
  • Key (색인): "나는 이런 정보를 가지고 있어. 네 질문과 얼마나 일치하니?"
  • Value (값): "일치한다면, 내가 가진 이 실제 정보를 줄게."

❷ Dot-product (QK^T): 관계의 수치화

질문(Q)과 색인(K)을 내적(Dot-product)하는 과정입니다. 두 벡터가 유사한 방향을 향할수록 내적값은 커집니다. 즉, 단어 사이의 연관성(Similarity)을 점수로 환산하는 단계입니다. 이 점수가 높을수록 해당 단어의 정보를 더 많이 가져오게 됩니다.

❸ Scaling ($\frac{1}{\sqrt{d_k}}): 왜 굳이 나누는가?

이 부분이 설계의 핵심입니다.

  • 문제점: 모델의 차원(d_k)이 커질수록 내적값(QK^T)의 절댓값도 기하급수적으로 커질 가능성이 높습니다.
  • 결과: 내적값이 너무 커지면 softmax 함수를 통과할 때 출력값이 0 또는 1에 극단적으로 치우치게 됩니다.
  • 치명적 단점: 소프트맥스 그래프의 끝부분에서는 기울기(Gradient)가 거의 0에 수렴하여, 기울기 소실(Vanishing Gradient) 문제가 발생하고 학습이 멈춰버립니다.
  • 해결: 이를 방지하기 위해 차원의 크기인 sqrt{d_k}로 나누어(Scaling) 값의 범위를 조절함으로써 학습의 안정성을 확보한 것입니다.

❹ Multi-Head Attention: 앙상블의 지혜

논문에서는 이 연산을 한 번만 하는 것이 아니라, 여러 개의 'Head'로 나누어 병렬로 수행합니다.

  • 한 Head는 '문법적 관계'에 집중하고,
  • 다른 Head는 '의미적 관계'에 집중하며,
  • 또 다른 Head는 *먼 거리의 맥락'에 집중합니다.
  • 이렇게 나온 서로 다른 결과들을 하나로 합침으로써(Concatenate), 모델은 문장을 다각도에서 입체적으로 이해할 수 있게 됩니다.

3. Encoder vs Decoder: 닮은 듯 다른 두 엔진

트랜스포머 아키텍처는 정보를 압축하는 인코더와 이를 바탕으로 새로운 정보를 생성하는 디코더의 협업 시스템입니다. 두 엔진은 겉보기엔 비슷하지만, 정보를 다루는 '태도'에서 결정적인 차이가 있습니다.

❶ Encoder: 양방향 문맥의 마스터 (Bidirectional Context)

인코더의 역할은 입력받은 문장을 완벽하게 이해하는 것입니다.

  • Self-Attention: 인코더 내에서는 모든 단어가 서로를 자유롭게 바라봅니다. 예를 들어 "사과가 맛있다"라는 문장에서 '사과'를 처리할 때 '맛있다'라는 정보를 즉시 가져올 수 있습니다.
  • Global Understanding: 문장 전체의 관계를 한 번에 파악하여 각 단어의 고차원적인 의미 벡터(Context Vector)를 만들어냅니다.

❷ Decoder: 예측의 마술사와 'Masking'의 규칙

디코더는 인코더가 넘겨준 정보를 바탕으로 한 단어씩 결과를 출력합니다. 여기서 가장 중요한 점은 "미래를 봐서는 안 된다"는 것입니다.

  • Look-ahead Masking: 번역을 할 때 모델이 다음에 올 단어를 미리 알고 있다면 학습이 제대로 되지 않습니다. 그래서 현재 시점보다 뒤에 있는 단어들을 수학적으로 '가리는(Masking)' 기법을 사용합니다. 이를 통해 디코더는 오직 '지금까지 생성한 단어들'만 참고하여 다음 단어를 예측하게 됩니다.
  • Auto-regressive: 자신의 출력을 다시 자신의 입력으로 사용하는 자기 회귀적 특성을 가집니다.

❸ Encoder-Decoder Attention: 두 엔진의 교차점

디코더의 중간에는 인코더와 대화하는 특별한 층이 있습니다.

  • The Bridge: 여기서 디코더는 "내가 지금 단어를 하나 만들어야 하는데, 인코더 네가 분석한 문장에서 어떤 부분에 집중하면 좋을까?"라고 질문(Query)을 던집니다.
  • Interaction: 인코더는 자신이 만든 Key와 Value를 제공하며 응답합니다. 이 과정을 통해 "I love you"라는 영어 문장에서 'love'를 처리할 때 한국어 '사랑'이라는 부분에 강한 Attention을 가할 수 있게 됩니다.

4 후기

이번 논문 스터디를 통해 얻은 가장 큰 수확은 "수학적 엄밀함이 곧 모델의 성능으로 이어진다"는 확신으로, 단순히 오픈 소스 코드를 복사해 붙여넣는 수동적인 방식에서 벗어나 아키텍처의 설계 의도를 논리적으로 파악할 때 비로소 모델을 완벽히 제어할 수 있음을 깨달았습니다. 특히 내적값이 커짐에 따라 발생하는 Gradient Vanishing 문제를 해결하기 위해 도입된 Scaling(sqrt{d_k})의 수학적 필연성을 이해하며 작은 수식 하나가 거대 모델의 학습 가능 여부를 결정짓는 결정적 단서임을 체감했고, 인과관계를 보존하기 위한 Masking 기법이 어떻게 행렬 연산 내부에서 논리적 제약 조건을 구현하는지 학습하며 딥러닝이 단순한 '블랙박스'가 아닌 철저히 계산된 공학의 산물임을 확인했습니다.

전에는 단순히 0~9까지의 손글씨 데이터가 있는 MNIST를 사용하였습니다.

이번에는 FashionMNIST 데이터셋을 활용하여 일반적인 딥러닝 모델(MLP)과 이미지 처리에 특화된 합성곱 신경망(CNN)의 성능 차이를 심층 분석해 보았습니다.

 

1. FashionMNIST 데이터셋이란?

MNIST가 손글씨 숫자였다면, FashionMNIST는 운동화, 셔츠, 가방 등 10가지 종류의 패션 아이템으로 구성된 데이터셋입니다.

  • 크기: 28 x 28 픽셀 (흑백)
  • 특징: 숫자 데이터보다 형태가 복잡하고 경계선이 다양하여, 일반적인 MLP로는 높은 정확도를 얻기가 더 까다롭습니다.

2.  MLP와 CNN의 구조 차이

단순 딥러닝 (MLP) 구조

가장 기본적인 형태인 다층 퍼셉트론(Multi-Layer Perceptron)입니다.

  • 특징: 이미지를 1차원으로 길게 펼쳐서(Flatten) 입력합니다.
  • 한계: 이미지를 한 줄로 세우다 보니 픽셀 간의 공간적 구조(예: 소매와 몸통의 연결성) 정보가 손실됩니다.

합성곱 신경망 (CNN) 구조

이미지의 특징을 추출하는 데 최적화된 CNN 모델입니다.

CNN이 강력한 이유:

  1. 커널(Kernel/Filter): 이미지의 국소적인 부분(가로선, 세로선, 질감 등)을 훑으며 특징을 추출합니다.
  2. 풀링(Pooling): 중요한 정보만 남기고 데이터 크기를 줄여 모델이 사소한 변화(이미지가 약간 치우침 등)에 강해지도록 만듭니다.
  3. 공간 정보 유지: 이미지를 펼치지 않고 2차원 그대로 학습하므로 형태를 훨씬 잘 이해합니다.

3. 전체 코드

코드가 다소 길어지는 관계로 링크 첨부 하였습니다.

https://github.com/docodocod/ML-DL/blob/main/DL/fashionMNIST.ipynb

 

ML-DL/DL/fashionMNIST.ipynb at main · docodocod/ML-DL

Contribute to docodocod/ML-DL development by creating an account on GitHub.

github.com

 

4.코드 상세 분석

두 모델 모두 데이터 준비 단계는 동일하지만, 딥러닝의 기초가 되는 매우 중요한 부분입니다.

train_dataset = datasets.FashionMNIST(root='FashionMNIST_data/', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = datasets.FashionMNIST(root='FashionMNIST_data/', train=False, transform=transforms.ToTensor(), download=True)
  • transforms.ToTensor(): 가장 중요한 전처리입니다. 0~255 사이의 픽셀 강도 값을 0~1 사이의 실수값으로 정규화(Normalization)하고, 데이터를 파이토치 연산에 최적화된 Tensor 형태로 변환합니다.
  • random_split: 데이터를 훈련용(85%)과 검증용(15%)으로 분리합니다. 모델이 훈련 데이터에만 익숙해지는 '과적합'을 방지하고, 중간중간 실력을 테스트하기 위함입니다.
  • DataLoader: 데이터를 BATCH_SIZE=32 단위로 쪼개서 공급합니다. 이는 메모리 절약뿐만 아니라, 가중치를 더 자주 업데이트하게 하여 학습의 효율을 높입니다.

[MLP 모델: 선형적인 정보 처리]

class MyDeepLearningModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()      # (1, 28, 28) 이미지를 784개의 긴 줄로 만듦
        self.fc1 = nn.Linear(784, 256)   # 784개의 특징 -> 256개의 특징으로 압축
        self.reLU = nn.ReLU()           # 비선형성 추가
        self.dropout = nn.Dropout(0.3)  # 과적합 방지 (뉴런 30% 끄기)
        self.fc2 = nn.Linear(256, 10)    # 최종 10개 클래스로 판별
  • 작동 방식: 이미지를 단순히 '숫자의 집합'으로 봅니다. 픽셀 간의 위치 관계보다는 각 픽셀값이 가지는 통계적인 빈도를 학습합니다.

[CNN 모델: 공간 정보를 보존하는 특징 추출]

class MyCNNModel(nn.Module):
    def __init__(self):
        super().__init__()
        # 1차 특징 추출: 3x3 필터 32개 사용
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1)
        # 2차 특징 추출: 3x3 필터 64개 사용
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1)
        # 정보 압축: 크기를 절반으로 줄임 (2x2 Max Pooling)
        self.pooling = nn.MaxPool2d(kernel_size=2, stride=2)
        # 분류기 (Fully Connected Layer)
        self.fc1 = nn.Linear(7*7*64, 256)
        self.fc2 = nn.Linear(256, 10)
  • 핵심 연산: Conv2d가 이미지 위를 훑으며 선, 면, 복잡한 문양 등의 특징 지도(Feature Map)를 생성합니다. view(-1, 7*7*64) 부분은 추출된 2차원 특징들을 최종 분류를 위해 1차원으로 변환하는 과정입니다.

학습 및 검증 루프 (Training & Evaluation)

두 코드에서 공통적으로 사용된 핵심 함수들입니다.

① model_train (학습)

  • model.train(): 모델을 학습 모드로 전환합니다. Dropout이 활성화되어 과적합을 방지합니다.
  • optimizer.zero_grad(): 딥러닝은 기울기를 누적하는 성질이 있습니다. 새로운 배치마다 이전의 기울기를 지워줘야 정확한 학습 방향을 잡습니다.
  • loss.backward(): 역전파(Backpropagation)입니다. 출력층에서 발생한 오차를 입력층까지 거꾸로 전달하며 각 가중치가 오차에 기여한 정도를 계산합니다.
  • optimizer.step(): 계산된 기울기를 바탕으로 가중치를 실제로 업데이트합니다.

② model_evaluate / model_test (평가)

  • model.eval(): 평가 모드로 전환합니다. Dropout을 비활성화하여 모든 뉴런의 지식을 총동원합니다.
  • with torch.no_grad(): 가중치를 업데이트하지 않으므로 미분 계산을 끕니다. 메모리 사용량을 대폭 줄이고 연산 속도를 높입니다.

최적화 도구 (Optimizer)의 차이

이 부분이 성능 차이의 숨은 조역입니다.

  • MLP (SGD): torch.optim.SGD. 전통적인 방식으로, 일정한 학습률로 경사를 따라 내려갑니다. 안정적이지만 최적점에 도달하는 속도가 느릴 수 있습니다.
  • CNN (Adam): torch.optim.Adam. 방향뿐만 아니라 속도까지 스스로 조절하는 영리한 옵티마이저입니다. 이 덕분에 CNN이 훨씬 빠르게 99%라는 경이로운 정확도에 도달할 수 있었습니다.

5. 결과 해석 및 결론 분석

MLP vs CNN 손실도

 

MLP vs CNN 정확도

 

  1. 정확도 (Accuracy): MLP(86.75%) vs CNN(99.42%).
    • CNN은 이미지를 있는 그대로 인식하기 때문에 복잡한 의류 패턴을 거의 완벽하게 구분해 냈습니다.
  2. 손실 (Loss): MLP는 손실값이 줄어드는 속도가 더디지만, CNN은 학습 초반에 이미 손실값이 0에 가깝게 급감합니다.
  3. 성능 요인:
    • CNN의 특징 추출(Feature Extraction) 능력.
    • Adam 옵티마이저의 효율적인 가중치 업데이트.
    • GPU(CUDA)를 활용한 대규모 행렬 연산 처리.

6. 후기

코드 전체를 비교해 본 결과 MLP는 이미지를 숫자로만 보지만 CNN은 이미지를 '형태'로 이해하기 때문에 이미지 데이터에는 CNN이 압도적으로 유리하다는 결론을 얻었습니다.

+ Recent posts