├── LICENSE
├── README.md
├── image_phase_vs_magnitude.ipynb
├── iris_dataset
└── iris.csv
├── network_boolean.ipynb
├── network_mnist.ipynb
├── single_neuron-periodic-iris.ipynb
├── single_neuron-periodic-mnist.ipynb
├── single_neuron-periodic.ipynb
├── single_neuron.ipynb
└── test_image
└── test.jpg
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # complex_valued_neuralnetwork
--------------------------------------------------------------------------------
/iris_dataset/iris.csv:
--------------------------------------------------------------------------------
1 | Type,PW,PL,SW,SL
2 | 0,2,14,33,50
3 | 1,24,56,31,67
4 | 1,23,51,31,69
5 | 0,2,10,36,46
6 | 1,20,52,30,65
7 | 1,19,51,27,58
8 | 2,13,45,28,57
9 | 2,16,47,33,63
10 | 1,17,45,25,49
11 | 2,14,47,32,70
12 | 0,2,16,31,48
13 | 1,19,50,25,63
14 | 0,1,14,36,49
15 | 0,2,13,32,44
16 | 2,12,40,26,58
17 | 1,18,49,27,63
18 | 2,10,33,23,50
19 | 0,2,16,38,51
20 | 0,2,16,30,50
21 | 1,21,56,28,64
22 | 0,4,19,38,51
23 | 0,2,14,30,49
24 | 2,10,41,27,58
25 | 2,15,45,29,60
26 | 0,2,14,36,50
27 | 1,19,51,27,58
28 | 0,4,15,34,54
29 | 1,18,55,31,64
30 | 2,10,33,24,49
31 | 0,2,14,42,55
32 | 1,15,50,22,60
33 | 2,14,39,27,52
34 | 0,2,14,29,44
35 | 2,12,39,27,58
36 | 1,23,57,32,69
37 | 2,15,42,30,59
38 | 1,20,49,28,56
39 | 1,18,58,25,67
40 | 2,13,44,23,63
41 | 2,15,49,25,63
42 | 2,11,30,25,51
43 | 1,21,54,31,69
44 | 1,25,61,36,72
45 | 2,13,36,29,56
46 | 1,21,55,30,68
47 | 0,1,14,30,48
48 | 0,3,17,38,57
49 | 2,14,44,30,66
50 | 0,4,15,37,51
51 | 2,17,50,30,67
52 | 1,22,56,28,64
53 | 1,15,51,28,63
54 | 2,15,45,22,62
55 | 2,14,46,30,61
56 | 2,11,39,25,56
57 | 1,23,59,32,68
58 | 1,23,54,34,62
59 | 1,25,57,33,67
60 | 0,2,13,35,55
61 | 2,15,45,32,64
62 | 1,18,51,30,59
63 | 1,23,53,32,64
64 | 2,15,45,30,54
65 | 1,21,57,33,67
66 | 0,2,13,30,44
67 | 0,2,16,32,47
68 | 1,18,60,32,72
69 | 1,18,49,30,61
70 | 0,2,12,32,50
71 | 0,1,11,30,43
72 | 2,14,44,31,67
73 | 0,2,14,35,51
74 | 0,4,16,34,50
75 | 2,10,35,26,57
76 | 1,23,61,30,77
77 | 2,13,42,26,57
78 | 0,1,15,41,52
79 | 1,18,48,30,60
80 | 2,13,42,27,56
81 | 0,2,15,31,49
82 | 0,4,17,39,54
83 | 2,16,45,34,60
84 | 2,10,35,20,50
85 | 0,2,13,32,47
86 | 2,13,54,29,62
87 | 0,2,15,34,51
88 | 2,10,50,22,60
89 | 0,1,15,31,49
90 | 0,2,15,37,54
91 | 2,12,47,28,61
92 | 2,13,41,28,57
93 | 0,4,13,39,54
94 | 1,20,51,32,65
95 | 2,15,49,31,69
96 | 2,13,40,25,55
97 | 0,3,13,23,45
98 | 0,3,15,38,51
99 | 2,14,48,28,68
100 | 0,2,15,35,52
101 | 1,25,60,33,63
102 | 2,15,46,28,65
103 | 0,3,14,34,46
104 | 2,18,48,32,59
105 | 2,16,51,27,60
106 | 1,18,55,30,65
107 | 0,5,17,33,51
108 | 1,22,67,38,77
109 | 1,21,66,30,76
110 | 1,13,52,30,67
111 | 2,13,40,28,61
112 | 2,11,38,24,55
113 | 0,2,14,34,52
114 | 1,20,64,38,79
115 | 0,6,16,35,50
116 | 1,20,67,28,77
117 | 2,12,44,26,55
118 | 0,3,14,30,48
119 | 0,2,19,34,48
120 | 1,14,56,26,61
121 | 0,2,12,40,58
122 | 1,18,48,28,62
123 | 2,15,45,30,56
124 | 0,2,14,32,46
125 | 0,4,15,44,57
126 | 1,24,56,34,63
127 | 1,16,58,30,72
128 | 1,21,59,30,71
129 | 1,18,56,29,63
130 | 2,12,42,30,57
131 | 1,23,69,26,77
132 | 2,13,56,29,66
133 | 0,2,15,34,52
134 | 2,10,37,24,55
135 | 0,2,15,31,46
136 | 1,19,61,28,74
137 | 0,3,13,35,50
138 | 1,18,63,29,73
139 | 2,15,47,31,67
140 | 2,13,41,30,56
141 | 2,13,43,29,64
142 | 1,22,58,30,65
143 | 0,3,14,35,51
144 | 2,14,47,29,61
145 | 1,19,53,27,64
146 | 0,2,16,34,48
147 | 1,20,50,25,57
148 | 2,13,40,23,55
149 | 0,2,17,34,54
150 | 1,24,51,28,58
151 | 0,2,15,37,53
152 |
--------------------------------------------------------------------------------
/network_boolean.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 26,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "# neural network of many complex valued neurons in 3 layers\n",
12 | "import numpy"
13 | ]
14 | },
15 | {
16 | "cell_type": "code",
17 | "execution_count": 27,
18 | "metadata": {
19 | "collapsed": false
20 | },
21 | "outputs": [],
22 | "source": [
23 | "class neuralNetwork:\n",
24 | " \n",
25 | " def __init__(self, inputnodes, hiddennodes, outputnodes, cats, periods):\n",
26 | " # set number of nodes in each input, hidden, output layer\n",
27 | " self.inodes = inputnodes + 1 # increament for bias node\n",
28 | " self.hnodes = hiddennodes\n",
29 | " self.onodes = outputnodes\n",
30 | " \n",
31 | " # link weight matrices, wih and who\n",
32 | " # weights inside the arrays are w_i_j, where link is from node i to node j in the next layer\n",
33 | " # w11 w21\n",
34 | " # w12 w22 etc \n",
35 | " self.wih = numpy.random.uniform(-1.0, 1.0, (self.hnodes, self.inodes))\n",
36 | " self.wih = numpy.array(self.wih, ndmin=2, dtype='complex128')\n",
37 | " self.wih += 1j * numpy.random.uniform(-1.0, 1.0, (self.hnodes, self.inodes))\n",
38 | " \n",
39 | " self.who = numpy.random.uniform(-1.0, 1.0, (self.onodes, self.hnodes))\n",
40 | " self.who = numpy.array(self.who, ndmin=2, dtype='complex128')\n",
41 | " self.who += 1j * numpy.random.random((self.onodes, self.hnodes))\n",
42 | " \n",
43 | " # number of output class categories\n",
44 | " self.categories = cats\n",
45 | " \n",
46 | " # todo periodicity\n",
47 | " self.periodicity = periods\n",
48 | " pass\n",
49 | " \n",
50 | " def z_to_class(self, z):\n",
51 | " # first work out the angle, but shift angle from [-pi/2, +pi.2] to [0,2pi]\n",
52 | " angle = numpy.mod(numpy.angle(z) + 2*numpy.pi, 2*numpy.pi)\n",
53 | " # from angle to category\n",
54 | " p = int(numpy.floor (self.categories * angle / (2*numpy.pi)))\n",
55 | " return p\n",
56 | "\n",
57 | " def class_to_angle(self, p):\n",
58 | " # class to angle, using bisector\n",
59 | " angle = ((p + 0.5) / self.categories) * 2 * numpy.pi\n",
60 | " return angle\n",
61 | " \n",
62 | " def status(self):\n",
63 | " print (\"self.wih = \", self.wih)\n",
64 | " print (\"self.who = \", self.who)\n",
65 | " pass\n",
66 | "\n",
67 | " def query(self, inputs_list):\n",
68 | " # add bias input\n",
69 | " inputs_list.append(1.0)\n",
70 | " \n",
71 | " # convert input to complex\n",
72 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
73 | " print(\"inputs = \\n\", inputs)\n",
74 | " \n",
75 | " # signal into hidden layer\n",
76 | " hidden_inputs = numpy.dot(self.wih, inputs)\n",
77 | " #print(\"hidden_inputs = \", hidden_inputs)\n",
78 | " #signal out of hidden layer\n",
79 | " hidden_outputs = numpy.exp(1j * numpy.angle(hidden_inputs))\n",
80 | " #print(\"hidden_outputs = \", hidden_outputs)\n",
81 | " \n",
82 | " # signal into final output layer\n",
83 | " final_inputs = numpy.dot(self.who, hidden_outputs)\n",
84 | " #print(\"final_input = \", final_inputs)\n",
85 | " #signal out of output layer\n",
86 | " final_outputs = numpy.exp(1j * numpy.angle(final_inputs))\n",
87 | " #print(\"final_outputs = \", final_outputs)\n",
88 | " \n",
89 | " # map to output classes\n",
90 | " output_classes = self.z_to_class(final_outputs)\n",
91 | " print(\"output_classes = \", output_classes)\n",
92 | " return output_classes\n",
93 | " \n",
94 | " def train(self, inputs_list, target_class_list):\n",
95 | " # add bias input\n",
96 | " inputs_list.append(1.0)\n",
97 | " \n",
98 | " # convert input to complex\n",
99 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
100 | " #print(\"inputs = \\n\", inputs)\n",
101 | " \n",
102 | " # map target classes to unit circle\n",
103 | " targets = numpy.exp(1j * self.class_to_angle(numpy.array(target_class_list, ndmin=2).T))\n",
104 | " #print(\"targets = \\n\", targets)\n",
105 | "\n",
106 | " # signal into hidden layer\n",
107 | " hidden_inputs = numpy.dot(self.wih, inputs)\n",
108 | " #print(\"hidden_inputs = \", hidden_inputs)\n",
109 | " #signal out of hidden layer\n",
110 | " hidden_outputs = numpy.exp(1j * numpy.angle(hidden_inputs))\n",
111 | " #print(\"hidden_outputs = \", hidden_outputs)\n",
112 | " \n",
113 | " # signal into final output layer\n",
114 | " final_inputs = numpy.dot(self.who, hidden_outputs)\n",
115 | " #print(\"final_inputs = \", final_inputs)\n",
116 | " #signal out of output layer\n",
117 | " final_outputs = numpy.exp(1j * numpy.angle(final_inputs))\n",
118 | " #print(\"final_outputs = \", final_outputs)\n",
119 | " \n",
120 | " # output layer error is the (target - actual)\n",
121 | " output_errors = targets - final_outputs\n",
122 | " #print(\"output_errors = \", output_errors)\n",
123 | " # hidden layer error is the output_errors split simply (not by weights)\n",
124 | " hidden_errors = numpy.dot(numpy.array(numpy.ones((self.hnodes)), ndmin=2).T / self.hnodes, output_errors)\n",
125 | " #print(\"hidden_errors = \", hidden_errors)\n",
126 | " \n",
127 | " # dw = e * x.T / (x.x.T)\n",
128 | " #dwho = (output_errors * numpy.conj(hidden_outputs.T)) / (self.hnodes)\n",
129 | " dwho = numpy.dot(output_errors, numpy.conj(hidden_outputs.T)) / (self.hnodes)\n",
130 | " #print(\"dwho = \", dwho)\n",
131 | " self.who += dwho\n",
132 | " \n",
133 | " #dwih = (hidden_errors * numpy.conj(inputs.T)) / (self.inodes)\n",
134 | " dwih = numpy.dot(hidden_errors, numpy.conj(inputs.T)) / (self.inodes)\n",
135 | " #print(\"dwih = \", dwih)\n",
136 | " self.wih += dwih \n",
137 | " pass"
138 | ]
139 | },
140 | {
141 | "cell_type": "code",
142 | "execution_count": 28,
143 | "metadata": {
144 | "collapsed": false
145 | },
146 | "outputs": [
147 | {
148 | "name": "stdout",
149 | "output_type": "stream",
150 | "text": [
151 | "self.wih = [[-0.97560880-0.44299654j 0.39673175+0.45313716j -0.36348055-0.42098974j]\n",
152 | " [-0.78914030+0.38495572j 0.06405584+0.12566801j 0.93014655+0.4663918j ]]\n",
153 | "self.who = [[-0.15796713+0.42202923j -0.66723068+0.01251784j]]\n"
154 | ]
155 | }
156 | ],
157 | "source": [
158 | "# number of input, hidden and output nodes\n",
159 | "input_nodes = 2\n",
160 | "hidden_nodes = 2\n",
161 | "output_nodes = 1\n",
162 | "\n",
163 | "# categories, periodicity\n",
164 | "categories = 2\n",
165 | "periodicity = 1\n",
166 | "\n",
167 | "# create instance of neural network\n",
168 | "n = neuralNetwork(input_nodes,hidden_nodes,output_nodes, categories, periodicity)\n",
169 | "n.status()"
170 | ]
171 | },
172 | {
173 | "cell_type": "code",
174 | "execution_count": 29,
175 | "metadata": {
176 | "collapsed": false
177 | },
178 | "outputs": [],
179 | "source": [
180 | "# train neural network - OR\n",
181 | "\n",
182 | "epochs = 5\n",
183 | "\n",
184 | "for e in range(epochs):\n",
185 | " n.train([-1.0, -1.0], [0])\n",
186 | " n.train([-1.0, 1.0], [1])\n",
187 | " n.train([1.0, -1.0], [1])\n",
188 | " n.train([1.0, 1.0], [1])\n",
189 | " pass"
190 | ]
191 | },
192 | {
193 | "cell_type": "code",
194 | "execution_count": 30,
195 | "metadata": {
196 | "collapsed": false
197 | },
198 | "outputs": [
199 | {
200 | "name": "stdout",
201 | "output_type": "stream",
202 | "text": [
203 | "self.wih = [[-0.95393264-1.0836447j 0.39135471-1.35898696j -0.32501294-2.01430814j]\n",
204 | " [-0.76746414-0.25569244j 0.05867880-1.68645611j 0.96861417-1.1269266j ]]\n",
205 | "self.who = [[ 1.17035804+0.61847302j -0.13069239-0.41321431j]]\n",
206 | "inputs = \n",
207 | " [[-1.+0.j]\n",
208 | " [-1.+0.j]\n",
209 | " [ 1.+0.j]]\n",
210 | "output_classes = 0\n",
211 | "inputs = \n",
212 | " [[-1.+0.j]\n",
213 | " [ 1.+0.j]\n",
214 | " [ 1.+0.j]]\n",
215 | "output_classes = 1\n",
216 | "inputs = \n",
217 | " [[ 1.+0.j]\n",
218 | " [-1.+0.j]\n",
219 | " [ 1.+0.j]]\n",
220 | "output_classes = 1\n",
221 | "inputs = \n",
222 | " [[ 1.+0.j]\n",
223 | " [ 1.+0.j]\n",
224 | " [ 1.+0.j]]\n",
225 | "output_classes = 1\n"
226 | ]
227 | },
228 | {
229 | "data": {
230 | "text/plain": [
231 | "1"
232 | ]
233 | },
234 | "execution_count": 30,
235 | "metadata": {},
236 | "output_type": "execute_result"
237 | }
238 | ],
239 | "source": [
240 | "# query after training\n",
241 | "n.status()\n",
242 | "n.query( [-1.0, -1.0] )\n",
243 | "n.query( [-1.0, 1.0] )\n",
244 | "n.query( [1.0, -1.0] )\n",
245 | "n.query( [1.0, 1.0] )"
246 | ]
247 | },
248 | {
249 | "cell_type": "code",
250 | "execution_count": null,
251 | "metadata": {
252 | "collapsed": false
253 | },
254 | "outputs": [],
255 | "source": []
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": null,
260 | "metadata": {
261 | "collapsed": true
262 | },
263 | "outputs": [],
264 | "source": []
265 | }
266 | ],
267 | "metadata": {
268 | "kernelspec": {
269 | "display_name": "Python 3",
270 | "language": "python",
271 | "name": "python3"
272 | },
273 | "language_info": {
274 | "codemirror_mode": {
275 | "name": "ipython",
276 | "version": 3
277 | },
278 | "file_extension": ".py",
279 | "mimetype": "text/x-python",
280 | "name": "python",
281 | "nbconvert_exporter": "python",
282 | "pygments_lexer": "ipython3",
283 | "version": "3.5.1"
284 | }
285 | },
286 | "nbformat": 4,
287 | "nbformat_minor": 0
288 | }
289 |
--------------------------------------------------------------------------------
/network_mnist.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 110,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "# neural network of many complex valued neurons in 3 layers\n",
12 | "# applied to the MNIST dataset\n",
13 | "import numpy"
14 | ]
15 | },
16 | {
17 | "cell_type": "code",
18 | "execution_count": 111,
19 | "metadata": {
20 | "collapsed": false
21 | },
22 | "outputs": [],
23 | "source": [
24 | "class neuralNetwork:\n",
25 | " \n",
26 | " def __init__(self, inputnodes, hiddennodes, outputnodes, cats, periods):\n",
27 | " # set number of nodes in each input, hidden, output layer\n",
28 | " self.inodes = inputnodes +1 # increament for bias node\n",
29 | " self.hnodes = hiddennodes\n",
30 | " self.onodes = outputnodes\n",
31 | " \n",
32 | " # link weight matrices, wih and who\n",
33 | " # weights inside the arrays are w_i_j, where link is from node i to node j in the next layer\n",
34 | " # w11 w21\n",
35 | " # w12 w22 etc \n",
36 | " self.wih = numpy.random.uniform(-1.0, 1.0, (self.hnodes, self.inodes))\n",
37 | " self.wih = numpy.array(self.wih, ndmin=2, dtype='complex128')\n",
38 | " self.wih += 1j * numpy.random.uniform(-1.0, 1.0, (self.hnodes, self.inodes))\n",
39 | " \n",
40 | " self.who = numpy.random.uniform(-1.0, 1.0, (self.onodes, self.hnodes))\n",
41 | " self.who = numpy.array(self.who, ndmin=2, dtype='complex128')\n",
42 | " self.who += 1j * numpy.random.random((self.onodes, self.hnodes))\n",
43 | " \n",
44 | " # number of output class categories\n",
45 | " self.categories = cats\n",
46 | " \n",
47 | " # todo periodicity\n",
48 | " self.periodicity = periods\n",
49 | " pass\n",
50 | " \n",
51 | " def z_to_class(self, z):\n",
52 | " # first work out the angle, but shift angle from [-pi/2, +pi.2] to [0,2pi]\n",
53 | " angle = numpy.mod(numpy.angle(z) + 2*numpy.pi, 2*numpy.pi)\n",
54 | " # from angle to category\n",
55 | " p = int(numpy.floor (self.categories * angle / (2*numpy.pi)))\n",
56 | " return p\n",
57 | "\n",
58 | " def class_to_angle(self, p):\n",
59 | " # class to angle, using bisector\n",
60 | " angle = ((p + 0.5) / self.categories) * 2 * numpy.pi\n",
61 | " return angle\n",
62 | " \n",
63 | " def status(self):\n",
64 | " print (\"self.wih = \", self.wih)\n",
65 | " print (\"self.who = \", self.who)\n",
66 | " pass\n",
67 | "\n",
68 | " def query(self, inputs_list):\n",
69 | " # add bias input\n",
70 | " inputs_list.append(1.0)\n",
71 | " \n",
72 | " # convert input to complex\n",
73 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
74 | " #print(\"inputs = \\n\", inputs)\n",
75 | " \n",
76 | " # signal into hidden layer\n",
77 | " hidden_inputs = numpy.dot(self.wih, inputs)\n",
78 | " #print(\"hidden_inputs = \", hidden_inputs)\n",
79 | " #signal out of hidden layer\n",
80 | " hidden_outputs = numpy.exp(1j * numpy.angle(hidden_inputs))\n",
81 | " #print(\"hidden_outputs = \", hidden_outputs)\n",
82 | " \n",
83 | " # signal into final output layer\n",
84 | " final_inputs = numpy.dot(self.who, hidden_outputs)\n",
85 | " #print(\"final_input = \", final_inputs)\n",
86 | " #signal out of output layer\n",
87 | " final_outputs = numpy.exp(1j * numpy.angle(final_inputs))\n",
88 | " #print(\"final_outputs = \", final_outputs)\n",
89 | " \n",
90 | " # map to output classes\n",
91 | " output_classes = self.z_to_class(final_outputs)\n",
92 | " #print(\"output_classes = \", output_classes)\n",
93 | " return output_classes\n",
94 | " \n",
95 | " def train(self, inputs_list, target_class_list):\n",
96 | " # add bias input\n",
97 | " inputs_list.append(1.0)\n",
98 | " \n",
99 | " # convert input to complex\n",
100 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
101 | " #print(\"inputs = \\n\", inputs)\n",
102 | " \n",
103 | " # map target classes to unit circle\n",
104 | " targets = numpy.exp(1j * self.class_to_angle(numpy.array(target_class_list, ndmin=2).T))\n",
105 | " #print(\"targets = \\n\", targets)\n",
106 | "\n",
107 | " # signal into hidden layer\n",
108 | " hidden_inputs = numpy.dot(self.wih, inputs)\n",
109 | " #print(\"hidden_inputs = \", hidden_inputs)\n",
110 | " #signal out of hidden layer\n",
111 | " hidden_outputs = numpy.exp(1j * numpy.angle(hidden_inputs))\n",
112 | " #print(\"hidden_outputs = \", hidden_outputs)\n",
113 | " \n",
114 | " # signal into final output layer\n",
115 | " final_inputs = numpy.dot(self.who, hidden_outputs)\n",
116 | " #print(\"final_inputs = \", final_inputs)\n",
117 | " #signal out of output layer\n",
118 | " final_outputs = numpy.exp(1j * numpy.angle(final_inputs))\n",
119 | " #print(\"final_outputs = \", final_outputs)\n",
120 | " \n",
121 | " # output layer error is the (target - actual)\n",
122 | " output_errors = targets - final_outputs\n",
123 | " #print(\"output_errors = \", output_errors)\n",
124 | " # hidden layer error is the output_errors split simply (not by weights)\n",
125 | " hidden_errors = numpy.dot(numpy.array(numpy.ones((self.hnodes)), ndmin=2).T / self.hnodes, output_errors)\n",
126 | " #print(\"hidden_errors = \", hidden_errors)\n",
127 | " \n",
128 | " # dw = e * x.T / (x.x.T)\n",
129 | " dwho = numpy.dot(output_errors, numpy.conj(hidden_outputs.T)) / (self.hnodes)\n",
130 | " #print(\"dwho = \", dwho)\n",
131 | " self.who += dwho\n",
132 | " \n",
133 | " dwih = numpy.dot(hidden_errors, numpy.conj(inputs.T)) / (self.inodes)\n",
134 | " #print(\"dwih = \", dwih)\n",
135 | " self.wih += dwih \n",
136 | " pass"
137 | ]
138 | },
139 | {
140 | "cell_type": "code",
141 | "execution_count": 112,
142 | "metadata": {
143 | "collapsed": false
144 | },
145 | "outputs": [],
146 | "source": [
147 | "# number of input, hidden and output nodes\n",
148 | "input_nodes = 784\n",
149 | "hidden_nodes = 100\n",
150 | "output_nodes = 1\n",
151 | "\n",
152 | "# categories, periodicity\n",
153 | "categories = 10\n",
154 | "periodicity = 1\n",
155 | "\n",
156 | "# create instance of neural network\n",
157 | "n = neuralNetwork(input_nodes,hidden_nodes,output_nodes, categories, periodicity)"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": 113,
163 | "metadata": {
164 | "collapsed": true
165 | },
166 | "outputs": [],
167 | "source": [
168 | "# load the mnist training data CSV file into a list\n",
169 | "training_data_file = open(\"mnist_dataset/mnist_train.csv\", 'r')\n",
170 | "training_data_list = training_data_file.readlines()\n",
171 | "training_data_file.close()"
172 | ]
173 | },
174 | {
175 | "cell_type": "code",
176 | "execution_count": 114,
177 | "metadata": {
178 | "collapsed": false
179 | },
180 | "outputs": [],
181 | "source": [
182 | "# train neural network - OR\n",
183 | "\n",
184 | "epochs = 1\n",
185 | "\n",
186 | "for e in range(epochs):\n",
187 | " # go through all records in the training data set\n",
188 | " for record in training_data_list:\n",
189 | " # split the record by the ',' commas\n",
190 | " all_values = record.split(',')\n",
191 | " # scale and shift the inputs\n",
192 | " inputs = numpy.exp(1j * (numpy.asfarray(all_values[1:]) / 255.0) * numpy.pi)\n",
193 | " inputs_list = inputs.tolist()\n",
194 | " # create the target class list\n",
195 | " targets = [int(all_values[0])]\n",
196 | " n.train(inputs_list, targets)\n",
197 | " pass\n",
198 | " pass"
199 | ]
200 | },
201 | {
202 | "cell_type": "code",
203 | "execution_count": 115,
204 | "metadata": {
205 | "collapsed": true
206 | },
207 | "outputs": [],
208 | "source": [
209 | "# load the mnist test data CSV file into a list\n",
210 | "test_data_file = open(\"mnist_dataset/mnist_test.csv\", 'r')\n",
211 | "test_data_list = test_data_file.readlines()\n",
212 | "test_data_file.close()"
213 | ]
214 | },
215 | {
216 | "cell_type": "code",
217 | "execution_count": 116,
218 | "metadata": {
219 | "collapsed": false
220 | },
221 | "outputs": [],
222 | "source": [
223 | "# test the neural network\n",
224 | "\n",
225 | "# scorecard for how well the network performs, initially empty\n",
226 | "scorecard = []\n",
227 | "\n",
228 | "# go through all the records in the test data set\n",
229 | "for record in test_data_list:\n",
230 | " # split the record by the ',' commas\n",
231 | " all_values = record.split(',')\n",
232 | " # correct answer is first value\n",
233 | " correct_label = int(all_values[0])\n",
234 | " # scale and shift the inputs\n",
235 | " inputs = numpy.exp(1j * (numpy.asfarray(all_values[1:]) / 255.0) * numpy.pi)\n",
236 | " inputs_list = inputs.tolist()\n",
237 | " # query the network\n",
238 | " output_label = n.query(inputs_list)\n",
239 | " # append correct or incorrect to list\n",
240 | " if (output_label == correct_label):\n",
241 | " # network's answer matches correct answer, add 1 to scorecard\n",
242 | " scorecard.append(1)\n",
243 | " else:\n",
244 | " # network's answer doesn't match correct answer, add 0 to scorecard\n",
245 | " scorecard.append(0)\n",
246 | " pass\n",
247 | " \n",
248 | " pass"
249 | ]
250 | },
251 | {
252 | "cell_type": "code",
253 | "execution_count": 117,
254 | "metadata": {
255 | "collapsed": false
256 | },
257 | "outputs": [
258 | {
259 | "name": "stdout",
260 | "output_type": "stream",
261 | "text": [
262 | "performance = 0.1719\n"
263 | ]
264 | }
265 | ],
266 | "source": [
267 | "# calculate the performance score, the fraction of correct answers\n",
268 | "scorecard_array = numpy.asarray(scorecard)\n",
269 | "print (\"performance = \", scorecard_array.sum() / scorecard_array.size)"
270 | ]
271 | },
272 | {
273 | "cell_type": "code",
274 | "execution_count": null,
275 | "metadata": {
276 | "collapsed": true
277 | },
278 | "outputs": [],
279 | "source": []
280 | }
281 | ],
282 | "metadata": {
283 | "kernelspec": {
284 | "display_name": "Python 3",
285 | "language": "python",
286 | "name": "python3"
287 | },
288 | "language_info": {
289 | "codemirror_mode": {
290 | "name": "ipython",
291 | "version": 3
292 | },
293 | "file_extension": ".py",
294 | "mimetype": "text/x-python",
295 | "name": "python",
296 | "nbconvert_exporter": "python",
297 | "pygments_lexer": "ipython3",
298 | "version": "3.5.1"
299 | }
300 | },
301 | "nbformat": 4,
302 | "nbformat_minor": 0
303 | }
304 |
--------------------------------------------------------------------------------
/single_neuron-periodic-iris.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 220,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "# simple neural network of one complex valued neuron\n",
12 | "# extended to use a periodic activation function\n",
13 | "import numpy\n",
14 | "# pandas for reading csv files\n",
15 | "import pandas\n",
16 | "# sklearn for splitting data into test/train sets\n",
17 | "import sklearn.cross_validation"
18 | ]
19 | },
20 | {
21 | "cell_type": "code",
22 | "execution_count": 221,
23 | "metadata": {
24 | "collapsed": false
25 | },
26 | "outputs": [],
27 | "source": [
28 | "class neuralNetwork:\n",
29 | " \n",
30 | " def __init__(self, inputs, cats, periods):\n",
31 | " # number of inputs\n",
32 | " self.inputs = inputs\n",
33 | " \n",
34 | " # link weights matrix\n",
35 | " self.w = numpy.random.normal(0.0, pow(1.0, -0.5), (self.inputs + 1))\n",
36 | " self.w = numpy.array(self.w, ndmin=2, dtype='complex128')\n",
37 | " self.w += 1j * numpy.random.normal(0.0, pow(1.0, -0.5), (self.inputs + 1))\n",
38 | " \n",
39 | " # testing overrride\n",
40 | " #self.w = numpy.array([1.0 + 0.0j, 1.0 + 0.0j], ndmin=2, dtype='complex128')\n",
41 | " \n",
42 | " # number of output class categories\n",
43 | " self.categories = cats\n",
44 | " \n",
45 | " # todo periodicity\n",
46 | " self.periodicity = periods\n",
47 | " \n",
48 | " pass\n",
49 | " \n",
50 | " def z_to_class(self, z):\n",
51 | " # first work out the angle, but shift angle from [-pi/2, +pi.2] to [0,2pi]\n",
52 | " angle = numpy.mod(numpy.angle(z) + 2*numpy.pi, 2*numpy.pi)\n",
53 | " # from angle to category\n",
54 | " p = int(numpy.floor (self.categories * self.periodicity * angle / (2*numpy.pi)))\n",
55 | " p = numpy.mod(p, self.categories)\n",
56 | " return p\n",
57 | "\n",
58 | " def class_to_angles(self, c):\n",
59 | " # class to several angles due to periodicity, using bisector\n",
60 | " angles = (c + 0.5 + (self.categories * numpy.arange(self.periodicity))) / (self.categories * self.periodicity) * 2 * numpy.pi\n",
61 | " return angles\n",
62 | " \n",
63 | " def status(self):\n",
64 | " print (\"w = \", self.w)\n",
65 | " print (\"categories = \", self.categories)\n",
66 | " print (\"periodicity = \", self.periodicity)\n",
67 | " pass\n",
68 | "\n",
69 | " def query(self, inputs_list):\n",
70 | " # add bias input\n",
71 | " inputs_list.append(1.0)\n",
72 | " \n",
73 | " # convert input to complex\n",
74 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
75 | " #print(\"inputs = \\n\", inputs)\n",
76 | " \n",
77 | " # combine inputs, weighted\n",
78 | " z = numpy.dot(self.w, inputs)\n",
79 | " #print(\"z = \", z)\n",
80 | " \n",
81 | " # map to output classes\n",
82 | " o = self.z_to_class(z)\n",
83 | " #print(\"output = \", o)\n",
84 | " #print (\"\")\n",
85 | " return o\n",
86 | " \n",
87 | " def train(self, inputs_list, target):\n",
88 | " # add bias input\n",
89 | " inputs_list.append(1.0)\n",
90 | " \n",
91 | " # convert inputs and outputs list to 2d array\n",
92 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
93 | "\n",
94 | " # combine inputs, weighted\n",
95 | " z = numpy.dot(self.w, inputs)[0]\n",
96 | " \n",
97 | " # desired angle from trainging set\n",
98 | " # first get all possible angles\n",
99 | " desired_angles = self.class_to_angles(target)\n",
100 | " \n",
101 | " # potential errors errors\n",
102 | " errors = numpy.exp(1j*desired_angles) - z\n",
103 | " # select smallest error\n",
104 | " e = errors[numpy.argmin(numpy.abs(errors))]\n",
105 | " \n",
106 | " # dw = e * x.T / (x.x.T)\n",
107 | " dw = (e * numpy.conj(inputs.T)) / (self.inputs + 1)\n",
108 | " #print(\"dw = \", dw)\n",
109 | " self.w += dw\n",
110 | " #print(\"new self.w = \", self.w )\n",
111 | " #print(\"test new self.w with query = \", self.query(inputs.T))\n",
112 | " #print(\"--\")\n",
113 | " pass"
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": 222,
119 | "metadata": {
120 | "collapsed": false
121 | },
122 | "outputs": [
123 | {
124 | "name": "stdout",
125 | "output_type": "stream",
126 | "text": [
127 | "w = [[ 0.38574064+1.66513146j 1.22031900+2.16144084j 1.21310153+0.176633j\n",
128 | " -1.12485307-0.25812644j -1.27266833-0.13015915j]]\n",
129 | "categories = 3\n",
130 | "periodicity = 3\n"
131 | ]
132 | }
133 | ],
134 | "source": [
135 | "# create instance of neural network\n",
136 | "number_of_inputs = 4\n",
137 | "categories = 3\n",
138 | "periods = 3\n",
139 | "\n",
140 | "n = neuralNetwork(number_of_inputs, categories, periods)\n",
141 | "n.status()"
142 | ]
143 | },
144 | {
145 | "cell_type": "code",
146 | "execution_count": 223,
147 | "metadata": {
148 | "collapsed": false,
149 | "scrolled": true
150 | },
151 | "outputs": [
152 | {
153 | "data": {
154 | "text/html": [
155 | "
\n",
156 | "
\n",
157 | " \n",
158 | " \n",
159 | " | \n",
160 | " Type | \n",
161 | " PW | \n",
162 | " PL | \n",
163 | " SW | \n",
164 | " SL | \n",
165 | "
\n",
166 | " \n",
167 | " \n",
168 | " \n",
169 | " 72 | \n",
170 | " 0 | \n",
171 | " 0.04 | \n",
172 | " 0.16 | \n",
173 | " 0.34 | \n",
174 | " 0.50 | \n",
175 | "
\n",
176 | " \n",
177 | " 88 | \n",
178 | " 0 | \n",
179 | " 0.02 | \n",
180 | " 0.15 | \n",
181 | " 0.37 | \n",
182 | " 0.54 | \n",
183 | "
\n",
184 | " \n",
185 | " 98 | \n",
186 | " 0 | \n",
187 | " 0.02 | \n",
188 | " 0.15 | \n",
189 | " 0.35 | \n",
190 | " 0.52 | \n",
191 | "
\n",
192 | " \n",
193 | " 0 | \n",
194 | " 0 | \n",
195 | " 0.02 | \n",
196 | " 0.14 | \n",
197 | " 0.33 | \n",
198 | " 0.50 | \n",
199 | "
\n",
200 | " \n",
201 | " 1 | \n",
202 | " 1 | \n",
203 | " 0.24 | \n",
204 | " 0.56 | \n",
205 | " 0.31 | \n",
206 | " 0.67 | \n",
207 | "
\n",
208 | " \n",
209 | "
\n",
210 | "
"
211 | ],
212 | "text/plain": [
213 | " Type PW PL SW SL\n",
214 | "72 0 0.04 0.16 0.34 0.50\n",
215 | "88 0 0.02 0.15 0.37 0.54\n",
216 | "98 0 0.02 0.15 0.35 0.52\n",
217 | "0 0 0.02 0.14 0.33 0.50\n",
218 | "1 1 0.24 0.56 0.31 0.67"
219 | ]
220 | },
221 | "execution_count": 223,
222 | "metadata": {},
223 | "output_type": "execute_result"
224 | }
225 | ],
226 | "source": [
227 | "# load the iris training data CSV file into a list\n",
228 | "df = pandas.read_csv('iris_dataset/iris.csv')\n",
229 | "\n",
230 | "# scale the lengths\n",
231 | "df[['PW', 'PL', 'SW', 'SL']] = df[['PW', 'PL', 'SW', 'SL']].astype(numpy.float64) * 0.01\n",
232 | "\n",
233 | "# shuffle and split dataframe into train and test sets, split 3/4 and 1/4\n",
234 | "iris_train, iris_test = sklearn.cross_validation.train_test_split(df, train_size=0.75)\n",
235 | "iris_test.head()"
236 | ]
237 | },
238 | {
239 | "cell_type": "code",
240 | "execution_count": 224,
241 | "metadata": {
242 | "collapsed": false
243 | },
244 | "outputs": [],
245 | "source": [
246 | "# train neural network\n",
247 | "\n",
248 | "epochs = 2\n",
249 | "\n",
250 | "for e in range(epochs):\n",
251 | " # go through all records in the training data set\n",
252 | " for idx, data in iris_train.iterrows():\n",
253 | " data_list = data.tolist()\n",
254 | " species = data_list[0]\n",
255 | " lengths = data_list[1:]\n",
256 | " n.train(lengths, species)\n",
257 | " pass\n",
258 | " pass"
259 | ]
260 | },
261 | {
262 | "cell_type": "code",
263 | "execution_count": 225,
264 | "metadata": {
265 | "collapsed": false
266 | },
267 | "outputs": [
268 | {
269 | "name": "stdout",
270 | "output_type": "stream",
271 | "text": [
272 | "w = [[ 0.94712904+1.0675523j 2.43183469+0.84406376j 1.07463099+0.46028561j\n",
273 | " -0.61066543-0.54791292j -1.05720782+0.55283372j]]\n",
274 | "categories = 3\n",
275 | "periodicity = 3\n"
276 | ]
277 | }
278 | ],
279 | "source": [
280 | "n.status()"
281 | ]
282 | },
283 | {
284 | "cell_type": "code",
285 | "execution_count": 226,
286 | "metadata": {
287 | "collapsed": false
288 | },
289 | "outputs": [
290 | {
291 | "name": "stdout",
292 | "output_type": "stream",
293 | "text": [
294 | "0 0\n",
295 | "0 0\n",
296 | "0 0\n",
297 | "0 0\n",
298 | "1 1\n",
299 | "2 2\n",
300 | "2 2\n",
301 | "1 1\n",
302 | "0 0\n",
303 | "0 0\n",
304 | "2 1\n",
305 | "1 1\n",
306 | "2 2\n",
307 | "2 2\n",
308 | "1 1\n",
309 | "1 1\n",
310 | "2 2\n",
311 | "2 2\n",
312 | "0 0\n",
313 | "1 1\n",
314 | "0 0\n",
315 | "2 2\n",
316 | "2 2\n",
317 | "1 1\n",
318 | "2 1\n",
319 | "2 2\n",
320 | "2 2\n",
321 | "0 0\n",
322 | "1 1\n",
323 | "1 1\n",
324 | "2 2\n",
325 | "1 1\n",
326 | "0 0\n",
327 | "0 0\n",
328 | "1 1\n",
329 | "2 2\n",
330 | "1 1\n",
331 | "0 0\n"
332 | ]
333 | }
334 | ],
335 | "source": [
336 | "# query after training\n",
337 | "\n",
338 | "scorecard = []\n",
339 | "\n",
340 | "for idx, data in iris_test.iterrows():\n",
341 | " data_list = data.tolist()\n",
342 | " correct_species = int(data_list[0])\n",
343 | " lengths = data_list[1:]\n",
344 | " answer = n.query(lengths)\n",
345 | " print(correct_species, answer)\n",
346 | " if (answer == correct_species):\n",
347 | " # network's answer matches correct answer, add 1 to scorecard\n",
348 | " scorecard.append(1)\n",
349 | " else:\n",
350 | " # network's answer doesn't match correct answer, add 0 to scorecard\n",
351 | " scorecard.append(0)\n",
352 | " pass\n",
353 | " pass"
354 | ]
355 | },
356 | {
357 | "cell_type": "code",
358 | "execution_count": 227,
359 | "metadata": {
360 | "collapsed": false
361 | },
362 | "outputs": [
363 | {
364 | "name": "stdout",
365 | "output_type": "stream",
366 | "text": [
367 | "performance = 0.947368421053\n"
368 | ]
369 | }
370 | ],
371 | "source": [
372 | "# calculate the performance score, the fraction of correct answers\n",
373 | "scorecard_array = numpy.asarray(scorecard)\n",
374 | "print (\"performance = \", scorecard_array.sum() / scorecard_array.size)"
375 | ]
376 | },
377 | {
378 | "cell_type": "code",
379 | "execution_count": null,
380 | "metadata": {
381 | "collapsed": true
382 | },
383 | "outputs": [],
384 | "source": []
385 | }
386 | ],
387 | "metadata": {
388 | "kernelspec": {
389 | "display_name": "Python 3",
390 | "language": "python",
391 | "name": "python3"
392 | },
393 | "language_info": {
394 | "codemirror_mode": {
395 | "name": "ipython",
396 | "version": 3
397 | },
398 | "file_extension": ".py",
399 | "mimetype": "text/x-python",
400 | "name": "python",
401 | "nbconvert_exporter": "python",
402 | "pygments_lexer": "ipython3",
403 | "version": "3.5.1"
404 | }
405 | },
406 | "nbformat": 4,
407 | "nbformat_minor": 0
408 | }
409 |
--------------------------------------------------------------------------------
/single_neuron-periodic-mnist.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 183,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "# simple neural network of one complex valued neuron\n",
12 | "# extended to use a periodic activation function\n",
13 | "import numpy"
14 | ]
15 | },
16 | {
17 | "cell_type": "code",
18 | "execution_count": 184,
19 | "metadata": {
20 | "collapsed": false
21 | },
22 | "outputs": [],
23 | "source": [
24 | "class neuralNetwork:\n",
25 | " \n",
26 | " def __init__(self, inputs, cats, periods):\n",
27 | " # number of inputs\n",
28 | " self.inputs = inputs\n",
29 | " \n",
30 | " # link weights matrix\n",
31 | " self.w = numpy.random.normal(0.0, pow(1.0, -0.5), (inputs + 1))\n",
32 | " self.w = numpy.array(self.w, ndmin=2, dtype='complex128')\n",
33 | " self.w += 1j * numpy.random.normal(0.0, pow(1.0, -0.5), (inputs + 1))\n",
34 | " \n",
35 | " # testing overrride\n",
36 | " #self.w = numpy.array([1.0 + 0.0j, 1.0 + 0.0j], ndmin=2, dtype='complex128')\n",
37 | " \n",
38 | " # number of output class categories\n",
39 | " self.categories = cats\n",
40 | " \n",
41 | " # todo periodicity\n",
42 | " self.periodicity = periods\n",
43 | " \n",
44 | " pass\n",
45 | " \n",
46 | " def z_to_class(self, z):\n",
47 | " # first work out the angle, but shift angle from [-pi/2, +pi.2] to [0,2pi]\n",
48 | " angle = numpy.mod(numpy.angle(z) + 2*numpy.pi, 2*numpy.pi)\n",
49 | " # from angle to category\n",
50 | " p = int(numpy.floor (self.categories * self.periodicity * angle / (2*numpy.pi)))\n",
51 | " p = numpy.mod(p, self.categories)\n",
52 | " return p\n",
53 | "\n",
54 | " def class_to_angles(self, c):\n",
55 | " # class to several angles due to periodicity, using bisector\n",
56 | " angles = (c + 0.5 + (self.categories * numpy.arange(self.periodicity))) / (self.categories * self.periodicity) * 2 * numpy.pi\n",
57 | " return angles\n",
58 | " \n",
59 | " def status(self):\n",
60 | " print (\"w = \", self.w)\n",
61 | " print (\"categories = \", self.categories)\n",
62 | " print (\"periodicity = \", self.periodicity)\n",
63 | " pass\n",
64 | "\n",
65 | " def query(self, inputs_list):\n",
66 | " # add bias input\n",
67 | " inputs_list.append(1.0)\n",
68 | " \n",
69 | " # convert input to complex\n",
70 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
71 | " #print(\"inputs = \\n\", inputs)\n",
72 | " \n",
73 | " # combine inputs, weighted\n",
74 | " z = numpy.dot(self.w, inputs)\n",
75 | " #print(\"z = \", z)\n",
76 | " \n",
77 | " # map to output classes\n",
78 | " o = self.z_to_class(z)\n",
79 | " #print(\"output = \", o)\n",
80 | " #print (\"\")\n",
81 | " return o\n",
82 | " \n",
83 | " def train(self, inputs_list, target):\n",
84 | " # add bias input\n",
85 | " inputs_list.append(1.0)\n",
86 | " \n",
87 | " # convert inputs and outputs list to 2d array\n",
88 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
89 | "\n",
90 | " # combine inputs, weighted\n",
91 | " z = numpy.dot(self.w, inputs)[0]\n",
92 | " \n",
93 | " # desired angle from trainging set\n",
94 | " # first get all possible angles\n",
95 | " desired_angles = self.class_to_angles(target)\n",
96 | " \n",
97 | " # potential errors errors\n",
98 | " errors = numpy.exp(1j*desired_angles) - z\n",
99 | " # select smallest error\n",
100 | " e = errors[numpy.argmin(numpy.abs(errors))]\n",
101 | " \n",
102 | " # dw = e * x.T / (x.x.T)\n",
103 | " dw = (e * numpy.conj(inputs.T)) / (self.inputs + 1)\n",
104 | " #print(\"dw = \", dw)\n",
105 | " self.w += dw\n",
106 | " #print(\"new self.w = \", self.w )\n",
107 | " #print(\"test new self.w with query = \", self.query(inputs.T))\n",
108 | " #print(\"--\")\n",
109 | " pass"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": 185,
115 | "metadata": {
116 | "collapsed": false
117 | },
118 | "outputs": [],
119 | "source": [
120 | "# create instance of neural network\n",
121 | "number_of_inputs = 784\n",
122 | "categories = 10\n",
123 | "periods = 3\n",
124 | "\n",
125 | "n = neuralNetwork(number_of_inputs, categories, periods)"
126 | ]
127 | },
128 | {
129 | "cell_type": "code",
130 | "execution_count": 186,
131 | "metadata": {
132 | "collapsed": false,
133 | "scrolled": true
134 | },
135 | "outputs": [],
136 | "source": [
137 | "# load the mnist training data CSV file into a list\n",
138 | "training_data_file = open(\"mnist_dataset/mnist_train.csv\", 'r')\n",
139 | "training_data_list = training_data_file.readlines()\n",
140 | "training_data_file.close()"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": 187,
146 | "metadata": {
147 | "collapsed": false
148 | },
149 | "outputs": [],
150 | "source": [
151 | "# train the neural network\n",
152 | "\n",
153 | "# epochs is the number of times the training data set is used for training\n",
154 | "epochs = 5\n",
155 | "\n",
156 | "for e in range(epochs):\n",
157 | " # go through all records in the training data set\n",
158 | " for record in training_data_list:\n",
159 | " # split the record by the ',' commas\n",
160 | " all_values = record.split(',')\n",
161 | " # scale and shift the inputs\n",
162 | " inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01\n",
163 | " inputs = inputs.tolist()\n",
164 | " n.train(inputs, int(all_values[0]))\n",
165 | " pass\n",
166 | " pass"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": 188,
172 | "metadata": {
173 | "collapsed": true
174 | },
175 | "outputs": [],
176 | "source": [
177 | "# load the mnist test data CSV file into a list\n",
178 | "test_data_file = open(\"mnist_dataset/mnist_test.csv\", 'r')\n",
179 | "test_data_list = test_data_file.readlines()\n",
180 | "test_data_file.close()"
181 | ]
182 | },
183 | {
184 | "cell_type": "code",
185 | "execution_count": 189,
186 | "metadata": {
187 | "collapsed": false
188 | },
189 | "outputs": [],
190 | "source": [
191 | "# test the neural network\n",
192 | "\n",
193 | "# scorecard for how well the network performs, initially empty\n",
194 | "scorecard = []\n",
195 | "\n",
196 | "# go through all the records in the test data set\n",
197 | "for record in test_data_list:\n",
198 | " # split the record by the ',' commas\n",
199 | " all_values = record.split(',')\n",
200 | " # correct answer is first value\n",
201 | " correct_label = int(all_values[0])\n",
202 | " # scale and shift the inputs\n",
203 | " inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01\n",
204 | " inputs = inputs.tolist()\n",
205 | " # query the network\n",
206 | " label = n.query(inputs)\n",
207 | "\n",
208 | " # append correct or incorrect to list\n",
209 | " if (label == correct_label):\n",
210 | " # network's answer matches correct answer, add 1 to scorecard\n",
211 | " scorecard.append(1)\n",
212 | " else:\n",
213 | " # network's answer doesn't match correct answer, add 0 to scorecard\n",
214 | " scorecard.append(0)\n",
215 | " pass\n",
216 | " \n",
217 | " pass"
218 | ]
219 | },
220 | {
221 | "cell_type": "code",
222 | "execution_count": 190,
223 | "metadata": {
224 | "collapsed": false
225 | },
226 | "outputs": [
227 | {
228 | "name": "stdout",
229 | "output_type": "stream",
230 | "text": [
231 | "performance = 0.1172\n"
232 | ]
233 | }
234 | ],
235 | "source": [
236 | "# calculate the performance score, the fraction of correct answers\n",
237 | "scorecard_array = numpy.asarray(scorecard)\n",
238 | "print (\"performance = \", scorecard_array.sum() / scorecard_array.size)"
239 | ]
240 | },
241 | {
242 | "cell_type": "code",
243 | "execution_count": null,
244 | "metadata": {
245 | "collapsed": true
246 | },
247 | "outputs": [],
248 | "source": []
249 | }
250 | ],
251 | "metadata": {
252 | "kernelspec": {
253 | "display_name": "Python 3",
254 | "language": "python",
255 | "name": "python3"
256 | },
257 | "language_info": {
258 | "codemirror_mode": {
259 | "name": "ipython",
260 | "version": 3
261 | },
262 | "file_extension": ".py",
263 | "mimetype": "text/x-python",
264 | "name": "python",
265 | "nbconvert_exporter": "python",
266 | "pygments_lexer": "ipython3",
267 | "version": "3.5.1"
268 | }
269 | },
270 | "nbformat": 4,
271 | "nbformat_minor": 0
272 | }
273 |
--------------------------------------------------------------------------------
/single_neuron-periodic.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 146,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "# simple neural network of one complex valued neuron\n",
12 | "# extended to use a periodic activation function\n",
13 | "import numpy"
14 | ]
15 | },
16 | {
17 | "cell_type": "code",
18 | "execution_count": 147,
19 | "metadata": {
20 | "collapsed": false
21 | },
22 | "outputs": [],
23 | "source": [
24 | "class neuralNetwork:\n",
25 | " \n",
26 | " def __init__(self, inputs, cats, periods):\n",
27 | " # link weights matrix\n",
28 | " self.w = numpy.random.normal(0.0, pow(1.0, -0.5), (inputs + 1))\n",
29 | " self.w = numpy.array(self.w, ndmin=2, dtype='complex128')\n",
30 | " self.w += 1j * numpy.random.normal(0.0, pow(1.0, -0.5), (inputs + 1))\n",
31 | " \n",
32 | " # testing overrride\n",
33 | " #self.w = numpy.array([1.0 + 0.0j, 1.0 + 0.0j], ndmin=2, dtype='complex128')\n",
34 | " \n",
35 | " # number of output class categories\n",
36 | " self.categories = cats\n",
37 | " \n",
38 | " # todo periodicity\n",
39 | " self.periodicity = periods\n",
40 | " \n",
41 | " pass\n",
42 | " \n",
43 | " def z_to_class(self, z):\n",
44 | " # first work out the angle, but shift angle from [-pi/2, +pi.2] to [0,2pi]\n",
45 | " angle = numpy.mod(numpy.angle(z) + 2*numpy.pi, 2*numpy.pi)\n",
46 | " # from angle to category\n",
47 | " p = int(numpy.floor (self.categories * self.periodicity * angle / (2*numpy.pi)))\n",
48 | " p = numpy.mod(p, self.categories)\n",
49 | " return p\n",
50 | "\n",
51 | " def class_to_angles(self, c):\n",
52 | " # class to several angles due to periodicity, using bisector\n",
53 | " angles = (c + 0.5 + (self.categories * numpy.arange(self.periodicity))) / (self.categories * self.periodicity) * 2 * numpy.pi\n",
54 | " return angles\n",
55 | " \n",
56 | " def status(self):\n",
57 | " print (\"w = \", self.w)\n",
58 | " print (\"categories = \", self.categories)\n",
59 | " print (\"periodicity = \", self.periodicity)\n",
60 | " pass\n",
61 | "\n",
62 | " def query(self, inputs_list):\n",
63 | " # add bias input\n",
64 | " inputs_list.append(1.0)\n",
65 | " \n",
66 | " # convert input to complex\n",
67 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
68 | " print(\"inputs = \\n\", inputs)\n",
69 | " \n",
70 | " # combine inputs, weighted\n",
71 | " z = numpy.dot(self.w, inputs)\n",
72 | " print(\"z = \", z)\n",
73 | " \n",
74 | " # map to output classes\n",
75 | " o = self.z_to_class(z)\n",
76 | " print(\"output = \", o)\n",
77 | " print (\"\")\n",
78 | " return o\n",
79 | " \n",
80 | " def train(self, inputs_list, target):\n",
81 | " # add bias input\n",
82 | " inputs_list.append(1.0)\n",
83 | " \n",
84 | " # convert inputs and outputs list to 2d array\n",
85 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
86 | "\n",
87 | " # combine inputs, weighted\n",
88 | " z = numpy.dot(self.w, inputs)[0]\n",
89 | " \n",
90 | " # desired angle from trainging set\n",
91 | " # first get all possible angles\n",
92 | " desired_angles = self.class_to_angles(target)\n",
93 | " \n",
94 | " # potential errors errors\n",
95 | " errors = numpy.exp(1j*desired_angles) - z\n",
96 | " # select smallest error\n",
97 | " e = errors[numpy.argmin(numpy.abs(errors))]\n",
98 | " \n",
99 | " # dw = e * x.T / (x.x.T)\n",
100 | " dw = (e * numpy.conj(inputs.T)) / (3)\n",
101 | " #print(\"dw = \", dw)\n",
102 | " self.w += dw\n",
103 | " #print(\"new self.w = \", self.w )\n",
104 | " #print(\"test new self.w with query = \", self.query(inputs.T))\n",
105 | " #print(\"--\")\n",
106 | " pass"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": 148,
112 | "metadata": {
113 | "collapsed": false
114 | },
115 | "outputs": [
116 | {
117 | "name": "stdout",
118 | "output_type": "stream",
119 | "text": [
120 | "w = [[-1.56572466+0.70528849j -2.71967065+0.00440014j 1.31235568-0.46018874j]]\n",
121 | "categories = 2\n",
122 | "periodicity = 2\n"
123 | ]
124 | }
125 | ],
126 | "source": [
127 | "# create instance of neural network\n",
128 | "number_of_inputs = 2\n",
129 | "categories = 2\n",
130 | "periods = 2\n",
131 | "\n",
132 | "n = neuralNetwork(number_of_inputs, categories, periods)\n",
133 | "n.status()"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": 149,
139 | "metadata": {
140 | "collapsed": false
141 | },
142 | "outputs": [],
143 | "source": [
144 | "# train neural network - XOR\n",
145 | "for i in range(10):\n",
146 | " n.train([-1.0, -1.0], 0)\n",
147 | " n.train([-1.0, 1.0], 1)\n",
148 | " n.train([1.0, -1.0], 1)\n",
149 | " n.train([1.0, 1.0], 0)\n",
150 | " pass"
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": 150,
156 | "metadata": {
157 | "collapsed": false
158 | },
159 | "outputs": [
160 | {
161 | "name": "stdout",
162 | "output_type": "stream",
163 | "text": [
164 | "inputs = \n",
165 | " [[-1.+0.j]\n",
166 | " [-1.+0.j]\n",
167 | " [ 1.+0.j]]\n",
168 | "z = [[ 0.70710678+0.70710678j]]\n",
169 | "output = 0\n",
170 | "\n",
171 | "inputs = \n",
172 | " [[-1.+0.j]\n",
173 | " [ 1.+0.j]\n",
174 | " [ 1.+0.j]]\n",
175 | "z = [[-0.70710678+0.70710678j]]\n",
176 | "output = 1\n",
177 | "\n",
178 | "inputs = \n",
179 | " [[ 1.+0.j]\n",
180 | " [-1.+0.j]\n",
181 | " [ 1.+0.j]]\n",
182 | "z = [[ 0.70710678-0.70710678j]]\n",
183 | "output = 1\n",
184 | "\n",
185 | "inputs = \n",
186 | " [[ 1.+0.j]\n",
187 | " [ 1.+0.j]\n",
188 | " [ 1.+0.j]]\n",
189 | "z = [[-0.70710678-0.70710678j]]\n",
190 | "output = 0\n",
191 | "\n"
192 | ]
193 | },
194 | {
195 | "data": {
196 | "text/plain": [
197 | "0"
198 | ]
199 | },
200 | "execution_count": 150,
201 | "metadata": {},
202 | "output_type": "execute_result"
203 | }
204 | ],
205 | "source": [
206 | "# query after training\n",
207 | "n.query( [-1.0, -1.0] )\n",
208 | "n.query( [-1.0, 1.0] )\n",
209 | "n.query( [1.0, -1.0] )\n",
210 | "n.query( [1.0, 1.0] )"
211 | ]
212 | },
213 | {
214 | "cell_type": "code",
215 | "execution_count": null,
216 | "metadata": {
217 | "collapsed": false
218 | },
219 | "outputs": [],
220 | "source": []
221 | },
222 | {
223 | "cell_type": "code",
224 | "execution_count": null,
225 | "metadata": {
226 | "collapsed": true
227 | },
228 | "outputs": [],
229 | "source": []
230 | }
231 | ],
232 | "metadata": {
233 | "kernelspec": {
234 | "display_name": "Python 3",
235 | "language": "python",
236 | "name": "python3"
237 | },
238 | "language_info": {
239 | "codemirror_mode": {
240 | "name": "ipython",
241 | "version": 3
242 | },
243 | "file_extension": ".py",
244 | "mimetype": "text/x-python",
245 | "name": "python",
246 | "nbconvert_exporter": "python",
247 | "pygments_lexer": "ipython3",
248 | "version": "3.5.1"
249 | }
250 | },
251 | "nbformat": 4,
252 | "nbformat_minor": 0
253 | }
254 |
--------------------------------------------------------------------------------
/single_neuron.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 112,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "# simple neural network of one complex valued neuron\n",
12 | "import numpy"
13 | ]
14 | },
15 | {
16 | "cell_type": "code",
17 | "execution_count": 113,
18 | "metadata": {
19 | "collapsed": false
20 | },
21 | "outputs": [],
22 | "source": [
23 | "class neuralNetwork:\n",
24 | " \n",
25 | " def __init__(self):\n",
26 | " # link weights matrix\n",
27 | " self.w = numpy.random.normal(0.0, pow(1.0, -0.5), (3))\n",
28 | " self.w = numpy.array(self.w, ndmin=2, dtype='complex128')\n",
29 | " self.w += 1j * numpy.random.normal(0.0, pow(1.0, -0.5), (3))\n",
30 | " \n",
31 | " # testing overrride\n",
32 | " #self.w = numpy.array([1.0 + 0.0j, 1.0 + 0.0j], ndmin=2, dtype='complex128')\n",
33 | " \n",
34 | " # number of output class categories\n",
35 | " self.categories = 2\n",
36 | " \n",
37 | " # todo periodicity self.periodicity = 2\n",
38 | " pass\n",
39 | " \n",
40 | " def z_to_class(self, z):\n",
41 | " # first work out the angle, but shift angle from [-pi/2, +pi.2] to [0,2pi]\n",
42 | " angle = numpy.mod(numpy.angle(z) + 2*numpy.pi, 2*numpy.pi)\n",
43 | " # from angle to category\n",
44 | " p = int(numpy.floor (self.categories * angle / (2*numpy.pi)))\n",
45 | " return p\n",
46 | "\n",
47 | " def class_to_angle(self, p):\n",
48 | " # class to angle, using bisector\n",
49 | " angle = ((p + 0.5) / self.categories) * 2 * numpy.pi\n",
50 | " return angle\n",
51 | " \n",
52 | " def status(self):\n",
53 | " print (\"w = \", self.w)\n",
54 | " pass\n",
55 | "\n",
56 | " def query(self, inputs_list):\n",
57 | " # add bias input\n",
58 | " inputs_list.append(1.0)\n",
59 | " \n",
60 | " # convert input to complex\n",
61 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
62 | " print(\"inputs = \\n\", inputs)\n",
63 | " \n",
64 | " # combine inputs, weighted\n",
65 | " z = numpy.dot(self.w, inputs)\n",
66 | " print(\"z = \", z)\n",
67 | " \n",
68 | " # map to output classes\n",
69 | " o = self.z_to_class(z)\n",
70 | " print(\"output = \", o)\n",
71 | " print (\"\")\n",
72 | " return o\n",
73 | " \n",
74 | " def train(self, inputs_list, targets_list):\n",
75 | " # add bias input\n",
76 | " inputs_list.append(1.0)\n",
77 | " \n",
78 | " # convert inputs and outputs list to 2d array\n",
79 | " inputs = numpy.array(inputs_list, ndmin=2, dtype='complex128').T\n",
80 | " targets = numpy.array(targets_list, ndmin=2).T\n",
81 | "\n",
82 | " # combine inputs, weighted\n",
83 | " z = numpy.dot(self.w, inputs)\n",
84 | " #print(\"z = \", z)\n",
85 | " \n",
86 | " # desired angle from trainging set\n",
87 | " desired_angle = self.class_to_angle(targets)\n",
88 | " #print(\"desired_angle = \", desired_angle)\n",
89 | " \n",
90 | " # error e\n",
91 | " e = numpy.exp(1j*desired_angle) - z\n",
92 | " #print(\"e = \", e)\n",
93 | " \n",
94 | " # dw = e * x.T / (x.x.T)\n",
95 | " dw = (e * numpy.conj(inputs.T)) / (3)\n",
96 | " #print(\"dw = \", dw)\n",
97 | " self.w += dw\n",
98 | " #print(\"new self.w = \", self.w )\n",
99 | " #print(\"test new self.w with query = \", self.query(inputs.T))\n",
100 | " #print(\"--\")\n",
101 | " pass"
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": 114,
107 | "metadata": {
108 | "collapsed": false
109 | },
110 | "outputs": [
111 | {
112 | "name": "stdout",
113 | "output_type": "stream",
114 | "text": [
115 | "w = [[-1.06236919+0.04312478j 0.50718034+1.69705651j -0.81702728-0.51196168j]]\n"
116 | ]
117 | }
118 | ],
119 | "source": [
120 | "# create instance of neural network\n",
121 | "n = neuralNetwork()\n",
122 | "n.status()"
123 | ]
124 | },
125 | {
126 | "cell_type": "code",
127 | "execution_count": 115,
128 | "metadata": {
129 | "collapsed": false
130 | },
131 | "outputs": [],
132 | "source": [
133 | "# train neural network - OR\n",
134 | "for i in range(5):\n",
135 | " n.train([-1.0, -1.0], [0])\n",
136 | " n.train([-1.0, 1.0], [1])\n",
137 | " n.train([1.0, -1.0], [1])\n",
138 | " n.train([1.0, 1.0], [1])\n",
139 | " pass"
140 | ]
141 | },
142 | {
143 | "cell_type": "code",
144 | "execution_count": 116,
145 | "metadata": {
146 | "collapsed": false
147 | },
148 | "outputs": [
149 | {
150 | "name": "stdout",
151 | "output_type": "stream",
152 | "text": [
153 | "w = [[ -6.35598582e-06-0.33336145j 3.17265351e-05-0.16667827j\n",
154 | " -2.53705493e-05-0.49996028j]]\n",
155 | "inputs = \n",
156 | " [[-1.+0.j]\n",
157 | " [-1.+0.j]\n",
158 | " [ 1.+0.j]]\n",
159 | "z = [[ -5.07410985e-05 +7.94330603e-05j]]\n",
160 | "output = 0\n",
161 | "\n",
162 | "inputs = \n",
163 | " [[-1.+0.j]\n",
164 | " [ 1.+0.j]\n",
165 | " [ 1.+0.j]]\n",
166 | "z = [[ 1.27119716e-05-0.3332771j]]\n",
167 | "output = 1\n",
168 | "\n",
169 | "inputs = \n",
170 | " [[ 1.+0.j]\n",
171 | " [-1.+0.j]\n",
172 | " [ 1.+0.j]]\n",
173 | "z = [[ -6.34530701e-05-0.66664346j]]\n",
174 | "output = 1\n",
175 | "\n",
176 | "inputs = \n",
177 | " [[ 1.+0.j]\n",
178 | " [ 1.+0.j]\n",
179 | " [ 1.+0.j]]\n",
180 | "z = [[ -1.83663848e-16-1.j]]\n",
181 | "output = 1\n",
182 | "\n"
183 | ]
184 | },
185 | {
186 | "data": {
187 | "text/plain": [
188 | "1"
189 | ]
190 | },
191 | "execution_count": 116,
192 | "metadata": {},
193 | "output_type": "execute_result"
194 | }
195 | ],
196 | "source": [
197 | "# query after training\n",
198 | "n.status()\n",
199 | "n.query( [-1.0, -1.0] )\n",
200 | "n.query( [-1.0, 1.0] )\n",
201 | "n.query( [1.0, -1.0] )\n",
202 | "n.query( [1.0, 1.0] )"
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": null,
208 | "metadata": {
209 | "collapsed": false
210 | },
211 | "outputs": [],
212 | "source": []
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": null,
217 | "metadata": {
218 | "collapsed": true
219 | },
220 | "outputs": [],
221 | "source": []
222 | }
223 | ],
224 | "metadata": {
225 | "kernelspec": {
226 | "display_name": "Python 3",
227 | "language": "python",
228 | "name": "python3"
229 | },
230 | "language_info": {
231 | "codemirror_mode": {
232 | "name": "ipython",
233 | "version": 3
234 | },
235 | "file_extension": ".py",
236 | "mimetype": "text/x-python",
237 | "name": "python",
238 | "nbconvert_exporter": "python",
239 | "pygments_lexer": "ipython3",
240 | "version": "3.5.1"
241 | }
242 | },
243 | "nbformat": 4,
244 | "nbformat_minor": 0
245 | }
246 |
--------------------------------------------------------------------------------
/test_image/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/makeyourownneuralnetwork/complex_valued_neuralnetwork/89d7b02ae5b8e6496db5fd0243e46ab66f55c8d2/test_image/test.jpg
--------------------------------------------------------------------------------