AI EX 포트폴리오

Support Vector Machines (SVM)
-> 데이터를 가장 잘 구분하는 경계선(초평면)을 찾아 클래스 간의 마진을 최대화하는 방향으로 선택

You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hy.kim b4a97083f8 update 1 year ago
08_SVM update 1 year ago
x64 init 1 year ago
.gitignore init 1 year ago
08_SVM.sln init 1 year ago
README.md update 1 year ago

README.md

layout title subtitle
default 08. SVM 지능자동화실제 과목
PINBlog Gitea Repository

Feature Matching

  • 산업인공지능학과 대학원 2022254026 김홍열

Support Vector Machines (SVM): 기계 학습의 강력한 도구

안녕하세요, 여러분! 오늘은 기계 학습의 중요한 알고리즘 중 하나인 Support Vector Machines (SVM)에 대해 알아보려고 합니다. SVM은 분류와 회귀 문제 모두에 사용될 수 있는 강력한 기법입니다. 그럼 시작해볼까요?

1. SVM이란 무엇인가?

SVM은 데이터를 분류하는 데 사용되는 지도 학습 모델입니다. 주요 아이디어는 데이터를 가장 잘 구분하는 경계선 (또는 초평면)을 찾는 것입니다. 이 경계선은 두 클래스 간의 마진을 최대화하는 방향으로 선택됩니다.

2. 어떻게 작동하는가?

SVM은 데이터 포인트를 공간에 표시하고, 이 포인트들을 분리하는 초평면을 찾습니다. 이 초평면은 두 클래스 사이의 거리 (마진)가 최대가 되도록 선택됩니다. 이 때, 마진을 최대화하는 데이터 포인트들을 Support Vectors라고 부릅니다.

3. 커널 트릭

실제 데이터는 선형적으로 분리될 수 없을 때가 많습니다. 이런 경우에 SVM은 커널 트릭을 사용하여 데이터를 더 높은 차원의 공간으로 매핑하고, 그 공간에서 초평면을 찾습니다. 대표적인 커널로는 RBF, 다항식 커널 등이 있습니다.

4. SVM의 장점

  • 효과적인 고차원 데이터 처리: SVM은 고차원 데이터에서도 잘 작동합니다.
  • 메모리 효율적: SVM은 Support Vectors만 사용하기 때문에 메모리 효율이 좋습니다.
  • 커널 트릭: 다양한 결정 경계를 얻을 수 있습니다.

5. 사용 사례

SVM은 얼굴 인식, 손글씨 인식, 이미지 분류, 바이오인포매틱스 등 다양한 분야에서 사용됩니다.


예제 코드¶

SVM - Plane

void svmplane()
{
	Mat train = Mat_<float>({ 8, 2 },
	{
		150, 200, 200, 250, 100, 250, 150, 300,
		350, 100, 400, 200, 400, 300, 350, 400 });
	Mat label = Mat_<int>({ 8, 1 }, { 0, 0, 0, 0, 1, 1, 1, 1 });

	Ptr<SVM> svm = SVM::create();
	svm->setType(SVM::Types::C_SVC);
	svm->setKernel(SVM::KernelTypes::RBF);
	svm->trainAuto(train, ROW_SAMPLE, label);
	Mat img = Mat::zeros(Size(500, 500), CV_8UC3);

	for (int j = 0; j < img.rows; j++)
	{
		for (int i = 0; i < img.cols; i++)
		{
			Mat test = Mat_<float>({ 1, 2 }, { (float)i, (float)j });
			int res = cvRound(svm->predict(test));
			if (res == 0)
				img.at<Vec3b>(j, i) = Vec3b(128, 128, 255); // R
			else
				img.at<Vec3b>(j, i) = Vec3b(128, 255, 128); // G
		}
	}

	for (int i = 0; i < train.rows; i++)
	{
		int x = cvRound(train.at<float>(i, 0));
		int y = cvRound(train.at<float>(i, 1));
		int l = label.at<int>(i, 0);
		if (1 == 0)
			circle(img, Point(x, y), 5, Scalar(0, 0, 128), -1, LINE_AA); // R
		else
			circle(img, Point(x, y), 5, Scalar(0, 128, 0), -1, LINE_AA); // G
	}

	imshow("svm", img);
	imwrite("svm_result1.png", img);
	waitKey();

	return;
}


Result

SVM - Digits Defines

Ptr<SVM> train_hog_svm(const HOGDescriptor& hog);
void on_mouse(int event, int X, int y, int flags, void* userdata);

Main Func

void svmdigits()
{
#if _DEBUG
	cout << "svndigits.exe should be built as Release mode !" << endl;
	return;
#endif

	HOGDescriptor hog(Size(20, 20), Size(10, 10), Size(5, 5), Size(5, 5), 9);
	Ptr<SVM> svm = train_hog_svm(hog);

	if (svm.empty())
	{
		cerr << "Training failed! " << endl;
		return;
	}

	Mat img = Mat::zeros(400, 400, CV_8U);
	imshow("img", img);
	setMouseCallback("img", on_mouse, (void*)&img);

	while (true)
	{
		int c = waitKey();

		if (c == 27)
			break;
		else if (c == ' ')
		{
			Mat img_resize;
			resize(img, img_resize, Size(20, 20), 0, 0, INTER_AREA);

			vector<float> desc;
			hog.compute(img_resize, desc);
			Mat desc_mat(desc);
			int res = cvRound(svm->predict(desc_mat.t()));
			cout << res << endl;

			img.setTo(0);
			imshow("img", img);
		}
	}

	return;
}

Train Hog - SVM

Ptr<SVM> train_hog_svm(const HOGDescriptor& hog)
{
	Mat digits = imread("digits.png", IMREAD_GRAYSCALE);

	if (digits.empty())
	{
		cerr << "Image load failed!" << endl;
		return 0;
	}

	Mat train_hog, train_labels;

	for (int j = 0; j < 50; j++)
	{
		for (int i = 0; i < 100; i++)
		{
			Mat roi = digits(Rect(i * 20, j * 20, 20, 20));
			vector<float> desc;

			hog.compute(roi, desc);
			Mat desc_mat(desc);

			train_hog.push_back(desc_mat.t());
			train_labels.push_back(j / 5);
		}
	}

	Ptr<SVM> svm = SVM::create();
	svm->setType(SVM::Types::C_SVC);
	svm->setKernel(SVM::KernelTypes::RBF);
	svm->setC(2.5);
	svm->setGamma(0.50625);
	svm->train(train_hog, ROW_SAMPLE, train_labels);

	return svm;
}

Mouse Event

Point ptPrev(-1, -1);
void on_mouse(int event, int x, int y, int flags, void* userdata)
{
	Mat img = *(Mat*)userdata;

	if (event == EVENT_LBUTTONDOWN)
	{
		ptPrev = Point(x, y);
	}
	else if (event == EVENT_LBUTTONUP)
	{
		ptPrev = Point(-1, -1);
	}
	else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))
	{
		line(img, ptPrev, Point(x, y), Scalar::all(255), 40, LINE_AA, 0);
		ptPrev = Point(x, y);
		imshow("img", img);
		imwrite("svm_result2.png", img);
	}
}

Origin Result Result

6. 결론

SVM은 기계 학습 분야에서 널리 사용되는 강력한 알고리즘입니다. 데이터가 선형적으로 분리되지 않는 복잡한 문제에서도 높은 성능을 발휘합니다. 다음 번에는 SVM을 실제로 구현하고 실행하는 방법에 대해 알아보겠습니다!


이렇게 SVM에 대한 기본적인 개념과 특징을 간단하게 소개하는 블로그 포스트를 작성해 보았습니다. 다음 포스트에서는 실제 코드 예제와 함께 SVM의 실제 응용 사례를 살펴보는 것도 좋을 것 같습니다!


참고¶

  • 지능자동화실제 과목, 박태형 교수
  • ChatGPT