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.
