Explorar el Código

Merge remote-tracking branch 'origin/Emilien'

Emile2
Emile Siboulet hace 4 años
padre
commit
afddae8f17
Se han modificado 4 ficheros con 192 adiciones y 19 borrados
  1. 17
    1
      README.md
  2. 7
    8
      code/resnet18/resnet18.py
  3. 17
    10
      code/resnet18/resnet18_snake.py
  4. 151
    0
      code/resnet18/resnet_snake.ipynb

+ 17
- 1
README.md Ver fichero

└── rapport.tex # Fichier source du rapport └── rapport.tex # Fichier source du rapport
``` ```


## To do list
## Emilien

Cette partie s'intéresse à l'efficacité de la fonction d'activation snake sur une tâche complexe de machine learning non-périodique. En effet pour que snake soit intéressant il faut qu'elle fasse aussi bien dans la plupart des tâches de ML comme la classification.
C'est pourquoi conformément à l'article un réseau de CNN ResNet18 est appliqué sur la base de données ciphar-10.

Pour utiliser :

Aller dans code/resnet18/

---> le fichier ResNet18.py est le script POO implémentant le réseau, les classes crées sont :

-- ResnetBlock une superclasse dont hérite la classe ResNet18, créant les resblock faisant apportant l'info résiduelle via la fonction call
-- ResNet18 qui implémente la structure de couches de convolution, elle prend comme argument le nombre de classe possible. Soit 10 dans le cas de CIPHAR-10
Pour faire varier la fonction d'activation --> juste décommenter #tf.nn.relu(x) lignes 44, 54, 84 et commenter x + tf.sin(x)**2

--> le fichier resnet_snake.ipynb est le notebook main python a exectuer faisant l'appel de toutes les fonctions ainsi que de la classe Resnet18

+ 7
- 8
code/resnet18/resnet18.py Ver fichero

self.__strides = [2, 1] if down_sample else [1, 1] self.__strides = [2, 1] if down_sample else [1, 1]


KERNEL_SIZE = (3, 3) KERNEL_SIZE = (3, 3)
# use He initialization, instead of Xavier (a.k.a 'glorot_uniform' in Keras), as suggested in [2]
INIT_SCHEME = "he_normal" INIT_SCHEME = "he_normal"


self.conv_1 = Conv2D(self.__channels, strides=self.__strides[0], self.conv_1 = Conv2D(self.__channels, strides=self.__strides[0],
self.merge = Add() self.merge = Add()


if self.__down_sample: if self.__down_sample:
# perform down sampling using stride of 2, according to [1].
self.res_conv = Conv2D(
self.res_conv = Conv2D(
self.__channels, strides=2, kernel_size=(1, 1), kernel_initializer=INIT_SCHEME, padding="same") self.__channels, strides=2, kernel_size=(1, 1), kernel_initializer=INIT_SCHEME, padding="same")
self.res_bn = BatchNormalization() self.res_bn = BatchNormalization()




x = self.conv_1(inputs) x = self.conv_1(inputs)
x = self.bn_1(x) x = self.bn_1(x)
x = tf.nn.relu(x)
x = x + tf.sin(x)**2 #tf.nn.relu(x)
x = self.conv_2(x) x = self.conv_2(x)
x = self.bn_2(x) x = self.bn_2(x)


res = self.res_conv(res) res = self.res_conv(res)
res = self.res_bn(res) res = self.res_bn(res)


# if not perform down sample, then add a shortcut directly
x = self.merge([x, res]) x = self.merge([x, res])
out = tf.nn.relu(x)
out = x + tf.sin(x)**2 #tf.nn.relu(x)
return out return out




self.res_4_2 = ResnetBlock(512) self.res_4_2 = ResnetBlock(512)
self.avg_pool = GlobalAveragePooling2D() self.avg_pool = GlobalAveragePooling2D()
self.flat = Flatten() self.flat = Flatten()
self.fc = Dense(num_classes, activation="softmax")
self.fc = Dense(num_classes, activation="sigmoid")


def call(self, inputs): def call(self, inputs):
out = self.conv_1(inputs) out = self.conv_1(inputs)
out = self.init_bn(out) out = self.init_bn(out)
out = tf.nn.relu(out)
out += tf.sin(out)**2 #tf.nn.relu(out)
out = self.pool_2(out) out = self.pool_2(out)
for res_block in [self.res_1_1, self.res_1_2, self.res_2_1, self.res_2_2, self.res_3_1, self.res_3_2, self.res_4_1, self.res_4_2]: for res_block in [self.res_1_1, self.res_1_2, self.res_2_1, self.res_2_2, self.res_3_1, self.res_3_2, self.res_4_1, self.res_4_2]:
out = res_block(out) out = res_block(out)

+ 17
- 10
code/resnet18/resnet18_snake.py Ver fichero

# Réseau inspiré de http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdf # Réseau inspiré de http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdf




from keras.callbacks import History

from tensorflow.python.ops.gen_array_ops import tensor_scatter_min_eager_fallback
from resnet18 import ResNet18 from resnet18 import ResNet18
import tensorflow as tf import tensorflow as tf
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
# Pour les utilisateurs de MacOS (pour utiliser plt & keras en même temps)
import os
#os.environ['KMP_DUPLICATE_LIB_OK']='True'




def displayConvFilers(model, layer_name, num_filter=4, filter_size=(3,3), num_channel=0, fig_size=(2,2)): def displayConvFilers(model, layer_name, num_filter=4, filter_size=(3,3), num_channel=0, fig_size=(2,2)):
## Chargement et normalisation des données ## Chargement et normalisation des données
resnet18 = tf.keras.datasets.cifar10 resnet18 = tf.keras.datasets.cifar10
(train_images, train_labels), (test_images, test_labels) = resnet18.load_data() (train_images, train_labels), (test_images, test_labels) = resnet18.load_data()
train_images = train_images.astype('float32')
test_images = test_images.astype('float32')

from sklearn.model_selection import train_test_split
train_images, val_images, train_labels, val_labels = train_test_split(train_images,train_labels, test_size = 0.2,shuffle = True)




'''
val_images = train_images[40000:] val_images = train_images[40000:]
val_labels = train_labels[40000:] val_labels = train_labels[40000:]


train_images = train_images[:40000] train_images = train_images[:40000]
train_labels = train_labels[:40000] train_labels = train_labels[:40000]
'''


train_images = train_images / 255.0 train_images = train_images / 255.0
val_images = val_images /255.0 val_images = val_images /255.0
test_images = test_images / 255.0 test_images = test_images / 255.0


# POUR LES CNN : On rajoute une dimension pour spécifier qu'il s'agit d'imgages en NdG # POUR LES CNN : On rajoute une dimension pour spécifier qu'il s'agit d'imgages en NdG
train_images = train_images.reshape(40000,32,32,3)
val_images = val_images.reshape(10000,32,32,3)
test_images = test_images.reshape(10000,32,32,3)
train_images = train_images.reshape(max(np.shape(train_images)),32,32,3)
val_images = val_images.reshape(max(np.shape(val_images)),32,32,3)
test_images = test_images.reshape(max(np.shape(test_images)),32,32,3)




# One hot encoding # One hot encoding


model = ResNet18(10) model = ResNet18(10)
model.build(input_shape = (None,32,32,3)) model.build(input_shape = (None,32,32,3))
filter_size_conv1 = (5,5)


''' '''
filter_size_conv1 = (5,5)
## Définition de l'architecture du modèle ## Définition de l'architecture du modèle
model = tf.keras.models.Sequential() model = tf.keras.models.Sequential()
# Expliquez à quoi correspondent les valeurs numériques qui définissent les couches du réseau # Expliquez à quoi correspondent les valeurs numériques qui définissent les couches du réseau


history = model.fit(train_images, history = model.fit(train_images,
train_labels, train_labels,
batch_size=64,
epochs=4,
batch_size=256,
epochs=50,
validation_data=(val_images, val_labels), validation_data=(val_images, val_labels),
) )



+ 151
- 0
code/resnet18/resnet_snake.ipynb Ver fichero

{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Untitled1.ipynb",
"provenance": [],
"collapsed_sections": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "hUYO09lse0Ew"
},
"outputs": [],
"source": [
"from tensorflow.python.ops.gen_array_ops import tensor_scatter_min_eager_fallback\n",
"from resnet18 import ResNet18\n",
"import tensorflow as tf\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"def snake(x):\n",
" return x + tf.sin(x)**2\n",
"\n"
]
},
{
"cell_type": "code",
"source": [
"## Chargement et normalisation des données\n",
"resnet18 = tf.keras.datasets.cifar10\n",
"(train_images, train_labels), (test_images, test_labels) = resnet18.load_data()\n",
"train_images = train_images.astype('float32')\n",
"test_images = test_images.astype('float32')\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"train_images, val_images, train_labels, val_labels = train_test_split(train_images,train_labels, test_size = 0.2,shuffle = True)\n",
"\n",
"train_images = train_images / 255.0\n",
"val_images = val_images /255.0\n",
"test_images = test_images / 255.0\n",
"\n",
"# POUR LES CNN : un tenseur d'ordre 3 pour les images en couleurs\n",
"train_images = train_images.reshape(max(np.shape(train_images)),32,32,3)\n",
"val_images = val_images.reshape(max(np.shape(val_images)),32,32,3)\n",
"test_images = test_images.reshape(max(np.shape(test_images)),32,32,3)\n",
"\n",
"\n"
],
"metadata": {
"id": "-iczeI91fEND"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# One hot encoding\n",
"train_labels = tf.keras.utils.to_categorical(train_labels)\n",
"val_labels = tf.keras.utils.to_categorical(val_labels)\n",
"test_labels = tf.keras.utils.to_categorical(test_labels)\n",
"\n",
"filter_size_conv1 = (3,3)\n",
"\n",
"\n",
"#création du réseau ResNet18\n",
"\n",
"model = ResNet18(10)\n",
"model.build(input_shape = (None,32,32,3))\n",
"print(model.summary())\n"
],
"metadata": {
"id": "9UGNJFoRfGTz"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"#Adam comme optimizer et categorical-crossentropy comme norme\n",
"sgd = tf.keras.optimizers.Adam()\n",
"model.compile(sgd, loss='categorical_crossentropy', metrics=['accuracy'])\n",
"\n",
"\n",
"\n",
"history = model.fit(train_images,\n",
" train_labels,\n",
" batch_size=64,\n",
" epochs=100,\n",
" validation_data=(val_images, val_labels),\n",
" )\n"
],
"metadata": {
"id": "PtY0q1p5fM-p"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"## Evaluation du modèle \n",
"test_loss, test_acc = model.evaluate(test_images, test_labels)\n",
"print('Test accuracy:', test_acc)\n",
"\n"
],
"metadata": {
"id": "FcehZmotfPCx"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"## on affiche et on sauvegarde les images\n",
"\n",
"fig, axs = plt.subplots(2, 1, figsize=(15,15))\n",
"\n",
"axs[0].plot(history.history['loss'])\n",
"axs[0].plot(history.history['val_loss'])\n",
"axs[0].title.set_text('Training Loss vs Validation Loss')\n",
"axs[0].legend(['Train', 'Val'])\n",
"\n",
"axs[1].plot(history.history['accuracy'])\n",
"axs[1].plot(history.history['val_accuracy'])\n",
"axs[1].title.set_text('Training Accuracy vs Validation Accuracy')\n",
"axs[1].legend(['Train', 'Val'])\n",
"plt.savefig('./resnet18snake.png')"
],
"metadata": {
"id": "8USwL2YTfRGN"
},
"execution_count": null,
"outputs": []
}
]
}

Cargando…
Cancelar
Guardar