Files
ml-arithmetic/ConvNet.ipynb
2018-09-10 14:47:18 -05:00

362 lines
13 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"There are 47 total answer categories.\n",
"There are 5000 total math images.\n",
"There are 3000 training math images.\n",
"There are 1000 validation math images.\n",
"There are 1000 test math images.\n"
]
}
],
"source": [
"from sklearn.datasets import load_files \n",
"from keras.utils import np_utils\n",
"import numpy as np\n",
"from glob import glob\n",
"\n",
"# define function to load train, test, and validation datasets\n",
"def load_dataset(path):\n",
" data = load_files(path, shuffle=False)\n",
" problem_files = np.array(data['filenames'])\n",
" problem_answers = np_utils.to_categorical(np.array(data['target']), 47)\n",
" return problem_files, problem_answers\n",
"\n",
"# load train, test, and validation datasets\n",
"train_files, train_targets = load_dataset('./data/train')\n",
"valid_files, valid_targets = load_dataset('./data/validate')\n",
"test_files, test_targets = load_dataset('./data/test')\n",
"\n",
"# load list of math answers\n",
"math_answers = [item[13:-1] for item in glob(\"./data/train/*/\")]\n",
"\n",
"# print statistics about the dataset\n",
"print('There are %d total answer categories.' % len(math_answers))\n",
"print('There are %s total math images.' % len(np.hstack([train_files, valid_files, test_files])))\n",
"print('There are %d training math images.' % len(train_files))\n",
"print('There are %d validation math images.' % len(valid_files))\n",
"print('There are %d test math images.'% len(test_files))"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from keras.preprocessing import image \n",
"from tqdm import tqdm\n",
"\n",
"def path_to_tensor(img_path):\n",
" # loads RGB image as PIL.Image.Image type\n",
" img = image.load_img(img_path, target_size=(128, 128))\n",
" # convert PIL.Image.Image type to 3D tensor with shape (128, 128, 1)\n",
" x = image.img_to_array(img)\n",
" # convert 3D tensor to 4D tensor with shape (1, 128, 128, 1) and return 4D tensor\n",
" return np.expand_dims(x, axis=0)\n",
"\n",
"def paths_to_tensor(img_paths):\n",
" list_of_tensors = [path_to_tensor(img_path) for img_path in tqdm(img_paths)]\n",
" return np.vstack(list_of_tensors)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|████████████████████████████████████████████████████████████████████████████| 3000/3000 [00:01<00:00, 1714.31it/s]\n",
"100%|████████████████████████████████████████████████████████████████████████████| 1000/1000 [00:00<00:00, 1808.34it/s]\n",
"100%|████████████████████████████████████████████████████████████████████████████| 1000/1000 [00:00<00:00, 1821.52it/s]\n"
]
}
],
"source": [
"from PIL import ImageFile \n",
"ImageFile.LOAD_TRUNCATED_IMAGES = True \n",
"\n",
"# pre-process the data for Keras\n",
"train_tensors = paths_to_tensor(train_files).astype('float32')/255\n",
"valid_tensors = paths_to_tensor(valid_files).astype('float32')/255\n",
"test_tensors = paths_to_tensor(test_files).astype('float32')/255"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"conv2d_1 (Conv2D) (None, 128, 128, 8) 104 \n",
"_________________________________________________________________\n",
"max_pooling2d_1 (MaxPooling2 (None, 64, 64, 8) 0 \n",
"_________________________________________________________________\n",
"conv2d_2 (Conv2D) (None, 64, 64, 16) 528 \n",
"_________________________________________________________________\n",
"max_pooling2d_2 (MaxPooling2 (None, 32, 32, 16) 0 \n",
"_________________________________________________________________\n",
"conv2d_3 (Conv2D) (None, 32, 32, 32) 2080 \n",
"_________________________________________________________________\n",
"max_pooling2d_3 (MaxPooling2 (None, 16, 16, 32) 0 \n",
"_________________________________________________________________\n",
"flatten_1 (Flatten) (None, 8192) 0 \n",
"_________________________________________________________________\n",
"dense_1 (Dense) (None, 256) 2097408 \n",
"_________________________________________________________________\n",
"dropout_1 (Dropout) (None, 256) 0 \n",
"_________________________________________________________________\n",
"dense_2 (Dense) (None, 47) 12079 \n",
"=================================================================\n",
"Total params: 2,112,199\n",
"Trainable params: 2,112,199\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D\n",
"from keras.layers import Dropout, Flatten, Dense\n",
"from keras.models import Sequential\n",
"\n",
"model = Sequential()\n",
"\n",
"### TODO: Define your architecture.\n",
"model.add(Conv2D(filters=8, kernel_size=2, padding='same', activation='relu', input_shape=train_tensors.shape[1:]))\n",
"model.add(MaxPooling2D(pool_size=2))\n",
"model.add(Conv2D(filters=16, kernel_size=2,padding='same', activation='relu'))\n",
"model.add(MaxPooling2D(pool_size=2))\n",
"model.add(Conv2D(filters=32, kernel_size=2, padding='same', activation='relu'))\n",
"model.add(MaxPooling2D(pool_size=2))\n",
"model.add(Flatten())\n",
"model.add(Dense(256, activation='relu'))\n",
"model.add(Dropout(0.3))\n",
"model.add(Dense(47, activation='softmax'))\n",
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train on 3000 samples, validate on 1000 samples\n",
"Epoch 1/10\n",
" - 6s - loss: 2.9525 - acc: 0.1733 - val_loss: 2.3098 - val_acc: 0.2620\n",
"\n",
"Epoch 00001: val_loss improved from inf to 2.30976, saving model to saved_models/weights.best.from_scratch.hdf5\n",
"Epoch 2/10\n",
" - 3s - loss: 1.8501 - acc: 0.3977 - val_loss: 1.3184 - val_acc: 0.5700\n",
"\n",
"Epoch 00002: val_loss improved from 2.30976 to 1.31842, saving model to saved_models/weights.best.from_scratch.hdf5\n",
"Epoch 3/10\n",
" - 3s - loss: 0.9732 - acc: 0.6790 - val_loss: 0.4666 - val_acc: 0.8830\n",
"\n",
"Epoch 00003: val_loss improved from 1.31842 to 0.46665, saving model to saved_models/weights.best.from_scratch.hdf5\n",
"Epoch 4/10\n",
" - 3s - loss: 0.4287 - acc: 0.8663 - val_loss: 0.1272 - val_acc: 0.9720\n",
"\n",
"Epoch 00004: val_loss improved from 0.46665 to 0.12724, saving model to saved_models/weights.best.from_scratch.hdf5\n",
"Epoch 5/10\n",
" - 3s - loss: 0.1949 - acc: 0.9407 - val_loss: 0.0425 - val_acc: 0.9930\n",
"\n",
"Epoch 00005: val_loss improved from 0.12724 to 0.04253, saving model to saved_models/weights.best.from_scratch.hdf5\n",
"Epoch 6/10\n",
" - 3s - loss: 0.0887 - acc: 0.9750 - val_loss: 0.0076 - val_acc: 1.0000\n",
"\n",
"Epoch 00006: val_loss improved from 0.04253 to 0.00764, saving model to saved_models/weights.best.from_scratch.hdf5\n",
"Epoch 7/10\n",
" - 3s - loss: 0.0657 - acc: 0.9800 - val_loss: 0.0028 - val_acc: 1.0000\n",
"\n",
"Epoch 00007: val_loss improved from 0.00764 to 0.00281, saving model to saved_models/weights.best.from_scratch.hdf5\n",
"Epoch 8/10\n",
" - 3s - loss: 0.0332 - acc: 0.9920 - val_loss: 8.5030e-04 - val_acc: 1.0000\n",
"\n",
"Epoch 00008: val_loss improved from 0.00281 to 0.00085, saving model to saved_models/weights.best.from_scratch.hdf5\n",
"Epoch 9/10\n",
" - 3s - loss: 0.0373 - acc: 0.9890 - val_loss: 3.2931e-04 - val_acc: 1.0000\n",
"\n",
"Epoch 00009: val_loss improved from 0.00085 to 0.00033, saving model to saved_models/weights.best.from_scratch.hdf5\n",
"Epoch 10/10\n",
" - 3s - loss: 0.0234 - acc: 0.9913 - val_loss: 1.4510e-04 - val_acc: 1.0000\n",
"\n",
"Epoch 00010: val_loss improved from 0.00033 to 0.00015, saving model to saved_models/weights.best.from_scratch.hdf5\n"
]
},
{
"data": {
"text/plain": [
"<keras.callbacks.History at 0x24ea4fb71d0>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from keras.callbacks import ModelCheckpoint \n",
"\n",
"### TODO: specify the number of epochs that you would like to use to train the model.\n",
"\n",
"epochs = 20\n",
"\n",
"### Do NOT modify the code below this line.\n",
"\n",
"checkpointer = ModelCheckpoint(filepath='saved_models/weights.best.from_scratch.hdf5', \n",
" verbose=1, save_best_only=True)\n",
"\n",
"model.fit(train_tensors, train_targets, \n",
" validation_data=(valid_tensors, valid_targets),\n",
" epochs=epochs, batch_size=20, callbacks=[checkpointer], verbose=2)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"model.load_weights('saved_models/weights.best.from_scratch.hdf5')"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test accuracy: 100.0000%\n"
]
}
],
"source": [
"# get index of predicted dog breed for each image in test set\n",
"math_predictions = [np.argmax(model.predict(np.expand_dims(tensor, axis=0))) for tensor in test_tensors]\n",
"\n",
"# report test accuracy\n",
"test_accuracy = 100*np.sum(np.array(math_predictions)==np.argmax(test_targets, axis=1))/len(math_predictions)\n",
"print('Test accuracy: %.4f%%' % test_accuracy)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"categories = list(set(list(map(int, math_answers))))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"categories[np.argmax(model.predict(path_to_tensor('./human/test.png')))]"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.argmax(model.predict(path_to_tensor('./human/test.png')))"
]
},
{
"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.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}