├── .gitignore ├── .ipynb_checkpoints └── 3DConv_example-checkpoint.ipynb ├── 3DkerasConv_example.ipynb ├── 3DpytorchConv_example.ipynb ├── README.md ├── keras_model.py ├── plot3D.py ├── pytorch_model.py └── voxelgrid.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .ipynb_checkpoints 3 | -------------------------------------------------------------------------------- /3DkerasConv_example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 19, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os\n", 10 | "os.environ[\"CUDA_DEVICE_ORDER\"] = \"PCI_BUS_ID\" #if like me you do not have a lot of memory in your GPU\n", 11 | "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"\" #then these two lines force keras to use your CPU\n", 12 | "import keras\n", 13 | "from keras.models import Sequential\n", 14 | "from keras.layers import Dense, Flatten, Conv3D, MaxPooling3D, Dropout, BatchNormalization\n", 15 | "from keras.utils import to_categorical\n", 16 | "import numpy as np\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "import h5py\n", 19 | "from plot3D import *" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 20, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "def array_to_color(array, cmap=\"Oranges\"):\n", 29 | " s_m = plt.cm.ScalarMappable(cmap=cmap)\n", 30 | " return s_m.to_rgba(array)[:,:-1]\n", 31 | "\n", 32 | "\n", 33 | "def rgb_data_transform(data):\n", 34 | " data_t = []\n", 35 | " for i in range(data.shape[0]):\n", 36 | " data_t.append(array_to_color(data[i]).reshape(16, 16, 16, 3))\n", 37 | " return np.asarray(data_t, dtype=np.float32)" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 77, 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "with h5py.File(\"./train_point_clouds.h5\", \"r\") as hf: \n", 47 | " a = hf[\"0\"]\n", 48 | " b = a['img'][:]\n", 49 | " s = a['points'][:]" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 94, 55 | "metadata": {}, 56 | "outputs": [ 57 | { 58 | "data": { 59 | "text/plain": [ 60 | "Text(0.5, 1.0, 'The figure 5 in 2d')" 61 | ] 62 | }, 63 | "execution_count": 94, 64 | "metadata": {}, 65 | "output_type": "execute_result" 66 | }, 67 | { 68 | "data": { 69 | "image/png": "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\n", 70 | "text/plain": [ 71 | "
" 72 | ] 73 | }, 74 | "metadata": { 75 | "needs_background": "light" 76 | }, 77 | "output_type": "display_data" 78 | } 79 | ], 80 | "source": [ 81 | "plt.imshow(b)\n", 82 | "plt.title('The figure 5 in 2d')" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 93, 88 | "metadata": {}, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "text/plain": [ 93 | "Text(0.5, 0.92, 'The figure 5 in 3d Cloud point')" 94 | ] 95 | }, 96 | "execution_count": 93, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | }, 100 | { 101 | "data": { 102 | "image/png": "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\n", 103 | "text/plain": [ 104 | "
" 105 | ] 106 | }, 107 | "metadata": { 108 | "needs_background": "light" 109 | }, 110 | "output_type": "display_data" 111 | } 112 | ], 113 | "source": [ 114 | "import matplotlib.pyplot as plt\n", 115 | "from mpl_toolkits.mplot3d import Axes3D\n", 116 | "fig = plt.figure()\n", 117 | "ax = fig.add_subplot(111, projection='3d')\n", 118 | "ax.scatter(s[:,0], s[:,1], zs=s[:,2])\n", 119 | "ax.view_init(10, 0)\n", 120 | "plt.title('The figure 5 in 3d Cloud point')\n" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 83, 126 | "metadata": {}, 127 | "outputs": [ 128 | { 129 | "data": { 130 | "text/plain": [ 131 | "array([0.15, 0.15, 0.15, ..., 0.15, 0.15, 0.15])" 132 | ] 133 | }, 134 | "execution_count": 83, 135 | "metadata": {}, 136 | "output_type": "execute_result" 137 | } 138 | ], 139 | "source": [ 140 | "s[:,0]" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 21, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [ 149 | "with h5py.File(\"./full_dataset_vectors.h5\", \"r\") as hf: \n", 150 | "\n", 151 | " # Split the data into training/test features/targets\n", 152 | " X_train = hf[\"X_train\"][:]\n", 153 | " targets_train = hf[\"y_train\"][:]\n", 154 | " X_test = hf[\"X_test\"][:] \n", 155 | " targets_test = hf[\"y_test\"][:]\n", 156 | "\n", 157 | " # Determine sample shape\n", 158 | " sample_shape = (16, 16, 16, 3)\n", 159 | "\n", 160 | " # Reshape data into 3D format\n", 161 | " X_train = rgb_data_transform(X_train)\n", 162 | " X_test = rgb_data_transform(X_test)\n", 163 | "\n", 164 | " # Convert target vectors to categorical targets\n", 165 | " targets_train = to_categorical(targets_train).astype(np.integer)\n", 166 | " targets_test = to_categorical(targets_test).astype(np.integer)" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 25, 172 | "metadata": {}, 173 | "outputs": [ 174 | { 175 | "data": { 176 | "text/plain": [ 177 | "(10000, 16, 16, 16, 3)" 178 | ] 179 | }, 180 | "execution_count": 25, 181 | "metadata": {}, 182 | "output_type": "execute_result" 183 | } 184 | ], 185 | "source": [ 186 | "X_train.shape" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": 11, 192 | "metadata": {}, 193 | "outputs": [ 194 | { 195 | "name": "stdout", 196 | "output_type": "stream", 197 | "text": [ 198 | "_________________________________________________________________\n", 199 | "Layer (type) Output Shape Param # \n", 200 | "=================================================================\n", 201 | "conv3d_5 (Conv3D) (None, 14, 14, 14, 32) 2624 \n", 202 | "_________________________________________________________________\n", 203 | "max_pooling3d_5 (MaxPooling3 (None, 7, 7, 7, 32) 0 \n", 204 | "_________________________________________________________________\n", 205 | "batch_normalization_5 (Batch (None, 7, 7, 7, 32) 128 \n", 206 | "_________________________________________________________________\n", 207 | "dropout_5 (Dropout) (None, 7, 7, 7, 32) 0 \n", 208 | "_________________________________________________________________\n", 209 | "conv3d_6 (Conv3D) (None, 5, 5, 5, 64) 55360 \n", 210 | "_________________________________________________________________\n", 211 | "max_pooling3d_6 (MaxPooling3 (None, 2, 2, 2, 64) 0 \n", 212 | "_________________________________________________________________\n", 213 | "batch_normalization_6 (Batch (None, 2, 2, 2, 64) 256 \n", 214 | "_________________________________________________________________\n", 215 | "dropout_6 (Dropout) (None, 2, 2, 2, 64) 0 \n", 216 | "_________________________________________________________________\n", 217 | "flatten_3 (Flatten) (None, 512) 0 \n", 218 | "_________________________________________________________________\n", 219 | "dense_6 (Dense) (None, 256) 131328 \n", 220 | "_________________________________________________________________\n", 221 | "dense_7 (Dense) (None, 256) 65792 \n", 222 | "_________________________________________________________________\n", 223 | "dense_8 (Dense) (None, 10) 2570 \n", 224 | "=================================================================\n", 225 | "Total params: 258,058\n", 226 | "Trainable params: 257,866\n", 227 | "Non-trainable params: 192\n", 228 | "_________________________________________________________________\n", 229 | "Train on 7000 samples, validate on 3000 samples\n", 230 | "Epoch 1/40\n", 231 | "7000/7000 [==============================] - 58s 8ms/step - loss: 2.3676 - acc: 0.2370 - val_loss: 2.2420 - val_acc: 0.2550\n", 232 | "Epoch 2/40\n", 233 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.7167 - acc: 0.4010 - val_loss: 3.1162 - val_acc: 0.1757\n", 234 | "Epoch 3/40\n", 235 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.5015 - acc: 0.4719 - val_loss: 2.8639 - val_acc: 0.2753\n", 236 | "Epoch 4/40\n", 237 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.3902 - acc: 0.5133 - val_loss: 2.1104 - val_acc: 0.2743\n", 238 | "Epoch 5/40\n", 239 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.3139 - acc: 0.5340 - val_loss: 2.1778 - val_acc: 0.3483\n", 240 | "Epoch 6/40\n", 241 | "7000/7000 [==============================] - 57s 8ms/step - loss: 1.2671 - acc: 0.5517 - val_loss: 1.5701 - val_acc: 0.4980\n", 242 | "Epoch 7/40\n", 243 | "7000/7000 [==============================] - 57s 8ms/step - loss: 1.2165 - acc: 0.5714 - val_loss: 1.8289 - val_acc: 0.4337\n", 244 | "Epoch 8/40\n", 245 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.1817 - acc: 0.5841 - val_loss: 2.2599 - val_acc: 0.3767\n", 246 | "Epoch 9/40\n", 247 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.1384 - acc: 0.5897 - val_loss: 1.1648 - val_acc: 0.6040\n", 248 | "Epoch 10/40\n", 249 | "7000/7000 [==============================] - 59s 8ms/step - loss: 1.1138 - acc: 0.6080 - val_loss: 3.9893 - val_acc: 0.3127\n", 250 | "Epoch 11/40\n", 251 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.1113 - acc: 0.6054 - val_loss: 2.4966 - val_acc: 0.3363\n", 252 | "Epoch 12/40\n", 253 | "7000/7000 [==============================] - 57s 8ms/step - loss: 1.0622 - acc: 0.6229 - val_loss: 2.8265 - val_acc: 0.3490\n", 254 | "Epoch 13/40\n", 255 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.0361 - acc: 0.6299 - val_loss: 2.4906 - val_acc: 0.2810\n", 256 | "Epoch 14/40\n", 257 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.0245 - acc: 0.6359 - val_loss: 2.0394 - val_acc: 0.4407\n", 258 | "Epoch 15/40\n", 259 | "7000/7000 [==============================] - 58s 8ms/step - loss: 1.0037 - acc: 0.6434 - val_loss: 1.9587 - val_acc: 0.4457\n", 260 | "Epoch 16/40\n", 261 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.9765 - acc: 0.6504 - val_loss: 1.3614 - val_acc: 0.5417\n", 262 | "Epoch 17/40\n", 263 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.9760 - acc: 0.6570 - val_loss: 1.2486 - val_acc: 0.5853\n", 264 | "Epoch 18/40\n", 265 | "7000/7000 [==============================] - 57s 8ms/step - loss: 0.9651 - acc: 0.6549 - val_loss: 3.0945 - val_acc: 0.2987\n", 266 | "Epoch 19/40\n", 267 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.9228 - acc: 0.6730 - val_loss: 4.0645 - val_acc: 0.2487\n", 268 | "Epoch 20/40\n", 269 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.9248 - acc: 0.6719 - val_loss: 1.6638 - val_acc: 0.5033\n", 270 | "Epoch 21/40\n", 271 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.8943 - acc: 0.6793 - val_loss: 3.4135 - val_acc: 0.3223\n", 272 | "Epoch 22/40\n", 273 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.8896 - acc: 0.6784 - val_loss: 1.1511 - val_acc: 0.5993\n", 274 | "Epoch 23/40\n", 275 | "7000/7000 [==============================] - 59s 8ms/step - loss: 0.8914 - acc: 0.6853 - val_loss: 2.7482 - val_acc: 0.3923\n", 276 | "Epoch 24/40\n", 277 | "7000/7000 [==============================] - 59s 8ms/step - loss: 0.8520 - acc: 0.6927 - val_loss: 1.3216 - val_acc: 0.5527\n", 278 | "Epoch 25/40\n", 279 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.8364 - acc: 0.7050 - val_loss: 1.7432 - val_acc: 0.5393\n", 280 | "Epoch 26/40\n", 281 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.8310 - acc: 0.7070 - val_loss: 2.1237 - val_acc: 0.4790\n", 282 | "Epoch 27/40\n", 283 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.8218 - acc: 0.7089 - val_loss: 4.6784 - val_acc: 0.3017\n", 284 | "Epoch 28/40\n", 285 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.7997 - acc: 0.7184 - val_loss: 2.4186 - val_acc: 0.3600\n", 286 | "Epoch 29/40\n", 287 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.7938 - acc: 0.7173 - val_loss: 3.3102 - val_acc: 0.3877\n", 288 | "Epoch 30/40\n", 289 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.7841 - acc: 0.7183 - val_loss: 4.4051 - val_acc: 0.3220\n", 290 | "Epoch 31/40\n", 291 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.7459 - acc: 0.7320 - val_loss: 2.2222 - val_acc: 0.4617\n", 292 | "Epoch 32/40\n", 293 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.7437 - acc: 0.7351 - val_loss: 1.4211 - val_acc: 0.6347\n", 294 | "Epoch 33/40\n", 295 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.7270 - acc: 0.7430 - val_loss: 1.1060 - val_acc: 0.6340\n", 296 | "Epoch 34/40\n", 297 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.7133 - acc: 0.7459 - val_loss: 2.3321 - val_acc: 0.4570\n", 298 | "Epoch 35/40\n", 299 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.7115 - acc: 0.7454 - val_loss: 1.5243 - val_acc: 0.5893\n", 300 | "Epoch 36/40\n", 301 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.6886 - acc: 0.7636 - val_loss: 4.3696 - val_acc: 0.3290\n", 302 | "Epoch 37/40\n", 303 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.6978 - acc: 0.7557 - val_loss: 3.8689 - val_acc: 0.3210\n", 304 | "Epoch 38/40\n", 305 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.6670 - acc: 0.7620 - val_loss: 1.7261 - val_acc: 0.4840\n", 306 | "Epoch 39/40\n", 307 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.6650 - acc: 0.7657 - val_loss: 6.4489 - val_acc: 0.2697\n", 308 | "Epoch 40/40\n", 309 | "7000/7000 [==============================] - 58s 8ms/step - loss: 0.6421 - acc: 0.7733 - val_loss: 1.5427 - val_acc: 0.5427\n", 310 | "Test loss: 1.579768424987793 / Test accuracy: 0.5235\n" 311 | ] 312 | }, 313 | { 314 | "data": { 315 | "image/png": "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d+70e/44IdbXda0y737V+5JVtyyLSvfAcg1Dz8Zc0Xu/Qin96e98rxc8/XlEX9Pf+T7oAX3iiSf0lltu8busrKxM8/LyVFU1JydHe/TooZWVlVUucFWj3OyLpqKiQseMGaOfffaZfvXVV54L7ODBg9qzZ0+PAk9LS9OFCxeqquo999yjN998s6oapf+b3/zG07e30j/llFP0zTffVFXV4uJiLSwsDCijqn+l//333+sJJ5ygOTk5qqqam5urqkbpjxkzRsvLy1VV9YYbbtDp06erqrkxZmRkqKrqOeeco0uWLFFVc1MsKyvTRx99VB944AFVVS0vL9eDBw9qTk6ODh48WAsKClRV9aGHHtL7779fVY3ie/LJJ1VV9e9//7v+6le/OmJfw5Hpvvvu0/T0dC0qKtKcnBzt0qWLbt++XRcuXKjnnXeeqqoeOHBAU1NTtaysrMrx2LBhg2ZlZXm+z5gxQ6+//voqxz8rK8ujkAsLC7W4uFhVVdesWaP2Oe2r9Lt3764HDhzQ4uJiPfbYY3XLli2efbeVfkJCgq5cuVJVVc8//3ydNWuWqqr26dPHczO57bbb/Cr9N954Q0eNGqXl5eW6fft2TUlJ8Sh9+z9VNTe+d955R1XNufXVV195lgVqp6p61VVX6euvv37Edp1Sr5T+e9OM0l/3aVS6D1fpx32cfjyjqtx5550sWrSIBg0asH37dr9un48//piPP/6Yvn37AlBQUMDatWvJz8/nvPPOo2nTpgCce+65AOTl5XHgwAGGDjX1jS+77DLOP/98T38XXnjhEdvIz89n+/btjB8/HjATYMBMbvMn4zHHHON3n+bPn8+kSZNo27YtAK1bt/YsO//880lISABgyZIlvPHGGwCMGDGC3Nxc8vLyGDhwIFOnTmXKlClMmDCBLl260L9/f6688krKysoYN24cmZmZfPbZZ6xevZqBAwcCcOjQIU477TTPtiZMmABAv379ePNN37LHh3EiE+A5zk2bNmX48OEsW7aMcePGcf3117Nnzx7efPNNJk6cSMOGVS+JnTt30q5d8ASGY8eO9fyHZWVl3HDDDaxatYqEhISAYz8jR44kJSUFgN69e7N582a6du1apU337t3JzMz0HIdNmzZx4MAB8vPzOf300wG4+OKLeffdd4/of9GiRUyePJmEhAQ6derEiBEjPMsWLFjAww8/TFFREfv27aNPnz6ec8+bYO3at2/vyBXkAhwqsN4DleatXeqU0r/v3D61vs0+ffoE9MW+9NJL5OTksGLFChITE0lNTfUbf6yq3HHHHfz617+u8vtjjz1WLZmaN2/udxs1kdG7n0Ahdd7b9bc9EeH2229nzJgxvP/++wwYMIB58+YxZMgQFi1axHvvvcell17KtGnTaNWqFaNHj+aVV17xu63GjRsDkJCQENRX7kQm73ff3y+99FJeeuklZs+ezfPPP3/E+k2bNg0ZU+4tw2OPPUaHDh345ptvqKys9Nx8fbH3DwLvo2+b4uLigP+zP/z9jyUlJVx33XUsX76crl27Mn36dL/7F6pdSUmJ50bnEoLSg9Z7QWzlsHAHckMwYsQISktLefbZZz2/ffXVV3z22Wfk5eXRvn17EhMTWbBgAZs3mwynSUlJ5Ofne9r/4he/4Pnnn6egwPzp27dvZ8+ePQwaNIj//ve/lJSUUFBQwHvvvQdASkoKrVq1YvHixQDMmjXLY/UHIjk5mS5duvDWW28BUFpaSlFRUUAZAzFy5EheffVVcnNzAdi3b5/fdkOGDOGll14CzABr27ZtSU5OZv369aSlpXHbbbeRnZ3NTz/9xObNm2nfvj1XX301v/rVr/j6668ZMGAAS5cuZd26dQAUFRUFjYjyd1ydygTw9ttvU1JSQm5uLgsXLqR///6AiWp5/PHHAXOD9+WEE05g06ZNjmXIy8ujY8eONGjQgFmzZlFRURF0n8KlVatWJCUl8b///Q+A2bNn+203ZMgQZs+eTUVFBTt37mTBggUAHsXdtm1bCgoKqhg03vsWrB3AmjVrOPnkkyO6b0cttrI/FB9Kv05Z+rFARJg7dy633HILDz30EE2aNCE1NZXHH3/c87ibnZ1NZmYmvXr1AqBNmzYMHDiQk08+mbPOOotHHnmEH3/80eO+aNGiBf/5z3/o378/Y8eOJSMjg27dupGdne155H/hhRe49tprKSoq4rjjjmPGjBkhZZ01axa//vWvuffee0lMTOS1115jypQpfmUMRJ8+fbjrrrsYOnQoCQkJ9O3bl5kzZx7Rbvr06VxxxRWkp6fTrFkzXnjhBQAef/xxFixYQEJCAr179+ass85i9uzZPPLIIyQmJtKiRQtefPFF2rVrx8yZM5k8eTKlpaUAPPDAA5xwwgkBZTv33HOZNGkSb7/9Nv/3f//nWCaAU045hTFjxrBlyxbuueceOnXqBECHDh046aSTGDdunN9tNm/enB49erBu3Tp69uzJ8OHDeeihh8jMzOSOO+44ov11113HxIkTee211xg+fLjfp7Ka8txzz3H11VfTvHlzhg0b5jlnvBk/fjzz588nLS2NE044wWM0tGzZkquvvpq0tDRSU1M9Nz8wN8Brr72Wpk2b8sUXXwRsV1ZWxrp168jOzo74vh2VlOZXfY814QwARPsVj9E70caOWCksLNR+/frpihUrYizR0YfvALA3hYWFetxxx+mBAwcCrv/mm2/qXXfdFS3xwsY+Z1RVH3zwQb3ppptqdftvvvmm3n333TXq42i/rqvw1ClmIHfe/VHpHncgt25xzTXXsHr1akpKSrjsssvIysqKtUj1hnnz5nHllVcydepUv9ayzfjx4z3urnjgvffe48EHH6S8vJxu3br5fRKLJuXl5fzud7+r1W3WaTyWfny4d0TDGBiKNtnZ2epbLvHHH3/kpJNOipFELi4u0aBeXdcPHguleZA5BcZFftKmiKxQVce+tqgO5IpISxF5XUR+EpEfReS00Gu5uLi4HCWowqH48ulH273zBPChqk4SkUZAsyhvz8XFxSV+KCsCrTSfj/boHRFJBoYAlwOo6iHgULS25+Li4hJ3ePvx48SnH033znFADjBDRFaKyL9F5Ij4NRG5RkSWi8jynJycKIrj4uLiUst4u3TixNKPptJvCGQB/1TVvkAhcLtvI1V9RlWzVTU71HT3WOGmVo4P4iG1crgsXLjQs+4777wTMDtlqP/C95xymqo5XLzlDYTT9NLfffcdl19+eYQkq6PY/vwmLeuFpb8N2KaqX1rfX8fcBOoUqm5qZX/bjQXxkFq5JowdO5bbbz/C7nGE7znlNFVzNHCq9NPS0ti2bRtbtmypBaniFNvST+p4+AYQY6Km9FV1F7BVRE60fhoJrI7W9qLFggULSExM5Nprr/X8lpmZyeDBgykoKGDkyJFkZWWRlpbG22+/DcDtt9/O+vXryczMZNq0aQA88sgj9O/fn/T0dO677z5PX3/84x/p1asXo0ePZvLkyTz66KOAubAGDBhAeno648ePZ//+/QAMGzaMO++8k6FDh/LEE08wffp0zzrr1q1j1KhRZGRkkJWVxfr16wPKGIwXX3yR9PR0MjIyuPTS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\n", 316 | "text/plain": [ 317 | "
" 318 | ] 319 | }, 320 | "metadata": { 321 | "needs_background": "light" 322 | }, 323 | "output_type": "display_data" 324 | } 325 | ], 326 | "source": [ 327 | "# Create the model\n", 328 | "model = Sequential()\n", 329 | "model.add(Conv3D(32, kernel_size=(3, 3, 3), activation='relu', kernel_initializer='he_uniform', input_shape=sample_shape))\n", 330 | "model.add(MaxPooling3D(pool_size=(2, 2, 2)))\n", 331 | "model.add(BatchNormalization(center=True, scale=True))\n", 332 | "model.add(Dropout(0.5))\n", 333 | "model.add(Conv3D(64, kernel_size=(3, 3, 3), activation='relu', kernel_initializer='he_uniform'))\n", 334 | "model.add(MaxPooling3D(pool_size=(2, 2, 2)))\n", 335 | "model.add(BatchNormalization(center=True, scale=True))\n", 336 | "model.add(Dropout(0.5))\n", 337 | "model.add(Flatten())\n", 338 | "model.add(Dense(256, activation='relu', kernel_initializer='he_uniform'))\n", 339 | "model.add(Dense(256, activation='relu', kernel_initializer='he_uniform'))\n", 340 | "model.add(Dense(10, activation='softmax'))\n", 341 | "\n", 342 | "# Compile the model\n", 343 | "model.compile(loss='categorical_crossentropy',\n", 344 | " optimizer=keras.optimizers.Adam(lr=0.001),\n", 345 | " metrics=['accuracy'])\n", 346 | "model.summary()\n", 347 | "# Fit data to model\n", 348 | "history = model.fit(X_train, targets_train,\n", 349 | " batch_size=128,\n", 350 | " epochs=40,\n", 351 | " verbose=1,\n", 352 | " validation_split=0.3)\n", 353 | "\n", 354 | "# Generate generalization metrics\n", 355 | "score = model.evaluate(X_test, targets_test, verbose=0)\n", 356 | "print(f'Test loss: {score[0]} / Test accuracy: {score[1]}')\n", 357 | "\n", 358 | "# Plot history: Categorical crossentropy & Accuracy\n", 359 | "plt.plot(history.history['loss'], label='Categorical crossentropy (training data)')\n", 360 | "plt.plot(history.history['val_loss'], label='Categorical crossentropy (validation data)')\n", 361 | "plt.plot(history.history['acc'], label='Accuracy (training data)')\n", 362 | "plt.plot(history.history['val_acc'], label='Accuracy (validation data)')\n", 363 | "plt.title('Model performance for 3D MNIST Keras Conv3D example')\n", 364 | "plt.ylabel('Loss value')\n", 365 | "plt.xlabel('No. epoch')\n", 366 | "plt.legend(loc=\"upper left\")\n", 367 | "plt.show()" 368 | ] 369 | }, 370 | { 371 | "cell_type": "code", 372 | "execution_count": null, 373 | "metadata": {}, 374 | "outputs": [], 375 | "source": [] 376 | } 377 | ], 378 | "metadata": { 379 | "kernelspec": { 380 | "display_name": "Python 3", 381 | "language": "python", 382 | "name": "python3" 383 | }, 384 | "language_info": { 385 | "codemirror_mode": { 386 | "name": "ipython", 387 | "version": 3 388 | }, 389 | "file_extension": ".py", 390 | "mimetype": "text/x-python", 391 | "name": "python", 392 | "nbconvert_exporter": "python", 393 | "pygments_lexer": "ipython3", 394 | "version": "3.7.6" 395 | } 396 | }, 397 | "nbformat": 4, 398 | "nbformat_minor": 4 399 | } 400 | -------------------------------------------------------------------------------- /3DpytorchConv_example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "# importing the libraries\n", 10 | "import pandas as pd\n", 11 | "import numpy as np\n", 12 | "from tqdm import tqdm\n", 13 | "import os\n", 14 | "\n", 15 | "# for reading and displaying images\n", 16 | "from skimage.io import imread\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "\n", 19 | "# for creating validation set\n", 20 | "from sklearn.model_selection import train_test_split\n", 21 | "# for evaluating the model\n", 22 | "from sklearn.metrics import accuracy_score\n", 23 | "\n", 24 | "\n", 25 | "# PyTorch libraries and modules\n", 26 | "import torch\n", 27 | "from torch.autograd import Variable\n", 28 | "import torch.nn as nn\n", 29 | "import torch.nn.functional as F\n", 30 | "from torch.optim import *\n", 31 | "import h5py\n", 32 | "from plot3D import *\n", 33 | "\n", 34 | "np.random.seed(47)\n", 35 | "%matplotlib inline" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 3, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "def array_to_color(array, cmap=\"Oranges\"):\n", 45 | " s_m = plt.cm.ScalarMappable(cmap=cmap)\n", 46 | " return s_m.to_rgba(array)[:,:-1]\n", 47 | "\n", 48 | "\n", 49 | "def rgb_data_transform(data):\n", 50 | " data_t = []\n", 51 | " for i in range(data.shape[0]):\n", 52 | " data_t.append(array_to_color(data[i]).reshape(16, 16, 16, 3))\n", 53 | " return np.asarray(data_t, dtype=np.float32)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 4, 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "with h5py.File(\"./train_point_clouds.h5\", \"r\") as hf: \n", 63 | " a = hf[\"0\"]\n", 64 | " b = a['img'][:]\n", 65 | " s = a['points'][:]" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 5, 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/plain": [ 76 | "Text(0.5, 1.0, 'The figure 5 in 2d')" 77 | ] 78 | }, 79 | "execution_count": 5, 80 | "metadata": {}, 81 | "output_type": "execute_result" 82 | }, 83 | { 84 | "data": { 85 | "image/png": "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\n", 86 | "text/plain": [ 87 | "
" 88 | ] 89 | }, 90 | "metadata": { 91 | "needs_background": "light" 92 | }, 93 | "output_type": "display_data" 94 | } 95 | ], 96 | "source": [ 97 | "plt.imshow(b)\n", 98 | "plt.title('The figure 5 in 2d')" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 6, 104 | "metadata": {}, 105 | "outputs": [ 106 | { 107 | "data": { 108 | "text/plain": [ 109 | "Text(0.5, 0.92, 'The figure 5 in 3d Cloud point')" 110 | ] 111 | }, 112 | "execution_count": 6, 113 | "metadata": {}, 114 | "output_type": "execute_result" 115 | }, 116 | { 117 | "data": { 118 | "image/png": "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\n", 119 | "text/plain": [ 120 | "
" 121 | ] 122 | }, 123 | "metadata": { 124 | "needs_background": "light" 125 | }, 126 | "output_type": "display_data" 127 | } 128 | ], 129 | "source": [ 130 | "import matplotlib.pyplot as plt\n", 131 | "from mpl_toolkits.mplot3d import Axes3D\n", 132 | "fig = plt.figure()\n", 133 | "ax = fig.add_subplot(111, projection='3d')\n", 134 | "ax.scatter(s[:,0], s[:,1], zs=s[:,2])\n", 135 | "ax.view_init(10, 0)\n", 136 | "plt.title('The figure 5 in 3d Cloud point')\n" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 7, 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "with h5py.File(\"./full_dataset_vectors.h5\", \"r\") as hf: \n", 146 | "\n", 147 | " # Split the data into training/test features/targets\n", 148 | " X_train = hf[\"X_train\"][:]\n", 149 | " targets_train = hf[\"y_train\"][:]\n", 150 | " X_test = hf[\"X_test\"][:] \n", 151 | " targets_test = hf[\"y_test\"][:]\n", 152 | "\n", 153 | " # Determine sample shape\n", 154 | " sample_shape = (16, 16, 16, 3)\n", 155 | "\n", 156 | " # Reshape data into 3D format\n", 157 | " X_train = rgb_data_transform(X_train)\n", 158 | " X_test = rgb_data_transform(X_test)\n", 159 | "\n", 160 | "# # Convert target vectors to categorical targets\n", 161 | "# targets_train = to_categorical(targets_train).astype(np.integer)\n", 162 | "# targets_test = to_categorical(targets_test).astype(np.integer)" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 8, 168 | "metadata": {}, 169 | "outputs": [ 170 | { 171 | "data": { 172 | "text/plain": [ 173 | "((10000, 16, 16, 16, 3), (2000, 16, 16, 16, 3))" 174 | ] 175 | }, 176 | "execution_count": 8, 177 | "metadata": {}, 178 | "output_type": "execute_result" 179 | } 180 | ], 181 | "source": [ 182 | "X_train.shape, X_test.shape" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": 9, 188 | "metadata": {}, 189 | "outputs": [], 190 | "source": [ 191 | "X_train = X_train.reshape(10000,3,16,16,16)\n", 192 | "X_test = X_test.reshape(2000,3,16,16,16)" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 10, 198 | "metadata": {}, 199 | "outputs": [ 200 | { 201 | "data": { 202 | "text/plain": [ 203 | "((10000,), (2000,))" 204 | ] 205 | }, 206 | "execution_count": 10, 207 | "metadata": {}, 208 | "output_type": "execute_result" 209 | } 210 | ], 211 | "source": [ 212 | "targets_train.shape, targets_test.shape" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": 11, 218 | "metadata": {}, 219 | "outputs": [], 220 | "source": [ 221 | "train_x = torch.from_numpy(X_train).float()\n", 222 | "train_y = torch.from_numpy(targets_train).long()" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": 12, 228 | "metadata": {}, 229 | "outputs": [], 230 | "source": [ 231 | "test_x = torch.from_numpy(X_test).float()\n", 232 | "test_y = torch.from_numpy(targets_test).long()" 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": 13, 238 | "metadata": {}, 239 | "outputs": [], 240 | "source": [ 241 | "# batch_size, epoch and iteration\n", 242 | "batch_size = 100\n", 243 | "\n", 244 | "\n", 245 | "# Pytorch train and test sets\n", 246 | "train = torch.utils.data.TensorDataset(train_x,train_y)\n", 247 | "test = torch.utils.data.TensorDataset(test_x,test_y)\n", 248 | "\n", 249 | "# data loader\n", 250 | "train_loader = torch.utils.data.DataLoader(train, batch_size = batch_size, shuffle = False)\n", 251 | "test_loader = torch.utils.data.DataLoader(test, batch_size = batch_size, shuffle = False)" 252 | ] 253 | }, 254 | { 255 | "cell_type": "code", 256 | "execution_count": 20, 257 | "metadata": {}, 258 | "outputs": [ 259 | { 260 | "name": "stdout", 261 | "output_type": "stream", 262 | "text": [ 263 | "CNNModel(\n", 264 | " (conv_layer1): Sequential(\n", 265 | " (0): Conv3d(3, 32, kernel_size=(3, 3, 3), stride=(1, 1, 1))\n", 266 | " (1): LeakyReLU(negative_slope=0.01)\n", 267 | " (2): MaxPool3d(kernel_size=(2, 2, 2), stride=(2, 2, 2), padding=0, dilation=1, ceil_mode=False)\n", 268 | " )\n", 269 | " (conv_layer2): Sequential(\n", 270 | " (0): Conv3d(32, 64, kernel_size=(3, 3, 3), stride=(1, 1, 1))\n", 271 | " (1): LeakyReLU(negative_slope=0.01)\n", 272 | " (2): MaxPool3d(kernel_size=(2, 2, 2), stride=(2, 2, 2), padding=0, dilation=1, ceil_mode=False)\n", 273 | " )\n", 274 | " (fc1): Linear(in_features=512, out_features=128, bias=True)\n", 275 | " (fc2): Linear(in_features=128, out_features=10, bias=True)\n", 276 | " (relu): LeakyReLU(negative_slope=0.01)\n", 277 | " (batch): BatchNorm1d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 278 | " (drop): Dropout(p=0.15, inplace=False)\n", 279 | ")\n" 280 | ] 281 | } 282 | ], 283 | "source": [ 284 | "num_classes = 10\n", 285 | "\n", 286 | "# Create CNN Model\n", 287 | "class CNNModel(nn.Module):\n", 288 | " def __init__(self):\n", 289 | " super(CNNModel, self).__init__()\n", 290 | " \n", 291 | " self.conv_layer1 = self._conv_layer_set(3, 32)\n", 292 | " self.conv_layer2 = self._conv_layer_set(32, 64)\n", 293 | " self.fc1 = nn.Linear(2**3*64, 128)\n", 294 | " self.fc2 = nn.Linear(128, num_classes)\n", 295 | " self.relu = nn.LeakyReLU()\n", 296 | " self.batch=nn.BatchNorm1d(128)\n", 297 | " self.drop=nn.Dropout(p=0.15) \n", 298 | " \n", 299 | " def _conv_layer_set(self, in_c, out_c):\n", 300 | " conv_layer = nn.Sequential(\n", 301 | " nn.Conv3d(in_c, out_c, kernel_size=(3, 3, 3), padding=0),\n", 302 | " nn.LeakyReLU(),\n", 303 | " nn.MaxPool3d((2, 2, 2)),\n", 304 | " )\n", 305 | " return conv_layer\n", 306 | " \n", 307 | "\n", 308 | " def forward(self, x):\n", 309 | " # Set 1\n", 310 | " out = self.conv_layer1(x)\n", 311 | " out = self.conv_layer2(out)\n", 312 | " out = out.view(out.size(0), -1)\n", 313 | " out = self.fc1(out)\n", 314 | " out = self.relu(out)\n", 315 | " out = self.batch(out)\n", 316 | " out = self.drop(out)\n", 317 | " out = self.fc2(out)\n", 318 | " \n", 319 | " return out\n", 320 | "\n", 321 | "#Definition of hyperparameters\n", 322 | "n_iters = 4500\n", 323 | "num_epochs = n_iters / (len(train_x) / batch_size)\n", 324 | "num_epochs = int(num_epochs)\n", 325 | "\n", 326 | "# Create CNN\n", 327 | "model = CNNModel()\n", 328 | "#model.cuda()\n", 329 | "print(model)\n", 330 | "\n", 331 | "# Cross Entropy Loss \n", 332 | "error = nn.CrossEntropyLoss()\n", 333 | "\n", 334 | "# SGD Optimizer\n", 335 | "learning_rate = 0.001\n", 336 | "optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)" 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": 21, 342 | "metadata": {}, 343 | "outputs": [ 344 | { 345 | "name": "stdout", 346 | "output_type": "stream", 347 | "text": [ 348 | "Iteration: 500 Loss: 1.8045936822891235 Accuracy: 33.099998474121094 %\n", 349 | "Iteration: 1000 Loss: 1.5683561563491821 Accuracy: 39.900001525878906 %\n", 350 | "Iteration: 1500 Loss: 1.4095323085784912 Accuracy: 45.900001525878906 %\n", 351 | "Iteration: 2000 Loss: 1.327325463294983 Accuracy: 48.45000076293945 %\n", 352 | "Iteration: 2500 Loss: 1.2187552452087402 Accuracy: 51.5 %\n", 353 | "Iteration: 3000 Loss: 1.1305687427520752 Accuracy: 53.25 %\n", 354 | "Iteration: 3500 Loss: 1.0787715911865234 Accuracy: 54.20000076293945 %\n", 355 | "Iteration: 4000 Loss: 1.040664553642273 Accuracy: 55.20000076293945 %\n", 356 | "Iteration: 4500 Loss: 0.9507399201393127 Accuracy: 55.20000076293945 %\n" 357 | ] 358 | } 359 | ], 360 | "source": [ 361 | "# CNN model training\n", 362 | "count = 0\n", 363 | "loss_list = []\n", 364 | "iteration_list = []\n", 365 | "accuracy_list = []\n", 366 | "for epoch in range(num_epochs):\n", 367 | " for i, (images, labels) in enumerate(train_loader):\n", 368 | " \n", 369 | " train = Variable(images.view(100,3,16,16,16))\n", 370 | " labels = Variable(labels)\n", 371 | " # Clear gradients\n", 372 | " optimizer.zero_grad()\n", 373 | " # Forward propagation\n", 374 | " outputs = model(train)\n", 375 | " # Calculate softmax and ross entropy loss\n", 376 | " loss = error(outputs, labels)\n", 377 | " # Calculating gradients\n", 378 | " loss.backward()\n", 379 | " # Update parameters\n", 380 | " optimizer.step()\n", 381 | " \n", 382 | " count += 1\n", 383 | " if count % 50 == 0:\n", 384 | " # Calculate Accuracy \n", 385 | " correct = 0\n", 386 | " total = 0\n", 387 | " # Iterate through test dataset\n", 388 | " for images, labels in test_loader:\n", 389 | " \n", 390 | " test = Variable(images.view(100,3,16,16,16))\n", 391 | " # Forward propagation\n", 392 | " outputs = model(test)\n", 393 | "\n", 394 | " # Get predictions from the maximum value\n", 395 | " predicted = torch.max(outputs.data, 1)[1]\n", 396 | " \n", 397 | " # Total number of labels\n", 398 | " total += len(labels)\n", 399 | " correct += (predicted == labels).sum()\n", 400 | " \n", 401 | " accuracy = 100 * correct / float(total)\n", 402 | " \n", 403 | " # store loss and iteration\n", 404 | " loss_list.append(loss.data)\n", 405 | " iteration_list.append(count)\n", 406 | " accuracy_list.append(accuracy)\n", 407 | " if count % 500 == 0:\n", 408 | " # Print Loss\n", 409 | " print('Iteration: {} Loss: {} Accuracy: {} %'.format(count, loss.data, accuracy))" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": 22, 415 | "metadata": {}, 416 | "outputs": [ 417 | { 418 | "data": { 419 | "image/png": "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\n", 420 | "text/plain": [ 421 | "
" 422 | ] 423 | }, 424 | "metadata": { 425 | "needs_background": "light" 426 | }, 427 | "output_type": "display_data" 428 | }, 429 | { 430 | "data": { 431 | "image/png": "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\n", 432 | "text/plain": [ 433 | "
" 434 | ] 435 | }, 436 | "metadata": { 437 | "needs_background": "light" 438 | }, 439 | "output_type": "display_data" 440 | } 441 | ], 442 | "source": [ 443 | "# visualization loss \n", 444 | "plt.plot(iteration_list,loss_list)\n", 445 | "plt.xlabel(\"Number of iteration\")\n", 446 | "plt.ylabel(\"Loss\")\n", 447 | "plt.title(\"CNN: Loss vs Number of iteration\")\n", 448 | "plt.show()\n", 449 | "\n", 450 | "# visualization accuracy \n", 451 | "plt.plot(iteration_list,accuracy_list,color = \"red\")\n", 452 | "plt.xlabel(\"Number of iteration\")\n", 453 | "plt.ylabel(\"Accuracy\")\n", 454 | "plt.title(\"CNN: Accuracy vs Number of iteration\")\n", 455 | "plt.show()" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": null, 461 | "metadata": {}, 462 | "outputs": [], 463 | "source": [] 464 | }, 465 | { 466 | "cell_type": "code", 467 | "execution_count": null, 468 | "metadata": {}, 469 | "outputs": [], 470 | "source": [] 471 | }, 472 | { 473 | "cell_type": "code", 474 | "execution_count": null, 475 | "metadata": {}, 476 | "outputs": [], 477 | "source": [] 478 | }, 479 | { 480 | "cell_type": "code", 481 | "execution_count": null, 482 | "metadata": {}, 483 | "outputs": [], 484 | "source": [] 485 | }, 486 | { 487 | "cell_type": "code", 488 | "execution_count": null, 489 | "metadata": {}, 490 | "outputs": [], 491 | "source": [] 492 | }, 493 | { 494 | "cell_type": "code", 495 | "execution_count": null, 496 | "metadata": {}, 497 | "outputs": [], 498 | "source": [] 499 | } 500 | ], 501 | "metadata": { 502 | "kernelspec": { 503 | "display_name": "Python 3", 504 | "language": "python", 505 | "name": "python3" 506 | }, 507 | "language_info": { 508 | "codemirror_mode": { 509 | "name": "ipython", 510 | "version": 3 511 | }, 512 | "file_extension": ".py", 513 | "mimetype": "text/x-python", 514 | "name": "python", 515 | "nbconvert_exporter": "python", 516 | "pygments_lexer": "ipython3", 517 | "version": "3.7.6" 518 | } 519 | }, 520 | "nbformat": 4, 521 | "nbformat_minor": 4 522 | } 523 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 3D Convolutional Neural Network 2 | ![](https://img.shields.io/badge/--) 3 | ![](https://img.shields.io/badge/--) 4 | 5 | 6 | 7 | [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/R5R11K2H4) 8 | 9 | 10 | Download the dataset and helper function on kaggle following this link: 11 | https://www.kaggle.com/daavoo/3d-mnist 12 | 13 | ### Structure 14 | - keras_model.py: General model in keras for the keras architecture 15 | - 3DkerasConv_example.ipynb: Jupyter notebook with example of keras usage (use after downloading the dataset) 16 | - pytorch_model.py: General model in keras for the pytorch architecture 17 | - 3DpytorchConv_example.ipynb: Jupyter notebook with example of pytorch usage (use after downloading the dataset) 18 | -------------------------------------------------------------------------------- /keras_model.py: -------------------------------------------------------------------------------- 1 | import keras 2 | from keras.models import Sequential 3 | from keras.layers import Dense, Flatten, Conv3D, MaxPooling3D, Dropout 4 | from keras.utils import to_categorical 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | import h5py 8 | 9 | 10 | def array_to_color(array, cmap="Oranges"): 11 | s_m = plt.cm.ScalarMappable(cmap=cmap) 12 | return s_m.to_rgba(array)[:,:-1] 13 | 14 | 15 | def rgb_data_transform(data): 16 | data_t = [] 17 | for i in range(data.shape[0]): 18 | data_t.append(array_to_color(data[i]).reshape(16, 16, 16, 3)) 19 | return np.asarray(data_t, dtype=np.float32) 20 | 21 | 22 | with h5py.File("./full_dataset_vectors.h5", "r") as hf: 23 | 24 | # Split the data into training/test features/targets 25 | X_train = hf["X_train"][:] 26 | targets_train = hf["y_train"][:] 27 | X_test = hf["X_test"][:] 28 | targets_test = hf["y_test"][:] 29 | 30 | # Determine sample shape 31 | sample_shape = (16, 16, 16, 3) 32 | 33 | # Reshape data into 3D format 34 | X_train = rgb_data_transform(X_train) 35 | X_test = rgb_data_transform(X_test) 36 | 37 | # Convert target vectors to categorical targets 38 | targets_train = to_categorical(targets_train).astype(np.integer) 39 | targets_test = to_categorical(targets_test).astype(np.integer) 40 | 41 | # Create the model 42 | model = Sequential() 43 | model.add(Conv3D(32, kernel_size=(3, 3, 3), activation='relu', kernel_initializer='he_uniform', input_shape=sample_shape)) 44 | model.add(MaxPooling3D(pool_size=(2, 2, 2))) 45 | model.add(Dropout(0.5)) 46 | model.add(Conv3D(64, kernel_size=(3, 3, 3), activation='relu', kernel_initializer='he_uniform')) 47 | model.add(MaxPooling3D(pool_size=(2, 2, 2))) 48 | model.add(Dropout(0.5)) 49 | model.add(Flatten()) 50 | model.add(Dense(256, activation='relu', kernel_initializer='he_uniform')) 51 | model.add(Dense(10, activation='softmax')) 52 | 53 | # Compile the model 54 | model.compile(loss='categorical_crossentropy', 55 | optimizer=keras.optimizers.Adam(lr=0.001), 56 | metrics=['accuracy']) 57 | 58 | # Fit data to model 59 | history = model.fit(X_train, targets_train, 60 | batch_size=128, 61 | epochs=30, 62 | verbose=1, 63 | validation_split=0.2) 64 | 65 | # Generate generalization metrics 66 | score = model.evaluate(X_test, targets_test, verbose=0) 67 | print(f'Test loss: {score[0]} / Test accuracy: {score[1]}') 68 | model.save('threeD.h5') 69 | print(history.history.keys()) 70 | with open('history.pickle','wb') as handle: 71 | pickle.dump(history.history, handle) 72 | 73 | # Plot history: Categorical crossentropy & Accuracy 74 | # plt.plot(history.history['loss'], label='Categorical crossentropy (training data)') 75 | # plt.plot(history.history['val_loss'], label='Categorical crossentropy (validation data)') 76 | # plt.plot(history.history['accuracy'], label='Accuracy (training data)') 77 | # plt.plot(history.history['val_accuracy'], label='Accuracy (validation data)') 78 | # plt.title('Model performance for 3D MNIST Keras Conv3D example') 79 | # plt.ylabel('Loss value') 80 | # plt.xlabel('No. epoch') 81 | # plt.legend(loc="upper left") 82 | # plt.show() -------------------------------------------------------------------------------- /plot3D.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | from IPython.display import IFrame 4 | from matplotlib import pyplot as plt 5 | 6 | 7 | 8 | def array_to_color(array, cmap="Oranges"): 9 | s_m = plt.cm.ScalarMappable(cmap=cmap) 10 | return s_m.to_rgba(array)[:,:-1] 11 | 12 | 13 | TEMPLATE_POINTS = """ 14 | 15 | 16 | 17 | PyntCloud 18 | 19 | 20 | 39 | 40 | 41 | 42 | 43 |
44 | 45 |
46 | 47 |
48 |
49 | 50 | 51 | 52 | 53 | 54 | 55 | 138 | 139 | 140 | 141 | """ 142 | 143 | def plot_points(xyz, colors=None, size=0.1, axis=False): 144 | 145 | positions = xyz.reshape(-1).tolist() 146 | 147 | camera_position = xyz.max(0) + abs(xyz.max(0)) 148 | 149 | look = xyz.mean(0) 150 | 151 | if colors is None: 152 | colors = [1,0.5,0] * len(positions) 153 | 154 | elif len(colors.shape) > 1: 155 | colors = colors.reshape(-1).tolist() 156 | 157 | if axis: 158 | axis_size = xyz.ptp() * 1.5 159 | else: 160 | axis_size = 0 161 | 162 | with open("plot_points.html", "w") as html: 163 | html.write(TEMPLATE_POINTS.format( 164 | camera_x=camera_position[0], 165 | camera_y=camera_position[1], 166 | camera_z=camera_position[2], 167 | look_x=look[0], 168 | look_y=look[1], 169 | look_z=look[2], 170 | positions=positions, 171 | colors=colors, 172 | points_size=size, 173 | axis_size=axis_size)) 174 | 175 | return IFrame("plot_points.html",width=800, height=800) 176 | 177 | 178 | TEMPLATE_VG = """ 179 | 180 | 181 | 182 | PyntCloud 183 | 184 | 185 | 203 | 204 | 205 | 206 | 207 |
208 | 209 |
210 | 211 |
212 |
213 | 214 | 215 | 216 | 217 | 218 | 219 | 309 | 310 | 311 | """ 312 | 313 | 314 | def plot_voxelgrid(v_grid, cmap="Oranges", axis=False): 315 | 316 | scaled_shape = v_grid.shape / min(v_grid.shape) 317 | 318 | # coordinates returned from argwhere are inversed so use [:, ::-1] 319 | points = np.argwhere(v_grid.vector)[:, ::-1] * scaled_shape 320 | 321 | s_m = plt.cm.ScalarMappable(cmap=cmap) 322 | rgb = s_m.to_rgba(v_grid.vector.reshape(-1)[v_grid.vector.reshape(-1) > 0])[:,:-1] 323 | 324 | camera_position = points.max(0) + abs(points.max(0)) 325 | look = points.mean(0) 326 | 327 | if axis: 328 | axis_size = points.ptp() * 1.5 329 | else: 330 | axis_size = 0 331 | 332 | with open("plotVG.html", "w") as html: 333 | html.write(TEMPLATE_VG.format( 334 | camera_x=camera_position[0], 335 | camera_y=camera_position[1], 336 | camera_z=camera_position[2], 337 | look_x=look[0], 338 | look_y=look[1], 339 | look_z=look[2], 340 | X=points[:,0].tolist(), 341 | Y=points[:,1].tolist(), 342 | Z=points[:,2].tolist(), 343 | R=rgb[:,0].tolist(), 344 | G=rgb[:,1].tolist(), 345 | B=rgb[:,2].tolist(), 346 | S_x=scaled_shape[0], 347 | S_y=scaled_shape[2], 348 | S_z=scaled_shape[1], 349 | n_voxels=sum(v_grid.vector.reshape(-1) > 0), 350 | axis_size=axis_size)) 351 | 352 | return IFrame("plotVG.html",width=800, height=800) -------------------------------------------------------------------------------- /pytorch_model.py: -------------------------------------------------------------------------------- 1 | import keras 2 | from keras.models import Sequential 3 | from keras.layers import Dense, Flatten, Conv3D, MaxPooling3D, Dropout 4 | from keras.utils import to_categorical 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | import h5py 8 | 9 | 10 | def array_to_color(array, cmap="Oranges"): 11 | s_m = plt.cm.ScalarMappable(cmap=cmap) 12 | return s_m.to_rgba(array)[:,:-1] 13 | 14 | 15 | def rgb_data_transform(data): 16 | data_t = [] 17 | for i in range(data.shape[0]): 18 | data_t.append(array_to_color(data[i]).reshape(16, 16, 16, 3)) 19 | return np.asarray(data_t, dtype=np.float32) 20 | 21 | with h5py.File("./full_dataset_vectors.h5", "r") as hf: 22 | 23 | # Split the data into training/test features/targets 24 | X_train = hf["X_train"][:] 25 | targets_train = hf["y_train"][:] 26 | X_test = hf["X_test"][:] 27 | targets_test = hf["y_test"][:] 28 | 29 | # Determine sample shape 30 | sample_shape = (16, 16, 16, 3) 31 | 32 | # Reshape data into 3D format 33 | X_train = rgb_data_transform(X_train) 34 | X_test = rgb_data_transform(X_test) 35 | 36 | X_train = X_train.reshape(10000,3,16,16,16) 37 | X_test = X_test.reshape(2000,3,16,16,16) 38 | 39 | train_x = torch.from_numpy(X_train).float() 40 | train_y = torch.from_numpy(targets_train).long() 41 | test_x = torch.from_numpy(X_test).float() 42 | test_y = torch.from_numpy(targets_test).long() 43 | 44 | # batch_size, epoch and iteration 45 | batch_size = 100 46 | 47 | 48 | # Pytorch train and test sets 49 | train = torch.utils.data.TensorDataset(train_x,train_y) 50 | test = torch.utils.data.TensorDataset(test_x,test_y) 51 | 52 | # data loader 53 | train_loader = torch.utils.data.DataLoader(train, batch_size = batch_size, shuffle = False) 54 | test_loader = torch.utils.data.DataLoader(test, batch_size = batch_size, shuffle = False) 55 | 56 | num_classes = 10 57 | 58 | # Create CNN Model 59 | class CNNModel(nn.Module): 60 | def __init__(self): 61 | super(CNNModel, self).__init__() 62 | 63 | self.conv_layer1 = self._conv_layer_set(3, 32) 64 | self.conv_layer2 = self._conv_layer_set(32, 64) 65 | self.fc1 = nn.Linear(2**3*64, 128) 66 | self.fc2 = nn.Linear(128, num_classes) 67 | self.relu = nn.LeakyReLU() 68 | self.batch=nn.BatchNorm1d(128) 69 | self.drop=nn.Dropout(p=0.15) 70 | 71 | def _conv_layer_set(self, in_c, out_c): 72 | conv_layer = nn.Sequential( 73 | nn.Conv3d(in_c, out_c, kernel_size=(3, 3, 3), padding=0), 74 | nn.LeakyReLU(), 75 | nn.MaxPool3d((2, 2, 2)), 76 | ) 77 | return conv_layer 78 | 79 | 80 | def forward(self, x): 81 | # Set 1 82 | out = self.conv_layer1(x) 83 | out = self.conv_layer2(out) 84 | out = out.view(out.size(0), -1) 85 | out = self.fc1(out) 86 | out = self.relu(out) 87 | out = self.batch(out) 88 | out = self.drop(out) 89 | out = self.fc2(out) 90 | 91 | return out 92 | 93 | #Definition of hyperparameters 94 | n_iters = 4500 95 | num_epochs = n_iters / (len(train_x) / batch_size) 96 | num_epochs = int(num_epochs) 97 | 98 | # Create CNN 99 | model = CNNModel() 100 | #model.cuda() 101 | print(model) 102 | 103 | # Cross Entropy Loss 104 | error = nn.CrossEntropyLoss() 105 | 106 | # SGD Optimizer 107 | learning_rate = 0.001 108 | optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) 109 | 110 | # CNN model training 111 | count = 0 112 | loss_list = [] 113 | iteration_list = [] 114 | accuracy_list = [] 115 | for epoch in range(num_epochs): 116 | for i, (images, labels) in enumerate(train_loader): 117 | 118 | train = Variable(images.view(100,3,16,16,16)) 119 | labels = Variable(labels) 120 | # Clear gradients 121 | optimizer.zero_grad() 122 | # Forward propagation 123 | outputs = model(train) 124 | # Calculate softmax and ross entropy loss 125 | loss = error(outputs, labels) 126 | # Calculating gradients 127 | loss.backward() 128 | # Update parameters 129 | optimizer.step() 130 | 131 | count += 1 132 | if count % 50 == 0: 133 | # Calculate Accuracy 134 | correct = 0 135 | total = 0 136 | # Iterate through test dataset 137 | for images, labels in test_loader: 138 | 139 | test = Variable(images.view(100,3,16,16,16)) 140 | # Forward propagation 141 | outputs = model(test) 142 | 143 | # Get predictions from the maximum value 144 | predicted = torch.max(outputs.data, 1)[1] 145 | 146 | # Total number of labels 147 | total += len(labels) 148 | correct += (predicted == labels).sum() 149 | 150 | accuracy = 100 * correct / float(total) 151 | 152 | # store loss and iteration 153 | loss_list.append(loss.data) 154 | iteration_list.append(count) 155 | accuracy_list.append(accuracy) 156 | if count % 500 == 0: 157 | # Print Loss 158 | print('Iteration: {} Loss: {} Accuracy: {} %'.format(count, loss.data, accuracy)) 159 | 160 | -------------------------------------------------------------------------------- /voxelgrid.py: -------------------------------------------------------------------------------- 1 | # HAKUNA MATATA 2 | 3 | """ 4 | VoxelGrid Class 5 | """ 6 | 7 | import numpy as np 8 | from matplotlib import pyplot as plt 9 | #from ..plot import plot_voxelgrid 10 | 11 | 12 | class VoxelGrid(object): 13 | 14 | def __init__(self, points, x_y_z=[1, 1, 1], bb_cuboid=True, build=True): 15 | """ 16 | Parameters 17 | ---------- 18 | points: (N,3) ndarray 19 | The point cloud from wich we want to construct the VoxelGrid. 20 | Where N is the number of points in the point cloud and the second 21 | dimension represents the x, y and z coordinates of each point. 22 | 23 | x_y_z: list 24 | The segments in wich each axis will be divided. 25 | x_y_z[0]: x axis 26 | x_y_z[1]: y axis 27 | x_y_z[2]: z axis 28 | 29 | bb_cuboid(Optional): bool 30 | If True(Default): 31 | The bounding box of the point cloud will be adjusted 32 | in order to have all the dimensions of equal lenght. 33 | If False: 34 | The bounding box is allowed to have dimensions of different sizes. 35 | """ 36 | self.points = points 37 | 38 | xyzmin = np.min(points, axis=0) - 0.001 39 | xyzmax = np.max(points, axis=0) + 0.001 40 | 41 | if bb_cuboid: 42 | #: adjust to obtain a minimum bounding box with all sides of equal lenght 43 | diff = max(xyzmax-xyzmin) - (xyzmax-xyzmin) 44 | xyzmin = xyzmin - diff / 2 45 | xyzmax = xyzmax + diff / 2 46 | 47 | self.xyzmin = xyzmin 48 | self.xyzmax = xyzmax 49 | 50 | segments = [] 51 | shape = [] 52 | 53 | for i in range(3): 54 | # note the +1 in num 55 | if type(x_y_z[i]) is not int: 56 | raise TypeError("x_y_z[{}] must be int".format(i)) 57 | s, step = np.linspace(xyzmin[i], xyzmax[i], num=(x_y_z[i] + 1), retstep=True) 58 | segments.append(s) 59 | shape.append(step) 60 | 61 | self.segments = segments 62 | 63 | self.shape = shape 64 | 65 | self.n_voxels = x_y_z[0] * x_y_z[1] * x_y_z[2] 66 | self.n_x = x_y_z[0] 67 | self.n_y = x_y_z[1] 68 | self.n_z = x_y_z[2] 69 | 70 | self.id = "{},{},{}-{}".format(x_y_z[0], x_y_z[1], x_y_z[2], bb_cuboid) 71 | 72 | if build: 73 | self.build() 74 | 75 | 76 | def build(self): 77 | 78 | structure = np.zeros((len(self.points), 4), dtype=int) 79 | 80 | structure[:,0] = np.searchsorted(self.segments[0], self.points[:,0]) - 1 81 | 82 | structure[:,1] = np.searchsorted(self.segments[1], self.points[:,1]) - 1 83 | 84 | structure[:,2] = np.searchsorted(self.segments[2], self.points[:,2]) - 1 85 | 86 | # i = ((y * n_x) + x) + (z * (n_x * n_y)) 87 | structure[:,3] = ((structure[:,1] * self.n_x) + structure[:,0]) + (structure[:,2] * (self.n_x * self.n_y)) 88 | 89 | self.structure = structure 90 | 91 | vector = np.zeros(self.n_voxels) 92 | count = np.bincount(self.structure[:,3]) 93 | vector[:len(count)] = count 94 | 95 | self.vector = vector.reshape(self.n_z, self.n_y, self.n_x) 96 | 97 | 98 | def plot(self, d=2, cmap="Oranges", axis=False): 99 | 100 | if d == 2: 101 | 102 | fig, axes= plt.subplots(int(np.ceil(self.n_z / 4)), 4, figsize=(8,8)) 103 | 104 | plt.tight_layout() 105 | 106 | for i,ax in enumerate(axes.flat): 107 | if i >= len(self.vector): 108 | break 109 | im = ax.imshow(self.vector[i], cmap=cmap, interpolation="none") 110 | ax.set_title("Level " + str(i)) 111 | 112 | fig.subplots_adjust(right=0.8) 113 | cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7]) 114 | cbar = fig.colorbar(im, cax=cbar_ax) 115 | cbar.set_label('NUMBER OF POINTS IN VOXEL') 116 | 117 | elif d == 3: 118 | return plot_voxelgrid(self, cmap=cmap, axis=axis) 119 | 120 | --------------------------------------------------------------------------------