Pratique PyTorch. Ceci est le contenu jusqu'à la dernière fois ↓ Implémentation d'une analyse de régression simple avec Keras Classification des vins par Keras Machine Sommelier by Keras- Préparation de l'ensemble de données pour PyTorch
--L'ensemble de données sera utilisé comme une image d'apprentissage / d'évaluation (vérification) en collectant et en développant une clé à crochet (62 feuilles) et une clé à molette (62 feuilles) à titre d'essai (Figure 1-a, b). C'est une classification d'outils.
Figure 1-a. Hook Wrench | Figure 1-b. Spanner Wrench |
Le NN self-made est appelé MyNet dans cet article. Il s'agit d'un réseau composé d'une couche d'entrée (28 * 28 * 3 nœuds), d'une couche intermédiaire (200 nœuds) et d'une couche de sortie (2 sorties). Cette fois, nous avons permis de considérer 3 canaux RVB. Le schéma conceptuel de la structure est la figure 2.
Figure 2.Schéma conceptuel de MyNet |
Dans la couche intermédiaire, ReLU est appliqué en tant que fonction d'activation, et Dropout est également appliqué. Appliquer la fonction softmax en tant que fonction d'activation dans la couche de sortie, et sortie pour chaque classe (2) Obtenir
Figure 3.Diagramme conceptuel des termes et de l'apprentissage en machine learning |
・ ** neurones, nœuds </ font> ** La partie qui reçoit un signal d'entrée et produit quelque chose. Comme le montre la figure 3, la partie arrondie est appelée un neurone (nœud), et elle convertit une fonction en un signal d'entrée et délivre un signal de sortie.
・ ** Fonction d'activation </ font> **: ReLU, softmax Une fonction qui transforme chaque neurone (nœud) lorsqu'il reçoit une sortie d'une entrée. Quelque chose comme $ f_ {()} $ montré dans la figure.
Figure 4-a.Fonction Softmax | Figure 4-b. ReLU | Figure 4-c.Fonction Sigmaid |
・ ** Fonction de perte </ font> **: categorical_crossentropy La valeur de perte est l'erreur entre la valeur prédite par le réseau neuronal et la bonne réponse, et la fonction pour trouver l'erreur est la fonction de perte. Comme le montre la figure, c'est une fonction qui calcule l'erreur à partir de la sortie du modèle et de l'étiquette de réponse correcte.
・ ** Fonction d'optimisation </ font> **: SGD La fonction d'optimisation est une fonction qui modifie le poids de sorte que la valeur de la fonction de perte diminue. Comme le montre la figure, calculez le gradient à partir de l'erreur et du poids et ajustez le poids.
・ ** Keras ** Une bibliothèque de réseau neuronal de haut niveau écrite en Python qui peut être exécutée sur TensorFlow, CNTK ou Theano.
・ ** PyTorch ** It’s a Python-based scientific computing package targeted at two sets of audiences: ・ Un remplacement pour NumPy pour utiliser la puissance des GPU ・ Une plate-forme de recherche d'apprentissage en profondeur qui offre une flexibilité et une vitesse maximales
Voir GitHub pour le programme complet. Ce qui suit est une extraction de la partie MyNet.
# Build a model
from keras.applications.mobilenet import MobileNet
from keras.applications.resnet50 import ResNet50
from keras.layers.pooling import GlobalAveragePooling2D
from keras.layers.core import Dense, Dropout, Flatten
from keras.models import Model, load_model, Sequential
from keras.optimizers import Adam, RMSprop, SGD
base_model = Sequential()
top_model = Sequential()
INPUT_SHAPE = (img_size[0], img_size[1], 3)
neuron_total = 500
elif type_backbone == "MyNet":
INPUT_SHAPE = (img_size[0], img_size[1], 3)
base_model.add(Dense(neuron_total, activation='relu',
input_shape=(INPUT_SHAPE[0]*INPUT_SHAPE[1]*INPUT_SHAPE[2],)))
base_model.add(Dropout(0.5))
top_model.add(Dense(nb_classes, activation='softmax',
input_shape=base_model.output_shape[1:]))
# Concatenate base_model(backbone) with top model
model = Model(input=base_model.input, output=top_model(base_model.output))
print("{}couche".format(len(model.layers)))
# Compile the model
model.compile(
optimizer = SGD(lr=0.001),
loss = 'categorical_crossentropy',
metrics = ["accuracy"]
)
model.summary()
Voir GitHub pour le programme complet. Ce qui suit est une extraction de la partie MyNet.
<détails>
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F
import torchvision.models
from torchsummary import summary
neuron_total = 200
INPUT_SHAPE = (img_size[0], img_size[1], 3)
print(INPUT_SHAPE)
print(nb_classes)
# Create my model
class MyNet(nn.Module):
def __init__(self):
super().__init__()
self.l1 = nn.Linear(INPUT_SHAPE[0]*INPUT_SHAPE[1]*INPUT_SHAPE[2], neuron_total)# Input Layer to Intermediate modules
self.dropout1 = torch.nn.Dropout2d(p=0.5)
self.l2 = nn.Linear(neuron_total, 2) #Intermediate modules to Output Layer
def forward(self, x):#Propagation vers l'avant
x = x.view(-1, INPUT_SHAPE[0]*INPUT_SHAPE[1]*INPUT_SHAPE[2] ) # x.view : Transform a tensor shape. If the first argument is "-1", automatically adjust to the second argument.
x = self.l1(x)
x = self.dropout1(x)
x = self.l2(x)
return x
if type_backbone == "ResNet50":
model = Resnet()
elif type_backbone == "Mobilenet":
model = Mobilenet()
elif type_backbone == "MyNet":
model = MyNet()
model = model.to(device)
# Show the model
summary(model, ( 3, img_size[1], img_size[0]))#channel, w, h
Premièrement, comme mentionné dans Preparing a dataset for PyTorch, il est dit que Keras utilise le format numpy et PyTorch utilise les formats DataLoader et tensor. Le point est différent.
Ensuite, en ce qui concerne la façon de créer un modèle, Keras correspondra automatiquement à la forme lors de la connexion de couches avec Dense etc., mais PyTorch doit le clarifier. Par exemple, si vous ajoutez des couches intermédiaires dans la figure 2.
base_model = Sequential()
top_model = Sequential()
INPUT_SHAPE = (img_size[0], img_size[1], 3)
base_model.add(Dense(neuron_total, activation='relu',
input_shape=(INPUT_SHAPE[0]*INPUT_SHAPE[1]*INPUT_SHAPE[2],)))
base_model.add(Dense(neuron_total, activation='relu'))
base_model.add(Dense(neuron_total, activation='relu'))
base_model.add(Dropout(0.5))
top_model.add(Dense(nb_classes, activation='softmax',
input_shape=base_model.output_shape[1:]))
# Concatenate base_model(backbone) with top model
model = Model(input=base_model.input, output=top_model(base_model.output))
Dans PyTorch
class MyNet2(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(INPUT_SHAPE[0]*INPUT_SHAPE[1]*INPUT_SHAPE[2], neuron_total)# Input Layer to Intermediate modules
self.fc2 = nn.Linear(neuron_total, int(neuron_total/2)) #Intermediate modules to Output Layer
self.dropout1 = torch.nn.Dropout2d(p=0.5)
self.fc3 = nn.Linear(int(neuron_total/2), 2)
def forward(self, x):#Propagation vers l'avant
x = x.view(-1, INPUT_SHAPE[0]*INPUT_SHAPE[1]*INPUT_SHAPE[2] ) # x.view : Transform a tensor shape. If the first argument is "-1", automatically adjust to the second argument.
x = self.fc1(x)
x = self.fc2(x)
x = F.relu(x)
x = self.dropout1(x)
x = self.fc3(x)
return x
Dans PyTorch, le nombre de nœuds est spécifié pour l'entrée et la sortie.
J'ai peur de ne pas en savoir grand-chose, mais Keras ne devrait pas avoir à basculer l'application Dropout entre l'apprentissage et l'évaluation. Dans PyTorch, Dropout est désactivé par model.eval (), donc lors du chargement de l'image de test, il est clairement indiqué qu'elle n'est pas en mode d'apprentissage.
param = torch.load(weights_folder_path + "/" + best_weights_path)
model.load_state_dict(param, strict=False)
model.eval()
# ~ Inference
Comme vous pouvez le voir, le nombre de paramètres correspondait exactement.
Figure 5.Résumé de Keras par modèle(la gauche)Et PyTorch(droite)Comparaison |
C'est une petite histoire, mais dans Keras, vous n'avez pas besoin de changer la description lors de l'utilisation du GPU, mais dans le cas de PyTorch
#image, label = Variable(image), Variable(label)
image, label = Variable(image).cuda(), Variable(label).cuda()
Il doit être réécrit comme.
Dans Keras, en écrivant comme model.fit, la boucle d'évaluation d'apprentissage est répétée pour le nombre d'époques. Dans PyTorch, répétez pour le nombre d'époques comme suit dans une boucle for.
def train(epoch):
#~Abréviation
def validation():
#~Abréviation
for epoch in range(1, total_epochs + 1):
train(epoch)
validation()
De plus, PyTorch utilise log_softmax par défaut, donc la probabilité de classe totale n'est pas 1 (spécifiez softmax ou convertissez-la vous-même).
Tout d'abord, lorsque j'ai vérifié l'état de fonctionnement du PC avec le gestionnaire de tâches, il y avait les différences suivantes.
Figure 6. Kera(la gauche)Et PyTorch(droite)Performance du gestionnaire de tâches lors de chaque apprentissage (par 10 époques) |
L'utilisation de la mémoire était faible du côté PyTorch. Puisque Keras contient des ensembles de données dans des listes et des tableaux numpy (dans ce programme), il consomme inévitablement de la mémoire. L'utilisation du GPU était également faible du côté de PyTorch.
Ensuite, comparez la vitesse d'exécution de l'apprentissage de chaque réseau de Keras et PyTorch. Le tableau ci-dessous résume le [s] temps requis pour 40 époques lors de la formation à l'aide d'un réseau.
Keras | PyTorch | |
---|---|---|
ResNet | 3520 s | 3640 s |
Mobilenet | 1600 s | 1760 s |
MyNet | 40 s | 680 s |
Keras définit verbose = 1 dans model.fit, donc je regarde la valeur des secondes qui a été sortie sans autorisation. Il est précis de calculer à partir du temps par pas, mais c'est ennuyeux, c'est donc une valeur approximative. D'après le tableau ci-dessus, PyTorch est légèrement plus lent (environ 3 secondes plus lent en 1 époque). Surtout MyNet est assez lent. Cependant, PyTorch est plus économe en énergie (?). Je voulais que PyTorch soit plus rapide, mais j'ai l'impression que le code est mauvais. Je pense que PyTorch est meilleur pour économiser de l'énergie à presque la même vitesse.
Les résultats estimés de la perte, de la précision et des images de test des résultats entraînés sont résumés ci-dessous. La courbe d'apprentissage est terrible, mais les résultats sont raisonnablement raisonnables.
Figure 7.Perte et précision (Keras) pour les époques d'apprentissage |
Figure 8-a.Résultat estimé par ResNet50(Keras) |
Figure 8-b.Devinez les résultats par Mobilenet v1(Keras) |
Figure 8-c.Devinez les résultats par MyNet(Keras) |
Les résultats estimés de la perte, de la précision et des images de test des résultats entraînés sont résumés ci-dessous. Similaire à Keras, le résultat est donc affiché dans le pli.
Figure 9.Perte et précision (PyTorch) pour les époques d'apprentissage |
Figure 10-a.Résultat estimé par ResNet50 (PyTorch) |
Figure 10-b.Deviner le résultat par Mobilenet v1 (PyTorch) |
Figure 10-c.Devinez les résultats par MyNet (PyTorch) |
Les deux ont tendance à être les mêmes (parce que j'ai essayé d'apprendre presque la même chose).
Keras et PyTorch peuvent être classés par ResNet et Mobilenet, mais pas par le niveau MNIST MyNet. Cependant, il semble que l'apprentissage ne se passe pas bien avec ResNet et Mobilenet pour voir comment la perte diminue. Cette fois, l'image de test est similaire aux données d'entraînement, donc je pense que c'était la bonne réponse. Dans le cas de problèmes de classification aussi similaires que la clé à ergot et la clé à molette, il semble que le nombre de données soit faible avec environ 60 feuilles. De plus, j'estime que même si toutes les données sont disponibles, elles ne peuvent pas être classées.
À propos, le résultat de la formation du nœud de couche intermédiaire avec 500 et le nombre d'apprentissage avec 100 epoch dans MyNet est le suivant.
Figure 11.Le résultat de la formation du nœud de couche intermédiaire avec 500 et le nombre d'apprentissage avec 100 epoch avec MyNet |
La valeur de perte de la validation ne diminuera pas. C'est peut-être un problème qui ne peut pas être catégorisé uniquement par un réseau neuronal non profond. Il est nécessaire de déterminer s'il faut augmenter le nombre de couches ou utiliser CNN (réseau de neurones convolutifs).
Nous classerons les logos des deux sociétés pour le logo du fabricant apparaissant dans le précédent sommelier de la machine-outil. Il existe des différences de forme, mais peut-il être classé comme un réseau neuronal? Je vais essayer ceci sur MyNet. Pour l'apprentissage et l'évaluation, j'ai utilisé le logo Makino Milling Co., Ltd. et le logo Okuma collectés en ligne, et pour le test, j'ai utilisé mon propre logo manuscrit. Celui que j'ai écrit moi-même.
Figure 12-a.Logo Makino Milling manuscrit | Figure 12-b.Logo Okuma peint à la main |
La transition de la perte et de la précision est la suivante.
Figure 13-a.Transition de la perte par rapport à l'époque | Figure 13-b.Transition de la précision par rapport à l'époque |
Vous apprenez peut-être mieux que d'apprendre la clé à crochet et la clé à molette. Je suppose que cela ressemble à ceci:
Figure 14-a.Résultat de l'estimation du logo Makino Milling | Figure 14-b.Résultat de l'estimation du logo Okuma |
Ce résultat est très bien catégorisé. Il semble qu'il soit possible de classer même un réseau de neurones qui n'est pas profond s'il y a une différence de forme comme un logo.
https://keras.io/ja/ https://pytorch.org/tutorials/beginner/blitz/tensor_tutorial.html https://qiita.com/sheep96/items/0c2c8216d566f58882aa https://rightcode.co.jp/blog/information-technology/pytorch-mnist-learning https://water2litter.net/rum/post/pytorch_tutorial_classifier/ https://qiita.com/jyori112/items/aad5703c1537c0139edb https://pystyle.info/pytorch-cnn-based-classification-model-with-fashion-mnist/ https://pytorch.org/docs/stable/torchvision/models.html https://qiita.com/perrying/items/857df46bb6cdc3047bd8 https://qiita.com/sakaia/items/5e8375d82db197222669 https://discuss.pytorch.org/t/low-accuracy-when-loading-the-model-and-testing/44991/5