以前のカラーライズ動画のURLです
イマイチですがこれをどれだけ改良できるか?
逆パターンもあるかもしれませんが、チャレンジです!
tensorflow1系から2系にアプグレードする方法もあるようです
コマンド
!tf_upgrade_v2 --infile 元のpyファイル --outfile アップグレード後のpyファイル
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
tf.executing_eagerly()
tf.disable_v2_behavior()
tf.executing_eagerly()
import os
import glob
import math
import random
from keras import callbacks
import numpy as np
import matplotlib.pyplot as plt
import keras
from keras import backend as K
from keras.models import Model, Sequential
from keras.layers import Conv2D, Dense, Input, MaxPooling2D, UpSampling2D, Lambda
from keras.preprocessing.image import load_img, img_to_array, array_to_img, ImageDataGenerator
import glob
import math
import random
from keras import callbacks
import numpy as np
import matplotlib.pyplot as plt
import keras
from keras import backend as K
from keras.models import Model, Sequential
from keras.layers import Conv2D, Dense, Input, MaxPooling2D, UpSampling2D, Lambda
from keras.preprocessing.image import load_img, img_to_array, array_to_img, ImageDataGenerator
data_path = 'img/colorize'
data_lists = glob.glob(os.path.join(data_path, '*.jpg')) # 画像をまとめてリスト化する
data_lists = glob.glob(os.path.join(data_path, '*.jpg')) # 画像をまとめてリスト化する
val_n_sample = math.floor(len(data_lists)*0.1) # 検証用に1割
test_n_sample = math.floor(len(data_lists)*0.1) # テスト用に1割
train_n_sample = len(data_lists) - val_n_sample - test_n_sample # 残り8割を学習用に
test_n_sample = math.floor(len(data_lists)*0.1) # テスト用に1割
train_n_sample = len(data_lists) - val_n_sample - test_n_sample # 残り8割を学習用に
val_lists = data_lists[:val_n_sample] # それぞれをリスト化する
test_lists = data_lists[val_n_sample:val_n_sample + test_n_sample]
train_lists = data_lists[val_n_sample + test_n_sample:train_n_sample + val_n_sample + test_n_sample]
test_lists = data_lists[val_n_sample:val_n_sample + test_n_sample]
train_lists = data_lists[val_n_sample + test_n_sample:train_n_sample + val_n_sample + test_n_sample]
print(len(train_lists), len(val_lists), len(test_lists)) # 表示して確認する
前処理:「RGB」を「LAB」に変換
import cv2
img_size = 224
def rgb2lab(rgb):
assert rgb.dtype == 'uint8' # 符号なしの8ビット整数
return cv2.cvtColor(rgb, cv2.COLOR_RGB2Lab) # OpenCVを使って RGB から LAB に変換する
def lab2rgb(lab):
assert lab.dtype == 'uint8'
return cv2.cvtColor(lab, cv2.COLOR_Lab2RGB) # OpenCVを使って LAB から RGB に変換する
assert lab.dtype == 'uint8'
return cv2.cvtColor(lab, cv2.COLOR_Lab2RGB) # OpenCVを使って LAB から RGB に変換する
def get_lab_from_data_list(data_list):
x_lab = []
for f in data_list: # リストから1個ずつload_imgで画像を読み込む
rgb = img_to_array( # それをimage_to_arrayで配列化する
load_img(
f,
target_size=(img_size, img_size)
)
).astype(np.uint8) # 符号なし8ビット整数の配列
lab = rgb2lab(rgb) # RGB から LAB に変換する
x_lab.append(lab) # それらを順に最後尾に追加していく
return np.stack(x_lab) # 新たな軸(次元)に沿って結合する
x_lab = []
for f in data_list: # リストから1個ずつload_imgで画像を読み込む
rgb = img_to_array( # それをimage_to_arrayで配列化する
load_img(
f,
target_size=(img_size, img_size)
)
).astype(np.uint8) # 符号なし8ビット整数の配列
lab = rgb2lab(rgb) # RGB から LAB に変換する
x_lab.append(lab) # それらを順に最後尾に追加していく
return np.stack(x_lab) # 新たな軸(次元)に沿って結合する
モデルの構築
## A の座標範囲:[-127, 127]、B の座標範囲:[-127, 127]
## cv2の LAB の値補正
## L = L * 255 / 100 (0~255) に補正
## a = a + 128 (1~255) に補正
## b = b + 128 (1~255) に補正
from keras.layers import Conv2DTranspose
## cv2の LAB の値補正
## L = L * 255 / 100 (0~255) に補正
## a = a + 128 (1~255) に補正
## b = b + 128 (1~255) に補正
from keras.layers import Conv2DTranspose
input_shape = (224, 224, 1) # 入力画像:L の1チャンネル(L=0:白、L=100:黒)
autoencoder = Sequential()
# Encoder
autoencoder.add(
Conv2D(32, (3, 3), activation='relu',padding='same', input_shape=(224, 224, 1))) # 224x224x32 フィルター数:32、カーネル:3
autoencoder.add(
Conv2D(64, (2, 2), strides=(2, 2), padding='same')) # 112x112x64
autoencoder.add(
Conv2D(128, (3, 3), strides=(2, 2), activation='relu', padding='same')) # 56x56x128
autoencoder.add(
Conv2D(256,(3, 3), strides=(2, 2), activation='relu', padding='same')) # 28x28x256
# Decoder
autoencoder.add(
Conv2DTranspose(128, (3, 3), strides=(2, 2), padding='same')) # 56x56x128
autoencoder.add(
Conv2DTranspose(64, (3, 3), strides=(2, 2), padding='same')) # 112x112x64
autoencoder.add(
Conv2DTranspose(32, (3, 3), strides=(2, 2), padding='same')) # 224x224x32
autoencoder.add(
Conv2D(2, (1, 1), activation='relu', padding='same')) # 224x224x2 出力画像:AB の2チャンネル
autoencoder.compile(optimizer='adam', loss='mse') # A:赤/マゼンタ(正の値)と緑(負の値)の間
autoencoder.summary() # B:黄色(正の値)と青(負の値)の間
autoencoder = Sequential()
# Encoder
autoencoder.add(
Conv2D(32, (3, 3), activation='relu',padding='same', input_shape=(224, 224, 1))) # 224x224x32 フィルター数:32、カーネル:3
autoencoder.add(
Conv2D(64, (2, 2), strides=(2, 2), padding='same')) # 112x112x64
autoencoder.add(
Conv2D(128, (3, 3), strides=(2, 2), activation='relu', padding='same')) # 56x56x128
autoencoder.add(
Conv2D(256,(3, 3), strides=(2, 2), activation='relu', padding='same')) # 28x28x256
# Decoder
autoencoder.add(
Conv2DTranspose(128, (3, 3), strides=(2, 2), padding='same')) # 56x56x128
autoencoder.add(
Conv2DTranspose(64, (3, 3), strides=(2, 2), padding='same')) # 112x112x64
autoencoder.add(
Conv2DTranspose(32, (3, 3), strides=(2, 2), padding='same')) # 224x224x32
autoencoder.add(
Conv2D(2, (1, 1), activation='relu', padding='same')) # 224x224x2 出力画像:AB の2チャンネル
autoencoder.compile(optimizer='adam', loss='mse') # A:赤/マゼンタ(正の値)と緑(負の値)の間
autoencoder.summary() # B:黄色(正の値)と青(負の値)の間
ジェネレータ関数の定義
def generator_with_preprocessing(data_list, batch_size, shuffle=False):
while True:
if shuffle:
np.random.shuffle(data_list)
for i in range(0, len(data_list), batch_size):
batch_list = data_list[i:i + batch_size] # datalistをbatch_sizeごとにリスト化する
batch_lab = get_lab_from_data_list(batch_list) # そのデータをLab形式のデータに変換する
batch_l = batch_lab[:, :, :, 0:1] # 更に、batch_labからLのリストだけを抜き出す
batch_ab = batch_lab[:, :, :, 1:] # 同様に、batch_labから AB のリストだけを抜き出す
yield (batch_l, batch_ab) # 新しくそれらをタプル形式でつなぎ合わせる yeild:生み出す
while True:
if shuffle:
np.random.shuffle(data_list)
for i in range(0, len(data_list), batch_size):
batch_list = data_list[i:i + batch_size] # datalistをbatch_sizeごとにリスト化する
batch_lab = get_lab_from_data_list(batch_list) # そのデータをLab形式のデータに変換する
batch_l = batch_lab[:, :, :, 0:1] # 更に、batch_labからLのリストだけを抜き出す
batch_ab = batch_lab[:, :, :, 1:] # 同様に、batch_labから AB のリストだけを抜き出す
yield (batch_l, batch_ab) # 新しくそれらをタプル形式でつなぎ合わせる yeild:生み出す
学習・検証・評価用ジェネレータの呼び出し
batch_size = 30
train_gen = generator_with_preprocessing(train_lists, batch_size, shuffle=True)
val_gen = generator_with_preprocessing(val_lists, batch_size)
test_gen = generator_with_preprocessing(test_lists, batch_size)
val_gen = generator_with_preprocessing(val_lists, batch_size)
test_gen = generator_with_preprocessing(test_lists, batch_size)
train_steps = math.ceil(len(train_lists)/batch_size)
val_steps = math.ceil(len(val_lists)/batch_size)
test_steps = math.ceil(len(test_lists)/batch_size)
val_steps = math.ceil(len(val_lists)/batch_size)
test_steps = math.ceil(len(test_lists)/batch_size)
from keras.callbacks import ModelCheckpoint
valid_ck = ModelCheckpoint('{epoch:02d}-{val_loss:.2f}.hdf5', monitor='val_loss', verbose=0, save_best_only=True, save_weights_only=False, mode='auto', period=1)
callbacks = [valid_ck]
callbacks = [valid_ck]
from keras import callbacks
epochs= 3000
autoencoder.fit_generator(
generator=train_gen,
steps_per_epoch=train_steps,
epochs=epochs,
validation_data=val_gen,
validation_steps=val_steps,
)
epochs= 3000
autoencoder.fit_generator(
generator=train_gen,
steps_per_epoch=train_steps,
epochs=epochs,
validation_data=val_gen,
validation_steps=val_steps,
)
以降は後程・・・