2025. 1. 20. 14:17ㆍLLM(Large Language Model)의 기초/딥러닝
1. Alexnet
* AlexNet은 2012년 ILSVRC(ImageNet Large Scale Visual Recognition Challenge)에서 우승한 딥러닝 모델로, 딥러닝의 대중화를 이끈 중요한 합성곱 신경망(CNN)입니다.
* 이 모델은 8개의 레이어(5개의 합성곱 레이어와 3개의 완전 연결 레이어)로 구성되어 있으며, ReLU 활성화 함수, 드롭아웃(dropout), 데이터 증강(data augmentation) 등을 사용해 과적합을 방지하고 학습 성능을 향상시켰습니다.
* AlexNet은 대규모 데이터셋과 GPU 병렬 연산을 활용해 1,000개의 클래스 분류 문제에서 top-1, top-5 error rates가 각각 37.5%, 17.5%로 뛰어난 성능을 보여, 컴퓨터 비전에서 딥러닝이 표준 기법으로 자리 잡는 데 기여했습니다.
* 이 성과는 당시 기준으로 매우 뛰어난 결과였습니다.
* 특히 AlexNet은 이전에 사용된 전통적인 머신러닝 방법론보다 훨씬 큰 차이로 성능을 끌어올리며, 딥러닝의 가능성을 보여주었습니다
논문 링크 : https://papers.nips.cc/paper/2012/file/c399862d3b9d6b76c8436e924a68c45b-Paper.pdf
참고 링크 : https://pytorch.org/vision/stable/generated/torchvision.datasets.CIFAR10.html#torchvision.datasets.CIFAR10
※ ImageNet LSVRC
* ImageNet LSVRC는 Large Scale Visual Recognition Challenge의 약자로, 이미지 인식 및 분류 기술을 겨루는 대회입니다.
* 2010년부터 매년 개최되었으며, ImageNet이라는 대규모 이미지 데이터셋을 기반으로 참가자들이 다양한 모델을 설계하고 경쟁했습니다.
* ImageNet 데이터셋: 약 1400만 장의 이미지를 포함하며, 1000개의 클래스(예: 고양이, 강아지, 자동차 등)로 분류된 대규모 이미지 데이터셋입니다.
* 목적: 컴퓨터 비전 및 딥러닝 기술의 발전을 촉진하고, 이미지 인식 분야에서 혁신적인 기술을 발견하는 것이 목표였습니다.
* LSVRC-2010: 이 대회에서 AlexNet이 2012년에 처음으로 딥러닝 기반 접근법을 사용해 뛰어난 성능을 보여줌으로써 딥러닝의 새로운 시대를 열었습니다.
### Error Rate
* 이미지 분류 모델의 성능을 평가하는 지표로, 모델이 이미지를 얼마나 정확히 분류했는지를 나타냅니다.
1. Top-1 Error Rate
* 모델이 예측한 가장 높은 확률의 클래스(Top-1)가 정답이 아닐 확률입니다.
예를 들어, 이미지에 "고양이"가 있고, 모델이 가장 높은 확률로 "강아지"라고 예측했다면, 이건 Top-1 에러입니다.
2. Top-5 Error Rate
* 모델이 예측한 상위 5개의 클래스 중 하나라도 정답에 포함되지 않았을 확률입니다.
* 예를 들어, 이미지가 "고양이"인데 모델이 "강아지", "토끼", "고양이", "호랑이", "여우"를 상위 5개로 예측했다면, 이건 정답으로 간주됩니다.
* Top-5를 사용하는 이유: 사람이 보기에 유사한 클래스(예: 치타와 표범)를 분류하는 것은 어렵기 때문에, 상위 5개 중에 정답이 있는지를 확인하는 방식으로 보다 실용적인 성능을 평가합니다.
2. CIFAR 데이터셋
* CIFAR 데이터셋은 torchvision 라이브러리에서 제공하는 이미지 데이터셋으로, 주로 딥러닝 모델의 학습 및 평가에 사용됩니다.
* CIFAR-10과 CIFAR-100 두 종류가 있으며, 각각 10개와 100개의 클래스에 대해 32x32 크기의 컬러 이미지로 구성됩니다.
* CIFAR-10은 클래스당 6,000개(총 60,000개)의 이미지로 이루어져 있으며, CIFAR-100은 클래스당 600개(총 60,000개)로 구성됩니다.
* PyTorch는 torchvision.datasets 모듈을 통해 이 데이터셋을 쉽게 불러올 수 있으며, 학습/테스트 데이터셋 분리, 데이터 증강(transforms), 정규화 등의 전처리를 지원합니다.
* 이 데이터셋은 이미지 분류 알고리즘을 실험하고 비교하는 데 널리 사용됩니다.
3. Alexnet 직접 구현(CIFAR 데이터셋 사용)
링크 주소: https://pytorch.org/vision/stable/datasets.html
예시 1)
import numpy as np
import matplotlib.pyplot as plt
# PyTorch 라이브러리 import
import torch
from torch.utils.data import DataLoader
from torch import nn
# torchvision 라이브러리에서 데이터셋과 변환(transform)을 import
from torchvision import datasets
from torchvision.transforms import transforms
from torchvision.transforms.functional import to_pil_image
# CIFAR-10 데이터셋 로드 (학습용 데이터셋)
train_img = datasets.CIFAR10(
root='data', # 데이터를 저장할 경로
train=True, # 학습용 데이터셋을 다운로드
download=True, # 데이터셋이 없으면 다운로드
transform=transforms.ToTensor() # 이미지를 텐서(Tensor) 형태로 변환
)
# CIFAR-10 데이터셋 로드 (테스트용 데이터셋)
test_img = datasets.CIFAR10(
root='data', # 데이터를 저장할 경로
train=False, # 학습용 데이터셋을 다운로드
download=True, # 데이터셋이 없으면 다운로드
transform=transforms.ToTensor() # 이미지를 텐서(Tensor) 형태로 변환
)
예시 2)
# CIFAR-10 데이터셋의 채널별 평균과 표준편차 계산
mean = train_img.data.mean(axis=(0,1,2)) / 255 # 픽셀 값의 평균 계산 (0~255 범위를 0~1로 정규화)
std = train_img.data.std(axis=(0,1,2)) / 255 # 픽셀 값의 표준편차 계산 (0~255 범위를 0~1로 정규화)
print(f'평균:{mean}, 표준편차:{std}') # 계산된 평균과 표준편차 출력
--->
평균:[0.49139968 0.48215841 0.44653091], 표준편차:[0.24703223 0.24348513 0.26158784]
예시 3)
# 학습 데이터에 사용할 변환(transform) 정의
transform_train = transforms.Compose([
transforms.ToTensor(), # 이미지를 텐서(Tensor)로 변환
transforms.RandomCrop(size=train_img.data.shape[1], padding=4), # 이미지를 랜덤하게 자르고(padding 포함) 크기 유지
transforms.RandomHorizontalFlip(), # 이미지를 좌우로 랜덤하게 뒤집기
transforms.Normalize(mean, std) # 데이터 정규화 (평균과 표준편차를 이용해 스케일링)
])
# 테스트 데이터에 사용할 변환(transform) 정의
transform_test = transforms.Compose([
transforms.ToTensor(), # 이미지를 텐서(Tensor)로 변환
transforms.Normalize(mean, std) # 데이터 정규화 (평균과 표준편차를 이용해 스케일링)
])
예시 4)
# CIFAR-10 학습용 데이터셋 로드 (transform_train 적용)
train_img = datasets.CIFAR10(
root='data', # 데이터를 저장할 경로
train=True, # 학습용 데이터셋을 다운로드
download=True, # 데이터셋이 없으면 다운로드
transform=transform_train # 학습 데이터에 정의한 변환 적용
)
# CIFAR-10 테스트용 데이터셋 로드 (transform_test 적용)
test_img = datasets.CIFAR10(
root='data', # 데이터를 저장할 경로
train=False, # 학습용 데이터셋을 다운로드
download=True, # 데이터셋이 없으면 다운로드
transform=transform_test # 테스트 데이터에 정의한 변환 적용
)
예시 5)
# 학습 관련 설정
EPOCH = 10 # 전체 학습 반복(epoch) 수
BATCH_SIZE = 128 # 한 번의 학습에 사용할 배치 크기
LEARNING_RATE = 1e-3 # 학습률(learning rate)
# 학습에 사용할 디바이스 설정 (GPU가 사용 가능하면 GPU 사용, 아니면 CPU 사용)
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") # CUDA 사용 가능 여부 확인
print("Using Device:", DEVICE) # 선택된 디바이스 출력
예시 6)
# DataLoader를 사용하여 학습 데이터와 테스트 데이터를 배치 단위로 로드
train_loader = DataLoader(
train_img, # 학습용 데이터셋
batch_size=BATCH_SIZE, # 배치 크기 설정
shuffle=True # 데이터를 섞어서 로드 (학습에 유리)
)
test_loader = DataLoader(
test_img, # 테스트용 데이터셋
batch_size=BATCH_SIZE, # 배치 크기 설정
shuffle=False # 데이터를 섞지 않고 로드 (평가 시 순서 유지)
)
# 학습 데이터셋과 테스트 데이터셋 정보를 출력
print(train_img, '\n------------------\n', test_img)
--->
Dataset CIFAR10
Number of datapoints: 50000
Root location: data
Split: Train
StandardTransform
Transform: Compose(
ToTensor()
RandomCrop(size=(32, 32), padding=4)
RandomHorizontalFlip(p=0.5)
Normalize(mean=[0.49139968 0.48215841 0.44653091], std=[0.24703223 0.24348513 0.26158784])
)
------------------
Dataset CIFAR10
Number of datapoints: 50000
Root location: data
Split: Train
StandardTransform
Transform: Compose(
ToTensor()
Normalize(mean=[0.49139968 0.48215841 0.44653091], std=[0.24703223 0.24348513 0.26158784])
)
예시 7)
# 학습 데이터셋의 첫 번째 샘플 가져오기
# train_img[0]은 CIFAR-10 데이터셋의 첫 번째 샘플을 반환
# 반환값은 (이미지, 레이블)의 튜플로 구성됨
first_sample = train_img[0] # 첫 번째 샘플 가져오기
# first_sample의 구조: (이미지 텐서, 정수형 레이블)
# 예: CIFAR-10의 경우, 이미지 텐서는 (채널, 높이, 너비)의 형태를 가지며 레이블은 해당 이미지의 클래스 정보
-->
(tensor([[[-1.9892e+00, 3.6025e-01, 4.2375e-01, ..., -9.0973e-01,
-1.1955e+00, -1.3066e+00],
[-1.9892e+00, -5.2496e-02, -1.0012e-01, ..., -1.1796e+00,
-1.7035e+00, -1.9892e+00],
[-1.9892e+00, -2.5887e-01, -8.4246e-02, ..., -6.7161e-01,
-1.2114e+00, -1.7352e+00],
...,
[-1.9892e+00, -1.1479e+00, -1.1002e+00, ..., 1.0429e+00,
1.1540e+00, 1.2016e+00],
[-1.9892e+00, -6.7161e-01, -4.4936e-01, ..., 1.0905e+00,
9.6349e-01, 7.5711e-01],
[-1.9892e+00, -3.6622e-02, 4.0787e-01, ..., 9.9524e-01,
8.5236e-01, 6.7774e-01]],
[[-1.9802e+00, 1.6905e-02, 3.3011e-02, ..., -1.1105e+00,
-1.2072e+00, -1.2394e+00],
[-1.9802e+00, -5.7902e-01, -6.4344e-01, ..., -1.5454e+00,
-1.8514e+00, -1.9802e+00],
[-1.9802e+00, -8.0450e-01, -6.2733e-01, ..., -1.1749e+00,
-1.5454e+00, -1.8675e+00],
...,
[-1.9802e+00, -1.4326e+00, -1.4810e+00, ..., 5.4840e-01,
6.1283e-01, 4.8398e-01],
[-1.9802e+00, -1.1266e+00, -9.8167e-01, ..., 4.8398e-01,
3.3902e-01, 7.9890e-04],
[-1.9802e+00, -4.9849e-01, -7.9731e-02, ..., 4.1955e-01,
3.0681e-01, 9.7435e-02]],
[[-1.7070e+00, -1.6289e-01, -1.7788e-01, ..., -1.0774e+00,
-1.0624e+00, -1.0324e+00],
[-1.7070e+00, -8.5249e-01, -9.5743e-01, ..., -1.5871e+00,
-1.7070e+00, -1.7070e+00],
[-1.7070e+00, -1.0774e+00, -9.5743e-01, ..., -1.3622e+00,
-1.5871e+00, -1.7070e+00],
...,
[-1.7070e+00, -1.4072e+00, -1.6021e+00, ..., -1.3022e+00,
-1.3172e+00, -1.1973e+00],
[-1.7070e+00, -1.1973e+00, -1.1973e+00, ..., -1.3322e+00,
-1.2573e+00, -1.0774e+00],
[-1.7070e+00, -6.2762e-01, -4.4772e-01, ..., -7.0258e-01,
-4.0275e-01, -2.9781e-01]]]),
6)
예시 8)
# 학습 데이터에서 첫 번째 배치 가져오기
# DataLoader를 통해 배치 단위로 데이터를 로드하고, 첫 번째 배치를 가져옴
train_features, train_labels = next(iter(train_loader))
# train_features: 배치에 포함된 이미지 데이터 (배치 크기, 채널, 높이, 너비)
# train_labels: 배치에 포함된 레이블 데이터 (배치 크기)
# 배치의 크기 및 구조 출력
print(f'Feature batch shape: {train_features.size()}') # 이미지 텐서의 크기 출력
print(f"Labels batch shape: {train_labels.size()}") # 레이블 텐서의 크기 출력
--->
eature batch shape: torch.Size([128, 3, 32, 32])
Labels batch shape: torch.Size([128])
예시 9)
# CIFAR-10 데이터셋의 레이블과 클래스 이름을 매핑하는 딕셔너리 정의
labels_map = {
0: "plane", # 클래스 0: 비행기
1: "car", # 클래스 1: 자동차
2: "bird", # 클래스 2: 새
3: "cat", # 클래스 3: 고양이
4: "deer", # 클래스 4: 사슴
5: "dog", # 클래스 5: 개
6: "frog", # 클래스 6: 개구리
7: "horse", # 클래스 7: 말
8: "ship", # 클래스 8: 배
9: "truck", # 클래스 9: 트럭
}
예시 10)
# 정규화된 이미지를 원래 픽셀 값으로 되돌리는 함수 정의
def denormalize(img, mean, std):
# mean과 std를 텐서 형태로 변환하고 이미지와 동일한 차원으로 맞춤
mean = torch.tensor(mean).view(3, 1, 1) # 3: 이미지 채널, 1: 공간 차원(높이와 너비)
std = torch.tensor(std).view(3, 1, 1) # 3: 이미지 채널, 1: 공간 차원(높이와 너비)
# 정규화된 이미지에 표준편차를 곱하고 평균을 더해 원래 값으로 복원
return img * std + mean
예시 11)
import torch
import matplotlib.pyplot as plt
from torchvision.transforms.functional import to_pil_image
# PyTorch에서 사용할 데이터셋과 관련된 설정 (가정: train_img, mean, std, labels_map이 이미 정의되어 있음)
figure = plt.figure(figsize=(8, 8)) # 그림 크기를 8x8로 설정
cols, rows = 5, 5 # 5x5 격자에 이미지를 표시하기 위한 열과 행의 수
for i in range(1, cols * rows + 1): # 총 25개의 이미지를 표시하기 위해 반복문 실행
# 데이터셋에서 랜덤한 인덱스 선택
sample_idx = torch.randint(len(train_img), size=(1,)).item()
# 선택한 인덱스의 이미지와 라벨 가져오기
img, label = train_img[sample_idx]
# denormalize: 이미지를 복원 (normalize 과정을 역으로 수행)
img = denormalize(img, mean, std) # denormalize 함수는 사용자 정의 함수라고 가정
# 행렬에 subplot 추가 (5x5 격자의 i번째 위치)
figure.add_subplot(rows, cols, i)
# subplot에 라벨(title) 추가 (라벨을 labels_map에서 매핑)
plt.title(labels_map[label])
# 축 숨김
plt.axis('off')
# 텐서를 PIL 이미지로 변환 후 subplot에 표시
# to_pil_image: 텐서를 PIL 이미지로 변환하는 함수
# 텐서 이미지는 0~1 또는 0~255 범위를 가져야 함
plt.imshow(to_pil_image(img))
# 모든 subplot을 화면에 표시
plt.show()
--->
예시 12)
import torch
import torch.nn as nn
# AlexNet 모델 정의
class AlexNet(nn.Module):
def __init__(self, num_classes=10):
super(AlexNet, self).__init__()
# 특징 추출 부분 (Feature Extractor)
self.features = nn.Sequential(
# 첫 번째 합성곱 계층 (Conv1)
nn.Conv2d(3, 96, kernel_size=3, stride=1, padding=1), # 입력 채널: 3, 출력 채널: 96, 커널 크기: 3x3, 스트라이드: 1, 패딩: 1
nn.ReLU(inplace=True), # 활성화 함수 ReLU
nn.MaxPool2d(kernel_size=2, stride=2), # 첫 번째 최대 풀링 계층 (2x2 커널, 스트라이드 2)
# 두 번째 합성곱 계층 (Conv2)
nn.Conv2d(96, 256, kernel_size=3, padding=1), # 입력 채널: 96, 출력 채널: 256, 커널 크기: 3x3, 패딩: 1
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2), # 두 번째 최대 풀링 계층
# 세 번째 합성곱 계층 (Conv3)
nn.Conv2d(256, 384, kernel_size=3, padding=1), # 입력 채널: 256, 출력 채널: 384, 커널 크기: 3x3, 패딩: 1
nn.ReLU(inplace=True),
# 네 번째 합성곱 계층 (Conv4)
nn.Conv2d(384, 384, kernel_size=3, padding=1), # 입력 채널: 384, 출력 채널: 384, 커널 크기: 3x3, 패딩: 1
nn.ReLU(inplace=True),
# 다섯 번째 합성곱 계층 (Conv5)
nn.Conv2d(384, 256, kernel_size=3, padding=1), # 입력 채널: 384, 출력 채널: 256, 커널 크기: 3x3, 패딩: 1
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2), # 세 번째 최대 풀링 계층
)
# 분류기 부분 (Classifier)
self.classifier = nn.Sequential(
nn.Linear(256 * 4 * 4, 4096), # 첫 번째 완전 연결 계층 (Flatten 크기: 256*4*4 -> 4096)
nn.Dropout(0.5), # 드롭아웃 계층 (50% 확률로 뉴런 비활성화)
nn.ReLU(inplace=True), # 활성화 함수 ReLU
nn.Linear(4096, 4096), # 두 번째 완전 연결 계층
nn.Dropout(0.5), # 드롭아웃 계층
nn.ReLU(inplace=True),
nn.Linear(4096, num_classes), # 세 번째 완전 연결 계층 (출력: 클래스 수)
)
# 순전파(Forward) 정의
def forward(self, x):
x = self.features(x) # 특징 추출
x = x.view(x.size(0), -1) # Flatten (다차원 텐서를 1차원으로 펼침)
x = self.classifier(x) # 분류 수행
return x
예시 13)
# Model instance 생성 및 Device로 이동
model = AlexNet().to(DEVICE) # AlexNet 인스턴스를 생성하고, DEVICE로 이동 (GPU 또는 CPU)
print(model) # 모델의 구조 출력
--->
AlexNet(
(features): Sequential(
(0): Conv2d(3, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(96, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(256, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): ReLU(inplace=True)
(8): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(classifier): Sequential(
(0): Linear(in_features=4096, out_features=4096, bias=True)
(1): Dropout(p=0.5, inplace=False)
(2): ReLU(inplace=True)
(3): Linear(in_features=4096, out_features=4096, bias=True)
(4): Dropout(p=0.5, inplace=False)
(5): ReLU(inplace=True)
(6): Linear(in_features=4096, out_features=10, bias=True)
)
)
예시 14)
# 손실 함수 설정
loss = nn.CrossEntropyLoss() # 교차 엔트로피 손실 함수, 분류 문제에서 주로 사용
# 최적화 알고리즘 설정
optimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE) # Adam 최적화 알고리즘, 학습률은 LEARNING_RATE로 설정
예시 15)
# 모델 학습 함수 정의
def train(train_loader, model, loss_fn, optimizer):
model.train() # 모델을 학습 모드로 설정
size = len(train_loader.dataset) # 전체 학습 데이터 크기
for batch, (X, y) in enumerate(train_loader): # 배치 단위로 데이터 로드
X, y = X.to(DEVICE), y.to(DEVICE) # 입력 데이터(X)와 라벨(y)를 DEVICE로 이동
pred = model(X) # 모델을 통해 예측 수행
# 손실 계산
loss = loss_fn(pred, y)
# 역전파 단계
optimizer.zero_grad() # 이전 단계에서의 그래디언트 초기화
loss.backward() # 그래디언트 계산
optimizer.step() # 파라미터 업데이트
# 100번째 배치마다 손실 정보 출력
if batch % 100 == 0:
loss, current = loss.item(), batch * len(X)
print(f'loss: {loss:>7f} [{current:>5d}]/{size:5d}')
예시 16)
# 모델 테스트 함수 정의
def test(test_loader, model, loss_fn):
model.eval() # 모델을 평가 모드로 설정
size = len(test_loader.dataset) # 전체 테스트 데이터 크기
num_batches = len(test_loader) # 배치 개수
test_loss, correct = 0, 0 # 초기화
with torch.no_grad(): # 그래디언트 계산 비활성화 (평가 시 필요 없음)
for X, y in test_loader: # 배치 단위로 데이터 로드
X, y = X.to(DEVICE), y.to(DEVICE) # 입력 데이터(X)와 라벨(y)를 DEVICE로 이동
pred = model(X) # 모델을 통해 예측 수행
test_loss += loss_fn(pred, y).item() # 배치 손실 계산 및 누적
correct += (pred.argmax(1) == y).type(torch.float).sum().item() # 올바른 예측 개수 누적
test_loss /= num_batches # 평균 손실 계산
correct /= size # 정확도 계산
print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:8f}\n") # 결과 출력
예시 17)
# 모델 학습 및 평가 루프
for i in range(EPOCH): # 전체 학습 epoch 반복
print(f"Epoch {i+1} \n------------------------") # 현재 epoch 출력
train(train_loader, model, loss, optimizer) # 학습 단계 실행
test(test_loader, model, loss) # 평가 단계 실행
print("Done!") # 학습 완료 메시지 출력
-->
Epoch 10
------------------------
loss: 0.652419 [ 0]/50000
loss: 0.723971 [12800]/50000
loss: 0.659195 [25600]/50000
loss: 0.767987 [38400]/50000
Test Error:
Accuracy: 78.6%, Avg loss: 0.616753
Done!
### itertools
* 파이썬 표준 라이브러리 모듈로 반복과 관련된 효율적이고 고성능의 도구를 제공합니다.
다양한 반복 가능한 객체나 순열, 조합을 생성하거나 조작하는 함수들을 포함하고 있습니다.
예시 1)
from itertools import product, permutations, combinations, islice
#데카르트 곱
# 데카르트 곱 계산 예제
color = ['red', 'blue'] # 색상 리스트
size = ['S', 'M', 'L'] # 사이즈 리스트
# itertools.product: 두 리스트의 모든 조합(데카르트 곱)을 생성
result = list(product(color, size)) # 색상과 사이즈의 가능한 모든 조합 생성
print(result) # 결과 출력
-->
[('red', 'S'), ('red', 'M'), ('red', 'L'), ('blue', 'S'), ('blue', 'M'), ('blue', 'L')]
예시 2)
# 순열
# 순열 계산 예제
number = [1, 2, 3] # 숫자 리스트
perm = list(permutations(number, 2)) # 길이가 2인 순열 생성
print(perm) # 결과 출력
--->
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
예제 3)
# 조합
# 조합 계산 예제
letter = ['A', 'B', 'C'] # 문자 리스트
comb = list(combinations(letter, 2)) # 길이가 2인 조합 생성
print(comb) # 결과 출력
-->
[('A', 'B'), ('A', 'C'), ('B', 'C')]
예제 4)
# 슬라이싱
number = range(10)
#2부터 7까지, 간격을 2로 설정
sliced = list(islice(number, 2, 8, 2))
print(sliced)
--->
[2, 4, 6]
예제 5)
import itertools
# 혼동 행렬 시각화 함수 정의
def plot_confusion_matrix(cm, target_names=None, cmap=None,
normalize=True, labels=True, title='Confusion matrix'):
# np.trace: 혼돈 행렬의 대각선 요소 합을 계산하여 정확도 추출
accuracy = np.trace(cm) / float(np.sum(cm)) # 정확도 계산
misclass = 1 - accuracy # 오분류율 계산
# 색상 맵 설정
if cmap is None:
cmap = plt.get_cmap('Blues')
# 정규화 옵션이 활성화된 경우 행별로 값을 정규화
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis] # 각 행의 합으로 나눔
# 그래프 생성
plt.figure(figsize=(8, 6))
plt.imshow(cm, interpolation='nearest', cmap=cmap) # 픽셀 간 간격 최소화
plt.title(title)
plt.colorbar() # 범례 추가
# 기준 임계값 설정
thresh = cm.max() / 1.5 if normalize else cm.max() / 2
# 클래스 이름이 주어진 경우 축 레이블 추가
if target_names is not None:
tick_marks = np.arange(len(target_names))
plt.xticks(tick_marks, target_names)
plt.yticks(tick_marks, target_names)
# 각 셀에 레이블 표시 (정규화 여부에 따라 다르게 표시)
if labels:
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
if normalize:
plt.text(j, i, "{:0.4f}".format(cm[i, j]),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
else:
plt.text(j, i, "{:,}".format(cm[i, j]),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
# 레이아웃 정렬 및 축 레이블 설정
plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass))
plt.show()
예제 6)
from sklearn.metrics import confusion_matrix
# 혼동 행렬 계산 및 모델 평가 코드
model.eval() # 모델을 평가 모드로 설정
ylabel = [] # 실제 라벨을 저장할 리스트
ypred_label = [] # 예측된 라벨을 저장할 리스트
# 테스트 데이터 로더를 순회하며 예측 수행
for batch_idx, (inputs, targets) in enumerate(test_loader):
inputs, targets = inputs.to(DEVICE), targets.to(DEVICE) # 입력과 타겟 데이터를 DEVICE로 이동
outputs = model(inputs) # 모델을 통해 예측 수행
_, predicted = outputs.max(1) # 예측값에서 가장 높은 확률의 클래스 선택
# 실제 타겟과 예측된 값을 리스트에 추가 (CPU로 이동하여 numpy 배열로 변환)
ylabel = np.concatenate((ylabel, targets.cpu().numpy()))
ypred_label = np.concatenate((ypred_label, predicted.cpu().numpy()))
# 혼동 행렬 계산
cnf_matrix = confusion_matrix(ylabel, ypred_label) # 실제 값과 예측 값을 기반으로 혼동 행렬 생성
예제 7)
ylabel
-->
array([6., 9., 9., ..., 9., 1., 1.])
예제 8)
ypred_label
-->
array([5., 9., 9., ..., 9., 1., 8.])
예제 9)
# 혼동 행렬 계산
cnf_matrix = confusion_matrix(ylabel, ypred_label) # 실제 값과 예측 값을 기반으로 혼동 행렬 생성
cnf_matrix
-->
array([[4234, 91, 199, 44, 48, 14, 7, 37, 237, 89],
[ 54, 4607, 13, 10, 5, 10, 6, 6, 86, 203],
[ 297, 33, 3739, 142, 334, 179, 130, 90, 37, 19],
[ 137, 27, 322, 2484, 338, 1206, 124, 221, 86, 55],
[ 116, 7, 276, 91, 4150, 125, 72, 131, 22, 10],
[ 54, 10, 280, 410, 287, 3620, 28, 279, 16, 16],
[ 53, 83, 317, 210, 336, 167, 3742, 38, 27, 27],
[ 92, 11, 147, 88, 498, 188, 8, 3912, 11, 45],
[ 233, 95, 45, 21, 25, 14, 10, 8, 4504, 45],
[ 105, 330, 20, 35, 19, 19, 7, 39, 131, 4295]])
예제 10)
plot_confusion_matrix(cnf_matrix,
target_names=labels_map.values(),
title='Confusion matrix, trained by AlexNet')
---->
'LLM(Large Language Model)의 기초 > 딥러닝' 카테고리의 다른 글
6. Alien vs. Predator 데이터셋 (2) | 2025.01.21 |
---|---|
5. 손글씨 도형 분류 FastAPI로 서빙 (2) | 2025.01.20 |
4. 손글씨 도형 분류하기 (2) | 2025.01.16 |
3. CNN(Convolutional Neural Network, 합성곱 신경망) (2) | 2025.01.15 |
2. Multi-class Weather Dataset (2) | 2025.01.14 |