/// <summary> /// Обновить ячейку с помощтю карт входа/выхода. /// </summary> /// <param name="cell">Ячейка.</param> /// <param name="inputMap">Входная карта.</param> /// <param name="outputMap">Выходная карта.</param> /// <param name="filterMatrixSize">Размер матрицы фильтра.</param> /// <param name="hyperParameters">Гиперпараметры.</param> public static void UpdateCellByIOMaps(this ModifiedCell cell, FigureMap inputMap, FigureMap outputMap, int filterMatrixSize, HyperParameters hyperParameters) { var xEndPoint = cell.X + filterMatrixSize; var yEndPoint = cell.Y + filterMatrixSize; var gradient = 0d; var x = 0; for (var xStartPoint = cell.X; xStartPoint < xEndPoint; ++xStartPoint) { var y = 0; for (var yStartPoint = cell.Y; yStartPoint < yEndPoint; ++yStartPoint) { var cellFromInputMap = inputMap.Cells .Find(c => c.X.Equals(xStartPoint) && c.Y.Equals(yStartPoint)); var cellFromOutputMap = outputMap.Cells.Find(c => c.X.Equals(x) && c.Y.Equals(y)); gradient += cellFromInputMap.Value * cellFromOutputMap.Value; ++y; } ++x; } var deltaValue = hyperParameters.Epsilon * gradient + hyperParameters.Alpha * cell.LastValueDelta; cell.UpdateLastDeltValue(deltaValue); var newValue = cell.Value + deltaValue; cell.UpdatedValue(newValue); }
/// <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="map">Карта данных.</param> public void SetData(FigureMap map) { if (!_isInitialized) { throw new Exception("Перед внесением данных в слой необходимо его проинициализировать!"); } if (!map.Cells.Count.Equals(Map.Cells.Count)) { throw new Exception("Размерность карты значений не совпадает!"); } Map = map; }
/// <summary> /// Инициализация. /// </summary> /// <param name="type">Тип мода нейронной сети.</param> public override void Initialize(NetworkModeType type) { if (_isInitialized) { throw new Exception("Невозможно инициализировать уже инициализированную модель!"); } // Независимо от типа мода нейронной сети возвращается карта. var size = GetDataSize(); _layerData = new FigureMap(size, _data); _isInitialized = true; }
/// <summary> /// Запись данных слоя. /// </summary> /// <param name="data">Данные.</param> public void SetData(double[,] data) { if (!_isInitialized) { throw new Exception("Перед внесением данных в слой необходимо его проинициализировать!"); } var inputDataSize = GetDataSize(data); var includedDataSize = GetDataSize(); if (!inputDataSize.Equals(includedDataSize)) { throw new Exception("Переданная матрица не соответствует размерностью" + " с уже содержащейся в слое матрицей."); } _data = data; _layerData = new FigureMap(inputDataSize, data); }
/// <summary> /// Запись данных слоя. /// </summary> /// <param name="map">Карта данных.</param> public void SetData(FigureMap map) { if (!_isInitialized) { throw new Exception("Перед внесением данных в слой необходимо его проинициализировать!"); } if (!map.Cells.Count.Equals(Map.Cells.Count)) { throw new Exception("Размерность карты значений не совпадает!"); } foreach (var cell in Map.Cells) { var newValue = map.Cells .Find(inputCell => inputCell.X.Equals(cell.X) && inputCell.Y.Equals(cell.Y)).Value; cell.Value = newValue; } }
/// <summary> /// Слой пуллинга. /// </summary> /// <param name="map">Карта изображения.</param> /// <param name="poolingMatrixSize">Размер матрицы макс-пуллинга.</param> public SubsamplingLayer(FigureMap map, int poolingMatrixSize) { Map = map; _poolingMatrixSize = poolingMatrixSize; }
/// <summary> /// Свёрточный слой. /// </summary> /// <param name="map">Карта значений.</param> /// <param name="filterMatrixSize">Размерность матрицы фильтра.</param> public ConvolutionLayer(FigureMap map, int filterMatrixSize) { Map = map; _filterMatrixSize = filterMatrixSize; }
/// <summary> /// Задать дельты слоя макс-пуллинга. /// </summary> /// <param name="hiddenLayerNeurons">Нейроны скрытого слоя.</param> /// <param name="map">Карта слоя макс-пуллинга.</param> private void SetDeltasInSubSamplingLayer(List <NeuronFromMap> hiddenLayerNeurons, FigureMap map) { foreach (var cell in map.Cells) { var summary = 0d; foreach (var neuron in hiddenLayerNeurons) { var weightInfo = neuron.WeightsToMapPosition. Find(weight => weight.OwnerCell.X.Equals(cell.X) && weight.OwnerCell.Y.Equals(cell.Y)); summary += weightInfo.Value * neuron.Delta; } cell.Delta = MathUtil.DerivativeActivationFunction(cell.Value, ActivationFunctionType.Sigmoid) * summary; } _virtualMaxPoolingMatrix = new VirtualMaxPoolingMatrix(map.Cells); }
/// <summary> /// Обновление весов между слоем макс-пуллинга и скрытым. /// </summary> /// <param name="hiddenLayerNeurons">Нейроны скрытого слоя.</param> /// <param name="map">Карта слоя макс-пуллинга.</param> private void UpdateWeightsSubsamplingToHidden(List <NeuronFromMap> hiddenLayerNeurons, FigureMap map) { foreach (var cell in map.Cells) { foreach (var neuron in hiddenLayerNeurons) { var gradient = neuron.Delta * cell.Value; var weight = neuron.WeightsToMapPosition. Find(weightInfo => weightInfo.OwnerCell.X.Equals(cell.X) && weightInfo.OwnerCell.Y.Equals(cell.Y)); var weightDelta = MathUtil.GetWeightsDelta(_hyperParameters, gradient, weight.LastValueDelta); weight.LastValueDelta = weightDelta; weight.Value += weightDelta; } } }