AI 부트캠프 - 13일차

Cookie Baking·2024년 10월 18일

AI 부트 캠프 TIL

목록 보기
12/42
ANN은 입력층, 은닉층, 출력층으로 구성된 컴퓨팅 시스템이다.
  • 입력층 : 입력층의 뉴런수는 입력데이터 피쳐수와 동일

  • 은닉층 : 은닉층의 뉴런수와 층수는 모델의 복잡성과 성능에 영향

  • 출력층 : 출력층의 뉴런 수는 예측하려는 클래스 수 또는 회귀문제 출력차원과 동일

동작 방식

  1. 순전파 (Forward Propagation)
    각 뉴런은 입력 값에 가중치(weight)를 곱하고, 바이어스(bias)를 더한 후 활성화 함수(activation function)를 통해 출력 값을 결정함

  2. 손실계산
    예측값과 실제 값의 차이를 손실 함수로 계산함

  3. 역전파 (Backpropagation)
    손실 함수의 기울기를 출력층에서 입력층 방향으로 계산하고, 이를 바탕으로 가중치를 업데이트 함

필요한 라이브러리 임포트

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

데이터 셋 로드 및 전처리

# 데이터셋 전처리
# 입력데이터를 정규화해주는 과정임
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

# MNIST 데이터셋 로드

# 학습 dataset 
# trainset: shuffle을 이용해 섞어줌
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)

testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)

ANN 모델의 정의

# nnModule은 모든 신경망 모듈의 기본 클래스를 말함
# nn.Linear은 선형 변환을 적용하는 완전 연결 레이어를 정의함
# relu 함수 (입력 값이 조건에 걸리는 지 여부에 따라 출력하는 값을 달리하는 함수)
# view : 텐서의 크기를 변경함 (입력 이미지를 특정 벡터로 변환)


class SimpleANN(nn.Module):

	# 레이어 정의에 해당
    def __init__(self):
        super(SimpleANN, self).__init__()
        self.fc1 = nn.Linear(28 * 28, 128)  # 입력층에서 은닉층으로
        self.fc2 = nn.Linear(128, 64)       # 은닉층에서 은닉층으로
        self.fc3 = nn.Linear(64, 10)        # 은닉층에서 출력층으로

	# 자동적으로 레이어 간의 연결관계를 설정
    def forward(self, x):
    
    	# 차원 변경해주는 view함수
        # 배치의 차원은 알아서 정의해줌 
        # -1이란 2차원 데이터를 기준으로 변환할 데이터를 알아서 결정하라는 의미 (자동으로 주어진 값에 따라 차원을 결정함)
        x = x.view(-1, 28 * 28)  # 입력 이미지를 1차원 벡터로 변환
        
        # 연결관계 명시
        # 선형 -> 비선형 활성화 함수 
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        # 로짓
        x = self.fc3(x)
        return x

모델 학습

  • 다중 클래스 분류 문제에서 주로 사용되는 손실 함수,
    예측 값과 실제 값 사이의 교차 엔트로피 손실을 계산함: nn.CrossEntropyLoss

  • optim.SGD : 확률적 경사 하강법 최적화 알고리즘을 정의함

  • 기울기는 초기화가 진행되며 가중치 자체는 초기화된 기울기를 기반으로 업데이트 되는 것임

# 모델 초기화
model = SimpleANN()

# 손실 함수와 최적화 알고리즘 정의

# 분류모델에서 손실함수 계산 : CrossEntropy
# 실제로 어떻게 다르냐를 측정
criterion = nn.CrossEntropyLoss()
# 가중치를 업데이트할 때 사용
# 경사하강법 (SGD 사용, lr은 모멘텀으로 지역최적값에 갇치지 않게 해줌)
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 모델 학습
for epoch in range(10):  # 10 에포크 동안 학습
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data

        # 기울기 초기화 (이전 배치에서 계산된 기울기를 지워주는 것일 뿐, 모델의 가중치 자체는 업데이트되는 것임)
        optimizer.zero_grad()

        # 순전파 + 역전파 + 최적화
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        # 역전파를 통해 기울기를 계산
        loss.backward()
        # 계산된 기울기를 바탕으로 가중치를 업데이트함
        optimizer.step()

        # 손실 출력
        running_loss += loss.item()
        if i % 100 == 99:  # 매 100 미니배치마다 출력
            print(f'[Epoch {epoch + 1}, Batch {i + 1}] loss: {running_loss / 100:.3f}')
            running_loss = 0.0

print('Finished Training')

모델 평가

correct = 0
total = 0
# 평가 단계에서는 기울기를 계산할 필요가 없으므로, 이를 비활성
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = model(images)
        # 텐서의 최대 값을 찾음
        # 지정한 차원(1)에서 (위에서 데이터가 2차원이기 때문에 1차원까지의 최댓값이 유의미하게 사용되겠음)
        예측한 값들 가운데 가장 높은 값을 가지는 클래스의 인덱스를 반환함 (prediced에대가)
        _, predicted = torch.max(outputs.data, 1)
        # 배치 크기를 반환함
        total += labels.size(0)
        # 예측 값과 실제 값이 일치하는 샘플의 수를 계산함
        correct += (predicted == labels).sum().item()

print(f'Accuracy of the network on the 10000 test images: {100 * correct / total:.2f}%')
torch.max(outputs.data,1) 에 대한 이해

outputs = tensor([[0.1, 0.3, 0.6],   # 첫 번째 샘플에 대한 예측
                  [0.2, 0.5, 0.3]])  # 두 번째 샘플에 대한 예측
                  
torch.max(outputs,1)
# [2,1]

합성곱 신경망 (CNN)

합성곱 신경망이란
  • 이미지에 특화 (2차원 데이터 분석)

  • 출력 레이어로 ANN 사용해야 함

  • CNN은 ANN보다 함께 보는 접근이기 때문에 특징맵을 잘 뽑아낼 수 있다는 것이 특징임

  • CNN - Pool - CNN으로 확장할 수 있다는 장점이 있음

  • Pool링 레이어의 크기를 줄이고 늘리는 역할은 padding이 함

풀링 레이어의 필요성과 종류

  • 풀링 층은 특징 맵의 크기를 줄이고, 중요한 특징을 추출하는 역할을 함
  • 풀링 층은 주로 Max Pooling과 Average Pooling이 사용됨 (중요한 특징만을 추출)
  • 이미지가 몇 차원으로 이루어졌느냐가 채널임
  • 최종 출력으로는 ANN으로 보내기 위한 1차원 처리를 하게 되는 데 이때에는 1차원의 데이터가 아닌 "축약된" 정보를 보내는 것임
  • 출력 채널의 개수를 증가할 수 있는 이유는 필터의 개수를 조절할 수 있기 때문임 (독립적 사용 가능)
  • 필터 내부의 값을 학습한다는 점에서 ANN과의 차이점이 있음

이해

  • ANN은 모든 데이터를 일차원으로 변환한 후, 모든 픽셀 값을 입력으로 넣고 그에 해당하는 가중치를 학습함
  • 이에 반해 CNN은 차원은 유지한 채 필터라는 작은 크기의 행렬을 사용해 합성곱 연산을 통해 특징을 추출하는 학습이 진행되는 것임 ( 내부 필터의 가중치 최적화가 목적 )
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 32, 3, padding=1)  # 입력 채널 3, 출력 채널 32, 커널 크기 3x3
        self.pool = nn.MaxPool2d(2, 2)               # 풀링 크기 2x2
       		# 필터 차원으로 동작하기 때문에 입력 차원과 출력차원은 독립적으로 동작 가능함
        	# 컬러여서 채널의 차원이 3
        self.conv2 = nn.Conv2d(32, 64, 3, padding=1) # 입력 채널 32, 출력 채널 64, 커널 크기 3x3
        self.fc1 = nn.Linear(64 * 8 * 8, 512)        # 완전 연결 층
        self.fc2 = nn.Linear(512, 10)                # 출력 층 (10개의 클래스)

    def forward(self, x):
    	# forward 함수 내에는 활성화 함수가 항상 존재해야 함
        x = self.pool(torch.relu(self.conv1(x)))
        x = self.pool(torch.relu(self.conv2(x)))
        # For ANN
        x = x.view(-1, 64 * 8 * 8)  # 플래튼
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x

모델학습

# 모델 초기화
model = SimpleCNN()

# 손실 함수와 최적화 알고리즘 정의
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 모델 학습
for epoch in range(10):  # 10 에포크 동안 학습
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data

        # 기울기 초기화
        optimizer.zero_grad()

        # 순전파 + 역전파 + 최적화
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # 손실 출력
        running_loss += loss.item()
        if i % 100 == 99:  # 매 100 미니배치마다 출력
            print(f'[Epoch {epoch + 1}, Batch {i + 1}] loss: {running_loss / 100:.3f}')
            running_loss = 0.0

print('Finished Training')


correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy of the network on the 10000 test images: {100 * correct / total:.2f}%')

순환 신경망 (RNN)

순환 신경망의 개념
  • 이전 정보를 반영하는 Sequential 데이터에 적합한 신경망 (순서가 필요한 데이터를 처리할 때에 유용함)
  • 모든 시점에서의 가중치를 업데이트 함
  • 소실되어야 하는 정보도 존재하긴 함, but 이는 최종 결과에 미치는 영향을 보고 결정해야 할 것임 (RNN이 sequential 데이터이기 때문에 발생하는 문제임)

LSTM

  • 셀 : 각 시점에서 정보의 흐름을 제어함
  • 게이트를 통해 셀이 얼마나 반영될 지를 결정함 (정보를 선택적으로 결정함)
    입력 게이트(새로운 정보가 셀에 얼마나 반영할 수 있을지를 반영) / 망각 게이트
  • For 장기 의존성

GRU

  • LSTM의 변형
  • update는 상태를 선택적으로 기억함
  • 이전 정보를 얼마나 잊을 지를 판단해 reset함
  • 새로운 정보는 그 중요도에 따라 update함
  • LSTM이랑은 다른 점은 단일 게이트를 사용한다는 점임

이해
BackPropagation은 함수를 계산할 때 가중치들을 조절해서 함수가 최소가 되도록 조절하는 역할을 함
단 RNN에서는 이 가중치들을 조절하는 LSTM, GRU가 존재하는 것임

시계열 데이터 처리

  • pytorch에서 tensor란 기울기를 계산하는 것임

  • 은닉 상태는 이전 정보를 바탕으로 만들어지는 것을 말함


Attention 메커니즘

  • Attention 메커니즘은 시퀀스 데이터에서 중요한 부분에 더 많은 가중치를 할당하여 정보를 효율적으로 처리하는 기법

  • 주로 자연어 처리와 시계열 데이터에서 사용되며, 기계 번역, 요약, 질의응답 시스템 등 다양한 분야에서 뛰어난 성능을 발휘함

  • 중요한 부분에 가중치를 할당할 수 있는 메커니즘

  • 그렇다면 이 중요한 정도는 어떻게 평가하느냐? -> 답과 질문을 갖고 평가함!
    질문 : query
    답 : key
    최종 요약 : value

    query와 key/value 간의 유사도를 판단함 (dot product)

    Self-Attention

  • Self-Attention은 시퀀스 내의 각 요소가 서로를 참조하는 매커니즘임

  • 입력 시퀀스의 모든 요소가 Query, Key, Value로 사용됨

  • 각 요소가 시퀀스 내 다른 요소들과의 관계를 학습할 수 있음

    Multi-Head Attention

  • Multi-Head Attention은 여러 개의 Self-Attention을 병렬로 수행하는 매커니즘임

  • 각 헤드는 서로 다른 부분의 정보를 학습하며, 이를 통해 모델이 다양한 관점에서 데이터를 처리할 수 있음

    중요도를 가중치로 바꾸는 것은 softmax 함수가 해주겠음


워드 임베딩 기법

  • 워드 임베딩은 단어를 고정된 크기의 벡터로 변환하는 기법으로, 단어 간의 의미적 유사성을 반영함
  • 대표적인 워드 임베딩 기법으로는 Word2Vec과 GloVe가 있음
  • 단어간의 의미적 유사성을 반영하여 벡터로 변환하는 것이 주요 포인트가 되겠음

Word2Vec

CBOW

  • 주변 단어를 보고 중심 단어를 예측함

Skip - Gram

  • 중심 단어를 보고 주변 단어를 예측함

GloVe

  • 단어-단어 공기행렬을 사용하여 단어를 예측함

학습한 단어는 벡터로 변환됨


시퀀스 모델

  • 입력 시퀀스 : 시퀀스 모델링에서는 입력 데이터가 순차적인 형태로 제공됨
  • 은닉 상태 : 순환 신경망은 이전 시간 단계의 은닉 상태를 현재 시간 단계로 전달하여, 시퀀스의 패턴을 학습함
  • 출력 시퀀스 : 시퀀스 모델링의 출력은 입력 시퀀스와 동일한 길이의 시퀀스일 수도 있고, 단일 값일 수도 있음

Transformer

  • Transformer는 순차적인 데이터를 병렬로 처리할 수 있는 모델로, 자연어 처리에서 뛰어난 성능을 보임
  • 각 벡터들은 서로의 관계를 반영한 벡터 모델을 만듦

구조
인코더 : 셀프 어텐션 -> 피드 포워드 신경망
디코더 : 셀프 어텐션 -> 인코더, 디코더 어텐션 -> 피드 포워드 신경망

  • 어텐션은 주변 단어와의 관계를 파악 후 중요도에 따라 강조 여부를 판단하게 해줌

BERT

  • BERT는 Transformer 인코더를 기반으로 한 사전 학습된 언어모델임
  • BERT는 양방향으로 문맥을 이해할 수 있어, 다양한 자연어 처리 작업에서 뛰어난 성능을 보임

사전 학습(Pre-training)

  • BERT는 대규모 텍스트 코퍼스를 사용하여 사전 학습됨
  • 마스킹 언어 모델과 다음 문장 예측 작업을 통해 학습됨

파인튜닝(Fine-tuning)

  • 사전 학습된 BERT 모델을 특정 작업에 맞게 파인튜닝함
  • 텍스트 분류, 질의 응답, 텍스트 생성 등 다양한 자연어 처리 작업에 적용할 수 있음

ResNet

비전 모델에서 성능을 대폭 올린 모델 (CNN에 결합하여 성능을 향상시킴)

  • 깊은 신경망을 학습하기 위해 개발된 모델
  • 잔차 학습을 도입하여 깊은 네트워크에서도 효율적인 학습이 가능하도록 함
  • 잔차 학습을 도입하였다는 의미는 이전에 입력 데이터를 학습하였던 것과 다르게 입력과 출력의 차이를 학습한다는 의미이다.
  • 네트워크의 깊이를 늘릴 수 있게 됨
  • 기울기 소실의 문제가 발생하였을 때 ResNet의 잔차 개념을 도입하게 되면 해결할 수 있음

DNN 기반 이미지 분류 모델

YOLO

  • YOLO는 객체 탐지 모델로, 이미지에서 객체의 위치와 클래스를 동시에 예측함
  • YOLO는 이미지 전체를 한 번에 처리하여, 빠르고 정확한 객체 탐지를 수행함

동작 원리

  • 입력 이미지를 CNN을 통해 특징맵으로 변환함
  • 특징 맵을 SxS 그리드로 나누고, 각 그리드 셀에서 바운딩 박스와 클래스 확률을 예측함
  • 예측된 바운딩 박스와 클래스 확률을 바탕으로 객체의 위치와 클래스를 결정함

이미지 세그멘테이션 기법과 응용

  • 이미지 세그멘테이션은 이미지의 각 픽셀을 클래스 레이블로 분류하는 작업임
  • 이미지 세그멘테이션은 주로 시멘틱 세그멘테이션 (이미지의 각 픽셀을 클래스 레이블로 분류)과 인스턴스 세그멘테이션 (시멘틱 세그멘테이션과 달리, 같은 클래스 내에서도 개별 객체를 구분함) 두가지로 나뉨

주요 세그멘테이션 모델

  • FCN : 모든 레이어를 합성곱 레이어로 구성하며, 픽셀 단위의 예측을 수행함
  • U-Net : U자형 구조를 가지며, 인코더-디코더 아키텍처를 사용하여 세그멘테이션을 수행함
  • Mask R-CNN : 객체 탐지와 인스턴스 세그멘테이션을 동시에 수행하는 모델임

오토인코더

  • 생성형 모델에서 필수적인 모델
  • 인코더 : 고차원 -> 저차원
  • 디코더 : 적은 데이터만을 보고 원본 데이터를 생성해야 함

그렇다면 오토인코더란?
입력데이터를 압축하고, 이를 다시 복원하는 과정을 통해 데이터를 효율적으로 표현하는 비지도 학습 모델임 -> 주로 자원 축소, 잡음 제거, 생성 모델 등 다양하게 활용됨


GAN

  • GAN은 두 개의 신경망, 즉 생성자와 판별자로 구성되어 있음
  • 생성자는 가짜 데이터를 생성하고, 판별자는 이 데이터가 가짜인지 진짜인지 판별하며, 서로 경쟁하여 동시에 학습함

생성자

  • 랜덤 노이즈 벡터를 입력으로 받아 가짜 데이터를 생성
  • 생성된 데이터는 판별자에게 전달되어 진짜 데이터처럼 보이도록 학습함

판별자

  • 진짜 데이터와 생성된 가짜 데이터를 입력으로 받아서 이를 구분하는 역할을 함
  • 판별자는 진짜 데이터를 1로, 가짜 데이터를 0으로 분류하도록 학습됨

경쟁과정

  • 생성자는 판별자를 속이기 위해 점점 더 진짜 같은 데이터를 생성하려고 노력함
  • 판별자는 생성자가 만든 가짜 데이터를 더 잘 구분하려고 노력함
  • 이 과정에서 두 네트워크는 서로 경쟁하며 동시에 발전하게 됨

다만 실제로 적용하기에는 조율해야 할 사항이 많아 다소 까다로운 모델이라고 할 수 있겠음


VAE

  • VAE는 잠재공간을 확률분포를 모델링 해 생성함
  • 즉 데이터가 나타내는 일반적인 지식을 학습하게 되는 것임
  • 입력데이터를 잠재 공간의 확률 분포로 모델링하여 구조적 분포를 파악함

Recontruction Loss
원래 데이터와 복원된 데이터 간의 차이를 최소화하는 손실 함수

쿨백 라이블러 발산
인코더가 학습한 잠재 분포와 정규 분포 간의 차이를 최소화하는 손실 함수


전이학습

  • 기존에 이미 학습된 모델의 지식으로 새로운 데이터에 적용하는 학습을 의미함

과적합 방지 기법


CNN을 GPU로 학습시키면 빠른데 CPU로 학습시키면 느림 왜그렇지??

torch의 가장 큰 값을 받아오는 이유는 무엇인가?
모델의 성능을 결정하는 것은 배치 사이즈인가?
모델생성에서 절대적이라는 것은 없음

0개의 댓글