Ukryty model szkolenia Markowa dla dynamicznych gestów?

Wiem, że istnieje wiele materiałów związanych z ukrytym modelem Markowa, a także przeczytałem wszystkie pytania i odpowiedzi związane z tym tematem. Rozumiem, jak to działa i jak można go wyszkolić, jednak nie jestem w stanie rozwiązać następującego problemu, który próbuję wyćwiczyć w prostym dynamicznym geście.

ja używamImplementacja HMM dla OpenCVZajrzałem do wcześniej zadawanych pytań i odpowiedzitutaj. Co naprawdę pomogło mi w zrozumieniu i użyciu modeli Markowa.

Mam w sumie dwa dynamiczne gesty, które są symetryczne (przesuń palcem w lewo i przesuń palcem w prawo). W sumie jest 5 obserwacji, w których 4 są różnymi etapami gestu, a 5 jest obserwacją, gdy nie występują żadne z tych etapów.

Przesunięcie palcem w lewo składa się z następujących obserwacji: 1-> 2-> 3-> 4 (co powinno wywołać ruch lewostronny) Podobnie gest prawego przesuwania składa się z następującej obserwacji: 4-> 3-> 2-> 1

Mam 25 sekwencji. Biorę 20 obserwacji dla każdej sekwencji, które są wykorzystywane do trenowania ukrytego modelu Markowa przy użyciu algorytmu Baum-Welcha.

Poniżej przedstawiono sekwencję wejściową:

1 0 1 1 0 2 2 2 2 0 0 2 3 3 3 0 0 4 4 4 
4 4 4 4 4 0 3 3 3 3 3 0 0 1 0 0 1 1 0 1 
4 4 4 4 4 4 0 3 3 3 3 3 0 0 1 0 0 1 1 0 
4 4 4 4 4 4 4 0 3 3 3 3 3 0 0 1 0 0 1 1 
1 1 1 1 0 2 2 2 0 1 0 3 3 0 0 0 4 4 4 4 
1 1 1 1 1 0 2 2 2 0 1 0 3 3 0 0 0 4 4 4 
0 1 1 1 1 1 0 2 2 2 0 1 0 3 3 0 0 0 4 4 
0 0 1 1 1 1 1 0 2 2 2 0 1 0 3 3 0 0 0 4 
4 4 0 0 3 0 3 3 3 3 0 0 0 0 0 1 1 1 1 1 
4 4 4 0 0 3 0 3 3 3 3 0 0 0 0 0 1 1 1 1 
4 4 4 4 0 0 3 0 3 3 3 3 0 0 0 0 0 1 1 1 
1 1 1 1 0 0 2 2 0 3 2 3 3 3 0 0 4 4 4 4 
1 1 1 1 1 0 0 2 2 0 3 2 3 3 3 0 0 4 4 4 
1 1 1 1 1 1 0 0 2 2 0 3 2 3 3 3 0 0 4 4 
1 3 4 4 4 0 3 0 0 0 0 0 3 2 0 0 1 1 1 1 

W tej sekwencji można zobaczyć wzór dla gestów Swipe w lewo i Przesuń w prawo.

Aby wytrenować ukryty model Markowa, inicjalizuję go następującymi wartościami, a następnie wywołuję funkcję pociągu, aby uzyskać wyjście:

TRANS:
0.7 0.15 0.15
0.3 0.4 0.3
0.3 0.4 0.3

EMIS:
0.3 0.1 0.1 0.1 0.1
0.2 0.1 0.2 0.2 0.3
0.2 0.3 0.2 0.2 0.1

INIT:
0.6 0.2 0.2

Po treningu dane wyjściowe to:

TRANS:
0.81611 0.0847926 0.0990979
0.398458 0.346433 0.255109
0.371391 0.35587 0.272739

EMIS:
0.534127 0.125568 0.0824495 0.200169 0.0576869
0.294653 0.0250053 0.0500311 0.200616 0.429694
0.238808 0.075001 0.0500019 0.130455 0.505733

INIT:
0.443984 0.391323 0.164693

Korzystając z tego modelu w moim programie rozpoznawania, nie otrzymuję wyników. Chcę, aby system pozostał w NULL STATE, chyba że zostanie wykryty jeden z gestów. W matrycy Przejście i Emisja podałem wartości dla obu tych gestów.

Jak myślisz, co mogę robić źle? Jakieś wskazówki lub pomoc?

Na koniec jest kod, którego używam do tego celu (jeśli ktoś chce się przyjrzeć)

double TRGUESSdata[] = {0.7, 0.15, 0.15,
                            0.3, 0.4, 0.3,
                            0.3, 0.4, 0.3};
    cv::Mat TRGUESS = cv::Mat(3,3,CV_64F,TRGUESSdata).clone();
    double EMITGUESSdata[] = {0.3, 0.1, 0.1, 0.1, 0.1,
                              0.2, 0.1, 0.2, 0.2, 0.3,
                              0.2, 0.3, 0.2, 0.2, 0.1};
    cv::Mat EMITGUESS = cv::Mat(3,5,CV_64F,EMITGUESSdata).clone();
    double INITGUESSdata[] = {0.6 , 0.2 , 0.2};
    cv::Mat INITGUESS = cv::Mat(1,3,CV_64F,INITGUESSdata).clone();
    std::cout << seq.rows << " "  << seq.cols << std::endl;
    int a = 0;
    std::ifstream fin;
    fin.open("observations.txt");

    for(int y =0; y < seq.rows; y++)
    {
        for(int x = 0; x<seq.cols ; x++)
        {

            fin >> a;
            seq.at<signed int>(y,x) = (signed int)a;
            std::cout << a;
        }
        std::cout << std::endl;
    }

     hmm.printModel(TRGUESS,EMITGUESS,INITGUESS);
    hmm.train(seq,1000,TRGUESS,EMITGUESS,INITGUESS);
    hmm.printModel(TRGUESS,EMITGUESS,INITGUESS);

Tutaj płetwa jest używana do odczytania obserwacji z mojego innego kodu.

questionAnswers(1)

yourAnswerToTheQuestion