Ich möchte verschwommenes RNN (Chainer Meetup 01) lernen war sehr interessant, deshalb habe ich es auch mit Chainer implementiert. Außerdem habe ich eine App erstellt, mit der Sie das trainierte Modell direkt über den Browser überprüfen können.
Als erstes habe ich im Grunde das zweite Gebräu der Originalfolie gemacht, und als ich vom Unterschied sprach, habe ich versucht, die Lerndaten zu erhöhen (es wurde nicht gut gelernt) und eine Webanwendung erstellt. Das ist alles.
Die Webanwendung, die ich erstellt habe, sieht folgendermaßen aus.
Die, die ich dieses Mal gemacht habe, ist auf [GitHub] verfügbar (https://github.com/butsugiri/bokete). Die Dokumentation kann bald geschrieben werden.
Es gibt Untersuchungen, dass es möglich ist, eine Beschreibung (Beschriftung) eines Bildes zu erzeugen, indem die Merkmale des Bildes, das unter Verwendung des Convolutional Neural Network (CNN) extrahiert wurde, in das Recurrent Neural Network (RNN) eingegeben werden. Berühmte Orte sind [Karpathy + 2015] und [Vinyals + 2014]. Kann erwähnt werden.
In dieser Figur wird ein Bild eingegeben und nach dem Durchlaufen eines mehrschichtigen CNN in LSTM (eine Art von RNN) eingegeben, und eine Erklärung wird Wort für Wort erzeugt. Es ist ein einfaches Modell, aber es funktioniert bekanntermaßen überraschend gut ein Beispiel für eine aktuelle Generation finden Sie hier (dies ist Karpathy)
Übrigens, wenn ** das Eingabebild in "Beschreibung" übersetzt werden kann, kann es möglich sein, ** das Eingabebild in "Unschärfe" zu übersetzen. Mit anderen Worten, ist es möglich, ** mit einem neuronalen Netz zu "verwischen"? Basierend auf dieser Intuition haben wir durch die Implementierung dieser Modelle mit Chainer ein "vollautomatisches verwischendes neuronales Netz" erstellt.
Für 1 war es einfach, das für Caffe bereitgestellte trainierte Modell zu verwenden. Dieses Mal habe ich CaffeNet verwendet, aber ich denke, dass andere Netzwerke verwendet werden können. Da jedoch die Ausgabe der fc7-Ebene (vollständig verbundene Ebene) erforderlich ist, um die Features aus dem Bild zu extrahieren, sieht sie wie [GoogleNet] aus (https://github.com/BVLC/caffe/tree/master/models/bvlc_googlenet). Leichtere Modelle sind (wahrscheinlich) unbrauchbar.
In Bezug auf 2 gibt es einen wunderbaren Webdienst namens bokete - ein Webdienst, der ein Wort mit Bildern verwischt, also werde ich von hier aus kriechen und ihn mit Begeisterung sammeln. Wie vom früheren Folienautor erwähnt, hat jede unscharfe Seite eine einfache Struktur von "1 Bild + 1 Text", daher denke ich, dass es nicht so schwierig ist, Daten zu sammeln.
Chainer ist sehr praktisch, da er das von Caffe trainierte Modell lesen kann. Ich habe die folgende Methode in Modellklasse definiert und die Ausgabe verwendet.
Model.py
def encode_image(self, img_array):
batchsize = img_array.shape[0]
if self.config["use_caffenet"]:
img_x = chainer.Variable(img_array, volatile='on')
y = self.enc_img(
inputs={"data": img_x},
outputs={"fc7"})[0]
else:
x = self.xp.random.rand(batchsize, 4096).astype(np.float32)
y = chainer.Variable(x)
y.volatile = 'off'
return self.img2x(y)
Die durch PIL usw. vektorisierte Bilddatei wird in img_array gespeichert. Zu diesem Zweck habe ich auf Lesen eines Kaffeemodells mit Chainer und Klassifizieren von Bildern - Qiita verwiesen.
Geben Sie die Merkmale des extrahierten Bildes in LSTM ein. Dies ist auch wie in [Modellklasse] definiert (https://github.com/butsugiri/bokete/blob/master/bin/img2seq/Model.py).
Model.py
def __call__(self, x, img_vec=None):
if img_vec is not None:
h0 = self.embed_mat(x) + img_vec
else:
h0 = self.embed_mat(x)
h1 = self.dec_lstm(h0)
y = self.l1(h1)
return y
Eigentlich wollen wir das Feature nur eingeben, wenn die Zeit t = 0 ist, also Der Bildvektor wird nur angegeben, wenn im Berechnungsprozess "n = 0" ist.
Trainer.py
def _calc_loss(self, batch):
boke, img = batch
boke = self.xp.asarray(boke, dtype=np.int32)
img = self.xp.asarray(img, dtype=np.float32)
# 1.Fügen Sie das vektorisierte Bild in CNN ein und machen Sie es zu einem Merkmalsvektor
img_vec = self.model.predictor.encode_image(img)
# 2.Lerne Boke zu dekodieren
accum_loss = 0
n = 0
for curr_words, next_words in zip(boke.T, boke[:, 1:].T):
if n == 0:
accum_loss += self.model(curr_words, img_vec, next_words)
else:
accum_loss += self.model(curr_words, next_words)
n += 1
return accum_loss
Sie fragen sich vielleicht: "Warum geben Sie nicht jede Stunde die Funktionen des Bildes ein?", Aber [Karpathy + 2015]
Note that we provide the image context vector b v to the RNN only at the first iteration, which we found to work better than at each time step.
Es scheint, dass Sie nur dann eine bessere Ausgabe erhalten können, wenn "t = 0" (ich habe es nicht wirklich versucht).
Der Pionier Ich möchte das verschwommene RNN (Chainer Meetup 01) lernen lernte mit 500 Proben und dann 20.000 Proben. Es wurde geschrieben, dass ich es ausprobieren wollte, also wollte ich es auch in dieser Größenordnung machen, also habe ich versucht, mit ungefähr 30.000 Proben zu lernen. (Word Embedding, versteckte Schicht von LSTM sind beide 100 Dimensionen, Stapelgröße 16 Dropout usw.)
Der Verlust nahm jedoch nicht gut ab.
average_loss.log
"average_loss":[
10.557335326276828,
9.724091438064605,
9.051927699901125,
8.728849313754363,
8.36422316245738,
8.1049892753394,
7.999240087562069,
7.78314874008182,
7.821357278519156,
7.629313596859783
]
(Übrigens ist es der Verlust von Trainingsdaten)
Im Stadium der Wende von etwa 30 Epochen nahm der Verlust nicht ab. Übrigens habe ich versucht, das Bild zu verwischen, aber ich konnte keine anständige Ausgabe erzielen ...
Dies liegt wahrscheinlich daran, dass es nur etwa 2000 Bilder der ursprünglichen Unschärfe für 30.000 Unschärfen gab. (Zu einem Bild werden mehrere Unschärfen hinzugefügt, um Daten von "unscharf" zu erfassen.) Da es wahrscheinlich mehr als 10 richtige Antworten (Übersetzungsziele) für ein Bild gibt, können die Parameter des Modells möglicherweise nicht in eine eindeutige Richtung angepasst werden. Ich denke.
Da "Ich möchte nur durch Reduzierung des Verlusts überprüfen", habe ich darauf geachtet, dass eine Unschärfe einem Bild entspricht, und ein Experiment mit kleinen Daten (ca. 300 Unschärfe) durchgeführt:
average_loss.log
"average_loss": [
6.765932078588577,
1.7259380289486477,
0.7160143222127642,
0.3597904167004994,
0.1992428061507997
]
Sicher ist der Verlust gesunken. (Auf insgesamt 100 Epochen gedreht)
Daraus ist auch bei großen Datenmengen zu erwarten, dass "der Verlust abnimmt (= gelernt werden kann), wenn eine Eins-zu-Eins-Entsprechung zwischen Bild und Unschärfe besteht".
Als ich es mit dem vorliegenden Bild versuchte, erhielt ich die folgende Ausgabe.
** (Ist das unscharf ...?) **
Ich habe viel gelernt und es ist langweilig, wenn ich es nicht über den Browser überprüfen kann. Deshalb habe ich eine Webanwendung erstellt. (Der Code ist öffentlich zugänglich)
Das trainierte Modell von Chainer wird hinter die Web-App geladen, und die Methode zur Erzeugung von Unschärfe wird ausgelöst, wenn eine Schaltfläche auf der Browserseite gedrückt wird.
Dieses Mal habe ich das Erklärungsgenerierungsmodell von Bildern wie [Karpathy + 2015] und [Vinyals + 2014] verwendet, um Unschärfe zu lernen und zu erzeugen, aber ich denke nicht, dass dieses Modell das beste ist, um mit Unschärfe umzugehen. Da dieses Modell unter der Annahme entworfen und bewertet wird, dass die Beschreibung des Bildes ** nur eine richtige Antwort enthält **, handelt es sich um eine "willkürlich richtige Antwort (= interessant)", wie z. B. "Verwischen des Bildes". Ich denke nicht, dass es für "unscharfe" Daten geeignet ist. Als Ergebnis des Versuchs zu lernen, indem einem Bild mehrere korrekte Antwortdaten (Unschärfe) gegeben wurden, litt ich unter dem Phänomen, dass der Verlust nicht abnimmt.
Auch wenn der Verlust an Trainingsdaten reduziert wird, wird der Verlust an Entwicklungsdaten wahrscheinlich nicht reduziert. (Es sollte auf jeden Fall notwendig sein, die Eingabe- / Ausgabedomäne stärker zu reduzieren, z. B. das Eingabebild auf den Ossan einzugrenzen, die Lücken nicht auszufüllen usw.)
Ist der Ansatz, "Unschärfe auf dem Eingabebild zu erzeugen", angemessen? Gibt es einen einfacheren Ansatz? Wenn Sie beispielsweise absichtlich eine Beschreibung eines völlig anderen Bildes zum Eingabebild ** hinzufügen, ist dies eine interessante Unschärfe.
Zum Beispiel so
(Es ist ein Bild)
Ist ein neuronales Netz wirklich notwendig für interessante Unschärfen ... Es ist ein sehr nerviger Ort.
Recommended Posts