일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 스택
- 이진 탐색
- 계수정렬
- BFS
- 최단 경로
- RESNET
- 정렬
- 큐
- AI
- rnn
- 다이나믹 프로그래밍
- 재귀함수
- 딥러닝
- 퀵정렬
- LSTM
- 그리디
- 캐치카페신촌점 #캐치카페 #카페대관 #대학생 #진학사 #취준생
- GRU
- pytorch
- DFS
- 선형대수
- 인공지능
- 삽입정렬
- 선택정렬
- Machine Learning
- 알고리즘
- 머신러닝
- Today
- Total
hyeonzzz's Tech Blog
[딥러닝 파이토치 교과서] 13장. 생성 모델 - (1) 본문
13.1 생성 모델이란
생성 모델(generative model)
: 주어진 데이터를 학습하여 데이터 분포를 따르는 유사한 데이터를 생성하는 모델
13.1.1 생성 모델 개념
<기존 합성곱 신경망>
: 입력 이미지(x)가 있을 때 그에 따른 정답(y)를 찾는 것
판별자 모델(discriminative model) : 이미지를 분류하는 것
- 이미지를 잘 분류하고자 특성들을 잘 찾는 것을 목표로 한다
생성자 모델(generative model) : 판별자 모델에서 추출한 특성들의 조합을 이용하여 새로운 이미지를 생성하는 것
- 입력 이미지에 대한 데이터 분포 p(x)를 학습하여 새로운 이미지를 생성하는 것을 목표로 한다
13.1.2 생성 모델의 유형
<생성 모델의 유형>
- 변형 오토인코더 모델(명시적 방법) : 모델의 확률 변수 구함. 이미지의 잠재 공간(latent space)에서 샘플링하여 완전히 새로운 이미지나 기존 이미지를 변형하는 방식으로 학습을 진행한다
- GAN 모델(암시적 방법) : 확률 변수 이용x. 생성자와 판별자가 서로 경쟁하면서 가짜 이미지를 진짜 이미지와 최대한 비슷하게 만들도록 학습을 진행한다
13.2 변형 오토인코더
변형 오토인코더는 오토인코더의 확장이다
13.2.1 오토인코더란
오토인코더
: 단순히 입력을 출력으로 복사하는 신경망
- 은닉층의 노드 수가 입력층의 노드 수(데이터 차원 수)보다 적은 것이 특징이다
- 입력과 출력이 동일한 이미지
왜 입력을 출력으로 복사하는 방법을 사용할까?
- 적은 수의 병목층(은닉층) 뉴런으로 데이터를 가장 잘 표현한다
<오토인코더의 4가지 주요 부분>
1. 인코더 (= 인지 네트워크 recognition network)
: 특성에 대한 학습을 수행하는 부분
2. 병목층(은닉층)
: 모델의 뉴런 개수가 최소인 계층
이 계층에는 차원이 가장 낮은 입력 데이터의 압축 표현이 포함된다
3. 디코더 (= 생성 네트워크 generative network)
: 병목층에서 압축된 데이터를 원래대로 재구성(reconstruction)하는 역할
최대한 입력에 가까운 출력을 생성하도록 한다
4. 손실 재구성
: 오토인코더는 입력층과 출력층의 뉴런 개수가 동일하다는 것을 제외하면 일반적인 다층 퍼셉트론과 구조가 동일하다
오토인코더는 압축된 입력을 출력층에서 재구성하며, 손실 함수는 입력과 출력의 차이를 가지고 계산한다
<수학적 접근>
입력과 출력이 같은 차원(R^d)에 존재한다는 가정하에 입력 데이터를 인코더 네트워크에 통과시켜 압축된 잠재 벡터 z를 구한다
압축된 z벡터에서 입력 데이터와 크기가 같은 출력 값은 다음과 같이 계산한다
손실값은 입력 값 x와 디코더를 통과한 y값의 차이로 다음과 같이 계산한다
즉, 디코더 네트워크를 통과한 출력 값은 입력 값과 크기가 같아야 한다
<오토인코더가 중요한 이유>
1. 데이터 압축
: 오토인코더를 이용하여 이미지나 음성 파일의 중요 특성만 압축하면 용량도 작아지고 품질도 더 좋아진다
2. 차원의 저주 예방
: 오코인코더는 특성 개수를 줄여 주기 때문에 데이터 차원이 감소하여 차원의 저주를 피할 수 있다
3. 특성 추출
: 오토인코더는 비지도 학습으로 자동으로 중요한 특성을 찾아 준다
<오토인코더 구현>
- MNIST 데이터셋을 내려받아 전처리
train_loader = DataLoader(train_dataset, batch_size=128, shuffle=True, num_workers=4, pin_memory=False)
- num_workers : 데이터를 불러올 때 몇 개의 프로세스를 사용할지 지정한다 (일반적으로 4 *GPU 개수로 지정)
- pin_memory : cpu를 사용하다 gpu로 전환할 때 속도 향상을 위해 사용한다. true로 설정하면 훈련에 사용할 데이터셋을 gpu에 미리 불러와서 학습시키기 때문에 속도가 향상된다
- 네트워크 생성
- 인코더 : 데이터셋을 저차원으로 압축하는 것
- 디코더 : 압축된 것을 다시 원래의 차원으로 복원하는 것
- 인코더와 디코더에서 사용하는 네트워크 계층은 같아야 한다 (대칭적인 구조를 유지해야 한다) ( 각 층이 노드 수, 계층 종류, 활성화 함수 등에서 유사하거나 동일해야 한다)
self.decoder_conv = nn.Sequential( # 인코더의 합성곱층에 대응
nn.ConvTranspose2d(32, 16, 3, stride=2, output_padding=0), # 7 * 7 * 16
nn.BatchNorm2d(16),
nn.ReLU(True),
nn.ConvTranspose2d(16, 8, 3, stride=2, padding=1, output_padding=1), # 14 * 14 * 8
nn.BatchNorm2d(8),
nn.ReLU(True),
nn.ConvTranspose2d(8, 1, 3, stride=2, padding=1, output_padding=1) # 28 * 28 * 1
)
- 첫 번째 ConvTranspose2d 레이어:
- 입력: 32×3×3
- 필터: 개의 3×3 필터
- 스트라이드: 2
- 패딩: 0
- 출력 크기 계산: Hout=(stride×(Hin−1))−2×padding+kernel_size+output_padding=(2×(3−1))−0+3+0=7
- Wout=(stride×(Win−1))−2×padding+kernel_size+output_padding=7
- 출력: 16×7×7
Padding
padding은 입력 이미지의 테두리 주위에 추가적인 픽셀을 추가하는 것을 의미합니다. 이 과정은 컨볼루션 연산 중에 경계 효과를 줄이고 출력 크기를 조절하는 데 사용됩니다.
예: Conv2d에서 padding=1은 입력 이미지의 모든 가장자리에 한 줄의 픽셀을 추가합니다.
예: ConvTranspose2d에서 padding=1은 입력 이미지의 가장자리를 한 줄 제거하는 것과 동일한 효과를 가집니다. 이 때문에 출력 이미지가 작아질 수 있습니다.
Output Padding
output_padding은 ConvTranspose2d 레이어에서만 사용되는 파라미터로, 주로 업샘플링 과정에서 정확한 출력 크기를 맞추기 위해 사용됩니다. 이는 컨볼루션 연산 후 출력 이미지의 크기를 조정하여 원하는 출력 크기를 맞출 수 있게 합니다.
예: ConvTranspose2d에서 output_padding=1은 출력 이미지에 추가적인 한 줄의 픽셀을 더합니다. 이는 주로 업샘플링 과정에서 크기 불일치를 해결하기 위해 사용됩니다.
차이점 정리
Padding: 입력 이미지의 가장자리에 패딩을 추가하거나 제거하여 출력 크기에 영향을 미칩니다. 컨볼루션 연산이 이루어질 때 입력 데이터의 크기를 변화시킵니다.
Output Padding: ConvTranspose2d 연산 후 결과 출력 이미지의 크기를 정확히 맞추기 위해 사용됩니다. 주로 업샘플링에서 원하는 크기를 달성하기 위해 사용됩니다.
- 손실 함수와 옵티마이저 지정
- 오토인코더에서는 손실 함수로 '평균 제곱 오차'와 '이진 크로스 엔트로피'를 주로 사용한다
- 입력 값이 (0, 1) 범위에 있으면 이진 크로스 엔트로피를 사용하고, 나머지는 평균 제곱 오차를 사용한다
- 옵티마이저는 Adam, RMSProp, adadelta 등을 이용한다
- 모델 학습 함수 생성
image_noisy = add_noise(image_batch,noise_factor)
일반적으로 데이터에 노이즈가 있으면 오토인코더가 원본 이미지를 복원하는 능력이 향상될 수 있습니다. 이는 다음과 같은 이유로 설명할 수 있습니다:
- 로버스트한 특성 학습: 노이즈가 추가된 데이터를 사용하면 모델이 더욱 로버스트한 특성을 학습할 수 있습니다. 즉, 노이즈가 추가된 상황에서도 정확한 특징을 추출하고 복원하는 데 유리할 수 있습니다.
- 일반화 능력 향상: 노이즈가 추가된 데이터를 사용하여 훈련하면 모델의 일반화 능력이 향상될 수 있습니다. 새로운 입력 데이터에서도 노이즈가 포함된 상황을 더 잘 처리할 수 있게 됩니다.
- 데이터 다양성 증가: 노이즈가 추가된 데이터는 원본 데이터보다 더 다양한 형태의 입력을 제공합니다. 이는 모델이 더 많은 데이터를 통해 학습할 수 있게 하여 성능을 향상시킬 수 있습니다.
그러나 이러한 이점이 항상 성립하는 것은 아닙니다. 노이즈의 종류나 크기에 따라 모델의 성능에 오히려 악영향을 미칠 수도 있습니다. 따라서 오토인코더를 훈련할 때는 노이즈를 추가하는 방법과 노이즈의 양을 조절하는 것이 중요합니다. 적절한 노이즈 수준을 선택하여 모델이 원본 이미지를 정확하게 복원할 수 있도록 해야 합니다.
- 노이즈 데이터 생성
def add_noise(inputs,noise_factor=0.3):
noisy = inputs+torch.randn_like(inputs) * noise_factor
noisy = torch.clip(noisy,0.,1.)
return noisy
- torch.randn_like(inputs) : 입력과 동일한 크기의 노이즈 텐서 생성
- torch.clip : 데이터 값의 범위 조정
- noisy : 값의 범위를 조정할 데이터셋
- 0. : 데이터의 범위 중 최솟값
- 1. : 데이터의 범위 중 최댓값
13.2.2 변형 오토인코더
오토인코더
: 입력 -> 인코더 -> 압축(차원 축소) -> 디코더 -> 출력
- 차원을 줄이는 것이 목표이기 때문에 새롭게 생성된 데이터의 확률 분포에는 관심이 없다
- 목표 : 실제 이미지와 동일한 이미지 출력
변형 오토인코더
: 표준편차와 평균을 이용하여 확률 분포를 만들고, 거기에서 샘플링하여 디코더를 통과시킨 후 새로운 데이터를 만들어 낸다
- 입력 데이터와 조금 다른 출력 데이터를 만들어 낸다. 이때 z라는 가우시안 분포를 이용한다
- 중요한 특성의 파라미터를 담고 있는 z분포에서 벡터를 랜덤하게 샘플링하고 이 분포의 오차를 이용하여 입력 데이터와 유사한 다양한 데이터를 만들어 낸다
- 목표 : 데이터가 만들어지는 확률 분포를 찾아 비슷한 데이터를 생성
<변형 오토인코더에서 인코더와 디코더에 대한 네트워크>
(인코더 네트워크) : x를 입력받아 잠재 벡터 z와 대응되는 평균과 분산을 구하는 네트워크
(디코더 네트워크) : z를 입력받아 x와 대응되는 평균과 분산을 구하는 네트워크
<인코더 네트워크>
1. 입력 x를 인코더 네트워크 q(z|x)에 보내 (µ, Σ)를 출력하고, 이를 이용하여 다음 수식의 ②항에 대한 값을 구한다
2. (µ, Σ)의 가우시안 분포에서 z를 샘플링한다
이렇게 구해진 z는 디코더 네트워크의 입력으로 사용된다
<디코더 네트워크>
1. 샘플링한 z를 디코더 네트워크 p(x|z)에 보내 (µ, Σ)를 출력한 후 이를 이용하여 ①항의 값을 구한다
2. (µ, Σ)의 가우시안 분포에서 z를 샘플링한 후 x'를 구한다
3. 역전파를 이용하여 L(x^(i), θ, Φ)의 값이 높아지는 방향으로 기울기를 업데이트한다. 즉, 가능도가 증가하는 방향으로 파라미터 θ와 Φ를 업데이트한다
최종적으로 x와 유사한 x'라는 이미지가 생성된다
<수식 정리>
① : z가 주어졌을 때 x'를 표현하기 위한 확률밀도 함수 (디코더 네트워크)
- 디코더 네트워크의 가능도가 크면 클수록 θ가 그 데이터를 잘 표현한다 -> ①항이 클수록 모델 가능도가 커진다
② : x에서 z를 표현하는 확률밀도 함수로 인코더 네트워크와 가우시안 분포가 얼마나 유사한지
- 유사한 정도가 높을수록 쿨백-라이블러 발산은 낮은 값을 나타낸다
- 인코더 네트워크가 가우시안 분포를 최대한 잘 표현할 수 있도록 가능도가 최대화된다 -> ②항이 작을수록 모델 가능도가 커진다
<변형 오토인코더 구현>
- 텐서보드 엑스
: 학습 과정을 시각적으로 확인하고자 할 때 사용하는 도구
- 인코더 네트워크 생성
인코더 역할 : 데이터(x)가 주어졌을 때 디코더가 원래 데이터로 잘 복원할 수 있는 이상적인 확률 분포 p(z|x)를 찾는 것
- 변형 오토인코더에서는 이상적인 확률 분포를 찾는 데 변분추론을 사용한다
- 디코더 네트워크 생성
디코더 역할 : 추출한 샘플을 입력으로 받아 다시 원본으로 재생성하는 역할
- 손실 함수 정의
변분추론으로 쿨백-라이블러 발산(KLD)을 계산하고, KLD가 줄어드는 쪽으로 q(z)를 조금씩 업데이트한다.
손실함수에서 반환되는 값을 위 수식처럼 모두 더하여 사용하는 것이 최종 손실 함수가 된다
- 모델 학습 함수 정의
writer.add_scalar("Train/Reconstruction Error", BCE.item(), batch_idx + epoch *
(len(train_loader.dataset)/batch_size) )
- "Train/Reconstruction Error" : 어떤 값을 기록할지에 대한 구분자
- BCE.item() : 텐서보드에서 확인하고자 하는 값 (y축)
- (len(train_loader.dataset)/batch_size) ) : x축
- 텐서보드에서 오차 확인
%load_ext tensorboard # 매직 커맨드
%tensorboard --logdir scalar --port=6013 # 로그 보여줌
- --logdir : 오차 등 데이터가 저장된 위치
- --port=6013 : 웹 브라우저에서 텐서보드를 확인할 때 사용하는 포트 번호
'Deep Learning > Pytorch' 카테고리의 다른 글
[딥러닝 파이토치 교과서] 13장. 생성 모델 - (2) (0) | 2024.07.12 |
---|---|
[딥러닝 파이토치 교과서] 12장. 강화학습 (0) | 2024.06.26 |
[딥러닝 파이토치 교과서] 10장. 임베딩 -(2) (1) | 2024.06.01 |
[딥러닝 파이토치 교과서] 10장. 임베딩 -(1) (0) | 2024.05.31 |
[딥러닝 파이토치 교과서] 9장. 자연어 전처리 (0) | 2024.05.16 |