Construire des convolutions et effectuer un pooling

1. Avant de commencer

Dans cet atelier de programmation, vous découvrirez les convolutions et pourquoi elles sont si performantes dans les scénarios de vision par ordinateur.

Dans l'atelier de programmation précédent, vous avez créé un réseau de neurones profond simple (DNN, Deep Neural Network) pour la vision par ordinateur des éléments de mode. Le nombre de membres était limité, car il fallait que le vêtement soit le seul élément présent dans l'image, et il devait être centré.

Bien sûr, ce scénario n'est pas réaliste. Vous souhaitez que votre DNN soit capable d'identifier le vêtement dans les photos avec d'autres objets, ou à l'endroit où il est positionné au premier plan. Pour ce faire, vous devrez utiliser des convolutions.

Conditions préalables

Cet atelier de programmation s'appuie sur les deux versements précédents : Découvrez le monde de l'ordinateur, et créez un modèle de vision par ordinateur. Veuillez les suivre avant de continuer.

Points abordés

  • Que sont les convolutions
  • Créer un mappage de caractéristiques
  • Qu'est-ce qui mène au pool ?

Objectifs de l'atelier

  • Une fonctionnalité d'une image

Prérequis

Vous trouverez le code pour le reste de l'atelier de programmation en cours d'exécution dans Colab.

TensorFlow et les bibliothèques que vous avez installées dans l'atelier de programmation précédent doivent également être installées.

2. Que sont les convolutions ?

Un convolution est un filtre qui transmet une image, la traite et extrait les caractéristiques importantes.

Imaginons que vous ayez une image d'une personne portant une basket. Comment pouvez-vous détecter une image de baskets ? Pour que votre programme puisse "voir" les baskets, vous devrez extraire les éléments importants et flouter ces éléments essentiels. C'est ce qu'on appelle le mappage de caractéristiques.

En principe, le processus de mappage des caractéristiques est simple. Vous allez scanner chaque pixel de l'image et examiner ses pixels adjacents. Vous multipliez les valeurs de ces pixels par les pondérations équivalentes dans un filtre.

Exemple :

Convolution sur image

Dans le cas présent, une matrice de convolution 3x3, ou noyau d'image, est spécifiée.

La valeur en pixels actuelle est de 192. Vous pouvez calculer la valeur du nouveau pixel en examinant les valeurs du voisin, en les multipliant par celles spécifiées dans le filtre, puis en définissant la nouvelle valeur de pixel sur le montant final.

À présent, il est temps d'explorer le fonctionnement des convolutions en créant une convolution de base sur une image en 2D en nuances de gris.

Vous le montrerez avec l'image de Montage de SciPy. Il s'agit d'une belle photo intégrée dotée de nombreux angles et lignes.

3. Commencer à coder

Commencez par importer quelques bibliothèques Python et la photo de montée:

import cv2
import numpy as np
from scipy import misc
i = misc.ascent()

Ensuite, utilisez la bibliothèque Pyplot matplotlib pour dessiner l'image afin de savoir à quoi elle ressemble:

import matplotlib.pyplot as plt
plt.grid(False)
plt.gray()
plt.axis('off')
plt.imshow(i)
plt.show()

EDB460dd5397f7f4.png

Comme vous pouvez le voir, il s'agit d'une image d'un escalier. Vous pouvez isoler de nombreuses fonctionnalités. Par exemple, il existe de fortes lignes verticales.

Comme l'image est stockée sous forme de tableau Numpy, nous pouvons la créer en copiant simplement ce tableau. Les variables size_x et size_y contiennent les dimensions de l'image afin que vous puissiez l'effectuer par la suite.

i_transformed = np.copy(i)
size_x = i_transformed.shape[0]
size_y = i_transformed.shape[1]

4. Créer la matrice de convolution

Commencez par créer une matrice (ou un noyau) de convolution en tant que tableau 3x3:

# This filter detects edges nicely
# It creates a filter that only passes through sharp edges and straight lines. 
# Experiment with different values for fun effects.
#filter = [ [0, 1, 0], [1, -4, 1], [0, 1, 0]] 
# A couple more filters to try for fun!
filter = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1]]
#filter = [ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]
 # If all the digits in the filter don't add up to 0 or 1, you 
# should probably do a weight to get it to do so
# so, for example, if your weights are 1,1,1 1,2,1 1,1,1
# They add up to 10, so you would set a weight of .1 if you want to normalize them
weight  = 1

Calculez maintenant les pixels de sortie. Itérez l'image en laissant une marge de 1 pixel, puis multipliez tous les voisins du pixel actuel par la valeur définie dans le filtre.

Cela signifie que le pixel suivant est placé au-dessus et à gauche de celui-ci multiplié par l'élément en haut à gauche du filtre. Ensuite, multipliez le résultat par la pondération et vérifiez que le résultat est compris entre 0 et 255.

Enfin, chargez la nouvelle valeur dans l'image transformée:

for x in range(1,size_x-1):
  for y in range(1,size_y-1):
      output_pixel = 0.0
      output_pixel = output_pixel + (i[x - 1, y-1] * filter[0][0])
      output_pixel = output_pixel + (i[x, y-1] * filter[0][1])
      output_pixel = output_pixel + (i[x + 1, y-1] * filter[0][2])
      output_pixel = output_pixel + (i[x-1, y] * filter[1][0])
      output_pixel = output_pixel + (i[x, y] * filter[1][1])
      output_pixel = output_pixel + (i[x+1, y] * filter[1][2])
      output_pixel = output_pixel + (i[x-1, y+1] * filter[2][0])
      output_pixel = output_pixel + (i[x, y+1] * filter[2][1])
      output_pixel = output_pixel + (i[x+1, y+1] * filter[2][2])
      output_pixel = output_pixel * weight
      if(output_pixel<0):
        output_pixel=0
      if(output_pixel>255):
        output_pixel=255
      i_transformed[x, y] = output_pixel

5. Examiner les résultats

Tracez maintenant l'image pour voir les effets de la transmission du filtre:

# Plot the image. Note the size of the axes -- they are 512 by 512
plt.gray()
plt.grid(False)
plt.imshow(i_transformed)
#plt.axis('off')
plt.show()   

48ff667b2df812ad.png

Prenez en compte les valeurs de filtre suivantes et leur impact sur l'image.

À l'aide de [-1,0,1,-2,0,2,-1,0,1], vous obtenez un très grand ensemble de lignes verticales:

Détection du filtre des lignes verticales

Les caractères [-1,-2,-1,0,0,0,1,2,1] vous permettent d'obtenir des lignes horizontales:

Détection de lignes horizontales

Explorez différentes valeurs ! Essayez aussi des filtres de taille différente, par exemple 5 x 5 ou 7 x 7.

6. Comprendre le pooling

Maintenant que vous avez identifié les principales caractéristiques de l'image, que faites-vous ? Comment utilisez-vous la carte de caractéristiques pour classer les images ?

Comme les convolutions, le pooling est parfaitement utile pour détecter les caractéristiques. Le regroupement des calques réduit la quantité globale d'informations dans une image tout en conservant les éléments géographiques détectés.

Il existe plusieurs types de pooling, mais vous allez en utiliser un intitulé appelé "Pooling maximal (max)".

Itérez l'image et, à chaque point de vue, le pixel et ses voisins immédiats en bas et en bas à droite, et en dessous du rectangle de droite. Prenez le plus grand nombre (d'ici le poolage max) et chargez-le dans la nouvelle image. Ainsi, la nouvelle image représentera un quart de la taille de l'ancienne. Pooling maximal

7. Rédiger le code commun

Le code suivant montre un pooling (2, 2). Exécutez-la pour afficher la sortie.

Bien que l'image représente un quart de la taille d'origine, elle a conservé toutes les caractéristiques.

new_x = int(size_x/2)
new_y = int(size_y/2)
newImage = np.zeros((new_x, new_y))
for x in range(0, size_x, 2):
  for y in range(0, size_y, 2):
    pixels = []
    pixels.append(i_transformed[x, y])
    pixels.append(i_transformed[x+1, y])
    pixels.append(i_transformed[x, y+1])
    pixels.append(i_transformed[x+1, y+1])
    pixels.sort(reverse=True)
    newImage[int(x/2),int(y/2)] = pixels[0]
 
# Plot the image. Note the size of the axes -- now 256 pixels instead of 512
plt.gray()
plt.grid(False)
plt.imshow(newImage)
#plt.axis('off')
plt.show()

1f5ebdafd1db2595.png

Notez les axes de ce tracé. Elle est désormais au format 256 x 256, soit un quart de sa taille d'origine, et les fonctionnalités détectées ont été améliorées, mais l'image contient moins de données.

8. Félicitations

Vous avez créé votre premier modèle de vision par ordinateur ! Pour savoir comment améliorer vos modèles de vision par ordinateur, consultez Développer des réseaux de neurones convolutifs (CNN).