{
"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
}