public void setup() { input = new MultiMatrix(new int[] { 2, 3, 3 }, new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, }); kernel = new Kernel(new int[] { 2, 2, 2 }, new double[] { 3, 3, 4, 4, 1, 1, 2, 2, }); expectedOutput = new MultiMatrix(new int[] { 1, 2, 2 }, new double[] { 120, 140, 180, 200, }); nextGradients = new MultiMatrix(new int[] { 1, 2, 2 }, new double[] { 4, 2, 3, 1, }); //expectedGradientInput = new MultiMatrix(new int[] { 2, 3, 3 }, new double[]{ }); }
public void slideOver() { var weights = MultiMatrix.Build.repeat(new int[] { 3, 3 }, 1); var kernel = new Kernel(weights); var inData = new MultiMatrix(new int[] { 5, 5 }, new double[] { 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 4, 5, 6, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, }); var expectedOutput = new MultiMatrix(new int[] { 3, 3 }, new double[] { 12, 21, 16, 27, 45, 33, 24, 39, 28, }); var output = kernel.slideOver(inData); Assert.IsTrue(output.EEquals(expectedOutput)); output = this.kernel.slideOver(this.input); Assert.IsTrue(output.EEquals(this.expectedOutput)); }
public MultiMatrix getGradientInputWithRotation(MultiMatrix nextGradient) { var correlationMatrix = new Kernel(this); correlationMatrix.rotate90(); return(correlationMatrix.slideOver(nextGradient.padded(this.Dimensions.add(-1)))); }// TODO check ?
public void getSumAt() { var dimensions = new int[] { 5, 5, 5 }; var data = MultiMatrix.Build.random(dimensions); var kernel = new Kernel(new int[] { 3, 3, 3 }); var coordTarget = new int[] { 1, 1, 1 }; var expectedSum = 0.0; foreach (var offset in kernel.Weights.AllCoords()) { expectedSum += kernel.Weights.at(offset) * data.at(coordTarget.add(offset)); } var sum = kernel.getSumAt(data, coordTarget); Assert.IsTrue(sum.EEquals(expectedSum)); var hardcodedData = new MultiMatrix(new int[] { 5, 5 }, new double[] { -100, -100, -100, -100, -100, -100, 1, 2, 3, -100, -100, 4, 5, 6, -100, -100, 7, 8, 9, -100, -100, -100, -100, -100, -100, }); var hardcodedWeights = new double[] { 2, 4, 6, 8, 10, 12, 14, 16, 18 }; var hardcodedKernel = new Kernel(new MultiMatrix(new int[] { 3, 3 }, hardcodedWeights)); var theSum = hardcodedKernel.getSumAt(hardcodedData, new int[] { 1, 1 }); var eSum = 1 * 2 + 2 * 4 + 3 * 6 + 4 * 8 + 5 * 10 + 6 * 12 + 7 * 14 + 8 * 16 + 9 * 18; Assert.IsTrue(theSum.EEquals(eSum)); }
public void getGradientInput() { var inData = new MultiMatrix(new int[] { 3, 3 }, new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, }); var weights = new double[] { 1, 2, 3, 4, }; var gradientNext = new MultiMatrix(new int[] { 2, 2 }, new double[] { 1, -1, 2, 3, }); var kernel = new Kernel(new int[] { 2, 2 }, weights); var expectedGradient = new MultiMatrix(new int[] { 3, 3 }, new double[] { 1, 1, -2, 5, 8, 2, 6, 17, 12, }); var gradient = kernel.getGradientInput(inData, gradientNext); Assert.IsTrue(expectedGradient.EEquals(gradient)); }
public void getGradientInput() { var inData = new MultiMatrix(new int[] { 5, 5 }, new double[] { 0, 1, 2, 3, 4, 10, 11, 9, 14, 13, 20, 24, 25, 26, 20, 32, 27, 28, 29, 21, 31, 33, 34, 35, -1, }); var gradientNext = new MultiMatrix(new int[] { 3, 3 }, new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, }); var expectedGradient = new MultiMatrix(new int[] { 5, 5 }, new double[] { 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, }); var pooler = new Pooler(new int[] { 2, 2 }); var gradient = pooler.getGradientInput(inData, gradientNext); Assert.IsTrue(expectedGradient.EEquals(gradient)); }
public override MultiMatrix slideOver(MultiMatrix inData) { var outData = new MultiMatrix(getOutputDims(inData)); foreach (var coords in outData.AllCoords()) { outData.setAt(coords, getSumAt(inData, coords.mapWith(Stride, (c, s) => c * s))); } return(outData); }
public void setup() { this.splittedExpected = new MultiMatrix[] { new MultiMatrix(new int[] { 2, 2 }, new double[] { 1, 2, 3, 4 }), new MultiMatrix(new int[] { 2, 2 }, new double[] { 5, 6, 7, 8 }), new MultiMatrix(new int[] { 2, 2 }, new double[] { 9, 10, 11, 12 }), }; this.mergedDataExp = new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; this.mergedExpected = new MultiMatrix(new int[] { 3, 2, 2 }, this.mergedDataExp); this.dimensionsExp = new int[] { 3, 2, 2 }; }
public static MultiMatrix[] toMultiMatrix(this MatrixD data, int[] entryDimensions) { int countEntries = data.RowCount; var dataArr = data.ToRowArrays(); MultiMatrix[] matrices = new MultiMatrix[countEntries]; for (int i = 0; i < countEntries; i++) { matrices[i] = MultiMatrix.Build.useData(dataArr[i], entryDimensions); } return(matrices); }
public override MultiMatrix getGradientInput(MultiMatrix inData, MultiMatrix nextGradient) { var gradientIn = MultiMatrix.Build.repeat(inData.Dimensions, 0); foreach (var coords in nextGradient.AllCoords()) { foreach (var offset in Weights.AllCoords()) { gradientIn.addAt(coords.add(offset), nextGradient.at(coords) * Weights.at(offset)); } } return(gradientIn); }
public double getSumAt(MultiMatrix inData, int[] coord) { var sum = 0.0; foreach (var offset in this.weights.AllCoords()) { var nearbyCoord = coord.add(offset); if (inData.areValidCoords(nearbyCoord)) { sum += inData.at(coord.add(offset)) * weights.at(offset); } } return(sum); }
}// TODO check ? public MultiMatrix getGradientWeights(MultiMatrix inData, MultiMatrix nextGradient) { var gradientW = new MultiMatrix(this.Dimensions); foreach (var coord in nextGradient.AllCoords()) { foreach (var offset in this.weights.AllCoords()) { var nearbyCoord = coord.add(offset); gradientW.addAt(offset, nextGradient.at(coord) * inData.at(nearbyCoord)); } } return(gradientW); }
public void findIndex() { int[] dimensions = new int[] { 3, 1, 2, 1 }; var mm = new MultiMatrix(dimensions); var index = mm.findIndex(new int[] { 2, 0, 0 }); var expectedIndex = 4; Assert.AreEqual(index, expectedIndex); dimensions = new int[] { 2, 2 }; mm = new MultiMatrix(dimensions); index = mm.findIndex(new int[] { 1, 1 }); expectedIndex = 3; Assert.AreEqual(index, expectedIndex); }
public void getMaxAt() { var inData = new MultiMatrix(new int[] { 5, 5 }, new double[] { 0, 0, 0, 0, 999, 0, 1, 2, 3, 0, 0, 4, 5, 6, 0, 0, 7, 8, 9, 0, 0, 0, 0, 99, 999, }); var pooler = new Pooler(new int[] { 2, 2 }); Assert.IsTrue(pooler.getMaxAt(inData, new int[] { 0, 0 }).EEquals(1)); Assert.IsTrue(pooler.getMaxAt(inData, new int[] { 2, 2 }).EEquals(9)); Assert.IsTrue(pooler.getMaxAt(inData, new int[] { 0, 4 }).EEquals(999)); Assert.IsTrue(pooler.getMaxAt(inData, new int[] { 4, 2 }).EEquals(99)); Assert.IsTrue(pooler.getMaxAt(inData, new int[] { 4, 4 }).EEquals(999)); }
public void slideOver() { var inData = new MultiMatrix(new int[] { 5, 5 }, new double[] { 0, 1, 2, 3, 4, 10, 11, 9, 14, 13, 20, 24, 25, 26, 20, 32, 27, 28, 29, 21, 31, 33, 34, 35, -1, }); var expectedOutput = new MultiMatrix(new int[] { 3, 3 }, new double[] { 11, 14, 13, 32, 29, 21, 33, 35, -1, }); var pooler = new Pooler(new int[] { 2, 2 }); var output = pooler.slideOver(inData); Assert.IsTrue(output.EEquals(expectedOutput)); }
public void backwardLearn() { var inData = new MultiMatrix(new int[] { 3, 3 }, new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, }); var weights = new double[] { 1, 2, 3, 4 }; var gradientNext = new MultiMatrix(new int[] { 2, 2 }, new double[] { 3, -1, 2, 1, }); var learnRate = 0.5; var kernel = new Kernel(new int[] { 2, 2 }, weights); var gradientW = kernel.getGradientWeights(inData, gradientNext); var expectedWeights = kernel.Weights + (gradientW.scalarMultiply(-learnRate)); kernel.backwardLearn(inData, gradientNext, learnRate); Assert.IsTrue(kernel.Weights.EEquals(expectedWeights)); }
public void setup() { this.depth = GlobalRandom.NextInt(2, 5); this.countEntries = GlobalRandom.NextInt(2, 5); this.inDims = GlobalRandom.NextIntArr(countEntries, 2, 5); this.entrySize = inDims.product(); this.kernels = ArrayBuilder.repeat( new Kernel(inDims.map(x => GlobalRandom.NextInt(2, x))), depth); this.layer = new ConvolutionLayer(this.kernels, this.inDims); MultiMatrix[] entries = ArrayBuilder.repeat(() => MultiMatrix.Build.random(inDims), countEntries); MultiMatrix[][] expectedOutputs = new MultiMatrix[countEntries][]; MultiMatrix[][] nextGradients = new MultiMatrix[countEntries][]; MultiMatrix[] expectedInGradients = new MultiMatrix[countEntries]; Kernel[] kerns = kernels.map(k => new Kernel(k)); for (int i = 0; i < countEntries; i++) { expectedInGradients[i] = MultiMatrix.Build.repeat(inDims, 0); expectedOutputs[i] = new MultiMatrix[depth]; } for (int i = 0; i < countEntries; i++) { nextGradients[i] = new MultiMatrix[depth]; for (var j = 0; j < kerns.Length; j++) { expectedOutputs[i][j] = kernels[j].slideOver(entries[i]); nextGradients[i][j] = MultiMatrix.Build.random(kernels[0].getOutputDims(inDims)); expectedInGradients[i] += kernels[j].getGradientInput(entries[i], nextGradients[i][j]); kerns[j].backwardLearn(entries[i], nextGradients[i][j], learnRate); } } this.entries = entries.toMatrixD(); this.expectedOutputs = expectedOutputs.map(o => new MultiMatrix(o)).toMatrixD(); this.nextGradients = nextGradients.map(g => new MultiMatrix(g)).toMatrixD(); this.expectedGradients = expectedInGradients.toMatrixD(); this.expectedLearnedWeights = kerns.map(k => k.Weights); }
public void setup() { this.countEntries = GlobalRandom.NextInt(2, 5); this.inDims = GlobalRandom.NextIntArr(countEntries, 2, 5); this.entrySize = inDims.product(); this.pooler = new Pooler(inDims.map(x => GlobalRandom.NextInt(2, x))); this.layer = new PoolingLayer(this.pooler, this.inDims); MultiMatrix[] entries = ArrayBuilder.repeat(() => MultiMatrix.Build.random(inDims), countEntries); MultiMatrix[] expectedOutputs = new MultiMatrix[countEntries]; MultiMatrix[] nextGradients = new MultiMatrix[countEntries]; MultiMatrix[] expectedGradients = new MultiMatrix[countEntries]; for (int i = 0; i < countEntries; i++) { expectedOutputs[i] = pooler.slideOver(entries[i]); nextGradients[i] = MultiMatrix.Build.random(pooler.getOutputDims(inDims)); expectedGradients[i] = pooler.getGradientInput(entries[i], nextGradients[i]); } this.inputs = entries.toMatrixD(); this.expectedOutputs = expectedOutputs.toMatrixD(); this.nextGradients = nextGradients.toMatrixD(); this.expectedGradients = expectedGradients.toMatrixD(); }
public Kernel(MultiMatrix weights, int[] stride) { this.weights = weights.copy(); this.stride = stride.ShallowCopy(); }
public int[] getOutputDims(MultiMatrix input) => getOutputDims(input.Dimensions);
public abstract void backwardLearn(MultiMatrix inData, MultiMatrix gradient, double learnRate);
public Kernel(int[] dimensions, int[] stride) { this.weights = MultiMatrix.Build.random(dimensions, -1, 1); this.stride = stride.ShallowCopy(); }
public Kernel(int[] dimensions) { this.weights = MultiMatrix.Build.random(dimensions, -1, 1); this.stride = ArrayBuilder.repeat(1, this.DimensionCount); }
public void getMergedDimensions() { MultiMatrix mm = new MultiMatrix(this.mergedExpected); Assert.IsTrue(mm.Dimensions.EEquals(this.dimensionsExp)); }
public void getMergedData() { var mm = new MultiMatrix(splittedExpected); Assert.IsTrue(mm.Data.EEquals(this.mergedDataExp)); }
public Kernel(int[] dimensions, double[] weights) { this.weights = new MultiMatrix(dimensions, weights); this.stride = ArrayBuilder.repeat(1, this.DimensionCount); }
public Kernel(int[] dimensions, double[] weights, int[] stride) { this.weights = new MultiMatrix(dimensions, weights); this.stride = stride.ShallowCopy(); }
public Kernel(MultiMatrix weights) { this.weights = weights.copy(); this.stride = ArrayBuilder.repeat(1, this.DimensionCount); }
public Kernel(Kernel filter) { this.weights = new MultiMatrix(filter.weights); this.stride = filter.Stride.ShallowCopy(); }
public override void backwardLearn(MultiMatrix inData, MultiMatrix nextGradient, double learnRate) { var gradientW = getGradientWeights(inData, nextGradient); this.weights.Data.changeWith(gradientW.Data, (w, g) => w - learnRate * g); }