├── genetics ├── basic │ ├── __init__.py │ ├── ffs.py │ ├── driver.py │ ├── geneticRun.py │ └── geneticAlgorithms.py └── README.md ├── selforganization ├── pso │ ├── __init__.py │ ├── driver.py │ ├── Problems.py │ ├── psoAlgorithm.py │ ├── Particle.py │ └── psoRun.py └── README.md ├── neuralnetworks ├── backpropagation │ ├── __init__.py │ ├── .old │ │ ├── driver.py │ │ ├── validation1.txt │ │ ├── validation2.txt │ │ ├── testing1.txt │ │ ├── face_graphs.py │ │ ├── testing2.txt │ │ ├── training1.txt │ │ └── training2.txt │ ├── analysis.py │ ├── utils.py │ ├── run_tests.py │ ├── tests.py │ └── network.py └── hopfield │ ├── testHisto.py │ └── hopfieldNetwork.py ├── requirements.txt ├── .gitignore └── README.md /genetics/basic/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /selforganization/pso/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /selforganization/pso/driver.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | sklearn 3 | scipy 4 | matplotlib 5 | 6 | -------------------------------------------------------------------------------- /selforganization/README.md: -------------------------------------------------------------------------------- 1 | Self-Organization 2 | ==== 3 | - Author: David Cunningham 4 | - Particle Swarm Optimization 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | neuralnetworks/backpropagation/results/ 3 | genetics/basic/results/ 4 | neuralnetworks/hopfield/results/ 5 | selforganization/pso/results 6 | 7 | -------------------------------------------------------------------------------- /genetics/README.md: -------------------------------------------------------------------------------- 1 | Genetics 2 | ===== 3 | - Basic Genetic Computation Algorithm 4 | - Features: 5 | - "drag-n-drop" fitness functions 6 | - crossover and mutation of genes 7 | - learning ability for offspring of each generation 8 | -------------------------------------------------------------------------------- /selforganization/pso/Problems.py: -------------------------------------------------------------------------------- 1 | import math 2 | def mdist(maxX, maxY): 3 | return math.sqrt(maxX**2 + maxY**2/2) 4 | def pdist(px, py): 5 | return math.sqrt((px-20)**2 + (py-7)**2) 6 | def ndist(px, py): 7 | return math.sqrt((px+20)**2 + (py+7)**2) 8 | def Problem1(pos, maxes): 9 | return 100*(1-pdist(pos[0], pos[1])/mdist(maxes[0], maxes[1])) 10 | def Problem2(pos, maxes): 11 | pd = pdist(pos[0], pos[1]) 12 | nd = ndist(pos[0], pos[1]) 13 | md = mdist(maxes[0], maxes[1]) 14 | 15 | ret = 9*max(0, 10-pd**2) 16 | ret+=10*(1-pd/md) 17 | ret+=70*(1-nd/md) 18 | return ret -------------------------------------------------------------------------------- /genetics/basic/ffs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | ############################################################## 4 | # ffs.py, fitness functions to be used in 5 | # genetic_algorithms.py 6 | # 7 | # Written by Jared Smith for COSC 427/527 8 | # at the University of Tennessee, Knoxville. 9 | ############################################################### 10 | 11 | 12 | def fitness_func_1(bit_sum, l): 13 | return (pow(((bit_sum *1.0)/ pow(2.0, l)), 10)) 14 | 15 | 16 | def fitness_func_2(bit_sum, l): 17 | return (pow(((1.0 - bit_sum) / pow(2.0, l)), 10)) 18 | -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/.old/driver.py: -------------------------------------------------------------------------------- 1 | # run multiple.py 2 | import os 3 | 4 | 5 | def recursive_run(hidden_layers, learning_rate, exp, tests): 6 | if len(hidden_layers) == 11: 7 | return 0 8 | hlstr = "" 9 | for i in hidden_layers: 10 | hlstr += str(i) + " " 11 | for test in tests: 12 | if test == 'f': 13 | os.system("python run_tests.py -exp " +str(exp) + " -ttype " + test + " -hidden_layers " + hlstr + " --learning_rate " + str(learning_rate) + ' --ftrain training1.txt --ftest testing1.txt --fvalid validation1.txt') 14 | exp += 1 15 | os.system("python run_tests.py -exp " +str(exp) + " -ttype " + test + " -hidden_layers " + hlstr + " --learning_rate " + str(learning_rate) + ' --ftrain training2.txt --ftest testing2.txt --fvalid validation2.txt') 16 | exp += 1 17 | else: 18 | os.system("python run_tests.py -exp " +str(exp) + " -ttype " + test + " -hidden_layers " + hlstr + " --learning_rate " + str(learning_rate)) 19 | learning_rate += .1 20 | 21 | if learning_rate == 1: 22 | learning_rate = .1 23 | if hidden_layers[len(hidden_layers)-1] == 100: 24 | for i in hidden_layers: 25 | i = 1 26 | hidden_layers.append(0) 27 | hidden_layers[len(hidden_layers)-1] += 1 28 | if recursive_run(hidden_layers, learning_rate, exp, tests) == 0: 29 | return 0 30 | else: 31 | return 1 32 | 33 | recursive_run([1], .1,0, ['x', 'i', 'd', 'f']) 34 | -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/.old/validation1.txt: -------------------------------------------------------------------------------- 1 | 0.003277 0.848481 0.500607 2 | -1.427406 1.964000 0.890860 3 | -1.391789 0.537382 0.228752 4 | -0.125430 0.683673 0.453343 5 | -1.507577 0.876596 0.432709 6 | -1.569817 -1.731977 0.785425 7 | -0.381805 -1.786936 0.766554 8 | 1.127473 0.462658 0.866206 9 | -0.065526 1.733933 0.546951 10 | 0.719028 -1.218122 0.348117 11 | 1.898024 0.785155 0.526406 12 | 1.041945 1.357749 0.234160 13 | 1.489717 1.965961 0.141295 14 | -0.255205 -0.159470 0.310978 15 | -0.417612 0.332953 0.235798 16 | -0.370680 0.763136 0.400042 17 | 0.026609 -1.618669 0.482745 18 | 1.324651 1.508803 0.187194 19 | 1.590378 -0.556722 0.692398 20 | -0.859758 -1.837694 0.972145 21 | -1.441049 -1.939670 0.883005 22 | 0.826141 1.102275 0.422983 23 | -0.942669 0.591992 0.202254 24 | -0.174097 -1.663213 0.616578 25 | -0.721853 -0.080824 0.050615 26 | 1.606988 1.548495 0.280356 27 | 0.203851 -0.424896 0.623611 28 | -0.986222 -1.100245 0.578388 29 | 0.286364 -1.509866 0.343910 30 | 1.292883 -0.369624 0.874598 31 | -0.918720 0.189327 0.025839 32 | -0.345168 -0.984532 0.493732 33 | -0.413866 0.072799 0.199344 34 | -0.516604 1.898701 0.858072 35 | 1.221189 -0.823151 0.628925 36 | 1.291934 -1.216164 0.350675 37 | 0.125816 0.987687 0.501899 38 | -0.658971 -1.998535 0.929958 39 | -1.934955 0.287829 0.454126 40 | -1.767661 -0.419288 0.358870 41 | -1.438061 0.661992 0.304436 42 | -1.048132 -1.683175 0.938094 43 | -1.555927 -0.097041 0.182553 44 | 0.528270 1.386355 0.289613 45 | -1.050745 0.607544 0.211839 46 | -0.710586 -0.100522 0.056373 47 | -0.821931 -1.974705 0.980188 48 | 0.641828 -0.633677 0.730154 49 | -0.994657 -0.568632 0.186552 50 | 1.858991 -0.336293 0.594873 51 | -------------------------------------------------------------------------------- /neuralnetworks/hopfield/testHisto.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | 6 | def normalize_data (data, scale): #Normalization function 7 | arr = np.copy(data) 8 | np_minmax = ((arr - arr.min()) / (arr.max() - arr.min())) * scale 9 | return np_minmax 10 | 11 | def plot_histogram(avg_basin_size): 12 | 13 | (num_rows, num_cols) = avg_basin_size.shape 14 | avg_basin_size[:][:] += 1 15 | #bins = np.arange(0, num_cols) 16 | 17 | fig = plt.figure() 18 | # Histogram normalized to 1 19 | plt.subplot(2, 1, 1) 20 | for i in range(1, num_rows + 1): 21 | if i % 2 == 0: 22 | label = 'p = %s' % str(i + 1) 23 | plt.hist(avg_basin_size[i - 1][:], num_cols, normed=True, alpha=0.5) 24 | plt.xlabel('B') 25 | plt.ylabel('Value') 26 | plt.title('Probability Distribution of Basin Sizes Normalized to 1') 27 | #plt.legend(loc=9, bbox_to_anchor=(0.5, -0.1), ncol=10) 28 | plt.grid() 29 | 30 | # Histogram normalized to p 31 | plt.subplot(2, 1, 2) 32 | for i in range(1, num_rows + 1): 33 | if i % 2 == 0: 34 | label = 'p = %s' % str(i + 1) 35 | plt.hist(avg_basin_size[i - 1][:], num_cols, normed=True, alpha=0.5) 36 | plt.xlabel('B') 37 | plt.ylabel('Value') 38 | plt.title('Probability Distribution of Basin Sizes Normalized to P') 39 | plt.grid() 40 | #plt.legend(loc=9, bbox_to_anchor=(0.5, -0.1), ncol=10) 41 | 42 | # Save the figure 43 | fig.tight_layout() 44 | fig.savefig('histo_file.jpg') 45 | 46 | if __name__ == '__main__': 47 | 48 | histo_file = sys.argv[1] 49 | 50 | # try to load the 2D array fromt he file 51 | # since it is the only structure in the file accessing all of the 52 | # possible file structures should give us just that array 53 | histo_data = np.load(histo_file) 54 | plot_histogram(histo_data) 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /genetics/basic/driver.py: -------------------------------------------------------------------------------- 1 | #driver.py 2 | import os 3 | 4 | def run(exp=0, l=20, N=30, G=10, pm=.033, pc=.6, NG=20): 5 | string = 'python .\geneticRun.py'\ 6 | + ' -exp ' + str(exp) \ 7 | + ' --num_bits '+ str(l) \ 8 | + ' --population_size ' + str(N)\ 9 | + ' --num_gens ' + str(G)\ 10 | + ' --pr_mutation ' + str(pm)\ 11 | + ' --pr_crossover ' + str(pc)\ 12 | + ' --num_learning_guesses ' + str(NG) 13 | print "DRIVER: %s" % string 14 | os.system(string) 15 | def learn(exp=0, l=20, N=30, G=10, pm=.033, pc=.6, learn=True, NG=20): 16 | string = 'python .\geneticRun.py'\ 17 | + ' -exp ' + str(exp) \ 18 | + ' --num_bits '+ str(l) \ 19 | + ' --population_size ' + str(N)\ 20 | + ' --num_gens ' + str(G)\ 21 | + ' --pr_mutation ' + str(pm)\ 22 | + ' --pr_crossover ' + str(pc)\ 23 | + ' --learn_offspring ' + str(learn)\ 24 | + ' --num_learning_guesses ' + str(NG) 25 | print "DRIVER: %s" % string; 26 | os.system(string) 27 | def CE(exp=0, l=20, N=30, G=10, pm=.033, pc=.6, learn=False, CE=True, NG=20, nruns=1, seed=123456): 28 | string = 'python .\geneticRun.py'\ 29 | + ' -exp ' + str(exp) \ 30 | + ' --num_bits '+ str(l) \ 31 | + ' --population_size ' + str(N)\ 32 | + ' --num_gens ' + str(G)\ 33 | + ' --pr_mutation ' + str(pm)\ 34 | + ' --pr_crossover ' + str(pc)\ 35 | + ' --learn_offspring ' + str(learn)\ 36 | + ' --change_environment ' + str(CE)\ 37 | + ' --num_learning_guesses ' + str(NG) 38 | print "DRIVER: %s" % string; 39 | os.system(string) 40 | 41 | exp = 0; 42 | pm = .033; 43 | N = 30 44 | print "DRIVER: EVALUATING POPULATION SIZE AND MUTATION PROBABILITY" 45 | run(exp = exp, N = N, pm = 1/N) 46 | 47 | while (N < 150): 48 | run(exp = exp, N = N, pm = 1/N) 49 | N+=10 50 | exp+=1 51 | print "DRIVER: EVALUATING CROSSOVER PROBABLITY" 52 | pc = .3 53 | while (pc < 1): 54 | run(exp = exp, pc = pc) 55 | pc +=.1 56 | exp+=1 57 | print "DRIVER: EVALUATING NUMBER OF GENERATIONS" 58 | G=30 59 | while (G <= 150): 60 | run(exp = exp, G = G); 61 | G+=10 62 | exp+=1 -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/.old/validation2.txt: -------------------------------------------------------------------------------- 1 | -1.387994 -1.695247 -0.606290 0.464565 2 | -1.119965 0.701889 0.866822 0.225974 3 | -0.764356 0.099740 -0.951961 0.120460 4 | 0.543036 0.589841 1.460780 0.183896 5 | -0.384500 0.561116 0.841566 0.082137 6 | -1.656176 -1.296764 0.746974 0.478035 7 | 1.854343 1.946642 1.772868 0.869584 8 | -0.158587 0.212779 1.813929 0.196212 9 | -0.253496 -0.620826 0.800135 0.073998 10 | -1.322347 0.106878 -0.197858 0.204899 11 | 1.346941 0.718884 0.106895 0.249749 12 | -1.259348 1.598919 -1.191216 0.461517 13 | 1.607474 -1.165437 0.908524 0.450251 14 | -1.344488 1.377599 -0.501635 0.369075 15 | -1.883708 -1.006901 -1.940519 0.704661 16 | 0.957858 -0.663077 -1.237284 0.228005 17 | -0.295168 -0.808734 -1.290642 0.156466 18 | -0.522300 1.032679 0.922137 0.162567 19 | -0.708371 -1.220817 -1.698689 0.339018 20 | -1.908236 -0.543164 0.408189 0.452464 21 | -0.106094 -1.196223 -0.872928 0.155333 22 | -1.999199 -0.455571 -1.274009 0.570774 23 | -1.190415 -0.848097 -0.439446 0.229980 24 | 1.718109 -0.192585 -1.061846 0.408506 25 | -0.783526 -0.076292 -0.068747 0.071556 26 | -0.724045 -1.118434 1.268176 0.249497 27 | 0.038671 0.586398 -1.540557 0.163546 28 | 0.748030 -1.935902 1.492122 0.481297 29 | -0.329833 -0.644273 -1.728695 0.216890 30 | -0.028523 -0.552509 -0.271859 0.027840 31 | -1.620334 1.341397 0.531918 0.457675 32 | -0.493262 1.342198 -1.923653 0.380137 33 | 0.232729 -1.848217 -0.771750 0.303373 34 | 1.793284 1.869892 1.035665 0.701904 35 | -1.268562 -0.913634 -1.040627 0.312368 36 | 0.662691 0.362321 -0.159061 0.062230 37 | -0.069132 -1.599007 -1.572663 0.339919 38 | 0.390310 1.149022 -1.508566 0.250430 39 | -0.117568 -1.180811 -0.152839 0.110198 40 | 0.153737 0.790666 1.294652 0.147515 41 | 1.881878 1.170332 0.636049 0.537330 42 | 0.413795 -1.322930 -0.021753 0.154411 43 | 0.490142 0.909799 0.130030 0.092367 44 | 1.718392 0.703083 -0.000078 0.378741 45 | 0.754057 1.434521 1.086288 0.291982 46 | 1.713430 0.097212 -0.551391 0.357018 47 | -0.445631 -1.971920 -0.150398 0.323332 48 | -0.018295 0.418390 -1.001375 0.071355 49 | 0.473139 -1.699178 -0.182186 0.249838 50 | -1.679700 0.454559 -1.391520 0.453151 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BioPy 2 | 3 | ####Overview: 4 | ---- 5 | BioPy is a collection (in-progress) of biologically-inspired algorithms written in Python. Some of the algorithms included are more focused on artificial model's of biological computation, such as Hopfield Neural Networks, while others are inherently more biologically-focused, such as the basic genetic programming module included in this project. Use it for whatever you like, and please contribute back to the project by cleaning up code that is here or contributing new code for 6 | applications in biology that you may find interesting to program. 7 | 8 | NOTE: The code is currently messy in some places. If you want to make a Pull Request by tidying up the code, that would certainly be merged. Since most of this was written while in the middle of our (jaredmichaelsmith and davpcunn) Graduate Bio-Inspired computation course, there are some places where the code has diverged into a dark chasm of non-pythonic mess, despite the algorithms still performing very well. Contributions in this area are much appreciated! 9 | 10 | ####Dependencies: 11 | ---- 12 | - NumPy 13 | - SciPy 14 | - Scikit-Learn 15 | - Matplotlib 16 | 17 | ####Categories 18 | ---- 19 | Below you will find several categories of applications in this project. 20 | 21 | #####Neural Networks: 22 | ---- 23 | - Hopfield Neural Network 24 | - Back Propagation Neural Network 25 | - Tests included: 26 | - XOR 27 | - Two Function Approximations 28 | - MNIST Handwritten Digits Recognition Test 29 | - From scikit-learn package 30 | - Fisher's Iris data set: http://en.wikipedia.org/wiki/Iris_flower_data_set 31 | - From scikit-learn package 32 | - Labelled Faces in the Wild Dataset: http://vis-www.cs.umass.edu/lfw/ 33 | - From scikit-learn package, originally collected by the University of Mass. Amherst 34 | 35 | #####Genetic Programming: 36 | ---- 37 | - Basic Genetic Computation Algorithm 38 | - Features: 39 | - "drag-n-drop" fitness functions 40 | - crossover and mutation of genes 41 | - learning ability for offspring of each generation 42 | 43 | #####Self-Organization and Autonomous Agents 44 | ---- 45 | - Particle Swarm Optimization 46 | - Features: 47 | - You can configure many of the parameters of the algorithm such as the velocity, acceleration, and number of initial particles, as well as several other parameters. 48 | 49 | -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/.old/testing1.txt: -------------------------------------------------------------------------------- 1 | -0.894011 1.105065 0.581007 2 | -1.439937 -1.574976 0.802565 3 | -0.345833 -0.373237 0.284707 4 | -0.209296 1.142366 0.535801 5 | -1.800757 -0.076113 0.347155 6 | -1.720433 0.716976 0.408574 7 | 0.926664 -1.108691 0.415612 8 | -1.888890 1.897929 0.585711 9 | -1.466422 -1.498806 0.762339 10 | 1.159332 1.648505 0.087558 11 | 1.873561 -1.245506 0.462891 12 | -0.293485 -0.685443 0.394517 13 | 0.689814 0.968724 0.521697 14 | 0.238872 -1.240571 0.432393 15 | 0.388073 -1.041329 0.481430 16 | -0.785712 -0.761762 0.327482 17 | -1.154504 -1.835098 0.969156 18 | 0.829942 -1.723989 0.062355 19 | -1.810994 -1.190410 0.543101 20 | -1.276121 1.968922 0.953162 21 | 1.099121 1.842483 0.021091 22 | -1.420573 -0.451002 0.200194 23 | 0.484757 -1.761188 0.179003 24 | 0.016850 0.477684 0.509679 25 | -1.308691 -1.134243 0.592590 26 | -0.710343 0.080045 0.054413 27 | -1.395020 0.925541 0.452529 28 | -1.188388 -0.244517 0.056578 29 | -1.083827 -0.055511 0.006211 30 | -0.478072 0.668368 0.330206 31 | -0.223811 -0.232511 0.339175 32 | 0.784943 0.346916 0.903415 33 | -0.891745 -1.168328 0.628784 34 | 0.400291 0.848522 0.569315 35 | -1.548245 1.539832 0.744308 36 | 1.461891 -1.170512 0.401003 37 | 1.710265 -0.565532 0.638619 38 | -1.876460 0.246080 0.410693 39 | -1.187173 1.162253 0.620648 40 | 0.311704 -1.315819 0.388073 41 | 1.779503 0.460370 0.627257 42 | -0.910216 -0.754686 0.313929 43 | 1.949063 0.353569 0.533958 44 | 1.047154 -1.246141 0.311980 45 | -1.377071 -0.794386 0.368336 46 | 1.064461 -1.332495 0.251849 47 | 1.586038 -1.622230 0.249054 48 | 1.033156 -1.498690 0.147654 49 | -1.764242 -0.685863 0.414285 50 | 1.382848 1.625841 0.156900 51 | -0.801693 1.405344 0.782971 52 | -1.218746 -1.504872 0.835424 53 | 0.711118 -1.555809 0.155626 54 | -0.527347 1.491345 0.756939 55 | 1.082711 -1.885725 0.012180 56 | -1.767399 1.178736 0.549500 57 | 0.211979 0.764774 0.559021 58 | -0.374174 -0.202070 0.236604 59 | 1.285752 0.033688 0.949841 60 | -1.892069 -0.583464 0.448656 61 | -0.385709 0.614842 0.338050 62 | -0.418979 1.396097 0.678235 63 | 0.793065 0.107214 0.967113 64 | 0.358678 1.579868 0.289035 65 | 0.678150 0.662579 0.721154 66 | -1.796763 0.895180 0.474279 67 | 0.395828 -0.892840 0.548792 68 | -1.033810 0.732985 0.296669 69 | -1.962138 0.018737 0.470292 70 | -1.576329 0.126668 0.197363 71 | -1.564678 1.740958 0.790083 72 | 1.852317 -0.678020 0.555692 73 | 1.764440 -1.884955 0.322128 74 | -1.879247 0.473723 0.430645 75 | 1.968412 -0.848127 0.505860 76 | 1.930345 -0.644890 0.528901 77 | 1.071014 1.750938 0.040652 78 | -1.023543 -1.282872 0.714781 79 | -1.320171 -1.245010 0.664471 80 | 0.416889 -0.821338 0.584343 81 | -0.429515 -0.386016 0.243353 82 | 1.338923 -0.533699 0.788079 83 | -1.496542 -0.769259 0.373963 84 | 1.775207 -0.648505 0.590690 85 | 0.626824 -0.680093 0.700611 86 | -1.858980 -0.749748 0.457920 87 | -1.449604 -1.678734 0.832986 88 | 0.066931 -0.702277 0.523654 89 | 0.316452 -0.022448 0.738283 90 | -1.415290 -1.605559 0.823477 91 | -1.020365 -0.035074 0.001014 92 | -0.884481 -0.696151 0.274086 93 | 0.573382 -0.192693 0.874056 94 | -1.853709 -0.417486 0.409735 95 | -1.807077 -1.790662 0.641219 96 | -0.608573 -1.649642 0.848122 97 | 1.945042 -1.099247 0.493306 98 | 0.249594 0.967685 0.509694 99 | -0.728726 -0.715864 0.303475 100 | -0.952055 -0.131154 0.011961 101 | -------------------------------------------------------------------------------- /selforganization/pso/psoAlgorithm.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | from Problems import * 4 | from Particle import * 5 | class PSO(object): 6 | '''Particle Swarm Optimization: 7 | Fields: 8 | inertia: the inertia of the world 9 | inertiaPrime: rate of change of a the inertia (a percentage) 10 | npart: number of particles in the world 11 | phi: The parameters of the world. Conscious, social and a potential 3rd neigborhood parameter 12 | dimensions: an array of n elements each representing the range for a dimension in the world 13 | maxvelocity: the maximum possible velocity of a particle in the world 14 | Q: Fitness function of the swarm 15 | swarm: the swarm of particles 16 | Fuctions: 17 | Update: moves all particles swarms to the next epoch 18 | setClosestNeighbors: for each particle sets as neighbors the k closest particles to it 19 | setEuclidianNeigbhbors: for each particle sets its neighbors as all particles within range 20 | getError: returns the error for the given orientation. 21 | ''' 22 | def __init__(self, npart = 40, inertia=.5, phi = (2, 2, 2), dimensions = (100, 100), maxvelocity=1, Q = Problem1, inertiaPrime = 1): 23 | self._inertia = inertia 24 | self.phi = phi 25 | self.globalBestFitness = 0 26 | self.maxvelocity = 1 27 | self.globalBest = None 28 | self.Q = Q 29 | self.inertiaPrime = inertiaPrime 30 | self.swarm = [] 31 | #Create and initialize the swarm 32 | for i in range(npart): 33 | pos = np.zeros(len(dimensions)) 34 | for j in range(len(dimensions)): 35 | pos[j] = random.randint(-1 * dimensions[j]/2, dimensions[j]/2) 36 | particle = Particle(pos, dimensions) 37 | fitness = particle.updateFitness(Q) 38 | if fitness > self.globalBestFitness or self.globalBestFitness == 0: 39 | self.globalBestFitness = fitness 40 | self.globalBest = particle.pos 41 | self.swarm.append(particle) 42 | def setClosestNeighbors(self, k): 43 | if k > 0: 44 | for i in self.swarm: 45 | #sort neighobrs into a stack 46 | sortedSwarm = sorted(self.swarm, key = (lambda other: i.getDistance(other.pos)), reverse = True) 47 | #the closest k particles that are not the target are its neighbors 48 | while len(i.neighborhood) < k: 49 | neighbor = sortedSwarm.pop() 50 | if i != neighbor: 51 | i.neighborhood.append(neighbor) 52 | print i.neighborhood 53 | #neighborhood is all particles within a certain range 54 | def setEuclidianNeigbors(self, radius): 55 | if radius > 0: 56 | for i in self.swarm: 57 | i.neighborhood = filter(lambda other: i != other and i.getDistance(other.pos) < radius, self.swarm) 58 | print i.neighborhood 59 | #updates the positions of all particles 60 | def Update(self): 61 | #update everybody's position 62 | for i in self.swarm: 63 | i.setVelocity(self._inertia, self.globalBest, self.phi) 64 | i.scaleVelocity(self.maxvelocity) 65 | i.Move() 66 | #Update everybody's fitness 67 | for i in self.swarm: 68 | i.updateFitness(self.Q) 69 | if i.bestFitness > self.globalBestFitness: 70 | self.globalBestFitness = i.bestFitness 71 | self.globalBest = i.best 72 | #degreade inertia 73 | self._inertia *= self.inertiaPrime 74 | #return the error of the swarm at the given orientation 75 | def getError(self): 76 | error = np.zeros(len(self.swarm[0].pos)); 77 | for i in self.swarm: 78 | error += (i.pos - self.globalBest)**2 79 | error = (1.0/(2*len(self.swarm))*error)**(.5) 80 | return error 81 | -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/.old/face_graphs.py: -------------------------------------------------------------------------------- 1 | from sklearn.datasets import load_iris, load_digits, fetch_lfw_people, fetch_lfw_pairs 2 | from sklearn.decomposition import RandomizedPCA 3 | from sklearn.cross_validation import train_test_split as sklearn_train_test_split 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | 7 | 8 | def plot_learning_rates_versus_epochs(num_image, autoscale, learning_rates, plot_file_path=None): 9 | x1 = np.arange(len(learning_rates)) 10 | y1 = learning_rates 11 | 12 | fig = plt.figure() 13 | subplt = plt.subplot(111) 14 | plt.plot(x1, y1) 15 | plt.xlabel('Epochs') 16 | plt.ylabel('Learning Rate') 17 | plt.title('Learning Rate Per Epoch Over %s Epochs' % str(len(x1))) 18 | plt.grid() 19 | if autoscale: 20 | subplt.autoscale_view(True,True,True) 21 | fig.tight_layout() 22 | 23 | plt.show() 24 | 25 | if plot_file_path is None: 26 | plot_file_name = "learning_rates-faces-%s.pdf" % (str(num_image)) 27 | else: 28 | plot_file_name = "%s/learning_rates-faces-%s.pdf" % (plot_file_path, str(num_image)) 29 | 30 | plt.savefig(plot_file_name, bbox_inches='tight') 31 | 32 | 33 | def plot_gallery(num_image, images, titles, h, w, n_row=3, n_col=4, plot_file_path=None): 34 | """Helper function to plot a gallery of portraits""" 35 | plt.figure(figsize=(1.8 * n_col, 2.4 * n_row)) 36 | plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35) 37 | for i in range(n_row * n_col): 38 | plt.subplot(n_row, n_col, i + 1) 39 | plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray) 40 | plt.title(titles[i], size=12) 41 | plt.xticks(()) 42 | plt.yticks(()) 43 | 44 | if plot_file_path is None: 45 | plot_file_name = "gallery-image-%s.pdf" % (num_image) 46 | else: 47 | plot_file_name = "%s/gallery-image-%s.pdf" % (plot_file_path, num_image) 48 | 49 | plt.savefig(plot_file_name, bbox_inches='tight') 50 | 51 | def title(y_pred, y_test, target_names, i): 52 | pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1] 53 | true_name = target_names[y_test[i]].rsplit(' ', 1)[-1] 54 | return 'predicted: %s\ntrue: %s' % (pred_name, true_name) 55 | 56 | 57 | lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4) 58 | 59 | # introspect the images arrays to find the shapes (for plotting) 60 | n_samples, h, w = lfw_people.images.shape 61 | 62 | # for machine learning we use the 2 data directly (as relative pixel 63 | # positions info is ignored by this model) 64 | X = lfw_people.data 65 | n_features = X.shape[1] 66 | 67 | # the label to predict is the id of the person 68 | y = lfw_people.target 69 | # y = self.translate_to_binary_array(y) 70 | 71 | target_names = lfw_people.target_names 72 | n_classes = target_names.shape[0] 73 | 74 | # split into a training and testing set 75 | X_train, X_test, y_train, y_test = sklearn_train_test_split( 76 | X, y, test_size=0.25) 77 | 78 | y_pred = None 79 | y_test = None 80 | with np.load('target-predicted-info-file-npz-exp-1.npz') as data: 81 | y_pred = data['arr_1'] 82 | y_test = data['arr_0'] 83 | 84 | learning_rates = None 85 | with np.load('learning-rates-info-file-npz-exp-1.npz') as data: 86 | learning_rates = data['arr_0'] 87 | 88 | plot_learning_rates_versus_epochs(1, False, learning_rates) 89 | 90 | 91 | prediction_titles = [title(y_pred, y_test, target_names, i) 92 | for i in range(y_pred.shape[0])] 93 | 94 | plot_gallery(1, X_test, prediction_titles, h, w) 95 | -------------------------------------------------------------------------------- /selforganization/pso/Particle.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | from Problems import * 4 | 5 | class Particle(object): 6 | '''Particle 7 | A representation of a particle in the PSO. 8 | Fields: 9 | pos: The position of the particle in the world array, represented as an array. 10 | The particles actual xyz... cordinate is equal to: pos - maxPos/2 11 | best: The position visited by this particle that has the best fitness 12 | curFitness: the fitness of the particle at its current position 13 | bestFitness: the best fitness of any position the particle has traveled to. 14 | In other words, the fitness coresponding to the "best" position field. 15 | Q: The fitness equation of the particle. Takes the pos and the max position 16 | velocity: a vector that represents the current velocity and direction of the particle 17 | maxPos: array of he maximum possible position of the particle in any dimension i. 18 | neighbors: a list of other particles considered "neighbors" to the given particle 19 | 20 | Functions: 21 | setVelocity: 22 | parameters: inertia, globalBest, phi 23 | Description: determines the velocity of the particle 24 | scaleVelocity: 25 | parameters: maxvelocity 26 | Description: rescales the particle velocity so that it does not 27 | exceed the global maxvelocity or exit the world range 28 | Move: 29 | parameters: none 30 | Description: updates the particles position according to its curent velocity 31 | updateFitness: 32 | parameters: Fitness 33 | Description: caclulates the fitness of the particle at its current position 34 | updates bestFitness and best fields if necessary 35 | getDistance: 36 | parameters: position s 37 | Description: Finds the distance between particle and point at position s 38 | ''' 39 | #initializes the paritcle 40 | def __init__(self, pos = [0, 0], maxPos = [100, 100]): 41 | self.pos = pos 42 | self.best = pos 43 | self.curFitness = 0 44 | self.bestFitness = 0 45 | self.velocity = np.zeros(len(pos)) 46 | self.maxPos = np.array(maxPos) 47 | self.neighborhood = [] 48 | #sets the velocity of the particle accoriing to its topology 49 | def setVelocity(self, inertia, globalBest, phi): 50 | #get best neighbor 51 | best_neighbor = self 52 | for i in self.neighborhood: 53 | if best_neighbor.curFitness < i.curFitness: 54 | best_neighbor = i 55 | for i in range(len(self.pos)): 56 | self.velocity[i] = inertia * self.velocity[i] 57 | self.velocity[i] += phi[0] * random.random() * (self.best[i] - self.pos[i]) 58 | self.velocity[i] += phi[1] * random.random() * (globalBest[i]-self.pos[i]) 59 | self.velocity[i] += phi[2] * random.random() * (best_neighbor.pos[i] - self.pos[i]) 60 | #scales the velocity to the global maxixmum velocity 61 | def scaleVelocity(self, maxvelocity): 62 | change_distance = 0 63 | for i in self.velocity: #compute sum of velocities in all dimensions velocities 64 | change_distance+=i**2 65 | change_distance = change_distance**(1.0/2) *1.0 66 | for i in range(len(self.pos)): #find velocity for ith dimension 67 | if abs(self.velocity[i]) > maxvelocity**2: 68 | self.velocity[i] *= (maxvelocity/change_distance) 69 | #adjusts the position of the swarm based on its current velocity 70 | def Move(self): 71 | for i in range(len(self.pos)): 72 | self.pos[i] = (self.pos[i] + self.velocity[i]) 73 | #evaluate and update fitness of particle 74 | def updateFitness(self, Q): 75 | #Find fitness at the current position, scaled to the range of the map 76 | self.curFitness = Q(self.pos, self.maxPos) 77 | if self.curFitness > self.bestFitness: 78 | self.bestFitness = self.curFitness 79 | #get distance between particle and position s (Wraps around) 80 | def getDistance(self, s): 81 | x = self.pos - s 82 | x = np.minimum(x, (self.maxPos)-x) 83 | return sum((x)**2)**.5 84 | -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/.old/testing2.txt: -------------------------------------------------------------------------------- 1 | 0.368665 -1.973397 -1.165540 0.393618 2 | 1.084376 1.366979 -0.535144 0.295940 3 | -0.163830 1.300969 -0.067870 0.133557 4 | -1.795341 -0.268578 0.280955 0.382016 5 | -0.114046 -1.131826 1.239461 0.188672 6 | -0.944945 -1.559992 -1.378464 0.399852 7 | 0.008773 -1.788264 0.468387 0.258657 8 | -1.413550 -0.192703 -1.109531 0.304432 9 | 0.441451 0.980665 -1.119144 0.168722 10 | 0.234062 -0.731869 -1.499174 0.177189 11 | -0.679303 1.636796 -1.472570 0.384433 12 | 0.155157 0.721172 1.894409 0.249830 13 | 1.620013 -1.442658 1.195378 0.545355 14 | -0.447857 -1.237999 -1.073200 0.207487 15 | 1.833097 0.647955 -0.205026 0.422442 16 | 1.072558 1.703010 0.234983 0.359018 17 | 1.694095 -0.288217 0.446719 0.349052 18 | 0.162482 0.298233 -1.745984 0.185761 19 | 1.052951 -1.260316 1.234682 0.338060 20 | 1.933806 0.973746 -1.497187 0.633751 21 | -1.565367 -1.705557 -1.860391 0.706175 22 | -1.037938 0.449600 0.860781 0.182601 23 | -1.143528 0.069612 1.418123 0.267280 24 | -1.948150 1.621755 -1.819877 0.831307 25 | -1.021350 1.454852 0.828078 0.322740 26 | 0.773624 0.527410 0.531088 0.106726 27 | -0.991393 0.221505 -1.757128 0.295306 28 | 1.455326 -1.616014 0.541105 0.462158 29 | 1.709342 1.436937 1.280789 0.590606 30 | 0.944024 1.370743 0.254535 0.251100 31 | 1.446836 1.805376 0.548978 0.509648 32 | 1.586445 -1.232562 -1.001422 0.465120 33 | 0.447226 -0.376090 1.068190 0.099787 34 | -0.134652 -0.324240 0.689944 0.037642 35 | 0.045472 0.654409 0.144796 0.034391 36 | -1.126450 -0.571967 -1.327794 0.273289 37 | 1.404639 0.436640 0.893711 0.288401 38 | 1.647511 -0.108034 1.277697 0.408268 39 | 0.188616 -0.398691 0.714634 0.045796 40 | -0.530595 -1.454668 0.085377 0.195679 41 | 1.723940 1.992169 -0.109247 0.648895 42 | 0.272918 1.578614 0.658192 0.225282 43 | 1.271495 0.025840 -1.717898 0.356854 44 | 0.339685 1.891188 -0.042139 0.288539 45 | -0.970371 -0.063340 -1.387730 0.220061 46 | 1.174425 0.810210 0.040304 0.209736 47 | 1.846631 0.214849 -1.523056 0.530846 48 | 0.740342 -0.137640 0.368911 0.072552 49 | 0.018039 -1.949025 1.970219 0.516193 50 | -1.267327 -0.479620 -1.484448 0.330146 51 | 0.818050 -0.755681 -1.492280 0.249618 52 | -1.291197 1.517237 -1.913666 0.580721 53 | 1.366995 0.788732 0.112174 0.264196 54 | 1.649096 -0.871583 0.003362 0.372227 55 | -0.393042 0.158046 1.940022 0.236882 56 | 0.219228 -0.667529 0.750232 0.072294 57 | -1.740468 -0.820898 -1.034919 0.463155 58 | -1.263524 1.919444 0.827441 0.507115 59 | 1.105387 -0.062517 0.878416 0.185803 60 | 1.075606 0.670155 -1.601204 0.315953 61 | 1.591158 -0.511794 -0.356885 0.319626 62 | -1.901122 0.197009 -0.839648 0.460690 63 | -1.814787 -0.435996 1.949084 0.613805 64 | 0.297387 -0.786900 -0.922499 0.106933 65 | -1.699252 0.820058 1.235547 0.472970 66 | -1.759230 -0.960714 -1.431983 0.546403 67 | 0.991002 -0.701182 -0.252881 0.154827 68 | 1.956083 0.035294 -0.333437 0.448002 69 | 0.783524 -0.859319 1.604046 0.276078 70 | -0.338060 -1.783713 0.274201 0.262265 71 | 0.060736 1.807445 1.762407 0.430919 72 | 1.703851 1.906324 -0.040584 0.614613 73 | -1.135796 -1.908463 1.523419 0.562914 74 | -1.186712 0.388923 -1.263480 0.266229 75 | -0.109211 0.689671 1.556578 0.177749 76 | -0.873664 0.930442 -1.404136 0.268412 77 | -0.305647 -0.078556 -0.105318 0.011894 78 | 1.441473 -0.122473 1.929976 0.455798 79 | -0.891964 -1.338948 -0.929343 0.279534 80 | -1.287918 0.322992 -0.713055 0.228751 81 | 0.986283 -1.616272 -0.905610 0.360505 82 | 0.748689 -1.912421 -0.999286 0.403622 83 | -1.291895 -1.048217 -0.907749 0.324635 84 | -1.768475 -0.234929 1.481174 0.491681 85 | -1.031955 1.655860 0.170845 0.335474 86 | -1.475378 -1.217804 -0.898713 0.411840 87 | -0.879514 0.476549 1.022731 0.167069 88 | 1.015168 -0.081978 -1.099742 0.189203 89 | 0.945144 1.026058 -0.438690 0.195160 90 | -1.984199 1.738139 1.884301 0.891511 91 | -0.697254 0.724422 -1.731971 0.269525 92 | 0.397136 -0.526888 -1.644391 0.195554 93 | 1.397851 0.181217 -0.692608 0.255661 94 | -1.509899 0.412741 1.072464 0.342514 95 | 1.971275 1.380786 0.728324 0.625638 96 | 0.142120 1.905408 1.510520 0.413241 97 | 1.243406 -0.974106 -0.012931 0.251392 98 | 0.266137 -1.958938 1.905091 0.512747 99 | 1.166395 0.986206 0.931149 0.281815 100 | -1.272296 1.002007 0.669288 0.289852 101 | -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/analysis.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | import sklearn as sk 4 | 5 | from utils import * 6 | 7 | def plot_cost_versus_epochs_colormap(plot_file_name, target_test, Y_pred, cost_list, cost_test_list, learning_rates): 8 | 9 | """ cost_test_list --> target testing error list for each epoch, where cost_test_list[i] is the testing error for epoch i. 10 | cost_list --> training error list for each epoch, where cost_list[i] is the training error for epoch i. 11 | """ 12 | 13 | x = np.arange(len(cost_list)) 14 | y = cost_list 15 | color_metric = cost_test_list 16 | 17 | fig = plt.figure() 18 | ax = fig.add_subplot(111) 19 | 20 | cmhot = plt.cm.get_cmap("hot") 21 | l = ax.scatter(x, y, c=color_metric, cmap=cmhot) 22 | fig.colorbar(l) 23 | plt.show() 24 | 25 | # Save the figure 26 | plt.savefig(plot_file_name, bbox_inches='tight') 27 | 28 | def plot_cost_versus_epochs(autoscale, plot_file_path, experiment_number, cost_list, cost_test_list): 29 | 30 | x1 = np.arange(len(cost_list)) 31 | y1 = cost_list 32 | 33 | x2 = np.arange(len(cost_test_list)) 34 | y2 = cost_test_list 35 | 36 | fig = plt.figure() 37 | subplt = plt.subplot(111) 38 | plt.plot(x1, y1) 39 | plt.xlabel('Epochs') 40 | plt.ylabel('Cost Function') 41 | plt.title('Cost Function Per Epoch Over %s Epochs' % str(len(x1))) 42 | plt.grid() 43 | if autoscale: 44 | subplt.autoscale_view(True, True, True) 45 | fig.tight_layout() 46 | 47 | plot_file_name = "%s/epoch-vs-cost-exp-%s.pdf" % (plot_file_path, experiment_number) 48 | plt.savefig(plot_file_name, bbox_inches='tight') 49 | 50 | fig = plt.figure() 51 | subplt = plt.subplot(111) 52 | plt.plot(x2, y2) 53 | plt.xlabel('Epochs') 54 | plt.ylabel('Cost Function') 55 | plt.title('Cost Function Per Testing Epoch Over %s Epochs' % str(len(x2))) 56 | plt.grid() 57 | if autoscale: 58 | subplt.autoscale_view(True,True,True) 59 | fig.tight_layout() 60 | 61 | plot_file_name = "%s/epoch-vs-testing-cost-exp-%s.pdf" % (plot_file_path, experiment_number) 62 | plt.savefig(plot_file_name, bbox_inches='tight') 63 | 64 | return plot_file_name 65 | 66 | def plot_rmse_versus_epochs(autoscale, plot_file_path, experiment_number, rmse): 67 | 68 | x1 = np.arange(len(rmse)) 69 | y1 = rmse 70 | 71 | fig = plt.figure() 72 | subplt = plt.subplot(111) 73 | plt.plot(x1, y1) 74 | plt.xlabel('Epochs') 75 | plt.ylabel('RMSE') 76 | plt.title('RMSE Per Epoch Over %s Epochs' % str(len(x1))) 77 | plt.grid() 78 | if autoscale: 79 | subplt.autoscale_view(True,True,True) 80 | fig.tight_layout() 81 | 82 | plot_file_name = "%s/epoch-vs-rmse-exp-%s.pdf" % (plot_file_path, experiment_number) 83 | plt.savefig(plot_file_name, bbox_inches='tight') 84 | 85 | return plot_file_name 86 | 87 | def plot_learning_rates_versus_epochs(autoscale, plot_file_path, experiment_number, learning_rates): 88 | x1 = np.arange(len(learning_rates)) 89 | y1 = learning_rates 90 | 91 | fig = plt.figure() 92 | subplt = plt.subplot(111) 93 | plt.plot(x1, y1) 94 | plt.xlabel('Epochs') 95 | plt.ylabel('Learning Rate') 96 | plt.title('Learning Rate Per Epoch Over %s Epochs' % str(len(x1))) 97 | plt.grid() 98 | if autoscale: 99 | subplt.autoscale_view(True,True,True) 100 | fig.tight_layout() 101 | 102 | plot_file_name = "%s/epoch-vs-lr-exp-%s.pdf" % (plot_file_path, experiment_number) 103 | plt.savefig(plot_file_name, bbox_inches='tight') 104 | 105 | return plot_file_name 106 | 107 | def plot_accuracy(plot_file_path, experiment_number, target_test, Y_pred): 108 | 109 | x1 = target_test 110 | y1 = Y_pred 111 | 112 | fig = plt.figure() 113 | plt.scatter(x1, y1, alpha=0.5) 114 | plt.xlabel('Target Values') 115 | plt.ylabel('Predicted Values') 116 | plt.title('Accuracy of Network') 117 | plt.grid() 118 | fig.tight_layout() 119 | 120 | plot_file_name = "%s/accuracy-exp-%s.pdf" % (plot_file_path, experiment_number) 121 | plt.savefig(plot_file_name, bbox_inches='tight') 122 | 123 | return plot_file_name 124 | 125 | def facial_recognition_graphs(): 126 | 127 | prediction_titles = [title(y_pred, y_test, target_names, i) 128 | for i in range(y_pred.shape[0])] 129 | 130 | plot_gallery(X_test, prediction_titles, h, w) 131 | 132 | # plot the gallery of the most significative eigenfaces 133 | 134 | eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])] 135 | plot_gallery(eigenfaces, eigenface_titles, h, w) 136 | 137 | plt.show() -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def sigmoid(z): 4 | """sigmoid is a basic sigmoid function returning values from 0-1""" 5 | return 1.0 / ( 1.0 + np.exp(-z) ) 6 | 7 | def sigmoidGradient(z): 8 | # Not used 9 | return self.sigmoid(z) * ( 1 - self.sigmoid(z) ) 10 | 11 | def format__1(digits,num): 12 | if digitsargs.minError: #if all values for every dimension is below min error, we can break 204 | cont = True 205 | #add percent convergence to plot list: 206 | convergence_plot.append(FindPercentConverge(pso.swarm, pso.globalBest)) 207 | #if swarm is 2D make a Scatter Plot 208 | if len(args.dim) == 2: 209 | logger.info("Creating scatter plot for iteration") 210 | PlotScatter(pso.swarm, args.dim, pso.globalBest, i) 211 | logger.info("Finished created scatter plot") 212 | #if we've converged to within a minimum error, break 213 | if cont is False: 214 | logger.info("Errors are below the threshold. Exiting now...") 215 | break 216 | #otherwise update and begin next iteration: 217 | logger.info("Updating PSO:") 218 | pso.Update() 219 | logger.info("\n\n######################ANALYZING DATA######################:") 220 | 221 | logger.info("Plotting error") 222 | PlotError(error_plot) 223 | logger.info("Finished plotting error") 224 | logger.info("Plotting percentage convergence") 225 | PlotConvergence(convergence_plot) 226 | logger.info("Finished plotting percentage convergence") 227 | 228 | logger.info("Experiment complete") 229 | if __name__ == "__main__": 230 | main() 231 | -------------------------------------------------------------------------------- /genetics/basic/geneticRun.py: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | #!/usr/bin/env python 3 | # -*- coding: utf-8 -*- 4 | # 5 | # genetic.py, general purpose genetic algorithm in Python 6 | # 7 | # Written by Jared Smith and David Cunningham for COSC 427/527 8 | # at the University of Tennessee, Knoxville 9 | # 10 | ############################################################### 11 | 12 | import os 13 | import argparse 14 | import logging 15 | import contextlib 16 | from argparse import RawTextHelpFormatter 17 | 18 | import numpy as np 19 | import matplotlib.pyplot as plt 20 | 21 | from geneticAlgorithms import BaseGeneticAlgorithm 22 | import ffs 23 | 24 | # Function for changing directories safely 25 | @contextlib.contextmanager 26 | def cd(newPath): 27 | savedPath = os.getcwd() 28 | os.chdir(newPath) 29 | yield 30 | os.chdir(savedPath) 31 | 32 | 33 | # Setup the command line parser 34 | def setup_argparser(): 35 | 36 | parser = argparse.ArgumentParser(description='' + 37 | ' PyNet: General Purpose Genetic ' + 38 | ' Algorithm in Python\n' + 39 | ' Written by: Jared Smith and ' + 40 | ' David Cunningham', 41 | version='1.0.0', 42 | formatter_class=RawTextHelpFormatter) 43 | 44 | requiredArguments = parser.add_argument_group('required Arguments') 45 | requiredArguments.add_argument('-exp', dest='experiment_number', required=True, type=str, help="Number of this experiment.") 46 | optionalArguments = parser.add_argument_group('optional Arguments') 47 | optionalArguments.add_argument('--num_bits', dest='l', required=False, type=int, default=20, help="Number of bits (genes) in the genetic string. Default is 20.") 48 | optionalArguments.add_argument('--population_size', dest='N', required=False, type=int, default=30, help="Size of the population. Default is 30.") 49 | optionalArguments.add_argument('--num_gens', dest='G', required=False, type=int, default=10, help="Number of generations. Default is 10.") 50 | optionalArguments.add_argument('--pr_mutation', dest='pm', required=False, type=float, default=0.033, help="Probability of Mutation. Default is 0.033.") 51 | optionalArguments.add_argument('--pr_crossover', dest='pc', required=False, type=float, default=0.6, help="Probability of Crossover. Default is 0.6.") 52 | optionalArguments.add_argument('--learn_offspring', dest='learn', required=False, type=bool, default=False, help="Specify whether to enforce learning on the offspring of each generation. Default is False.") 53 | optionalArguments.add_argument('--change_environment', dest='ce', required=False, type=bool, default=False, help="Specify whether to inflict a sudden change of environment on the final population. Default is False.") 54 | optionalArguments.add_argument('--num_learning_guesses', dest='NG', required=False, type=int, default=20, help="Specify the number of guesses to take when learning with the offspring. Default is 20.") 55 | optionalArguments.add_argument('--fitness_func', dest='ff', required=False, type=callable, default=ffs.fitness_func_1, help="Specify the fitness function to use. Default is fitness_func_1 from ffs.py.") 56 | optionalArguments.add_argument('--plot', dest='plot', required=False, type=bool, default=True, help="Specify if data is to be plotted. Default is True.") 57 | optionalArguments.add_argument('--autoscale', dest='autoscale', required=False, type=bool, default=True, help="Specify plots should be autoscaled to data frame. Default is True.") 58 | optionalArguments.add_argument('--nruns', dest='nruns', required=False, type=int, default=10, help="Specify the number of runs to do of the algorithm. Default is 10.") 59 | optionalArguments.add_argument('--seed', dest='rs', required=False, type=int, default=None, help="seed for RNG. Default is none") 60 | return parser 61 | 62 | def setup_logger(log_path, logger_name, logfile_name): 63 | 64 | logFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 65 | rootLogger = logging.getLogger(logger_name) 66 | rootLogger.setLevel(logging.INFO) 67 | 68 | fileHandler = logging.FileHandler("{0}/{1}.log".format(log_path, logfile_name), mode='w') 69 | fileHandler.setFormatter(logFormatter) 70 | rootLogger.addHandler(fileHandler) 71 | 72 | consoleHandler = logging.StreamHandler() 73 | consoleHandler.setFormatter(logFormatter) 74 | rootLogger.addHandler(consoleHandler) 75 | 76 | return rootLogger 77 | 78 | 79 | def plot_results(G, nruns, avg_fitness_vals, best_fitness_vals, num_correct_bits, 80 | autoscale, plot_file_path, experiment_number, ce): 81 | x = np.arange(0, G) 82 | 83 | # Plot average fitness values 84 | fig = plt.figure() 85 | subplt = plt.subplot(111) 86 | 87 | for nrun in range(nruns): 88 | plt.plot(x, avg_fitness_vals[nrun][0][:G]) 89 | plt.xlabel('Generations') 90 | plt.ylabel('Average Fitness Value') 91 | plt.title('Average Fitness Values Over %d Runs with %d Generations' % 92 | (avg_fitness_vals.shape[0], G)) 93 | plt.grid() 94 | if autoscale: 95 | subplt.autoscale_view(True, True, True) 96 | fig.tight_layout() 97 | plot_file_name = "%s/avg-fit-vals-exp-%s.pdf" % (plot_file_path, experiment_number) 98 | plt.savefig(plot_file_name, bbox_inches='tight') 99 | 100 | # Plot the best fitness values 101 | fig = plt.figure() 102 | subplt = plt.subplot(111) 103 | 104 | for nrun in range(nruns): 105 | plt.plot(x, best_fitness_vals[nrun][0][:G]) 106 | plt.xlabel('Generations') 107 | plt.ylabel('Best Fitness Value') 108 | plt.title('Best Fitness Values Over %d Runs with %d Generations' % 109 | (best_fitness_vals.shape[0], G)) 110 | plt.grid() 111 | if autoscale: 112 | subplt.autoscale_view(True, True, True) 113 | fig.tight_layout() 114 | plot_file_name = "%s/best-fit-vals-exp-%s.pdf" % (plot_file_path, experiment_number) 115 | plt.savefig(plot_file_name, bbox_inches='tight') 116 | 117 | # Plot the number of correct bits for the best individual 118 | fig = plt.figure() 119 | subplt = plt.subplot(111) 120 | 121 | for nrun in range(nruns): 122 | plt.plot(x, num_correct_bits[nrun][0][:G]) 123 | plt.xlabel('Generations') 124 | plt.ylabel('Number of Correct Bits') 125 | plt.title('Number of Correct Bits Over %d Runs with %d Generations' % 126 | (num_correct_bits.shape[0], G)) 127 | plt.grid() 128 | if autoscale: 129 | subplt.autoscale_view(True, True, True) 130 | fig.tight_layout() 131 | plot_file_name = "%s/num-correct-bits-exp-%s.pdf" % (plot_file_path, experiment_number) 132 | plt.savefig(plot_file_name, bbox_inches='tight') 133 | 134 | if ce: 135 | x = np.arange(0, G + 30) 136 | 137 | # Plot average fitness values 138 | fig = plt.figure() 139 | subplt = plt.subplot(111) 140 | 141 | for nrun in range(nruns): 142 | plt.plot(x, avg_fitness_vals[nrun][1][:(G + 30)]) 143 | plt.xlabel('Generations') 144 | plt.ylabel('Average Fitness Value') 145 | plt.title('Average Fitness Values Over %d Runs with %d Max Generations' % 146 | (avg_fitness_vals.shape[0], avg_fitness_vals.shape[2])) 147 | plt.grid() 148 | if autoscale: 149 | subplt.autoscale_view(True, True, True) 150 | fig.tight_layout() 151 | plot_file_name = "%s/ce-avg-fit-vals-exp-%s.pdf" % (plot_file_path, experiment_number) 152 | plt.savefig(plot_file_name, bbox_inches='tight') 153 | 154 | # Plot the best fitness values 155 | fig = plt.figure() 156 | subplt = plt.subplot(111) 157 | 158 | for nrun in range(nruns): 159 | plt.plot(x, best_fitness_vals[nrun][1][:(G + 30)]) 160 | plt.xlabel('Generations') 161 | plt.ylabel('Best Fitness Value') 162 | plt.title('Best Fitness Values Over %d Runs with %d Max Generations' % 163 | (best_fitness_vals.shape[0], best_fitness_vals.shape[2])) 164 | plt.grid() 165 | if autoscale: 166 | subplt.autoscale_view(True, True, True) 167 | fig.tight_layout() 168 | plot_file_name = "%s/ce-best-fit-vals-exp-%s.pdf" % (plot_file_path, experiment_number) 169 | plt.savefig(plot_file_name, bbox_inches='tight') 170 | 171 | # Plot the number of correct bits for the best individual 172 | fig = plt.figure() 173 | subplt = plt.subplot(111) 174 | 175 | for nrun in range(nruns): 176 | plt.plot(x, num_correct_bits[nrun][1][:(G + 30)]) 177 | plt.xlabel('Generations') 178 | plt.ylabel('Number of Correct Bits') 179 | plt.title('Number of Correct Bits Over %d Runs with %d Max Generations' % 180 | (num_correct_bits.shape[0], num_correct_bits.shape[2])) 181 | plt.grid() 182 | if autoscale: 183 | subplt.autoscale_view(True, True, True) 184 | fig.tight_layout() 185 | plot_file_name = "%s/ce-num-correct-bits-exp-%s.pdf" % (plot_file_path, experiment_number) 186 | plt.savefig(plot_file_name, bbox_inches='tight') 187 | 188 | 189 | def main(): 190 | parser = setup_argparser() 191 | args = parser.parse_args() 192 | experiment_number = args.experiment_number 193 | 194 | # Setup directories for storing results 195 | if not os.path.exists('results'): 196 | os.makedirs('results') 197 | 198 | with cd('results'): 199 | if not os.path.exists('data'): 200 | os.makedirs('data') 201 | with cd('data'): 202 | if not os.path.exists('Experiment-' + str(experiment_number)): 203 | os.makedirs('Experiment-' + str(experiment_number)) 204 | 205 | logger = setup_logger('results/data/Experiment-' 206 | + str(experiment_number), "__main__", "main") 207 | logger.info("###################################RUNNING EXPERIMENT NUM " + 208 | "%s#########################", str(experiment_number)) 209 | logger.info("Program Arguments:") 210 | args_dict = vars(args) 211 | for key, value in args_dict.iteritems(): 212 | logger.info("%s=%s" % (str(key), str(value))) 213 | 214 | logger.info("Running Base Genetic Algorithm...") 215 | gen_alg = BaseGeneticAlgorithm(args, logger) 216 | avg_fitness_vals, best_fitness_vals, num_correct_bits = gen_alg.run() 217 | logger.info("Finished Base Genetic Algorithm.") 218 | 219 | if args.plot: 220 | plot_file_path = 'results/data/Experiment-%s' % (experiment_number) 221 | plot_results(args.G, args.nruns, avg_fitness_vals, best_fitness_vals, num_correct_bits, 222 | args.autoscale, plot_file_path, experiment_number, args.ce) 223 | 224 | if __name__ == "__main__": 225 | main() 226 | -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/tests.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | import numpy as np 4 | import math as math 5 | import pylab as plt 6 | from time import time 7 | from sklearn.datasets import load_iris, load_digits, fetch_lfw_people, fetch_lfw_pairs 8 | from sklearn.decomposition import RandomizedPCA 9 | from sklearn.cross_validation import train_test_split as sklearn_train_test_split 10 | 11 | 12 | from network import BackPropagationNetwork 13 | from utils import * 14 | 15 | class Tests(object): 16 | 17 | def __init__(self, logger, args): 18 | 19 | self.logger = logger 20 | self.args = args 21 | 22 | def run_tests(self): 23 | if self.args.test_type == 'x': 24 | self.logger.info("###################################RUNNING XOR TEST##################################") 25 | target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse = self.XOR_test(self.args.reg_term, self.args.hidden_layers, self.args.epochs, self.args.learning_rate, self.args.momentum_rate, self.args.learning_reward, self.args.learning_penalty) 26 | return (target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse) 27 | elif self.args.test_type == 'd': 28 | self.logger.info("###################################RUNNING DIGITS TEST###############################") 29 | target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse = self.digits_test(self.args.reg_term, self.args.hidden_layers, self.args.epochs, self.args.learning_rate, self.args.momentum_rate, self.args.learning_reward, self.args.learning_penalty) 30 | return (target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse) 31 | elif self.args.test_type == 'i': 32 | self.logger.info("###################################RUNNING IRIS TEST#################################") 33 | target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse = self.iris_test(self.args.reg_term, self.args.hidden_layers, self.args.epochs, self.args.learning_rate, self.args.momentum_rate, self.args.learning_reward, self.args.learning_penalty) 34 | return (target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse) 35 | elif self.args.test_type == 'f': 36 | self.logger.info("###################################RUNNING APPROX TEST###############################") 37 | target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse = self.fnct_aprox(self.args.reg_term, self.args.hidden_layers, self.args.epochs, self.args.learning_rate, self.args.momentum_rate, self.args.learning_reward, self.args.learning_penalty, self.args.ftrain, self.args.ftest, self.args.fvalid) 38 | return (target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse) 39 | elif self.args.test_type == 'w': 40 | self.logger.info("###################################RUNNING FACES TEST###############################") 41 | target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse = self.faces_test(self.args.reg_term, self.args.hidden_layers, self.args.epochs, self.args.learning_rate, self.args.momentum_rate, self.args.learning_reward, self.args.learning_penalty) 42 | return (target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse) 43 | 44 | 45 | def translate_to_binary_array(self, target): 46 | n_obs = len(target) 47 | unique_targets = np.unique(target) 48 | n_unique_targets = len(np.unique(target)) 49 | 50 | # Translation of target values to array indicies 51 | target_translation = dict(zip(unique_targets, range(n_unique_targets))) 52 | 53 | # Create initial target array with all zeros 54 | target_array = np.zeros((n_obs, n_unique_targets)) 55 | 56 | # Set 1 value 57 | for i, val in enumerate(target): 58 | target_array[i][target_translation[val]] = 1 59 | 60 | return target_array 61 | 62 | def train_test_split(self, data_array, target_array, split=.8): 63 | """ 64 | Split into randomly shuffled train and test sets 65 | Split on Number of records or Percent of records in the training set 66 | if split is <= 1 then split is a percent, else split is the number of records 67 | """ 68 | 69 | n_obs = len(data_array) 70 | 71 | if split <= 1: 72 | train_len = int(split * n_obs) 73 | else: 74 | train_len = int(np.round(split)) 75 | 76 | shuffled_index = range(n_obs) 77 | np.random.shuffle(shuffled_index) 78 | 79 | train_data = data_array[shuffled_index[:train_len]] 80 | test_data = data_array[shuffled_index[train_len:]] 81 | 82 | train_target = target_array[shuffled_index[:train_len]] 83 | test_target = target_array[shuffled_index[train_len:]] 84 | 85 | print train_data.shape 86 | print test_data.shape 87 | 88 | print train_target.shape 89 | print test_target.shape 90 | 91 | self.logger.info('Data Set: %d Observations, %d Features' % (data_array.shape[0], data_array.shape[1])) 92 | self.logger.info('Training Set: %d Observations, %d Features' % (train_data.shape[0], train_data.shape[1])) 93 | self.logger.info('Test Set: %d Observations, %d Features' % (test_data.shape[0], test_data.shape[1])) 94 | self.logger.info('Target Set: %d Observations, %d Classes' % (target_array.shape[0], target_array.shape[1])) 95 | self.logger.info('Training Set: %d Observations, %d Features' % (train_target.shape[0], train_target.shape[1])) 96 | self.logger.info('Test Set: %d Observations, %d Features' % (test_target.shape[0], test_target.shape[1])) 97 | 98 | return train_data, test_data, train_target, test_target 99 | 100 | def iris_test(self, reg_term, hidden_layers, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup): 101 | 102 | data_set = load_iris() 103 | 104 | data = data_set.data 105 | target = self.translate_to_binary_array(data_set.target) 106 | 107 | # Split into train, test sets 108 | data_train, data_test, target_train, target_test = self.train_test_split(data, target, .75) 109 | 110 | NN = BackPropagationNetwork(self.logger, data_train, target_train, hidden_layers, reg_term) 111 | return BackPropagationNetwork.test(NN, data_train, target_train, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup, data_test, target_test) 112 | 113 | def digits_test(self, reg_term, hidden_layers, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup): 114 | 115 | data_set = load_digits() 116 | 117 | data = data_set.data 118 | target = self.translate_to_binary_array(data_set.target) 119 | 120 | # Split into train, test sets 121 | data_train, data_test, target_train, target_test = self.train_test_split(data, target, .75) 122 | 123 | NN = BackPropagationNetwork(self.logger, data_train, target_train, hidden_layers, reg_term) 124 | return BackPropagationNetwork.test(NN, data_train, target_train, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup, data_test, target_test) 125 | 126 | def XOR_test(self, reg_term, hidden_layers, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup): 127 | """ 128 | XOR_test is a simple test of the nn self.logger.info(ing the predicted value to std out 129 | Trains on a sample XOR data set 130 | Predicts a single value 131 | Accepts an option parameter to set architecture of hidden layers 132 | """ 133 | 134 | # Set Data for XOR Test 135 | data_train = np.zeros((4,2)) 136 | data_train[0,0] = 1. 137 | data_train[1,1] = 1. 138 | data_train[2,:] = 1. 139 | data_train[3,:] = 0. 140 | 141 | target_train = np.array([1.,1.,0.,0.]).reshape(4,1) # Single Class 142 | 143 | # Test X and Y 144 | data_test = np.array([[1,0],[0,1],[1,1],[0,0]]) 145 | target_test = np.array([[1],[1],[0],[0]]) 146 | 147 | self.logger.info('Training Data: X') 148 | for data_i in data_train: 149 | self.logger.info("%s" % str(data_i)) 150 | self.logger.info('Training Data: Y') 151 | for target_i in target_train: 152 | self.logger.info("%s" % str(target_i)) 153 | 154 | NN = BackPropagationNetwork(self.logger, data_train, target_train, hidden_layers, reg_term) 155 | return BackPropagationNetwork.test(NN, data_train, target_train, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup, data_test, target_test) 156 | 157 | def fnct_aprox(self, reg_term, hidden_layers, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup, training_name, testing_name, validation_name): 158 | 159 | #read in train 160 | data_train, target_train = self.parse_file(training_name, 200) 161 | np.random.shuffle(data_train) 162 | np.random.shuffle(target_train) 163 | #read in test 164 | data_test, target_test = self.parse_file(testing_name, 100) 165 | np.random.shuffle(data_test) 166 | np.random.shuffle(target_test) 167 | #read in validation 168 | data_val, target_val = self.parse_file(validation_name, 50) 169 | np.random.shuffle(data_val) 170 | np.random.shuffle(target_val) 171 | 172 | NN = BackPropagationNetwork(self.logger, data_train, target_train, hidden_layers, reg_term) 173 | return BackPropagationNetwork.test(NN, data_train, target_train, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup, data_test, target_test, data_val = data_val,target_val = target_val) 174 | 175 | def parse_file(self, filename, num_lines): 176 | 177 | data = [] 178 | target = [] 179 | f = open(filename, 'r') 180 | for line in f: 181 | floats = map(float, line.split()) 182 | target.append([floats.pop()]) 183 | data.append(floats) 184 | f.close() 185 | return np.array(data), np.array(target) 186 | 187 | def faces_test(self, reg_term, hidden_layers, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup): 188 | 189 | lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4) 190 | 191 | # introspect the images arrays to find the shapes (for plotting) 192 | n_samples, h, w = lfw_people.images.shape 193 | 194 | # for machine learning we use the 2 data directly (as relative pixel 195 | # positions info is ignored by this model) 196 | X = lfw_people.data 197 | n_features = X.shape[1] 198 | 199 | # the label to predict is the id of the person 200 | y = lfw_people.target 201 | y = self.translate_to_binary_array(y) 202 | 203 | 204 | target_names = lfw_people.target_names 205 | n_classes = target_names.shape[0] 206 | 207 | self.logger.info("n_samples: {}".format(n_samples)) 208 | self.logger.info("n_features: {}".format(n_features)) 209 | self.logger.info("n_classes: {}".format(n_classes)) 210 | 211 | # split into a training and testing set 212 | X_train, X_test, y_train, y_test = sklearn_train_test_split( 213 | X, y, test_size=0.25) 214 | 215 | # Compute a PCA (eigenfaces) on the face dataset (treated as unlabeled 216 | # dataset): unsupervised feature extraction / dimensionality reduction 217 | n_components = 150 218 | 219 | self.logger.info("Extracting the top %d eigenfaces from %d faces" 220 | % (n_components, X_train.shape[0])) 221 | t0 = time() 222 | pca = RandomizedPCA(n_components=n_components, whiten=True).fit(X_train) 223 | self.logger.info("done in %0.3fs" % (time() - t0)) 224 | 225 | eigenfaces = pca.components_.reshape((n_components, h, w)) 226 | 227 | self.logger.info("Projecting the input data on the eigenfaces orthonormal basis") 228 | t0 = time() 229 | X_train_pca = pca.transform(X_train) 230 | X_test_pca = pca.transform(X_test) 231 | self.logger.info("done in %0.3fs" % (time() - t0)) 232 | 233 | NN = BackPropagationNetwork(self.logger, X_train_pca, y_train, hidden_layers, reg_term) 234 | return BackPropagationNetwork.test(NN, X_train_pca, y_train, epochs, learning_rate, momentum_rate, learning_acceleration, learning_backup, X_test_pca, y_test) -------------------------------------------------------------------------------- /neuralnetworks/hopfield/hopfieldNetwork.py: -------------------------------------------------------------------------------- 1 | ''' 2 | hopnet.py 3 | Hopfield Neural Network Implmentation in Python 4 | 5 | Written by: Jared Smith and David Cunningham 6 | 7 | How to get up and running: 8 | 9 | 1) Make a virtualenv with 'virtualenv venv' and 'source venv/bin/activate' 10 | If you don't already have the command 'virtualenv', then you can install 11 | virtualenv with pip. 12 | 2) Install program dependencies with 'pip install -r requirements.txt' 13 | 3) Run 'python hopnet.py -h' to see the required arguments for running the program. 14 | 15 | ''' 16 | 17 | 18 | # Built-in Python libraries 19 | import os 20 | import random 21 | import contextlib 22 | import sys 23 | import argparse 24 | from argparse import RawTextHelpFormatter 25 | 26 | # Third party libraries 27 | import numpy as np 28 | import matplotlib.pyplot as plt 29 | import sklearn as sk 30 | 31 | # Initialize the random seed 32 | random.seed() 33 | 34 | # Function for changing directories safely 35 | @contextlib.contextmanager 36 | def cd(newPath): 37 | savedPath = os.getcwd() 38 | os.chdir(newPath) 39 | yield 40 | os.chdir(savedPath) 41 | 42 | # Setup the command line parser 43 | def setup_argparser(): 44 | 45 | parser = argparse.ArgumentParser(description='' + 46 | 'Written by: Jared Smith and David Cunningham.', 47 | version='1.0.0', formatter_class=RawTextHelpFormatter) 48 | requiredArguments = parser.add_argument_group('required Arguments') 49 | requiredArguments.add_argument('-exp', metavar='Exp_Num', dest='experiment_number', required=True, type=str, help='Number of this experiment.') 50 | requiredArguments.add_argument('-npat', metavar='Num_Patterns', dest='npat', required=True, type=int, help='Number of patterns.') 51 | requiredArguments.add_argument('-nnsize', metavar='Netw_Size', dest='nnsize', required=True, type=int, help='Size of Neural Network.') 52 | requiredArguments.add_argument('-nruns', metavar='Num_Runs', dest= 'nruns', required =True, type=int, help='Number of runs of the experiment.') 53 | requiredArguments.add_argument('-dfn', metavar='Data_File_Name', dest= 'dfn', required =True, type=str, help='Data file name to save experiment data to.') 54 | requiredArguments.add_argument('-hfn', metavar='Histo_File_Name', dest= 'hfn', required =True, type=str, help='Data file name to save histogram data to.') 55 | 56 | 57 | return parser 58 | 59 | # Get Peak of Data Curve 60 | def getpeak(data): 61 | peak_y = np.max(data) 62 | peak_x = np.argmax(data) 63 | return peak_x, peak_y 64 | 65 | # Normalize Data 66 | def normalize_data (data, scale, p): 67 | norm_data = data.copy() 68 | b = np.min(norm_data) 69 | norm_data -= b 70 | norm_data /= p 71 | norm_data *= scale 72 | 73 | return norm_data 74 | 75 | # Make the graphs for each run and the overall average of runs 76 | def plot_graph_data(experiment_number, nvec, avg_stable_prob, avg_unstable_prob, run_no): 77 | 78 | run_str = '' 79 | p = list(xrange(nvec)) 80 | 81 | abs_path = os.path.abspath(".") 82 | root_path = 'results/data/Experiment-' + str(experiment_number) 83 | file_path = 'file://' + abs_path 84 | if run_no == 0: 85 | run_str = '' 86 | else: 87 | run_str = '-runnum-%s-' % str(run_no) 88 | path = 'Graph-for-Experiment-' + experiment_number + run_str + '.jpg' 89 | 90 | fig = plt.figure() 91 | 92 | # Plot Unstable Imprints 93 | plt.subplot(2, 1, 1) 94 | plt.plot(p, avg_unstable_prob) 95 | plt.xlabel('p') 96 | plt.ylabel('Fraction of Unstable Imprints') 97 | if run_no == 0: 98 | plt.title('Overall Fraction of Unstable Imprints for %s Patterns' % nvec) 99 | else: 100 | plt.title('Fraction of Unstable Imprints for %s Patterns' % nvec) 101 | plt.legend(loc=0) 102 | plt.grid() 103 | 104 | # Plot Stable Imprints 105 | plt.subplot(2, 1, 2) 106 | plt.plot(p, avg_stable_prob) 107 | plt.xlabel('p') 108 | plt.ylabel('Fraction of Stable Imprints') 109 | if run_no == 0: 110 | plt.title('Overall Fraction of Stable Imprints for %s Patterns' % nvec) 111 | else: 112 | plt.title('Fraction of Stable Imprints for %s Patters' % nvec) 113 | plt.legend(loc=0) 114 | plt.grid() 115 | fig.tight_layout() 116 | 117 | # Save the figure 118 | fig.savefig(root_path + '/' + path) 119 | 120 | return file_path + '/' + root_path + '/' + path 121 | 122 | # Plot the Histogram 123 | def plot_histogram(avg_basin_size, experiment_number): 124 | 125 | (num_rows, num_cols) = avg_basin_size.shape 126 | avg_basin_size[:][:] += 1 127 | 128 | abs_path = os.path.abspath(".") 129 | root_path = 'results/data/Experiment-' + str(experiment_number) 130 | file_path = 'file://' + abs_path 131 | path = 'Histogram-for-Experiment-' + experiment_number + '.jpg' 132 | 133 | fig = plt.figure() 134 | 135 | # Plot the Histogram Normalized to 1 136 | plt.subplot(2, 1, 1) 137 | for i in range(1, num_rows + 1): 138 | if i % 2 == 1: 139 | text_str = '%d' % ((i + 1)) 140 | n = normalize_data(avg_basin_size[i-1][:], 1, i) 141 | peak_x, peak_y = getpeak(n) 142 | plt.plot(np.arange(0, num_cols), n) 143 | 144 | # Label the curve 145 | if peak_y < 1.0 and peak_x > 1: 146 | plt.text(peak_x, peak_y+.1, text_str) 147 | 148 | plt.xlabel('B') 149 | plt.ylabel('Value') 150 | plt.title('Probability Distribution of Basin Sizes Normalized to 1') 151 | plt.grid() 152 | plt.ylim(0, 1.3) 153 | 154 | # Plot the Histogram Normalized to 1 155 | plt.subplot(2, 1, 2) 156 | for i in range(1, num_rows + 1): 157 | if i % 2 == 1: 158 | text_str = '%d' % ((i + 1)) 159 | n = normalize_data(avg_basin_size[i-1][:], i, i) 160 | peak_x, peak_y = getpeak(n) 161 | plt.plot(np.arange(0, num_cols), n) 162 | 163 | # Label the Curve 164 | if peak_y < 4.3 and peak_x > 1: 165 | plt.text(peak_x, peak_y+.1, text_str) 166 | 167 | plt.xlabel('B') 168 | plt.ylabel('Value') 169 | plt.title('Probability Distribution of Basin Sizes Normalized to P') 170 | plt.grid() 171 | plt.ylim(0,4.5) 172 | 173 | # Fix layout issues in plot. 174 | fig.tight_layout() 175 | 176 | # Save the figure 177 | fig.savefig(root_path + '/' + path) 178 | 179 | return file_path + '/' + root_path + '/' + path 180 | 181 | # Handle Invalid weights 182 | class InvalidWeightsException(Exception): 183 | pass 184 | 185 | # Handle Invalid NN Input 186 | class InvalidNetworkInputException(Exception): 187 | pass 188 | 189 | # Class for maintaining all of the data structures used for the simulation 190 | class Data(object): 191 | 192 | # Initialize Class 193 | def __init__(self, args, histo_file=None): 194 | self._nnsize = args.nnsize 195 | self._npat = args.npat 196 | self._exp = args.experiment_number 197 | self._stable = np.zeros(self._npat) 198 | self._basin_hist = np.zeros((self._npat, self._npat + 1)) 199 | self._prunstable = np.copy(self._stable) 200 | self._data_file_name = args.dfn 201 | self._histo_data_file_name = histo_file 202 | 203 | # Calculate the probablity vectors 204 | def calc_prob(self): 205 | stable_prob = np.zeros(self._npat) 206 | for p in range(self._npat): 207 | stable_prob[p] = self._stable[p] / (p+1) 208 | self._prunstable[p] = 1 - stable_prob[p] 209 | 210 | # Sum each run 211 | def sum(self, data): 212 | self._stable += data._stable 213 | self._prunstable += data._prunstable 214 | self._basin_hist += data._basin_hist 215 | 216 | # Average all of the runs 217 | def avg(self, nruns): 218 | self._stable /= nruns 219 | self._basin_hist /= nruns 220 | self._prunstable /= nruns 221 | 222 | # Save the report data as a human readable text file 223 | # Can also be read back into NumPy Arrays or Python Lists 224 | def save_report_data(self): 225 | with file(self._data_file_name, 'w') as outfile: 226 | outfile.write('# Average Stable Probability Data\n') 227 | outfile.write('# Array shape {0}\n'.format(self._stable)) 228 | np.savetxt(outfile, self._stable, fmt='%-7.2f') 229 | outfile.write('\n') 230 | 231 | outfile.write('# Average Unstable Probability Data\n') 232 | outfile.write('# Array shape {0}\n'.format(self._prunstable)) 233 | np.savetxt(outfile, self._prunstable, fmt='%-7.2f') 234 | outfile.write('\n') 235 | 236 | outfile.write('# Average Basin Histogram Data\n') 237 | outfile.write('# Array shape {0}\n'.format(self._basin_hist)) 238 | np.savetxt(outfile, self._basin_hist, fmt='%-7.2f') 239 | outfile.write('\n') 240 | 241 | # Save Histogram data for use in plotting separately 242 | def save_histo_data(self): 243 | np.save(self._histo_data_file_name, self._basin_hist) 244 | 245 | # Graph each run 246 | def graph(self, run): 247 | return plot_graph_data(self._exp, self._npat, self._stable, self._prunstable, run) 248 | 249 | # Class for the Hopfield Neural Network Model used 250 | class HopfieldNetwork(object): 251 | 252 | # Initialize Class 253 | def __init__(self, num_inputs): 254 | self._num_inputs = num_inputs 255 | self._weights = np.random.uniform(-1.0, 1.0, (num_inputs,num_inputs)) 256 | 257 | # Set the weights of the weight vector 258 | def set_weights(self, weights): 259 | if weights.shape != (self._num_inputs, self._num_inputs): 260 | raise InvalidWeightsException() 261 | 262 | self._weights = weights 263 | 264 | # Get the weights 265 | def get_weights(self): 266 | return self._weights 267 | 268 | # Evaluate the state of the Neural Network 269 | def evaluate(self, input_pattern): 270 | if input_pattern.shape != (self._num_inputs, ): 271 | raise InvalidNetworkInputException() 272 | 273 | weights = np.copy(self._weights) 274 | 275 | # Compute the sums of the input patterns 276 | # Uses dot product 277 | sums = input_pattern.dot(weights) 278 | 279 | s = np.zeros(self._num_inputs) 280 | 281 | # Enumerate the sums of the inputs and calculate new values 282 | for i, value in enumerate(sums): 283 | if value > 0: 284 | s[i] = 1 285 | else: 286 | s[i] = -1 287 | 288 | return s 289 | 290 | # Run the updating of the Network for a specified iteration count 291 | # Default number of iterations is 10 292 | def run(self, input_pattern, iterations=10): 293 | last_input_pattern = input_pattern 294 | iteration_count = 0 295 | 296 | while True: 297 | result = self.evaluate(last_input_pattern) 298 | 299 | iteration_count += 1 300 | if np.array_equal(result, last_input_pattern) or iteration_count == iterations: 301 | return result 302 | else: 303 | last_input_pattern = result 304 | 305 | # Imprint the patterns onto the network 306 | def imprint_patterns(network, input_patterns, p): 307 | num_neurons = network.get_weights().shape[0] 308 | weights = np.zeros((num_neurons, num_neurons)) 309 | 310 | for i in range(num_neurons): 311 | for j in range(num_neurons): 312 | if i == j: continue 313 | for m in range(p): 314 | weights[i, j] += input_patterns[m][i] * input_patterns[m][j] 315 | 316 | weights *= 1 / float(network._num_inputs) 317 | 318 | network.set_weights(weights) 319 | 320 | # Test the patterns for stability 321 | def test_patterns(p, input_patterns, network, data): 322 | for k in range(p): 323 | pattern = input_patterns[k][:] 324 | updated_pattern = np.copy(pattern) 325 | updated_pattern = network.run(updated_pattern, 1) 326 | if np.array_equal(updated_pattern, pattern): 327 | data._stable[p - 1] +=1 328 | 329 | # Run Basin test 330 | data = basin_test(p, pattern, network, data, 5) 331 | else: 332 | data._basin_hist[p - 1][0] += 1 333 | 334 | return data 335 | 336 | # Run the basin size tests 337 | def basin_test(p, input_pattern, network, data, runs): 338 | basin = 0 339 | 340 | for run in range(runs): 341 | converge = True 342 | array = np.random.permutation(data._nnsize) 343 | updated_pattern = np.copy(input_pattern) 344 | 345 | for i in range(1, data._npat + 1): 346 | for j in range (i): 347 | updated_pattern[array[j]] *= -1 348 | 349 | updated_pattern = network.run(updated_pattern) 350 | if not np.array_equal(updated_pattern, input_pattern): 351 | converge = False 352 | basin += i 353 | break 354 | 355 | if converge: 356 | basin += 50 357 | 358 | basin = round((basin / runs), 0) 359 | data._basin_hist[p - 1][basin] += 1 360 | return data 361 | 362 | # Run the experiment 363 | def run_experiment(args): 364 | stable = np.zeros((args.npat)) 365 | input_patterns = np.random.choice([-1,1], ((args.npat), (args.nnsize))) 366 | Hnet = HopfieldNetwork((args.nnsize)) 367 | data = Data(args) 368 | 369 | # Go through all npat patterns and run tests 370 | for p in range (1, args.npat + 1): 371 | imprint_patterns(Hnet, input_patterns, p) 372 | test_patterns(p, input_patterns, Hnet, data) 373 | data.calc_prob() 374 | 375 | return data 376 | 377 | # Execute on program start 378 | if __name__ == '__main__': 379 | 380 | graph_list = [] 381 | 382 | parser = setup_argparser() 383 | args = parser.parse_args() 384 | experiment_number = args.experiment_number 385 | histo_file = 'results/data/Experiment-%s/%s' % (experiment_number, args.hfn) 386 | 387 | # Setup directories for storing results 388 | if not os.path.exists('results'): 389 | os.makedirs('results') 390 | 391 | with cd('results'): 392 | if not os.path.exists('data'): 393 | os.makedirs('data') 394 | with cd('data'): 395 | if not os.path.exists('Experiment-' + str(experiment_number)): 396 | os.makedirs('Experiment-' + str(experiment_number)) 397 | 398 | avg_data = Data(args, histo_file) 399 | 400 | # Run experiment for nruns number of times 401 | for i in range(1, int(args.nruns) + 1): 402 | exp_data = run_experiment(args) 403 | graph_list += exp_data.graph(i) 404 | avg_data.sum(exp_data) 405 | 406 | avg_data.avg(args.nruns) 407 | 408 | # Save the average data 409 | avg_data.save_report_data() 410 | avg_data.save_histo_data() 411 | 412 | # Plot the average stability graphs and make the histogram for basin sizes 413 | plot_graph_data(experiment_number, args.npat, avg_data._stable, avg_data._prunstable, 0) 414 | plot_histogram(avg_data._basin_hist, experiment_number) 415 | 416 | 417 | -------------------------------------------------------------------------------- /neuralnetworks/backpropagation/network.py: -------------------------------------------------------------------------------- 1 | #!./usr/bin/python 2 | # -*- coding: utf-8 -*-# 3 | 4 | import numpy as np 5 | np.set_printoptions(precision=4, suppress=True) 6 | import math as math 7 | from matplotlib.pyplot import plot 8 | from sklearn.datasets import load_iris, load_digits 9 | 10 | from utils import * 11 | 12 | class BackPropagationNetwork(object): 13 | """ 14 | 15 | Initialize as: 16 | nn = BackPropagationNetwork(n_features, n_classes, hidden_layers, reg_term) 17 | 18 | --> reg_term (i.e. lambda) is the regularization term 19 | nn input and output units determined by training data 20 | 21 | Set nn.hidden_layers to list of integers to create hidden layer architecture 22 | nn.hidden_layers does not include the bias unit for each layer 23 | nn.hidden_layers is list containing number of units in each hidden layer 24 | [4, 4, 2] will create 3 hidden layers of 4 units, 4 units, and 2 units 25 | Entire architecture will be 5 layers with units [n_features, 4, 4, 2, n_classes] 26 | 27 | nn.fit(X, Y, epochs) where X is training data np.array of features, Y is training data of np.array of output classes , epochs is integer specifying the number of training iterations 28 | For multi-class prediction, each observation in Y should be implemented as a vector with length = number of classes where each position represents a class with 1 for the True class and 0 for all other classes 29 | For multi-class prediction, Y will have shape n_observations by n_classes 30 | 31 | nn.predict(X) returns vector of probability of class being true or false 32 | For multi-class prediction, returns a vector for each observation will return a vector where each position in the vector is the probability of a class 33 | 34 | Test a simple XOR problem with nn.XOR_test() 35 | nn.XOR_test() accepts an optional list of integers to determine the hidden layer architecture 36 | """ 37 | 38 | def __init__(self, logger, n_features, n_classes, hidden_layers, reg_term, test_type=None): 39 | self.logger = logger 40 | self.test_type = test_type 41 | self.n_features = n_features 42 | self.n_classes = n_classes 43 | self.hidden_layers = hidden_layers 44 | self.reg_term = reg_term 45 | self.epochs = 2 46 | self.learning_rate = 0.5 47 | self.learning_reward = 1.05 48 | self.learning_penalty = 0.5 49 | self.momentum_rate = 0.1 50 | self.Theta_L = [] 51 | 52 | self.initialize_theta() 53 | 54 | def initialize_theta(self): 55 | """ 56 | initialize_theta creates architecture of neural network 57 | Defines self.Theta_L 58 | 59 | Parameters: 60 | hidden_unit_length_list - List of hidden layer units 61 | input_unit_count - integer, number of input units (features) 62 | output_class_count - integer, number of output classes 63 | """ 64 | 65 | unit_count_list = [len(self.n_features[0])] 66 | unit_count_list += self.hidden_layers 67 | unit_count_list.append(len(self.n_classes[0])) 68 | self.Theta_L = [ 2 * (np.random.rand(unit_count, unit_count_list[l-1]+1) - 0.5) for l, unit_count in enumerate(unit_count_list) if l > 0] 69 | 70 | def print_theta(self): 71 | 72 | T = len(self.Theta_L) 73 | 74 | self.logger.info('\n') 75 | self.logger.info('NN ARCHITECTURE') 76 | self.logger.info('%s Layers (%s Hidden)' % ((T + 1), (T-1))) 77 | self.logger.info('%s Thetas' % T) 78 | self.logger.info('%s Input Features' % (self.Theta_L[0].shape[1]-1)) 79 | self.logger.info('%s Output Classes' % self.Theta_L[T-1].shape[0]) 80 | self.logger.info('\n') 81 | 82 | self.logger.info('Units per layer') 83 | for t, theta in enumerate(self.Theta_L): 84 | if t == 0: 85 | self.logger.info(' - Input: %s Units' % (theta.shape[1] - 1)) 86 | if t < T-1: 87 | self.logger.info(' - Hidden %s: %s Units' % ((t+1), theta.shape[0])) 88 | else: 89 | self.logger.info(' - Output: %s Units' % theta.shape[0]) 90 | 91 | self.logger.info('Theta Shapes') 92 | for l, theta in enumerate(self.Theta_L): 93 | self.logger.info('Theta %s: %s' % (l, theta.shape)) 94 | 95 | self.logger.info('Theta Values') 96 | for l, theta in enumerate(self.Theta_L): 97 | self.logger.info('Theta %s:' % l) 98 | self.logger.info("\n" + str(theta)) 99 | self.logger.info('\n') 100 | 101 | def cost_function(self, Y, Y_pred): 102 | """ 103 | cost_function implements cost function 104 | 105 | y is n_observations by n_classes (n_classes = 1 for n_classes <=2) 106 | pred_y is predicted y values and must be same shape as y 107 | 108 | Returns cost - list of cost values 109 | """ 110 | 111 | if Y.shape != Y_pred.shape: 112 | if Y.shape[0] != Y_pred.shape: 113 | raise ValueError,'Wrong number of predictions' 114 | else: 115 | raise ValueError,'Wrong number of prediction classes' 116 | 117 | n_observations = len(Y) 118 | tiny = 1e-6 119 | # Cost Function 120 | cost = (-1.0 / n_observations)*(Y * np.log(Y_pred + tiny) + ((1-Y) * np.log(1-Y_pred + tiny))).sum() 121 | 122 | return cost 123 | 124 | 125 | def predict(self, X): 126 | """ 127 | predict calculates activations for all layers, returns prediction for Y 128 | 129 | Parameters 130 | X is array of input features dimensions n_observations by n_features 131 | 132 | Returns 133 | a_N is outputs of all units 134 | a_N[L] is array of predicted Y values dimensions n_observations by n_classes 135 | """ 136 | 137 | m = len(X) 138 | T = len(self.Theta_L) 139 | 140 | a_N_predict = [] # List of activations including bias unit for non-output layers 141 | 142 | # Input Layer inputs 143 | a_N_predict.append( X ) 144 | # Loop through each Theta_List theta 145 | # t is Theta for calculating layer t+1 from layer t 146 | for t, theta in enumerate(self.Theta_L): 147 | # Add bias unit 148 | if a_N_predict[t].ndim == 1: 149 | a_N_predict[t].resize(1, a_N_predict[t].shape[0]) 150 | a_N_predict[t] = np.append(np.ones((a_N_predict[t].shape[0],1)), a_N_predict[t], 1) 151 | 152 | # Calculate and Append new z and a arrays to z_N and a_N lists 153 | z = a_N_predict[t].dot(theta.T) 154 | a_N_predict.append(sigmoid(z)) 155 | 156 | return a_N_predict, a_N_predict[T] 157 | 158 | 159 | def back_prop(self, a_N_backprop, Y_train): 160 | """ 161 | a_N - list of layer outputs with dimensions n_observations by n_units 162 | Y_train is n_observations, n_classes 163 | 164 | Returns 165 | Theta_Gradient_L 166 | """ 167 | 168 | T = len(self.Theta_L) 169 | Y_pred = a_N_backprop[T] 170 | n_observations = len(Y_pred) 171 | 172 | # Backprop Error; One list element for each layer 173 | delta_N = [] 174 | 175 | # Get Error for Output Layer 176 | delta = Y_pred - Y_train 177 | if delta.ndim == 1: 178 | delta.resize(1, len(delta)) 179 | delta_N.append( delta ) 180 | 181 | # Get Error for Hidden Layers working backwards (stop before layer 0; no error in input layer) 182 | for t in range(T-1,0,-1): 183 | delta = delta.dot(self.Theta_L[t][:,1:]) * ( a_N_backprop[t][:,1:] * (1 - a_N_backprop[t][:,1:]) ) 184 | delta_N.append( delta ) 185 | # Reverse the list so that delta_N[t] is delta that Theta[t] causes on a_N[t+1] 186 | delta_N.reverse() 187 | 188 | # Calculate Gradient from delta and activation 189 | # t is the Theta from layer t to layer t+1 190 | Theta_Gradient_L = [] 191 | for t in range(T): 192 | Theta_Gradient_L.append( delta_N[t].T.dot(a_N_backprop[t]) ) 193 | 194 | # Create modified copy of the Theta_L for Regularization 195 | # Coefficient for theta values from bias unit set to 0 so that bias unit is not regularized 196 | regTheta = [np.zeros_like(theta) for theta in self.Theta_L] 197 | for t, theta in enumerate(self.Theta_L): 198 | regTheta[t][:,1:] = theta[:,1:] 199 | 200 | # Average Error + regularization penalty 201 | for t in range(T): 202 | Theta_Gradient_L[t] = Theta_Gradient_L[t] * (1.0/n_observations) + (self.reg_term * regTheta[t]) 203 | 204 | return Theta_Gradient_L 205 | 206 | def fit(self, X_train, Y_train, X_test=None, Y_test=None): 207 | """ 208 | fit() calls the predict and back_prop functions for the 209 | given number of cycles, tracks error and error improvement rates 210 | 211 | Parameters: 212 | X_train - np.array of training data with dimension n_observations by n_features 213 | Y_train - np.array of training classes with dimension n_observations by n_classes 214 | epochs - integer of number of times to update Theta_L 215 | learning_rate 216 | momentum_rate 217 | learning_reward 218 | learning_penalty 219 | X_test - np.array of training data with dimension n_observations by n_features 220 | Y_test - np.array of training classes with dimension n_observations by n_classes 221 | Returns 222 | cost_list - list of result of cost function for each epoch 223 | Learning_rates - list of learning rates used for each epoch 224 | Notes 225 | Training and Test data are assumed to be in random order; mini-batch processing does not need to re-randomize 226 | """ 227 | 228 | # Initial Learning Rate 229 | learning_rates = [] 230 | learning_rates.append( self.learning_rate ) 231 | 232 | # Initial Weight Change Terms 233 | weight_change_L = [np.zeros_like(theta) for theta in self.Theta_L] 234 | 235 | # List of results of cost functions 236 | cost_list = [0] * self.epochs 237 | cost_test_list = [0] * self.epochs 238 | rmse = [0] * self.epochs 239 | # Initial Forward Pass 240 | a_N_train, Y_pred = self.predict(X_train) 241 | # Initial Cost 242 | cost_list[0] = self.cost_function(Y_train, Y_pred) 243 | 244 | # Test Error 245 | if Y_test is not None: 246 | a_N_test, Y_pred_test = self.predict(X_test) 247 | cost_test_list[0] = self.cost_function(Y_test, Y_pred_test) 248 | 249 | for i in range(1, self.epochs): 250 | 251 | # Back Prop to get Theta Gradients 252 | Theta_grad = self.back_prop(a_N_train, Y_train) 253 | 254 | # Update Theta with Momentum 255 | for l, theta_g in enumerate(Theta_grad): 256 | weight_change_L[l] = self.learning_rate * theta_g + (weight_change_L[l] * self.momentum_rate) 257 | self.Theta_L[l] = self.Theta_L[l] - weight_change_L[l] 258 | 259 | # Update Units 260 | a_N_train, Y_pred_new = self.predict(X_train) 261 | 262 | # Check to see if Cost decreased 263 | cost_new = self.cost_function(Y_train, Y_pred_new) 264 | 265 | if cost_new > cost_list[i-1]: 266 | # Reduce learning rate 267 | self.learning_rate = self.learning_rate * self.learning_penalty 268 | # Reverse part of adjustment (add back new learning_rate * Theta_grad); Leave momentum in place 269 | self.Theta_L = [t + (self.learning_rate * tg) for t, tg in zip(self.Theta_L, Theta_grad)] 270 | # Cut prior weight_change as an approximate fix to momentum 271 | weight_change_L = [m * self.learning_penalty for m in weight_change_L] 272 | 273 | a_N_train, Y_pred_new = self.predict(X_train) 274 | cost_new = self.cost_function(Y_train, Y_pred_new) 275 | else: 276 | self.learning_rate = np.min((10, self.learning_rate * self.learning_reward)) 277 | 278 | learning_rates.append(self.learning_rate) 279 | cost_list[i] = cost_new 280 | 281 | if Y_test is not None: 282 | a_N_test, Y_pred_test = self.predict(X_test) 283 | 284 | sum_e = 0 285 | for j in range(len(Y_test)): 286 | sum_e += pow((Y_test[j] - Y_pred_test[j]), 2) 287 | 288 | if len(sum_e) > 1: 289 | sum_e = np.sum(sum_e) 290 | 291 | rmse_epoch = math.sqrt((1.0 / (2.0 * len(Y_test))) * sum_e) 292 | rmse[i] = rmse_epoch 293 | 294 | cost_test_list[i] = self.cost_function(Y_test, Y_pred_test) 295 | 296 | for t, theta in enumerate(self.Theta_L): 297 | self.logger.info('Theta: %s' % t) 298 | for theta_i in np.round(theta, 2): 299 | self.logger.info("%s" % str(theta_i)) 300 | 301 | #self.logger.info('i: %ld - cost: %ld' % (i, cost_list[i])) 302 | #self.logger.info('i: %ld - cost test: %ld' % (i, cost_test_list[i])) 303 | 304 | return cost_list, learning_rates, cost_test_list, rmse 305 | 306 | def test(self, data_train, target_train, epochs, learning_rate, momentum_rate, learning_reward, learning_penalty, data_test=None, target_test=None, data_val=None, target_val=None): 307 | 308 | self.epochs = epochs 309 | self.learning_rate = learning_rate 310 | self.momentum_rate = momentum_rate 311 | self.learning_reward = learning_reward 312 | self.learning_penalty = learning_penalty 313 | 314 | # Initialize Theta based on selected architecture 315 | # self.initialize_theta(data_train.shape[1], target_train.shape[1], hidden_unit_length_list) 316 | 317 | # Fit 318 | cost_list, learning_rates, cost_test_list, rmse = self.fit(data_train, target_train, X_test=data_test, Y_test=target_test) 319 | 320 | error = 0 321 | # Predict for test log 322 | plot_vals = [] 323 | a_N, Y_pred = self.predict(data_test) 324 | self.logger.info('###################################Testing Results###################################') 325 | self.logger.info('Given X:') 326 | for x in data_test[:5]: 327 | self.logger.info(x) 328 | for p in zip(target_test[:10], np.round(Y_pred[:10],6)): 329 | plot_vals.append(p) 330 | self.logger.info('Actual Y, Predicted Y:') 331 | for pv in plot_vals: 332 | self.logger.info("%s" % str(pv)) 333 | self.logger.info('Cost Efficiency on Test Set: %s' % str(self.cost_function(target_test , Y_pred))) 334 | sum_e = 0 335 | for j in range(len(target_test)): 336 | sum_e += pow((target_test[j] - Y_pred[j]), 2) 337 | if len(sum_e) > 1: 338 | sum_e = np.sum(sum_e) 339 | self.logger.info('Final Testing Sum Over Outputs: %s' % str(sum_e)) 340 | rmse_test_final = math.sqrt((1.0 / (2.0 * len(target_test))) * sum_e) 341 | self.logger.info('Final Testing RMSE: %s' % str(rmse_test_final)) 342 | 343 | error = 0 344 | #Predict for validation results 345 | 346 | if data_val is not None: 347 | plot_vals = [] 348 | va_N, vY_pred = self.predict(data_val) 349 | self.logger.info('###################################Validation Results###############################') 350 | self.logger.info('Given X:') 351 | for x in data_val[:5]: 352 | self.logger.info(x) 353 | for p in zip(target_val[:10], np.round(vY_pred[:10],6)): 354 | plot_vals.append(p) 355 | self.logger.info('Actual Y, Predicted Y:') 356 | for pv in plot_vals: 357 | self.logger.info((pv)) 358 | self.logger.info('Cost Efficiency on Validation Set: %s' % str(self.cost_function(target_val , vY_pred))) 359 | sum_e = 0 360 | for j in range(len(target_val)): 361 | sum_e += pow((target_val[j] - vY_pred[j]), 2) 362 | if len(sum_e) > 1: 363 | sum_e = np.sum(sum_e) 364 | self.logger.info('Final Validation Sum Over Outputs: %s' % str(sum_e)) 365 | rmse_val_final = math.sqrt((1.0 / (2.0 * len(target_val))) * sum_e) 366 | self.logger.info('Final Validation RMSE: %s' % str(rmse_val_final)) 367 | 368 | return target_test, Y_pred, cost_list, cost_test_list, learning_rates, rmse 369 | 370 | -------------------------------------------------------------------------------- /genetics/basic/geneticAlgorithms.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | ############################################################## 4 | # genetic_algorithms.py, general purpose genetic 5 | # algorithm in Python 6 | # 7 | # Written by Jared Smith and David Cunningham for COSC 427/527 8 | # at the University of Tennessee, Knoxville. 9 | ############################################################### 10 | # TODO: 11 | # - Generalize ff call to fitness function using kwargs argument 12 | # 13 | ############################################################### 14 | 15 | import random 16 | 17 | import bitstring as bs 18 | from scipy import stats 19 | import numpy as np 20 | 21 | import ffs 22 | 23 | 24 | class BaseGeneticAlgorithm(object): 25 | 26 | """ 27 | 28 | Basic class for executing a genetic algorithm. 29 | 30 | Parameters: 31 | l is the size of the bit strings (each bit is a gene) 32 | N is the size of the population 33 | G is the number of generations 34 | pr_mutation is the probability of mutation among the genes 35 | pr_crossover is the probability of crossover among the genes 36 | population is a list of bit strings (gene strings) of size N 37 | current_offspring is the current generation of children 38 | nruns is the number of runs to run the algorithm 39 | learn is a bool specifying whether to learn the offspring 40 | NG is the number of guesses to use when learning the offspring 41 | ff is the fitness function to use 42 | ce is a bool specifying whether to inflict a sudden change of 43 | environment on the final population 44 | rs is the seed for the random number generator; if left blank it will default to None. 45 | 46 | """ 47 | 48 | def __init__(self, args, logger): 49 | # Parameters of the algorithm 50 | self.args = args 51 | self.l = args.l 52 | self.N = args.N 53 | self.G = args.G 54 | self.pr_mutation = args.pm 55 | self.pr_crossover = args.pc 56 | random.seed(args.rs); #seed the RNG 57 | self.population = [] 58 | self.current_offspring = [] 59 | self.nruns = args.nruns 60 | self.NG = args.NG 61 | self.learn = args.learn 62 | self.ff = args.ff 63 | self.ce = args.ce 64 | self.max_recovery = 100 65 | 66 | # Helper objects 67 | self.logger = logger 68 | self.orig_fitness_vals = np.zeros((self.G + self.max_recovery, self.N)) 69 | self.norm_fitness_vals = np.zeros((self.G + self.max_recovery, self.N)) 70 | self.total_fitness_vals = np.zeros((self.G + self.max_recovery, self.N)) 71 | self.parents = [[None, None] for x in xrange(self.G + self.max_recovery)] 72 | self.pr_mut_dist = None 73 | self.pr_cr_dist = None 74 | self.env_state = 0 75 | 76 | # Statistics Objects 77 | self.avg_fitness_vals = np.zeros((self.nruns, 2, self.G + self.max_recovery)) 78 | self.best_fitness_vals = np.zeros((self.nruns, 2, self.G + self.max_recovery)) 79 | self.num_correct_bits = np.zeros((self.nruns, 2, self.G + self.max_recovery)) 80 | self.recovery_time = 0 81 | 82 | 83 | def initialize_algorithm(self): 84 | # Initialize the population 85 | self.logger.info("Initializing population...") 86 | self.initialize_pop() 87 | self.logger.info("Initialization Complete.") 88 | 89 | # Generate probablility distributions for mutation and crossover 90 | self.logger.info("Generating probability distributions for mutation and " + 91 | "crossover...") 92 | self.generate_prob_distributions() 93 | self.logger.info("Generated probability distributions for mutation and " + 94 | "crossover.") 95 | 96 | # Initialize the Population 97 | def initialize_pop(self): 98 | # Generate N random bitstrings 99 | self.population = [] 100 | self.current_offspring = [] 101 | for i in range(self.N): 102 | tmp_bitstring = ''.join(random.choice('01') for _ in range(self.l)) 103 | tmp_bitstring = bs.BitArray(bin=tmp_bitstring) 104 | self.population.append(tmp_bitstring) 105 | 106 | # Initialize the genetic environment 107 | def initialize_env(self): 108 | # Get the appropriate fitness function 109 | self.logger.info("Initializing environment...") 110 | if self.env_state != 0: 111 | self.recovery_time = 0 112 | self.logger.info("Initialized environment.") 113 | 114 | # Generate probability distributions for mutation and crossover 115 | def generate_prob_distributions(self): 116 | # xk is an array of size 2 (0, 1), that represents the possible 117 | # values we can get out of the distribution 118 | xk = np.arange(2) 119 | 120 | # pk1 and pk2 are the probabilities for getting the corresponding 121 | # xk value for mutation and crossover, respectively 122 | pk1 = (1 - self.pr_mutation, self.pr_mutation) 123 | pk2 = (1 - self.pr_crossover, self.pr_crossover) 124 | 125 | # Generate the object that will be used to get random numbers 126 | # according to each distribution. 127 | self.pr_mut_dist = stats.rv_discrete(name='pr_mut_dist', 128 | values=(xk, pk1)) 129 | self.pr_cr_dist = stats.rv_discrete(name='pr_cr_dist', 130 | values=(xk, pk2)) 131 | 132 | # Calculate the fitness of each individual of the population 133 | def fitness(self, g, nrun, ff=ffs.fitness_func_1): 134 | total_fitness = 0 135 | 136 | self.logger.debug("Getting fitness of generation %d" % g) 137 | 138 | # Step through each bitstring in the population 139 | for i, bitstring in enumerate(self.population): 140 | # Get the integer value of the string 141 | bit_sum = bitstring.uint 142 | self.logger.info("Sum of bitstring at %d of population: %d" % (i, bit_sum)) 143 | fitness_val = self.ff(bit_sum, self.l) 144 | self.orig_fitness_vals[g][i] = fitness_val 145 | self.logger.debug("Fitness Value at index %d in population: %lf" % (i, fitness_val)) 146 | total_fitness += fitness_val 147 | 148 | self.logger.debug("Total fitness from step 1: %lf" % total_fitness) 149 | if total_fitness > 0: 150 | self.norm_fitness_vals[g] = self.orig_fitness_vals[g] / total_fitness 151 | self.logger.debug("Sum of norm fitness vals: %lf" % np.sum(self.norm_fitness_vals[g])) 152 | 153 | prev_norm_fitness_val = 0 154 | for i in range(self.N): 155 | self.logger.debug("Normalized Fitness Value at index %d in population: %lf" % (i, self.norm_fitness_vals[g][i])) 156 | self.total_fitness_vals[g][i] = ( 157 | self.norm_fitness_vals[g][i] + prev_norm_fitness_val) 158 | prev_norm_fitness_val = self.total_fitness_vals[g][i] 159 | self.logger.debug("Total Fitness Value at index %d in population: %lf" % (i, self.total_fitness_vals[g][i])) 160 | 161 | # Select parents from population 162 | def select(self, g): 163 | rand_nums = np.random.uniform(0, 1, 2) 164 | 165 | # Select the first parent 166 | self.logger.info("Selecting the first parent...") 167 | prev_individual_fit = 0 168 | j = 0 169 | while True: 170 | if j >= self.N: 171 | j = 0 172 | rand_nums = np.random.uniform(0, 1, 2) 173 | 174 | individual_fit = self.total_fitness_vals[g][j] 175 | if rand_nums[0] < self.total_fitness_vals[g][0]: 176 | self.logger.debug("1: Prev_Individual Fit: %lf" % prev_individual_fit) 177 | self.logger.debug("1: Individual Fit: %lf" % individual_fit) 178 | self.logger.debug("1: Rand Num: %lf" % rand_nums[0]) 179 | self.logger.debug("1: Population at %d: %s" % (j, self.population[j].bin)) 180 | self.parents[g][0] = self.population[0] 181 | break 182 | 183 | if j != 0: 184 | self.logger.debug("1: Prev_Individual Fit: %lf" % prev_individual_fit) 185 | self.logger.debug("1: Individual Fit: %lf" % individual_fit) 186 | self.logger.debug("1: Rand Num: %lf" % rand_nums[0]) 187 | self.logger.debug("1: Population at %d: %s" % (j, self.population[j].bin)) 188 | 189 | if (prev_individual_fit <= rand_nums[0] <= individual_fit): 190 | self.logger.debug("1: selected individuval from population at %d: %s" % (j, self.population[j].bin)) 191 | self.parents[g][0] = self.population[j] 192 | self.logger.debug("1: parents[%d][0]: %s" % (g, str(self.parents[g][0]))) 193 | break 194 | prev_individual_fit = individual_fit 195 | j += 1 196 | self.logger.info("First parent has been selected.") 197 | 198 | # Select the second parent 199 | self.logger.info("Selecting the second parent...") 200 | prev_individual_fit = 0 201 | j = 0 202 | cycles = 0 203 | while True: 204 | if j >= self.N: 205 | cycles += j 206 | if cycles >= 100: 207 | self.parents[g][1] = self.parents[g][0] 208 | break 209 | else: 210 | j = 0 211 | rand_nums = np.random.uniform(0, 1, 2) 212 | 213 | individual_fit = self.total_fitness_vals[g][j] 214 | if rand_nums[1] < self.total_fitness_vals[g][0]: 215 | self.logger.debug("2: prev_individual fit: %lf" % prev_individual_fit) 216 | self.logger.debug("2: individual fit: %lf" % individual_fit) 217 | self.logger.debug("2: rand num: %lf" % rand_nums[1]) 218 | self.logger.debug("2: population at %d: %s" % (j, self.population[j].bin)) 219 | self.parents[g][1] = self.population[0] 220 | break 221 | 222 | if j != 0: 223 | self.logger.debug("2: prev_individual fit: %lf" % prev_individual_fit) 224 | self.logger.debug("2: individual fit: %lf" % individual_fit) 225 | self.logger.debug("2: rand num: %lf" % rand_nums[1]) 226 | self.logger.debug("2: population at %d: %s" % (j, self.population[j].bin)) 227 | 228 | if (prev_individual_fit <= rand_nums[1] <= individual_fit): 229 | if (self.population[j] != self.parents[g][0]): 230 | self.logger.debug("2: selected individuval from population at %d: %s" % (j, self.population[j].bin)) 231 | self.parents[g][1] = self.population[j] 232 | self.logger.debug("1: parents[%d][0]: %s" % (g, str(self.parents[g][1]))) 233 | break 234 | 235 | prev_individual_fit = individual_fit 236 | j += 1 237 | 238 | self.logger.info("Second parent has been selected.") 239 | 240 | # Mutate the parents 241 | def mutate(self, g): 242 | 243 | for parent in self.parents[g]: 244 | for index_bit in xrange(0, self.l): 245 | # Determine whether we will perform a mutation on the bit 246 | to_mutate = self.pr_mut_dist.rvs(size=1) 247 | 248 | # Mutate the bit if choice is 1, otherwise skip it 249 | if to_mutate: 250 | parent.invert(index_bit) 251 | 252 | 253 | # Crossover the parents 254 | def crossover(self, g): 255 | to_crossover = self.pr_cr_dist.rvs(size=1) 256 | 257 | # Crossover the parents if to_crossover is 1, otherwise copy the 258 | # parents exactly into the children 259 | if to_crossover: 260 | # Create empty children 261 | c1 = bs.BitArray(length=self.l) 262 | c2 = bs.BitArray(length=self.l) 263 | 264 | # Select the bit at which to crossover the parents 265 | crossover_bit = random.randint(0, self.l) 266 | 267 | # Perform the crossover 268 | c1.overwrite(self.parents[g][0][:crossover_bit], 0) 269 | c1.overwrite(self.parents[g][1][:(self.l - crossover_bit)], crossover_bit) 270 | c2.overwrite(self.parents[g][1][:crossover_bit], 0) 271 | c1.overwrite(self.parents[g][0][:(self.l - crossover_bit)], crossover_bit) 272 | 273 | self.current_offspring.append(c1) 274 | self.current_offspring.append(c2) 275 | else: 276 | self.current_offspring.append(self.parents[g][0]) 277 | self.current_offspring.append(self.parents[g][1]) 278 | 279 | # Learn the children on the fitness function. 280 | def learn_offspring(self, g, ff=ffs.fitness_func_1): 281 | # For every child in the current generation, iterate for NG guesses, 282 | # manipulating the child every time trying to find a best fitness, 283 | # and when the children are exhausted, the children will have been 284 | # fine tuned according to the original fitness function. 285 | for child in self.current_offspring: 286 | for guess in xrange(0, self.NG): 287 | current_child = child.copy() 288 | max_fitness = 0 289 | 290 | for ibit in xrange(0, self.l): 291 | if random.choice([0, 1]): 292 | if current_child[ibit]: 293 | current_child.set(False, ibit) 294 | elif not current_child[ibit]: 295 | current_child.set(True, ibit) 296 | 297 | bit_sum = current_child.uint 298 | current_fitness = ff(bit_sum, self.l) 299 | max_fitness = max(current_fitness, max_fitness) 300 | 301 | if current_fitness == max_fitness: 302 | child = current_child 303 | 304 | def compute_statistics(self, g, nrun): 305 | # Get the number of correct bits in the best individual 306 | index_bi = self.orig_fitness_vals[g].argmax() 307 | bi_bitstring = self.population[index_bi] 308 | individual_num_correct_bits = bi_bitstring.count(1) 309 | self.num_correct_bits[nrun][self.env_state][g] = individual_num_correct_bits 310 | 311 | # Get the numerical value of the best fitness 312 | self.best_fitness_vals[nrun][self.env_state][g] = self.orig_fitness_vals[g][index_bi] 313 | 314 | # Get the average value of the fitness 315 | self.avg_fitness_vals[nrun][self.env_state][g] = np.average(self.orig_fitness_vals[g]) 316 | 317 | # Logging computed statistics to stdout and to file 318 | self.logger.info("Number of Correct Bits in Best Individual: %d" 319 | % individual_num_correct_bits) 320 | self.logger.info("Fitness Value of Best Individual: %lf" 321 | % self.best_fitness_vals[nrun][self.env_state][g]) 322 | self.logger.info("Average Fitness Value of Generation: %lf" 323 | % self.avg_fitness_vals[nrun][self.env_state][g]) 324 | 325 | # Check if the population has recovered from an environment change 326 | def check_population_recovery(self, g, nrun): 327 | checks = [] 328 | checks.append((self.best_fitness_vals[nrun][1][g] > self.best_fitness_vals[nrun][0][self.G - 1])) 329 | checks.append((self.avg_fitness_vals[nrun][1][g] > self.avg_fitness_vals[nrun][0][self.G - 1])) 330 | for check in checks: 331 | print check 332 | if all(checks): 333 | return True 334 | 335 | # Run one generation 336 | def reproduce(self, nrun, g): 337 | self.logger.info("Running fitness function on generation " + 338 | "%d..." % g) 339 | self.fitness(g, nrun, self.ff) 340 | 341 | # Select the parents of the next generation and generate the 342 | # new offspring. 343 | for i in range(self.N / 2): 344 | self.logger.info("Selecting the parents of generation %d..." 345 | % g) 346 | self.select(g) 347 | self.logger.info("Selection of the parents of generation " + 348 | "%d finished." % g) 349 | 350 | self.logger.info("Performing crossover and mutation of " + 351 | "the parent's offspring from generation " + 352 | "%d..." % g) 353 | self.crossover(g) 354 | self.mutate(g) 355 | self.logger.info("Crossover and mutation of the " + 356 | "the parent's offspring of " + 357 | " generation %d finished.", g) 358 | 359 | # Learn the offspring if specified 360 | if self.learn: 361 | self.logger.info("Performing learning on the offspring" + 362 | " of generation %d..." % g) 363 | self.learn_offspring(g, self.ff) 364 | self.logger.info("Learning on the offspring" + 365 | " of generation %d finished." % g) 366 | 367 | # Compute statistics for this generation 368 | self.logger.info("Computing statistics for Run %d, Generation %d..." % (nrun, g)) 369 | self.compute_statistics(g, nrun) 370 | self.logger.info("Computation of statistics finished for Run %d, Generation %d." % (nrun, g)) 371 | 372 | # Replace the old population with the new population 373 | self.population = self.current_offspring 374 | self.current_offspring = [] 375 | 376 | # Run through the total runs specified 377 | def run(self): 378 | for nrun in range(self.nruns): 379 | self.logger.info("Starting run %d..." % nrun) 380 | self.initialize_algorithm() 381 | 382 | self.env_state = 0 383 | self.ff = ffs.fitness_func_1 384 | self.logger.info("Fitness Function before normal generation run: %s" % str(self.ff.__name__)) 385 | 386 | for g in range(self.G): 387 | self.logger.info("Generation %d running..." % g) 388 | self.reproduce(nrun, g) 389 | self.logger.info("Generation %d finished." % g) 390 | 391 | if self.ce: 392 | self.logger.info("Running Sudden change in environment test starting at generation %d..." % g) 393 | self.env_state = 1 394 | self.initialize_env() 395 | self.ff = ffs.fitness_func_2 396 | self.logger.info("Fitness Function before changed environment generation run: %s" % str(self.ff.__name__)) 397 | 398 | while True: 399 | g += 1 400 | self.recovery_time += 1 401 | self.logger.info("Recovery Time: %d, Max Recovery: %d, Generation %d In Changed Environment" % (self.recovery_time, self.max_recovery, g)) 402 | if self.recovery_time >= self.max_recovery: 403 | self.logger.info("Population has not recovered after %d iterations. Quitting now." % self.recovery_time) 404 | break 405 | self.reproduce(nrun, g) 406 | if self.check_population_recovery(g, nrun): 407 | self.logger.info("Population has recovered after %d iterations." % self.recovery_time) 408 | break 409 | self.logger.info("Population has not recovered...continuing generation.") 410 | 411 | self.logger.info("Finished run %d." % nrun) 412 | 413 | return (self.avg_fitness_vals, self.best_fitness_vals, 414 | self.num_correct_bits) 415 | --------------------------------------------------------------------------------