https://github.com/rezoo/illustration2vec illustration2vec ist ein Modell, das die Merkmale und Tags von Abbildungen erkennen kann. Die Struktur des Modells ist fast ein VGG-Modell. Es gibt einige Änderungen gegenüber der ursprünglichen VGG. Einzelheiten finden Sie im Kommentarpapier unter dem obigen Link. Es ist ein Modell von Kaffee und Ketten. Es ist ein interessantes Modell, aber Chainer scheint mit der Entwicklung fertig zu sein, also wollte ich es definitiv wiederverwenden und schrieb einen Konvertierungscode für Keras. Ich habe noch nie eine Taschenlampe benutzt, also lass uns durchgehen.
Die Ausführung erfolgte mit Google Colaboratory, also Link unten. https://colab.research.google.com/drive/1UZN7pn4UzU5s501dwSIA2IHGmjnAmouY
Wenn Sie den Link nicht öffnen können, kopieren Sie Folgendes in colab und es wird funktionieren.
!git clone https://github.com/rezoo/illustration2vec.git
!sh illustration2vec/get_models.sh
!pip install -r /content/illustration2vec/requirements.txt
!mv /content/illustration2vec/i2v /content/
import i2v
illust2vec_tag = i2v.make_i2v_with_chainer('/content/illustration2vec/illust2vec_tag_ver200.caffemodel', '/content/illustration2vec/tag_list.json')
%tensorflow_version 2.x
import tensorflow as tf
import numpy as np
#tag estimater model
model_tag = tf.keras.Sequential(name='illustration2vec_tag')
model_tag.add(tf.keras.layers.Input(shape=(224, 224, 3)))
pool_idx = [0, 1, 3, 5, 7]
for i, chainer_layer in enumerate(illust2vec_tag.net.children()):
kernel, bias = tuple(chainer_layer.params())
k_kernel = np.transpose(kernel.data, axes=[3, 2, 1, 0])
bias = bias.data
if i == 0:
k_kernel = k_kernel[:,:,::-1,:]
channel = bias.shape[0]
keras_layer = tf.keras.layers.Conv2D(channel, 3, padding='SAME', activation='relu', kernel_initializer=tf.keras.initializers.constant(k_kernel), bias_initializer=tf.keras.initializers.constant(bias), name='Conv_%d'%i)
model_tag.add(keras_layer)
if i in pool_idx:
model_tag.add(tf.keras.layers.MaxPooling2D())
del kernel, bias
model_tag.add(tf.keras.layers.AveragePooling2D(pool_size=(7, 7)))
model_tag.add(tf.keras.layers.Lambda(lambda x : tf.nn.sigmoid(tf.squeeze(x, axis=[1, 2])), name='sigmoid'))
model_tag.save('illust2vec_tag_ver200.h5')
del model_tag, illust2vec_tag
#feature vector model
illust2vec = i2v.make_i2v_with_chainer('/content/illustration2vec/illust2vec_ver200.caffemodel')
model = tf.keras.Sequential(name='illustration2vec')
model.add(tf.keras.layers.Input(shape=(224, 224, 3)))
pool_idx = [0, 1, 3, 5, 7]
for i, chainer_layer in enumerate(illust2vec.net.children()):
if i == 12:
break
kernel, bias = tuple(chainer_layer.params())
if len(kernel.data.shape) == 4:
k_kernel = np.transpose(kernel.data, axes=[3, 2, 1, 0])
bias = bias.data
if i == 0:
k_kernel = k_kernel[:,:,::-1,:]
channel = bias.shape[0]
keras_layer = tf.keras.layers.Conv2D(channel, 3, padding='SAME', activation='relu', kernel_initializer=tf.keras.initializers.constant(k_kernel), bias_initializer=tf.keras.initializers.constant(bias), name='Conv_%d'%i)
model.add(keras_layer)
if i in pool_idx:
model.add(tf.keras.layers.MaxPooling2D())
elif i == 10:
model.add(tf.keras.layers.Flatten())
elif len(kernel.data.shape) == 2:
model.add(tf.keras.layers.Dense(4096, kernel_initializer=tf.keras.initializers.constant(kernel.data), bias_initializer=tf.keras.initializers.constant(bias.data), name='encode1'))
del kernel, bias
model.save('illust2vec_ver200.h5')
del model, illust2vec
def resize(imgs):
mean = tf.constant(np.array([181.13838569, 167.47864617, 164.76139251]).reshape((1, 1, 3)), dtype=tf.float32)
resized = []
for img in imgs:
img = tf.cast(img, tf.float32)
im_max = tf.reduce_max(img, keepdims=True)
im_min = tf.reduce_min(img, keepdims=True)
im_std = (img - im_min) / (im_max - im_min + 1e-10)
resized_std = tf.image.resize(im_std, (224, 224))
resized_im = resized_std*(im_max - im_min) + im_min
resized_im = resized_im - mean
resized.append(tf.expand_dims(resized_im, 0))
return tf.concat(resized, 0)
Wir definieren lediglich ein Modell mit derselben Struktur in Keras und initialisieren es mit dem Gewicht des Chainer-Modells. Es gibt drei Änderungen wie folgt. ・ Gewicht transponieren Der Faltungskern dieses Kettenmodells ist (out_channel, in_channel, k_size, k_size), wurde jedoch für das Keras-Modell in (k_size, k_size, in_channel, out_channel) transponiert.
Die Eingabe des konvertierten Modells hat die Größe (Batch, 224, 224, 3). Wenn Sie die Liste von numpy.array des Bildes an den obigen Colab-Link oder die Größenänderungsfunktion im gesamten Code übergeben, wird die Größe geändert + normalisiert. Es gibt zwei Modelle, illust2vec_tag_ver200.h5 und illust2vec_ver200.h5, aber die erste Ausgabe ist die tag_list unter https://github.com/rezoo/illustration2vec. Dies ist die Wahrscheinlichkeit für jedes der 1539 Tags in .json. Die Ausgabe des zweiten Modells ist ein Merkmalsvektor des Bildes.
Bitte weisen Sie auf Mängel hin.
Recommended Posts