Example #1
0
        protected override NdArray NeedPreviousForwardCpu(NdArray x)
        {
            int outputHeight = (int)Math.Floor((x.Shape[1] - this._kHeight + this._padY * 2.0) / this._strideY) + 1;
            int outputWidth  = (int)Math.Floor((x.Shape[2] - this._kWidth + 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._kHeight * this._kWidth;

                    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._kHeight + oy - this._padY < x.Shape[1] ? this._kHeight + 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._kWidth + ox - this._padX < x.Shape[2] ? this._kWidth + 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._kHeight * this._kWidth;

                                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._kWidth + ix - ox + this._padX;
                                        int xIndex = xChOffset + iy * x.Shape[2] + ix;

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

            if (this.Activator != 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.Activator.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.Activator != null)
            {
                for (int i = 0; i < y.Length; i++)
                {
                    y[i] = this.Activator.ForwardActivate(y[i]);
                }
            }

            return(NdArray.Convert(y, new[] { this.OutputCount, outputHeight, outputWidth }, x.BatchCount, this));
        }
Example #2
0
        protected override NdArray NeedPreviousForwardCpu(NdArray input)
        {
            int outputHeight = (input.Shape[1] - 1) * this._strideY + this._kHeight - this._padY * 2;
            int outputWidth  = (input.Shape[2] - 1) * this._strideX + this._kWidth - 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.Activator != 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.Activator.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.Activator != 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.Activator.ForwardActivate(result[outputIndex]);
                            }
                        }
                    }
                }
            }

            return(NdArray.Convert(result, new[] { this.OutputCount, outputHeight, outputWidth }, input.BatchCount, this));
        }
        public override NdArray SingleInputForward(NdArray x)
        {
            if (Finetune)
            {
                N++;
                Decay = 1 - 1 / N;
            }

            int dataSize = x.Length / ChannelSize;

            //計算用パラメータの取得
            if (this.Train)
            {
                //メンバのMeanとVarianceを設定する
                this.Variance = new Real[this.ChannelSize];
                this.Mean     = new Real[this.ChannelSize];

                for (int i = 0; i < this.ChannelSize; i++)
                {
                    for (int b = 0; b < x.BatchCount; b++)
                    {
                        for (int location = 0; location < dataSize; location++)
                        {
                            this.Mean[i] += x.Data[b * x.Length + i * dataSize + location];
                        }
                    }

                    this.Mean[i] /= x.BatchCount * dataSize;

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

                    this.Variance[i] /= x.BatchCount * dataSize;
                }
            }
            else
            {
                this.Mean     = this.AvgMean.Data;
                this.Variance = this.AvgVar.Data;
            }

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

            //結果を計算
            this.Xhat = new Real[x.Data.Length];

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

            for (int i = 0; i < this.ChannelSize; i++)
            {
                for (int b = 0; b < x.BatchCount; b++)
                {
                    for (int location = 0; location < dataSize; location++)
                    {
                        int index = b * x.Length + 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];
                    }
                }
            }

            //パラメータを更新
            if (this.Train)
            {
                Real adjust = x.BatchCount / Math.Max(x.BatchCount - 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));
        }
Example #4
0
        protected override NdArray NeedPreviousForwardCpu(NdArray input)
        {
            int outputHeight = (int)Math.Floor((input.Shape[1] - this._kHeight + this._padY * 2.0) / this._strideY) + 1;
            int outputWidth  = (int)Math.Floor((input.Shape[2] - this._kWidth + this._padX * 2.0) / this._strideX) + 1;

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

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

                for (int och = 0; och < this.OutputCount; och++)
                {
                    //Wインデックス用
                    int outChOffset = och * this.InputCount * this._kHeight * this._kWidth;

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

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

                            for (int ich = 0; ich < this.InputCount; ich++)
                            {
                                //Wインデックス用
                                int inChOffset = ich * this._kHeight * this._kWidth;

                                //inputインデックス用
                                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 + this._padY) * this._kWidth + kx - ox + this._padX;
                                        int inputIndex = inputOffset + ky * input.Shape[2] + kx + batchCounter * input.Length;

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

                            resultIndex++;
                        }
                    }
                }
            }

            if (this.Activator != null && !NoBias)
            {
                for (int batchCounter = 0; batchCounter < input.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++)
                        {
                            result[resultIndex] += this.Bias.Data[och];
                            result[resultIndex]  = this.Activator.ForwardActivate(result[resultIndex]);

                            resultIndex++;
                        }
                    }
                }
            }
            else if (!NoBias)
            {
                for (int batchCounter = 0; batchCounter < input.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++)
                        {
                            result[resultIndex] += this.Bias.Data[och];
                            resultIndex++;
                        }
                    }
                }
            }
            else if (this.Activator != null)
            {
                for (int batchCounter = 0; batchCounter < input.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++)
                        {
                            result[resultIndex] = this.Activator.ForwardActivate(result[resultIndex]);
                            resultIndex++;
                        }
                    }
                }
            }

            return(NdArray.Convert(result, new[] { this.OutputCount, outputHeight, outputWidth }, input.BatchCount, this));
        }
Example #5
0
        public static NdArray <Real> SingleInputForward(NdArray <Real> x, bool train, NdArray <Real> gamma, NdArray <Real> beta, NdArray <Real> avgMean, NdArray <Real> avgVar, ref Real n, bool finetune, ref Real decay, Real Eps, out Real[] std, out Real[] xhat, int channelSize, IFunction <Real> batchNorm)
        {
            Real[] Mean;
            Real[] Variance;

            if (finetune)
            {
                n++;
                decay = 1 - 1 / n;
            }

            int dataSize = x.Length / channelSize;

            //計算用パラメータの取得
            if (train)
            {
                //メンバのMeanとVarianceを設定する
                Variance = new Real[channelSize];
                Mean     = new Real[channelSize];

                for (int i = 0; i < channelSize; i++)
                {
                    for (int b = 0; b < x.BatchCount; b++)
                    {
                        for (int location = 0; location < dataSize; location++)
                        {
                            Mean[i] += x.Data[b * x.Length + i * dataSize + location];
                        }
                    }

                    Mean[i] /= x.BatchCount * dataSize;

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

                    Variance[i] /= x.BatchCount * dataSize;
                }
            }
            else
            {
                Mean     = avgMean.Data;
                Variance = avgVar.Data;
            }

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

            //結果を計算
            xhat = new Real[x.Data.Length];

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


            for (int b = 0; b < x.BatchCount; b++)
            {
                for (int i = 0; i < channelSize; i++)
                {
                    for (int location = 0; location < dataSize; location++)
                    {
                        int index = b * x.Length + i * dataSize + location;
                        xhat[index] = (x.Data[index] - Mean[i]) / std[i];
                        y[index]    = gamma.Data[i] * xhat[index] + beta.Data[i];
                    }
                }
            }

            //パラメータを更新
            if (train)
            {
                Real adjust = x.BatchCount / Math.Max(x.BatchCount - 1, 1.0f); // unbiased estimation

                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, batchNorm));
        }
Example #6
0
        private TestDataSet <T> GetRandomData(int batchCount, Func <int> getIndexFunc)
        {
            T[]   data  = new T[NdArray.ShapeToLength(Shape) * batchCount];
            int[] label = new int[batchCount];

            for (int i = 0; i < batchCount; i++)
            {
                int index = getIndexFunc();

                T[] labeledData = Get(index);
                Array.Copy(labeledData, 0, data, i * labeledData.Length, labeledData.Length);

                label[i] = DataLabel[index];
            }

            TestDataSet <T> result = new TestDataSet <T>(NdArray.Convert(data, Shape, batchCount), NdArray.Convert(label, new[] { 1 }, batchCount));

            return(result);
        }
Example #7
0
        //全データを読み込む
        public TestDataSet <T> GetAllDataSet()
        {
            int batchCount = Data.Length;

            T[] data = new T[NdArray.ShapeToLength(Shape) * Data.Length];

            for (int i = 0; i < batchCount; i++)
            {
                T[] labeledData = Get(i);
                Array.Copy(labeledData, 0, data, i * labeledData.Length, labeledData.Length);
            }

            TestDataSet <T> result = new TestDataSet <T>(NdArray.Convert(data, Shape, batchCount), NdArray.Convert(DataLabel, new[] { 1 }, batchCount));

            return(result);
        }