Ressources scientifiques
pour l'enseignement de la physique

Un partenariat entre

ENS Lyon Eduscol
Outils personnels
Navigation

Aller au contenu. | Aller à la navigation

Vous êtes ici : Accueil Images articles IA-Bernet Reconnaissance-chiffres-IA-Colin-Bernet.py
Culture Sciences Physique fête ses 20 ans

Julien Bobroff à l’ENS de Lyon et en direct

Le co-créateur de "La Physique Autrement" présentera une conférence le jeudi 7 décembre 2023 à 14h30 à l'ENS de Lyon.

En savoir plus

Reconnaissance-chiffres-IA-Colin-Bernet.py

Python Source icon Reconnaissance-chiffres-IA-Colin-Bernet.py — Python Source, 3 ko (3495 bytes)

Contenu du fichier

#!/usr/bin/env python
# coding: utf-8

# # Reconnaissance de chiffres manuscrits avec scikit-learn
# @ Colin Bernet IP2I Lyon

# ## Échantillon de données de chiffres manuscrits
# 
# Une version basse résolution de cet échantillon est fourni avec scikit-learn.
# 
# On commence par charger l'échantillon : 

# In[13]:


from sklearn import datasets
digits = datasets.load_digits()


# Puis on imprime la première image : 

# In[53]:


print(digits.images[0])


# Comme toutes les images de l'échantillon, celle-ci est une image de 8x8 pixels, noir et blanc (un seul niveau de couleur par pixel). On peut l'afficher de la manière suivante, en indiquant également l'étiquette correspondante (le chiffre auquel correspond l'image) : 

# In[31]:


import matplotlib.pyplot as plt
plt.imshow(digits.images[0],cmap='binary')
plt.title(digits.target[0])
plt.axis('off')
plt.show()


# Nous allons entraîner un réseau de neurones simple à reconnaître les chiffres dans ces images. Ce réseau va prendre en entrée des tableaux 1D de 8x8=64 valeurs. Nous devons donc convertir nos images 2D en tableaux 1D :

# In[32]:


x = digits.images.reshape((len(digits.images), -1))
# x contient toutes les images en version 1D.
# nous imprimons ici la première, que nous avons déjà vue : 
print(x[0])


# Le réseau va agir comme une fonction permettant de passer d'un tableau de 64 valeurs en entrée à une valeur en sortie, son estimation du chiffre. Voici les valeurs de sortie : 

# In[33]:


y = digits.target


# In[ ]:


print(len(digits.images)) # Nombre d'images dans le set d'échantillons


# ## Définition et entraînement du réseau

# Nous décidons de créer un réseau de neurones relativement simple, avec une seule couche de 15 neurones : 

# In[54]:


from sklearn.neural_network import MLPClassifier

mlp = MLPClassifier(hidden_layer_sizes=(15,))


# Nous allons entraîner ce réseau sur les 1000 premières images de notre échantillon, et réserver les images suivantes pour tester les performances du réseau : 

# In[55]:


x_train = x[:1000]
y_train = y[:1000]
x_test = x[1000:]
y_test = y[1000:]


# In[56]:


mlp.fit(x_train, y_train)


# Et voilà ! nous pouvons maintenant regarder ce que donne le réseau pour les images suivantes, qui n'ont pas été vues par le réseau lors de l'entraînement : 

# In[57]:


mlp.predict(x_test[:10])


# In[58]:


y_test[:10]


# Pour les 10 premières images de test, les estimations sont excellentes ! 

# ## Performances

# Nous pouvons maintenant évaluer le réseau pour toutes les images de test

# In[78]:


y_pred = mlp.predict(x_test)


# Puis rechercher les images pour lesquelles le réseau s'est trompé : 

# In[60]:


error = (y_pred != y_test)


# Voici le calcul du taux d'erreur :

# In[61]:


import numpy as np
np.sum(error) / len(y_test)


# environ 11%, ce qui veut dire que 89% des prédictions sont correctes: 

# Nous pouvons enfin sélectionner les mauvaises prédictions pour les afficher :

# In[81]:


x_error = x_test[error].reshape((-1, 8,8))
y_error = y_test[error]
y_pred_error = y_pred[error]
i = 1
plt.imshow(x_error[i],cmap='binary')
plt.title(f'cible: {y_error[i]}, prediction: {y_pred_error[i]}')
plt.axis('off')
plt.show()


# Comme on peut le voir, il est difficile de classifier ces images, même pour un humain.
# 
# Pour de meilleures performances, il faudrait utiliser des images de plus haute résolution et un réseau de neurones plus complexe, comme un réseau convolutionnel.
#