예제 #1
0
        public static NdArray <Real> SingleInputForward(NdArray <Real> x, NdArray <Real> weight, NdArray <Real> bias, ICompressibleActivation <Real> activation, IFunction <Real> linear)
        {
            int outputCount = weight.Shape[0];
            int inputCount  = weight.Shape[1];

            Real[] y = bias == null ? new Real[outputCount * x.BatchCount] : GetBiasedValue(x.BatchCount, outputCount, bias.Data);

            for (int batchCount = 0; batchCount < x.BatchCount; batchCount++)
            {
                for (int i = 0; i < outputCount; i++)
                {
                    for (int j = 0; j < inputCount; j++)
                    {
                        y[batchCount * outputCount + i] += x.Data[batchCount * inputCount + j] * weight.Data[i * inputCount + j];
                    }
                }
            }

            if (activation != null)
            {
                for (int i = 0; i < y.Length; i++)
                {
                    y[i] = activation.ForwardActivate(y[i]);
                }
            }

            return(NdArray.Convert(y, new[] { outputCount }, x.BatchCount, linear));
        }
예제 #2
0
        public static NdArray NeedPreviousForwardCpu(this ICompressibleActivation compressibleActivation, NdArray x)
        {
            Real[] y = new Real[x.Data.Length];

            for (int i = 0; i < y.Length; i++)
            {
                y[i] = compressibleActivation.ForwardActivate(x.Data[i]);
            }

            return(NdArray.Convert(y, x.Shape, x.BatchCount, compressibleActivation));
        }
예제 #3
0
        public static NdArray <Real> SingleInputForward(NdArray <Real> x, NdArray <Real> weight, NdArray <Real> bias, int strideX, int strideY, int padX, int padY, ICompressibleActivation <Real> activation, IFunction <Real> conv2d)
        {
            int outputCount  = weight.Shape[0];
            int inputCount   = weight.Shape[1];
            int kernelHeight = weight.Shape[2];
            int kernelWidth  = weight.Shape[3];

            int outputHeight = (int)Math.Floor((x.Shape[1] - kernelHeight + padY * 2.0f) / strideY) + 1;
            int outputWidth  = (int)Math.Floor((x.Shape[2] - kernelWidth + padX * 2.0f) / strideX) + 1;

            Real[] y = new Real[x.BatchCount * outputCount * outputHeight * outputWidth];

            for (int batchCounter = 0; batchCounter < x.BatchCount; batchCounter++)
            {
                int yBatchOffset = batchCounter * outputCount * outputHeight * outputWidth;
                int xBatchOffset = batchCounter * x.Length;

                for (int och = 0; och < outputCount; och++)
                {
                    int kOchOffset = och * inputCount * kernelHeight * kernelWidth;

                    int yChOffset = yBatchOffset + och * outputHeight * outputWidth;

                    for (int oy = 0; oy < outputHeight * strideY; oy += strideY)
                    {
                        int iyStart = oy - padY < 0 ? 0 : oy - padY;
                        int iyLimit = kernelHeight + oy - padY < x.Shape[1] ? kernelHeight + oy - padY : x.Shape[1];

                        for (int ox = 0; ox < outputWidth * strideX; ox += strideX)
                        {
                            int ixStart = ox - padX < 0 ? 0 : ox - padX;
                            int ixLimit = kernelWidth + ox - padX < x.Shape[2] ? kernelWidth + ox - padX : x.Shape[2];

                            int yIndex = yChOffset + oy / strideY * outputWidth + ox / strideX;

                            for (int ich = 0; ich < inputCount; ich++)
                            {
                                int kIchOffset = kOchOffset + ich * kernelHeight * kernelWidth;

                                int xChOffset = xBatchOffset + ich * x.Shape[1] * x.Shape[2];

                                for (int iy = iyStart; iy < iyLimit; iy++)
                                {
                                    for (int ix = ixStart; ix < ixLimit; ix++)
                                    {
                                        int wIndex = kIchOffset + (iy - oy + padY) * kernelWidth + ix - ox + padX;
                                        int xIndex = xChOffset + iy * x.Shape[2] + ix;

                                        y[yIndex] += x.Data[xIndex] * weight.Data[wIndex];
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (activation != null && bias != null)
            {
                for (int batchCounter = 0; batchCounter < x.BatchCount; batchCounter++)
                {
                    int resultIndex = batchCounter * outputCount * outputHeight * outputWidth;

                    for (int och = 0; och < outputCount; och++)
                    {
                        for (int location = 0; location < outputHeight * outputWidth; location++)
                        {
                            y[resultIndex] += bias.Data[och];
                            y[resultIndex]  = activation.ForwardActivate(y[resultIndex]);

                            resultIndex++;
                        }
                    }
                }
            }
            else if (bias != null)
            {
                for (int batchCounter = 0; batchCounter < x.BatchCount; batchCounter++)
                {
                    int resultIndex = batchCounter * outputCount * outputHeight * outputWidth;

                    for (int och = 0; och < outputCount; och++)
                    {
                        for (int location = 0; location < outputHeight * outputWidth; location++)
                        {
                            y[resultIndex] += bias.Data[och];
                            resultIndex++;
                        }
                    }
                }
            }
            else if (activation != null)
            {
                for (int i = 0; i < y.Length; i++)
                {
                    y[i] = activation.ForwardActivate(y[i]);
                }
            }

            return(NdArray.Convert(y, new[] { outputCount, outputHeight, outputWidth }, x.BatchCount, conv2d));
        }
예제 #4
0
        public static NdArray <Real> SingleInputForward(NdArray <Real> input, NdArray <Real> weight, NdArray <Real> bias, int strideX, int strideY, int padX, int padY, ICompressibleActivation <Real> activation, IFunction <Real> deconv2d)
        {
            int inputCount   = weight.Shape[0];
            int outputCount  = weight.Shape[1];
            int kernelHeight = weight.Shape[2];
            int kernelWidth  = weight.Shape[3];

            int outputHeight = (input.Shape[1] - 1) * strideY + kernelHeight - padY * 2;
            int outputWidth  = (input.Shape[2] - 1) * strideX + kernelWidth - padX * 2;

            Real[] result = new Real[input.BatchCount * outputCount * outputWidth * outputHeight];

            int outSizeOffset   = outputWidth * outputHeight;
            int inputSizeOffset = input.Shape[1] * input.Shape[2];
            int kSizeOffset     = weight.Shape[2] * weight.Shape[3];

            for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
            {
                for (int och = 0; och < outputCount; och++)
                {
                    for (int oy = padY; oy < outputHeight + padY; oy++)
                    {
                        int iyLimit = oy / strideY + 1 < input.Shape[1] ? oy / strideY + 1 : input.Shape[1];
                        int iyStart = oy - weight.Shape[2] < 0 ? 0 : (oy - weight.Shape[2]) / strideY + 1;

                        for (int ox = padX; ox < outputWidth + padX; ox++)
                        {
                            int ixLimit = ox / strideX + 1 < input.Shape[2] ? ox / strideX + 1 : input.Shape[2];
                            int ixStart = ox - weight.Shape[3] < 0 ? 0 : (ox - weight.Shape[3]) / strideX + 1;

                            int outputIndex = batchCount * outputCount * outSizeOffset + och * outSizeOffset + (oy - padY) * outputWidth + ox - padX;

                            for (int ich = 0; ich < input.Shape[0]; ich++)
                            {
                                int inputIndexOffset  = batchCount * input.Length + ich * inputSizeOffset;
                                int kernelIndexOffset = ich * weight.Shape[1] * kSizeOffset + och * kSizeOffset;

                                for (int iy = iyStart; iy < iyLimit; iy++)
                                {
                                    for (int ix = ixStart; ix < ixLimit; ix++)
                                    {
                                        int inputIndex  = inputIndexOffset + iy * input.Shape[2] + ix;
                                        int kernelIndex = kernelIndexOffset + (oy - iy * strideY) * weight.Shape[3] + (ox - ix * strideX);

                                        result[outputIndex] += input.Data[inputIndex] * weight.Data[kernelIndex];
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (activation != null && bias != null)
            {
                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    for (int och = 0; och < outputCount; och++)
                    {
                        for (int oy = padY; oy < outputHeight + padY; oy++)
                        {
                            for (int ox = padX; ox < outputWidth + padX; ox++)
                            {
                                int outputIndex = batchCount * outputCount * outSizeOffset + och * outSizeOffset + (oy - padY) * outputWidth + ox - padX;

                                result[outputIndex] += bias.Data[och];
                                result[outputIndex]  = activation.ForwardActivate(result[outputIndex]);
                            }
                        }
                    }
                }
            }
            else if (bias != null)
            {
                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    for (int och = 0; och < outputCount; och++)
                    {
                        for (int oy = padY; oy < outputHeight + padY; oy++)
                        {
                            for (int ox = padX; ox < outputWidth + padX; ox++)
                            {
                                int outputIndex = batchCount * outputCount * outSizeOffset + och * outSizeOffset + (oy - padY) * outputWidth + ox - padX;

                                result[outputIndex] += bias.Data[och];
                            }
                        }
                    }
                }
            }
            else if (activation != null)
            {
                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    for (int och = 0; och < outputCount; och++)
                    {
                        for (int oy = padY; oy < outputHeight + padY; oy++)
                        {
                            for (int ox = padX; ox < outputWidth + padX; ox++)
                            {
                                int outputIndex = batchCount * outputCount * outSizeOffset + och * outSizeOffset + (oy - padY) * outputWidth + ox - padX;

                                result[outputIndex] = activation.ForwardActivate(result[outputIndex]);
                            }
                        }
                    }
                }
            }

            return(NdArray.Convert(result, new[] { outputCount, outputHeight, outputWidth }, input.BatchCount, deconv2d));
        }