Exemple #1
0
        public override NdArray SingleInputForward(NdArray input)
        {
            int outputHeight = (input.Shape[1] - 1) * this.StrideY + this.KernelHeight - this.PadY * 2;
            int outputWidth  = (input.Shape[2] - 1) * this.StrideX + this.KernelWidth - this.PadX * 2;

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

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

            for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
            {
                for (int och = 0; och < this.OutputCount; och++)
                {
                    for (int oy = this.PadY; oy < outputHeight + this.PadY; oy++)
                    {
                        int iyLimit = oy / this.StrideY + 1 < input.Shape[1] ? oy / this.StrideY + 1 : input.Shape[1];
                        int iyStart = oy - this.Weight.Shape[2] < 0 ? 0 : (oy - this.Weight.Shape[2]) / this.StrideY + 1;

                        for (int ox = this.PadX; ox < outputWidth + this.PadX; ox++)
                        {
                            int ixLimit = ox / this.StrideX + 1 < input.Shape[2] ? ox / this.StrideX + 1 : input.Shape[2];
                            int ixStart = ox - this.Weight.Shape[3] < 0 ? 0 : (ox - this.Weight.Shape[3]) / this.StrideX + 1;

                            int outputIndex = batchCount * this.OutputCount * outSizeOffset + och * outSizeOffset + (oy - this.PadY) * outputWidth + ox - this.PadX;

                            for (int ich = 0; ich < input.Shape[0]; ich++)
                            {
                                int inputIndexOffset  = batchCount * input.Length + ich * inputSizeOffset;
                                int kernelIndexOffset = ich * this.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 * this.StrideY) * this.Weight.Shape[3] + (ox - ix * this.StrideX);

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

            if (this.Activation != null && !NoBias)
            {
                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    for (int och = 0; och < this.OutputCount; och++)
                    {
                        for (int oy = this.PadY; oy < outputHeight + this.PadY; oy++)
                        {
                            for (int ox = this.PadX; ox < outputWidth + this.PadX; ox++)
                            {
                                int outputIndex = batchCount * this.OutputCount * outSizeOffset + och * outSizeOffset + (oy - this.PadY) * outputWidth + ox - this.PadX;

                                result[outputIndex] += this.Bias.Data[och];
                                result[outputIndex]  = this.Activation.ForwardActivate(result[outputIndex]);
                            }
                        }
                    }
                }
            }
            else if (!NoBias)
            {
                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    for (int och = 0; och < this.OutputCount; och++)
                    {
                        for (int oy = this.PadY; oy < outputHeight + this.PadY; oy++)
                        {
                            for (int ox = this.PadX; ox < outputWidth + this.PadX; ox++)
                            {
                                int outputIndex = batchCount * this.OutputCount * outSizeOffset + och * outSizeOffset + (oy - this.PadY) * outputWidth + ox - this.PadX;

                                result[outputIndex] += this.Bias.Data[och];
                            }
                        }
                    }
                }
            }
            else if (this.Activation != null)
            {
                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    for (int och = 0; och < this.OutputCount; och++)
                    {
                        for (int oy = this.PadY; oy < outputHeight + this.PadY; oy++)
                        {
                            for (int ox = this.PadX; ox < outputWidth + this.PadX; ox++)
                            {
                                int outputIndex = batchCount * this.OutputCount * outSizeOffset + och * outSizeOffset + (oy - this.PadY) * outputWidth + ox - this.PadX;

                                result[outputIndex] = this.Activation.ForwardActivate(result[outputIndex]);
                            }
                        }
                    }
                }
            }

            return(NdArray.Convert(result, new[] { this.OutputCount, outputHeight, outputWidth }, input.BatchCount, this));
        }
        protected override NdArray NeedPreviousForwardCpu([NotNull] NdArray input)
        {
            int outputHeight = (input.Shape[1] - 1) * _subSampleY + _kHeight - _trimY * 2;
            int outputWidth  = (input.Shape[2] - 1) * _subSampleX + _kWidth - _trimX * 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 = _trimY; oy < outputHeight + _trimY; oy++)
                    {
                        int iyLimit = oy / _subSampleY + 1 < input.Shape[1] ? oy / _subSampleY + 1 : input.Shape[1];
                        int iyStart = oy - Weight.Shape[2] < 0 ? 0 : (oy - Weight.Shape[2]) / _subSampleY + 1;

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

                            int outputIndex = batchCount * OutputCount * outSizeOffset + och * outSizeOffset + (oy - _trimY) * outputWidth + ox - _trimX;

                            for (int ich = 0; ich < input.Shape[0]; ich++)
                            {
                                int inputIndexOffset  = batchCount * input.Length + ich * inputSizeOffset;
                                int kernelIndexOffset = och * Weight.Shape[1] * kSizeOffset + ich * 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 * _subSampleY) * Weight.Shape[3] + (ox - ix * _subSampleX);

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

            if (Activator != null && !NoBias)
            {
                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    for (int och = 0; och < OutputCount; och++)
                    {
                        for (int oy = _trimY; oy < outputHeight + _trimY; oy++)
                        {
                            for (int ox = _trimX; ox < outputWidth + _trimX; ox++)
                            {
                                int outputIndex = batchCount * OutputCount * outSizeOffset + och * outSizeOffset + (oy - _trimY) * outputWidth + ox - _trimX;

                                result[outputIndex] += Bias.Data[och];
                                result[outputIndex]  = Activator.ForwardActivate(result[outputIndex]);
                            }
                        }
                    }
                }
            }
            else if (!NoBias)
            {
                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    for (int och = 0; och < OutputCount; och++)
                    {
                        for (int oy = _trimY; oy < outputHeight + _trimY; oy++)
                        {
                            for (int ox = _trimX; ox < outputWidth + _trimX; ox++)
                            {
                                int outputIndex = batchCount * OutputCount * outSizeOffset + och * outSizeOffset + (oy - _trimY) * outputWidth + ox - _trimX;

                                result[outputIndex] += Bias.Data[och];
                            }
                        }
                    }
                }
            }
            else if (Activator != null)
            {
                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    for (int och = 0; och < OutputCount; och++)
                    {
                        for (int oy = _trimY; oy < outputHeight + _trimY; oy++)
                        {
                            for (int ox = _trimX; ox < outputWidth + _trimX; ox++)
                            {
                                int outputIndex = batchCount * OutputCount * outSizeOffset + och * outSizeOffset + (oy - _trimY) * outputWidth + ox - _trimX;

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

            return(NdArray.Convert(result, new[] { OutputCount, outputHeight, outputWidth }, input.BatchCount, this));
        }
Exemple #3
0
        public NdArray ForwardCpu(params NdArray[] xs)
        {
            Real[] result = new Real[xs[0].Data.Length];

            switch (_operation)
            {
            case EltwiseParameter.EltwiseOp.Prod:
                Array.Copy(xs[0].Data, result, result.Length);
                for (int i = 1; i < xs.Length; i++)
                {
                    for (int j = 0; j < result.Length; j++)
                    {
                        result[j] *= xs[i].Data[j];
                    }
                }
                break;

            case EltwiseParameter.EltwiseOp.Sum:
                if (this._coeffs != null)
                {
                    for (int i = 0; i < xs.Length; i++)
                    {
                        for (int j = 0; j < result.Length; j++)
                        {
                            result[j] += xs[i].Data[j] * _coeffs[i];
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < xs.Length; i++)
                    {
                        for (int j = 0; j < result.Length; j++)
                        {
                            result[j] += xs[i].Data[j];
                        }
                    }
                }
                break;

            case EltwiseParameter.EltwiseOp.Max:
                Array.Copy(xs[0].Data, result, result.Length);
                int[] outputIndex = new int[result.Length];

                for (int i = 1; i < xs.Length; i++)
                {
                    for (int j = 0; j < result.Length; j++)
                    {
                        if (result[j] < xs[i].Data[j])
                        {
                            outputIndex[j] = i;
                            result[j]      = xs[i].Data[j];
                        }
                    }
                }

                PrevOutputIndex.Add(outputIndex);
                break;
            }

            return(NdArray.Convert(result, xs[0].Shape, xs[0].BatchCount, this));
        }
        private NdArray ForwardCpu(NdArray x)
        {
            //Acquisition of calculation parameters
            if (this.IsTrain)
            {
                //Set Mean and Variance of members
                this.Variance = new Real[this.ChannelSize];
                for (int i = 0; i < this.Variance.Length; i++)
                {
                    this.Variance[i] = 0;
                }

                this.Mean = new Real[this.ChannelSize];
                for (int i = 0; i < this.Mean.Length; i++)
                {
                    for (int index = 0; index < x.BatchCount; index++)
                    {
                        this.Mean[i] += x.Data[i + index * x.Length];
                    }

                    this.Mean[i] /= x.BatchCount;
                }

                for (int i = 0; i < this.Mean.Length; i++)
                {
                    for (int index = 0; index < x.BatchCount; index++)
                    {
                        this.Variance[i] += (x.Data[i + index * x.Length] - this.Mean[i]) * (x.Data[i + index * x.Length] - this.Mean[i]);
                    }

                    this.Variance[i] /= x.BatchCount;
                }

                for (int i = 0; i < this.Variance.Length; i++)
                {
                    this.Variance[i] += this.Eps;
                }
            }
            else
            {
                this.Mean     = this.AvgMean.Data;
                this.Variance = this.AvgVar.Data;
            }

            this.Std = new Real[this.Variance.Length];
            for (int i = 0; i < this.Variance.Length; i++)
            {
                this.Std[i] = Math.Sqrt(this.Variance[i]);
            }

            //Calculate result
            this.Xhat = new Real[x.Data.Length];

            Real[] y = new Real[x.Data.Length];

            int dataSize = 1;

            for (int i = 1; i < x.Shape.Length; i++)
            {
                dataSize *= x.Shape[i];
            }

            for (int batchCount = 0; batchCount < x.BatchCount; batchCount++)
            {
                for (int i = 0; i < this.ChannelSize; i++)
                {
                    for (int location = 0; location < dataSize; location++)
                    {
                        int index = batchCount * this.ChannelSize * dataSize + i * dataSize + location;
                        this.Xhat[index] = (x.Data[index] - this.Mean[i]) / this.Std[i];
                        y[index]         = this.Gamma.Data[i] * this.Xhat[index] + this.Beta.Data[i];
                    }
                }
            }

            //Update parameters
            if (this.IsTrain)
            {
                int  m      = x.BatchCount;
                Real adjust = m / Math.Max(m - 1.0, 1.0); //unbiased estimation

                for (int i = 0; i < this.AvgMean.Data.Length; i++)
                {
                    this.AvgMean.Data[i] *= this.Decay;
                    this.Mean[i]         *= 1 - this.Decay; //reuse buffer as a temporary
                    this.AvgMean.Data[i] += this.Mean[i];

                    this.AvgVar.Data[i] *= this.Decay;
                    this.Variance[i]    *= (1 - this.Decay) * adjust; //reuse buffer as a temporary
                    this.AvgVar.Data[i] += this.Variance[i];
                }
            }

            return(NdArray.Convert(y, x.Shape, x.BatchCount, this));
        }
Exemple #5
0
        protected override NdArray NeedPreviousForwardCpu(NdArray input)
        {
            int outputHeight = (int)Math.Floor((input.Shape[1] - _kHeight + _padY * 2.0) / _strideY) + 1;
            int outputWidth  = (int)Math.Floor((input.Shape[2] - _kWidth + _padX * 2.0) / _strideX) + 1;

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

            for (int batchCounter = 0; batchCounter < input.BatchCount; batchCounter++)
            {
                int resultIndex = batchCounter * OutputCount * outputHeight * outputWidth;

                for (int och = 0; och < OutputCount; och++)
                {
                    //For W index
                    int outChOffset = och * InputCount * _kHeight * _kWidth;

                    for (int oy = 0; oy < outputHeight * _strideY; oy += _strideY)
                    {
                        int kyStartIndex = oy - _padY < 0 ? 0 : oy - _padY;
                        int kyLimit      = _kHeight + oy - _padY < input.Shape[1] ? _kHeight + oy - _padY : input.Shape[1];

                        for (int ox = 0; ox < outputWidth * _strideX; ox += _strideX)
                        {
                            int kxStartIndex = ox - _padX < 0 ? 0 : ox - _padX;
                            int kxLimit      = _kWidth + ox - _padX < input.Shape[2] ? _kWidth + ox - _padX : input.Shape[2];

                            for (int ich = 0; ich < InputCount; ich++)
                            {
                                //For W index
                                int inChOffset = ich * _kHeight * _kWidth;

                                //For input index
                                int inputOffset = ich * input.Shape[1] * input.Shape[2];

                                for (int ky = kyStartIndex; ky < kyLimit; ky++)
                                {
                                    for (int kx = kxStartIndex; kx < kxLimit; kx++)
                                    {
                                        int wIndex     = outChOffset + inChOffset + (ky - oy + _padY) * _kWidth + kx - ox + _padX;
                                        int inputIndex = inputOffset + ky * input.Shape[2] + kx + batchCounter * input.Length;

                                        result[resultIndex] += input.Data[inputIndex] * Weight.Data[wIndex];
                                    }
                                }
                            }

                            resultIndex++;
                        }
                    }
                }
            }

            if (Activator != null && !NoBias)
            {
                for (int batchCounter = 0; batchCounter < input.BatchCount; batchCounter++)
                {
                    int resultIndex = batchCounter * OutputCount * outputHeight * outputWidth;

                    for (int och = 0; och < OutputCount; och++)
                    {
                        for (int location = 0; location < outputHeight * outputWidth; location++)
                        {
                            result[resultIndex] += Bias.Data[och];
                            result[resultIndex]  = Activator.ForwardActivate(result[resultIndex]);

                            resultIndex++;
                        }
                    }
                }
            }
            else if (!NoBias)
            {
                for (int batchCounter = 0; batchCounter < input.BatchCount; batchCounter++)
                {
                    int resultIndex = batchCounter * OutputCount * outputHeight * outputWidth;

                    for (int och = 0; och < OutputCount; och++)
                    {
                        for (int location = 0; location < outputHeight * outputWidth; location++)
                        {
                            result[resultIndex] += Bias.Data[och];
                            resultIndex++;
                        }
                    }
                }
            }
            else if (Activator != null)
            {
                for (int batchCounter = 0; batchCounter < input.BatchCount; batchCounter++)
                {
                    int resultIndex = batchCounter * OutputCount * outputHeight * outputWidth;

                    for (int och = 0; och < OutputCount; och++)
                    {
                        for (int location = 0; location < outputHeight * outputWidth; location++)
                        {
                            result[resultIndex] = Activator.ForwardActivate(result[resultIndex]);
                            resultIndex++;
                        }
                    }
                }
            }

            return(NdArray.Convert(result, new[] { OutputCount, outputHeight, outputWidth }, input.BatchCount, this));
        }
Exemple #6
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));
        }
Exemple #7
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));
        }
Exemple #8
0
        public static NdArray <Real>[] MultiInputForward(NdArray <Real>[] xs, EltwiseParameter.EltwiseOp operation, float[] coeffs, List <int[]> PrevOutputIndex, IFunction <Real> eltwise)
        {
            Real[] result = new Real[xs[0].Data.Length];

            switch (operation)
            {
            case EltwiseParameter.EltwiseOp.Prod:
                Array.Copy(xs[0].Data, result, result.Length);
                for (int i = 1; i < xs.Length; i++)
                {
                    for (int j = 0; j < result.Length; j++)
                    {
                        result[j] *= xs[i].Data[j];
                    }
                }
                break;

            case EltwiseParameter.EltwiseOp.Sum:
                if (coeffs != null)
                {
                    for (int i = 0; i < xs.Length; i++)
                    {
                        for (int j = 0; j < result.Length; j++)
                        {
                            result[j] += xs[i].Data[j] * coeffs[i];
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < xs.Length; i++)
                    {
                        for (int j = 0; j < result.Length; j++)
                        {
                            result[j] += xs[i].Data[j];
                        }
                    }
                }
                break;

            case EltwiseParameter.EltwiseOp.Max:
                Array.Copy(xs[0].Data, result, result.Length);
                int[] outputIndex = new int[result.Length];

                for (int i = 1; i < xs.Length; i++)
                {
                    for (int j = 0; j < result.Length; j++)
                    {
                        if (result[j] < xs[i].Data[j])
                        {
                            outputIndex[j] = i;
                            result[j]      = xs[i].Data[j];
                        }
                    }
                }

                PrevOutputIndex.Add(outputIndex);
                break;
            }

            return(new [] { NdArray.Convert(result, xs[0].Shape, xs[0].BatchCount, eltwise) });
        }
Exemple #9
0
        private NdArray ForwardCpu([NotNull] NdArray x)
        {
            // Acquire parameters for calculation
            if (IsTrain)
            {
                // Set Mean and Variance of member
                Variance = new Real[ChannelSize];
                for (int i = 0; i < Variance.Length; i++)
                {
                    Variance[i] = 0;
                }

                Mean = new Real[ChannelSize];
                for (int i = 0; i < Mean.Length; i++)
                {
                    for (int index = 0; index < x.BatchCount; index++)
                    {
                        Mean[i] += x.Data[i + index * x.Length];
                    }

                    Mean[i] /= x.BatchCount;
                }

                for (int i = 0; i < Mean.Length; i++)
                {
                    for (int index = 0; index < x.BatchCount; index++)
                    {
                        Variance[i] += (x.Data[i + index * x.Length] - Mean[i]) * (x.Data[i + index * x.Length] - Mean[i]);
                    }

                    Variance[i] /= x.BatchCount;
                }

                for (int i = 0; i < Variance.Length; i++)
                {
                    Variance[i] += Eps;
                }
            }
            else
            {
                Mean     = AvgMean.Data;
                Variance = AvgVar.Data;
            }

            Std = new Real[Variance.Length];
            for (int i = 0; i < Variance.Length; i++)
            {
                Std[i] = Math.Sqrt(Variance[i]);
            }

            // Calculate result
            Xhat = new Real[x.Data.Length];

            Real[] y = new Real[x.Data.Length];

            int dataSize = 1;

            for (int i = 1; i < x.Shape.Length; i++)
            {
                dataSize *= x.Shape[i];
            }

            for (int batchCount = 0; batchCount < x.BatchCount; batchCount++)
            {
                for (int i = 0; i < ChannelSize; i++)
                {
                    for (int location = 0; location < dataSize; location++)
                    {
                        int index = batchCount * ChannelSize * dataSize + i * dataSize + location;
                        Xhat[index] = (x.Data[index] - Mean[i]) / Std[i];
                        y[index]    = Gamma.Data[i] * Xhat[index] + Beta.Data[i];
                    }
                }
            }

            // Update parameters
            if (IsTrain)
            {
                int  m      = x.BatchCount;
                Real adjust = m / Math.Max(m - 1.0, 1.0); // unbiased estimation
                if (Verbose)
                {
                    RILogManager.Default?.ViewerSendWatch("Unbiased Estimation", adjust);
                }

                for (int i = 0; i < AvgMean.Data.Length; i++)
                {
                    AvgMean.Data[i] *= Decay;
                    Mean[i]         *= 1 - Decay; // reuse buffer as a temporary
                    AvgMean.Data[i] += Mean[i];
                    AvgVar.Data[i]  *= Decay;
                    Variance[i]     *= (1 - Decay) * adjust; // reuse buffer as a temporary
                    AvgVar.Data[i]  += Variance[i];
                }
            }

            return(NdArray.Convert(y, x.Shape, x.BatchCount, this));
        }
        public override NdArray SingleInputForward(NdArray x)
        {
            int outputHeight = (int)Math.Floor((x.Shape[1] - this.KernelHeight + this.PadY * 2.0) / this.StrideY) + 1;
            int outputWidth  = (int)Math.Floor((x.Shape[2] - this.KernelWidth + this.PadX * 2.0) / this.StrideX) + 1;

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

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

                for (int och = 0; och < this.OutputCount; och++)
                {
                    int kOchOffset = och * this.InputCount * this.KernelHeight * this.KernelWidth;

                    int yChOffset = yBatchOffset + och * outputHeight * outputWidth;

                    for (int oy = 0; oy < outputHeight * this.StrideY; oy += this.StrideY)
                    {
                        int iyStart = oy - this.PadY < 0 ? 0 : oy - this.PadY;
                        int iyLimit = this.KernelHeight + oy - this.PadY < x.Shape[1] ? this.KernelHeight + oy - this.PadY : x.Shape[1];

                        for (int ox = 0; ox < outputWidth * this.StrideX; ox += this.StrideX)
                        {
                            int ixStart = ox - this.PadX < 0 ? 0 : ox - this.PadX;
                            int ixLimit = this.KernelWidth + ox - this.PadX < x.Shape[2] ? this.KernelWidth + ox - this.PadX : x.Shape[2];

                            int yIndex = yChOffset + oy / this.StrideY * outputWidth + ox / this.StrideX;

                            for (int ich = 0; ich < this.InputCount; ich++)
                            {
                                int kIchOffset = kOchOffset + ich * this.KernelHeight * this.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 + this.PadY) * this.KernelWidth + ix - ox + this.PadX;
                                        int xIndex = xChOffset + iy * x.Shape[2] + ix;

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

            if (this.Activation != null && !NoBias)
            {
                for (int batchCounter = 0; batchCounter < x.BatchCount; batchCounter++)
                {
                    int resultIndex = batchCounter * this.OutputCount * outputHeight * outputWidth;

                    for (int och = 0; och < this.OutputCount; och++)
                    {
                        for (int location = 0; location < outputHeight * outputWidth; location++)
                        {
                            y[resultIndex] += this.Bias.Data[och];
                            y[resultIndex]  = this.Activation.ForwardActivate(y[resultIndex]);

                            resultIndex++;
                        }
                    }
                }
            }
            else if (!NoBias)
            {
                for (int batchCounter = 0; batchCounter < x.BatchCount; batchCounter++)
                {
                    int resultIndex = batchCounter * this.OutputCount * outputHeight * outputWidth;

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

            return(NdArray.Convert(y, new[] { this.OutputCount, outputHeight, outputWidth }, x.BatchCount, this));
        }