public override InternalArray Forward(InternalArray ar1) { InternalArray ar = ar1.Clone(); var n = ar1.Shape[0]; var c = ar1.Shape[1]; List <double> data = new List <double>(); int pos0 = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < c; j++) { var img = ar.GetNext2dImageFrom4dArray(ref pos0); for (int z = 0; z < img.Data.Length; z++) { img.Data[z] = img.Data[z] < 0 ? (img.Data[z] * Weight.Data[j]) : img.Data[z]; } data.AddRange(img.Data); } } ar.Data = data.ToArray(); return(ar); }
public InternalArray ProcessImageOptimized2(InternalArray ar, int hout, int wout, int c, int hin, int win) { InternalArray ret = new InternalArray(new int[] { outChannels, hout, wout }); InternalArray[,] filters = new InternalArray[outChannels, c]; int pos0 = 0; for (int ch = 0; ch < outChannels; ch++) { for (int zz = 0; zz < c; zz++) { var kernel = Weight.GetNext2dImageFrom4dArray(ref pos0); var kernel2 = Weight.Get2DImageFrom4DArray(ch, zz); filters[ch, zz] = kernel; } } int shiftx = padding[0] - kernelSize[0] / 2; int shifty = padding[1] - kernelSize[1] / 2; Parallel.For(0, hout, (i) => { var imul = (i) * stride[0] - kernelSize[0] / 2 - shiftx; var maxi1 = Math.Min((ar.Shape[1] - imul) / dilation[0], kernelSize[0]); var mini1 = Math.Max((int)Math.Ceiling(-(double)imul / dilation[0]), 0); Parallel.For(0, wout, (j) => { var jmul = (j) * stride[1] - kernelSize[1] / 2 - shifty; var minj1 = Math.Max((int)Math.Ceiling(-(double)jmul / dilation[1]), 0); var maxj1 = Math.Min((ar.Shape[2] - jmul) / dilation[1], kernelSize[1]); for (int ch = 0; ch < outChannels; ch++) { double val = 0; for (int zz = 0; zz < c; zz++) { var kernel = filters[ch, zz]; var offset1 = zz * ar.offsets[0]; int kindex = 0; for (int i1 = mini1; i1 < maxi1; i1++) { var x = imul + i1 * dilation[0]; for (int j1 = minj1; j1 < maxj1; j1++) { var y = jmul + j1 * dilation[1]; var index = offset1 + x * ar.offsets[1] + y; val += kernel.Data[kindex] * ar.Data[index]; kindex++; } } } ret.Set3D(ch, i, j, val); } }); }); //for (int i = 0; i < hout; i++) { } return(ret); }