job 인터뷰/2025년 1분기 USA

딥러닝 라이브코딩 연습

hyunkookim 2025. 2. 1. 21:29

🔥 1. PyTorch 기본 문법 연습

인터뷰에서 PyTorch 관련 질문이 나오면 텐서 연산, 자동 미분, 기본 모델 구현 등을 잘 이해하고 있어야 해.

1.1. PyTorch Tensor 기본 연산

import torch

# Tensor 생성
x = torch.tensor([[1, 0], [0, 1]], dtype=torch.float32)
y = torch.tensor([[5, 6], [7, 8]], dtype=torch.float32)

# 기본 연산
print(x + y)   # 덧셈
print(x - y)   # 뺄셈
print(x * y)   # 원소별 곱
print(x @ y) # 행렬 곱

"""
tensor([[6., 6.],
        [7., 9.]])
tensor([[-4., -6.],
        [-7., -7.]])
tensor([[5., 0.],
        [0., 8.]])
tensor([[5., 6.],
        [7., 8.]])
"""

 

🎯 연습 문제

  • 랜덤한 텐서 (3, 3)을 생성하고, 정규화를 수행하는 코드를 작성해 봐.
import torch
import numpy as np

# create random tensor
random_tensor = torch.rand(3, 3, dtype=torch.float32)
print(random_tensor)

# min-max normalization
min_val = random_tensor.min()
max_val = random_tensor.max()
normalized_tensor = (random_tensor-min_val)/(max_val-min_val)
print(normalized_tensor)

"""
tensor([[0.7960, 0.9164, 0.5767],
        [0.0654, 0.5653, 0.2052],
        [0.4380, 0.4607, 0.7325]])
tensor([[0.8586, 1.0000, 0.6008],
        [0.0000, 0.5875, 0.1643],
        [0.4379, 0.4645, 0.7839]])
"""

1.2. PyTorch Autograd (자동 미분)

# requires_grad=True 설정 시 자동 미분 가능
a = torch.tensor(2.0, requires_grad=True)
b = torch.tensor(3.0, requires_grad=True)

y = a**2 + b**3  # 수식
y.backward()  # 미분 계산

print(a.grad)  # dy/da
print(b.grad)  # dy/db

"""
tensor(4.)
tensor(27.)
"""
 

🎯 연습 문제

  • f(x) = x^3 + 2x^2 + 5x + 1의 도함수를 자동 미분으로 구해보자.
import torch
import numpy as np

x = torch.tensor(2.0, requires_grad=True)

f_x = x**3 + 2*x**2 + 5*x + 1
f_x.backward()

print(f"f'(x) at x=2: {x.grad}") # d f_x /dx 

"""
f'(x) at x=2: 25.0
"""

🔥 2. PyTorch를 활용한 간단한 모델 구현

PyTorch에서 딥러닝 모델을 직접 구현하고 학습하는 과정을 이해하는 것이 중요해.

2.1. 간단한 신경망 (MLP) 구현

import torch.nn as nn
import torch.optim as optim

# 간단한 MLP 모델
class SimpleMLP(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(SimpleMLP, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x

# 모델 생성
model = SimpleMLP(input_size=10, hidden_size=20, output_size=1)
print(model)

"""
SimpleMLP(
  (fc1): Linear(in_features=10, out_features=20, bias=True)
  (relu): ReLU()
  (fc2): Linear(in_features=20, out_features=1, bias=True)
)
"""

 

🎯 연습 문제

  • 입력 차원이 5이고 출력이 2인 다층 퍼셉트론(MLP) 을 직접 만들어 보고 forward-pass를 실행해 봐.
import torch.nn as nn
import torch.optim as optim

# simple MLP
class MyMLP(nn.Module):
  def __init__(self, input=5, hidden=10, output=2):
    super(MyMLP, self).__init__()

    self.fc1 = nn.Linear(input, hidden)
    self.relu = nn.ReLU()
    self.fc2 = nn.Linear(hidden, output)

  def forward(self, x):
    x = self.fc1(x)
    x = self.relu(x)
    x = self.fc2(x)
    return x

# create model
my_model = MyMLP()
my_model.eval()
print(my_model)

# create random data, batch 1, input 5
input_data = torch.rand(1, 5, dtype=torch.float32)
print(f"input_data: {input_data}")

# run forward-pass
out_put = my_model(input_data)

# print
print(f"MLP forward-pass: {out_put}")

"""
MyMLP(
  (fc1): Linear(in_features=5, out_features=10, bias=True)
  (relu): ReLU()
  (fc2): Linear(in_features=10, out_features=2, bias=True)
)
input_data: tensor([[0.0203, 0.0835, 0.7752, 0.7813, 0.6338]])
MLP forward-pass: tensor([[-0.2510,  0.3278]], grad_fn=<AddmmBackward0>)
"""

2.2. PyTorch로 간단한 선형 회귀 모델 학습

100개의 랜덤한 데이터를 사용하여 다음과 같은 선형 모델을 학습하려고 한다.

y = 2x + 3

- PyTorch를 사용하여 x_train과 y_train 데이터를 생성하시오.
- 위에서 생성한 데이터를 이용하여 PyTorch의 nn.Linear를 사용하여 선형 회귀 모델을 정의하시오.
- 또한, 손실 함수로 nn.MSELoss()를 설정하시오.
- 학습률(learning rate)이 0.1인 SGD(Stochastic Gradient Descent) 옵티마이저를 설정하시오.
- 에포크(epoch)를 100으로 설정하고, 모델을 학습하는 코드를 작성하고, 10 에포크마다 손실(loss)을 출력하시오.
- 학습이 완료된 후, model.parameters()를 이용하여 학습된 가중치(weight)와 편향(bias)을 출력하시오.
출력된 값이 실제 수식 y = 2x + 3 과 유사한지 확인하시오.

예제 출력 예시
```
Epoch 0: Loss = 4.531
Epoch 10: Loss = 0.312
Epoch 20: Loss = 0.058
...
Epoch 90: Loss = 0.004
Learned Parameters: [tensor(1.98), tensor(3.01)]

 

import torch
import torch.nn as nn
import torch.optim as optim

# 데이터 생성 (y = 2x + 3)
x_train = torch.randn(100, 1)
y_train = 2 * x_train + 3 # + 0.1 * torch.randn(100, 1)

# 모델 정의
model = nn.Linear(1, 1)
loss_fn = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)

# 학습 과정
for epoch in range(100):
    y_pred = model(x_train)
    loss = loss_fn(y_pred, y_train)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 10 == 0:
        print(f'Epoch {epoch}: Loss = {loss.item()}')

# 학습된 가중치 출력
print("Learned Parameters:", list(model.parameters()))


"""
Epoch 0: Loss = 19.1948
Epoch 10: Loss = 0.1817
Epoch 20: Loss = 0.0018
Epoch 30: Loss = 0.0000
Epoch 40: Loss = 0.0000
Epoch 50: Loss = 0.0000
Epoch 60: Loss = 0.0000
Epoch 70: Loss = 0.0000
Epoch 80: Loss = 0.0000
Epoch 90: Loss = 0.0000

Learned Weight: 2.0000
Learned Bias: 3.0000
"""

 

🎯 연습 문제

  • y = 3x^2 + 2x + 1 형태의 비선형 회귀 모델을 MLP로 구현해보고 학습해 봐.
import torch
import torch.nn as nn
import torch.optim as optim

torch.manual_seed(42)
# data
x_train = torch.rand(100, 1, dtype=torch.float32)
y_train = 3 * x_train**2 + 2*x_train + 1

# define Model
class myLiearModel(nn.Module):
  def __init__(self, input=1, hidden=10, output=1):
    super(myLiearModel, self).__init__()

    self.fc1 = nn.Linear(input, hidden)
    self.relu = nn.ReLU()
    self.fc2 = nn.Linear(hidden, output)

  def forward(self, x):
    x = self.fc1(x)
    x = self.relu(x)
    x = self.fc2(x)
    return x

myModel = myLiearModel()

# define loss, optimizer
loss_fn = nn.MSELoss()
optimiser = optim.SGD(params=myModel.parameters(), lr=0.1)

# train
train_epoches = 10000
for ep in range(train_epoches):
  y_pred = myModel(x_train)

  loss = loss_fn(y_pred, y_train)

  optimiser.zero_grad()
  loss.backward()
  optimiser.step()

  if ep % 1000 == 0:
    print(f"Epoch ({ep}): loss = {loss.item():.4f} ")

"""
Epoch (0): loss = 0.0042 
Epoch (1000): loss = 0.0022 
Epoch (2000): loss = 0.0022 
Epoch (3000): loss = 0.0022 
Epoch (4000): loss = 0.0022 
Epoch (5000): loss = 0.0022 
Epoch (6000): loss = 0.0022 
Epoch (7000): loss = 0.0022 
Epoch (8000): loss = 0.0022 
Epoch (9000): loss = 0.0022 
"""

 

학습 결과 확인

# train results

"""
torch.linspace(start, end, steps)
* torch.linspace(-2, 2, 100): -2에서 2까지 균등한 간격으로 100개의 숫자를 생성, 
* 즉, x_test 값은 -2, -1.96, -1.92, ..., 1.96, 2.0 이런 식으로 100개의 값이 생성

.reshape(-1, 1)
* .reshape(-1, 1)은 텐서의 차원을 변형하는 함수야.
* -1을 사용하면 PyTorch가 자동으로 적절한 크기를 맞춤.
* (100,) 형태의 1D 텐서를 (100,1) 형태의 2D 텐서로 변환.
"""
x_text = torch.linspace(-2, 2, 100).reshape(-1, 1)  # -2~2까지 균등간격의 100개 데이터 생성해서, 100x1 텐서 생성

y_test_pred = myModel(x_text).detach().numpy()

# 6. 예측 결과 시각화
import matplotlib.pyplot as plt 

plt.scatter(x_train.numpy(), y_train.numpy(), label="Train Data")
plt.plot(x_text.numpy(), y_test_pred, color="red", label="MLP Prediction")
plt.legend()
plt.title("Non-Linear Regression using MLP")
plt.show()

 

 

 


🔥 3. CNN을 이용한 이미지 분류

PyTorch에서는 torchvision을 이용해 이미지 데이터를 쉽게 다룰 수 있어.
아래 코드는 MNIST 손글씨 데이터셋을 활용한 CNN 모델을 구현하는 예제야.

 

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms

# MNIST 데이터셋 로드
transform = transforms.Compose([transforms.ToTensor()])
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)

# CNN 모델 정의
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
        self.relu = nn.ReLU()
        self.fc1 = nn.Linear(16 * 28 * 28, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.relu(x)
        x = x.view(x.size(0), -1)
        x = self.fc1(x)
        return x

model = SimpleCNN()
optimizer = optim.Adam(model.parameters(), lr=0.001)
loss_fn = nn.CrossEntropyLoss()

# 간단한 학습 루프
for epoch in range(1):
    for images, labels in trainloader:
        optimizer.zero_grad()
        outputs = model(images)
        loss = loss_fn(outputs, labels)
        loss.backward()
        optimizer.step()

print("Training Complete!")

 

🎯 연습 문제

  • 위 코드를 수정해서 2개의 컨볼루션 레이어를 가진 CNN 모델로 변경해 봐.

🔥 4. Transformer 기반 모델 구현

인터뷰에서 Transformer 관련 개념이 나올 가능성이 있으므로, 간단한 Self-Attention 구현도 연습해 두는 게 좋아.

import torch
import torch.nn as nn

class SelfAttention(nn.Module):
    def __init__(self, embed_size):
        super(SelfAttention, self).__init__()
        self.query = nn.Linear(embed_size, embed_size)
        self.key = nn.Linear(embed_size, embed_size)
        self.value = nn.Linear(embed_size, embed_size)
        self.softmax = nn.Softmax(dim=-1)

    def forward(self, x):
        Q = self.query(x)
        K = self.key(x)
        V = self.value(x)

        attention = self.softmax(Q @ K.transpose(-2, -1) / (x.size(-1) ** 0.5))
        return attention @ V

# 테스트
x = torch.randn(4, 10)  # (배치 크기, 임베딩 크기)
attention_layer = SelfAttention(embed_size=10)
output = attention_layer(x)
print(output.shape)

 

🎯 연습 문제

  • Transformer에서 Multi-Head Attention을 직접 구현해 봐.

🔥 5. PyTorch 실전 문제 대비

이제 실전 문제를 연습해 보자.

🔹 LeetCode에서 PyTorch 관련 문제: https://github.com/Exorust/TorchLeet

🔹 추가 연습 문제

  • ResNet-18을 PyTorch로 직접 구현하기
  • YOLO 같은 객체 탐지 모델의 기본 구조 이해

📌 정리

1️⃣ PyTorch 기본 문법 (텐서 조작, Autograd)
2️⃣ MLP, CNN, Transformer 등 간단한 모델 구현
3️⃣ PyTorch를 이용한 데이터 전처리 및 학습 루프 구현
4️⃣ 실전 문제를 연습하여 인터뷰 대비

이제 위 내용을 하나씩 연습해 보면 면접 준비에 도움이 될 거야! 🚀