寫公式的地方

已知有一系列觀測Y_0, Y_1,\cdots, Y_{N-1}贱案,且Y_i\in\mathcal{N}刀脏,其表達式如下
y_n=\lfloor x_n\rfloor=\lfloor x_0+an+\varepsilon \rfloor

其中噪聲\varepsilon\sim\mathcal{N}(0,\sigma^2),現(xiàn)需要求解x_0,a

根據(jù)問題最住,易得x_i的概率密度函數(shù)為
f(x_i|x_0,a)=\frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{1}{2\sigma^2}(x_i-x_0-ai)}

因此可以得到
P(y_i=Y_i|x_0,a)=\int_{Y_i}^{Y_i+1}f(x_i|x_0,a)dx_i=\Phi(\frac{Y_i+1-x_0-an}{\sigma})-\Phi(\frac{Y_i-x_0-an}{\sigma})

其中\Phi(x)=\frac{1}{2\pi}\int_{-\infty}^xe^{-\frac{1}{2}t^2}dt钞澳,為標準累積分布函數(shù)

如果認為每次測量獨立,則所有觀測的先驗概率為
P(y_0=Y_0,\cdots,y_{n-1}=Y_{n-1}|x_0,a)=\prod_{i=0}^{N-1}P(y_i=Y_i|x_0,a)

現(xiàn)在需要求解x_0,a使得上式最大涨缚,這里采用數(shù)值解法

  1. 首先假設(shè)y_i\approx x_i轧粟,直接通過最小二乘(高斯下的最優(yōu)解)得到x_0,a的初始值
  2. 求解導(dǎo)數(shù)\frac{\partial P}{\partial x_0}, \frac{\partial P}{\partial a}
    \frac{\partial P}{\partial x_0}=\sum_{j=0}^{N-1}[-f(Y_j+1)+f(Y_j)]\prod_{i\ne j}P(y_i=Y_i|x_0,a)

\frac{\partial P}{\partial a}=\sum_{j=0}^{N-1}j[-f(Y_j+1)+f(Y_j)]\prod_{i\ne j}P(y_i=Y_i|x_0,a)

  1. 更新直到收斂

=================================================================================

\min\quad(e^\boldsymbol\omega\boldsymbol\mu_1-\boldsymbol\mu_2)^T(e^\boldsymbol\omega\boldsymbol\Sigma_1{e^\boldsymbol\omega}^T+\boldsymbol\Sigma_2)^{-1}(e^\boldsymbol\omega\boldsymbol\mu_1-\boldsymbol\mu_2)

\min\quad\boldsymbol{f}(\boldsymbol\omega)^T\boldsymbol{f}(\boldsymbol\omega)

\boldsymbol{J}=\frac{\partial \boldsymbol{f}(\boldsymbol\omega)}{\partial\boldsymbol\omega}

\boldsymbol{f}(\boldsymbol\omega)=(e^\boldsymbol\omega\boldsymbol\Sigma_1{e^\boldsymbol\omega}^T+\boldsymbol\Sigma_2)^{-\frac{1}{2}}(e^\boldsymbol\omega\boldsymbol\mu_1-\boldsymbol\mu_2)

cmake_minimum_required(VERSION 3.9)

project(aoi)
enable_language(CUDA)


set(CMAKE_BUILD_TYPE Release)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
# set(CMAKE_CUDA_ARCHITECTURES 61)


include_directories(${PROJECT_SOURCE_DIR}/include)

aux_source_directory(src SRC_LIST)                                                                                                                                                                                                                                                                                                                                                      

add_executable(${PROJECT_NAME} ${SRC_LIST})
#include <iostream>
#include <chrono>
#include "cuda_operator.cuh"



int main() {
    auto time_start = std::chrono::system_clock::now();

    auto time_end = std::chrono::system_clock::now();
    auto duration = time_end - time_start;

    std::cout << "cost time: " << duration.count() / 1000000.0 << " ms" << std::endl;

    MatchTemplateGPU();

    return 0;
}
#include <iostream>
#include <vector>
#include <chrono>
#include "cuda_operator.cuh"


__global__ void MatchTemplateKernel(int *image, int image_width, int image_height, float *conv_res) {
    // image size : height * width
    // conv_res size : (height + 1) * (width + 1)

    int row_col = blockIdx.x * blockDim.x + threadIdx.x;

    int *image_ptr = image + row_col * image_width;
    float *res_ptr = conv_res + (row_col + 1) * (image_width + 1);
    float temp     = 0.0;

    if(row_col < image_height) {
        *res_ptr = 0;
        for(int i = 0; i < image_width; ++i) {
            temp += *image_ptr;
            ++image_ptr;

            ++res_ptr;
            *res_ptr = temp;
        }
    }

    // __syncthreads();
    __threadfence();

    res_ptr = conv_res + row_col + 1;
    temp = 0.0;
    if(row_col < image_width) {
        *res_ptr = 0;
        for(int i = 0; i < image_height; ++i) {
            res_ptr += image_width + 1;
            temp += *res_ptr;
            *res_ptr = temp;
        }
    }
}

__global__ void PrefixSumRow(int *image, int image_width, int image_height, float *res) {
    // image size : height * width
    // res size : (height + 1) * (width + 1)

    int row = blockIdx.x * blockDim.x + threadIdx.x;

    int *image_ptr = image + row * image_width;
    float *res_ptr = res + (row + 1) * (image_width + 1);
    float temp     = 0.0;

    if(row < image_height) {
        *res_ptr = 0;
        for(int i = 0; i < image_width; ++i) {
            temp += *image_ptr;
            ++image_ptr;

            ++res_ptr;
            *res_ptr = temp;
        }
    }
}


__global__ void PrefixSumColumn(float *res, int res_width, int res_height) {
    int col = blockIdx.x * blockDim.x + threadIdx.x;

    float *res_ptr = res + col;
    float pre_sum  = *res_ptr;

    if(col < res_width) {
        *res_ptr = pre_sum;
        for(int i = 0; i < res_height; ++i) {
            res_ptr += res_width;
            pre_sum += *res_ptr;
            *res_ptr = pre_sum;
        }
    }
}


__global__ void PrefixSumColumn1(float *img, int img_width, int img_height) {
    __shared__ float integral_img[32][32];

    int bundle_row_num      = blockDim.x / 32;
    int local_row           = threadIdx.x / 32;
    int local_col           = threadIdx.x % 32;
    int global_col          = blockIdx.x * 32 + local_col;
    
    int row_start           = 0;
    float cur_thread_value  = 0.0;
    float pre_sum           = 0.0;
    float step_sum          = 0.0;
    float *integral_ptr     = NULL;
    
    // integral_img[local_row][local_col] = 0.0;
    // __syncthreads();

    for(row_start = 0; row_start + bundle_row_num <= img_height; row_start += bundle_row_num) {
        if(global_col < img_width) {
            integral_ptr = img + (row_start + local_row) * img_width + global_col;

            integral_img[local_row][local_col] = *integral_ptr;

            __syncthreads();

            step_sum = integral_img[threadIdx.x % bundle_row_num][threadIdx.x / bundle_row_num];

#pragma unroll
            for(int i = 1; i <= 16; i *= 2) {
                cur_thread_value = __shfl_up_sync(0xffffffff, step_sum, i, 32);
                if(threadIdx.x % bundle_row_num >= i) {
                    step_sum += cur_thread_value;
                }
            }

            step_sum += pre_sum;
            pre_sum = __shfl_sync(0xffffffff, step_sum, bundle_row_num - 1, bundle_row_num);

            __syncthreads();

            *integral_ptr = step_sum;
        }
    }

    if(row_start + local_row < img_height && global_col < img_width) {
        integral_ptr = img + (row_start + local_row) * img_width + global_col;

        integral_img[local_row][local_col] = *integral_ptr;

        __syncthreads();

        step_sum = integral_img[threadIdx.x % bundle_row_num][threadIdx.x / bundle_row_num];

#pragma unroll
        for(int i = 1; i <= 16; i *= 2) {
            cur_thread_value = __shfl_up_sync(0xffffffff, step_sum, i, 32);
            if(threadIdx.x % bundle_row_num >= i) {
                step_sum += cur_thread_value;
            }
        }

        step_sum += pre_sum;

        __syncthreads();

        *integral_ptr = step_sum;
    }
}


void MatchTemplateGPU() {
    int image_width = 10;
    int image_height = 10;
    int image_size = image_width * image_height;
    int integral_image_size = (image_width + 1) * (image_height + 1);

    std::vector<float> res(integral_image_size, 0);
    std::vector<int> image(image_size, 0);

    for(int i = 0; i < image.size(); ++i) {
        image[i] = i + 1;
    }

    float count = 1;
    for(int i = image_width + 1; i < res.size(); ++i) {
        if(i % (image_width + 1) == 0) continue;
        res[i] = count++;
    }

    std::cout << "conv res" << std::endl;
    for(int i = 0; i <= image_height; ++i) {
        for(int j = 0; j <= image_width; ++j) {
            std::cout << res[i * (image_width + 1) + j] << " ";
        }
        std::cout << std::endl;
    }


    image_size = image_size * sizeof(int);
    integral_image_size = integral_image_size * sizeof(float);

    dim3 threads_per_block(32 * 32);
    dim3 blocks_per_grid((max(image_width, image_height) + threads_per_block.x - 1) / threads_per_block.x);

    int *image_gpu;
    float *res_gpu;
    cudaMalloc(&image_gpu, image_size);
    cudaMalloc(&res_gpu, integral_image_size);
    // cudaMemset(res_gpu, 0, integral_image_size);
    
    cudaMemcpy(image_gpu, &image[0], image_size, cudaMemcpyHostToDevice);
    cudaMemcpy(res_gpu, &res[0], integral_image_size, cudaMemcpyHostToDevice);

    auto time_start = std::chrono::system_clock::now();

    // MatchTemplateKernel<<<blocks_per_grid, threads_per_block>>>(image_gpu, image_width, image_height, res_gpu);
    // cudaDeviceSynchronize();

    // PrefixSumRow<<<blocks_per_grid, threads_per_block>>>(image_gpu, image_width, image_height, res_gpu);
    // PrefixSumColumn<<<blocks_per_grid, threads_per_block>>>(res_gpu, image_width + 1, image_height + 1);
    PrefixSumColumn1<<<blocks_per_grid, threads_per_block>>>(res_gpu, image_width + 1, image_height + 1);

    // cudaError_t err = cudaGetLastError();
    // if(err != cudaSuccess) {
    //     printf("CUDA Error: %s\n", cudaGetErrorString(err));
    // }

    auto time_end = std::chrono::system_clock::now();
    auto duration = time_end - time_start;

    cudaMemcpy(&res[0], res_gpu, integral_image_size, cudaMemcpyDeviceToHost);

    std::cout << "GPU cost time: " << duration.count() / 1000000.0 << " ms" << std::endl;

    cudaFree(image_gpu);
    cudaFree(res_gpu);

    // std::cout << "image" << std::endl;
    // for(int i = 0; i < image_height; ++i) {
    //     for(int j = 0; j < image_width; ++j) {
    //         std::cout << image[i * image_width + j] << " ";
    //     }
    //     std::cout << std::endl;
    // }


    std::cout << "conv res" << std::endl;
    for(int i = 0; i <= image_height; ++i) {
        for(int j = 0; j <= image_width; ++j) {
            std::cout << res[i * (image_width + 1) + j] << " ";
        }
        std::cout << std::endl;
    }
}





最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市脓魏,隨后出現(xiàn)的幾起案子兰吟,更是在濱河造成了極大的恐慌,老刑警劉巖茂翔,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件混蔼,死亡現(xiàn)場離奇詭異,居然都是意外死亡珊燎,警方通過查閱死者的電腦和手機惭嚣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門遵湖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人晚吞,你說我怎么就攤上這事延旧。” “怎么了槽地?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵垄潮,是天一觀的道長。 經(jīng)常有香客問我闷盔,道長弯洗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任逢勾,我火速辦了婚禮牡整,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘溺拱。我一直安慰自己逃贝,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布迫摔。 她就那樣靜靜地躺著沐扳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪句占。 梳的紋絲不亂的頭發(fā)上沪摄,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音纱烘,去河邊找鬼杨拐。 笑死,一個胖子當(dāng)著我的面吹牛擂啥,可吹牛的內(nèi)容都是我干的哄陶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼哺壶,長吁一口氣:“原來是場噩夢啊……” “哼屋吨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起山宾,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤至扰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后塌碌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渊胸,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡旬盯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年台妆,在試婚紗的時候發(fā)現(xiàn)自己被綠了翎猛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡接剩,死狀恐怖切厘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情懊缺,我是刑警寧澤疫稿,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站鹃两,受9級特大地震影響遗座,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俊扳,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一途蒋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧馋记,春花似錦号坡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至茸习,卻和暖如春畜隶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背号胚。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工代箭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涕刚。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓嗡综,卻偏偏與公主長得像,于是被迫代替她去往敵國和親杜漠。 傳聞我的和親對象是個殘疾皇子极景,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 微積分共七講,其中上冊有三講:極限驾茴、一元函數(shù)微分學(xué)盼樟、一元函數(shù)積分學(xué);下冊有四講:多元微分學(xué)锈至、二重積分晨缴、微分方程、無...
    蘇醒7閱讀 2,218評論 3 5
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險厭惡者峡捡,不喜歡去冒險击碗,但是人生放棄了冒險筑悴,也就放棄了無數(shù)的可能。 ...
    yichen大刀閱讀 6,052評論 0 4
  • 公元:2019年11月28日19時42分農(nóng)歷:二零一九年 十一月 初三日 戌時干支:己亥乙亥己巳甲戌當(dāng)月節(jié)氣:立冬...
    石放閱讀 6,880評論 0 2
  • 昨天考過了阿里規(guī)范稍途,心里舒坦了好多阁吝,敲代碼也猶如神助。早早完成工作回家嘍
    常亞星閱讀 3,038評論 0 1
  • 三軍可奪氣械拍,將軍可奪心突勇。是故朝氣銳,晝氣惰坷虑,暮氣歸甲馋。善用兵者,避其銳氣迄损,擊其惰歸摔刁,此治氣者也。以治待亂海蔽,以靜待嘩共屈,...
    生姜牛奶泡騰片閱讀 1,577評論 0 1