AI 연구 과학자 면접 질문

Milad Bonakdar
작성자
딥러닝, 트랜스포머, 실험 설계, 모델 평가, 연구 발표를 중심으로 AI 연구 과학자 면접을 준비하는 질문 모음입니다.
소개
AI 연구 과학자 면접은 연구자처럼 사고할 수 있는지를 봅니다. 가설을 세우고, 설계 선택을 설명하고, 핵심 아이디어를 구현하고, 모델을 공정하게 평가하며, 논문이나 연구 발표의 트레이드오프를 명확히 말할 수 있어야 합니다. 딥러닝과 트랜스포머 질문뿐 아니라 실험 설계, 재현성, 안전성, 다음 연구 방향도 자주 다룹니다.
이 가이드는 기술적으로 정확하고 설명하기 쉬운 답변을 연습하는 데 초점을 둡니다. 강한 지원자는 수식과 코드를 연구 판단과 연결합니다. 왜 그 방법이 효과적일지, 어떻게 검증할지, 어떤 실패 사례를 볼지, 불확실성을 어떻게 전달할지까지 말할 수 있어야 합니다.
딥러닝 이론 (5 문제)
1. 역전파와 연쇄 법칙을 자세히 설명하세요.
답변: 역전파는 연쇄 법칙을 사용하여 효율적으로 기울기를 계산합니다.
- 연쇄 법칙: 합성 함수의 경우, 미분은 미분들의 곱입니다.
- 순전파: 출력을 계산하고 중간값을 캐싱합니다.
- 역전파: 출력에서 입력으로 기울기를 계산합니다.
import numpy as np
# 역전파를 시연하기 위한 간단한 신경망
class SimpleNN:
def __init__(self, input_size, hidden_size, output_size):
# 가중치 초기화
self.W1 = np.random.randn(input_size, hidden_size) * 0.01
self.b1 = np.zeros((1, hidden_size))
self.W2 = np.random.randn(hidden_size, output_size) * 0.01
self.b2 = np.zeros((1, output_size))
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(self, x):
return x * (1 - x)
def forward(self, X):
# 레이어 1
self.z1 = np.dot(X, self.W1) + self.b1
self.a1 = self.sigmoid(self.z1)
# 레이어 2
self.z2 = np.dot(self.a1, self.W2) + self.b2
self.a2 = self.sigmoid(self.z2)
return self.a2
def backward(self, X, y, output, learning_rate=0.01):
m = X.shape[0]
# 출력 레이어 기울기
# dL/da2 = a2 - y (이진 교차 엔트로피의 경우)
# dL/dz2 = dL/da2 * da2/dz2 = (a2 - y) * sigmoid'(z2)
dz2 = output - y
dW2 = (1/m) * np.dot(self.a1.T, dz2)
db2 = (1/m) * np.sum(dz2, axis=0, keepdims=True)
# 숨겨진 레이어 기울기 (연쇄 법칙)
# dL/da1 = dL/dz2 * dz2/da1 = dz2 * W2.T
# dL/dz1 = dL/da1 * da1/dz1 = dL/da1 * sigmoid'(z1)
da1 = np.dot(dz2, self.W2.T)
dz1 = da1 * self.sigmoid_derivative(self.a1)
dW1 = (1/m) * np.dot(X.T, dz1)
db1 = (1/m) * np.sum(dz1, axis=0, keepdims=True)
# 가중치 업데이트
self.W2 -= learning_rate * dW2
self.b2 -= learning_rate * db2
self.W1 -= learning_rate * dW1
self.b1 -= learning_rate * db1
def train(self, X, y, epochs=1000):
for epoch in range(epochs):
# 순전파
output = self.forward(X)
# 역전파
self.backward(X, y, output)
if epoch % 100 == 0:
loss = -np.mean(y * np.log(output) + (1-y) * np.log(1-output))
print(f'Epoch {epoch}, Loss: {loss:.4f}')
# 사용 예
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]]) # XOR
nn = SimpleNN(input_size=2, hidden_size=4, output_size=1)
nn.train(X, y, epochs=5000)희소성: 매우 흔함 난이도: 어려움
2. 기울기 소실 문제는 무엇이며 어떻게 해결합니까?
답변: 기울기 소실은 깊은 네트워크에서 기울기가 매우 작아질 때 발생합니다.
- 원인:
- 시그모이드/tanh 활성화 함수 (미분 < 1)
- 깊은 네트워크 (기울기가 곱해짐)
- 해결책:
- ReLU 활성화 함수
- 배치 정규화
- 잔차 연결 (ResNet)
- RNN을 위한 LSTM/GRU
- 신중한 초기화 (Xavier, He)
import torch
import torch.nn as nn
# 문제: 시그모이드를 사용한 깊은 네트워크
class VanishingGradientNet(nn.Module):
def __init__(self):
super().__init__()
self.layers = nn.Sequential(*[
nn.Sequential(nn.Linear(100, 100), nn.Sigmoid())
for _ in range(20) # 20 레이어
])
def forward(self, x):
return self.layers(x)
# 해결책 1: ReLU 활성화 함수
class ReLUNet(nn.Module):
def __init__(self):
super().__init__()
self.layers = nn.Sequential(*[
nn.Sequential(nn.Linear(100, 100), nn.ReLU())
for _ in range(20)
])
def forward(self, x):
return self.layers(x)
# 해결책 2: 잔차 연결
class ResidualBlock(nn.Module):
def __init__(self, dim):
super().__init__()
self.layers = nn.Sequential(
nn.Linear(dim, dim),
nn.ReLU(),
nn.Linear(dim, dim)
)
def forward(self, x):
return x + self.layers(x) # 스킵 연결
class ResNet(nn.Module):
def __init__(self):
super().__init__()
self.blocks = nn.Sequential(*[
ResidualBlock(100) for _ in range(20)
])
def forward(self, x):
return self.blocks(x)
# 해결책 3: 배치 정규화
class BatchNormNet(nn.Module):
def __init__(self):
super().__init__()
self.layers = nn.Sequential(*[
nn.Sequential(
nn.Linear(100, 100),
nn.BatchNorm1d(100),
nn.ReLU()
)
for _ in range(20)
])
def forward(self, x):
return self.layers(x)
# 기울기 흐름 분석
def analyze_gradients(model, x, y):
model.zero_grad()
output = model(x)
loss = nn.MSELoss()(output, y)
loss.backward()
# 기울기 크기 확인
for name, param in model.named_parameters():
if param.grad is not None:
grad_norm = param.grad.norm().item()
print(f"{name}: {grad_norm:.6f}")희소성: 매우 흔함 난이도: 어려움
3. 어텐션 메커니즘과 자기 어텐션을 설명하세요.
답변: 어텐션을 통해 모델은 입력의 관련 부분에 집중할 수 있습니다.
- 어텐션: 쿼리-키 유사성을 기반으로 한 값의 가중 합
- 자기 어텐션: 쿼리, 키, 값이 동일한 소스에서 오는 어텐션
- 스케일링된 닷-프로덕트 어텐션: Q·K^T / √d_k
import torch
import torch.nn as nn
import torch.nn.functional as F
import math
class ScaledDotProductAttention(nn.Module):
def __init__(self, temperature):
super().__init__()
self.temperature = temperature
def forward(self, q, k, v, mask=None):
"""
q: (batch, seq_len, d_k)
k: (batch, seq_len, d_k)
v: (batch, seq_len, d_v)
"""
# 어텐션 점수 계산
attn = torch.matmul(q, k.transpose(-2, -1)) / self.temperature
# 마스크 적용 (패딩 또는 인과 관계 어텐션)
if mask is not None:
attn = attn.masked_fill(mask == 0, -1e9)
# 어텐션 가중치를 얻기 위한 소프트맥스
attn_weights = F.softmax(attn, dim=-1)
# 값에 어텐션 적용
output = torch.matmul(attn_weights, v)
return output, attn_weights
class MultiHeadAttention(nn.Module):
def __init__(self, d_model, n_heads, dropout=0.1):
super().__init__()
assert d_model % n_heads == 0
self.d_model = d_model
self.n_heads = n_heads
self.d_k = d_model // n_heads
# 선형 투영
self.w_q = nn.Linear(d_model, d_model)
self.w_k = nn.Linear(d_model, d_model)
self.w_v = nn.Linear(d_model, d_model)
self.w_o = nn.Linear(d_model, d_model)
self.attention = ScaledDotProductAttention(temperature=math.sqrt(self.d_k))
self.dropout = nn.Dropout(dropout)
def forward(self, q, k, v, mask=None):
batch_size = q.size(0)
# 선형 투영 및 헤드로 분할
q = self.w_q(q).view(batch_size, -1, self.n_heads, self.d_k).transpose(1, 2)
k = self.w_k(k).view(batch_size, -1, self.n_heads, self.d_k).transpose(1, 2)
v = self.w_v(v).view(batch_size, -1, self.n_heads, self.d_k).transpose(1, 2)
# 어텐션 적용
output, attn_weights = self.attention(q, k, v, mask)
# 헤드 연결
output = output.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
# 최종 선형 투영
output = self.w_o(output)
return output, attn_weights
# 사용 예
d_model = 512
n_heads = 8
seq_len = 10
batch_size = 2
mha = MultiHeadAttention(d_model, n_heads)
x = torch.randn(batch_size, seq_len, d_model)
# 자기 어텐션 (q, k, v 모두 x에서)
output, attn = mha(x, x, x)
print(f"Output shape: {output.shape}")
print(f"Attention weights shape: {attn.shape}")희소성: 매우 흔함 난이도: 어려움
4. 배치 정규화와 레이어 정규화의 차이점은 무엇입니까?
답변: 둘 다 활성화를 정규화하지만 다른 차원을 따라 정규화합니다.
- 배치 정규화:
- 배치 차원에 걸쳐 정규화
- 배치 통계 필요
- 작은 배치, RNN에 문제 있음
- 레이어 정규화:
- 특징 차원에 걸쳐 정규화
- 배치 크기와 무관
- RNN, 트랜스포머에 더 적합
import torch
import torch.nn as nn
# 배치 정규화
class BatchNormExample(nn.Module):
def __init__(self, num_features):
super().__init__()
self.bn = nn.BatchNorm1d(num_features)
def forward(self, x):
# x: (batch_size, num_features)
# 각 특징에 대해 배치 차원에 걸쳐 정규화
return self.bn(x)
# 레이어 정규화
class LayerNormExample(nn.Module):
def __init__(self, normalized_shape):
super().__init__()
self.ln = nn.LayerNorm(normalized_shape)
def forward(self, x):
# x: (batch_size, seq_len, d_model)
# 각 샘플에 대해 특징 차원에 걸쳐 정규화
return self.ln(x)
# 수동 구현
class ManualLayerNorm(nn.Module):
def __init__(self, normalized_shape, eps=1e-5):
super().__init__()
self.eps = eps
self.gamma = nn.Parameter(torch.ones(normalized_shape))
self.beta = nn.Parameter(torch.zeros(normalized_shape))
def forward(self, x):
# 마지막 차원에 걸쳐 평균 및 분산 계산
mean = x.mean(dim=-1, keepdim=True)
var = x.var(dim=-1, keepdim=True, unbiased=False)
# 정규화
x_norm = (x - mean) / torch.sqrt(var + self.eps)
# 스케일 및 이동
return self.gamma * x_norm + self.beta
# 비교
batch_size, seq_len, d_model = 2, 10, 512
# 배치 정규화 (CNN용)
x_cnn = torch.randn(batch_size, d_model, 28, 28)
bn = nn.BatchNorm2d(d_model)
out_bn = bn(x_cnn)
# 레이어 정규화 (트랜스포머용)
x_transformer = torch.randn(batch_size, seq_len, d_model)
ln = nn.LayerNorm(d_model)
out_ln = ln(x_transformer)
print(f"Batch Norm output: {out_bn.shape}")
print(f"Layer Norm output: {out_ln.shape}")희소성: 흔함 난이도: 중간
5. 트랜스포머 아키텍처를 자세히 설명하세요.
답변: 트랜스포머는 순환 없이 시퀀스 모델링을 위해 자기 어텐션을 사용합니다.
- 구성 요소:
- 인코더: 자기 어텐션 + FFN
- 디코더: 마스크된 자기 어텐션 + 교차 어텐션 + FFN
- 위치 인코딩: 위치 정보 주입
- 멀티 헤드 어텐션: 병렬 어텐션 메커니즘
import torch
import torch.nn as nn
import math
class PositionalEncoding(nn.Module):
def __init__(self, d_model, max_len=5000):
super().__init__()
# 위치 인코딩 행렬 생성
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
div_term = torch.exp(torch.arange(0, d_model, 2).float() *
(-math.log(10000.0) / d_model))
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
pe = pe.unsqueeze(0)
self.register_buffer('pe', pe)
def forward(self, x):
return x + self.pe[:, :x.size(1)]
class TransformerEncoderLayer(nn.Module):
def __init__(self, d_model, n_heads, d_ff, dropout=0.1):
super().__init__()
# 멀티 헤드 어텐션
self.self_attn = nn.MultiheadAttention(d_model, n_heads, dropout=dropout)
# 피드 포워드 네트워크
self.ffn = nn.Sequential(
nn.Linear(d_model, d_ff),
nn.ReLU(),
nn.Dropout(dropout),
nn.Linear(d_ff, d_model)
)
# 레이어 정규화
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x, mask=None):
# 잔차 연결을 사용한 자기 어텐션
attn_output, _ = self.self_attn(x, x, x, attn_mask=mask)
x = self.norm1(x + self.dropout(attn_output))
# 잔차 연결을 사용한 피드 포워드
ffn_output = self.ffn(x)
x = self.norm2(x + self.dropout(ffn_output))
return x
class TransformerEncoder(nn.Module):
def __init__(self, vocab_size, d_model, n_heads, d_ff, n_layers, dropout=0.1):
super().__init__()
self.embedding = nn.Embedding(vocab_size, d_model)
self.pos_encoding = PositionalEncoding(d_model)
self.layers = nn.ModuleList([
TransformerEncoderLayer(d_model, n_heads, d_ff, dropout)
for _ in range(n_layers)
])
self.dropout = nn.Dropout(dropout)
def forward(self, x, mask=None):
# 임베딩 + 위치 인코딩
x = self.embedding(x) * math.sqrt(self.embedding.embedding_dim)
x = self.pos_encoding(x)
x = self.dropout(x)
# 인코더 레이어 적용
for layer in self.layers:
x = layer(x, mask)
return x
# 사용 예
vocab_size = 10000
d_model = 512
n_heads = 8
d_ff = 2048
n_layers = 6
encoder = TransformerEncoder(vocab_size, d_model, n_heads, d_ff, n_layers)
# 입력: (batch_size, seq_len)
x = torch.randint(0, vocab_size, (2, 10))
output = encoder(x)
print(f"Output shape: {output.shape}") # (2, 10, 512)희소성: 매우 흔함 난이도: 어려움
연구 방법론 (4 문제)
6. 연구 문제와 가설을 어떻게 공식화합니까?
답변: 연구는 격차를 식별하고 검증 가능한 가설을 공식화하는 것으로 시작됩니다.
- 단계:
- 문헌 조사: 최첨단 기술 이해
- 격차 식별: 무엇이 누락되었거나 개선될 수 있습니까?
- 가설 공식화: 구체적이고 검증 가능한 주장
- 실험 설계: 가설을 테스트하는 방법?
- 지표 정의: 성공을 측정하는 방법?
- 예:
- 격차: 현재 모델은 장거리 의존성에 어려움을 겪습니다.
- 가설: 희소 어텐션은 복잡성을 줄이면서 성능을 유지할 수 있습니다.
- 실험: 긴 시퀀스에서 희소 어텐션과 전체 어텐션 비교
- 지표: 퍼플렉서티, 정확도, 추론 시간
희소성: 매우 흔함 난이도: 중간
7. 제거 연구를 어떻게 설계합니까?
답변: 제거 연구는 개별 구성 요소의 기여도를 분리합니다.
- 목적: 모델이 작동하는 이유 이해
- 방법: 한 번에 하나의 구성 요소 제거/수정
- 모범 사례:
- 다른 모든 변수 제어
- 동일한 랜덤 시드 사용
- 신뢰 구간 보고
- 여러 데이터 세트에서 테스트
# 제거 연구 예
class ModelWithAblations:
def __init__(self, use_attention=True, use_residual=True, use_dropout=True):
self.use_attention = use_attention
self.use_residual = use_residual
self.use_dropout = use_dropout
def build_model(self):
layers = []
if self.use_attention:
layers.append(AttentionLayer())
layers.append(FFNLayer())
if self.use_dropout:
layers.append(nn.Dropout(0.1))
if self.use_residual:
return ResidualWrapper(nn.Sequential(*layers))
else:
return nn.Sequential(*layers)
# 제거 실험 실행
configs = [
{'use_attention': True, 'use_residual': True, 'use_dropout': True}, # 전체 모델
{'use_attention': False, 'use_residual': True, 'use_dropout': True}, # 어텐션 없음
{'use_attention': True, 'use_residual': False, 'use_dropout': True}, # 잔차 없음
{'use_attention': True, 'use_residual': True, 'use_dropout': False}, # 드롭아웃 없음
]
results = []
for config in configs:
model = ModelWithAblations(**config)
accuracy = train_and_evaluate(model, seed=42)
results.append({**config, 'accuracy': accuracy})
# 결과 분석
import pandas as pd
df = pd.DataFrame(results)
print(df)희소성: 매우 흔함 난이도: 중간
8. 연구에서 재현성을 어떻게 보장합니까?
답변: 재현성은 과학적 타당성에 매우 중요합니다.
- 모범 사례:
- 코드: 버전 관리, 명확한 문서
- 데이터: 버전, 전처리 문서화
- 환경: Docker, requirements.txt
- 시드: 모든 랜덤 시드 고정
- 하이퍼파라미터: 모든 설정 기록
- 하드웨어: GPU/CPU 사양 문서화
import random
import numpy as np
import torch
import os
def set_all_seeds(seed=42):
"""재현성을 위해 시드 설정"""
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
os.environ['PYTHONHASHSEED'] = str(seed)
# 결정적 연산
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
# 모든 것 기록
import logging
import json
def log_experiment(config, results):
experiment_log = {
'timestamp': datetime.now().isoformat(),
'config': config,
'results': results,
'environment': {
'python_version': sys.version,
'torch_version': torch.__version__,
'cuda_version': torch.version.cuda,
'gpu': torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'CPU'
}
}
with open('experiment_log.json', 'w') as f:
json.dump(experiment_log, f, indent=2)
# 코드 및 모델 공유
"""
# README.md
## 재현성
### 환경
```bash
conda create -n research python=3.9
conda activate research
pip install -r requirements.txt데이터
Download from: [link]
Preprocess: python preprocess.py
훈련
python train.py --config configs/experiment1.yaml --seed 42평가
python evaluate.py --checkpoint checkpoints/best_model.pt"""
**희소성:** 매우 흔함
**난이도:** 쉬움
---
### 9. 모델을 공정하게 평가하고 비교하는 방법은 무엇입니까?
**답변:**
공정한 비교에는 신중한 실험 설계가 필요합니다.
- **고려 사항:**
- **동일한 데이터 분할:** 동일한 훈련/검증/테스트 사용
- **여러 실행:** 평균 및 표준 편차 보고
- **통계 테스트:** T-검정, 윌콕슨
- **계산 비용:** FLOP, 매개변수, 시간
- **여러 지표:** 체리 피킹하지 마세요
- **여러 데이터 세트:** 일반화
```python
import numpy as np
from scipy import stats
class ModelComparison:
def __init__(self, n_runs=5):
self.n_runs = n_runs
self.results = {}
def evaluate_model(self, model_name, model_fn, X_train, y_train, X_test, y_test):
scores = []
for seed in range(self.n_runs):
# 이 실행에 대한 시드 설정
set_all_seeds(seed)
# 모델 훈련
model = model_fn()
model.fit(X_train, y_train)
# 평가
score = model.score(X_test, y_test)
scores.append(score)
self.results[model_name] = {
'scores': scores,
'mean': np.mean(scores),
'std': np.std(scores),
'ci_95': stats.t.interval(
0.95, len(scores)-1,
loc=np.mean(scores),
scale=stats.sem(scores)
)
}
def compare_models(self, model_a, model_b):
"""통계적 유의성 테스트"""
scores_a = self.results[model_a]['scores']
scores_b = self.results[model_b]['scores']
# 쌍체 t-검정
statistic, p_value = stats.ttest_rel(scores_a, scores_b)
return {
'statistic': statistic,
'p_value': p_value,
'significant': p_value < 0.05,
'better_model': model_a if np.mean(scores_a) > np.mean(scores_b) else model_b
}
def report(self):
for model_name, result in self.results.items():
print(f"\n{model_name}:")
print(f" Mean: {result['mean']:.4f}")
print(f" Std: {result['std']:.4f}")
print(f" 95% CI: [{result['ci_95'][0]:.4f}, {result['ci_95'][1]:.4f}]")
# 사용법
comparison = ModelComparison(n_runs=10)
comparison.evaluate_model('Model A', lambda: ModelA(), X_train, y_train, X_test, y_test)
comparison.evaluate_model('Model B', lambda: ModelB(), X_train, y_train, X_test, y_test)
comparison.report()
result = comparison.compare_models('Model A', 'Model B')
print(f"\nStatistical test: p-value = {result['p_value']:.4f}")
희소성: 매우 흔함 난이도: 중간
고급 주제 (4 문제)
10. 대조 학습 및 응용 분야를 설명하세요.
답변: 대조 학습은 유사한 샘플과 유사하지 않은 샘플을 비교하여 표현을 학습합니다.
- 핵심 아이디어: 유사한 샘플을 함께 당기고, 유사하지 않은 샘플을 밀어냅니다.
- 손실: InfoNCE, NT-Xent
- 응용 분야: SimCLR, MoCo, CLIP
import torch
import torch.nn as nn
import torch.nn.functional as F
class ContrastiveLoss(nn.Module):
def __init__(self, temperature=0.5):
super().__init__()
self.temperature = temperature
def forward(self, features):
"""
features: (2*batch_size, dim) - 증강된 샘플 쌍
"""
batch_size = features.shape[0] // 2
# 특징 정규화
features = F.normalize(features, dim=1)
# 유사성 행렬 계산
similarity_matrix = torch.matmul(features, features.T)
# 레이블 생성 (양성 쌍)
labels = torch.cat([torch.arange(batch_size) + batch_size,
torch.arange(batch_size)]).to(features.device)
# 자체 유사성을 제거하기 위한 마스크
mask = torch.eye(2 * batch_size, dtype=torch.bool).to(features.device)
similarity_matrix = similarity_matrix.masked_fill(mask, -9e15)
# 손실 계산
similarity_matrix = similarity_matrix / self.temperature
loss = F.cross_entropy(similarity_matrix, labels)
return loss
class SimCLR(nn.Module):
def __init__(self, encoder, projection_dim=128):
super().__init__()
self.encoder = encoder
self.projection = nn.Sequential(
nn.Linear(encoder.output_dim, 512),
nn.ReLU(),
nn.Linear(512, projection_dim)
)
def forward(self, x1, x2):
# 두 개의 증강된 뷰 인코딩
h1 = self.encoder(x1)
h2 = self.encoder(x2)
# 대조 공간으로 투영
z1 = self.projection(h1)
z2 = self.projection(h2)
# 대조 손실을 위해 연결
features = torch.cat([z1, z2], dim=0)
return features
# 훈련 루프
model = SimCLR(encoder, projection_dim=128)
criterion = ContrastiveLoss(temperature=0.5)
optimizer = torch.optim.Adam(model.parameters())
for epoch in range(100):
for batch in dataloader:
# 두 개의 증강된 뷰 가져오기
x1, x2 = augment(batch)
# 순전파
features = model(x1, x2)
loss = criterion(features)
# 역전파
optimizer.zero_grad()
loss.backward()
optimizer.step()희소성: 흔함 난이도: 어려움
11. Vision Transformers (ViT)는 무엇이며 어떻게 작동합니까?
답변: Vision Transformers는 트랜스포머 아키텍처를 이미지에 적용합니다.
- 핵심 아이디어:
- 이미지를 패치로 분할
- 패치의 선형 임베딩
- 위치 임베딩 추가
- 트랜스포머 인코더 적용
- 장점: 확장성, 글로벌 수용 필드
- 과제: 큰 데이터 세트 필요
import torch
import torch.nn as nn
class PatchEmbedding(nn.Module):
def __init__(self, img_size=224, patch_size=16, in_channels=3, embed_dim=768):
super().__init__()
self.img_size = img_size
self.patch_size = patch_size
self.n_patches = (img_size // patch_size) ** 2
# 패치 추출 및 임베딩을 위한 컨볼루션
self.projection = nn.Conv2d(

