public override Vol forward(Vol V, bool is_training)
        {
            this.in_act = V;
            var N  = this.out_depth;
            var V2 = new Vol(this.out_sx, this.out_sy, this.out_depth, 0.0);

            // optimization branch. If we're operating on 1D arrays we dont have
            // to worry about keeping track of x,y,d coordinates inside
            // input volumes. In convnets we do :(
            if (this.out_sx == 1 && this.out_sy == 1)
            {
                for (var i = 0; i < N; i++)
                {
                    var ix = i * this.group_size; // base index offset
                    var a  = V.w[ix];
                    var ai = 0;
                    for (var j = 1; j < this.group_size; j++)
                    {
                        var a2 = V.w[ix + j];
                        if (a2 > a)
                        {
                            a  = a2;
                            ai = j;
                        }
                    }
                    V2.w[i]          = a;
                    this.switches[i] = ix + ai;
                }
            }
            else
            {
                var n = 0; // counter for switches
                for (var x = 0; x < V.sx; x++)
                {
                    for (var y = 0; y < V.sy; y++)
                    {
                        for (var i = 0; i < N; i++)
                        {
                            var ix = i * this.group_size;
                            var a  = V.get(x, y, ix);
                            var ai = 0;
                            for (var j = 1; j < this.group_size; j++)
                            {
                                var a2 = V.get(x, y, ix + j);
                                if (a2 > a)
                                {
                                    a  = a2;
                                    ai = j;
                                }
                            }
                            V2.set(x, y, i, a);
                            this.switches[n] = ix + ai;
                            n++;
                        }
                    }
                }
            }
            this.out_act = V2;
            return(this.out_act);
        }
Example #2
0
        public static Vol img_to_vol(Bitmap img, bool convert_grayscale)
        {
            ImageConverter converter = new ImageConverter();

            var            p  = (byte[])converter.ConvertTo(img, typeof(byte[]));
            var            W  = img.Width;
            var            H  = img.Height;
            Stack <double> pv = new Stack <double>();

            for (var i = 0; i < p.Length; i++)
            {
                pv.Push(p[i] / 255.0 - 0.5); // normalize image pixels to [-0.5, 0.5]
            }
            var x = new Vol(W, H, 4, 0.0);   //input volume (image)

            x.w = pv.ToArray();

            if (convert_grayscale)
            {
                // flatten into depth=1 array
                var x1 = new Vol(W, H, 1, 0.0);
                for (var i = 0; i < W; i++)
                {
                    for (var j = 0; j < H; j++)
                    {
                        x1.set(i, j, 0, x.get(i, j, 0));
                    }
                }
                x = x1;
            }


            return(x);
        }
Example #3
0
        public override Vol forward(Vol V, bool is_training)
        {
            this.in_act = V;

            var A = new Vol(this.out_sx, this.out_sy, this.out_depth, 0.0);

            var n = 0; // a counter for switches

            for (var d = 0; d < this.out_depth; d++)
            {
                var x = -this.pad;
                var y = -this.pad;
                for (var ax = 0; ax < this.out_sx; x += this.stride, ax++)
                {
                    y = -this.pad;
                    for (var ay = 0; ay < this.out_sy; y += this.stride, ay++)
                    {
                        // convolve centered at this particular location
                        double a = -99999; // hopefully small enough ;\
                        int    winx = -1, winy = -1;
                        for (var fx = 0; fx < this.sx; fx++)
                        {
                            for (var fy = 0; fy < this.sy; fy++)
                            {
                                var oy = y + fy;
                                var ox = x + fx;
                                if (oy >= 0 && oy < V.sy && ox >= 0 && ox < V.sx)
                                {
                                    var v = V.get(ox, oy, d);
                                    // perform max pooling and store pointers to where
                                    // the max came from. This will speed up backprop
                                    // and can help make nice visualizations in future
                                    if (v > a)
                                    {
                                        a = v; winx = ox; winy = oy;
                                    }
                                }
                            }
                        }
                        this.switchx[n] = winx;
                        this.switchy[n] = winy;
                        n++;
                        A.set(ax, ay, d, a);
                    }
                }
            }
            this.out_act = A;
            return(this.out_act);
        }
        public override Vol forward(Vol V, bool is_training)
        {
            // optimized code by @mdda that achieves 2x speedup over previous version

            this.in_act = V;
            var A = new Vol(this.out_sx | 0, this.out_sy | 0, this.out_depth | 0, 0.0);

            var V_sx      = V.sx | 0;
            var V_sy      = V.sy | 0;
            var xy_stride = this.stride | 0;

            for (var d = 0; d < this.out_depth; d++)
            {
                var f = this.filters[d];
                var x = -this.pad | 0;
                var y = -this.pad | 0;
                for (var ay = 0; ay < this.out_sy; y += xy_stride, ay++) // xy_stride
                {
                    x = -this.pad | 0;
                    for (var ax = 0; ax < this.out_sx; x += xy_stride, ax++) // xy_stride

                    // convolve centered at this particular location
                    {
                        var a = 0.0;
                        for (var fy = 0; fy < f.sy; fy++)
                        {
                            var oy = y + fy; // coordinates in the original input array coordinates
                            for (var fx = 0; fx < f.sx; fx++)
                            {
                                var ox = x + fx;
                                if (oy >= 0 && oy < V_sy && ox >= 0 && ox < V_sx)
                                {
                                    for (var fd = 0; fd < f.depth; fd++)
                                    {
                                        // avoid function call overhead (x2) for efficiency, compromise modularity :(
                                        a += f.w[((f.sx * fy) + fx) * f.depth + fd] * V.w[((V_sx * oy) + ox) * V.depth + fd];
                                    }
                                }
                            }
                        }
                        a += this.biases.w[d];
                        A.set(ax, ay, d, a);
                    }
                }
            }
            this.out_act = A;
            return(this.out_act);
        }