/// <summary> /// Задать значение дельт нейронам предыдущего слоя от слоя макс-пуллинга. /// </summary> /// <param name="sumbsamplinLayer">Слой макс-пуллинга.</param> public void SetDeltaToConvolutionLayer(SubsamplingLayer sumbsamplinLayer) { var map = sumbsamplinLayer.Map; var size = sumbsamplinLayer.PoolingMatrix.Size; var index = 0; for (var x = 0; x <= map.Size - size; x += size) { for (var y = 0; y <= map.Size - size; y += size) { var xEndPoint = x + size; var yEndPoint = y + size; var cells = map.Cells. FindAll(cellInMap => cellInMap.X >= x && cellInMap.X < xEndPoint && cellInMap.Y >= y && cellInMap.Y < yEndPoint); var trueValueCell = cells.First(); foreach (var someCell in cells) { if (someCell.Value > trueValueCell.Value) { trueValueCell = someCell; } } trueValueCell.Delta = MathUtil.DerivativeActivationFunction(trueValueCell.Value, Enums.ActivationFunctionType.Sigmoid) * _cells[index].Delta; foreach (var falseValueCell in cells) { if (falseValueCell.X.Equals(trueValueCell.X) && falseValueCell.Y.Equals(trueValueCell.Y)) { continue; } falseValueCell.Delta = 0; } ++index; } } }
public static ConvolutionalNeuralNetwork Parse(string filename) { var jobject = JObject.Parse(File.ReadAllText(filename)); var jsonLayers = jobject.GetValue("layers"); var network = new ConvolutionalNeuralNetwork(); var netLayers = new List <CNNLayer>(); foreach (var jsonLayer in jsonLayers.ToArray()) { var type = jsonLayer["layer_type"].ToObject <string>(); CNNLayer layer; switch (type) { case "input": layer = new InputLayer(); break; case "conv": layer = new ConvolutionalLayer { FilterSize = jsonLayer["sx"].ToObject <int>(), Stride = jsonLayer["stride"].ToObject <int>(), L1Decay = jsonLayer["l1_decay_mul"].ToObject <double>(), L2Decay = jsonLayer["l2_decay_mul"].ToObject <double>(), Pad = jsonLayer["pad"].ToObject <int>(), Biases = Volume.ParseJSON(jsonLayer["biases"]), Kernels = Volume.ArrayParseJSON(jsonLayer["filters"]) }; break; case "relu": layer = new ReLuLayer(); break; case "pool": layer = new SubsamplingLayer { FilterSize = jsonLayer["sx"].ToObject <int>(), Stride = jsonLayer["stride"].ToObject <int>(), Pad = jsonLayer["pad"].ToObject <int>(), }; break; case "fc": layer = new FullyConnectedLayer { L1Decay = jsonLayer["l1_decay_mul"].ToObject <double>(), L2Decay = jsonLayer["l2_decay_mul"].ToObject <double>(), NeuronsCount = jsonLayer["out_depth"].ToObject <int>(), Biases = Volume.ParseJSON(jsonLayer["biases"]), Weights = Volume.ArrayParseJSON(jsonLayer["filters"]) }; break; case "softmax": layer = new SoftmaxLayer(); break; default: throw new ArgumentException("Unknown layer type"); } if (netLayers.Count != 0) { layer.InSize = netLayers.Last().OutSize; layer.InDepth = netLayers.Last().OutDepth; } layer.OutDepth = jsonLayer["out_depth"].ToObject <int>(); layer.OutSize = new Size( jsonLayer["out_sx"].ToObject <int>(), jsonLayer["out_sy"].ToObject <int>()); if (type == "fc") { (layer as FullyConnectedLayer)._inputsCount = layer.InSize.Width * layer.InSize.Height * layer.InDepth; } else if (type == "pool") { (layer as SubsamplingLayer)._oldX = new int[layer.OutSize.Width * layer.OutSize.Height * layer.OutDepth]; (layer as SubsamplingLayer)._oldY = new int[layer.OutSize.Width * layer.OutSize.Height * layer.OutDepth]; } else if (type == "softmax") { (layer as SoftmaxLayer)._es = new double[layer.OutDepth]; } layer.OutVolume = new Volume(layer.OutSize.Width, layer.OutSize.Height, layer.OutDepth, 0); netLayers.Add(layer); } network.Layers = netLayers; network.InputLayer = (InputLayer)netLayers.First(); return(network); }
/// <summary> /// Инициализация реальной схемы. /// </summary> /// <param name="filterMatrixSize">Размер матриц фильтра.</param> /// <param name="poolingMatrixSize">Размер пуллинговых матриц.</param> private Dictionary <int, List <Layer> > InitializeRealScheme(int filterMatrixSize, int poolingMatrixSize) { var realScheme = new Dictionary <int, List <Layer> >(); var virtualScheme = _topology.GetScheme(); var firstValue = _dataSet.GetDataSetForNumber().First().Value.First(); foreach (var pair in virtualScheme) { var virtualElements = pair.Value; var realElements = new List <Layer>(); var index = 0; foreach (var layerType in virtualElements) { Layer element = null; switch (layerType) { case LayerType.Input: element = new InputLayer(firstValue); element.Initialize(NetworkModeType.Learning); break; case LayerType.Convolution: var previousKey = pair.Key - 1; var previousElements = realScheme[previousKey]; var previousType = virtualScheme[previousKey].First(); if (previousElements.Count != virtualElements.Count && previousType.Equals(LayerType.Input)) { var previousElement = previousElements.FirstOrDefault() as InputLayer; if (previousElement is null) { throw new Exception("Предыдущий слой оказался Null!"); } var map = previousElement.GetData(LayerReturnType.Map); element = new ConvolutionLayer(map, filterMatrixSize); element.Initialize(NetworkModeType.Learning); } else { throw new NotImplementedException(); } break; case LayerType.Subsampling: previousKey = pair.Key - 1; previousElements = realScheme[previousKey]; previousType = virtualScheme[previousKey][index]; if (previousElements.Count == virtualElements.Count && previousType.Equals(LayerType.Convolution)) { var previousElement = previousElements[index] as ConvolutionLayer; if (previousElement is null) { throw new Exception("Предыдущий слой оказался Null!"); } var map = previousElement.GetData(LayerReturnType.Map); element = new SubsamplingLayer(map, poolingMatrixSize); element.Initialize(NetworkModeType.Learning); } else { throw new NotImplementedException(); } break; case LayerType.Hidden: previousKey = pair.Key - 1; previousElements = realScheme[previousKey]; previousType = virtualScheme[previousKey][index]; if (previousElements.Count == virtualElements.Count && previousType.Equals(LayerType.Subsampling)) { var previousElement = previousElements[index] as SubsamplingLayer; if (previousElement is null) { throw new Exception("Предыдущий слой оказался Null!"); } var neurons = previousElement.GetData(LayerReturnType.Neurons) as List <NeuronFromMap>; element = new HiddenLayer(neurons); element.Initialize(NetworkModeType.Learning); } else { throw new NotImplementedException(); } break; case LayerType.Output: previousKey = pair.Key - 1; previousElements = realScheme[previousKey]; previousType = virtualScheme[previousKey][index]; if (previousElements.Count > virtualElements.Count && previousType.Equals(LayerType.Hidden)) { var neurons = new List <Neuron>(); foreach (var elementInLastLayer in previousElements) { var previousElement = elementInLastLayer as HiddenLayer; if (previousElement is null) { throw new Exception("Предыдущий слой оказался Null!"); } var data = previousElement.GetData(LayerReturnType.Neurons) as List <NeuronFromMap>; neurons.AddRange(data); } var outputs = neurons.Select(neuron => neuron.Output).ToList(); element = new OutputLayer(outputs); element.Initialize(NetworkModeType.Learning); } else { throw new NotImplementedException(); } break; default: throw new Exception("Неизвестный тип слоя!"); } realElements.Add(element); ++index; } realScheme.Add(pair.Key, realElements); } return(realScheme); }
/// <summary> /// Загрузить файл настроек и инициализировать сеть. /// </summary> /// <param name="path">Путь к файлу настроек.</param> /// <param name="inputData">Входные данные.</param> /// <returns>Возвращает сеть с данными.</returns> public static Dictionary <int, List <Layer> > LoadAndInitialize(string path, double[,] inputData) { var document = XDocument.Load(path); var realTopology = new Dictionary <int, List <Layer> >(); var baseElement = document.Elements().ToList() .Find(element => string.Equals( element.Name.LocalName, IOConstants.NETWORK_BASE_ELEMENT_NAME, StringComparison.InvariantCultureIgnoreCase)); var inputDataSize = baseElement.Elements().ToList() .Find(element => string.Equals( element.Name.LocalName, IOConstants.INPUT_DATA_SIZE_ELEMENT_NAME, StringComparison.InvariantCultureIgnoreCase)).Value; var size = int.Parse(inputDataSize); var xSize = inputData.GetLength(0); var ySize = inputData.GetLength(1); if (!xSize.Equals(size) || !ySize.Equals(size)) { throw new Exception($"Размер входных данных не соотвествует ожидаемому размеру {size}!"); } var inputLayer = new InputLayer(inputData); inputLayer.Initialize(Enums.NetworkModeType.Recognizing); var currentNumber = Topology.FIRST_NUMBER; realTopology.Add(currentNumber, new List <Layer> { inputLayer }); var layers = baseElement.Elements().ToList() .FindAll(element => string.Equals( element.Name.LocalName, IOConstants.LAYERS_ELEMENT_NAME, StringComparison.InvariantCultureIgnoreCase)); var layersCount = layers.Count; var layersCountWithoutOutput = layersCount - 1; var previousKey = realTopology.First().Key; foreach (var layer in layers) { var layerElements = layer.Elements().ToList(); var name = layerElements.First().Name.LocalName; if (string.Equals(name, IOConstants.CONVOLUTION_LAYER_ELEMENT_NAME, StringComparison.InvariantCultureIgnoreCase)) { var previousElementsCount = realTopology[previousKey].Count; dynamic inputToLayer; if (!previousElementsCount.Equals(1)) { throw new NotImplementedException(); } inputToLayer = realTopology[previousKey].First() .GetData(Enums.LayerReturnType.Map) as FigureMap; var layersInTopology = new List <Layer>(); foreach (var element in layerElements) { var filterMatrixElement = element .Elements().ToList().First(); var filterMatrixSize = int.Parse(filterMatrixElement .Attribute(IOConstants.SIZE_ATTRIBUTE_NAME) .Value); var cells = new List <ModifiedCell>(); foreach (var cellElement in filterMatrixElement.Elements()) { var x = int.Parse(cellElement.Attribute(IOConstants.X_ATTRIBUTE_NAME).Value); var y = int.Parse(cellElement.Attribute(IOConstants.Y_ATTRIBUTE_NAME).Value); var value = double.Parse(cellElement.Value.Replace(".", ",")); cells.Add(new ModifiedCell(x, y, value)); } var filterMatrix = new FilterMatrix(filterMatrixSize, Enums.NetworkModeType.Recognizing, cells); var convolutionLayer = new ConvolutionLayer(inputToLayer, filterMatrix, Enums.NetworkModeType.Recognizing); layersInTopology.Add(convolutionLayer); } realTopology.Add(previousKey + 1, layersInTopology); ++previousKey; } if (string.Equals(name, IOConstants.SUBSAMPLING_LAYER_ELEMENT_NAME, StringComparison.InvariantCultureIgnoreCase)) { var previousElements = realTopology[previousKey]; var layersInTopology = new List <Layer>(); var indexOfElementInPreviousPart = 0; foreach (var element in layerElements) { var inputDataInLayer = previousElements[indexOfElementInPreviousPart] .GetData(Enums.LayerReturnType.Map) as FigureMap; var poolingMatrixSize = int.Parse(element.Elements() .ToList().First().Attribute(IOConstants.SIZE_ATTRIBUTE_NAME).Value); var subsamplingLayer = new SubsamplingLayer(inputDataInLayer, poolingMatrixSize); subsamplingLayer.Initialize(Enums.NetworkModeType.Recognizing); layersInTopology.Add(subsamplingLayer); ++indexOfElementInPreviousPart; } realTopology.Add(previousKey + 1, layersInTopology); ++previousKey; } if (string.Equals(name, IOConstants.HIDDEN_LAYER_ELEMENT_NAME, StringComparison.InvariantCultureIgnoreCase)) { var previousElements = realTopology[previousKey]; var layersInTopology = new List <Layer>(); var indexOfElementInPreviousPart = 0; foreach (var element in layerElements) { var temporaryNeurons = previousElements[indexOfElementInPreviousPart] .GetData(Enums.LayerReturnType.Neurons) as List <NeuronFromMap>; var realNeurons = new List <NeuronFromMap>(); var index = 0; foreach (var neuronElement in element.Elements().First().Elements()) { var weights = new List <double>(); foreach (var weightElement in neuronElement.Elements()) { weights.Add(double.Parse(weightElement.Value.Replace(".", ","))); } var inputs = temporaryNeurons[index].Inputs; var neuron = new NeuronFromMap(inputs, weights); realNeurons.Add(neuron); ++index; } var hiddenLayer = new HiddenLayer(realNeurons); layersInTopology.Add(hiddenLayer); ++indexOfElementInPreviousPart; } realTopology.Add(previousKey + 1, layersInTopology); ++previousKey; } } var inputValues = new List <double>(); foreach (HiddenLayer hiddenLayer in realTopology.Last().Value) { inputValues.AddRange((hiddenLayer.GetData(Enums.LayerReturnType.Neurons) as List <NeuronFromMap>).Select(neuron => neuron.Output)); } var neurons = new List <Neuron>(); var neuronsElement = layers.Last().Elements().First().Elements().First().Elements(); foreach (var outputNeuron in neuronsElement) { var weights = outputNeuron.Elements() .Select(weight => double.Parse(weight.Value.Replace(".", ","))).ToList(); neurons.Add(new Neuron(inputValues, weights)); } var outputLayer = new OutputLayer(neurons, Enums.NetworkModeType.Recognizing, Enums.OutputLayerType.NumberRecognizing); outputLayer.Initialize(Enums.NetworkModeType.Recognizing); var lastKey = realTopology.Last().Key; realTopology.Add(lastKey + 1, new List <Layer> { outputLayer }); return(realTopology); }