{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Training a model for the Tribune\n", "\n", "This notebook uses the [Tensorflow for poets](https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/) tutorial to train a new model for classifying images in the Tribune collection.\n", "\n", "First we'll clone the code repository." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!git clone https://github.com/googlecodelabs/tensorflow-for-poets-2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's move into the new directory" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Errno 2] No such file or directory: 'tensorflow-for-poets-2'\n", "/Users/tim/mycode/glam-workbench/image-recognition/notebooks/tensorflow-for-poets-2\n" ] } ], "source": [ "cd tensorflow-for-poets-2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Our categories\n", "\n", "For our initial experiment we're going to try and distinguish between two categories — protests and portraits." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "img_sets = {\n", " 'protests': ['FL4520808', 'FL4520807', 'FL4520809', 'FL4520810', 'FL4520811', 'FL4520812', 'FL4520813', 'FL4520814', 'FL4520816', 'FL4520817', 'FL4520818', 'FL4520820', 'FL4520821', 'FL4520822', 'FL4520823', 'FL4520825', 'FL4520826', 'FL4520827', 'FL4520828', 'FL4520829', 'FL4520830', 'FL4520832', 'FL4520833', 'FL4520834', 'FL4520835', 'FL4520836', 'FL4562467', 'FL4562470', 'FL4562473', 'FL4562477', 'FL4562493', 'FL4562496', 'FL4562498', 'FL4562502', 'FL4562504', 'FL4562506', 'FL4562507', 'FL4562514', 'FL4562526', 'FL4562531', 'FL4562534', 'FL4562538', 'FL4562543', 'FL4562548', 'FL4431373', 'FL4431375', 'FL4431376', 'FL4431377', 'FL4431405', 'FL4431403', 'FL4534782','FL4534784','FL4534786','FL4534787','FL4534789','FL4548906','FL4548908','FL4548910','FL4548914','FL4548915','FL4548916','FL4548918','FL4548919','FL4548920','FL4548924','FL4581459','FL4581460','FL4581461','FL4581462','FL4581463','FL4581468','FL4581469','FL4581470','FL4581471','FL4581473','FL4581474','FL4581475','FL4581477','FL4581478','FL4581481','FL4544430','FL4544432','FL4544435','FL4544437','FL4544438','FL4544439','FL4544441','FL4544448','FL4528139','FL4528140','FL4528141','FL4528142','FL4528143','FL4528144','FL4527324','FL4527326','FL4527329','FL4527333','FL4527335','FL4530238'],\n", " 'portraits': ['FL4549209', 'FL4564140', 'FL4549684', 'FL4545567', 'FL4488477', 'FL4545569', 'FL4534794', 'FL4510388', 'FL4513567', 'FL4513591', 'FL4513594', 'FL4468261', 'FL4531198', 'FL4531240', 'FL4517378', 'FL4517384', 'FL4529746', 'FL4512049', 'FL4512055', 'FL4485185', 'FL4487605', 'FL4487592', 'FL4485540', 'FL4484944', 'FL4484950', 'FL4481774', 'FL4481787', 'FL4478835', 'FL4486661', 'FL4486662', 'FL4474330', 'FL4474354', 'FL4480349', 'FL4480384', 'FL4486300', 'FL4473256', 'FL4474185', 'FL4474152', 'FL4479422', 'FL4479449', 'FL4474018', 'FL4472433', 'FL4479794', 'FL4466608', 'FL4466614', 'FL4450989', 'FL4489424', 'FL4480459', 'FL4588049', 'FL4492349', 'FL4502482', 'FL4491527', 'FL4444441', 'FL4490697', 'FL4433631', 'FL4434468', 'FL4430650', 'FL4430652', 'FL4468274', 'FL4529677', 'FL4532361', 'FL4495950', 'FL8797006', 'FL4522775', 'FL4517556', 'FL4517563', 'FL4518600', 'FL4515829', 'FL4515847', 'FL4519602', 'FL4424262', 'FL4424263', 'FL4424264', 'FL4424278', 'FL4424279', 'FL4588015', 'FL4588016', 'FL4588017', 'FL4537870', 'FL4537872', 'FL4537873', 'FL4537874', 'FL4537878', 'FL4537880', 'FL4537881', 'FL4537882', 'FL4537883', 'FL4537888', 'FL4537889', 'FL4537891', 'FL4537895', 'FL4537896', 'FL4537897', 'FL4537899', 'FL4537902', 'FL4537906', 'FL4537907', 'FL4537909', 'FL4537911', 'FL4540963', 'FL4540964', 'FL4540966', 'FL4540970', 'FL4540972', 'FL4540973', 'FL4540975', 'FL4539968', 'FL4539969', 'FL4539970', 'FL4539971', 'FL4539972', 'FL4539974', 'FL4539988', 'FL4539989', 'FL4490339', 'FL4538816', 'FL4538817', 'FL4538818', 'FL4538825', 'FL4538826', 'FL4538827', 'FL4538828', 'FL4538829', 'FL4538838', 'FL4538839', 'FL4538840', 'FL4538841']\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Download the training images." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "062337f2f30c464789148ff0b0773265", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7e209324aca649bab778a17689ee968b", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=127), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "import os\n", "from urllib.parse import urlparse\n", "from tqdm import tqdm_notebook\n", "import requests\n", "# Download training images\n", "for img_set in ['protests', 'portraits']:\n", " img_dir = os.path.join('tf_files', 'tribune', img_set)\n", " os.makedirs(img_dir, exist_ok=True)\n", " for img in tqdm_notebook(img_sets[img_set]):\n", " img_url = 'https://s3-ap-southeast-2.amazonaws.com/wraggetribune/images/500/{0}-500.jpg'.format(img)\n", " parsed = urlparse(img_url)\n", " filename = os.path.join(img_dir, os.path.basename(parsed.path))\n", " response = requests.get(img_url, stream=True)\n", " with open(filename, 'wb') as fd:\n", " for chunk in response.iter_content(chunk_size=128):\n", " fd.write(chunk)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[34mportraits\u001b[m\u001b[m/ \u001b[34mprotests\u001b[m\u001b[m/\r\n" ] } ], "source": [ "ls tf_files/tribune" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run this in a terminal, Jupyter doesn't allow background processes...\n", "\n", "I'm assuming this won't be possible on Binder?\n", "\n", "```\n", "tensorboard --logdir tf_files/training_summaries &\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Train the model" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:tensorflow:Looking for images in 'portraits'\n", "INFO:tensorflow:Looking for images in 'protests'\n", "2018-10-28 14:42:43.281542: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA\n", "INFO:tensorflow:100 bottleneck files created.\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548906-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548916-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4534787-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4528144-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548920-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4544437-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4527333-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581473-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581463-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4534786-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4544435-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581461-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581471-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4534784-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581478-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581468-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548914-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4527329-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581469-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581470-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581460-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581475-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4534789-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4527335-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548918-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548908-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4544438-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4528142-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4544439-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581474-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4544430-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4527324-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548919-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4528140-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548924-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4530238-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4544432-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581459-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4527326-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:200 bottleneck files created.\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4544441-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4528141-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4544448-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548915-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4548910-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4534782-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581462-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581481-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4528143-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4528139-500.jpg_mobilenet_0.50_224.txt\n", "INFO:tensorflow:Creating bottleneck at tf_files/bottlenecks/protests/FL4581477-500.jpg_mobilenet_0.50_224.txt\n", "WARNING:tensorflow:From /Users/tim/mycode/glam-workbench/image-recognition/notebooks/tensorflow-for-poets-2/scripts/retrain.py:790: softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "\n", "Future major versions of TensorFlow will allow gradients to flow\n", "into the labels input on backprop by default.\n", "\n", "See `tf.nn.softmax_cross_entropy_with_logits_v2`.\n", "\n", "INFO:tensorflow:2018-10-28 14:42:45.403470: Step 0: Train accuracy = 86.0%\n", "INFO:tensorflow:2018-10-28 14:42:45.403937: Step 0: Cross entropy = 0.309668\n", "INFO:tensorflow:2018-10-28 14:42:45.628682: Step 0: Validation accuracy = 92.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:45.994709: Step 10: Train accuracy = 94.0%\n", "INFO:tensorflow:2018-10-28 14:42:45.994839: Step 10: Cross entropy = 0.257828\n", "INFO:tensorflow:2018-10-28 14:42:46.029826: Step 10: Validation accuracy = 80.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:46.386835: Step 20: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:46.386965: Step 20: Cross entropy = 0.007310\n", "INFO:tensorflow:2018-10-28 14:42:46.421428: Step 20: Validation accuracy = 95.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:46.782148: Step 30: Train accuracy = 98.0%\n", "INFO:tensorflow:2018-10-28 14:42:46.782288: Step 30: Cross entropy = 0.052359\n", "INFO:tensorflow:2018-10-28 14:42:46.817271: Step 30: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:47.180937: Step 40: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:47.181071: Step 40: Cross entropy = 0.004318\n", "INFO:tensorflow:2018-10-28 14:42:47.218462: Step 40: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:47.580580: Step 50: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:47.580705: Step 50: Cross entropy = 0.007924\n", "INFO:tensorflow:2018-10-28 14:42:47.615264: Step 50: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:47.971581: Step 60: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:47.971710: Step 60: Cross entropy = 0.007916\n", "INFO:tensorflow:2018-10-28 14:42:48.006999: Step 60: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:48.363424: Step 70: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:48.363547: Step 70: Cross entropy = 0.002402\n", "INFO:tensorflow:2018-10-28 14:42:48.397967: Step 70: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:48.752027: Step 80: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:48.752154: Step 80: Cross entropy = 0.002464\n", "INFO:tensorflow:2018-10-28 14:42:48.787513: Step 80: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:49.141937: Step 90: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:49.142069: Step 90: Cross entropy = 0.002755\n", "INFO:tensorflow:2018-10-28 14:42:49.176506: Step 90: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:49.527722: Step 100: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:49.527856: Step 100: Cross entropy = 0.003589\n", "INFO:tensorflow:2018-10-28 14:42:49.562754: Step 100: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:49.916231: Step 110: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:49.916356: Step 110: Cross entropy = 0.001157\n", "INFO:tensorflow:2018-10-28 14:42:49.950865: Step 110: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:50.305482: Step 120: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:50.305609: Step 120: Cross entropy = 0.001758\n", "INFO:tensorflow:2018-10-28 14:42:50.340320: Step 120: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:50.693725: Step 130: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:50.693856: Step 130: Cross entropy = 0.002027\n", "INFO:tensorflow:2018-10-28 14:42:50.728312: Step 130: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:51.088048: Step 140: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:51.088175: Step 140: Cross entropy = 0.001670\n", "INFO:tensorflow:2018-10-28 14:42:51.122916: Step 140: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:51.476977: Step 150: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:51.477119: Step 150: Cross entropy = 0.000966\n", "INFO:tensorflow:2018-10-28 14:42:51.511913: Step 150: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:51.864215: Step 160: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:51.864342: Step 160: Cross entropy = 0.000542\n", "INFO:tensorflow:2018-10-28 14:42:51.898882: Step 160: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:52.254269: Step 170: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:52.254397: Step 170: Cross entropy = 0.001178\n", "INFO:tensorflow:2018-10-28 14:42:52.289158: Step 170: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:52.655582: Step 180: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:52.655716: Step 180: Cross entropy = 0.001364\n", "INFO:tensorflow:2018-10-28 14:42:52.692782: Step 180: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:53.062017: Step 190: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:53.062143: Step 190: Cross entropy = 0.000615\n", "INFO:tensorflow:2018-10-28 14:42:53.097311: Step 190: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:53.451888: Step 200: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:53.452016: Step 200: Cross entropy = 0.001257\n", "INFO:tensorflow:2018-10-28 14:42:53.486594: Step 200: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:53.846465: Step 210: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:53.846589: Step 210: Cross entropy = 0.000895\n", "INFO:tensorflow:2018-10-28 14:42:53.881588: Step 210: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:54.245489: Step 220: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:54.245617: Step 220: Cross entropy = 0.000290\n", "INFO:tensorflow:2018-10-28 14:42:54.280449: Step 220: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:54.642830: Step 230: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:54.642963: Step 230: Cross entropy = 0.001514\n", "INFO:tensorflow:2018-10-28 14:42:54.677905: Step 230: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:55.031232: Step 240: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:55.031357: Step 240: Cross entropy = 0.000443\n", "INFO:tensorflow:2018-10-28 14:42:55.065901: Step 240: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:55.429473: Step 250: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:55.429611: Step 250: Cross entropy = 0.000302\n", "INFO:tensorflow:2018-10-28 14:42:55.464584: Step 250: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:55.827542: Step 260: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:55.827668: Step 260: Cross entropy = 0.000705\n", "INFO:tensorflow:2018-10-28 14:42:55.862233: Step 260: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:56.236931: Step 270: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:56.237069: Step 270: Cross entropy = 0.000997\n", "INFO:tensorflow:2018-10-28 14:42:56.273377: Step 270: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:56.644086: Step 280: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:56.644221: Step 280: Cross entropy = 0.000648\n", "INFO:tensorflow:2018-10-28 14:42:56.682252: Step 280: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:57.057642: Step 290: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:57.057790: Step 290: Cross entropy = 0.001493\n", "INFO:tensorflow:2018-10-28 14:42:57.093669: Step 290: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:57.485280: Step 300: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:57.485414: Step 300: Cross entropy = 0.000987\n", "INFO:tensorflow:2018-10-28 14:42:57.521119: Step 300: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:57.880160: Step 310: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:57.880294: Step 310: Cross entropy = 0.000806\n", "INFO:tensorflow:2018-10-28 14:42:57.915277: Step 310: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:58.269446: Step 320: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:58.269580: Step 320: Cross entropy = 0.000892\n", "INFO:tensorflow:2018-10-28 14:42:58.304194: Step 320: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:58.665735: Step 330: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:58.665869: Step 330: Cross entropy = 0.000690\n", "INFO:tensorflow:2018-10-28 14:42:58.701489: Step 330: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:59.063143: Step 340: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:59.063275: Step 340: Cross entropy = 0.000744\n", "INFO:tensorflow:2018-10-28 14:42:59.098365: Step 340: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:59.462170: Step 350: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:59.462298: Step 350: Cross entropy = 0.000758\n", "INFO:tensorflow:2018-10-28 14:42:59.497309: Step 350: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:42:59.864110: Step 360: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:42:59.864244: Step 360: Cross entropy = 0.000658\n", "INFO:tensorflow:2018-10-28 14:42:59.899951: Step 360: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:00.260083: Step 370: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:00.260219: Step 370: Cross entropy = 0.000778\n", "INFO:tensorflow:2018-10-28 14:43:00.297879: Step 370: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:00.656371: Step 380: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:00.656503: Step 380: Cross entropy = 0.000410\n", "INFO:tensorflow:2018-10-28 14:43:00.691937: Step 380: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:01.059119: Step 390: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:01.059251: Step 390: Cross entropy = 0.000362\n", "INFO:tensorflow:2018-10-28 14:43:01.093824: Step 390: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:01.447903: Step 400: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:01.448039: Step 400: Cross entropy = 0.000542\n", "INFO:tensorflow:2018-10-28 14:43:01.482609: Step 400: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:01.836444: Step 410: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:01.836576: Step 410: Cross entropy = 0.000501\n", "INFO:tensorflow:2018-10-28 14:43:01.871385: Step 410: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:02.229445: Step 420: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:02.229575: Step 420: Cross entropy = 0.000416\n", "INFO:tensorflow:2018-10-28 14:43:02.263784: Step 420: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:02.620229: Step 430: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:02.620364: Step 430: Cross entropy = 0.000427\n", "INFO:tensorflow:2018-10-28 14:43:02.655607: Step 430: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:03.019248: Step 440: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:03.019377: Step 440: Cross entropy = 0.000420\n", "INFO:tensorflow:2018-10-28 14:43:03.054494: Step 440: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:03.410948: Step 450: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:03.411081: Step 450: Cross entropy = 0.000351\n", "INFO:tensorflow:2018-10-28 14:43:03.445594: Step 450: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:03.801125: Step 460: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:03.801254: Step 460: Cross entropy = 0.000424\n", "INFO:tensorflow:2018-10-28 14:43:03.836485: Step 460: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:04.194659: Step 470: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:04.194787: Step 470: Cross entropy = 0.000623\n", "INFO:tensorflow:2018-10-28 14:43:04.229901: Step 470: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:04.585500: Step 480: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:04.585633: Step 480: Cross entropy = 0.000350\n", "INFO:tensorflow:2018-10-28 14:43:04.621165: Step 480: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:04.976775: Step 490: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:04.976908: Step 490: Cross entropy = 0.000727\n", "INFO:tensorflow:2018-10-28 14:43:05.012645: Step 490: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:2018-10-28 14:43:05.331810: Step 499: Train accuracy = 100.0%\n", "INFO:tensorflow:2018-10-28 14:43:05.331937: Step 499: Cross entropy = 0.000311\n", "INFO:tensorflow:2018-10-28 14:43:05.366962: Step 499: Validation accuracy = 100.0% (N=100)\n", "INFO:tensorflow:Final test accuracy = 84.6% (N=26)\n", "INFO:tensorflow:Froze 2 variables.\n", "INFO:tensorflow:Converted 2 variables to const ops.\n" ] } ], "source": [ "%%bash\n", "IMAGE_SIZE=224\n", "ARCHITECTURE=\"mobilenet_0.50_${IMAGE_SIZE}\"\n", "\n", "python -m scripts.retrain \\\n", " --bottleneck_dir=tf_files/bottlenecks \\\n", " --how_many_training_steps=500 \\\n", " --model_dir=tf_files/models/ \\\n", " --summaries_dir=tf_files/training_summaries/\"${ARCHITECTURE}\" \\\n", " --output_graph=tf_files/tribune_graph.pb \\\n", " --output_labels=tf_files/tribune_labels.txt \\\n", " --architecture=\"${ARCHITECTURE}\" \\\n", " --image_dir=tf_files/tribune" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test the trained model\n", "\n", "First let's test against the training set." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# Make a list of all the test images\n", "import os\n", "import random\n", "from IPython.display import display, HTML\n", "imgs = []\n", "data_dir = 'tf_files/tribune/'\n", "for img_dir in [d for d in os.listdir(data_dir) if os.path.isdir(os.path.join(data_dir, d))]:\n", " for img in [i for i in os.listdir(os.path.join(data_dir, img_dir)) if i[-4:] == '.jpg']:\n", " imgs.append(os.path.join(data_dir, img_dir, img)) " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
tf_files/tribune/portraits/FL4444441-500.jpg" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Choose one image at random\n", "img = random.sample(imgs, 1)[0]\n", "display(HTML('
{0}'.format(img)))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2018-10-28 14:45:45.051535: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA\n", "\n", "Evaluation time (1-image): 0.213s\n", "\n", "portraits (score=1.00000)\n", "protests (score=0.00000)\n" ] } ], "source": [ "!python -m scripts.label_image --graph=tf_files/tribune_graph.pb --labels=tf_files/tribune_labels.txt --image=$img" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test against a randomly selected image from the complete collection\n", "\n", "Let's see how our model goes against images it's never seen before..." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "# Load Tribune images data\n", "import pandas as pd\n", "df = pd.read_csv('https://raw.githubusercontent.com/GLAM-Workbench/ozglam-data-records-of-resistance/master/data/images.csv')" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "# Set up a directory for test images\n", "test_dir = os.path.join('tf_files', 'tribune_tests')\n", "os.makedirs(test_dir, exist_ok=True)\n", "images = df['images']" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
tf_files/tribune_tests/FL4526748-500.jpg" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# get a random image\n", "img = images.sample(1).iloc[0]\n", "img_url = 'https://s3-ap-southeast-2.amazonaws.com/wraggetribune/images/500/{0}-500.jpg'.format(img)\n", "filename = os.path.join(test_dir, '{}-500.jpg'.format(img))\n", "response = requests.get(img_url, stream=True)\n", "with open(filename, 'wb') as fd:\n", " for chunk in response.iter_content(chunk_size=128):\n", " fd.write(chunk)\n", "display(HTML('
{0}'.format(filename)))" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2018-10-28 14:46:08.328867: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA\n", "\n", "Evaluation time (1-image): 0.208s\n", "\n", "portraits (score=1.00000)\n", "protests (score=0.00000)\n" ] } ], "source": [ "!python -m scripts.label_image --graph=tf_files/tribune_graph.pb --labels=tf_files/tribune_labels.txt --image=$filename" ] }, { "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.5" } }, "nbformat": 4, "nbformat_minor": 2 }