/// <summary>Gets base conditionals.</summary> /// <param name="x">The Matrix to process.</param> /// <returns>An array of measure.</returns> private Measure[] GetBaseConditionals(Matrix x) { Measure[] features = new Measure[x.Cols]; for (int i = 0; i < features.Length; i++) { Property p = Descriptor.At(i); var f = new Measure { Discrete = p.Discrete, Label = Descriptor.ColumnAt(i), }; IEnumerable <Statistic> fstats; if (f.Discrete) { fstats = x[i, VectorType.Col].Distinct().OrderBy(d => d) .Select(d => Statistic.Make(p.Convert(d).ToString(), d, 1)); } else { fstats = x[i, VectorType.Col].Segment(Width) .Select(d => Statistic.Make(f.Label, d, 1)); } f.Probabilities = fstats.ToArray(); features[i] = f; } return(features); }
/// <summary> /// Creates a new deep neural network based on the supplied inputs and layers. /// </summary> /// <param name="d">Descriptor object.</param> /// <param name="X">Training examples</param> /// <param name="y">Training labels</param> /// <param name="activationFunction">Activation Function for each output layer.</param> /// <param name="outputFunction">Ouput Function for each output layer.</param> /// <param name="hiddenLayers">The intermediary (hidden) layers / ensembles in the network.</param> /// <returns>A Deep Neural Network</returns> public static Network Create(this Network network, Descriptor d, Matrix X, Vector y, IFunction activationFunction, IFunction outputFunction = null, params NetworkLayer[] hiddenLayers) { // set output to number of choices of available // 1 if only two choices int distinct = y.Distinct().Count(); int output = distinct > 2 ? distinct : 1; // identity function for bias nodes IFunction ident = new Ident(); // creating input nodes network.In = new Neuron[X.Cols + 1]; network.In[0] = new Neuron { Label = "B0", ActivationFunction = ident }; for (int i = 1; i < X.Cols + 1; i++) { network.In[i] = new Neuron { Label = d.ColumnAt(i - 1), ActivationFunction = ident } } ; // creating output nodes network.Out = new Neuron[output]; for (int i = 0; i < output; i++) { network.Out[i] = new Neuron { Label = Network.GetLabel(i, d), ActivationFunction = activationFunction, OutputFunction = outputFunction } } ; for (int layer = 0; layer < hiddenLayers.Count(); layer++) { if (layer == 0 && hiddenLayers[layer].IsAutoencoder) { // init and train it. } // connect input with previous layer or input layer // connect last layer with output layer } // link input to hidden. Note: there are // no inputs to the hidden bias node //for (int i = 1; i < h.Length; i++) // for (int j = 0; j < nn.In.Length; j++) // Edge.Create(nn.In[j], h[i]); //// link from hidden to output (full) //for (int i = 0; i < nn.Out.Length; i++) // for (int j = 0; j < h.Length; j++) // Edge.Create(h[j], nn.Out[i]); return(network); }
/// <summary>Defaults.</summary> /// <param name="network">The network.</param> /// <param name="d">The Descriptor to process.</param> /// <param name="x">The Vector to process.</param> /// <param name="y">The Vector to process.</param> /// <param name="activationFunction">The activation.</param> /// <param name="outputFunction">The ouput function for hidden nodes (Optional).</param> /// <param name="epsilon">epsilon</param> /// <returns>A Network.</returns> public static Network Create( this Network network, Descriptor d, Matrix x, Vector y, IFunction activationFunction, IFunction outputFunction = null, double epsilon = double.NaN) { // set output to number of choices of available // 1 if only two choices var distinct = y.Distinct().Count(); var output = distinct > 2 ? distinct : 1; // identity funciton for bias nodes IFunction ident = new Ident(); // set number of hidden units to (Input + Hidden) * 2/3 as basic best guess. var hidden = (int)System.Math.Ceiling((x.Cols + output) * 2.0 / 3.0); return(network.Create( x.Cols, output, activationFunction, outputFunction, fnNodeInitializer: (l, i) => { if (l == 0) { return new Neuron(false) { Label = d.ColumnAt(i - 1), ActivationFunction = activationFunction, NodeId = i, LayerId = l } } ; if (l == 2) { return new Neuron(false) { Label = Network.GetLabel(i, d), ActivationFunction = activationFunction, NodeId = i, LayerId = l } } ; return new Neuron(false) { ActivationFunction = activationFunction, NodeId = i, LayerId = l }; }, hiddenLayers: hidden)); }
/// <summary>Defaults.</summary> /// <param name="d">The Descriptor to process.</param> /// <param name="x">The Vector to process.</param> /// <param name="y">The Vector to process.</param> /// <param name="activation">The activation.</param> /// <returns>A Network.</returns> public static Network Default(Descriptor d, Matrix x, Vector y, IFunction activation) { Network nn = new Network(); // set output to number of choices of available // 1 if only two choices int distinct = y.Distinct().Count(); int output = distinct > 2 ? distinct : 1; // identity funciton for bias nodes IFunction ident = new Ident(); // set number of hidden units to (Input + Hidden) * 2/3 as basic best guess. int hidden = (int)System.Math.Ceiling((decimal)(x.Cols + output) * 2m / 3m); // creating input nodes nn.In = new Node[x.Cols + 1]; nn.In[0] = new Node { Label = "B0", Activation = ident }; for (int i = 1; i < x.Cols + 1; i++) nn.In[i] = new Node { Label = d.ColumnAt(i - 1), Activation = ident }; // creating hidden nodes Node[] h = new Node[hidden + 1]; h[0] = new Node { Label = "B1", Activation = ident }; for (int i = 1; i < hidden + 1; i++) h[i] = new Node { Label = String.Format("H{0}", i), Activation = activation }; // creating output nodes nn.Out = new Node[output]; for (int i = 0; i < output; i++) nn.Out[i] = new Node { Label = GetLabel(i, d), Activation = activation }; // link input to hidden. Note: there are // no inputs to the hidden bias node for (int i = 1; i < h.Length; i++) for (int j = 0; j < nn.In.Length; j++) Edge.Create(nn.In[j], h[i]); // link from hidden to output (full) for (int i = 0; i < nn.Out.Length; i++) for (int j = 0; j < h.Length; j++) Edge.Create(h[j], nn.Out[i]); return nn; }
/// <summary>Defaults.</summary> /// <param name="d">The Descriptor to process.</param> /// <param name="x">The Vector to process.</param> /// <param name="y">The Vector to process.</param> /// <param name="activationFunction">The activation.</param> /// <param name="outputFunction">The ouput function for hidden nodes (Optional).</param> /// <param name="epsilon">epsilon</param> /// <returns>A Network.</returns> public static Network Create(this Network network, Descriptor d, Matrix x, Vector y, IFunction activationFunction, IFunction outputFunction = null, double epsilon = double.NaN, ILossFunction lossFunction = null) { // set output to number of choices of available // 1 if only two choices int distinct = y.Distinct().Count(); int output = distinct > 2 ? distinct : 1; // identity funciton for bias nodes IFunction ident = new Ident(); // set number of hidden units to (Input + Hidden) * 2/3 as basic best guess. int hidden = (int)System.Math.Ceiling((double)(x.Cols + output) * 2.0 / 3.0); return(network.Create(x.Cols, output, activationFunction, outputFunction, fnNodeInitializer: new Func <int, int, NodeType, Neuron>((l, i, type) => { if (type == NodeType.Input) { return new Neuron(false) { Label = d.ColumnAt(i - 1), ActivationFunction = activationFunction, NodeId = i, LayerId = l } } ; else if (type == NodeType.Output) { return new Neuron(false) { Label = Network.GetLabel(i, d), ActivationFunction = activationFunction, NodeId = i, LayerId = l } } ; else { return new Neuron(false) { ActivationFunction = activationFunction, NodeId = i, LayerId = l } }; }), lossFunction: lossFunction, hiddenLayers: hidden)); }
/// <summary>Defaults.</summary> /// <param name="d">The Descriptor to process.</param> /// <param name="x">The Vector to process.</param> /// <param name="y">The Vector to process.</param> /// <param name="activationFunction">The activation.</param> /// <param name="outputFunction">The ouput function for hidden nodes (Optional).</param> /// <param name="epsilon">epsilon</param> /// <returns>A Network.</returns> public static Network Create(this Network network, Descriptor d, Matrix x, Vector y, IFunction activationFunction, IFunction outputFunction = null, double epsilon = double.NaN) { // set output to number of choices of available // 1 if only two choices int distinct = y.Distinct().Count(); int output = distinct > 2 ? distinct : 1; // identity funciton for bias nodes IFunction ident = new Ident(); // set number of hidden units to (Input + Hidden) * 2/3 as basic best guess. int hidden = (int)System.Math.Ceiling((double)(x.Cols + output) * 2.0 / 3.0); return network.Create(x.Cols, output, activationFunction, outputFunction, fnNodeInitializer: new Func<int, int, Neuron>((l, i) => { if (l == 0) return new Neuron(false) { Label = d.ColumnAt(i - 1), ActivationFunction = activationFunction, NodeId = i, LayerId = l }; else if (l == 2) return new Neuron(false) { Label = Network.GetLabel(i, d), ActivationFunction = activationFunction, NodeId = i, LayerId = l }; else return new Neuron(false) { ActivationFunction = activationFunction, NodeId = i, LayerId = l }; }), hiddenLayers: hidden); }
/// <summary> /// Creates a new deep neural network based on the supplied inputs and layers. /// </summary> /// <param name="d">Descriptor object.</param> /// <param name="X">Training examples</param> /// <param name="y">Training labels</param> /// <param name="activationFunction">Activation Function for each output layer.</param> /// <param name="outputFunction">Ouput Function for each output layer.</param> /// <param name="hiddenLayers">The intermediary (hidden) layers / ensembles in the network.</param> /// <returns>A Deep Neural Network</returns> public static Network Create(this Network network, Descriptor d, Matrix X, Vector y, IFunction activationFunction, IFunction outputFunction = null, params NetworkLayer[] hiddenLayers) { // set output to number of choices of available // 1 if only two choices int distinct = y.Distinct().Count(); int output = distinct > 2 ? distinct : 1; // identity function for bias nodes IFunction ident = new Ident(); // creating input nodes network.In = new Neuron[X.Cols + 1]; network.In[0] = new Neuron { Label = "B0", ActivationFunction = ident }; for (int i = 1; i < X.Cols + 1; i++) network.In[i] = new Neuron { Label = d.ColumnAt(i - 1), ActivationFunction = ident }; // creating output nodes network.Out = new Neuron[output]; for (int i = 0; i < output; i++) network.Out[i] = new Neuron { Label = Network.GetLabel(i, d), ActivationFunction = activationFunction, OutputFunction = outputFunction }; for (int layer = 0; layer < hiddenLayers.Count(); layer++) { if (layer == 0 && hiddenLayers[layer].IsAutoencoder) { // init and train it. } // connect input with previous layer or input layer // connect last layer with output layer } // link input to hidden. Note: there are // no inputs to the hidden bias node //for (int i = 1; i < h.Length; i++) // for (int j = 0; j < nn.In.Length; j++) // Edge.Create(nn.In[j], h[i]); //// link from hidden to output (full) //for (int i = 0; i < nn.Out.Length; i++) // for (int j = 0; j < h.Length; j++) // Edge.Create(h[j], nn.Out[i]); return network; }
/// <summary>Builds a tree.</summary> /// <param name="x">The Matrix to process.</param> /// <param name="y">The Vector to process.</param> /// <param name="depth">The depth.</param> /// <param name="used">The used.</param> /// <returns>A Node.</returns> private Node BuildTree(Matrix x, Vector y, int depth, List <int> used, Tree tree) { if (depth < 0) { return(BuildLeafNode(y.Mode())); } var tuple = GetBestSplit(x, y, used); var col = tuple.Item1; var gain = tuple.Item2; var measure = tuple.Item3; // uh oh, need to return something? // a weird node of some sort... // but just in case... if (col == -1) { return(BuildLeafNode(y.Mode())); } used.Add(col); Node node = new Node { Column = col, Gain = gain, IsLeaf = false, Name = Descriptor.ColumnAt(col) }; // populate edges List <Edge> edges = new List <Edge>(measure.Segments.Length); for (int i = 0; i < measure.Segments.Length; i++) { // working set var segment = measure.Segments[i]; var edge = new Edge() { ParentId = node.Id, Discrete = measure.Discrete, Min = segment.Min, Max = segment.Max }; IEnumerable <int> slice; if (edge.Discrete) { // get discrete label edge.Label = Descriptor.At(col).Convert(segment.Min).ToString(); // do value check for matrix slicing slice = x.Indices(v => v[col] == segment.Min); } else { // get range label edge.Label = string.Format("{0} <= x < {1}", segment.Min, segment.Max); // do range check for matrix slicing slice = x.Indices(v => v[col] >= segment.Min && v[col] < segment.Max); } // something to look at? // if this number is 0 then this edge // leads to a dead end - the edge will // not be built if (slice.Count() > 0) { Vector ySlice = y.Slice(slice); // only one answer, set leaf if (ySlice.Distinct().Count() == 1) { var child = BuildLeafNode(ySlice[0]); tree.AddVertex(child); edge.ChildId = child.Id; } // otherwise continue to build tree else { var child = BuildTree(x.Slice(slice), ySlice, depth - 1, used, tree); tree.AddVertex(child); edge.ChildId = child.Id; } edges.Add(edge); } } // problem, need to convert // parent to terminal node // with mode if (edges.Count <= 1) { var val = y.Mode(); node.IsLeaf = true; node.Value = val; } tree.AddVertex(node); if (edges.Count > 1) { foreach (var e in edges) { tree.AddEdge(e); } } return(node); }
/// <summary>Defaults.</summary> /// <param name="d">The Descriptor to process.</param> /// <param name="x">The Vector to process.</param> /// <param name="y">The Vector to process.</param> /// <param name="activation">The activation.</param> /// <returns>A Network.</returns> public static Network Default(Descriptor d, Matrix x, Vector y, IFunction activation) { var nn = new Network(); // set output to number of choices of available // 1 if only two choices var distinct = y.Distinct().Count(); var output = distinct > 2 ? distinct : 1; // identity funciton for bias nodes IFunction ident = new Ident(); // set number of hidden units to (Input + Hidden) * 2/3 as basic best guess. var hidden = (int)Math.Ceiling((decimal)(x.Cols + output) * 2m / 3m); // creating input nodes nn.In = new Node[x.Cols + 1]; nn.In[0] = new Node { Label = "B0", Activation = ident }; for (var i = 1; i < x.Cols + 1; i++) { nn.In[i] = new Node { Label = d.ColumnAt(i - 1), Activation = ident }; } // creating hidden nodes var h = new Node[hidden + 1]; h[0] = new Node { Label = "B1", Activation = ident }; for (var i = 1; i < hidden + 1; i++) { h[i] = new Node { Label = string.Format("H{0}", i), Activation = activation }; } // creating output nodes nn.Out = new Node[output]; for (var i = 0; i < output; i++) { nn.Out[i] = new Node { Label = GetLabel(i, d), Activation = activation }; } // link input to hidden. Note: there are // no inputs to the hidden bias node for (var i = 1; i < h.Length; i++) { for (var j = 0; j < nn.In.Length; j++) { Edge.Create(nn.In[j], h[i]); } } // link from hidden to output (full) for (var i = 0; i < nn.Out.Length; i++) { for (var j = 0; j < h.Length; j++) { Edge.Create(h[j], nn.Out[i]); } } return(nn); }