Académique Documents
Professionnel Documents
Culture Documents
Le jeu de données CALTECH-101 est un jeu de données de 101 catégories d'objets avec 40 à 800 images par
classe. L'objectif de l'ensemble de données est de former un modèle capable de prédire la classe cible.
La raison pour laquelle nous utilisons un sous-ensemble de l'ensemble de données est que vous pouvez
facilement suivre cet exemple et former le réseau à partir de zéro, même si vous n'avez pas de GPU.
http://www.vision.caltech.edu/Image_Datasets/Caltech101/
Une fois désarchivé, vous devez retrouvez les 101 catégories d'images:
import matplotlib
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.regularizers import l2
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import cv2
import os
4.3 StridedNet
Le CNN que nous utiliserons aujourd'hui, "StridedNet" qui a trois caractéristiques importantes :
La première couche CONV utilise des filtres 7×7 mais toutes les autres couches du réseau utilisent des
filtres 3×3 (similaires à VGG)
L'algorithme de distribution normale est utilisé pour initialiser tous les poids dans le réseau
(Régularisation L2)
4.3.1 Construisez une fonction build qui prend 6 paramètres:
dropout_1: 0.25
dropout_2: 0.25
dropout_3: 0.25
dropout_4: 0.5
# stack two more CONV layers, keeping the size of each filter
# as 3x3 but increasing to 64 total learned filters
# fully-connected layer
return model
4.4 Préparation base de données
Initialiser le jeu d'étiquettes à partir du jeu de données CALTECH-101 qu'on va former notre réseau sur.
data sera une liste pour contenir nos images sur lesquelles notre réseau sera formé.
labels sera Une liste pour contenir nos étiquettes de classe qui correspondent aux données.
Hint:
Et finalement, chaque élément dans la liste date doit être une image de 96 pixels 96 pixels
# A compléter
Conversion des données en un tableau NumPy avec chaque image mise à l'échelle dans la plage [0, 1]
et binariser nos étiquettes en « One-Hot Encoding »
### START CODE HERE ###
Compiler le modèle avec avec l'optimiseur Adam et la décroissance du taux d'apprentissage, notre
Imprimer le résultat
predictions = model.predict(x=x_test, batch_size=32)
print(classification_report(y_test.argmax(axis=1), predictions.argmax(axis=1),
target_names=lb.classes_))
N = 50
plt.figure()
plt.plot(np.arange(0, N), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, N), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, N), H.history["acc"], label="train_acc")
plt.plot(np.arange(0, N), H.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy on Dataset")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.show()
En enspirant du chapitre 4.4 du cours, créer un modèle à partir de la structure du modèle ResNet-50,
en l'adaptant avec notre problème actuel.
4.6.5 Ajouter les couhches de sorties, Fully Connected. Compiler et entraîner le modèle
“
Attention, le temps d'exécution va probablement dépasser 1h.
### START CODE HERE ###
Epoch 1/50
53/53 [==============================] - 115s 2s/step - loss: 1.1691 - accuracy:
0.5407 - val_loss: 1.3906 - val_accuracy: 0.1919
Epoch 2/50
53/53 [==============================] - 124s 2s/step - loss: 0.9121 - accuracy:
0.6471 - val_loss: 1.8136 - val_accuracy: 0.1919
...
...
...
Epoch 50/50
53/53 [==============================] - 119s 2s/step - loss: 0.0761 - accuracy:
0.9737 - val_loss: 0.1888 - val_accuracy: 0.9472
4.7 Conclusion
5 Rétropropagation dans les réseaux de neurones convolutifs
5.1 Introduction
Dans les cadres de Deep Learning modernes, vous n'avez qu'à implémenter la passe avant(Forward Pass), et
le cadre prend en charge la passe en arrière, de sorte que la plupart des ingénieurs d'apprentissage en
profondeur n'ont pas besoin de se soucier des détails de la passe en arrière. Le passage en arrière pour les
réseaux convolutifs est compliqué. L'objective de cette partie du séminaire est donc de vous montrer à quoi
ressemble la rétropropagation dans un réseau convolutif.
Dans le cours vous avez implémenté un réseau de neurones simple (entièrement connecté), vous avez
utilisé la rétropropagation pour calculer les dérivées par rapport au coût de mise à jour des paramètres. De
même, dans les réseaux de neurones convolutifs, vous pouvez calculer les dérivées par rapport au coût afin
de mettre à jour les paramètres. Les équations de rétropropagation ne sont pas triviales et nous ne les
avons pas dérivées en cours, mais nous les avons brièvement présentées ci-dessous.
5.2.1 Calcul de dA
Voici la formule de calcul de par rapport au coût d'un certain filtre et d'un exemple d'apprentissage
donné :
Où est un filtre et est un scalaire correspondant au gradient du coût par rapport à la sortie de la
couche de conv Z à la h ième ligne et à la w ième colonne.
Dans le code, à l'intérieur des boucles for appropriées, cette formule se traduit par :
5.2.2 Calcul de dW
5.2.3 Calcul de db
Dans le code, à l'intérieur des boucles for appropriées, cette formule se traduit par :
db[:,:,:,c] += dZ[i,h,w,c]
Implémentez la fonction conv_backward ci-dessous. Vous devez additionner tous les exemples
d'entraînement, les filtres, les hauteurs et les largeurs. Vous devez ensuite calculer les dérivées en utilisant
les formules 1, 2 et 3 ci-dessus.
Arguments:
dZ -- gradient of the cost with respect to the output of the conv layer (Z),
numpy array of shape (m, n_H, n_W, n_C)
cache -- cache of values needed for the conv_backward(), output of
conv_forward()
Returns:
dA_prev -- gradient of the cost with respect to the input of the conv layer
(A_prev),
numpy array of shape (m, n_H_prev, n_W_prev, n_C_prev)
dW -- gradient of the cost with respect to the weights of the conv layer (W)
numpy array of shape (f, f, n_C_prev, n_C)
db -- gradient of the cost with respect to the biases of the conv layer (b)
numpy array of shape (1, 1, 1, n_C)
"""
vert_end = vert_start + f
horiz_start = w * stride
horiz_end = horiz_start + f
# où Z et cache_conv sont les deux paramètres que vous avez déini pendant le
chapitre 04 du module 04.
np.random.seed(1)
dA, dW, db = conv_backward(Z, cache_conv)
print("dA_mean =", np.mean(dA))
print("dW_mean =", np.mean(dW))
print("db_mean =", np.mean(db))
Expected Output:
dA_mean = 2.6497022199743
dW_mean = 52.66658438709006
db_mean = 5376.827563159339
Ensuite, implémentons le passage en arrière pour la couche de pooling, en commençant par la couche MAX-
POOL. Même si une couche de pooling n'a pas de paramètres pour la mise à jour de rétropropagation, vous
devez toujours rétro-propager le dégradé à travers la couche de pooling afin de calculer les gradients pour
les couches antérieures à la couche de pooling.
Avant de sauter dans la rétropropagation de la couche de Max_pooling, vous allez créer une fonction
d'assistance appelée create_mask_from_window() qui effectue les opérations suivantes :
Comme vous pouvez le voir, cette fonction crée une matrice "masque" qui garde une trace de l'endroit où se
trouve le maximum de la matrice. Vrai (1) (true) indique la position du maximum dans X, les autres entrées
sont Faux (0) (false). Vous verrez plus tard que la passe arrière pour la Average pooling sera similaire à celle-
ci mais en utilisant un masque différent.
5.3.1.1 Implémentez create_mask_from_window().
Note: Ici, vous n'avez pas besoin de considérer les cas où il y a plusieurs maxima dans une matrice.
def create_mask_from_window(x):
"""
Creates a mask from an input matrix x, to identify the max entry of x.
Arguments:
x -- Array of shape (f, f)
Returns:
mask -- Array of the same shape as window, contains a True at the position
corresponding to the max entry of x.
"""
return mask
np.random.seed(1)
x = np.random.randn(2,3)
mask = create_mask_from_window(x)
print('x = ', x)
print("mask = ", mask)
Expected Output:
Dans la Max pooling, pour chaque fenêtre d'entrée, toute "l'influence" sur la sortie provenait d'une seule
valeur d'entrée - la valeur max. Dans la Average pooling, chaque élément de la fenêtre d'entrée a une
influence égale sur la sortie. Donc, pour implémenter la rétropropagation, vous allez maintenant
implémenter une fonction d'assistance qui reflète cela.
Par exemple, si nous avons fait une average pooling dans la passe avant en utilisant un filtre 2x2, alors le
masque que vous utiliserez pour la passe arrière ressemblera à :
Cela implique que chaque position dans la matrice contribue également à la sortie car dans la passe
avant, nous avons pris une moyenne.
5.3.2.1 Implémentez la fonction ci-dessous pour distribuer également une valeur dz à travers une matrice
de forme dimensionnelle.
Arguments:
dz -- input scalar
shape -- the shape (n_H, n_W) of the output matrix for which we want to
distribute the value of dz
Returns:
a -- Array of size (n_H, n_W) for which we distributed the value of dz
"""
# Create a matrix where every entry is the "average" value (≈1 line)
a = np.ones(shape) * average
### END CODE HERE ###
return a
a = distribute_value(2, (2,2))
print('distributed value =', a)
Expected Output:
Implémentez la fonction pool_backward dans les deux modes ("max" et "average"). Vous utiliserez à
nouveau 4 boucles for (itération sur les exemples d'entraînement, la hauteur, la largeur et les canaux). Vous
devez utiliser une instruction if/elif pour voir si le mode est égal à 'max' ou 'average'. S'il est égal à
"moyenne", vous devez utiliser la fonction distribu_value() que vous avez implémentée ci-dessus pour créer
une matrice de la même forme que a_slice. Sinon, le mode est égal à 'max', et vous allez créer un masque
avec create_mask_from_window() et le multiplier par la valeur correspondante de dZ.
Arguments:
dA -- gradient of cost with respect to the output of the pooling layer, same
shape as A
cache -- cache output from the forward pass of the pooling layer, contains the
layer's input and hparameters
mode -- the pooling mode you would like to use, defined as a string ("max" or
"average")
Returns:
dA_prev -- gradient of cost with respect to the input of the pooling layer,
same shape as A_prev
"""
# Retrieve dimensions from A_prev's shape and dA's shape (≈2 lines)
m, n_H_prev, n_W_prev, n_C_prev = A_prev.shape
m, n_H, n_W, n_C = dA.shape
return dA_prev
np.random.seed(1)
A_prev = np.random.randn(5, 5, 3, 2)
hparameters = {"stride" : 1, "f": 2}
dA = np.random.randn(5, 4, 2, 2)
Expected Output:
mode = max
mean of dA = 0.14571390272918056
dA_prev[1,1] = [[ 0. 0. ]
[ 5.05844394 -1.68282702]
[ 0. 0. ]]
mode = average
mean of dA = 0.14571390272918056
dA_prev[1,1] = [[ 0.08485462 0.2787552 ]
[ 1.26461098 -0.25749373]
[ 1.17975636 -0.53624893]]