11.케창딥 - 텍스트생성
12장 텍스트 생성
[FYI] 생성이란?
생성 모델
은 주어진 데이터를 학습한 후, 새로운 데이터를 만들어내는 과정!- 텍스트 생성은
시퀀스에 강한 모델
(RNN, LSTM 등),트랜스포머
기반 모델들을 사용하고,샘플링
기법(탐욕,확률)으로 다양성을 높임 이미지 생성
에서는딥드림
,뉴럴 스타일 트랜스퍼
,GANs
등이 사용되어 예술적인 이미지나 사실적인 이미지를 생성할 수 있음
시퀀스 데이터의 생성
- 훈련된 모델을 통해 샘플링!
- 입력: 초기 텍스트 문자열
- 출력: 새로운 글자, 단어
- 생성된 출력 → 입력 데이터에 추가해 샘플링 반복
텍스트 생성 샘플링 전략
- 탐욕적 샘플링: 항상 높은 확률을 가진 글자를 선택
-
확률적 샘플링: 다음 단어를 확률 분포에서 샘플링 과정 중 무작위성 주입
- 소프트 맥스 온도(temperature): 샘플링 과정 중 확률의 양을 조절(486)
- 샘플링에 사용되는 확률 분포의 엔트로피를 나타내며 놀랍거나 예상되는 단어를 선택할지 결정
- 소프트 맥스 온도 ↑
- 놀랍고 창의적인 시퀀스 생성(무작위성이 많음)
- 소프트 맥스 온도 ↓
- 예상 가능한 구조의 시퀀스 생성(결정적임)
- 소프트 맥스 온도 ↑
→ temperature 1.0일때 원본 확률 분포
**temperature 값이 낮아질수록 다른 확률은 거의 0에 가까워져 탐욕점 샘플링이 됨**
- 샘플링에 사용되는 확률 분포의 엔트로피를 나타내며 놀랍거나 예상되는 단어를 선택할지 결정
텍스트 생성의 모델 구성
-
Q. 텍스트 생성에서는 왜 소스 시퀀스(입력 시퀀스)가 없을까?
A. 소스 시퀀스가 없이 디코더가 주어진 과거 토큰(이전에 생성한 단어들)을 기반으로 다음 토큰을 예측하기 때문
-
Q. 텍스트 생성 작업에서는 무조건 디코더만 사용하는게 유리한지?
A.
-
디코더만 사용하는 텍스트 생성 모델(예: GPT)은 인코더가 없다.
이 모델들은 이전에 생성된 단어들만을 바탕으로 다음 단어를 예측
-
인코더-디코더 구조를 사용하는 모델(예: BART)은 소스 시퀀스가 주어졌을 때 이를 인코딩하여 텍스트 생성을 진행한다.
기계 번역, 텍스트 요약 같은 작업에선 인코더가 필요.
-
-
텍스트 생성은 소스 시퀀스가 존재 X
- 디코더만 사용
- 과거 토큰이 주어지면 타킷 시퀀스에 있는 다음 토큰을 예측하는 것뿐
- 코잘 패딩을 통해 N+1을 예측하기 위해 0 ~ N까지만 사용 가능
텍스트 생성의 작업 원리
- 시퀀스-투-스퀀스 모델(디코더) 사용
- 작업 원리
- 시작 단어에서부터 텍스트 생성
- 현재 시퀀스를 모델에 주입
- 마지막 타임스텝의 예측을 추출해 다음 단어를 샘플링
- 예측값을 가변 온도 샘플링 함수를 통해 확률적 샘플링 실행(코드 12-7)
- 생성된 단어를 현재 시퀀스에 추가후 반복
12.2 딥드림
-
딥드림이란?
합성곱 신경망이 학습한 표현(사전 훈련된 컨브넷)을 사용하여 이미지를 조작하는 기법
컨브 넷을 거꾸로 실행함 - 컨브 넷 필터 시각화 기법과 거의 동일
- 컨브 넷 필터 시각 화 기법과 달리 특정 필터가 아니라 전체 층의 활성화를 최대화. 한꺼번에 많은 특성을 섞어 시각 화 → 필터 시각 화의 다중 스케일 버전
- 입력 이미지는 이미 가지고 있는 이미지를 사용. (빈 이미지/ 노이즈 X)
- 입력 이미지는 시각 품질을 높이기 위해 여러 다른 스케일(옥타브)로 처리
- 딥드림 과정은 이미지 모델이나 컨브넷에 국한되지 않음. 음성, 음악 등에도 적용 할 수 있음. 아래 소개하는 것은 가장 간단한 과정임.
-
딥드림 파이프라인
- 테스트 이미지 내려받기
- 사전 훈련된 컨브넷 로드하기
- 딥드림 손실에 대해 각 층 기여도 설정하기
- 연속적인 여러 옥타브에 걸쳐 경사 상승법 실행하기
- 사전 훈련된 컨브넷 로드하기
- 컨브넷을 거꾸로 실행하여 진행하기 대문에 사전 학습된 모델을 불러와서 사용
- VGG16, VGG19, Xception, ResNet50등을 사용 할 수 있음.
- 딥드림 손실에 대해 각 층 기여도 설정하기
- 경사 상승법으로 각 스케일마다 최대화
- 딥드림 알고리즘은 필터 시각화의 다중 스케일 버전임
-
Q. 필터 시각화의 다중 스케일 버전을 딥드림 알고리즘에 맵핑하면 어떻게 설명 할 수 있을지??
다중 스케일 : 스케일을 늘리면서 적용. 동적
→ 큰 스케일은 이미지의 전체적인 패턴 이 강화
https://images.app.goo.gl/D1qf1sokdQ4MrA3u8
-
- 연속적인 여러 옥타브에 걸쳐 경사 상승법 실행하기
- 옥타브 강조!!
- 스케일의 리스트(옥타브) 정의
- 아래 예시는 3개의 다른 ‘옥타브’로 이미지를 처리하는 것
- 연속적으로 스케일을 늘리고(옥타브)
- 스케일이 증가된 이미지에 디테일을 재주입
- 이미지 디테일 손실 방지를 위한 간단한 기교
- 스케일을 늘린 후 이미지에 손실된 디테일 재주입
- 작은 이미지 크기(S), 큰 이미지 크기(L) : S→L
- L - S = 차이 계산(잃어버린 디테일)
12.3 뉴럴 스타일 트랜스퍼
뉴럴 스타일 트랜스퍼
원본이미지(Content image)에 스타일(style image)을 덧씌우는, 텍스쳐 생성기법
- 네트워크의 가중치는 고정한 후 이미지 변경 → 이미지 업데이트
- 참조 이미지(스타일) ⇒ 타겟 이미지(구조) 에 씌운다.
스타일의 이미지의 화풍이 이미지 전체에서 나타나고 스타일에 나타나는 구조물은 사라짐
- 컨텐츠 이미지(타겟 이미지)
- 스타일 이미지(참조 이미지)
- 컴비네이션 이미지(타겟 이미지, 초기값: 노이즈 이미지
두 가지 손실 비교 : 콘텐츠 손실 vs 스타일 손실
- 콘텐츠 손실
- 타깃 이미지와 생성 이미지를, 사전 훈련된 컨브넷 주입해서 층활성화 함
- L2노름
- 손실을 줄이는 목적 :
(원본타깃이미지-생성된 이미지 비슷하게 만들기 위해서)
- 콘텐츠 보존하기 위해!
- 원본 타깃이미지, 생성 이미지간 “상층위의 활성화”를 비슷하게 유지
- 이미지 손실
-
컨브넷 여러 층 사용 ( ↔ 콘텐츠 손실은 하나의 상위층만 사용)
- 참조 이미지에서 컨브넷으로 추출한 모든 스타일을 잡아야 하기 때문.
- 층 별 활성화 출력은, 그람 행렬 사용
(아래참조)
- 손실을 줄이는 목적 :
(참조이미지, 층 안에 내재된 상관관계 비슷하게 보존하기 위해서) - 스타일 보존하기 위해서!
- 저수준 층, 고수준 층 활성화 안에서 “상관관계”를 비슷하게 유지
그람 행렬(Gram matrix) - 스타일 손실
그람행렬이란?
특성 맵들 간의 내적을 계산하여 각 필터 간 상관 관계를 표현한 행렬. 이미지의 스타일(패턴과 텍스처)을 포착하는 데 사용됨
내적을 구한다? = 층 특성 사이 상간관계를 계산한다
-
내적계산?
### 그람 행렬 계산 방법
특성 맵이 있다고 가정했을 때, 그람 행렬은 해당 특성 맵의 벡터 표현의 내적을 구하는 방식으로 계산됩니다. 더 구체적으로 설명하면:
- 특성 맵을 펼침: 주어진 층에서 나온 특성 맵들을 벡터로 변환합니다. 예를 들어, C×H×W크기의 특성 맵에서 C는 채널 수(필터의 개수), H와 W는 높이와 너비를 나타냅니다. 이 특성 맵을 C×(H×W)형태로 펼칩니다.
- 벡터 내적 계산: 각 특성 맵의 벡터들 간의 내적을 계산하여 C×C 크기의 그람 행렬을 만듭니다. 이 행렬의 각 원소는 두 필터가 이미지에서 감지한 패턴 사이의 상관 관계를 나타냅니다.
-
그림예시
https://youtu.be/ChoV5h7tw5A?si=KE0p07x6Ixn5WFub
LOSS TERM
스타일 손실: 유틸리티 함수를 사용해 입력 행렬의 그람 행렬을 계산
def style_loss(style_img, combination_img)
S = gram_matrix(style_img)
C = gram_matrix(combination_img)
channles = 3
size = img_height * img_width
return tf.reduce(tf.square(S - C) / (4.0 * (channels ** 2) * (size ** 2)
케라스로 뉴럴 스타일 트랜스퍼 구현하기
- VGG19의 층 활성화 동시 계산 네트워크 설정
- 스타일 참조 이미지, 베이스 이미지, 생성된 이미지
- 손실 함수 정의하고 손실 최소화하여 구현
- 세 이미지에서 계산한 층 활성화 사용
- 경사 하강법 과정 설정: 손실 함수를 최소화
VGG19 구조
![VGG-19는 5개 블록으로 그룹화된 16개의 합성곱 레이어를 보유]
VGG-19는 5개 블록으로 그룹화된 16개의 합성곱 레이어를 보유
- VGG는 입력 이미지를 1000가지 다른 범주로 분류
유틸리티 함수
# 이미지를 로드하고 크기를 바꾸어 적절한 배열로 변환하는 유틸리티 함수
def preprocess_image(image_path):
.
.
# 넘파이 배열을 이미지로 변환하는 유틸리
def deprocess_image(img):
VGG19 모델 사용 특성 추출기 만들기
# imageNet에서 사전 훈련된 가중치로 VGG19 모델 생성
model = keras.application.vgg19.VGG19(weights="imagenet", include_top=False)
.
.
# 모든 타깃 층의 활성화 값을 하나의 딕셔너리로 반환
..keras.Model(inputs=model.inputs, outputs=outputs_dict)
콘텐츠 손실
# 콤비네이션(타겟이미지(생성))이미지 - 컨텐츠 이미지(타겟이미지(구조))
..tf.square(combination_img - base_img)
스타일 손실
# 유틸리티 함수 사용. 입력 행렬의 그람 행렬 계산
def gram_matrix(x):
.
.
def style_loss(style_img, combination_img):
.
.
return tf.reduce(tf.square(S - C) / (4.0 * (channels ** 2) * (size ** 2)
총 변위 손실(total variation loss)
두 손실에 하나 더 추가하는 생성된 이미지 픽셀을 사용해 계산
- 생성된 이미지가 공간적인 연속성을 가지도록 도와줌.
- 픽셀의 격자무늬가 과도하게 타나나는 것을 막아줌 (규제 항 해석)
def total_variation_loss(x):
.
.
x[:, : img_height - 1, : img_width - 1, :] - x[:, : img_height - 1, 1:, :]
→ 세 손실의 가중치 평균(최소화할 손실)
사용하는 스타일/콘텐츠 이미지 따라 콘텐츠 가중치 조정
if 콘텐츠 가중치가 높다? 생성된 이미지(콤비네이션) 타깃 컨텐츠(구조)가 더 강조
최소화할 최종 손실 정의
경사 하강법 단계 정의(모델 손실 최소화)
학습률 스케줄(learning rate schedule)
옵티마이저 기능
높은 값(100)→ 낮은 값(20)까지 점진적으로 학습률 줄임
효과: 훈련 초기에는 빠른 속도로 진행, 최소 손실에 가까울 수록 점점 조심스럽게 훈련 진행
SGD 옵티마이저로 미니 배치 경사 하강법 수행
- 미니 배치 경사 하강법은 전체 데이터셋이 아니라, 미니 배치라는 작은 부분 집합을 사용하여 가중치를 업데이트하는 방식
- SGD(Stochastic Gradient Descent)는 경사 하강법을 데이터셋의 각 샘플이나 미니 배치에 대해 수행하는 기법
결론
콘텐츠 이미지의 구조적 정보를 유지하면서, 스타일 이미지의 미적 디테일한 요소(색상, 질감, 패턴 등)를 적용하여 새로운 생성 이미지를 만드는 기법이다.
스타일 트랜스퍼 알고리즘은 느리지만 간단한 변환 수행 → 작고 빠른 컨브넷 사용하여 학습
- 적절한 양 훈련 데이터 필요(입력-출력 훈련 샘플)
참고: https://big-dream-world.tistory.com/87
댓글남기기