# 미니 테스트: 딥러닝 기초

## 기본 정보
- **제목**: 딥러닝 기초 미니 테스트
- **관련 섹션**: 파트 8-9 (딥러닝 기초)
- **난이도**: 중상
- **예상 소요 시간**: 30분

## 이론 파트 (50점)

### 1. 인공 신경망 기본 구조 (10점)
다음 중 인공 신경망(Artificial Neural Network)의 기본 구성 요소로 올바르지 않은 것은?

1. 입력층(Input Layer)
2. 은닉층(Hidden Layer)
3. 출력층(Output Layer)
4. 회귀층(Regression Layer)

**정답**: 4

### 2. 활성화 함수 (10점)
다음 중 ReLU(Rectified Linear Unit) 활성화 함수의 특성으로 올바른 것은?

1. 항상 -1과 1 사이의 값을 출력한다
2. 그래디언트 소실 문제를 완전히 해결한다
3. 입력이 0보다 작으면 0을, 0보다 크거나 같으면 입력값 그대로를 출력한다
4. 확률 분포를 모델링하는 데 주로 사용된다

**정답**: 3

### 3. 손실 함수 선택 (10점)
다음 중 이진 분류 문제에 가장 적합한 손실 함수는?

1. 평균 제곱 오차(Mean Squared Error)
2. 범주형 교차 엔트로피(Categorical Cross-Entropy)
3. 이진 교차 엔트로피(Binary Cross-Entropy)
4. 쿨백-라이블러 발산(Kullback-Leibler Divergence)

**정답**: 3

### 4. 과적합 방지 기법 (10점)
다음 중 딥러닝에서 과적합(Overfitting)을 방지하는 기법이 아닌 것은?

1. Dropout
2. 배치 정규화(Batch Normalization)
3. L1/L2 규제화(Regularization)
4. 학습률 증가(Learning Rate Increase)

**정답**: 4

### 5. 딥러닝 프레임워크 (10점)
TensorFlow와 PyTorch의 주요 차이점으로 올바른 것은?

1. TensorFlow는 동적 계산 그래프를, PyTorch는 정적 계산 그래프를 사용한다
2. TensorFlow는 Python만 지원하지만 PyTorch는 여러 프로그래밍 언어를 지원한다
3. PyTorch는 즉시 실행(eager execution)과 동적 계산 그래프를 기본으로 한다
4. TensorFlow는 학술 연구용이고 PyTorch는 산업용으로만 사용된다

**정답**: 3

## 실습 파트 (50점)

### 6. 신경망 구조 이해 (10점)
다음 PyTorch 코드가 정의하는 신경망의 구조를 설명하시오.

```python
import torch.nn as nn

class MyNetwork(nn.Module):
    def __init__(self, input_size, hidden_size, num_classes):
        super(MyNetwork, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, num_classes)
        self.sigmoid = nn.Sigmoid()
    
    def forward(self, x):
        out = self.fc1(x)
        out = self.relu(out)
        out = self.fc2(out)
        out = self.sigmoid(out)
        return out
```

**정답**:
이 코드는 간단한 완전 연결(fully connected) 신경망을 정의합니다. 구조는 다음과 같습니다:
1. 입력층: input_size 크기의 입력을 받음
2. 첫 번째 완전 연결 층: 입력을 hidden_size 차원으로 변환
3. ReLU 활성화 함수: 비선형성 추가
4. 두 번째 완전 연결 층: hidden_size에서 num_classes 차원으로 변환
5. Sigmoid 활성화 함수: 출력을 0과 1 사이의 값으로 변환 (이진 분류에 적합)

전체적으로 이 네트워크는 이진 분류나 다중 이진 레이블 분류에 사용될 수 있는 간단한 2층 신경망입니다.

### 7. 신경망 학습 과정 (10점)
다음 코드에서 신경망을 학습시키는 과정을 단계별로 설명하시오.

```python
import torch
import torch.nn as nn
import torch.optim as optim

# 모델, 손실 함수, 옵티마이저 설정
model = MyNetwork(input_size, hidden_size, num_classes)
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 학습 루프
for epoch in range(num_epochs):
    # 순전파
    outputs = model(inputs)
    loss = criterion(outputs, targets)
    
    # 역전파 및 최적화
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
```

**정답**:
이 코드는 신경망 학습의 기본적인 과정을 보여줍니다:
1. **초기화**: 먼저 모델, 손실 함수(이진 교차 엔트로피), 그리고 옵티마이저(Adam)를 설정합니다.
2. **반복 학습**: 여러 에포크(epoch)에 걸쳐 학습을 반복합니다.
3. **순전파(Forward Pass)**: 입력 데이터를 모델에 통과시켜 예측값(outputs)을 얻습니다.
4. **손실 계산**: 예측값과 실제 타겟 값을 비교하여 손실(loss)을 계산합니다.
5. **그래디언트 초기화**: `optimizer.zero_grad()`로 이전 단계에서 계산된 그래디언트를 초기화합니다.
6. **역전파(Backward Pass)**: `loss.backward()`로 손실에 대한 그래디언트를 계산합니다.
7. **가중치 업데이트**: `optimizer.step()`으로 계산된 그래디언트를 사용하여 모델의 가중치를 업데이트합니다.

이 과정은 손실이 최소화되는 방향으로 모델 파라미터를 조정하며 반복됩니다.

### 8. 합성곱 신경망 이해 (10점)
합성곱 신경망(CNN)의 다음 레이어들의 역할을 설명하시오:
- 합성곱 레이어(Convolutional Layer)
- 풀링 레이어(Pooling Layer)
- 완전 연결 레이어(Fully Connected Layer)

**정답**:
**합성곱 레이어(Convolutional Layer)**:
- 입력 데이터(주로 이미지)에서 특성을 추출하는 역할
- 필터(또는 커널)를 사용하여 입력 데이터를 스캔하며 특성 맵(feature map) 생성
- 이미지의 공간적 구조를 유지하면서 지역적 패턴(엣지, 텍스처 등)을 감지

**풀링 레이어(Pooling Layer)**:
- 특성 맵의 크기를 줄이는 역할(다운샘플링)
- 계산 비용을 줄이고 과적합을 방지
- 가장 일반적인 형태는 최대 풀링(max pooling)으로, 각 영역에서 최대값만 선택
- 위치 불변성(position invariance) 제공으로 특성의 작은 위치 변화에 강건

**완전 연결 레이어(Fully Connected Layer)**:
- 추출된 특성들을 최종 출력으로 변환하는 역할
- 주로 CNN의 마지막 부분에 위치
- 모든 뉴런이 이전 층의 모든 뉴런과 연결됨
- 고수준 추론을 수행하여 최종 분류 또는 회귀 작업 수행

### 9. 전이 학습 구현 (10점)
다음 요구사항을 만족하는 PyTorch 코드를 작성하시오:
1. 사전 학습된 ResNet18 모델을 로드
2. 새 분류 문제(10개 클래스)에 맞게 마지막 층 수정
3. 전체 모델은 고정하고 마지막 층만 학습하도록 설정

**정답**:
```python
import torch
import torch.nn as nn
import torchvision.models as models

def create_transfer_learning_model():
    # 1. 사전 학습된 ResNet18 모델 로드
    model = models.resnet18(pretrained=True)
    
    # 2. 특성 추출기의 파라미터 고정
    for param in model.parameters():
        param.requires_grad = False
    
    # 3. 새 분류 문제에 맞게 마지막 완전 연결 층 수정
    num_features = model.fc.in_features
    model.fc = nn.Linear(num_features, 10)  # 10개 클래스로 변경
    
    return model

# 모델 생성
model = create_transfer_learning_model()

# 옵티마이저 설정 (마지막 층의 파라미터만 학습)
optimizer = torch.optim.Adam(model.fc.parameters(), lr=0.001)
```

### 10. 실제 문제 해결 (10점)
당신은 의료 영상에서 질병을 감지하는 딥러닝 모델을 개발하고 있습니다. 데이터셋은 소량(500장)이고 불균형(90%가 정상, 10%가 질병)합니다. 다음 질문에 답하시오:

a) 이 상황에서 심층 합성곱 신경망(Deep CNN)을 처음부터 학습시키는 것의 문제점은 무엇인가?

b) 이 문제를 해결하기 위한 두 가지 접근 방법을 제시하시오.

c) 모델이 특정 환자의 질병 위험을 95%로 예측했을 때, 이것이 실제 임상 결정에 어떻게 사용되어야 하는지 설명하시오.

**정답**:
a) 처음부터 심층 CNN을 학습시키는 문제점:
- 데이터셋이 너무 작아 과적합 위험이 높음
- 클래스 불균형으로 인해 모델이 다수 클래스(정상)에 편향될 가능성
- 의료 영상은 복잡한 패턴을 가지므로 500개 샘플로는 일반화하기 어려움
- 훈련에 필요한 계산 리소스가 많고 모델의 수렴이 불안정할 수 있음

b) 문제 해결 접근 방법:
1. **전이 학습(Transfer Learning)**:
   - 대규모 데이터셋(예: ImageNet)에서 사전 학습된 모델 사용
   - 마지막 몇 개 층만 의료 영상 데이터로 미세 조정
   - 모델이 이미 기본적인 시각적 특징을 학습했으므로 적은 데이터로도 효과적

2. **데이터 증강(Data Augmentation) 및 균형 조정**:
   - 회전, 크기 조정, 뒤집기 등의 기법으로 학습 데이터 증강
   - SMOTE와 같은 기법으로 소수 클래스(질병) 샘플 생성
   - 클래스 가중치 부여 또는 언더/오버샘플링으로 불균형 해결

c) 임상 결정에서의 활용:
- 95%의 예측은 모델의 확신 정도를 나타내지만, 직접적인 진단으로 사용해서는 안 됨
- 이것은 의사의 진단을 보조하는 정보로 활용되어야 함
- 거짓 양성(false positive)과 거짓 음성(false negative)의 임상적 결과를 고려해야 함
- 모델의 신뢰도, 민감도, 특이도 등 다양한 성능 지표를 함께 검토해야 함
- 최종 결정은 환자의 임상 정보, 다른 검사 결과, 의사의 경험 등을 종합적으로 고려하여 내려야 함

## 채점 기준
- 객관식 문제: 정답이면 만점, 오답이면 0점
- 단답형 문제: 핵심 개념을 정확히 설명하면 만점
- 코드 작성 문제: 기능적으로 올바른 해결책을 제시하면 만점
- 실제 문제 해결: 각 하위 질문에 대해 적절하게 답변하면 만점 