[PYTHON] 4. Entourez les paramètres avec un réseau neuronal!

introduction

C'est le 4e de la série.

Jusqu'à présent, NN (partie 2) qui produit la valeur moyenne et l'écart type des données numériques aléatoires données, et produit les trois paramètres utilisés pour créer les données de forme d'onde de distribution normale à partir des données de forme d'onde de distribution normale données. J'ai créé NN (3e).

Cette fois, à partir des données d'image bidimensionnelles du dessin d'un cercle, la convolution NN (convolution NN (coordonnée x du centre du cercle, coordonnée y, rayon, épaisseur de la ligne de crayon) qui est utilisée pour dessiner le cercle est sortie. Créer CNN).

Les données d'image ont été créées avec Objective-C.

Création de données d'image

Le premier est la création de données d'image. Créez une image d'un cercle de 50 pixels x 50 pixels, récupérez-y les données de pixels et exportez-la dans un fichier avec les quatre paramètres utilisés pour dessiner le cercle. Un élément de données se compose de 2504 éléments de données séparés par des virgules. Les 2500 premiers sont des nombres de 0 à 1, et les 4 restants sont les x, y, le rayon et l'épaisseur de ligne du centre du cercle. Séparez les données par un saut de ligne (\ n).

J'ai utilisé la classe NSImage en Objective-C pour créer les données.

4-001.c


//La taille de l'image est de 50 pixels x 50 pixels
//Déterminez les coordonnées du centre, le rayon et l'épaisseur de ligne avec des nombres aléatoires.
//Le rayon est de 5 à 25
//Les coordonnées du centre garantissent que le cercle est inclus dans l'image.
//L'épaisseur de la ligne est de 0.2 à 5
#import <Cocoa/Cocoa.h>
-(uint8_t *)pixelDataFromImage(NSImage *image);//main()Déclaration prototype de la fonction utilisée dans

int main(int argc, const char * argv[]) {
    srand((unsigned int)time(NULL));//Initialisation aléatoire
    //Ouvrez le fichier de destination
    char *fileName = "~/imageLearningData.txt";
    FILE *fp = fopen(fileName, "w");

    //Créer 50 000 feuilles
    for(int mmm = 0; mmm < 50000;mmm++){
        double radius = (double)rand()/RAND_MAX*20 + 5;
        double x = (double)rand()/RAND_MAX*(50 - radius * 2) + radius;
        double y = (double)rand()/RAND_MAX*(50 - radius * 2) + radius;
        double lineWidth = (double)rand()/RAND_MAX*4.8 + 0.2;
        [NSBezierPath setDefaultLineWidth:lineWidth];
    
        NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(50, 50)];    
        NSBezierPath *bezierPath = [NSBezierPath bezierPath];
        //Dessiner une image
        [image lockFocus];
        [bezierPath appendBezierPathWithOvalInRect:NSMakeRect(x - radius, y - radius, radius * 2, radius * 2)];
        [bezierPath stroke];
        [image unlockFocus];
    
        uint8_t *pixels = pixelDataFromImage(image);
    
        //Données de pixel de sortie
        NSSize size = [image size];
        uint32_t width = (uint32_t) size.width;
        uint32_t height = (uint32_t) size.height;
        int components = 4;
        for(int iii = 0; iii < height ;iii ++){
            for(int kkk = 0; kkk < width ; kkk++){
                double value = 0;
                value += pixels[( width * iii + kkk )*4     ]/255.0;
                value += pixels[( width * iii + kkk )*4 + 1 ]/255.0;
                value += pixels[( width * iii + kkk )*4 + 2 ]/255.0;
                //Ce qui suit est un périphérique pour réduire la taille du fichier de sortie. "1.Sortie "1" au lieu de "0000000".
                value /= 3;
                if(value == 1){
                    fprintf(fp,"%d,",1);
                }else{
                    fprintf(fp,"%f,",value);
                }
            }
        }
    
        fprintf(fp,"%f,%f,%f,%f\n",x,y,radius,lineWidth);
        free(pixels);
    }
    fclose(fp);
}

Concernant la méthode pixelDataFromImage dans le code ci-dessus, j'ai fait ce qui suit en modifiant légèrement Code de M. Shimapyon @ shimacpyon. Merci, monsieur Shimapyon.

4-002.c


-(uint8_t *)pixelDataFromImage(NSImage *image){
    /*Créer une instance de NSBitmapImageRep*/
    NSBitmapImageRep*bitmapRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
    /*Si vous enregistrez au format JPEG, supprimez le canal alpha*/
    [bitmapRep setAlpha:NO];
    /*Obtenez de la qualité pour le stockage*/
    float quality = 1.0;
    /*Créer une propriété*/
    NSDictionary* properties = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:quality] forKey:NSImageCompressionFactor];
    /*Créer des données JPEG*/
    NSData *data = [bitmapRep representationUsingType:NSJPEGFileType properties:properties];

    //Créer à nouveau NSImage à partir de NSData
    NSImage *newImage = [[NSImage alloc] initWithData:data];

    if (newImage != nil) {
        NSSize size = [newImage size];
        uint32_t width = (uint32_t) size.width, height = (uint32_t) size.height, components = 4;
        uint8_t *pixels = (uint8_t *) malloc(size.width * size.height * components);//0 à 255
        if (pixels) {
            CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
            CGContextRef bitmapContext = CGBitmapContextCreate(pixels, width, height, 8, components * width, colorSpace, kCGImageAlphaPremultipliedLast);
            NSRect rect = NSMakeRect(0, 0, width, height);
            NSGraphicsContext *graphicsContext = (NSGraphicsContext *) [[NSGraphicsContext currentContext] graphicsPort];
            CGImageRef cgImage = [newImage CGImageForProposedRect:&rect context:graphicsContext hints:nil];
            CGContextDrawImage(bitmapContext, NSRectToCGRect(rect), cgImage);
            CGContextRelease(bitmapContext);
            CGColorSpaceRelease(colorSpace);
            return pixels;
        }
    }
    return nil;
}

Il n'était pas possible d'extraire les données de pixels directement de NSImage, j'ai donc obtenu des données au format JPEG (NSData) de NSImage, créé à nouveau NSImage sur cette base et en ai extrait les données de pixels. Il existe peut-être un moyen plus intelligent, mais j'aimerais passer à autre chose.

Division des données d'entraînement

Quatre données d'entraînement créées (2504 données x 50000 lignes), c'est-à-dire

  1. Données d'entrée pour la formation (2500 données x 40000 lignes),
  2. Corriger les données de réponse pour la formation (4 données x 40000 lignes),
  3. Données d'entrée pour l'évaluation (2500 données x 10000 lignes),
  4. Corrigez les données de réponse pour l'évaluation (4 données x 10 000 lignes),

Diviser en.

4-003.py


import numpy as np
d = np.loadtxt('./imageLearningData.txt', delimiter=',')
#-4:Est du 4e à la fin de l'arrière.
d_training_x = d[:40000,:-4]
d_training_y = d[:40000,-4:]
d_test_x = d[40000:,:-4]
d_test_y = d[40000:,-4:]

#Changer la forme des données
d_training_x = d_training_x.reshape(40000,50,50,1)
d_test_x = d_test_x.reshape(10000,50,50,1)

Conception CNN

Concevez le CNN. Nous utilisons un réseau de neurones convolutifs pour former une image bidimensionnelle. La conception de CNN a été conçue de manière appropriée en fonction de mon intuition. Les points suivants ont été pris en considération.

  1. Placez quelques couches de pliage.
  2. Réduisez le nombre de données dans la couche de pooling Max.
  3. Combinez plusieurs couches entièrement connectées et réduisez progressivement le nombre de données à 4.
  4. La fonction de perte utilise la somme des carrés d'erreur.
  5. La forme d'entrée de la première couche est (50,50,1).
  6. Le nombre de sorties dans la dernière couche est de 4.

4-004.py


import keras
from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPool2D
from keras.optimizers import Adam
from keras.layers.core import Dense, Activation, Dropout, Flatten

#Définition du modèle
model = Sequential()
model.add(Conv2D(32,5,input_shape=(50,50,1)))
model.add(Activation('tanh'))
model.add(Conv2D(32,3))
model.add(Activation('relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Conv2D(64,3))
model.add(Activation('relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(1024))
model.add(Activation('relu'))
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dense(4, activation='linear'))

adam = Adam(lr=1e-4)

model.compile(optimizer=adam, loss='mean_squared_error', metrics=["accuracy"])
model.summary()

Commencer à apprendre

Le nombre de paramètres est de 6 722 916. Il semble que cela prendra du temps ..... Commencer à apprendre.

4-005.py


batch_size = 128  #128 données sont réunies
epochs = 20

history = model.fit(d_training_x, d_training_y,
batch_size=batch_size,
epochs=20,
verbose=1,
validation_data=(d_test_x, d_test_y))

Cela prenait 107 secondes par époque. Faites un graphique de la progression de l'apprentissage. loss est la valeur de perte calculée à partir des données d'apprentissage et val_loss est la valeur de perte calculée à partir des données d'évaluation.

4-006.py


#Dessiner un graphique
import matplotlib.pyplot as plt
plt.plot(history.history['loss'],label="loss")
plt.plot(history.history['val_loss'],label="val_loss")
plt.legend() #Afficher la légende
plt.title("Can CNN learn to predict 4 parameters used to draw a circle?")
plt.xlabel("epoch")
plt.ylabel("Loss")
plt.show()

Figure_4-1.png On dirait que vous avez bien appris.

Évaluation de CNN

À quel point pouvez-vous prédire avec précision? Jetons les 200 premières données des données d'évaluation dans le CNN après l'entraînement.

4-007.py


inp = d_test_x[:200,:]
out = d_test_y[:200,:]
pred = model.predict(inp, batch_size=1)

#Faites un graphique.
plt.title("Can NN deduce circle parameters?")

plt.scatter(out[:,0], pred[:,0],label = "x",marker='.', s=20,alpha=0.7)
plt.scatter(out[:,1], pred[:,1],label = "y",marker='.', s=20,color="green",alpha=0.7)
plt.scatter(out[:,2], pred[:,2],label = "r",marker='.', s=20,color="red",alpha=0.7)
plt.scatter(out[:,3], pred[:,3],label = "line width",marker='.', s=20,color="black",alpha=0.7)

plt.legend(fontsize=14) #Afficher la légende
plt.xlabel("expected value")
plt.ylabel("prediction")
#C'est difficile à voir, donc x=La ligne y est omise
#x = np.arange(-1, 41, 0.01)  
#y = x
#plt.plot(x, y,color="black")
plt.show()

Figure_4-3.png

L'axe horizontal est la valeur du paramètre utilisé lors de la création des données du cercle et l'axe vertical est la valeur sortie par CNN en fonction des données d'image.

Si vous prenez la ligne $ x = y $ tirée du coin inférieur gauche vers le coin supérieur droit, vous avez réussi la sortie.

Ce n'est pas parfait, mais il semble que j'ai beaucoup appris. Est-ce que ce sera un peu mieux si je change la configuration du réseau, etc.?

Résumé

Il est maintenant possible d'afficher l'emplacement et la taille d'un cercle dans une image en tant que paramètre pour dessiner un cercle.

C'est la fin de la 4ème série!

Série 1ère préparation Moyenne et écart type de la deuxième série Série 3e distribution normale Série 4e yen

Recommended Posts

4. Entourez les paramètres avec un réseau neuronal!
3. Distribution normale avec un réseau neuronal!
Réseau de neurones commençant par Chainer
Réseau neuronal avec OpenCV 3 et Python 3
Modèle de classification simple avec réseau neuronal
[TensorFlow] [Keras] Construction d'un réseau neuronal avec Keras
Composez avec un réseau neuronal! Run Magenta
Prédire les données de séries chronologiques avec un réseau neuronal
Persister le réseau de neurones construit avec PyBrain
2. Écart moyen et standard avec le réseau neuronal!
Réseau neuronal paramétrique
Expérimentez avec divers algorithmes d'optimisation sur le réseau neuronal
Implémenter le réseau neuronal à partir de zéro
Expérience de réseau de neurones pliable
Entraînez les données MNIST avec PyTorch en utilisant un réseau neuronal
Chainer Tech Circle ML # 8 avec modèle récurrent de langage neuronal
Implémenter un réseau neuronal à 3 couches
Simuler l'activité neurale avec Brian2
Essayez de créer un réseau de neurones / d'apprentissage en profondeur avec scratch
Un exemple de python pour apprendre XOR avec un algorithme génétique sur un réseau neuronal
Classification d'images avec un réseau de neurones auto-fabriqué par Keras et PyTorch
Réglage des paramètres Keras avec Keras Tuner
Ajustement des paramètres LightGBM avec Optuna
[Apprentissage en profondeur] Classification d'images avec un réseau neuronal convolutif [DW jour 4]
Tutoriel sur le réseau neuronal (CNN) de Pytorch 1.3.1.
Implémentation de réseau neuronal (NumPy uniquement)
Tutoriel TensorFlow - Réseau neuronal à convolution (traduction)
Programmation réseau avec Python Scapy
Mesure de la performance du réseau avec iperf
Comprendre le nombre de paramètres d'entrée / sortie du réseau neuronal convolutif
Implémentation simple d'un réseau neuronal à l'aide de Chainer
Paramètre de fonction uniquement pour l'astérisque '*'
Implémentation d'un réseau de neurones à deux couches 2
PRML Chapitre 5 Implémentation Python du réseau neuronal
Qu'est-ce que le réseau neuronal convolutif?
Dessinez un beau cercle avec numpy
Ecrire un réseau résiduel avec TFLearn
J'ai essayé de mettre en œuvre un réseau de neurones à deux couches
Théorie et implémentation simples des réseaux neuronaux
Touchez l'objet du réseau neuronal
[Traitement du langage 100 coups 2020] Chapitre 8: Réseau neuronal
Exploitez l'espace de noms réseau Linux avec Go
Créez un classificateur avec un taux de reconnaissance de l'écriture manuscrite de 99,2% à l'aide du réseau neuronal convolutif TensorFlow