[PYTHON] Lernen Sie mit Chainer, monochrome Bilder einzufärben

Überblick

――Lassen Sie das Erlernen der Kolorierung von monochromen Bildern mit Chainer einfach implementieren. ――Recent Chainer kann abstrakt geschrieben werden, daher werde ich es mit Trainer usw. implementieren.

Datensatz

Verwenden Sie CIFAR-100 für den Datensatz. Chainer verfügt über mehrere benutzerfreundliche Datensätze wie MNIST und CIFAR-100. Dieses Mal habe ich mich für CIFAR-100 entschieden, mit dem sich schnell viele Farbbilder erstellen lassen. Ich denke jedoch, dass ein Datensatz mit mehr Bildtypen ursprünglich geeignet ist.

Die Verwendung von CIFAR-100 mit Chainer ist wie folgt implementiert.

train, test = chainer.datasets.get_cifar100(withlabel=False)

Der von Chainer überwachte Trainingsdatensatz wird implementiert, indem ein Array von "(Trainingsdaten, Lehrerdaten)" an den Iterator übergeben wird. Um die Kolorierung von monochromen Bildern zu lernen, benötigen Sie eine Reihe von "(monochrome Bilder, Farbbilder)". Aus der diesmal verwendeten chainer.datasets.get_cifar100 () können Sie ein Array von Tapples mit dem Namen(image, label)abrufen. Da Sie jedoch keine Beschriftung benötigen, setzen Sie withlabel auf False und nur auf das image-Array. Bekommen

Ändern Sie als Nächstes den erhaltenen Farbbilddatensatz in "(Schwarzweißbild, Farbbild)". Wenn Sie mit Chainer ein eigenes Dataset erstellen, implementieren Sie es häufig mit "chainer.datasets.TupleDataset (Trainingsdatenarray, Lehrerdatenarray)". Da es jedoch einfach ist, ein monochromes Bild aus einem Farbbild zu generieren, verwenden wir dieses Mal eine Klasse, die chainer.dataset.DatasetMixin erbt, und implementieren sie, indem wir kurz vor dem Erstellen eines Mini-Batches ein monochromes Bild vorbereiten. Dieses Beispiel ist hilfreich. Es scheint, dass es einfach ist, eine Verarbeitung durchzuführen, z. B. das Bild zuzuschneiden und auf diese Weise Rauschen hinzuzufügen.

class PreprocessedDataset(chainer.dataset.DatasetMixin):
    def __init__(self, base_image_dataset):
        self.base = base_image_dataset

    def __len__(self):
        return len(self.base)

    def get_example(self, i):
        color_image = self.base[i]
        gray_image = np.ndarray((32, 32), dtype=np.float32)
        for ch in range(3):
            gray_image = (
                0.298912*color_image[0]
                + 0.586611*color_image[1]
                + 0.114478*color_image[2]
            )
        return gray_image, color_image

Netzwerkkonfiguration

Dieses Mal werde ich zwei Arten von NN ausprobieren. Eine verbindet einfach die vollständig verbundenen Schichten und die andere verbindet die Entfaltungsschicht hinter der Faltungsschicht.

class AIC_FC(chainer.Chain):
    def __init__(self, n_units):
        initializer = chainer.initializers.HeNormal()
        super(AIC_FC, self).__init__(
            fc_in = L.Linear(None, n_units),
            bn1 = L.BatchNormalization(n_units),
            fc2 = L.Linear(None, n_units),
            bn2 = L.BatchNormalization(n_units),
            fc_out = L.Linear(None, 32*32*3)
        )

    def __call__(self, x, t):
        y = self.colorize(x)
        loss = F.mean_squared_error(y, t)
        chainer.reporter.report({
            'loss': loss
        })
        return loss

    def colorize(self, x, test=False):
        h = F.elu(self.bn1(self.fc_in(x), test=test))
        h = F.elu(self.bn2(self.fc2(h), test=test))
        y = F.reshape(self.fc_out(h), (h.shape[0], 3, 32, 32))
        return y

class AIC_DC(chainer.Chain):
    def __init__(self, n_ch):
        initializer = chainer.initializers.HeNormal()
        super(AIC_DC, self).__init__(
            cv_in = L.Convolution2D(1, n_ch//4, 4, 2, 1),
            bn1 = L.BatchNormalization(n_ch//4),
            cv1 = L.Convolution2D(n_ch//4, n_ch//2, 4, 2, 1),
            bn2 = L.BatchNormalization(n_ch//2),
            cv2 = L.Convolution2D(n_ch//2, n_ch, 4, 2, 1),
            bn3 = L.BatchNormalization(n_ch),
            cv3 = L.Convolution2D(n_ch, n_ch, 4, 2, 1),
            bn4 = L.BatchNormalization(n_ch),
            dc1 = L.Deconvolution2D(n_ch, n_ch, 4, 2, 1),
            bn5 = L.BatchNormalization(n_ch),
            dc2 = L.Deconvolution2D(n_ch, n_ch//2, 4, 2, 1),
            bn6 = L.BatchNormalization(n_ch//2),
            dc3 = L.Deconvolution2D(n_ch//2, n_ch//4, 4, 2, 1),
            bn7 = L.BatchNormalization(n_ch//4),
            dc_out = L.Deconvolution2D(n_ch//4, 3, 4, 2, 1, outsize=(32, 32))
        )

    def __call__(self, x, t):
        y = self.colorize(x)
        loss = F.mean_squared_error(y, t)
        chainer.reporter.report({
            'loss': loss
        })
        return loss

    def colorize(self, x, test=False):
        h = F.reshape(x, (x.shape[0], 1, 32, 32))
        h = F.elu(self.bn1(self.cv_in(h), test=test))
        h = F.elu(self.bn2(self.cv1(h), test=test))
        h = F.elu(self.bn3(self.cv2(h), test=test))
        h = F.elu(self.bn4(self.cv3(h), test=test))
        h = F.elu(self.bn5(self.dc1(h), test=test))
        h = F.elu(self.bn6(self.dc2(h), test=test))
        h = F.elu(self.bn7(self.dc3(h), test=test))
        y = self.dc_out(h)
        return y

Als ich versuchte, das vollständig verbundene NN zu vertiefen, wurde nur ein verschwommenes Bild erzeugt (Konvergenz ist langsam?), Also habe ich es flacher gemacht.

Übrigens scheint das tatsächlich kolorierte NN ein komplizierteres Design zu haben. (Referenz)

Umsetzung des Lernens

Der Fluss der Lernimplementierung in Chainer

  1. Erstellen Sie ein Modell
  2. Optimierungseinstellungen
  3. Vorbereitung des Datensatzes
  4. Erstellen Sie einen Iterator aus dem Datensatz
  5. Stellen Sie Updater ein
  6. Richten Sie den Trainer ein

Es wird sein. Neben Adam verfügt Optimizer auch über grundlegende Funktionen wie SGD und Momentum SGD, und es scheint, dass Standard Updater für Probleme ausreicht, bei denen Updater keine komplizierten Verlustberechnungen wie GAN durchführt. Im Vergleich zu der Zeit, als ich alles selbst geschrieben habe, kann ich es sehr genießen, weil diejenigen vorbereitet sind, die sich standardmäßig gut anfühlen. Da nur die erforderlichen Teile geändert werden müssen, ist es für andere Personen leichter zu verstehen, und ich bin dankbar.

Implementieren Sie Modelltests

Probleme wie dieses sind allein aufgrund des Verlustwerts schwer zu verstehen, daher möchte ich sie visualisieren. Implementieren Sie also den Modelltest mit der Trainer-Erweiterung. Erweiterungen erben von chainer.training.extention.Extension usw. oder werden mit chainer.training.make_extension () erstellt. Implementieren Sie Modelltests und das Speichern von Bildern mit "chainer.training.make_extension ()" wie folgt. (Imsave von scipy.misc wird importiert.)

Ein Testbild wird getrennt von den Trainingsdaten erstellt.

@chainer.training.make_extension(trigger=(1, 'epoch'))
def test_model(trainer):
    colorized_img = chainer.cuda.to_cpu(F.clipped_relu(model.colorize(test_img, test=True), z=1.0).data)
    imsave(
        'test_colorized{}.png'.format(trainer.updater.epoch),
        colorized_img
        .transpose(0, 2, 3, 1)
        .reshape((8, 8, 32, 32, 3))
        .transpose(1, 2, 0, 3, 4)
        .reshape(8*32, 8*32, 3)
    )
trainer.extend(test_model)

Lernergebnis

Ich werde das Ergebnis des Lernens vorstellen. Dieses Mal habe ich zwei NNs ausprobiert, ein vollständig verbundenes NN und ein verschlungenes NN, daher werde ich sie mit dem Lernstatus zum Zeitpunkt des Lernens in der 30. Epoche vergleichen. Wir haben gelernt, dass n_Einheiten von vollständig verbundenem NN 2048 und n_ch von Faltung NN 512 ist.

Farbbild

test.png

Monochromes Bild

test_gray.png

Nach 30 Epochen

Vollständig verbunden NN 30epoch3L2048units.png

Falten NN 30epochELU512ch.png

Vollständig kombiniertes NN scheint insgesamt ein körniges Bild zu sein. Ich war überrascht, dass selbst ein einfaches NN viele Farben hatte, aber ich habe das Gefühl, dass das gefaltete NN lebendigere und schönere Bilder ausgeben kann.

Wenn man sich jedes Bild ansieht, scheint es, dass der Himmel und das Meer gut erkannt werden und die Farben ordentlich platziert sind. Es scheint jedoch schwierig zu sein, zwischen dem blauen Himmel und dem Sonnenuntergang zu unterscheiden. Im Bild unten rechts, das ein kleines Tier zu zeigen scheint, wird der Boden erkannt und die Braun- und Grasfarben werden reproduziert. Es ist jedoch etwas zu grasig im Vergleich zur richtigen Antwort.

Änderungen aufgrund unterschiedlicher Aktivierungsfunktionen

Das obige Bild zeigt die Verwendung von elu für die Aktivierungsfunktion. Ich habe auch untersucht, wie sich das Finish ändert, wenn relu oder leaky_relu als Aktivierungsfunktion verwendet wird. Es werden nur die Ergebnisse mit der Faltung NN, 30 Epoche mit n_ch von 512 vorgestellt.

relu 30epochRelu512ch.png

leaky_relu 30epoch512ch.png

elu 30epochELU512ch.png

Das Relu ist lebendig verarbeitet, hat aber einen leicht unscharfen Eindruck. elu und undichtes relu scheinen in der Bildschärfe dem relu überlegen zu sein. undichtes relu vermittelt einen eindruck zwischen elu und relu.

Ganzer Code verwendet

#! /usr/bin/env python
# coding : utf-8

import argparse
import numpy as np
from scipy.misc import imsave
import chainer
import chainer.functions as F
import chainer.links as L
from chainer.training import extensions 


class PreprocessedDataset(chainer.dataset.DatasetMixin):
    def __init__(self, base_image_dataset):
        self.base = base_image_dataset

    def __len__(self):
        return len(self.base)

    def get_example(self, i):
        color_image = self.base[i]
        gray_image = np.ndarray((32, 32), dtype=np.float32)
        for ch in range(3):
            #Berechnen Sie die Helligkeit und erstellen Sie ein monochromes Bild
            gray_image = (
                0.298912*color_image[0]
                + 0.586611*color_image[1]
                + 0.114478*color_image[2]
            )
        return gray_image, color_image

class AIC_FC(chainer.Chain):
    def __init__(self, n_units):
        initializer = chainer.initializers.HeNormal()
        super(AIC_FC, self).__init__(
            fc_in = L.Linear(None, n_units),
            bn1 = L.BatchNormalization(n_units),
            fc2 = L.Linear(None, n_units),
            bn2 = L.BatchNormalization(n_units),
            fc_out = L.Linear(None, 32*32*3)
        )

    def __call__(self, x, t):
        y = self.colorize(x)
        loss = F.mean_squared_error(y, t)
        chainer.reporter.report({
            'loss': loss
        })
        return loss

    def colorize(self, x, test=False):
        h = F.elu(self.bn1(self.fc_in(x), test=test))
        h = F.elu(self.bn2(self.fc2(h), test=test))
        y = F.reshape(self.fc_out(h), (h.shape[0], 3, 32, 32))
        return y

class AIC_DC(chainer.Chain):
    def __init__(self, n_ch):
        initializer = chainer.initializers.HeNormal()
        super(AIC_DC, self).__init__(
            cv_in = L.Convolution2D(1, n_ch//4, 4, 2, 1),
            bn1 = L.BatchNormalization(n_ch//4),
            cv1 = L.Convolution2D(n_ch//4, n_ch//2, 4, 2, 1),
            bn2 = L.BatchNormalization(n_ch//2),
            cv2 = L.Convolution2D(n_ch//2, n_ch, 4, 2, 1),
            bn3 = L.BatchNormalization(n_ch),
            cv3 = L.Convolution2D(n_ch, n_ch, 4, 2, 1),
            bn4 = L.BatchNormalization(n_ch),
            dc1 = L.Deconvolution2D(n_ch, n_ch, 4, 2, 1),
            bn5 = L.BatchNormalization(n_ch),
            dc2 = L.Deconvolution2D(n_ch, n_ch//2, 4, 2, 1),
            bn6 = L.BatchNormalization(n_ch//2),
            dc3 = L.Deconvolution2D(n_ch//2, n_ch//4, 4, 2, 1),
            bn7 = L.BatchNormalization(n_ch//4),
            dc_out = L.Deconvolution2D(n_ch//4, 3, 4, 2, 1, outsize=(32, 32))
        )

    def __call__(self, x, t):
        y = self.colorize(x)
        loss = F.mean_squared_error(y, t)
        chainer.reporter.report({
            'loss': loss
        })
        return loss

    def colorize(self, x, test=False):
        #Umformen, so dass ndim 4 für die Eingabe in die Faltungsebene ist
        h = F.reshape(x, (x.shape[0], 1, 32, 32))
        h = F.elu(self.bn1(self.cv_in(h), test=test))
        h = F.elu(self.bn2(self.cv1(h), test=test))
        h = F.elu(self.bn3(self.cv2(h), test=test))
        h = F.elu(self.bn4(self.cv3(h), test=test))
        h = F.elu(self.bn5(self.dc1(h), test=test))
        h = F.elu(self.bn6(self.dc2(h), test=test))
        h = F.elu(self.bn7(self.dc3(h), test=test))
        y = self.dc_out(h)
        return y


def main():
    parser = argparse.ArgumentParser(description='Automatic Image Colorization')
    parser.add_argument('--batchsize', '-b', type=int, default=64,
                        help='Number of images in each mini-batch')
    parser.add_argument('--epoch', '-e', type=int, default=30,
                        help='Number of sweeps over the dataset to train')
    parser.add_argument('--gpu', '-g', type=int, default=0,
                        help='GPU ID (negative value indicates CPU)')
    parser.add_argument('--resume', '-r', default='',
                        help='Resume the training from snapshot')
    parser.add_argument('--n_ch', '-nc', type=int, default=1024,
                        help='Number of channels')
    parser.add_argument('--n_units', '-nu', type=int, default=0,
                        help='Number of units')
    args = parser.parse_args()
    print('# GPU: {}'.format(args.gpu))
    print('# Minibatch-size: {}'.format(args.batchsize))
    print('# epoch: {}'.format(args.epoch))

    if args.n_units > 0:
        print('# n_units: {}\n'.format(args.n_units))
        model = AIC_FC(args.n_units)
    else:
        print('# n_ch: {}\n'.format(args.n_ch))
        model = AIC_DC(args.n_ch)
    if args.gpu >= 0:
        chainer.cuda.get_device().use()
        model.to_gpu()

    opt = chainer.optimizers.Adam()
    opt.setup(model)

    train, test = chainer.datasets.get_cifar100(withlabel=False)
    test_img = (
        0.298912*test[:64,0]
        + 0.586611*test[:64,1]
        + 0.114478*test[:64,2]
    )
    #Speichern Sie 64 Bilder als einzelnes 8x8-Bild
    imsave(
        'test.png',
        test[:64]
        .transpose(0, 2, 3, 1)
        .reshape((8, 8, 32, 32, 3))
        .transpose(1, 2, 0, 3, 4)
        .reshape(8*32, 8*32, 3)
    )
    imsave(
        'test_gray.png',
        test_img
        .reshape((8, 8, 32, 32))
        .transpose(1, 2, 0, 3)
        .reshape(8*32, 8*32)
    )
    if args.gpu >= 0:
        test_img = chainer.cuda.to_gpu(test_img)


    dataset = PreprocessedDataset(train)
    iterator = chainer.iterators.MultiprocessIterator(dataset, args.batchsize)

    updater = chainer.training.StandardUpdater(iterator, opt, device=args.gpu)
    trainer = chainer.training.Trainer(updater, (args.epoch, 'epoch'))

    trainer.extend(extensions.LogReport())
    trainer.extend(extensions.PrintReport([
        'epoch', 'loss', 'elapsed_time'
    ]))
    @chainer.training.make_extension(trigger=(10, 'epoch'))
    def test_model(trainer):
        #Wertebereich 0~Beschnitten auf 1_Durch relu
        colorized_img = chainer.cuda.to_cpu(F.clipped_relu(model.colorize(test_img, test=True), z=1.0).data)
        imsave(
            'test_colorized{}.png'.format(trainer.updater.epoch),
            colorized_img
            .transpose(0, 2, 3, 1)
            .reshape((8, 8, 32, 32, 3))
            .transpose(1, 2, 0, 3, 4)
            .reshape(8*32, 8*32, 3)
        )
    trainer.extend(test_model)
    trainer.extend(extensions.ProgressBar(update_interval=100))

    trainer.run()

if __name__ == '__main__':
    main()

Recommended Posts

Lernen Sie mit Chainer, monochrome Bilder einzufärben
Ich habe versucht, die Sündenfunktion mit Chainer zu trainieren
Lernen Sie mit Chainer elliptische Bahnen
Ich möchte Bilder kratzen und trainieren
Fügen Sie mit Pythonista Bilder zu iOS-Fotos hinzu
Fügen Sie Bildern mit Python2.7 Gaußsches Rauschen hinzu
Vorbereitung auf das Erlernen technischer Indikatoren mit TFlearn
Laden Sie Bilder mit Python auf Google Drive hoch
Betreiben Sie Paints Chainer mit Selen, um Bilder im Verzeichnis automatisch einzufärben
Ich habe versucht, den Winkel von Sin und Cos mit Chainer zu lernen
Öffnen Sie AI Gym, um mit PD-gesteuertem Cart Pole zu lernen
Ich habe versucht, mit TF Learn die logische Operation zu lernen
Lernen Sie mit Caffe, handschriftliche Zahlen (MNIST) zu erkennen
Laden Sie das Kaffeemodell mit Chainer und klassifizieren Sie die Bilder
Konvertieren Sie PDFs mit Python in Massenbilder
Ich möchte mehrere Bilder mit matplotlib anzeigen.
Kategorisieren Sie Gesichtsbilder von Anime-Charakteren mit Chainer
Ein Liner, um Lena-Bilder mit scipy zu machen
So zeigen Sie Bilder kontinuierlich mit matplotlib Memo an
Seq2Seq (1) mit Chainer
AWS-Schrittfunktionen zum Lernen anhand eines Beispiels
Laden Sie Bilder mit tkinter mit GUI auf S3 hoch
Wie man Kaldi mit JUST Corpus trainiert
Erfahren Sie, wie Sie Bilder aus dem TensorFlow-Code aufblasen
Mit matplotlib erstellte Bilder werden von dvi nach pdf verschoben
So verarbeiten Sie Kamerabilder mit Teams und Zoom
Ich habe versucht, DCGAN mit PyTorch zu implementieren und zu lernen
Site-Zusammenfassung zum Erlernen des maschinellen Lernens mit englischen Videos
Autoencoder im Chainer (Hinweise zur Verwendung von + Trainer)
Wie man strukturiertes SVM von ChainCRF mit PyStruct lernt
[How to!] Lerne und spiele Super Mario mit Tensorflow !!
MVC-Model Edition, um nur mit Voreingenommenheit von 0 zu lernen
Lerne Python mit ChemTHEATER
Konvertieren Sie 202003 bis 2020-03 mit Pandas
Lerne Zundokokiyoshi mit LSTM
Pandas lernen mit Chemoinfomatik
Verwenden Sie Tensorboard mit Chainer
Scikit-Lernen mit Chemoinfomatik
Lernen Sie mit Chemo Informatics Matplotlib
Einführung in Private Chainer
Lernen Sie mit Chemo Informatics NumPy
DCGAN mit TF Learn
Bild mit Python-Pptx zentrieren
Lernen Sie Pendulum-v0 mit DDPG
Ist es möglich, ähnliche Bilder nur mit ImageHash zu erkennen?
Cloud-Funktionen zum Ändern der Bildgröße mithilfe von OpenCV mit Cloud Storage-Trigger
So laden Sie keine Bilder, wenn Sie PhantomJS mit Selen verwenden
Verfahren zum Erlernen und Ableiten eines Transformator-Englisch-Japanisch-Übersetzungsmodells mit CloudTPU
Konvertieren Sie Bilder mit PIL (Python Imaging Library) in Sepia.
Konvertieren Sie verstümmelte gescannte Bilder mit Pillow und PyPDF in PDF
[Lass uns mit Python spielen] Bildverarbeitung zu Monochrom und Punkten
Ich habe versucht, ListNet of Rank Learning mit Chainer zu implementieren
Maschinelles Lernen mit Nogisaka 46 und Keyakizaka 46 Teil 1 Einführung
Speichern Sie Bilder im Web mit Python (Colab) auf einem Laufwerk.