


생성자가 이미지를 넣었을 때 (학습을 중단한 상태인)판별자가 가짜라고 판별할 것이고, 가짜와 진짜와의 LOSS(간격)을 생성자에게 넘겨줌
이 과정을 반복하며 훈련함
모델이 만든 예측값이 0.5(평균값)에 가까워졌을 때 판별하기 어려워질 때 생성이미지를 생성함.











# 관련 라이브러리 설치
!pip install transformers scipy ftfy accelerate diffusers
import torch
from diffusers import StableDiffusionPipeline # 텍스트를 이용해서 이미지를 만들어내는 파이프라인
# 파이프라인 객체생성
TxtToImage_pipe = StableDiffusionPipeline.from_pretrained(
'CompVis/stable-diffusion-v1-4', # 활용한 사전학습 모델 저장소 이름
torch_dtype=torch.float16 # 16비트 float타입으로 설정하여 메모리를 절약
)
# 파이프라인이 GPU를 사용하도록 설정
TxtToImage_pipe = TxtToImage_pipe.to('cuda')
- 프롬프트 참고 사이트
https://civitai.com/
# 이미지 생성에 활용한 프롬포트
prompt = "A super cute kitten. Its a wide angle shot, the subject full body is viewable, The view is from behind and you can see mountains and valleys in the distance lit by golden hour sunlight. In the sky you see the words 'The Search for Buzz' on the next line 'Never Ends'"
create_image = TxtToImage_pipe(prompt) # 파이프라인을 활용해 이미지 생성
create_image

prompt = "Cats and dogs laughing and playing in a wide, green field, high quality, photograph, colorful"
generator = torch.Generator('cuda').manual_seed(816)
# 파이프라인을 활용해 이미지 생성
create_image = TxtToImage_pipe(prompt,
generator = generator,
num_inference_steps = 80) # 이미지 생성시 파이프라인 반복 횟수 제어

!pip install peft opencv-python mediapipe
!pip install -U controlnet-aux
from diffusers.utils import load_image, make_image_grid # 이미지를 로딩하고 grid 형태로 시각화하는 함수
# 추가 조건을 넣을 수 있는 ControlNet 모델과 파이프라인 관련 클래스
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, UniPCMultistepScheduler
from diffusers import StableDiffusionControlNetInpaintPipeline
# Openpose를 활용하여 사람의 관절 정보를 추출하는 도구
from controlnet_aux import OpenposeDetector
from PIL import Image # 파이썬 이미지처리 라이브러리
import cv2 # OpenCV 라이브러리
import numpy as np
# 원본 이미지, 마스크 이미지
init_image = Image.open('./data/cyh1_origin.jpg')
mask_image = Image.open('./data/cyh1_mask.jpg')
# 이미지 리사이징
# default 512*512
init_image = init_image.resize((512,512))
mask_image = mask_image.resize((512,512))
# 원본, 마스크 이미지 시각화
make_image_grid([init_image, mask_image], rows=1, cols=2)

# 인페인팅을 위한 컨디션 이미지를 생성하는 함수 정의
def make_inpaint_condition(image, image_mask): # 원본 이미지를 RGB 모드로 변환하고 numpy 배열로 변경한 후, float32 타입으로 변환하고 0~1 사이로 정규화
# 마스크 이미지를 그레이스케일(L 모드)로 변환하고 numpy 배열로 변경한 후, float32 타입으로 변환하고 0~1 사이로 정규화
image = np.array(image.convert("RGB")).astype(np.float32) / 255.0
image_mask = np.array(image_mask.convert("L")).astype(np.float32) / 255.0
assert image.shape[0:1] == image_mask.shape[0:1] # 원본 이미지와 마스크 이미지의 높이와 너비가 동일한지 확인
# 마스크 이미지에서 값이 0.5보다 큰 위치(마스크된 영역)에 해당하는 원본 이미지의 픽셀 값을 -1.0으로 설정
image[image_mask > 0.5] = -1.0 # 마스크된 픽셀로 설정
image = np.expand_dims(image, 0).transpose(0, 3, 1, 2) # 이미지 배열에 배치 차원을 추가하고, 차원 순서를 (배치, 채널, 높이, 너비)로 변경
image = torch.from_numpy(image) # numpy 배열을 PyTorch 텐서로 변환
return image # 변환된 이미지를 반환
# 초기 이미지와 마스크 이미지를 이용해 컨디션 이미지 생성
condition_image = make_inpaint_condition(init_image, mask_image)
# controlnet 모델 로딩
controlnet = ControlNetModel.from_pretrained(
"lllyasviel/control_v11p_sd15_inpaint", # 인페인팅용으로 학습된 사전학습 모델 주소
torch_dtype = torch.float16, # 모델의 데이터 타입을 float16으로 줄여서 메모리 사용량을 적게 만듬
use_safetensors=True # 텐서연산을 안정화 시켜주는 역할
)
# pipeline 구축
pipeline = StableDiffusionControlNetInpaintPipeline.from_pretrained(
"sd-legacy/stable-diffusion-v1-5", # 사용할 stable diffusion 모델
controlnet = controlnet, # 파이프라인과 결합할 사전학습된 controlnet 연결
torch_dtype = torch.float16, # 모델의 데이터 타입을 float16으로 줄여서 메모리 사용량을 적게 만듦
use_safetensors=True # 텐서연산을 안정화 시켜주는 역할
)
# 스케줄러를 UniPCMultistepScheduler로 변경
# 기존 파이프라인의 스케줄러 설정을 가져와서 새로운 스케줄러를 생성함
pipeline.scheduler = UniPCMultistepScheduler.from_config(pipeline.scheduler.config)
# 모델 CPU 오프로드를 활성화함
# - 이 기능을 사용하면 GPU 메모리가 부족할 때 CPU로 모델의 일부를 이동시켜 메모리 효율을 높일 수 있음
pipeline.enable_model_cpu_offload()
prompt = "big eyes, eyebrow, scared, best quality, extremely detailed"
# 생성 시 제외할 요소를 지정하는 네거티브 프롬프트를 설정
# 원하지 않는 이미지의 특징을 나열
negative_prompt = "monochrome, lowres, bad anatomy, worst quality, low quality, full body shot"
# 흑백, 저해상도, 나쁜 해부학, 최악의 화질, 저화질, 전신 샷
# 재현성을 위해 시드를 고정함
generator = torch.Generator("cuda").manual_seed(2024)
# 파이프라인을 실행하여 이미지를 생성
output = pipeline(
prompt, # 텍스트 프롬프트
num_inference_steps=80, # 디노이징 스텝 수 (클수록 품질 향상)
# eta=1.0, # 다양성 조절 파라미터 (DDIM 스케줄러에서 사용)
image=init_image, # 초기 이미지 (인페인팅 전 원본 이미지)
mask_image=mask_image, # 마스크 이미지 (수정할 영역을 지정)
control_image=condition_image, # 컨디션 이미지 (모델에 추가 정보를 제공)
generator=generator, # 랜덤 시드 설정을 위한 생성기
negative_prompt=negative_prompt # 네거티브 프롬프트 (생성에서 제외할 요소)
).images[0]
# 초기 이미지, 마스크 이미지, 생성된 이미지를 한 행에 나란히 표시함
make_image_grid([init_image, mask_image, output], rows=1, cols=3)
output.save("output.jpg")