[PYTHON] Effets de la rotation d'image, de l'agrandissement, de la couleur, etc. sur le réseau neuronal convolutif (CNN)

Les performances de classification sont améliorées lorsque l'image est tournée, agrandie, changée de couleur, etc. dans le but de comprendre les caractéristiques du réseau de neurones convolutifs (CNN) et d'autres méthodes d'apprentissage automatique (amplification de gradient, perceptron multicouche). J'ai essayé comment cela allait changer.

L'image a été générée par la méthode de Générer automatiquement une image de koala et d'ours. Pouvez-vous distinguer Koala et Kuma par leur silhouette?

code

Lecture des données d'image

from PIL import Image

koalas = []
for i in range(num_data):
    koala = Image.open("koala_or_bear/koala_{}.jpg ".format(i))
    koalas.append(koala)

bears = []
for i in range(num_data):
    bear = Image.open("koala_or_bear/bear_{}.jpg ".format(i))
    bears.append(bear)

Premier affichage des données

%matplotlib inline
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10,10))
for i in range(16):
    ax = fig.add_subplot(4, 4, i+1)
    ax.axis('off')
    if i < 8:
        ax.set_title('koala_{}'.format(i))
        ax.imshow(koalas[i],cmap=plt.cm.gray, interpolation='none')
    else:
        ax.set_title('bear_{}'.format(i - 8))
        ax.imshow(bears[i - 8],cmap=plt.cm.gray, interpolation='none')
plt.show()

Variable explicative / variable objective

import numpy as np

X = [] #Variable explicative
Y = [] #Variable objective

index = 0
for koala in koalas:
    resize_img = koala.resize((128, 128))
    r, g, b = resize_img.split()
    r_resize_img = np.asarray(np.float32(r)/255.0)
    g_resize_img = np.asarray(np.float32(g)/255.0)
    b_resize_img = np.asarray(np.float32(b)/255.0)
    rgb_resize_img = np.asarray([r_resize_img, g_resize_img, b_resize_img])
    X.append(rgb_resize_img)
    Y.append(0)
    index += 1
    if index >= num_data:
        break

index = 0
for bear in bears:
    resize_img = bear.resize((128, 128))
    r, g, b = resize_img.split()
    r_resize_img = np.asarray(np.float32(r)/255.0)
    g_resize_img = np.asarray(np.float32(g)/255.0)
    b_resize_img = np.asarray(np.float32(b)/255.0)
    rgb_resize_img = np.asarray([r_resize_img, g_resize_img, b_resize_img])
    X.append(rgb_resize_img)
    Y.append(1)
    index += 1
    if index >= num_data:
        break

X = np.array(X, dtype='float32')
Y = np.array(Y, dtype='int64')

Séparé en ensemble enseignant et ensemble test

from sklearn import model_selection
X_train, X_test, Y_train, Y_test = model_selection.train_test_split(
    X, Y, test_size=0.1
)

Conversion de type de données pour scikit-learn

d1, d2, d3, d4 = X_train.shape
X_train_a = X_train.reshape((d1, d2 * d3 * d4))
Y_train_onehot = np.identity(2)[Y_train]
d1, d2, d3, d4 = X_test.shape
X_test_a = X_test.reshape((d1, d2 * d3 * d4))
Y_test_onehot = np.identity(2)[Y_test]

Conversion de type de données pour PyTorch

import torch
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader

X_train_t = torch.from_numpy(X_train).float()
Y_train_t = torch.from_numpy(Y_train).long()

X_train_v = torch.autograd.Variable(X_train_t)
Y_train_v = torch.autograd.Variable(Y_train_t)

X_test_t = torch.from_numpy(X_test).float()
Y_test_t = torch.from_numpy(Y_test).long()

X_test_v = torch.autograd.Variable(X_test_t)
Y_test_v = torch.autograd.Variable(Y_test_t)

train = TensorDataset(X_train_t, Y_train_t)
train_loader = DataLoader(train, batch_size=32, shuffle=True)

Augmentation du gradient

%%time
from sklearn.ensemble import GradientBoostingClassifier

classifier = GradientBoostingClassifier()
classifier.fit(X_train_a, Y_train)
print("Accuracy score (train): ", classifier.score(X_train_a, Y_train))
print("Accuracy score (test): ", classifier.score(X_test_a, Y_test))

Perceptron multicouche (1 couche intermédiaire)

%%time
from sklearn.neural_network import MLPClassifier

classifier = MLPClassifier(max_iter=10000, early_stopping=True)
classifier.fit(X_train_a, Y_train)
print("Accuracy score (train): ", classifier.score(X_train_a, Y_train))
print("Accuracy score (test): ", classifier.score(X_test_a, Y_test))

Perceptron multicouche (2 couches intermédiaires)

%%time
from sklearn.neural_network import MLPClassifier
classifier = MLPClassifier(max_iter=10000, early_stopping=True,
                           hidden_layer_sizes=(100, 100))
classifier.fit(X_train_a, Y_train)
print("Accuracy score (train): ", classifier.score(X_train_a, Y_train))
print("Accuracy score (test): ", classifier.score(X_test_a, Y_test))

Réseau neuronal convolutif (CNN)

Définition du réseau

class CNN(torch.nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = torch.nn.Conv2d(3, 10, 5)
        self.conv2 = torch.nn.Conv2d(10, 20, 5)
        self.fc1 = torch.nn.Linear(20 * 29 * 29, 50)
        self.fc2 = torch.nn.Linear(50, 2)
    
    def forward(self, x):
        x = torch.nn.functional.relu(self.conv1(x))
        x = torch.nn.functional.max_pool2d(x, 2)
        x = torch.nn.functional.relu(self.conv2(x))
        x = torch.nn.functional.max_pool2d(x, 2)
        x = x.view(-1, 20 * 29 * 29)
        x = torch.nn.functional.relu(self.fc1(x))
        x = torch.nn.functional.log_softmax(self.fc2(x), 1)
        return x

Vérification de la structure du réseau

from torchsummary import summary
model = CNN()
summary(model, X[0].shape)
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 10, 124, 124]             760
            Conv2d-2           [-1, 20, 58, 58]           5,020
            Linear-3                   [-1, 50]         841,050
            Linear-4                    [-1, 2]             102
================================================================
Total params: 846,932
Trainable params: 846,932
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.19
Forward/backward pass size (MB): 1.69
Params size (MB): 3.23
Estimated Total Size (MB): 5.11
----------------------------------------------------------------

Fonction d'exécution

def learn(model, criterion, optimizer, n_iteration):
    for epoch in range(n_iteration):
        total_loss = np.array(0, dtype='float64')
        for x, y in train_loader:
            x = torch.autograd.Variable(x)
            y = torch.autograd.Variable(y)
            optimizer.zero_grad()
            y_pred = model(x)
            loss = criterion(y_pred, y)
            loss.backward()
            optimizer.step()
            total_loss += loss.data.numpy()
        
        if (epoch + 1) % 10 == 0:
            print(epoch + 1, total_loss)
        
        if total_loss == np.array(0, dtype='float64'):
            break
        
        loss_history.append(total_loss)
    
    return model

Code d'exécution

#%%time
model = CNN()
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
loss_history = []
model = learn(model, criterion, optimizer, 300)

Affichage de l'historique des pertes

ax = plt.subplot(2, 1, 1)
ax.plot(loss_history)
ax.grid()
ax = plt.subplot(2, 1, 2)
ax.plot(loss_history)
ax.set_yscale('log')
ax.grid()

Taux de réponse correct

Taux de réponse correct (ensemble de l'enseignant)

Y_pred = torch.max(model(X_train_v).data, 1)[1]
accuracy = sum(Y_train == Y_pred.numpy()) / len(Y_train)
print(accuracy)

Taux de réponse correct (ensemble de test)

Y_pred = torch.max(model(X_test_v).data, 1)[1]
accuracy = sum(Y_test == Y_pred.numpy()) / len(Y_test)
print(accuracy)

résultat

Premièrement, la question la plus simple pour distinguer Koala et Kuma.

基本

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 1min 2s 1.0 1.0
Perceptron multicouche (couche intermédiaire 1) 50,9 s 1,0 1,0
Perceptron multicouche (2 couches intermédiaires) 35,1 s 1,0 1,0
Réseau neuronal à convolution (CNN) - 1.0 1.0

Toutes les méthodes de prédiction ont pu répondre parfaitement.

Expansion

Agrandissons Koala et Kuma à des grossissements aléatoires. À ce stade, je vais essayer de le décaler légèrement verticalement et horizontalement.

拡大

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 5min 11s 1,0 0,975
Perceptron multicouche (couche intermédiaire 1) 1min 4s 1,0 1,0
Perceptron multicouche (2 couches intermédiaires) 1min 4s 0,977 1,0
Réseau neuronal à convolution (CNN) - 1.0 1.0

Le pourcentage de réponses correctes pour le renforcement du gradient a légèrement diminué. Le réseau de neurones convolutifs (CNN) a le pourcentage parfait de bonnes réponses.

Il y a un obstacle

Dessinez quelque chose qui pourrait vous gêner en arrière-plan.

邪魔物あり

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 1min 23s 1.0 1.0
Perceptron multicouche (couche intermédiaire 1) 38,3 s 1,0 1,0
Perceptron multicouche (2 couches intermédiaires) 1min 3s 0,983 1,0
Réseau neuronal à convolution (CNN) - 1.0 1.0

Cela semble n'avoir pratiquement aucun effet.

Ne colorez que l'arrière-plan

Rendons l'arrière-plan coloré.

背景だけ彩色

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 1min 30s 1.0 1.0
Perceptron multicouche (1 couche intermédiaire) 43,9 s 0,9916 1,0
Perceptron multicouche (2 couches intermédiaires) 41,6 s 1,0 1,0
Réseau neuronal à convolution (CNN) - 1.0 1.0

Cela semble également avoir peu d'effet.

Couleur uniquement des animaux

Rendons Koala et Kuma colorés.

動物だけ彩色

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 4min 26s 1,0 0,975
Perceptron multicouche (1 couche intermédiaire) 27,8 s 0,494 0,55
Perceptron multicouche (2 couches intermédiaires) 1min 9s 0,816 0,775
Réseau neuronal à convolution (CNN) - 0,505 0,45

La précision des prévisions a considérablement diminué. Les performances du réseau de neurones convolutifs (CNN) ont chuté. cette? Étonnamment, le Perceptron multicouche (deux couches du milieu) se porte bien. Et les performances de l'augmentation de gradient ne se sont guère détériorées. C'est incroyable.

Agrandi / coloré / avec des obstacles

拡大・彩色・邪魔物

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 7min 24s 1,0 0,9
Perceptron multicouche (couche intermédiaire 1) 42,4 s 0,6861 0,6
Perceptron multicouche (2 couches intermédiaires) 1min 50s 0,925 0,75
Réseau neuronal à convolution (CNN) - 0,5 0,5

La difficulté a augmenté, mais le renforcement du gradient est plutôt bon. Le réseau de neurones convolutifs (CNN) est totalement inutile.

Agrandissement / coloration / seuls les animaux sont noirs / il y a des obstacles

拡大・彩色・動物だけ黒・邪魔物あり

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 6min 12s 1,0 0,975
Perceptron multicouche (couche intermédiaire 1) 1min 1s 0,9916 0,975
Perceptron multicouche (2 couches intermédiaires) 1min 12s 1.0 1.0
Réseau neuronal à convolution (CNN) - 1.0 1.0

Toutes les performances de prédiction ont été restaurées simplement en unifiant les couleurs de Koala et Kuma au noir. Après tout, c'est le critère.

rotation

Il se retourne Koala se retourne Les ours se retournent aussi

回転

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 3min 10s 1,0 0,925
Perceptron multicouche (couche intermédiaire 1) 27,4 s 0,5 0,5
Perceptron multicouche (2 couches intermédiaires) 1min 20s 0,994 1,0
Réseau neuronal à convolution (CNN) - 1.0 1.0

Le Perceptron multicouche (couche intermédiaire 1) ne fonctionnait pas, mais tout le monde semble l'avoir fait à propos de la rotation. L'amplification du gradient semble être un peu faible en rotation.

Faire pivoter / agrandir

Développons tout en tournant.

回転・拡大・グレースケール

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 5min 28s 1,0 0,775
Perceptron multicouche (1 couche intermédiaire) 1min 33s 0,825 0,7
Perceptron multicouche (deux couches intermédiaires) 30,9 s 0,65 0,675
Réseau neuronal à convolution (CNN) - 0,505 0,45

Ce n'est pas grave si c'est juste une rotation, ça va si c'est juste une expansion. Cependant, il semble que tout le monde soit confus s'il se dilate en tournant. Pourtant, en augmentant le gradient, je fais de mon mieux.

Rotation / agrandissement / coloration / noir uniquement pour les animaux / avec obstacles

回転・拡大・彩色・動物だけ黒・邪魔物あり

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 7min 6s 1,0 0,6
Perceptron multicouche (couche intermédiaire 1) 29,5 s 0,5194 0,325
Perceptron multicouche (2 couches du milieu) 33 s 0,572 0,65
Réseau neuronal à convolution (CNN) - 0,5194 0,325

Si différents facteurs (rotation, agrandissement, obstacles, couleurs) sont attaqués individuellement, il semble que ce sera difficile si ces facteurs sont mélangés et attaqués, même si ce n'est pas un gros problème.

Tous les différents facteurs

いろんな要因全部のせ

Méthode Temps d'apprentissage Taux de réponse correct (ensemble de l'enseignant) Taux de réponse correct (ensemble de tests)
Augmentation du gradient 7min 55s 1,0 0,45
Perceptron multicouche (1 couche intermédiaire) 31,8 s 0,505 0,45
Perceptron multicouche (2 couches intermédiaires) 55,7 s 0,6027 0,45
Réseau neuronal à convolution (CNN) - 0,505 0,45

J'ai pu piloter tous les différents facteurs. Cela semble en aucun cas être un gâchis.

Résumé

Je voulais avoir une idée du réseau de neurones convolutifs (CNN), donc je voulais obtenir un résultat "CNN gagne seul !!!" </ b>, mais la conclusion est "gradient boosting". Super ouais ouais! "</ B>. (ヽ ´ω`)

Recommended Posts