/// <summary> /// Creates a deep copy of this network. /// </summary> /// <returns>A new instance of <see cref="NeuralNetwork"/> which has the same layers as this network.</returns> public NeuralNetwork Clone() { DenseLayer[] clonnedLayers = new DenseLayer[layers.Length]; for (int k = 0; k < layers.Length; k++) { clonnedLayers[k] = layers[k].Clone(); } return(new NeuralNetwork(clonnedLayers)); }
/// <summary> /// Constructs a new instance of <see cref="NeuralNetwork"/> using topology and weights specified in /// the <paramref name="networkInString"/> argument. /// </summary> /// <remarks> /// The given string must have 2 lines, the first containing layers' sizes /// separated by ',' sign, and the second containing weights also separated by ','. /// </remarks> /// <param name="networkInString">An instance of string containing the topology and weights of the network. /// </param> /// <returns>The new constructed neural network.</returns> /// <exception cref="ArgumentException"> /// Thrown if input parameter <paramref name="networkInString"/> contains invalid network representation. /// </exception> public static NeuralNetwork ConstructFromString(string networkInString) { string[] lines = networkInString.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); if (lines.Length < 2) { throw new ArgumentException(string.Format("Invalid input parameter {0}. The string must contain 2 lines.", "networkInString")); } string[] sizes = lines[0].Split(','); if (sizes.Length < 4) { throw new ArgumentException(string.Format("Invalid input parameter {0}. The string must contain sizes for at least 2 layers.", "networkInString")); } string[] weightsInString = lines[1].Split(','); DenseLayer[] denseLayers = new DenseLayer[sizes.Length / 2]; int k = 0; for (int c = 0; c < sizes.Length; c += 2) { int selfNeuronsCount; if (!int.TryParse(sizes[c], out selfNeuronsCount) || selfNeuronsCount < 1) { throw new ArgumentException(string.Format("Invalid input parameter {0}. The neural layer must contain at least 1 neuron.", "networkInString")); } int outputNeuronsCount; if (!int.TryParse(sizes[c + 1], out outputNeuronsCount) || outputNeuronsCount < 1) { throw new ArgumentException(string.Format("Invalid input parameter {0}. Output vector of neural layer must contain at least 1 neuron.", "networkInString")); } double[,] weights = new double[selfNeuronsCount + 1, outputNeuronsCount]; for (int i = 0; i <= selfNeuronsCount; i++) { for (int j = 0; j < outputNeuronsCount; j++) { double weight; if (k >= weightsInString.Length || !double.TryParse(weightsInString[k++], out weight)) { throw new ArgumentException(string.Format("Invalid input parameter {0}. Weights count must match to typology.", "networkInString")); } weights[i, j] = weight; } } denseLayers[c / 2] = new DenseLayer(weights, LayerActivationFunctions.Sigmoid); } return(new NeuralNetwork(denseLayers)); }