Example #1
0
        /// <summary>
        /// Макс пул
        /// </summary>
        /// <param name="inp"></param>
        /// <param name="h"></param>
        /// <param name="w"></param>
        /// <returns></returns>
        public NNValue MaxPooling(NNValue input, int h, int w)
        {
            //Func<double[], double> funcMax = (dataArray) =>
            //{
            //    return dataArray.Max();
            //};

            int outpH = input.H / h, outpW = input.W / w, outpD = input.D;

            double[] data = new double[h * w];
            bool[,,] map = new bool[input.H, input.W, input.D];


            if ((outpW < 1) || (outpH < 1))
            {
                throw new Exception("Недостаточная размерность выхода");
            }

            int modW = input.W % w;
            int modH = input.H % h;

            int maxX = input.W - modW;
            int maxY = input.H - modH;

            NNValue returnObj = new NNValue(outpH, outpW, outpD);

            for (int s = 0; s < outpD; s++)
            {
                for (int y = 0, y1 = 0; y < maxY; y += h, y1++)
                {
                    for (int x = 0, x1 = 0; x < maxX; x += w, x1++)
                    {
                        int i = y, j = x;

                        for (int dy = 0; dy < h; dy++)
                        {
                            for (int dx = 0; dx < w; dx++)
                            {
                                if (input[i, j, s] < input[y + dy, x + dx, s])
                                {
                                    i = y + dy;
                                    j = x + dx;
                                }
                            }
                        }

                        var max = input[i, j, s];
                        returnObj[y1, x1, s] = max;

                        map[i, j, s] = true;
                    }
                }
            }
            ;
            //------------------------------------------------------------------------------------------

            // Обратный проход
            if (this.ApplyBackprop)
            {
                int i = 0;

                Runnable bp = new Runnable();
                bp.Run = delegate()
                {
                    for (int n = 0; n < input.D; n++)
                    {
                        for (int y = 0; y < input.H; y++)
                        {
                            for (int x = 0; x < input.W; x++)
                            {
                                input.DifData[input.W * y + x + input.W * input.H * n] = map[y, x, n]? returnObj.DifData[i++]:0;
                            }
                        }
                    }
                };
                Backprop.Add(bp);
            }
            return(returnObj);
        }
Example #2
0
        /// <summary>
        /// Свертка
        /// </summary>
        /// <param name="input">Тензор входа</param>
        /// <param name="filters">Фильтры</param>
        public NNValue Convolution(NNValue input, NNValue[] filters, int padX, int padY)
        {
            int outpH, outpW, outpD = filters.Length;


            outpH = input.H - filters[0].H + 1 + padY;
            outpW = input.W - filters[0].W + 1 + padX;

            if ((outpW < 1) || (outpH < 1))
            {
                throw new Exception("Недостаточная размерность выхода");
            }


            NNValue returnObj = new NNValue(outpH, outpW, outpD);

            //  Parallel.For(0, outpD, new ParallelOptions() { MaxDegreeOfParallelism = 2}, s =>
            for (int s = 0; s < outpD; s++)
            {
                for (int y = -padY; y < outpH; y++)
                {
                    for (int x = -padX; x < outpW; x++)
                    {
                        for (int z = 0; z < input.D; z++)
                        {
                            for (int dy = 0; dy < filters[0].H; dy++)
                            {
                                int y1 = y + dy;

                                for (int dx = 0; dx < filters[0].W; dx++)
                                {
                                    int x1 = x + dx;
                                    if ((x1 > -1) && (y1 > -1) && (x1 < outpW) && (y1 < outpH))
                                    {
                                        returnObj[y1, x1, s] += input[y + dy, x + dx, z] * filters[s][dy, dx, z];
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //------------------------------------------------------------------------------------------



            // Обратный проход
            if (this.ApplyBackprop)
            {
                Runnable bp = new Runnable();
                bp.Run = delegate()
                {
                    Parallel.For(0, outpD, new ParallelOptions()
                    {
                        MaxDegreeOfParallelism = 2
                    }, d =>
                    {
                        for (int z = 0; z < input.D; z++)
                        {
                            for (int y = 0; y < filters[0].H; y++)
                            {
                                for (int x = 0; x < filters[0].W; x++)
                                {
                                    for (int a = -padY; a < outpH; a++)
                                    {
                                        for (int b = -padX; b < outpW; b++)
                                        {
                                            int x1 = b + x;
                                            int y1 = a + y;

                                            if ((y1 > -1) && (x1 > -1) && (y1 < outpH) && (x1 < outpW))
                                            {
                                                double delt = returnObj.DifData[outpW * y1 + x1 + outpW * outpH * d];
                                                filters[d].DifData[filters[0].W * y + x + filters[0].W * filters[0].H * z] +=
                                                    delt * input[a + y, b + x, z];
                                            }
                                            // --------------- ------------- ------------ ---------------//
                                        }
                                    }
                                }
                            }
                        }
                    });

                    Parallel.For(0, input.D, new ParallelOptions()
                    {
                        MaxDegreeOfParallelism = 2
                    }, n =>
                    {
                        for (int y = -padY; y < input.H; y++)
                        {
                            for (int x = -padX; x < input.W; x++)
                            {
                                for (int i = 0; i < outpD; i++)
                                {
                                    for (int dy = 0; dy < filters[0].H; dy++)
                                    {
                                        var dyy = y - dy;
                                        for (int dx = 0; dx < filters[0].W; dx++)
                                        {
                                            var dxx = x - dx;
                                            if ((dyy > -1) && (dxx > -1) && (dyy < outpH) && (dxx < outpW))
                                            {
                                                if ((dxx > -1) && (dyy > -1) && (dyy < outpH) && (dxx < outpW))
                                                {
                                                    double delt = returnObj.DifData[outpW * (y - dy) + (x - dx) + outpW * outpH * i];
                                                    input.DifData[input.W * y + x + input.W * input.H * n] += delt * filters[i][dy, dx, n];
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    });
                };
                Backprop.Add(bp);
            }
            return(returnObj);
        }