Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • daconcea/fidle
  • bossardl/fidle
  • Julie.Remenant/fidle
  • abijolao/fidle
  • monsimau/fidle
  • karkars/fidle
  • guilgautier/fidle
  • cailletr/fidle
  • talks/fidle
9 results
Show changes
Showing
with 1810 additions and 2283 deletions
# ------------------------------------------------------------------
# _____ _ _ _
# | ___(_) __| | | ___
# | |_ | |/ _` | |/ _ \
# | _| | | (_| | | __/
# |_| |_|\__,_|_|\___| Dataset reader
# ------------------------------------------------------------------
# Formation Introduction au Deep Learning (FIDLE) - CNRS/MIAI/UGA
# ------------------------------------------------------------------
# JL Parouty 2023
import h5py
import os
import fidle
def read_dataset(enhanced_dir, dataset_name, scale=1):
'''
Reads h5 dataset
Args:
filename : datasets filename
dataset_name : dataset name, without .h5
Returns:
x_train,y_train, x_test,y_test data, x_meta,y_meta
'''
# ---- Read dataset
#
chrono=fidle.Chrono()
chrono.start()
filename = f'{enhanced_dir}/{dataset_name}.h5'
with h5py.File(filename,'r') as f:
x_train = f['x_train'][:]
y_train = f['y_train'][:]
x_test = f['x_test'][:]
y_test = f['y_test'][:]
x_meta = f['x_meta'][:]
y_meta = f['y_meta'][:]
# ---- Rescale
#
print('Original shape :', x_train.shape, y_train.shape)
x_train,y_train, x_test,y_test = fidle.utils.rescale_dataset(x_train,y_train,x_test,y_test, scale=scale)
print('Rescaled shape :', x_train.shape, y_train.shape)
# ---- Shuffle
#
x_train,y_train=fidle.utils.shuffle_np_dataset(x_train,y_train)
# ---- done
#
duration = chrono.get_delay()
size = fidle.utils.hsize(os.path.getsize(filename))
print(f'\nDataset "{dataset_name}" is loaded and shuffled. ({size} in {duration})')
return x_train,y_train, x_test,y_test, x_meta,y_meta
print('Module my_loader loaded.')
\ No newline at end of file
# ------------------------------------------------------------------
# _____ _ _ _
# | ___(_) __| | | ___
# | |_ | |/ _` | |/ _ \
# | _| | | (_| | | __/
# |_| |_|\__,_|_|\___| Some nice models
# ------------------------------------------------------------------
# Formation Introduction au Deep Learning (FIDLE) - CNRS/MIAI/UGA
# ------------------------------------------------------------------
# JL Parouty 2023
import keras
# ------------------------------------------------------------------
# -- A simple model, for 24x24 or 48x48 images --
# ------------------------------------------------------------------
#
def get_model_01(lx,ly,lz):
model = keras.models.Sequential()
model.add( keras.layers.Input((lx,ly,lz)) )
model.add( keras.layers.Conv2D(96, (3,3), activation='relu' ))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Dropout(0.2))
model.add( keras.layers.Conv2D(192, (3, 3), activation='relu'))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Dropout(0.2))
model.add( keras.layers.Flatten())
model.add( keras.layers.Dense(1500, activation='relu'))
model.add( keras.layers.Dropout(0.5))
model.add( keras.layers.Dense(43, activation='softmax'))
return model
# ------------------------------------------------------------------
# -- A more sophisticated model, for 48x48 images --
# ------------------------------------------------------------------
#
def get_model_02(lx,ly,lz):
model = keras.models.Sequential()
model.add( keras.layers.Input((lx,ly,lz)) )
model.add( keras.layers.Conv2D(32, (3,3), activation='relu'))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Dropout(0.5))
model.add( keras.layers.Conv2D(64, (3, 3), activation='relu'))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Dropout(0.5))
model.add( keras.layers.Conv2D(128, (3, 3), activation='relu'))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Dropout(0.5))
model.add( keras.layers.Conv2D(256, (3, 3), activation='relu'))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Dropout(0.5))
model.add( keras.layers.Flatten())
model.add( keras.layers.Dense(1152, activation='relu'))
model.add( keras.layers.Dropout(0.5))
model.add( keras.layers.Dense(43, activation='softmax'))
return model
def get_model(name, lx,ly,lz):
'''
Return a model given by name
Args:
f_name : function name to retreive model
lxly,lz : inpuy shape
Returns:
model
'''
if name=='model_01' : return get_model_01(lx,ly,lz)
if name=='model_02' : return get_model_01(lx,ly,lz)
print('*** Model not found : ', name)
return None
# A More fun version ;-)
def get_model2(name, lx,ly,lz):
get_model=globals()['get_'+name]
model=get_model(lx,ly,lz)
return model
print('Module my_models loaded.')
\ No newline at end of file
# ------------------------------------------------------------------
# _____ _ _ _
# | ___(_) __| | | ___
# | |_ | |/ _` | |/ _ \
# | _| | | (_| | | __/
# |_| |_|\__,_|_|\___| A small traffic sign classifier
# ------------------------------------------------------------------
# Formation Introduction au Deep Learning (FIDLE) - CNRS/MIAI/UGA
# ------------------------------------------------------------------
# JL Parouty 2023
import numpy as np
import matplotlib.pyplot as plt
import fidle
def show_prediction( prediction, x, y, x_meta ):
# ---- A prediction is just the output layer
#
fidle.utils.subtitle("Output layer from model is (x100) :")
with np.printoptions(precision=2, suppress=True, linewidth=95):
print(prediction*100)
# ---- Graphic visualisation
#
fidle.utils.subtitle("Graphically :")
plt.figure(figsize=(8,2))
plt.bar(range(43), prediction[0], align='center', alpha=0.5)
plt.ylabel('Probability')
plt.ylim((0,1))
plt.xlabel('Class')
plt.title('Trafic Sign prediction')
fidle.scrawler.save_fig('05-prediction-proba')
plt.show()
# ---- Predict class
#
p = np.argmax(prediction)
# ---- Show result
#
fidle.utils.subtitle('In pictures :')
print("\nThe image : Prediction : Real stuff:")
fidle.scrawler.images([x,x_meta[p], x_meta[y]], [p,p,y], range(3), columns=3, x_size=1.5, y_size=1.5, save_as='06-prediction-images')
if p==y:
print("YEEES ! that's right!")
else:
print("oups, that's wrong ;-(")
\ No newline at end of file
source diff could not be displayed: it is too large. Options to address this: view the blob.
source diff could not be displayed: it is too large. Options to address this: view the blob.
%% Cell type:markdown id: tags:
German Traffic Sign Recognition Benchmark (GTSRB)
=================================================
---
Introduction au Deep Learning (IDLE) - S. Aria, E. Maldonado, JL. Parouty - CNRS/SARI/DEVLOG - 2020
## Episode 2 : First Convolutions
Our main steps:
- Read dataset
- Build a model
- Train the model
- Model evaluation
## 1/ Import and init
%% Cell type:code id: tags:
``` python
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.callbacks import TensorBoard
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import time
import idle.pwk as ooo
ooo.init()
```
%% Output
IDLE 2020 - Practical Work Module
Version : 0.1.1
Run time : Monday 6 January 2020, 14:35:14
Matplotlib style : idle/talk.mplstyle
TensorFlow version : 2.0.0
Keras version : 2.2.4-tf
%% Cell type:markdown id: tags:
## 2/ Reload dataset (RGB25)
Dataset is one of the saved dataset: RGB25, RGB35, L25, L35, etc.
First of all, we're going to use the dataset : **L25**
(with a GPU, it only takes 35'' compared to more than 5' with a CPU !)
%% Cell type:code id: tags:
``` python
%%time
dataset ='RGB25'
img_lx = 25
img_ly = 25
img_lz = 3
# ---- Read dataset
x_train = np.load('./data/{}/x_train.npy'.format(dataset))
y_train = np.load('./data/{}/y_train.npy'.format(dataset))
x_test = np.load('./data/{}/x_test.npy'.format(dataset))
y_test = np.load('./data/{}/y_test.npy'.format(dataset))
# ---- Reshape data
x_train = x_train.reshape( x_train.shape[0], img_lx, img_ly, img_lz)
x_test = x_test.reshape( x_test.shape[0], img_lx, img_ly, img_lz)
input_shape = (img_lx, img_ly, img_lz)
print("Dataset loaded, size={:.1f} Mo\n".format(ooo.get_directory_size('./data/'+dataset)))
```
%% Output
Dataset loaded, size=742.0 Mo
CPU times: user 0 ns, sys: 708 ms, total: 708 ms
Wall time: 6.07 s
%% Cell type:markdown id: tags:
## 3/ Have a look to the dataset
Note: Data must be reshape for matplotlib
%% Cell type:code id: tags:
``` python
print("x_train : ", x_train.shape)
print("y_train : ", y_train.shape)
print("x_test : ", x_test.shape)
print("y_test : ", y_test.shape)
if img_lz>1:
ooo.plot_images(x_train.reshape(-1,img_lx,img_ly,img_lz), y_train, range(6), columns=3, x_size=4, y_size=3)
ooo.plot_images(x_train.reshape(-1,img_lx,img_ly,img_lz), y_train, range(36), columns=12, x_size=1, y_size=1)
else:
ooo.plot_images(x_train.reshape(-1,img_lx,img_ly), y_train, range(6), columns=6, x_size=2, y_size=2)
ooo.plot_images(x_train.reshape(-1,img_lx,img_ly), y_train, range(36), columns=12, x_size=1, y_size=1)
```
%% Output
x_train : (39209, 25, 25, 3)
y_train : (39209,)
x_test : (12630, 25, 25, 3)
y_test : (12630,)
%% Cell type:markdown id: tags:
## 4/ Create model
%% Cell type:code id: tags:
``` python
batch_size = 128
num_classes = 43
epochs = 5
```
%% Cell type:code id: tags:
``` python
keras.backend.clear_session()
model = keras.models.Sequential()
model.add( keras.layers.Conv2D(96, (3,3), activation='relu', input_shape=(img_lx, img_ly, img_lz)))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Conv2D(192, (3, 3), activation='relu'))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Flatten())
model.add( keras.layers.Dense(3072, activation='relu'))
model.add( keras.layers.Dense(500, activation='relu'))
model.add( keras.layers.Dense(43, activation='softmax'))
model.summary()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
```
%% Output
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 23, 23, 96) 2688
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 11, 11, 96) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 9, 9, 192) 166080
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 4, 4, 192) 0
_________________________________________________________________
flatten (Flatten) (None, 3072) 0
_________________________________________________________________
dense (Dense) (None, 3072) 9440256
_________________________________________________________________
dense_1 (Dense) (None, 500) 1536500
_________________________________________________________________
dense_2 (Dense) (None, 43) 21543
=================================================================
Total params: 11,167,067
Trainable params: 11,167,067
Non-trainable params: 0
_________________________________________________________________
%% Cell type:markdown id: tags:
## 5/ Run model
%% Cell type:code id: tags:
``` python
%%time
history = model.fit( x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))
```
%% Output
Train on 39209 samples, validate on 12630 samples
Epoch 1/5
39209/39209 [==============================] - 18s 468us/sample - loss: 0.9595 - accuracy: 0.7357 - val_loss: 0.4068 - val_accuracy: 0.9015
Epoch 2/5
39209/39209 [==============================] - 16s 417us/sample - loss: 0.0876 - accuracy: 0.9770 - val_loss: 0.3472 - val_accuracy: 0.9190
Epoch 3/5
39209/39209 [==============================] - 16s 409us/sample - loss: 0.0375 - accuracy: 0.9900 - val_loss: 0.2917 - val_accuracy: 0.9363
Epoch 4/5
39209/39209 [==============================] - 17s 421us/sample - loss: 0.0263 - accuracy: 0.9928 - val_loss: 0.3384 - val_accuracy: 0.9284
Epoch 5/5
39209/39209 [==============================] - 17s 421us/sample - loss: 0.0237 - accuracy: 0.9929 - val_loss: 0.3022 - val_accuracy: 0.9433
CPU times: user 16min 31s, sys: 1min 27s, total: 17min 59s
Wall time: 1min 23s
%% Cell type:markdown id: tags:
## 6/ Evaluation
%% Cell type:code id: tags:
``` python
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss : {:5.4f}'.format(score[0]))
print('Test accuracy : {:5.4f}'.format(score[1]))
```
%% Output
Test loss : 0.3022
Test accuracy : 0.9433
%% Cell type:markdown id: tags:
---
### Results :
```
L25 : size=250 Mo 93.15%
RGB25 : size=740 Mo 94.33%
...
```
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
German Traffic Sign Recognition Benchmark (GTSRB)
=================================================
---
Introduction au Deep Learning (IDLE) - S. Aria, E. Maldonado, JL. Parouty - CNRS/SARI/DEVLOG - 2020
## Episode 3 : Tracking and visualizing
Our main steps:
- Monitoring and understanding our model training
- Analyze the results
- Improving our model
- Add recovery points
## 1/ Import and init
%% Cell type:code id: tags:
``` python
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.callbacks import TensorBoard
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import time, random
from importlib import reload
import idle.pwk as ooo
ooo.init()
```
%% Output
IDLE 2020 - Practical Work Module
Version : 0.1.1
Run time : Wednesday 8 January 2020, 11:31:25
Matplotlib style : idle/talk.mplstyle
TensorFlow version : 2.0.0
Keras version : 2.2.4-tf
%% Cell type:markdown id: tags:
## 2/ Reload dataset
Dataset is one of the saved dataset: RGB25, RGB35, L25, L35, etc.
First of all, we're going to use the dataset : **L25**
(with a GPU, it only takes 35'' compared to more than 5' with a CPU !)
%% Cell type:code id: tags:
``` python
%%time
dataset ='L25'
img_lx = 25
img_ly = 25
img_lz = 1
# ---- Read dataset
x_train = np.load('./data/{}/x_train.npy'.format(dataset))
y_train = np.load('./data/{}/y_train.npy'.format(dataset))
x_test = np.load('./data/{}/x_test.npy'.format(dataset))
y_test = np.load('./data/{}/y_test.npy'.format(dataset))
# ---- Reshape data
x_train = x_train.reshape( x_train.shape[0], img_lx, img_ly, img_lz)
x_test = x_test.reshape( x_test.shape[0], img_lx, img_ly, img_lz)
input_shape = (img_lx, img_ly, img_lz)
print("Dataset loaded, size={:.1f} Mo\n".format(ooo.get_directory_size('./data/'+dataset)))
```
%% Output
Dataset loaded, size=247.6 Mo
CPU times: user 0 ns, sys: 328 ms, total: 328 ms
Wall time: 523 ms
%% Cell type:markdown id: tags:
## 3/ Have a look to the dataset
Note: Data must be reshape for matplotlib
%% Cell type:code id: tags:
``` python
print("x_train : ", x_train.shape)
print("y_train : ", y_train.shape)
print("x_test : ", x_test.shape)
print("y_test : ", y_test.shape)
if img_lz>1:
ooo.plot_images(x_train.reshape(-1,img_lx,img_ly,img_lz), y_train, range(6), columns=3, x_size=4, y_size=3)
ooo.plot_images(x_train.reshape(-1,img_lx,img_ly,img_lz), y_train, range(36), columns=12, x_size=1, y_size=1)
else:
ooo.plot_images(x_train.reshape(-1,img_lx,img_ly), y_train, range(6), columns=6, x_size=2, y_size=2)
ooo.plot_images(x_train.reshape(-1,img_lx,img_ly), y_train, range(36), columns=12, x_size=1, y_size=1)
```
%% Output
x_train : (39209, 25, 25, 1)
y_train : (39209,)
x_test : (12630, 25, 25, 1)
y_test : (12630,)
%% Cell type:markdown id: tags:
## 4/ Create model
%% Cell type:code id: tags:
``` python
batch_size = 64
num_classes = 43
epochs = 20
```
%% Cell type:code id: tags:
``` python
tf.keras.backend.clear_session()
model = keras.models.Sequential()
model.add( keras.layers.Conv2D(96, (3,3), activation='relu', input_shape=(img_lx, img_ly, img_lz)))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Conv2D(192, (3, 3), activation='relu'))
model.add( keras.layers.MaxPooling2D((2, 2)))
model.add( keras.layers.Flatten())
model.add( keras.layers.Dense(3072, activation='relu'))
model.add( keras.layers.Dense(500, activation='relu'))
model.add( keras.layers.Dense(500, activation='relu'))
model.add( keras.layers.Dense(43, activation='softmax'))
model.summary()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
```
%% Output
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 23, 23, 96) 960
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 11, 11, 96) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 9, 9, 192) 166080
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 4, 4, 192) 0
_________________________________________________________________
flatten (Flatten) (None, 3072) 0
_________________________________________________________________
dense (Dense) (None, 3072) 9440256
_________________________________________________________________
dense_1 (Dense) (None, 500) 1536500
_________________________________________________________________
dense_2 (Dense) (None, 500) 250500
_________________________________________________________________
dense_3 (Dense) (None, 43) 21543
=================================================================
Total params: 11,415,839
Trainable params: 11,415,839
Non-trainable params: 0
_________________________________________________________________
%% Cell type:markdown id: tags:
## 5/ Add callbacks
Nous allons ajouter 2 callbacks :
- **TensorBoard**
Training logs, which can be visualised with Tensorboard.
`#tensorboard --logdir ./run/logs`
IMPORTANT : Relancer tensorboard à chaque run
- **Model backup**
It is possible to save the model each xx epoch or at each improvement.
The model can be saved completely or partially (weight).
For full format, we can use HDF5 format.
%% Cell type:code id: tags:
``` python
# To clean logs and saved model, run this cell
!/bin/rm -r ./run/logs ./run/models
!/bin/ls -l ./run
```
%% Output
total 0
%% Cell type:code id: tags:
``` python
ooo.mkdir('./run/models')
ooo.mkdir('./run/logs')
# ---- Callback tensorboard
log_dir = "./run/logs/tb_" + ooo.tag_now()
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
# ---- Callback ModelCheckpoint - Save best model
save_dir = "./run/models/best-model.h5"
bestmodel_callback = tf.keras.callbacks.ModelCheckpoint(filepath=save_dir, verbose=0, monitor='accuracy', save_best_only=True)
# ---- Callback ModelCheckpoint - Save model each epochs
save_dir = "./run/models/model-{epoch:04d}.h5"
savemodel_callback = tf.keras.callbacks.ModelCheckpoint(filepath=save_dir, verbose=0, save_freq=2000*5)
```
%% Cell type:markdown id: tags:
## 5/ Run model
%% Cell type:code id: tags:
``` python
%%time
history = model.fit( x_train[:2000], y_train[:2000],
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test[:200], y_test[:200]),
callbacks=[tensorboard_callback, bestmodel_callback, savemodel_callback] )
model.save('./run/models/last-model.h5')
```
%% Output
Train on 2000 samples, validate on 200 samples
Epoch 1/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 3.6179 - accuracy: 0.0595 - val_loss: 3.5203 - val_accuracy: 0.0550
Epoch 2/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 3.4567 - accuracy: 0.0600 - val_loss: 3.4113 - val_accuracy: 0.0750
Epoch 3/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 2.9967 - accuracy: 0.2045 - val_loss: 2.7160 - val_accuracy: 0.2450
Epoch 4/20
2000/2000 [==============================] - 5s 2ms/sample - loss: 2.1231 - accuracy: 0.3710 - val_loss: 2.2007 - val_accuracy: 0.3550
Epoch 5/20
2000/2000 [==============================] - 5s 2ms/sample - loss: 1.5418 - accuracy: 0.5290 - val_loss: 1.6167 - val_accuracy: 0.5050
Epoch 6/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 1.1403 - accuracy: 0.6315 - val_loss: 1.6735 - val_accuracy: 0.5100
Epoch 7/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 0.8817 - accuracy: 0.7070 - val_loss: 1.1985 - val_accuracy: 0.6300
Epoch 8/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 0.6063 - accuracy: 0.8005 - val_loss: 1.1051 - val_accuracy: 0.7050
Epoch 9/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 0.4553 - accuracy: 0.8540 - val_loss: 1.1474 - val_accuracy: 0.6850
Epoch 10/20
2000/2000 [==============================] - 6s 3ms/sample - loss: 0.3155 - accuracy: 0.9005 - val_loss: 0.9822 - val_accuracy: 0.7500
Epoch 11/20
2000/2000 [==============================] - 6s 3ms/sample - loss: 0.2466 - accuracy: 0.9220 - val_loss: 0.9238 - val_accuracy: 0.7550
Epoch 12/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 0.1964 - accuracy: 0.9365 - val_loss: 1.0252 - val_accuracy: 0.7600
Epoch 13/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 0.1690 - accuracy: 0.9445 - val_loss: 0.9506 - val_accuracy: 0.7550
Epoch 14/20
2000/2000 [==============================] - 6s 3ms/sample - loss: 0.1053 - accuracy: 0.9690 - val_loss: 1.1243 - val_accuracy: 0.7300
Epoch 15/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 0.1054 - accuracy: 0.9730 - val_loss: 0.8967 - val_accuracy: 0.8000
Epoch 16/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 0.1285 - accuracy: 0.9620 - val_loss: 0.9004 - val_accuracy: 0.7850
Epoch 17/20
2000/2000 [==============================] - 6s 3ms/sample - loss: 0.0744 - accuracy: 0.9805 - val_loss: 0.8287 - val_accuracy: 0.8200
Epoch 18/20
2000/2000 [==============================] - 6s 3ms/sample - loss: 0.0400 - accuracy: 0.9915 - val_loss: 1.0527 - val_accuracy: 0.8150
Epoch 19/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 0.0618 - accuracy: 0.9805 - val_loss: 0.9737 - val_accuracy: 0.8000
Epoch 20/20
2000/2000 [==============================] - 5s 3ms/sample - loss: 0.0806 - accuracy: 0.9755 - val_loss: 1.1634 - val_accuracy: 0.8050
CPU times: user 6min 23s, sys: 2min 26s, total: 8min 49s
Wall time: 1min 47s
%% Cell type:markdown id: tags:
## 6/ History
The return of model.fit() returns us the learning history
%% Cell type:code id: tags:
``` python
ooo.plot_history(history)
```
%% Output
%% Cell type:markdown id: tags:
## 7/ Restore and evaluate
List of saved models :
%% Cell type:code id: tags:
``` python
!find ./run/models/
```
%% Output
./run/models/
./run/models/best-model.h5
./run/models/last-model.h5
%% Cell type:markdown id: tags:
Restore current model :
%% Cell type:code id: tags:
``` python
best_model = tf.keras.models.load_model('./run/models/best-model.h5')
# best_model.summary()
print("Loaded.")
```
%% Output
Loaded.
%% Cell type:markdown id: tags:
Evaluate it :
%% Cell type:code id: tags:
``` python
score = best_model.evaluate(x_test, y_test, verbose=0)
print('Test loss : {:5.4f}'.format(score[0]))
print('Test accuracy : {:5.4f}'.format(score[1]))
```
%% Output
Test loss : 0.8608
Test accuracy : 0.8466
%% Cell type:markdown id: tags:
Make a prediction :
%% Cell type:code id: tags:
``` python
i = random.randint(1,len(x_test))
x,y = x_test[i-1:i], y_test[i]
predictions = best_model.predict(x)
with np.printoptions(precision=2, suppress=True, linewidth=95):
print(predictions*100)
plt.figure(figsize=(8,8))
plt.barh(range(43), predictions[0], align='center', alpha=0.5)
plt.xlabel('Probability')
plt.ylabel('Class')
plt.title('Trafic Sign prediction')
plt.show()
```
%% Output
[[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 100. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0.]]
%% Cell type:markdown id: tags:
---
### A faire :
- Restauration
- Reprise apprentissage
- Evaluation
- Matrice de confusion
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
German Traffic Sign Recognition Benchmark (GTSRB)
=================================================
---
Introduction au Deep Learning (IDLE)
S. Aria, E. Maldonado, JL. Parouty
CNRS/SARI/DEVLOG - 2020
Objectives of this practical work
---------------------------------
Traffic sign classification with **CNN**, using Tensorflow and **Keras**
Prerequisite
------------
Environment, with the following packages :
- Python 3.6
- numpy
- Matplotlib
- Tensorflow 2.0
- scikit-image
You can create it from the `environment.yml` file :
```
# conda env create -f environment.yml
```
About the dataset
-----------------
Name : [German Traffic Sign Recognition Benchmark (GTSRB)](http://benchmark.ini.rub.de/?section=gtsrb)
Available [here](https://sid.erda.dk/public/archives/daaeac0d7ce1152aea9b61d9f1e19370/published-archive.html)
or on **[kaggle](https://www.kaggle.com/meowmeowmeowmeowmeow/gtsrb-german-traffic-sign)**
A nice example from : [Alex Staravoitau](https://navoshta.com/traffic-signs-classification/)
In few words :
- Images : Variable dimensions, rgb
- Train set : 39209 images
- Test set : 12630 images
- Classes : 0 to 42
Episodes
--------
**[01 - Preparation of data](01-Preparation-of-data.ipynb)**
- Understanding the dataset
- Preparing and formatting data
- Organize and backup data
**[02 - First convolutions](02-First-convolutions.ipynb)**
- Read dataset
- Build a model
- Train the model
- Model evaluation
%% Cell type:code id: tags:
``` python
```
German Traffic Sign Recognition Benchmark (GTSRB)
=================================================
---
FIDLE - Formation Introduction au Deep Learning
1/ Objectives
----------
Traffic sign classification with **CNN**, using Tensorflow and **Keras**
2/ About the dataset
-----------------
Name : [German Traffic Sign Recognition Benchmark (GTSRB)](http://benchmark.ini.rub.de/?section=gtsrb)
Available [here](https://sid.erda.dk/public/archives/daaeac0d7ce1152aea9b61d9f1e19370/published-archive.html)
or on **[kaggle](https://www.kaggle.com/meowmeowmeowmeowmeow/gtsrb-german-traffic-sign)**
A nice example from : [Alex Staravoitau](https://navoshta.com/traffic-signs-classification/)
In few words :
- Images : Variable dimensions, rgb
- Train set : 39209 images
- Test set : 12630 images
- Classes : 0 to 42
3/ Episodes
--------
01 - Dataset preparation
- Undestand the data
02 - First convolutions
7bb54a6fdefd74be4d659322f77a90cbba9757ec
\ No newline at end of file
VERSION='0.1a'
\ No newline at end of file
# ==================================================================
# ____ _ _ _ __ __ _
# | _ \ _ __ __ _ ___| |_(_) ___ __ _| | \ \ / /__ _ __| | __
# | |_) | '__/ _` |/ __| __| |/ __/ _` | | \ \ /\ / / _ \| '__| |/ /
# | __/| | | (_| | (__| |_| | (_| (_| | | \ V V / (_) | | | <
# |_| |_| \__,_|\___|\__|_|\___\__,_|_| \_/\_/ \___/|_| |_|\_\
# module pwk
# ==================================================================
# A simple module to host some common functions for practical work
# pjluc 2019
import os
import glob
from datetime import datetime
import itertools
import datetime
import math
import numpy as np
import tensorflow as tf
from tensorflow import keras
import matplotlib
import matplotlib.pyplot as plt
VERSION='0.1.1'
# -------------------------------------------------------------
# init_all
# -------------------------------------------------------------
#
def init(mplstyle='idle/talk.mplstyle'):
global VERSION
# ---- matplotlib
matplotlib.style.use(mplstyle)
# ---- Hello world
now = datetime.datetime.now()
print('IDLE 2020 - Practical Work Module')
print(' Version :', VERSION)
print(' Run time : {}'.format(now.strftime("%A %-d %B %Y, %H:%M:%S")))
print(' Matplotlib style :', mplstyle)
print(' TensorFlow version :',tf.__version__)
print(' Keras version :',tf.keras.__version__)
# -------------------------------------------------------------
# Folder cooking
# -------------------------------------------------------------
#
def tag_now():
return datetime.datetime.now().strftime("%Y-%m-%d_%Hh%Mm%Ss")
def mkdir(path):
os.makedirs(path, mode=0o750, exist_ok=True)
def get_directory_size(path):
"""
Return the directory size, but only 1 level
args:
path : directory path
return:
size in Mo
"""
size=0
for f in os.listdir(path):
if os.path.isfile(path+'/'+f):
size+=os.path.getsize(path+'/'+f)
return size/(1024*1024)
# -------------------------------------------------------------
# shuffle_dataset
# -------------------------------------------------------------
#
def shuffle_np_dataset(x, y):
assert (len(x) == len(y)), "x and y must have same size"
p = np.random.permutation(len(x))
return x[p], y[p]
def update_progress(what,i,imax):
bar_length = min(40,imax)
if (i%int(imax/bar_length))!=0 and i<imax:
return
progress = float(i/imax)
block = int(round(bar_length * progress))
endofline = '\r' if progress<1 else '\n'
text = "{:16s} [{}] {:>5.1f}% of {}".format( what, "#"*block+"-"*(bar_length-block), progress*100, imax)
print(text, end=endofline)
# -------------------------------------------------------------
# show_images
# -------------------------------------------------------------
#
def plot_images(x,y, indices, columns=12, x_size=1, y_size=1, colorbar=False, y_pred=None, cm='binary'):
"""
Show some images in a grid, with legends
args:
X: images
y: real classes
indices: indices of images to show
columns: number of columns (12)
x_size,y_size: figure size
colorbar: show colorbar (False)
y_pred: predicted classes (None)
cm: Matplotlib olor map
returns:
nothing
"""
rows = math.ceil(len(indices)/columns)
fig=plt.figure(figsize=(columns*x_size, rows*(y_size+0.35)))
n=1
errors=0
if np.any(y_pred)==None:
y_pred=y
for i in indices:
axs=fig.add_subplot(rows, columns, n)
n+=1
img=axs.imshow(x[i],cmap = cm, interpolation='lanczos')
img=axs.imshow(x[i],cmap = cm)
axs.spines['right'].set_visible(True)
axs.spines['left'].set_visible(True)
axs.spines['top'].set_visible(True)
axs.spines['bottom'].set_visible(True)
axs.set_yticks([])
axs.set_xticks([])
if y[i]!=y_pred[i]:
axs.set_xlabel('{} ({})'.format(y_pred[i],y[i]))
axs.xaxis.label.set_color('red')
errors+=1
else:
axs.set_xlabel(y[i])
if colorbar:
fig.colorbar(img,orientation="vertical", shrink=0.65)
plt.show()
# -------------------------------------------------------------
# show_history
# -------------------------------------------------------------
#
def plot_history(history, figsize=(8,6)):
"""
Show history
args:
history: history
save_as: filename to save or None
"""
# Accuracy
plt.figure(figsize=figsize)
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()
# Loss values
plt.figure(figsize=figsize)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()
# -------------------------------------------------------------
# plot_confusion_matrix
# -------------------------------------------------------------
#
def plot_confusion_matrix(cm,
target_names,
title='Confusion matrix',
figsize=(8,6),
cmap=None,
normalize=True):
"""
given a sklearn confusion matrix (cm), make a nice plot
Args:
cm: confusion matrix from sklearn.metrics.confusion_matrix
target_names: given classification classes such as [0, 1, 2]
the class names, for example: ['high', 'medium', 'low']
title: the text to display at the top of the matrix
cmap: color map
normalize: False : plot raw numbers, True: plot proportions
save_as: If not None, filename to save
Citiation:
http://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html
"""
accuracy = np.trace(cm) / float(np.sum(cm))
misclass = 1 - accuracy
if (figsize[0]==figsize[1]):
aspect='equal'
else:
aspect='auto'
if cmap is None:
cmap = plt.get_cmap('Blues')
plt.figure(figsize=figsize)
plt.imshow(cm, interpolation='nearest', cmap=cmap, aspect=aspect)
plt.title(title)
plt.colorbar()
if target_names is not None:
tick_marks = np.arange(len(target_names))
plt.xticks(tick_marks, target_names, rotation=45)
plt.yticks(tick_marks, target_names)
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
thresh = cm.max() / 1.5 if normalize else cm.max() / 2
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
if normalize:
plt.text(j, i, "{:0.4f}".format(cm[i, j]),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
else:
plt.text(j, i, "{:,}".format(cm[i, j]),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
# plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass))
plt.show()
# See : https://matplotlib.org/users/customizing.html
axes.titlesize : 24
axes.labelsize : 20
axes.edgecolor : dimgrey
axes.labelcolor : dimgrey
axes.linewidth : 2
axes.grid : False
axes.prop_cycle : cycler('color', ['steelblue', 'tomato', '2ca02c', 'd62728', '9467bd', '8c564b', 'e377c2', '7f7f7f', 'bcbd22', '17becf'])
lines.linewidth : 3
lines.markersize : 10
xtick.color : black
xtick.labelsize : 18
ytick.color : black
ytick.labelsize : 18
axes.spines.left : True
axes.spines.bottom : True
axes.spines.top : False
axes.spines.right : False
savefig.dpi : 300 # figure dots per inch or 'figure'
savefig.facecolor : white # figure facecolor when saving
savefig.edgecolor : white # figure edgecolor when saving
savefig.format : svg
savefig.bbox : tight
savefig.pad_inches : 0.1
savefig.transparent : True
savefig.jpeg_quality: 95
%% Cell type:markdown id: tags:
<img width="800px" src="../fidle/img/header.svg"></img>
# <!-- TITLE --> [LINR1] - Linear regression with direct resolution
<!-- DESC --> Low-level implementation, using numpy, of a direct resolution for a linear regression
<!-- AUTHOR : Jean-Luc Parouty (CNRS/SIMaP) -->
## Objectives :
- Just one, the illustration of a direct resolution :-)
## What we're going to do :
Equation : $$Y = X.\theta + N$$
Where N is a noise vector
and $\theta = (a,b)$ a vector as y = a.x + b
%% Cell type:markdown id: tags:
## Step 1 - Import and init
%% Cell type:code id: tags:
``` python
import numpy as np
import math
import matplotlib
import matplotlib.pyplot as plt
import sys
import fidle
# Init Fidle environment
run_id, run_dir, datasets_dir = fidle.init('LINR1')
```
%% Cell type:markdown id: tags:
## Step 2 - Retrieve a set of points
%% Cell type:code id: tags:
``` python
# ---- Paramètres
nb = 100 # Nombre de points
xmin = 0 # Distribution / x
xmax = 10
a = 4 # Distribution / y
b = 2 # y= a.x + b (+ bruit)
noise = 7 # bruit
theta = np.array([[a],[b]])
# ---- Vecteur X (1,x) x nb
# la premiere colonne est a 1 afin que X.theta <=> 1.b + x.a
Xc1 = np.ones((nb,1))
Xc2 = np.random.uniform(xmin,xmax,(nb,1))
X = np.c_[ Xc1, Xc2 ]
# ---- Noise
# N = np.random.uniform(-noise,noise,(nb,1))
N = noise * np.random.normal(0,1,(nb,1))
# ---- Vecteur Y
Y = (X @ theta) + N
# print("X:\n",X,"\nY:\n ",Y)
```
%% Cell type:markdown id: tags:
### Show it
%% Cell type:code id: tags:
``` python
width = 12
height = 6
fig, ax = plt.subplots()
fig.set_size_inches(width,height)
ax.plot(X[:,1], Y, ".")
ax.tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
ax.set_xlabel('x axis')
ax.set_ylabel('y axis')
fidle.scrawler.save_fig('01-set_of_points')
plt.show()
```
%% Cell type:markdown id: tags:
## Step 3 - Direct calculation of the normal equation
We'll try to find an optimal value of $\theta$, minimizing a cost function.
The cost function, classically used in the case of linear regressions, is the **root mean square error** (racine carré de l'erreur quadratique moyenne):
$$RMSE(X,h_\theta)=\sqrt{\frac1n\sum_{i=1}^n\left[h_\theta(X^{(i)})-Y^{(i)}\right]^2}$$
With the simplified variant : $$MSE(X,h_\theta)=\frac1n\sum_{i=1}^n\left[h_\theta(X^{(i)})-Y^{(i)}\right]^2$$
The optimal value of regression is : $$\hat{ \theta } =( X^{T} .X)^{-1}.X^{T}.Y$$
Démontstration : https://eli.thegreenplace.net/2014/derivation-of-the-normal-equation-for-linear-regression
%% Cell type:code id: tags:
``` python
theta_hat = np.linalg.inv(X.T @ X) @ X.T @ Y
print("Theta :\n",theta,"\n\ntheta hat :\n",theta_hat)
```
%% Cell type:markdown id: tags:
### Show it
%% Cell type:code id: tags:
``` python
Xd = np.array([[1,xmin], [1,xmax]])
Yd = Xd @ theta_hat
fig, ax = plt.subplots()
fig.set_size_inches(width,height)
ax.plot(X[:,1], Y, ".")
ax.plot(Xd[:,1], Yd, "-")
ax.tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
ax.set_xlabel('x axis')
ax.set_ylabel('y axis')
fidle.scrawler.save_fig('02-regression-line')
plt.show()
```
%% Cell type:code id: tags:
``` python
fidle.end()
```
%% Cell type:markdown id: tags:
---
<img width="80px" src="../fidle/img/logo-paysage.svg"></img>
%% Cell type:markdown id: tags:
<img width="800px" src="../fidle/img/header.svg"></img>
# <!-- TITLE --> [GRAD1] - Linear regression with gradient descent
<!-- DESC --> Low level implementation of a solution by gradient descent. Basic and stochastic approach.
<!-- AUTHOR : Jean-Luc Parouty (CNRS/SIMaP) -->
## Objectives :
- To illustrate the iterative approach of a gradient descent
## What we're going to do :
Equation : $ Y = X.\Theta + N$
Where N is a noise vector
and $\Theta = (a,b)$ a vector as y = a.x + b
We will calculate a loss function and its gradient.
We will descend this gradient in order to find a minimum value of our loss function.
$
\triangledown_\theta MSE(\Theta)=\begin{bmatrix}
\frac{\partial}{\partial \theta_0}MSE(\Theta)\\
\frac{\partial}{\partial \theta_1}MSE(\Theta)\\
\vdots\\
\frac{\partial}{\partial \theta_n}MSE(\Theta)
\end{bmatrix}=\frac2m X^T\cdot(X\cdot\Theta-Y)
$
and :
$\Theta \leftarrow \Theta - \eta \cdot \triangledown_\theta MSE(\Theta)$
where $\eta$ is the learning rate
## Step 1 - Import and init
%% Cell type:code id: tags:
``` python
import numpy as np
import sys
import fidle
from modules.RegressionCooker import RegressionCooker
# Init Fidle environment
#
run_id, run_dir, datasets_dir = fidle.init('GRAD1')
# ---- Instanciate a Regression Cooker
#
cooker = RegressionCooker(fidle)
```
%% Cell type:markdown id: tags:
## Step 2 - Get a dataset
%% Cell type:code id: tags:
``` python
X,Y = cooker.get_dataset(1000000)
cooker.plot_dataset(X,Y)
```
%% Cell type:markdown id: tags:
## Step 3 : Data normalization
%% Cell type:code id: tags:
``` python
X_norm = ( X - X.mean() ) / X.std()
Y_norm = ( Y - Y.mean() ) / Y.std()
cooker.vector_infos('X origine',X)
cooker.vector_infos('X normalized',X_norm)
```
%% Cell type:markdown id: tags:
## Step 4 - Basic descent
%% Cell type:code id: tags:
``` python
theta = cooker.basic_descent(X_norm, Y_norm, epochs=200, eta=0.01)
```
%% Cell type:markdown id: tags:
## Step 5 - Minibatch descent
%% Cell type:code id: tags:
``` python
theta = cooker.minibatch_descent(X_norm, Y_norm, epochs=10, batchs=20, batch_size=10, eta=0.01)
```
%% Cell type:code id: tags:
``` python
fidle.end()
```
%% Cell type:markdown id: tags:
---
<img width="80px" src="../fidle/img/logo-paysage.svg"></img>
%% Cell type:markdown id: tags:
<img width="800px" src="../fidle/img/header.svg"></img>
# <!-- TITLE --> [POLR1] - Complexity Syndrome
<!-- DESC --> Illustration of the problem of complexity with the polynomial regression
<!-- AUTHOR : Jean-Luc Parouty (CNRS/SIMaP) -->
## Objectives :
- Visualizing and understanding under and overfitting
## What we're going to do :
We are looking for a polynomial function to approximate the observed series :
$ y = a_n\cdot x^n + \dots + a_i\cdot x^i + \dots + a_1\cdot x + b $
## Step 1 - Import and init
%% Cell type:code id: tags:
``` python
import numpy as np
import math
import random
import matplotlib
import matplotlib.pyplot as plt
import sys
import fidle
# Init Fidle environment
run_id, run_dir, datasets_dir = fidle.init('POLR1')
```
%% Cell type:markdown id: tags:
## Step 2 - Dataset generation
%% Cell type:code id: tags:
``` python
# ---- Parameters
n = 100
xob_min = -5
xob_max = 5
deg = 7
a_min = -2
a_max = 2
noise = 2000
# ---- Train data
# X,Y : data
# X_norm,Y_norm : normalized data
X = np.random.uniform(xob_min,xob_max,(n,1))
# N = np.random.uniform(-noise,noise,(n,1))
N = noise * np.random.normal(0,1,(n,1))
a = np.random.uniform(a_min,a_max, (deg,))
fy = np.poly1d( a )
Y = fy(X) + N
# ---- Data normalization
#
X_norm = (X - X.mean(axis=0)) / X.std(axis=0)
Y_norm = (Y - Y.mean(axis=0)) / Y.std(axis=0)
# ---- Data visualization
width = 12
height = 6
nb_viz = min(2000,n)
def vector_infos(name,V):
m=V.mean(axis=0).item()
s=V.std(axis=0).item()
print("{:8} : mean={:+12.4f} std={:+12.4f} min={:+12.4f} max={:+12.4f}".format(name,m,s,V.min(),V.max()))
fidle.utils.display_md('#### Generator :')
print(f"Nomber of points={n} deg={deg} bruit={noise}")
fidle.utils.display_md('#### Datasets :')
print(f"{nb_viz} points visibles sur {n})")
plt.figure(figsize=(width, height))
plt.plot(X[:nb_viz], Y[:nb_viz], '.')
plt.tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
plt.xlabel('x axis')
plt.ylabel('y axis')
fidle.scrawler.save_fig("01-dataset")
plt.show()
fidle.utils.display_md('#### Before normalization :')
vector_infos('X',X)
vector_infos('Y',Y)
fidle.utils.display_md('#### After normalization :')
vector_infos('X_norm',X_norm)
vector_infos('Y_norm',Y_norm)
```
%% Cell type:markdown id: tags:
## Step 3 - Polynomial regression with NumPy
### 3.1 - Underfitting
%% Cell type:code id: tags:
``` python
def draw_reg(X_norm, Y_norm, x_hat,fy_hat, size, save_as):
plt.figure(figsize=size)
plt.plot(X_norm, Y_norm, '.')
x_hat = np.linspace(X_norm.min(), X_norm.max(), 100)
plt.plot(x_hat, fy_hat(x_hat))
plt.tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
plt.xlabel('x axis')
plt.ylabel('y axis')
fidle.scrawler.save_fig(save_as)
plt.show()
```
%% Cell type:code id: tags:
``` python
reg_deg=1
a_hat = np.polyfit(X_norm.reshape(-1,), Y_norm.reshape(-1,), reg_deg)
fy_hat = np.poly1d( a_hat )
print(f'Nombre de degrés : {reg_deg}')
draw_reg(X_norm[:nb_viz],Y_norm[:nb_viz], X_norm,fy_hat, (width,height), save_as='02-underfitting')
```
%% Cell type:markdown id: tags:
### 3.2 - Good fitting
%% Cell type:code id: tags:
``` python
reg_deg=5
a_hat = np.polyfit(X_norm.reshape(-1,), Y_norm.reshape(-1,), reg_deg)
fy_hat = np.poly1d( a_hat )
print(f'Nombre de degrés : {reg_deg}')
draw_reg(X_norm[:nb_viz],Y_norm[:nb_viz], X_norm,fy_hat, (width,height), save_as='03-good_fitting')
```
%% Cell type:markdown id: tags:
### 3.3 - Overfitting
%% Cell type:code id: tags:
``` python
reg_deg=24
a_hat = np.polyfit(X_norm.reshape(-1,), Y_norm.reshape(-1,), reg_deg)
fy_hat = np.poly1d( a_hat )
print(f'Nombre de degrés : {reg_deg}')
draw_reg(X_norm[:nb_viz],Y_norm[:nb_viz], X_norm,fy_hat, (width,height), save_as='04-over_fitting')
```
%% Cell type:code id: tags:
``` python
fidle.end()
```
%% Cell type:markdown id: tags:
---
<img width="80px" src="../fidle/img/logo-paysage.svg"></img>
%% Cell type:markdown id: tags:
<img width="800px" src="../fidle/img/header.svg"></img>
# <!-- TITLE --> [LOGR1] - Logistic regression
<!-- DESC --> Simple example of logistic regression with a sklearn solution
<!-- AUTHOR : Jean-Luc Parouty (CNRS/SIMaP) -->
## Objectives :
- A logistic regression has the objective of providing a probability of belonging to a class.
- Découvrir une implémentation 100% Tensorflow ..et apprendre à aimer Keras
## What we're going to do :
X contains characteristics
y contains the probability of membership (1 or 0)
We'll look for a value of $\theta$ such that the linear regression $\theta^{T}X$ can be used to calculate our probability:
$\hat{p} = h_\theta(X) = \sigma(\theta^T{X})$
Where $\sigma$ is the logit function, typically a sigmoid (S) function:
$
\sigma(t) = \dfrac{1}{1 + \exp(-t)}
$
The predicted value $\hat{y}$ will then be calculated as follows:
$
\hat{y} =
\begin{cases}
0 & \text{if } \hat{p} < 0.5 \\
1 & \text{if } \hat{p} \geq 0.5
\end{cases}
$
**Calculation of the cost of the regression:**
For a training observation x, the cost can be calculated as follows:
$
c(\theta) =
\begin{cases}
-\log(\hat{p}) & \text{if } y = 1 \\
-\log(1 - \hat{p}) & \text{if } y = 0
\end{cases}
$
The regression cost function (log loss) over the whole training set can be written as follows:
$
J(\theta) = -\dfrac{1}{m} \sum_{i=1}^{m}{\left[ y^{(i)} log\left(\hat{p}^{(i)}\right) + (1 - y^{(i)}) log\left(1 - \hat{p}^{(i)}\right)\right]}
$
## Step 1 - Import and init
You can also adjust the verbosity by changing the value of TF_CPP_MIN_LOG_LEVEL :
- 0 = all messages are logged (default)
- 1 = INFO messages are not printed.
- 2 = INFO and WARNING messages are not printed.
- 3 = INFO , WARNING and ERROR messages are not printed.
%% Cell type:code id: tags:
``` python
# import os
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import numpy as np
from sklearn import metrics
from sklearn.linear_model import LogisticRegression
import matplotlib
import matplotlib.pyplot as plt
# import math
import random
# import os
import sys
import fidle
# Init Fidle environment
run_id, run_dir, datasets_dir = fidle.init('LOGR1')
```
%% Cell type:markdown id: tags:
### 1.1 - Usefull stuff (hidden)
%% Cell type:code id: tags:
``` python
def vector_infos(name,V):
'''Displaying some information about a vector'''
with np.printoptions(precision=4, suppress=True):
print("{:16} : ndim={} shape={:10} Mean = {} Std = {}".format( name,V.ndim, str(V.shape), V.mean(axis=0), V.std(axis=0)))
def do_i_have_it(hours_of_work, hours_of_sleep):
'''Returns the exam result based on work and sleep hours'''
hours_of_sleep_min = 5
hours_of_work_min = 4
hours_of_game_max = 3
# ---- Have to sleep and work
if hours_of_sleep < hours_of_sleep_min: return 0
if hours_of_work < hours_of_work_min: return 0
# ---- Gameboy is not good for you
hours_of_game = 24 - 10 - hours_of_sleep - hours_of_work + random.gauss(0,0.4)
if hours_of_game > hours_of_game_max: return 0
# ---- Fine, you got it
return 1
def make_students_dataset(size, noise):
'''Fabrique un dataset pour <size> étudiants'''
x = []
y = []
for i in range(size):
w = random.gauss(5,1)
s = random.gauss(7,1.5)
r = do_i_have_it(w,s)
x.append([w,s])
y.append(r)
return (np.array(x), np.array(y))
def plot_data(x,y, colors=('green','red'), legend=True):
'''Affiche un dataset'''
fig, ax = plt.subplots(1, 1)
fig.set_size_inches(10,8)
ax.plot(x[y==1, 0], x[y==1, 1], 'o', color=colors[0], markersize=4, label="y=1 (positive)")
ax.plot(x[y==0, 0], x[y==0, 1], 'o', color=colors[1], markersize=4, label="y=0 (negative)")
if legend : ax.legend()
plt.tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
plt.xlabel('Hours of work')
plt.ylabel('Hours of sleep')
plt.show()
def plot_results(x_test,y_test, y_pred):
'''Affiche un resultat'''
precision = metrics.precision_score(y_test, y_pred)
recall = metrics.recall_score(y_test, y_pred)
print("Accuracy = {:5.3f} Recall = {:5.3f}".format(precision, recall))
x_pred_positives = x_test[ y_pred == 1 ] # items prédits positifs
x_real_positives = x_test[ y_test == 1 ] # items réellement positifs
x_pred_negatives = x_test[ y_pred == 0 ] # items prédits négatifs
x_real_negatives = x_test[ y_test == 0 ] # items réellement négatifs
fig, axs = plt.subplots(2, 2)
fig.subplots_adjust(wspace=.1,hspace=0.2)
fig.set_size_inches(14,10)
axs[0,0].plot(x_pred_positives[:,0], x_pred_positives[:,1], 'o',color='lightgreen', markersize=10, label="Prédits positifs")
axs[0,0].plot(x_real_positives[:,0], x_real_positives[:,1], 'o',color='green', markersize=4, label="Réels positifs")
axs[0,0].legend()
axs[0,0].tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
axs[0,0].set_xlabel('$x_1$')
axs[0,0].set_ylabel('$x_2$')
axs[0,1].plot(x_pred_negatives[:,0], x_pred_negatives[:,1], 'o',color='lightsalmon', markersize=10, label="Prédits négatifs")
axs[0,1].plot(x_real_negatives[:,0], x_real_negatives[:,1], 'o',color='red', markersize=4, label="Réels négatifs")
axs[0,1].legend()
axs[0,1].tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
axs[0,1].set_xlabel('$x_1$')
axs[0,1].set_ylabel('$x_2$')
axs[1,0].plot(x_pred_positives[:,0], x_pred_positives[:,1], 'o',color='lightgreen', markersize=10, label="Prédits positifs")
axs[1,0].plot(x_pred_negatives[:,0], x_pred_negatives[:,1], 'o',color='lightsalmon', markersize=10, label="Prédits négatifs")
axs[1,0].plot(x_real_positives[:,0], x_real_positives[:,1], 'o',color='green', markersize=4, label="Réels positifs")
axs[1,0].plot(x_real_negatives[:,0], x_real_negatives[:,1], 'o',color='red', markersize=4, label="Réels négatifs")
axs[1,0].tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
axs[1,0].set_xlabel('$x_1$')
axs[1,0].set_ylabel('$x_2$')
axs[1,1].pie([precision,1-precision], explode=[0,0.1], labels=["","Errors"],
autopct='%1.1f%%', shadow=False, startangle=70, colors=["lightsteelblue","coral"])
axs[1,1].axis('equal')
plt.show()
```
%% Cell type:markdown id: tags:
### 1.2 - Parameters
%% Cell type:code id: tags:
``` python
data_size = 1000 # Number of observations
data_cols = 2 # observation size
data_noise = 0.2
random_seed = 123
```
%% Cell type:markdown id: tags:
## Step 2 - Data preparation
### 2.1 - Get some data
The data here are totally fabricated and represent the **examination results** (passed or failed) based on the students' **working** and **sleeping hours** .
X=(working hours, sleeping hours) y={result} where result=0 (failed) or 1 (passed)
%% Cell type:code id: tags:
``` python
x_data,y_data=make_students_dataset(data_size,data_noise)
```
%% Cell type:markdown id: tags:
### 2.2 - Show it
%% Cell type:code id: tags:
``` python
plot_data(x_data, y_data)
vector_infos('Dataset X',x_data)
vector_infos('Dataset y',y_data)
```
%% Cell type:markdown id: tags:
### 2.3 - Preparation of data
We're going to:
- split the data to have : :
- a training set
- a test set
- normalize the data
%% Cell type:code id: tags:
``` python
# ---- Split data
n = int(data_size * 0.8)
x_train = x_data[:n]
y_train = y_data[:n]
x_test = x_data[n:]
y_test = y_data[n:]
# ---- Normalization
mean = np.mean(x_train, axis=0)
std = np.std(x_train, axis=0)
x_train = (x_train-mean)/std
x_test = (x_test-mean)/std
# ---- About it
vector_infos('X_train',x_train)
vector_infos('y_train',y_train)
vector_infos('X_test',x_test)
vector_infos('y_test',y_test)
y_train_h = y_train.reshape(-1,) # nécessaire pour la visu.
```
%% Cell type:markdown id: tags:
### 2.4 - Have a look
%% Cell type:code id: tags:
``` python
fidle.utils.display_md('**This is what we know :**')
plot_data(x_train, y_train)
fidle.utils.display_md('**This is what we want to classify :**')
plot_data(x_test, y_test, colors=("gray","gray"), legend=False)
```
%% Cell type:markdown id: tags:
## Step 3 - Logistic model #1
### 3.1 - Here is the classifier
%% Cell type:code id: tags:
``` python
# ---- Create an instance
# Use SAGA solver (Stochastic Average Gradient descent solver)
#
logreg = LogisticRegression(C=1e5, verbose=0, solver='saga')
# ---- Fit the data.
#
logreg.fit(x_train, y_train)
# ---- Do a prediction
#
y_pred = logreg.predict(x_test)
```
%% Cell type:markdown id: tags:
### 3.3 - Evaluation
Accuracy = Ability to avoid false positives = $\frac{Tp}{Tp+Fp}$
Recall = Ability to find the right positives = $\frac{Tp}{Tp+Fn}$
Avec :
$T_p$ (true positive) Correct positive answer
$F_p$ (false positive) False positive answer
$T_n$ (true negative) Correct negative answer
$F_n$ (false negative) Wrong negative answer
%% Cell type:code id: tags:
``` python
plot_results(x_test,y_test, y_pred)
```
%% Cell type:markdown id: tags:
## Step 4 - Bending the space to a model #2 ;-)
We're going to increase the characteristics of our observations, with : ${x_1}^2$, ${x_2}^2$, ${x_1}^3$ et ${x_2}^3$
$
X=
\begin{bmatrix}1 & x_{11} & x_{12} \\
\vdots & \dots\\
1 & x_{m1} & x_{m2} \end{bmatrix}
\text{et }
X_{ng}=\begin{bmatrix}1 & x_{11} & x_{12} & x_{11}^2 & x_{12}^2& x_{11}^3 & x_{12}^3 \\
\vdots & & & \dots \\
1 & x_{m1} & x_{m2} & x_{m1}^2 & x_{m2}^2& x_{m1}^3 & x_{m2}^3 \end{bmatrix}
$
Note : `sklearn.preprocessing.PolynomialFeatures` can do that for us, but we'll do it ourselves:
### 4.1 - Extend data
%% Cell type:code id: tags:
``` python
x_train_enhanced = np.c_[x_train,
x_train[:, 0] ** 2,
x_train[:, 1] ** 2,
x_train[:, 0] ** 3,
x_train[:, 1] ** 3]
x_test_enhanced = np.c_[x_test,
x_test[:, 0] ** 2,
x_test[:, 1] ** 2,
x_test[:, 0] ** 3,
x_test[:, 1] ** 3]
```
%% Cell type:markdown id: tags:
### 4.2 - Run the classifier
%% Cell type:code id: tags:
``` python
# ---- Create an instance
# Use SAGA solver (Stochastic Average Gradient descent solver)
#
logreg = LogisticRegression(C=1e5, verbose=0, solver='saga', max_iter=5000, n_jobs=-1)
# ---- Fit the data.
#
logreg.fit(x_train_enhanced, y_train)
# ---- Do a prediction
#
y_pred = logreg.predict(x_test_enhanced)
```
%% Cell type:markdown id: tags:
### 4.3 - Evaluation
%% Cell type:code id: tags:
``` python
plot_results(x_test_enhanced, y_test, y_pred)
```
%% Cell type:code id: tags:
``` python
fidle.end()
```
%% Cell type:markdown id: tags:
---
<img width="80px" src="../fidle/img/logo-paysage.svg"></img>
# ------------------------------------------------------------------
# _____ _ _ _
# | ___(_) __| | | ___
# | |_ | |/ _` | |/ _ \
# | _| | | (_| | | __/
# |_| |_|\__,_|_|\___| Regression cooker
# ------------------------------------------------------------------
# Formation Introduction au Deep Learning (FIDLE)
# CNRS/SARI/DEVLOG 2020 - S. Arias, E. Maldonado, JL. Parouty
# ------------------------------------------------------------------
# Initial version by JL Parouty, feb 2020
import numpy as np
import math
import random
import datetime, time, sys
import matplotlib
import matplotlib.pyplot as plt
from IPython.display import display,Markdown,HTML
class RegressionCooker():
fidle = None
version = '0.1'
def __init__(self, fidle):
self.fidle = fidle
fidle.utils.subtitle('FIDLE 2020 - Regression Cooker')
print('Version :', self.version)
print('Run time : {}'.format(time.strftime("%A %d %B %Y, %H:%M:%S")))
@classmethod
def about(cls):
print('\nFIDLE 2020 - Regression Cooker)')
print('Version :', cls.version)
@classmethod
def vector_infos(cls,name,V):
"""
Show some nice infos about a vector
args:
name : vector name
V : vector
"""
m=V.mean(axis=0).item()
s=V.std(axis=0).item()
print("{:16} : mean={:8.3f} std={:8.3f} min={:8.3f} max={:8.3f}".format(name,m,s,V.min(),V.max()))
def get_dataset(self,n):
"""
Return a dataset of n observation
args:
n : dataset size
return:
X,Y : with X shapes = (n,1) Y shape = (n,)
"""
xob_min = 0 # x min and max
xob_max = 10
a_min = -30 # a min and max
a_max = 30
b_min = -10 # b min and max
b_max = 10
noise_min = 10 # noise min and max
noise_max = 50
a0 = random.randint(a_min,a_max)
b0 = random.randint(b_min,b_max)
noise = random.randint(noise_min,noise_max)
# ---- Construction du jeu d'apprentissage ---------------
# X,Y : données brutes
X = np.random.uniform(xob_min,xob_max,(n,1))
N = noise * np.random.normal(0,1,(n,1))
Y = a0*X + b0 + N
return X,Y
def plot_dataset(self,X,Y,title='Dataset :',width=12,height=6):
"""
Plot dataset X,Y
args:
X : Observations
Y : Values
"""
nb_viz = min(1000,len(X))
display(Markdown(f'### {title}'))
print(f"X shape : {X.shape} Y shape : {Y.shape} plot : {nb_viz} points")
plt.figure(figsize=(width, height))
plt.plot(X[:nb_viz], Y[:nb_viz], '.')
self.fidle.scrawler.save_fig('01-dataset')
plt.show()
self.vector_infos('X',X)
self.vector_infos('Y',Y)
def __plot_theta(self, i, theta,x_min,x_max, loss,gradient,alpha):
Xd = np.array([[x_min], [x_max]])
Yd = Xd * theta.item(1) + theta.item(0)
plt.plot(Xd, Yd, color=(1.,0.4,0.3,alpha))
if i<0:
print( " #i Loss Gradient Theta")
else:
print(" {:3d} {:+7.3f} {:+7.3f} {:+7.3f} {:+7.3f} {:+7.3f}".format(i,loss,gradient.item(0),
gradient.item(1),theta.item(0),
theta.item(1)))
def __plot_XY(self, X,Y,width=12,height=6):
nb_viz = min(1000,len(X))
plt.figure(figsize=(width, height))
plt.plot(X[:nb_viz], Y[:nb_viz], '.')
plt.tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
plt.xlabel('x axis')
plt.ylabel('y axis')
def __plot_loss(self,loss, width=8,height=4):
plt.figure(figsize=(width, height))
plt.tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False)
plt.ylim(0, 20)
plt.plot(range(len(loss)), loss)
plt.xlabel('Iterations')
plt.ylabel('Loss')
def basic_descent(self, X, Y, epochs=200, eta=0.01,width=12,height=6):
"""
Performs a gradient descent where the gradient is updated at the end
of each iteration for all observations.
args:
X,Y : Observations
epochs : Number of epochs (200)
eta : learning rate
width,height : graphic size
return:
theta : theta
"""
display(Markdown(f'### Basic gradient descent :'))
display(Markdown(f'**With :** '))
print('with :')
print(f' epochs = {epochs}')
print(f' eta = {eta}')
display(Markdown(f'**epochs :** '))
x_min = X.min()
x_max = X.max()
y_min = Y.min()
y_max = Y.max()
n = len(X)
# ---- Initialization
theta = np.array([[y_min],[0]])
X_b = np.c_[np.ones((n, 1)), X]
# ---- Visualization
self.__plot_XY(X,Y,width,height)
self.__plot_theta( -1, theta,x_min,x_max, None,None,0.1)
# ---- Training
loss=[]
for i in range(epochs+1):
gradient = (2/n) * X_b.T @ ( X_b @ theta - Y)
mse = ((X_b @ theta - Y)**2).mean(axis=None)
theta = theta - eta * gradient
loss.append(mse)
if (i % (epochs/10))==0:
self.__plot_theta( i, theta,x_min,x_max, mse,gradient,i/epochs)
# ---- Visualization
self.fidle.utils.subtitle('Visualization :')
self.fidle.scrawler.save_fig('02-basic_descent')
plt.show()
self.fidle.utils.subtitle('Loss :')
self.__plot_loss(loss)
self.fidle.scrawler.save_fig('03-basic_descent_loss')
plt.show()
return theta
def minibatch_descent(self, X, Y, epochs=200, batchs=5, batch_size=10, eta=0.01,width=12,height=6):
"""
Performs a gradient descent where the gradient is updated at the end
of each iteration for all observations.
args:
X,Y : Observations
epochs : Number of epochs (200)
eta : learning rate
width,height : graphic size
return:
theta : theta
"""
display(Markdown(f'### Mini batch gradient descent :'))
display(Markdown(f'**With :** '))
print('with :')
print(f' epochs = {epochs}')
print(f' batchs = {batchs}')
print(f' batch size = {batch_size}')
print(f' eta = {eta}')
display(Markdown(f'**epochs :** '))
x_min = X.min()
x_max = X.max()
y_min = Y.min()
y_max = Y.max()
n = len(X)
# ---- Initialization
theta = np.array([[y_min],[0]])
X_b = np.c_[np.ones((n, 1)), X]
# ---- Visualization
self.__plot_XY(X,Y,width,height)
self.__plot_theta( -1, theta,x_min,x_max, None,None,0.1)
# ---- Training
def learning_schedule(t):
return 1 / (t + 100)
loss=[]
for epoch in range(epochs):
for i in range(batchs):
random_index = np.random.randint(n-batch_size)
xi = X_b[random_index:random_index+batch_size]
yi = Y[random_index:random_index+batch_size]
mse = ((xi @ theta - yi)**2).mean(axis=None)
gradient = 2 * xi.T.dot(xi.dot(theta) - yi)
eta = learning_schedule(epoch*150)
theta = theta - eta * gradient
loss.append(mse)
self.__plot_theta( epoch, theta,x_min,x_max, mse,gradient,epoch/epochs)
# draw_theta(epoch,mse,gradients, theta,0.1+epoch/(n_epochs+1))
# draw_theta(epoch,mse,gradients,theta,1)
# ---- Visualization
self.fidle.utils.subtitle('Visualization :')
self.fidle.scrawler.save_fig('04-minibatch_descent')
plt.show()
self.fidle.utils.subtitle('Loss :')
self.__plot_loss(loss)
self.fidle.scrawler.save_fig('05-minibatch_descent_loss')
plt.show()
return theta
%% Cell type:markdown id: tags:
<img width="800px" src="../fidle/img/header.svg"></img>
# <!-- TITLE --> [K3MNIST1] - Simple classification with DNN
<!-- DESC --> An example of classification using a dense neural network for the famous MNIST dataset
<!-- AUTHOR : Jean-Luc Parouty (CNRS/SIMaP) -->
## Objectives :
- Recognizing handwritten numbers
- Understanding the principle of a classifier DNN network
- Implementation with Keras
The [MNIST dataset](http://yann.lecun.com/exdb/mnist/) (Modified National Institute of Standards and Technology) is a must for Deep Learning.
It consists of 60,000 small images of handwritten numbers for learning and 10,000 for testing.
## What we're going to do :
- Retrieve data
- Preparing the data
- Create a model
- Train the model
- Evaluate the result
%% Cell type:markdown id: tags:
## Step 1 - Init python stuff
%% Cell type:code id: tags:
``` python
import os
os.environ['KERAS_BACKEND'] = 'torch'
import keras
import numpy as np
import matplotlib.pyplot as plt
import sys,os
from importlib import reload
# Init Fidle environment
import fidle
run_id, run_dir, datasets_dir = fidle.init('K3MNIST1')
```
%% Cell type:markdown id: tags:
Verbosity during training : 0 = silent, 1 = progress bar, 2 = one line per epoch
%% Cell type:code id: tags:
``` python
fit_verbosity = 1
```
%% Cell type:markdown id: tags:
Override parameters (batch mode) - Just forget this cell
%% Cell type:code id: tags:
``` python
fidle.override('fit_verbosity')
```
%% Cell type:markdown id: tags:
## Step 2 - Retrieve data
MNIST is one of the most famous historic dataset.
Include in [Keras datasets](https://keras.io/datasets)
%% Cell type:code id: tags:
``` python
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
print("x_train : ",x_train.shape)
print("y_train : ",y_train.shape)
print("x_test : ",x_test.shape)
print("y_test : ",y_test.shape)
```
%% Cell type:markdown id: tags:
## Step 3 - Preparing the data
%% Cell type:code id: tags:
``` python
print('Before normalization : Min={}, max={}'.format(x_train.min(),x_train.max()))
xmax=x_train.max()
x_train = x_train / xmax
x_test = x_test / xmax
print('After normalization : Min={}, max={}'.format(x_train.min(),x_train.max()))
```
%% Cell type:markdown id: tags:
### Have a look
%% Cell type:code id: tags:
``` python
fidle.scrawler.images(x_train, y_train, [27], x_size=5,y_size=5, colorbar=True, save_as='01-one-digit')
fidle.scrawler.images(x_train, y_train, range(5,41), columns=12, save_as='02-many-digits')
```
%% Cell type:markdown id: tags:
## Step 4 - Create model
About informations about :
- [Optimizer](https://keras.io/api/optimizers)
- [Activation](https://keras.io/api/layers/activations)
- [Loss](https://keras.io/api/losses)
- [Metrics](https://keras.io/api/metrics)
%% Cell type:code id: tags:
``` python
hidden1 = 100
hidden2 = 100
model = keras.Sequential([
keras.layers.Input((28,28)),
keras.layers.Flatten(),
keras.layers.Dense( hidden1, activation='relu'),
keras.layers.Dense( hidden2, activation='relu'),
keras.layers.Dense( 10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
```
%% Cell type:markdown id: tags:
## Step 5 - Train the model
%% Cell type:code id: tags:
``` python
batch_size = 512
epochs = 16
history = model.fit( x_train, y_train,
batch_size = batch_size,
epochs = epochs,
verbose = fit_verbosity,
validation_data = (x_test, y_test))
```
%% Cell type:markdown id: tags:
## Step 6 - Evaluate
### 6.1 - Final loss and accuracy
%% Cell type:code id: tags:
``` python
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss :', score[0])
print('Test accuracy :', score[1])
```
%% Cell type:markdown id: tags:
### 6.2 - Plot history
%% Cell type:code id: tags:
``` python
fidle.scrawler.history(history, figsize=(6,4), save_as='03-history')
```
%% Cell type:markdown id: tags:
### 6.3 - Plot results
%% Cell type:code id: tags:
``` python
#y_pred = model.predict_classes(x_test) Deprecated after 01/01/2021 !!
y_sigmoid = model.predict(x_test, verbose=fit_verbosity)
y_pred = np.argmax(y_sigmoid, axis=-1)
fidle.scrawler.images(x_test, y_test, range(0,200), columns=12, x_size=1, y_size=1, y_pred=y_pred, save_as='04-predictions')
```
%% Cell type:markdown id: tags:
### 6.4 - Plot some errors
%% Cell type:code id: tags:
``` python
errors=[ i for i in range(len(x_test)) if y_pred[i]!=y_test[i] ]
errors=errors[:min(24,len(errors))]
fidle.scrawler.images(x_test, y_test, errors[:15], columns=6, x_size=2, y_size=2, y_pred=y_pred, save_as='05-some-errors')
```
%% Cell type:code id: tags:
``` python
fidle.scrawler.confusion_matrix(y_test,y_pred,range(10),normalize=True, save_as='06-confusion-matrix')
```
%% Cell type:code id: tags:
``` python
fidle.end()
```
%% Cell type:markdown id: tags:
<div class="todo">
A few things you can do for fun:
<ul>
<li>Changing the network architecture (layers, number of neurons, etc.)</li>
<li>Display a summary of the network</li>
<li>Retrieve and display the softmax output of the network, to evaluate its "doubts".</li>
</ul>
</div>
%% Cell type:markdown id: tags:
---
<img width="80px" src="../fidle/img/logo-paysage.svg"></img>
%% Cell type:markdown id: tags:
<img width="800px" src="../fidle/img/header.svg"></img>
# <!-- TITLE --> [K3MNIST2] - Simple classification with CNN
<!-- DESC --> An example of classification using a convolutional neural network for the famous MNIST dataset
<!-- AUTHOR : Jean-Luc Parouty (CNRS/SIMaP) -->
## Objectives :
- Recognizing handwritten numbers
- Understanding the principle of a classifier DNN network
- Implementation with Keras
The [MNIST dataset](http://yann.lecun.com/exdb/mnist/) (Modified National Institute of Standards and Technology) is a must for Deep Learning.
It consists of 60,000 small images of handwritten numbers for learning and 10,000 for testing.
## What we're going to do :
- Retrieve data
- Preparing the data
- Create a model
- Train the model
- Evaluate the result
%% Cell type:markdown id: tags:
## Step 1 - Init python stuff
%% Cell type:code id: tags:
``` python
import os
os.environ['KERAS_BACKEND'] = 'torch'
import keras
import numpy as np
import matplotlib.pyplot as plt
import sys,os
from importlib import reload
# Init Fidle environment
import fidle
run_id, run_dir, datasets_dir = fidle.init('K3MNIST2')
```
%% Cell type:markdown id: tags:
Verbosity during training : 0 = silent, 1 = progress bar, 2 = one line per epoch
%% Cell type:code id: tags:
``` python
fit_verbosity = 1
```
%% Cell type:markdown id: tags:
Override parameters (batch mode) - Just forget this cell
%% Cell type:code id: tags:
``` python
fidle.override('fit_verbosity')
```
%% Cell type:markdown id: tags:
## Step 2 - Retrieve data
MNIST is one of the most famous historic dataset.
Include in [Keras datasets](https://keras.io/datasets)
%% Cell type:code id: tags:
``` python
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(-1,28,28,1)
x_test = x_test.reshape(-1,28,28,1)
print("x_train : ",x_train.shape)
print("y_train : ",y_train.shape)
print("x_test : ",x_test.shape)
print("y_test : ",y_test.shape)
```
%% Cell type:markdown id: tags:
## Step 3 - Preparing the data
%% Cell type:code id: tags:
``` python
print('Before normalization : Min={}, max={}'.format(x_train.min(),x_train.max()))
xmax=x_train.max()
x_train = x_train / xmax
x_test = x_test / xmax
print('After normalization : Min={}, max={}'.format(x_train.min(),x_train.max()))
```
%% Cell type:markdown id: tags:
### Have a look
%% Cell type:code id: tags:
``` python
fidle.scrawler.images(x_train, y_train, [27], x_size=5,y_size=5, colorbar=True, save_as='01-one-digit')
fidle.scrawler.images(x_train, y_train, range(5,41), columns=12, save_as='02-many-digits')
```
%% Cell type:markdown id: tags:
## Step 4 - Create model
About informations about :
- [Optimizer](https://keras.io/api/optimizers)
- [Activation](https://keras.io/api/layers/activations)
- [Loss](https://keras.io/api/losses)
- [Metrics](https://keras.io/api/metrics)
%% Cell type:code id: tags:
``` python
model = keras.models.Sequential()
model.add( keras.layers.Input((28,28,1)) )
model.add( keras.layers.Conv2D(8, (3,3), activation='relu') )
model.add( keras.layers.MaxPooling2D((2,2)))
model.add( keras.layers.Dropout(0.2))
model.add( keras.layers.Conv2D(16, (3,3), activation='relu') )
model.add( keras.layers.MaxPooling2D((2,2)))
model.add( keras.layers.Dropout(0.2))
model.add( keras.layers.Flatten())
model.add( keras.layers.Dense(100, activation='relu'))
model.add( keras.layers.Dropout(0.5))
model.add( keras.layers.Dense(10, activation='softmax'))
```
%% Cell type:code id: tags:
``` python
model.summary()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
```
%% Cell type:markdown id: tags:
## Step 5 - Train the model
%% Cell type:code id: tags:
``` python
batch_size = 512
epochs = 16
history = model.fit( x_train, y_train,
batch_size = batch_size,
epochs = epochs,
verbose = fit_verbosity,
validation_data = (x_test, y_test))
```
%% Cell type:markdown id: tags:
## Step 6 - Evaluate
### 6.1 - Final loss and accuracy
Note : With a DNN, we had a precision of the order of : 97.7%
%% Cell type:code id: tags:
``` python
score = model.evaluate(x_test, y_test, verbose=0)
print(f'Test loss : {score[0]:4.4f}')
print(f'Test accuracy : {score[1]:4.4f}')
```
%% Cell type:markdown id: tags:
### 6.2 - Plot history
%% Cell type:code id: tags:
``` python
fidle.scrawler.history(history, figsize=(6,4), save_as='03-history')
```
%% Cell type:markdown id: tags:
### 6.3 - Plot results
%% Cell type:code id: tags:
``` python
#y_pred = model.predict_classes(x_test) Deprecated after 01/01/2021 !!
y_sigmoid = model.predict(x_test, verbose=fit_verbosity)
y_pred = np.argmax(y_sigmoid, axis=-1)
fidle.scrawler.images(x_test, y_test, range(0,200), columns=12, x_size=1, y_size=1, y_pred=y_pred, save_as='04-predictions')
```
%% Cell type:markdown id: tags:
### 6.4 - Plot some errors
%% Cell type:code id: tags:
``` python
errors=[ i for i in range(len(x_test)) if y_pred[i]!=y_test[i] ]
errors=errors[:min(24,len(errors))]
fidle.scrawler.images(x_test, y_test, errors[:15], columns=6, x_size=2, y_size=2, y_pred=y_pred, save_as='05-some-errors')
```
%% Cell type:code id: tags:
``` python
fidle.scrawler.confusion_matrix(y_test,y_pred,range(10),normalize=True, save_as='06-confusion-matrix')
```
%% Cell type:code id: tags:
``` python
fidle.end()
```
%% Cell type:markdown id: tags:
<div class="todo">
A few things you can do for fun:
<ul>
<li>Changing the network architecture (layers, number of neurons, etc.)</li>
<li>Display a summary of the network</li>
<li>Retrieve and display the softmax output of the network, to evaluate its "doubts".</li>
</ul>
</div>
%% Cell type:markdown id: tags:
---
<img width="80px" src="../fidle/img/logo-paysage.svg"></img>