Beispiel #1
0
        /// <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;
                }
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <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);
        }