public static int[,] GetFilterMatrix(FilterMatrix type) { int[,] H = new int[3, 3]; switch (type) { case FilterMatrix.H_9: H[0, 0] = 1; H[0, 1] = 1; H[0, 2] = 1; H[1, 0] = 1; H[1, 1] = 1; H[1, 2] = 1; H[2, 0] = 1; H[2, 1] = 1; H[2, 2] = 1; break; case FilterMatrix.H_10: H[0, 0] = 1; H[0, 1] = 1; H[0, 2] = 1; H[1, 0] = 1; H[1, 1] = 2; H[1, 2] = 1; H[2, 0] = 1; H[2, 1] = 1; H[2, 2] = 1; break; case FilterMatrix.H_16: H[0, 0] = 1; H[0, 1] = 2; H[0, 2] = 1; H[1, 0] = 2; H[1, 1] = 4; H[1, 2] = 2; H[2, 0] = 1; H[2, 1] = 2; H[2, 2] = 1; break; default: break; } return(H); }
/// <summary> /// Свёрточный слой. /// </summary> /// <param name="map">Карта значений.</param> /// <param name="filterMatrix">Матрица фильтра.</param> /// <param name="modeType">Тип мода ети (для обучения выдаёт исключение).</param> public ConvolutionLayer(FigureMap map, FilterMatrix filterMatrix, NetworkModeType modeType) { if (!modeType.Equals(NetworkModeType.Recognizing)) { throw new Exception("Данный конструктор не может использоваться для обучения!"); } Map = map; FilterMatrix = filterMatrix; _isInitialized = true; }
/// <summary> /// Инициализация. /// </summary> /// <param name="type">Тип мода нейронной сети.</param> public override void Initialize(NetworkModeType type) { if (_isInitialized) { throw new Exception("Невозможно инициализировать уже инициализированную модель!"); } if (type.Equals(NetworkModeType.Learning)) { FilterMatrix = new FilterMatrix(_filterMatrixSize, type); FilterMatrix.Initialize(); } else { //TODO: Реализовать. throw new NotImplementedException(); } _isInitialized = true; }
public static Bitmap ReduceColors(Bitmap image, FilterMatrix filterMatrix, int numberOfColors, bool blackAndWhite) { double[,] filter = new double[1, 1]; switch (filterMatrix) { case FilterMatrix.FloydAndSteinberg: filter = new double[3, 3]; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { filter[i, j] = 0; } } filter[2, 1] = 7.0 / 16; filter[0, 2] = 3.0 / 16; filter[1, 2] = 5.0 / 16; filter[2, 2] = 1.0 / 16; break; case FilterMatrix.Burkes: filter = new double[5, 3]; for (int i = 0; i < 5; ++i) { for (int j = 0; j < 3; ++j) { filter[i, j] = 0; } } filter[3, 1] = 8.0 / 32; filter[4, 1] = 4.0 / 32; filter[0, 2] = 2.0 / 32; filter[1, 2] = 4.0 / 32; filter[2, 2] = 8.0 / 32; filter[3, 2] = 4.0 / 32; filter[4, 2] = 2.0 / 32; break; case FilterMatrix.Stucky: filter = new double[5, 5]; for (int i = 0; i < 5; ++i) { for (int j = 0; j < 5; ++j) { filter[i, j] = 0; } } filter[3, 2] = 8.0 / 42; filter[4, 2] = 4.0 / 42; filter[0, 3] = 2.0 / 42; filter[1, 3] = 4.0 / 42; filter[2, 3] = 8.0 / 42; filter[3, 3] = 4.0 / 42; filter[4, 3] = 2.0 / 42; filter[0, 4] = 1.0 / 42; filter[1, 4] = 2.0 / 42; filter[2, 4] = 4.0 / 42; filter[3, 4] = 2.0 / 42; filter[4, 4] = 1.0 / 42; break; default: break; } Bitmap _return = new Bitmap(image.Width, image.Height); MyColor[,] table = new MyColor[image.Width, image.Height]; for (int x = 0; x < image.Width; ++x) { for (int y = 0; y < image.Height; ++y) { table[x, y] = new MyColor(image.GetPixel(x, y)); } } int diffX = filter.GetLength(0) / 2; int diffY = filter.GetLength(1) / 2; for (int y = 0; y < image.Height; ++y) { for (int x = 0; x < image.Width; ++x) { MyColor oldPixel = table[x, y]; MyColor K = Approximate(table[x, y].ToColor(), numberOfColors, blackAndWhite); table[x, y] = K; MyColor error = oldPixel - table[x, y]; for (int i = 0; i < filter.GetLength(0); ++i) { for (int j = 0; j < filter.GetLength(1); ++j) { if (x + i - diffX >= 0 && y + j - diffY >= 0 && x + i - diffX < table.GetLength(0) && y + j - diffY < table.GetLength(1)) { table[x + i - diffX, y + j - diffY] = table[x + i - diffX, y + j - diffY] + (error * filter[i, j]); } } } } } for (int x = 0; x < image.Width; ++x) { for (int y = 0; y < image.Height; ++y) { _return.SetPixel(x, y, table[x, y].ToColor()); } } return(_return); }
/// <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); }