[PYTHON] _ 3ème jour jusqu'à ce qu'une bonne précision soit obtenue par classification des feuilles

Je vais enfin le mettre en œuvre. Cette fois, il est implémenté dans Chainer. ** chainer utilisé 2.0.0 **. La version de chainer est

import chainer
chainer.__version__

Vous pouvez vérifier en faisant.

Construire

Examen du prétraitement

Tout d'abord, je vais l'examiner brièvement. Pour les données d'image, etc., j'ai téléchargé la classification des feuilles de Kaggle telle quelle et j'ai renommé le dossier appelé images en images2.

redimensionner

Dans le prétraitement du code ci-dessous, 1584 données d'image dans le dossier appelé images2 sont modifiées à la taille d'image de 32x32, puis enregistrées dans le dossier appelé images.


images=[]
for i in range(1, 1585):
    image = cv2.imread("images2/%d.jpg "%i) #Extrait d'images2
    grayed = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    images.append(grayed) #Stocker en images

def resize_image(img):
    end_size = 32
    max_ = np.maximum(img.shape[0], img.shape[1])
    scale = end_size / max_
    height, width = img.shape
    size = (int(width*scale), int(height*scale))

    rescale_image = cv2.resize(img, size, interpolation=cv2.INTER_CUBIC)

    height, width = rescale_image.shape

    if width > height:
        z_pad = np.zeros([int((width-height)/2), width], dtype=np.uint8)
        end_image = np.vstack((z_pad, rescale_image, z_pad))
    else:
        z_pad = np.zeros([height, int((height - width)/2)], dtype=np.uint8)
        end_image = np.hstack((z_pad, rescale_image, z_pad))

    end_image = cv2.resize(end_image, (end_size, end_size))
    
    return end_image

for i,img in enumerate(images):
    cv2.imwrite("images/%d.jpg "%(i+1), resize_image(img)) #Stocker des images dans un dossier appelé images

Créer un jeu de données

Créons maintenant un ensemble de données pouvant être utilisé pour l'entraînement à partir des données d'entraînement.

dataset.py


import numpy as np
import pandas as pd
import cv2

#Train à Kaggle.Téléchargez csv et chargez-le
#(train.csv n'a qu'une étiquette)
train = pd.read_csv("train.csv")
labels=train["species"].values

#Les étiquettes contiennent maintenant une chaîne, alors scikit-la-Utilisez la fonction d'apprentissage pour convertir en une étiquette numérique
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(labels)
labels = le.transform(labels)
labels = labels.astype(np.int32)

#Depuis le dossier images, formez.Apportez l'image redimensionnée de la colonne id de csv.
resized_images = []
for i in train.id:
    image = cv2.imread("images/%d.jpg "%i)
    grayed = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    resized_images.append(grayed)

#Convertissez en un type qui peut être lu par le chaîneur.
resized_images = np.array([resized_images])
resized_images = resized_images.reshape(-1, 1024).astype(np.float32)
resized_images /=255 #0~255 données 0~Changer à 1 données

#train_test_split est scikit-Si la version d'apprentissage est nouvelle, croisez_modèle au lieu de validation_C'est dans la sélection.
#Créez un ensemble de données d'entraînement à partir des données de matrice d'image et des données d'étiquette.
from sklearn.cross_validation import train_test_split 
X_train, X_test, y_train, y_test = train_test_split(resized_images, labels, test_size=0.2, random_state=0)

#Spécifiez le numéro à utiliser ultérieurement.
N_train = y_train.size
N_test = y_test.size

En faisant cela, j'ai pu créer un ensemble de données.

Classer par NN

Tout d'abord, faisons-le à partir de NN au lieu de CNN.

NN_class.py


class MLP(chainer.Chain):
    
    def __init__(self):
        super().__init__(
            l1 = L.Linear(1024, 1000),
            l2 = L.Linear(1000, 900),
            l3 = L.Linear(900, 500),
            l4 = L.Linear(500, 99),
        )
        
    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        h3 = F.relu(self.l3(h2))
        return self.l4(h3)

ici,

__call__

Une description de la pièce peut être trouvée dans Comment utiliser la méthode call dans les classes Python.

Pour le moment, l'entrée est de 1024 (32x32), la sortie est de 99 (classification de 99 classes) Donc, cela ressemble à connecter NN (réseau neuronal) et à utiliser la fonction relu comme fonction d'activation.

Construire un modèle

model.py


model = L.Classifier(MLP())

from chainer import optimizers
optimizer = optimizers.Adam()
optimizer.setup(model)

Vous venez de créer un modèle. Sur mon PC **, j'ai eu une erreur lorsque j'ai défini optimizer = chainer.optimizers.Adam () ** pour une raison quelconque, donc dans ce cas, je pense que c'est correct d'écrire comme ça.

Courir

NN_Courir.py



batchsize = 99 #Taille de lot unique
n_epoch = 8 #Nombre de répétitions d'apprentissage

train_loss = []
train_accuracy = []
test_loss = []
test_accuracy = []

for epoch in range(n_epoch):
    print("epoch", epoch+1)
    
    perm = np.random.permutation(N_train)
    
    sum_accuracy, sum_loss = 0,0
    
    for i in range(0, N_train, batchsize):
        X_batch = X_train[perm[i:i+batchsize]]
        y_batch = y_train[perm[i:i+batchsize]]
        
        
        optimizer.update(model, X_batch, y_batch)
        
        sum_loss += float(model.loss.data)
        sum_accuracy += float(model.accuracy.data)
        
        
    mean_loss = sum_loss/(N_train/batchsize)
    mean_accuracy = sum_accuracy/(N_train/batchsize)
    print("train_mean_loss={:.3f}, train_mean_accuracy={:.3f}".format(mean_loss, mean_accuracy))
    
    train_loss.append(model.loss.data)
    train_accuracy.append(model.accuracy.data)
    
    #Il y en a peu, alors testons tout
    sum_loss, sum_accuracy= 0,0
    
    for i in range(0, N_test, batchsize):
        X_batch = X_test[i:i+batchsize]
        y_batch = y_test[i:i+batchsize]
        
        loss = model(X_batch, y_batch)
        
        sum_loss += float(model.loss.data)
        sum_accuracy += float(model.accuracy.data)
        
    mean_loss = sum_loss/(N_test/batchsize)
    mean_accuracy = sum_accuracy/(N_test/batchsize)
    print("test_mean_loss={:.3f}, test_mean_accuracy={:.3f}".format(mean_loss, mean_accuracy))
    
    test_loss.append(model.loss.data)
    test_accuracy.append(model.accuracy.data)

L'explication détaillée de la partie code ici est expliquée de manière très facile à comprendre par le site référencé, je vais donc l'omettre.

La partie réécrite était N_train.size = 792, donc j'ai mis batchsize = 99 et n_epoch = 8.

Donc, le résultat de l'exécution est comme ça.

スクリーンショット 2017-07-19 1.59.28.png

Eh bien, j'aimerais comprendre qu'il était impossible de faire ** 99 classification avec des données pour chaque 10 chacun. ** ** Je vais essayer de l'implémenter avec CNN pour le moment.

CNN

Construire un modèle

model_CNN.py



class CNN(chainer.Chain):
    
    def __init__(self):
        super(CNN, self).__init__(
            conv1 = L.Convolution2D(1, 32, 5),
            conv2 = L.Convolution2D(32, 64, 5),
            conv3 = L.Convolution2D(64, 64, 5),
            l1 = L.Linear(None, 500),
            l2 = L.Linear(500, 99)
        )
        
    def __call__(self, x):
        x = x.reshape((len(x.data), 1, 32, 32))
        
        h = F.relu(self.conv1(x))
        h = F.max_pooling_2d(h, 2)
        h = F.relu(self.conv2(h))
        h = F.max_pooling_2d(h, 2)
        h = F.relu(self.conv3(h))
        h = F.max_pooling_2d(h, 2)
        h = F.dropout(F.relu(self.l1(h)))
        y = self.l2(h)
        return y

model = L.Classifier(CNN())

from chainer import optimizers
optimizer = optimizers.Adam()
optimizer.setup(model)

Ceci est également plus facile à comprendre si vous regardez le site auquel vous avez fait référence, je vais donc omettre l'explication. Et ** le code d'exécution est exactement le même que NN **, donc je ne publierai que le résultat.

スクリーンショット 2017-07-19 2.04.41.png

** ,,, cette? ** ** J'ai été impressionné par le fait que le pourcentage de bonnes réponses serait si bas **. Après tout, il semble que ** nous devons augmenter le nombre de jeux de données **. C'est pourquoi cela continue le 4ème jour.

Site référencé

[Machine learning] J'expliquerai en essayant le cadre d'apprentissage profond Chainer. C'est très facile à comprendre. Puisque FunctionSet etc. n'est pas dans 2.0.0, je pense que vous devriez le faire en regardant d'autres sites, mais l'explication de la fonction relu etc. est très polie. J'ai emprunté le code de formation d'ici.

Essayez l'exemple MNIST de Chainer Cette personne écrit pour donner la construction du modèle comme valeur initiale de l'argument, donc j'ai pu en quelque sorte comprendre ce que je faisais. J'ai emprunté une partie de la façon d'écrire la construction du modèle de CNN à partir d'ici.

Dépannage pour divers utilisateurs de chaînes C'est le site que j'ai trouvé lorsque j'ai recherché des codes d'erreur de données.

Recommended Posts

_ 3ème jour jusqu'à ce qu'une bonne précision soit obtenue par classification des feuilles
_ 2ème jour jusqu'à ce qu'une bonne précision soit obtenue par la classification des feuilles
_1e jour jusqu'à ce qu'une bonne précision soit obtenue par la classification des feuilles