2022. 3. 31. 14:07ㆍ카테고리 없음
목차
1. GAN이란 무엇일까 https://www.youtube.com/watch?v=odpjk7_tGY0
2. CycleGAN 총정리 http://www.kwangsiklee.com/2018/03/cyclegan%EC%9D%B4-%EB%AC%B4%EC%97%87%EC%9D%B8%EC%A7%80-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90/
* GAN이란 무엇일까
Unsupervised Learning : train data의 분포를 보고 image를 생성
확률분포
이미지는 더 많은 케이스(64x64x3)가 있어서 확률분포가 어렵게 생겼을 것임.
만약 이렇게 생겼다고 한다.
안경 낀 남자
금발 여자
(실제로는 x가 고차원벡터임)
generative model이 하고자 하는 것
저 데이터 분포를 잘 근사하는 모델을 만드는 것(실제같은 이미지 생성)
GAN - 두 가지 모델 존재 (Discriminator과 Generator)
Discriminator : 진짜가 들어가면 진짜1로 구분, 가짜면 0. input은 이미지의 고차원 벡터(64x64x3), output은 1차원 0~1사이 값
Generator : 랜덤한 코드를 받아서 이미지를 생성해냈을 떄 Fake image를 만들어서 Discriminator를 속여야(1이 나오게) 한다. 따라서 Generator는 학습을 하면 할수록 진짜같은 가짜 이미지를 만들어낸다.
GAN의 수식 - Discriminator
D = GAN의 loss함수
log(D(x)) = D가 1일때 0, D가 0이면 -무한대
GAN의 수식 - Generator
Generator는 Discriminator에 가짜 이미지를 넣었을 떄 최대한 1이 나오도록 학습을 해야한다.
GAN 코드
Discriminator
intput : 18x18 MNIST를 1차원으로 펼침 = 784
output : 0~1 사이 값. 진짜스러운지 가짜스러운지, size 1(sigmoid 거침)
Generator
intput : latent code
output : 다시 이미지 생성. 18x18 = 784
Loss function - Binary Cross Entropy Loss
h(x) = hypothesis, y = label(실제정답)
Optimizer - Adam D와 G를 따로따로 구현해야함.
Data - tensor
실제 학습되는 코드 -Discriminator
진짜 이미지 넣으면 1을, 가짜이미지 넣으면 0을 내놓도록 학습
실제 학습되는 코드 - Generator
생성한 가짜이미지를 D한테 넣어줬을 떄 점점 1이 나오도록 학습
g_optimizer.step() = D는 학습안하고 G만 학습한다.
D와 G는 각각 backpropagation이 서로의 weight를 업데이트하진 않는다. D는 D것만 업데이트, G는 G것만 업데이트
전체 코드 아래에
https://github.com/yunjey/pytorch-tutorial
초반에는 D(G(z))가 0이 나오기 떄문에 빠르게 그럴듯한 이미지를 만들 시점으로 들어서도록 아래와 같이 한다.
Generator는 초반에 매우 형편없는 이미지를 만들게 된다. 그럼 D(G(z))는 0에 가까운 값을 내놓는다.
그럼 log(1-0.00001) 을 하면 안된다. 따라서 log(1-DG)가 아닌 log(DG)를 해야한다.
따라서 y에 1을 대입해서 처음엔 이렇게 하게 한다.
총 정리
GAN의 목표 : 실제 데이터 분포와 모델이 생성한 데이터 분포간의 차이를 줄이는 것
GAN의 loss 함수를 변형한 여러 GAN 모델들
1. DCGAN(Deep Convolutional GAN 2015)
- 1차원 18x18=784가 아닌 2차원 CNN을 사용
- G에서 deconvolution을 진행
- pooling layer를 사용하지 않는다. (unpooling할 떄 이상한 이미지를 만들어낼 수 있어서)
- Adam optimizer : 보통 64x64 이미지 생성할때 convolution layer를 4개 사용하여 모델을 만드는데, 저 beta1,2를 사용하면 학습이 잘 된다고 하여 저렇게 한다.
- 흥미로운 점 : latent vector를 가지고 연산을 할 수 있다. word2vec처럼
안경쓴남자 - 안경안쓴남자 + 안경안쓴여자 = 안경쓴여자
2. LSGAN(Least Squares GAN)
- 기존 GAN은 D를 속이기만 하면 되는데,
- 아래서 파란 선 : 기존 GAN D의 Dicission Boundary 진짜가짜를 구분하기 위한. 0.5를 기준으로 높으면 진짜, 가짜
- 빨간 선 : LSGAN의 D의 Dicission Boundary. 분홍색 점들 : 가짜 데이터인데 완벽히 속였다. 그러나 진짜 데이터인 빨간색 점들과 먼 것을 보아 좋지않은 이미지를 생성하긴 한 것. 그러므로 완벽히 속였다 하더라도 좋지 않은 이미지일 수 있다. 그러므로 저 분홍점을 Discission Boundary에 가깝게 좀더 끌어올려서 별로인 이미지는 걸러지고 좋은 이미지만 D가 1을 내뱉도록, 확실히 속도록 하는 게 LSGAN
- 기존과 다르게 sigmoid를 없앰.
- 큰 차이점 : 기존엔 cross entropy를 썼는데, LSGAN은 least squre loss로 바꿈(L2)
기존이랑 LSGAN 둘 다 진짜이미지는 1로 가고, 가짜이미지는 0으로 가는데 차이는
D(G(z))가 만약 1보다 훨씬 큰값 = 3 등을 낸다고 해도, G(z)가 이상한 이미지 일수 있는 문제점이 있었다.
그러므로 LSGAN으로 바꾸면 1보다 크든 작든 Dicission Boundary쪽으로 밀어준다.
DCGAN보다는 좋긴 좋다. 근데 몇 개는 보다시피 이상한 것도 있음.
3. SGAN - MNIST데이터로 설명
기존과 다르게 D가 더이상 진짜가짜를 구분하지 않고 class를 구분한다. MNIST의 기본 10개 클래스에(0~9까지 숫자그림) + 가짜 클래스 1개를 추가함.
- one-hot vector : class를 나타냄 [0,0,0,1,0,0] -> 숫자3를 의미 등
- 진짜 정상적인 5를 받으면 class로 5를 내뱉고, 가짜이미지 비정상적인 걸 받으면 fake class를 내뱉음
따라서 이 GAN의 목적은 가짜 이미지를 만들어도 input으로 준 one-hot vector랑 output으로 나오는 one-hot vector가 같도록 만들어줘야한다.
그래서 반은 supervised learn이고 반은 unsupervised learn이어서 semi supervised라고 부름.( class가 있어서 training시 label(정답)이 존재해야하므로)
z벡터는 그대로 두고, class(one-hot vector)만 바꾸게 되면 예를 들어 저 보라머리 캐릭터가 있으면
z벡터는 보라머리캐릭터 생성이고, class는 저 포즈나 표정이다. 그래서 class를 바꾸면 캐릭터는 보라머리 그대로인데 포즈만 바뀌게 됨.
z가 조금변하면 캐릭터도 조금변하고, z가 많이 변하면 캐릭터도 많이 변함.
4. ACGAN(Auxiliary Classifier GAN 2016)
- Semi supervised GAN 이랑 비슷한데 D가 해야되는 task가 두개이다. 진짜인지 가짜인지도 구분하고, class도 구분해야 한다. 즉, 가짜임에도 불구하고 class는 2같다.라고 구분해야함.
그래서 ACGAN은 MNIST지만 class가 10개임. 가짜지만, 3 이런식으로 진짜,5
- 그래서 SGAN은 좋은 가짜이미지를 만드는 데 특화라면, ACGAN은 Data augmentation? 좀 noise가 껴있어도 잘 만들어낸다?
여태까지는 loss 함수를 바꾸거나 label을 추가한 형태였다면, 앞으로는 조금 더 확장된 GAN을 살펴보자
5. CycleGAN
- 이미지의 도메인 또는 스타일을 바꾸는 GAN, 얼룩말을 말로, 말을 얼룩말로, 여름을 겨울로
input : latent code를 받지 않고, image를 받는다
A도메인을 B도메인으로 바꾸고 싶다. (A 얼룩말 B 그냥말)
그래서 D를 학습시킬 떄는 얼룩말을 넣지 않고 그냥 말만 넣어서 학습
그러면 얼룩말을 받았을 떄 가짜이미지라고 판별할 것임.
그래서 D를 속이기 위해 얼룩말을 말로 바꾸게 된다. 그러나 속이기만 하면 되므로
꼭 저 input때의 말 자세가 아닌 뛰는 말 자세 등 말이기만 하면 되는 사진을 Generate한다.
그러므로 이 task의 목표 : 얼룩말을 말로 바꾸되, 그 자세는 유지하도록 하는 것.
그럼 모양 유지는 어떻게 하냐?
얼룩말 -> 말로 바꾸고, 그 말을 다시 얼룩말로 바꾼다.
예를 들어 저 맨왼쪽 얼룩말을 뛰고있는 말 이미지로 바꿨다. 그리고 그걸 다시 원래 얼룩말로 복원시키려면(generate하려면) 자세가 다르기 때문에 쉽지 않을 것이다(loss가 크다?) 따라서 이 작업을 잘 해내기 위해 최대한 자세가 변하지 않은 황토말 이미지를 생성하게 될 것이다.
즉, 모양은 유지하되 말색깔(도메인)만 바꾸기 위해서는 reconstruction error가 적도록, D를 속일 수 있게 하는 방향으로 학습시키면 될 것이다.
이 설명하신 분이 구현하신 코드
https://github.com/yunjey/mnist-svhn-transfer
* CycleGAN 총정리
CycleGAN으로 할 수 있는 일
- 말<->얼룩말 변환, 대신 자세는 유지
- 여름<-> 겨울 변환
- 아이폰사진 <-> DSLR 사진 변환
- 모네그림 <-> 실제풍경
CycleGAN의 탄생 : pix2pix에다가 GAN을 더해서 CycleGAN을 만듦
pix2pix : supervised learning, input,output 이 모두 사진임, 즉 흑백사진 -> 컬러사진
- self supervised 이다 왜냐면 label을 붙여주지 않아도 흑백/컬러 사진을 정답지로 학습시킬 수 있기 때문.
- loss 는 |G(x)-y|
- 또는 이렇게 건물구조도를 주면 실제 건물처럼 만들어낼 수 있음. 단 정답에 비해 뿌옇고 부조화스러움
- 흑백-> 컬러사진도 역시 뿌옇다. 왜냐하면 loss를 막기위해 흑백이 아닌 색을 모델이 선택하는데 이때 색깔값에 대한 가이드라인이 없어 모델이 중간값을 고르는 경향이 나타난다.
따라서 pix2pix의 intuition : 사람이 보기에 output과 ground truth는 명확히 구별된다(Discriminator) 그러면 이 D를 뉴럴 네트워크가 하도록 하자! -> GAN의 탄생
GAN
- 우리의 목적은 흑백사진 입력을 컬러사진으로 만드는 것, 이것이 G 네트워크
- 여기에 D를 추가하여 G(x)가 real인지 fake인지 구별하게끔 만든다.
- 즉 D는 fake를 구별하려 하고, G는 fake image로 D를 속여야 한다.
GAN의 수식
- D 네트워크
- real은 0에 가깝게, fake는 1에 가깝게 구별한다.
- D의 loss함수는 저 식과 같다. argmax 사용. logD(G(x))+ log(1-D(y))를 넣은 저 값. 즉 0~1사이가 나온다
- log(D(G(x))) 를 통해 G가 만들어내는 결과는 1(fake)에 가깝게 만들고,
log(1-D(y))를 통해 실제 정답이미지의 결과는 0(real)에 가깝게 만든다.
- G 네트워크
- argMin. D와 반대로
- log(D(G(x)))를 통해 G가 만들어내는 결과는 0(real)에 가깝게 만든다
- log(1-D(y))를 통해 실제 정답 이미지는 1(fake)에 가깝게 만든다. 즉, D를 속인다.
GAN 네트워크 총 수식 정의
- G의 관점에서는 D가 loss function이다.
개선된 pix2pix
- pix2pix의 loss는 픽셀 level loss(y-G(x)만 사용)와 GAN의 loss를 합쳐서 개선하였다.
pix2pix의 한계점
- 데이터셋을 구성하기 쉽지 않다(모네의 실제 그림과 실물 이미지를 1000장씩 구하려면?)
CycleGAN
- 완전히 똑같지 않은 원하는 style의 사진을 쉽게 구할 수 있다.
- 기존의 GAN loss를 사용하나 조금 변형해야한다. 왜냐면 기존 GAN은 2가지 한계가 있음
1. input의 특성이 무시됨 2. 같은 output으로 매몰될 여지가 있음.
- 그러므로! CycleGAN은 추가 loss를 적용. 원본 이미지로 reconstruct해봤을 때의 loss를 추가하는 것.
즉, 도메인은 바꾸되 다시 원래 그림으로 복구가능할 정도로만 바꿔라.
CycleGAN의 정방향 loss함수
- 기존 GAN의 loss(argmin argmax log어쩌구)는 유지한다. (=LGAN)
- 추가적으로 생긴 loss는 generation한 이미지를 reconstruction한 이미지와 원래의 x의 loss가 최소화 되어야 한다.(=F(G(x))-x)
즉 기존 GAN에서는 G만 하는데, 여기는 reconstruct작업인 F도 추가된 느낌.
반대방향 학습
- 같은 맥락으로 반대 방향의 학습도 가능하다. F가 G의 역함수 개념이니 가능.
- 모네 -> 실물의 학습이 가능하면, 실물 -> 모네로의 학습도 가능하다.
CycleGAN 의 최종 loss함수
- 두 방향의 학습을 모두 합친 아래 loss 모습이 최종이 된다.
- GAN은 두 방향의 loss를 합친다. ( 한 방향으로만 학습시켰을 떄는 결과가 좋지 않았다고 함 )
CycleGAN의 학습결과
- 그림-> 사진, 사진-> 그림 변환
- city scape cycleGAN을 사용했을때가 제일 잘 원본으로 돌아오고, 한 이미지로의 수렴도 일어나지 않았다.
- GTA와 실제 도로 사진으로의 reconstruction. 원본은 GTA 스샷, 정답지는 자율주행 차량 사진
- GTA <-> real street view
CycleGAN의 아키텍쳐
- CycleGAN에서는 G의 아키텍쳐가 굉장히 중요함
- 최초의 CycleGAN은 G로 U-Net을 채택하였다( 장점 : skip connection으로 디테일이 많이 간직된다. 단점 : 두 가지 컨텐츠가 비슷할 경우, skip connection을 최대한 사용하려고 하여 성능이 좋지 못함.
- 최근 CycleGAN은 G로 ResNet을 채택하였다.( 장점 : 이미지 퀄리티가 좋음. 단점 : 메모리를 많이 사용함 )
CycleGAN의 loss함수의 변경
- GAN으로 cross entropy를 사용하였더니 Gradient Vanishing 문제가 발생. 따라서 LSGAN을 사용
CycleGAN의 한계점
1. 모양
- 도메인은 바꾸나 모양은 바꾸기 어려움. 사과를 오렌지로 바꾸기
2. 데이터 분포
- 말->얼룩말에서 말 위에 사람이 타 있는 사진은 제대롣 동작하지 못했음
- Optimization의 문제라기보다는 Dataset의 문제
GTA와 자율주행의 관계
- 무인자동차의 학습 도구로 GTA 게임을 사용하기가 좋다.
- 실사에 가까운 GTA 게임에서 Object Detection을 훈련시키고 실제 도로에서 검증한다고 한다.
- 그러나 GTA에서 학습된 모델로 실제 환경에서 돌렸을 때 정확도가 그리 높지는 않았었는데 CycleGAN을 사용하면
82.8%의 정확도(per-lixel accuracy)로 괜찮은 성과를 낸다.