matlab除錯卷積深度置信網路CDBN-master的時候出現crbm_forward2D_batch_mex沒法識別(解決)

塵封的記憶0發表於2017-05-04

   今天幫群裡的一個群友調matlab程式碼,CDBN,卷積深度置信網路,他說的是這個錯誤改了好幾天都沒法改,其實就是matlab如何呼叫c語言的問題,挺簡單的。下面說說我的做法和如何在matlab中呼叫c語言的問題。

有一個通俗的比喻, 如果程式設計語言是車,那麼C 語言就是全能手, C十十語言是加強版的C 語言, MATLAB是科學

家用來完成特殊任務的工具。作為使用MATLAB 的科學家和工程師, 通過混合程式設計,就可以借用CIC十十語言這兩個全能手增強

MATLAB 的功能;作為使用C/C十十語言開發的開發者,也可以通過混合程式設計來使用MATLAB強大的科學計算與資料視覺化功能。

  1. 準備好C語言程式,一般情況下要清楚C語言的入口函式,比如,如下的C語言函式:

    void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

  2. 編寫mexfunction函式。mexfunction函式為C語言與MATLAB語言的介面函式。呼叫例項在mylinedetect.c檔案中,檔案內容如下:

    #include <math.h>
    #include <mex.h>
    #include <matrix.h>
    #include <time.h>
    #include <string.h>


    void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    {
    const mxArray  *model, *layer, *batch_data;
         mxArray  *model_new, *h_input_array, *h_sample_array, *output_array;
        int            ni,N,n_dim,n_map_h, n_map_v, nh,nv,j,i,jj,ii,id,
                  Hstride,Wstride,Hfilter,Wfilter,Hres,Wres,H,W,Hpool,Wpool,Hout,Wout;
    int            *_id;
    double         *s_filter, *stride, *h, *data, *weights, *h_bias, *block, *pool,
                       *h_input, *h_sample, *output, *gaussian;
    mwSize         *dim_vi, *dim_hi, *dim_id, *dim_h, *dim_out;
        mxChar         *type;


        model          = prhs[0];
    layer          = prhs[1];
    batch_data     = prhs[2];

        dim_vi         = mxGetDimensions(batch_data);
        n_dim          = mxGetNumberOfDimensions(batch_data);


        if (n_dim == 2 || n_dim == 3)
        N = 1;
        else
        N = dim_vi[3];


        dim_h          = (mwSize*)mxMalloc(sizeof(mwSize)*4);
    dim_hi         = mxGetDimensions(mxGetField(model,0,"h_input"));
        dim_h[0]       = dim_hi[0];
        dim_h[1]       = dim_hi[1];
        dim_h[2]       = dim_hi[2];
        dim_h[3]       = N;


        n_map_h        = mxGetScalar(mxGetField(layer,0,"n_map_h"));
    n_map_v        = mxGetScalar(mxGetField(layer,0,"n_map_v"));
        s_filter       = mxGetPr(mxGetField(layer,0,"s_filter"));   
        stride         = mxGetPr(mxGetField(layer,0,"stride"));
        data           = mxGetPr(batch_data);
        weights        = mxGetPr(mxGetField(model,0,"W"));
        h              = mxGetPr(mxCreateNumericArray(4,dim_h,mxDOUBLE_CLASS,mxREAL));
        h_bias         = mxGetPr(mxGetField(model,0,"h_bias"));
        block          = mxGetPr(mxCreateNumericArray(4,dim_h,mxDOUBLE_CLASS,mxREAL));
        pool           = mxGetPr(mxGetField(layer,0,"s_pool"));
    h_input_array  = mxCreateNumericArray(4,dim_h,mxDOUBLE_CLASS, mxREAL);
    h_input        = mxGetPr(h_input_array);
    h_sample_array = mxCreateNumericArray(4,dim_h,mxDOUBLE_CLASS, mxREAL);
    h_sample       = mxGetPr(h_sample_array);
        dim_out        = mxGetDimensions(mxGetField(model,0,"output"));
        dim_out[3]     = N;
        output_array   = plhs[0] = mxCreateNumericArray(4,dim_out,mxDOUBLE_CLASS, mxREAL);
        output         = mxGetPr(output_array);
        gaussian       = mxGetPr(mxGetField(model,0,"start_gau"));
        type           = mxGetChars(mxGetField(layer,0,"type_input"));


        /*Here need to pay attention to the _id:mxUINT32_CLASS*/
        dim_id         = (mwSize*)mxMalloc(sizeof(mwSize)*2);
        dim_id[0]      = pool[0]; dim_id[1] = pool[1];
        _id            = mxGetPr(mxCreateNumericArray(2,dim_id,mxUINT32_CLASS,mxREAL));


        mxFree(dim_id);
        mxFree(dim_h);


        Hstride        = stride[0];
        Wstride        = stride[1];
        Hfilter        = s_filter[0];
        Wfilter        = s_filter[1];
        H              = dim_vi[0];
        W              = dim_vi[1];
        Hres           = dim_hi[0];
        Wres           = dim_hi[1];
        Hpool          = pool[0];
        Wpool          = pool[1];
        Hout           = floor(Hres/Hpool);
        Wout           = floor(Wres/Wpool);


        for (ni = 0; ni < N; ni++){
            for (nh = 0; nh < n_map_h; nh++){


                for (j = 0; j < Wres; j++){
                    for (i = 0; i < Hres; i++){
                        id = i+Hres*j+Hres*Wres*nh+Hres*Wres*n_map_h*ni;
                        h[id] = 0;
                        h_input[id] = 0;


                        for (nv = 0; nv < n_map_v; nv++){
                            for (jj = 0; jj < Wfilter; jj++){
                                for (ii = 0; ii < Hfilter; ii++){


                                    h[id] += data[(i*Hstride+ii)+H*(j*Wstride+jj)+H*W*nv+H*W*n_map_v*ni]
                                            * weights[(ii+Hfilter*jj)+Hfilter*Wfilter*nv+Hfilter*Wfilter*n_map_v*nh];


                                }
                            }
                        }


                        h_input[id] = h[id] + h_bias[nh];


                        /* for crbm blocksum & outpooing */
                        if (type[0] == 'B')
                            block[id] = exp(h_input[id]);
                        if (type[0] == 'G')
                            block[id] = exp(1.0/(gaussian[0]*gaussian[0])*h_input[id]);
                    }
                }




                /* output the pooling & crbm blocksum: hidden activation summation */


                for (j = 0; j < Wout; j++){
                    for (i = 0; i < Hout; i++){


                        double sum = 0.0;
                        for (jj = 0; jj < Wpool; jj++){
                            _id[jj*Hpool] = i*Hpool+(j*Wpool+jj)*Hres + Hres*Wres*nh+Hres*Wres*n_map_h*ni;
                            sum += block[_id[jj*Hpool]];
                            for (ii = 1; ii < Hpool; ii++){


                                _id[jj*Hpool+ii] = _id[jj*Hpool+ii-1] + 1;
                                sum += block[_id[jj*Hpool+ii]];


                            }
                        }


                        int out_id = i+j*Hout+Hout*Wout*nh+Hout*Wout*n_map_h*ni;
                        for (jj = 0; jj < Hpool*Wpool; jj++){
                            h_sample[_id[jj]] = 1.0-(1.0/(1.0+sum));


                        }


                        output[out_id] = h_sample[_id[0]];
                    }
                }
            }
        }


        return;


    }

  3. 4

    在MATLAB中呼叫mex指令編譯相關檔案,將C語言編譯為MEX檔案,如下所示。

    mex mylinedetect.c linedetect.c

    編譯完成後,生成mylinedetect.mexw32或mylinedetect.mexw64檔案,此檔案即mex檔案,用於MATLAB與C語言介面函式

  4. 5

    編譯完成之後,編寫MATLAB函式,呼叫MEX檔案。如下所示。

    load trees;

    %以MEX檔案的形式呼叫編譯完成的C語言函式

    [o1,o2]=mylinedetect(double(X).');

    ......

  5. 6

    輸出結果,上述linedetect函式完成影象中直線檢測功能,帶入MATLAB中呼叫後,形成如下結果。




  6. 不懂的可以加我的QQ群:522869126(語音訊號處理) 歡迎你

    到來哦,看了博文給點腳印唄,謝謝啦~~


相關文章