Dies ist ein Memo des Datensatzes, als DCGAN, eine Ableitung von GAN, mit Tensorflow durchgeführt wurde. Ich werde es grob erklären, ohne zu tief zu gehen. Ich habe neulich fast den gleichen Artikel geschrieben, aber er wurde durcheinander gebracht, also werde ich ihn ein wenig neu organisieren.
Ich möchte im Titel eine Seekuh erzeugen! Es heißt, aber zuerst dachte ich daran, Pokemon mit DCGAN zu generieren. Ich denke, ich werde es vorerst kurz aus dem Versuch heraus schreiben, Pokemon zu generieren.
Umiushi ist übrigens so eine Kreatur. Es gibt viele bunte Typen und sie sind wunderschön
Ich werde kurz über GAN schreiben. GAN ist ein Typ, der zwei Dinge trainiert: "Generator", um eine Fälschung zu machen, und "Diskriminator", um zu diskriminieren und Daten so nah wie möglich an der Realität zu generieren. Der Generator erstellt aus zufälligem Rauschen ein neues Bild mit Bezug auf reale Daten. Der Diskriminator unterscheidet das vom Generator erzeugte Bild als "falsch oder echt". Generator und Diskriminator sind gute Rivalen. Wenn Sie dies immer wieder wiederholen, werden der Generator und der Diskriminator immer intelligenter. Infolgedessen werden Bilder generiert, die den realen Daten nahe kommen.
↓ Es sieht so aus
↓ Was ich leichter geschrieben habe
Dies ist der grundlegende Mechanismus von GAN. DCGAN verwendet CNN (Convolutional Neural Network) für dieses GAN. CNN ist auf verschiedene Weise kompliziert, aber einfach ausgedrückt ist es möglich, Gewichte zwischen neuronalen Netzen zu teilen, indem das neuronale Netzwerk unter Verwendung von zwei Schichten, ** Faltungsschicht ** und ** Poolschicht **, zu einer mehrschichtigen Struktur gemacht wird. Wird möglich sein. Infolgedessen kann DCGAN das Lernen effizienter und genauer als GAN durchführen.
Ich werde dieses DCGAN verwenden, um Pokemon und Umiushi zu generieren. Auch die Erklärung von GAN und DCGAN GAN (1) Verständnis der Grundstruktur, die ich nicht mehr hören kann GAN, das ich nicht mehr hören kann (2) Bilderzeugung durch DCGAN Ist leicht zu verstehen.
Es gibt viele Arten von Pokémon, und ich habe es als Thema gewählt, weil ich dachte, es würde Spaß machen mit einem vertrauten Thema. Es gibt heute so viele Arten von Pokémon. Das Pokemon-Bild ist [hier](https://kamigame.jp/%E3%83%9D%E3%82%B1%E3%83%A2%E3%83%B3USUM/%E3%83%9D%E3%82 % B1% E3% 83% A2% E3% 83% B3 /% E8% 89% B2% E9% 81% 95% E3% 81% 84% E3% 83% 9D% E3% 82% B1% E3% 83% Heruntergeladen von A2% E3% 83% B3% E4% B8% 80% E8% A6% A7.html).
Dieses Mal habe ich übrigens die Chrome-Erweiterung ** "Image Downloader" ** verwendet, um Pokemon-Bilder zu sammeln. Es wird empfohlen, da es leicht verwendet werden kann, ohne Code zu schreiben. Ich dachte, dass die Anzahl der Daten zu gering war, also fügte ich Rotation und Inversion mit dem folgenden Code hinzu und blies ihn auf. Übrigens wird es zum einfachen Lesen im Format ".npy" gespeichert.
import os,glob
import numpy as np
from tqdm import tqdm
from keras.preprocessing.image import load_img,img_to_array
from keras.utils import np_utils
from sklearn import model_selection
from PIL import Image
#Speichern Sie Klassen in einem Array
classes = ["class1", "class2"]
num_classes = len(classes)
img_size = 128
color=False
#Bilder laden
#Schließlich werden das Bild und die Beschriftung in der Liste gespeichert
temp_img_array_list=[]
temp_index_array_list=[]
for index,classlabel in enumerate(classes):
photos_dir = "./" + classlabel
#Holen Sie sich mit glob eine Liste mit Bildern für jede Klasse
img_list = glob.glob(photos_dir + "/*.jpg ")
for img in tqdm(img_list):
temp_img=load_img(img,grayscale=color,target_size=(img_size, img_size))
temp_img_array=img_to_array(temp_img)
temp_img_array_list.append(temp_img_array)
temp_index_array_list.append(index)
#Rotationsverarbeitung
for angle in range(-20,20,5):
#Drehung
img_r = temp_img.rotate(angle)
data = np.asarray(img_r)
temp_img_array_list.append(data)
temp_index_array_list.append(index)
#Umkehren
img_trans = img_r.transpose(Image.FLIP_LEFT_RIGHT)
data = np.asarray(img_trans)
temp_img_array_list.append(data)
temp_index_array_list.append(index)
X=np.array(temp_img_array_list)
Y=np.array(temp_index_array_list)
np.save("./img_128RGB.npy", X)
np.save("./index_128RGB.npy", Y)
Ich wollte ein chimäres Pokemon machen, indem ich Pokemon voller DCGAN mische
↓
Aber was ich tatsächlich getan habe, war
Es war deutlich übertrainiert, wie Sie sowohl am erzeugten Bild als auch am Verlust sehen können. Der Diskriminator ist wahnsinnig stark. Als nächstes dachte ich über die Ursache nach und löste sie.
――Pokemon hat verschiedene Farben und Formen, so dass es einfach ist, chaotische Typen zu generieren? ――Ich möchte etwas verwenden, das bis zu einem gewissen Grad eine einheitliche Form hat. Wechseln Sie nun von der Pokemon-Generation zur ** Seekuh-Generation **. ――Die Farbe und Form von Umiushi sind jedoch nicht so einheitlich, daher halte ich es für ein heikles Thema. Aber ich sage dir, dass es dich motiviert, etwas zu machen, das dir gefällt.
――Wir haben über 500 Bilder von Umiushi aus Pokemon-Bildern gesammelt. Die Drehung (-20 ° ~ 20 °) und die Inversion werden wahrscheinlich um das 16-fache zunehmen, sodass sich die Datenmenge um ** "500 x 16 = 8000" ** erhöht hat.
from flickrapi import FlickrAPI
from urllib.request import urlretrieve
from pprint import pprint
import os, time, sys
#AP Schlüssel I Informationen
key = "********"
secret = "********"
wait_time = 1
#Geben Sie den Speicherordner an
savedir = "./gazou"
flickr = FlickrAPI(key, secret, format="parsed-json")
result = flickr.photos.search(
per_page = 100,
tags = "seaslug",
media = "photos",
sort = "relevance",
safe_search = 1,
extras = "url_q, licence"
)
photos = result["photos"]
#Speichern Sie Informationen in einem Foto durch Schleifenverarbeitung
for i, photo in enumerate(photos['photo']):
url_q = photo["url_q"]
filepath = savedir + "/" + photo["id"] + ".jpg "
if os.path.exists(filepath): continue
urlretrieve(url_q, filepath)
time.sleep(wait_time)
Dies wird einige Daten sammeln, aber ich wollte mehr, also werde ich Bilder mit ** icrawler ** sammeln. Es ist wahnsinnig einfach zu bedienen.
$ pip install icrawler
from icrawler.builtin import GoogleImageCrawler
crawler = GoogleImageCrawler(storage={"root_dir": "gazou"})
crawler.crawl(keyword="Seekuh", max_num=100)
Dies allein speichert das Seeigelbild im angegebenen Ordner. Wie Pokemon wurde dieses Bild durch Drehen und Umdrehen aufgeblasen.
def discriminator(x, reuse=False, alpha=0.2):
with tf.variable_scope("discriminator", reuse=reuse):
x1 = tf.layers.conv2d(x, 32, 5, strides=2, padding="same")
x1 = tf.maximum(alpha * x1, x1)
x1_drop = tf.nn.dropout(x1, 0.5)
x2 = tf.layers.conv2d(x1_drop, 64, 5, strides=2, padding="same")
x2 = tf.layers.batch_normalization(x2, training=True)
x2 = tf.maximum(alpha * x2, x2)
x2_drop = tf.nn.dropout(x2, 0.5)
x3 = tf.layers.conv2d(x2_drop, 128, 5, strides=2, padding="same")
x3 = tf.layers.batch_normalization(x3, training=True)
x3 = tf.maximum(alpha * x3, x3)
x3_drop = tf.nn.dropout(x3, 0.5)
x4 = tf.layers.conv2d(x3_drop, 256, 5, strides=2, padding="same")
x4 = tf.layers.batch_normalization(x4, training=True)
x4 = tf.maximum(alpha * x4, x4)
x4_drop = tf.nn.dropout(x4, 0.5)
x5 = tf.layers.conv2d(x4_drop, 512, 5, strides=2, padding="same")
x5 = tf.layers.batch_normalization(x5, training=True)
x5 = tf.maximum(alpha * x5, x5)
x5_drop = tf.nn.dropout(x5, 0.5)
flat = tf.reshape(x5_drop, (-1, 4*4*512))
logits = tf.layers.dense(flat, 1)
logits_drop = tf.nn.dropout(logits, 0.5)
out = tf.sigmoid(logits_drop)
return out, logits
――Wenn die Lernrate hoch ist, wird das Training schnell fortgesetzt, aber es wird leicht auseinander gehen und es wird schwierig zu lernen sein. ――Wenn ich tatsächlich mit verschiedenen Werten ab 1e-2 verifiziert habe, ist 1e-4 genau richtig? Es war so. In meinem Fall wurde das Lernen bei 1e-5 zu langsam.
―― Anfangs war es ungefähr 8: 2, aber es wurde auf 6: 4 geändert. Ich konnte den Effekt nicht wirklich spüren
100epoch
200epoch
300epoch
400epoch
500epoch
»Vorerst habe ich es um die 500 Epoche gedreht. Wenn ich es aus der Ferne betrachte, habe ich das Gefühl, dass Seekühe produziert werden. ――Aber ehrlich, das Ergebnis ist subtil ... ――Mögliche Faktoren sind: „Gibt es nicht genug Epochen?“ „Enthält das Bild zu viel Extra (felsiger Hintergrund usw.)?“ „Ist die Ebene zu tief?“ „Immerhin ist das Bild etwas einfacher Verschiedene Dinge können in Betracht gezogen werden, wie "Ist es gut?" ――Ich wollte es weiter verbessern und etwas weiter drehen, aber es läuft auf ** Google Colaboratory ** und ist aufgrund der Verbindungszeit ziemlich schwierig.
Colaboratory Colaboratory ist eine Jupyter-Notebook-Umgebung, die in der von Google bereitgestellten Cloud ausgeführt wird. Sie können eine GPU von etwa 800.000 Yen verwenden. Darüber hinaus ist es nicht erforderlich, eine Umgebung zu erstellen oder Datalab zu beantragen. Weiter kostenlos. Es ist wahnsinnig praktisch, hat aber die folgenden Einschränkungen.
――Wenn Sie eine GPU-Verbindung für eine bestimmte Zeit pro Tag haben (vor kurzem ungefähr 4 Stunden [500 Epochen]), können Sie diesen Tag nicht verwenden. (Dies ist auf den Mangel an GPU-Ressourcen in Colaboratory zurückzuführen. Es gibt also keine Problemumgehung und keine andere Wahl, als zu warten. Es scheint, dass GPUs bevorzugt Benutzern zugewiesen werden, die sie nicht ständig verwenden.) --Die Laufzeit wird nach 90 Minuten bei Inaktivität bis zu 12 Stunden getrennt und die Lernergebnisse des Notebooks werden initialisiert. ―― Deshalb habe ich ** Hyperdash ** verwendet, um das 90-Minuten-Problem zu lösen. Auf diese Weise können Sie die Laufzeit für mehr als 90 Minuten verbinden.
#Starten Sie zunächst Hyperdash, eine Smartphone-App, und erstellen Sie ein Konto.
#Hyperdash-Installation
!pip install hyperdash
from hyperdash import monitor_cell
!hyperdash login --email
Sie werden nach Ihrer Hyperdash-E-Mail-Adresse und Ihrem Passwort gefragt. Geben Sie diese ein. Schreiben Sie dann den Code, der Hyperdash verwendet, und Sie können loslegen.
#Verwenden von Hyperdash
from tensorflow.keras.callbacks import Callback
from hyperdash import Experiment
class Hyperdash(Callback):
def __init__(self, entries, exp):
super(Hyperdash, self).__init__()
self.entries = entries
self.exp = exp
def on_epoch_end(self, epoch, logs=None):
for entry in self.entries:
log = logs.get(entry)
if log is not None:
self.exp.metric(entry, log)
exp = Experiment("Jeder Name")
hd_callback = Hyperdash(["val_loss", "loss", "val_accuracy", "accuracy"], exp)
~~~Ausführungscode für das Training~~~
exp.end()
Wenn Sie sich jetzt die Smartphone-App Hyperdash ansehen, sollten Sie das Lernprotokoll sehen.
Die Verwendung von Hyperdash löste das Problem für 90 Minuten, aber aus irgendeinem Grund kann die Laufzeit unterbrochen werden. Ich denke, es ist eine gute Idee, das Training in kleinere Teile aufzuteilen und sie als ".ckpt" zu speichern. Dieses .ckpt
verschwindet auch, wenn die Laufzeit getrennt wird. Speichern Sie es daher frühzeitig.
#Lernergebnisse.Speichern Sie mit ckpt
saver.save(sess, "/****1.ckpt")
# .Lesen Sie das von ckpt gespeicherte Lernergebnis und starten Sie es von dort aus neu
saver.restore(sess, "/****1.ckpt")
# .Speichern Sie ckpt im angegebenen Verzeichnis
from google.colab import files
files.download( "/****1.ckpt.data-00000-of-00001" )
--DCGAN ist schwierig, da das Modell kompliziert ist und wahrscheinlich ein Übertraining auftritt. Die erste Überlegung besteht darin, ein einfaches Modell mit einer flacheren Schicht zu erstellen. ――Es scheint, dass es nicht direkt mit Überlernen zusammenhängt, aber seien Sie vorsichtig mit der oben erwähnten "Epochennummer", "einfachem Bild" und "vereinfachen Sie das Thema". ――Ist die latente Variable auch ein ziemlich wichtiger Parameter? Ich werde mehr untersuchen. ――Es war möglicherweise ein schwieriger Artikel zu lesen, weil ich gerade aufgeschrieben habe, was ich tat. Vielen Dank für das Lesen bis zum Ende. DCGAN macht Spaß, weil die Ergebnisse als Bilder angezeigt werden. Ich werde auch versuchen, Verbesserungen und Änderungen vorzunehmen.
Recommended Posts