コード例 #1
0
        public static List <Gaussian_2D> fit(List <Vector2> pts_init, int num_clusters_init)
        {
            pts          = pts_init;
            num_clusters = num_clusters_init;
            int num_points = pts.Count();
            List <Gaussian_2D> gau_list = new List <Gaussian_2D>();

            int iter_counter = 0;

            init_centroid = random_state.choice(pts, num_clusters);
            List <int>     closest_centroid = new List <int>();
            List <Vector2> centroid         = init_centroid;
            List <Vector2> old_centroid     = init_centroid;

            do
            {
                old_centroid     = centroid;
                closest_centroid = ClosestCentroid(old_centroid);
                centroid         = ShiftCentroid(closest_centroid);
                iter_counter++;
            } while (!CloseCentroid(old_centroid, centroid) && iter_counter <= 50);

            foreach (Vector2 miu in centroid)
            {
                Gaussian_2D gau = new Gaussian_2D(rand, miu);
                gau_list.Add(gau);
            }
            return(gau_list);
        }
コード例 #2
0
        public static List <Gaussian_2D> fit(List <Vector2> pts_init, int num_clusters_init)
        {
            pts          = pts_init;
            num_clusters = num_clusters_init;
            int num_points   = pts.Count();
            int iter_counter = 0;

            List <Gaussian_2D>    gau_list   = new List <Gaussian_2D>();
            List <List <double> > membership = InitializeMemberships();
            //List<List<double>> old_membership = new List<List<double>>();
            List <Vector2> centers     = UpdateCenter(membership);
            List <Vector2> old_centres = new List <Vector2>();

            do
            {
                iter_counter++;
                //old_membership = membership;
                old_centres = centers;
                membership  = UpdateMemberships(centers);
                centers     = UpdateCenter(membership);
            } while (!CloseCentroid(old_centres, centers) && iter_counter <= 50);


            foreach (Vector2 miu in centers)
            {
                Gaussian_2D gau = new Gaussian_2D(rand, miu);
                gau_list.Add(gau);
            }

            return(gau_list);
        }
コード例 #3
0
        /// <summary>
        /// Initialize and add new gaussians at the beginning of each level
        /// </summary>
        /// <param name="level">
        /// Level index
        /// </param>
        private void InitLevel(int level, int init_type)
        {
            Console.WriteLine("level {0} begin ", level);

            List <Gaussian_2D> level_gaussian_list = new List <Gaussian_2D>();

            //TODO: initialize gaussians at smaller scale for deeper levels, only within the parent domain
            //gau.Sigma.m00 /= level + 1;
            //gau.Sigma.m11 /= level + 1;
            if (init_type == 0 || init_type == 1) // kmeans_init (0) || FCM_init (1)
            {
                level_gaussian_list = ClusteringInitGMM(level, init_type);
            }
            else if (init_type == 2)
            {
                IEnumerable <int> level_gaussian_idx = GetLevel(level);
                foreach (int i in level_gaussian_idx)
                {
                    //Each gaussian is randomly initialized at four corners
                    Gaussian_2D gaussian_rand = new Gaussian_2D(rand, (i % 8) + 1, true);
                    level_gaussian_list.Add(gaussian_rand);
                }
            }

            foreach (Gaussian_2D gaussian in level_gaussian_list)
            {
                gaussian_list.Add(gaussian);
                //All gaussians at each level are initialized with equal class prior
                class_prior.Add(1 / (double)(num_gaussian));
                //A list of constitute sufficient statistics for updating gaussian parameters in parallel.
                //See paper section 3.5
                T.Add(new List <double>(new double[] { 0, 0, 0, 0, 0, 0, 0 }));
            }
        }
コード例 #4
0
ファイル: pointgeneration.cs プロジェクト: luckysama/GMM2D
        public static (List <Vector2>, List <Gaussian_2D>) Generate(int num_of_points, int num_gaussians)
        {
            List <Gaussian_2D> ground_truth_gaussian_list = new List <Gaussian_2D>();
            List <Vector2>     pts  = new List <Vector2>();
            Random             rand = new Random();

            int ptsPerGaussian = (int)Math.Round((double)num_of_points / num_gaussians);

            for (int loop = 0; loop < num_gaussians; loop++)
            {
                Gaussian_2D sample_gaussian = new Gaussian_2D(rand);
                ground_truth_gaussian_list.Add(sample_gaussian);

                sample_gaussian.Sigma.UpdateEigens();
                double angle;
                if (sample_gaussian.Sigma.m00 > sample_gaussian.Sigma.m11)
                {
                    angle = Math.Atan2(sample_gaussian.Sigma.eigenvector_0.y, sample_gaussian.Sigma.eigenvector_0.x);
                }
                else
                {
                    angle = Math.Atan2(sample_gaussian.Sigma.eigenvector_1.y, sample_gaussian.Sigma.eigenvector_1.x);
                }

                double u1, u2;
                int    x_old, y_old;
                int    x, y;

                for (int i = 0; i < ptsPerGaussian; i++)
                {
                    do
                    {
                        u1 = rand.NextDouble();
                        u2 = rand.NextDouble();
                    } while (u1 == 0 && u2 == 0);
                    x_old = (int)Math.Round(Math.Sqrt(sample_gaussian.Sigma.m00) * Math.Sqrt(-2 * Math.Log(u2)) * Math.Cos(2 * Math.PI * u1));
                    y_old = (int)Math.Round(Math.Sqrt(sample_gaussian.Sigma.m11) * Math.Sqrt(-2 * Math.Log(u2)) * Math.Sin(2 * Math.PI * u1));
                    x     = (int)Math.Round(x_old * Math.Cos(angle) - y_old * Math.Sin(angle) + sample_gaussian.miu.x);
                    y     = (int)Math.Round(x_old * Math.Sin(angle) + y_old * Math.Cos(angle) + sample_gaussian.miu.y);
                    pts.Add(new Vector2(x, y));
                }
            }
            return(pts, ground_truth_gaussian_list);
        }
コード例 #5
0
ファイル: Form1.cs プロジェクト: luckysama/GMM2D
        private void Draw3SigmaEllipse(Graphics g, Gaussian_2D gaussian, Pen pen)
        {
            gaussian.Sigma.UpdateEigens();
            float major_axis, minor_axis;

            if (gaussian.Sigma.eigenvalue_0 > gaussian.Sigma.eigenvalue_1)
            {
                major_axis = (float)(2 * Math.Sqrt(5.991f * gaussian.Sigma.eigenvalue_0));
                minor_axis = (float)(2 * Math.Sqrt(5.991f * gaussian.Sigma.eigenvalue_1));
            }
            else
            {
                major_axis = (float)(2 * Math.Sqrt(5.991f * gaussian.Sigma.eigenvalue_1));
                minor_axis = (float)(2 * Math.Sqrt(5.991f * gaussian.Sigma.eigenvalue_0));
            }

            float  x_axis, y_axis;
            double angle;

            if (gaussian.Sigma.m00 > gaussian.Sigma.m11)
            {
                x_axis = major_axis;
                y_axis = minor_axis;
                angle  = Math.Atan2(gaussian.Sigma.eigenvector_0.y, gaussian.Sigma.eigenvector_0.x);
            }
            else
            {
                x_axis = minor_axis;
                y_axis = major_axis;
                angle  = Math.Atan2(gaussian.Sigma.eigenvector_1.y, gaussian.Sigma.eigenvector_1.x);
            }
            if (Double.IsNaN(angle))
            {
                label_status.Text = "One or more gaussians failed to fit. Modify your input parameters.";
                return;
            }
            g.TranslateTransform(gaussian.miu.x, gaussian.miu.y);
            g.RotateTransform((float)(angle * 180 / Math.PI)); //Rad to Deg
            g.DrawEllipse(pen, new RectangleF(-(int)Math.Round(x_axis / 2),
                                              -(int)Math.Round(y_axis / 2),
                                              x_axis,
                                              y_axis));
            g.ResetTransform();
        }
コード例 #6
0
        /// <summary>
        /// Calculate multivariate normal probablity density function.
        /// Hardcoded for Vector2 and Matrix22 datatype.
        /// Use double precision to increase robustness.
        /// </summary>
        /// <param name="pt"></param>
        /// <param name="miu"></param>
        /// <param name="covariance"></param>
        /// <returns></returns>
        private static double MultiNormalPDF(Vector2 pt, Gaussian_2D gaussian)
        {
            Vector2  miu        = gaussian.miu;
            Matrix22 covariance = gaussian.Sigma;

            Vector2  x_minus_miu = pt.Minus(miu);
            Matrix22 inv_cov     = covariance.Inverse();

            //Break Matrix22 into two rows (Vector2) for dot product
            Vector2 row1 = new Vector2(inv_cov.m00, inv_cov.m01);
            Vector2 row2 = new Vector2(inv_cov.m10, inv_cov.m11);

            float dot_row1 = row1.Dot(x_minus_miu);
            float dot_row2 = row2.Dot(x_minus_miu);

            //Assemble two rows
            Vector2 temp_v = new Vector2(dot_row1, dot_row2);

            double numerator = Math.Exp(-x_minus_miu.Dot(temp_v) / 2);
            double denom     = 2 * Math.PI * Math.Sqrt(covariance.Det());

            return(numerator / denom);
        }
コード例 #7
0
        private List <Gaussian_2D> ClusteringInitGMM(int level, int init_type)
        {
            List <Gaussian_2D> cluster_list = new List <Gaussian_2D>();

            if (level != 0)
            {
                IEnumerable <int> parent_level_gaussians = GetLevel(level - 1);
                foreach (int i in parent_level_gaussians)
                {
                    List <Vector2>     parent_pts     = new List <Vector2>();
                    List <Gaussian_2D> cluster_list_i = new List <Gaussian_2D>();

                    foreach (Vector2 pt in pts)
                    {
                        if (pt.gaussian_idx[level - 1] == i)
                        {
                            parent_pts.Add(pt);
                        }
                    }

                    //if there are fewer points than num_gaussian * 2 in the parent gaussian, stop partition
                    //if (parent_pts.Count <= num_gaussian * 2 || gaussian_list[i].partition == false)
                    if (parent_pts.Count < num_gaussian || gaussian_list[i].partition == false)
                    {
                        Console.WriteLine("===========Stopping at gaussian {0}==============", i);
                        //gaussian_list[i].partition = false;
                        for (int j = 0; j < num_gaussian; j++)
                        {
                            Gaussian_2D gau = new Gaussian_2D();
                            gau.partition = false;
                            gau.dropped   = true;
                            cluster_list_i.Add(gau);
                        }
                        cluster_list = cluster_list.Concat(cluster_list_i).ToList();

                        if (parent_pts.Count > 2 && gaussian_list[i].dropped == false)
                        {
                            BaseModel lineModel = new LineModel();
                            lineModel = RANSAC.Fit(parent_pts, lineModel, 2, 2.00F);
                            baseModels.Add(lineModel);
                        }

                        continue;
                    }

                    if (init_type == 1)
                    {
                        cluster_list_i = FuzzyCMeans.fit(parent_pts, num_gaussian);
                    }
                    else if (init_type == 0)
                    {
                        cluster_list_i = KMeans.fit(parent_pts, num_gaussian);
                    }
                    cluster_list = cluster_list.Concat(cluster_list_i).ToList();
                }
            }
            else
            {
                if (init_type == 1)
                {
                    cluster_list = FuzzyCMeans.fit(pts, num_gaussian);
                }
                else if (init_type == 0)
                {
                    cluster_list = KMeans.fit(pts, num_gaussian);
                }
            }

            return(cluster_list);
        }