diff --git a/08_SVM/svm_result2.png b/08_SVM/svm_result2.png index dd8fc3b..c61a1c8 100644 Binary files a/08_SVM/svm_result2.png and b/08_SVM/svm_result2.png differ diff --git a/08_SVM/svm_result3.png b/08_SVM/svm_result3.png new file mode 100644 index 0000000..eac8790 Binary files /dev/null and b/08_SVM/svm_result3.png differ diff --git a/README.md b/README.md index e69de29..2872ced 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,291 @@ +--- +layout: default +title: 08. SVM +subtitle: 지능자동화실제 과목 +--- +----- + +[PINBlog Gitea Repository](https://gitea.pinblog.codes/CBNU/08_SVM) + +----- + +# 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 + +
+ +```c++ + +void svmplane() +{ + Mat train = Mat_({ 8, 2 }, + { + 150, 200, 200, 250, 100, 250, 150, 300, + 350, 100, 400, 200, 400, 300, 350, 400 }); + Mat label = Mat_({ 8, 1 }, { 0, 0, 0, 0, 1, 1, 1, 1 }); + + Ptr 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_({ 1, 2 }, { (float)i, (float)j }); + int res = cvRound(svm->predict(test)); + if (res == 0) + img.at(j, i) = Vec3b(128, 128, 255); // R + else + img.at(j, i) = Vec3b(128, 255, 128); // G + } + } + + for (int i = 0; i < train.rows; i++) + { + int x = cvRound(train.at(i, 0)); + int y = cvRound(train.at(i, 1)); + int l = label.at(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](/08_SVM/svm_result1.png) + +
+
+ + +
+SVM - Digits + +Defines +
+ +```c++ + +Ptr train_hog_svm(const HOGDescriptor& hog); +void on_mouse(int event, int X, int y, int flags, void* userdata); + +``` + +
+ +Main Func +
+ +```c++ + +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 = 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 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 +
+ +```c++ + +Ptr 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 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::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 +
+ +```c++ + +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](/08_SVM/digits.png) +![Result](/08_SVM/svm_result2.png) +![Result](/08_SVM/svm_result3.png) + +
+ +
+ + + +# **6. 결론** + +SVM은 기계 학습 분야에서 널리 사용되는 강력한 알고리즘입니다. +데이터가 선형적으로 분리되지 않는 복잡한 문제에서도 높은 성능을 발휘합니다. +다음 번에는 SVM을 실제로 구현하고 실행하는 방법에 대해 알아보겠습니다! + +--- + +이렇게 SVM에 대한 기본적인 개념과 특징을 간단하게 소개하는 블로그 포스트를 작성해 보았습니다. 다음 포스트에서는 실제 코드 예제와 함께 SVM의 실제 응용 사례를 살펴보는 것도 좋을 것 같습니다! + +--- + +### 참고[¶]() + +- 지능자동화실제 과목, 박태형 교수 +- ChatGPT