즐겁게!! 자신있게!! 살아보세!!

재밌는 인생을 위하여! 영촤!

AI/Deep Learning

[DL] Keras MNIST Dataset으로 U-net 구현

Godwony 2020. 5. 7. 09:35
728x90
반응형

MNIST DATA로 UNET 모델 구현하는 실습을 진행하였습니다.

 

모델 구조를 파악하고 MNIST에 맞는 구조를 build 하였습니다.

MNIST의 train, test 셋은 lebeling 된 데이터라 약간의 변형이 필요했습니다.

 

unet에서 쓰이는 y_train, test set은 MNIST와 같은 0~9로 이루어진 숫자가 아니라 image가 필요했습니다.

 

1. Data set 선정

변경 전 변경 후 내용
x_trian y_train 학습 할 실제 이미지의 라벨링
x_test y_test 평가 할 실제 이미지의 라벨링

기존의 실제 image data set은 label image로 대체하고,

 

train 하기 위한 dataset은 x_train image에 직접적으로 noise를 추가하였습니다.

 

2. 모델 구조

MNIST는 28x28 크기의 image로 많이 공개되어 있는 unet의 conv 5번, deconv 4번을 할 수가 없었습니다.

 

28 > 14 > 7 > 3 > 1 > 3 > 7 > 14 > 28

 

중간 layer를 삭제하고 28 > 14 > 7 > 14 > 28 이런 식의 네트워크를 구성하게 되었습니다..

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, MaxPooling2D, Conv2DTranspose, concatenate
from tensorflow.keras import backend as keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import ModelCheckpoint, LearningRateScheduler


def unet(input_size=(28,28,1)):
    inputs = Input(input_size)
    depth = 14

    conv1 = Conv2D(depth*1, (3, 3), activation='relu', padding='same')(inputs)
    conv1 = BatchNormalization()(conv1)
    conv1 = Conv2D(depth*1, (3, 3), activation='relu', padding='same')(conv1)
    conv1 = BatchNormalization()(conv1)
    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)

    conv2 = Conv2D(depth*2, (3, 3), activation='relu', padding='same')(pool1)
    conv2 = BatchNormalization()(conv2)
    conv2 = Conv2D(depth*2, (3, 3), activation='relu', padding='same')(conv2)
    conv2 = BatchNormalization()(conv2)
    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)

    conv3 = Conv2D(depth*4, (3, 3), activation='relu', padding='same')(pool2)
    conv3 = BatchNormalization()(conv3)
    conv3 = Conv2D(depth*4, (3, 3), activation='relu', padding='same')(conv3)
    conv3 = BatchNormalization()(conv3)

    up1 = concatenate([Conv2DTranspose(depth*2, (2, 2), strides=(2, 2), padding='same')(conv3), conv2], axis=3)
    dconv1 = Conv2D(depth*2, (3, 3), activation='relu', padding='same')(up1)
    dconv1 = BatchNormalization()(dconv1)
    dconv1 = Conv2D(depth*2, (3, 3), activation='relu', padding='same')(dconv1)
    dconv1 = BatchNormalization()(dconv1)

    up2 = concatenate([Conv2DTranspose(depth*1, (2, 2), strides=(2, 2), padding='same')(dconv1), conv1], axis=3)
    dconv2 = Conv2D(depth*1, (3, 3), activation='relu', padding='same')(up2)
    dconv2 = BatchNormalization()(dconv2)
    dconv2 = Conv2D(depth*1, (3, 3), activation='relu', padding='same')(dconv2)
    dconv2 = BatchNormalization()(dconv2)

    outputs = Conv2D(1, (1, 1), activation='sigmoid')(dconv2)
    return Model(inputs=[inputs], outputs=[outputs])

model = unet()

model.compile(loss="binary_crossentropy", optimizer="adam", metrics=['accuracy'])
model.summary()

 

3. 첫 번째 실습

동일 위치의 noise를 추가한 train set을 학습했더니 결과가 만족스럽지 못했습니다.

 

동일 위치의 noise가 학습된 model로 prediction을 하면 그 외의 noise는 잡아내지 못하였습니다.

 

accuray도 생각보다 낮은 수치입니다.

 

사실 처음부터 '동일 위치'라는 전제 조건이 있었던 건 아닙니다.

 

4. 두 번째 실습

x_trian set 전부를 random noise를 적용시켜봤습니다.

 

첫 번째 실습보다는 다소 noise size가 작아졌지만 전체 image의 random noise를 잘 소화해 낼 수 있는지가 관건이었습니다.

5. 결과

epoch = 10

batch_size = 3

train data set = train 1000개 7:3 비율 (validation_split=0.3)

 

random noise로 구성해서 학습시켰더니 좀 더 결과물이 좋았습니다.

 

git link : https://github.com/hiwony7933/Unet

728x90
반응형