# Part 7: 딥러닝 기초 실습 (PyTorch) # 이 스크립트를 실행하기 전에 라이브러리를 설치해야 합니다. # pip install torch torchvision scikit-learn import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, TensorDataset from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.datasets import load_iris from sklearn.metrics import accuracy_score import numpy as np # --- 1. 데이터 준비 및 전처리 --- print("--- 1. 데이터 준비 및 전처리 ---") # Scikit-learn에 내장된 붓꽃(Iris) 데이터셋 로드 iris = load_iris() X = iris.data y = iris.target # 훈련/테스트 데이터 분리 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y ) # 데이터 스케일링 scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) # PyTorch 텐서로 변환 X_train_tensor = torch.FloatTensor(X_train_scaled) y_train_tensor = torch.LongTensor(y_train) X_test_tensor = torch.FloatTensor(X_test_scaled) y_test_tensor = torch.LongTensor(y_test) # DataLoader 생성 # 딥러닝 모델은 보통 미니배치 단위로 학습하므로 DataLoader를 사용 train_dataset = TensorDataset(X_train_tensor, y_train_tensor) train_loader = DataLoader(dataset=train_dataset, batch_size=16, shuffle=True) print("PyTorch 텐서 및 DataLoader 준비 완료") print(f"훈련 데이터 크기: {X_train_tensor.shape}") print(f"훈련 타겟 크기: {y_train_tensor.shape}") print("-" * 30) # --- 2. 딥러NING 모델 정의 --- print("\n--- 2. 딥러닝 모델 정의 ---") class SimpleNN(nn.Module): def __init__(self, input_size, hidden_size, num_classes): super(SimpleNN, self).__init__() self.fc1 = nn.Linear(input_size, hidden_size) self.relu = nn.ReLU() self.fc2 = nn.Linear(hidden_size, num_classes) def forward(self, x): out = self.fc1(x) out = self.relu(out) out = self.fc2(out) return out # 모델 파라미터 설정 input_size = X_train.shape[1] # 특성의 수: 4 hidden_size = 32 num_classes = len(np.unique(y_train)) # 클래스의 수: 3 learning_rate = 0.01 num_epochs = 50 model = SimpleNN(input_size, hidden_size, num_classes) print("모델 구조:") print(model) print("-" * 30) # --- 3. 손실 함수 및 옵티마이저 정의 --- print("\n--- 3. 손실 함수 및 옵티마이저 정의 ---") # 다중 분류 문제이므로 CrossEntropyLoss 사용 criterion = nn.CrossEntropyLoss() # Adam 옵티마이저 사용 optimizer = optim.Adam(model.parameters(), lr=learning_rate) print(f"손실 함수: {criterion}") print(f"옵티마이저: {optimizer}") print("-" * 30) # --- 4. 모델 훈련 --- print("\n--- 4. 모델 훈련 ---") for epoch in range(num_epochs): for i, (features, labels) in enumerate(train_loader): # 순전파 (Forward pass) outputs = model(features) loss = criterion(outputs, labels) # 역전파 및 최적화 (Backward and optimize) optimizer.zero_grad() # 이전 그래디언트 초기화 loss.backward() # 그래디언트 계산 optimizer.step() # 가중치 업데이트 if (epoch + 1) % 10 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') print("모델 훈련 완료") print("-" * 30) # --- 5. 모델 평가 --- print("\n--- 5. 모델 평가 ---") # 모델을 평가 모드로 설정 (dropout, batchnorm 등 비활성화) model.eval() # 테스트 데이터로 예측 with torch.no_grad(): # 그래디언트 계산 비활성화 outputs = model(X_test_tensor) # 가장 높은 확률을 가진 클래스를 예측값으로 선택 _, predicted = torch.max(outputs.data, 1) accuracy = accuracy_score(y_test_tensor.numpy(), predicted.numpy()) print(f'테스트 데이터 정확도: {100 * accuracy:.2f}%') # 일부 예측 결과 확인 print("\n일부 샘플 예측 결과:") print(f"실제 값: {y_test_tensor[:10].numpy()}") print(f"예측 값: {predicted[:10].numpy()}") print("-" * 30)