CNNで白黒画像をカラー化してみる①
なにかCNNで面白いことできないかなと思ってやってみた。 初投稿なのでぎこちないのは堪忍。
データの用意
データセットはCIFAR-100を使用。
本来は画像分類のためのデータセットなのだが、
- いろいろなものの画像がある
- サイズが32*32と小さく扱いやすい
- CIFAR-10に比べ多様な画像がある
ということで採用した。kerasのデータセットを使えば簡単にロードできる。訓練用5万+テスト用1万をロードして、白黒(グレースケール)化しておく。白黒化は以下の記事を参考にした。
OpenCVとか使ってもできるらしいが、NumPyだけでも十分簡単にできそう。
(col_train, _train), (col_test, _test) = cifar100.load_data()
yuv = [0.299, 0.587, 0.114]
col_train = col_train.astype("float32") / 255
col_test = col_test.astype("float32") / 255
gray_train = yuv[0] * col_train[:, :, :, 0] + yuv[1] * col_train[:, :, :, 1] + yuv[2] * col_train[:, :, :, 2]
gray_test = yuv[0] * col_test[:, :, :, 0] + yuv[1] * col_test[:, :, :, 1] + yuv[2] * col_test[:, :, :, 2]
結果
こんな感じになった。良い感じ。次はいよいよ学習。
モデルの構築
kerasを使ってCNNのモデルを組む。 画像から新たな画像を生成するので、プーリング層はなしでひたすら畳み込む。
momentum = 0.8
model = Sequential()
model.add(Input(shape=(32,32)))
model.add(Reshape((32,32,1)))
model.add(Conv2D(32, kernel_size = 3, padding = 'same', activation = 'relu'))
model.add(Conv2D(32, kernel_size = 3, padding = 'same', activation = 'relu'))
model.add(BatchNormalization(momentum=momentum))
model.add(Dropout(0.25))
model.add(Conv2D(128, kernel_size = 5, padding = 'same', activation = 'relu'))
model.add(Conv2D(128, kernel_size = 5, padding = 'same', activation = 'relu'))
model.add(BatchNormalization(momentum=momentum))
model.add(Dropout(0.25))
model.add(Conv2D(128, kernel_size = 5, padding = 'same', activation = 'relu'))
model.add(Conv2D(128, kernel_size = 5, padding = 'same', activation = 'relu'))
model.add(BatchNormalization(momentum=momentum))
model.add(Dropout(0.25))
model.add(Conv2D(32, kernel_size = 3, padding = 'same', activation = 'relu'))
model.add(Conv2D(32, kernel_size = 3, padding = 'same', activation = 'relu'))
model.add(BatchNormalization(momentum=momentum))
model.add(Dropout(0.25))
model.add(Conv2D(3, kernel_size = 1, padding = 'same', activation = 'tanh'))
結果
左側が実際の画像、右側が今回生成された画像。いずれもテストデータ。
空とか海とかの色は結構学習できている感じだけど、ほかはひたすら茶色。なんか昔のセピア写真とかでありそう。難しい。やはり単純なCNNでは限界なのか。
次はもう少し工夫してやってみる。