6. U-Net (Color to Gray)
데이터 소개
- portrait 데이터로 유명한 PFCN dataset 사용
이미지는 다음과 같은 것을 보여준다.
- 800 x 600의 사람 portrait 이미지
- 사람 영역에 대한 흑백 portrait 이미지
- pfcn_original
- 원본 800 x 600 이미지들
- pfcn_small
- colab용 100 x 75 이미지들
최종 목표
- 작게 줄인 PFCN 데이터를 이용해 사람 영역 추출
- 코앱에 구글 drive 연동
- 큰 사진을 작게 줄이기
- 이미지에 대한 오토인코더식 접근 방법
- 칼라 사진을 흑백 사진으로 만드는 모델 이해
전처리
1
2
3
4
5
6
7
8
9
10
"""
데이터 불러오기
"""
dataset = np.load('datasets/pfcn_small.npz')
print(list(dataset.keys()))
# ['train_images', 'test_images', 'train_mattes', 'test_mattes']
train_images = dataset['train_images']
test_images = dataset['test_images']
1
2
3
4
5
6
7
8
9
10
"""
칼라 이미지를 흑백이미지로 변환하여 학습 데이터 생성
"""
from skimage import color
train_gray_images = np.array([color.rgb2gray(img).reshape(100, 75, 1) for img in train_images])
test_gray_images = np.array([color.rgb2gray(img).reshape(100, 75, 1) for img in test_images])
print(train_gray_images.shape) # (1700, 100, 75, 1)
print(test_gray_images.shape) # (300, 100, 75, 1)
모델링 및 학습
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
from keras.layers import Dense, Input, MaxPool2D, Conv2D, Conv2DTranspose, Flatten, Reshape, Activation
from keras.layers import BatchNormalization, Dropout, Activation, concatenate
from keras.models import Model
def conv2d_block(x, channel):
x = Conv2D(filters=channel, kernel_size=3, padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(filters=channel, kernel_size=3, padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
return x
def unet_black():
inputs = Input(shape=(100, 75, 3))
c1 = conv2d_block(inputs, 16)
p1 = MaxPool2D(pool_size=(2))(c1)
p1 = Dropout(0.1)(p1)
c2 = conv2d_block(p1, 32)
p2 = MaxPool2D(pool_size=(2))(c2)
p2 = Dropout(0.1)(p2)
c3 = conv2d_block(p2, 64)
p3 = MaxPool2D(pool_size=(2))(c3)
p3 = Dropout(0.1)(p3)
c4 = conv2d_block(p3, 128)
p4 = MaxPool2D(pool_size=(2))(c4)
p4 = Dropout(0.1)(p4)
c5 = conv2d_block(p4, 256)
u6 = Conv2DTranspose(128, kernel_size=2, strides=2, padding='valid', output_padding=(0, 1))(c5)
u6 = concatenate([u6, c4])
u6 = Dropout(0.1)(u6)
c6 = conv2d_block(u6, 128)
u7 = Conv2DTranspose(64, kernel_size=2, strides=2, padding='valid', output_padding=(1, 0))(c6)
u7 = concatenate([u7, c3])
u7 = Dropout(0.1)(u7)
c7 = conv2d_block(u7, 64)
u8 = Conv2DTranspose(32, kernel_size=2, strides=2, padding='valid', output_padding=(0, 1))(c7)
u8 = concatenate([u8, c2])
u8 = Dropout(0.1)(u8)
c8 = conv2d_block(u8, 32)
u9 = Conv2DTranspose(16, kernel_size=2, strides=2, padding='valid', output_padding=(0, 1))(c8)
u9 = concatenate([u9, c1])
u9 = Dropout(0.1)(u9)
c9 = conv2d_block(u9, 16)
outputs = Conv2D(filters = 1, kernel_size = 1, activation = 'sigmoid')(c9)
model = Model(inputs, outputs)
return model
model = unet_black()
model.compile(loss = 'mae', optimizer = 'adam', metrics=['accuracy'])
hist = model.fit(
train_images,
train_gray_images,
validation_data=(
test_images,
test_gray_images
),
epochs= 15,
verbose=1
)
매우 간단한 모델
1
2
3
4
5
6
7
8
9
10
11
from keras import backend as K
def simple_black():
inputs = Input(shape = (100, 75, 3))
x = Conv2D(filters = 3, kernel_size = 1, use_bias=False)(inputs) # 30 -> 15 -> 3
x = Conv2D(filters = 1, kernel_size = 1, use_bias=False)(x)
x = K.clip(x, 0.0, 1.0) # 0 ~ 1 까지로 보정
return Model(inputs, x)
# 학습은 이전과 동일하게
This post is licensed under CC BY 4.0 by the author.