오토인코더 학습을 돌린 후 GAN으로 돌리면 어떻게 될지 궁금했습니다.
GAN도 비지도 학습 이미지 생성이긴 한데 특징을 뽑아내어 생성하는 오토인코더와는 달리 노이즈로부터 이미지를 생성해 나가니까요. 데이터도 부족하고 해서 아마 잘 생성되진 않을 것이라 예측했습니다.
GAN 모델을 가져와서 데이터에 맞도록 크기를 설정해주고 학습 2000번, 200번 마다 사진 저장으로 학습시켰습니다. 처음에 코랩에서 진행했는데 이렇게 가다간 와이파이가 끊어지던, 시간이 다 되던 할 것 같아서 주피터 노트북으로 옮겨서 진행했습니다. 총 시간은 597m 1.0s 가 걸렸습니다. 학습을 돌리면서 충전 중에는 과열이 많이 되기도 해서 쿨링은 꼭 필요한 것 같습니다... 수고했다. 노트북아..... 미안.....
파라미터가 76,733,314 라니...... 오래 걸릴 것은 예측하고 있었습니다.
코드와 그 과정을 봐보겠습니다.
from tensorflow.keras.layers import Input, Dense, Reshape, Flatten, Dropout
from tensorflow.keras.layers import BatchNormalization, Activation, LeakyReLU, UpSampling2D, Conv2D
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Conv2D, MaxPooling2D, UpSampling2D
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.preprocessing import image
import keras.utils as image
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os
import random
#데이터 불러오기
face = "C:/Users/seongeun/Desktop/전북과학고등학교/STEAM/2P1L/face"
os.listdir(face)
#데이터 리스트 만들기
img_list = os.listdir(face)
print(img_list)
random.shuffle(img_list)
print(img_list)
from PIL import ImageEnhance, ImageFilter
def thkimg(img, img_size):
img = img.filter(ImageFilter.GaussianBlur(10))
enhancer = ImageEnhance.Brightness(img)
img = enhancer.enhance(4)
img = img.resize((img_size, img_size))
return img
from PIL import Image
l = len(img_list)
print(l)
img_size = 300
train_list = img_list[:int(l*0.7)]
test_list = img_list[int(l*0.7):]
train = np.empty((0, img_size, img_size))
test = np.empty((0, img_size, img_size))
img = Image.open(face+'/'+train_list[0]).convert('L')
img = img.resize((img_size, img_size))
#plt.imshow(img)
#plt.show()
for name in train_list:
img = Image.open(face+'/'+name).convert('L')
thkimg(img, img_size)
img = img.resize((img_size, img_size))
#plt.imshow(img)
#plt.show()
img_array = np.array(img)
train = np.append(train, np.array([img_array]), axis=0)
for name in test_list:
img = Image.open(face+'/'+name).convert('L')
thkimg(img, img_size)
img = img.resize((img_size, img_size))
img_array = np.array(img)
test = np.append(test, np.array([img_array]), axis=0)
print(len(train))
print(len(test))
#print(train)
#print(test)
np.savez("파일경로/face_img.npz", train=train, test=test)
face_img = "파일경로/face_img.npz"
from tensorflow.keras.layers import Input, Dense, Reshape, Flatten, Dropout
from tensorflow.keras.layers import BatchNormalization, Activation, LeakyReLU, UpSampling2D, Conv2D
from tensorflow.keras.models import Sequential, Model
import numpy as np
import matplotlib.pyplot as plt
# 생성자 모델
generator = Sequential()
generator.add(Dense(128*75*75, input_dim=100, activation=LeakyReLU(0.2)))
generator.add(BatchNormalization())
generator.add(Reshape((75, 75, 128)))
generator.add(UpSampling2D())
generator.add(Conv2D(64, kernel_size=5, padding='same'))
generator.add(BatchNormalization())
generator.add(Activation(LeakyReLU(0.2)))
generator.add(UpSampling2D())
generator.add(Conv2D(1, kernel_size=5, padding='same', activation='tanh'))
# 판별자 모델
discriminator = Sequential()
discriminator.add(Conv2D(64, kernel_size=5, strides=2, input_shape=(300,300,1), padding="same"))
discriminator.add(Activation(LeakyReLU(0.2)))
discriminator.add(Dropout(0.3))
discriminator.add(Conv2D(128, kernel_size=5, strides=2, padding="same"))
discriminator.add(Activation(LeakyReLU(0.2)))
discriminator.add(Dropout(0.3))
discriminator.add(Flatten())
discriminator.add(Dense(1, activation='sigmoid'))
discriminator.compile(loss='binary_crossentropy', optimizer='adam')
discriminator.trainable = False
# 생성자와 판별자 모델을 연결시키는 gan 모델
ginput = Input(shape=(100,))
dis_output = discriminator(generator(ginput))
gan = Model(ginput, dis_output)
gan.compile(loss='binary_crossentropy', optimizer='adam')
gan.summary()
# 신경망을 실행
def gan_train(epoch, batch_size, saving_interval):
# 데이터 불러오기
(X_train), (_) = np.load(face_img)
X_train = train.reshape(train.shape[0], 300, 300, 1).astype('float32')
X_train = (train - 127.5) / 127.5 #-1에서 1사이의 값으로 바꾸기
# X_train.shape, Y_train.shape, X_test.shape, Y_test.shape
true = np.ones((batch_size, 1))
fake = np.zeros((batch_size, 1))
for i in range(epoch):
# 실제 데이터를 판별자에 입력
idx = np.random.randint(0, X_train.shape[0], batch_size)
imgs = X_train[idx]
d_loss_real = discriminator.train_on_batch(imgs, true)
# 가상 이미지를 판별자에 입력
noise = np.random.normal(0, 1, (batch_size, 100))
gen_imgs = generator.predict(noise)
d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)
# 판별자와 생성자의 오차 계산
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
g_loss = gan.train_on_batch(noise, true)
print('epoch:%d' % i, ' d_loss:%.4f' % d_loss, ' g_loss:%.4f' % g_loss)
#중간 과정을 이미지로 저장
if i % saving_interval == 0:
#r, c = 5, 5
noise = np.random.normal(0, 1, (25, 100))
gen_imgs = generator.predict(noise)
# Rescale images 0 - 1
gen_imgs = 0.5 * gen_imgs + 0.5
fig, axs = plt.subplots(5, 5)
count = 0
for j in range(5):
for k in range(5):
axs[j, k].imshow(gen_imgs[count, :, :, 0], cmap='gray')
axs[j, k].axis('off')
count += 1
fig.savefig("./gan_face_%d.png" % i)
gan_train(2001, 32, 200) # 2000번 반복, 배치 사이즈 32, 200번마다 결과 저장
결과
역시 잘 나오진 않았습니다.
아마 학습 횟수도 부족하고 데이터도 부족해서 그런 것 같습니다.
시간이 된다면 데이터를 더 만들어서 해봐야겠습니다.
'프로그래밍 > 2P1L project' 카테고리의 다른 글
프로젝트 마무리 (0) | 2023.09.15 |
---|---|
데이터 생성과 오토인코더 활용 (1) | 2023.08.27 |
오토인코더 학습 (0) | 2023.08.22 |
데이터셋 나누기 (0) | 2023.08.12 |
코랩에서 이미지 불러오기 (0) | 2023.08.12 |