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.
#