Hi Juan,
Great!
It looks like the emoticon problem hit your source code about halfway down. This is where F# constructs such as ":>" get rendered as emoticons by the server. It's annoying, of course - I think the first way to fix it is by editing the HTML by hand?
regards
don
Topic tags
- f# × 3707
- websharper × 2884
- core × 418
- bolero × 329
- compiler × 291
- enhancement × 215
- functional × 201
- bug × 177
- ui next × 140
- ui × 132
- c# × 122
- classes × 97
- web × 97
- .net × 84
- book × 84
- async × 77
- ui.next × 67
- templates × 58
- website × 51
- trywebsharper × 50
- question × 46
- html × 45
- server × 45
- owin × 44
- javascript × 43
- parallel × 43
- parsing × 41
- testing × 41
- typescript × 39
- template × 38
- sitelet × 31
- asynchronous × 30
- feature request × 28
- monad × 28
- ocaml × 28
- warp × 28
- tutorial × 27
- haskell × 26
- dotnet-ws × 23
- linq × 22
- sitelets × 22
- workflows × 22
- rpc × 21
- getting started × 20
- wpf × 20
- fpish × 19
- introduction × 19
- silverlight × 19
- monodevelop × 17
- piglets × 17
- suave × 17
- docs × 16
- collections × 15
- jquery × 15
- proposal × 15
- aspnetcore × 14
- pipeline × 14
- reactive × 14
- 4.6.0.361 × 13
- documentation × 13
- kendoui × 13
- formlets × 12
- 4.1.0.171 × 11
- monads × 11
- released: v0.1 × 11
- websocket × 11
- 4.4.0.280 × 10
- 4.4.1.288 × 10
- opinion × 10
- tryfsharponwasm × 10
- 4.0.190.100-rc × 9
- deployment × 9
- fixed × 9
- in × 9
- json × 9
- plugin × 9
- scheme × 9
- solid × 9
- wontfix × 9
- 4.3.0.274 × 8
- 4.5.4.317 × 8
- basics × 8
- concurrent × 8
- highcharts × 8
- how-to × 8
- mvu × 8
- python × 8
- released: v0.11 × 8
- 4.1.1.175 × 7
- 4.5.1.304 × 7
- complexity × 7
- remoting × 7
- visual studio × 7
- 4.1.2.178 × 6
- 4.5.4.151 × 6
- authentication × 6
- datefns × 6
- lisp × 6
- real-world × 6
- released in 4.0.192.103-rc × 6
- resources × 6
- scala × 6
- websharper ui.next × 6
- workshop × 6
- xaml × 6
- 4.0.193.110 × 5
- 4.2.11.258 × 5
- 4.2.3.236 × 5
- aspnetmvc × 5
- azure × 5
- bootstrap × 5
- conference × 5
- css × 5
- dsl × 5
- formlet × 5
- java × 5
- list × 5
- metaprogramming × 5
- ml × 5
- q&a × 5
- released in Zafir.4.0.188.91-beta10 × 5
- released: v0.4 × 5
- released: v0.8 × 5
- spa × 5
- sql × 5
- visualstudio × 5
- websharper.forms × 5
- zafir × 5
- 4.0.192.106 × 4
- 4.0.195.127 × 4
- 4.1.0.38 × 4
- 4.2.1.86 × 4
- 4.2.13.263 × 4
- 4.2.6.118 × 4
- 4.5.5.155 × 4
- 4.6.4.404 × 4
- discussion × 4
- example × 4
- extension × 4
- extensions × 4
- fsi × 4
- fsx × 4
- help wanted × 4
- highlightjs × 4
- html5 × 4
- jqueryui × 4
- lift × 4
- performance × 4
- qna × 4
- react × 4
- reflection × 4
- released: v0.10 × 4
- released: v0.5 × 4
- remote × 4
- rest × 4
- teaching × 4
- todomvc × 4
- 4.0.196.147 × 3
- 4.1.0.34 × 3
- 4.1.6.207 × 3
- 4.2.1.223-beta × 3
- 4.2.14.264 × 3
- 4.2.4.114 × 3
- 4.2.4.247 × 3
- 4.2.5.115 × 3
- 4.2.6.253 × 3
- 4.2.9.256 × 3
- 4.5.0.140 × 3
- 4.5.0.290 × 3
- 4.5.18.348 × 3
- 4.5.2.309 × 3
- 4.5.8.327 × 3
- 4.6.2.386 × 3
- ajax × 3
- alt.net × 3
- aml × 3
- asp.net mvc × 3
- build × 3
- canvas × 3
- cloudsharper × 3
- compilation × 3
- d3 × 3
- data × 3
- database × 3
- erlang × 3
- events × 3
- file upload × 3
- forums × 3
- how to × 3
- http × 3
- inline × 3
- issue × 3
- kendo × 3
- macro × 3
- materialui × 3
- mono × 3
- msbuild × 3
- mvc × 3
- pattern × 3
- piglet × 3
- released in Zafir.4.0.187.90-beta10 × 3
- released: v0.12 × 3
- released: v0.9 × 3
- svg × 3
- type provider × 3
- view × 3
- websharper4 × 3
- 4.1.1.64 × 2
- 4.1.5.203 × 2
- 4.1.7.232 × 2
- 4.2.10.257 × 2
- 4.2.3.111 × 2
- 4.2.5.249 × 2
- 4.3.0.127 × 2
- 4.3.1.275 × 2
- 4.5.10.166 × 2
- 4.5.10.332 × 2
- 4.5.15.342 × 2
- 4.5.19.349 × 2
- 4.5.3.146 × 2
- 4.5.9.301 × 2
- android × 2
- api × 2
- asp.net × 2
- beginner × 2
- blog × 2
- chart × 2
- client × 2
- client server app × 2
- clojure × 2
- computation expressions × 2
- constructor × 2
- corporate × 2
- courses × 2
- cufp × 2
- debugging × 2
- direct × 2
- discriminated union × 2
- dom × 2
- elm × 2
- endpoint × 2
- endpoints × 2
- enterprise × 2
- entity framework × 2
- event × 2
- f# interactive × 2
- fable × 2
- flowlet × 2
- formdata × 2
- forms × 2
- fsc × 2
- fsharp × 2
- google × 2
- google maps × 2
- hosting × 2
- https × 2
- iis 8.0 × 2
- install × 2
- interactive × 2
- interface × 2
- iphone × 2
- iteratee × 2
- jobs × 2
- jquery mobile × 2
- keynote × 2
- lens × 2
- lenses × 2
- linux × 2
- listmodel × 2
- mac × 2
- maps × 2
- numeric × 2
- oauth × 2
- obfuscation × 2
- offline × 2
- oop × 2
- osx × 2
- packaging × 2
- pattern matching × 2
- pipelines × 2
- post × 2
- quotation × 2
- reference × 2
- released in Zafir.4.0.185.88-beta10 × 2
- released: v0.13 × 2
- released: v0.6 × 2
- remarkable × 2
- rx × 2
- script × 2
- security × 2
- self host × 2
- seq × 2
- sockets × 2
- stm × 2
- sweetalert × 2
- tcp × 2
- trie × 2
- tutorials × 2
- type × 2
- url × 2
- var × 2
- websharper.charting × 2
- websockets × 2
- wig × 2
- xna × 2
- zh × 2
- .net framework × 1
- .net interop × 1
- 2012 × 1
- 4.0.194.126 × 1
- 4.1.3.184 × 1
- 4.1.4.189 × 1
- 4.2.0.214-beta × 1
- 4.2.12.259 × 1
- 4.2.2.231-beta × 1
- 4.2.8.255 × 1
- 4.4.1.137 × 1
- 4.5.1.141 × 1
- 4.5.11.334 × 1
- 4.5.12.177 × 1
- 4.5.13.318 × 1
- 4.5.13.338 × 1
- 4.5.16.344 × 1
- 4.5.2.145 × 1
- 4.5.3.144 × 1
- 4.5.3.310 × 1
- 4.5.5.319 × 1
- 4.5.6.156 × 1
- 4.5.6.320 × 1
- 4.5.7.322 × 1
- 4.5.8.161 × 1
- 4.5.9.164 × 1
- 4.6.1.127 × 1
- 4.6.1.381 × 1
- 4.6.3.388 × 1
- 4.6.5.406 × 1
- 4.6.6.407 × 1
- Canvas Sample Example × 1
- DynamicStyle Animated Style × 1
- ES8 × 1
- Fixed in 4.0.190.100-rc × 1
- Metro-Ui-Css × 1
- Metro4 × 1
- Released in Zafir.UI.Next.4.0.169.79-beta10 × 1
- SvgDynamicAttribute × 1
- Swiper × 1
- WebComponent × 1
- WebSharper.TypeScript × 1
- abstract class × 1
- accumulator × 1
- active pattern × 1
- actor × 1
- addin × 1
- agents × 1
- aggregation × 1
- agile × 1
- alter session × 1
- animation × 1
- anonymous object × 1
- apache × 1
- appcelerator × 1
- architecture × 1
- array × 1
- arrays × 1
- asp.net 4.5 × 1
- asp.net core × 1
- asp.net integration × 1
- asp.net mvc 4 × 1
- asp.net web api × 1
- aspnet × 1
- ast × 1
- attributes × 1
- authorization × 1
- b-tree × 1
- back button × 1
- badimageformatexception × 1
- bash script × 1
- batching × 1
- binding-vars × 1
- bistro × 1
- body × 1
- bundle × 1
- camtasia studio × 1
- cas protocol × 1
- charts × 1
- clarity × 1
- class × 1
- cli × 1
- clipboard × 1
- clojurescript × 1
- closures × 1
- cloud × 1
- cms × 1
- code-review × 1
- coding diacritics × 1
- color highlighting × 1
- color zones × 1
- combinator × 1
- combinators × 1
- compile × 1
- compile code on server × 1
- config × 1
- confirm × 1
- content × 1
- context × 1
- context.usersession × 1
- continuation-passing style × 1
- coords × 1
- cordova × 1
- cors × 1
- coursera × 1
- cross-domain × 1
- csla × 1
- current_schema × 1
- custom content × 1
- data grid × 1
- datetime × 1
- debug × 1
- declarative × 1
- delete × 1
- devexpress × 1
- dhtmlx × 1
- dictionary × 1
- directattribute × 1
- disqus × 1
- distance × 1
- do binding × 1
- doc elt ui.next upgrade × 1
- docker × 1
- dojo × 1
- dol × 1
- domain × 1
- dotnet core × 1
- du × 1
- duf-101 × 1
- dynamic × 1
- eastern language × 1
- eclipse × 1
- edsl × 1
- em algorithm × 1
- emacs × 1
- emotion × 1
- enums × 1
- error × 1
- etw × 1
- euclidean × 1
- eventhandlerlist × 1
- examples × 1
- ext js × 1
- extension methods × 1
- extjs × 1
- extra × 1
- facet pattern × 1
- failed to translate × 1
- fake × 1
- fantomas × 1
- fear × 1
- float × 1
- form × 1
- form-data × 1
- forum × 1
- fp × 1
- frank × 1
- fsdoc × 1
- fsharp.core × 1
- fsharp.powerpack × 1
- fsharpx × 1
- fsunit × 1
- function × 1
- functional style × 1
- game × 1
- games × 1
- gc × 1
- generic × 1
- geometry × 1
- getlastwin32error × 1
- getting-started × 1
- good first issue × 1
- google visualization timeline × 1
- google.maps × 1
- grid × 1
- group × 1
- guide × 1
- hash × 1
- headers × 1
- hello world example × 1
- heroku × 1
- highchart × 1
- history × 1
- html-templating × 1
- http405 × 1
- httpcontext × 1
- hubfs × 1
- i18n × 1
- ide × 1
- ie 8 × 1
- if-doc × 1
- iis × 1
- image × 1
- images × 1
- inheritance × 1
- initialize × 1
- input × 1
- install "visual studio" × 1
- installer × 1
- int64 × 1
- interfaces × 1
- internet explorer × 1
- interop × 1
- interpreter × 1
- invalid × 1
- io × 1
- iobservable × 1
- ios × 1
- iot × 1
- ipad × 1
- isomorphic × 1
- javascript optimization × 1
- javascript semanticui resources × 1
- jquery-plugin × 1
- jquery-ui × 1
- jquery-ui-datepicker × 1
- jquerymobile × 1
- js × 1
- kendo datasource × 1
- kendochart × 1
- kendoui compiler × 1
- knockout × 1
- l10n × 1
- leaflet × 1
- learning × 1
- library × 1
- libs × 1
- license × 1
- licensing × 1
- lineserieszonescfg × 1
- local setting × 1
- localization × 1
- logging × 1
- loop × 1
- macros × 1
- mailboxprocessor × 1
- mapping × 1
- markerclusterer × 1
- markup × 1
- marshal × 1
- math × 1
- mathjax × 1
- message × 1
- message passing × 1
- message-passing × 1
- meta × 1
- metro style × 1
- metro-ui × 1
- micro orm × 1
- minimum-requirements × 1
- mix × 1
- mobile installation × 1
- mod_mono × 1
- modal × 1
- module × 1
- mouseevent × 1
- mouseposition × 1
- multidimensional × 1
- multiline × 1
- multithreading × 1
- mysql × 1
- mysqlclient × 1
- nancy × 1
- native × 1
- nested × 1
- nested loops × 1
- netstandard × 1
- node × 1
- nunit × 1
- object relation mapper × 1
- object-oriented × 1
- om × 1
- onboarding × 1
- onclick × 1
- optimization × 1
- option × 1
- orm × 1
- os x × 1
- output-path × 1
- override × 1
- paper × 1
- parameter × 1
- persistence × 1
- persistent data structure × 1
- phonegap × 1
- plotly × 1
- pola × 1
- powerpack × 1
- prefix tree × 1
- principle of least authority × 1
- privacy × 1
- private × 1
- profile × 1
- programming × 1
- project × 1
- project euler × 1
- projekt_feladat × 1
- protected × 1
- provider × 1
- proxy × 1
- ptvs × 1
- public × 1
- pure f# × 1
- purescript × 1
- quant × 1
- query sitelet × 1
- quotations × 1
- range × 1
- raphael × 1
- razor × 1
- rc × 1
- reactjs × 1
- real-time × 1
- ref × 1
- region × 1
- released in 4.0.190.100-rc × 1
- released: v0.2 × 1
- released: v0.3 × 1
- released: v0.7 × 1
- reporting × 1
- responsive design × 1
- rest api × 1
- rest sitelet × 1
- restful × 1
- round table × 1
- router × 1
- routing × 1
- rpc reverseproxy × 1
- runtime × 1
- sales × 1
- sample × 1
- sampleapp × 1
- scriptcs × 1
- scripting × 1
- search × 1
- self hosted × 1
- semanticui × 1
- sequence × 1
- serialisation × 1
- service × 1
- session-state × 1
- sharepoint × 1
- signals × 1
- sitelet website × 1
- sitelet.protect × 1
- sitlets × 1
- slickgrid × 1
- source code × 1
- sqlentityconnection × 1
- ssl × 1
- standards × 1
- static content × 1
- stickynotes × 1
- streamreader × 1
- stress × 1
- strong name × 1
- structures × 1
- submitbutton × 1
- subscribe × 1
- svg example html5 websharper.ui.next × 1
- system.datetime × 1
- system.reflection.targetinvocationexception × 1
- table storage × 1
- targets × 1
- tdd × 1
- template ClientServer × 1
- templates ui.next × 1
- templating × 1
- text parsing × 1
- three.js × 1
- time travel × 1
- tls × 1
- tooltip × 1
- tracing × 1
- tsunamiide × 1
- turkish × 1
- twitter-bootstrap × 1
- type erasure × 1
- type inference × 1
- type providers × 1
- type-providers × 1
- typeprovider × 1
- ui next forms × 1
- ui-next × 1
- ui.next jqueryui × 1
- ui.next charting × 1
- ui.next formlets × 1
- ui.next forms × 1
- ui.next suave visualstudio × 1
- ui.next templating × 1
- unicode × 1
- unittest client × 1
- up for grabs × 1
- upload × 1
- usersession × 1
- validation × 1
- vb × 1
- vb.net × 1
- vector × 1
- view.map × 1
- visal studio × 1
- visual f# × 1
- visual studio 11 × 1
- visual studio 2012 × 1
- visual studio code × 1
- visual studio shell × 1
- visualstudio-websharper × 1
- vs2017 compiler zafir × 1
- vsix × 1
- web api × 1
- web-scraping × 1
- webapi × 1
- webcomponents × 1
- webforms × 1
- webgl × 1
- webrtc × 1
- webshaper × 1
- websharper async × 1
- websharper codemirror × 1
- websharper f# google × 1
- websharper forms × 1
- websharper reactive × 1
- websharper rpc × 1
- websharper sitelets routing × 1
- websharper warp × 1
- websharper-interface-generator × 1
- websharper.chartsjs × 1
- websharper.com × 1
- websharper.exe × 1
- websharper.owin × 1
- websharper.ui.next × 1
- websharper.ui.next jquery × 1
- websockets iis × 1
- webspeech × 1
- why-websharper × 1
- windows 7 × 1
- windows 8 × 1
- windows-phone × 1
- winrt × 1
- www.grabbitmedia.com × 1
- xamarin × 1
- xml × 1
- yeoman × 1
- yield × 1
- zafir beta × 1
- zafir websharper4 × 1
- zarovizsga × 1
|
Copyright (c) 2011-2012 IntelliFactory. All rights reserved. Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy |
Built with WebSharper |







Here is an implementation of a neuroevolution algorithm. Neuroevolution is using genetic algorithms to evolve neural networks. This implementation also uses enforced subpopulations to evolve the networks at the neuron level. I also have a simpler GA implementation if you need the GA without the stuff I had to add to get it to work with the neural networks.
I'm interested in getting the code reviewed, because I think I've relied too much on the imperative features of f#. So I want to get some feedback on portions of the code that you think could be rewritten on a functional manner.
You'll also notice that I maintain the populations in an array and do replacement in place. One of the reasons for me doing this was because I was concerned for efficiency, having to copy the population many times. So what's the way to go in this scenario, array or lists?
The neural network:
#light open System open System.IO open System.Collections.Generic //--------------------------- // global random number gen let random = new System.Random() let randInt x y = random.Next(x, y+1) let randBit() = random.Next(2) let randF() = random.NextDouble() let randWeight(wMin, wMax) = (random.NextDouble() * (wMax + abs_float(wMin))) + wMin let setLast (var: array<'a>) b = var.[var.Length-1] <- b type NeuralNetwork = class val mutable inputNodes: int val mutable hiddenNodes: int val mutable outputNodes: int val mutable network: float array array val mutable wi: float array array; val mutable wo: float array array; val inputLayer: int val hiddenLayer: int val outputLayer: int val bias: float val mutable bestScore: float val mutable bestWi: float array array val mutable bestWo: float array array val mutable sigmoid: float -> float val wMax: float val wMin: float //-----------------------------------------// new (_inputNodes, _hiddenNodes, _outputNodes) as this = { inputNodes = _inputNodes; hiddenNodes = _hiddenNodes; outputNodes = _outputNodes; network = [| |]; wi = [| |]; wo = [| |]; inputLayer = 0; hiddenLayer = 1; outputLayer = 2; bias = -1.; bestScore = 10000.; bestWi = [| |]; bestWo = [| |]; sigmoid = tanh; wMax = 1.; wMin = -1.; } then this.init() //-----------------------------------------// new (_inputNodes, _hiddenNodes, _outputNodes, _args: Dictionary<string,string>) as this = { // +1 done in GA init inputNodes = _inputNodes; hiddenNodes = _hiddenNodes; outputNodes = _outputNodes; network = [| |]; wi = [| |]; wo = [| |]; inputLayer = 0; hiddenLayer = 1; outputLayer = 2; bias = float_of_string(_args.Item "bias"); bestScore = 100.; bestWi = [| |]; bestWo = [| |]; sigmoid = if _args.Item "sigmoid" = "log" then fun var -> if var > 45. then 1. elif var < -45. then 0. else 1./(1. + exp (-var)) else tanh wMax = float_of_string(_args.Item "wMax"); wMin = float_of_string(_args.Item "wMin"); } then this.init() //-----------------------------------------// /// Do all declarations we couldn't do on the constructor member this.init() = this.network <- Array.init 3 (fun i -> match i with | 0 -> Array.create this.inputNodes 0. | 1 -> Array.create this.hiddenNodes 0. | 2 -> Array.create this.outputNodes 0. | _ -> Array.create this.outputNodes 0. ) this.wi <- Array.init this.inputNodes (fun x -> Array.init this.hiddenNodes (fun x -> randWeight(this.wMin, this.wMax))) this.wo <- Array.init this.hiddenNodes (fun x -> Array.init this.outputNodes (fun x -> randWeight(this.wMin, this.wMax))) this.bestWi <- Array.init this.inputNodes (fun x -> Array.init this.hiddenNodes (fun x -> randWeight(this.wMin, this.wMax))) this.bestWo <- Array.init this.hiddenNodes (fun x -> Array.init this.outputNodes (fun x -> randWeight(this.wMin, this.wMax))) //-----------------------------------------// member this.setSigmoid(newSigmoid) = this.sigmoid <- newSigmoid //-----------------------------------------// /// Feedforward propagation /// args: array containing a single case member this.feedforward (input: float array) = // set input activations Array.iteri (fun j x -> if j < (this.inputNodes-1) then this.network.[this.inputLayer].[j] <- input.[j]) this.network.[this.inputLayer] setLast this.network.[this.inputLayer] this.bias // from input to hidden for j=0 to this.network.[this.hiddenLayer].Length-1 do let sum = ref 0. for i=0 to this.network.[this.inputLayer].Length-1 do sum := !sum + this.network.[this.inputLayer].[i] * this.wi.[i].[j] this.network.[this.hiddenLayer].[j] <- this.sigmoid !sum setLast this.network.[this.hiddenLayer] this.bias // from hidden to output for j=0 to this.network.[this.outputLayer].Length-1 do let sum = ref 0. for i=0 to this.network.[this.hiddenLayer].Length-1 do sum := !sum + this.network.[this.hiddenLayer].[i] * this.wo.[i].[j] done this.network.[this.outputLayer].[j] <- this.sigmoid !sum //-----------------------------------------// member this.Output = this.network.[this.outputLayer].[0] // quick fix for now //-----------------------------------------// /// Do a run of the neural network on a set of test cases /// args: training_data_set bool_flag_print_test_run member this.testNet trainData printFlag = let net, wi, wo = this.network, this.wi, this.wo let getLast (var: float array) = var.[var.Length-1] let classify = ref 0 let error = ref 0. trainData |> Array.iter (fun x -> this.feedforward x let output = this.Output if printFlag then printf "%f -> %f\n" (getLast x) output if (getLast x) = 1. && output < 0.55 then incr classify elif (getLast x) = 0. && output > 0.45 then incr classify error := !error + (x.[x.Length-1]-output) * (x.[x.Length-1]-output) ) printf "Error: %f, Wrong class: %d\n" !error !classify if !error < this.bestScore then ( this.bestScore <- !error // copy best wi this.bestWi |> Array.iteri (fun i row -> row |> Array.iteri (fun j _ -> row.[j] <- wi.[i].[j]) ) // copy best wo this.bestWo |> Array.iteri (fun i row -> row |> Array.iteri (fun j _ -> row.[j] <- wo.[i].[j]) ) printf "Better network found\n" ) else () !error endThe genetic algorithm:
#light open System open System.IO open System.Collections.Generic open Nn //--------------------------- // global random number gen let random = new System.Random() let randInt x y = random.Next(x, y+1) let randBit() = random.Next(2) let randF() = random.NextDouble() let randWeight(wMin, wMax) = (random.NextDouble() * (wMax + abs_float(wMin))) + wMin //-----------------------------------// let getTrainingData filename = let allLines = File.ReadAllLines(filename) let train = Array.init allLines.Length (fun i -> allLines.[i].Split([| ' ' |], System.StringSplitOptions.RemoveEmptyEntries) |> Array.map (fun x -> float_of_string(x))) train //-----------------------------------// /// Shuffle training data /// args: 2d array where each row contains a single training example with desired target at the very end let randomShuffle data = let swap arr a b = let temp = arr.[a] arr.[a] <- arr.[b] arr.[b] <- temp data |> Array.iteri (fun i _ -> swap data i (randInt 0 (data.Length-1))) //-----------------------------------// type individual = { mutable fitness:float; chromosome:float array } let fitnessComparer = { new IComparer<individual> with Compare(s1, s2) = s1.fitness.CompareTo(s2.fitness) } let ints var = int_of_string(var) let floats var = float_of_string(var) //-----------------------------------// type NEGeneticAlgorithm = class val mutable xoRate: float val mutable mutRate: float val mutable numSubPops: int val mutable subPopSize: int val mutable chromLen: int val mutable maxGens: int val mutable tourSize: int val mutable permutations: int val train: float array array val mutable pop: individual array array; val mutable NN: NeuralNetwork val args: Dictionary<string,string> new(_args:Dictionary<string,string>) as this = { xoRate = 0.70; mutRate = 0.01; numSubPops = 10; subPopSize = 10; chromLen = 10; maxGens = 10; tourSize = 2; permutations = 3; pop= [| |]; NN = new NeuralNetwork(0,0,0); args = _args; train = getTrainingData (_args.Item "train"); } then this.createPop() //-----------------------------------------// /// Create the population, do all the declarations not possible in the constructor member this.createPop() = let args = this.args this.xoRate <- floats(args.Item "xoRate"); this.mutRate <- floats(args.Item "mutRate"); let hiddenNodes = ints(args.Item "hiddenNodes") + 1 let outputNodes = ints(args.Item "outputNodes") let inputNodes = (this.train.[0].Length - outputNodes) + 1 this.numSubPops <- hiddenNodes this.subPopSize <- ints(this.args.Item "subPopSize"); this.maxGens <- ints(this.args.Item "maxGens"); this.tourSize <- ints(this.args.Item "tourSize"); this.permutations <- ints(this.args.Item "permutations"); this.chromLen <- inputNodes + outputNodes this.pop <- Array.init this.numSubPops (fun i -> Array.init this.subPopSize (fun j -> let chrom = Array.init this.chromLen (fun k -> randWeight(this.NN.wMin, this.NN.wMax)) { fitness=0.; chromosome=chrom } )) randomShuffle this.train this.NN <- new NeuralNetwork(inputNodes, hiddenNodes, outputNodes, args); //-----------------------------------------// /// Mutate chromosome by adding a random float member this.mutate(chrom) = let permute weight = if randF() < 0.5 then weight + randF() else weight - randF() Array.map (fun w -> if randF() < this.mutRate then permute w else w) chrom //-----------------------------------------// /// Crossover two individuals /// args: individual1 individual2 member this.crossover (p1:individual) (p2:individual) = let xoPoint = randInt 1 (p1.chromosome.Length-2) let c1, c2 = p1.chromosome |> Array.copy , p2.chromosome |> Array.copy for i=0 to p1.chromosome.Length-1 do if i >= xoPoint then c1.[i] <- p2.chromosome.[i] c2.[i] <- p1.chromosome.[i] let c1, c2 = this.mutate c1, this.mutate c2 {fitness = 0.; chromosome=c1}, {fitness = 0.; chromosome=c2} //-----------------------------------------// /// Pick 2 parents from a subpopulation using tournament selection of size n member this.pickParents (subpop: individual array) = let tour() = let player = List.init this.tourSize (fun x -> subpop.[randInt 0 (subpop.Length-1)]) let winner = List.fold_left (fun acc x -> if acc.fitness < x.fitness then acc else x) (List.hd player) player winner tour(), tour() //-----------------------------------------// /// Evaluate the current population /// Construct a network by taking a node from each subpopulation /// Assign the score of the network as the fitness of each node member this.evalPop() = let swap arr a b = let temp = arr.[a] arr.[a] <- arr.[b] arr.[b] <- temp let pop = this.pop let shuffleSubPop subPop = subPop |> Array.iteri (fun i _ -> swap subPop i (randInt 0 (subPop.Length-1))) let inputNodes = this.NN.inputNodes for i in {0 .. this.permutations-1} do pop |> Array.iter shuffleSubPop // for every individual in a subpopulation for j in {0 .. pop.[0].Length-1} do // for every subpopulation for k in {0 .. pop.Length-1} do let chrom = pop.[k].[j].chromosome this.NN.wi |> Array.iteri (fun index x -> x.[k] <- chrom.[index]) this.NN.wo.[k] |> Array.iteri (fun index _ -> this.NN.wo.[k].[index] <- chrom.[index+inputNodes]) let score = this.NN.testNet this.train false // for every node (from each subpop) used to construct the NN // give its fitness for k in {0 .. pop.Length-1} do pop.[k].[j].fitness <- pop.[k].[j].fitness + score let perm = float_of_int(this.permutations) pop |> Array.iter (fun x -> x |> Array.iteri (fun i y -> x.[i].fitness <- y.fitness/perm) ) //-----------------------------------------// /// Create next population from offspring member this.nextGen() = let pop = this.pop // for every subpop pop |> Array.iter (fun subpop -> Array.Sort(subpop, fitnessComparer)) for i=0 to pop.Length-1 do // for every ind in subpop // leave first 4 individuals (top 4) in pop for j in {4 .. 2 .. pop.[i].Length-1} do let p1, p2 = this.pickParents pop.[i] let c1, c2 = this.crossover p1 p2 pop.[i].[j] <- c1 pop.[i].[j+1] <- c2 //-----------------------------------------// /// Test the currently best saved network member this.testBest() = let pop = this.pop // copy best wi back this.NN.wi |> Array.iteri (fun i row -> row |> Array.iteri (fun j _ -> row.[j] <- this.NN.bestWi.[i].[j]) ) // copy best wo back this.NN.wo |> Array.iteri (fun i row -> row |> Array.iteri (fun j _ -> row.[j] <- this.NN.bestWo.[i].[j]) ) let score = this.NN.testNet this.train true printf "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" printf "Best saved network score: %f\n" score //-----------------------------------------// /// Test the currently best saved network member this.testHoldout holdout = let pop = this.pop // copy best wi back this.NN.wi |> Array.iteri (fun i row -> row |> Array.iteri (fun j _ -> row.[j] <- this.NN.bestWi.[i].[j]) ) // copy best wo back this.NN.wo |> Array.iteri (fun i row -> row |> Array.iteri (fun j _ -> row.[j] <- this.NN.bestWo.[i].[j]) ) let score = this.NN.testNet holdout true printf "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" printf "Testing on holdout set: %f\n" score endThe program driver:
#light open System open System.IO open System.Collections.Generic open Nn open Ga //-----------------------------------// let parseArgs filename = let args = new Dictionary<string,string>() using (File.OpenText(filename)) (fun f -> while not f.EndOfStream do let (line:string) = f.ReadLine() if line.[0] <> '#' then let data = line.Split([| ' '; '=' |], System.StringSplitOptions.RemoveEmptyEntries) args.Add(data.[0],data.[1]) ) args //-----------------------------------// let runNE() = let args = parseArgs "config" let myga = new NEGeneticAlgorithm(args) let maxGens = int_of_string(args.Item "maxGens") let holdout = getTrainingData("mytrain1.dat") for i=0 to maxGens-1 do printf "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nGen %d\n" i myga.evalPop() myga.nextGen() if (i % 50) = 0 then myga.testHoldout holdout myga.testBest() myga.testHoldout holdout runNE()