362 lines
13 KiB
Plaintext
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
|
|
}
|