[PYTHON] Implémentation de réseaux neuronaux "flous" avec Chainer

introduction

Dec-01-2016 13-02-04.gif

Je veux apprendre RNN flou (Chainer meetup 01) était très intéressant, je l'ai donc implémenté avec Chainer également. De plus, j'ai créé une application qui vous permet de vérifier le modèle entraîné directement depuis le navigateur.

Tout d'abord, ce que j'ai fait était essentiellement le deuxième breuvage de la diapositive originale, et en parlant de la différence, j'ai essayé d'augmenter les données d'apprentissage (ce n'était pas bien appris) et j'ai créé une application Web. C'est à peu près ça.

L'application Web que j'ai créée ressemble à ceci. Nov-30-2016 21-21-21.gif

Celui que j'ai créé cette fois-ci est disponible sur GitHub. La documentation pourrait être rédigée prochainement.

Modèle de "flou"

Il y a des recherches qu'il est possible de générer une description (légende) d'une image en entrant les caractéristiques de l'image extraite à l'aide du réseau neuronal convolutif (CNN) au réseau neuronal récurrent (RNN). Les lieux célèbres incluent [Karpathy + 2015] et [Vinyals + 2014]. Peut être mentionné.

Screenshot 2016-11-30 21.44.43.png (À partir de [Vinyals + 2014])

Sur cette figure, une image est entrée, et après avoir traversé un CNN multicouche, elle est entrée dans LSTM (un type de RNN), et une explication est générée mot par mot. C'est un modèle simple, mais il est connu pour fonctionner étonnamment bien, vous pouvez voir un exemple de génération réel ici (c'est Karpathy)

En passant, si ** l'image d'entrée peut être traduite en "description", il peut être possible de ** traduire l'image d'entrée en "floue". En d'autres termes, est-il possible de «brouiller» ** avec un réseau neuronal? Sur la base de cette intuition, en implémentant ces modèles avec Chainer, nous avons créé un "réseau neuronal flou entièrement automatique".

Ressources de données utilisées

  1. Modèle formé par CNN
  2. Données floues pour l'image

Pour 1, il était facile d'utiliser le modèle entraîné fourni pour Caffe. Cette fois, j'ai utilisé CaffeNet, mais je pense que d'autres réseaux peuvent être utilisés. Cependant, comme la sortie de la couche fc7 (couche entièrement connectée) est nécessaire pour extraire les caractéristiques de l'image, cela ressemble à GoogleNet. Les modèles plus légers sont (probablement) inutilisables.

En ce qui concerne 2, il existe un merveilleux service Web appelé bokete-un service Web qui brouille un mot avec des images, donc je vais ramper à partir d'ici et le collecter avec enthousiasme. Comme mentionné par l'ancien auteur de diapositives, il n'est pas si difficile de collecter des données car chaque page floue a une structure simple de "1 image + 1 texte".

environnement

Extraction de caractéristiques à partir de l'image d'origine

Chainer est très pratique car il peut lire le modèle entraîné de Caffe. J'ai défini la méthode suivante dans Model Class et utilisé la sortie.

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)

Le fichier image vectorisé par PIL etc. est stocké dans img_array. Pour cela, je me suis référé à Reading caffemodel with Chainer and classifying images --Qiita.

Entrez l'image d'origine dans LSTM

Entrez les caractéristiques de l'image extraite dans LSTM. Ceci est également défini dans Model Class.

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

En fait, nous voulons entrer la fonction uniquement lorsque le temps t = 0, donc Le vecteur d'image n'est donné que lorsque n = 0 dans le processus de calcul.

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.Mettez l'image vectorisée dans CNN et faites-en un vecteur de caractéristiques
    img_vec = self.model.predictor.encode_image(img)

    # 2.Apprenez à décoder la boke
    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

Vous vous demandez peut-être: "N'entrez-vous pas les caractéristiques de l'image toutes les heures?", Mais [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.

Il semble que vous ne pouvez obtenir une meilleure sortie que lorsque t = 0 (je ne l'ai pas vraiment essayé).

Train bokeh: données volumineuses

Le pionnier je veux apprendre le RNN flou (Chainer meetup 01) a appris avec 500 échantillons, puis 20 000 échantillons. Il était écrit que je voulais l'essayer, donc je voulais aussi le faire à cette échelle, alors j'ai essayé d'apprendre avec environ 30 000 échantillons. (Word Embedding, la couche cachée de LSTM est de 100 dimensions, la taille du lot 16 Dropout, etc.)

Cependant, la perte n'a pas bien diminué.

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
]

(Au fait, c'est la perte de données d'entraînement)

Au stade de tourner environ 30 époques, la perte n'a pas diminué. Au fait, j'ai essayé de brouiller l'image à portée de main, mais je ne pouvais pas obtenir une sortie décente ...

C'est probablement parce qu'il n'y avait qu'environ 2000 images du flou d'origine pour 30 000 flous. (Plusieurs flous sont ajoutés à une image pour faciliter l'acquisition de données à partir de "flou") Puisqu'il y a probablement plus de 10 réponses correctes (destinations de traduction) pour une image, les paramètres du modèle peuvent ne pas être ajustés dans une direction unique. Je pense.

Apprendre le bokeh: petites données

Puisque "je veux vérifier simplement en réduisant la perte", j'ai veillé à ce qu'un flou corresponde à une image, et ai mené une expérience avec des données à petite échelle (environ 300 flous):

average_loss.log


"average_loss": [
    6.765932078588577,
    1.7259380289486477,
    0.7160143222127642,
    0.3597904167004994,
    0.1992428061507997
]

Certes, la perte a diminué. (Tourné jusqu'à un total de 100 époques)

À partir de là, même dans le cas de données à grande échelle, on peut s'attendre à ce que "la perte diminuera (= peut être apprise) s'il y a une correspondance biunivoque entre l'image et le flou".

Résultat d'apprentissage

Lorsque je l'ai essayé avec l'image à portée de main, j'ai obtenu la sortie suivante. ____________________________2016-10-31_13.11.20.png ** (Est-ce flou ...?) **

Créer une application Web

J'ai beaucoup appris, et c'est ennuyeux si je ne peux pas le vérifier depuis le navigateur, j'ai donc créé une application Web. (Le code est ouvert au public)

Backend_API.png C'est un état. Backend_API.png Vous pouvez voir les statistiques des données utilisées pour la formation. Backend_API 2.png En appuyant sur le bouton Générer, vous pouvez voir le flou des données de formation / développement.

Le modèle entraîné de Chainer est chargé derrière l'application Web et la méthode de génération de flou se déclenche lorsqu'un bouton est enfoncé du côté du navigateur.

en conclusion

Cette fois, j'ai utilisé le modèle de génération d'explications d'images comme [Karpathy + 2015] et [Vinyals + 2014] pour apprendre et générer du flou, mais je ne pense pas que ce modèle soit le meilleur pour gérer le flou. Puisque ce modèle est conçu et évalué sur l'hypothèse qu'il n'y a qu'une seule réponse correcte dans la description de l'image **, il s'agit d'une "réponse correcte arbitraire (= intéressante)" telle que "flou sur l'image". C'est parce que je ne pense pas qu'il convient aux données «floues». En fait, après avoir essayé d'apprendre en donnant plusieurs données de réponse correcte (flou) à une image, j'ai souffert du phénomène selon lequel la perte ne diminue pas.

De plus, même si la perte sur les données d'apprentissage est réduite, la perte sur les données de développement ne sera probablement pas réduite. (Il devrait certainement être nécessaire de réduire davantage le domaine d'entrée / sortie, par exemple, réduire l'image d'entrée à l'ossan, ne pas remplir les espaces, etc.)

En premier lieu, est-ce que l'approche consistant à «générer du flou sur l'image d'entrée» est appropriée? Existe-t-il une approche plus simple? Par exemple, si vous ajoutez intentionnellement une description d'image complètement différente à l'image d'entrée **, ce serait un flou intéressant.

Par exemple comme ça mig.jpg Screenshot 2016-12-01 18.05.56.png (C'est une image)

Un réseau neuronal est-il vraiment nécessaire pour un flou intéressant ... C'est un endroit très ennuyeux.

Recommended Posts

Implémentation de réseaux neuronaux "flous" avec Chainer
Implémentation simple d'un réseau neuronal à l'aide de Chainer
Apprentissage des classements à l'aide d'un réseau neuronal (implémentation RankNet par Chainer)
Mise en œuvre de l'optimisation bayésienne des hyper paramètres du réseau de neurones (Chainer + GPyOpt)
Implémentation d'un réseau de neurones convolutifs utilisant uniquement Numpy
Implémentation d'un réseau de neurones à deux couches 2
Implémentation d'un réseau neuronal à 3 couches (pas d'apprentissage)
Implémentation de réseau neuronal simple à l'aide de la préparation Chainer-Data-
Implémentation de réseau neuronal simple à l'aide de la description du modèle Chainer-
Implémentation simple d'un réseau de neurones à l'aide de Chainer ~ Définition d'un algorithme d'optimisation ~
Implémentation de TF-IDF à l'aide de gensim
Présentation de DNC (Differentiable Neural Computers) + Implémentation par Chainer
Réseau de neurones commençant par Chainer
Implémentation de réseau neuronal en python
Mise en œuvre de l'apprentissage en série de Chainer à l'aide de mini-lots de longueur variable
Implémentation de réseau neuronal (NumPy uniquement)
PRML Chapitre 5 Implémentation Python du réseau neuronal
Théorie et implémentation simples des réseaux neuronaux
Implémentation des notifications de bureau à l'aide de Python
Touchez l'objet du réseau neuronal
Prédiction des survivants à l'aide du réseau neuronal titanesque de Kaggle [80,8%]
Essayez d'utiliser TensorFlow-Part 2-Convolution Neural Network (MNIST)
[Chainer] Classification des documents par réseau de neurones convolutifs
Python vs Ruby "Deep Learning from scratch" Chapitre 3 Implémentation d'un réseau neuronal à 3 couches
Apprentissage par renforcement 10 Essayez d'utiliser un réseau neuronal formé.
Une autre méthode de conversion de style utilisant le réseau neuronal convolutif
Vérification de la normalisation des lots avec un réseau neuronal multicouche
Reconnaissance des nombres manuscrits par un réseau neuronal multicouche
[Deep Learning from scratch] Valeur initiale du poids du réseau neuronal utilisant la fonction sigmoïde
Réseau neuronal paramétrique
[Deep Learning from scratch] Poids initial du réseau neuronal lors de l'utilisation de la fonction Relu
[Python] Implémentation du clustering à l'aide d'un modèle gaussien mixte
Estimation de l'auteur à l'aide du réseau neuronal et de Doc2Vec (Aozora Bunko)
Implémentation de la condition de jugement d'authenticité d'objet à l'aide de la méthode __bool__
Modèle utilisant un réseau neuronal convolutif dans le traitement du langage naturel
L'histoire de la création d'un réseau neuronal de génération musicale
Implémentez un réseau de neurones feedforward dans Chainer pour classer les documents
Analysons les émotions de Tweet en utilisant Chainer (2ème)
Bases de PyTorch (2) -Comment créer un réseau de neurones-
Analysons les émotions de Tweet en utilisant Chainer (1er)
Implémenter un réseau neuronal convolutif
Implémentation de la séquence de Fibonacci
Implémenter le réseau neuronal à partir de zéro
Expérience de réseau de neurones pliable
Bases des programmes réseau?
À propos de la variable du chainer
Exemple d'utilisation de lambda
Comment dessiner facilement la structure d'un réseau de neurones sur Google Colaboratory à l'aide de "convnet-tiroir"
Précautions lors de l'utilisation de Chainer
Implémentation de VGG16 à l'aide de Keras créé sans utiliser de modèle entraîné
Essayez de créer un réseau de neurones en Python sans utiliser de bibliothèque
Vérification et mise en œuvre de la méthode de reconstruction vidéo en utilisant GRU et Autoencoder
Construction d'un réseau neuronal qui reproduit XOR par Z3
Série d'accélération CNN ~ FCNN: Introduction du réseau neuronal convolutif de Fourier ~
Etude du réseau neuronal récurrent (RNN) par Chainer ~ Vérification de l'exactitude des nombres aléatoires dans Excel et R ~