Caffe2 - Guide rapide
Ces dernières années, le Deep Learning est devenu une grande tendance dans le Machine Learning. Il a été appliqué avec succès pour résoudre des problèmes auparavant insolubles dans Vision, Speech Recognition and Natural Language Processing(PNL). Il existe de nombreux autres domaines dans lesquels le Deep Learning est appliqué et a montré son utilité.
Caffe (Convolutional Architecture for Fast Feature Embedding) est un cadre d'apprentissage en profondeur développé à Berkeley Vision and Learning Center (BVLC). Le projet Caffe a été créé par Yangqing Jia pendant son doctorat. à l'Université de Californie - Berkeley. Caffe offre un moyen simple d'expérimenter l'apprentissage profond. Il est écrit en C ++ et fournit des liaisons pourPython et Matlab.
Il prend en charge de nombreux types d'architectures d'apprentissage en profondeur tels que CNN (Réseau neuronal convolutif), LSTM(Mémoire longue durée) et FC (entièrement connecté). Il prend en charge le GPU et est donc parfaitement adapté aux environnements de production impliquant des réseaux de neurones profonds. Il prend également en charge les bibliothèques de noyau basées sur le processeur telles queNVIDIA, Bibliothèque CUDA Deep Neural Network (cuDNN) et bibliothèque Intel Math Kernel (Intel MKL).
En avril 2017, la société américaine de services de réseaux sociaux Facebook a annoncé Caffe2, qui inclut désormais RNN (Recurrent Neural Networks) et en mars 2018, Caffe2 a été fusionnée avec PyTorch. Les créateurs de Caffe2 et les membres de la communauté ont créé des modèles pour résoudre divers problèmes. Ces modèles sont disponibles au public sous forme de modèles pré-formés. Caffe2 aide les créateurs à utiliser ces modèles et à créer son propre réseau pour faire des prédictions sur l'ensemble de données.
Avant d'entrer dans les détails de Caffe2, comprenons la différence entre machine learning et deep learning. Ceci est nécessaire pour comprendre comment les modèles sont créés et utilisés dans Caffe2.
Machine Learning v / s Deep Learning
Dans tout algorithme d'apprentissage automatique, qu'il soit traditionnel ou d'apprentissage en profondeur, la sélection des fonctionnalités dans l'ensemble de données joue un rôle extrêmement important pour obtenir la précision de prédiction souhaitée. Dans les techniques traditionnelles d'apprentissage automatique, lefeature selectionse fait principalement par inspection humaine, jugement et connaissance approfondie du domaine. Parfois, vous pouvez demander de l'aide à quelques algorithmes testés pour la sélection des fonctionnalités.
Le flux d'apprentissage automatique traditionnel est illustré dans la figure ci-dessous:
Dans l'apprentissage profond, la sélection des fonctionnalités est automatique et fait partie de l'algorithme d'apprentissage profond lui-même. Ceci est illustré dans la figure ci-dessous -
Dans les algorithmes d'apprentissage profond, feature engineeringse fait automatiquement. Généralement, l'ingénierie des fonctionnalités prend du temps et nécessite une bonne expertise dans le domaine. Pour implémenter l'extraction automatique des fonctionnalités, les algorithmes d'apprentissage en profondeur demandent généralement une énorme quantité de données, donc si vous n'avez que des milliers et des dizaines de milliers de points de données, la technique d'apprentissage en profondeur peut ne pas vous donner des résultats satisfaisants.
Avec des données plus volumineuses, les algorithmes d'apprentissage en profondeur produisent de meilleurs résultats par rapport aux algorithmes ML traditionnels avec l'avantage supplémentaire d'une ingénierie de fonctionnalités réduite ou nulle.
Maintenant que vous avez un aperçu de l'apprentissage profond, laissez-nous avoir un aperçu de ce qu'est Caffe.
Former un CNN
Apprenons le processus de formation d'un CNN pour la classification des images. Le processus comprend les étapes suivantes -
Data Preparation- Dans cette étape, nous recadrons les images au centre et les redimensionnons afin que toutes les images pour la formation et les tests soient de la même taille. Cela se fait généralement en exécutant un petit script Python sur les données d'image.
Model Definition- Dans cette étape, nous définissons une architecture CNN. La configuration est stockée dans.pb (protobuf)fichier. Une architecture CNN typique est illustrée dans la figure ci-dessous.
Solver Definition- Nous définissons le fichier de configuration du solveur. Le solveur effectue l'optimisation du modèle.
Model Training- Nous utilisons l'utilitaire Caffe intégré pour entraîner le modèle. La formation peut prendre un temps considérable et une utilisation du processeur considérable. Une fois la formation terminée, Caffe stocke le modèle dans un fichier, qui peut ensuite être utilisé sur les données de test et le déploiement final pour les prédictions.
Quoi de neuf dans Caffe2
Dans Caffe2, vous trouverez de nombreux modèles pré-entraînés prêts à l'emploi et vous tirerez également assez fréquemment parti des contributions de la communauté de nouveaux modèles et algorithmes. Les modèles que vous créez peuvent évoluer facilement en utilisant la puissance du GPU dans le cloud et peuvent également être réduits à l'utilisation de masses sur mobile avec ses bibliothèques multiplateformes.
Les améliorations apportées à Caffe2 par rapport à Caffe peuvent être résumées comme suit -
- Déploiement mobile
- Nouveau support matériel
- Prise en charge de la formation distribuée à grande échelle
- Calcul quantifié
- Stress testé sur Facebook
Démo de modèle pré-entraîné
Le site du Berkeley Vision and Learning Center (BVLC) propose des démonstrations de leurs réseaux pré-formés. Un tel réseau pour la classification des images est disponible sur le lien indiqué ci-jointhttps://caffe2.ai/docs/learn-more#null__caffe-neural-network-for-image-classification et est illustré dans la capture d'écran ci-dessous.
Dans la capture d'écran, l'image d'un chien est classée et étiquetée avec sa précision de prédiction. Il dit également qu'il a fallu juste0.068 secondspour classer l'image. Vous pouvez essayer une image de votre choix en spécifiant l'URL de l'image ou en téléchargeant l'image elle-même dans les options indiquées en bas de l'écran.
Maintenant que vous avez suffisamment d'informations sur les capacités de Caffe2, il est temps d'expérimenter Caffe2 par vous-même. Pour utiliser les modèles pré-entraînés ou pour développer vos modèles dans votre propre code Python, vous devez d'abord installer Caffe2 sur votre machine.
Sur la page d'installation du site Caffe2 disponible sur le lien https://caffe2.ai/docs/getting-started.html vous verrez ce qui suit pour sélectionner votre plate-forme et le type d'installation.
Comme vous pouvez le voir dans la capture d'écran ci-dessus, Caffe2 prend en charge plusieurs plates-formes populaires, y compris les mobiles.
Maintenant, nous allons comprendre les étapes pour MacOS installation sur lequel tous les projets de ce tutoriel sont testés.
Installation MacOS
L'installation peut être de quatre types comme indiqué ci-dessous -
- Fichiers binaires prédéfinis
- Construire à partir de la source
- Images Docker
- Cloud
Selon vos préférences, sélectionnez l'une des options ci-dessus comme type d'installation. Les instructions données ici sont celles du site d'installation de Caffe2 pourpre-built binaries. Il utilise Anaconda pourJupyter environment. Exécutez la commande suivante sur votre invite de console
pip install torch_nightly -f
https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html
En plus de ce qui précède, vous aurez besoin de quelques bibliothèques tierces, qui sont installées à l'aide des commandes suivantes -
conda install -c anaconda setuptools
conda install -c conda-forge graphviz
conda install -c conda-forge hypothesis
conda install -c conda-forge ipython
conda install -c conda-forge jupyter
conda install -c conda-forge matplotlib
conda install -c anaconda notebook
conda install -c anaconda pydot
conda install -c conda-forge python-nvd3
conda install -c anaconda pyyaml
conda install -c anaconda requests
conda install -c anaconda scikit-image
conda install -c anaconda scipy
Certains des didacticiels du site Web Caffe2 nécessitent également l'installation de zeromq, qui est installé à l'aide de la commande suivante -
conda install -c anaconda zeromq
Installation Windows / Linux
Exécutez la commande suivante sur votre invite de console -
conda install -c pytorch pytorch-nightly-cpu
Comme vous avez dû le remarquer, vous auriez besoin d'Anaconda pour utiliser l'installation ci-dessus. Vous devrez installer les packages supplémentaires comme spécifié dans leMacOS installation.
Tester l'installation
Pour tester votre installation, un petit script Python est donné ci-dessous, que vous pouvez couper et coller dans votre projet Juypter et exécuter.
from caffe2.python import workspace
import numpy as np
print ("Creating random data")
data = np.random.rand(3, 2)
print(data)
print ("Adding data to workspace ...")
workspace.FeedBlob("mydata", data)
print ("Retrieving data from workspace")
mydata = workspace.FetchBlob("mydata")
print(mydata)
Lorsque vous exécutez le code ci-dessus, vous devriez voir la sortie suivante -
Creating random data
[[0.06152718 0.86448082]
[0.36409966 0.52786113]
[0.65780886 0.67101053]]
Adding data to workspace ...
Retrieving data from workspace
[[0.06152718 0.86448082]
[0.36409966 0.52786113]
[0.65780886 0.67101053]]
La capture d'écran de la page de test d'installation est affichée ici pour votre référence rapide -
Maintenant que vous avez installé Caffe2 sur votre machine, procédez à l'installation des applications du didacticiel.
Installation du didacticiel
Téléchargez la source des didacticiels à l'aide de la commande suivante sur votre console -
git clone --recursive https://github.com/caffe2/tutorials caffe2_tutorials
Une fois le téléchargement terminé, vous trouverez plusieurs projets Python dans le caffe2_tutorialsdossier dans votre répertoire d'installation. La capture d'écran de ce dossier est donnée pour votre lecture rapide.
/Users/yourusername/caffe2_tutorials
Vous pouvez ouvrir certains de ces didacticiels pour voir ce que Caffe2 coderessemble à. Les deux projets suivants décrits dans ce didacticiel sont largement basés sur les exemples présentés ci-dessus.
Il est maintenant temps de faire notre propre codage Python. Comprenons comment utiliser un modèle pré-entraîné de Caffe2. Plus tard, vous apprendrez à créer votre propre réseau neuronal trivial pour vous entraîner sur votre propre ensemble de données.
Avant d'apprendre à utiliser un modèle pré-entraîné dans votre application Python, vérifions d'abord que les modèles sont installés sur votre machine et sont accessibles via le code Python.
Lorsque vous installez Caffe2, les modèles pré-entraînés sont copiés dans le dossier d'installation. Sur la machine avec l'installation d'Anaconda, ces modèles sont disponibles dans le dossier suivant.
anaconda3/lib/python3.7/site-packages/caffe2/python/models
Consultez le dossier d'installation sur votre machine pour la présence de ces modèles. Vous pouvez essayer de charger ces modèles à partir du dossier d'installation avec le court script Python suivant -
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
print(INIT_NET)
print(PREDICT_NET)
Lorsque le script s'exécute avec succès, vous verrez la sortie suivante -
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/init_net.pb
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/predict_net.pb
Cela confirme que le squeezenet module est installé sur votre machine et est accessible à votre code.
Vous êtes maintenant prêt à écrire votre propre code Python pour la classification d'images à l'aide de Caffe2 squeezenet module pré-formé.
Dans cette leçon, vous apprendrez à utiliser un modèle pré-entraîné pour détecter des objets dans une image donnée. Vous utiliserezsqueezenet module pré-formé qui détecte et classe les objets dans une image donnée avec une grande précision.
Ouvrez un nouveau Juypter notebook et suivez les étapes pour développer cette application de classification d'images.
Importation de bibliothèques
Tout d'abord, nous importons les packages requis en utilisant le code ci-dessous -
from caffe2.proto import caffe2_pb2
from caffe2.python import core, workspace, models
import numpy as np
import skimage.io
import skimage.transform
from matplotlib import pyplot
import os
import urllib.request as urllib2
import operator
Ensuite, nous avons mis en place quelques variables -
INPUT_IMAGE_SIZE = 227
mean = 128
Les images utilisées pour la formation seront évidemment de tailles variées. Toutes ces images doivent être converties en une taille fixe pour un entraînement précis. De même, les images de test et l'image que vous souhaitez prédire dans l'environnement de production doivent également être converties à la taille, identique à celle utilisée lors de la formation. Ainsi, nous créons une variable ci-dessus appeléeINPUT_IMAGE_SIZE ayant de la valeur 227. Par conséquent, nous convertirons toutes nos images à la taille227x227 avant de l'utiliser dans notre classificateur.
Nous déclarons également une variable appelée mean ayant de la valeur 128, qui est utilisé plus tard pour améliorer les résultats de classification.
Ensuite, nous développerons deux fonctions de traitement de l'image.
Traitement d'image
Le traitement de l'image se compose de deux étapes. Le premier consiste à redimensionner l'image et le second à recadrer l'image au centre. Pour ces deux étapes, nous écrirons deux fonctions de redimensionnement et de recadrage.
Redimensionnement d'image
Tout d'abord, nous allons écrire une fonction de redimensionnement de l'image. Comme dit précédemment, nous redimensionnerons l'image pour227x227. Alors définissons la fonctionresize comme suit -
def resize(img, input_height, input_width):
Nous obtenons le rapport hauteur / largeur de l'image en divisant la largeur par la hauteur.
original_aspect = img.shape[1]/float(img.shape[0])
Si le rapport hauteur / largeur est supérieur à 1, cela indique que l'image est large, c'est-à-dire qu'elle est en mode paysage. Nous ajustons maintenant la hauteur de l'image et renvoyons l'image redimensionnée en utilisant le code suivant -
if(original_aspect>1):
new_height = int(original_aspect * input_height)
return skimage.transform.resize(img, (input_width,
new_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
Si le rapport hauteur / largeur est less than 1, il indique le portrait mode. Nous ajustons maintenant la largeur en utilisant le code suivant -
if(original_aspect<1):
new_width = int(input_width/original_aspect)
return skimage.transform.resize(img, (new_width,
input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
Si le rapport hauteur / largeur est égal à 1, nous n'effectuons aucun réglage de hauteur / largeur.
if(original_aspect == 1):
return skimage.transform.resize(img, (input_width,
input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
Le code de fonction complet est donné ci-dessous pour votre référence rapide -
def resize(img, input_height, input_width):
original_aspect = img.shape[1]/float(img.shape[0])
if(original_aspect>1):
new_height = int(original_aspect * input_height)
return skimage.transform.resize(img, (input_width,
new_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
if(original_aspect<1):
new_width = int(input_width/original_aspect)
return skimage.transform.resize(img, (new_width,
input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
if(original_aspect == 1):
return skimage.transform.resize(img, (input_width,
input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
Nous allons maintenant écrire une fonction pour recadrer l'image autour de son centre.
Recadrage d'image
Nous déclarons le crop_image fonction comme suit -
def crop_image(img,cropx,cropy):
Nous extrayons les dimensions de l'image en utilisant la déclaration suivante -
y,x,c = img.shape
Nous créons un nouveau point de départ pour l'image en utilisant les deux lignes de code suivantes -
startx = x//2-(cropx//2)
starty = y//2-(cropy//2)
Enfin, nous retournons l'image recadrée en créant un objet image avec les nouvelles dimensions -
return img[starty:starty+cropy,startx:startx+cropx]
Le code de fonction complet est donné ci-dessous pour votre référence rapide -
def crop_image(img,cropx,cropy):
y,x,c = img.shape
startx = x//2-(cropx//2)
starty = y//2-(cropy//2)
return img[starty:starty+cropy,startx:startx+cropx]
Maintenant, nous allons écrire du code pour tester ces fonctions.
Traitement de l'image
Tout d'abord, copiez un fichier image dans images sous-dossier dans le répertoire de votre projet. tree.jpgLe fichier est copié dans le projet. Le code Python suivant charge l'image et l'affiche sur la console -
img = skimage.img_as_float(skimage.io.imread("images/tree.jpg")).astype(np.float32)
print("Original Image Shape: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Original image')
La sortie est la suivante -
Notez que la taille de l'image d'origine est 600 x 960. Nous devons redimensionner ceci à notre spécification de227 x 227. Appelant notre défini précédemmentresizefonction fait ce travail.
img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after resizing: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Resized image')
La sortie est comme donnée ci-dessous -
Notez que maintenant la taille de l'image est 227 x 363. Nous devons recadrer ceci pour227 x 227pour le flux final de notre algorithme. Nous appelons la fonction de recadrage précédemment définie à cet effet.
img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after cropping: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Center Cropped')
Ci-dessous mentionné est la sortie du code -
À ce stade, l'image est de taille 227 x 227et est prêt pour un traitement ultérieur. Nous échangeons maintenant les axes de l'image pour extraire les trois couleurs dans trois zones différentes.
img = img.swapaxes(1, 2).swapaxes(0, 1)
print("CHW Image Shape: " , img.shape)
Ci-dessous est la sortie -
CHW Image Shape: (3, 227, 227)
Notez que le dernier axe est maintenant devenu la première dimension du tableau. Nous allons maintenant tracer les trois canaux en utilisant le code suivant -
pyplot.figure()
for i in range(3):
pyplot.subplot(1, 3, i+1)
pyplot.imshow(img[i])
pyplot.axis('off')
pyplot.title('RGB channel %d' % (i+1))
La sortie est indiquée ci-dessous -
Enfin, nous effectuons des traitements supplémentaires sur l'image tels que la conversion Red Green Blue à Blue Green Red (RGB to BGR), en supprimant la moyenne pour de meilleurs résultats et en ajoutant un axe de taille de lot en utilisant les trois lignes de code suivantes -
# convert RGB --> BGR
img = img[(2, 1, 0), :, :]
# remove mean
img = img * 255 - mean
# add batch size axis
img = img[np.newaxis, :, :, :].astype(np.float32)
À ce stade, votre image est en NCHW formatet est prêt à alimenter notre réseau. Ensuite, nous allons charger nos fichiers de modèle pré-entraînés et y insérer l'image ci-dessus pour la prédiction.
Prédire les objets dans l'image traitée
Nous commençons par configurer les chemins pour le init et predict réseaux définis dans les modèles pré-entraînés de Caffe.
Définition des chemins de fichier du modèle
Rappelez-vous de notre discussion précédente, tous les modèles pré-entraînés sont installés dans le modelsdossier. Nous avons configuré le chemin d'accès à ce dossier comme suit -
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
Nous avons tracé le chemin vers le init_net fichier protobuf du squeezenet modèle comme suit -
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
De même, nous mettons en place le chemin vers le predict_net protobuf comme suit -
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
Nous imprimons les deux chemins à des fins de diagnostic -
print(INIT_NET)
print(PREDICT_NET)
Le code ci-dessus avec la sortie est donné ici pour votre référence rapide -
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
print(INIT_NET)
print(PREDICT_NET)
La sortie est mentionnée ci-dessous -
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/init_net.pb
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/predict_net.pb
Ensuite, nous allons créer un prédicteur.
Créer un prédicteur
Nous lisons les fichiers de modèle en utilisant les deux instructions suivantes -
with open(INIT_NET, "rb") as f:
init_net = f.read()
with open(PREDICT_NET, "rb") as f:
predict_net = f.read()
Le prédicteur est créé en passant des pointeurs vers les deux fichiers en tant que paramètres vers le Predictor fonction.
p = workspace.Predictor(init_net, predict_net)
le pobject est le prédicteur, qui est utilisé pour prédire les objets dans une image donnée. Notez que chaque image d'entrée doit être au format NCHW comme ce que nous avons fait précédemment à notretree.jpg fichier.
Prédire les objets
Prédire les objets dans une image donnée est trivial - il suffit d'exécuter une seule ligne de commande. Nous appelonsrun méthode sur le predictor objet pour une détection d'objet dans une image donnée.
results = p.run({'data': img})
Les résultats de la prédiction sont désormais disponibles dans le results objet, que nous convertissons en un tableau pour notre lisibilité.
results = np.asarray(results)
Imprimez les dimensions du tableau pour votre compréhension en utilisant la déclaration suivante -
print("results shape: ", results.shape)
La sortie est comme indiqué ci-dessous -
results shape: (1, 1, 1000, 1, 1)
Nous allons maintenant supprimer l'axe inutile -
preds = np.squeeze(results)
La prédication la plus élevée peut maintenant être récupérée en prenant le max valeur dans le preds tableau.
curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1))
print("Prediction: ", curr_pred)
print("Confidence: ", curr_conf)
La sortie est la suivante -
Prediction: 984
Confidence: 0.89235985
Comme vous le voyez, le modèle a prédit un objet avec une valeur d'index 984 avec 89%confiance. L'indice de 984 n'a pas beaucoup de sens pour nous pour comprendre quel type d'objet est détecté. Nous devons obtenir le nom stringifié de l'objet en utilisant sa valeur d'index. Le type d'objets que le modèle reconnaît ainsi que leurs valeurs d'index correspondantes sont disponibles sur un référentiel github.
Maintenant, nous allons voir comment récupérer le nom de notre objet ayant une valeur d'index de 984.
Résultat stringifiant
Nous créons un objet URL vers le référentiel github comme suit -
codes = "https://gist.githubusercontent.com/aaronmarkham/cd3a6b6ac0
71eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes"
Nous lisons le contenu de l'URL -
response = urllib2.urlopen(codes)
La réponse contiendra une liste de tous les codes et leurs descriptions. Quelques lignes de la réponse sont affichées ci-dessous pour votre compréhension de ce qu'elle contient -
5: 'electric ray, crampfish, numbfish, torpedo',
6: 'stingray',
7: 'cock',
8: 'hen',
9: 'ostrich, Struthio camelus',
10: 'brambling, Fringilla montifringilla',
Nous parcourons maintenant l'ensemble du tableau pour localiser notre code souhaité de 984 à l'aide d'un for boucle comme suit -
for line in response:
mystring = line.decode('ascii')
code, result = mystring.partition(":")[::2]
code = code.strip()
result = result.replace("'", "")
if (code == str(curr_pred)):
name = result.split(",")[0][1:]
print("Model predicts", name, "with", curr_conf, "confidence")
Lorsque vous exécutez le code, vous verrez la sortie suivante -
Model predicts rapeseed with 0.89235985 confidence
Vous pouvez maintenant essayer le modèle sur une autre image.
Prédire une image différente
Pour prédire une autre image, copiez simplement le fichier image dans le imagesdossier de votre répertoire de projet. C'est le répertoire dans lequel notre ancientree.jpgle fichier est stocké. Modifiez le nom du fichier image dans le code. Une seule modification est requise comme indiqué ci-dessous
img = skimage.img_as_float(skimage.io.imread("images/pretzel.jpg")).astype(np.float32)
L'image originale et le résultat de la prédiction sont affichés ci-dessous -
La sortie est mentionnée ci-dessous -
Model predicts pretzel with 0.99999976 confidence
Comme vous le voyez, le modèle pré-entraîné est capable de détecter des objets dans une image donnée avec une grande précision.
Source complète
La source complète du code ci-dessus qui utilise un modèle pré-entraîné pour la détection d'objet dans une image donnée est mentionnée ici pour votre référence rapide -
def crop_image(img,cropx,cropy):
y,x,c = img.shape
startx = x//2-(cropx//2)
starty = y//2-(cropy//2)
return img[starty:starty+cropy,startx:startx+cropx]
img = skimage.img_as_float(skimage.io.imread("images/pretzel.jpg")).astype(np.float32)
print("Original Image Shape: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Original image')
img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after resizing: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Resized image')
img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after cropping: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Center Cropped')
img = img.swapaxes(1, 2).swapaxes(0, 1)
print("CHW Image Shape: " , img.shape)
pyplot.figure()
for i in range(3):
pyplot.subplot(1, 3, i+1)
pyplot.imshow(img[i])
pyplot.axis('off')
pyplot.title('RGB channel %d' % (i+1))
# convert RGB --> BGR
img = img[(2, 1, 0), :, :]
# remove mean
img = img * 255 - mean
# add batch size axis
img = img[np.newaxis, :, :, :].astype(np.float32)
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
print(INIT_NET)
print(PREDICT_NET)
with open(INIT_NET, "rb") as f:
init_net = f.read()
with open(PREDICT_NET, "rb") as f:
predict_net = f.read()
p = workspace.Predictor(init_net, predict_net)
results = p.run({'data': img})
results = np.asarray(results)
print("results shape: ", results.shape)
preds = np.squeeze(results)
curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1))
print("Prediction: ", curr_pred)
print("Confidence: ", curr_conf)
codes = "https://gist.githubusercontent.com/aaronmarkham/cd3a6b6ac071eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes"
response = urllib2.urlopen(codes)
for line in response:
mystring = line.decode('ascii')
code, result = mystring.partition(":")[::2]
code = code.strip()
result = result.replace("'", "")
if (code == str(curr_pred)):
name = result.split(",")[0][1:]
print("Model predicts", name, "with", curr_conf, "confidence")
À ce stade, vous savez comment utiliser un modèle pré-entraîné pour effectuer les prédictions sur votre ensemble de données.
La prochaine étape consiste à apprendre à définir votre neural network (NN) architectures dans Caffe2et formez-les sur votre ensemble de données. Nous allons maintenant apprendre à créer un NN simple couche simple.
Dans cette leçon, vous apprendrez à définir un single layer neural network (NN)dans Caffe2 et exécutez-le sur un ensemble de données généré aléatoirement. Nous allons écrire du code pour représenter graphiquement l'architecture du réseau, imprimer l'entrée, la sortie, les poids et les valeurs de biais. Pour comprendre cette leçon, vous devez être familiarisé avecneural network architectures, son terms et mathematics utilisé en eux.
Architecture de réseau
Considérons que nous voulons construire une seule couche NN comme le montre la figure ci-dessous -
Mathématiquement, ce réseau est représenté par le code Python suivant -
Y = X * W^T + b
Où X, W, b sont des tenseurs et Yest la sortie. Nous allons remplir les trois tenseurs avec des données aléatoires, exécuter le réseau et examiner leYproduction. Pour définir le réseau et les tenseurs, Caffe2 fournit plusieursOperator les fonctions.
Opérateurs Caffe2
Dans Caffe2, Operatorest l'unité de base du calcul. Le Caffe2Operator est représenté comme suit.
Caffe2 fournit une liste exhaustive d'opérateurs. Pour le réseau que nous concevons actuellement, nous utiliserons l'opérateur appelé FC, qui calcule le résultat du passage d'un vecteur d'entréeX dans un réseau entièrement connecté avec une matrice de poids bidimensionnelle W et un vecteur de biais unidimensionnel b. En d'autres termes, il calcule l'équation mathématique suivante
Y = X * W^T + b
Où X a des dimensions (M x k), W a des dimensions (n x k) et b est (1 x n). Le résultatY sera de dimension (M x n), où M est la taille du lot.
Pour les vecteurs X et W, nous utiliserons le GaussianFillopérateur pour créer des données aléatoires. Pour générer des valeurs de biaisb, nous utiliserons ConstantFill opérateur.
Nous allons maintenant procéder à la définition de notre réseau.
Créer un réseau
Tout d'abord, importez les packages requis -
from caffe2.python import core, workspace
Ensuite, définissez le réseau en appelant core.Net comme suit -
net = core.Net("SingleLayerFC")
Le nom du réseau est spécifié comme SingleLayerFC. À ce stade, l'objet réseau appelé net est créé. Il ne contient aucune couche pour le moment.
Création de tenseurs
Nous allons maintenant créer les trois vecteurs requis par notre réseau. Tout d'abord, nous allons créer un tenseur X en appelantGaussianFill opérateur comme suit -
X = net.GaussianFill([], ["X"], mean=0.0, std=1.0, shape=[2, 3], run_once=0)
le X le vecteur a des dimensions 2 x 3 avec la valeur moyenne des données de 0,0 et l'écart type de 1.0.
De même, nous créons W tenseur comme suit -
W = net.GaussianFill([], ["W"], mean=0.0, std=1.0, shape=[5, 3], run_once=0)
le W le vecteur est de taille 5 x 3.
Enfin, nous créons des biais b matrice de taille 5.
b = net.ConstantFill([], ["b"], shape=[5,], value=1.0, run_once=0)
Maintenant, vient la partie la plus importante du code et qui définit le réseau lui-même.
Définition du réseau
Nous définissons le réseau dans l'instruction Python suivante -
Y = X.FC([W, b], ["Y"])
Nous appelons FC opérateur sur les données d'entrée X. Les poids sont spécifiés dansWet biais en b. La sortie estY. Vous pouvez également créer le réseau à l'aide de l'instruction Python suivante, qui est plus détaillée.
Y = net.FC([X, W, b], ["Y"])
À ce stade, le réseau est simplement créé. Tant que nous n'exécutons pas le réseau au moins une fois, il ne contiendra aucune donnée. Avant d'exécuter le réseau, nous examinerons son architecture.
Architecture de réseau d'impression
Caffe2 définit l'architecture réseau dans un fichier JSON, qui peut être examiné en appelant la méthode Proto sur le net objet.
print (net.Proto())
Cela produit la sortie suivante -
name: "SingleLayerFC"
op {
output: "X"
name: ""
type: "GaussianFill"
arg {
name: "mean"
f: 0.0
}
arg {
name: "std"
f: 1.0
}
arg {
name: "shape"
ints: 2
ints: 3
}
arg {
name: "run_once"
i: 0
}
}
op {
output: "W"
name: ""
type: "GaussianFill"
arg {
name: "mean"
f: 0.0
}
arg {
name: "std"
f: 1.0
}
arg {
name: "shape"
ints: 5
ints: 3
}
arg {
name: "run_once"
i: 0
}
}
op {
output: "b"
name: ""
type: "ConstantFill"
arg {
name: "shape"
ints: 5
}
arg {
name: "value"
f: 1.0
}
arg {
name: "run_once"
i: 0
}
}
op {
input: "X"
input: "W"
input: "b"
output: "Y"
name: ""
type: "FC"
}
Comme vous pouvez le voir dans la liste ci-dessus, il définit d'abord les opérateurs X, W et b. Examinons la définition deWpar exemple. Le type deW est spécifié comme GausianFill. lemean est défini comme float 0.0, l'écart type est défini comme flottant 1.0, et le shape est 5 x 3.
op {
output: "W"
name: "" type: "GaussianFill"
arg {
name: "mean"
f: 0.0
}
arg {
name: "std"
f: 1.0
}
arg {
name: "shape"
ints: 5
ints: 3
}
...
}
Examiner les définitions de X et bpour votre propre compréhension. Enfin, regardons la définition de notre réseau monocouche, qui est reproduite ici
op {
input: "X"
input: "W"
input: "b"
output: "Y"
name: ""
type: "FC"
}
Ici, le type de réseau est FC (Entièrement connecté) avec X, W, b comme entrées et Yest la sortie. Cette définition de réseau est trop verbeuse et pour les grands réseaux, il deviendra fastidieux d'examiner son contenu. Heureusement, Caffe2 fournit une représentation graphique des réseaux créés.
Représentation graphique du réseau
Pour obtenir la représentation graphique du réseau, exécutez l'extrait de code suivant, qui ne comprend essentiellement que deux lignes de code Python.
from caffe2.python import net_drawer
from IPython import display
graph = net_drawer.GetPydotGraph(net, rankdir="LR")
display.Image(graph.create_png(), width=800)
Lorsque vous exécutez le code, vous verrez la sortie suivante -
Pour les grands réseaux, la représentation graphique devient extrêmement utile pour visualiser et déboguer les erreurs de définition de réseau.
Enfin, il est maintenant temps de faire fonctionner le réseau.
Réseau en cours d'exécution
Vous exécutez le réseau en appelant le RunNetOnce méthode sur le workspace objet -
workspace.RunNetOnce(net)
Une fois le réseau exécuté une fois, toutes nos données générées au hasard seraient créées, introduites dans le réseau et la sortie sera créée. Les tenseurs créés après l'exécution du réseau sont appelésblobsdans Caffe2. L'espace de travail se compose dublobsvous créez et stockez en mémoire. Ceci est assez similaire à Matlab.
Après avoir exécuté le réseau, vous pouvez examiner le blobs que l'espace de travail contient en utilisant les éléments suivants print commander
print("Blobs in the workspace: {}".format(workspace.Blobs()))
Vous verrez la sortie suivante -
Blobs in the workspace: ['W', 'X', 'Y', 'b']
Notez que l'espace de travail se compose de trois objets blob d'entrée - X, W et b. Il contient également l'objet blob de sortie appeléY. Examinons maintenant le contenu de ces blobs.
for name in workspace.Blobs():
print("{}:\n{}".format(name, workspace.FetchBlob(name)))
Vous verrez la sortie suivante -
W:
[[ 1.0426593 0.15479846 0.25635982]
[-2.2461145 1.4581774 0.16827184]
[-0.12009818 0.30771437 0.00791338]
[ 1.2274994 -0.903331 -0.68799865]
[ 0.30834186 -0.53060573 0.88776857]]
X:
[[ 1.6588869e+00 1.5279824e+00 1.1889904e+00]
[ 6.7048723e-01 -9.7490678e-04 2.5114202e-01]]
Y:
[[ 3.2709925 -0.297907 1.2803618 0.837985 1.7562964]
[ 1.7633215 -0.4651525 0.9211631 1.6511179 1.4302125]]
b:
[1. 1. 1. 1. 1.]
Notez que les données sur votre machine ou en fait sur chaque exécution du réseau seraient différentes car toutes les entrées sont créées au hasard. Vous avez maintenant défini avec succès un réseau et l'exécutez sur votre ordinateur.
Dans la leçon précédente, vous avez appris à créer un réseau trivial, à l'exécuter et à examiner sa sortie. Le processus de création de réseaux complexes est similaire au processus décrit ci-dessus. Caffe2 fournit un vaste ensemble d'opérateurs pour créer des architectures complexes. Nous vous encourageons à consulter la documentation Caffe2 pour une liste d'opérateurs. Après avoir étudié la fonction des différents opérateurs, vous seriez en mesure de créer des réseaux complexes et de les former. Pour former le réseau, Caffe2 met à disposition plusieurspredefined computation units- ce sont les opérateurs. Vous devrez sélectionner les opérateurs appropriés pour former votre réseau au type de problème que vous essayez de résoudre.
Une fois qu'un réseau est formé à votre satisfaction, vous pouvez le stocker dans un fichier modèle similaire aux fichiers modèle pré-entraînés que vous avez utilisés précédemment. Ces modèles formés peuvent être ajoutés au référentiel Caffe2 pour le bénéfice d'autres utilisateurs. Ou vous pouvez simplement mettre le modèle entraîné pour votre propre utilisation de production privée.
Sommaire
Caffe2, qui est un cadre d'apprentissage en profondeur, vous permet d'expérimenter plusieurs types de réseaux de neurones pour prédire vos données. Le site Caffe2 fournit de nombreux modèles pré-entraînés. Vous avez appris à utiliser l'un des modèles pré-entraînés pour classer les objets dans une image donnée. Vous avez également appris à définir une architecture de réseau neuronal de votre choix. Ces réseaux personnalisés peuvent être formés à l'aide de nombreux opérateurs prédéfinis dans Caffe. Un modèle entraîné est stocké dans un fichier qui peut être intégré à un environnement de production.