dlib 08 dlib自带demo 基于ResNet34的imagenet图像分类

来源:互联网 发布:部落冲突三王升级数据 编辑:程序博客网 时间:2024/05/18 10:31

01 资源

代码:dlib\examples\dnn_imagenet_ex.cpp
工程名:dnn_imagenet_ex
模型文件:http://dlib.net/files/resnet34_1000_imagenet_classifier.dnn.bz2
下载后,解压到Debug/Release目录:resnet34_1000_imagenet_classifier.dnn
测试图像文件:dlib\data\cat.jpg(这个小猫来自caffe的imagenet demo里。)
cat.jpg

02 项目设置

把examples解决方案中的dnn_imagenet_ex 工程设置为启动项。

配置属性==>调试==>命令参数==>..\..\..\data\cat.jpg配置属性==>调试==>工作目录==>$(OutDir)

这里写图片描述

03 运行结果

0.263102: tiger_cat0.148648: Egyptian_cat0.117797: tabby0.0624845: lynx0.0490106: PembrokeHit enter to process the next image

04 代码

// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt/*    This example shows how to classify an image into one of the 1000 imagenet    categories using the deep learning tools from the dlib C++ Library.  We will    use the pretrained ResNet34 model available on the dlib website.    The ResNet34 architecture is from the paper Deep Residual Learning for Image    Recognition by He, Zhang, Ren, and Sun.  The model file that comes with dlib    was trained using the dnn_imagenet_train_ex.cpp program on a Titan X for    about 2 weeks.  This pretrained model has a top5 error of 7.572% on the 2012    imagenet validation dataset.    For an introduction to dlib's DNN module read the dnn_introduction_ex.cpp and    dnn_introduction2_ex.cpp example programs.    Finally, these tools will use CUDA and cuDNN to drastically accelerate    network training and testing.  CMake should automatically find them if they    are installed and configure things appropriately.  If not, the program will    still run but will be much slower to execute.*/#include <dlib/dnn.h>#include <iostream>#include <dlib/data_io.h>#include <dlib/gui_widgets.h>#include <dlib/image_transforms.h>using namespace std;using namespace dlib;// ----------------------------------------------------------------------------------------// This block of statements defines the resnet-34 networktemplate <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>using residual = add_prev1<block<N,BN,1,tag1<SUBNET>>>;template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>using residual_down = add_prev2<avg_pool<2,2,2,2,skip1<tag2<block<N,BN,2,tag1<SUBNET>>>>>>;template <int N, template <typename> class BN, int stride, typename SUBNET> using block  = BN<con<N,3,3,1,1,relu<BN<con<N,3,3,stride,stride,SUBNET>>>>>;template <int N, typename SUBNET> using ares      = relu<residual<block,N,affine,SUBNET>>;template <int N, typename SUBNET> using ares_down = relu<residual_down<block,N,affine,SUBNET>>;template <typename SUBNET> using level1 = ares<512,ares<512,ares_down<512,SUBNET>>>;template <typename SUBNET> using level2 = ares<256,ares<256,ares<256,ares<256,ares<256,ares_down<256,SUBNET>>>>>>;template <typename SUBNET> using level3 = ares<128,ares<128,ares<128,ares_down<128,SUBNET>>>>;template <typename SUBNET> using level4 = ares<64,ares<64,ares<64,SUBNET>>>;using anet_type = loss_multiclass_log<fc<1000,avg_pool_everything<                            level1<                            level2<                            level3<                            level4<                            max_pool<3,3,2,2,relu<affine<con<64,7,7,2,2,                            input_rgb_image_sized<227>                            >>>>>>>>>>>;// ----------------------------------------------------------------------------------------rectangle make_random_cropping_rect_resnet(    const matrix<rgb_pixel>& img,    dlib::rand& rnd){    // figure out what rectangle we want to crop from the image    double mins = 0.466666666, maxs = 0.875;    auto scale = mins + rnd.get_random_double()*(maxs-mins);    auto size = scale*std::min(img.nr(), img.nc());    rectangle rect(size, size);    // randomly shift the box around    point offset(rnd.get_random_32bit_number()%(img.nc()-rect.width()),                 rnd.get_random_32bit_number()%(img.nr()-rect.height()));    return move_rect(rect, offset);}// ----------------------------------------------------------------------------------------void randomly_crop_images (    const matrix<rgb_pixel>& img,    dlib::array<matrix<rgb_pixel>>& crops,    dlib::rand& rnd,    long num_crops){    std::vector<chip_details> dets;    for (long i = 0; i < num_crops; ++i)    {        auto rect = make_random_cropping_rect_resnet(img, rnd);        dets.push_back(chip_details(rect, chip_dims(227,227)));    }    extract_image_chips(img, dets, crops);    for (auto&& img : crops)    {        // Also randomly flip the image        if (rnd.get_random_double() > 0.5)            img = fliplr(img);        // And then randomly adjust the colors.        apply_random_color_offset(img, rnd);    }}// ----------------------------------------------------------------------------------------int main(int argc, char** argv) try{    if (argc == 1)    {        cout << "Give this program image files as command line arguments.\n" << endl;        cout << "You will also need a copy of the file resnet34_1000_imagenet_classifier.dnn " << endl;        cout << "available at http://dlib.net/files/resnet34_1000_imagenet_classifier.dnn.bz2" << endl;        cout << endl;        return 1;    }    std::vector<string> labels;    anet_type net;    deserialize("resnet34_1000_imagenet_classifier.dnn") >> net >> labels;    // Make a network with softmax as the final layer.  We don't have to do this    // if we just want to output the single best prediction, since the anet_type    // already does this.  But if we instead want to get the probability of each    // class as output we need to replace the last layer of the network with a    // softmax layer, which we do as follows:    softmax<anet_type::subnet_type> snet;     snet.subnet() = net.subnet();    dlib::array<matrix<rgb_pixel>> images;    matrix<rgb_pixel> img, crop;    dlib::rand rnd;    image_window win;    // Read images from the command prompt and print the top 5 best labels for each.    for (int i = 1; i < argc; ++i)    {        load_image(img, argv[i]);        const int num_crops = 16;        // Grab 16 random crops from the image.  We will run all of them through the        // network and average the results.        randomly_crop_images(img, images, rnd, num_crops);        // p(i) == the probability the image contains object of class i.        matrix<float,1,1000> p = sum_rows(mat(snet(images.begin(), images.end())))/num_crops;        win.set_image(img);        // Print the 5 most probable labels        for (int k = 0; k < 5; ++k)        {            unsigned long predicted_label = index_of_max(p);            cout << p(predicted_label) << ": " << labels[predicted_label] << endl;            p(predicted_label) = 0;        }        cout << "Hit enter to process the next image";        cin.get();    }}catch(std::exception& e){    cout << e.what() << endl;}