public Bitmap AddCountData(int cellWidth, Bitmap img) { Graphics g = Graphics.FromImage(img); int[,] count = new int[dimensions[0], dimensions[1]]; foreach (var p in data.PointList) { SOMNeuron bmu = GetBestMatchingUnit(p); var pos = utilGetPosFromID(bmu.id); count[pos.Item1, pos.Item2]++; } int max = 0; for (int x = 0; x < dimensions[0]; x++) { for (int y = 0; y < dimensions[1]; y++) { max = Math.Max(max, count[x, y]); } } for (int x = 0; x < dimensions[0]; x++) { for (int y = 0; y < dimensions[1]; y++) { int intensity = (int)(255.0 * (double)count[x, y] / (double)max); Color c = Color.FromArgb(intensity, 255, 0, 0); Brush b = new SolidBrush(c); g.FillRectangle(b, new Rectangle(new Point(x * cellWidth, y * cellWidth), new Size(cellWidth, cellWidth))); } } return(img); }
public SelfOrganizingMap(PointSet data, List <int> dimensions, int totalItt, double learningRate) { //Get initial learning rate this.initialLearningRate = learningRate; this.learningRate = learningRate; influence = 0; this.totalItterations = totalItt; itterations = 1; this.dimensions = dimensions; this.data = data; rng = new Random((int)DateTime.Now.Ticks); int numNeurons = 1; foreach (int d in dimensions) { numNeurons *= d; } int[] pos = new int[dimensions.Count]; for (int i = 0; i < dimensions.Count; i++) { pos[i] = 0; } //Scale each attribute from [0,1] and store the conversion matrix conversionMatrix = data.GetMinMaxWeights().Max.Coordinates; foreach (KPoint d in data.PointList) { d.Normalize(conversionMatrix); } //Here We will initialize Our Neurons neurons = new List <SOMNeuron>(); KPoint zero = KPoint.Zero(data[0].Dimensions); KPoint one = KPoint.One(data[0].Dimensions); for (int i = 0; i < numNeurons; i++) { //Generate our neurons double[] posNeuron = new double[dimensions.Count]; for (int d = 0; d < dimensions.Count; d++) { posNeuron[d] = (double)pos[d]; } SOMNeuron neuron = new SOMNeuron(zero, one, rng, new KPoint(posNeuron), i); neurons.Add(neuron); addOneCarry(ref pos, dimensions); } //Get the max radius setRadius(); this.timeConstant = (double)totalItterations / Math.Log(radius); }
private SOMNeuron GetBestMatchingUnit(KPoint data) { SOMNeuron best = null; double dist = Double.MaxValue; foreach (SOMNeuron n in neurons) { double d = n.weights.distanceSquared(data); if (d < dist) { dist = d; best = n; } } return best; }
public void Epoch(KPoint p) { //get a random item SOMNeuron bmu = GetBestMatchingUnit(p); neighborhoodRadius = radius * Math.Exp(-(double)itterations / timeConstant); double neighborSqr = neighborhoodRadius * neighborhoodRadius; QuadTreePointStruct center = new QuadTreePointStruct() { Index = -1, X = bmu.position[0], Y = bmu.position[1] }; QuadTreePointStruct halfLength = new QuadTreePointStruct() { Index = -1, X = neighborhoodRadius, Y = neighborhoodRadius }; List <int> neuronsInArea = neuronQuadTree.QueryRange(new QuadTreeBoundingBox() { Center = center, HalfLength = halfLength }); //Now we need to update each neuron foreach (int i in neuronsInArea) { SOMNeuron n = neurons[i]; double distToBMU = n.position.elucideanDistance(bmu.position); if (distToBMU <= neighborhoodRadius) { influence = Math.Exp(-(distToBMU * distToBMU) / (2 * neighborSqr)); n.updateWeights(p, learningRate, influence); } } learningRate = this.initialLearningRate * Math.Exp(-(double)itterations / (double)this.totalItterations); itterations++; }
public void Epoch(KPoint p) { //get a random item SOMNeuron bmu = GetBestMatchingUnit(p); neighborhoodRadius = radius * Math.Exp(-(double)itterations / timeConstant); double neighborSqr = neighborhoodRadius * neighborhoodRadius; //Now we need to update each neuron foreach (SOMNeuron n in neurons) { double distToBMUSqr = n.position.elucideanDistance(bmu.position); if (distToBMUSqr <= neighborSqr) { influence = Math.Exp(-(distToBMUSqr) / (2 * neighborSqr)); n.updateWeights(p, learningRate, influence); } } learningRate = this.initialLearningRate * Math.Exp(-(double)itterations / (double)this.totalItterations); itterations++; }
public HexagonalSelfOrganizingMap(PointSet data, int dimension, double learningRate) { _dimension = dimension; //Get initial learning rate this.initialLearningRate = learningRate; this.learningRate = learningRate; influence = 0; itterations = 1; this.data = data; rng = new Random(); int numNeurons = dimension * dimension; //Scale each attribute from [0,1] and store the conversion matrix conversionMatrix = data.GetMinMaxWeights().Max.Coordinates; foreach (KPoint d in data.PointList) { d.Normalize(conversionMatrix); } //Here We will initialize Our Neurons neurons = new List <SOMNeuron>(); KPoint zero = KPoint.Zero(data[0].Dimensions); KPoint one = KPoint.One(data[0].Dimensions); double halfNeuronDelta = 1 / Math.Sqrt(3.0); //Initialize our Quadtree for reference double centerX = (dimension - 0.5) * (2 * halfNeuronDelta) / 2.0; double centerY = (dimension - 1.0) / 2.0; QuadTreePointStruct center = new QuadTreePointStruct() { Index = -1, X = centerX, Y = centerY }; QuadTreePointStruct halfDistance = new QuadTreePointStruct() { Index = -1, X = centerX + halfNeuronDelta, Y = centerY + 0.5 }; neuronQuadTree = new QuadTree(new QuadTreeBoundingBox() { Center = center, HalfLength = halfDistance }); int neuronIndex = 0; for (int r = 0; r < dimension; r++) { double xPos = (r % 2 == 1) ? halfNeuronDelta : 0.0; for (int c = 0; c < dimension; c++) { //Generate our neurons double[] posNeuron = { xPos, (double)r }; SOMNeuron neuron = new SOMNeuron(zero, one, rng, new KPoint(posNeuron), neuronIndex); QuadTreePointStruct neuronQTPos = new QuadTreePointStruct() { Index = neuronIndex, X = posNeuron[0], Y = posNeuron[1] }; neuronQuadTree.Insert(neuronQTPos); neurons.Add(neuron); xPos += 2 * halfNeuronDelta; neuronIndex++; } } //Get the max radius SetRadius(); timeConstant = (double)totalItterations / Math.Log(radius); }
public List <Bitmap> GetUMatrix(int cellWidth, int labelCount = 0, int[] labels = null) { cellWidth += (cellWidth % 2); //make it even int halfCellWidth = cellWidth / 2; double verticalOffset = (double)halfCellWidth / Math.Tan(Math.PI / 6); double halfVerticalHeight = (double)halfCellWidth / Math.Cos(Math.PI / 6); List <Bitmap> images = new List <Bitmap>(); List <Graphics> imgGraphics = new List <Graphics>(); Size imageSize = new Size((int)((_dimension + .5) * cellWidth), (int)((_dimension - 1) * verticalOffset + 2 * halfVerticalHeight)); Bitmap img = new Bitmap(imageSize.Width, imageSize.Height); Bitmap imgPointCount = new Bitmap(imageSize.Width, imageSize.Height); Graphics g = Graphics.FromImage(img); Graphics gpc = Graphics.FromImage(imgPointCount); images.Add(img); images.Add(imgPointCount); imgGraphics.Add(g); imgGraphics.Add(gpc); if (labels != null) { for (int i = 0; i < labelCount; i++) { Bitmap classImg = new Bitmap(imageSize.Width, imageSize.Height); Graphics classG = Graphics.FromImage(classImg); images.Add(classImg); imgGraphics.Add(classG); } } //Calculate the distance matrix double maxValue = 0.0; double minValue = double.MaxValue; double[,] weights = new double[_dimension, _dimension]; for (int x = 0; x < _dimension; x++) { for (int y = 0; y < _dimension; y++) { weights[x, y] = 0; int[] neighborCoordPairsEven = { x - 1, y - 1, x, y - 1, x - 1, y, x + 1, y, x - 1, y + 1, x, y + 1 }; int[] neighborCoordPairsOdd = { x, y - 1, x + 1, y - 1, x - 1, y, x + 1, y, x, y + 1, x + 1, y + 1 }; SOMNeuron n = neurons[y * _dimension + x]; int neighborCount = 0; for (int i = 0; i < 12; i += 2) { int index = 0; if (y % 2 == 0) { index = GetNeuronIndexFromPos(neighborCoordPairsEven[i], neighborCoordPairsEven[i + 1]); } else { index = GetNeuronIndexFromPos(neighborCoordPairsOdd[i], neighborCoordPairsOdd[i + 1]); } if (index >= 0) { weights[x, y] += n.weights.elucideanDistance(neurons[index].weights); neighborCount++; } } weights[x, y] /= (double)neighborCount; maxValue = Math.Max(maxValue, weights[x, y]); minValue = Math.Min(minValue, weights[x, y]); } } //now get neuron matching count int[] matchingCount = new int[_dimension * _dimension]; int[,] matchingCountSpecific = (labelCount > 0) ? new int[_dimension * _dimension, labelCount] : null; for (int kIndex = 0; kIndex < data.Count; kIndex++) { var bmu = GetBestMatchingUnit(data[kIndex]); matchingCount[bmu.id]++; if (labelCount > 0) { matchingCountSpecific[bmu.id, labels[kIndex]]++; } } int maxMatchingCount = matchingCount.Max(); int[] maxMatchingLabel = (labelCount > 0) ? new int[labelCount] : null; if (labelCount > 0) { for (int n = 0; n < neurons.Count; n++) { for (int l = 0; l < labelCount; l++) { maxMatchingLabel[l] = Math.Max(maxMatchingLabel[l], matchingCountSpecific[n, l]); } } } //Now that we have a weight matrix and the maxvalue //we can print our nodes! for (int x = 0; x < _dimension; x++) { for (int y = 0; y < _dimension; y++) { double distanceShifted = weights[x, y] - minValue; double intensity = distanceShifted / (maxValue - minValue); int bright = (int)((1.0 - intensity) * 255.0); Color c = Color.FromArgb(bright, bright, bright); Brush b = new SolidBrush(c); //Calculate the brush for the point matching list Color cCount = Color.White; if (matchingCount[x + y * _dimension] > 0) { double countIntensity = (matchingCount[x + y * _dimension] - 1.0) / (maxMatchingCount - 1.0); cCount = LerpColor(Color.Aqua, Color.Red, countIntensity); } Brush bC = new SolidBrush(cCount); //get x double xAdjusted = (double)x * cellWidth + halfCellWidth; if (y % 2 == 1) { xAdjusted += halfCellWidth; } double yAdjusted = (double)y * verticalOffset + halfVerticalHeight; Point[] hexagon = GetCenteredHexagon(xAdjusted, yAdjusted, halfCellWidth, halfVerticalHeight); g.FillPolygon(b, hexagon, FillMode.Winding); gpc.FillPolygon(bC, hexagon, FillMode.Winding); //Color the specific class images for (int i = 0; i < labelCount; i++) { Color classColor = Color.White; if (matchingCountSpecific[x + y * _dimension, i] > 0) { double countIntensity = (matchingCountSpecific[x + y * _dimension, i] - 1.0) / (maxMatchingLabel[i] - 1.0); classColor = LerpColor(Color.Aqua, Color.Red, countIntensity); } Brush classBrush = new SolidBrush(classColor); imgGraphics[i + 2].FillPolygon(classBrush, hexagon, FillMode.Winding); } } } foreach (Graphics gr in imgGraphics) { gr.Dispose(); } return(images); }
public Bitmap GetUMatrix(int cellWidth, bool use8Neighbors) { if (dimensions.Count == 2) { Bitmap img = new Bitmap(dimensions[0] * cellWidth, dimensions[1] * cellWidth); Graphics g = Graphics.FromImage(img); double maxValue = 0.0; double minValue = double.MaxValue; double[,] weights = new double[dimensions[0], dimensions[1]]; for (int x = 0; x < dimensions[0]; x++) { for (int y = 0; y < dimensions[1]; y++) { weights[x, y] = 0; SOMNeuron n = neurons[utilGet1dIndex(x, y)]; int neighborCount = 0; for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { int nx = x + dx; int ny = y + dy; if (!(dx == 0 && dy == 0) && (nx >= 0 && nx < dimensions[0]) && (ny >= 0 && ny < dimensions[1])) { if ((!use8Neighbors && (Math.Abs(dx) == Math.Abs(dy))) || use8Neighbors) { SOMNeuron no = neurons[utilGet1dIndex(nx, ny)]; weights[x, y] += n.weights.elucideanDistance(no.weights); neighborCount++; } } } } weights[x, y] /= (double)neighborCount; maxValue = Math.Max(maxValue, weights[x, y]); minValue = Math.Min(minValue, weights[x, y]); } } //Now that we have a weight matrix and the maxvalue //we can print our nodes! for (int x = 0; x < dimensions[0]; x++) { for (int y = 0; y < dimensions[1]; y++) { double distanceShifted = weights[x, y] - minValue; double intensity = distanceShifted / (maxValue - minValue); int bright = (int)((1.0 - intensity) * 255.0); Color c = Color.FromArgb(bright, bright, bright); Brush b = new SolidBrush(c); //get x g.FillRectangle(b, new Rectangle(new Point(x * cellWidth, y * cellWidth), new Size(cellWidth, cellWidth))); } } return(img); } else { return(new Bitmap(10, 10)); } }