Repository: calvinschmdt/EasyTensorflow
Branch: master
Commit: 41ac269218f0
Files: 21
Total size: 90.5 KB
Directory structure:
gitextract_0gqp2iax/
├── LICENSE
├── MANIFEST.in
├── README.rst
├── docs/
│ ├── Makefile
│ ├── make.bat
│ └── source/
│ ├── README
│ ├── _static/
│ │ └── .gitkeep
│ ├── conf.py
│ └── index.rst
├── easy_tensorflow/
│ ├── __init__.py
│ ├── evolve_functions.py
│ ├── main.py
│ ├── metadata.py
│ ├── tf_dictionaries.py
│ └── tf_functions.py
├── pavement.py
├── requirements-dev.txt
├── requirements.txt
├── setup.py
├── tests/
│ └── test_main.py
└── tox.ini
================================================
FILE CONTENTS
================================================
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015 Calvin Schmidt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: MANIFEST.in
================================================
# Informational files
include README.rst
include LICENSE
# Include docs and tests. It's unclear whether convention dictates
# including built docs. However, Sphinx doesn't include built docs, so
# we are following their lead.
graft docs
prune docs/build
graft tests
# Exclude any compile Python files (most likely grafted by tests/ directory).
global-exclude *.pyc
# Setup-related things
include pavement.py
include requirements-dev.txt
include requirements.txt
include setup.py
include tox.ini
================================================
FILE: README.rst
================================================
=========================
Easy Tensorflow
=========================
This package provides users with methods for the automated building, training, and testing of complex neural networks using Google's Tensorflow package. The project includes objects that perform both regression and classification tasks.
In addition, there is a function included that uses the DEAP genetic algorithm package to evolve the optimal network architecture. The evolution function is almost entirely based off of the sample DEAP evolution.
This project is meant to simplify the tensorflow experience, and therefore it reduces the customizibility of the networks. Patches that expand functionality are welcome and encouraged, as long they do not reduce the simplicity of usage. I will try to keep up with maintenance as best as I can, but please be patient; I am new to this.
Project Setup
=============
Dependancies
------------
Full support for Python 2.7. Python 3.3 not tested.
Requires tensorflow (tested on version 0.6.0). Installation instructions `on the Tensorflow website <https://www.tensorflow.org/versions/master/get_started/os_setup.html>`_ .
Requires DEAP (tested on version 1.0) for evolving. Installation instructions `here <http://deap.readthedocs.org/en/1.0.x/installation.html>`_.
Installation
------------
1. Either download and extract the zipped file, or clone directly from github using::
git clone https://github.com/calvinschmdt/EasyTensorflow.git easy_tensorflow
This should create a new directory containing the required files.
2. Install the dependancies manually or by running this command while in the easy_tensorflow directory::
sudo pip install -r requirements.txt
3. Install the project by running this command while in the easy_tensorflow directory::
sudo python setup.py install
Usage
=====
Prediction Objects
------------------
This package uses objects to hold the neural networks. There are separate objects for performing regression and classification (the two objects are Regresser and Classifier), but the two objects have the same basic functions.
Instantiation
-------------
Instantiate the object by assigning it to a variable. The only required argument for instantiation is a list that describes the neural network::
net_type = ['none', 20, 'sigmoid', 30, 'bias_add', 30, 'sigmoid']
reg = etf.tf_functions.Regresser(net_type)
The net_type list needs to be in a specific format: alternating strings and integers starting and ending with a string. The strings describe the transformation that is made between each layer of the neural network, while the integers denote the number of size of the layer after the transformation is made. For example, the above network would look like this:
+---------------------------------------------------------------------------+
| Input with n samples and f features |
+---------------------------------------------------------------------------+
| *Matrix multiplication by adjustable weights* |
+---------------------------------------------------------------------------+
| Layer 1 with n samples and 20 features |
+---------------------------------------------------------------------------+
| *Sigmoid transformation on a matrix multiplication by adjustable weights* |
+---------------------------------------------------------------------------+
| Layer 2 with n samples and 30 features |
+---------------------------------------------------------------------------+
| *Addition to each feature of an adjustable weight* |
+---------------------------------------------------------------------------+
| Layer 3 with n samples and 30 features |
+---------------------------------------------------------------------------+
| *Sigmoid transformation on a matrix multiplication by adjustable weights* |
+---------------------------------------------------------------------------+
| Output with n samples and o features |
+---------------------------------------------------------------------------+
The number of input and output features do not have to be specified upon instantiation, but are learned during training.
The transformations available are:
- 'relu': Relu transformation on a matrix multiplication by adjustable weights. Relu applies a ramp function.
- 'softplus': Softplus transformation on a matrix multiplication by adjustable weights. Softplus applies a smoothed ramp function.
- 'dropout': Randomly pushes features to zero. Prevents overfitting. Does not change the number of features.
- 'bias_add': Adds an adjustable weight to each feature. Does not change the number of features.
- 'sigmoid': Sigmoid transformation on a matrix multiplication by adjustable weights. Sigmoid forces values to approach 0 or 1.
- 'tanh': Hyperbolic tangent transformation on a matrix multiplication by adjustable weights. Tanh forces values very positive or very negative.
- 'none': Matrix multiplication with adjustable weights.
- 'normalize': Normalizes features of a sample using an L2 norm. Does not change the number of features.
- 'sum': Sum across all features. Reduces to 1 feature, so most useful as a final transformation in a regression.
- 'prod': Multiplies all features. Reduces to 1 feature, so most useful as a final transformation in a regression.
- 'min': Takes minimum value of all features. Reduces to 1 feature, so most useful as a final transformation in a regression.
- 'max': Takes maximum value of all features. Reduces to 1 feature, so most useful as a final transformation in a regression.
- 'mean': Takes mean of all features. Reduces to 1 feature, so most useful as a final transformation in a regression.
- 'softmax': Normalizes the features so that the sum equals 1 on a matrix multiplication by adjustable weights. Most useful as a final transformation in a classification to give class probabilities.
The object has several optional arguments:
loss_type: String that defines the error measurement term. This is used during training to determine the weights that give the most accurate output. The loss types available are:
- 'l2_loss' - Uses tensorflow's nn.l2_loss function on the difference between the predicted and actual. Computes half the L2 norm without the sqrt. Use for regression, and the default loss_type for the regression object.
- 'cross_entropy' - Calculates the cross-entropy between two probability distributions as defined in Tensorflow's MNIST tutorial (-tf.reduce_sum(y * tf.log(py_x))). Use for classification, and the default loss_type for the classification object.
optimizer: String that defines the optimization algorithm for training. If a string is passed, the optimizers will be used with default learning rates. If you wish to use a custom training rate, instead of a string, pass in a tuple with the tensorflow optimizer as the first index, and a tuple with the arguments to pass in as the second index. The optimizers available are:
- 'GradientDescent': Implements the gradient descent algorithm with a default learning rate of 0.001.
- 'Adagrad': Implements the Adagrad algorithm with a default learning rate of 0.001.
- 'Momentum': Implements the Momentum algorithm with a default learning rate of 0.001 and momentum of 0.1.
- 'Adam': Implements the Adam algorithm.
- 'FTRL': Implements the FTRL algorithm with a learning rate of 0.001.
- 'RMSProp': Implements the RMSProp algorithm with a learning rate of 0.001 and a decay of 0.9.
Training
--------
Objects are trained by calling object.train() with certain arguments::
trX = training_data
try = training_output
training_steps = 50
reg.train(trX, try, training_steps)
Both objects are trained by passing in a set of data with known outputs. The training input data should be passed in as a numpy array, with each sample as a row and features as the columns. The training output data can take multiple forms:
- For regression tasks, it can be an iterable list with one output value for each sample, or it can be a numpy array of shape (n, 1).
- For classification tasks, it can be a numpy array of shape (n, m), where m is the number of classes. In this array, there is a 1 in each row in the column of the class that that sample belongs to, and a 0 in all other rows. Otherwise, an iterable list can be passed in with the class name for each sample. This is required is the class names, and not a probability matrix, are to be returned during testing.
In addition to the training data and training output, the number of times to iterate over training must be passed in as the third argument.
There are several optional arguments for training that control how long training the network takes:
- full_train: Denotes whether to use the entire training set each iteration. Set to True by default.
- train_size: If full train is set to False, denotes how many samples to use from the training set each iteration of training. Pulls randomly from the training set with possible repeats.
Predicting
----------
After the object is trained, the network can be used to predict the output of test data that is given to it by calling object.predict() with certain arguments::
teX = test_data
p = reg.predict(teX)
The test data should have the same number of features as the training data, though the number of samples may be different.
The output for a regression object will be a numpy array of shape (n, ) with the predicted value for each sample.
The output for a classification object will be a list with a predicted class for each sample. If a probability matrix is desired, the pass the argument return_encoded = False when predicting, and a numpy array of shape (n, m) will be returned.
Closing
-------
Calling object.close() will close the network, freeing up resources. It cannot be used again, and a new object must be started for training and predicting to occur.
Evolving
========
For those who do not know the neural network architecture for your problem, we can use a genetic selection algorithm to evolve the optimal architecture.
To do this, use the command evolve() with several required arguments:
- predict_type: String denoting the type of neural network to evolve. Two options: 'regression' and 'classification'.
- fitness_measure: String denoting the type of measurement to use for evaluating the performance of the network type. Options:
- 'rmse': Root mean squared error between the predicted values and known values. Use for regression.
- 'r_squared': Coefficient of determination for determining how well the data fits the model. Use for regression.
- 'accuracy': Fraction of samples that were classified correctly. Use for classification, and can be used for multi-class classification.
- 'sensitivity': Fraction of positive samples correctly identified as positive. Use for classification with two classes, and the second class is the positive class.
- 'specificity': Fraction of negative samples correctly identified as negative. Use for classification with two classes, and the first class is the negative class.
- trX: Numpy array with input data to use for training. Will pull randomly from this array to create test and training sets.
- trY: Numpy array with output data to use for training.
After the evolution finishes, it will return a net_type and optimizer that can be fed into an regression or classification object, along with the measurement that net_type produced. If "Error during training" is printed, it only means that an error was encountered at some point during the evolution.::
net_type, opt, m = etf.evolve_functions.evolve('classification', 'accuracy', trX, trY)
There are many optional arguments that allow for customization of the evolution:
- max_layers: Integer denoting the maximum number of layers that exist between the input and output layer. Set at 5 by default.
- num_gens: Number of generations to simulate. Set at 10 by default.
- gen_size: Number of individual members per generation. Set at 40 by default.
- teX: If a specific test set is desired, enter the input data here as a numpy array.
- teY: Test output data as a numpy array.
- layer_types: List of strings denoting the layer types possible to be used. Can have repeated types for an increased probability of incorporation. Set to ['relu', 'softplus', 'dropout', 'bias_add', 'sigmoid', 'tanh', 'none', 'normalize'] by default.
- layer_sizes: List of integers denoting the layer sizes possible to be used. Layer sizes of 0 drop out a layer. List must be of the same length as layer_types. Set to [0, 0, 10, 50, 100, 200, 500, 1000] by default.
- end_types: List of strings denoting the options for the type of transformation that gives the output. Forced to be softmax by default during classification. List must be of same length as layer_types. Set to ['sum', 'prod', 'min', 'max', 'mean', 'none', 'sigmoid', 'tanh'] by default.
- train_types: List of strings denoting the optimizer types possible to be used. List must be of same length as layer_types. Set to ['GradientDescent', 'GradientDescent', 'GradientDescent', 'Adagrad', 'Momentum', 'Adam', 'Ftrl', 'RMSProp'] by default.
- cross_prob: Float value denoting the probability of crossing the genetics of different individuals. Set at 0.2 by default.
- mut_prob: Float value denoting the probability of changing the genetics of a single individual. Set at 0.2 by default.
- tourn_size: Integer denoting the number of individuals to carry from each generation. Set at 5 by default.
- train_iters: Integer denoting the number of training iterations to use for each neural network. Set at 5 by default.
- squash_errors: Boolean value denoting whether to give a fail value if the network results in an error. Set to True by default. Recommended to leave true, as it is difficult to complete a long evolution without running into some type of error.
Licenses
========
The code which makes up this Python project template is licensed under the MIT/X11 license. Feel free to use it in your free software/open-source or proprietary projects.
Issues
======
Please report any bugs or requests that you have using the GitHub issue tracker!
Development
===========
If you wish to contribute, first make your changes. Then run the following from the project root directory::
source internal/test.sh
This will copy the template directory to a temporary directory, run the generation, then run tox. Any arguments passed will go directly to the tox command line, e.g.::
source internal/test.sh -e py27
This command line would just test Python 2.7.
Acknowledgements
================
Both Tensorflow and DEAP were creating by other (very smart) people, this package just combines the two.
This package was set up using Sean Fisk's Python Project Template package.
Authors
=======
* Calvin Schmidt
================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS = -W
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/EasyTensorflow.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/EasyTensorflow.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $HOME/.local/share/devhelp/EasyTensorflow"
@echo "# ln -s $(BUILDDIR)/devhelp $HOME/.local/share/devhelp/EasyTensorflow"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
================================================
FILE: docs/make.bat
================================================
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=build
set SPHINXOPTS=-W
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
set I18NSPHINXOPTS=%SPHINXOPTS% source
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\EasyTensorflow.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\EasyTensorflow.qhc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end
================================================
FILE: docs/source/README
================================================
Run `sphinx-apidoc -o . ../../easy_tensorflow' in this directory.
This will generate `modules.rst' and `easy_tensorflow.rst'.
Then include `modules.rst' in your `index.rst' file.
================================================
FILE: docs/source/_static/.gitkeep
================================================
================================================
FILE: docs/source/conf.py
================================================
# -*- coding: utf-8 -*-
# This file is based upon the file generated by sphinx-quickstart. However,
# where sphinx-quickstart hardcodes values in this file that you input, this
# file has been changed to pull from your module's metadata module.
#
# This file is execfile()d with the current directory set to its containing
# dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import os
import sys
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../..'))
# Import project metadata
from easy_tensorflow import metadata
# -- General configuration ----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx',
'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode']
# show todos
todo_include_todos = True
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = metadata.project
copyright = metadata.copyright
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = metadata.version
# The full version, including alpha/beta/rc tags.
release = metadata.version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output --------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'nature'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = metadata.project_no_spaces + 'doc'
# -- Options for LaTeX output -------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author,
# documentclass [howto/manual]).
latex_documents = [
('index', metadata.project_no_spaces + '.tex',
metadata.project + ' Documentation', metadata.authors_string,
'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output -------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', metadata.package, metadata.project + ' Documentation',
metadata.authors_string, 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', metadata.project_no_spaces,
metadata.project + ' Documentation', metadata.authors_string,
metadata.project_no_spaces, metadata.description, 'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'python': ('http://docs.python.org/', None),
}
# Extra local configuration. This is useful for placing the class description
# in the class docstring and the __init__ parameter documentation in the
# __init__ docstring. See
# <http://sphinx-doc.org/ext/autodoc.html#confval-autoclass_content> for more
# information.
autoclass_content = 'both'
================================================
FILE: docs/source/index.rst
================================================
EasyTensorflow
==============
Contents:
.. toctree::
:maxdepth: 2
.. only:: html
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
================================================
FILE: easy_tensorflow/__init__.py
================================================
# -*- coding: utf-8 -*-
"""Provides objects that allow for easy setup, training, and running of neural networks, based on Google's tensorflow library. Also allows for the evolution of effective networks using a genetic algorithm derived from the DEAP package."""
from easy_tensorflow import metadata, tf_functions, evolve_functions
__version__ = metadata.version
__author__ = metadata.authors[0]
__license__ = metadata.license
__copyright__ = metadata.copyright
================================================
FILE: easy_tensorflow/evolve_functions.py
================================================
import numpy as np
import scipy.stats
import random
from deap import base
from deap import creator
from deap import tools
import tf_functions
def rmse(p, t):
'''
Calculates the root means squared error between two vectors.
:param p: One-dimensional numpy array with the predicted values.
:param t: One-dimensional numpy array with the known values.
:return: Float value between 0 and infinity.
'''
return np.sqrt(np.average(np.square(np.subtract(p, t))))
def r_squared(p, t):
'''
Coefficient of determination for determining how well the data fits the model.
:param p: Numpy array with the predicted values.
:param t: Numpy array with the known values.
:return: Float value between 0 and 1.
'''
# Reshapes into one-dimensional array if necessary.
if len(t.shape) == 2:
t = [i[0] for i in t]
if len(p.shape) == 2:
p = [i[0] for i in p]
# Get r value for squaring.
slope, intercept, r_value, p_value, std_err = scipy.stats.linregress(p, t)
return r_value ** 2
def accuracy(p, t):
'''
Fraction of samples that were classified correctly.
:param p: Multi-dimensional numpy array with the predicted values.
:param t: Multi-dimensional numpy array with the known values.
:return: Float value between 0 and 1.
'''
return sum([1 for i, j in zip(np.argmax(p, axis=1), np.argmax(t, axis=1)) if i == j]) / float(len(p))
def specificity(p, t):
'''
Fraction of positive samples correctly identified as positive.
:param p: Multi-dimensional numpy array with the predicted values.
:param t: Multi-dimensional numpy array with the known values.
:return: Float value between 0 and 1.
'''
# Calculates number of correctly identified positive samples.
num = sum([1 for i, j in zip(np.argmax(p, axis=1), np.argmax(t, axis=1)) if i == 0 and j == 0])
# Calculates total number of positive samples.
denom = sum([1 for i in np.argmax(t, axis=1) if i == 0])
return num / float(denom)
def sensitivity(p, t):
'''
Fraction of negative samples correctly identified as negative.
:param p: Multi-dimensional numpy array with the predicted values.
:param t: Multi-dimensional numpy array with the known values.
:return: Float value between 0 and 1.
'''
# Calculates number of correctly identified negative samples.
num = sum([1 for i, j in zip(np.argmax(p, axis=1), np.argmax(t, axis=1)) if i == 1 and j == 1])
# Calculates total number of negative samples.
denom = sum([1 for i in np.argmax(t, axis=1) if i == 1])
return num / float(denom)
def test_train_split(X, y, num_test = 0):
'''
Splits a full set of input and output data randomly into train and test sets. Keeps the input and output values
connected.
:param X: Numpy array with input data.
:param y: Numpy array with output data.
:param num_test: Number of samples to use for the test set. Set to 0 by default, which cause 1/5 of the full set to
be split off for testing.
:return: Four numpy arrays corresponding to the training input, training output, testing input, and testing output
data.
'''
# Splits off 1/5 of data if no specific amount is given.
if num_test == 0:
num_test = y.shape[0] / 5
# Turns one-dimensional vector into array of shape (n, 1).
if len(y.shape) == 1:
y = y.reshape(len(y), 1)
# Records the number of output features.
output_features = y.shape[1]
# Combines the input and output features so that the outputs can stay connected.
all_vals = np.append(X, y, 1)
# Randomly shuffles the samples.
np.random.shuffle(all_vals)
# Pulls out the test and train input and output features.
teX, teY = all_vals[:num_test, :-output_features], all_vals[:num_test, -output_features:]
trX, trY = all_vals[num_test:, :-output_features], all_vals[num_test:, -output_features:]
return trX, trY, teX, teY
def evolve(predict_type, fitness_measure, trX, trY,
max_layers = 5, num_gens = 10, gen_size = 40, teX = [], teY = [],
layer_types = ['relu', 'softplus', 'dropout', 'bias_add', 'sigmoid', 'tanh', 'none', 'normalize'],
layer_sizes = [0, 0, 10, 50, 100, 200, 500, 1000],
end_types = ['sum', 'prod', 'min', 'max', 'mean', 'none', 'sigmoid', 'tanh'],
train_types = ['GradientDescent', 'GradientDescent', 'GradientDescent', 'Adagrad', 'Momentum', 'Adam', 'Ftrl', 'RMSProp'],
cross_prob = 0.2, mut_prob = 0.2, tourn_size = 5, train_iters = 5, squash_errors = True):
'''
:param predict_type: String denoting the type of neural network to evolve. Two options: 'regression' and
'classification'.
:param fitness_measure: String denoting the type of measurement to use for evaluating the performance of the network
type. Options:
- 'rmse': Root mean squared error between the predicted values and known values. Use for regression.
- 'r_squared': Coefficient of determination for determining how well the data fits the model. Use for
regression.
- 'accuracy': Fraction of samples that were classified correctly. Use for classification, and can be used for
multi-class classification.
- 'sensitivity': Fraction of positive samples correctly identified as positive. Use for classification with two
classes, and the second class is the positive class.
- 'specificity': Fraction of negative samples correctly identified as negative. Use for classification with two
classes, and the first class is the negative class.
:param trX: Numpy array with input data to use for training. Will pull randomly from this array to create test and
training sets.
:param trY: Numpy array with output data to use for training.
:param max_layers: Integer denoting the maximum number of layers that exist between the input and output layer. Set
at 5 by default.
:param num_gens: Number of generations to simulate. Set at 10 by default.
:param gen_size: Number of individual members per generation. Set at 40 by default.
:param teX: If a specific test set is desired, enter the input data here as a numpy array.
:param teY: Test output data as a numpy array.
:param layer_types: List of strings denoting the layer types possible to be used. Set to ['relu', 'softplus',
'dropout', 'bias_add', 'sigmoid', 'tanh', 'none', 'normalize'] by default.
:param layer_sizes: List of integers denoting the layer sizes possible to be used. List must be of the same length
as layer_types. Set to [0, 0, 10, 50, 100, 200, 500, 1000] by default.
:param end_types: List of strings denoting the options for the type of transformation that gives the output. List
must be of same length as layer_types. Set to ['sum', 'prod', 'min', 'max', 'mean', 'none', 'sigmoid', 'tanh']
by default.
:param train_types: List of strings denoting the optimizer types possible to be used. List must be of same length as
layer_types. Set to ['GradientDescent', 'GradientDescent', 'GradientDescent', 'Adagrad', 'Momentum', 'Adam',
'Ftrl', 'RMSProp'] by default.
:param cross_prob: Float value denoting the probability of crossing the genetics of different individuals. Set at
0.2 by default.
:param mut_prob: Float value denoting the probability of changing the genetics of a single individual. Set at 0.2 by
default.
:param tourn_size: Integer denoting the number of individuals to carry from each generation. Set at 5 by default.
:param train_iters: Integer denoting the number of training iterations to use for each neural network. Set at 5 by
default.
:param squash_errors: Boolean value denoting whether to give a fail value if the network results in an error. Set to
True by default.
:return: List of strings giving the best net_type, string denoting the best optimizer, and Float value denoting the
measure of the best network type.
'''
# Checks that the different options have the same size.
if not len(layer_types) == len(layer_sizes) == len(end_types) == len(train_types):
print('Input attribute lists have different sizes.')
return None
# Gets the type of network to check.
if predict_type == 'regression':
predictor = tf_functions.Regresser
elif predict_type == 'classification':
predictor = tf_functions.Classifier
end_types = ['softmax'] * len(layer_types)
# Gets the type of success measure to use.
if fitness_measure == 'rmse':
measure = rmse
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin)
fail_val = np.inf
elif fitness_measure == 'r_squared':
measure = r_squared
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)
fail_val = 0
elif fitness_measure == 'accuracy':
measure = accuracy
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)
fail_val = 0
elif fitness_measure == 'specificity':
measure = specificity
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)
fail_val = 0
elif fitness_measure == 'sensitivity':
measure = sensitivity
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)
fail_val = 0
toolbox = base.Toolbox()
# Attribute generator.
toolbox.register("attr_ints", random.randint, 0, len(layer_types) - 1)
# Structure initializers.
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_ints, n=(max_layers * 2) + 2)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
# Operator registering.
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutUniformInt,low = 0, up = len(layer_types) - 1, indpb=0.5)
toolbox.register("select", tools.selTournament, tournsize = tourn_size)
# Gets the initial population.
pop = toolbox.population(n = gen_size)
# Performs an initial selection.
for ind in pop:
# Turns the individual's genes into a net_type and an optimizer.
net_type = []
for i in range(max_layers):
net_type.append(layer_types[ind[i * 2]])
net_type.append(layer_sizes[ind[i * 2 + 1]])
net_type.append(end_types[ind[-2]])
# Splits into test and train if needed.
if teX == []:
ttrX, ttrY, tteX, tteY = test_train_split(trX, trY)
else:
ttrX, ttrY, tteX, tteY = trX, trY, teX, teY
# Attempts to test network if errors to be squashed.
if squash_errors:
try:
# Sets up, trains, and tests network.
ind_predictor = predictor(net_type, optimizer = train_types[ind[-1]])
ind_predictor.train(ttrX, ttrY, train_iters)
p = ind_predictor.predict(tteX)
m = measure(p, tteY)
ind_predictor.close()
# Upon an error, gives the worst possible value.
except:
m = fail_val
if np.isnan(m):
m = fail_val
else:
ind_predictor = predictor(net_type, optimizer = train_types[ind[-1]])
ind_predictor.train(ttrX, ttrY, train_iters)
p = ind_predictor.predict(tteX)
m = measure(p, tteY)
ind_predictor.close()
ind.fitness.values = (m,)
# Begins the evolution.
for g in range(num_gens):
# Selects the next generation individuals.
offspring = toolbox.select(pop, len(pop))
# Clones the selected individuals.
offspring = list(map(toolbox.clone, offspring))
# Applies crossover and mutation on the offspring.
for child1, child2 in zip(offspring[::2], offspring[1::2]):
if random.random() < cross_prob:
toolbox.mate(child1, child2)
del child1.fitness.values
del child2.fitness.values
for mutant in offspring:
if random.random() < mut_prob:
toolbox.mutate(mutant)
del mutant.fitness.values
# Evaluates the individuals with an invalid fitness.
invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
for ind in invalid_ind:
net_type = []
for i in range(max_layers):
net_type.append(layer_types[ind[i * 2]])
net_type.append(layer_sizes[ind[i * 2 + 1]])
net_type.append(end_types[ind[-2]])
if squash_errors:
try:
ind_predictor = predictor(net_type, optimizer = train_types[ind[-1]])
ind_predictor.train(ttrX, ttrY, train_iters)
p = ind_predictor.predict(tteX)
m = measure(p, tteY)
ind_predictor.close()
except:
m = fail_val
if np.isnan(m):
m = fail_val
else:
ind_predictor = predictor(net_type, optimizer = train_types[ind[-1]])
ind_predictor.train(ttrX, ttrY, train_iters)
p = ind_predictor.predict(tteX)
m = measure(p, tteY)
ind_predictor.close()
ind.fitness.values = (m,)
# The population is entirely replaced by the offspring.
pop[:] = offspring
# Gets the best individual remaining after
best_ind = tools.selBest(pop, 1)[0]
net_type = []
for i in range(max_layers):
net_type.append(layer_types[best_ind[i * 2]])
net_type.append(layer_sizes[best_ind[i * 2 + 1]])
net_type.append(end_types[best_ind[-2]])
optimizer = train_types[best_ind[-1]]
return net_type, optimizer, best_ind.fitness.values
================================================
FILE: easy_tensorflow/main.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Program entry point"""
from __future__ import print_function
import argparse
import sys
from easy_tensorflow import metadata, tf_functions, evolve_functions
def main(argv):
"""Program entry point.
:param argv: command-line arguments
:type argv: :class:`list`
"""
author_strings = []
for name, email in zip(metadata.authors, metadata.emails):
author_strings.append('Author: {0} <{1}>'.format(name, email))
epilog = '''
{project} {version}
{authors}
URL: <{url}>
'''.format(
project=metadata.project,
version=metadata.version,
authors='\n'.join(author_strings),
url=metadata.url)
arg_parser = argparse.ArgumentParser(
prog=argv[0],
formatter_class=argparse.RawDescriptionHelpFormatter,
description=metadata.description,
epilog=epilog)
arg_parser.add_argument(
'-V', '--version',
action='version',
version='{0} {1}'.format(metadata.project, metadata.version))
arg_parser.parse_args(args=argv[1:])
print(epilog)
return 0
def entry_point():
"""Zero-argument entry point for use with setuptools/distribute."""
raise SystemExit(main(sys.argv))
if __name__ == '__main__':
entry_point()
================================================
FILE: easy_tensorflow/metadata.py
================================================
# -*- coding: utf-8 -*-
"""Project metadata
Information describing the project.
"""
# The package name, which is also the "UNIX name" for the project.
package = 'easy_tensorflow'
project = "EasyTensorflow"
project_no_spaces = project.replace(' ', '')
version = '0.1'
description = 'Provides objects that allow for easy setup, training, and running of neural networks, based on Google\'s ' \
'tensorflow library. Also allows for the evolution of effective networks using a genetic algorithm derived' \
' from the DEAP package.'
authors = ['Calvin Schmidt']
authors_string = ', '.join(authors)
emails = ['calvins@stanford.edu']
license = 'MIT'
copyright = '2015 ' + authors_string
url = 'https://github.com/calvinschmdt/EasyTensorflow'
================================================
FILE: easy_tensorflow/tf_dictionaries.py
================================================
import tensorflow as tf
transform_dict = {
'relu': (tf.nn.relu, (tf.nn.bias_add, ((tf.matmul, ('X', 'weight1')), 'weight2'))),
'softplus': (tf.nn.softplus, (tf.nn.bias_add, ((tf.matmul, ('X', 'weight1')), 'weight2'))),
'dropout': (tf.nn.dropout, ('X', 'weight')),
'bias_add': (tf.nn.bias_add, ('X', 'weight')),
'sigmoid': (tf.nn.sigmoid, (tf.nn.bias_add, ((tf.matmul, ('X', 'weight1')), 'weight2'))),
'tanh': (tf.nn.tanh, (tf.nn.bias_add, ((tf.matmul, ('X', 'weight1')), 'weight2'))),
'none': (tf.nn.bias_add, ((tf.matmul, ('X', 'weight1')), 'weight2')),
'normalize': (tf.nn.l2_normalize, ('X', 1)),
'sum': (tf.reduce_sum, ('X', 1)),
'prod': (tf.reduce_prod, ('X', 1)),
'min': (tf.reduce_min, ('X', 1)),
'max': (tf.reduce_max, ('X', 1)),
'mean': (tf.reduce_mean, ('X', 1)),
'softmax': (tf.nn.softmax, (tf.matmul, ('X', 'weight')))
}
optimizer_dict = {
'GradientDescent': (tf.train.GradientDescentOptimizer, (0.001, )),
'Adagrad': (tf.train.AdagradOptimizer, (0.001, )),
'Momentum': (tf.train.MomentumOptimizer, (0.001, 0.1)),
'Adam': (tf.train.AdamOptimizer, ()),
'Ftrl': (tf.train.FtrlOptimizer, (0.001, )),
'RMSProp': (tf.train.RMSPropOptimizer, (0.001, 0.9))
}
================================================
FILE: easy_tensorflow/tf_functions.py
================================================
import tensorflow as tf
import numpy as np
import random
import tf_dictionaries
def random_index_list(list_size, sample_size):
'''
Creates a list of random integers that are constrained in the max value. May have repeating indexes.
:param list_size: Integer denoting the length of the final list.
:param sample_size: Integer denoting the maximum index to include.
:return: List of integers.
'''
return [random.randint(0, sample_size - 1) for i in range(0, list_size)]
def encode_classifications(class_list):
'''
Given a list of class labels, encodes the list in a manner that is usable in neural networks. For each sample,
there will be a list of 0s and one 1 corresponding to the label that sample is encoded. Also returns the list of
so that encoded sample lists can be decoded.
:param class_list: List of labels, that can be either strings or numbers.
:return: classes: List of strings denoting the different labels found in the list.
encoded: Numpy array of encoded labels. One row for each sample, with the numbers in the row corresponding to
the label for that sample.
'''
# Iterates through the list, recording all the samples.
classes = []
for i in class_list:
if i not in classes:
classes.append(i)
# Creates a list of 0s for each sample.
encoded = [[0] * len(classes) for i in range(len(class_list))]
# Iterates through the list to be encoded, marking a 1 in the position for the given label for that sample.
for e, i in enumerate(class_list):
encoded[e][classes.index(i)] = 1
return classes, np.array(encoded)
def decode_classifications(classes, encoded):
'''
Given an array of labels encoded in array format, returns a that array as their original labels.
:param classes: List of strings denoting the different labels found in the list.
:param encoded: Numpy array of encoded labels. One row for each sample, with the numbers in the row corresponding to
the label for that sample.
:return: List of strings denoting the label of each sample.
'''
return [classes[i] for i in encoded]
def unpack_transform(transform, X, weight):
'''
Turns a tuple of tensorflow functions and their inputs into tensorflow functions ready to use.
:param transform: Tuple containing a tensorflow tensor as the first part, and a tuple containing the tensor input in
the second part.
:param X: Tensor containing the input matrix to be transformed.
:param weight: Tensor, integer, or float containing a weight as the second tensor input.
:return: Completed tensor, with inputs placed in.
'''
# If the first part of the tensor's input should be X, then applies the X as the incoming tensor.
if transform[1][0] == 'X':
# If a weight tensor or value should be applied to the tensor, then uses the supplied weight. If there is not a
# weight, uses 1 to direct the axis of tensor transformation.
if transform[1][1] == 'weight' or transform[1][1] == 'weight1':
w = weight
elif transform[1][1] == 1:
w = 1
return transform[0](X, w)
if transform[1][1] == 'weight2':
return transform[0](unpack_transform(transform[1][0], X, weight[0]), weight[1])
# If the first part of the tensor's input is not X, then unpacks the tensor that should be the input, and uses that.
else:
return transform[0](unpack_transform(transform[1], X, weight))
def compile_model(X, weights, models, transform_dict):
'''
Converts lists of weights and models into a tensorflow neural network that can take in an input tensor and return
an output tensor.
:param X: Tensor that contains the input values to be transformed through the network.
:param weights: List of tensors (or single value in the case of dropouts) that transform the X value through the
layers.
:param models: List of the different types of layers. Should be in the same order as the weights list, and be the
desired order of layers.
:return: Tensor that has been transformed through the different layers.
'''
# Iterates through each layer.
for model, weight in zip(models, weights):
# Finds the layer type, and transforms through that layer type.
transform = transform_dict[model]
X = unpack_transform(transform, X, weight)
return X
def make_model(X, input_size, output_size, net_type, transform_dict):
'''
Creates the lists of weight tensors and layer types that are used to compile a tensorflow neural network.
:param X: Tensor that contains the input values to be transformed through the network.
:param input_size: Float value giving the number of features being fed into the network.
:param output_size: Float value giving the number of output values desired.
:param net_type: List of alternating string values and integer values. Must always start and end with a string
values. The strings denote the type of each layer. The integer values denote the end size of each layer, though
this is constrained for certain layer types. Sizes of zero drop that layer out.
:return: Function that represents the neural network.
'''
weights = []
models = []
started = False
last = input_size
# Iterates through each layer of the network.
for e in range(0, len(net_type) - 1, 2):
# Creates the weight type for the layer, depending on the layer type. Dropouts don't use a tensor, just a float
# value.
if net_type[e] == 'dropout' or net_type[e] == 'normalize':
next = last
weight = random.random()
# Bias add uses a linear layer to transform without changing the size.
elif net_type[e] == 'bias_add':
next = last
weight = tf.Variable(tf.constant(0.0, shape=[next]))
elif net_type[e] == 'relu' or net_type[e] == 'softplus' or net_type[e] == 'tanh' or \
net_type[e] == 'sigmoid' or net_type[e] == 'none':
next = last
weight1 = tf.Variable(tf.random_normal([last, next], stddev=0.01))
weight2 = tf.Variable(tf.constant(0.0, shape=[next]))
weight = (weight1, weight2)
# Other types use a matrix to transform the size.
else:
next = net_type[e + 1]
weight = tf.Variable(tf.random_normal([last, next], stddev=0.01))
# Records the layer type and weight used for transforming into that layer for each layer.
if net_type[e + 1] > 0:
# The first layer pulls from the input size, while the rest pull from the last size.
if not started:
weights.append(weight)
models.append(net_type[e])
last = next
started = True
else:
weights.append(weight)
models.append(net_type[e])
last = next
# Makes sure the last layer can change the size.
if net_type[-1] == 'bias_add' or net_type[-1] == 'dropout' or net_type[-1] == 'normalize':
final = 'sigmoid'
else:
final = net_type[-1]
# Adds in the last layer.
if final == 'relu' or final == 'softplus' or final == 'tanh' or \
final == 'sigmoid' or final == 'none':
weight1 = tf.Variable(tf.random_normal([last, output_size], stddev=0.01))
weight2 = tf.Variable(tf.random_normal([output_size], stddev=0.01))
weight = (weight1, weight2)
else:
weight = tf.Variable(tf.random_normal([last, output_size], stddev=0.01))
weights.append(weight)
models.append(final)
# Returns the compiled function.
return compile_model(X, weights, models, transform_dict)
def train_tensorflow(sess, trX, trY, train_steps, full_train, train_size, net_type, transform_dict, loss_type,
optimizer, optimizer_dict):
'''
Automatically constructs, trains, and tests a tensorflow neural network, returning the r squared value of the
output.
:param sess: A tensorflow session.
:param trX: Numpy array that contains the training features.
:param trY: Numpy array that contains the training outputs. Must have shape of at least 1 on columns.
:param train_steps: Integer value denoting the number of times to iterate through training.
:param full_train: Boolean value denoting whether to use the full training set for each iteration.
:param train_size: Integer value denoting the number of samples to pull from the training set for each iteration of
training.
:param net_type: List of alternating string values and integer values. Must always start and end with a string
values. The strings denote the type of each layer. The integer values denote the end size of each layer, though
this is constrained for certain layer types. Sizes of zero drop that layer out.
:param transform_dict: Dictionary of strings to tuples of tensors that encode how to set up the layers of the neural
network.
:param loss_type: String denoting type of tensor to use for loss type. Use l2_loss for regression, cross_entropy for
classification.
:param optimizer: String denoting the type of optimization tensor to use for training the neural network.
:param optimizer_dict: Dictionary of strings to tuples of tensors that encode how to set up the optimizers of the
neural network.
:return: predict_op: Tensor that encodes the neural network.
X: Placeholder tensor for the features array.
y: Placeholder tensor for the output array.
'''
# Set up input and output tensors.
X = tf.placeholder("float", [None, trX.shape[1]])
y = tf.placeholder("float", [None, trY.shape[1]])
# Set up network.
py_x = make_model(X, trX.shape[1], trY.shape[1], net_type, transform_dict)
# Set up cost and training type.
if loss_type == 'l2_loss':
cost = tf.nn.l2_loss(tf.sub(py_x, y))
elif loss_type == 'cross_entropy':
cost = -tf.reduce_sum(y * tf.log(py_x))
# Gets the optimizer to be used for training and sets it up.
if type(optimizer) == str:
train_op = optimizer_dict[optimizer][0](*optimizer_dict[optimizer][1]).minimize(cost)
else:
train_op = optimizer[0](*optimizer[1]).minimize(cost)
predict_op = py_x
# Initialize session.
init = tf.initialize_all_variables()
sess.run(init)
# Trains given number of times
try:
for i in range(train_steps):
# If full_train is selected, the trains on the full set of training data, in 100 sample increments.
if full_train:
for start, end in zip(range(0, len(trX), 100), range(100, len(trX), 100)):
sess.run(train_op, feed_dict={X: trX[start:end], y: trY[start:end]})
# If full_train is not selected, then trains on a random set of samples from the training data.
else:
indices = random_index_list(train_size, len(trY))
sess.run(train_op, feed_dict={X: trX[indices], y: trY[indices]})
# If training throws an error for whatever reason, stops the program from breaking. Throws an error message and \
# closes the session.
except:
print("Error during training")
sess.close()
return None
return predict_op, X, y
class Classifier:
'''
Object that holds a neural network used for classifying a set of data.
'''
def __init__(self, net_type, loss_type = 'cross_entropy', optimizer = 'Adam'):
'''
Initializing function. Records the neural network type and, if given, the loss type and optimizer type.
:param net_type: List of alternating string values and integer values. Must always start and end with a string
values. The strings denote the type of each layer. The integer values denote the end size of each layer, though
this is constrained for certain layer types. Sizes of zero drop that layer out.
:param loss_type: String denoting type of tensor to use for loss type. Set as cross_entropy by default.
:param optimizer: String denoting the type of optimization tensor to use for training the neural network. Set
as Adam by default. Tuple containing optimization tensor and input tuple can be used in place of a string to
set specific parameters for the optimization.
'''
# Sets up initial parameters and starts the tensorflow session.
self.net_type = net_type
self.loss_type = loss_type
self.optimizer = optimizer
self.sess = tf.Session()
self.transform_dict = tf_dictionaries.transform_dict
self.optimizer_dict = tf_dictionaries.optimizer_dict
def train(self, trX, trY, iterations, full_train = True, train_size = 0):
'''
Sets up and trains the neural network.
:param trX: Numpy array that contains the training features.
:param trY: Numpy array that contains the training outputs. Can be in the encoded or unencoded format.
:param iterations: Integer denoting the number of iterations to train the model.
:param full_train: Boolean value denoting whether to use the full training set for each iteration. Set as True
by default.
:param train_size: Integer value denoting the number of samples to pull from the training set for each iteration
of training. Set as 0 by default.
:return: Does not return anything, but stores the input, output, and transformation tensors for predicting.
'''
# If the labels are not encoded in matrix format, does that and stores the list of classes.
if trY.shape[1] == 1:
self.class_list, trY = encode_classifications(trY)
# Sets up and trains tensorflow.
self.predict_op, self.X, self.y = train_tensorflow(self.sess, trX, trY, iterations,
full_train, train_size,
self.net_type, self.transform_dict,
self.loss_type,
self.optimizer, self.optimizer_dict)
def predict(self, teX, return_encoded = True):
'''
Uses the trained neural network to classify the samples based on their features.
:param teX: Numpy array of features to be used for the classification.
:param return_encoded: Boolean value denoting whether to decode the classifications if needed. Must have
generated class list by encoding during the training.
:return: Either encoded or decoded classifications for the input samples as a numpy array or list.
'''
# Use the neural network for predicting the classes.
p = self.sess.run(self.predict_op, feed_dict={self.X: teX})
# Decodes if desired.
if not return_encoded:
p = np.argmax(p, axis=1)
return decode_classifications(p, self.class_list)
return p
def close(self):
'''
Closes the session.
:return: Nothing, but closes the session.
'''
self.sess.close()
class Regresser:
'''
Object that holds a neural network used for predicting a set of data's numerical outputs.
'''
def __init__(self, net_type, loss_type = 'l2_loss', optimizer = 'Adam'):
'''
Initializing function. Records the neural network type and, if given, the loss type and optimizer type.
:param net_type: List of alternating string values and integer values. Must always start and end with a string
values. The strings denote the type of each layer. The integer values denote the end size of each layer, though
this is constrained for certain layer types. Sizes of zero drop that layer out.
:param loss_type: String denoting type of tensor to use for loss type. Set as l2_loss by default.
:param optimizer: String denoting the type of optimization tensor to use for training the neural network. Set
as Adam by default. Tuple containing optimization tensor and input tuple can be used in place of a string to
set specific parameters for the optimization.
'''
# Sets up initial parameters and starts the tensorflow session.
self.net_type = net_type
self.loss_type = loss_type
self.optimizer = optimizer
self.sess = tf.Session()
self.transform_dict = tf_dictionaries.transform_dict
self.optimizer_dict = tf_dictionaries.optimizer_dict
def train(self, trX, trY, iterations, full_train = True, train_size = 0):
'''
Sets up and trains the neural network.
:param trX: Numpy array that contains the training features.
:param trY: Numpy array that contains the training outputs. If if in vector format, then reshapes as array.
:param iterations: Integer denoting the number of iterations to train the model.
:param full_train: Boolean value denoting whether to use the full training set for each iteration. Set as True
by default.
:param train_size: Integer value denoting the number of samples to pull from the training set for each iteration
of training. Set as 0 by default.
:return: Does not return anything, but stores the input, output, and transformation tensors for predicting.
'''
# The training outputs are not in the correct shape, fits into correct shape.
if len(trY.shape) == 1:
trY = trY.reshape(len(trY), 1)
# Sets up and trains tensorflow.
self.predict_op, self.X, self.y = train_tensorflow(self.sess, trX, trY, iterations,
full_train, train_size,
self.net_type, self.transform_dict,
self.loss_type,
self.optimizer, self.optimizer_dict)
def predict(self, teX):
'''
Uses the trained neural network to classify the samples based on their features.
:param teX: Numpy array of features to be used for the classification.
:return: Numpy vector of predicted outputs..
'''
# Use the neural network for predicting the classes.
p = self.sess.run(self.predict_op, feed_dict={self.X: teX})
# Reshapes array of columns into vector.
if len(p.shape) > 1:
p = np.array([i[0] for i in np.ndarray.tolist(p)])
return np.array(p)
def close(self):
'''
Closes the session.
:return: Nothing, but closes the session.
'''
self.sess.close()
================================================
FILE: pavement.py
================================================
# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import sys
import time
import subprocess
# Import parameters from the setup file.
sys.path.append('.')
from setup import (
setup_dict, get_project_files, print_success_message,
print_failure_message, _lint, _test, _test_all,
CODE_DIRECTORY, DOCS_DIRECTORY, TESTS_DIRECTORY, PYTEST_FLAGS)
from paver.easy import options, task, needs, consume_args
from paver.setuputils import install_distutils_tasks
options(setup=setup_dict)
install_distutils_tasks()
## Miscellaneous helper functions
def print_passed():
# generated on http://patorjk.com/software/taag/#p=display&f=Small&t=PASSED
print_success_message(r''' ___ _ ___ ___ ___ ___
| _ \/_\ / __/ __| __| \
| _/ _ \\__ \__ \ _|| |) |
|_|/_/ \_\___/___/___|___/
''')
def print_failed():
# generated on http://patorjk.com/software/taag/#p=display&f=Small&t=FAILED
print_failure_message(r''' ___ _ ___ _ ___ ___
| __/_\ |_ _| | | __| \
| _/ _ \ | || |__| _|| |) |
|_/_/ \_\___|____|___|___/
''')
class cwd(object):
"""Class used for temporarily changing directories. Can be though of
as a `pushd /my/dir' then a `popd' at the end.
"""
def __init__(self, newcwd):
""":param newcwd: directory to make the cwd
:type newcwd: :class:`str`
"""
self.newcwd = newcwd
def __enter__(self):
self.oldcwd = os.getcwd()
os.chdir(self.newcwd)
return os.getcwd()
def __exit__(self, type_, value, traceback):
# This acts like a `finally' clause: it will always be executed.
os.chdir(self.oldcwd)
## Task-related functions
def _doc_make(*make_args):
"""Run make in sphinx' docs directory.
:return: exit code
"""
if sys.platform == 'win32':
# Windows
make_cmd = ['make.bat']
else:
# Linux, Mac OS X, and others
make_cmd = ['make']
make_cmd.extend(make_args)
# Account for a stupid Python "bug" on Windows:
# <http://bugs.python.org/issue15533>
with cwd(DOCS_DIRECTORY):
retcode = subprocess.call(make_cmd)
return retcode
## Tasks
@task
@needs('doc_html', 'setuptools.command.sdist')
def sdist():
"""Build the HTML docs and the tarball."""
pass
@task
def test():
"""Run the unit tests."""
raise SystemExit(_test())
@task
def lint():
# This refuses to format properly when running `paver help' unless
# this ugliness is used.
('Perform PEP8 style check, run PyFlakes, and run McCabe complexity '
'metrics on the code.')
raise SystemExit(_lint())
@task
def test_all():
"""Perform a style check and run all unit tests."""
retcode = _test_all()
if retcode == 0:
print_passed()
else:
print_failed()
raise SystemExit(retcode)
@task
@consume_args
def run(args):
"""Run the package's main script. All arguments are passed to it."""
# The main script expects to get the called executable's name as
# argv[0]. However, paver doesn't provide that in args. Even if it did (or
# we dove into sys.argv), it wouldn't be useful because it would be paver's
# executable. So we just pass the package name in as the executable name,
# since it's close enough. This should never be seen by an end user
# installing through Setuptools anyway.
from easy_tensorflow.main import main
raise SystemExit(main([CODE_DIRECTORY] + args))
@task
def commit():
"""Commit only if all the tests pass."""
if _test_all() == 0:
subprocess.check_call(['git', 'commit'])
else:
print_failure_message('\nTests failed, not committing.')
@task
def coverage():
"""Run tests and show test coverage report."""
try:
import pytest_cov # NOQA
except ImportError:
print_failure_message(
'Install the pytest coverage plugin to use this task, '
"i.e., `pip install pytest-cov'.")
raise SystemExit(1)
import pytest
pytest.main(PYTEST_FLAGS + [
'--cov', CODE_DIRECTORY,
'--cov-report', 'term-missing',
TESTS_DIRECTORY])
@task # NOQA
def doc_watch():
"""Watch for changes in the docs and rebuild HTML docs when changed."""
try:
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
except ImportError:
print_failure_message('Install the watchdog package to use this task, '
"i.e., `pip install watchdog'.")
raise SystemExit(1)
class RebuildDocsEventHandler(FileSystemEventHandler):
def __init__(self, base_paths):
self.base_paths = base_paths
def dispatch(self, event):
"""Dispatches events to the appropriate methods.
:param event: The event object representing the file system event.
:type event: :class:`watchdog.events.FileSystemEvent`
"""
for base_path in self.base_paths:
if event.src_path.endswith(base_path):
super(RebuildDocsEventHandler, self).dispatch(event)
# We found one that matches. We're done.
return
def on_modified(self, event):
print_failure_message('Modification detected. Rebuilding docs.')
# # Strip off the path prefix.
# import os
# if event.src_path[len(os.getcwd()) + 1:].startswith(
# CODE_DIRECTORY):
# # sphinx-build doesn't always pick up changes on code files,
# # even though they are used to generate the documentation. As
# # a workaround, just clean before building.
doc_html()
print_success_message('Docs have been rebuilt.')
print_success_message(
'Watching for changes in project files, press Ctrl-C to cancel...')
handler = RebuildDocsEventHandler(get_project_files())
observer = Observer()
observer.schedule(handler, path='.', recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
@task
@needs('doc_html')
def doc_open():
"""Build the HTML docs and open them in a web browser."""
doc_index = os.path.join(DOCS_DIRECTORY, 'build', 'html', 'index.html')
if sys.platform == 'darwin':
# Mac OS X
subprocess.check_call(['open', doc_index])
elif sys.platform == 'win32':
# Windows
subprocess.check_call(['start', doc_index], shell=True)
elif sys.platform == 'linux2':
# All freedesktop-compatible desktops
subprocess.check_call(['xdg-open', doc_index])
else:
print_failure_message(
"Unsupported platform. Please open `{0}' manually.".format(
doc_index))
@task
def get_tasks():
"""Get all paver-defined tasks."""
from paver.tasks import environment
for task in environment.get_tasks():
print(task.shortname)
@task
def doc_html():
"""Build the HTML docs."""
retcode = _doc_make('html')
if retcode:
raise SystemExit(retcode)
@task
def doc_clean():
"""Clean (delete) the built docs."""
retcode = _doc_make('clean')
if retcode:
raise SystemExit(retcode)
================================================
FILE: requirements-dev.txt
================================================
# Runtime requirements
--requirement requirements.txt
# Testing
pytest==2.5.1
py==1.4.19
mock==1.0.1
# Linting
flake8==2.1.0
mccabe==0.2.1
pep8==1.4.6
pyflakes==0.7.3
# Documentation
Sphinx==1.2
docutils==0.11
Jinja2==2.7.1
MarkupSafe==0.18
Pygments==1.6
# Miscellaneous
Paver==1.2.1
colorama==0.2.7
# Function
deap==1.0
tensorflow
================================================
FILE: requirements.txt
================================================
# Python 2.6 compatibility
# argparse==1.2.1
# Function
deap==1.0
tensorflow
================================================
FILE: setup.py
================================================
# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import sys
import imp
import subprocess
## Python 2.6 subprocess.check_output compatibility. Thanks Greg Hewgill!
if 'check_output' not in dir(subprocess):
def check_output(cmd_args, *args, **kwargs):
proc = subprocess.Popen(
cmd_args, *args,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
out, err = proc.communicate()
if proc.returncode != 0:
raise subprocess.CalledProcessError(args)
return out
subprocess.check_output = check_output
from setuptools import setup, find_packages
from setuptools.command.test import test as TestCommand
from distutils import spawn
try:
import colorama
colorama.init() # Initialize colorama on Windows
except ImportError:
# Don't require colorama just for running paver tasks. This allows us to
# run `paver install' without requiring the user to first have colorama
# installed.
pass
# Add the current directory to the module search path.
sys.path.insert(0, os.path.abspath('.'))
## Constants
CODE_DIRECTORY = 'easy_tensorflow'
DOCS_DIRECTORY = 'docs'
TESTS_DIRECTORY = 'tests'
PYTEST_FLAGS = ['--doctest-modules']
# Import metadata. Normally this would just be:
#
# from easy_tensorflow import metadata
#
# However, when we do this, we also import `easy_tensorflow/__init__.py'. If this
# imports names from some other modules and these modules have third-party
# dependencies that need installing (which happens after this file is run), the
# script will crash. What we do instead is to load the metadata module by path
# instead, effectively side-stepping the dependency problem. Please make sure
# metadata has no dependencies, otherwise they will need to be added to
# the setup_requires keyword.
metadata = imp.load_source(
'metadata', os.path.join(CODE_DIRECTORY, 'metadata.py'))
## Miscellaneous helper functions
def get_project_files():
"""Retrieve a list of project files, ignoring hidden files.
:return: sorted list of project files
:rtype: :class:`list`
"""
if is_git_project() and has_git():
return get_git_project_files()
project_files = []
for top, subdirs, files in os.walk('.'):
for subdir in subdirs:
if subdir.startswith('.'):
subdirs.remove(subdir)
for f in files:
if f.startswith('.'):
continue
project_files.append(os.path.join(top, f))
return project_files
def is_git_project():
return os.path.isdir('.git')
def has_git():
return bool(spawn.find_executable("git"))
def get_git_project_files():
"""Retrieve a list of all non-ignored files, including untracked files,
excluding deleted files.
:return: sorted list of git project files
:rtype: :class:`list`
"""
cached_and_untracked_files = git_ls_files(
'--cached', # All files cached in the index
'--others', # Untracked files
# Exclude untracked files that would be excluded by .gitignore, etc.
'--exclude-standard')
uncommitted_deleted_files = git_ls_files('--deleted')
# Since sorting of files in a set is arbitrary, return a sorted list to
# provide a well-defined order to tools like flake8, etc.
return sorted(cached_and_untracked_files - uncommitted_deleted_files)
def git_ls_files(*cmd_args):
"""Run ``git ls-files`` in the top-level project directory. Arguments go
directly to execution call.
:return: set of file names
:rtype: :class:`set`
"""
cmd = ['git', 'ls-files']
cmd.extend(cmd_args)
return set(subprocess.check_output(cmd).splitlines())
def print_success_message(message):
"""Print a message indicating success in green color to STDOUT.
:param message: the message to print
:type message: :class:`str`
"""
try:
import colorama
print(colorama.Fore.GREEN + message + colorama.Fore.RESET)
except ImportError:
print(message)
def print_failure_message(message):
"""Print a message indicating failure in red color to STDERR.
:param message: the message to print
:type message: :class:`str`
"""
try:
import colorama
print(colorama.Fore.RED + message + colorama.Fore.RESET,
file=sys.stderr)
except ImportError:
print(message, file=sys.stderr)
def read(filename):
"""Return the contents of a file.
:param filename: file path
:type filename: :class:`str`
:return: the file's content
:rtype: :class:`str`
"""
with open(os.path.join(os.path.dirname(__file__), filename)) as f:
return f.read()
def _lint():
"""Run lint and return an exit code."""
# Flake8 doesn't have an easy way to run checks using a Python function, so
# just fork off another process to do it.
# Python 3 compat:
# - The result of subprocess call outputs are byte strings, meaning we need
# to pass a byte string to endswith.
project_python_files = [filename for filename in get_project_files()
if filename.endswith(b'.py')]
retcode = subprocess.call(
['flake8', '--max-complexity=10'] + project_python_files)
if retcode == 0:
print_success_message('No style errors')
return retcode
def _test():
"""Run the unit tests.
:return: exit code
"""
# Make sure to import pytest in this function. For the reason, see here:
# <http://pytest.org/latest/goodpractises.html#integration-with-setuptools-test-commands> # NOPEP8
import pytest
# This runs the unit tests.
# It also runs doctest, but only on the modules in TESTS_DIRECTORY.
return pytest.main(PYTEST_FLAGS + [TESTS_DIRECTORY])
def _test_all():
"""Run lint and tests.
:return: exit code
"""
return _lint() + _test()
# The following code is to allow tests to be run with `python setup.py test'.
# The main reason to make this possible is to allow tests to be run as part of
# Setuptools' automatic run of 2to3 on the source code. The recommended way to
# run tests is still `paver test_all'.
# See <http://pythonhosted.org/setuptools/python3.html>
# Code based on <http://pytest.org/latest/goodpractises.html#integration-with-setuptools-test-commands> # NOPEP8
class TestAllCommand(TestCommand):
def finalize_options(self):
TestCommand.finalize_options(self)
# These are fake, and just set to appease distutils and setuptools.
self.test_suite = True
self.test_args = []
def run_tests(self):
raise SystemExit(_test_all())
# define install_requires for specific Python versions
python_version_specific_requires = []
# as of Python >= 2.7 and >= 3.2, the argparse module is maintained within
# the Python standard library, otherwise we install it as a separate package
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 3):
python_version_specific_requires.append('argparse')
# See here for more options:
# <http://pythonhosted.org/setuptools/setuptools.html>
setup_dict = dict(
name=metadata.package,
version=metadata.version,
author=metadata.authors[0],
author_email=metadata.emails[0],
maintainer=metadata.authors[0],
maintainer_email=metadata.emails[0],
url=metadata.url,
description=metadata.description,
long_description=read('README.rst'),
# Find a list of classifiers here:
# <http://pypi.python.org/pypi?%3Aaction=list_classifiers>
classifiers=[
'Development Status :: 1 - Planning',
'Environment :: Console',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Documentation',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: System :: Installation/Setup',
'Topic :: System :: Software Distribution',
],
packages=find_packages(exclude=(TESTS_DIRECTORY,)),
install_requires=[
# your module dependencies
] + python_version_specific_requires,
# Allow tests to be run with `python setup.py test'.
tests_require=[
'pytest==2.5.1',
'mock==1.0.1',
'flake8==2.1.0',
],
cmdclass={'test': TestAllCommand},
zip_safe=False, # don't use eggs
entry_points={
'console_scripts': [
'easy_tensorflow_cli = easy_tensorflow.main:entry_point'
],
# if you have a gui, use this
# 'gui_scripts': [
# 'easy_tensorflow_gui = easy_tensorflow.gui:entry_point'
# ]
}
)
def main():
setup(**setup_dict)
if __name__ == '__main__':
main()
================================================
FILE: tests/test_main.py
================================================
# -*- coding: utf-8 -*-
from pytest import raises
# The parametrize function is generated, so this doesn't work:
#
# from pytest.mark import parametrize
#
import pytest
parametrize = pytest.mark.parametrize
from easy_tensorflow import metadata
from easy_tensorflow.main import main
class TestMain(object):
@parametrize('helparg', ['-h', '--help'])
def test_help(self, helparg, capsys):
with raises(SystemExit) as exc_info:
main(['progname', helparg])
out, err = capsys.readouterr()
# Should have printed some sort of usage message. We don't
# need to explicitly test the content of the message.
assert 'usage' in out
# Should have used the program name from the argument
# vector.
assert 'progname' in out
# Should exit with zero return code.
assert exc_info.value.code == 0
@parametrize('versionarg', ['-V', '--version'])
def test_version(self, versionarg, capsys):
with raises(SystemExit) as exc_info:
main(['progname', versionarg])
out, err = capsys.readouterr()
# Should print out version.
assert err == '{0} {1}\n'.format(metadata.project, metadata.version)
# Should exit with zero return code.
assert exc_info.value.code == 0
================================================
FILE: tox.ini
================================================
# Tox (http://tox.testrun.org/) is a tool for running tests in
# multiple virtualenvs. This configuration file will run the test
# suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.
#
# To run tox faster, check out Detox
# (https://pypi.python.org/pypi/detox), which runs your tox runs in
# parallel. To use it, "pip install detox" and then run "detox" from
# this directory.
[tox]
envlist = py26,py27,py33,pypy,docs
[testenv]
deps =
--no-deps
--requirement
{toxinidir}/requirements-dev.txt
commands = paver test_all
[testenv:docs]
basepython = python
commands = paver doc_html
gitextract_0gqp2iax/ ├── LICENSE ├── MANIFEST.in ├── README.rst ├── docs/ │ ├── Makefile │ ├── make.bat │ └── source/ │ ├── README │ ├── _static/ │ │ └── .gitkeep │ ├── conf.py │ └── index.rst ├── easy_tensorflow/ │ ├── __init__.py │ ├── evolve_functions.py │ ├── main.py │ ├── metadata.py │ ├── tf_dictionaries.py │ └── tf_functions.py ├── pavement.py ├── requirements-dev.txt ├── requirements.txt ├── setup.py ├── tests/ │ └── test_main.py └── tox.ini
SYMBOL INDEX (64 symbols across 6 files)
FILE: easy_tensorflow/evolve_functions.py
function rmse (line 9) | def rmse(p, t):
function r_squared (line 19) | def r_squared(p, t):
function accuracy (line 38) | def accuracy(p, t):
function specificity (line 48) | def specificity(p, t):
function sensitivity (line 64) | def sensitivity(p, t):
function test_train_split (line 80) | def test_train_split(X, y, num_test = 0):
function evolve (line 115) | def evolve(predict_type, fitness_measure, trX, trY,
FILE: easy_tensorflow/main.py
function main (line 13) | def main(argv):
function entry_point (line 51) | def entry_point():
FILE: easy_tensorflow/tf_functions.py
function random_index_list (line 6) | def random_index_list(list_size, sample_size):
function encode_classifications (line 16) | def encode_classifications(class_list):
function decode_classifications (line 42) | def decode_classifications(classes, encoded):
function unpack_transform (line 53) | def unpack_transform(transform, X, weight):
function compile_model (line 82) | def compile_model(X, weights, models, transform_dict):
function make_model (line 104) | def make_model(X, input_size, output_size, net_type, transform_dict):
function train_tensorflow (line 183) | def train_tensorflow(sess, trX, trY, train_steps, full_train, train_size...
class Classifier (line 258) | class Classifier:
method __init__ (line 263) | def __init__(self, net_type, loss_type = 'cross_entropy', optimizer = ...
method train (line 283) | def train(self, trX, trY, iterations, full_train = True, train_size = 0):
method predict (line 307) | def predict(self, teX, return_encoded = True):
method close (line 326) | def close(self):
class Regresser (line 334) | class Regresser:
method __init__ (line 339) | def __init__(self, net_type, loss_type = 'l2_loss', optimizer = 'Adam'):
method train (line 359) | def train(self, trX, trY, iterations, full_train = True, train_size = 0):
method predict (line 383) | def predict(self, teX):
method close (line 399) | def close(self):
FILE: pavement.py
function print_passed (line 27) | def print_passed():
function print_failed (line 36) | def print_failed():
class cwd (line 45) | class cwd(object):
method __init__ (line 49) | def __init__(self, newcwd):
method __enter__ (line 55) | def __enter__(self):
method __exit__ (line 60) | def __exit__(self, type_, value, traceback):
function _doc_make (line 67) | def _doc_make(*make_args):
function sdist (line 91) | def sdist():
function test (line 97) | def test():
function lint (line 103) | def lint():
function test_all (line 112) | def test_all():
function run (line 124) | def run(args):
function commit (line 137) | def commit():
function coverage (line 146) | def coverage():
function doc_watch (line 163) | def doc_watch():
function doc_open (line 216) | def doc_open():
function get_tasks (line 235) | def get_tasks():
function doc_html (line 243) | def doc_html():
function doc_clean (line 252) | def doc_clean():
FILE: setup.py
function check_output (line 11) | def check_output(cmd_args, *args, **kwargs):
function get_project_files (line 60) | def get_project_files():
function is_git_project (line 83) | def is_git_project():
function has_git (line 87) | def has_git():
function get_git_project_files (line 91) | def get_git_project_files():
function git_ls_files (line 110) | def git_ls_files(*cmd_args):
function print_success_message (line 122) | def print_success_message(message):
function print_failure_message (line 135) | def print_failure_message(message):
function read (line 149) | def read(filename):
function _lint (line 161) | def _lint():
function _test (line 178) | def _test():
function _test_all (line 191) | def _test_all():
class TestAllCommand (line 205) | class TestAllCommand(TestCommand):
method finalize_options (line 206) | def finalize_options(self):
method run_tests (line 212) | def run_tests(self):
function main (line 279) | def main():
FILE: tests/test_main.py
class TestMain (line 15) | class TestMain(object):
method test_help (line 17) | def test_help(self, helparg, capsys):
method test_version (line 31) | def test_version(self, versionarg, capsys):
Condensed preview — 21 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (97K chars).
[
{
"path": "LICENSE",
"chars": 1150,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Calvin Schmidt\n\nPermission is hereby granted, free of charge, to any person ob"
},
{
"path": "MANIFEST.in",
"chars": 498,
"preview": "# Informational files\ninclude README.rst\ninclude LICENSE\n\n# Include docs and tests. It's unclear whether convention dict"
},
{
"path": "README.rst",
"chars": 15346,
"preview": "=========================\n Easy Tensorflow\n=========================\n\nThis package provides users with methods for the a"
},
{
"path": "docs/Makefile",
"chars": 5606,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS = -W\nSPHINXBUI"
},
{
"path": "docs/make.bat",
"chars": 5139,
"preview": "@ECHO OFF\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset BUI"
},
{
"path": "docs/source/README",
"chars": 180,
"preview": "Run `sphinx-apidoc -o . ../../easy_tensorflow' in this directory.\n\nThis will generate `modules.rst' and `easy_tensorflow"
},
{
"path": "docs/source/_static/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "docs/source/conf.py",
"chars": 8706,
"preview": "# -*- coding: utf-8 -*-\n\n# This file is based upon the file generated by sphinx-quickstart. However,\n# where sphinx-quic"
},
{
"path": "docs/source/index.rst",
"chars": 195,
"preview": "EasyTensorflow\n==============\n\nContents:\n\n.. toctree::\n :maxdepth: 2\n\n\n.. only:: html\n\n Indices and tables\n ======"
},
{
"path": "easy_tensorflow/__init__.py",
"chars": 465,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Provides objects that allow for easy setup, training, and running of neural networks, based o"
},
{
"path": "easy_tensorflow/evolve_functions.py",
"chars": 14289,
"preview": "import numpy as np\nimport scipy.stats\nimport random\nfrom deap import base\nfrom deap import creator\nfrom deap import tool"
},
{
"path": "easy_tensorflow/main.py",
"chars": 1299,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\"\"\"Program entry point\"\"\"\n\nfrom __future__ import print_function\n\nimport a"
},
{
"path": "easy_tensorflow/metadata.py",
"chars": 764,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Project metadata\n\nInformation describing the project.\n\"\"\"\n\n# The package name, which is also "
},
{
"path": "easy_tensorflow/tf_dictionaries.py",
"chars": 1246,
"preview": "import tensorflow as tf\n\ntransform_dict = {\n 'relu': (tf.nn.relu, (tf.nn.bias_add, ((tf.matmul, ('X', 'weight1')), 'w"
},
{
"path": "easy_tensorflow/tf_functions.py",
"chars": 19030,
"preview": "import tensorflow as tf\nimport numpy as np\nimport random\nimport tf_dictionaries\n\ndef random_index_list(list_size, sample"
},
{
"path": "pavement.py",
"chars": 7368,
"preview": "# -*- coding: utf-8 -*-\n\nfrom __future__ import print_function\n\nimport os\nimport sys\nimport time\nimport subprocess\n\n# Im"
},
{
"path": "requirements-dev.txt",
"chars": 337,
"preview": "# Runtime requirements\n--requirement requirements.txt\n\n# Testing\npytest==2.5.1\npy==1.4.19\nmock==1.0.1\n\n# Linting\nflake8="
},
{
"path": "requirements.txt",
"chars": 78,
"preview": "# Python 2.6 compatibility\n# argparse==1.2.1\n\n# Function\ndeap==1.0\ntensorflow\n"
},
{
"path": "setup.py",
"chars": 9001,
"preview": "# -*- coding: utf-8 -*-\nfrom __future__ import print_function\n\nimport os\nimport sys\nimport imp\nimport subprocess\n\n## Pyt"
},
{
"path": "tests/test_main.py",
"chars": 1309,
"preview": "# -*- coding: utf-8 -*-\nfrom pytest import raises\n\n# The parametrize function is generated, so this doesn't work:\n#\n# "
},
{
"path": "tox.ini",
"chars": 656,
"preview": "# Tox (http://tox.testrun.org/) is a tool for running tests in\n# multiple virtualenvs. This configuration file will run "
}
]
About this extraction
This page contains the full source code of the calvinschmdt/EasyTensorflow GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 21 files (90.5 KB), approximately 23.0k tokens, and a symbol index with 64 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.