├── LICENSE ├── Makefile ├── README.md ├── debian.sh ├── debian ├── changelog ├── compat ├── control ├── copyright ├── docs ├── libdeep-dev.dirs ├── libdeep-dev.install ├── libdeep0-dev.links ├── libdeep0.dirs ├── libdeep0.install ├── libdeep0.links └── rules ├── edit.sh ├── examples ├── concreteslump │ ├── Makefile │ ├── concreteslump.c │ ├── slump_test.data │ └── slump_test.names └── facerec │ ├── Makefile │ ├── facerec.c │ └── images │ ├── face1.a.png │ ├── face1.b.png │ ├── face1.c.png │ ├── face10.a.png │ ├── face10.b.png │ ├── face11.a.png │ ├── face11.b.png │ ├── face11.c.png │ ├── face12.a.png │ ├── face12.b.png │ ├── face12.c.png │ ├── face12.d.png │ ├── face13.a.png │ ├── face13.b.png │ ├── face13.c.png │ ├── face13.d.png │ ├── face14.a.png │ ├── face14.b.png │ ├── face14.c.png │ ├── face15.a.png │ ├── face15.b.png │ ├── face15.c.png │ ├── face15.d.png │ ├── face16.a.png │ ├── face16.b.png │ ├── face16.c.png │ ├── face16.d.png │ ├── face17.a.png │ ├── face17.b.png │ ├── face17.c.png │ ├── face17.d.png │ ├── face18.a.png │ ├── face18.b.png │ ├── face18.c.png │ ├── face18.d.png │ ├── face2.a.png │ ├── face2.b.png │ ├── face2.c.png │ ├── face2.d.png │ ├── face3.a.png │ ├── face3.b.png │ ├── face3.c.png │ ├── face3.d.png │ ├── face4.a.png │ ├── face4.b.png │ ├── face5.a.png │ ├── face5.b.png │ ├── face5.c.png │ ├── face6.a.png │ ├── face6.b.png │ ├── face6.c.png │ ├── face7.a.png │ ├── face7.b.png │ ├── face7.c.png │ ├── face7.d.png │ ├── face8.a.png │ ├── face8.b.png │ ├── face8.c.png │ ├── face9.a.png │ └── face9.b.png ├── fedora.sh ├── img ├── logo-14.png ├── logo-192.png └── logo-64.png ├── libtest └── main.c ├── man └── libdeep.1.gz ├── rpmpackage ├── libdeep.conf └── libdeep.spec ├── src ├── backprop.c ├── backprop.h ├── backprop_neuron.c ├── backprop_neuron.h ├── deeplearn.c ├── deeplearn.h ├── deeplearn_images.c ├── deeplearn_images.h ├── deeplearn_random.c ├── deeplearn_random.h └── globals.h └── unittests ├── maintest.c ├── tests_backprop.c ├── tests_backprop.h ├── tests_deeplearn.c ├── tests_deeplearn.h ├── tests_images.c ├── tests_images.h ├── tests_random.c └── tests_random.h /LICENSE: -------------------------------------------------------------------------------- 1 | libdeep - a library for deep learning 2 | Copyright (C) 2013 Bob Mottram 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 3. Neither the name of the University nor the names of its contributors 13 | may be used to endorse or promote products derived from this software 14 | without specific prior written permission. 15 | . 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 20 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | APP=libdeep 2 | VERSION=1.00 3 | RELEASE=1 4 | SONAME=$(APP).so.0 5 | LIBNAME=$(APP)-$(VERSION).so.0.0.$(RELEASE) 6 | USRBASE=/usr 7 | 8 | all: 9 | gcc -c -std=c99 -pedantic -fPIC -o $(APP)_neuron.o src/backprop_neuron.c -Isrc -lm -fopenmp 10 | gcc -c -std=c99 -pedantic -fPIC -o $(APP).o src/backprop.c -Isrc -lm -fopenmp 11 | gcc -c -std=c99 -pedantic -fPIC -o $(APP)learn.o src/deeplearn.c -Isrc -lm -fopenmp 12 | gcc -c -std=c99 -pedantic -fPIC -o $(APP)random.o src/deeplearn_random.c -Isrc -lm 13 | gcc -c -std=c99 -pedantic -fPIC -o $(APP)images.o src/deeplearn_images.c -Isrc -lm -lpng 14 | gcc -shared -Wl,-soname,$(SONAME) -o $(LIBNAME) $(APP).o $(APP)_neuron.o $(APP)learn.o $(APP)random.o $(APP)images.o 15 | # objdump -p ${LIBNAME} | sed -n -e's/^[[:space:]]*SONAME[[:space:]]*//p' | sed -e's/\([0-9]\)\.so\./\1-/; s/\.so\.//' 16 | 17 | debug: 18 | gcc -c -std=c99 -pedantic -fPIC -g -o $(APP).o src/backprop.c -Isrc -lm -fopenmp 19 | gcc -c -std=c99 -pedantic -fPIC -g -o $(APP)_neuron.o src/backprop_neuron.c -Isrc -lm -fopenmp 20 | gcc -c -std=c99 -pedantic -fPIC -g -o $(APP)learn.o src/deeplearn.c -Isrc -lm -fopenmp 21 | gcc -c -std=c99 -pedantic -fPIC -g -o $(APP)random.o src/deeplearn_random.c -Isrc -lm 22 | gcc -c -std=c99 -pedantic -fPIC -g -o $(APP)images.o src/deeplearn_images.c -Isrc -lm -lpng 23 | gcc -shared -Wl,-soname,$(SONAME) -o $(LIBNAME) $(APP).o $(APP)_neuron.o $(APP)learn.o $(APP)random.o $(APP)images.o 24 | 25 | tests: 26 | gcc -Wall -std=c99 -pedantic -g -o $(APP)_tests unittests/*.c src/*.c -Isrc -Iunittests -lm -lpng -fopenmp 27 | 28 | ltest: 29 | gcc -Wall -std=c99 -pedantic -g -o $(APP) libtest/*.c -ldeep -lm -lpng -fopenmp 30 | 31 | source: 32 | tar -cvzf ../$(APP)_$(VERSION).orig.tar.gz ../$(APP)-$(VERSION) --exclude=.bzr 33 | 34 | install: 35 | mkdir -m 755 -p $(USRBASE)/lib 36 | cp $(LIBNAME) $(USRBASE)/lib 37 | cp man/$(APP).1.gz $(USRBASE)/share/man/man1 38 | mkdir -m 755 -p $(USRBASE)/include/$(APP) 39 | cp src/*.h $(USRBASE)/include/$(APP) 40 | chmod 755 $(USRBASE)/lib/$(LIBNAME) 41 | chmod 644 $(USRBASE)/include/$(APP)/*.h 42 | chmod 644 $(USRBASE)/share/man/man1/$(APP).1.gz 43 | ln -sf $(USRBASE)/lib/$(LIBNAME) $(USRBASE)/lib/$(SONAME) 44 | ln -sf $(USRBASE)/lib/$(LIBNAME) $(USRBASE)/lib/$(APP).so 45 | ldconfig 46 | 47 | clean: 48 | rm -f $(LIBNAME) $(APP) $(APP).so.* $(APP).o $(APP)_tests $(APP)-* *.dot 49 | rm -f *.dat *.png *.txt *.rb agent.c agent 50 | rm -f \#* \.#* debian/*.substvars debian/*.log *.so.0.0.1 *.o 51 | rm -rf deb.* debian/$(APP)0 debian/$(APP)0-dev 52 | rm ../$(APP)*.deb ../$(APP)*.changes ../$(APP)*.asc ../$(APP)*.dsc ../$(APP)_$(VERSION)*.gz 53 | 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libdeep 2 | ======= 3 | 4 | A deep learning library for C/C++ 5 | 6 | License: BSD 7 | 8 | For usage information see the man page. 9 | 10 | man libdeep 11 | -------------------------------------------------------------------------------- /debian.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | APP=libdeep 4 | VERSION=1.00 5 | ARCH_TYPE=`uname -m` 6 | 7 | if [ $ARCH_TYPE == "x86_64" ]; then 8 | ARCH_TYPE="amd64" 9 | fi 10 | 11 | if [ $ARCH_TYPE == "i686" ]; then 12 | ARCH_TYPE="i386" 13 | fi 14 | if [ $ARCH_TYPE == "armv5tel" ]; then 15 | ARCH_TYPE="armel" 16 | fi 17 | # Create a source archive 18 | make clean 19 | make source 20 | 21 | # Build the package 22 | fakeroot dpkg-buildpackage -b 23 | 24 | # sign files 25 | gpg -ba ../${APP}0-dev_${VERSION}-1_${ARCH_TYPE}.deb 26 | gpg -ba ../${APP}0_${VERSION}-1_${ARCH_TYPE}.deb 27 | gpg -ba ../${APP}_${VERSION}.orig.tar.gz 28 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | libdeep (1.00-1) unstable; urgency=low 2 | 3 | * Initial release 4 | 5 | -- Bob Mottram (4096 bits) Sat, 5 Jan 2013 17:20:00 +0100 6 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: libdeep 2 | Priority: extra 3 | Maintainer: Bob Mottram 4 | Build-Depends: debhelper (>= 7.0.50~) 5 | Standards-Version: 3.8.4 6 | Section: libs 7 | Homepage: https://launchpad.net/libdeep 8 | Vcs-Bzr: https://code.launchpad.net/libdeep 9 | Vcs-Browser: http://bazaar.launchpad.net/~fuzzgun/libdeep/trunk/files 10 | 11 | Package: libdeep0-dev 12 | Section: libdevel 13 | Architecture: any 14 | Depends: libdeep0 (= ${binary:Version}), gnuplot 15 | Description: Headers and manual for the libdeep deep learning library 16 | The aim of libdeep is to make using deep learning easy to include 17 | within any C/C++ application. 18 | 19 | Package: libdeep0 20 | Section: libs 21 | Architecture: any 22 | Depends: ${shlibs:Depends}, ${misc:Depends}, gnuplot 23 | Description: Library for genetic programming 24 | The aim of libdeep is to make using deep learning easy to include 25 | within any C/C++ application. 26 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://dep.debian.net/deps/dep5 2 | Upstream-Name: libdeep 3 | Source: https://code.launchpad.net/libdeep 4 | 5 | Files: * 6 | Copyright: 2013 Bob Mottram 7 | License: BSD-3-Clause 8 | 9 | Files: debian/* 10 | Copyright: 2013 Bob Mottram 11 | License: BSD-3-Clause 12 | 13 | License: BSD-3-Clause 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions 16 | are met: 17 | 1. Redistributions of source code must retain the above copyright 18 | notice, this list of conditions and the following disclaimer. 19 | 2. Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 3. Neither the name of the University nor the names of its contributors 23 | may be used to endorse or promote products derived from this software 24 | without specific prior written permission. 25 | . 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 30 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README 2 | -------------------------------------------------------------------------------- /debian/libdeep-dev.dirs: -------------------------------------------------------------------------------- 1 | usr/lib 2 | usr/include/libdeep 3 | -------------------------------------------------------------------------------- /debian/libdeep-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/libdeep/* 2 | usr/lib/lib*.a 3 | usr/lib/lib*.so 4 | usr/lib/lib*.so.* 5 | usr/lib/pkgconfig/* 6 | usr/lib/*.la 7 | usr/share/pkgconfig/* 8 | -------------------------------------------------------------------------------- /debian/libdeep0-dev.links: -------------------------------------------------------------------------------- 1 | usr/lib/libdeep-1.00.so.0.0.1 usr/lib/libdeep.so 2 | -------------------------------------------------------------------------------- /debian/libdeep0.dirs: -------------------------------------------------------------------------------- 1 | usr/lib 2 | -------------------------------------------------------------------------------- /debian/libdeep0.install: -------------------------------------------------------------------------------- 1 | usr/lib/lib*.so.* 2 | usr/lib/lib*.so 3 | -------------------------------------------------------------------------------- /debian/libdeep0.links: -------------------------------------------------------------------------------- 1 | usr/lib/libdeep-1.00.so.0.0.1 usr/lib/libdeep.so.0 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | APP=libdeep 4 | VERSION=1.00 5 | RELEASE=1 6 | SONAME=$(APP).so.0 7 | LIBNAME=$(APP)-$(VERSION).so.0.0.$(RELEASE) 8 | USRBASE=/usr 9 | 10 | library = $(CURDIR)/$(LIBNAME) 11 | libraryso = $(CURDIR)/$(SONAME) 12 | header = $(CURDIR)/src/*.h 13 | man_page = $(CURDIR)/man/$(APP).1.gz 14 | 15 | DEST_INCLUDE = $(CURDIR)/debian/$(APP)0-dev$(USRBASE)/include/$(APP) 16 | DEST_LIB = $(CURDIR)/debian/$(APP)0$(USRBASE)/lib 17 | DEST_MAN = $(CURDIR)/debian/$(APP)0-dev$(USRBASE)/share/man/man1 18 | 19 | CPPFLAGS:=$(shell dpkg-buildflags --get CPPFLAGS) 20 | CFLAGS:=$(shell dpkg-buildflags --get CFLAGS) 21 | CXXFLAGS:=$(shell dpkg-buildflags --get CXXFLAGS) 22 | LDFLAGS:=$(shell dpkg-buildflags --get LDFLAGS) 23 | 24 | build: build-stamp 25 | gcc -c -std=c99 -pedantic -fPIC $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $(APP).o src/backprop.c -Isrc -lm -fopenmp 26 | gcc -c -std=c99 -pedantic -fPIC $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $(APP)_neuron.o src/backprop_neuron.c -Isrc -lm -fopenmp 27 | gcc -c -std=c99 -pedantic -fPIC $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $(APP)learn.o src/deeplearn.c -Isrc -lm -fopenmp 28 | gcc -c -std=c99 -pedantic -fPIC $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $(APP)random.o src/deeplearn_random.c -Isrc -lm 29 | gcc -c -std=c99 -pedantic -fPIC $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $(APP)images.o src/deeplearn_images.c -Isrc -lm -lpng 30 | gcc -shared -Wl,-soname,$(SONAME) $(CFLAGS) $(LDFLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $(LIBNAME) $(APP).o $(APP)_neuron.o $(APP)learn.o $(APP)random.o $(APP)images.o 31 | 32 | build-stamp: 33 | dh_testdir 34 | touch build-stamp 35 | 36 | clean: 37 | dh_testdir 38 | dh_testroot 39 | rm -f build-stamp 40 | dh_clean 41 | 42 | install: build clean $(library) $(man_page) 43 | dh_testdir 44 | dh_testroot 45 | dh_prep 46 | dh_installdirs 47 | 48 | mkdir -m 755 -p $(DEST_LIB) 49 | mkdir -m 755 -p $(DEST_INCLUDE) 50 | mkdir -m 755 -p $(DEST_MAN) 51 | 52 | install -m 755 --strip $(library) $(DEST_LIB) 53 | install -m 644 $(man_page) $(DEST_MAN) 54 | install -m 644 $(header) $(DEST_INCLUDE) 55 | 56 | binary-indep: build install 57 | dh_makeshlibs 58 | dh_shlibdeps 59 | dh_testdir 60 | dh_testroot 61 | dh_installchangelogs 62 | dh_installdocs 63 | dh_installexamples 64 | dh_installman 65 | dh_link 66 | dh_compress 67 | dh_fixperms 68 | dh_installdeb 69 | dh_gencontrol 70 | dh_md5sums 71 | dh_builddeb 72 | 73 | binary-arch: build install 74 | 75 | binary: binary-indep binary-arch 76 | .PHONY: build clean binary-indep binary-arch binary install 77 | -------------------------------------------------------------------------------- /edit.sh: -------------------------------------------------------------------------------- 1 | emacs -nw *.sh templates/*.txt README.md LICENSE examples/concreteslump/*.c examples/facerec/*.c libtest/*.c unittests/*.c unittests/*.h man/* debian/* rpmpackage/*.spec rpmpackage/*.conf src/*.c src/*.h Makefile 2 | -------------------------------------------------------------------------------- /examples/concreteslump/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | gcc -Wall -ansi -pedantic -o concreteslump concreteslump.c -ldeep -lm -lpng -fopenmp 4 | 5 | debug: 6 | gcc -Wall -ansi -pedantic -g -o concreteslump concreteslump.c -ldeep -lm -lpng -fopenmp 7 | 8 | clean: 9 | rm -f *.o concreteslump 10 | -------------------------------------------------------------------------------- /examples/concreteslump/concreteslump.c: -------------------------------------------------------------------------------- 1 | /* 2 | Concrete slump demo 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include "libdeep/globals.h" 32 | #include "libdeep/deeplearn.h" 33 | 34 | #define MAX_EXAMPLES 200 35 | #define MAX_TEST_EXAMPLES 20 36 | #define MAX_FIELDS 12 37 | 38 | float data_max_value[MAX_FIELDS]; 39 | float data_min_value[MAX_FIELDS]; 40 | float concrete_data[MAX_EXAMPLES*MAX_FIELDS]; 41 | float test_data[MAX_TEST_EXAMPLES*MAX_FIELDS]; 42 | float * current_data_set; 43 | 44 | int no_of_examples = 0; 45 | int no_of_test_examples = 0; 46 | int fields_per_example = 0; 47 | int no_of_inputs = 0; 48 | 49 | deeplearn learner; 50 | 51 | /* create a test data set from the original data. 52 | The test data can be used to calculate a final fitness 53 | value, because it was not seen during training and so 54 | provides an indication of how well the system has generalised */ 55 | static int create_test_data(float * training_data, 56 | int * no_of_training_examples, 57 | int fields_per_example, 58 | float * test_data) 59 | { 60 | int i,j,index; 61 | int no_of_test_examples = 0; 62 | unsigned int random_seed = (unsigned int)time(NULL); 63 | 64 | for (i = 0; i < MAX_TEST_EXAMPLES; i++) { 65 | /* pick an example from the loaded data set */ 66 | index = rand_num(&random_seed)%(*no_of_training_examples); 67 | 68 | /* increase the number of test examples */ 69 | for (j = 0; j < fields_per_example; j++) { 70 | test_data[no_of_test_examples*fields_per_example + j] = 71 | training_data[index*fields_per_example + j]; 72 | } 73 | no_of_test_examples++; 74 | 75 | /* reshuffle the original data set */ 76 | for (j = index+1; j < (*no_of_training_examples); j++) { 77 | training_data[(j-1)*fields_per_example + j] = 78 | training_data[j*fields_per_example + j]; 79 | } 80 | /* decrease the number of training data examples */ 81 | *no_of_training_examples = *no_of_training_examples - 1; 82 | } 83 | 84 | return no_of_test_examples; 85 | } 86 | 87 | 88 | static int load_data(char * filename, float * training_data, 89 | int max_examples, 90 | int * fields_per_example) 91 | { 92 | int i, field_number, ctr, examples_loaded = 0; 93 | FILE * fp; 94 | char line[2000],valuestr[256],*retval; 95 | float value; 96 | int training_data_index = 0; 97 | 98 | for (i = 0; i < MAX_FIELDS; i++) { 99 | data_min_value[i] = 9999; 100 | data_max_value[i] = -9999; 101 | } 102 | 103 | fp = fopen(filename,"r"); 104 | if (!fp) return 0; 105 | 106 | while (!feof(fp)) { 107 | retval = fgets(line,1999,fp); 108 | if (retval) { 109 | if (strlen(line)>0) { 110 | field_number = 0; 111 | ctr = 0; 112 | for (i = 0; i < strlen(line); i++) { 113 | if ((line[i]==',') || 114 | (i==strlen(line)-1)) { 115 | if (i==strlen(line)-1) { 116 | valuestr[ctr++]=line[i]; 117 | } 118 | valuestr[ctr]=0; 119 | ctr=0; 120 | 121 | /* get the value from the string */ 122 | value = 0; 123 | if (valuestr[0]!='?') { 124 | if ((valuestr[0]>='0') && 125 | (valuestr[0]<='9')) { 126 | value = atof(valuestr); 127 | } 128 | } 129 | 130 | /* insert value into the array */ 131 | training_data[training_data_index] = value; 132 | if (value > data_max_value[field_number]) { 133 | data_max_value[field_number] = value; 134 | } 135 | if (value < data_min_value[field_number]) { 136 | data_min_value[field_number] = value; 137 | } 138 | field_number++; 139 | training_data_index++; 140 | } 141 | else { 142 | /* update the value string */ 143 | valuestr[ctr++] = line[i]; 144 | } 145 | } 146 | *fields_per_example = field_number; 147 | examples_loaded++; 148 | if (examples_loaded >= max_examples) { 149 | fclose(fp); 150 | return examples_loaded; 151 | } 152 | } 153 | } 154 | } 155 | 156 | fclose(fp); 157 | 158 | return examples_loaded; 159 | } 160 | 161 | /* returns a normalised version of a value suitable for inserting 162 | into a neuron value */ 163 | float data_to_neuron_value(int field_number, 164 | float value) 165 | { 166 | float range = 167 | data_max_value[field_number] - 168 | data_min_value[field_number]; 169 | 170 | if (range > 0) { 171 | return 0.25f + 172 | ((value - data_min_value[field_number])*0.5f/range); 173 | } 174 | return 0.5f; 175 | } 176 | 177 | /* converts a neuron value into a data value within the expected range */ 178 | float neuron_value_to_data(int field_number, 179 | float neuron_value) 180 | { 181 | float range = 182 | data_max_value[field_number] - 183 | data_min_value[field_number]; 184 | 185 | if (range > 0) { 186 | return data_min_value[field_number] + 187 | ((neuron_value - 0.25f)*range); 188 | } 189 | return 0; 190 | } 191 | 192 | /* returns the performance on the test data set as a percentage value */ 193 | float get_performance(deeplearn * learner, 194 | float * data_set, int data_set_size) 195 | { 196 | int index,i,hits=0; 197 | float reference, v, error_percent, total_error=0, average_error; 198 | 199 | for (index = 0; index < data_set_size; index++) { 200 | /* load the ingredients into the network inputs */ 201 | for (i = 1; i < fields_per_example-3; i++) { 202 | v = data_set[index*fields_per_example + i]; 203 | v = data_to_neuron_value(i, v); 204 | deeplearn_set_input(learner, i-1, v); 205 | } 206 | 207 | deeplearn_feed_forward(learner); 208 | 209 | for (i = 0; i < 3; i++) { 210 | reference = data_set[index*fields_per_example + 211 | fields_per_example - 3 + i]; 212 | v = neuron_value_to_data(fields_per_example - 3 + i, 213 | deeplearn_get_output(learner,i)); 214 | if (reference != 0) { 215 | error_percent = (v-reference)/reference; 216 | total_error += error_percent*error_percent; 217 | hits++; 218 | } 219 | } 220 | } 221 | if (hits > 0) { 222 | average_error = (float)sqrt(total_error / hits) * 100; 223 | if (average_error > 100) average_error = 100; 224 | return 100 - average_error; 225 | } 226 | return 0; 227 | } 228 | 229 | /* train the deep learner */ 230 | static void concreteslump_training() 231 | { 232 | int no_of_hiddens = 4*4; 233 | int hidden_layers=1; 234 | int no_of_outputs=3; 235 | int itt,i,index; 236 | unsigned int random_seed = 123; 237 | char filename[256]; 238 | char title[256]; 239 | char weights_filename[256]; 240 | int weights_image_width = 480; 241 | int weights_image_height = 800; 242 | float error_threshold[] = { 0.008f, 0.001f }; 243 | float v; 244 | const int logging_interval = 400000; 245 | 246 | current_data_set = concrete_data; 247 | 248 | sprintf(weights_filename,"%s","weights.png"); 249 | sprintf(title, "%s", "Concrete Slump Training"); 250 | 251 | /* create the learner */ 252 | deeplearn_init(&learner, 253 | no_of_inputs, no_of_hiddens, 254 | hidden_layers, 255 | no_of_outputs, 256 | error_threshold, 257 | &random_seed); 258 | 259 | /* set learning rate */ 260 | deeplearn_set_learning_rate(&learner, 0.2f); 261 | 262 | /* perform pre-training with an autocoder */ 263 | itt = 0; 264 | while (learner.current_hidden_layer < hidden_layers) { 265 | /* index of the example to be used */ 266 | index = rand_num(&random_seed)%no_of_examples; 267 | 268 | /* load the ingredients into the network inputs */ 269 | for (i = 1; i < fields_per_example-3; i++) { 270 | v = current_data_set[index*fields_per_example + i]; 271 | v = data_to_neuron_value(i, v); 272 | deeplearn_set_input(&learner, i-1, v); 273 | } 274 | 275 | /* set the desired outputs */ 276 | for (i = 0; i < 3; i++) { 277 | v = current_data_set[index*fields_per_example + 278 | fields_per_example - 3 + i]; 279 | v = data_to_neuron_value(fields_per_example - 3 + i,v); 280 | deeplearn_set_output(&learner, i, v); 281 | } 282 | 283 | /* update the learner */ 284 | deeplearn_update(&learner); 285 | 286 | itt++; 287 | if ((itt % logging_interval == 0) && (itt>0)) { 288 | printf("%d: %.5f\n", 289 | learner.current_hidden_layer, learner.BPerror); 290 | 291 | /* save a graph */ 292 | sprintf(filename,"%s","training_error.png"); 293 | deeplearn_plot_history(&learner, 294 | filename, title, 295 | 1024, 480); 296 | /* plot the weights */ 297 | if ((&learner)->autocoder != 0) { 298 | bp_plot_weights((&learner)->autocoder, 299 | weights_filename, 300 | weights_image_width, 301 | weights_image_height, 302 | 0); 303 | } 304 | } 305 | } 306 | 307 | /* save a graph */ 308 | sprintf(filename,"%s","training_error.png"); 309 | deeplearn_plot_history(&learner, 310 | filename, title, 311 | 1024, 480); 312 | /* plot the weights */ 313 | bp_plot_weights((&learner)->net, 314 | weights_filename, 315 | weights_image_width, 316 | weights_image_height, 317 | 0); 318 | 319 | /* perform the final training between the last 320 | hidden layer and the outputs */ 321 | while (learner.training_complete == 0) { 322 | /* index of the example to be used */ 323 | index = rand_num(&random_seed)%no_of_examples; 324 | 325 | /* load the ingredients into the network inputs */ 326 | for (i = 1; i < fields_per_example-3; i++) { 327 | v = current_data_set[index*fields_per_example + i]; 328 | v = data_to_neuron_value(i, v); 329 | deeplearn_set_input(&learner, i-1, v); 330 | } 331 | 332 | /* set the desired outputs */ 333 | for (i = 0; i < 3; i++) { 334 | v = current_data_set[index*fields_per_example + 335 | fields_per_example - 3 + i]; 336 | v = data_to_neuron_value(fields_per_example - 3 + i,v); 337 | deeplearn_set_output(&learner, i, v); 338 | } 339 | 340 | /* update the learner */ 341 | deeplearn_update(&learner); 342 | 343 | itt++; 344 | if ((itt % logging_interval == 0) && (itt>0)) { 345 | printf("Final: %.5f %.2f%%/%.2f%%\n", learner.BPerror, 346 | get_performance(&learner, 347 | concrete_data,no_of_examples), 348 | get_performance(&learner, 349 | test_data,no_of_test_examples)); 350 | 351 | /* save a graph */ 352 | sprintf(filename,"%s","training_error.png"); 353 | deeplearn_plot_history(&learner, 354 | filename, title, 355 | 1024, 480); 356 | /* plot the weights */ 357 | if ((&learner)->autocoder!=0) { 358 | bp_plot_weights((&learner)->autocoder, 359 | weights_filename, 360 | weights_image_width, 361 | weights_image_height, 362 | 0); 363 | } 364 | } 365 | } 366 | 367 | /* save a graph */ 368 | sprintf(filename,"%s","training_error.png"); 369 | deeplearn_plot_history(&learner, 370 | filename, title, 371 | 1024, 480); 372 | /* plot the weights */ 373 | bp_plot_weights((&learner)->net, 374 | weights_filename, 375 | weights_image_width, 376 | weights_image_height, 377 | 0); 378 | 379 | printf("Training performance: %.2f%%/nTest Performance: %.2f%%\n", 380 | get_performance(&learner,concrete_data,no_of_examples), 381 | get_performance(&learner,test_data,no_of_test_examples)); 382 | } 383 | 384 | 385 | int main(int argc, char* argv[]) 386 | { 387 | /* 388 | char * sensor_names[] = { 389 | "Cement", 390 | "Slag", 391 | "Fly Ash", 392 | "Water", 393 | "Sand", 394 | "Coarse Aggr.", 395 | "Fine Aggr." 396 | }; 397 | char * actuator_names[] = { 398 | "Slump", "Flow", "Compressive Strength" 399 | }; 400 | */ 401 | 402 | /* load the data */ 403 | no_of_examples = 404 | load_data("slump_test.data", 405 | concrete_data, MAX_EXAMPLES, 406 | &fields_per_example); 407 | 408 | /* create a test data set */ 409 | no_of_test_examples = 410 | create_test_data(concrete_data, 411 | &no_of_examples, 412 | fields_per_example, 413 | test_data); 414 | 415 | no_of_inputs = fields_per_example-4; 416 | 417 | printf("Number of training examples: %d\n",no_of_examples); 418 | printf("Number of test examples: %d\n",no_of_test_examples); 419 | printf("Number of fields: %d\n",fields_per_example); 420 | 421 | 422 | concreteslump_training(); 423 | 424 | return 1; 425 | } 426 | 427 | -------------------------------------------------------------------------------- /examples/concreteslump/slump_test.data: -------------------------------------------------------------------------------- 1 | 1,273,82,105,210,9,904,680,23,62,34.99 2 | 2,163,149,191,180,12,843,746,0,20,41.14 3 | 3,162,148,191,179,16,840,743,1,20,41.81 4 | 4,162,148,190,179,19,838,741,3,21.5,42.08 5 | 5,154,112,144,220,10,923,658,20,64,26.82 6 | 6,147,89,115,202,9,860,829,23,55,25.21 7 | 7,152,139,178,168,18,944,695,0,20,38.86 8 | 8,145,0,227,240,6,750,853,14.5,58.5,36.59 9 | 9,152,0,237,204,6,785,892,15.5,51,32.71 10 | 10,304,0,140,214,6,895,722,19,51,38.46 11 | 11,145,106,136,208,10,751,883,24.5,61,26.02 12 | 12,148,109,139,193,7,768,902,23.75,58,28.03 13 | 13,142,130,167,215,6,735,836,25.5,67,31.37 14 | 14,354,0,0,234,6,959,691,17,54,33.91 15 | 15,374,0,0,190,7,1013,730,14.5,42.5,32.44 16 | 16,159,116,149,175,15,953,720,23.5,54.5,34.05 17 | 17,153,0,239,200,6,1002,684,12,35,28.29 18 | 18,295,106,136,206,11,750,766,25,68.5,41.01 19 | 19,310,0,143,168,10,914,804,20.5,48.2,49.3 20 | 20,296,97,0,219,9,932,685,15,48.5,29.23 21 | 21,305,100,0,196,10,959,705,20,49,29.77 22 | 22,310,0,143,218,10,787,804,13,46,36.19 23 | 23,148,180,0,183,11,972,757,0,20,18.52 24 | 24,146,178,0,192,11,961,749,18,46,17.19 25 | 25,142,130,167,174,11,883,785,0,20,36.72 26 | 26,140,128,164,183,12,871,775,23.75,53,33.38 27 | 27,308,111,142,217,10,783,686,25,70,42.08 28 | 28,295,106,136,208,6,871,650,26.5,70,39.4 29 | 29,298,107,137,201,6,878,655,16,26,41.27 30 | 30,314,0,161,207,6,851,757,21.5,64,41.14 31 | 31,321,0,164,190,5,870,774,24,60,45.82 32 | 32,349,0,178,230,6,785,721,20,68.5,43.95 33 | 33,366,0,187,191,7,824,757,24.75,62.7,52.65 34 | 34,274,89,115,202,9,759,827,26.5,68,35.52 35 | 35,137,167,214,226,6,708,757,27.5,70,34.45 36 | 36,275,99,127,184,13,810,790,25.75,64.5,43.54 37 | 37,252,76,97,194,8,835,821,23,54,33.11 38 | 38,165,150,0,182,12,1023,729,14.5,20,18.26 39 | 39,158,0,246,174,7,1035,706,19,43,34.99 40 | 40,156,0,243,180,11,1022,698,21,57,33.78 41 | 41,145,177,227,209,11,752,715,2.5,20,35.66 42 | 42,154,141,181,234,11,797,683,23,65,33.51 43 | 43,160,146,188,203,11,829,710,13,38,33.51 44 | 44,291,105,0,205,6,859,797,24,59,27.62 45 | 45,298,107,0,186,6,879,815,3,20,30.97 46 | 46,318,126,0,210,6,861,737,17.5,48,31.77 47 | 47,280,92,118,207,9,883,679,25.5,64,37.39 48 | 48,287,94,121,188,9,904,696,25,61,43.01 49 | 49,332,0,170,160,6,900,806,0,20,58.53 50 | 50,326,0,167,174,6,884,792,21.5,42,52.65 51 | 51,320,0,163,188,9,866,776,23.5,60,45.69 52 | 52,342,136,0,225,11,770,747,21,61,32.04 53 | 53,356,142,0,193,11,801,778,8,30,36.46 54 | 54,309,0,142,218,10,912,680,24,62,38.59 55 | 55,322,0,149,186,8,951,709,20.5,61.5,45.42 56 | 56,159,193,0,208,12,821,818,23,50,19.19 57 | 57,307,110,0,189,10,904,765,22,40,31.5 58 | 58,313,124,0,205,11,846,758,22,49,29.63 59 | 59,143,131,168,217,6,891,672,25,69,26.42 60 | 60,140,128,164,237,6,869,656,24,65,29.5 61 | 61,278,0,117,205,9,875,799,19,48,32.71 62 | 62,288,0,121,177,7,908,829,22.5,48.5,39.93 63 | 63,299,107,0,210,10,881,745,25,63,28.29 64 | 64,291,104,0,231,9,857,725,23,69,30.43 65 | 65,265,86,111,195,6,833,790,27,60,37.39 66 | 66,159,0,248,175,12,1041,683,21,51,35.39 67 | 67,160,0,250,168,12,1049,688,18,48,37.66 68 | 68,166,0,260,183,13,859,827,21,54,40.34 69 | 69,320,127,164,211,6,721,723,2,20,46.36 70 | 70,336,134,0,222,6,756,787,26,64,31.9 71 | 71,276,90,116,180,9,870,768,0,20,44.08 72 | 72,313,112,0,220,10,794,789,23,58,28.16 73 | 73,322,116,0,196,10,818,813,25.5,67,29.77 74 | 74,294,106,136,207,6,747,778,24,47,41.27 75 | 75,146,106,137,209,6,875,765,24,67,27.89 76 | 76,149,109,139,193,6,892,780,23.5,58.5,28.7 77 | 77,159,0,187,176,11,990,789,12,39,32.57 78 | 78,261,78,100,201,9,864,761,23,63.5,34.18 79 | 79,140,1.4,198.1,174.9,4.4,1049.9,780.5,16.25,31,30.83 80 | 80,141.1,0.6,209.5,188.8,4.6,996.1,789.2,23.5,53,30.43 81 | 81,140.1,4.2,215.9,193.9,4.7,1049.5,710.1,24.5,57,26.42 82 | 82,140.1,11.8,226.1,207.8,4.9,1020.9,683.8,21,64,26.28 83 | 83,160.2,0.3,240,233.5,9.2,781,841.1,24,75,36.19 84 | 84,140.2,30.5,239,169.4,5.3,1028.4,742.7,21.25,46,36.32 85 | 85,140.2,44.8,234.9,171.3,5.5,1047.6,704,23.5,52.5,33.78 86 | 86,140.5,61.1,238.9,182.5,5.7,1017.7,681.4,24.5,60,30.97 87 | 87,143.3,91.8,239.8,200.8,6.2,964.8,647.1,25,55,27.09 88 | 88,194.3,0.3,240,234.2,8.9,780.6,811.3,26.5,78,38.46 89 | 89,150.4,110.9,239.7,168.1,6.5,1000.2,667.2,9.5,27.5,37.92 90 | 90,150.3,111.4,238.8,167.3,6.5,999.5,670.5,14.5,36.5,38.19 91 | 91,155.4,122.1,240,179.9,6.7,966.8,652.5,14.5,41.5,35.52 92 | 92,165.3,143.2,238.3,200.4,7.1,883.2,652.6,17,27,32.84 93 | 93,303.8,0.2,239.8,236.4,8.3,780.1,715.3,25,78,44.48 94 | 94,172,162.1,238.5,166,7.4,953.3,641.4,0,20,41.54 95 | 95,172.8,158.3,239.5,166.4,7.4,952.6,644.1,0,20,41.81 96 | 96,184.3,153.4,239.2,179,7.5,920.2,640.9,0,20,41.01 97 | 97,215.6,112.9,239,198.7,7.4,884,649.1,27.5,64,39.13 98 | 98,295.3,0,239.9,236.2,8.3,780.3,722.9,25,77,44.08 99 | 99,248.3,101,239.1,168.9,7.7,954.2,640.6,0,20,49.97 100 | 100,248,101,239.9,169.1,7.7,949.9,644.1,2,20,50.23 101 | 101,258.8,88,239.6,175.3,7.6,938.9,646,0,20,50.5 102 | 102,297.1,40.9,239.9,194,7.5,908.9,651.8,27.5,67,49.17 103 | 103,348.7,0.1,223.1,208.5,9.6,786.2,758.1,29,78,48.77 104 | -------------------------------------------------------------------------------- /examples/concreteslump/slump_test.names: -------------------------------------------------------------------------------- 1 | Title: Concrete Slump Test 2 | 3 | Abstract: Concrete is a highly complex material. The slump flow of concrete is not 4 | only determined by the water content, but that is also influenced by other concrete 5 | ingredients. 6 | 7 | ---------------------------------------------------------------------------------------- 8 | 9 | Data Set Characteristics: Multivariate 10 | Attribute Characteristics: Real 11 | Associated Tasks: Regression 12 | Number of Instances: 103 13 | Number of Attributes: 10 14 | Missing Values? N/A 15 | Area: Computer 16 | Date Donated: 2009-04-30 17 | 18 | ---------------------------------------------------------------------------------------- 19 | 20 | Source: 21 | 22 | Donor: I-Cheng Yeh 23 | Email: icyeh 'at' chu.edu.tw 24 | Institution: Department of Information Management, Chung-Hua University (Republic of China) 25 | Other contact information: Department of Information Management, Chung-Hua University, 26 | Hsin Chu, Taiwan 30067, R.O.C. 27 | 28 | ---------------------------------------------------------------------------------------- 29 | 30 | Data Set Information: 31 | 32 | The data set includes 103 data points. There are 7 input variables, and 3 output 33 | variables in the data set. The initial data set included 78 data. After several 34 | years, we got 25 new data points. 35 | 36 | ---------------------------------------------------------------------------------------- 37 | 38 | Attribute Information: 39 | 40 | Input variables (7)(component kg in one M^3 concrete): 41 | Cement 42 | Slag 43 | Fly ash 44 | Water 45 | SP 46 | Coarse Aggr. 47 | Fine Aggr. 48 | 49 | Output variables (3): 50 | SLUMP (cm) 51 | FLOW (cm) 52 | 28-day Compressive Strength (Mpa) 53 | 54 | ---------------------------------------------------------------------------------------- 55 | 56 | Relevant Papers: 57 | 58 | 1. Yeh, I-Cheng, "Modeling slump of concrete with fly ash and superplasticizer," 59 | Computers and Concrete, Vol.5, No.6, 559-572, 2008. 60 | 61 | 2. Yeh, I-Cheng, "Simulation of concrete slump using neural networks," Construction 62 | Materials,Vol.162, No.1, 11-18, 2009. 63 | 64 | 3. Yeh, I-Cheng, "Prediction of workability of concrete using design of experiments 65 | for mixtures," COMPUTERS AND CONCRETE, Vol.5, No.1, 1-20, 2008. 66 | 67 | 4. Yeh, I-Cheng, "Modeling slump flow of concrete using second-order regressions and 68 | artificial neural networks," Cement and Concrete Composites, Vol.29, No. 6, 474-480, 69 | 2007. 70 | 71 | 5. Yeh, I-Cheng, "Exploring concrete slump model using artificial neural networks," J. 72 | of Computing in Civil Engineering, ASCE, Vol.20, No.3, 217-221, 2006. 73 | 74 | ---------------------------------------------------------------------------------------- 75 | 76 | Citation Request: 77 | 78 | Yeh, I-Cheng, "Modeling slump flow of concrete using second-order regressions and 79 | artificial neural networks," Cement and Concrete Composites, Vol.29, No. 6, 474-480, 80 | 2007. 81 | -------------------------------------------------------------------------------- /examples/facerec/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | gcc -Wall -ansi -pedantic -o facerec facerec.c -ldeep -lm -lpng -fopenmp 4 | 5 | debug: 6 | gcc -Wall -ansi -pedantic -g -o facerec facerec.c -ldeep -lm -lpng -fopenmp 7 | 8 | clean: 9 | rm -f *.o facerec 10 | -------------------------------------------------------------------------------- /examples/facerec/facerec.c: -------------------------------------------------------------------------------- 1 | /* 2 | Face recognition demo 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include "libdeep/globals.h" 32 | #include "libdeep/deeplearn.h" 33 | #include "libdeep/deeplearn_images.h" 34 | 35 | /* the dimensions of each face image */ 36 | int image_width = 32; 37 | int image_height = 32; 38 | 39 | /* the number of face images */ 40 | int no_of_images; 41 | 42 | /* array storing the face images */ 43 | unsigned char **images; 44 | 45 | /* image classification labels */ 46 | char ** classifications; 47 | 48 | /* the classification number assigned to each image */ 49 | int * class_number; 50 | 51 | deeplearn learner; 52 | 53 | /* train the deep learner */ 54 | static void facerec_training() 55 | { 56 | int no_of_inputs = image_width*image_height; 57 | int no_of_hiddens = 6*6; 58 | int hidden_layers=4; 59 | int no_of_outputs=5*5; 60 | int itt,i,index; 61 | unsigned int random_seed = 123; 62 | char filename[256]; 63 | char title[256]; 64 | char weights_filename[256]; 65 | int weights_image_width = 480; 66 | int weights_image_height = 800; 67 | float error_threshold[] = { 0.01f, 0.01f,0.01f,0.01f,0.005f}; 68 | const int logging_interval = 1000; 69 | 70 | sprintf(weights_filename,"%s","weights.png"); 71 | sprintf(title, "%s", "Face Image Training"); 72 | 73 | /* create the learner */ 74 | deeplearn_init(&learner, 75 | no_of_inputs, no_of_hiddens, 76 | hidden_layers, 77 | no_of_outputs, 78 | error_threshold, 79 | &random_seed); 80 | 81 | /* set learning rate */ 82 | deeplearn_set_learning_rate(&learner, 1.0f); 83 | 84 | /* perform pre-training with an autocoder */ 85 | itt = 0; 86 | while (learner.current_hidden_layer < hidden_layers) { 87 | /* load the patch into the network inputs */ 88 | deeplearn_inputs_from_image(&learner, 89 | images[rand_num(&random_seed)%no_of_images], 90 | image_width, image_height); 91 | 92 | 93 | deeplearn_update(&learner); 94 | itt++; 95 | if ((itt % logging_interval == 0) && (itt>0)) { 96 | printf("%d: %.5f\n", 97 | learner.current_hidden_layer, learner.BPerror); 98 | 99 | /* save a graph */ 100 | sprintf(filename,"%s","training_error.png"); 101 | deeplearn_plot_history(&learner, 102 | filename, title, 103 | 1024, 480); 104 | /* plot the weights */ 105 | if ((&learner)->autocoder != 0) { 106 | if (learner.current_hidden_layer==0) { 107 | bp_plot_weights((&learner)->autocoder, 108 | weights_filename, 109 | weights_image_width, 110 | weights_image_height, 111 | image_width); 112 | } 113 | else { 114 | bp_plot_weights((&learner)->autocoder, 115 | weights_filename, 116 | weights_image_width, 117 | weights_image_height, 118 | 0); 119 | } 120 | } 121 | } 122 | } 123 | 124 | /* save a graph */ 125 | sprintf(filename,"%s","training_error.png"); 126 | deeplearn_plot_history(&learner, 127 | filename, title, 128 | 1024, 480); 129 | /* plot the weights */ 130 | bp_plot_weights((&learner)->net, 131 | weights_filename, 132 | weights_image_width, 133 | weights_image_height, 134 | image_width); 135 | 136 | /* perform the final training between the last 137 | hidden layer and the outputs */ 138 | while (learner.training_complete == 0) { 139 | index = rand_num(&random_seed)%no_of_images; 140 | /* load the patch into the network inputs */ 141 | deeplearn_inputs_from_image(&learner, 142 | images[index], 143 | image_width, image_height); 144 | 145 | for (i = 0; i < no_of_outputs; i++) { 146 | if (i == class_number[index]) { 147 | deeplearn_set_output(&learner,i, 0.8f); 148 | } 149 | else { 150 | deeplearn_set_output(&learner,i, 0.2f); 151 | } 152 | } 153 | deeplearn_update(&learner); 154 | 155 | itt++; 156 | if ((itt % logging_interval == 0) && (itt>0)) { 157 | printf("Final: %.5f\n",learner.BPerror); 158 | 159 | /* save a graph */ 160 | sprintf(filename,"%s","training_error.png"); 161 | deeplearn_plot_history(&learner, 162 | filename, title, 163 | 1024, 480); 164 | /* plot the weights */ 165 | if ((&learner)->autocoder!=0) { 166 | bp_plot_weights((&learner)->autocoder, 167 | weights_filename, 168 | weights_image_width, 169 | weights_image_height, 170 | image_width); 171 | } 172 | } 173 | } 174 | 175 | /* save a graph */ 176 | sprintf(filename,"%s","training_error.png"); 177 | deeplearn_plot_history(&learner, 178 | filename, title, 179 | 1024, 480); 180 | /* plot the weights */ 181 | bp_plot_weights((&learner)->net, 182 | weights_filename, 183 | weights_image_width, 184 | weights_image_height, 185 | image_width); 186 | } 187 | 188 | /* deallocate images */ 189 | static void free_mem(unsigned char ** images, 190 | char ** classifications, 191 | int * class_number, 192 | int no_of_images) 193 | { 194 | int i; 195 | 196 | if (images==NULL) return; 197 | 198 | for (i = 0; i < no_of_images; i++) { 199 | if (images[i] != NULL) { 200 | free(images[i]); 201 | images[i] = 0; 202 | } 203 | free(classifications[i]); 204 | } 205 | free(images); 206 | free(classifications); 207 | free(class_number); 208 | 209 | deeplearn_free(&learner); 210 | } 211 | 212 | static void plot_training_images() 213 | { 214 | int max_images = no_of_images; 215 | 216 | if (max_images > 4) max_images = 4; 217 | 218 | bp_plot_images(images, max_images, 219 | image_width, image_height, 220 | "training_images.png"); 221 | } 222 | 223 | int main(int argc, char* argv[]) 224 | { 225 | images = NULL; 226 | 227 | /* load training images into an array */ 228 | no_of_images = 229 | deeplearn_load_training_images("images", &images, &classifications, 230 | &class_number, 231 | image_width, image_height); 232 | 233 | printf("No of images: %d\n", no_of_images); 234 | 235 | plot_training_images(); 236 | 237 | facerec_training(); 238 | 239 | free_mem(images, classifications, class_number, no_of_images); 240 | return 1; 241 | } 242 | 243 | -------------------------------------------------------------------------------- /examples/facerec/images/face1.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face1.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face1.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face1.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face1.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face1.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face10.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face10.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face10.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face10.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face11.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face11.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face11.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face11.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face11.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face11.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face12.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face12.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face12.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face12.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face12.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face12.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face12.d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face12.d.png -------------------------------------------------------------------------------- /examples/facerec/images/face13.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face13.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face13.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face13.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face13.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face13.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face13.d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face13.d.png -------------------------------------------------------------------------------- /examples/facerec/images/face14.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face14.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face14.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face14.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face14.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face14.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face15.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face15.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face15.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face15.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face15.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face15.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face15.d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face15.d.png -------------------------------------------------------------------------------- /examples/facerec/images/face16.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face16.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face16.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face16.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face16.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face16.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face16.d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face16.d.png -------------------------------------------------------------------------------- /examples/facerec/images/face17.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face17.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face17.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face17.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face17.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face17.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face17.d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face17.d.png -------------------------------------------------------------------------------- /examples/facerec/images/face18.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face18.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face18.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face18.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face18.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face18.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face18.d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face18.d.png -------------------------------------------------------------------------------- /examples/facerec/images/face2.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face2.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face2.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face2.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face2.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face2.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face2.d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face2.d.png -------------------------------------------------------------------------------- /examples/facerec/images/face3.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face3.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face3.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face3.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face3.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face3.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face3.d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face3.d.png -------------------------------------------------------------------------------- /examples/facerec/images/face4.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face4.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face4.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face4.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face5.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face5.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face5.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face5.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face5.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face5.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face6.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face6.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face6.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face6.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face6.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face6.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face7.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face7.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face7.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face7.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face7.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face7.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face7.d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face7.d.png -------------------------------------------------------------------------------- /examples/facerec/images/face8.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face8.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face8.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face8.b.png -------------------------------------------------------------------------------- /examples/facerec/images/face8.c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face8.c.png -------------------------------------------------------------------------------- /examples/facerec/images/face9.a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face9.a.png -------------------------------------------------------------------------------- /examples/facerec/images/face9.b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/examples/facerec/images/face9.b.png -------------------------------------------------------------------------------- /fedora.sh: -------------------------------------------------------------------------------- 1 | APP=libdeep 2 | VERSION=1.00 3 | SOURCEDIR=. 4 | ARCH_TYPE=`uname -m` 5 | RELEASE=1 6 | SONAME=${APP}.so.0 7 | LIBNAME=${APP}-${VERSION}.so.0.0.${RELEASE} 8 | USRBASE=/usr 9 | 10 | sudo yum groupinstall "Development Tools" 11 | sudo yum install rpmdevtools 12 | 13 | make 14 | 15 | rm -rf ~/rpmbuild 16 | sudo rm -rf rpmpackage/$APP-$VERSION 17 | rpmdev-setuptree 18 | mkdir rpmpackage/$APP-$VERSION 19 | 20 | mkdir rpmpackage/$APP-$VERSION/etc 21 | mkdir rpmpackage/$APP-$VERSION/etc/$APP 22 | mkdir rpmpackage/$APP-$VERSION/usr 23 | mkdir rpmpackage/$APP-$VERSION/usr/lib 24 | mkdir rpmpackage/$APP-$VERSION/usr/include 25 | mkdir rpmpackage/$APP-$VERSION/usr/include/$APP 26 | mkdir rpmpackage/$APP-$VERSION/usr/bin 27 | mkdir rpmpackage/$APP-$VERSION/usr/share 28 | mkdir rpmpackage/$APP-$VERSION/usr/share/man 29 | mkdir rpmpackage/$APP-$VERSION/usr/share/man/man1 30 | install -m 755 $LIBNAME rpmpackage/$APP-$VERSION/usr/lib 31 | install -m 644 src/*.h rpmpackage/$APP-$VERSION/usr/include/$APP 32 | install -m 644 man/$APP.1.gz rpmpackage/$APP-$VERSION/usr/share/man/man1 33 | #ln -sf /usr/lib/$LIBNAME /usr/lib/$SONAME 34 | #ln -sf /usr/lib/$LIBNAME /usr/lib/$APP.so 35 | 36 | cd rpmpackage 37 | mkdir $APP-$VERSION/etc/$APP 38 | install -m 644 $APP.conf $APP-$VERSION/etc/$APP/ 39 | tar -zcvf $APP-$VERSION.tar.gz $APP-$VERSION/ 40 | 41 | rm -rf ~/rpmbuild/BUILD/$APP-$VERSION 42 | rm ~/rpmbuild/SOURCES/$APP*.* 43 | cp $APP-$VERSION.tar.gz ~/rpmbuild/SOURCES/ 44 | cp $APP.spec ~/rpmbuild/SPECS/ 45 | 46 | rpmbuild -ba ~/rpmbuild/SPECS/$APP.spec 47 | 48 | sudo rm -rf $APP-$VERSION 49 | rm $APP-$VERSION.tar.gz 50 | cp -r ~/rpmbuild/RPMS/* . 51 | cd .. 52 | echo --------------------------------------------------------- 53 | echo RPM files can be found in the rpmpackage directory 54 | echo under architecture subdirectories. 55 | echo --------------------------------------------------------- 56 | -------------------------------------------------------------------------------- /img/logo-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/img/logo-14.png -------------------------------------------------------------------------------- /img/logo-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/img/logo-192.png -------------------------------------------------------------------------------- /img/logo-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/img/logo-64.png -------------------------------------------------------------------------------- /libtest/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include "libdeep/deeplearn.h" 32 | 33 | static void test() 34 | { 35 | } 36 | 37 | int main(int argc, char* argv[]) 38 | { 39 | test(); 40 | return 1; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /man/libdeep.1.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rizer/libdeep/402084d39f123651062d5c057e8dd1492ad30d78/man/libdeep.1.gz -------------------------------------------------------------------------------- /rpmpackage/libdeep.conf: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /rpmpackage/libdeep.spec: -------------------------------------------------------------------------------- 1 | # 2 | # rpm spec for libdeep 3 | # 4 | 5 | %define __spec_install_post %{nil} 6 | %define debug_package %{nil} 7 | %define __os_install_post %{_dbpath}/brp-compress 8 | 9 | Summary: Genetic programming 10 | Name: libdeep 11 | Version: 1.00 12 | Release: 1 13 | License: BSD 14 | Group: libs 15 | SOURCE0 : %{name}-%{version}.tar.gz 16 | URL: https://launchpad.net/libdeep 17 | Packager: Bob Mottram 18 | Requires: gnuplot 19 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root 20 | 21 | %description 22 | The aim of libdeep is to make using deep learning easy to include within any C/C++ application. 23 | 24 | %prep 25 | %setup -q 26 | 27 | %build 28 | # Empty section. 29 | 30 | %install 31 | rm -rf %{buildroot} 32 | mkdir -p %{buildroot} 33 | 34 | # in builddir 35 | cp -a * %{buildroot} 36 | 37 | %clean 38 | rm -rf %{buildroot} 39 | 40 | %files 41 | %defattr(-,root,root,-) 42 | %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf 43 | %{_bindir}/* 44 | %attr(644,root,root) /usr/share/man/man1/%{name}.1.gz 45 | 46 | %changelog 47 | * Thu Jan 5 2013 Bob Mottram 48 | - Spec file created 49 | 50 | -------------------------------------------------------------------------------- /src/backprop.c: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "backprop.h" 31 | 32 | void bp_init(bp * net, 33 | int no_of_inputs, 34 | int no_of_hiddens, 35 | int hidden_layers, 36 | int no_of_outputs, 37 | unsigned int * random_seed) 38 | { 39 | int i, j, l; 40 | bp_neuron * n; 41 | 42 | net->learningRate = 0.2f; 43 | net->noise = 0.0f; 44 | net->random_seed = *random_seed; 45 | net->BPerror = DEEPLEARN_UNKNOWN_ERROR; 46 | net->BPerrorAverage = DEEPLEARN_UNKNOWN_ERROR; 47 | net->BPerrorTotal = DEEPLEARN_UNKNOWN_ERROR; 48 | net->itterations = 0; 49 | net->DropoutPercent = 20; 50 | 51 | net->NoOfInputs = no_of_inputs; 52 | net->inputs = (bp_neuron**)malloc(no_of_inputs*sizeof(bp_neuron*)); 53 | 54 | net->NoOfHiddens = no_of_hiddens; 55 | net->HiddenLayers = hidden_layers; 56 | net->hiddens = 57 | (bp_neuron***)malloc(hidden_layers*sizeof(bp_neuron**)); 58 | for (l = 0; l < hidden_layers; l++) { 59 | net->hiddens[l] = 60 | (bp_neuron**)malloc(no_of_hiddens*sizeof(bp_neuron*)); 61 | } 62 | 63 | net->NoOfOutputs = no_of_outputs; 64 | net->outputs = (bp_neuron**)malloc(no_of_outputs*sizeof(bp_neuron*)); 65 | 66 | /* create inputs */ 67 | for (i = 0; i < net->NoOfInputs; i++) { 68 | net->inputs[i] = (bp_neuron*)malloc(sizeof(struct bp_n)); 69 | bp_neuron_init(net->inputs[i], 1, random_seed); 70 | } 71 | 72 | /* create hiddens */ 73 | for (l = 0; l < hidden_layers; l++) { 74 | for (i = 0; i < net->NoOfHiddens; i++) { 75 | net->hiddens[l][i] = 76 | (bp_neuron*)malloc(sizeof(bp_neuron)); 77 | n = net->hiddens[l][i]; 78 | if (l == 0) { 79 | bp_neuron_init(n, no_of_inputs, random_seed); 80 | /* connect to input layer */ 81 | for (j = 0; j < net->NoOfInputs; j++) { 82 | bp_neuron_add_connection(n, j, net->inputs[j]); 83 | } 84 | } 85 | else { 86 | bp_neuron_init(n, no_of_hiddens, random_seed); 87 | /* connect to previous hidden layer */ 88 | for (j = 0; j < net->NoOfHiddens; j++) { 89 | bp_neuron_add_connection(n, j, net->hiddens[l-1][j]); 90 | } 91 | } 92 | } 93 | } 94 | 95 | /* create outputs */ 96 | for (i = 0; i < net->NoOfOutputs; i++) { 97 | net->outputs[i] = (bp_neuron*)malloc(sizeof(bp_neuron)); 98 | n = net->outputs[i]; 99 | bp_neuron_init(n, no_of_hiddens, random_seed); 100 | for (j = 0; j < net->NoOfHiddens; j++) { 101 | bp_neuron_add_connection(n, j, 102 | net->hiddens[hidden_layers-1][j]); 103 | } 104 | } 105 | } 106 | 107 | /* deallocates memory */ 108 | void bp_free(bp * net) 109 | { 110 | int l,i; 111 | 112 | for (i = 0; i < net->NoOfInputs; i++) { 113 | bp_neuron_free(net->inputs[i]); 114 | free(net->inputs[i]); 115 | net->inputs[i] = 0; 116 | } 117 | free(net->inputs); 118 | for (l = 0; l < net->HiddenLayers; l++) { 119 | for (i = 0; i < net->NoOfHiddens; i++) { 120 | bp_neuron_free(net->hiddens[l][i]); 121 | free(net->hiddens[l][i]); 122 | net->hiddens[l][i] = 0; 123 | } 124 | free(net->hiddens[l]); 125 | net->hiddens[l] = 0; 126 | } 127 | free(net->hiddens); 128 | 129 | for (i = 0; i < net->NoOfOutputs; i++) { 130 | bp_neuron_free(net->outputs[i]); 131 | free(net->outputs[i]); 132 | net->outputs[i] = 0; 133 | } 134 | free(net->outputs); 135 | } 136 | 137 | void bp_feed_forward(bp * net) 138 | { 139 | int i,l; 140 | bp_neuron * n; 141 | 142 | for (l = 0; l < net->HiddenLayers; l++) { 143 | for (i = 0; i < net->NoOfHiddens; i++) { 144 | n = net->hiddens[l][i]; 145 | bp_neuron_feedForward(n, net->noise, &net->random_seed); 146 | } 147 | } 148 | 149 | for (i = 0; i < net->NoOfOutputs; i++) { 150 | n = net->outputs[i]; 151 | bp_neuron_feedForward(n, net->noise, &net->random_seed); 152 | } 153 | } 154 | 155 | /* feed forward for a number of layers */ 156 | void bp_feed_forward_layers(bp * net, int layers) 157 | { 158 | int i,l; 159 | bp_neuron * n; 160 | 161 | for (l = 0; l < layers; l++) { 162 | if (l < net->HiddenLayers) { 163 | for (i = 0; i < net->NoOfHiddens; i++) { 164 | n = net->hiddens[l][i]; 165 | bp_neuron_feedForward(n, net->noise, &net->random_seed); 166 | } 167 | } 168 | else { 169 | for (i = 0; i < net->NoOfOutputs; i++) { 170 | n = net->outputs[i]; 171 | bp_neuron_feedForward(n, net->noise, &net->random_seed); 172 | } 173 | } 174 | } 175 | } 176 | 177 | /* back-propogate errors */ 178 | void bp_backprop(bp * net) 179 | { 180 | int i,l; 181 | bp_neuron * n; 182 | 183 | /* clear all previous backprop errors */ 184 | for (i = 0; i < net->NoOfInputs; i++) { 185 | n = net->inputs[i]; 186 | n->BPerror = 0; 187 | } 188 | 189 | for (l = 0; l < net->HiddenLayers; l++) { 190 | for (i = 0; i < net->NoOfHiddens; i++) { 191 | n = net->hiddens[l][i]; 192 | n->BPerror = 0; 193 | } 194 | } 195 | 196 | /* now back-propogate the error from the output units */ 197 | net->BPerrorTotal = 0; 198 | for (i = 0; i < net->NoOfOutputs; i++) { 199 | n = net->outputs[i]; 200 | bp_neuron_backprop(n); 201 | net->BPerrorTotal += n->BPerror; 202 | } 203 | 204 | /* error on the output units */ 205 | net->BPerror = fabs(net->BPerrorTotal / net->NoOfOutputs); 206 | 207 | /* update the running average */ 208 | if (net->BPerrorAverage == DEEPLEARN_UNKNOWN_ERROR) { 209 | net->BPerrorAverage = net->BPerror; 210 | } 211 | else { 212 | net->BPerrorAverage = 213 | (net->BPerrorAverage*0.98f) + 214 | (net->BPerror*0.02f); 215 | } 216 | 217 | /* back-propogate through the hidden layers */ 218 | for (l = net->HiddenLayers-1; l >= 0; l--) { 219 | for (i = 0; i < net->NoOfHiddens; i++) { 220 | n = net->hiddens[l][i]; 221 | bp_neuron_backprop(n); 222 | net->BPerrorTotal += n->BPerror; 223 | } 224 | } 225 | 226 | /* overall average error */ 227 | net->BPerrorTotal = 228 | fabs(net->BPerrorTotal / 229 | (net->NoOfOutputs + net->NoOfHiddens)); 230 | 231 | /* increment the number of training itterations */ 232 | if (net->itterations < UINT_MAX) { 233 | net->itterations++; 234 | } 235 | } 236 | 237 | /* adjust connection weights and bias values */ 238 | void bp_learn(bp * net) 239 | { 240 | int i,l; 241 | bp_neuron * n; 242 | 243 | /* hidden layers */ 244 | for (l = 0; l < net->HiddenLayers; l++) { 245 | for (i = 0; i < net->NoOfHiddens; i++) { 246 | n = net->hiddens[l][i]; 247 | bp_neuron_learn(n,net->learningRate); 248 | } 249 | } 250 | 251 | /* output layer */ 252 | for (i = 0; i < net->NoOfOutputs; i++) { 253 | n = net->outputs[i]; 254 | bp_neuron_learn(n,net->learningRate); 255 | } 256 | } 257 | 258 | void bp_set_input(bp * net, int index, float value) 259 | { 260 | bp_neuron * n; 261 | 262 | n = net->inputs[index]; 263 | n->value = value; 264 | } 265 | 266 | /* Set the unputs of the network from a patch within an image. 267 | It is assumed that the image is mono (1 byte per pixel) */ 268 | void bp_inputs_from_image_patch(bp * net, 269 | unsigned char * img, 270 | int image_width, int image_height, 271 | int tx, int ty) 272 | { 273 | int px,py,i=0,n; 274 | int patch_size = (int)sqrt(net->NoOfInputs); 275 | 276 | assert(patch_size*patch_size <= net->NoOfInputs); 277 | 278 | /* set the inputs */ 279 | for (py = ty; py < ty+patch_size; py++) { 280 | if (py >= image_height) break; 281 | for (px = tx; px < tx+patch_size; px++, i++) { 282 | if (px >= image_width) break; 283 | n = (py*image_width) + px; 284 | bp_set_input(net, i, 0.25f + (img[n]*0.5f/255.0f)); 285 | } 286 | } 287 | } 288 | 289 | /* Set the inputs of the network from an image. 290 | It is assumed that the image is mono (1 byte per pixel) */ 291 | void bp_inputs_from_image(bp * net, 292 | unsigned char * img, 293 | int image_width, int image_height) 294 | { 295 | int px,py,i=0; 296 | 297 | /* check that the number of inputs is the same as the 298 | number of pixels */ 299 | assert(net->NoOfInputs == image_width*image_height); 300 | 301 | /* set the inputs */ 302 | for (py = 0; py < image_height; py++) { 303 | for (px = 0; px < image_width; px++, i++) { 304 | bp_set_input(net, i, 0.25f + (img[i]*0.5f/255.0f)); 305 | } 306 | } 307 | } 308 | 309 | /* plots weight matrices within an image */ 310 | void bp_plot_weights(bp * net, 311 | char * filename, 312 | int image_width, int image_height, 313 | int input_image_width) 314 | { 315 | int layer, neurons_x, neurons_y, ty, by, h, x, y, ix, iy; 316 | int wx, wy, inputs_x, inputs_y, n, i, unit, no_of_neurons; 317 | int no_of_weights,wdth; 318 | float neuronx, neurony,dw; 319 | bp_neuron ** neurons, * curr_neuron; 320 | unsigned char * img; 321 | 322 | /* allocate memory for the image */ 323 | img = (unsigned char*)malloc(image_width*image_height*3); 324 | 325 | /* clear the image with a white background */ 326 | memset((void*)img,'\255',image_width*image_height*3); 327 | 328 | /* dimension of the neurons matrix for each layer */ 329 | neurons_x = (int)sqrt(net->NoOfHiddens); 330 | neurons_y = (net->NoOfHiddens/neurons_x); 331 | 332 | /* dimensions of the weight matrix */ 333 | if (input_image_width <= 0) { 334 | inputs_x = (int)sqrt(net->NoOfInputs); 335 | } 336 | else { 337 | inputs_x = input_image_width; 338 | } 339 | inputs_y = (net->NoOfInputs/inputs_x); 340 | 341 | no_of_weights = net->NoOfInputs;; 342 | 343 | /* plot the inputs */ 344 | ty = 0; 345 | by = image_height/(net->HiddenLayers+3); 346 | h = (by-ty)*95/100; 347 | wdth = h; 348 | if (wdth>=image_width) wdth=image_width; 349 | for (y = 0; y < h; y++) { 350 | iy = y*inputs_y/h; 351 | for (x = 0; x < wdth; x++) { 352 | ix = x*inputs_x/wdth; 353 | unit = (iy*inputs_x) + ix; 354 | if (unit < net->NoOfInputs) { 355 | n = (y*image_width + x)*3; 356 | img[n] = (unsigned char)(net->inputs[unit]->value*255); 357 | img[n+1] = img[n]; 358 | img[n+2] = img[n]; 359 | } 360 | } 361 | } 362 | 363 | for (layer = 0; layer < net->HiddenLayers+1; layer++) { 364 | 365 | /* vertical top and bottom coordinates */ 366 | ty = (layer+1)*image_height/(net->HiddenLayers+3); 367 | by = (layer+2)*image_height/(net->HiddenLayers+3); 368 | h = (by-ty)*95/100; 369 | 370 | /* number of patches across and down for the final layer */ 371 | if (layer == net->HiddenLayers) { 372 | neurons_x = (int)sqrt(net->NoOfOutputs); 373 | neurons_y = (net->NoOfOutputs/neurons_x); 374 | neurons = net->outputs; 375 | no_of_neurons = net->NoOfOutputs; 376 | } 377 | else { 378 | neurons = net->hiddens[layer]; 379 | no_of_neurons = net->NoOfHiddens; 380 | } 381 | 382 | /* for every pixel within the region */ 383 | for (y = ty; y < by; y++) { 384 | neurony = (y-ty)*neurons_y/(float)h; 385 | /* y coordinate within the weights */ 386 | wy = (neurony - (int)neurony)*inputs_y; 387 | for (x = 0; x < image_width; x++) { 388 | neuronx = x*neurons_x/(float)image_width; 389 | /* x coordinate within the weights */ 390 | wx = (neuronx - (int)neuronx)*inputs_x; 391 | /* coordinate within the image */ 392 | n = ((y * image_width) + x)*3; 393 | /* weight index */ 394 | i = (wy*inputs_x) + wx; 395 | if (i < no_of_weights) { 396 | /* neuron index */ 397 | unit = ((int)neurony*neurons_x) + (int)neuronx; 398 | if (unit < no_of_neurons) { 399 | curr_neuron = neurons[unit]; 400 | dw = curr_neuron->max_weight - 401 | curr_neuron->min_weight; 402 | if (dw > 0.0001f) { 403 | img[n] = 404 | (int)((curr_neuron->weights[i] - 405 | curr_neuron->min_weight)*255/dw); 406 | img[n+1] = img[n]; 407 | img[n+2] = img[n]; 408 | } 409 | else { 410 | img[n] = 411 | (int)(curr_neuron->weights[i]*255); 412 | img[n+1] = img[n]; 413 | img[n+2] = img[n]; 414 | } 415 | } 416 | } 417 | } 418 | } 419 | /* dimensions of the weight matrix for the next layer */ 420 | inputs_x = (int)sqrt(net->NoOfHiddens); 421 | inputs_y = (net->NoOfHiddens/inputs_x); 422 | no_of_weights = net->NoOfHiddens;; 423 | } 424 | 425 | ty = (net->HiddenLayers+2)*image_height/(net->HiddenLayers+3); 426 | by = (net->HiddenLayers+3)*image_height/(net->HiddenLayers+3); 427 | h = (by-ty)*95/100; 428 | 429 | inputs_x = (int)sqrt(net->NoOfOutputs); 430 | inputs_y = (net->NoOfOutputs/inputs_x); 431 | 432 | wdth = h; 433 | if (wdth >= image_width) wdth = image_width; 434 | for (y = 0; y < h; y++) { 435 | iy = y*inputs_y/h; 436 | for (x = 0; x < wdth; x++) { 437 | ix = x*inputs_x/wdth; 438 | unit = (iy*inputs_x) + ix; 439 | if (unit < net->NoOfOutputs) { 440 | n = ((ty+y)*image_width + x)*3; 441 | img[n] = (unsigned char)(net->outputs[unit]->value*255); 442 | img[n+1] = img[n]; 443 | img[n+2] = img[n]; 444 | } 445 | } 446 | } 447 | 448 | /* write the image to file */ 449 | deeplearn_write_png(filename, 450 | image_width, image_height, img); 451 | 452 | /* free the image memory */ 453 | free(img); 454 | } 455 | 456 | static float bp_get_input(bp * net, int index) 457 | { 458 | bp_neuron * n; 459 | 460 | n = net->inputs[index]; 461 | return n->value; 462 | } 463 | 464 | void bp_set_output(bp * net, int index, float value) 465 | { 466 | bp_neuron * n; 467 | 468 | n = net->outputs[index]; 469 | n->desiredValue = value; 470 | } 471 | 472 | static float bp_get_hidden(bp * net, int layer, int index) 473 | { 474 | bp_neuron * n; 475 | 476 | n = net->hiddens[layer][index]; 477 | return n->value; 478 | } 479 | 480 | float bp_get_output(bp * net, int index) 481 | { 482 | bp_neuron * n; 483 | 484 | n = net->outputs[index]; 485 | return n->value; 486 | } 487 | 488 | /* clears the exclusion flags on neurons which have dropped out */ 489 | static void bp_clear_dropouts(bp * net) 490 | { 491 | int l,i; 492 | 493 | if (net->DropoutPercent==0) return; 494 | 495 | /* clear exclusions */ 496 | for (l = 0; l < net->HiddenLayers; l++) { 497 | for (i = 0; i < net->NoOfHiddens; i++) { 498 | net->hiddens[l][i]->excluded = 0; 499 | } 500 | } 501 | } 502 | 503 | /* sets exclusion flags to cause neurons to drop out */ 504 | static void bp_dropouts(bp * net) 505 | { 506 | int l,i,no_of_dropouts,hidden_units,n; 507 | 508 | if (net->DropoutPercent==0) return; 509 | 510 | /* total number of hidden units */ 511 | hidden_units = net->HiddenLayers * net->NoOfHiddens; 512 | 513 | /* total number of dropouts */ 514 | no_of_dropouts = net->DropoutPercent*hidden_units/100; 515 | 516 | /* set the exclusion flags */ 517 | for (n = 0; n < no_of_dropouts; n++) { 518 | l = rand_num(&net->random_seed)%net->HiddenLayers; 519 | i = rand_num(&net->random_seed)%net->NoOfHiddens; 520 | net->hiddens[l][i]->excluded = 1; 521 | } 522 | } 523 | 524 | void bp_update(bp * net) 525 | { 526 | bp_dropouts(net); 527 | bp_feed_forward(net); 528 | bp_backprop(net); 529 | bp_learn(net); 530 | bp_clear_dropouts(net); 531 | } 532 | 533 | static void bp_update_autocoder(bp * net) 534 | { 535 | int i; 536 | 537 | /* number of input and output units should be the same */ 538 | assert(net->NoOfInputs == net->NoOfOutputs); 539 | 540 | /* set the target outputs to be the same as the inputs */ 541 | for (i = 0; i < net->NoOfInputs; i++) { 542 | bp_set_output(net,i,net->inputs[i]->value); 543 | } 544 | 545 | /* run the autocoder */ 546 | bp_update(net); 547 | } 548 | 549 | /* coppies the hidden layer from the autocoder to the main network */ 550 | void bp_update_from_autocoder(bp * net, 551 | bp * autocoder, 552 | int hidden_layer) 553 | { 554 | int i; 555 | 556 | for (i = 0; i < net->NoOfHiddens; i++) { 557 | bp_neuron_copy(autocoder->hiddens[0][i], 558 | net->hiddens[hidden_layer][i]); 559 | } 560 | } 561 | 562 | /* generates an autocoder for the given layer */ 563 | void bp_create_autocoder(bp * net, 564 | int hidden_layer, 565 | bp * autocoder) 566 | { 567 | int no_of_inputs = net->NoOfHiddens; 568 | 569 | if (hidden_layer == 0) { 570 | no_of_inputs = net->NoOfInputs; 571 | } 572 | 573 | bp_init(autocoder, 574 | no_of_inputs, 575 | net->NoOfHiddens,1, 576 | no_of_inputs, 577 | &net->random_seed); 578 | 579 | autocoder->DropoutPercent = net->DropoutPercent; 580 | autocoder->learningRate = net->learningRate; 581 | } 582 | 583 | /* pre-trains a hidden layer using an autocoder */ 584 | void bp_pretrain(bp * net, 585 | bp * autocoder, 586 | int hidden_layer) 587 | { 588 | int i; 589 | float hidden_value; 590 | 591 | /* feed forward to the given hidden layer */ 592 | bp_feed_forward_layers(net, hidden_layer); 593 | 594 | if (hidden_layer > 0) { 595 | /* check that the number of inputs is valid */ 596 | assert(net->NoOfHiddens == autocoder->NoOfInputs); 597 | 598 | /* copy the hidden unit values to the inputs 599 | of the autocoder */ 600 | for (i = 0; i < net->NoOfHiddens; i++) { 601 | hidden_value = bp_get_hidden(net, hidden_layer-1, i); 602 | bp_set_input(autocoder,i, hidden_value); 603 | } 604 | } 605 | else { 606 | /* check that the number of inputs is valid */ 607 | assert(autocoder->NoOfInputs == net->NoOfInputs); 608 | 609 | /* copy the input unit values to the inputs 610 | of the autocoder */ 611 | for (i = 0; i < net->NoOfInputs; i++) { 612 | bp_set_input(autocoder, i, 613 | bp_get_input(net, i)); 614 | } 615 | } 616 | 617 | /* run the autocoder */ 618 | bp_update_autocoder(autocoder); 619 | } 620 | 621 | /* save a network to file */ 622 | int bp_save(FILE * fp, bp * net) 623 | { 624 | int retval,i,l; 625 | 626 | retval = fwrite(&net->itterations, sizeof(unsigned int), 1, fp); 627 | retval = fwrite(&net->NoOfInputs, sizeof(int), 1, fp); 628 | retval = fwrite(&net->NoOfHiddens, sizeof(int), 1, fp); 629 | retval = fwrite(&net->NoOfOutputs, sizeof(int), 1, fp); 630 | retval = fwrite(&net->HiddenLayers, sizeof(int), 1, fp); 631 | retval = fwrite(&net->learningRate, sizeof(float), 1, fp); 632 | retval = fwrite(&net->noise, sizeof(float), 1, fp); 633 | retval = fwrite(&net->BPerrorAverage, sizeof(float), 1, fp); 634 | retval = fwrite(&net->DropoutPercent, sizeof(float), 1, fp); 635 | 636 | for (l = 0; l < net->HiddenLayers; l++) { 637 | for (i = 0; i < net->NoOfHiddens; i++) { 638 | bp_neuron_save(fp,net->hiddens[l][i]); 639 | } 640 | } 641 | for (i = 0; i < net->NoOfOutputs; i++) { 642 | bp_neuron_save(fp,net->outputs[i]); 643 | } 644 | 645 | return retval; 646 | } 647 | 648 | /* load a network from file */ 649 | int bp_load(FILE * fp, bp * net, 650 | unsigned int * random_seed) 651 | { 652 | int retval,i,l; 653 | int no_of_inputs=0, no_of_hiddens=0, no_of_outputs=0; 654 | int hidden_layers=0; 655 | float learning_rate=0, noise=0, BPerrorAverage=0; 656 | float DropoutPercent=0; 657 | unsigned int itterations=0; 658 | 659 | retval = fread(&itterations, sizeof(unsigned int), 1, fp); 660 | retval = fread(&no_of_inputs, sizeof(int), 1, fp); 661 | retval = fread(&no_of_hiddens, sizeof(int), 1, fp); 662 | retval = fread(&no_of_outputs, sizeof(int), 1, fp); 663 | retval = fread(&hidden_layers, sizeof(int), 1, fp); 664 | retval = fread(&learning_rate, sizeof(float), 1, fp); 665 | retval = fread(&noise, sizeof(float), 1, fp); 666 | retval = fread(&BPerrorAverage, sizeof(float), 1, fp); 667 | retval = fread(&DropoutPercent, sizeof(float), 1, fp); 668 | 669 | bp_init(net, no_of_inputs, no_of_hiddens, 670 | hidden_layers, no_of_outputs, 671 | random_seed); 672 | 673 | for (l = 0; l < net->HiddenLayers; l++) { 674 | for (i = 0; i < net->NoOfHiddens; i++) { 675 | bp_neuron_load(fp,net->hiddens[l][i]); 676 | } 677 | } 678 | for (i = 0; i < net->NoOfOutputs; i++) { 679 | bp_neuron_load(fp,net->outputs[i]); 680 | } 681 | 682 | net->learningRate = learning_rate; 683 | net->noise = noise; 684 | net->BPerrorAverage = BPerrorAverage; 685 | net->BPerror = BPerrorAverage; 686 | net->BPerrorTotal = BPerrorAverage; 687 | net->itterations = itterations; 688 | net->DropoutPercent = DropoutPercent; 689 | 690 | return retval; 691 | } 692 | 693 | /* compares two networks and returns a greater than zero 694 | value if they are the same */ 695 | int bp_compare(bp * net1, bp * net2) 696 | { 697 | int retval,i,l; 698 | 699 | if (net1->NoOfInputs != net2->NoOfInputs) { 700 | return -1; 701 | } 702 | if (net1->NoOfHiddens != net2->NoOfHiddens) { 703 | return -2; 704 | } 705 | if (net1->NoOfOutputs != net2->NoOfOutputs) { 706 | return -3; 707 | } 708 | if (net1->HiddenLayers != net2->HiddenLayers) { 709 | return -4; 710 | } 711 | if (net1->learningRate != net2->learningRate) { 712 | return -5; 713 | } 714 | if (net1->noise != net2->noise) { 715 | return -6; 716 | } 717 | for (l = 0; l < net1->HiddenLayers; l++) { 718 | for (i = 0; i < net1->NoOfHiddens; i++) { 719 | retval = 720 | bp_neuron_compare(net1->hiddens[l][i], 721 | net2->hiddens[l][i]); 722 | if (retval == 0) return -7; 723 | } 724 | } 725 | for (i = 0; i < net1->NoOfOutputs; i++) { 726 | retval = bp_neuron_compare(net1->outputs[i], net2->outputs[i]); 727 | if (retval == 0) return -8; 728 | } 729 | if (net1->itterations != net2->itterations) { 730 | return -9; 731 | } 732 | if (net1->BPerrorAverage != net2->BPerrorAverage) { 733 | return -9; 734 | } 735 | if (net1->DropoutPercent!= net2->DropoutPercent) { 736 | return -10; 737 | } 738 | return 1; 739 | } 740 | 741 | /* Extract the classification from the filename. 742 | This assumes a filename of the type class.instance.extension 743 | */ 744 | void bp_get_classification_from_filename(char * filename, 745 | char * classification) 746 | { 747 | int i,start=0; 748 | 749 | classification[0] = 0; 750 | 751 | for (i = 0; i < strlen(filename); i++) { 752 | if (filename[i] == '/') { 753 | start = i+1; 754 | } 755 | } 756 | 757 | for (i = start; i < strlen(filename); i++) { 758 | if (filename[i] == '.') break; 759 | classification[i-start] = filename[i]; 760 | } 761 | classification[i-start] = 0; 762 | } 763 | 764 | /* takes a set of classification labels for each instance within 765 | a training/test set and produces an array of numbers corresponding 766 | to that */ 767 | void bp_classifications_to_numbers(int no_of_instances, 768 | char ** instance_classification, 769 | int * numbers) 770 | { 771 | int i,j; 772 | int unique_ctr = 0; 773 | char ** unique_classification; 774 | 775 | /* allocate memory for a list of unique classifications */ 776 | unique_classification = 777 | (char**)malloc(no_of_instances * sizeof(char*)); 778 | 779 | /* create a list of unique classification names */ 780 | for (i = 0; i < no_of_instances; i++) { 781 | for (j = 0; j < unique_ctr; j++) { 782 | if (strcmp(instance_classification[i], 783 | unique_classification[j])==0) { 784 | numbers[i] = j; 785 | break; 786 | } 787 | } 788 | if (j == unique_ctr) { 789 | unique_classification[unique_ctr] = 790 | (char*)malloc((1+strlen(instance_classification[i]))* 791 | sizeof(char)); 792 | sprintf(unique_classification[unique_ctr], 793 | "%s", instance_classification[i]); 794 | numbers[i] = unique_ctr; 795 | unique_ctr++; 796 | } 797 | } 798 | 799 | /* free memory */ 800 | for (i = 0; i < unique_ctr; i++) { 801 | free(unique_classification[i]); 802 | } 803 | free(unique_classification); 804 | } 805 | -------------------------------------------------------------------------------- /src/backprop.h: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef DEEPLEARN_BACKPROP_H 31 | #define DEEPLEARN_BACKPROP_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include "globals.h" 37 | #include "deeplearn_random.h" 38 | #include "deeplearn_images.h" 39 | #include "backprop_neuron.h" 40 | 41 | struct backprop { 42 | int NoOfInputs,NoOfHiddens,NoOfOutputs; 43 | int HiddenLayers; 44 | float DropoutPercent; 45 | bp_neuron ** inputs; 46 | bp_neuron *** hiddens; 47 | bp_neuron ** outputs; 48 | float BPerrorTotal; 49 | float BPerror, BPerrorAverage; 50 | float learningRate; 51 | float noise; 52 | unsigned int random_seed; 53 | unsigned int itterations; 54 | }; 55 | typedef struct backprop bp; 56 | 57 | void bp_init(bp * net, 58 | int no_of_inputs, 59 | int no_of_hiddens, 60 | int hidden_layers, 61 | int no_of_outputs, 62 | unsigned int * random_seed); 63 | void bp_free(bp * net); 64 | void bp_feed_forward(bp * net); 65 | void bp_feed_forward_layers(bp * net, int layers); 66 | void bp_backprop(bp * net); 67 | void bp_learn(bp * net); 68 | void bp_set_input(bp * net, int index, float value); 69 | void bp_set_output(bp * net, int index, float value); 70 | float bp_get_output(bp * net, int index); 71 | void bp_update(bp * net); 72 | void bp_create_autocoder(bp * net, int hidden_layer, bp * autocoder); 73 | void bp_pretrain(bp * net, bp * autocoder, int hidden_layer); 74 | void bp_update_from_autocoder(bp * net, bp * autocoder, int hidden_layer); 75 | int bp_save(FILE * fp, bp * net); 76 | int bp_load(FILE * fp, bp * net, 77 | unsigned int * random_seed); 78 | int bp_compare(bp * net1, bp * net2); 79 | void bp_inputs_from_image_patch(bp * net, 80 | unsigned char * img, 81 | int image_width, int image_height, 82 | int tx, int ty); 83 | void bp_inputs_from_image(bp * net, 84 | unsigned char * img, 85 | int image_width, int image_height); 86 | void bp_plot_weights(bp * net, 87 | char * filename, 88 | int image_width, int image_height, 89 | int input_image_width); 90 | void bp_get_classification_from_filename(char * filename, 91 | char * classification); 92 | void bp_classifications_to_numbers(int no_of_instances, 93 | char ** instance_classification, 94 | int * numbers); 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /src/backprop_neuron.c: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "backprop_neuron.h" 31 | 32 | /* randomly initialises the weights within the given range */ 33 | static void bp_neuron_init_weights(bp_neuron * n, 34 | float minVal, float maxVal, 35 | unsigned int * random_seed) 36 | { 37 | float min, max; 38 | int i; 39 | 40 | min = minVal; 41 | max = maxVal; 42 | 43 | n->min_weight = 9999; 44 | n->max_weight = -9999; 45 | 46 | /* do the weights */ 47 | for (i = 0; i < n->NoOfInputs; i++) { 48 | n->weights[i] = 49 | min + (((rand_num(random_seed)%10000)/10000.0f) * 50 | (max - min)); 51 | n->lastWeightChange[i] = 0; 52 | if (n->weights[i] < n->min_weight) { 53 | n->min_weight = n->weights[i]; 54 | } 55 | if (n->weights[i] > n->max_weight) { 56 | n->max_weight = n->weights[i]; 57 | } 58 | } 59 | 60 | /* dont forget the bias value */ 61 | n->bias = 62 | min + (((rand_num(random_seed)%10000)/10000.0f) * 63 | (max - min)); 64 | n->lastBiasChange = 0; 65 | } 66 | 67 | /* copy weights from one neuron to another */ 68 | void bp_neuron_copy(bp_neuron * source, 69 | bp_neuron * dest) 70 | { 71 | int i; 72 | 73 | if (source->NoOfInputs != 74 | dest->NoOfInputs) { 75 | printf("Warning: neurons have different numbers of inputs\n"); 76 | return; 77 | } 78 | 79 | for (i = 0; i < source->NoOfInputs; i++) { 80 | dest->weights[i] = source->weights[i]; 81 | } 82 | dest->bias = source->bias; 83 | } 84 | 85 | /* initialises the neuron */ 86 | void bp_neuron_init(bp_neuron * n, 87 | int no_of_inputs, 88 | unsigned int * random_seed) 89 | { 90 | int i; 91 | 92 | assert(no_of_inputs > 0); 93 | n->NoOfInputs = no_of_inputs; 94 | n->weights = (float*)malloc(no_of_inputs*sizeof(float)); 95 | n->lastWeightChange = (float*)malloc(no_of_inputs*sizeof(float)); 96 | n->inputs = (struct bp_n **)malloc(no_of_inputs* 97 | sizeof(struct bp_n *)); 98 | bp_neuron_init_weights(n, -0.1f, 0.1f, random_seed); 99 | n->desiredValue = -1; 100 | n->value = 0; 101 | n->BPerror = 0; 102 | n->excluded = 0; 103 | 104 | /* clear the input pointers */ 105 | for (i = 0; i < no_of_inputs; i++) { 106 | n->inputs[i] = 0; 107 | } 108 | } 109 | 110 | /* compares two neurons and returns a non-zero value 111 | if they are the same */ 112 | int bp_neuron_compare(bp_neuron * n1, bp_neuron * n2) 113 | { 114 | int i; 115 | 116 | if ((n1->NoOfInputs != n2->NoOfInputs) || 117 | (n1->bias != n2->bias)) { 118 | return 0; 119 | } 120 | 121 | for (i = 0; i < n1->NoOfInputs; i++) { 122 | if ((n1->weights[i] != n2->weights[i]) || 123 | (n1->lastWeightChange[i] != n2->lastWeightChange[i])) { 124 | return 0; 125 | } 126 | } 127 | return 1; 128 | } 129 | 130 | /* free memory */ 131 | void bp_neuron_free(bp_neuron * n) 132 | { 133 | int i; 134 | 135 | free(n->weights); 136 | for (i = 0; i < n->NoOfInputs; i++) { 137 | n->inputs[i]=0; 138 | } 139 | free(n->inputs); 140 | free(n->lastWeightChange); 141 | } 142 | 143 | /* activation function */ 144 | static float af(float x) 145 | { 146 | return x * (1.0f - x); 147 | } 148 | 149 | 150 | /* adds a connection to a neuron */ 151 | void bp_neuron_add_connection(bp_neuron * dest, 152 | int index, bp_neuron * source) 153 | { 154 | dest->inputs[index] = source; 155 | } 156 | 157 | /* feed forward */ 158 | void bp_neuron_feedForward(bp_neuron * n, 159 | float noise, 160 | unsigned int * random_seed) 161 | { 162 | float adder; 163 | int i; 164 | 165 | if (n->excluded > 0) return; 166 | 167 | adder = n->bias; 168 | 169 | for (i = 0; i < n->NoOfInputs; i++) { 170 | if (n->inputs[i] != 0) { 171 | adder += n->weights[i] * n->inputs[i]->value; 172 | } 173 | } 174 | 175 | /* add some random noise */ 176 | if (noise > 0) { 177 | adder = ((1.0f - noise) * adder) + 178 | (noise * ((rand_num(random_seed)%10000)/10000.0f)); 179 | } 180 | 181 | n->value = 1.0f / (1.0f + exp(-adder)); 182 | } 183 | 184 | /* back-propagate the error */ 185 | void bp_neuron_backprop(bp_neuron * n) 186 | { 187 | int i; 188 | bp_neuron * nrn; 189 | float afact; 190 | 191 | if (n->excluded > 0) return; 192 | 193 | if (n->desiredValue > -1) { 194 | /* output unit */ 195 | n->BPerror = n->desiredValue - n->value; 196 | } 197 | 198 | afact = af(n->value); 199 | 200 | for (i = 0; i < n->NoOfInputs; i++) { 201 | nrn = n->inputs[i]; 202 | if (nrn != 0) { 203 | nrn->BPerror += 204 | (n->BPerror * afact * n->weights[i]); 205 | } 206 | } 207 | } 208 | 209 | 210 | /* adjust the weights */ 211 | void bp_neuron_learn(bp_neuron * n, 212 | float learningRate) 213 | { 214 | int i; 215 | float afact,e,gradient; 216 | 217 | if (n->excluded > 0) return; 218 | 219 | e = learningRate / (1.0f + n->NoOfInputs); 220 | afact = af(n->value); 221 | gradient = afact * n->BPerror; 222 | n->lastBiasChange = e * (n->lastBiasChange + 1.0f) * gradient; 223 | n->bias += n->lastBiasChange; 224 | n->min_weight = 9999; 225 | n->max_weight = -9999; 226 | for (i = 0; i < n->NoOfInputs; i++) { 227 | if (n->inputs[i] != 0) { 228 | n->lastWeightChange[i] = 229 | e * (n->lastWeightChange[i] + 1) * 230 | gradient * n->inputs[i]->value; 231 | n->weights[i] += n->lastWeightChange[i]; 232 | if (n->weights[i] < n->min_weight) { 233 | n->min_weight = n->weights[i]; 234 | } 235 | if (n->weights[i] > n->max_weight) { 236 | n->max_weight = n->weights[i]; 237 | } 238 | } 239 | } 240 | } 241 | 242 | /* saves neuron parameters. Note that there is no need to 243 | save the connections, since layers are always fully 244 | interconnected */ 245 | int bp_neuron_save(FILE * fp, bp_neuron * n) 246 | { 247 | int retval; 248 | 249 | retval = fwrite(&n->NoOfInputs, sizeof(int), 1, fp); 250 | 251 | retval = fwrite(n->weights, sizeof(float), 252 | n->NoOfInputs, fp); 253 | retval = fwrite(n->lastWeightChange, sizeof(float), 254 | n->NoOfInputs, fp); 255 | 256 | retval = fwrite(&n->min_weight, sizeof(float), 1, fp); 257 | retval = fwrite(&n->max_weight, sizeof(float), 1, fp); 258 | 259 | retval = fwrite(&n->bias, sizeof(float), 1, fp); 260 | retval = fwrite(&n->lastBiasChange, sizeof(float), 1, fp); 261 | retval = fwrite(&n->desiredValue, sizeof(float), 1, fp); 262 | 263 | return retval; 264 | } 265 | 266 | /* load neuron parameters */ 267 | int bp_neuron_load(FILE * fp, bp_neuron * n) 268 | { 269 | int retval; 270 | 271 | retval = fread(&n->NoOfInputs, sizeof(int), 1, fp); 272 | 273 | retval = fread(n->weights, sizeof(float), 274 | n->NoOfInputs, fp); 275 | retval = fread(n->lastWeightChange, sizeof(float), 276 | n->NoOfInputs, fp); 277 | 278 | retval = fread(&n->min_weight, sizeof(float), 1, fp); 279 | retval = fread(&n->max_weight, sizeof(float), 1, fp); 280 | 281 | retval = fread(&n->bias, sizeof(float), 1, fp); 282 | retval = fread(&n->lastBiasChange, sizeof(float), 1, fp); 283 | retval = fread(&n->desiredValue, sizeof(float), 1, fp); 284 | 285 | n->value = 0; 286 | n->BPerror = 0; 287 | n->excluded = 0; 288 | 289 | return retval; 290 | } 291 | -------------------------------------------------------------------------------- /src/backprop_neuron.h: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef DEEPLEARN_BACKPROP_NEURON_H 31 | #define DEEPLEARN_BACKPROP_NEURON_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include "deeplearn_random.h" 43 | 44 | struct bp_n { 45 | int NoOfInputs; 46 | float * weights; 47 | float * lastWeightChange; 48 | struct bp_n ** inputs; 49 | float min_weight,max_weight; 50 | float bias; 51 | float lastBiasChange; 52 | float BPerror; 53 | int excluded; 54 | 55 | float value; 56 | float desiredValue; 57 | }; 58 | typedef struct bp_n bp_neuron; 59 | 60 | void bp_neuron_init(bp_neuron * n, 61 | int no_of_inputs, 62 | unsigned int * random_seed); 63 | void bp_neuron_add_connection(bp_neuron * dest, 64 | int index, bp_neuron * source); 65 | void bp_neuron_feedForward(bp_neuron * n, 66 | float noise, 67 | unsigned int * random_seed); 68 | void bp_neuron_backprop(bp_neuron * n); 69 | void bp_neuron_learn(bp_neuron * n, 70 | float learningRate); 71 | void bp_neuron_free(bp_neuron * n); 72 | void bp_neuron_copy(bp_neuron * source, 73 | bp_neuron * dest); 74 | int bp_neuron_save(FILE * fp, bp_neuron * n); 75 | int bp_neuron_load(FILE * fp, bp_neuron * n); 76 | int bp_neuron_compare(bp_neuron * n1, bp_neuron * n2); 77 | void bp_neuron_fix_weights(bp_neuron * n); 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/deeplearn.c: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "deeplearn.h" 31 | 32 | /* update the learning history */ 33 | static void deeplean_update_history(deeplearn * learner) 34 | { 35 | int i; 36 | float error_value; 37 | 38 | learner->history_ctr++; 39 | if (learner->history_ctr >= learner->history_step) { 40 | error_value = learner->BPerror; 41 | if (error_value == DEEPLEARN_UNKNOWN_ERROR) { 42 | error_value = 0; 43 | } 44 | 45 | learner->history[learner->history_index] = 46 | error_value; 47 | learner->history_index++; 48 | learner->history_ctr = 0; 49 | 50 | if (learner->history_index >= DEEPLEARN_HISTORY_SIZE) { 51 | for (i = 0; i < learner->history_index; i++) { 52 | learner->history[i/2] = learner->history[i]; 53 | } 54 | learner->history_index /= 2; 55 | learner->history_step *= 2; 56 | } 57 | } 58 | } 59 | 60 | /* initialise a deep learner */ 61 | void deeplearn_init(deeplearn * learner, 62 | int no_of_inputs, 63 | int no_of_hiddens, 64 | int hidden_layers, 65 | int no_of_outputs, 66 | float error_threshold[], 67 | unsigned int * random_seed) 68 | { 69 | /* has not been trained */ 70 | learner->training_complete = 0; 71 | 72 | /* create the error thresholds for each layer */ 73 | learner->error_threshold = 74 | (float*)malloc((hidden_layers+1)*sizeof(float)); 75 | memcpy((void*)learner->error_threshold, 76 | (void*)error_threshold, 77 | (hidden_layers+1)*sizeof(float)); 78 | 79 | /* clear history */ 80 | learner->history_index = 0; 81 | learner->history_ctr = 0; 82 | learner->history_step = 1; 83 | 84 | /* clear the number of training itterations */ 85 | learner->itterations = 0; 86 | 87 | /* set the current layer being trained */ 88 | learner->current_hidden_layer = 0; 89 | 90 | /* create the network */ 91 | learner->net = (bp*)malloc(sizeof(bp)); 92 | 93 | /* initialise the network */ 94 | bp_init(learner->net, 95 | no_of_inputs, no_of_hiddens, 96 | hidden_layers, no_of_outputs, 97 | random_seed); 98 | 99 | /* create the autocoder */ 100 | learner->autocoder = (bp*)malloc(sizeof(bp)); 101 | bp_create_autocoder(learner->net, 102 | learner->current_hidden_layer, 103 | learner->autocoder); 104 | 105 | learner->BPerror = DEEPLEARN_UNKNOWN_ERROR; 106 | } 107 | 108 | void deeplearn_feed_forward(deeplearn * learner) 109 | { 110 | bp_feed_forward(learner->net); 111 | } 112 | 113 | void deeplearn_update(deeplearn * learner) 114 | { 115 | float max_backprop_error = 0; 116 | 117 | /* only continue if training is not complete */ 118 | if (learner->training_complete == 1) return; 119 | 120 | /* get the maximum backprop error after which a layer 121 | will be considered to have been trained */ 122 | max_backprop_error = 123 | learner->error_threshold[learner->current_hidden_layer]; 124 | 125 | /* pretraining */ 126 | if (learner->current_hidden_layer < 127 | learner->net->HiddenLayers) { 128 | 129 | /* train the autocoder */ 130 | bp_pretrain(learner->net, learner->autocoder, 131 | learner->current_hidden_layer); 132 | 133 | /* update the backprop error value */ 134 | learner->BPerror = learner->autocoder->BPerrorAverage; 135 | 136 | /* If below the error threshold. 137 | Only do this after a minimum number of itterations 138 | in order to allow the running average to stabilise */ 139 | if ((learner->BPerror < max_backprop_error) && 140 | (learner->autocoder->itterations > 100)) { 141 | 142 | /* copy the hidden units */ 143 | bp_update_from_autocoder(learner->net, 144 | learner->autocoder, 145 | learner->current_hidden_layer); 146 | 147 | /* delete the existing autocoder */ 148 | bp_free(learner->autocoder); 149 | free(learner->autocoder); 150 | learner->autocoder = 0; 151 | 152 | /* advance to the next hidden layer */ 153 | learner->current_hidden_layer++; 154 | 155 | /* if not the final hidden layer */ 156 | if (learner->current_hidden_layer < 157 | learner->net->HiddenLayers) { 158 | 159 | /* make a new autocoder */ 160 | learner->autocoder = (bp*)malloc(sizeof(bp)); 161 | bp_create_autocoder(learner->net, 162 | learner->current_hidden_layer, 163 | learner->autocoder); 164 | } 165 | 166 | /* reset the error value */ 167 | learner->BPerror = DEEPLEARN_UNKNOWN_ERROR; 168 | } 169 | } 170 | else { 171 | /* ordinary network training */ 172 | bp_update(learner->net); 173 | 174 | /* update the backprop error value */ 175 | learner->BPerror = learner->net->BPerrorAverage; 176 | 177 | /* set the training completed flag */ 178 | if (learner->BPerror < max_backprop_error) { 179 | learner->training_complete = 1; 180 | } 181 | } 182 | 183 | /* record the history of error values */ 184 | deeplean_update_history(learner); 185 | 186 | /* increment the number of itterations */ 187 | if (learner->net->itterations < UINT_MAX) { 188 | learner->net->itterations++; 189 | } 190 | } 191 | 192 | /* free the deep learner's allocated memory */ 193 | void deeplearn_free(deeplearn * learner) 194 | { 195 | /* free the learner */ 196 | bp_free(learner->net); 197 | free(learner->net); 198 | 199 | /* free the error thresholds */ 200 | free(learner->error_threshold); 201 | 202 | /* free the autocoder */ 203 | if (learner->autocoder != 0) { 204 | bp_free(learner->autocoder); 205 | free(learner->autocoder); 206 | } 207 | } 208 | 209 | /* sets the value of an input to the network */ 210 | void deeplearn_set_input(deeplearn * learner, int index, float value) 211 | { 212 | bp_set_input(learner->net, index, value); 213 | } 214 | 215 | /* sets the value of an output */ 216 | void deeplearn_set_output(deeplearn * learner, int index, float value) 217 | { 218 | bp_set_output(learner->net, index, value); 219 | } 220 | 221 | /* returns the value of an output */ 222 | float deeplearn_get_output(deeplearn * learner, int index) 223 | { 224 | return bp_get_output(learner->net, index); 225 | } 226 | 227 | /* save to file */ 228 | int deeplearn_save(FILE * fp, deeplearn * learner) 229 | { 230 | int retval,val; 231 | 232 | retval = fwrite(&learner->training_complete, sizeof(int), 1, fp); 233 | retval = fwrite(&learner->itterations, sizeof(unsigned int), 1, fp); 234 | retval = fwrite(&learner->current_hidden_layer, sizeof(int), 1, fp); 235 | retval = fwrite(&learner->BPerror, sizeof(float), 1, fp); 236 | 237 | retval = bp_save(fp, learner->net); 238 | if (learner->autocoder != 0) { 239 | val = 1; 240 | retval = fwrite(&val, sizeof(int), 1, fp); 241 | retval = bp_save(fp, learner->autocoder); 242 | } 243 | else { 244 | val = 0; 245 | retval = fwrite(&val, sizeof(int), 1, fp); 246 | } 247 | 248 | /* save error thresholds */ 249 | retval = fwrite(learner->error_threshold, sizeof(float), 250 | learner->net->HiddenLayers+1, fp); 251 | 252 | /* save the history */ 253 | retval = fwrite(&learner->history_index, sizeof(int), 1, fp); 254 | retval = fwrite(&learner->history_ctr, sizeof(int), 1, fp); 255 | retval = fwrite(&learner->history_step, sizeof(int), 1, fp); 256 | retval = fwrite(learner->history, sizeof(float), 257 | learner->history_index, fp); 258 | 259 | return retval; 260 | } 261 | 262 | /* load from file */ 263 | int deeplearn_load(FILE * fp, deeplearn * learner, 264 | unsigned int * random_seed) 265 | { 266 | int retval,val=0; 267 | 268 | retval = fread(&learner->training_complete, sizeof(int), 1, fp); 269 | retval = fread(&learner->itterations, sizeof(unsigned int), 1, fp); 270 | retval = fread(&learner->current_hidden_layer, sizeof(int), 1, fp); 271 | retval = fread(&learner->BPerror, sizeof(float), 1, fp); 272 | 273 | learner->net = (bp*)malloc(sizeof(bp)); 274 | retval = bp_load(fp, learner->net, random_seed); 275 | retval = fread(&val, sizeof(int), 1, fp); 276 | if (val == 1) { 277 | learner->autocoder = (bp*)malloc(sizeof(bp)); 278 | retval = bp_load(fp, learner->autocoder, random_seed); 279 | } 280 | else { 281 | learner->autocoder = 0; 282 | } 283 | 284 | /* load error thresholds */ 285 | learner->error_threshold = 286 | (float*)malloc((learner->net->HiddenLayers+1)* 287 | sizeof(float)); 288 | retval = fread(learner->error_threshold, sizeof(float), 289 | learner->net->HiddenLayers+1, fp); 290 | 291 | /* load the history */ 292 | retval = fread(&learner->history_index, sizeof(int), 1, fp); 293 | retval = fread(&learner->history_ctr, sizeof(int), 1, fp); 294 | retval = fread(&learner->history_step, sizeof(int), 1, fp); 295 | retval = fread(learner->history, sizeof(float), 296 | learner->history_index, fp); 297 | 298 | return retval; 299 | } 300 | 301 | /* compares two deep learners and returns a greater 302 | than zero value if they are the same */ 303 | int deeplearn_compare(deeplearn * learner1, 304 | deeplearn * learner2) 305 | { 306 | int retval,i; 307 | 308 | if (learner1->current_hidden_layer != 309 | learner2->current_hidden_layer) { 310 | return -1; 311 | } 312 | if (learner1->BPerror != learner2->BPerror) { 313 | return -2; 314 | } 315 | retval = bp_compare(learner1->net,learner2->net); 316 | if (retval < 1) return -3; 317 | if ((learner1->autocoder==0) != 318 | (learner2->autocoder==0)) { 319 | return -4; 320 | } 321 | if (learner1->history_index != 322 | learner2->history_index) { 323 | return -5; 324 | } 325 | if (learner1->history_ctr != 326 | learner2->history_ctr) { 327 | return -6; 328 | } 329 | if (learner1->history_step != 330 | learner2->history_step) { 331 | return -7; 332 | } 333 | for (i = 0; i < learner1->history_index; i++) { 334 | if (learner1->history[i] != 335 | learner2->history[i]) { 336 | return -8; 337 | } 338 | } 339 | if (learner1->itterations != 340 | learner2->itterations) { 341 | return -9; 342 | } 343 | for (i = 0; i < learner1->net->HiddenLayers+1; i++) { 344 | if (learner1->error_threshold[i] != 345 | learner2->error_threshold[i]) { 346 | return -10; 347 | } 348 | } 349 | return 1; 350 | } 351 | 352 | /* uses gnuplot to plot the training error for the given learner */ 353 | int deeplearn_plot_history(deeplearn * learner, 354 | char * filename, char * title, 355 | int image_width, int image_height) 356 | { 357 | int index,retval; 358 | FILE * fp; 359 | char data_filename[256]; 360 | char plot_filename[256]; 361 | char command_str[256]; 362 | float value; 363 | float max_value = 0.01f; 364 | 365 | sprintf(data_filename,"%s%s",DEEPLEARN_TEMP_DIRECTORY,"libgpr_data.dat"); 366 | sprintf(plot_filename,"%s%s",DEEPLEARN_TEMP_DIRECTORY,"libgpr_data.plot"); 367 | 368 | /* save the data */ 369 | fp = fopen(data_filename,"w"); 370 | if (!fp) return -1; 371 | for (index = 0; index < learner->history_index; index++) { 372 | value = learner->history[index]; 373 | fprintf(fp,"%d %.10f\n", 374 | index*learner->history_step,value); 375 | /* record the maximum error value */ 376 | if (value > max_value) { 377 | max_value = value; 378 | } 379 | } 380 | fclose(fp); 381 | 382 | /* create a plot file */ 383 | fp = fopen(plot_filename,"w"); 384 | if (!fp) return -1; 385 | fprintf(fp,"%s","reset\n"); 386 | fprintf(fp,"set title \"%s\"\n",title); 387 | fprintf(fp,"set xrange [0:%d]\n", 388 | learner->history_index*learner->history_step); 389 | fprintf(fp,"set yrange [0:%f]\n",max_value*102/100); 390 | fprintf(fp,"%s","set lmargin 9\n"); 391 | fprintf(fp,"%s","set rmargin 2\n"); 392 | fprintf(fp,"%s","set xlabel \"Time Step\"\n"); 393 | fprintf(fp,"%s","set ylabel \"Training Error\"\n"); 394 | 395 | fprintf(fp,"%s","set grid\n"); 396 | fprintf(fp,"%s","set key right top\n"); 397 | 398 | fprintf(fp,"set terminal png size %d,%d\n", 399 | image_width, image_height); 400 | fprintf(fp,"set output \"%s\"\n", filename); 401 | fprintf(fp,"plot \"%s\" using 1:2 notitle with lines\n", 402 | data_filename); 403 | fclose(fp); 404 | 405 | /* run gnuplot using the created files */ 406 | sprintf(command_str,"gnuplot %s", plot_filename); 407 | retval = system(command_str); /* I assume this is synchronous */ 408 | 409 | /* remove temporary files */ 410 | sprintf(command_str,"rm %s %s", data_filename,plot_filename); 411 | retval = system(command_str); 412 | return retval; 413 | } 414 | 415 | void deeplearn_inputs_from_image_patch(deeplearn * learner, 416 | unsigned char * img, 417 | int image_width, int image_height, 418 | int tx, int ty) 419 | { 420 | bp_inputs_from_image_patch(learner->net, 421 | img, image_width, image_height, 422 | tx, ty); 423 | } 424 | 425 | void deeplearn_inputs_from_image(deeplearn * learner, 426 | unsigned char * img, 427 | int image_width, int image_height) 428 | { 429 | bp_inputs_from_image(learner->net, img, image_width, image_height); 430 | } 431 | 432 | void deeplearn_set_learning_rate(deeplearn * learner, float rate) 433 | { 434 | learner->net->learningRate = rate; 435 | if (learner->autocoder != 0) { 436 | learner->autocoder->learningRate = rate; 437 | } 438 | } 439 | 440 | void deeplearn_set_dropouts(deeplearn * learner, float dropout_percent) 441 | { 442 | learner->net->DropoutPercent = dropout_percent; 443 | if (learner->autocoder != 0) { 444 | learner->autocoder->DropoutPercent = dropout_percent; 445 | } 446 | } 447 | -------------------------------------------------------------------------------- /src/deeplearn.h: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef DEEPLEARN_H 31 | #define DEEPLEARN_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include "globals.h" 37 | #include "backprop.h" 38 | 39 | struct deepl { 40 | bp * net; 41 | bp * autocoder; 42 | int current_hidden_layer; 43 | float BPerror; 44 | unsigned int itterations; 45 | float * error_threshold; 46 | int training_complete; 47 | 48 | float history[DEEPLEARN_HISTORY_SIZE]; 49 | int history_index, history_ctr, history_step; 50 | }; 51 | typedef struct deepl deeplearn; 52 | 53 | void deeplearn_init(deeplearn * learner, 54 | int no_of_inputs, 55 | int no_of_hiddens, 56 | int hidden_layers, 57 | int no_of_outputs, 58 | float error_threshold[], 59 | unsigned int * random_seed); 60 | void deeplearn_feed_forward(deeplearn * learner); 61 | void deeplearn_update(deeplearn * learner); 62 | void deeplearn_free(deeplearn * learner); 63 | void deeplearn_set_input(deeplearn * learner, int index, float value); 64 | void deeplearn_set_output(deeplearn * learner, int index, float value); 65 | float deeplearn_get_output(deeplearn * learner, int index); 66 | int deeplearn_save(FILE * fp, deeplearn * learner); 67 | int deeplearn_load(FILE * fp, deeplearn * learner, 68 | unsigned int * random_seed); 69 | int deeplearn_compare(deeplearn * learner1, 70 | deeplearn * learner2); 71 | int deeplearn_plot_history(deeplearn * learner, 72 | char * filename, char * title, 73 | int image_width, int image_height); 74 | void deeplearn_inputs_from_image_patch(deeplearn * learner, 75 | unsigned char * img, 76 | int image_width, int image_height, 77 | int tx, int ty); 78 | void deeplearn_inputs_from_image(deeplearn * learner, 79 | unsigned char * img, 80 | int image_width, int image_height); 81 | void deeplearn_set_learning_rate(deeplearn * learner, float rate); 82 | void deeplearn_set_dropouts(deeplearn * learner, float dropout_percent); 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/deeplearn_images.c: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "deeplearn_images.h" 31 | 32 | 33 | void deeplearn_read_png(char * filename, 34 | int * width, int * height, 35 | unsigned char ** buffer) 36 | { 37 | png_structp png_ptr; 38 | png_infop info_ptr; 39 | int y,n,bpp,i; 40 | png_bytep * row_pointers; 41 | char header[8]; // 8 is the maximum size that can be checked 42 | 43 | /* open file and test for it being a png */ 44 | FILE *fp = fopen(filename, "rb"); 45 | if (!fp) 46 | printf("[read_png_file] File %s could not be opened for reading", filename); 47 | fread(header, 1, 8, fp); 48 | if (png_sig_cmp((png_bytep)header, 0, 8)) 49 | printf("[read_png_file] File %s is not recognized as a PNG file", filename); 50 | 51 | 52 | /* initialize stuff */ 53 | png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 54 | 55 | if (!png_ptr) 56 | printf("[read_png_file] png_create_read_struct failed"); 57 | 58 | info_ptr = png_create_info_struct(png_ptr); 59 | if (!info_ptr) 60 | printf("[read_png_file] png_create_info_struct failed"); 61 | 62 | if (setjmp(png_jmpbuf(png_ptr))) 63 | printf("[read_png_file] Error during init_io"); 64 | 65 | png_init_io(png_ptr, fp); 66 | png_set_sig_bytes(png_ptr, 8); 67 | 68 | png_read_info(png_ptr, info_ptr); 69 | 70 | *width = png_get_image_width(png_ptr, info_ptr); 71 | *height = png_get_image_height(png_ptr, info_ptr); 72 | 73 | png_read_update_info(png_ptr, info_ptr); 74 | 75 | /* read the image from file */ 76 | if (setjmp(png_jmpbuf(png_ptr))) 77 | printf("[read_png_file] Error during read_image"); 78 | 79 | row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * (*height)); 80 | for (y = 0; y < *height; y++) { 81 | row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr)); 82 | } 83 | png_read_image(png_ptr, row_pointers); 84 | 85 | /* convert into a standard form */ 86 | *buffer = (unsigned char*)malloc((*width)*(*height)*3* 87 | sizeof(unsigned char)); 88 | n = 0; 89 | bpp = png_get_rowbytes(png_ptr,info_ptr)/(*width); 90 | for (y = 0; y < *height; y++) { 91 | for (i = 0; i < png_get_rowbytes(png_ptr,info_ptr); 92 | i += bpp, n += 3) { 93 | switch(bpp) { 94 | case 3: { 95 | (*buffer)[n] = (unsigned char)row_pointers[y][i]; 96 | (*buffer)[n+1] = (unsigned char)row_pointers[y][i+1]; 97 | (*buffer)[n+2] = (unsigned char)row_pointers[y][i+2]; 98 | break; 99 | } 100 | case 1: { 101 | (*buffer)[n] = (unsigned char)row_pointers[y][i]; 102 | (*buffer)[n+1] = (*buffer)[n]; 103 | (*buffer)[n+2] = (*buffer)[n]; 104 | break; 105 | } 106 | case 6: { 107 | (*buffer)[n] = (unsigned char)(row_pointers[y][i+1]>>8); 108 | (*buffer)[n+1] = (unsigned char)(row_pointers[y][i+2]>>8); 109 | (*buffer)[n+2] = (unsigned char)(row_pointers[y][i+4]>>8); 110 | break; 111 | } 112 | } 113 | } 114 | } 115 | 116 | /* free the row pointers */ 117 | for (y=0; y < *height; y++) free(row_pointers[y]); 118 | free(row_pointers); 119 | 120 | fclose(fp); 121 | } 122 | 123 | 124 | int deeplearn_write_png(char* filename, 125 | int width, int height, 126 | unsigned char *buffer) 127 | { 128 | png_structp png_ptr; 129 | png_infop info_ptr; 130 | int y,n,i; 131 | png_bytep * row_pointers; 132 | 133 | /* create file */ 134 | FILE *fp = fopen(filename, "wb"); 135 | if (!fp) 136 | printf("[write_png_file] File %s could not be opened for writing", filename); 137 | 138 | 139 | /* initialize stuff */ 140 | png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 141 | 142 | if (!png_ptr) 143 | printf("[write_png_file] png_create_write_struct failed"); 144 | 145 | info_ptr = png_create_info_struct(png_ptr); 146 | if (!info_ptr) 147 | printf("[write_png_file] png_create_info_struct failed"); 148 | 149 | if (setjmp(png_jmpbuf(png_ptr))) 150 | printf("[write_png_file] Error during init_io"); 151 | 152 | png_init_io(png_ptr, fp); 153 | 154 | /* write header */ 155 | if (setjmp(png_jmpbuf(png_ptr))) 156 | printf("[write_png_file] Error during writing header"); 157 | 158 | /* create info */ 159 | png_set_IHDR(png_ptr, info_ptr, width, height, 160 | 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, 161 | PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 162 | 163 | /* save the info */ 164 | png_write_info(png_ptr, info_ptr); 165 | 166 | /* write bytes */ 167 | if (setjmp(png_jmpbuf(png_ptr))) 168 | printf("[write_png_file] Error during writing bytes"); 169 | 170 | /* create row pointers */ 171 | row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * (height)); 172 | for (y = 0; y < height; y++) { 173 | row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr)); 174 | } 175 | 176 | /* save image data into row pointers */ 177 | n = 0; 178 | for (y = 0; y < height; y++) { 179 | for (i = 0; i < width*3; i++, n++) { 180 | row_pointers[y][i] = buffer[n]; 181 | } 182 | } 183 | 184 | /* write the row pointers */ 185 | png_write_image(png_ptr, row_pointers); 186 | 187 | /* end write */ 188 | if (setjmp(png_jmpbuf(png_ptr))) 189 | printf("[write_png_file] Error during end of write"); 190 | 191 | png_write_end(png_ptr, NULL); 192 | 193 | /* free row pointers */ 194 | for (y = 0; y < height; y++) { 195 | free(row_pointers[y]); 196 | } 197 | free(row_pointers); 198 | 199 | fclose(fp); 200 | return 1; 201 | } 202 | 203 | static int number_of_images(char * images_directory, 204 | char * extension) 205 | { 206 | int ctr,no_of_images = 0; 207 | struct dirent **namelist; 208 | int n,len; 209 | 210 | /* get image filenames */ 211 | n = scandir(images_directory, &namelist, 0, alphasort); 212 | if (n >= 0) { 213 | /* count the number of image files */ 214 | ctr = n; 215 | while (ctr--) { 216 | /* is the filename long enough? */ 217 | len = strlen(namelist[ctr]->d_name); 218 | if (len > 4) { 219 | /* is this a png image? */ 220 | if ((namelist[ctr]->d_name[len-4]=='.') && 221 | (namelist[ctr]->d_name[len-3]==extension[0]) && 222 | (namelist[ctr]->d_name[len-2]==extension[1]) && 223 | (namelist[ctr]->d_name[len-1]==extension[2])) { 224 | no_of_images++; 225 | } 226 | } 227 | free(namelist[ctr]); 228 | } 229 | free(namelist); 230 | } 231 | return no_of_images; 232 | } 233 | 234 | /* downsample a colour image to a mono fixes size image */ 235 | static void deeplearn_downsample(unsigned char * img, 236 | int width, int height, 237 | unsigned char * downsampled, 238 | int downsampled_width, 239 | int downsampled_height) 240 | { 241 | int x,y,n2,xx,yy,n=0; 242 | 243 | for (y = 0; y < downsampled_height; y++) { 244 | yy = y * height / downsampled_height; 245 | for (x = 0; x < downsampled_width; x++, n++) { 246 | xx = x * width / downsampled_width; 247 | n2 = ((yy*width) + xx)*3; 248 | downsampled[n] = (img[n2]+img[n2+1]+img[n2+2])/3; 249 | } 250 | } 251 | } 252 | 253 | int deeplearn_load_training_images(char * images_directory, 254 | unsigned char *** images, 255 | char *** classifications, 256 | int ** classification_number, 257 | int width, int height) 258 | { 259 | int ctr,no_of_images = 0; 260 | struct dirent **namelist; 261 | int n,len,im_width,im_height; 262 | unsigned char * img, * downsampled; 263 | char * extension = "png"; 264 | char filename[256]; 265 | char * classification; 266 | 267 | /* how many images are there? */ 268 | no_of_images = number_of_images(images_directory, extension); 269 | if (no_of_images == 0) { 270 | return 0; 271 | } 272 | 273 | /* allocate an array for the images */ 274 | *images = 275 | (unsigned char**)malloc(no_of_images* 276 | sizeof(unsigned char*)); 277 | 278 | /* allocate memory for the classifications */ 279 | *classifications = (char**)malloc(no_of_images* 280 | sizeof(char*)); 281 | 282 | /* allocate memory for the class number assigned to each image */ 283 | *classification_number = (int*)malloc(no_of_images * sizeof(int)); 284 | 285 | /* get image filenames */ 286 | no_of_images = 0; 287 | n = scandir(images_directory, &namelist, 0, alphasort); 288 | if (n >= 0) { 289 | /* for every filename */ 290 | ctr = n; 291 | while (ctr--) { 292 | /* is the filename long enough? */ 293 | len = strlen(namelist[ctr]->d_name); 294 | if (len > 4) { 295 | sprintf(filename,"%s/%s", 296 | images_directory,namelist[ctr]->d_name); 297 | len = strlen(filename); 298 | /* is this a png image? */ 299 | if ((filename[len-4]=='.') && 300 | (filename[len-3]==extension[0]) && 301 | (filename[len-2]==extension[1]) && 302 | (filename[len-1]==extension[2])) { 303 | 304 | /* obtain an image from the filename */ 305 | deeplearn_read_png(filename, 306 | &im_width, &im_height, &img); 307 | 308 | /* was an image returned? */ 309 | if (img != NULL) { 310 | /* create a fixed size image */ 311 | downsampled = 312 | (unsigned char*)malloc(width*height* 313 | sizeof(unsigned char)); 314 | deeplearn_downsample(img, im_width, im_height, 315 | downsampled, width, height); 316 | 317 | (*images)[no_of_images] = downsampled; 318 | 319 | /* free the original image */ 320 | free(img); 321 | } 322 | else { 323 | (*images)[no_of_images] = NULL; 324 | } 325 | 326 | /* allocate memory for the classification */ 327 | classification = 328 | (char*)malloc(256* 329 | sizeof(char)); 330 | 331 | /* get the name of the classification */ 332 | bp_get_classification_from_filename(filename, 333 | classification); 334 | (*classifications)[no_of_images] = classification; 335 | 336 | no_of_images++; 337 | } 338 | } 339 | free(namelist[ctr]); 340 | } 341 | free(namelist); 342 | } 343 | 344 | /* assign a class number to each image */ 345 | bp_classifications_to_numbers(no_of_images, 346 | *classifications, 347 | (*classification_number)); 348 | 349 | return no_of_images; 350 | } 351 | 352 | /* plots mono images */ 353 | void bp_plot_images(unsigned char **images, 354 | int no_of_images, 355 | int image_width, int image_height, 356 | char * filename) 357 | { 358 | int i,y,x,n1,n2; 359 | unsigned char * img; 360 | 361 | /* allocate memory for the image */ 362 | img = (unsigned char*)malloc(image_width*image_height*no_of_images*3); 363 | 364 | for (i = 0; i < no_of_images; i++) { 365 | for (y = 0; y < image_height; y++) { 366 | for (x = 0; x < image_width; x++) { 367 | n1 = ((y+(i*image_height))*image_width + x)*3; 368 | n2 = (y*image_width) + x; 369 | img[n1] = images[i][n2]; 370 | img[n1+1] = img[n1]; 371 | img[n1+2] = img[n1]; 372 | } 373 | } 374 | } 375 | 376 | /* write the image to file */ 377 | deeplearn_write_png(filename, 378 | image_width, image_height*no_of_images, img); 379 | 380 | /* free the image memory */ 381 | free(img); 382 | } 383 | 384 | -------------------------------------------------------------------------------- /src/deeplearn_images.h: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef DEEPLEARN_IMAGES_H 31 | #define DEEPLEARN_IMAGES_H 32 | 33 | #define _SVID_SOURCE 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | 43 | #include 44 | #include 45 | #include 46 | 47 | #define PNG_DEBUG 3 48 | #include 49 | #include "backprop.h" 50 | 51 | void deeplearn_read_png(char * filename, 52 | int * width, int * height, 53 | unsigned char ** buffer); 54 | int deeplearn_write_png(char* filename, 55 | int width, int height, 56 | unsigned char *buffer); 57 | int deeplearn_load_training_images(char * images_directory, 58 | unsigned char *** images, 59 | char *** classifications, 60 | int ** classification_number, 61 | int width, int height); 62 | void bp_plot_images(unsigned char **images, 63 | int no_of_images, 64 | int image_width, int image_height, 65 | char * filename); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/deeplearn_random.c: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "deeplearn_random.h" 31 | 32 | /* Lehmer random number generator */ 33 | int rand_num(unsigned int * seed) 34 | { 35 | unsigned int v = 36 | ((unsigned long long)(*seed) * 279470273UL) % 4294967291UL; 37 | if (v==0) v = (int)time(NULL); /* avoid the singularity */ 38 | *seed = v; 39 | return abs((int)v); 40 | } 41 | -------------------------------------------------------------------------------- /src/deeplearn_random.h: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef DEEPLEARN_RANDOM_H 31 | #define DEEPLEARN_RANDOM_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | int rand_num(unsigned int * seed); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/globals.h: -------------------------------------------------------------------------------- 1 | #ifndef DEEPLEARN_GLOBALS_H 2 | #define DEEPLEARN_GLOBALS_H 3 | 4 | #define DEEPLEARN_TEMP_DIRECTORY "/tmp/" 5 | #define DEEPLEARN_HISTORY_SIZE 1024 6 | #define DEEPLEARN_UNKNOWN_ERROR 9999 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /unittests/maintest.c: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include "tests_random.h" 34 | #include "tests_backprop.h" 35 | #include "tests_deeplearn.h" 36 | #include "tests_images.h" 37 | 38 | int main(int argc, char* argv[]) 39 | { 40 | run_tests_images(); 41 | run_tests_random(); 42 | run_tests_backprop(); 43 | run_tests_deeplearn(); 44 | 45 | return 1; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /unittests/tests_backprop.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013 Bob Mottram 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 3. Neither the name of the University nor the names of its contributors 13 | may be used to endorse or promote products derived from this software 14 | without specific prior written permission. 15 | . 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 20 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "tests_backprop.h" 30 | 31 | static void test_backprop_neuron_init() 32 | { 33 | bp_neuron n; 34 | int no_of_inputs=10; 35 | unsigned int random_seed = 123; 36 | 37 | printf("test_backprop_neuron_init..."); 38 | 39 | bp_neuron_init(&n, no_of_inputs, &random_seed); 40 | bp_neuron_free(&n); 41 | 42 | printf("Ok\n"); 43 | } 44 | 45 | static void test_backprop_inputs_from_image() 46 | { 47 | bp net; 48 | int image_width=10; 49 | int image_height=10; 50 | int x,y,i=0; 51 | unsigned char * img; 52 | int no_of_inputs=image_width*image_height; 53 | int no_of_hiddens=4*4; 54 | int hidden_layers=2; 55 | int no_of_outputs=2*2; 56 | unsigned int random_seed = 123; 57 | 58 | printf("test_backprop_inputs_from_image..."); 59 | 60 | /* create a mono image */ 61 | img = (unsigned char*)malloc(image_width*image_height); 62 | for (y = 0; y < image_height; y++) { 63 | for (x = 0; x < image_width; x++,i++) { 64 | img[i] = i%256; 65 | } 66 | } 67 | 68 | /* create a network */ 69 | bp_init(&net, 70 | no_of_inputs, no_of_hiddens, 71 | hidden_layers, 72 | no_of_outputs, &random_seed); 73 | assert((&net)->inputs!=0); 74 | assert((&net)->hiddens!=0); 75 | assert((&net)->outputs!=0); 76 | 77 | /* set inputs to zero */ 78 | for (i = 0; i < no_of_inputs; i++) { 79 | (&net)->inputs[i]->value = 0; 80 | } 81 | 82 | /* insert the image into the input units */ 83 | bp_inputs_from_image(&net, img, image_width, image_height); 84 | 85 | /* check that the imputs are within range */ 86 | for (i = 0; i < no_of_inputs; i++) { 87 | assert((&net)->inputs[i]->value > 0.1f); 88 | assert((&net)->inputs[i]->value < 0.9f); 89 | } 90 | 91 | /* free the memory */ 92 | free(img); 93 | bp_free(&net); 94 | 95 | printf("Ok\n"); 96 | } 97 | 98 | static void test_backprop_neuron_copy() 99 | { 100 | bp_neuron n1, n2; 101 | int retval, no_of_inputs=10; 102 | unsigned int random_seed = 123; 103 | 104 | printf("test_backprop_neuron_copy..."); 105 | 106 | bp_neuron_init(&n1, no_of_inputs, &random_seed); 107 | bp_neuron_init(&n2, no_of_inputs, &random_seed); 108 | 109 | bp_neuron_copy(&n1, &n2); 110 | 111 | retval = bp_neuron_compare(&n1, &n2); 112 | if (retval != 1) { 113 | printf("\nretval %d\n", retval); 114 | } 115 | assert(retval == 1); 116 | 117 | bp_neuron_free(&n1); 118 | bp_neuron_free(&n2); 119 | 120 | printf("Ok\n"); 121 | } 122 | 123 | static void test_backprop_init() 124 | { 125 | bp net; 126 | int no_of_inputs=10; 127 | int no_of_hiddens=4; 128 | int hidden_layers=2; 129 | int no_of_outputs=2; 130 | unsigned int random_seed = 123; 131 | 132 | printf("test_backprop_init..."); 133 | 134 | bp_init(&net, 135 | no_of_inputs, no_of_hiddens, 136 | hidden_layers, 137 | no_of_outputs, &random_seed); 138 | assert((&net)->inputs!=0); 139 | assert((&net)->hiddens!=0); 140 | assert((&net)->outputs!=0); 141 | bp_free(&net); 142 | 143 | printf("Ok\n"); 144 | } 145 | 146 | static void test_backprop_feed_forward() 147 | { 148 | bp net; 149 | int no_of_inputs=10; 150 | int no_of_hiddens=4; 151 | int hidden_layers=2; 152 | int no_of_outputs=5; 153 | int i; 154 | unsigned int random_seed = 123; 155 | 156 | printf("test_backprop_feed_forward..."); 157 | 158 | bp_init(&net, 159 | no_of_inputs, no_of_hiddens, 160 | hidden_layers, 161 | no_of_outputs, &random_seed); 162 | assert((&net)->inputs!=0); 163 | assert((&net)->hiddens!=0); 164 | assert((&net)->outputs!=0); 165 | 166 | /* set some inputs */ 167 | for (i = 0; i < no_of_inputs; i++) { 168 | bp_set_input(&net, i, i/(float)no_of_inputs); 169 | } 170 | /* clear the outputs */ 171 | for (i = 0; i < no_of_outputs; i++) { 172 | (&net)->outputs[i]->value = 999; 173 | } 174 | 175 | /* feed forward */ 176 | bp_feed_forward(&net); 177 | 178 | /* check for non-zero outputs */ 179 | for (i = 0; i < no_of_outputs; i++) { 180 | assert((&net)->outputs[i]->value != 999); 181 | } 182 | 183 | bp_free(&net); 184 | 185 | printf("Ok\n"); 186 | } 187 | 188 | static void test_backprop() 189 | { 190 | bp net; 191 | int no_of_inputs=10; 192 | int no_of_hiddens=4; 193 | int hidden_layers=2; 194 | int no_of_outputs=5; 195 | int i,l; 196 | unsigned int random_seed = 123; 197 | 198 | printf("test_backprop..."); 199 | 200 | bp_init(&net, 201 | no_of_inputs, no_of_hiddens, 202 | hidden_layers, 203 | no_of_outputs, &random_seed); 204 | assert((&net)->inputs!=0); 205 | assert((&net)->hiddens!=0); 206 | assert((&net)->outputs!=0); 207 | 208 | /* set some inputs */ 209 | for (i = 0; i < no_of_inputs; i++) { 210 | bp_set_input(&net, i, i/(float)no_of_inputs); 211 | (&net)->inputs[i]->BPerror = 999; 212 | } 213 | for (l = 0; l < hidden_layers; l++) { 214 | for (i = 0; i < no_of_hiddens; i++) { 215 | (&net)->hiddens[l][i]->BPerror = 999; 216 | } 217 | } 218 | /* set some target outputs */ 219 | for (i = 0; i < no_of_outputs; i++) { 220 | (&net)->outputs[i]->BPerror = 999; 221 | bp_set_output(&net, i, i/(float)no_of_inputs); 222 | } 223 | 224 | /* feed forward */ 225 | bp_feed_forward(&net); 226 | bp_backprop(&net); 227 | 228 | /* check for non-zero backprop error values */ 229 | for (i = 0; i < no_of_inputs; i++) { 230 | assert((&net)->inputs[i]->BPerror != 999); 231 | } 232 | for (l = 0; l < hidden_layers; l++) { 233 | for (i = 0; i < no_of_hiddens; i++) { 234 | assert((&net)->hiddens[l][i]->BPerror != 999); 235 | } 236 | } 237 | for (i = 0; i < no_of_outputs; i++) { 238 | assert((&net)->outputs[i]->BPerror != 999); 239 | } 240 | 241 | bp_free(&net); 242 | 243 | printf("Ok\n"); 244 | } 245 | 246 | static void test_backprop_update() 247 | { 248 | bp net; 249 | int no_of_inputs=10; 250 | int no_of_hiddens=4; 251 | int hidden_layers=2; 252 | int no_of_outputs=5; 253 | int i; 254 | unsigned int random_seed = 123; 255 | 256 | printf("test_backprop_update..."); 257 | 258 | bp_init(&net, 259 | no_of_inputs, no_of_hiddens, 260 | hidden_layers, 261 | no_of_outputs, &random_seed); 262 | assert((&net)->inputs!=0); 263 | assert((&net)->hiddens!=0); 264 | assert((&net)->outputs!=0); 265 | 266 | /* set some inputs */ 267 | for (i = 0; i < no_of_inputs; i++) { 268 | bp_set_input(&net, i, i/(float)no_of_inputs); 269 | } 270 | 271 | for (i = 0; i < 100; i++) { 272 | bp_update(&net); 273 | } 274 | 275 | bp_free(&net); 276 | 277 | printf("Ok\n"); 278 | } 279 | 280 | static void test_backprop_training() 281 | { 282 | bp * net; 283 | int no_of_inputs=2; 284 | int no_of_hiddens=2; 285 | int hidden_layers=1; 286 | int no_of_outputs=1; 287 | int itt,example; 288 | unsigned int random_seed = 123; 289 | float state_TRUE = 0.8f; 290 | float state_FALSE = 0.2f; 291 | 292 | printf("test_backprop_training..."); 293 | 294 | net = (bp*)malloc(sizeof(bp)); 295 | bp_init(net, 296 | no_of_inputs, no_of_hiddens, 297 | hidden_layers, 298 | no_of_outputs, &random_seed); 299 | assert(net->inputs!=0); 300 | assert(net->hiddens!=0); 301 | assert(net->outputs!=0); 302 | 303 | /* training */ 304 | example=0; 305 | for (itt = 0; itt < 500000; itt++, example++) { 306 | if (example>=4) example=0; 307 | 308 | /* select an example from the XOR truth table */ 309 | switch(example) { 310 | case 0: { 311 | bp_set_input(net, 0, state_FALSE); 312 | bp_set_input(net, 1, state_FALSE); 313 | bp_set_output(net, 0, state_FALSE); 314 | break; 315 | } 316 | case 1: { 317 | bp_set_input(net, 0, state_TRUE); 318 | bp_set_input(net, 1, state_FALSE); 319 | bp_set_output(net, 0, state_TRUE); 320 | break; 321 | } 322 | case 2: { 323 | bp_set_input(net, 0, state_FALSE); 324 | bp_set_input(net, 1, state_TRUE); 325 | bp_set_output(net, 0, state_TRUE); 326 | break; 327 | } 328 | case 3: { 329 | bp_set_input(net, 0, state_TRUE); 330 | bp_set_input(net, 1, state_TRUE); 331 | bp_set_output(net, 0, state_FALSE); 332 | break; 333 | } 334 | } 335 | 336 | /* train on the example */ 337 | bp_update(net); 338 | } 339 | 340 | bp_set_input(net, 0, state_FALSE); 341 | bp_set_input(net, 1, state_FALSE); 342 | bp_feed_forward(net); 343 | if (bp_get_output(net, 0) >= 0.5f) { 344 | printf("\n%.5f\n",bp_get_output(net, 0)); 345 | } 346 | assert(bp_get_output(net, 0) < 0.5f); 347 | 348 | bp_set_input(net, 0, state_FALSE); 349 | bp_set_input(net, 1, state_TRUE); 350 | bp_feed_forward(net); 351 | if (bp_get_output(net, 0) <= 0.5f) { 352 | printf("\n%.5f\n",bp_get_output(net, 0)); 353 | } 354 | assert(bp_get_output(net, 0) > 0.5f); 355 | 356 | bp_set_input(net, 0, state_TRUE); 357 | bp_set_input(net, 1, state_FALSE); 358 | bp_feed_forward(net); 359 | if (bp_get_output(net, 0) <= 0.5f) { 360 | printf("\n%.5f\n",bp_get_output(net, 0)); 361 | } 362 | assert(bp_get_output(net, 0) > 0.5f); 363 | 364 | bp_set_input(net, 0, state_FALSE); 365 | bp_set_input(net, 1, state_FALSE); 366 | bp_feed_forward(net); 367 | if (bp_get_output(net, 0) >= 0.5f) { 368 | printf("\n%.5f\n",bp_get_output(net, 0)); 369 | } 370 | assert(bp_get_output(net, 0) < 0.5f); 371 | 372 | bp_free(net); 373 | free(net); 374 | 375 | printf("Ok\n"); 376 | } 377 | 378 | static void test_backprop_autocoder() 379 | { 380 | bp autocoder; 381 | int itt,i,j; 382 | int no_of_inputs=10; 383 | int no_of_hiddens=4; 384 | int no_of_outputs=10; 385 | unsigned int random_seed = 123; 386 | float tot; 387 | 388 | printf("test_backprop_autocoder..."); 389 | 390 | /* create the autocoder */ 391 | bp_init(&autocoder, 392 | no_of_inputs, 393 | no_of_hiddens,1, 394 | no_of_outputs, 395 | &random_seed); 396 | 397 | autocoder.learningRate = 0.5f; 398 | 399 | /* run the autocoder for some itterations */ 400 | for (itt = 0; itt < 100; itt++) { 401 | /* set the inputs */ 402 | for (i = 0; i < no_of_inputs; i++) { 403 | bp_set_input(&autocoder,i,0.25f + (i*0.5f/(float)no_of_inputs)); 404 | bp_set_output(&autocoder,i,0.75f - (i*0.5f/(float)no_of_inputs)); 405 | } 406 | /* update */ 407 | bp_update(&autocoder); 408 | } 409 | 410 | for (i = 0; i < no_of_hiddens; i++) { 411 | /* check that some errors have been back-propogated */ 412 | assert((&autocoder)->hiddens[0][i]->BPerror != 0); 413 | /* check that weights have changed */ 414 | tot = 0; 415 | for (j = 0; j < no_of_inputs; j++) { 416 | assert((&autocoder)->hiddens[0][i]->lastWeightChange[j]!=0); 417 | tot += fabs((&autocoder)->hiddens[0][i]->lastWeightChange[j]); 418 | } 419 | /* total weight change */ 420 | assert(tot > 0.00001f); 421 | } 422 | 423 | bp_free(&autocoder); 424 | 425 | printf("Ok\n"); 426 | } 427 | 428 | 429 | static void test_backprop_deep() 430 | { 431 | bp net; 432 | bp autocoder; 433 | int l,itt,i; 434 | int no_of_inputs=10; 435 | int no_of_hiddens=4; 436 | int hidden_layers=3; 437 | int no_of_outputs=2; 438 | unsigned int random_seed = 123; 439 | 440 | printf("test_backprop_deep..."); 441 | 442 | bp_init(&net, 443 | no_of_inputs, no_of_hiddens, 444 | hidden_layers, 445 | no_of_outputs, &random_seed); 446 | assert((&net)->inputs!=0); 447 | assert((&net)->hiddens!=0); 448 | assert((&net)->outputs!=0); 449 | 450 | for (l = 0; l < hidden_layers; l++) { 451 | /* create an autocoder for this layer */ 452 | bp_create_autocoder(&net,l,&autocoder); 453 | /* do some training */ 454 | for (itt = 0; itt < 100; itt++) { 455 | /* set the inputs */ 456 | for (i = 0; i < no_of_inputs; i++) { 457 | bp_set_input(&net,i,i/(float)no_of_inputs); 458 | } 459 | /* update */ 460 | bp_pretrain(&net,&autocoder,l); 461 | } 462 | /* move the autocoder hidden weights into the main network */ 463 | bp_update_from_autocoder(&net,&autocoder,l); 464 | /* delete the autocoder */ 465 | bp_free(&autocoder); 466 | } 467 | 468 | bp_free(&net); 469 | 470 | printf("Ok\n"); 471 | } 472 | 473 | static void test_backprop_neuron_save_load() 474 | { 475 | bp_neuron n1, n2; 476 | int no_of_inputs=10; 477 | unsigned int random_seed = 123; 478 | char filename[256]; 479 | FILE * fp; 480 | 481 | printf("test_backprop_neuron_save_load..."); 482 | 483 | /* create neurons */ 484 | bp_neuron_init(&n1, no_of_inputs, &random_seed); 485 | bp_neuron_init(&n2, no_of_inputs, &random_seed); 486 | 487 | sprintf(filename,"%stemp_deep.dat",DEEPLEARN_TEMP_DIRECTORY); 488 | 489 | /* save the first neuron */ 490 | fp = fopen(filename,"wb"); 491 | assert(fp!=0); 492 | bp_neuron_save(fp, &n1); 493 | fclose(fp); 494 | 495 | /* load into the second neuron */ 496 | fp = fopen(filename,"rb"); 497 | assert(fp!=0); 498 | bp_neuron_load(fp, &n2); 499 | fclose(fp); 500 | 501 | /* compare the two */ 502 | assert(bp_neuron_compare(&n1, &n2)==1); 503 | 504 | /* free memory */ 505 | bp_neuron_free(&n1); 506 | bp_neuron_free(&n2); 507 | 508 | printf("Ok\n"); 509 | } 510 | 511 | static void test_backprop_save_load() 512 | { 513 | bp net1, net2; 514 | int no_of_inputs=10; 515 | int no_of_hiddens=4; 516 | int no_of_outputs=3; 517 | int hidden_layers=3; 518 | int retval; 519 | unsigned int random_seed = 123; 520 | char filename[256]; 521 | FILE * fp; 522 | 523 | printf("test_backprop_save_load..."); 524 | 525 | /* create network */ 526 | bp_init(&net1, 527 | no_of_inputs, no_of_hiddens, 528 | hidden_layers, no_of_outputs, 529 | &random_seed); 530 | 531 | sprintf(filename,"%stemp_deep.dat",DEEPLEARN_TEMP_DIRECTORY); 532 | 533 | /* save the first network */ 534 | fp = fopen(filename,"wb"); 535 | assert(fp!=0); 536 | bp_save(fp, &net1); 537 | fclose(fp); 538 | 539 | /* load into the second network */ 540 | fp = fopen(filename,"rb"); 541 | assert(fp!=0); 542 | bp_load(fp, &net2, &random_seed); 543 | fclose(fp); 544 | 545 | /* compare the two */ 546 | retval = bp_compare(&net1, &net2); 547 | if (retval<1) { 548 | printf("\nretval = %d\n",retval); 549 | } 550 | assert(retval==1); 551 | 552 | /* free memory */ 553 | bp_free(&net1); 554 | bp_free(&net2); 555 | 556 | printf("Ok\n"); 557 | } 558 | 559 | static void test_backprop_classification_from_filename() 560 | { 561 | char classification[256]; 562 | 563 | printf("test_backprop_classification_from_filename..."); 564 | 565 | bp_get_classification_from_filename("class.number.png", 566 | classification); 567 | assert(strcmp(classification,"class")==0); 568 | bp_get_classification_from_filename("/my/directory/test.number.png", 569 | classification); 570 | assert(strcmp(classification,"test")==0); 571 | printf("Ok\n"); 572 | } 573 | 574 | static void test_backprop_classifications_to_numbers() 575 | { 576 | char * classifications[] = { 577 | "face7", "face1", "face7", "face10", "face10", "face1" }; 578 | int numbers[6]; 579 | 580 | printf("test_backprop_classifications_to_numbers..."); 581 | 582 | bp_classifications_to_numbers(6, classifications, numbers); 583 | assert(numbers[0] == 0); 584 | assert(numbers[1] == 1); 585 | assert(numbers[2] == 0); 586 | assert(numbers[3] == 2); 587 | assert(numbers[4] == 2); 588 | assert(numbers[5] == 1); 589 | 590 | printf("Ok\n"); 591 | } 592 | 593 | int run_tests_backprop() 594 | { 595 | printf("\nRunning backprop tests\n"); 596 | 597 | test_backprop_neuron_init(); 598 | test_backprop_neuron_copy(); 599 | test_backprop_init(); 600 | test_backprop_feed_forward(); 601 | test_backprop(); 602 | test_backprop_update(); 603 | test_backprop_training(); 604 | test_backprop_deep(); 605 | test_backprop_neuron_save_load(); 606 | test_backprop_save_load(); 607 | test_backprop_inputs_from_image(); 608 | test_backprop_autocoder(); 609 | test_backprop_classification_from_filename(); 610 | test_backprop_classifications_to_numbers(); 611 | 612 | printf("All backprop tests completed\n"); 613 | return 1; 614 | } 615 | -------------------------------------------------------------------------------- /unittests/tests_backprop.h: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef DEEPLEARN_TESTS_BACKPROP_H 31 | #define DEEPLEARN_TESTS_BACKPROP_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "globals.h" 40 | #include "backprop.h" 41 | 42 | int run_tests_backprop(); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /unittests/tests_deeplearn.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013 Bob Mottram 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 3. Neither the name of the University nor the names of its contributors 13 | may be used to endorse or promote products derived from this software 14 | without specific prior written permission. 15 | . 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 20 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "tests_deeplearn.h" 30 | 31 | static void test_deeplearn_init() 32 | { 33 | deeplearn learner; 34 | int no_of_inputs=10; 35 | int no_of_hiddens=4; 36 | int hidden_layers=2; 37 | int no_of_outputs=2; 38 | float error_threshold[] = { 0.01f, 0.01f, 0.01f }; 39 | unsigned int random_seed = 123; 40 | 41 | printf("test_deeplearn_init..."); 42 | 43 | /* create the learner */ 44 | deeplearn_init(&learner, 45 | no_of_inputs, no_of_hiddens, 46 | hidden_layers, 47 | no_of_outputs, 48 | error_threshold, 49 | &random_seed); 50 | 51 | assert((&learner)->net!=0); 52 | assert((&learner)->autocoder!=0); 53 | 54 | /* free memory */ 55 | deeplearn_free(&learner); 56 | 57 | printf("Ok\n"); 58 | } 59 | 60 | static void test_deeplearn_update() 61 | { 62 | deeplearn learner, learner2; 63 | int no_of_inputs=10; 64 | int no_of_hiddens=4; 65 | int hidden_layers=2; 66 | int no_of_outputs=2; 67 | float error_threshold[] = { 0.1f, 0.1f, 0.1f }; 68 | int itt,i,retval; 69 | unsigned int random_seed = 123; 70 | float v,diff; 71 | int itterations[3]; 72 | char filename[256]; 73 | FILE * fp; 74 | 75 | printf("test_deeplearn_update..."); 76 | 77 | itterations[0] = 0; 78 | itterations[1] = 0; 79 | itterations[2] = 0; 80 | 81 | /* create the learner */ 82 | deeplearn_init(&learner, 83 | no_of_inputs, no_of_hiddens, 84 | hidden_layers, 85 | no_of_outputs, 86 | error_threshold, 87 | &random_seed); 88 | 89 | assert((&learner)->net!=0); 90 | assert((&learner)->autocoder!=0); 91 | 92 | /* perform pre-training with an autocoder */ 93 | for (itt = 0; itt < 10000; itt++) { 94 | for (i = 0; i < no_of_inputs; i++) { 95 | deeplearn_set_input(&learner,i, 96 | 0.25f + (i*0.5f/(float)no_of_inputs)); 97 | } 98 | deeplearn_update(&learner); 99 | 100 | itterations[learner.current_hidden_layer]++; 101 | 102 | if (learner.current_hidden_layer==hidden_layers) { 103 | break; 104 | } 105 | } 106 | if (learner.current_hidden_layer < hidden_layers) { 107 | printf("\nDidn't finish training (at layer %d)\nBPerror %.5f\n", 108 | learner.current_hidden_layer,learner.BPerror); 109 | } 110 | assert(learner.current_hidden_layer >= hidden_layers); 111 | 112 | /* we expect that there will be some non-zero error */ 113 | assert(learner.BPerror!=0); 114 | 115 | /* test that it took some itterations to train */ 116 | assert(itterations[0] > 4); 117 | assert(itterations[1] > 4); 118 | 119 | /* perform the final training between the last 120 | hidden layer and the outputs */ 121 | for (itt = 0; itt < 10000; itt++) { 122 | for (i = 0; i < no_of_inputs; i++) { 123 | deeplearn_set_input(&learner,i,i/(float)no_of_inputs); 124 | } 125 | for (i = 0; i < no_of_outputs; i++) { 126 | deeplearn_set_output(&learner,i, 127 | 1.0f - (i/(float)no_of_inputs)); 128 | } 129 | deeplearn_update(&learner); 130 | 131 | itterations[learner.current_hidden_layer]++; 132 | } 133 | 134 | /* test that it took some itterations to 135 | do the final training */ 136 | assert(itterations[2] > 4); 137 | 138 | /* we expect that there will be some non-zero error */ 139 | assert(learner.BPerror!=0); 140 | 141 | /* check that there is some variation in the outputs */ 142 | v = deeplearn_get_output(&learner,0); 143 | for (i = 1; i < no_of_outputs; i++) { 144 | diff = fabs(v - deeplearn_get_output(&learner,i)); 145 | assert(diff > 0); 146 | } 147 | 148 | sprintf(filename,"%stemp_deep.dat",DEEPLEARN_TEMP_DIRECTORY); 149 | 150 | /* save the first learner */ 151 | fp = fopen(filename,"wb"); 152 | assert(fp!=0); 153 | deeplearn_save(fp, &learner); 154 | fclose(fp); 155 | 156 | /* load into the second learner */ 157 | fp = fopen(filename,"rb"); 158 | assert(fp!=0); 159 | deeplearn_load(fp, &learner2, &random_seed); 160 | fclose(fp); 161 | 162 | /* compare the two */ 163 | retval = deeplearn_compare(&learner, &learner2); 164 | if (retval<1) { 165 | printf("\nretval = %d\n",retval); 166 | } 167 | assert(retval==1); 168 | 169 | /* save a graph */ 170 | sprintf(filename,"%stemp_graph.png",DEEPLEARN_TEMP_DIRECTORY); 171 | deeplearn_plot_history(&learner, 172 | filename, "Training Error", 173 | 1024, 480); 174 | 175 | /* free memory */ 176 | deeplearn_free(&learner); 177 | deeplearn_free(&learner2); 178 | 179 | printf("Ok\n"); 180 | } 181 | 182 | static void test_deeplearn_save_load() 183 | { 184 | deeplearn learner1, learner2; 185 | int no_of_inputs=10; 186 | int no_of_hiddens=4; 187 | int no_of_outputs=3; 188 | int hidden_layers=3; 189 | float error_threshold[] = { 0.01f, 0.01f, 0.01f, 0.01f }; 190 | int retval; 191 | unsigned int random_seed = 123; 192 | char filename[256]; 193 | FILE * fp; 194 | 195 | printf("test_deeplearn_save_load..."); 196 | 197 | /* create network */ 198 | deeplearn_init(&learner1, 199 | no_of_inputs, no_of_hiddens, 200 | hidden_layers, no_of_outputs, 201 | error_threshold, 202 | &random_seed); 203 | 204 | sprintf(filename,"%stemp_deep.dat",DEEPLEARN_TEMP_DIRECTORY); 205 | 206 | /* save the first learner */ 207 | fp = fopen(filename,"wb"); 208 | assert(fp!=0); 209 | deeplearn_save(fp, &learner1); 210 | fclose(fp); 211 | 212 | /* load into the second learner */ 213 | fp = fopen(filename,"rb"); 214 | assert(fp!=0); 215 | deeplearn_load(fp, &learner2, &random_seed); 216 | fclose(fp); 217 | 218 | /* compare the two */ 219 | retval = deeplearn_compare(&learner1, &learner2); 220 | if (retval<1) { 221 | printf("\nretval = %d\n",retval); 222 | } 223 | assert(retval==1); 224 | 225 | /* free memory */ 226 | deeplearn_free(&learner1); 227 | deeplearn_free(&learner2); 228 | 229 | printf("Ok\n"); 230 | } 231 | 232 | int run_tests_deeplearn() 233 | { 234 | printf("\nRunning deeplearn tests\n"); 235 | 236 | test_deeplearn_init(); 237 | test_deeplearn_save_load(); 238 | test_deeplearn_update(); 239 | 240 | printf("All deeplearn tests completed\n"); 241 | return 1; 242 | } 243 | -------------------------------------------------------------------------------- /unittests/tests_deeplearn.h: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef DEEPLEARN_TESTS_DEEPLEARN_H 31 | #define DEEPLEARN_TESTS_DEEPLEARN_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "globals.h" 40 | #include "backprop.h" 41 | #include "deeplearn.h" 42 | 43 | int run_tests_deeplearn(); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /unittests/tests_images.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013 Bob Mottram 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 3. Neither the name of the University nor the names of its contributors 13 | may be used to endorse or promote products derived from this software 14 | without specific prior written permission. 15 | . 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 20 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "tests_images.h" 30 | 31 | static void save_image(char * filename) 32 | { 33 | int width = 80; 34 | int height = 80; 35 | unsigned char * buffer; 36 | int i; 37 | FILE * fp; 38 | 39 | /* allocate memory */ 40 | buffer = (unsigned char*)malloc(width*height*3* 41 | sizeof(unsigned char)); 42 | assert(buffer != 0); 43 | 44 | /* create a random image */ 45 | for (i = 0; i < width*height*3; i+=3) { 46 | buffer[i] = i%256; 47 | buffer[i+1] = 255 - buffer[i]; 48 | buffer[i+2] = buffer[i]; 49 | } 50 | 51 | /* write to file */ 52 | deeplearn_write_png(filename, width, height, buffer); 53 | 54 | /* free memory */ 55 | free(buffer); 56 | 57 | /* check that the file has saved */ 58 | fp = fopen(filename,"rb"); 59 | assert(fp); 60 | fclose(fp); 61 | } 62 | 63 | static void test_save_image() 64 | { 65 | char filename[256], commandstr[256]; 66 | 67 | printf("test_save_image..."); 68 | 69 | sprintf(filename,"%stemp_img.png",DEEPLEARN_TEMP_DIRECTORY); 70 | save_image(filename); 71 | 72 | /* remove the image */ 73 | sprintf(commandstr,"rm -f %stemp_img.png", 74 | DEEPLEARN_TEMP_DIRECTORY); 75 | system(commandstr); 76 | 77 | printf("Ok\n"); 78 | } 79 | 80 | static void test_load_image() 81 | { 82 | char filename[256], commandstr[256]; 83 | unsigned char * buffer; 84 | int i,width,height; 85 | 86 | printf("test_load_image..."); 87 | 88 | /* save a tests image */ 89 | sprintf(filename,"%stemp_deeplearn_img.png",DEEPLEARN_TEMP_DIRECTORY); 90 | save_image(filename); 91 | 92 | /* load image from file */ 93 | deeplearn_read_png(filename, &width, &height, &buffer); 94 | 95 | /* check image properties */ 96 | assert(width==80); 97 | assert(height==80); 98 | 99 | /* check the pixels */ 100 | for (i = 0; i < width*height*3; i+=3) { 101 | assert(buffer[i] == i%256); 102 | assert(buffer[i+1] == 255 - buffer[i]); 103 | assert(buffer[i+2] == buffer[i]); 104 | } 105 | 106 | /* free memory */ 107 | free(buffer); 108 | 109 | /* remove the image */ 110 | sprintf(commandstr,"rm -f %stemp_deeplearn_img.png", 111 | DEEPLEARN_TEMP_DIRECTORY); 112 | system(commandstr); 113 | 114 | printf("Ok\n"); 115 | } 116 | 117 | static void test_load_training_images() 118 | { 119 | char filename[256]; 120 | unsigned char ** images=NULL; 121 | char ** classifications=NULL; 122 | int * numbers; 123 | int im; 124 | int no_of_images = 3; 125 | int no_of_images2; 126 | int width=40,height=40; 127 | char commandstr[256],str[256]; 128 | 129 | printf("test_load_training_images..."); 130 | 131 | /* create a directory for the images */ 132 | sprintf(commandstr,"mkdir %sdeeplearn_test_images", 133 | DEEPLEARN_TEMP_DIRECTORY); 134 | system(commandstr); 135 | 136 | /* save a tests images */ 137 | for (im = 0; im < no_of_images; im++) { 138 | sprintf(filename,"%sdeeplearn_test_images/img%d.%d.png", 139 | DEEPLEARN_TEMP_DIRECTORY, im%2, im); 140 | save_image(filename); 141 | } 142 | 143 | sprintf(str,"%sdeeplearn_test_images", 144 | DEEPLEARN_TEMP_DIRECTORY); 145 | 146 | /* load the images */ 147 | no_of_images2 = 148 | deeplearn_load_training_images(str, 149 | &images, 150 | &classifications, 151 | &numbers, 152 | width, height); 153 | assert(no_of_images == no_of_images2); 154 | assert(images!=NULL); 155 | 156 | /* free memory */ 157 | for (im = 0; im < no_of_images; im++) { 158 | free(images[im]); 159 | free(classifications[im]); 160 | } 161 | free(images); 162 | free(classifications); 163 | free(numbers); 164 | 165 | /* remove the images */ 166 | sprintf(commandstr,"rm -rf %sdeeplearn_test_images", 167 | DEEPLEARN_TEMP_DIRECTORY); 168 | system(commandstr); 169 | 170 | printf("Ok\n"); 171 | } 172 | 173 | int run_tests_images() 174 | { 175 | printf("\nRunning images tests\n"); 176 | 177 | test_save_image(); 178 | test_load_image(); 179 | test_load_training_images(); 180 | 181 | printf("All images tests completed\n"); 182 | return 1; 183 | } 184 | -------------------------------------------------------------------------------- /unittests/tests_images.h: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef DEEPLEARN_TESTS_IMAGES_H 31 | #define DEEPLEARN_TESTS_IMAGES_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "globals.h" 40 | #include "deeplearn_images.h" 41 | 42 | int run_tests_images(); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /unittests/tests_random.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013 Bob Mottram 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 3. Neither the name of the University nor the names of its contributors 13 | may be used to endorse or promote products derived from this software 14 | without specific prior written permission. 15 | . 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 20 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "tests_random.h" 30 | 31 | static void test_rand_num() 32 | { 33 | unsigned int random_seed=0; 34 | int i,j,t,v,min=0,max=0; 35 | int test1[50]; 36 | int test2[50]; 37 | int test3[50]; 38 | int * result; 39 | int same=0,repeats=0; 40 | 41 | printf("test_rand_num..."); 42 | 43 | /* run three sequences with different seeds */ 44 | for (t = 0; t < 3; t++) { 45 | switch(t) { 46 | case 0: { random_seed = 123; result = (int*)test1; break; } 47 | case 1: { random_seed = 555; result = (int*)test2; break; } 48 | case 2: { random_seed = 8323; result = (int*)test3; break; } 49 | } 50 | for (i = 0; i < 50; i++) { 51 | result[i] = rand_num(&random_seed); 52 | } 53 | } 54 | 55 | for (i = 0; i < 50; i++) { 56 | /* check that the sequences are different */ 57 | if ((test1[i]==test2[i]) || 58 | (test1[i]==test3[i]) || 59 | (test2[i]==test3[i])) { 60 | same++; 61 | } 62 | 63 | /* check the number of repeats within each sequence */ 64 | for (j = 0; j < 50; j++) { 65 | if (i!=j) { 66 | if ((test1[i]==test1[j]) || 67 | (test2[i]==test2[j]) || 68 | (test3[i]==test3[j])) { 69 | repeats++; 70 | } 71 | } 72 | } 73 | } 74 | assert(same < 2); 75 | assert(repeats < 2); 76 | 77 | /* check that the range is not too restricted */ 78 | for (i = 0; i < 10000; i ++) { 79 | v = rand_num(&random_seed); 80 | if ((i==0) || 81 | ((i>0) && (v0) && (v>max))) { 86 | max = v; 87 | } 88 | } 89 | assert(max > min); 90 | assert(min >= 0); 91 | assert(max - min > 60000); 92 | 93 | printf("Ok\n"); 94 | } 95 | 96 | int run_tests_random() 97 | { 98 | printf("\nRunning random number generator tests\n"); 99 | 100 | test_rand_num(); 101 | 102 | printf("All random number generator tests completed\n"); 103 | return 1; 104 | } 105 | -------------------------------------------------------------------------------- /unittests/tests_random.h: -------------------------------------------------------------------------------- 1 | /* 2 | libdeep - a library for deep learning 3 | Copyright (C) 2013 Bob Mottram 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the University nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | . 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef DEEPLEARN_TESTS_RANDOM_H 31 | #define DEEPLEARN_TESTS_RANDOM_H 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "deeplearn_random.h" 40 | 41 | int run_tests_random(); 42 | 43 | #endif 44 | --------------------------------------------------------------------------------