Exemplo n.º 1
0
        public static TrivectorMap1D Reference(TrivectorMap1D x, Quaternion.QuaternionFilter1D w, int kwidth, int stride)
        {
            int inchannels = x.Channels, outchannels = w.OutChannels, batch = x.Batch;
            int inw  = x.Width;
            int outw = (inw - kwidth) / stride + 1;

            TrivectorMap1D y = new TrivectorMap1D(outchannels, outw, batch);

            for (int kx = 0; kx < kwidth; kx++)
            {
                for (int th = 0; th < batch; th++)
                {
                    for (int ox = 0; ox < outw; ox++)
                    {
                        for (int outch = 0; outch < outchannels; outch++)
                        {
                            Trivector sum = y[outch, ox, th];

                            for (int inch = 0; inch < inchannels; inch++)
                            {
                                sum += x[inch, kx + ox * stride, th] * w[inch, outch, kx];
                            }

                            y[outch, ox, th] = sum;
                        }
                    }
                }
            }

            return(y);
        }
Exemplo n.º 2
0
        public void ReferenceTest()
        {
            int inchannels = 9, outchannels = 12, kwidth = 3, stride = 2, inwidth = 7, batch = 3;
            int outwidth = (inwidth - kwidth) / stride + 1;

            float[] yval = (new float[outwidth * outchannels * batch]).Select((_, idx) => idx * 1e-3f).ToArray();
            float[] wval = (new float[kwidth * outchannels * inchannels / 9 * 4]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

            Trivector[] ycval = (new Trivector[yval.Length / 3])
                                .Select((_, idx) => new Trivector(yval[idx * 3], yval[idx * 3 + 1], yval[idx * 3 + 2])).ToArray();

            Quaternion.Quaternion[] wcval = (new Quaternion.Quaternion[wval.Length / 4])
                                            .Select((_, idx) => new Quaternion.Quaternion(wval[idx * 4], wval[idx * 4 + 1], wval[idx * 4 + 2], wval[idx * 4 + 3])).ToArray();

            TrivectorMap1D y = new TrivectorMap1D(outchannels / 3, outwidth, batch, ycval);

            Quaternion.QuaternionFilter1D w = new Quaternion.QuaternionFilter1D(inchannels / 3, outchannels / 3, kwidth, wcval);

            TrivectorMap1D x = Reference(y, w, inwidth, kwidth, stride);

            float[] x_expect =
            {
                1.443468000e-03f, 9.190920000e-04f, 1.172196000e-03f, 1.347564000e-03f, 8.553480000e-04f, 1.092708000e-03f,
                1.254988000e-03f, 7.939080000e-04f, 1.016036000e-03f, 5.122680000e-04f, 3.062280000e-04f, 4.041960000e-04f,
                4.563000000e-04f, 2.701320000e-04f, 3.585000000e-04f, 4.036600000e-04f, 2.363400000e-04f, 3.156200000e-04f,
                4.514232000e-03f, 3.883272000e-03f, 4.153512000e-03f, 4.214136000e-03f, 3.625224000e-03f, 3.876264000e-03f,
                3.926840000e-03f, 3.377928000e-03f, 3.610792000e-03f, 1.670316000e-03f, 1.420500000e-03f, 1.519044000e-03f,
                1.499916000e-03f, 1.272276000e-03f, 1.361220000e-03f, 1.338988000e-03f, 1.132500000e-03f, 1.212356000e-03f,
                7.715064000e-03f, 6.996552000e-03f, 7.267944000e-03f, 7.186104000e-03f, 6.514248000e-03f, 6.766440000e-03f,
                6.682232000e-03f, 6.054984000e-03f, 6.289000000e-03f, 2.828364000e-03f, 2.534772000e-03f, 2.633892000e-03f,
                2.543532000e-03f, 2.274420000e-03f, 2.363940000e-03f, 2.274316000e-03f, 2.028660000e-03f, 2.109092000e-03f,
                4.410360000e-04f, 3.736200000e-04f, 3.913320000e-04f, 3.435960000e-04f, 2.883720000e-04f, 3.026280000e-04f,
                2.617720000e-04f, 2.177160000e-04f, 2.290280000e-04f, 1.047486000e-02f, 9.736212000e-03f, 9.991044000e-03f,
                9.814476000e-03f, 9.114900000e-03f, 9.353988000e-03f, 9.175852000e-03f, 8.514324000e-03f, 8.738180000e-03f,
                3.986412000e-03f, 3.649044000e-03f, 3.748740000e-03f, 3.587148000e-03f, 3.276564000e-03f, 3.366660000e-03f,
                3.209644000e-03f, 2.924820000e-03f, 3.005828000e-03f, 1.411672800e-02f, 1.322311200e-02f, 1.349680800e-02f,
                1.313004000e-02f, 1.229229600e-02f, 1.254679200e-02f, 1.219301600e-02f, 1.140909600e-02f, 1.164541600e-02f,
                5.144460000e-03f, 4.763316000e-03f, 4.863588000e-03f, 4.630764000e-03f, 4.278708000e-03f, 4.369380000e-03f,
                4.144972000e-03f, 3.820980000e-03f, 3.902564000e-03f, 1.731756000e-02f, 1.633639200e-02f, 1.661124000e-02f,
                1.610200800e-02f, 1.518132000e-02f, 1.543696800e-02f, 1.494840800e-02f, 1.408615200e-02f, 1.432362400e-02f,
                6.302508000e-03f, 5.877588000e-03f, 5.978436000e-03f, 5.674380000e-03f, 5.280852000e-03f, 5.372100000e-03f,
                5.080300000e-03f, 4.717140000e-03f, 4.799300000e-03f, 1.012140000e-03f, 8.963400000e-04f, 9.157800000e-04f,
                7.925880000e-04f, 6.958920000e-04f, 7.118760000e-04f, 6.070840000e-04f, 5.284680000e-04f, 5.415080000e-04f,
                1.950625200e-02f, 1.855333200e-02f, 1.880989200e-02f, 1.828138800e-02f, 1.737445200e-02f, 1.761526800e-02f,
                1.709671600e-02f, 1.623474000e-02f, 1.646032400e-02f, 7.460556000e-03f, 6.991860000e-03f, 7.093284000e-03f,
                6.717996000e-03f, 6.282996000e-03f, 6.374820000e-03f, 6.015628000e-03f, 5.613300000e-03f, 5.696036000e-03f,
                2.371922400e-02f, 2.256295200e-02f, 2.284010400e-02f, 2.204594400e-02f, 2.095936800e-02f, 2.121732000e-02f,
                2.045919200e-02f, 1.944026400e-02f, 1.968004000e-02f, 8.618604000e-03f, 8.106132000e-03f, 8.208132000e-03f,
                7.761612000e-03f, 7.285140000e-03f, 7.377540000e-03f, 6.950956000e-03f, 6.509460000e-03f, 6.592772000e-03f,
                2.692005600e-02f, 2.567623200e-02f, 2.595453600e-02f, 2.501791200e-02f, 2.384839200e-02f, 2.410749600e-02f,
                2.321458400e-02f, 2.211732000e-02f, 2.235824800e-02f, 9.776652000e-03f, 9.220404000e-03f, 9.322980000e-03f,
                8.805228000e-03f, 8.287284000e-03f, 8.380260000e-03f, 7.886284000e-03f, 7.405620000e-03f, 7.489508000e-03f,
                1.583244000e-03f, 1.419060000e-03f, 1.440228000e-03f, 1.241580000e-03f, 1.103412000e-03f, 1.121124000e-03f,
                9.523960000e-04f, 8.392200000e-04f, 8.539880000e-04f
            };

            float[] x_actual = x.ToArray();

            AssertError.Tolerance(x_expect, x_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch}");
        }
Exemplo n.º 3
0
        public static TrivectorMap1D Reference(TrivectorMap1D y, Quaternion.QuaternionFilter1D w, int inw, int kwidth, int stride)
        {
            int inchannels = w.InChannels, outchannels = w.OutChannels, batch = y.Batch;
            int outw = (inw - kwidth) / stride + 1;

            if (y.Width != outw)
            {
                throw new ArgumentException("mismatch shape");
            }

            TrivectorMap1D x = new TrivectorMap1D(inchannels, inw, batch);

            for (int kx = 0; kx < kwidth; kx++)
            {
                for (int th = 0; th < batch; th++)
                {
                    for (int ox = 0; ox < outw; ox++)
                    {
                        for (int outch = 0; outch < outchannels; outch++)
                        {
                            Trivector v = y[outch, ox, th];

                            for (int inch = 0; inch < inchannels; inch++)
                            {
                                x[inch, kx + ox * stride, th] += v * w[inch, outch, kx];
                            }
                        }
                    }
                }
            }

            return(x);
        }
Exemplo n.º 4
0
        public void ExecuteTest()
        {
            float max_err = 0;

            foreach (int batch in new int[] { 1, 2, 3 })
            {
                foreach (int inchannels in new int[] { 3, 6, 9, 12 })
                {
                    foreach (int outchannels in new int[] { 3, 6, 9, 12 })
                    {
                        foreach (int kwidth in new int[] { 1, 3, 5 })
                        {
                            foreach (int stride in new int[] { 1, 2, 3 })
                            {
                                foreach (int inwidth in new int[] { 8, 9, 13, 17 })
                                {
                                    int outwidth = (inwidth - kwidth) / stride + 1;

                                    float[] xval = (new float[inwidth * inchannels * batch]).Select((_, idx) => idx * 1e-3f).ToArray();
                                    float[] wval = (new float[kwidth * inchannels * outchannels / 9 * 4]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

                                    Trivector[] xcval = (new Trivector[xval.Length / 3])
                                                        .Select((_, idx) => new Trivector(xval[idx * 3], xval[idx * 3 + 1], xval[idx * 3 + 2])).ToArray();

                                    Quaternion.Quaternion[] wcval = (new Quaternion.Quaternion[wval.Length / 4])
                                                                    .Select((_, idx) => new Quaternion.Quaternion(wval[idx * 4], wval[idx * 4 + 1], wval[idx * 4 + 2], wval[idx * 4 + 3])).ToArray();

                                    TrivectorMap1D x = new TrivectorMap1D(inchannels / 3, inwidth, batch, xcval);
                                    Quaternion.QuaternionFilter1D w = new Quaternion.QuaternionFilter1D(inchannels / 3, outchannels / 3, kwidth, wcval);

                                    TrivectorMap1D y = Reference(x, w, kwidth, stride);

                                    OverflowCheckedTensor x_tensor = new OverflowCheckedTensor(Shape.Map1D(inchannels, inwidth, batch), xval);
                                    OverflowCheckedTensor w_tensor = new OverflowCheckedTensor(Shape.Kernel1D(inchannels / 3 * 4, outchannels / 3, kwidth), wval);

                                    OverflowCheckedTensor y_tensor = new OverflowCheckedTensor(Shape.Map1D(outchannels, outwidth, batch));

                                    TrivectorConvolution1D ope = new TrivectorConvolution1D(inwidth, inchannels, outchannels, kwidth, stride, gradmode: false, batch);

                                    ope.Execute(x_tensor, w_tensor, y_tensor);

                                    float[] y_expect = y.ToArray();
                                    float[] y_actual = y_tensor.State;

                                    CollectionAssert.AreEqual(xval, x_tensor.State);
                                    CollectionAssert.AreEqual(wval, w_tensor.State);

                                    AssertError.Tolerance(y_expect, y_actual, 1e-7f, 1e-5f, ref max_err, $"mismatch value {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch}");

                                    Console.WriteLine($"pass: {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch}");
                                }
                            }
                        }
                    }
                }
            }

            Console.WriteLine($"maxerr:{max_err}");
        }
Exemplo n.º 5
0
        public void ReferenceTest()
        {
            int inchannels = 9, outchannels = 12, kwidth = 3, stride = 2, inwidth = 7, batch = 3;
            int outwidth = (inwidth - kwidth) / stride + 1;

            float[] xval = (new float[batch * inwidth * inchannels]).Select((_, idx) => idx * 1e-3f).ToArray();
            float[] wval = (new float[kwidth * outchannels * inchannels / 9 * 4]).Select((_, idx) => idx * 1e-3f).Reverse().ToArray();

            Trivector[] xcval = (new Trivector[xval.Length / 3])
                                .Select((_, idx) => new Trivector(xval[idx * 3], xval[idx * 3 + 1], xval[idx * 3 + 2])).ToArray();

            Quaternion.Quaternion[] wcval = (new Quaternion.Quaternion[wval.Length / 4])
                                            .Select((_, idx) => new Quaternion.Quaternion(wval[idx * 4], wval[idx * 4 + 1], wval[idx * 4 + 2], wval[idx * 4 + 3])).ToArray();

            TrivectorMap1D x = new TrivectorMap1D(inchannels / 3, inwidth, batch, xcval);

            Quaternion.QuaternionFilter1D w = new Quaternion.QuaternionFilter1D(inchannels / 3, outchannels / 3, kwidth, wcval);

            TrivectorMap1D y = Reference(x, w, kwidth, stride);

            float[] y_expect =
            {
                2.965368000e-03f, 2.182950000e-03f, 2.538060000e-03f, 2.200728000e-03f, 1.579446000e-03f, 1.861116000e-03f,
                1.581240000e-03f, 1.100358000e-03f, 1.318956000e-03f, 1.106904000e-03f, 7.456860000e-04f, 9.115800000e-04f,
                9.274404000e-03f, 8.317026000e-03f, 8.674080000e-03f, 7.195620000e-03f, 6.422706000e-03f, 6.706320000e-03f,
                5.448612000e-03f, 4.839426000e-03f, 5.059968000e-03f, 4.033380000e-03f, 3.567186000e-03f, 3.735024000e-03f,
                1.558344000e-02f, 1.445110200e-02f, 1.481010000e-02f, 1.219051200e-02f, 1.126596600e-02f, 1.155152400e-02f,
                9.315984000e-03f, 8.578494000e-03f, 8.800980000e-03f, 6.959856000e-03f, 6.388686000e-03f, 6.558468000e-03f,
                2.504699400e-02f, 2.365221600e-02f, 2.401413000e-02f, 1.968285000e-02f, 1.853085600e-02f, 1.881933000e-02f,
                1.511704200e-02f, 1.418709600e-02f, 1.441249800e-02f, 1.134957000e-02f, 1.062093600e-02f, 1.079363400e-02f,
                3.135603000e-02f, 2.978629200e-02f, 3.015015000e-02f, 2.467774200e-02f, 2.337411600e-02f, 2.366453400e-02f,
                1.898441400e-02f, 1.792616400e-02f, 1.815351000e-02f, 1.427604600e-02f, 1.344243600e-02f, 1.361707800e-02f,
                3.766506600e-02f, 3.592036800e-02f, 3.628617000e-02f, 2.967263400e-02f, 2.821737600e-02f, 2.850973800e-02f,
                2.285178600e-02f, 2.166523200e-02f, 2.189452200e-02f, 1.720252200e-02f, 1.626393600e-02f, 1.644052200e-02f,
                4.712862000e-02f, 4.512148200e-02f, 4.549020000e-02f, 3.716497200e-02f, 3.548226600e-02f, 3.577754400e-02f,
                2.865284400e-02f, 2.727383400e-02f, 2.750604000e-02f, 2.159223600e-02f, 2.049618600e-02f, 2.067568800e-02f,
                5.343765600e-02f, 5.125555800e-02f, 5.162622000e-02f, 4.215986400e-02f, 4.032552600e-02f, 4.062274800e-02f,
                3.252021600e-02f, 3.101290200e-02f, 3.124705200e-02f, 2.451871200e-02f, 2.331768600e-02f, 2.349913200e-02f,
                5.974669200e-02f, 5.738963400e-02f, 5.776224000e-02f, 4.715475600e-02f, 4.516878600e-02f, 4.546795200e-02f,
                3.638758800e-02f, 3.475197000e-02f, 3.498806400e-02f, 2.744518800e-02f, 2.613918600e-02f, 2.632257600e-02f,
            };

            float[] y_actual = y.ToArray();

            AssertError.Tolerance(y_expect, y_actual, 1e-7f, 1e-5f, $"mismatch value {inchannels},{outchannels},{kwidth},{stride},{inwidth},{batch}");
        }
Exemplo n.º 6
0
        public static Quaternion.QuaternionFilter1D Reference(TrivectorMap1D x, TrivectorMap1D gy, Quaternion.QuaternionFilter1D w, int kwidth, int stride)
        {
            int inchannels = x.Channels, outchannels = gy.Channels, batch = x.Batch;
            int inw = x.Width, outw = gy.Width;

            if (outw != (inw - kwidth) / stride + 1)
            {
                throw new ArgumentException("mismatch shape");
            }

            Quaternion.QuaternionFilter1D gw = new Quaternion.QuaternionFilter1D(inchannels, outchannels, kwidth);

            for (int kx = 0; kx < kwidth; kx++)
            {
                for (int th = 0; th < batch; th++)
                {
                    for (int inch, outch = 0; outch < outchannels; outch++)
                    {
                        for (inch = 0; inch < inchannels; inch++)
                        {
                            Quaternion.Quaternion sum = 0;
                            Quaternion.Quaternion q   = w[inch, outch, kx];

                            for (int ix = kx, ox = 0; ox < outw; ix += stride, ox++)
                            {
                                sum += Trivector.MulQGrad(x[inch, ix, th], gy[outch, ox, th], q);
                            }

                            gw[inch, outch, kx] += sum;
                        }
                    }
                }
            }

            return(gw);
        }