From 21861222bd8e4472cd48e27340d4fe8acff05c07 Mon Sep 17 00:00:00 2001 From: aprowe Date: Mon, 14 Nov 2016 23:57:51 -0600 Subject: [PATCH] Added output function to CPPN --- evo.coffee | 27 +++++++++++++++------------ evo.js | 22 ++++++++++++---------- evo.min.js | 2 +- src/cppn.coffee | 3 ++- src/feedforward.coffee | 12 +----------- src/network.coffee | 12 ++++++++++++ 6 files changed, 43 insertions(+), 35 deletions(-) diff --git a/evo.coffee b/evo.coffee index 4f5db13..193e348 100644 --- a/evo.coffee +++ b/evo.coffee @@ -526,6 +526,18 @@ root = if window? then window else this class Network constructor: (@weights, @config)-> + if typeof @config.output_fn == 'function' + @output_fn = @config.output_fn + + else if @config.output_fn == 'linear' + @output_fn = evo.util.linear + + else if @config.output_fn == 'step' + @output_fn = evo.util.step + + else + @output_fn = evo.util.tanh + calc: (input)-> ## Compositional Pattern Producing Network @@ -553,6 +565,7 @@ root = if window? then window else this @weights = copy[..] + super @weights, @config calc: (input)-> # input.push 0 while input.length < @config.input @@ -591,7 +604,7 @@ root = if window? then window else this # fn = @node_fn[@config.hidden_layers-1][i] output[j] += hidden_weights[@config.hidden_layers-1][i] * copy.pop() - output[j] = evo.util.tanh output[j] + output[j] = @output_fn output[j] return output @@ -600,17 +613,7 @@ root = if window? then window else this class FeedForward extends Network constructor: (@weights, @config) -> - if typeof @config.output_fn == 'function' - @output_fn = @config.output_fn - - else if @config.output_fn == 'linear' - @output_fn = evo.util.linear - - else if @config.output_fn == 'step' - @output_fn = evo.util.step - - else - @output_fn = evo.util.tanh + super @weights, @config calc: (input)-> if input.length != @config.input_nodes diff --git a/evo.js b/evo.js index d162cd8..71736d3 100644 --- a/evo.js +++ b/evo.js @@ -520,6 +520,15 @@ function Network(weights, config1) { this.weights = weights; this.config = config1; + if (typeof this.config.output_fn === 'function') { + this.output_fn = this.config.output_fn; + } else if (this.config.output_fn === 'linear') { + this.output_fn = evo.util.linear; + } else if (this.config.output_fn === 'step') { + this.output_fn = evo.util.step; + } else { + this.output_fn = evo.util.tanh; + } } Network.prototype.calc = function(input) {}; @@ -554,6 +563,7 @@ } } this.weights = copy.slice(0); + Cppn.__super__.constructor.call(this, this.weights, this.config); } Cppn.prototype.calc = function(input) { @@ -590,7 +600,7 @@ for (i = v = 0, ref7 = this.config.hidden_nodes - 1; 0 <= ref7 ? v <= ref7 : v >= ref7; i = 0 <= ref7 ? ++v : --v) { output[j] += hidden_weights[this.config.hidden_layers - 1][i] * copy.pop(); } - output[j] = evo.util.tanh(output[j]); + output[j] = this.output_fn(output[j]); } return output; }; @@ -604,15 +614,7 @@ function FeedForward(weights, config1) { this.weights = weights; this.config = config1; - if (typeof this.config.output_fn === 'function') { - this.output_fn = this.config.output_fn; - } else if (this.config.output_fn === 'linear') { - this.output_fn = evo.util.linear; - } else if (this.config.output_fn === 'step') { - this.output_fn = evo.util.step; - } else { - this.output_fn = evo.util.tanh; - } + FeedForward.__super__.constructor.call(this, this.weights, this.config); } FeedForward.prototype.calc = function(input) { diff --git a/evo.min.js b/evo.min.js index 54b2b87..18f1821 100644 --- a/evo.min.js +++ b/evo.min.js @@ -4,4 +4,4 @@ * Copyright (c) 2016 Alex Rowe * Licensed MIT **/ -(function(){var a,b=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a},c={}.hasOwnProperty;a="undefined"!=typeof window&&null!==window?window:this,function(b){return"object"==typeof exports?module.exports=b.call(a):"function"==typeof define&&define.amd?define(function(){return b.call(a)}):a.evo=b.call(a)}(function(){var a,c,d,e,f,g;return g={},g.population=function(a){return a=g.util.extend(g.config.pool,a),new f(a)},g.network=function(a,b,e){return e=g.util.extend(g.config.network,e),"feedforward"===a?new d(b,e):"cppn"===a?new c(b,e):void 0},g.configure=function(a){return g.config=g.util.extend(g.config,a)},g.config={pool:{genes:200,cross_rate:.05,mutate_rate:.05,mutate_amount:1,size:100,ratios:{top:.25,mutate:.25,cross:.25,random:.1,average:.05,fresh:.1},run_conditions:{generations:1e3,iterations:void 0,score:1/0,auto_stop:!1,min_generations:10,"while":void 0},on_breed:void 0,on_member:void 0,on_run:void 0,on_finish:void 0},network:{output_fn:"tanh",output_nodes:2,hidden_layers:2,hidden_nodes:2,input_nodes:2}},g.util={random:function(a,b){return null==a&&(a=-1),null==b&&(b=1),Math.random()*(b-a)+a},sin:function(a,b,c){return null==b&&(b=1),null==c&&(c=0),Math.sin(a*b*6.2832+c)},gaussian:function(a,b,c){return null==b&&(b=0),null==c&&(c=1),Math.exp(-Math.pow(b-a,2)*c)},linear:function(a,b,c){return null==b&&(b=1),null==c&&(c=0),(a+c)*b},flatten:function(a){return a>1?1:-1>a?-1:a},tanh:function(a){var b,c;return-3>a||a>3?g.util.flatten(a):(b=Math.exp(a),c=Math.exp(-a),(b-c)/(b+c))},step:function(a){return 0>a?-1:1},sample:function(a){return a[Math.floor(Math.random()*a.length)]},shuffle:function(a){var b,c,d,e,f,g;for(d=a.length,g=Array(d),b=c=0,f=d-1;f>=0?f>=c:c>=f;b=f>=0?++c:--c)e=Math.floor(Math.random()*b),e!==b&&(g[b]=g[e]),g[e]=a[b];return g},clone:function(a){var b,c;if(null===a||"object"!=typeof a)return a;c=a.constructor();for(b in a)a.hasOwnProperty(b)&&(c[b]=a[b]);return c},extend:function(a,b){var c;if(a=g.util.clone(a),null==b)return a;for(c in b)b[c]&&b[c].constructor&&b[c].constructor===Object?(a[c]=a[c]||{},a[c]=arguments.callee(a[c],b[c])):a[c]=b[c];return a},normalize:function(a){var b,c,d,e;d=0;for(b in a)e=a[b],d+=e;c={};for(b in a)e=a[b],e||(e=0),c[b]=e/d;return c},mean:function(a){var b,c,d,e,f;if(null==a.length||0===a.length)throw"data must be a list of numbers";for(f=0,b=a.length,d=0,e=a.length;e>d;d++)c=a[d],f+=c;return f/b},stddev:function(a){var b,c,d,e,f,h;for(f=g.util.mean(a),b=a.length,h=0,d=0,e=a.length;e>d;d++)c=a[d],h+=(c-f)*(c-f);return Math.sqrt(h/b)}},a=function(){function a(){}return a.prototype.config={},a.prototype.on=function(a,b){return this.config["on_"+a]=b,this},a.prototype.trigger=function(a,b){return null==b&&(b=null),null!=this.config["on_"+a]?this.config["on_"+a].call(this,b):void 0},a}(),f=function(a){function c(a){var b,c,d;for(this.config=a,this.generation=0,this.iteration=0,this.genes=[],b=c=1,d=this.config.size;d>=1?d>=c:c>=d;b=d>=1?++c:--c)this.genes.push(this._freshGenes());this.average=0,this._prevGenes=this.genes.slice(0),this._scoredGenes=[],this._history=[]}return b(c,a),c.prototype.constructMember=function(a){var b;return null==a&&(a=null),b=this.trigger("member",a),null==b?null:(b._evo={},b._evo.genes=a,b._evo.score=0,b._evo.report=function(a){return function(){return a.report(b)}}(this),b)},c.prototype.nextGenes=function(){var a;if(a=this.genes.pop(),0===this.genes.length){if(!(this._scoredGenes.length>0))throw"Gene pool is empty";this._generate()}return a},c.prototype.nextMember=function(){return null!=this.config.on_member?this.constructMember(this.nextGenes()):void 0},c.prototype.report=function(a,b){return null==b&&(b=0),this.iteration++,null!=a._evo&&(b=a._evo.score,a=a._evo.genes),this._scoredGenes.push({genes:a,score:b})},c.prototype._checkRun=function(a){var b;return b=!0,null!=a.generations&&(b=b&&this.generationc*c)},c.prototype.run=function(a){for(null==a&&(a={}),"number"==typeof a?a={iterations:a}:"function"==typeof a&&(a={"while":a}),null!=a.generations&&(a.generations+=this.generation),null!=a.iterations&&(a.iterations+=this.iteration),a=g.util.extend(this.config.run_conditions,a);this._checkRun(a);)this._runOnce();return this.trigger("finish")},c.prototype.bestGenes=function(a){return null==a?this._prevGenes[0]:this._prevGenes.slice(0,+(a-1)+1||9e9)},c.prototype.loadGenes=function(a){return this.genes=a.slice(0),this._scoredGenes=[]},c.prototype._freshGenes=function(){var a,b,c,d;for(d=[],a=b=1,c=this.config.genes;c>=1?c>=b:b>=c;a=c>=1?++b:--b)d.push(g.util.random()*this.config.mutate_amount);return d},c.prototype._cloneGenes=function(a){return a.slice(0)},c.prototype._mutateGenes=function(a){var b,c,d,e,f;for(f=[],c=d=0,e=a.length;e>d;c=++d)b=a[c],f[c]=a[c],Math.random()f;e=++f)d=a[e],Math.random()e;d=++e)c=a[d],g.push((a[d]+b[d])/2);return g},c.prototype._runOnce=function(){var a,b;if(a=this.nextMember()||this.nextGenes(),b=this.trigger("run",a),null!=a._evo)return this.report(a);if("undefined"!=typeof b)return this.report(a,b);throw"score was not returned in run function"},c.prototype._generate=function(){var a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r,s;for(l=g.util.normalize(this.config.ratios),this.genes=[],q=function(){var b,c,d,e;for(d=this._scoredGenes,e=[],b=0,c=d.length;c>b;b++)a=d[b],e.push(a.score);return e}.call(this),this.average=g.util.mean(q),this._scoredGenes=this._scoredGenes.sort(function(a,b){return a.score-b.score}),s=this._scoredGenes.reverse().slice(0,+(this.config.ratios.top*this.config.size)+1||9e9),this._history.push(s[0].score),r=this.config.size,1>r&&(r=0),e=0,f=s.length;f>e;e++)a=s[e],this.genes.push(this._cloneGenes(a.genes));if(l.mutate>0)for(d=h=1,m=l.mutate*r;m>=1?m>=h:h>=m;d=m>=1?++h:--h)this.genes.push(this._mutateGenes(g.util.sample(s).genes));if(l.cross>0)for(d=i=1,n=l.cross*r;n>=1?n>=i:i>=n;d=n>=1?++i:--i)b=g.util.sample(s).genes,c=g.util.sample(s).genes,this.genes.push(this._crossGenes(b,c));if(l.average>0)for(d=j=1,o=l.meld*r;o>=1?o>=j:j>=o;d=o>=1?++j:--j)b=g.util.sample(s).genes,c=g.util.sample(s).genes,this.genes.push(this._averageGenes(b,c));if(l.random>0)for(d=k=1,p=l.random*r;p>=1?p>=k:k>=p;d=p>=1?++k:--k)this.genes.push(this._cloneGenes(g.util.sample(this._scoredGenes).genes));for(;this.genes.length<=r;)this.genes.push(this._freshGenes());return this.generation++,this._prevGenes=this.genes.slice(0),this.genes=g.util.shuffle(this.genes),this.trigger("breed"),this._scoredGenes=[]},c}(a),e=function(){function a(a,b){this.weights=a,this.config=b}return a.prototype.calc=function(){},a}(),c=function(a){function c(a,b){var c,d,e,f,g,h,i;for(this.config=b,this.node_fn=[],c=a.slice(0),d=f=0,h=this.config.hidden_layers-1;h>=0?h>=f:f>=h;d=h>=0?++f:--f)for(this.node_fn[d]=[],e=g=0,i=this.config.hidden_nodes-1;i>=0?i>=g:g>=i;e=i>=0?++g:--g)this.node_fn[d].push(this.get_fn(c.pop()));this.weights=c.slice(0)}return b(c,a),c.node_fn=[g.util.gaussian,g.util.sin,function(a,b,c){return g.util.tanh(g.util.linear(a,b,c))}],c.prototype.get_fn=function(a){var b;return b=Math.round(Math.abs(a)*c.node_fn.length)%c.node_fn.length,c.node_fn[b]},c.prototype.calc=function(a){var b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B;for(i=this.config.hidden_nodes,b=this.weights.slice(0),c=[],f=h=0,p=this.config.hidden_layers-1;p>=0?p>=h:h>=p;f=p>=0?++h:--h)for(c[f]=[],d=k=0,q=this.config.hidden_nodes-1;q>=0?q>=k:k>=q;d=q>=0?++k:--k)c[f][d]=0;for(m=0,j=a.length;j>m;m++)for(B=a[m],d=n=0,r=this.config.hidden_nodes-1;r>=0?r>=n:n>=r;d=r>=0?++n:--n)c[0][d]+=B*b.pop();for(f=o=0,s=this.config.hidden_layers-2;s>=0?s>=o:o>=s;f=s>=0?++o:--o)for(d=x=0,t=this.config.hidden_nodes-1;t>=0?t>=x:x>=t;d=t>=0?++x:--x)if(c[f][d]=this.node_fn[f][d](c[f][d],b.pop(),b.pop()),f+1=0?u>=y:y>=u;e=u>=0?++y:--y)c[f+1][e]+=c[f][d]*b.pop();for(l=[],e=z=0,v=this.config.output_nodes-1;v>=0?v>=z:z>=v;e=v>=0?++z:--z){for(l[e]=0,d=A=0,w=this.config.hidden_nodes-1;w>=0?w>=A:A>=w;d=w>=0?++A:--A)l[e]+=c[this.config.hidden_layers-1][d]*b.pop();l[e]=g.util.tanh(l[e])}return l},c}(e),d=function(a){function c(a,b){this.weights=a,this.config=b,this.output_fn="function"==typeof this.config.output_fn?this.config.output_fn:"linear"===this.config.output_fn?g.util.linear:"step"===this.config.output_fn?g.util.step:g.util.tanh}return b(c,a),c.prototype.calc=function(a){var b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(a.length!==this.config.input_nodes)throw Error("Inputs dont match. Expected: "+this.config.input_nodes+", Received: "+a.length);for(b=this.weights.slice(0).reverse(),d=[],f=h=0,t=this.config.hidden_nodes-1;t>=0?t>=h:h>=t;f=t>=0?++h:--h)d[f]=0;for(p=[],f=n=0,u=this.config.output_nodes-1;u>=0?u>=n:n>=u;f=u>=0?++n:--n)p[f]=0;for(q=0,i=a.length;i>q;q++)for(e=a[q],f=r=0,j=d.length;j>r;f=++r)c=d[f],d[f]+=e*b.pop();for(e=s=0,k=d.length;k>s;e=++s)for(c=d[e],d[e]+=b.pop(),d[e]=g.util.tanh(d[e]),f=v=0,l=p.length;l>v;f=++v)o=p[f],p[f]+=d[e]*b.pop();for(e=w=0,m=p.length;m>w;e=++w)o=p[e],p[e]=this.output_fn(p[e]);return 1===p.length?p[0]:p},c}(e),g})}).call(this); \ No newline at end of file +(function(){var a,b=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a},c={}.hasOwnProperty;a="undefined"!=typeof window&&null!==window?window:this,function(b){return"object"==typeof exports?module.exports=b.call(a):"function"==typeof define&&define.amd?define(function(){return b.call(a)}):a.evo=b.call(a)}(function(){var a,c,d,e,f,g;return g={},g.population=function(a){return a=g.util.extend(g.config.pool,a),new f(a)},g.network=function(a,b,e){return e=g.util.extend(g.config.network,e),"feedforward"===a?new d(b,e):"cppn"===a?new c(b,e):void 0},g.configure=function(a){return g.config=g.util.extend(g.config,a)},g.config={pool:{genes:200,cross_rate:.05,mutate_rate:.05,mutate_amount:1,size:100,ratios:{top:.25,mutate:.25,cross:.25,random:.1,average:.05,fresh:.1},run_conditions:{generations:1e3,iterations:void 0,score:1/0,auto_stop:!1,min_generations:10,"while":void 0},on_breed:void 0,on_member:void 0,on_run:void 0,on_finish:void 0},network:{output_fn:"tanh",output_nodes:2,hidden_layers:2,hidden_nodes:2,input_nodes:2}},g.util={random:function(a,b){return null==a&&(a=-1),null==b&&(b=1),Math.random()*(b-a)+a},sin:function(a,b,c){return null==b&&(b=1),null==c&&(c=0),Math.sin(a*b*6.2832+c)},gaussian:function(a,b,c){return null==b&&(b=0),null==c&&(c=1),Math.exp(-Math.pow(b-a,2)*c)},linear:function(a,b,c){return null==b&&(b=1),null==c&&(c=0),(a+c)*b},flatten:function(a){return a>1?1:-1>a?-1:a},tanh:function(a){var b,c;return-3>a||a>3?g.util.flatten(a):(b=Math.exp(a),c=Math.exp(-a),(b-c)/(b+c))},step:function(a){return 0>a?-1:1},sample:function(a){return a[Math.floor(Math.random()*a.length)]},shuffle:function(a){var b,c,d,e,f,g;for(d=a.length,g=Array(d),b=c=0,f=d-1;f>=0?f>=c:c>=f;b=f>=0?++c:--c)e=Math.floor(Math.random()*b),e!==b&&(g[b]=g[e]),g[e]=a[b];return g},clone:function(a){var b,c;if(null===a||"object"!=typeof a)return a;c=a.constructor();for(b in a)a.hasOwnProperty(b)&&(c[b]=a[b]);return c},extend:function(a,b){var c;if(a=g.util.clone(a),null==b)return a;for(c in b)b[c]&&b[c].constructor&&b[c].constructor===Object?(a[c]=a[c]||{},a[c]=arguments.callee(a[c],b[c])):a[c]=b[c];return a},normalize:function(a){var b,c,d,e;d=0;for(b in a)e=a[b],d+=e;c={};for(b in a)e=a[b],e||(e=0),c[b]=e/d;return c},mean:function(a){var b,c,d,e,f;if(null==a.length||0===a.length)throw"data must be a list of numbers";for(f=0,b=a.length,d=0,e=a.length;e>d;d++)c=a[d],f+=c;return f/b},stddev:function(a){var b,c,d,e,f,h;for(f=g.util.mean(a),b=a.length,h=0,d=0,e=a.length;e>d;d++)c=a[d],h+=(c-f)*(c-f);return Math.sqrt(h/b)}},a=function(){function a(){}return a.prototype.config={},a.prototype.on=function(a,b){return this.config["on_"+a]=b,this},a.prototype.trigger=function(a,b){return null==b&&(b=null),null!=this.config["on_"+a]?this.config["on_"+a].call(this,b):void 0},a}(),f=function(a){function c(a){var b,c,d;for(this.config=a,this.generation=0,this.iteration=0,this.genes=[],b=c=1,d=this.config.size;d>=1?d>=c:c>=d;b=d>=1?++c:--c)this.genes.push(this._freshGenes());this.average=0,this._prevGenes=this.genes.slice(0),this._scoredGenes=[],this._history=[]}return b(c,a),c.prototype.constructMember=function(a){var b;return null==a&&(a=null),b=this.trigger("member",a),null==b?null:(b._evo={},b._evo.genes=a,b._evo.score=0,b._evo.report=function(a){return function(){return a.report(b)}}(this),b)},c.prototype.nextGenes=function(){var a;if(a=this.genes.pop(),0===this.genes.length){if(!(this._scoredGenes.length>0))throw"Gene pool is empty";this._generate()}return a},c.prototype.nextMember=function(){return null!=this.config.on_member?this.constructMember(this.nextGenes()):void 0},c.prototype.report=function(a,b){return null==b&&(b=0),this.iteration++,null!=a._evo&&(b=a._evo.score,a=a._evo.genes),this._scoredGenes.push({genes:a,score:b})},c.prototype._checkRun=function(a){var b;return b=!0,null!=a.generations&&(b=b&&this.generationc*c)},c.prototype.run=function(a){for(null==a&&(a={}),"number"==typeof a?a={iterations:a}:"function"==typeof a&&(a={"while":a}),null!=a.generations&&(a.generations+=this.generation),null!=a.iterations&&(a.iterations+=this.iteration),a=g.util.extend(this.config.run_conditions,a);this._checkRun(a);)this._runOnce();return this.trigger("finish")},c.prototype.bestGenes=function(a){return null==a?this._prevGenes[0]:this._prevGenes.slice(0,+(a-1)+1||9e9)},c.prototype.loadGenes=function(a){return this.genes=a.slice(0),this._scoredGenes=[]},c.prototype._freshGenes=function(){var a,b,c,d;for(d=[],a=b=1,c=this.config.genes;c>=1?c>=b:b>=c;a=c>=1?++b:--b)d.push(g.util.random()*this.config.mutate_amount);return d},c.prototype._cloneGenes=function(a){return a.slice(0)},c.prototype._mutateGenes=function(a){var b,c,d,e,f;for(f=[],c=d=0,e=a.length;e>d;c=++d)b=a[c],f[c]=a[c],Math.random()f;e=++f)d=a[e],Math.random()e;d=++e)c=a[d],g.push((a[d]+b[d])/2);return g},c.prototype._runOnce=function(){var a,b;if(a=this.nextMember()||this.nextGenes(),b=this.trigger("run",a),null!=a._evo)return this.report(a);if("undefined"!=typeof b)return this.report(a,b);throw"score was not returned in run function"},c.prototype._generate=function(){var a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r,s;for(l=g.util.normalize(this.config.ratios),this.genes=[],q=function(){var b,c,d,e;for(d=this._scoredGenes,e=[],b=0,c=d.length;c>b;b++)a=d[b],e.push(a.score);return e}.call(this),this.average=g.util.mean(q),this._scoredGenes=this._scoredGenes.sort(function(a,b){return a.score-b.score}),s=this._scoredGenes.reverse().slice(0,+(this.config.ratios.top*this.config.size)+1||9e9),this._history.push(s[0].score),r=this.config.size,1>r&&(r=0),e=0,f=s.length;f>e;e++)a=s[e],this.genes.push(this._cloneGenes(a.genes));if(l.mutate>0)for(d=h=1,m=l.mutate*r;m>=1?m>=h:h>=m;d=m>=1?++h:--h)this.genes.push(this._mutateGenes(g.util.sample(s).genes));if(l.cross>0)for(d=i=1,n=l.cross*r;n>=1?n>=i:i>=n;d=n>=1?++i:--i)b=g.util.sample(s).genes,c=g.util.sample(s).genes,this.genes.push(this._crossGenes(b,c));if(l.average>0)for(d=j=1,o=l.meld*r;o>=1?o>=j:j>=o;d=o>=1?++j:--j)b=g.util.sample(s).genes,c=g.util.sample(s).genes,this.genes.push(this._averageGenes(b,c));if(l.random>0)for(d=k=1,p=l.random*r;p>=1?p>=k:k>=p;d=p>=1?++k:--k)this.genes.push(this._cloneGenes(g.util.sample(this._scoredGenes).genes));for(;this.genes.length<=r;)this.genes.push(this._freshGenes());return this.generation++,this._prevGenes=this.genes.slice(0),this.genes=g.util.shuffle(this.genes),this.trigger("breed"),this._scoredGenes=[]},c}(a),e=function(){function a(a,b){this.weights=a,this.config=b,this.output_fn="function"==typeof this.config.output_fn?this.config.output_fn:"linear"===this.config.output_fn?g.util.linear:"step"===this.config.output_fn?g.util.step:g.util.tanh}return a.prototype.calc=function(){},a}(),c=function(a){function c(a,b){var d,e,f,g,h,i,j;for(this.config=b,this.node_fn=[],d=a.slice(0),e=g=0,i=this.config.hidden_layers-1;i>=0?i>=g:g>=i;e=i>=0?++g:--g)for(this.node_fn[e]=[],f=h=0,j=this.config.hidden_nodes-1;j>=0?j>=h:h>=j;f=j>=0?++h:--h)this.node_fn[e].push(this.get_fn(d.pop()));this.weights=d.slice(0),c.__super__.constructor.call(this,this.weights,this.config)}return b(c,a),c.node_fn=[g.util.gaussian,g.util.sin,function(a,b,c){return g.util.tanh(g.util.linear(a,b,c))}],c.prototype.get_fn=function(a){var b;return b=Math.round(Math.abs(a)*c.node_fn.length)%c.node_fn.length,c.node_fn[b]},c.prototype.calc=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A;for(h=this.config.hidden_nodes,b=this.weights.slice(0),c=[],f=g=0,o=this.config.hidden_layers-1;o>=0?o>=g:g>=o;f=o>=0?++g:--g)for(c[f]=[],d=j=0,p=this.config.hidden_nodes-1;p>=0?p>=j:j>=p;d=p>=0?++j:--j)c[f][d]=0;for(l=0,i=a.length;i>l;l++)for(A=a[l],d=m=0,q=this.config.hidden_nodes-1;q>=0?q>=m:m>=q;d=q>=0?++m:--m)c[0][d]+=A*b.pop();for(f=n=0,r=this.config.hidden_layers-2;r>=0?r>=n:n>=r;f=r>=0?++n:--n)for(d=w=0,s=this.config.hidden_nodes-1;s>=0?s>=w:w>=s;d=s>=0?++w:--w)if(c[f][d]=this.node_fn[f][d](c[f][d],b.pop(),b.pop()),f+1=0?t>=x:x>=t;e=t>=0?++x:--x)c[f+1][e]+=c[f][d]*b.pop();for(k=[],e=y=0,u=this.config.output_nodes-1;u>=0?u>=y:y>=u;e=u>=0?++y:--y){for(k[e]=0,d=z=0,v=this.config.hidden_nodes-1;v>=0?v>=z:z>=v;d=v>=0?++z:--z)k[e]+=c[this.config.hidden_layers-1][d]*b.pop();k[e]=this.output_fn(k[e])}return k},c}(e),d=function(a){function c(a,b){this.weights=a,this.config=b,c.__super__.constructor.call(this,this.weights,this.config)}return b(c,a),c.prototype.calc=function(a){var b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(a.length!==this.config.input_nodes)throw Error("Inputs dont match. Expected: "+this.config.input_nodes+", Received: "+a.length);for(b=this.weights.slice(0).reverse(),d=[],f=h=0,t=this.config.hidden_nodes-1;t>=0?t>=h:h>=t;f=t>=0?++h:--h)d[f]=0;for(p=[],f=n=0,u=this.config.output_nodes-1;u>=0?u>=n:n>=u;f=u>=0?++n:--n)p[f]=0;for(q=0,i=a.length;i>q;q++)for(e=a[q],f=r=0,j=d.length;j>r;f=++r)c=d[f],d[f]+=e*b.pop();for(e=s=0,k=d.length;k>s;e=++s)for(c=d[e],d[e]+=b.pop(),d[e]=g.util.tanh(d[e]),f=v=0,l=p.length;l>v;f=++v)o=p[f],p[f]+=d[e]*b.pop();for(e=w=0,m=p.length;m>w;e=++w)o=p[e],p[e]=this.output_fn(p[e]);return 1===p.length?p[0]:p},c}(e),g})}).call(this); \ No newline at end of file diff --git a/src/cppn.coffee b/src/cppn.coffee index bd3c038..20bec80 100644 --- a/src/cppn.coffee +++ b/src/cppn.coffee @@ -23,6 +23,7 @@ class Cppn extends Network @weights = copy[..] + super @weights, @config calc: (input)-> # input.push 0 while input.length < @config.input @@ -61,6 +62,6 @@ class Cppn extends Network # fn = @node_fn[@config.hidden_layers-1][i] output[j] += hidden_weights[@config.hidden_layers-1][i] * copy.pop() - output[j] = evo.util.tanh output[j] + output[j] = @output_fn output[j] return output diff --git a/src/feedforward.coffee b/src/feedforward.coffee index 1016a8e..3e82780 100644 --- a/src/feedforward.coffee +++ b/src/feedforward.coffee @@ -3,17 +3,7 @@ class FeedForward extends Network constructor: (@weights, @config) -> - if typeof @config.output_fn == 'function' - @output_fn = @config.output_fn - - else if @config.output_fn == 'linear' - @output_fn = evo.util.linear - - else if @config.output_fn == 'step' - @output_fn = evo.util.step - - else - @output_fn = evo.util.tanh + super @weights, @config calc: (input)-> if input.length != @config.input_nodes diff --git a/src/network.coffee b/src/network.coffee index 1530633..ca840a4 100644 --- a/src/network.coffee +++ b/src/network.coffee @@ -2,4 +2,16 @@ class Network constructor: (@weights, @config)-> + if typeof @config.output_fn == 'function' + @output_fn = @config.output_fn + + else if @config.output_fn == 'linear' + @output_fn = evo.util.linear + + else if @config.output_fn == 'step' + @output_fn = evo.util.step + + else + @output_fn = evo.util.tanh + calc: (input)->