Accéder au contenu principal

Implémenter la régression logistique sur une image

Dans cet article nous allons implémenter et tester la régression logistique sur une image. Pour ce faire nous écrirons trois fonctions :

  • une fonction create_array_from_dir qui permet de récupérer des images à partir d'un répertoire donné sur le système, les redimensionner et les transformer en matrices, et ensuite retourner un tableau (array) contenant la liste de ces images ainsi transformées;
  • une fonction linear_regression qui permet d'effectuer la régression linéaire sur un vecteur X donnée;
  • une fonction sigmoide qui permet d'effectuer la régression logistique sur un input Z donné. 
Pour rappel, voici la structure de notre projet Visual Studio Code. Nous avons les dossiers train et test qui contiennent respectivement nos datasets pour l'apprentissage et les tests; le fichier library.py dans lequel nous allons mettre nos fonctions qui vont être appelé dans le programme principal classifier.py. Nous allons utiliser l'image chat1.jpg dans le dossier images comme input de la régression logistique. 

Transformer les images en matrice RGB

On va ouvrir le fichier library.py et importer les librairies nécessaires. 

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import os
from os import listdir

Image: module de la librairie PIL pour manipuler les images.
numpy: permet d'effectuer du calcul scientifique avec python. 
matplotlib.pyplot: permet entre autres de représenter les fonctions sous forme de figures. On va l'utiliser ici notamment pour afficher les images transformées en matrices. 
os: pour effectuer des opérations diverses sur le système d'exploitation. On va l'utiliser pour accéder aux répertoires et fichiers sur le système (nos images en l'occurrence). 

Dans library.py on va écrire la fonction create_array_from_dir qui permet de transformer les images, récupérées d'un répertoire donnée, en matrices. Elle effectue un filtre sur les images d'extension ext et redimensionne les images avec size. Par exemple si size est (128,128) alors l'image finale sera de 128x128 pixels et on aura une matrice de dimension (128,128,3) en sortie.  La fonction retourne à son tour une matrice de dimension (m,128,128,3), m étant le nombre d'images récupérées du répertoire. 

def create_array_from_dir(path, ext, size):
    """
    Args :
        - path: OS path where images are stored
        - ext : extension of images to pick (.jpg .png etc.)*
        - size : every image in the list will be resized usign this size
    Outputs :
        - image_array : an array of images transformed in matrix from the given path
    """
    #Create an empty list to hold images
    list = []
    #loop over images in path
    for image in os.listdir(path):
        #check if image has "ext" extension and do the magic
        if (image.endswith(ext)):
            #pick the image from directory
            img_original = Image.open(path+image)
            #resize and transform the image to a matrix using numpy array
            img_matrix = np.array(img_original.resize(size))
            #append image matrix to the list
            list.append(img_matrix)
    #create an array form list
    images_array = np.array(list)
    #return finally the array
    return images_array

Pour tester la fonction on va ouvrir le fichier classifier.py et importer la librairie. ia est l'alias qu'on donne à notre librairie. On va importer également les mêmes librairies python dont on aura besoin. On y ajoute la librairie random qui par la suite nous permettra d'initialiser le paramètre b avec un réel généré au hasard. 

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import os
from os import listdir
import library as ia
import random


On va récupérer la seule image dans le dossier nommé images, la transformer et la mettre dans la matrice X_CATS. La méthode shape de numpy retourne la dimension d'un array. shape[i] retourne l'élément i de cette dimension. Par exemple shape[0] retourne le nombre d'élément dans l'array (la matrice X_CATS ici). On utilise ensuite pyplot pour visualiser la matrice dans un graphe. 

#define path, extension and size variables
path="images/"
extension=".jpg"
size=(128,128)
#create matrix holding all images matrix in given directory and extension .
X_CATS = ia.create_array_from_dir(path, extension,size)
#Print matrix details...
dim = X_CATS.shape
mcats = X_CATS.shape[0]
print("X_CATS matrix dimension :", dim)
print("X_CATS matrix number of images :", mcats)
print("X_CATS matrix image content :", X_CATS[0])
#... and plot the first image in the matrix
print("Plotting image")
plt.imshow(X_CATS[0])
plt.show()

Voici le résultat obtenu lors de l'exécution. On peut y voir l'image représentée sous forme de matrice et affichée. 


Régression linéaire 

Dans le fichier library.py on va écrire la fonction linear_regression suivante qui effectue la régression linéaire sur un input X avec des paramètres w et b. Dans notre cas X sera une matrice de dimension (nx,m) contenant l'ensemble des images {x1,x2,....,xm). m est le nombre d'images. Pour pouvoir effectuer la régression, chacune des images sera transformée par la suite en un vecteur contenant l'ensemble des points. Cet ensemble de point est le produit de 128*128*3 qu'on va nommer nx . Cela veut dire qu'au finale une image sera transformée en une matrice de nx lignes et 1 colonne, ce qui est équivalent à un vecteur de dimension nx. Le paramètre w est un vecteur de dimension nx comme pour une image. Et le paramètre b est un réel. La fonction retourne Z

def linear_regression(X,w,b):
    """
    Args:
        - X = Matrix of images exemples of shape (nx,m)
        - w = Vector of parameters of shape (nx,1).
        - b = interceptor , a real number
    Return :
        - Z = Vector of results of linear regression with shape (1,m)
    """
    Z = (np.dot(w.T,X) + b)  
    return Z

Régression logistique (sigmoïde)

Dans le fichier library.py on va écrire la fonction sigmoide qui effectue le calcul de sigmoïde de Z, ce dernier étant le résultat de la régression linéaire. Elle retourne s. 

def sigmoide(Z):
    """
    Args:
        - Z = linear regression function result

    Return :
        - s = predicted yp

    """
    s = 1/(1+np.exp(-Z))
    return s



Commentaires

Posts les plus consultés de ce blog