메뉴 건너뛰기

enjoyTools.net

dlib dnn_metric_learning_ex.cpp

2020.02.07 02:46

꿈돌이 조회 수:4880

번역기 돌린 거

 

// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt

/*

    This is an example illustrating the use of the deep learning tools from the

    dlib C++ Library.  In it, we will show how to use the loss_metric layer to do

    metric learning.  

 

    The main reason you might want to use this kind of algorithm is because you

    would like to use a k-nearest neighbor classifier or similar algorithm, but

    you don't know a good way to calculate the distance between two things.  A

    popular example would be face recognition.  There are a whole lot of papers

    that train some kind of deep metric learning algorithm that embeds face

    images in some vector space where images of the same person are close to each

    other and images of different people are far apart.  Then in that vector

    space it's very easy to do face recognition with some kind of k-nearest

    neighbor classifier.  

 

    To keep this example as simple as possible we won't do face recognition.

    Instead, we will create a very simple network and use it to learn a mapping

    from 8D vectors to 2D vectors such that vectors with the same class labels

    are near each other.  If you want to see a more complex example that learns

    the kind of network you would use for something like face recognition read

    the dnn_metric_learning_on_images_ex.cpp example.

 

    You should also have read the examples that introduce the dlib DNN API before 

    continuing.  These are dnn_introduction_ex.cpp and dnn_introduction2_ex.cpp.

 

    이것은 Dlib C++ 라이브러리의 딥러닝 도구 사용을 보여 주는 예입니다.

    여기서는 loss_metric 계층을 사용하여 메트릭 학습을 수행하는 방법을 보여줍니다.

 

    이러한 종류의 알고리즘을 사용하는 주된 이유는 k-최근접 이웃 분류기 또는 비슷한 알고리즘을 사용하려고 하지만,

    두 사물 사이의 거리를 계산하는 좋은 방법을 모르기 때문입니다.

    일반적인 예는 얼굴 인식입니다.

    같은 사람의 이미지가 서로 가깝고 다른 사람의 이미지가 멀리 떨어져 있는 벡터 공간에 얼굴 이미지를 심는

    일종의 deep metric learning 알고리즘을 훈련시키는 논문들이 많이 있습니다.

    그 벡터 공간에서는 가장 k-최근접 이웃 분류기로 얼굴 인식을 하는 것이 매우 쉽습니다.

 

    이 예제를 최대한 간단하게 유지하기 위해 얼굴 인식은 하지 않겠습니다.

    대신, 매우 간단한 네트워크를 생성하여 동일한 클래스 레이블을 가진 벡터가 서로 가까이 있도록

    8D 벡터에서 2D 벡터로 매핑하는 방법을 배우도록 하겠습니다.

    얼굴 인식에 사용할 네트워크 종류를 배우는 더 복잡한 예를 보려면 dnn_metric_learning_on_images_ex.cpp 예제를 읽어보십시오.

 

    계속하기 전에 dlib DNN API를 소개하는 예제인

    dnn_instruction_ex.cpp 및 dnn_instruction2_ex.cpp를 읽어보십시오.

*/

 

#include <dlib/dnn.h>

#include <iostream>

 

using namespace std;

using namespace dlib;

 

 

int main() try

{

    // The API for doing metric learning is very similar to the API for

    // multi-class classification.  In fact, the inputs are the same, a bunch of

    // labeled objects.  So here we create our dataset.  We make up some simple

    // vectors and label them with the integers 1,2,3,4.  The specific values of

    // the integer labels don't matter.

    /*

    메트릭 학습을 수행하기위한 API는 다중 클래스 분류를위한 API와 매우 유사합니다.

    실제로 입력은 라벨이 붙은 객체 묶음으로써 동일합니다.

    그러니 여기서 우리의 데이터 셋을 만듭니다.

    간단한 벡터를 구성하고 정수 1,2,3,4라는 라벨을 붙입니다.

    정수 라벨에 지정된 값은 중요하지 않습니다.

    */

    std::vector<matrix<double,0,1>> samples;

    std::vector<unsigned long> labels;

 

    // class 1 training vectors

    samples.push_back({1,0,0,0,0,0,0,0}); labels.push_back(1);

    samples.push_back({0,1,0,0,0,0,0,0}); labels.push_back(1);

 

    // class 2 training vectors

    samples.push_back({0,0,1,0,0,0,0,0}); labels.push_back(2);

    samples.push_back({0,0,0,1,0,0,0,0}); labels.push_back(2);

 

    // class 3 training vectors

    samples.push_back({0,0,0,0,1,0,0,0}); labels.push_back(3);

    samples.push_back({0,0,0,0,0,1,0,0}); labels.push_back(3);

 

    // class 4 training vectors

    samples.push_back({0,0,0,0,0,0,1,0}); labels.push_back(4);

    samples.push_back({0,0,0,0,0,0,0,1}); labels.push_back(4);

 

 

    // Make a network that simply learns a linear mapping from 8D vectors to 2D

    // vectors.

    /*

    8D 벡터에서 2D 벡터로 선형 매핑을 학습하는 네트워크를 만듭니다.

    */

    using net_type = loss_metric<fc<2,input<matrix<double,0,1>>>>; 

    net_type net;

    dnn_trainer<net_type> trainer(net);

    trainer.set_learning_rate(0.1);

 

    // It should be emphasized out that it's really important that each mini-batch contain

    // multiple instances of each class of object.  This is because the metric learning

    // algorithm needs to consider pairs of objects that should be close as well as pairs

    // of objects that should be far apart during each training step.  Here we just keep

    // training on the same small batch so this constraint is trivially satisfied.

    /*

    각 미니 배치는 각 개체 클래스의 여러 인스턴스를 포함하는 것이 매우 중요합니다.

    이는 메트릭 학습 알고리즘이 각 교육 단계에서 멀리 떨어져 있어야 하는 개체 쌍뿐만 아니라

    가까이 있어야 하는 개체 쌍을 고려해야 하기 때문입니다.

    여기서는 동일한 소규모 배치로 계속 교육하므로 이 제약 조건이 3가지로 충족됩니다.

    */

    while(trainer.get_learning_rate() >= 1e-4)

        trainer.train_one_step(samples, labels);

 

    // Wait for training threads to stop

    trainer.get_net();

    cout << "done training" << endl;

 

 

    // Run all the samples through the network to get their 2D vector embeddings.

    /*

    모든 샘플을 네트워크를 통해 2D 벡터 임베딩을 가져옵니다.

    */

    std::vector<matrix<float,0,1>> embedded = net(samples);

 

    // Print the embedding for each sample to the screen.  If you look at the

    // outputs carefully you should notice that they are grouped together in 2D

    // space according to their label.

    /*

    각 샘플의 임베딩을 화면에 출력합니다.

    출력을 주의 깊게 살펴보면 라벨에 따라 2D 공간에 함께 그룹화되어 있습니다.

    */

    for (size_t i = 0; i < embedded.size(); ++i)

        cout << "label: " << labels[i] << "\t" << trans(embedded[i]);

 

    // Now, check if the embedding puts things with the same labels near each other and

    // things with different labels far apart.

    /*

    이제, 엠베딩이 같은 라벨을 가진 물건들과 서로 다른 라벨을 가진 물건들을 서로 멀리 떨어져 있는지 확인합니다.

    */

    int num_right = 0;

    int num_wrong = 0;

    for (size_t i = 0; i < embedded.size(); ++i)

    {

        for (size_t j = i+1; j < embedded.size(); ++j)

        {

            if (labels[i] == labels[j])

            {

                // The loss_metric layer will cause things with the same label to be less

                // than net.loss_details().get_distance_threshold() distance from each

                // other.  So we can use that distance value as our testing threshold for

                // "being near to each other".

                /*

                loss_metric 레이어는 같은 라벨을 가진 것들이 서로 "net.loss_details (). get_distance_threshold ()"거리보다 작아지게 합니다.

                따라서 거리 값을 "서로 가까이있는"테스트 임계 값으로 사용할 수 있습니다.

                */

                if (length(embedded[i]-embedded[j]) < net.loss_details().get_distance_threshold())

                    ++num_right;

                else

                    ++num_wrong;

            }

            else

            {

                if (length(embedded[i]-embedded[j]) >= net.loss_details().get_distance_threshold())

                    ++num_right;

                else

                    ++num_wrong;

            }

        }

    }

 

    cout << "num_right: "<< num_right << endl;

    cout << "num_wrong: "<< num_wrong << endl;

}

catch(std::exception& e)

{

    cout << e.what() << endl;

}

 

 

번호 제목 글쓴이 날짜 조회 수
공지 툴 북마크 꿈돌이 2021.02.11 80866
56 3d 모델 사이트 꿈돌이 2020.03.02 1292
55 svm_c_ex.cpp 꿈돌이 2020.02.16 1201
» dlib dnn_metric_learning_ex.cpp 꿈돌이 2020.02.07 4880
53 dlib dnn_metric_learning_on_images_ex.cpp 꿈돌이 2020.02.07 1404
52 dlib bearid 메모 꿈돌이 2020.02.03 1840
51 12864 결선 - OLED 0.96 결선 확인용 file 꿈돌이 2020.01.27 1256
50 ender 3 메모 꿈돌이 2020.01.05 321
49 Cura, PrusaSlicer (Slic3r) 포터블 꿈돌이 2019.12.25 172
48 Bed leveling 꿈돌이 2019.11.30 262
47 ms sql-server 명령 몇개 꿈돌이 2019.11.25 622
46 Klipper display config for SKR mini E3 v1.2 on ender 3 꿈돌이 2019.11.21 381
45 SKR mini E3 교체한 Ender 3에 Klipper OctoPrint 설치, 설정 및 적용 외 꿈돌이 2019.11.16 7525
44 윈도우에서 가상머신 또는 다른 곳으로 포트포워딩 꿈돌이 2019.09.02 454
43 윈도우10 배율 (dpi) 변경 스크립트 file 꿈돌이 2019.08.27 3936
42 윈도우 작업표시줄에 날짜와 시간 한 줄 표시, 요일 표시 꿈돌이 2019.08.20 465
41 윈도우 cmd에서 저장된 WIFI Profile의 비번 확인 꿈돌이 2019.07.03 2948
40 mysql update _priv='Y' root 복구용 꿈돌이 2019.06.25 395
39 리눅스 sh에서 실행파일 삭제 꿈돌이 2019.06.10 485
38 공중파 케이블 vod file 꿈돌이 2019.05.26 9374
37 윈도우10 앱 및 기능 에서 삭제 안되는 프로그램을 목록에서 강제로 제거하기 꿈돌이 2019.05.02 12539