public float[][][] BackPropagation(float[][][] errors, ICNNLayer nextLayer) { float[][][] PartialDerivative = new float[Depth][][]; for (int i = 0; i < Depth; i++) { PartialDerivative[i] = new float[OutputSideLength][]; for (int j = 0; j < OutputSideLength; j++) { PartialDerivative[i][j] = new float[OutputSideLength]; } } ConvolutionalLayer conv = nextLayer as ConvolutionalLayer; //i is layer in input and output for (int i = 0; i < nextLayer.Depth; i++) { //y is part of position in output for (int y = 0; y < nextLayer.OutputSideLength; y++) { //x is part of position in output for (int x = 0; x < nextLayer.OutputSideLength; x++) { for (int j = 0; j < nextLayer.ExpectedInputDepth; j++) { //k is part of position in filter for (int k = 0; k < nextLayer.FilterSideLength; k++) { int absY = y * nextLayer.StrideLength + k; if (absY < nextLayer.ZeroPaddingSize || absY >= nextLayer.ExpectedInputWidth + nextLayer.ZeroPaddingSize) { continue; } //l is part of position in filter for (int l = 0; l < nextLayer.FilterSideLength; l++) { int absX = x * nextLayer.StrideLength + l; if (absX < nextLayer.ZeroPaddingSize || absX >= nextLayer.ExpectedInputWidth + nextLayer.ZeroPaddingSize) { continue; } float weightThing = 1f; if (conv != null) { weightThing = conv.Weights[i][j][k][l]; } else { throw new NotImplementedException(); } PartialDerivative[j][absY][absX] += weightThing * errors[j][y][x]; } } } } } } return(PartialDerivative); }
public float[][][] BackPropagation(float[][][] derivatives, ICNNLayer nextLayer) { ConvolutionalLayer conv = nextLayer as ConvolutionalLayer; //i is depth in output for (int i = 0; i < nextLayer.Depth; i++) { //y is part of position in output for (int y = 0; y < nextLayer.OutputSideLength; y++) { //x is part of position in output for (int x = 0; x < nextLayer.OutputSideLength; x++) { //j is depth in input for (int j = 0; j < nextLayer.ExpectedInputDepth; j++) { //k is part of position in filter for (int k = 0; k < nextLayer.FilterSideLength; k++) { int absY = y * nextLayer.StrideLength + k; if (absY < nextLayer.ZeroPaddingSize || absY >= nextLayer.ExpectedInputWidth + nextLayer.ZeroPaddingSize) { continue; } //l is part of position in filter for (int l = 0; l < nextLayer.FilterSideLength; l++) { int absX = x * nextLayer.StrideLength + l; if (absX < nextLayer.ZeroPaddingSize || absX >= nextLayer.ExpectedInputWidth + nextLayer.ZeroPaddingSize) { continue; } float weightThing = 1f; if (conv == null) { weightThing = nextLayer.LastIns[j][absY][absX] == nextLayer.LastOuts[i][y][x] ? 1 : 0; } else { weightThing = conv.Weights[i][j][k][l]; } PartialDerivative[j][absY][absX] += weightThing * derivatives[j][y][x]; } } } } } } return(Backprop(derivatives)); }