Showing preview only (947K chars total). Download the full file or copy to clipboard to get everything.
Repository: thibo73800/capsnet-traffic-sign-classifier
Branch: master
Commit: 21a1fbce2ad2
Files: 19
Total size: 921.6 KB
Directory structure:
gitextract_oohy2z2g/
├── .floydignore
├── .gitignore
├── LICENSE
├── README.md
├── Traffic_Sign_Classifier.ipynb
├── _config.yml
├── caps_net.py
├── data_handler.py
├── floyd_requirements.txt
├── floyd_run.txt
├── logger.py
├── model.py
├── model_base.py
├── settings/
│ └── hyperparameters.json
├── signnames.csv
├── test.py
├── test_web_images.py
├── train.py
└── utils.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .floydignore
================================================
# Directories and files to ignore when uploading code to floyd
images/*
dataset/*
outputs/*
.git
.eggs
eggs
lib
lib64
parts
sdist
var
*.pyc
*.swp
.DS_Store
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
outputs/*
dataset/*
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# Capsnet - Traffic sign classifier - Tensorflow
A Tensorflow implementation of CapsNet(Capsules Net) apply on the German traffic sign dataset
[](CONTRIBUTING.md)
[](https://opensource.org/licenses/Apache-2.0)

This implementation is based on this paper: <b>Dynamic Routing Between Capsules</b> (https://arxiv.org/abs/1710.09829) from Sara Sabour, Nicholas Frosst and Geoffrey E. Hinton.
This repository is a work in progress implementation of a Capsules Net. Since I am using a different dataset (Not MNIST) some details in the architecture are different. The code for the CapsNet is located in the following file: <b>caps_net.py</b> while the whole model is created inside the <b>model.py</b> file. The two main methods used to build the CapsNet are <b>conv_caps_layer</b> and <b>fully_connected_caps_layer</b>
<img src="images/chart.jpg"></img>
## Requirements
- Python 3
- NumPy 1.13.1
- Tensorflow 1.3.0
- docopt 0.6.2
- Sklearn: 0.18.1
- Matplotlib
## Install
$> git clone https://github.com/thibo73800/capsnet_traffic_sign_classifier.git
$> cd capsnet_traffic_sign_classifier.git
$> wget https://d17h27t6h515a5.cloudfront.net/topher/2017/February/5898cd6f_traffic-signs-data/traffic-signs-data.zip
$> unzip traffic-signs-data.zip
$> mkdir dataset
$> mv *.p dataset/
$> rm traffic-signs-data.zip
## Train
$> python train.py -h
$> python train.py dataset/
During the training, the checkpoint is saved by default into the outputs/checkpoints/ folder. The exact path and name of the checkpoint is print during the training.
## Test
In order to measure the accuracy and the loss on the Test dataset you need to used the test.py script as follow:
$> python test.py outputs/checkpoints/ckpt_name dataset/
## Metrics / Tensorboard
<b>Accuracy: </b>
<ul>
<li>Train: 99%</li>
<li>Validation: 98%</li>
<li>Test: 97%</li>
</ul>
Checkpoints and tensorboard files are stored inside the <b>outputs</b> folder.
<img src="images/tensorboard.png"></img>
Exemple of some prediction:
<img src="images/softmax.png"></img>
================================================
FILE: Traffic_Sign_Classifier.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"## Step 0: Load The Data"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(34799, 32, 32, 3)\n",
"(34799,)\n"
]
}
],
"source": [
"# Load pickled data\n",
"import pickle\n",
"\n",
"# TODO: Fill this in based on where you saved the training and testing data\n",
"\n",
"training_file = \"dataset/train.p\"\n",
"validation_file= \"dataset/valid.p\"\n",
"testing_file = \"dataset/test.p\"\n",
"\n",
"with open(training_file, mode='rb') as f:\n",
" train = pickle.load(f)\n",
"with open(validation_file, mode='rb') as f:\n",
" valid = pickle.load(f)\n",
"with open(testing_file, mode='rb') as f:\n",
" test = pickle.load(f)\n",
" \n",
"X_train, y_train = train['features'], train['labels']\n",
"X_valid, y_valid = valid['features'], valid['labels']\n",
"X_test, y_test = test['features'], test['labels']\n",
"\n",
"# Print the shape of variables\n",
"print(X_train.shape)\n",
"print(y_train.shape)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Step 1: Dataset Summary & Exploration\n",
"\n",
"The pickled data is a dictionary with 4 key/value pairs:\n",
"\n",
"- `'features'` is a 4D array containing raw pixel data of the traffic sign images, (num examples, width, height, channels).\n",
"- `'labels'` is a 1D array containing the label/class id of the traffic sign. The file `signnames.csv` contains id -> name mappings for each id.\n",
"- `'sizes'` is a list containing tuples, (width, height) representing the original width and height the image.\n",
"- `'coords'` is a list containing tuples, (x1, y1, x2, y2) representing coordinates of a bounding box around the sign in the image. **THESE COORDINATES ASSUME THE ORIGINAL IMAGE. THE PICKLED DATA CONTAINS RESIZED VERSIONS (32 by 32) OF THESE IMAGES**\n",
"\n",
"Complete the basic data summary below. Use python, numpy and/or pandas methods to calculate the data summary rather than hard coding the results. For example, the [pandas shape method](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.shape.html) might be useful for calculating some of the summary results. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Provide a Basic Summary of the Data Set Using Python, Numpy and/or Pandas"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Number of training examples = 34799\n",
"Number of testing examples = 12630\n",
"Image data shape = (32, 32, 3)\n",
"Number of classes = 43\n"
]
}
],
"source": [
"### Replace each question mark with the appropriate value. \n",
"### Use python, pandas or numpy methods rather than hard coding the results\n",
"\n",
"# TODO: Number of training example\n",
"n_train = X_train.shape[0]\n",
"\n",
"# TODO: Number of validation example\n",
"n_validation = X_valid.shape[0]\n",
"\n",
"# TODO: Number of testing example.\n",
"n_test = X_test.shape[0]\n",
"\n",
"# TODO: What's the shape of an traffic sign image?\n",
"image_shape = X_train.shape[1:]\n",
"\n",
"# TODO: How many unique classes/labels there are in the dataset.\n",
"n_classes = len(set(y_train))\n",
"\n",
"print(\"Number of training examples =\", n_train)\n",
"print(\"Number of testing examples =\", n_test)\n",
"print(\"Image data shape =\", image_shape)\n",
"print(\"Number of classes =\", n_classes)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Include an exploratory visualization of the dataset"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Visualize the German Traffic Signs Dataset using the pickled file(s). This is open ended, suggestions include: plotting traffic sign images, plotting the count of each sign, etc. \n",
"\n",
"The [Matplotlib](http://matplotlib.org/) [examples](http://matplotlib.org/examples/index.html) and [gallery](http://matplotlib.org/gallery.html) pages are a great resource for doing visualizations in Python.\n",
"\n",
"**NOTE:** It's recommended you start with something simple first. If you wish to do more, come back to it after you've completed the rest of the sections. It can be interesting to look at the distribution of classes in the training, validation and test set. Is the distribution the same? Are there more examples of some classes than others?"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA2QAAANeCAYAAAB9Cc0DAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xm8ZWdV5//v2uecO9StSqqSqiSVVJIikAAJhIBhiICi\nGExQG5SfIiKCguivHbDb/nUj3b8W/Wm/0J+obTu0jIkDk0YkIIghJEYQgSSEkIGQkLlSQ2q4Nd7h\nnLOf/uPsgls3d63n3Htu3X2q6vN+vepV997nPHs/Zw9r7+cMa1lKSQAAAACAlVfUPQAAAAAAOFEx\nIQMAAACAmjAhAwAAAICaMCEDAAAAgJowIQMAAACAmjAhAwAAAICanNATMjM7YGbnHYXlmpm938z2\nmNmXlnv5ixzLVWb2W0F7dhuY2WYzS2bWXP4RYlBm9ikze33d48DyITYRm44HxCYcDwY5js3snCqW\nNZZ7XEdDFU+fUvc4TkQDTcjM7EEz22FmE3P+9iYzu3Hgka2AlNLqlNL9R2HRL5J0uaRNKaXnHYXl\nL5ujuA2Glpn9uJndY2b7quP3ajM7KXh8MrODVVA9YGbvWaFxvt3M/ir3uJTSlSmlq5ew/OM28BKb\nXMSmIUZs+tbyj9vYhPpV14ep6pzZXr04tNp7/FKP46rvw1Us61brvtHM3rTUseP4tRzvkDUkvWUZ\nlnM8OVfSgymlg4vtyCu9y8vZnv8q6btTSidJOk9SU5L7Sn3lWVVQXZ1SGopgWr3bcUK/y51BbHoi\nYtOQIDYBtfqhlNJqSc+RdKmk/zb/AYMex0c7ZhKTjy/LETD/f0n/yczWLtRoZt9pZl82s73V/9/p\nLah61eLXzOyu6iM17zezsaptnZl9wswer9o+YWab5vR9g5ndb2b7zewBM3tt9fenmNk/V+vfaWYf\nntPnW6/CVa+Q/ImZ/UO1jC+a2ZPnPPZl1SuXe83sT6tlPuHiZ2ZvlPQeSZdVr778RvX3nzWz+8xs\nt5lda2ZnzhvHL5jZvZLuXWCZnzKzX5z3t6+a2Y9UPz/NzK6rln2Pmf3YvEWsC57X3G0wbmbvNLOH\nquf5OTMbX2A8J5vZe81sq5ltMbPfsurt+Gh7L7Ccf2dmd5rZZPWq0dOrv/8XM/vbeY/9n2b2R32s\n/w1m9nkz+wMz2yXp7fPXW71itW3On7qSluXV2Oo4+tNqnx2oxnKGmf1hddx+3cyePefxZ5rZNdVx\n/YCZ/XL19yskvU3Sq6vlfLX6+41m9ttm9nlJhySdZ/NecauOtbur/X2XmT1ngXHeVP341Wr5r57T\nNzpOf97M7q322Z+YmVVtfe/3FURsOvI5EJuITcSm4YhNGBIppS2SPiXpGVL+ODazwsz+WxWLdpjZ\nX5jZyVXb4Y9Qv9HMHpb02Tl/a5rZb0t6saQ/ro7tP66O1XfOHVN1fP+HhcZrC8RkC65lZvbTc865\n+83s5+Yt7/+p4tVjZvYzy7NVsSQppSX/k/SgpO+T9HeSfqv625sk3Vj9fIqkPZJep94rfa+pfj81\nWN4dks6u+n5+znJPlfQqSaskrZH0N5L+vmqbkLRP0lOr3zdKuqj6+YOS/qt6k88xSS+as74k6SnV\nz1dJ2iXpedVY/1rSh6q29dXyf6Rqe4uktqQ3Oc/jDZI+N+f375W0U71XYkYl/S9JN80bx3XVcx5f\nYHk/Jenzc36/UNJktawJSY9I+ulqbM+u1nVh7nktsA3+RNKNks5S792F76zWsbl6XLN63Ecl/Xm1\n7tMkfUnSz+W297zndIGkg+p9fKol6T9Luk/SiHqv4h+StKZ6bEPSVkkv6GP9b5DUkfRL1fN9wvas\nHvciSXur53VQ0suC4zxJekzSNvWO9c3BY6+qtv93VM//s5IeqPZhQ71Xu2+oHltIukXSf6+e93mS\n7pf0/VX72yX91bzl3yjpYUkXVc+vVf3tTVX7j0raIum5kky9m7lzg+f1lEUep5+QtFbSOZIel3TF\nYvb7Sv0TsYnYRGwiNg1hbOJf/f9UXR+qn8+WdKek/6/6PXcc/0wVD86TtLo67/6yattcHYt/UcWA\ncT0xRn1rWdXvz6vO4aL6fb16MeZ0Z+xHxGRlrmWSfkDSk6tz7rurZT+nartC0nb1JqMTkj4w/9zj\n3woel8txUFc7c6+kDTrypud1kr40r88XJL0hWN7Pz/n95ZK+6Tz2Ekl7qp8n1LsJeJXmXeSqE+Nd\n6n1nYqEDe+5Nz3vmrfvr1c8/JekLc9pMvRuNfm963ivpd+f8vlq9m6bNc8bxvcF2XqPehfnc6vff\nlvS+6udXS/qXeY//c0m/nntec7eBeherKfU+/jJ//ZurxzUlnS5pZu52rgLADbntPW+Z/6+kj8z5\nvVDvYv2S6vfPSfqp6ufLDx8Hfaz/DZIeXsQxfJZ6NxcXBI/5LvVuStZK+mP1bsybzmOvkvTuOb//\nkqS75/z+TEmT1c/Pnz9WSb8m6f3Vz2/Xwjc9v7nA3w5fLD4t6S19Pvf5Nz39HKdzJw0fkfTWxez3\nlfonYhOxKRGb5j32KhGbao9N/Kv/n3rx/IB6sfkhSX96+Lzt4zi+XtK/n9P21OpYbM6JR+fNaT/8\ntwUnZNXf7pZ0efXzL0r6ZDD2I2KyFn8t+/vD56Gk90l6x5y2C+afe/xbuX/L8hnvlNId6r069dZ5\nTWeqd7DP9ZB6FxrPI/Mee6YkmdkqM/vz6m3ifZJukrTWzBqp932IV0v6eUlbrfcRmKdVy/jP6t2k\nfKn6CEr0luzcj4ocUi/oH34e3xpX6h25jwbLme+I7ZBSOqDeK8Nzt8Mj8zvNefx+Sf8g6cerP71G\nvVeTpd4rts+vPqYxaWaTkl4r6Yw5i/Ce11zr1Xv18JuZ53Kueq8YbZ2zvj9X79Vgqf/tPX+blOpt\ng8Pb5APV85Skn6h+72f9UrAt50u9jyv8o6QPBY+5KaU0m1KaVO8diM2Snh4sdvucn6cW+P3w9j9X\n0pnz9t3b1Luxi0TP72zl96Gnn+PUO5YWc56tGGJTFrHpiYhNxCYc/16ZUlqbUjo3pfTvU0pTc9qi\n43j+teMhffsFoX76L+RqST9Z/fyTkv4y8/i5yw+vZWZ2pZn9W/VR30n1XvhaP6fv/OsaarKcXwj8\ndUm3Spr7WdjH1Avsc52j3kXGc/a8xz5W/fyr6r0S8fyU0jYzu0TSV9QLtEopfVrSp633vYLfkvRu\nSS9Ovc/j/6wkmdmLJH3GzG5KKd23iOe2VdLc74TY3N/7cMR2sF7mt1PVe9X1sJRZxgcl/Xr1+fox\nSTdUf39E0j+nlC5fxHgWslPStHpvbX81eNwj6r0KvD6l1JnfuIjt/Zh6r8iqeqypt+8Pb5O/kfRO\n630X54clXdbP+g8PIxj/QprqPe/FsEU+fiGPSHogpXS+0+49j+j5PaLFP5fD+jlOFx7Q8pxnRwux\nyUdsIjYthNiEE1l0HM+/dpyj3keRt+vbsTfqv1DbX0m6w8yepd4LKn+/iPG51zIzG5V0jXqfpPhY\nSqltZn+vb8eIrXridQ01WbYsSFVw+7CkX57z509KusDMfqL6QuOr1fuOwSeCRf2CmW0ys1PU+9z3\n4S/grlHvFbzJqu3XD3cws9PN7BVVkJ5R763osmr7Ufv2F+z3qHcgl4t8ev8g6Zlm9krrZbX5BR35\nKm/OByX9tJldUp0g/0PSF1NKDy5iGZ9U76T7TUkfrl61lXrb8gIze52Ztap/z7XqS+j9qpb3Pkm/\nb70vczfM7LJqvHMft1XSP6l3Q3KS9b7g+mQz+25pUdv7I5J+wMxeamYt9W5qZ9TLMqaU0uPqvbX/\nfvVuDO7uZ/39MLPXmtk51c/nqvcxq+udx15U7beG9dLi/r56NwF397u+wJck7bdeooDxah3PMLPn\nVu3bJW22xWV5eo96iSy+w3qeUj3HhWxX73Pwhy35OF2m8+yoIDaFiE1PRGwiNgGeD0r6D2b2pOq8\n+x/qxT3vRZj55h/bSik9KunL6r0zds28d+tyomvZiHrfuXxcUsfMrpT0sjl9PyLpDWZ2oZmt0pxr\nF1becqel/U31vjMhSUop7ZL0g+pd0Hap99GBH0wp7QyW8QH1Lmr3q/fxhsMpf/9QvS8w7pT0bzry\nlexC0n9U75WC3ep9cfH/rtqeK+mLZnZA0rXqfXZ2UbVtqvH+qKTfrZ7HhZJuVu8i3U//z6j3vYRr\n1HtF4sn69kd8+h3DjHpfHv0+ffsjMoc/MvSyanmHv9z9O+qdhIv1nyR9Tb3AsLtazkLHyE+pd6Lf\npd4F7m/VS1Yg9bm9U0r3qPfW/P9Sb5/+kHppaGfnPOwD859vH+vvx4WS/tXMDqqXnOEeVa+gSt/K\nHPe26tfT1bvx3qfeMXmuesdwexHrW1Dq1SX5QfW+c/SAetvhPZJOrh7yN9X/u8zs1j6X+Tfq3cR9\nQNJ+9V5pO8V5+NslXW29jyT92IDH6cDn2VFGbFq4P7Hpic+H2ERsAjzvU2/idJN658a0et/H7Nf/\nlPR/WS+z6R/N+fvV6r0zn/u44hGia1kVg39ZvYnXHvU+Yn3tnL6fUu/69Vn1EpV8djHrxvKy3lcO\nhoOZPajelx0/U/dYItWrgo9Kem1K6Ybc4wEc24hNAICjxcy+S72PLp6bhunGHCuGwo19MrPvN7O1\n1ccl3qbeZ3D/reZhATjBEZsA4NhVfTT6LeplnWUydoJiQta/y9T7mNLhj7C8cpGf8wWAo4HYBADH\noOo7tZPqfbT5D2seDmo0VB9ZBAAAAIATCe+QAQAAAEBNlrMOWVZRFKkovDlgXDplkHfybICqLFFW\n36LZCPsWDb8993zKjp9BdXxkLOw7MjbutnW63bBvp+Mn6LLMhmy1Wm5b0cgcauGy4/UuR9GdhRzN\n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\naG5p+LQbSyKnR9LV5caGJvzyzwBQqtT85014uXMqtg/IuXAFV71Hks2is795iedsJy93nLR1uLFg\nC9+XacoHvdGi35bhwYMjNPfwKb+kcXWWLzdDDqKBHH+P7+YBv8z2K1/sl7UHgOe/7Go3NpPj27md\nDCGnIkf+SM4vafyqq/2y0QCwPe9fI+7++n6a++QBv5x1qPF9VCn58WMHedn7a5p3fwAArN3EX2+2\n4l8vT57hJce/9bX73VgXKSl+JQjBUHFuZDo6eWsNK/vlumPthgqb/DLh6aZ2mlvc65cnz5R4+4R0\n8xY3Zqv4MRj8SytgfFttvMkv89++PtLCZHqVG5oY48dvrc2/1ygXeIukdW3+deCqm/0xEwAyNf/Y\n2L/vuzS3POnf/6C/n+a2PX+jG5t5lAxAACaf8u/pVu2+iebefLW/f8evu4bmHj7il8UfO8b30Xzp\nEzIREREREZEW0YRMRERERESkRTQhExERERERaRFNyERERERERFpEEzIREREREZEW0YRMRERERESk\nRTQhExERERERaZHL2ocsoN5Po+mKRPqMJaRfBms7AQBGmm2kkWRL/BXrWsX7Fmy59sVubPwM71tQ\nnR1zY4VTfj8EAOjquM6NpbENTcOxTlV+MusVBvD2WSH2vkGt6IZYn7F6qt+PCTne76RMXtNMmTwv\n6n2vXJFWcYHsh9geYueRLabZ33OcWYJce/P+J9kO3hfFsn5vrVrkuK/V/B5XlcjINjblx584wvvg\njYz750xH5LKQJb0M+9v4MfTaF2x3Y7tv2UZzHx72++1MneG9tV79Er9340H4zwsA9+/1x5Afzfi9\nhwDg+nV9fu6L+Oudnp11Y6eORPre1PyeSWHWP14BYPqo3zOpcxXvPdVGRqCpcf+aBgAz4/5rOrR/\nkuaudJlsglUDza9Ha9bwnk85cv9zfJJfW5Pn+32dJgb9HmUAMHrSvwZ2wO9XBwBt68hritzDsGjv\nNXxbgdzvsV6pALB/1u+PVWnj2/m6dn8cma3y689Vqd+DMcvuMwAYGQo2b1hDc1Eh42bkViK3xd8P\nydpIn7mCf/3JVDbQ3Bs7d7mxR4a/SnMPjfrX1Nw6fjxjHw+fp0/IREREREREWkQTMhERERERkRbR\nhExERERERKRFNCETERERERFpEU3IREREREREWkQTMhERERERkRa5rGXvDX4J+ljBba9c/ryS2QNI\n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\n3DDu9/F8ZIJf06fItdUi10fW8zKQ/p8AMFsi17E8H497+vyeX7lb30pzK2S5dppfW9t6/etAkvA+\nieWS38MVVd6HtWetf25szfHtnPT715Brtr2E5t70lH/fvf/0WZo7Meb3HNzRwceYUo8/Xs+QnqAA\ncOioPwa15XmPxd52//o0OsT7n82XPiETERERERFpEU3IREREREREWkQTMhERERERkRbRhExERERE\nRKRFNCETERERERFpEU3IREREREREWuSylr1HCKg5ZblTkHrcALIdeTfW1cVLLVdqfv3os2O8XDIC\n2US12HyWlEkNkVruIOVm2fMCSEi52UxklWukOmtphpRmBXCu5O+jxHjZ11LZL+2a1ngp01rVL6kf\nQqyYu3/chchyjR2yNAgk7HiP5ZI4a1tQfwApRRw5B1eyQrmCx446pXrbJ2hutssvE17O81Lua/sG\n3Fgl5ecM66rRbvzY3b3VLw39vFWvpbnDky92Y8UyHyPCrH+uTk/N0tyhqdP+85ZO0twf33mtG/t6\ngY8RDz2xx411jp+jue3kPc+Zst9SBQB6p/1rU/eW62nu9ddudWM37eSlv5+a9UtWP3EyUrqelLMu\nzfgxAAh9fW4sN7iJ5q50aTDMFpofSzc/bzXNzVT81guny3x8ypX8a8J0ifflSEmPldT4jUiFtfYp\n8RY6COQ6luMl83PkVnLLDr5YgG3LyH1I9D6FIPcDW7fx592akn04dYLmlg4dcmMPPvxtmjue+s9d\nIm1VAOCefX5suMhfb3unv49WtfP7H+v0D45MO2+dMl/6hExERERERKRFNCETERERERFpEU3IRERE\nREREWkQTMhERERERkRbRhExERERERKRFNCETERERERFpEU3IREREREREWuSy9iELAGpOf4lYV66U\n9OSZmuC9xKoFv79NLdJrKk39vgalcpHmso4IlvJeGiGQPmSsAREAkNwK6dkFAIG8Xov0xyqV/b2Y\nyfs9yoBYDyx+dLBcy0R6a7FWcbHeIDS8mNzI66X7gS838KOS5q5k2Xw71m57ftNYOdIPrEL219S0\n3wMIAOysP3Z1RXrmtGXI8B3pc7imx89d37+G5taStW4sjRy72UW8BVio7nJjvZGeXms7/X5vI/v4\n9eMrxx93YzNneI+6xDrcmEX6KU2THlBYezXNvflFr3ZjG3fSVJwo+8fs1/ceobn/+PkvuLHS+DGa\n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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7fec8bd53898>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Most common index\n",
"index: 2 => Speed limit (50km/h) = 0.0591355252409\n",
"index: 1 => Speed limit (30km/h) = 0.0582529054612\n",
"index: 13 => Yield = 0.0564876659017\n",
"index: 12 => Priority road = 0.055605046122\n",
"index: 38 => Keep right = 0.0547224263423\n",
"index: 10 => No passing for vehicles over 3.5 metric tons = 0.0529571867829\n",
"index: 4 => Speed limit (70km/h) = 0.0520745670032\n",
"index: 5 => Speed limit (80km/h) = 0.0485440878843\n",
"index: 25 => Road work = 0.0397178900872\n",
"index: 9 => No passing = 0.0388352703074\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAagAAAEYCAYAAAAJeGK1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGAdJREFUeJzt3X2UXVd93vHvg2yXFzuojVVXlhTkgEKWoLURim0gTXmJ\nG0k2KF3pauVADF5ZVRVsCiksKtw3oE0KIaXBxbGqgBtUXIwLCRWg4vD+0iIjGYxs2bgMQl6SEXgM\n9VtMbMn+9Y97tLiMRporzYxmz53vZ61Zc88++9y7z55Z88ze99x9UlVIktSaJ810AyRJGo8BJUlq\nkgElSWqSASVJapIBJUlqkgElSWqSAaXmJdmd5MUz3Y6ZlOQfJNmX5OEkzzuO496a5IPT2TZpuhhQ\nmlFJ9ib51TFlr0nylcPbVfWcqvrCBM+zNEklOWWamjrT/hC4sqpOr6pvzHRjpJPBgJIG0EDwPQPY\nPcNtkE4qA0rN6x9lJTk/yc4kDyb5QZJ3d9W+1H2/v5sGe0GSJyX5V0nuTnJvki1Jnt73vJd1+36Y\n5F+PeZ23JvlIkg8meRB4TffaX01yf5IDSd6b5LS+56skr03y7SQPJfl3SZ6Z5P907b2xv/6Ycxy3\nrUn+WpKHgXnAN5N85yjHPyfJp5P8qOuXq45S738k+X6SB5J8Kclz+vatSXJH1/Z7krypKz8zySe6\n8/5Rki8neVK37+wkH00ymuS7Sf5Z3/ON+7NK8uSuX3/YPeeOJGcd85dAc5IBpdnmPcB7qupngGcC\nN3blv9J9n99Ng30VeE339RLg54HTgfcCJFkO/DHwSmAh8HRg0ZjXWgt8BJgPXA88DvwucCbwAuBl\nwGvHHPNrwPOBC4E3A5uBVwFLgOcClx7lvMZta1U9WlWnd3XOrapnjj0wyRnAZ4BPAWcDzwI+e5TX\n+V/AMuBvAl/vzuuw9wP/tKrO6Nr6ua78jcB+YAFwFnAVUF1IfRz4Jr2+exnwhiS/1h13tJ/Vq+n1\n9xLgZ4ENwI+P0l7NYQaUWvCx7j/p+5PcTy84juYg8KwkZ1bVw1W1/Rh1Xwm8u6r2VNXDwFuAdd10\n3T8EPl5VX6mqx4B/A4xdmPKrVfWxqnqiqn5cVbdU1faqOlRVe4H/Avy9Mcf8QVU9WFW7gduBv+he\n/wF64XC0CxyO1daJXAJ8v6r+Y1X9VVU9VFU3j1exqq7r9j8KvBU4t29UeRBYnuRnqur/VdXX+8oX\n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\nZEBJkppkQEmSmmRASZKaZEBJkppkQEmSmmRASZKaZEBJkppkQEmSmmRASZKaZEBJkppkQEmSmmRA\nSZKaZEBJkppkQEmSmmRASZKaZEBJkppkQEmSmmRASZKaZEBJkppkQEmSmmRASZKaZEBJkppkQEmS\nmmRASZKaNFBAJVmV5K4kI0k2jrM/Sa7u9u9KsqIrX5Lk80nuSLI7yeun+gQkScNpwoBKMg+4BlgN\nLAcuTbJ8TLXVwLLuaz1wbVd+CHhjVS0HLgSuGOdYSZKOcMoAdc4HRqpqD0CSG4C1wB19ddYCW6qq\ngO1J5idZWFUHgAMAVfVQkjuBRWOOlX7K0o2fPOb+ve+4+CS1RC3y92PuGGSKbxGwr297f1d2XHWS\nLAWeB9w83oskWZ9kZ5Kdo6OjAzRLkjTMTspFEklOBz4KvKGqHhyvTlVtrqqVVbVywYIFJ6NZkqSG\nDRJQ9wBL+rYXd2UD1UlyKr1wur6q/uzEmypJmksGCagdwLIk5yQ5DVgHbB1TZytwWXc134XAA1V1\nIEmA9wN3VtW7p7TlkqShNuFFElV1KMmVwE3APOC6qtqdZEO3fxOwDVgDjACPAJd3h78I+C3gtiS3\ndmVXVdW2qT0NSdKwGeQqPrpA2TambFPf4wKuGOe4rwCZZBslSXOQK0lIkppkQEmSmmRASZKaNNB7\nUJI0LFyJYvZwBCVJapIBJUlqkgElSWqSASVJapIBJUlqklfxadbxKqzpZf+qFY6gJElNMqAkSU0y\noCRJTTKgJElNMqAkSU3yKj5JU8qrADVVHEFJkppkQEmSmuQUnzTLOIWmucIRlCSpSQaUJKlJBpQk\nqUkGlCSpSQaUJKlJXsUnqSkTXaWoucMRlCSpSQMFVJJVSe5KMpJk4zj7k+Tqbv+uJCv69l2X5N4k\nt09lwyVJw23CKb4k84BrgIuA/cCOJFur6o6+aquBZd3XBcC13XeAPwXeC2yZumYPP6c5Tpx9p8nw\n96cdg4ygzgdGqmpPVT0G3ACsHVNnLbClerYD85MsBKiqLwE/mspGS5KG3yABtQjY17e9vys73jrH\nlGR9kp1Jdo6Ojh7PoZKkIdTMVXxVtRnYDLBy5cqa4eZIM8YpptnNtRKnziAjqHuAJX3bi7uy460j\nSdLABgmoHcCyJOckOQ1YB2wdU2crcFl3Nd+FwANVdWCK2ypJmkMmDKiqOgRcCdwE3AncWFW7k2xI\n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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7fec6d15eda0>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"### Data exploration visualization code goes here.\n",
"### Feel free to use as many code cells as needed.\n",
"import matplotlib.pyplot as plt\n",
"import random\n",
"from PIL import Image\n",
"import numpy as np\n",
"import random\n",
"from PIL import Image, ImageEnhance\n",
"# Visualizations will be shown in the notebook.\n",
"%matplotlib inline\n",
"\n",
"# Load name of id\n",
"with open(\"signnames.csv\", \"r\") as f:\n",
" signnames = f.read()\n",
"id_to_name = { int(line.split(\",\")[0]):line.split(\",\")[1] for line in signnames.split(\"\\n\")[1:] if len(line) > 0}\n",
"\n",
"\n",
"graph_size = 3\n",
"random_index_list = [random.randint(0, X_train.shape[0]) for _ in range(graph_size * graph_size)]\n",
"fig = plt.figure(figsize=(15, 15))\n",
"for i, index in enumerate(random_index_list):\n",
" a=fig.add_subplot(graph_size, graph_size, i+1)\n",
" #im = Image.fromarray(np.rollaxis(X_train[index] * 255, 0,3))\n",
" imgplot = plt.imshow(X_train[index])\n",
" # Plot some images\n",
" a.set_title('%s' % id_to_name[y_train[index]])\n",
"\n",
"plt.show()\n",
"\n",
"\n",
"\n",
"fig, ax = plt.subplots()\n",
"# the histogram of the data\n",
"values, bins, patches = ax.hist(y_train, n_classes, normed=10)\n",
"\n",
"# add a 'best fit' line\n",
"ax.set_xlabel('Smarts')\n",
"ax.set_title(r'Histogram of classess')\n",
"\n",
"# Tweak spacing to prevent clipping of ylabel\n",
"fig.tight_layout()\n",
"\n",
"print (\"Most common index\")\n",
"most_common_index = sorted(range(len(values)), key=lambda k: values[k], reverse=True)\n",
"for index in most_common_index[:10]:\n",
" print(\"index: %s => %s = %s\" % (index, id_to_name[index], values[index]))\n",
"\n",
" \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"----\n",
"\n",
"## Step 2: Design and Test a Model Architecture\n",
"\n",
"Design and implement a deep learning model that learns to recognize traffic signs. Train and test your model on the [German Traffic Sign Dataset](http://benchmark.ini.rub.de/?section=gtsrb&subsection=dataset).\n",
"\n",
"The LeNet-5 implementation shown in the [classroom](https://classroom.udacity.com/nanodegrees/nd013/parts/fbf77062-5703-404e-b60c-95b78b2f3f9e/modules/6df7ae49-c61c-4bb2-a23e-6527e69209ec/lessons/601ae704-1035-4287-8b11-e2c2716217ad/concepts/d4aca031-508f-4e0b-b493-e7b706120f81) at the end of the CNN lesson is a solid starting point. You'll have to change the number of classes and possibly the preprocessing, but aside from that it's plug and play! \n",
"\n",
"With the LeNet-5 solution from the lecture, you should expect a validation set accuracy of about 0.89. To meet specifications, the validation set accuracy will need to be at least 0.93. It is possible to get an even higher accuracy, but 0.93 is the minimum for a successful project submission. \n",
"\n",
"There are various aspects to consider when thinking about this problem:\n",
"\n",
"- Neural network architecture (is the network over or underfitting?)\n",
"- Play around preprocessing techniques (normalization, rgb to grayscale, etc)\n",
"- Number of examples per label (some have more than others).\n",
"- Generate fake data.\n",
"\n",
"Here is an example of a [published baseline model on this problem](http://yann.lecun.com/exdb/publis/pdf/sermanet-ijcnn-11.pdf). It's not required to be familiar with the approach used in the paper but, it's good practice to try to read papers like these."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Pre-process the Data Set (normalization, grayscale, etc.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Minimally, the image data should be normalized so that the data has mean zero and equal variance. For image data, `(pixel - 128)/ 128` is a quick way to approximately normalize the data and can be used in this project. \n",
"\n",
"Other pre-processing steps are optional. You can try different techniques to see if it improves performance. \n",
"\n",
"Use the code cell (or multiple code cells, if necessary) to implement the first step of your project."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n"
]
}
],
"source": [
"### Preprocess the data here. It is required to normalize the data. Other preprocessing steps could include \n",
"### converting to grayscale, etc.\n",
"### Feel free to use as many code cells as needed.\n",
"\n",
"# I used keras only for the ImageDataGenerator\n",
"from keras.preprocessing.image import ImageDataGenerator\n",
"\n",
"\n",
"X_train = X_train / 255\n",
"X_valid = X_valid / 255\n",
"X_test = X_test / 255\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def preprocessing_function(img):\n",
" \"\"\"\n",
" Custom preprocessing_function\n",
" \"\"\"\n",
" img = img * 255\n",
" img = Image.fromarray(img.astype('uint8'), 'RGB')\n",
" img = ImageEnhance.Brightness(img).enhance(random.uniform(0.6, 1.5))\n",
" img = ImageEnhance.Contrast(img).enhance(random.uniform(0.6, 1.5))\n",
"\n",
" return np.array(img) / 255\n",
"\n",
"train_datagen = ImageDataGenerator()\n",
"train_datagen_augmented = ImageDataGenerator(\n",
" rotation_range=20,\n",
" shear_range=0.2,\n",
" width_shift_range=0.2,\n",
" height_shift_range=0.2,\n",
" horizontal_flip=True,\n",
" preprocessing_function=preprocessing_function)\n",
"inference_datagen = ImageDataGenerator()\n",
"train_datagen.fit(X_train)\n",
"train_datagen_augmented.fit(X_train)\n",
"inference_datagen.fit(X_valid)\n",
"inference_datagen.fit(X_test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exemple of augmented images"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n10RYRiUw/iIAAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7febbb1a5240>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure()\n",
"\n",
"n = 0\n",
"\n",
"graph_size = 3\n",
"\n",
"for x_batch, y_batch in train_datagen_augmented.flow(X_train, y_train, batch_size=1):\n",
" a=fig.add_subplot(graph_size, graph_size, n+1)\n",
" imgplot = plt.imshow(x_batch[0])\n",
" n = n + 1\n",
" if n > 8:\n",
" break\n",
"\n",
" \n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Model Architecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### CapsNet"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import numpy as np\n",
"import tensorflow as tf\n",
"import numpy as np\n",
"\n",
"\n",
"def conv_caps_layer(input_layer, capsules_size, nb_filters, kernel, stride=2):\n",
" \"\"\"\n",
" Capsule layer for the convolutional inputs\n",
" **input:\n",
" *input_layer: (Tensor)\n",
" *capsule_numbers: (Integer) the number of capsule in this layer.\n",
" *kernel_size: (Integer) Size of the kernel for each filter.\n",
" *stride: (Integer) 2 by default\n",
" \"\"\"\n",
" # \"In convolutional capsule layers each unit in a capsule is a convolutional unit.\n",
" # Therefore, each capsule will output a grid of vectors rather than a single vector output.\"\n",
" capsules = tf.contrib.layers.conv2d(\n",
" input_layer, nb_filters * capsules_size, kernel, stride, padding=\"VALID\")\n",
" # conv shape: [?, kernel, kernel, nb_filters]\n",
" shape = capsules.get_shape().as_list()\n",
" capsules = tf.reshape(capsules, shape=(-1, np.prod(shape[1:3]) * nb_filters, capsules_size, 1))\n",
" # capsules shape: [?, nb_capsules, capsule_size, 1]\n",
" return squash(capsules)\n",
"\n",
"def routing(u_hat, b_ij, nb_capsules, nb_capsules_p, iterations=4):\n",
" \"\"\"\n",
" Routing algorithm\n",
"\n",
" **input:\n",
" *u_hat: Dot product (weights between previous capsule and current capsule)\n",
" *b_ij: the log prior probabilities that capsule i should be coupled to capsule j\n",
" *nb_capsules_p: Number of capsule in the previous layer\n",
" *nb_capsules: Number of capsule in this layer\n",
" \"\"\"\n",
" # Start the routing algorithm\n",
" for it in range(iterations):\n",
" with tf.variable_scope('routing_' + str(it)):\n",
" # Line 4 of algo\n",
" # probabilities that capsule i should be coupled to capsule j.\n",
" # c_ij: [nb_capsules_p, nb_capsules, 1, 1]\n",
" c_ij = tf.nn.softmax(b_ij, dim=2)\n",
"\n",
" # Line 5 of algo\n",
" # c_ij: [ nb_capsules_p, nb_capsules, 1, 1]\n",
" # u_hat: [?, nb_capsules_p, nb_capsules, len_v_j, 1]\n",
" s_j = tf.multiply(c_ij, u_hat)\n",
" # s_j: [?, nb_capsules_p, nb_capsules, len_v_j, 1]\n",
" s_j = tf.reduce_sum(s_j, axis=1, keep_dims=True)\n",
" # s_j: [?, 1, nb_capsules, len_v_j, 1)\n",
"\n",
" # line 6:\n",
" # squash using Eq.1,\n",
" v_j = squash(s_j)\n",
" # v_j: [1, 1, nb_capsules, len_v_j, 1)\n",
"\n",
" # line 7:\n",
" # Frist reshape & tile v_j\n",
" # [? , 1, nb_capsules, len_v_j, 1] ->\n",
" # [?, nb_capsules_p, nb_capsules, len_v_j, 1]\n",
" v_j_tiled = tf.tile(v_j, [1, nb_capsules_p, 1, 1, 1])\n",
" # u_hat: [?, nb_capsules_p, nb_capsules, len_v_j, 1]\n",
" # v_j_tiled [1, nb_capsules_p, nb_capsules, len_v_j, 1]\n",
" u_dot_v = tf.matmul(u_hat, v_j_tiled, transpose_a=True)\n",
" # u_produce_v: [?, nb_capsules_p, nb_capsules, 1, 1]\n",
" b_ij += tf.reduce_sum(u_dot_v, axis=0, keep_dims=True)\n",
" #b_ih: [1, nb_capsules_p, nb_capsules, 1, 1]\n",
"\n",
" return tf.squeeze(v_j, axis=1)\n",
"\n",
"def fully_connected_caps_layer(input_layer, capsules_size, nb_capsules, iterations=4):\n",
" \"\"\"\n",
" Second layer receiving inputs from all capsules of the layer below\n",
" **input:\n",
" *input_layer: (Tensor)\n",
" *capsules_size: (Integer) Size of each capsule\n",
" *nb_capsules: (Integer) Number of capsule\n",
" *iterations: (Integer) Number of iteration for the routing algorithm\n",
"\n",
" i refer to the layer below.\n",
" j refer to the layer above (the current layer).\n",
" \"\"\"\n",
" shape = input_layer.get_shape().as_list()\n",
" # Get the size of each capsule in the previous layer and the current layer.\n",
" len_u_i = np.prod(shape[2])\n",
" len_v_j = capsules_size\n",
" # Get the number of capsule in the layer bellow.\n",
" nb_capsules_p = np.prod(shape[1])\n",
"\n",
" # w_ij: Used to compute u_hat by multiplying the output ui of a capsule in the layer below\n",
" # with this matrix\n",
" # [nb_capsules_p, nb_capsules, len_v_j, len_u_i]\n",
" _init = tf.random_normal_initializer(stddev=0.01, seed=0)\n",
" _shape = (nb_capsules_p, nb_capsules, len_v_j, len_u_i)\n",
" w_ij = tf.get_variable('weight', shape=_shape, dtype=tf.float32, initializer=_init)\n",
"\n",
" # Adding one dimension to the input [batch_size, nb_capsules_p, length(u_i), 1] ->\n",
" # [batch_size, nb_capsules_p, 1, length(u_i), 1]\n",
" # To allow the next dot product\n",
" input_layer = tf.reshape(input_layer, shape=(-1, nb_capsules_p, 1, len_u_i, 1))\n",
" input_layer = tf.tile(input_layer, [1, 1, nb_capsules, 1, 1])\n",
"\n",
" # Eq.2, calc u_hat\n",
" # Prediction uj|i made by capsule i\n",
" # w_ij: [ nb_capsules_p, nb_capsules, len_v_j, len_u_i, ]\n",
" # input: [batch_size, nb_capsules_p, nb_capsules, len_ui, 1]\n",
" # u_hat: [batch_size, nb_capsules_p, nb_capsules, len_v_j, 1]\n",
" # Each capsule of the previous layer capsule layer is associated to a capsule of this layer\n",
" u_hat = tf.einsum('abdc,iabcf->iabdf', w_ij, input_layer)\n",
"\n",
" # bij are the log prior probabilities that capsule i should be coupled to capsule j\n",
" # [nb_capsules_p, nb_capsules, 1, 1]\n",
" b_ij = tf.zeros(shape=[nb_capsules_p, nb_capsules, 1, 1], dtype=np.float32)\n",
"\n",
" return routing(u_hat, b_ij, nb_capsules, nb_capsules_p, iterations=iterations)\n",
"\n",
"def squash(vector):\n",
" \"\"\"\n",
" Squashing function corresponding to Eq. 1\n",
" **input: **\n",
" *vector\n",
" \"\"\"\n",
" vector += 0.00001 # Workaround for the squashing function ...\n",
" vec_squared_norm = tf.reduce_sum(tf.square(vector), -2, keep_dims=True)\n",
" scalar_factor = vec_squared_norm / (1 + vec_squared_norm) / tf.sqrt(vec_squared_norm)\n",
" vec_squashed = scalar_factor * vector # element-wise\n",
" return(vec_squashed)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Main Model"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"#!/usr/bin/python3\n",
"# -*- coding: utf-8 -*-\n",
"\n",
"import numpy as np\n",
"from model_base import ModelBase\n",
"import tensorflow as tf\n",
"\n",
"class ModelTrafficSign(ModelBase):\n",
" \"\"\"\n",
" ModelTrafficSign.\n",
" This class is used to create the conv graph using:\n",
" Dynamic Routing Between Capsules\n",
" \"\"\"\n",
"\n",
" # Numbers of label to predict\n",
" NB_LABELS = 43\n",
"\n",
" def __init__(self, model_name, output_folder):\n",
" \"\"\"\n",
" **input:\n",
" *model_name: (Integer) Name of this model\n",
" *output_folder: Output folder to saved data (tensorboard, checkpoints)\n",
" \"\"\"\n",
" ModelBase.__init__(self, model_name, output_folder=output_folder)\n",
"\n",
" def _build_inputs(self):\n",
" \"\"\"\n",
" Build tensorflow inputs\n",
" (Placeholder)\n",
" **return: **\n",
" *tf_images: Images Placeholder\n",
" *tf_labels: Labels Placeholder\n",
" \"\"\"\n",
" # Images 32*32*3\n",
" tf_images = tf.placeholder(tf.float32, [None, 32, 32, 3], name='images')\n",
" # Labels: [0, 1, 6, 20, ...]\n",
" tf_labels = tf.placeholder(tf.int64, [None], name='labels')\n",
" return tf_images, tf_labels\n",
"\n",
" def _build_main_network(self, images, conv_2_dropout):\n",
" \"\"\"\n",
" This method is used to create the two convolutions and the CapsNet on the top\n",
" **input:\n",
" *images: Image PLaceholder\n",
" *conv_2_dropout: Dropout value placeholder\n",
" **return: **\n",
" *Caps1: Output of first Capsule layer\n",
" *Caps2: Output of second Capsule layer\n",
" \"\"\"\n",
" # First BLock:\n",
" # Layer 1: Convolution.\n",
" shape = (self.h.conv_1_size, self.h.conv_1_size, 3, self.h.conv_1_nb)\n",
" conv1 = self._create_conv(self.tf_images, shape, relu=True, max_pooling=False, padding='VALID')\n",
" # Layer 2: Convolution.\n",
" #shape = (self.h.conv_2_size, self.h.conv_2_size, self.h.conv_1_nb, self.h.conv_2_nb)\n",
" #conv2 = self._create_conv(conv1, shape, relu=True, max_pooling=False, padding='VALID')\n",
" conv1 = tf.nn.dropout(conv1, keep_prob=conv_2_dropout)\n",
"\n",
" # Create the first capsules layer\n",
" caps1 = conv_caps_layer(\n",
" input_layer=conv1,\n",
" capsules_size=self.h.caps_1_vec_len,\n",
" nb_filters=self.h.caps_1_nb_filter,\n",
" kernel=self.h.caps_1_size)\n",
" # Create the second capsules layer used to predict the output\n",
" caps2 = fully_connected_caps_layer(\n",
" input_layer=caps1,\n",
" capsules_size=self.h.caps_2_vec_len,\n",
" nb_capsules=self.NB_LABELS,\n",
" iterations=self.h.routing_steps)\n",
"\n",
" return caps1, caps2\n",
"\n",
" def _build_decoder(self, caps2, one_hot_labels, batch_size):\n",
" \"\"\"\n",
" Build the decoder part from the last capsule layer\n",
" **input:\n",
" *Caps2: Output of second Capsule layer\n",
" *one_hot_labels\n",
" *batch_size\n",
" \"\"\"\n",
" labels = tf.reshape(one_hot_labels, (-1, self.NB_LABELS, 1))\n",
" # squeeze(caps2): [?, len_v_j, capsules_nb]\n",
" # labels: [?, NB_LABELS, 1] with capsules_nb == NB_LABELS\n",
" mask = tf.matmul(tf.squeeze(caps2), labels, transpose_a=True)\n",
" # Select the good capsule vector\n",
" capsule_vector = tf.reshape(mask, shape=(batch_size, self.h.caps_2_vec_len))\n",
" # capsule_vector: [?, len_v_j]\n",
"\n",
" # Reconstruct image\n",
" fc1 = tf.contrib.layers.fully_connected(capsule_vector, num_outputs=400)\n",
" fc1 = tf.reshape(fc1, shape=(batch_size, 5, 5, 16))\n",
" upsample1 = tf.image.resize_nearest_neighbor(fc1, (8, 8))\n",
" conv1 = tf.layers.conv2d(upsample1, 4, (3,3), padding='same', activation=tf.nn.relu)\n",
"\n",
" upsample2 = tf.image.resize_nearest_neighbor(conv1, (16, 16))\n",
" conv2 = tf.layers.conv2d(upsample2, 8, (3,3), padding='same', activation=tf.nn.relu)\n",
"\n",
" upsample3 = tf.image.resize_nearest_neighbor(conv2, (32, 32))\n",
" conv6 = tf.layers.conv2d(upsample3, 16, (3,3), padding='same', activation=tf.nn.relu)\n",
"\n",
" # 3 channel for RGG\n",
" logits = tf.layers.conv2d(conv6, 3, (3,3), padding='same', activation=None)\n",
" decoded = tf.nn.sigmoid(logits, name='decoded')\n",
" tf.summary.image('reconstruction_img', decoded)\n",
"\n",
" return decoded\n",
"\n",
" def init(self):\n",
" \"\"\"\n",
" Init the graph\n",
" \"\"\"\n",
" # Get graph inputs\n",
" self.tf_images, self.tf_labels = self._build_inputs()\n",
" # Dropout inputs\n",
" self.tf_conv_2_dropout = tf.placeholder(tf.float32, shape=(), name='conv_2_dropout')\n",
" # Dynamic batch size\n",
" batch_size = tf.shape(self.tf_images)[0]\n",
" # Translate labels to one hot array\n",
" one_hot_labels = tf.one_hot(self.tf_labels, depth=self.NB_LABELS)\n",
" # Create the first convolution and the CapsNet\n",
" self.tf_caps1, self.tf_caps2 = self._build_main_network(self.tf_images, self.tf_conv_2_dropout)\n",
"\n",
" # Build the images reconstruction\n",
" self.tf_decoded = self._build_decoder(self.tf_caps2, one_hot_labels, batch_size)\n",
"\n",
" # Build the loss\n",
" _loss = self._build_loss(\n",
" self.tf_caps2, one_hot_labels, self.tf_labels, self.tf_decoded, self.tf_images)\n",
" (self.tf_loss_squared_rec, self.tf_margin_loss_sum, self.tf_predicted_class,\n",
" self.tf_correct_prediction, self.tf_accuracy, self.tf_loss, self.tf_margin_loss,\n",
" self.tf_reconstruction_loss) = _loss\n",
"\n",
" # Build optimizer\n",
" optimizer = tf.train.AdamOptimizer(learning_rate=self.h.learning_rate)\n",
" self.tf_optimizer = optimizer.minimize(self.tf_loss, global_step=tf.Variable(0, trainable=False))\n",
"\n",
" # Log value into tensorboard\n",
" tf.summary.scalar('margin_loss', self.tf_margin_loss)\n",
" tf.summary.scalar('accuracy', self.tf_accuracy)\n",
" tf.summary.scalar('total_loss', self.tf_loss)\n",
" tf.summary.scalar('reconstruction_loss', self.tf_reconstruction_loss)\n",
"\n",
" self.tf_test = tf.random_uniform([2], minval=0, maxval=None, dtype=tf.float32, seed=None, name=\"tf_test\")\n",
"\n",
" self.init_session()\n",
"\n",
"\n",
" def _build_loss(self, caps2, one_hot_labels, labels, decoded, images):\n",
" \"\"\"\n",
" Build the loss of the graph\n",
" \"\"\"\n",
" # Get the length of each capsule\n",
" capsules_length = tf.sqrt(tf.reduce_sum(tf.square(caps2), axis=2, keep_dims=True))\n",
"\n",
" max_l = tf.square(tf.maximum(0., 0.9 - capsules_length))\n",
" max_l = tf.reshape(max_l, shape=(-1, self.NB_LABELS))\n",
" max_r = tf.square(tf.maximum(0., capsules_length - 0.1))\n",
" max_r = tf.reshape(max_r, shape=(-1, self.NB_LABELS))\n",
" t_c = one_hot_labels\n",
" m_loss = t_c * max_l + 0.5 * (1 - t_c) * max_r\n",
" margin_loss_sum = tf.reduce_sum(m_loss, axis=1)\n",
" margin_loss = tf.reduce_mean(margin_loss_sum)\n",
"\n",
" # Reconstruction loss\n",
" loss_squared_rec = tf.square(decoded - images)\n",
" reconstruction_loss = tf.reduce_mean(loss_squared_rec)\n",
"\n",
" # 3. Total loss\n",
" loss = margin_loss + (0.0005 * reconstruction_loss)\n",
"\n",
" # Accuracy\n",
" predicted_class = tf.argmax(capsules_length, axis=1)\n",
" predicted_class = tf.reshape(predicted_class, [tf.shape(capsules_length)[0]])\n",
" correct_prediction = tf.equal(predicted_class, labels)\n",
" accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))\n",
"\n",
" return (loss_squared_rec, margin_loss_sum, predicted_class, correct_prediction, accuracy,\n",
" loss, margin_loss, reconstruction_loss)\n",
"\n",
" def optimize(self, images, labels, tb_save=True):\n",
" \"\"\"\n",
" Train the model\n",
" **input: **\n",
" *images: Image to train the model on\n",
" *labels: True classes\n",
" *tb_save: (Boolean) Log this optimization in tensorboard\n",
" **return: **\n",
" Loss: The loss of the model on this batch\n",
" Acc: Accuracy of the model on this batch\n",
" \"\"\"\n",
" tensors = [self.tf_optimizer, self.tf_margin_loss, self.tf_accuracy, self.tf_tensorboard]\n",
" _, loss, acc, summary = self.sess.run(tensors,\n",
" feed_dict={\n",
" self.tf_images: images,\n",
" self.tf_labels: labels,\n",
" self.tf_conv_2_dropout: self.h.conv_2_dropout\n",
" })\n",
"\n",
" if tb_save:\n",
" # Write data to tensorboard\n",
" self.train_writer.add_summary(summary, self.train_writer_it)\n",
" self.train_writer_it += 1\n",
"\n",
" return loss, acc\n",
"\n",
" def evaluate(self, images, labels, tb_train_save=False, tb_test_save=False):\n",
" \"\"\"\n",
" Evaluate dataset\n",
" **input: **\n",
" *images: Image to train the model on\n",
" *labels: True classes\n",
" *tb_train_save: (Boolean) Log this optimization in tensorboard under the train part\n",
" *tb_test_save: (Boolean) Log this optimization in tensorboard under the test part\n",
" **return: **\n",
" Loss: The loss of the model on this batch\n",
" Acc: Accuracy of the model on this batch\n",
" \"\"\"\n",
" tensors = [self.tf_margin_loss, self.tf_accuracy, self.tf_tensorboard]\n",
" loss, acc, summary = self.sess.run(tensors,\n",
" feed_dict={\n",
" self.tf_images: images,\n",
" self.tf_labels: labels,\n",
" self.tf_conv_2_dropout: 1.\n",
" })\n",
"\n",
" if tb_test_save:\n",
" # Write data to tensorboard\n",
" self.test_writer.add_summary(summary, self.test_writer_it)\n",
" self.test_writer_it += 1\n",
"\n",
" if tb_train_save:\n",
" # Write data to tensorboard\n",
" self.train_writer.add_summary(summary, self.train_writer_it)\n",
" self.train_writer_it += 1\n",
"\n",
" return loss, acc\n",
"\n",
" def predict(self, images):\n",
" \"\"\"\n",
" Method used to predict a class\n",
" Return a softmax\n",
" **input: **\n",
" *images: Image to train the model on\n",
" **return:\n",
" *softmax: Softmax between all capsules\n",
" \"\"\"\n",
" tensors = [self.tf_caps2]\n",
"\n",
" caps2 = self.sess.run(tensors,\n",
" feed_dict={\n",
" self.tf_images: images,\n",
" self.tf_conv_2_dropout: 1.\n",
" })[0]\n",
"\n",
" # tf.sqrt(tf.reduce_sum(tf.square(caps2), axis=2, keep_dims=True))\n",
" caps2 = np.sqrt(np.sum(np.square(caps2), axis=2, keepdims=True))\n",
" caps2 = np.reshape(caps2, (len(images), self.NB_LABELS))\n",
" # softmax\n",
" softmax = np.exp(caps2) / np.sum(np.exp(caps2), axis=1, keepdims=True)\n",
"\n",
" return softmax\n",
"\n",
" def reconstruction(self, images, labels):\n",
" \"\"\"\n",
" Method used to get the reconstructions given a batch\n",
" Return the result as a softmax\n",
" **input: **\n",
" *images: Image to train the model on\n",
" *labels: True classes\n",
" \"\"\"\n",
" tensors = [self.tf_decoded]\n",
"\n",
" decoded = self.sess.run(tensors,\n",
" feed_dict={\n",
" self.tf_images: images,\n",
" self.tf_labels: labels,\n",
" self.tf_conv_2_dropout: 1.\n",
" })[0]\n",
"\n",
" return decoded\n",
"\n",
" def evaluate_dataset(self, images, labels, batch_size=10):\n",
" \"\"\"\n",
" Evaluate a full dataset\n",
" This method is used to fully evaluate the dataset batch per batch. Useful when\n",
" the dataset can't be fit inside to the GPU.\n",
" *input: **\n",
" *images: Image to train the model on\n",
" *labels: True classes\n",
" *return: **\n",
" *loss: Loss overall your dataset\n",
" *accuracy: Accuracy overall your dataset\n",
" *predicted_class: Predicted class\n",
" \"\"\"\n",
" tensors = [self.tf_loss_squared_rec, self.tf_margin_loss_sum, self.tf_correct_prediction,\n",
" self.tf_predicted_class]\n",
"\n",
" loss_squared_rec_list = None\n",
" margin_loss_sum_list = None\n",
" correct_prediction_list = None\n",
" predicted_class = None\n",
"\n",
" b = 0\n",
" for batch in self.get_batches([images, labels], batch_size, shuffle=False):\n",
" images_batch, labels_batch = batch\n",
" loss_squared_rec, margin_loss_sum, correct_prediction, classes = self.sess.run(tensors,\n",
" feed_dict={\n",
" self.tf_images: images_batch,\n",
" self.tf_labels: labels_batch,\n",
" self.tf_conv_2_dropout: 1.\n",
" })\n",
" if loss_squared_rec_list is not None:\n",
" predicted_class = np.concatenate((predicted_class, classes))\n",
" loss_squared_rec_list = np.concatenate((loss_squared_rec_list, loss_squared_rec))\n",
" margin_loss_sum_list = np.concatenate((margin_loss_sum_list, margin_loss_sum))\n",
" correct_prediction_list = np.concatenate((correct_prediction_list, correct_prediction))\n",
" else:\n",
" predicted_class = classes\n",
" loss_squared_rec_list = loss_squared_rec\n",
" margin_loss_sum_list = margin_loss_sum\n",
" correct_prediction_list = correct_prediction\n",
" b += batch_size\n",
"\n",
" margin_loss = np.mean(margin_loss_sum_list)\n",
" reconstruction_loss = np.mean(loss_squared_rec_list)\n",
" accuracy = np.mean(correct_prediction_list)\n",
"\n",
" loss = margin_loss\n",
"\n",
" return loss, accuracy, predicted_class\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Train, Validate and Test the Model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A validation set can be used to assess how well the model is performing. A low accuracy on the training and validation\n",
"sets imply underfitting. A high accuracy on the training set but low accuracy on the validation set implies overfitting."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"# Init model\n",
"model = ModelTrafficSign(\"TrafficSign\", output_folder=\"outputs\")\n",
"model.init()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[Train] Batch ID = 0, loss = 2.42539, acc = 0.02\n",
"[Validation] Batch ID = 0, loss = 0.800529, acc = 0.04\n",
"Evaluate full validation dataset ...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"ModelBase::Saving model ...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Current loss: 0.781535 Best loss: None\n",
"[TOTAL Validation] Batch ID = 0, loss = 0.781535, acc = 0.0185941043084\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"ModelBase::Model successfully saved here: outputs/checkpoints/c1s_9_c1n_256_c2s_6_c2n_64_c2d_0.7_c1vl_16_c1s_5_c1nf_16_c2vl_32_lr_0.0001_rs_1--TrafficSign--1510487290.423481\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Augmented Factor = 0.891\n",
"[Train] Batch ID = 10, loss = 0.754666, acc = 0.04\n",
"[Validation] Batch ID = 10, loss = 0.753758, acc = 0.04\n",
"[Train] Batch ID = 20, loss = 0.690922, acc = 0.06\n",
"[Validation] Batch ID = 20, loss = 0.702244, acc = 0.06\n",
"[Train] Batch ID = 30, loss = 0.6284, acc = 0.1\n",
"[Validation] Batch ID = 30, loss = 0.659595, acc = 0.06\n",
"[Train] Batch ID = 40, loss = 0.63592, acc = 0.1\n",
"[Validation] Batch ID = 40, loss = 0.659709, acc = 0.04\n",
"[Train] Batch ID = 50, loss = 0.616082, acc = 0.16\n",
"[Validation] Batch ID = 50, loss = 0.599504, acc = 0.06\n",
"[Train] Batch ID = 60, loss = 0.621295, acc = 0.1\n",
"[Validation] Batch ID = 60, loss = 0.604651, acc = 0.1\n",
"[Train] Batch ID = 70, loss = 0.617128, acc = 0.06\n",
"[Validation] Batch ID = 70, loss = 0.597139, acc = 0.1\n",
"[Train] Batch ID = 80, loss = 0.590053, acc = 0.14\n",
"[Validation] Batch ID = 80, loss = 0.579464, acc = 0.1\n",
"[Train] Batch ID = 90, loss = 0.596748, acc = 0.06\n",
"[Validation] Batch ID = 90, loss = 0.590638, acc = 0.16\n",
"[Train] Batch ID = 100, loss = 0.571133, acc = 0.16\n",
"[Validation] Batch ID = 100, loss = 0.593388, acc = 0.16\n",
"[Train] Batch ID = 110, loss = 0.584303, acc = 0.12\n",
"[Validation] Batch ID = 110, loss = 0.593405, acc = 0.08\n",
"[Train] Batch ID = 120, loss = 0.591267, acc = 0.14\n",
"[Validation] Batch ID = 120, loss = 0.570968, acc = 0.18\n",
"[Train] Batch ID = 130, loss = 0.576181, acc = 0.16\n",
"[Validation] Batch ID = 130, loss = 0.559474, acc = 0.18\n",
"[Train] Batch ID = 140, loss = 0.571011, acc = 0.1\n",
"[Validation] Batch ID = 140, loss = 0.537225, acc = 0.22\n",
"[Train] Batch ID = 150, loss = 0.571272, acc = 0.12\n",
"[Validation] Batch ID = 150, loss = 0.543216, acc = 0.24\n",
"[Train] Batch ID = 160, loss = 0.550595, acc = 0.18\n",
"[Validation] Batch ID = 160, loss = 0.581442, acc = 0.12\n",
"[Train] Batch ID = 170, loss = 0.58082, acc = 0.1\n",
"[Validation] Batch ID = 170, loss = 0.576819, acc = 0.16\n",
"[Train] Batch ID = 180, loss = 0.566915, acc = 0.2\n",
"[Validation] Batch ID = 180, loss = 0.57347, acc = 0.1\n",
"[Train] Batch ID = 190, loss = 0.576022, acc = 0.16\n",
"[Validation] Batch ID = 190, loss = 0.567339, acc = 0.2\n",
"[Train] Batch ID = 200, loss = 0.536268, acc = 0.22\n",
"[Validation] Batch ID = 200, loss = 0.521454, acc = 0.24\n",
"[Train] Batch ID = 210, loss = 0.59091, acc = 0.06\n",
"[Validation] Batch ID = 210, loss = 0.535439, acc = 0.26\n",
"[Train] Batch ID = 220, loss = 0.563106, acc = 0.14\n",
"[Validation] Batch ID = 220, loss = 0.496016, acc = 0.28\n",
"[Train] Batch ID = 230, loss = 0.572187, acc = 0.2\n",
"[Validation] Batch ID = 230, loss = 0.55189, acc = 0.22\n",
"[Train] Batch ID = 240, loss = 0.579677, acc = 0.16\n",
"[Validation] Batch ID = 240, loss = 0.503579, acc = 0.26\n",
"[Train] Batch ID = 250, loss = 0.54702, acc = 0.18\n",
"[Validation] Batch ID = 250, loss = 0.545198, acc = 0.18\n",
"[Train] Batch ID = 260, loss = 0.565367, acc = 0.16\n",
"[Validation] Batch ID = 260, loss = 0.544931, acc = 0.24\n",
"[Train] Batch ID = 270, loss = 0.550182, acc = 0.24\n",
"[Validation] Batch ID = 270, loss = 0.518467, acc = 0.2\n",
"[Train] Batch ID = 280, loss = 0.502248, acc = 0.28\n",
"[Validation] Batch ID = 280, loss = 0.516729, acc = 0.22\n",
"[Train] Batch ID = 290, loss = 0.592575, acc = 0.14\n",
"[Validation] Batch ID = 290, loss = 0.533068, acc = 0.26\n",
"[Train] Batch ID = 300, loss = 0.526132, acc = 0.24\n",
"[Validation] Batch ID = 300, loss = 0.50696, acc = 0.34\n",
"[Train] Batch ID = 310, loss = 0.560534, acc = 0.2\n",
"[Validation] Batch ID = 310, loss = 0.555453, acc = 0.24\n",
"[Train] Batch ID = 320, loss = 0.490622, acc = 0.34\n",
"[Validation] Batch ID = 320, loss = 0.541549, acc = 0.24\n",
"[Train] Batch ID = 330, loss = 0.544868, acc = 0.28\n",
"[Validation] Batch ID = 330, loss = 0.551774, acc = 0.26\n",
"[Train] Batch ID = 340, loss = 0.544464, acc = 0.12\n",
"[Validation] Batch ID = 340, loss = 0.49482, acc = 0.42\n",
"[Train] Batch ID = 350, loss = 0.575958, acc = 0.14\n",
"[Validation] Batch ID = 350, loss = 0.493718, acc = 0.3\n",
"[Train] Batch ID = 360, loss = 0.54912, acc = 0.22\n",
"[Validation] Batch ID = 360, loss = 0.531574, acc = 0.3\n",
"[Train] Batch ID = 370, loss = 0.540033, acc = 0.2\n",
"[Validation] Batch ID = 370, loss = 0.505985, acc = 0.4\n",
"[Train] Batch ID = 380, loss = 0.525236, acc = 0.24\n",
"[Validation] Batch ID = 380, loss = 0.516121, acc = 0.3\n",
"[Train] Batch ID = 390, loss = 0.555539, acc = 0.18\n",
"[Validation] Batch ID = 390, loss = 0.548367, acc = 0.16\n",
"[Train] Batch ID = 400, loss = 0.568358, acc = 0.12\n",
"[Validation] Batch ID = 400, loss = 0.50561, acc = 0.32\n",
"[Train] Batch ID = 410, loss = 0.52281, acc = 0.2\n",
"[Validation] Batch ID = 410, loss = 0.510524, acc = 0.3\n",
"[Train] Batch ID = 420, loss = 0.498897, acc = 0.32\n",
"[Validation] Batch ID = 420, loss = 0.489266, acc = 0.38\n",
"[Train] Batch ID = 430, loss = 0.528072, acc = 0.2\n",
"[Validation] Batch ID = 430, loss = 0.492686, acc = 0.3\n",
"[Train] Batch ID = 440, loss = 0.533394, acc = 0.24\n",
"[Validation] Batch ID = 440, loss = 0.522744, acc = 0.18\n",
"[Train] Batch ID = 450, loss = 0.519317, acc = 0.22\n",
"[Validation] Batch ID = 450, loss = 0.502148, acc = 0.28\n",
"[Train] Batch ID = 460, loss = 0.532956, acc = 0.22\n",
"[Validation] Batch ID = 460, loss = 0.496181, acc = 0.28\n",
"[Train] Batch ID = 470, loss = 0.554523, acc = 0.16\n",
"[Validation] Batch ID = 470, loss = 0.489495, acc = 0.34\n",
"[Train] Batch ID = 480, loss = 0.543094, acc = 0.16\n",
"[Validation] Batch ID = 480, loss = 0.513759, acc = 0.26\n",
"[Train] Batch ID = 490, loss = 0.552911, acc = 0.14\n",
"[Validation] Batch ID = 490, loss = 0.528018, acc = 0.22\n",
"[Train] Batch ID = 500, loss = 0.547266, acc = 0.2\n",
"[Validation] Batch ID = 500, loss = 0.491217, acc = 0.32\n",
"[Train] Batch ID = 510, loss = 0.548772, acc = 0.24\n",
"[Validation] Batch ID = 510, loss = 0.476296, acc = 0.36\n",
"[Train] Batch ID = 520, loss = 0.521309, acc = 0.18\n",
"[Validation] Batch ID = 520, loss = 0.487757, acc = 0.26\n",
"[Train] Batch ID = 530, loss = 0.494148, acc = 0.3\n",
"[Validation] Batch ID = 530, loss = 0.472203, acc = 0.38\n",
"[Train] Batch ID = 540, loss = 0.556524, acc = 0.22\n",
"[Validation] Batch ID = 540, loss = 0.511071, acc = 0.24\n",
"[Train] Batch ID = 550, loss = 0.515253, acc = 0.26\n",
"[Validation] Batch ID = 550, loss = 0.472468, acc = 0.32\n",
"[Train] Batch ID = 560, loss = 0.516666, acc = 0.24\n",
"[Validation] Batch ID = 560, loss = 0.483363, acc = 0.3\n",
"[Train] Batch ID = 570, loss = 0.524725, acc = 0.28\n",
"[Validation] Batch ID = 570, loss = 0.468372, acc = 0.42\n",
"[Train] Batch ID = 580, loss = 0.505188, acc = 0.26\n",
"[Validation] Batch ID = 580, loss = 0.427392, acc = 0.5\n",
"[Train] Batch ID = 590, loss = 0.516176, acc = 0.24\n",
"[Validation] Batch ID = 590, loss = 0.464795, acc = 0.4\n",
"[Train] Batch ID = 600, loss = 0.480228, acc = 0.36\n",
"[Validation] Batch ID = 600, loss = 0.467607, acc = 0.38\n",
"[Train] Batch ID = 610, loss = 0.519255, acc = 0.28\n",
"[Validation] Batch ID = 610, loss = 0.480409, acc = 0.3\n",
"[Train] Batch ID = 620, loss = 0.45362, acc = 0.38\n",
"[Validation] Batch ID = 620, loss = 0.479688, acc = 0.32\n",
"[Train] Batch ID = 630, loss = 0.505263, acc = 0.36\n",
"[Validation] Batch ID = 630, loss = 0.43897, acc = 0.48\n",
"[Train] Batch ID = 640, loss = 0.524474, acc = 0.2\n",
"[Validation] Batch ID = 640, loss = 0.434479, acc = 0.5\n",
"[Train] Batch ID = 650, loss = 0.532827, acc = 0.18\n",
"[Validation] Batch ID = 650, loss = 0.470422, acc = 0.4\n",
"[Train] Batch ID = 660, loss = 0.540052, acc = 0.2\n",
"[Validation] Batch ID = 660, loss = 0.468874, acc = 0.38\n",
"[Train] Batch ID = 670, loss = 0.507133, acc = 0.34\n",
"[Validation] Batch ID = 670, loss = 0.471876, acc = 0.38\n",
"[Train] Batch ID = 680, loss = 0.507654, acc = 0.26\n",
"[Validation] Batch ID = 680, loss = 0.472959, acc = 0.36\n",
"[Train] Batch ID = 690, loss = 0.510228, acc = 0.24\n",
"[Validation] Batch ID = 690, loss = 0.454647, acc = 0.46\n",
"[Train] Batch ID = 700, loss = 0.539066, acc = 0.2\n",
"[Validation] Batch ID = 700, loss = 0.475782, acc = 0.42\n",
"[Train] Batch ID = 710, loss = 0.478445, acc = 0.36\n",
"[Validation] Batch ID = 710, loss = 0.548267, acc = 0.18\n",
"[Train] Batch ID = 720, loss = 0.531311, acc = 0.22\n",
"[Validation] Batch ID = 720, loss = 0.469229, acc = 0.32\n",
"[Train] Batch ID = 730, loss = 0.538671, acc = 0.16\n",
"[Validation] Batch ID = 730, loss = 0.45337, acc = 0.36\n",
"[Train] Batch ID = 740, loss = 0.486048, acc = 0.3\n",
"[Validation] Batch ID = 740, loss = 0.447456, acc = 0.34\n",
"[Train] Batch ID = 750, loss = 0.47318, acc = 0.32\n",
"[Validation] Batch ID = 750, loss = 0.45879, acc = 0.32\n",
"[Train] Batch ID = 760, loss = 0.492232, acc = 0.34\n",
"[Validation] Batch ID = 760, loss = 0.427461, acc = 0.36\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[Train] Batch ID = 770, loss = 0.480728, acc = 0.32\n",
"[Validation] Batch ID = 770, loss = 0.491949, acc = 0.34\n",
"[Train] Batch ID = 780, loss = 0.538773, acc = 0.22\n",
"[Validation] Batch ID = 780, loss = 0.467119, acc = 0.36\n",
"[Train] Batch ID = 790, loss = 0.494922, acc = 0.38\n",
"[Validation] Batch ID = 790, loss = 0.453295, acc = 0.34\n",
"[Train] Batch ID = 800, loss = 0.403864, acc = 0.54\n",
"[Validation] Batch ID = 800, loss = 0.457517, acc = 0.4\n",
"[Train] Batch ID = 810, loss = 0.481897, acc = 0.4\n",
"[Validation] Batch ID = 810, loss = 0.464976, acc = 0.34\n",
"[Train] Batch ID = 820, loss = 0.479418, acc = 0.34\n",
"[Validation] Batch ID = 820, loss = 0.388256, acc = 0.52\n",
"[Train] Batch ID = 830, loss = 0.523011, acc = 0.22\n",
"[Validation] Batch ID = 830, loss = 0.424948, acc = 0.48\n",
"[Train] Batch ID = 840, loss = 0.50887, acc = 0.28\n",
"[Validation] Batch ID = 840, loss = 0.440439, acc = 0.4\n",
"[Train] Batch ID = 850, loss = 0.410404, acc = 0.5\n",
"[Validation] Batch ID = 850, loss = 0.496405, acc = 0.36\n",
"[Train] Batch ID = 860, loss = 0.516683, acc = 0.3\n",
"[Validation] Batch ID = 860, loss = 0.392151, acc = 0.44\n",
"[Train] Batch ID = 870, loss = 0.497217, acc = 0.28\n",
"[Validation] Batch ID = 870, loss = 0.448474, acc = 0.28\n",
"[Train] Batch ID = 880, loss = 0.500635, acc = 0.3\n",
"[Validation] Batch ID = 880, loss = 0.408743, acc = 0.44\n",
"[Train] Batch ID = 890, loss = 0.500936, acc = 0.26\n",
"[Validation] Batch ID = 890, loss = 0.442819, acc = 0.32\n",
"[Train] Batch ID = 900, loss = 0.468844, acc = 0.38\n",
"[Validation] Batch ID = 900, loss = 0.427008, acc = 0.44\n",
"[Train] Batch ID = 910, loss = 0.46857, acc = 0.42\n",
"[Validation] Batch ID = 910, loss = 0.417586, acc = 0.44\n",
"[Train] Batch ID = 920, loss = 0.472717, acc = 0.34\n",
"[Validation] Batch ID = 920, loss = 0.467422, acc = 0.36\n",
"[Train] Batch ID = 930, loss = 0.469254, acc = 0.36\n",
"[Validation] Batch ID = 930, loss = 0.376776, acc = 0.54\n",
"[Train] Batch ID = 940, loss = 0.434811, acc = 0.44\n",
"[Validation] Batch ID = 940, loss = 0.467765, acc = 0.38\n",
"[Train] Batch ID = 950, loss = 0.483722, acc = 0.3\n",
"[Validation] Batch ID = 950, loss = 0.417313, acc = 0.42\n",
"[Train] Batch ID = 960, loss = 0.375907, acc = 0.54\n",
"[Validation] Batch ID = 960, loss = 0.452141, acc = 0.4\n",
"[Train] Batch ID = 970, loss = 0.47038, acc = 0.36\n",
"[Validation] Batch ID = 970, loss = 0.407389, acc = 0.4\n",
"[Train] Batch ID = 980, loss = 0.442751, acc = 0.34\n",
"[Validation] Batch ID = 980, loss = 0.406002, acc = 0.48\n",
"[Train] Batch ID = 990, loss = 0.506468, acc = 0.26\n",
"[Validation] Batch ID = 990, loss = 0.434915, acc = 0.42\n",
"[Train] Batch ID = 1000, loss = 0.497463, acc = 0.26\n",
"[Validation] Batch ID = 1000, loss = 0.4204, acc = 0.4\n",
"Evaluate full validation dataset ...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"ModelBase::Saving model ...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Current loss: 0.420879 Best loss: 0.781535\n",
"[TOTAL Validation] Batch ID = 1000, loss = 0.420879, acc = 0.470975056689\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"ModelBase::Model successfully saved here: outputs/checkpoints/c1s_9_c1n_256_c2s_6_c2n_64_c2d_0.7_c1vl_16_c1s_5_c1nf_16_c2vl_32_lr_0.0001_rs_1--TrafficSign--1510487290.423481\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Augmented Factor = 0.8019000000000001\n",
"[Train] Batch ID = 1010, loss = 0.496853, acc = 0.24\n",
"[Validation] Batch ID = 1010, loss = 0.409362, acc = 0.62\n",
"[Train] Batch ID = 1020, loss = 0.471861, acc = 0.34\n",
"[Validation] Batch ID = 1020, loss = 0.427412, acc = 0.44\n",
"[Train] Batch ID = 1030, loss = 0.514602, acc = 0.22\n",
"[Validation] Batch ID = 1030, loss = 0.416222, acc = 0.5\n",
"[Train] Batch ID = 1040, loss = 0.460027, acc = 0.42\n",
"[Validation] Batch ID = 1040, loss = 0.392695, acc = 0.52\n",
"[Train] Batch ID = 1050, loss = 0.468029, acc = 0.34\n",
"[Validation] Batch ID = 1050, loss = 0.369591, acc = 0.52\n",
"[Train] Batch ID = 1060, loss = 0.492225, acc = 0.26\n",
"[Validation] Batch ID = 1060, loss = 0.420142, acc = 0.44\n",
"[Train] Batch ID = 1070, loss = 0.364011, acc = 0.54\n",
"[Validation] Batch ID = 1070, loss = 0.445401, acc = 0.38\n",
"[Train] Batch ID = 1080, loss = 0.504283, acc = 0.3\n",
"[Validation] Batch ID = 1080, loss = 0.456438, acc = 0.4\n",
"[Train] Batch ID = 1090, loss = 0.465189, acc = 0.34\n",
"[Validation] Batch ID = 1090, loss = 0.428296, acc = 0.46\n",
"[Train] Batch ID = 1100, loss = 0.478776, acc = 0.32\n",
"[Validation] Batch ID = 1100, loss = 0.395044, acc = 0.4\n",
"[Train] Batch ID = 1110, loss = 0.451158, acc = 0.46\n",
"[Validation] Batch ID = 1110, loss = 0.432168, acc = 0.42\n",
"[Train] Batch ID = 1120, loss = 0.458794, acc = 0.48\n",
"[Validation] Batch ID = 1120, loss = 0.359051, acc = 0.6\n",
"[Train] Batch ID = 1130, loss = 0.50207, acc = 0.28\n",
"[Validation] Batch ID = 1130, loss = 0.398094, acc = 0.46\n",
"[Train] Batch ID = 1140, loss = 0.44812, acc = 0.42\n",
"[Validation] Batch ID = 1140, loss = 0.405418, acc = 0.4\n",
"[Train] Batch ID = 1150, loss = 0.347661, acc = 0.58\n",
"[Validation] Batch ID = 1150, loss = 0.405562, acc = 0.44\n",
"[Train] Batch ID = 1160, loss = 0.462926, acc = 0.3\n",
"[Validation] Batch ID = 1160, loss = 0.397567, acc = 0.46\n",
"[Train] Batch ID = 1170, loss = 0.491247, acc = 0.32\n",
"[Validation] Batch ID = 1170, loss = 0.355188, acc = 0.56\n",
"[Train] Batch ID = 1180, loss = 0.459735, acc = 0.4\n",
"[Validation] Batch ID = 1180, loss = 0.37437, acc = 0.54\n",
"[Train] Batch ID = 1190, loss = 0.446793, acc = 0.38\n",
"[Validation] Batch ID = 1190, loss = 0.341955, acc = 0.52\n",
"[Train] Batch ID = 1200, loss = 0.468472, acc = 0.38\n",
"[Validation] Batch ID = 1200, loss = 0.340791, acc = 0.62\n",
"[Train] Batch ID = 1210, loss = 0.484371, acc = 0.34\n",
"[Validation] Batch ID = 1210, loss = 0.360404, acc = 0.54\n",
"[Train] Batch ID = 1220, loss = 0.310755, acc = 0.68\n",
"[Validation] Batch ID = 1220, loss = 0.413266, acc = 0.48\n",
"[Train] Batch ID = 1230, loss = 0.473296, acc = 0.38\n",
"[Validation] Batch ID = 1230, loss = 0.360279, acc = 0.54\n",
"[Train] Batch ID = 1240, loss = 0.34034, acc = 0.62\n",
"[Validation] Batch ID = 1240, loss = 0.35162, acc = 0.6\n",
"[Train] Batch ID = 1250, loss = 0.278886, acc = 0.7\n",
"[Validation] Batch ID = 1250, loss = 0.396671, acc = 0.48\n",
"[Train] Batch ID = 1260, loss = 0.449707, acc = 0.38\n",
"[Validation] Batch ID = 1260, loss = 0.381212, acc = 0.54\n",
"[Train] Batch ID = 1270, loss = 0.376544, acc = 0.48\n",
"[Validation] Batch ID = 1270, loss = 0.390168, acc = 0.38\n",
"[Train] Batch ID = 1280, loss = 0.451085, acc = 0.44\n",
"[Validation] Batch ID = 1280, loss = 0.359862, acc = 0.64\n",
"[Train] Batch ID = 1290, loss = 0.456261, acc = 0.28\n",
"[Validation] Batch ID = 1290, loss = 0.355488, acc = 0.6\n",
"[Train] Batch ID = 1300, loss = 0.436061, acc = 0.42\n",
"[Validation] Batch ID = 1300, loss = 0.355017, acc = 0.56\n",
"[Train] Batch ID = 1310, loss = 0.433736, acc = 0.44\n",
"[Validation] Batch ID = 1310, loss = 0.384685, acc = 0.5\n",
"[Train] Batch ID = 1320, loss = 0.456236, acc = 0.44\n",
"[Validation] Batch ID = 1320, loss = 0.326546, acc = 0.58\n",
"[Train] Batch ID = 1330, loss = 0.452049, acc = 0.34\n",
"[Validation] Batch ID = 1330, loss = 0.346212, acc = 0.64\n",
"[Train] Batch ID = 1340, loss = 0.490594, acc = 0.32\n",
"[Validation] Batch ID = 1340, loss = 0.367138, acc = 0.54\n",
"[Train] Batch ID = 1350, loss = 0.427571, acc = 0.42\n",
"[Validation] Batch ID = 1350, loss = 0.405136, acc = 0.5\n",
"[Train] Batch ID = 1360, loss = 0.457444, acc = 0.4\n",
"[Validation] Batch ID = 1360, loss = 0.34277, acc = 0.68\n",
"[Train] Batch ID = 1370, loss = 0.427655, acc = 0.46\n",
"[Validation] Batch ID = 1370, loss = 0.401085, acc = 0.44\n",
"[Train] Batch ID = 1380, loss = 0.331077, acc = 0.62\n",
"[Validation] Batch ID = 1380, loss = 0.34276, acc = 0.58\n",
"[Train] Batch ID = 1390, loss = 0.448891, acc = 0.38\n",
"[Validation] Batch ID = 1390, loss = 0.352252, acc = 0.62\n",
"[Train] Batch ID = 1400, loss = 0.323489, acc = 0.58\n",
"[Validation] Batch ID = 1400, loss = 0.346049, acc = 0.58\n",
"[Train] Batch ID = 1410, loss = 0.460835, acc = 0.32\n",
"[Validation] Batch ID = 1410, loss = 0.320473, acc = 0.64\n",
"[Train] Batch ID = 1420, loss = 0.441399, acc = 0.46\n",
"[Validation] Batch ID = 1420, loss = 0.356037, acc = 0.6\n",
"[Train] Batch ID = 1430, loss = 0.42792, acc = 0.4\n",
"[Validation] Batch ID = 1430, loss = 0.372609, acc = 0.5\n",
"[Train] Batch ID = 1440, loss = 0.421128, acc = 0.46\n",
"[Validation] Batch ID = 1440, loss = 0.338345, acc = 0.48\n",
"[Train] Batch ID = 1450, loss = 0.413183, acc = 0.44\n",
"[Validation] Batch ID = 1450, loss = 0.27971, acc = 0.72\n",
"[Train] Batch ID = 1460, loss = 0.25103, acc = 0.8\n",
"[Validation] Batch ID = 14
gitextract_oohy2z2g/ ├── .floydignore ├── .gitignore ├── LICENSE ├── README.md ├── Traffic_Sign_Classifier.ipynb ├── _config.yml ├── caps_net.py ├── data_handler.py ├── floyd_requirements.txt ├── floyd_run.txt ├── logger.py ├── model.py ├── model_base.py ├── settings/ │ └── hyperparameters.json ├── signnames.csv ├── test.py ├── test_web_images.py ├── train.py └── utils.py
SYMBOL INDEX (47 symbols across 9 files)
FILE: caps_net.py
function conv_caps_layer (line 6) | def conv_caps_layer(input_layer, capsules_size, nb_filters, kernel, stri...
function routing (line 25) | def routing(u_hat, b_ij, nb_capsules, nb_capsules_p, iterations=4):
function fully_connected_caps_layer (line 70) | def fully_connected_caps_layer(input_layer, capsules_size, nb_capsules, ...
function squash (line 116) | def squash(vector):
FILE: data_handler.py
function get_data (line 11) | def get_data(folder):
FILE: logger.py
class Logger (line 19) | class Logger(object):
method __init__ (line 21) | def __init__(self, label):
method debug (line 26) | def debug(self, string):
method info (line 29) | def info(self, string):
method warning (line 32) | def warning(self, string):
method error (line 35) | def error(self, string):
method critical (line 38) | def critical(self, string):
FILE: model.py
class ModelTrafficSign (line 9) | class ModelTrafficSign(ModelBase):
method __init__ (line 19) | def __init__(self, model_name, output_folder):
method _build_inputs (line 27) | def _build_inputs(self):
method _build_main_network (line 41) | def _build_main_network(self, images, conv_2_dropout):
method _build_decoder (line 75) | def _build_decoder(self, caps2, one_hot_labels, batch_size):
method init (line 110) | def init(self):
method _build_loss (line 150) | def _build_loss(self, caps2, one_hot_labels, labels, decoded, images):
method optimize (line 182) | def optimize(self, images, labels, tb_save=True):
method evaluate (line 208) | def evaluate(self, images, labels, tb_train_save=False, tb_test_save=F...
method predict (line 240) | def predict(self, images):
method reconstruction (line 265) | def reconstruction(self, images, labels):
method evaluate_dataset (line 284) | def evaluate_dataset(self, images, labels, batch_size=10):
FILE: model_base.py
class Hyperparameters (line 16) | class Hyperparameters(object):
method __init__ (line 20) | def __init__(self):
method set_hyp (line 25) | def set_hyp(self, hyp):
class ModelBase (line 35) | class ModelBase(object):
method __init__ (line 44) | def __init__(self, model_name, hyperparameters_name=None, hyperparamet...
method _create_conv (line 86) | def _create_conv(self, prev, shape, padding='VALID', strides=[1, 1, 1,...
method _fc (line 103) | def _fc(self, prev, input_size, output_size, relu=False, sigmoid=False...
method init_session (line 128) | def init_session(self):
method get_equal_batches (line 164) | def get_equal_batches(self, data, labels, batch_size):
method get_batches (line 208) | def get_batches(self, data_list, batch_size, shuffle=True):
method save (line 229) | def save(self, name=None):
method _set_hyperparameters_name (line 246) | def _set_hyperparameters_name(self):
method _set_names (line 260) | def _set_names(self):
method dump_batch (line 272) | def dump_batch(self, folder, data):
method load (line 285) | def load(self, ckpt):
FILE: test.py
function plot_confusion_matrix (line 30) | def plot_confusion_matrix(cm, classes, normalize=True, title='Confusion ...
function test (line 62) | def test(dataset, ckpt):
FILE: test_web_images.py
function test_web_images (line 28) | def test_web_images(dataset, ckpt):
FILE: train.py
function train (line 35) | def train(dataset, ckpt=None, output=None):
FILE: utils.py
class Utils (line 9) | class Utils(object):
method __init__ (line 14) | def __init__(self, arg):
method progress (line 18) | def progress(count, total, suffix=''):
method read_json_file (line 35) | def read_json_file(path):
Condensed preview — 19 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (990K chars).
[
{
"path": ".floydignore",
"chars": 158,
"preview": "\n# Directories and files to ignore when uploading code to floyd\n\nimages/*\ndataset/*\noutputs/*\n.git\n.eggs\neggs\nlib\nlib64\n"
},
{
"path": ".gitignore",
"chars": 1178,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\noutputs/*\ndataset/*\n\n# C extensions\n*.so\n\n# D"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 2369,
"preview": "# Capsnet - Traffic sign classifier - Tensorflow\n\nA Tensorflow implementation of CapsNet(Capsules Net) apply on the Germ"
},
{
"path": "Traffic_Sign_Classifier.ipynb",
"chars": 883317,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"---\\n\",\n \"## Step 0: Load The Da"
},
{
"path": "_config.yml",
"chars": 26,
"preview": "theme: jekyll-theme-cayman"
},
{
"path": "caps_net.py",
"chars": 5779,
"preview": "import numpy as np\nimport tensorflow as tf\nimport numpy as np\n\n\ndef conv_caps_layer(input_layer, capsules_size, nb_filte"
},
{
"path": "data_handler.py",
"chars": 955,
"preview": "#!/usr/bin/python3\n# -*- coding: utf-8 -*-\n\nimport os\nimport pickle\n\nTRAIN_FILE = \"train.p\"\nVALID_FILE = \"valid.p\"\nTEST_"
},
{
"path": "floyd_requirements.txt",
"chars": 7,
"preview": "docopt\n"
},
{
"path": "floyd_run.txt",
"chars": 103,
"preview": "floyd run --gpu --data thibo73800/datasets/trafic_sign/1:/datasets 'python train.py /datasets /output'\n"
},
{
"path": "logger.py",
"chars": 1137,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport logging\nfrom logging.handlers import RotatingFileHandler\n\nlogger ="
},
{
"path": "model.py",
"chars": 13451,
"preview": "#!/usr/bin/python3\n# -*- coding: utf-8 -*-\n\nimport numpy as np\nfrom model_base import ModelBase\nfrom caps_net import con"
},
{
"path": "model_base.py",
"chars": 12573,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport tensorflow as tf\nfrom collections import Counter\nfrom utils import"
},
{
"path": "settings/hyperparameters.json",
"chars": 272,
"preview": "{\n \"conv_1_size\": 9,\n \"conv_1_nb\": 256,\n \"conv_2_size\": 6,\n \"conv_2_nb\": 64,\n \"conv_2_dropout\": 0.7,\n "
},
{
"path": "signnames.csv",
"chars": 999,
"preview": "ClassId,SignName\n0,Speed limit (20km/h)\n1,Speed limit (30km/h)\n2,Speed limit (50km/h)\n3,Speed limit (60km/h)\n4,Speed lim"
},
{
"path": "test.py",
"chars": 2752,
"preview": "#!/usr/bin/python3\n# -*- coding: utf-8 -*-\n\n\"\"\"\nTest the model\n\nUsage:\n test.py <ckpt> <dataset>\n\nOptions:\n -h --help "
},
{
"path": "test_web_images.py",
"chars": 1957,
"preview": "#!/usr/bin/python3\n# -*- coding: utf-8 -*-\n\n\"\"\"\nTest the model\n\nUsage:\n test.py <ckpt> <dataset>\n\nOptions:\n -h --help "
},
{
"path": "train.py",
"chars": 4141,
"preview": "#!/usr/bin/python3\n# -*- coding: utf-8 -*-\n\n\"\"\"\nTrain the model.\n\nUsage:\n train.py <dataset> [<output>] [--ckpt=<ckpt>]"
},
{
"path": "utils.py",
"chars": 1146,
"preview": "# coding: utf-8\n\nimport numpy as np\nimport json\nimport sys\nimport os\n\n\nclass Utils(object):\n \"\"\"\n Util class t"
}
]
About this extraction
This page contains the full source code of the thibo73800/capsnet-traffic-sign-classifier GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 19 files (921.6 KB), approximately 438.1k tokens, and a symbol index with 47 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.