IEnumerable<Connection> GetNeuronConnections(Link[] prior,NeuronBase neuron, Bias bias) { foreach(Link link in prior) yield return new Connection(link,neuron); if(bias!=null) yield return new Connection(bias,neuron); }
public Connection(Weight weight,Link previous,NeuronBase next) { Utility.Verify(()=> weight!=null && previous!=null && next!=null); Weight=weight; Next=next; Previous=previous; }
public ConvolutionalNetwork Create(ConvolutionalTopology topology) { Utility.Verify(topology,t => t!=null,"Invalid network topology"); var l=topology.Layers.Length; Link[][] layers=new Link[l][]; Bias bias=null; if(topology.Bias.HasValue) bias=new Bias(topology.Bias.Value); for(var i=0; i<l-1;i++){ if(i==0) layers[i]=Utility.Generate<Link>(topology.Layers[i]).ToArray(); int j=i+1; int size=topology.Layers[j]; if(topology.Map[i] is SubSampling) layers[j]= Utility.Generate<SubSamplingNeuron>(size).ToArray(); else layers[j]= Utility.Generate<Neuron>(size).ToArray(); topology.Map[i].Connect(layers[i],(NeuronBase[])layers[j],bias); } SetIdentity(layers); foreach(Link[] layer in layers) foreach(Link link in layer) if(link is NeuronBase) ((NeuronBase)link).Func=topology.Func; return new ConvolutionalNetwork(new NetworkStructure(layers,bias)); }
public override void Connect(Link[] prior,Node[] next) { Utility.Verify(prior,x => x!=null,"Invalid prior layer"); Utility.Verify(next,x => x!=null,"Invalid next layer"); Utility.Verify(() => next.Length % FeatureMapsCount==0,"FeatureMapsCount - next layer size conflict"); Node[][] fm=GetFeatureMaps(next); Link[][] kernelSet=GetKernelSet(prior); if(Bias!=null) Bias.Next=new Connection[next.Length]; foreach(Link[] featureMap in fm) Utility.Verify(() => featureMap.Length==kernelSet.Length,"featureMap - kernel conflict"); Dictionary<Link,int> ccd=new Dictionary<Link,int>(); foreach(Link p in prior) ccd[p]=GetConnectionsCount(p,fm.Length,kernelSet); for(int f=0;f<fm.Length;f++) { Node[] featureMap=fm[f]; int weightCount=KernelSize*KernelSize; if(Bias!=null) weightCount++; double[] weightValues=Utility.Generate<double>(WeightGenerator,weightCount).ToArray(); Weight[] weights=weightValues.Select(x => new Weight(x)).ToArray(); for(int n=0; n<featureMap.Length;n++){ Node node=featureMap[n]; Link[] kernel=kernelSet[n]; ConnectKernel(kernel,node,weights,Bias,ccd); } } }
public NetworkStructure(Link[][] layers,Bias bias) { Utility.Verify(() => layers!=null && layers.All(x => x!=null&&x.Length>0),"layers"); Layers=layers; Bias=bias; Elements=Gather(layers,bias).ToArray(); }
public override void Connect(Link[] prior,NeuronBase[] next,Bias bias) { Utility.Verify(prior,x => x!=null && prior.Length>0,"Invalid prior layer"); Utility.Verify(next,x => x!=null && next.Length>0,"Invalid next layer"); Utility.Verify(() => next.Length % FeatureMapsCount==0,"FeatureMapsCount - next layer size conflict"); Utility.Verify(() => prior.Length % FeatureMapsCount==0,"FeatureMapsCount - prior layer size conflict"); Link[][] c=GetFeatureMaps(prior,FeatureMapsCount); NeuronBase[][] s=GetFeatureMaps(next,FeatureMapsCount); Link[][][] kernelCollection=GetKernelCollection(c,2,0); //always x/2 Dictionary<Link,List<Connection>> map=new Dictionary<Link,List<Connection>>(); for(var i=0;i<kernelCollection.Length;i++) ConnectFeatureMaps(s[i],kernelCollection[i],bias,map); foreach(Link link in prior) link.Next= map[link].ToArray(); foreach(NeuronBase neuron in next) neuron.Previous=map[neuron].ToArray(); if(bias!=null){ if(bias.Next==null) bias.Next=new Connection[] { }; bias.Next=bias.Next.Concat(map[bias]).ToArray(); } }
void Connect(Link pre,Node post,Weight weight) { Connection i=new Connection(weight); pre.Next[Utility.FirstNull(pre.Next)]=i; post.Previous[Utility.FirstNull(post.Previous)]=i; i.Previous=pre; i.Next=post; i.Identity=string.Format("{0} --> {1}",i.Previous.Identity,i.Next.Identity); }
IEnumerable<Link> Gather(Link[][] layers,Bias bias) { foreach(Link[] layer in layers) foreach(Link link in layer) yield return link; if(bias!=null) yield return bias; yield break; }
void Map(Link a,Link b,Weight weight,Dictionary<Link,List<Connection>> map) { Connection connection=new Connection(weight,a,(NeuronBase)b); if(!map.ContainsKey(a)) map[a]=new List<Connection>(); map[a].Add(connection); if(!map.ContainsKey(b)) map[b]=new List<Connection>(); map[b].Add(connection); }
protected void SetIdentity(Link[][] structure) { var idx=0; for(int i=0;i<structure.Length;i++) { for(int j=0;j<structure[i].Length;j++) { string pref=i==0?"Link":"Neuron"; structure[i][j].Identity=string.Format("{0}.{1}, L{2}",pref,idx++,i); } } }
void ConnectFeatureMaps(Neuron[] next,Link[][] kernelCollection,Dictionary<Link,List<Connection>> map) { Weight[] weights=Utility.Generate(() => new SharedWeight(kernelCollection.Length),KernelSize*KernelSize).ToArray(); for(int i=0;i<kernelCollection.Length;i++){ for(var j=0; j<kernelCollection[i].Length; j++){ Link link=kernelCollection[i][j]; Map(link,next[i],weights[j],map); } } }
void ConnectFeatureMaps(NeuronBase[] next,Link[][] kernelCollection,Bias bias,Dictionary<Link,List<Connection>> map) { SharedWeight weight=new SharedWeight(next.Length); SharedWeight biasWeight=new SharedWeight(next.Length); for(var i=0;i<kernelCollection.Length;i++){ ConnectKernel(next[i],kernelCollection[i],weight,map); if(bias!=null){ Map(bias,next[i],biasWeight,map); } } }
void ConnectKernel(Link[] kernel,Node node,Weight[] weights, Bias bias,Dictionary<Link,int> ccd) { int l=kernel.Length; if(bias!=null) l++; node.Previous=new Connection[l]; for(var i=0;i<kernel.Length;i++) { kernel[i].Next=kernel[i].Next??new Connection[ccd[kernel[i]]]; Connect(kernel[i],node,weights[i]); } if(bias!=null) Connect(bias,node,weights[kernel.Length]); }
void CheckConnection(Link pre, NeuronBase post,ref int i) { var bridge= from a in pre.Next join b in post.Previous on a equals b select a; Assert.AreEqual(bridge.Count(),1); Connection inp=bridge.First(); Assert.AreEqual(inp.Previous,pre); Assert.AreEqual(inp.Next,post); i++; if(post.Next!=null){ foreach(var n in post.Next) { var pp=n.Next; CheckConnection(post,pp,ref i); } } }
public override void Connect(Link[] prior,NeuronBase[] next,Bias bias) { Utility.Verify(prior,x => x!=null && prior.Length>0,"Invalid prior layer"); Utility.Verify(next,x => x!=null && next.Length>0,"Invalid next layer"); foreach(NeuronBase neuron in next) neuron.Previous=GetNeuronConnections(prior,neuron,bias).ToArray(); int idx=0; foreach(Link link in prior) link.Next=GetLinkConnections(idx++,next).ToArray(); if(bias!=null){ var biasConnections=GetBiasConnections(bias,next); if(bias.Next==null) bias.Next=new Connection[] { }; bias.Next=bias.Next.Concat(biasConnections).ToArray(); } }
protected NetworkStructure GetLayers(int[] layers,Bias bias,IContinuousActivator func) { var l=layers.Length; Link[][] structure=new Link[l][]; FullLayerConnector connector=new FullLayerConnector(); for(var i=0;i<l-1;i++) { if(i==0) structure[i]=Utility.Generate<Link>(layers[i]).ToArray(); int j=i+1; structure[j]= Utility.Generate<Neuron>(layers[j]).ToArray(); connector.Connect(structure[i],(NeuronBase[])structure[j],bias); } SetIdentity(structure); foreach(Link[] layer in structure) foreach(Link link in layer) if(link is NeuronBase) ((NeuronBase)link).Func=func; return new NetworkStructure(structure,bias); }
public override void Connect(Link[] prior,NeuronBase[] next,Bias bias) { Utility.Verify(prior,x => x!=null && prior.Length>0,"Invalid prior layer"); Utility.Verify(next,x => x!=null && next.Length>0,"Invalid next layer"); Utility.Verify(() => next.Length % NextFeatureMapsCount==0,"NextFeatureMapsCount - next layer size conflict"); Utility.Verify(() => prior.Length % PriorFeatureMapsCount==0,"PriorFeatureMapsCount - prior layer size conflict"); Link[][] fmp=GetFeatureMaps(prior,PriorFeatureMapsCount); Link[][] fmn=GetFeatureMaps(next,NextFeatureMapsCount); Link[][][] kernelCollection=GetKernelCollection(fmp,KernelSize,Overlap); Dictionary<Link,List<Connection>> map=new Dictionary<Link,List<Connection>>(); for(int f=0;f<fmn.Length;f++) { Neuron[] nextFeatureMap=fmn[f].Select(x => (Neuron)x).ToArray(); for(int p=0;p<fmp.Length;p++) { bool inSchema=Schema[p][f]; if(inSchema) ConnectFeatureMaps(nextFeatureMap,kernelCollection[p],map); } if(bias!=null) { Weight weight=new SharedWeight(nextFeatureMap.Length); foreach(Neuron node in nextFeatureMap) Map(bias,node,weight,map); } } foreach(Link link in prior) link.Next= map[link].ToArray(); foreach(Neuron node in next) node.Previous=map[node].ToArray(); if(bias!=null){ if(bias.Next==null) bias.Next=new Connection[] { }; bias.Next=bias.Next.Concat(map[bias]).ToArray(); } }
int GetWeightsCount(Link[] network,bool next,bool previous) { HashSet<Connection> hs= GetConnections(network,next,previous); HashSet<Weight> whs=new HashSet<Weight>(); foreach(Connection c in hs) whs.Add(c.Weight); return whs.Count; }
int GetConnectionsCount(Link[] network,bool next,bool previous) { return GetConnections(network,next,previous).Count; }
HashSet<Connection> GetConnections(Link[] network,bool next,bool previous) { HashSet<Connection> hs=new HashSet<Connection>(); foreach(Link link in network) { if(next&&link.Next!=null) foreach(Connection c in link.Next) hs.Add(c); if(previous&& link is NeuronBase) { NeuronBase nb=(NeuronBase)link; foreach(Connection c in nb.Previous) hs.Add(c); } } return hs; }
Link[] GetKernel(Link[] layer,int offsetX,int offsetY) { Utility.Verify(() => offsetX+KernelSize<layer.Length && offsetY+KernelSize<layer.Length,"Invalid receptive field"); int size=(int)Math.Sqrt(layer.Length); List<Link> kernel=new List<Link>(KernelSize*KernelSize); for(int y=offsetY;y<offsetY+KernelSize;y++) { for(int x=offsetX;x<offsetX+KernelSize;x++) { Link link=layer[y*size + x]; kernel.Add(link); } } return kernel.ToArray(); }
Link[][] GetKernelSet(Link[] layer) { int size=(int)Math.Sqrt(layer.Length); int step=KernelSize-Overlap; List<Link[]> kernelSet=new List<Link[]>(); for(int y=0;y+KernelSize<=size;y+=step) { for(int x=0;x+KernelSize<=size;x+=step) { Link[] kernel=GetKernel(layer,x,y); kernelSet.Add(kernel); } } return kernelSet.ToArray(); }
public Connection(Link previous,NeuronBase next) : this(new Weight(),previous,next) { }
int GetConnectionsCount(Link link, int fmc,Link[][] kernelSet) { int toret=0; foreach(Link[] kernel in kernelSet) foreach(Link l in kernel) if(l==link) toret++; return toret*fmc; }
public abstract void Connect(Link[] prior,NeuronBase[] next, Bias bias);
void ConnectKernel(NeuronBase neuron,Link[] kernel,SharedWeight weight,Dictionary<Link,List<Connection>> map) { foreach(Link link in kernel) { Map(link,neuron,weight,map); } }