diff --git a/.gitignore b/.gitignore index 894a44c..64a350a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,104 +1,106 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +Satellite.ipynb diff --git a/Indian_pines_corrected.mat b/Indian_pines_corrected.mat new file mode 100644 index 0000000..75b6d6e Binary files /dev/null and b/Indian_pines_corrected.mat differ diff --git a/Project.ipynb b/Project.ipynb new file mode 100644 index 0000000..b4d3010 --- /dev/null +++ b/Project.ipynb @@ -0,0 +1,867 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hyperspectral image ground classification\n", + "## Using Deep Learning" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:46:53.649003Z", + "start_time": "2018-11-18T17:46:53.638579Z" + }, + "init_cell": true + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "import keras\n", + "from keras.layers import Dense, Flatten, Dropout\n", + "from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D, Dropout, Activation, Average\n", + "from keras.models import Model\n", + "from keras.optimizers import SGD\n", + "from keras.engine.input_layer import Input\n", + "from keras.models import Sequential, load_model\n", + "from keras.utils import np_utils\n", + "from keras.wrappers.scikit_learn import KerasClassifier\n", + "\n", + "from keras import backend as K\n", + "K.set_image_dim_ordering('th')\n", + "K.set_image_data_format('channels_last')\n", + "\n", + "import numpy as np\n", + "\n", + "from sklearn.ensemble import RandomForestClassifier, VotingClassifier\n", + "from sklearn.decomposition import PCA\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.metrics import classification_report, confusion_matrix\n", + "from sklearn import preprocessing\n", + "from sklearn.preprocessing import MultiLabelBinarizer\n", + "import skimage as sk\n", + "from skimage import transform\n", + "from skimage import util\n", + "\n", + "import scipy\n", + "import scipy.ndimage\n", + "import scipy.io as sio\n", + "\n", + "import matplotlib.pyplot as plt\n", + "from matplotlib import patches\n", + "import itertools\n", + "import spectral\n", + "from spectral import spy_colors\n", + "\n", + "import time\n", + "import os\n", + "import sys\n", + "import random\n", + "from random import shuffle\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Global variables and hyperparameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:46:53.685194Z", + "start_time": "2018-11-18T17:46:53.651513Z" + }, + "init_cell": true + }, + "outputs": [], + "source": [ + "numPCAcomponents = 50\n", + "PATCH_SIZE = 3\n", + "C1 = 3*numPCAcomponents\n", + "\n", + "batch_size = 128\n", + "epochs = 2\n", + "\n", + "label_dictionary = {\n", + " 0: 'Rien',\n", + " 1: 'Luzerne', \n", + " 2: 'Maïs- Pas de Technique de Conservation des sols', \n", + " 3: 'Maïs- Minimum Tillage', \n", + " 4: 'Maïs',\n", + " 5: 'Herbe-Pâturage', \n", + " 6: 'Herbe-Arbre', \n", + " 7: 'Herbe-Pâturage-Tondu',\n", + " 8: 'Foin-andains', \n", + " 9: 'Avoine', \n", + " 10: 'Soja-Pas de Technique de Conservation des sols', \n", + " 11: 'Soja-Minimum Tillage',\n", + " 12: 'Soja', \n", + " 13: 'Blé', \n", + " 14: 'BoisBâtiment-Herbe-Arbre-drives', \n", + " 15: 'Bâtiment-Herbe-Arbre-drives',\n", + " 16: 'Pierre-Acier-Tour'}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Some useful functions for reuse" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:46:53.738095Z", + "start_time": "2018-11-18T17:46:53.688357Z" + }, + "init_cell": true + }, + "outputs": [], + "source": [ + "\n", + "#Function found on stackoverflow\n", + "def printProgressBar (iteration, total, prefix = 'Progress: ', suffix = ' Complete', decimals = 1, length = 40, fill = '█'):\n", + " \"\"\"\n", + " Call in a loop to create terminal progress bar\n", + " @params:\n", + " iteration - Required : current iteration (Int)\n", + " total - Required : total iterations (Int)\n", + " prefix - Optional : prefix string (Str)\n", + " suffix - Optional : suffix string (Str)\n", + " decimals - Optional : positive number of decimals in percent complete (Int)\n", + " length - Optional : character length of bar (Int)\n", + " fill - Optional : bar fill character (Str)\n", + " \"\"\"\n", + " percent = (\"{0:.\" + str(decimals) + \"f}\").format(100 * (iteration / float(total)))\n", + " filledLength = int(length * iteration // total)\n", + " bar = fill * filledLength + '-' * (length - filledLength)\n", + " print('\\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end = '\\r')\n", + " sys.stdout.flush()\n", + " # Print New Line on Complete\n", + " if iteration == total: \n", + " print()\n", + "\n", + "\n", + "def print_shape(**kwargs):\n", + " \"\"\"\n", + " Print multiple shapes of np.ndarray\n", + " \"\"\"\n", + " for key, value in kwargs.items():\n", + " print (\"%s: %s\" %(key, value.shape))\n", + " \n", + "def loadData():\n", + " data_path = os.path.join(os.getcwd(),'.')\n", + " data = sio.loadmat(os.path.join(data_path, 'Indian_pines_corrected.mat'))['indian_pines_corrected']\n", + " train_labels = np.load(\"train_data.npy\")\n", + " test_labels = np.load(\"test_data.npy\")\n", + " \n", + " return data, train_labels, test_labels\n", + "\n", + "def displayPrincipalComponents(X, cmap=\"gray\"):\n", + " \"\"\"\n", + " Display principal components of the sensor data array\n", + " ...\n", + " \n", + " Parameters\n", + " ----------\n", + " X : np.ndarray of dim MxNxP\n", + " Sensor data of MxN pixels and P bands\n", + " cmap : str, optional\n", + " Custom color map for matplotlib\n", + " \"\"\"\n", + " pc = spectral.principal_components(X_train)\n", + " plt.figure()\n", + " plt.imshow(pc.cov, cmap=cmap)\n", + " \n", + " return pc\n", + "\n", + "def reduceComponents(X, reduce_factor=7):\n", + " \"\"\"\n", + " Reduce aviris sensor data array in principal components\n", + " ...\n", + " \n", + " Parameters\n", + " ----------\n", + " X : np.ndarray of dim MxNxP\n", + " Sensor data of MxN pixels and P bands\n", + " reduce_factor : int, optional\n", + " Determines the strength of dimensionality reduction\n", + " \"\"\"\n", + " switcher = {\n", + " 1: 0.9,\n", + " 2: 0.99,\n", + " 3: 0.999,\n", + " 4: 0.9999,\n", + " 5: 0.99999,\n", + " 6: 0.999999,\n", + " 7: 0.9999999\n", + " }\n", + " fraction = switcher.get(reduce_factor, 7)\n", + " pc = spectral.principal_components(X).reduce(fraction=fraction)\n", + "\n", + " # How many eigenvalues are left?\n", + "\n", + " print(\"Reflectance bands remaining: %s\" %(len(pc.eigenvalues)))\n", + " newX = pc.transform(X)\n", + "\n", + " #v = plt.imshow(img_pc[:,:,1], cmap=\"cool\")\n", + " return newX\n", + "\n", + "def displayImage(X, img_num=3, cmap=\"gray\"):\n", + " \"\"\"\n", + " Display image from sensor data array\n", + " ...\n", + " \n", + " Parameters\n", + " ----------\n", + " X : np.ndarray of dim MxNxP\n", + " Sensor data of MxN pixels and P bands\n", + " img_num : int, optional\n", + " Display band 'img_num'\n", + " cmap : str, optional\n", + " Custom color map for matplotlib\n", + " \"\"\"\n", + " plt.figure()\n", + " plt.imshow(X[:,:,img_num], cmap=cmap)\n", + " \n", + "def patch_1dim_split(X, train_data, test_data, PATCH_SIZE):\n", + " padding = int((PATCH_SIZE - 1) / 2) #Patch de 3*3 = padding de 1 (centre + 1 de chaque coté)\n", + " #X_padding = np.zeros(X)\n", + " X_padding = np.pad(X, [(padding, padding), (padding, padding), (0, 0)], mode='constant')\n", + " \n", + " X_patch = np.zeros((X.shape[0] * X.shape[1], PATCH_SIZE, PATCH_SIZE, X.shape[2]))\n", + " y_train_patch = np.zeros((train_data.shape[0] * train_data.shape[1]))\n", + " y_test_patch = np.zeros((test_data.shape[0] * test_data.shape[1]))\n", + " \n", + " index = 0\n", + " for i in range(0, X_padding.shape[0] - 2 * padding):\n", + " for j in range(0, X_padding.shape[1] - 2 * padding):\n", + " # This condition is for less frequent updates. \n", + " if i % 8 == 0 or index == (X_padding.shape[0] - 2 * padding) * (X_padding.shape[1] - 2 * padding) - 1:\n", + " printProgressBar(index + 1, (X_padding.shape[0] - 2 * padding) * (X_padding.shape[1] - 2 * padding))\n", + " patch = X_padding[i:i + 2 * padding + 1, j:j + 2 * padding + 1]\n", + " X_patch[index, :, :, :] = patch\n", + " y_train_patch[index] = train_data[i, j]\n", + " y_test_patch[index] = test_data[i, j]\n", + " index += 1\n", + " \n", + " print(\"\\nCreating train/test arrays and removing zero labels...\")\n", + " printProgressBar(1, 7)\n", + " X_train_patch = np.copy(X_patch)\n", + " printProgressBar(2, 7)\n", + " X_test_patch = np.copy(X_patch)\n", + " \n", + " printProgressBar(3, 7)\n", + " X_train_patch = X_train_patch[y_train_patch > 0,:,:,:]\n", + " printProgressBar(4, 7)\n", + " X_test_patch = X_test_patch[y_test_patch > 0,:,:,:]\n", + " printProgressBar(5, 7)\n", + " y_train_patch = y_train_patch[y_train_patch > 0] - 1\n", + " printProgressBar(6, 70)\n", + " y_test_patch = y_test_patch[y_test_patch > 0] - 1\n", + " printProgressBar(7, 7)\n", + " print(\"Done.\")\n", + " \n", + " return X_train_patch, X_test_patch, y_train_patch, y_test_patch\n", + "\n", + "def dimensionalityReduction(X, numComponents=75, standardize=True):\n", + " if standardize:\n", + " newX = np.reshape(X, (-1, X.shape[2]))\n", + " scaler = preprocessing.StandardScaler().fit(newX) \n", + " newX = scaler.transform(newX)\n", + " X = np.reshape(newX, (X.shape[0],X.shape[1],X.shape[2]))\n", + " \n", + " newX = np.reshape(X, (-1, X.shape[2]))\n", + " pca = PCA(n_components=numComponents, whiten=True)\n", + " newX = pca.fit_transform(newX)\n", + " newX = np.reshape(newX, (X.shape[0],X.shape[1], numComponents))\n", + " return newX, pca\n", + "\n", + "\n", + "def BoostDataset(X, y, n_samples=0):\n", + " # Techniques from \n", + " # https://medium.com/@thimblot/data-augmentation-boost-your-image-dataset-with-few-lines-of-python-155c2dc1baec\n", + " \n", + " orig_shape = X.shape[0]\n", + " index = orig_shape\n", + " print(\"Boosting Dataset...\")\n", + " for i in range(n_samples):\n", + " if i % 5 == 0 or i + 1 == n_samples:\n", + " printProgressBar(i + 1, n_samples)\n", + " num_sample = random.randint(0, orig_shape)\n", + " patch = X[num_sample,:,:,:]\n", + " #print(patch.shape)\n", + " num = random.randint(0, 4)\n", + " if (num == 0):\n", + " new_patch = np.flipud(patch)\n", + " \n", + " if (num == 1):\n", + " new_patch = np.fliplr(patch)\n", + " \n", + " if (num == 2):\n", + " new_patch = sk.util.random_noise(patch)\n", + " \n", + " if (num == 3 or num == 4):\n", + " random_degree = random.uniform(-25, 25)\n", + " new_patch = sk.transform.rotate(patch, random_degree)\n", + " \n", + " #print(new_patch.shape)\n", + " #time.sleep(5)\n", + " \n", + " X = np.append(X, [new_patch], axis=0)\n", + " y = np.append(y, y[num_sample])\n", + " \n", + " return X, y\n", + "\n", + "def reports (X_test,y_test):\n", + " Y_pred = model.predict(X_test)\n", + " y_pred = np.argmax(Y_pred, axis=1)\n", + " target_names = ['Luzerne',\n", + " 'Maïs- Pas de Technique de Conservation des sols',\n", + " 'Maïs- Minimum Tillage',\n", + " 'Maïs','Herbe-Pâturage',\n", + " 'Herbe-Arbre','Herbe-Pâturage-Tondu','Foin-andains','Avoine',\n", + " 'Soja-Pas de Technique de Conservation des sols', 'Soja-Minimum Tillage','Soja',\n", + " 'Blé', 'BoisBâtiment-Herbe-Arbre-drives', 'Bâtiment-Herbe-Arbre-drives','Pierre-Acier-Tour']\n", + "\n", + " \n", + " classification = classification_report(np.argmax(y_test, axis=1), y_pred, target_names=target_names)\n", + " confusion = confusion_matrix(np.argmax(y_test, axis=1), y_pred)\n", + " score = model.evaluate(X_test, y_test, batch_size=32)\n", + " Test_Loss = score[0]*100\n", + " Test_accuracy = score[1]*100\n", + " \n", + " return classification, confusion, Test_Loss, Test_accuracy\n", + "\n", + "def Patch(data,height_index,width_index):\n", + " #transpose_array = data.transpose((2,0,1))\n", + " #print transpose_array.shape\n", + " height_slice = slice(height_index, height_index+PATCH_SIZE)\n", + " width_slice = slice(width_index, width_index+PATCH_SIZE)\n", + " patch = data[height_slice, width_slice, :]\n", + " \n", + " return patch\n", + "\n", + "\n", + "def oversampleWeakClasses(X, y):\n", + " uniqueLabels, labelCounts = np.unique(y, return_counts=True)\n", + " maxCount = np.max(labelCounts)\n", + " labelInverseRatios = maxCount / labelCounts \n", + " # repeat for every label and concat\n", + " newX = X[y == uniqueLabels[0], :, :, :].repeat(round(labelInverseRatios[0]), axis=0)\n", + " newY = y[y == uniqueLabels[0]].repeat(round(labelInverseRatios[0]), axis=0)\n", + " for label, labelInverseRatio in zip(uniqueLabels[1:], labelInverseRatios[1:]):\n", + " cX = X[y== label,:,:,:].repeat(round(labelInverseRatio), axis=0)\n", + " cY = y[y == label].repeat(round(labelInverseRatio), axis=0)\n", + " print(cX)\n", + " newX = np.concatenate((newX, cX))\n", + " newY = np.concatenate((newY, cY))\n", + " np.random.seed(seed=42)\n", + " rand_perm = np.random.permutation(newY.shape[0])\n", + " newX = newX[rand_perm, :, :, :]\n", + " newY = newY[rand_perm]\n", + " return newX, newY\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load and preprocess data according to our needs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:46:53.834909Z", + "start_time": "2018-11-18T17:46:53.741821Z" + }, + "init_cell": true + }, + "outputs": [], + "source": [ + "X, train_data, test_data = loadData()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:46:54.385476Z", + "start_time": "2018-11-18T17:46:53.837098Z" + }, + "init_cell": true + }, + "outputs": [], + "source": [ + "X, pca = dimensionalityReduction(X, numComponents=numPCAcomponents, standardize=False)\n", + "X.shape" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:46:58.992724Z", + "start_time": "2018-11-18T17:46:54.387999Z" + }, + "init_cell": true + }, + "outputs": [], + "source": [ + "# Add padding, move patch along the array, make image one dimensional, and split provided train and test_data with removing zeros labels at the same time\n", + "# X.shape : (Pixels_in_one_band, patch_row, patch_col, reflectance_band) \n", + "# Pixels_in_one_band.shape = 145 * 145 = 21025\n", + "\n", + "X_train, X_test, y_train, y_test = patch_1dim_split(X, train_data, test_data, PATCH_SIZE)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:46:59.004948Z", + "start_time": "2018-11-18T17:46:58.996442Z" + }, + "init_cell": true, + "scrolled": true + }, + "outputs": [], + "source": [ + "# Check if X and y have compatible shapes (X_*.shape[0] === y_*.shape[0])\n", + "\n", + "print(X_train.shape)\n", + "print(y_train.shape)\n", + "print(X_test.shape)\n", + "print(y_test.shape)\n", + "print(np.unique(y_train, return_counts=True))\n", + "print(np.unique(y_test, return_counts=True))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:00:01.943104Z", + "start_time": "2018-11-18T17:00:01.056374Z" + }, + "deletable": false, + "editable": false, + "init_cell": true, + "run_control": { + "frozen": true + } + }, + "outputs": [], + "source": [ + "X_train, y_train = oversampleWeakClasses(X_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:47:02.313768Z", + "start_time": "2018-11-18T17:46:59.009077Z" + }, + "init_cell": true + }, + "outputs": [], + "source": [ + "# Add samples. Warning: 33.3s for 100 samples on my PC if no dimensionality reduction. There's room for optimization here. \n", + "# Optimization Tip: Array is recreated at each iteration.\n", + "X_train, y_train = BoostDataset(X_train, y_train, n_samples=100)\n", + "print(X_train.shape)\n", + "print(y_train.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:47:02.320616Z", + "start_time": "2018-11-18T17:47:02.316331Z" + }, + "init_cell": true + }, + "outputs": [], + "source": [ + "#X_train = np.reshape(X_train, (X_train.shape[0],X_train.shape[3], X_train.shape[1], X_train.shape[2]))\n", + "#X_test = np.reshape(X_test, (X_test.shape[0],X_test.shape[3], X_test.shape[1], X_test.shape[2]))\n", + "\n", + "y_train = np_utils.to_categorical(y_train, num_classes=16)\n", + "y_test = np_utils.to_categorical(y_test, num_classes=16)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:47:02.359795Z", + "start_time": "2018-11-18T17:47:02.324197Z" + }, + "init_cell": true + }, + "outputs": [], + "source": [ + "input_shape= X_train[0].shape\n", + "print(input_shape)\n", + "\n", + "print(X_train.shape)\n", + "print(y_train.shape)\n", + "print(X_test.shape)\n", + "print(y_test.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:48:01.649862Z", + "start_time": "2018-11-18T17:47:58.323328Z" + } + }, + "outputs": [], + "source": [ + "def sequential_cnn_model(input_shape, optimizer='adam'):\n", + " model = Sequential()\n", + " \n", + " model.add(Conv2D(C1, (3,3), activation='relu', input_shape=input_shape))\n", + " model.add(Conv2D(3*C1, (1,1), activation='relu'))\n", + " model.add(Dropout(0.25))\n", + " \n", + " \n", + " \n", + " model.add(Flatten())\n", + " model.add(Dense(30*numPCAcomponents, activation='relu'))\n", + " model.add(Dropout(0.5))\n", + " model.add(Dense(16, activation='softmax'))\n", + " \n", + " model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n", + " return model\n", + "\n", + "#model = KerasClassifier(build_fn=create_model, verbose=0)\n", + "sequential_cnn_model = sequential_cnn_model(input_shape)\n", + "\n", + "# On a 9 classes en réalité, donc une accuracy > 100/9 ~=11.11 est supérieure au hasard. \n", + "sequential_cnn_model.fit(X_train, y_train,\n", + " batch_size=batch_size,\n", + " epochs=epochs,\n", + " verbose=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:48:04.086421Z", + "start_time": "2018-11-18T17:48:04.034793Z" + }, + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "outputs": [], + "source": [ + "def nin_cnn():\n", + " model = Sequential()\n", + " #mlpconv block 1\n", + " model.add(Conv2D(32, (5, 5), activation='relu',padding='valid', input_shape=input_shape))\n", + " model.add(Conv2D(32, (1, 1), activation='relu'))\n", + " model.add(Conv2D(32, (1, 1), activation='relu'))\n", + " model.add(MaxPooling2D((1,1), dim_ordering=\"th\"))\n", + " model.add(Dropout(0.5))\n", + " \n", + " #mlpconv block2\n", + " model.add(Conv2D(64, (1, 1), activation='relu',padding='valid'))\n", + " model.add(Conv2D(64, (1, 1), activation='relu'))\n", + " model.add(Conv2D(64, (1, 1), activation='relu'))\n", + " model.add(MaxPooling2D((1,1), dim_ordering=\"th\"))\n", + " model.add(Dropout(0.5))\n", + " \n", + " #mlpconv block3\n", + " model.add(Conv2D(128, (1, 1), activation='relu',padding='valid'))\n", + " model.add(Conv2D(32, (1, 1), activation='relu'))\n", + " model.add(Conv2D(16, (1, 1)))\n", + " \n", + " model.add(GlobalAveragePooling2D())\n", + " model.add(Activation(activation='softmax'))\n", + " \n", + " model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n", + " return model\n", + "\n", + "nin_cnn = nin_cnn()\n", + "nin_cnn.fit(X_train, y_train,\n", + " batch_size=batch_size,\n", + " epochs=5,\n", + " verbose=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:48:07.599619Z", + "start_time": "2018-11-18T17:48:06.921262Z" + } + }, + "outputs": [], + "source": [ + "def evaluate_error(model):\n", + " pred = model.predict(X_test, batch_size = 32)\n", + " pred = np.argmax(pred, axis=1)\n", + " pred = np.expand_dims(pred, axis=1) # make same shape as y_test\n", + " error = np.sum(np.not_equal(pred, y_test)) / y_test.shape[0] \n", + " return error\n", + "\n", + "def ensemble(models, model_input):\n", + " \n", + " outputs = [model.outputs[0] for model in models]\n", + " y = Average()(outputs)\n", + " model = Model(model_input, y, name='ensemble')\n", + " \n", + " return model\n", + "\n", + "#models = [nin_cnn, sequential_cnn_model]\n", + "\n", + "#ensemble_model = ensemble(models, input_shape)\n", + "\n", + "print(evaluate_error(sequential_cnn_model))\n", + "#print(evaluate_error(nin_cnn))\n", + "model = sequential_cnn_model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T15:30:26.196422Z", + "start_time": "2018-11-18T15:30:26.163395Z" + }, + "deletable": false, + "editable": false, + "run_control": { + "frozen": true + } + }, + "outputs": [], + "source": [ + "mlb = MultiLabelBinarizer(classes=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])\n", + "y_enc = mlb.fit_transform(y_train)\n", + "clf2 = LogisticRegression()\n", + "print(y_enc)\n", + "voting = VotingClassifier(estimators=[('cnn', model), ('lr', clf2)], weights=[1.0, 1.0])\n", + "voting.fit(X_train, y_enc)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:48:11.619306Z", + "start_time": "2018-11-18T17:48:10.531365Z" + } + }, + "outputs": [], + "source": [ + "classification, confusion, Test_loss, Test_accuracy = reports(X_test,y_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:48:11.671792Z", + "start_time": "2018-11-18T17:48:11.667106Z" + } + }, + "outputs": [], + "source": [ + "print(classification)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:39:10.473656Z", + "start_time": "2018-11-18T17:39:10.469182Z" + } + }, + "outputs": [], + "source": [ + "print(Test_loss)\n", + "print(Test_accuracy)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:39:12.836077Z", + "start_time": "2018-11-18T17:39:12.763198Z" + } + }, + "outputs": [], + "source": [ + "X_garbage, train_data, test_data = loadData()\n", + "#X = dimensionalityReduction(X, )\n", + "y = np.add(train_data, test_data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:39:48.609630Z", + "start_time": "2018-11-18T17:39:13.357726Z" + } + }, + "outputs": [], + "source": [ + "height = y.shape[0]\n", + "width = y.shape[1]\n", + "print(width, height)\n", + "\n", + "# calculate the predicted image\n", + "outputs = np.zeros((height,width)) # zeroed image\n", + "for i in range(0, height-PATCH_SIZE+1):\n", + " for j in range(0, width-PATCH_SIZE+1):\n", + " target = int(y[int(i+PATCH_SIZE/2)][int(j+PATCH_SIZE/2)])\n", + " if target == 0 :\n", + " continue\n", + " else :\n", + " image_patch=Patch(X,i,j)\n", + " #print (image_patch.shape)\n", + " X_test_image = image_patch.reshape(1,image_patch.shape[2],image_patch.shape[0],image_patch.shape[1]).astype('float32') \n", + " prediction = (model.predict_classes(X_test_image)) \n", + " outputs[int(i+PATCH_SIZE/2)][int(j+PATCH_SIZE/2)] = prediction + 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:39:49.072760Z", + "start_time": "2018-11-18T17:39:48.700362Z" + } + }, + "outputs": [], + "source": [ + "ground_truth = spectral.imshow(classes = y,figsize =(5,5))\n", + "print(np.unique(y))\n", + "\n", + "labelPatches = [ patches.Patch(color=spy_colors[x]/255.,\n", + " label=label_dictionary[x]) for x in np.unique(y) ]\n", + "plt.legend(handles=labelPatches, ncol=2, fontsize='medium', \n", + " loc='upper center', bbox_to_anchor=(0.5, -0.05));" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-11-18T17:39:49.283323Z", + "start_time": "2018-11-18T17:39:49.143463Z" + } + }, + "outputs": [], + "source": [ + "predict_image = spectral.imshow(classes = outputs.astype(int),figsize =(5,5))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "celltoolbar": "Initialization Cell", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.5" + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/TP.ipynb b/TP.ipynb new file mode 100644 index 0000000..8a6638e --- /dev/null +++ b/TP.ipynb @@ -0,0 +1,272 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "im1=np.random.randint(0,255, size=(50,50)).astype(np.float32)\n", + "im2=np.random.randint(0,255, size=(50,50,3)).astype(np.float32)\n", + "\n", + "ax1=plt.subplot(121)\n", + "ax2=plt.subplot(122)\n", + "ax1.imshow(im1,cmap='gray')\n", + "ax1.set_title(\"Image d'une matrice 2D\")\n", + "ax2.imshow(im2)\n", + "ax2.set_title(\"Image d'une matrice 3D\")\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/meryll/miniconda3/envs/eca/lib/python3.5/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n", + " from ._conv import register_converters as _register_converters\n", + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "import keras\n", + "from keras.datasets import mnist\n", + "from keras.layers import Dense, Flatten\n", + "from keras.layers import Conv2D, MaxPooling2D\n", + "from keras.models import Model\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n", + "w, h = 28, 28 #taille des images\n", + "\n", + "plt.imshow(x_train[2],cmap=\"gray\")\n", + "print(y_train[2])\n", + "plt.title(\"Première image dans x_train\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "x_train = x_train.reshape(x_train.shape[0], w, h, 1)\n", + "x_test = x_test.reshape(x_test.shape[0], w, h, 1)\n", + "mon_shape = (w, h, 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "x_train = x_train.astype('float32')\n", + "x_test = x_test.astype('float32')\n", + "x_train /= 255\n", + "x_test /= 255" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initial: 5\n", + "Transformed: [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]\n" + ] + } + ], + "source": [ + "print(\"Initial:\",y_train[0])\n", + "num_classes=10\n", + "y_train = keras.utils.to_categorical(y_train, num_classes)\n", + "y_test = keras.utils.to_categorical(y_test, num_classes)\n", + "print(\"Transformed:\",y_train[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "mon_input=keras.engine.input_layer.Input(shape=mon_shape)\n", + "\n", + "# Feature Extraction\n", + "cnn=Conv2D(32, kernel_size=(5, 5), strides=(1, 1),activation='relu')(mon_input)\n", + "cnn=MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(cnn)\n", + "cnn=Conv2D(64, (5, 5), activation='relu')(cnn)\n", + "cnn=MaxPooling2D(pool_size=(2, 2))(cnn)\n", + "\n", + "# Learning Process\n", + "output_cnn=Flatten()(cnn)\n", + "cnn=Dense(1000, activation='relu')(output_cnn)\n", + "cnn=Dense(num_classes, activation='softmax')(cnn)\n", + "\n", + "# Building the model\n", + "model=Model(inputs=[mon_input], outputs=[cnn])" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "model.compile(loss=keras.losses.categorical_crossentropy,\n", + " optimizer=keras.optimizers.Adam(),\n", + " metrics=['accuracy'])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "mon_batch_size = 128\n", + "epo = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 60000 samples, validate on 10000 samples\n", + "Epoch 1/1\n", + "60000/60000 [==============================] - 35s 590us/step - loss: 0.0246 - acc: 0.9924 - val_loss: 0.0271 - val_acc: 0.9906\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.fit(x_train, y_train,\n", + " batch_size=mon_batch_size,\n", + " epochs=epo,\n", + " verbose=1,\n", + " validation_data=(x_test, y_test))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[7, 5, 4, 1, 3, 2, 8, 9, 6, 0]])" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# plt.imshow(x_train[2],cmap=\"gray\")\n", + "# plt.title(\"Première image dans x_train\")\n", + "# plt.show()\n", + "np.argsort(model.predict(np.array([x_train[1]])))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/test_data.npy b/test_data.npy new file mode 100644 index 0000000..92717b7 Binary files /dev/null and b/test_data.npy differ diff --git a/train_data.npy b/train_data.npy new file mode 100644 index 0000000..867a985 Binary files /dev/null and b/train_data.npy differ