From 876716fb27c059e2723964ed81c6aec81bfc52f7 Mon Sep 17 00:00:00 2001 From: agam1994 Date: Fri, 8 Jul 2016 11:57:39 +0530 Subject: [PATCH 01/14] Update fetch_selective_search_data.sh --- data/scripts/fetch_selective_search_data.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/scripts/fetch_selective_search_data.sh b/data/scripts/fetch_selective_search_data.sh index 84c0acaf5..d8222341c 100755 --- a/data/scripts/fetch_selective_search_data.sh +++ b/data/scripts/fetch_selective_search_data.sh @@ -4,8 +4,8 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" && pwd )" cd $DIR FILE=selective_search_data.tgz -URL=http://www.cs.berkeley.edu/~rbg/fast-rcnn-data/$FILE -CHECKSUM=7078c1db87a7851b31966b96774cd9b9 +URL=ftp://ftp.cs.berkeley.edu/pub/projects/vision/$FILE +CHECKSUM=c341da31579e305292bf5ec08298b87c if [ -f $FILE ]; then echo "File already exists. Checking md5..." @@ -23,7 +23,7 @@ if [ -f $FILE ]; then fi fi -echo "Downloading precomputed selective search boxes (0.5G)..." +echo "Downloading Edge boxes for COCO train, val, and test-dev set..." wget $URL -O $FILE From 03a051ebcf4014acf2bb4697f4520dd1d13530c6 Mon Sep 17 00:00:00 2001 From: agam1994 Date: Fri, 8 Jul 2016 12:08:11 +0530 Subject: [PATCH 02/14] Update fetch_selective_search_data.sh --- data/scripts/fetch_selective_search_data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/scripts/fetch_selective_search_data.sh b/data/scripts/fetch_selective_search_data.sh index d8222341c..dd3204e49 100755 --- a/data/scripts/fetch_selective_search_data.sh +++ b/data/scripts/fetch_selective_search_data.sh @@ -3,7 +3,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" && pwd )" cd $DIR -FILE=selective_search_data.tgz +FILE=edge_box_data.tgz URL=ftp://ftp.cs.berkeley.edu/pub/projects/vision/$FILE CHECKSUM=c341da31579e305292bf5ec08298b87c From 601f27634fd97aa0d1a32c19901eab9abbc88035 Mon Sep 17 00:00:00 2001 From: agam1994 Date: Fri, 8 Jul 2016 12:10:26 +0530 Subject: [PATCH 03/14] Rename fetch_selective_search_data.sh to fetch_edge_box_data.sh --- .../{fetch_selective_search_data.sh => fetch_edge_box_data.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename data/scripts/{fetch_selective_search_data.sh => fetch_edge_box_data.sh} (100%) diff --git a/data/scripts/fetch_selective_search_data.sh b/data/scripts/fetch_edge_box_data.sh similarity index 100% rename from data/scripts/fetch_selective_search_data.sh rename to data/scripts/fetch_edge_box_data.sh From e933fe15d87265bd34f835006bb5d1ed48d350ff Mon Sep 17 00:00:00 2001 From: agam1994 Date: Fri, 8 Jul 2016 12:16:05 +0530 Subject: [PATCH 04/14] Update imdb.py --- lib/datasets/imdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/datasets/imdb.py b/lib/datasets/imdb.py index b56bf0a80..1679aba84 100644 --- a/lib/datasets/imdb.py +++ b/lib/datasets/imdb.py @@ -21,7 +21,7 @@ def __init__(self, name): self._num_classes = 0 self._classes = [] self._image_index = [] - self._obj_proposer = 'selective_search' + self._obj_proposer = 'edge_box' self._roidb = None self._roidb_handler = self.default_roidb # Use this dict for storing dataset specific config options From 5f8feb2478cfb30aa3a39608fa9bd44110e7a0ec Mon Sep 17 00:00:00 2001 From: agam1994 Date: Fri, 8 Jul 2016 12:21:57 +0530 Subject: [PATCH 05/14] Update pascal_voc.py --- lib/datasets/pascal_voc.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/datasets/pascal_voc.py b/lib/datasets/pascal_voc.py index b55f2f6b2..3d63373e9 100644 --- a/lib/datasets/pascal_voc.py +++ b/lib/datasets/pascal_voc.py @@ -37,7 +37,7 @@ def __init__(self, image_set, year, devkit_path=None): self._image_ext = '.jpg' self._image_index = self._load_image_set_index() # Default to roidb handler - self._roidb_handler = self.selective_search_roidb + self._roidb_handler = self.edge_box_roidb self._salt = str(uuid.uuid4()) self._comp_id = 'comp4' @@ -111,15 +111,15 @@ def gt_roidb(self): return gt_roidb - def selective_search_roidb(self): + def edge_box_roidb(self): """ - Return the database of selective search regions of interest. + Return the database of edge box regions of interest. Ground-truth ROIs are also included. This function loads/saves from/to a cache file to speed up future calls. """ cache_file = os.path.join(self.cache_path, - self.name + '_selective_search_roidb.pkl') + self.name + '_edge_box_roidb.pkl') if os.path.exists(cache_file): with open(cache_file, 'rb') as fid: @@ -129,10 +129,10 @@ def selective_search_roidb(self): if int(self._year) == 2007 or self._image_set != 'test': gt_roidb = self.gt_roidb() - ss_roidb = self._load_selective_search_roidb(gt_roidb) + ss_roidb = self._load_edge_box_roidb(gt_roidb) roidb = imdb.merge_roidbs(gt_roidb, ss_roidb) else: - roidb = self._load_selective_search_roidb(None) + roidb = self._load_edge_box_roidb(None) with open(cache_file, 'wb') as fid: cPickle.dump(roidb, fid, cPickle.HIGHEST_PROTOCOL) print 'wrote ss roidb to {}'.format(cache_file) @@ -158,12 +158,12 @@ def _load_rpn_roidb(self, gt_roidb): box_list = cPickle.load(f) return self.create_roidb_from_box_list(box_list, gt_roidb) - def _load_selective_search_roidb(self, gt_roidb): + def _load_edge_box_roidb(self, gt_roidb): filename = os.path.abspath(os.path.join(cfg.DATA_DIR, - 'selective_search_data', + 'edge_box_data', self.name + '.mat')) assert os.path.exists(filename), \ - 'Selective search data not found at: {}'.format(filename) + 'edge data not found at: {}'.format(filename) raw_data = sio.loadmat(filename)['boxes'].ravel() box_list = [] From e355af039a7014063f35472828f72f4f3f0931f4 Mon Sep 17 00:00:00 2001 From: agam1994 Date: Fri, 8 Jul 2016 12:32:15 +0530 Subject: [PATCH 06/14] Update config.py --- lib/fast_rcnn/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fast_rcnn/config.py b/lib/fast_rcnn/config.py index 253017369..c3db065e7 100644 --- a/lib/fast_rcnn/config.py +++ b/lib/fast_rcnn/config.py @@ -89,7 +89,7 @@ __C.TRAIN.BBOX_NORMALIZE_STDS = (0.1, 0.1, 0.2, 0.2) # Train using these proposals -__C.TRAIN.PROPOSAL_METHOD = 'selective_search' +__C.TRAIN.PROPOSAL_METHOD = 'edge_box' # Make minibatches from images that have similar aspect ratios (i.e. both # tall and thin or both short and wide) in order to avoid wasting computation @@ -152,7 +152,7 @@ __C.TEST.HAS_RPN = False # Test using these proposals -__C.TEST.PROPOSAL_METHOD = 'selective_search' +__C.TEST.PROPOSAL_METHOD = 'edge_box' ## NMS threshold used on RPN proposals __C.TEST.RPN_NMS_THRESH = 0.7 From c54dd43101bd2b430658b4f66af669d65ba5c99a Mon Sep 17 00:00:00 2001 From: agam1994 Date: Fri, 8 Jul 2016 12:42:32 +0530 Subject: [PATCH 07/14] Update eval_recall.py --- tools/eval_recall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/eval_recall.py b/tools/eval_recall.py index b1a59dc27..9ebc6ddb6 100755 --- a/tools/eval_recall.py +++ b/tools/eval_recall.py @@ -17,7 +17,7 @@ def parse_args(): default='voc_2007_test', type=str) parser.add_argument('--method', dest='method', help='proposal method', - default='selective_search', type=str) + default='edge_box', type=str) parser.add_argument('--rpn-file', dest='rpn_file', default=None, type=str) From ff00564a78bafb4493c0e3c8d0712363cef2208a Mon Sep 17 00:00:00 2001 From: agam1994 Date: Thu, 14 Jul 2016 11:36:30 +0530 Subject: [PATCH 08/14] Add files via upload --- BingObjectnessCVPR14 (1).zip | Bin 0 -> 333552 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 BingObjectnessCVPR14 (1).zip diff --git a/BingObjectnessCVPR14 (1).zip b/BingObjectnessCVPR14 (1).zip new file mode 100644 index 0000000000000000000000000000000000000000..4cc4cb6a17a1afa31d1a71074f1e7de00475fd4f GIT binary patch literal 333552 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

>KE3gs06A)rd;5OMOyR8eZsN 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 z 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

Nj&I#f}OPxne7FEh8=_zF2Y4) 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

F%|2 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

J;N3|cgSS6C#VX~HpkvT;uB)CY@u`0mZ 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

NCyqtGEi2r&M$bA?u_dSSt0`GRwtSLOapw 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 CuKj?9;Y8r9 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 Date: Thu, 14 Jul 2016 11:39:50 +0530 Subject: [PATCH 09/14] Add files via upload --- Bing/LICENSE | 27 + Bing/README.md | 63 + Bing/Src/CMakeLists.txt | 30 + Bing/Src/CMakeLists.txt.user | 176 ++ Bing/Src/CmFile.cpp | 173 ++ Bing/Src/CmFile.h | 75 + Bing/Src/CmShow.cpp | 82 + Bing/Src/CmShow.h | 9 + Bing/Src/CmTimer.h | 89 + Bing/Src/DataSetVOC.cpp | 224 ++ Bing/Src/DataSetVOC.h | 71 + Bing/Src/FilterTIG.cpp | 78 + Bing/Src/FilterTIG.h | 45 + Bing/Src/ImgContrastBB.h | 62 + Bing/Src/LibLinear/LibLinear.vcxproj | 94 + Bing/Src/LibLinear/README.1.93.txt | 531 +++++ Bing/Src/LibLinear/blas/Makefile | 22 + Bing/Src/LibLinear/blas/blas.h | 25 + Bing/Src/LibLinear/blas/blasp.h | 430 ++++ Bing/Src/LibLinear/blas/daxpy.c | 49 + Bing/Src/LibLinear/blas/ddot.c | 50 + Bing/Src/LibLinear/blas/dnrm2.c | 62 + Bing/Src/LibLinear/blas/dscal.c | 44 + Bing/Src/LibLinear/linear.cpp | 2811 ++++++++++++++++++++++++++ Bing/Src/LibLinear/linear.h | 74 + Bing/Src/LibLinear/train.c | 401 ++++ Bing/Src/LibLinear/tron.cpp | 235 +++ Bing/Src/LibLinear/tron.h | 36 + Bing/Src/Objectness.cpp | 1118 ++++++++++ Bing/Src/Objectness.h | 116 ++ Bing/Src/ReadMe.txt | 49 + Bing/Src/ValStructVec.h | 72 + Bing/Src/kyheader.cpp | 5 + Bing/Src/kyheader.h | 110 + Bing/Src/main.cpp | 55 + Bing/Src/xml2yaml.m | 22 + Bing/Src/yml.m | 17 + 37 files changed, 7632 insertions(+) create mode 100644 Bing/LICENSE create mode 100644 Bing/README.md create mode 100644 Bing/Src/CMakeLists.txt create mode 100644 Bing/Src/CMakeLists.txt.user create mode 100644 Bing/Src/CmFile.cpp create mode 100644 Bing/Src/CmFile.h create mode 100644 Bing/Src/CmShow.cpp create mode 100644 Bing/Src/CmShow.h create mode 100644 Bing/Src/CmTimer.h create mode 100644 Bing/Src/DataSetVOC.cpp create mode 100644 Bing/Src/DataSetVOC.h create mode 100644 Bing/Src/FilterTIG.cpp create mode 100644 Bing/Src/FilterTIG.h create mode 100644 Bing/Src/ImgContrastBB.h create mode 100644 Bing/Src/LibLinear/LibLinear.vcxproj create mode 100644 Bing/Src/LibLinear/README.1.93.txt create mode 100644 Bing/Src/LibLinear/blas/Makefile create mode 100644 Bing/Src/LibLinear/blas/blas.h create mode 100644 Bing/Src/LibLinear/blas/blasp.h create mode 100644 Bing/Src/LibLinear/blas/daxpy.c create mode 100644 Bing/Src/LibLinear/blas/ddot.c create mode 100644 Bing/Src/LibLinear/blas/dnrm2.c create mode 100644 Bing/Src/LibLinear/blas/dscal.c create mode 100644 Bing/Src/LibLinear/linear.cpp create mode 100644 Bing/Src/LibLinear/linear.h create mode 100644 Bing/Src/LibLinear/train.c create mode 100644 Bing/Src/LibLinear/tron.cpp create mode 100644 Bing/Src/LibLinear/tron.h create mode 100644 Bing/Src/Objectness.cpp create mode 100644 Bing/Src/Objectness.h create mode 100644 Bing/Src/ReadMe.txt create mode 100644 Bing/Src/ValStructVec.h create mode 100644 Bing/Src/kyheader.cpp create mode 100644 Bing/Src/kyheader.h create mode 100644 Bing/Src/main.cpp create mode 100644 Bing/Src/xml2yaml.m create mode 100644 Bing/Src/yml.m diff --git a/Bing/LICENSE b/Bing/LICENSE new file mode 100644 index 000000000..7f8edefa4 --- /dev/null +++ b/Bing/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2014, Ming-Ming Cheng & Shuai Zheng +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the {organization} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Bing/README.md b/Bing/README.md new file mode 100644 index 000000000..7118cf0e6 --- /dev/null +++ b/Bing/README.md @@ -0,0 +1,63 @@ +Objectness Proposal Generator with BING +========== +BING Objectness proposal estimator Linux Ubuntu 14.04/Mac OSX Yosemite/iOS 8.1 version implementation, +runs at 1000 FPS at a Dell 7600 workstation with Linux Ubuntu 14.04. +## INSTALL +To make this program running fast, you need to enable release mode: +> cmake -DCMAKE_BUILD_TYPE=Release ../ + +## DEMO +If you run this in Ubuntu 14.04 or other similar Linux system, feel free to +change the path in main.cpp +> DataSetVOC voc2007("YOUR_PATH_TO_THE_VOC2007DATA"); + +Notice that WinRecall.m is generated by this code, you do not need them. If you +want to make this code working with other datasets, one simple solution is to +make the folders similar to the VOC 2007 one. + +## Introduction +This is the 1000 FPS BING objectness linux version library for efficient +objectness proposal estimator,We would appreciate if you could cite and refer to +the papers below. +``` +@inproceedings{BingObj2014, + title={{BING}: Binarized Normed Gradients for Objectness Estimation at 300fps}, + author={Ming-Ming Cheng and Ziming Zhang and Wen-Yan Lin and Philip H. S. Torr}, + booktitle={IEEE CVPR}, + year={2014}, +} +``` +``` +@inproceedings{depthobjectproposals_GCPR2015, +author = {Shuai Zheng and Victor Adrian Prisacariu and Melinos Averkiou and Ming-Ming Cheng and Niloy J. Mitra and Jamie Shotton and Philip H. S. Torr and Carsten Rother}, +title = {Object Proposal Estimation in Depth Images using Compact 3D Shape Manifolds}, +booktitle = {German Conference on Pattern Recognition (GCPR)}, +year = {2015} +} +``` +The original author Ming-Ming Cheng has already released the source code for +windows 64-bit platform. In this library, we intend to release the code for the +linux/mac/iOS users. You can maintain the code with Qt Creator IDE. + +Please find the original windows code / FAQ / Paper from this link: +http://mmcheng.net/bing/ + +## FAQ +In order to make the code running as the original version in windows, you need +to download the images/annotations PASCAL VOC 2007 data from the website. +(http://pascallin.ecs.soton.ac.uk/challenges/VOC/voc2007/#testdata) + +We have tested the code, it produces the same accuracy results as the original windows +version, while it runs at 1111 FPS(frame per second) at Ubuntu 12.04 with a Dell T7600 +workstation computer, which has two Intel Xeon E5-2687W (3.1GHz, 1600MHz) and 64 GB +1600MHz DDR3 Memory. + +## Author Info +Author: Ming-Ming Cheng removethisifyouarehuman-cmm.thu@gmail.com +Linux Author: Shuai Zheng (Kyle) removethisifyouarehuman-szhengcvpr@gmail.com +Please find more information from http://kylezheng.org/objectproposal/ +Date: 19, February + +## License +BSD license. + diff --git a/Bing/Src/CMakeLists.txt b/Bing/Src/CMakeLists.txt new file mode 100644 index 000000000..9c1af52de --- /dev/null +++ b/Bing/Src/CMakeLists.txt @@ -0,0 +1,30 @@ +project(BING_linux) +cmake_minimum_required(VERSION 2.8) + +find_package(OpenMP REQUIRED) + +# compile LibLinear +include_directories("LibLinear") +file(GLOB SOURCES "LibLinear/*.cpp" "LibLinear/blas/*.c") +add_library(LibLinear STATIC ${SOURCES}) + +#OPENCV +#include_directories(/usr/local/include) +#link_directories(/usr/local/lib) +##if this does not work, then try to uncomment the things below. +find_package( OpenCV REQUIRED ) +if(OpenCV_FOUND) + include_directories( ${OpenCV_INCLUDE_DIRS} ) +endif( OpenCV_FOUND ) +list( APPEND CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -fopenmp -ftree-vectorize") +#list( APPEND CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -fopenmp -ftest-coverage -fprofile-arcs") + +# compile BING +file(GLOB SOURCES "*.cpp") +add_library(BING STATIC ${SOURCES}) + +add_executable(${PROJECT_NAME} main.cpp) + +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wall") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall") +target_link_libraries(${PROJECT_NAME} opencv_core opencv_imgproc opencv_highgui opencv_imgcodecs ${EXTERNAL_LIBS} BING LibLinear) diff --git a/Bing/Src/CMakeLists.txt.user b/Bing/Src/CMakeLists.txt.user new file mode 100644 index 000000000..685b8403b --- /dev/null +++ b/Bing/Src/CMakeLists.txt.user @@ -0,0 +1,176 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + System + false + 4 + false + true + 1 + true + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + + CMakeProjectManager.DefaultCMakeTarget + 0 + 0 + 0 + + /home/bittnt/BING/BING_beta3/build + ProjectExplorer.ToolChain.Gcc:{966d53c9-fe6c-4bac-8571-0e5a33bebf05} + ProjectExplorer.ToolChain.Gcc:{966d53c9-fe6c-4bac-8571-0e5a33bebf05} + + + + + false + true + Make + + CMakeProjectManager.MakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + clean + + true + true + Make + + CMakeProjectManager.MakeStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + all + + CMakeProjectManager.CMakeBuildConfiguration + + 1 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + No deployment + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + + false + false + false + false + true + 0.01 + 10 + true + 25 + + true + /usr/bin/valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + BING_linux + + false + + + BING_linux + + CMakeProjectManager.CMakeRunConfiguration. + 3768 + true + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {1c480e06-4a57-40ca-8868-29ff19bb1281} + + + ProjectExplorer.Project.Updater.FileVersion + 11 + + diff --git a/Bing/Src/CmFile.cpp b/Bing/Src/CmFile.cpp new file mode 100644 index 000000000..804c2ec3b --- /dev/null +++ b/Bing/Src/CmFile.cpp @@ -0,0 +1,173 @@ +#include "kyheader.h" + + +#ifdef _WIN32 +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif + + +// Get image names from a wildcard. Eg: GetNames("D:\\*.jpg", imgNames); +int CmFile::GetNames(CStr &_nameW, vecS &_names) +{ + string _dir = GetFolder(_nameW); + _names.clear(); + + DIR *dir; + struct dirent *ent; + if((dir = opendir(_dir.c_str()))!=NULL){ + //print all the files and directories within directory + while((ent = readdir(dir))!=NULL){ + if(ent->d_name[0] == '.') + continue; + if(ent->d_type ==4) + continue; + _names.push_back(ent->d_name); + } + closedir(dir); + } else { + perror(""); + return EXIT_FAILURE; + } + return (int)_names.size(); +} +int CmFile::GetNames(CStr &_nameW, vecS &_names, string &_dir) +{ + _dir = GetFolder(_nameW); + _names.clear(); + + DIR *dir; + struct dirent *ent; + if((dir = opendir(_dir.c_str()))!=NULL){ + //print all the files and directories within directory + while((ent = readdir(dir))!=NULL){ + if(ent->d_name[0] == '.') + continue; + if(ent->d_type ==4) + continue; + _names.push_back(ent->d_name); + } + closedir(dir); + } else { + perror(""); + return EXIT_FAILURE; + } + return (int)_names.size(); +} +int CmFile::GetSubFolders(CStr &folder, vecS &subFolders) +{ + subFolders.clear(); + string nameWC = GetFolder(folder);//folder + "/*"; + + DIR *dir; + struct dirent *ent; + if((dir = opendir(nameWC.c_str()))!=NULL){ + while((ent = readdir(dir))!=NULL){ + if(ent->d_name[0] == '.') + continue; + if(ent->d_type == 4){ + subFolders.push_back(ent->d_name); + } + } + closedir(dir); + } else { + perror(""); + return EXIT_FAILURE; + } + return (int)subFolders.size(); +} +int CmFile::GetNames(CStr& rootFolder, CStr &fileW, vecS &names) +{ + GetNames(rootFolder + fileW, names); + vecS subFolders, tmpNames; + int subNum = CmFile::GetSubFolders(rootFolder, subFolders);// + for (int i = 0; i < subNum; i++){ + subFolders[i] += "/"; + int subNum = GetNames(rootFolder + subFolders[i], fileW, tmpNames); + for (int j = 0; j < subNum; j++) + names.push_back(subFolders[i] + tmpNames[j]); + } + return (int)names.size(); +} +int CmFile::GetNamesNE(CStr& nameWC, vecS &names) +{ + string dir = string(); + string ext = string(); + int fNum = GetNames(nameWC, names, dir); + ext = GetExtention(nameWC); + for (int i = 0; i < fNum; i++) + names[i] = GetNameNE(names[i]); + return fNum; +} +int CmFile::GetNamesNE(CStr& nameWC, vecS &names, string &dir, string &ext) +{ + int fNum = GetNames(nameWC, names, dir); + ext = GetExtention(nameWC); + for (int i = 0; i < fNum; i++) + names[i] = GetNameNE(names[i]); + return fNum; +} +int CmFile::GetNamesNE(CStr& rootFolder, CStr &fileW, vecS &names) +{ + int fNum = GetNames(rootFolder, fileW, names); + int extS = GetExtention(fileW).size(); + for (int i = 0; i < fNum; i++) + names[i].resize(names[i].size() - extS); + return fNum; +} +bool CmFile::MkDir(CStr &_path) +{ + if(_path.size() == 0) + return false; + static char buffer[1024]; + strcpy(buffer, _S(_path)); +#ifdef _WIN32 + for (int i = 0; buffer[i] != 0; i ++) { + if (buffer[i] == '\\' || buffer[i] == '/') { + buffer[i] = '\0'; + CreateDirectoryA(buffer, 0); + buffer[i] = '/'; + } + } + return CreateDirectoryA(_S(_path), 0); +#else + for (int i = 0; buffer[i] != 0; i ++) { + if (buffer[i] == '\\' || buffer[i] == '/') { + buffer[i] = '\0'; + mkdir(buffer, 0755); + buffer[i] = '/'; + } + } + return mkdir(_S(_path), 0755); +#endif +} +vecS CmFile::loadStrList(CStr &fName) +{ + ifstream fIn(fName); + string line; + vecS strs; + while(getline(fIn, line) && line.size()){ + unsigned sz = line.size(); + line.resize(sz - 1); //Please use script to convert the VOC format data into the OpenCV format data + //line.resize(sz); + strs.push_back(line); + } + return strs; +} +bool CmFile::writeStrList(CStr &fName, const vecS &strs) +{ + FILE *f = fopen(_S(fName), "w"); + if (f == NULL) + return false; + for (size_t i = 0; i < strs.size(); i++) + fprintf(f, "%s\n", _S(strs[i])); + fclose(f); + return true; +} diff --git a/Bing/Src/CmFile.h b/Bing/Src/CmFile.h new file mode 100644 index 000000000..ca6330fd2 --- /dev/null +++ b/Bing/Src/CmFile.h @@ -0,0 +1,75 @@ +#pragma once +#ifdef _WIN32 +#include +#else +#include +#include +#include +#include +#endif +struct CmFile +{ + static inline string GetFolder(CStr& path); + static inline string GetName(CStr& path); + static inline string GetNameNE(CStr& path); + static inline string GetPathNE(CStr& path); + + // Get file names from a wildcard. Eg: GetNames("D:\\*.jpg", imgNames); + static int GetNames(CStr &nameW, vecS &names, string &_dir); + static int GetNames(CStr &nameW, vecS &names); + static int GetNames(CStr& rootFolder, CStr &fileW, vecS &names); + static int GetNamesNE(CStr& nameWC, vecS &names, string &dir, string &ext); + static int GetNamesNE(CStr& nameWC, vecS &names); + static int GetNamesNE(CStr& rootFolder, CStr &fileW, vecS &names); + static inline string GetExtention(CStr name); + + static int GetSubFolders(CStr& folder, vecS& subFolders); + + static inline string GetWkDir(); + + static bool MkDir(CStr& path); + static vecS loadStrList(CStr &fName); + static bool writeStrList(CStr &fName, const vecS &strs); +}; + +/************************************************************************/ +/* Implementation of inline functions */ +/************************************************************************/ +string CmFile::GetFolder(CStr& path) +{ + return path.substr(0, path.find_last_of("\\/")+1); +} + +string CmFile::GetName(CStr& path) +{ + int start = path.find_last_of("\\/")+1; + int end = path.find_last_not_of(' ')+1; + return path.substr(start, end - start); +} + +string CmFile::GetNameNE(CStr& path) +{ + int start = path.find_last_of("\\/")+1; + int end = path.find_last_of('.'); + if (end >= 0) + return path.substr(start, end - start); + else + return path.substr(start, path.find_last_not_of(' ')+1 - start); +} + +string CmFile::GetPathNE(CStr& path) +{ + int end = path.find_last_of('.'); + if (end >= 0) + return path.substr(0, end); + else + return path.substr(0, path.find_last_not_of(' ') + 1); +} + +string CmFile::GetExtention(CStr name) +{ + return name.substr(name.find_last_of('.')); +} +/************************************************************************/ +/* Implementations */ +/************************************************************************/ diff --git a/Bing/Src/CmShow.cpp b/Bing/Src/CmShow.cpp new file mode 100644 index 000000000..7c7c593b0 --- /dev/null +++ b/Bing/Src/CmShow.cpp @@ -0,0 +1,82 @@ +#include "kyheader.h" +#include "CmShow.h" + + + +typedef pair CostiIdx; +Mat CmShow::HistBins(CMat& color3f, CMat& val, CStr& title, bool descendShow, CMat &with) +{ + // Prepare data + int H = 300, spaceH = 6, barH = 10, n = color3f.cols; + CV_Assert(color3f.size() == val.size() && color3f.rows == 1); + Mat binVal1i, binColor3b, width1i; + if (with.size() == val.size()) + with.convertTo(width1i, CV_32S, 400/sum(with).val[0]); // Default shown width + else + width1i = Mat(1, n, CV_32S, Scalar(10)); // Default bin width = 10 + int W = cvRound(sum(width1i).val[0]); + color3f.convertTo(binColor3b, CV_8UC3, 255); + double maxVal, minVal; + minMaxLoc(val, &minVal, &maxVal); + printf("%g\n", H/max(maxVal, -minVal)); + val.convertTo(binVal1i, CV_32S, 20000); + Size szShow(W, H + spaceH + barH); + szShow.height += minVal < 0 && !descendShow ? H + spaceH : 0; + Mat showImg3b(szShow, CV_8UC3, Scalar(255, 255, 255)); + int* binH = (int*)(binVal1i.data); + Vec3b* binColor = (Vec3b*)(binColor3b.data); + int* binW = (int*)(width1i.data); + vector costIdx(n); + if (descendShow){ + for (int i = 0; i < n; i++) + costIdx[i] = make_pair(binH[i], i); + sort(costIdx.begin(), costIdx.end(), std::greater()); + } + + // Show image + for (int i = 0, x = 0; i < n; i++){ + int idx = descendShow ? costIdx[i].second : i; + int h = descendShow ? abs(binH[idx]) : binH[idx]; + Scalar color(binColor[idx]); + Rect reg(x, H + spaceH, binW[idx], barH); + showImg3b(reg) = color; // Draw bar + rectangle(showImg3b, reg, Scalar(0)); + + reg.height = abs(h); + reg.y = h >= 0 ? H - h : H + 2 * spaceH + barH; + showImg3b(reg) = color; + rectangle(showImg3b, reg, Scalar(0)); + + x += binW[idx]; + } + imshow(title, showImg3b); + return showImg3b; +} + +void CmShow::showTinyMat(CStr &title, CMat &m) +{ + int scale = 50, sz = m.rows * m.cols; + while (sz > 200){ + scale /= 2; + sz /= 4; + } + + Mat img; + resize(m, img, Size(), scale, scale, CV_INTER_NN); + if (img.channels() == 3) + cvtColor(img, img, CV_RGB2BGR); + SaveShow(img, title); +} + +void CmShow::SaveShow(CMat& img, CStr& title) +{ + if (title.size() == 0) + return; + + int mDepth = CV_MAT_DEPTH(img.type()); + double scale = (mDepth == CV_32F || mDepth == CV_64F ? 255 : 1); + if (title.size() > 4 && title[title.size() - 4] == '.') + imwrite(title, img*scale); + else if (title.size()) + imshow(title, img); +} diff --git a/Bing/Src/CmShow.h b/Bing/Src/CmShow.h new file mode 100644 index 000000000..11d99a046 --- /dev/null +++ b/Bing/Src/CmShow.h @@ -0,0 +1,9 @@ +#pragma once +class CmShow +{ +public: + static Mat HistBins(CMat& color3f, CMat& val, CStr& title, bool descendShow = false, CMat &with = Mat()); + static void showTinyMat(CStr &title, CMat &m); + static inline void SaveShow(CMat& img, CStr& title); +}; + diff --git a/Bing/Src/CmTimer.h b/Bing/Src/CmTimer.h new file mode 100644 index 000000000..7883567f9 --- /dev/null +++ b/Bing/Src/CmTimer.h @@ -0,0 +1,89 @@ +#pragma once +#include +class CmTimer +{ +public: + CmTimer(CStr t):title(t) { is_started = false; gettimeofday(&start_clock,NULL); gettimeofday(&end_clock,NULL); n_starts = 0; } + + ~CmTimer(){ if (is_started) printf("CmTimer '%s' is started and is being destroyed.\n", title.c_str()); } + + inline void Start(); + inline void Stop(); + inline void Reset(); + + inline bool Report(); + inline bool StopAndReport() { Stop(); return Report(); } + inline float TimeInSeconds(); + +private: + CStr title; + + bool is_started; + struct timeval start_clock, end_clock; + //clock_t start_clock; + //clock_t cumulative_clock; + unsigned int n_starts; +}; + +/************************************************************************/ +/* Implementations */ +/************************************************************************/ + +void CmTimer::Start() +{ + if (is_started){ + printf("CmTimer '%s' is already started. Nothing done.\n", title.c_str()); + return; + } + + is_started = true; + n_starts++; + //start_clock = clock(); + gettimeofday(&start_clock,NULL); +} + +void CmTimer::Stop() +{ + if (!is_started){ + printf("CmTimer '%s' is started. Nothing done\n", title.c_str()); + return; + } + gettimeofday(&end_clock,NULL); + //cumulative_clock += clock() - start_clock; + is_started = false; +} + +void CmTimer::Reset() +{ + if (is_started) { + printf("CmTimer '%s'is started during reset request.\n Only reset cumulative time.\n"); + return; + } + gettimeofday(&start_clock,NULL); + gettimeofday(&end_clock,NULL); + //cumulative_clock = 0; +} + +bool CmTimer::Report() +{ + if (is_started){ + printf("CmTimer '%s' is started.\n Cannot provide a time report.", title.c_str()); + return false; + } + + float timeUsed = TimeInSeconds(); + printf("[%s] CumuTime: %gs, #run: %d, AvgTime: %gs\n", title.c_str(), timeUsed, n_starts, timeUsed/n_starts); + return true; +} + +float CmTimer::TimeInSeconds() +{ + if (is_started){ + printf("CmTimer '%s' is started. Nothing done\n", title.c_str()); + return 0; + } + return double((end_clock.tv_sec - start_clock.tv_sec) * 1000000u + + end_clock.tv_usec - start_clock.tv_usec) / 1.e6; + //return float(cumulative_clock) / CLOCKS_PER_SEC; +} + diff --git a/Bing/Src/DataSetVOC.cpp b/Bing/Src/DataSetVOC.cpp new file mode 100644 index 000000000..bb99a7de0 --- /dev/null +++ b/Bing/Src/DataSetVOC.cpp @@ -0,0 +1,224 @@ +#include "kyheader.h" +#include "DataSetVOC.h" + + +DataSetVOC::DataSetVOC(CStr &_wkDir) +{ + wkDir = _wkDir; + resDir = wkDir + "Results/"; + localDir = wkDir + "Local/"; + imgPathW = wkDir + "JPEGImages/%s.jpg"; + annoPathW = wkDir + "Annotations/%s.yml"; + CmFile::MkDir(resDir); + CmFile::MkDir(localDir); + + trainSet = CmFile::loadStrList(wkDir + "ImageSets/Main/train.txt"); + testSet = CmFile::loadStrList(wkDir + "ImageSets/Main/test.txt"); + classNames = CmFile::loadStrList(wkDir + "ImageSets/Main/class.txt"); + + // testSet.insert(testSet.end(), trainSet.begin(), trainSet.end()); + // testSet.resize(min(1000, (int)testSet.size())); + + trainNum = trainSet.size(); + testNum = testSet.size(); +} + + +Vec4i getMaskRange(CMat &mask1u, int ext = 0) +{ + int maxX = INT_MIN, maxY = INT_MIN, minX = INT_MAX, minY = INT_MAX, rows = mask1u.rows, cols = mask1u.cols; + for (int r = 0; r < rows; r++) { + const byte* data = mask1u.ptr(r); + for (int c = 0; c < cols; c++) + if (data[c] > 10) { + maxX = max(maxX, c); + minX = min(minX, c); + maxY = max(maxY, r); + minY = min(minY, r); + } + } + + maxX = maxX + ext + 1 < cols ? maxX + ext + 1 : cols; + maxY = maxY + ext + 1 < rows ? maxY + ext + 1 : rows; + minX = minX - ext > 0 ? minX - ext : 0; + minY = minY - ext > 0 ? minY - ext : 0; + + return Vec4i(minX + 1, minY + 1, maxX, maxY); // Rect(minX, minY, maxX - minX, maxY - minY); +} + + +DataSetVOC::~DataSetVOC(void) +{ +} + +void DataSetVOC::loadAnnotations() +{ + gtTrainBoxes.resize(trainNum); + gtTrainClsIdx.resize(trainNum); + for (int i = 0; i < trainNum; i++) + if (!loadBBoxes(trainSet[i], gtTrainBoxes[i], gtTrainClsIdx[i])) + return; + + gtTestBoxes.resize(testNum); + gtTestClsIdx.resize(testNum); + for (int i = 0; i < testNum; i++) + if(!loadBBoxes(testSet[i], gtTestBoxes[i], gtTestClsIdx[i])) + return; + printf("Load annotations finished\n"); +} + +void DataSetVOC::loadDataGenericOverCls() +{ + vecS allSet = trainSet; + allSet.insert(allSet.end(), testSet.begin(), testSet.end()); + int imgN = (int)allSet.size(); + trainSet.clear(), testSet.clear(); + trainSet.reserve(imgN), testSet.reserve(imgN); + vector> gtBoxes(imgN); + vector gtClsIdx(imgN); + for (int i = 0; i < imgN; i++){ + if (!loadBBoxes(allSet[i], gtBoxes[i], gtClsIdx[i])) + return; + vector trainBoxes, testBoxes; + vecI trainIdx, testIdx; + for (size_t j = 0; j < gtBoxes[i].size(); j++) + if (gtClsIdx[i][j] < 6){ + trainBoxes.push_back(gtBoxes[i][j]); + trainIdx.push_back(gtClsIdx[i][j]); + } + else{ + testBoxes.push_back(gtBoxes[i][j]); + testIdx.push_back(gtClsIdx[i][j]); + } + if (trainBoxes.size()){ + trainSet.push_back(allSet[i]); + gtTrainBoxes.push_back(trainBoxes); + gtTrainClsIdx.push_back(trainIdx); + } + else{ + testSet.push_back(allSet[i]); + gtTestBoxes.push_back(testBoxes); + gtTestClsIdx.push_back(testIdx); + } + } + trainNum = trainSet.size(); + testNum = testSet.size(); + printf("Load annotations (generic over classes) finished\n"); +} + +void DataSetVOC::loadBox(const FileNode &fn, vector &boxes, vecI &clsIdx){ + string isDifficult; + fn["difficult"]>>isDifficult; + if (isDifficult == "1") + return; + + string strXmin, strYmin, strXmax, strYmax; + fn["bndbox"]["xmin"] >> strXmin; + fn["bndbox"]["ymin"] >> strYmin; + fn["bndbox"]["xmax"] >> strXmax; + fn["bndbox"]["ymax"] >> strYmax; + boxes.push_back(Vec4i(atoi(_S(strXmin)), atoi(_S(strYmin)), atoi(_S(strXmax)), atoi(_S(strYmax)))); + + string clsName; + fn["name"]>>clsName; + clsIdx.push_back(findFromList(clsName, classNames)); + CV_Assert_(clsIdx[clsIdx.size() - 1] >= 0, ("Invalidate class name\n")); +} + +bool DataSetVOC::loadBBoxes(CStr &nameNE, vector &boxes, vecI &clsIdx) +{ + string fName = format(_S(annoPathW), _S(nameNE)); + FileStorage fs(fName, FileStorage::READ); + FileNode fn = fs["annotation"]["object"]; + boxes.clear(); + clsIdx.clear(); + if (fn.isSeq()){ + for (FileNodeIterator it = fn.begin(), it_end = fn.end(); it != it_end; it++){ + loadBox(*it, boxes, clsIdx); + } + } + else + loadBox(fn, boxes, clsIdx); + return true; +} + +// Needs to call yml.m in this solution before running this function. +bool DataSetVOC::cvt2OpenCVYml(CStr &annoDir) +{ + vecS namesNE; + int imgNum = CmFile::GetNamesNE(annoDir + "*.yaml", namesNE); + printf("Converting annotations to OpenCV yml format:\n"); + for (int i = 0; i < imgNum; i++){ + printf("%d/%d %s.yaml\r", i, imgNum, _S(namesNE[i])); + string fPath = annoDir + namesNE[i]; + cvt2OpenCVYml(fPath + ".yaml", fPath + ".yml"); + } + return true; +} + +// Needs to call yml.m in this solution before running this function. +bool DataSetVOC::cvt2OpenCVYml(CStr &yamlName, CStr &ymlName) +{ + ifstream f(yamlName); + FILE *fO = fopen(_S(ymlName), "w"); + if (!f.is_open() && fO == NULL) + return false; + fprintf(fO, "%s\n", "%YAML:1.0\n"); + string line; + + int addIdent = 0; + while(getline(f, line)){ + if (line.substr(0, 12) == " filename: ") + line = " filename: \"" + line.substr(12) + "\""; + int tmp = line.find_first_of('-'); + if (tmp != string::npos){ + bool allSpace = true; + for (int k = 0; k < tmp; k++) + if (line[k] != ' ') + allSpace = false; + if (allSpace) + addIdent = tmp; + } + for (int k = 0; k < addIdent; k++) + fprintf(fO, " "); + fprintf(fO, "%s\n", _S(line)); + } + fclose(fO); + + FileStorage fs(ymlName, FileStorage::READ); + string tmp; + fs["annotation"]["folder"]>>tmp; + return true; +} + + +// Get training and testing for demonstrating the generative of the objectness over classes +void DataSetVOC::getTrainTest() +{ + const int TRAIN_CLS_NUM = 6; + string trainCls[TRAIN_CLS_NUM] = {"bird", "car", "cat", "cow", "dog", "sheep"}; + +} + +void DataSetVOC::getXmlStrVOC(CStr &fName, string &buf) +{ + ifstream fin(fName); + string strLine; + buf.clear(); + buf.reserve(100000); + buf += "\n\n"; + while (getline(fin, strLine) && strLine.size()) { + int startP = strLine.find_first_of(">") + 1; + int endP = strLine.find_last_of("<"); + if (endP > startP){ + string val = keepXmlChar(strLine.substr(startP, endP - startP)); + if (val.size() < endP - startP) + strLine = strLine.substr(0, startP) + val + strLine.substr(endP); + } + buf += strLine + "\n"; + } + buf += "\n"; + //FileStorage fs(buf, FileStorage::READ + FileStorage::MEMORY); + ofstream fout("D:/t.xml"); + fout<< buf; +} diff --git a/Bing/Src/DataSetVOC.h b/Bing/Src/DataSetVOC.h new file mode 100644 index 000000000..4c1ec38af --- /dev/null +++ b/Bing/Src/DataSetVOC.h @@ -0,0 +1,71 @@ +#pragma once + +struct DataSetVOC +{ + DataSetVOC(CStr &wkDir); + ~DataSetVOC(void); + + // Organization structure data for the dataset + string wkDir; // Root working directory, all other directories are relative to this one + string resDir, localDir; // Directory for saving results and local data + string imgPathW, annoPathW; // Image and annotation path + + // Information for training and testing + int trainNum, testNum; + vecS trainSet, testSet; // File names (NE) for training and testing images + vecS classNames; // Object class names + vector> gtTrainBoxes, gtTestBoxes; // Ground truth bounding boxes for training and testing images + vector gtTrainClsIdx, gtTestClsIdx; // Object class indexes + + + // Load annotations + void loadAnnotations(); + + static bool cvt2OpenCVYml(CStr &annoDir); // Needs to call yml.m in this solution before running this function. + + static inline double interUnio(const Vec4i &box1, const Vec4i &box2); + + // Get training and testing for demonstrating the generative of the objectness over classes + void getTrainTest(); + +public: // Used for testing the ability of generic over classes + void loadDataGenericOverCls(); + +private: + void loadBox(const FileNode &fn, vector &boxes, vecI &clsIdx); + bool loadBBoxes(CStr &nameNE, vector &boxes, vecI &clsIdx); + static void getXmlStrVOC(CStr &fName, string &buf); + static inline string keepXmlChar(CStr &str); + static bool cvt2OpenCVYml(CStr &yamlName, CStr &ymlName); // Needs to call yml.m in this solution before running this function. +}; + +string DataSetVOC::keepXmlChar(CStr &_str) +{ + string str = _str; + int sz = (int)str.size(), count = 0; + for (int i = 0; i < sz; i++){ + char c = str[i]; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == ' ' || c == '.') + str[count++] = str[i]; + } + str.resize(count); + return str; +} + +double DataSetVOC::interUnio(const Vec4i &bb, const Vec4i &bbgt) +{ + int bi[4]; + bi[0] = max(bb[0], bbgt[0]); + bi[1] = max(bb[1], bbgt[1]); + bi[2] = min(bb[2], bbgt[2]); + bi[3] = min(bb[3], bbgt[3]); + + double iw = bi[2] - bi[0] + 1; + double ih = bi[3] - bi[1] + 1; + double ov = 0; + if (iw>0 && ih>0){ + double ua = (bb[2]-bb[0]+1)*(bb[3]-bb[1]+1)+(bbgt[2]-bbgt[0]+1)*(bbgt[3]-bbgt[1]+1)-iw*ih; + ov = iw*ih/ua; + } + return ov; +} diff --git a/Bing/Src/FilterTIG.cpp b/Bing/Src/FilterTIG.cpp new file mode 100644 index 000000000..8643011e7 --- /dev/null +++ b/Bing/Src/FilterTIG.cpp @@ -0,0 +1,78 @@ +#include "kyheader.h" +#include "FilterTIG.h" +#include "CmShow.h" + + +void FilterTIG::update(CMat &w1f){ + CV_Assert(w1f.cols * w1f.rows == D && w1f.type() == CV_32F && w1f.isContinuous()); + float b[D], residuals[D]; + memcpy(residuals, w1f.data, sizeof(float)*D); + for (int i = 0; i < NUM_COMP; i++){ + float avg = 0; + for (int j = 0; j < D; j++){ + b[j] = residuals[j] >= 0.0f ? 1.0f : -1.0f; + avg += residuals[j] * b[j]; + } + avg /= D; + _coeffs1[i] = avg, _coeffs2[i] = avg*2, _coeffs4[i] = avg*4, _coeffs8[i] = avg*8; + for (int j = 0; j < D; j++) + residuals[j] -= avg*b[j]; + UINT64 tig = 0; + for (int j = 0; j < D; j++) + tig = (tig << 1) | (b[j] > 0 ? 1 : 0); + _bTIGs[i] = tig; + } +} + +void FilterTIG::reconstruct(Mat &w1f){ + w1f = Mat::zeros(8, 8, CV_32F); + float *weight = (float*)w1f.data; + for (int i = 0; i < NUM_COMP; i++){ + UINT64 tig = _bTIGs[i]; + for (int j = 0; j < D; j++) + weight[j] += _coeffs1[i] * (((tig >> (63-j)) & 1) ? 1 : -1); + } +} + +// For a W by H gradient magnitude map, find a W-7 by H-7 CV_32F matching score map +// Please refer to my paper for definition of the variables used in this function +Mat FilterTIG::matchTemplate(const Mat &mag1u){ + const int H = mag1u.rows, W = mag1u.cols; + const Size sz(W+1, H+1); // Expand original size to avoid dealing with boundary conditions + Mat_ Tig1 = Mat_::zeros(sz), Tig2 = Mat_::zeros(sz); + Mat_ Tig4 = Mat_::zeros(sz), Tig8 = Mat_::zeros(sz); + Mat_ Row1 = Mat_::zeros(sz), Row2 = Mat_::zeros(sz); + Mat_ Row4 = Mat_::zeros(sz), Row8 = Mat_::zeros(sz); + Mat_ scores(sz); + for(int y = 1; y <= H; y++){ + const byte* G = mag1u.ptr(y-1); + INT64* T1 = Tig1.ptr(y); // Binary TIG of current row + INT64* T2 = Tig2.ptr(y); + INT64* T4 = Tig4.ptr(y); + INT64* T8 = Tig8.ptr(y); + INT64* Tu1 = Tig1.ptr(y-1); // Binary TIG of upper row + INT64* Tu2 = Tig2.ptr(y-1); + INT64* Tu4 = Tig4.ptr(y-1); + INT64* Tu8 = Tig8.ptr(y-1); + byte* R1 = Row1.ptr(y); + byte* R2 = Row2.ptr(y); + byte* R4 = Row4.ptr(y); + byte* R8 = Row8.ptr(y); + float *s = scores.ptr(y); + for (int x = 1; x <= W; x++) { + byte g = G[x-1]; + R1[x] = (R1[x-1] << 1) | ((g >> 4) & 1); + R2[x] = (R2[x-1] << 1) | ((g >> 5) & 1); + R4[x] = (R4[x-1] << 1) | ((g >> 6) & 1); + R8[x] = (R8[x-1] << 1) | ((g >> 7) & 1); + T1[x] = (Tu1[x] << 8) | R1[x]; + T2[x] = (Tu2[x] << 8) | R2[x]; + T4[x] = (Tu4[x] << 8) | R4[x]; + T8[x] = (Tu8[x] << 8) | R8[x]; + s[x] = dot(T1[x], T2[x], T4[x], T8[x]); + } + } + Mat matchCost1f; + scores(Rect(8, 8, W-7, H-7)).copyTo(matchCost1f); + return matchCost1f; +} diff --git a/Bing/Src/FilterTIG.h b/Bing/Src/FilterTIG.h new file mode 100644 index 000000000..d8b3a2a7f --- /dev/null +++ b/Bing/Src/FilterTIG.h @@ -0,0 +1,45 @@ +#pragma once + +class FilterTIG +{ +public: + void update(CMat &w); + + // For a W by H gradient magnitude map, find a W-7 by H-7 CV_32F matching score map + Mat matchTemplate(const Mat &mag1u); + + inline float dot(const INT64 tig1, const INT64 tig2, const INT64 tig4, const INT64 tig8); + +public: + void reconstruct(Mat &w); // For illustration purpose + +private: + static const int NUM_COMP = 2; // Number of components + static const int D = 64; // Dimension of TIG + INT64 _bTIGs[NUM_COMP]; // Binary TIG features + float _coeffs1[NUM_COMP]; // Coefficients of binary TIG features + + // For efficiently deals with different bits in CV_8U gradient map + float _coeffs2[NUM_COMP], _coeffs4[NUM_COMP], _coeffs8[NUM_COMP]; +}; + + +inline float FilterTIG::dot(const INT64 tig1, const INT64 tig2, const INT64 tig4, const INT64 tig8) +{ + INT64 bcT1 = __builtin_popcountll(tig1); + INT64 bcT2 = __builtin_popcountll(tig2); + INT64 bcT4 = __builtin_popcountll(tig4); + INT64 bcT8 = __builtin_popcountll(tig8); + + INT64 bc01 = (__builtin_popcountll(_bTIGs[0] & tig1) << 1) - bcT1; + INT64 bc02 = ((__builtin_popcountll(_bTIGs[0] & tig2) << 1) - bcT2) << 1; + INT64 bc04 = ((__builtin_popcountll(_bTIGs[0] & tig4) << 1) - bcT4) << 2; + INT64 bc08 = ((__builtin_popcountll(_bTIGs[0] & tig8) << 1) - bcT8) << 3; + + INT64 bc11 = (__builtin_popcountll(_bTIGs[1] & tig1) << 1) - bcT1; + INT64 bc12 = ((__builtin_popcountll(_bTIGs[1] & tig2) << 1) - bcT2) << 1; + INT64 bc14 = ((__builtin_popcountll(_bTIGs[1] & tig4) << 1) - bcT4) << 2; + INT64 bc18 = ((__builtin_popcountll(_bTIGs[1] & tig8) << 1) - bcT8) << 3; + + return _coeffs1[0] * (bc01 + bc02 + bc04 + bc08) + _coeffs1[1] * (bc11 + bc12 + bc14 + bc18); +} diff --git a/Bing/Src/ImgContrastBB.h b/Bing/Src/ImgContrastBB.h new file mode 100644 index 000000000..71c5fb5e9 --- /dev/null +++ b/Bing/Src/ImgContrastBB.h @@ -0,0 +1,62 @@ +#pragma once + +struct ImgContrastBB +{ + ImgContrastBB(CStr &imgPath); + ImgContrastBB(CMat &img3u); + + inline float contrastVal(Vec4i ¢er); + inline int regSum(Vec4i &box, Vec3i &sumColor); // Return region size and sum color + +private: + Mat iImg; + int _w, _h; + inline void assertBBox(Vec4i ¢er, CStr &name); +}; + +ImgContrastBB::ImgContrastBB(CStr &imgPath) +{ + Mat img3u = imread(imgPath); + integral(img3u, iImg, CV_32SC3); + _w = img3u.cols; + _h = img3u.rows; +} + +ImgContrastBB::ImgContrastBB(CMat &img3u) +{ + integral(img3u, iImg, CV_32SC3); + _w = img3u.cols; + _h = img3u.rows; +} + +int ImgContrastBB::regSum(Vec4i &box, Vec3i &sumColor) +{ + int x1 = box[0] - 1, y1 = box[1] - 1, x2 = box[2] - 1, y2 = box[3] - 1; + sumColor = iImg.at(y2, x2) + iImg.at(y1, x1) - iImg.at(y1, x2) - iImg.at(y2, x1); + return (x2 - x1)*(y2 - y1); +} + + +float ImgContrastBB::contrastVal(Vec4i ¢er) +{ + int wd = (center[2] - center[0])/2, hd = (center[3] - center[1])/2; + Vec4i surround(max(center[0] - wd, 1), max(center[1] - hd, 1), min(center[2] + wd, _w), min(center[3] + hd, _h)); + Vec3i cColr, sColr; + + assertBBox(center, "Center"); + assertBBox(center, "Surround"); + int cSz = regSum(center, cColr); + int sSz = regSum(surround, sColr); + + sColr -= cColr; + sSz -= cSz; + sColr /= sSz; + cColr /= cSz; + return sqrtf((float)(sqr(sColr[0] - cColr[0]) + sqr(sColr[1] - cColr[1]) + sqr(sColr[2] - cColr[2])))/100.0f; +} + +void ImgContrastBB::assertBBox(Vec4i ¢er, CStr &name) +{ + if (center[0] < 1 || center[1] < 1 || center[2] > _w || center[3] > _h) + printf("%s: (%d, %d, %d, %d), (%d, %d)\n", _S(name), center[0], center[1], center[2], center[3], _w, _h); +} \ No newline at end of file diff --git a/Bing/Src/LibLinear/LibLinear.vcxproj b/Bing/Src/LibLinear/LibLinear.vcxproj new file mode 100644 index 000000000..62d1e650e --- /dev/null +++ b/Bing/Src/LibLinear/LibLinear.vcxproj @@ -0,0 +1,94 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {86266F16-8B7E-4666-A12F-96E351579ADA} + Win32Proj + LibLinear + + + + StaticLibrary + true + MultiByte + v110 + + + StaticLibrary + false + true + MultiByte + v110 + + + + + + + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Bing/Src/LibLinear/README.1.93.txt b/Bing/Src/LibLinear/README.1.93.txt new file mode 100644 index 000000000..3a659e080 --- /dev/null +++ b/Bing/Src/LibLinear/README.1.93.txt @@ -0,0 +1,531 @@ +LIBLINEAR is a simple package for solving large-scale regularized linear +classification and regression. It currently supports +- L2-regularized logistic regression/L2-loss support vector classification/L1-loss support vector classification +- L1-regularized L2-loss support vector classification/L1-regularized logistic regression +- L2-regularized L2-loss support vector regression/L1-loss support vector regression. +This document explains the usage of LIBLINEAR. + +To get started, please read the ``Quick Start'' section first. +For developers, please check the ``Library Usage'' section to learn +how to integrate LIBLINEAR in your software. + +Table of Contents +================= + +- When to use LIBLINEAR but not LIBSVM +- Quick Start +- Installation +- `train' Usage +- `predict' Usage +- Examples +- Library Usage +- Building Windows Binaries +- Additional Information +- MATLAB/OCTAVE interface +- PYTHON interface + +When to use LIBLINEAR but not LIBSVM +==================================== + +There are some large data for which with/without nonlinear mappings +gives similar performances. Without using kernels, one can +efficiently train a much larger set via linear classification/regression. +These data usually have a large number of features. Document classification +is an example. + +Warning: While generally liblinear is very fast, its default solver +may be slow under certain situations (e.g., data not scaled or C is +large). See Appendix B of our SVM guide about how to handle such +cases. +http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf + +Warning: If you are a beginner and your data sets are not large, you +should consider LIBSVM first. + +LIBSVM page: +http://www.csie.ntu.edu.tw/~cjlin/libsvm + + +Quick Start +=========== + +See the section ``Installation'' for installing LIBLINEAR. + +After installation, there are programs `train' and `predict' for +training and testing, respectively. + +About the data format, please check the README file of LIBSVM. Note +that feature index must start from 1 (but not 0). + +A sample classification data included in this package is `heart_scale'. + +Type `train heart_scale', and the program will read the training +data and output the model file `heart_scale.model'. If you have a test +set called heart_scale.t, then type `predict heart_scale.t +heart_scale.model output' to see the prediction accuracy. The `output' +file contains the predicted class labels. + +For more information about `train' and `predict', see the sections +`train' Usage and `predict' Usage. + +To obtain good performances, sometimes one needs to scale the +data. Please check the program `svm-scale' of LIBSVM. For large and +sparse data, use `-l 0' to keep the sparsity. + +Installation +============ + +On Unix systems, type `make' to build the `train' and `predict' +programs. Run them without arguments to show the usages. + +On other systems, consult `Makefile' to build them (e.g., see +'Building Windows binaries' in this file) or use the pre-built +binaries (Windows binaries are in the directory `windows'). + +This software uses some level-1 BLAS subroutines. The needed functions are +included in this package. If a BLAS library is available on your +machine, you may use it by modifying the Makefile: Unmark the following line + + #LIBS ?= -lblas + +and mark + + LIBS ?= blas/blas.a + +`train' Usage +============= + +Usage: train [options] training_set_file [model_file] +options: +-s type : set type of solver (default 1) + for multi-class classification + 0 -- L2-regularized logistic regression (primal) + 1 -- L2-regularized L2-loss support vector classification (dual) + 2 -- L2-regularized L2-loss support vector classification (primal) + 3 -- L2-regularized L1-loss support vector classification (dual) + 4 -- support vector classification by Crammer and Singer + 5 -- L1-regularized L2-loss support vector classification + 6 -- L1-regularized logistic regression + 7 -- L2-regularized logistic regression (dual) + for regression + 11 -- L2-regularized L2-loss support vector regression (primal) + 12 -- L2-regularized L2-loss support vector regression (dual) + 13 -- L2-regularized L1-loss support vector regression (dual) +-c cost : set the parameter C (default 1) +-p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1) +-e epsilon : set tolerance of termination criterion + -s 0 and 2 + |f'(w)|_2 <= eps*min(pos,neg)/l*|f'(w0)|_2, + where f is the primal function and pos/neg are # of + positive/negative data (default 0.01) + -s 11 + |f'(w)|_2 <= eps*|f'(w0)|_2 (default 0.001) + -s 1, 3, 4 and 7 + Dual maximal violation <= eps; similar to libsvm (default 0.1) + -s 5 and 6 + |f'(w)|_inf <= eps*min(pos,neg)/l*|f'(w0)|_inf, + where f is the primal function (default 0.01) + -s 12 and 13\n" + |f'(alpha)|_1 <= eps |f'(alpha0)|, + where f is the dual function (default 0.1) +-B bias : if bias >= 0, instance x becomes [x; bias]; if < 0, no bias term added (default -1) +-wi weight: weights adjust the parameter C of different classes (see README for details) +-v n: n-fold cross validation mode +-q : quiet mode (no outputs) + +Option -v randomly splits the data into n parts and calculates cross +validation accuracy on them. + +Formulations: + +For L2-regularized logistic regression (-s 0), we solve + +min_w w^Tw/2 + C \sum log(1 + exp(-y_i w^Tx_i)) + +For L2-regularized L2-loss SVC dual (-s 1), we solve + +min_alpha 0.5(alpha^T (Q + I/2/C) alpha) - e^T alpha + s.t. 0 <= alpha_i, + +For L2-regularized L2-loss SVC (-s 2), we solve + +min_w w^Tw/2 + C \sum max(0, 1- y_i w^Tx_i)^2 + +For L2-regularized L1-loss SVC dual (-s 3), we solve + +min_alpha 0.5(alpha^T Q alpha) - e^T alpha + s.t. 0 <= alpha_i <= C, + +For L1-regularized L2-loss SVC (-s 5), we solve + +min_w \sum |w_j| + C \sum max(0, 1- y_i w^Tx_i)^2 + +For L1-regularized logistic regression (-s 6), we solve + +min_w \sum |w_j| + C \sum log(1 + exp(-y_i w^Tx_i)) + +For L2-regularized logistic regression (-s 7), we solve + +min_alpha 0.5(alpha^T Q alpha) + \sum alpha_i*log(alpha_i) + \sum (C-alpha_i)*log(C-alpha_i) - a constant + s.t. 0 <= alpha_i <= C, + +where + +Q is a matrix with Q_ij = y_i y_j x_i^T x_j. + +For L2-regularized L2-loss SVR (-s 11), we solve + +min_w w^Tw/2 + C \sum max(0, |y_i-w^Tx_i|-epsilon)^2 + +For L2-regularized L2-loss SVR dual (-s 12), we solve + +min_beta 0.5(beta^T (Q + lambda I/2/C) beta) - y^T beta + \sum |beta_i| + +For L2-regularized L1-loss SVR dual (-s 13), we solve + +min_beta 0.5(beta^T Q beta) - y^T beta + \sum |beta_i| + s.t. -C <= beta_i <= C, + +where + +Q is a matrix with Q_ij = x_i^T x_j. + +If bias >= 0, w becomes [w; w_{n+1}] and x becomes [x; bias]. + +The primal-dual relationship implies that -s 1 and -s 2 give the same +model, -s 0 and -s 7 give the same, and -s 11 and -s 12 give the same. + +We implement 1-vs-the rest multi-class strategy for classification. +In training i vs. non_i, their C parameters are (weight from -wi)*C +and C, respectively. If there are only two classes, we train only one +model. Thus weight1*C vs. weight2*C is used. See examples below. + +We also implement multi-class SVM by Crammer and Singer (-s 4): + +min_{w_m, \xi_i} 0.5 \sum_m ||w_m||^2 + C \sum_i \xi_i + s.t. w^T_{y_i} x_i - w^T_m x_i >= \e^m_i - \xi_i \forall m,i + +where e^m_i = 0 if y_i = m, + e^m_i = 1 if y_i != m, + +Here we solve the dual problem: + +min_{\alpha} 0.5 \sum_m ||w_m(\alpha)||^2 + \sum_i \sum_m e^m_i alpha^m_i + s.t. \alpha^m_i <= C^m_i \forall m,i , \sum_m \alpha^m_i=0 \forall i + +where w_m(\alpha) = \sum_i \alpha^m_i x_i, +and C^m_i = C if m = y_i, + C^m_i = 0 if m != y_i. + +`predict' Usage +=============== + +Usage: predict [options] test_file model_file output_file +options: +-b probability_estimates: whether to output probability estimates, 0 or 1 (default 0); currently for logistic regression only +-q : quiet mode (no outputs) + +Note that -b is only needed in the prediction phase. This is different +from the setting of LIBSVM. + +Examples +======== + +> train data_file + +Train linear SVM with L2-loss function. + +> train -s 0 data_file + +Train a logistic regression model. + +> train -v 5 -e 0.001 data_file + +Do five-fold cross-validation using L2-loss svm. +Use a smaller stopping tolerance 0.001 than the default +0.1 if you want more accurate solutions. + +> train -c 10 -w1 2 -w2 5 -w3 2 four_class_data_file + +Train four classifiers: +positive negative Cp Cn +class 1 class 2,3,4. 20 10 +class 2 class 1,3,4. 50 10 +class 3 class 1,2,4. 20 10 +class 4 class 1,2,3. 10 10 + +> train -c 10 -w3 1 -w2 5 two_class_data_file + +If there are only two classes, we train ONE model. +The C values for the two classes are 10 and 50. + +> predict -b 1 test_file data_file.model output_file + +Output probability estimates (for logistic regression only). + +Library Usage +============= + +- Function: model* train(const struct problem *prob, + const struct parameter *param); + + This function constructs and returns a linear classification + or regression model according to the given training data and + parameters. + + struct problem describes the problem: + + struct problem + { + int l, n; + int *y; + struct feature_node **x; + double bias; + }; + + where `l' is the number of training data. If bias >= 0, we assume + that one additional feature is added to the end of each data + instance. `n' is the number of feature (including the bias feature + if bias >= 0). `y' is an array containing the target values. (integers + in classification, real numbers in regression) And `x' is an array + of pointers, each of which points to a sparse representation (array + of feature_node) of one training vector. + + For example, if we have the following training data: + + LABEL ATTR1 ATTR2 ATTR3 ATTR4 ATTR5 + ----- ----- ----- ----- ----- ----- + 1 0 0.1 0.2 0 0 + 2 0 0.1 0.3 -1.2 0 + 1 0.4 0 0 0 0 + 2 0 0.1 0 1.4 0.5 + 3 -0.1 -0.2 0.1 1.1 0.1 + + and bias = 1, then the components of problem are: + + l = 5 + n = 6 + + y -> 1 2 1 2 3 + + x -> [ ] -> (2,0.1) (3,0.2) (6,1) (-1,?) + [ ] -> (2,0.1) (3,0.3) (4,-1.2) (6,1) (-1,?) + [ ] -> (1,0.4) (6,1) (-1,?) + [ ] -> (2,0.1) (4,1.4) (5,0.5) (6,1) (-1,?) + [ ] -> (1,-0.1) (2,-0.2) (3,0.1) (4,1.1) (5,0.1) (6,1) (-1,?) + + struct parameter describes the parameters of a linear classification + or regression model: + + struct parameter + { + int solver_type; + + /* these are for training only */ + double eps; /* stopping criteria */ + double C; + int nr_weight; + int *weight_label; + double* weight; + double p; + }; + + solver_type can be one of L2R_LR, L2R_L2LOSS_SVC_DUAL, L2R_L2LOSS_SVC, L2R_L1LOSS_SVC_DUAL, MCSVM_CS, L1R_L2LOSS_SVC, L1R_LR, L2R_LR_DUAL, L2R_L2LOSS_SVR, L2R_L2LOSS_SVR_DUAL, L2R_L1LOSS_SVR_DUAL. + for classification + L2R_LR L2-regularized logistic regression (primal) + L2R_L2LOSS_SVC_DUAL L2-regularized L2-loss support vector classification (dual) + L2R_L2LOSS_SVC L2-regularized L2-loss support vector classification (primal) + L2R_L1LOSS_SVC_DUAL L2-regularized L1-loss support vector classification (dual) + MCSVM_CS support vector classification by Crammer and Singer + L1R_L2LOSS_SVC L1-regularized L2-loss support vector classification + L1R_LR L1-regularized logistic regression + L2R_LR_DUAL L2-regularized logistic regression (dual) + for regression + L2R_L2LOSS_SVR L2-regularized L2-loss support vector regression (primal) + L2R_L2LOSS_SVR_DUAL L2-regularized L2-loss support vector regression (dual) + L2R_L1LOSS_SVR_DUAL L2-regularized L1-loss support vector regression (dual) + + C is the cost of constraints violation. + p is the sensitiveness of loss of support vector regression. + eps is the stopping criterion. + + nr_weight, weight_label, and weight are used to change the penalty + for some classes (If the weight for a class is not changed, it is + set to 1). This is useful for training classifier using unbalanced + input data or with asymmetric misclassification cost. + + nr_weight is the number of elements in the array weight_label and + weight. Each weight[i] corresponds to weight_label[i], meaning that + the penalty of class weight_label[i] is scaled by a factor of weight[i]. + + If you do not want to change penalty for any of the classes, + just set nr_weight to 0. + + *NOTE* To avoid wrong parameters, check_parameter() should be + called before train(). + + struct model stores the model obtained from the training procedure: + + struct model + { + struct parameter param; + int nr_class; /* number of classes */ + int nr_feature; + double *w; + int *label; /* label of each class */ + double bias; + }; + + param describes the parameters used to obtain the model. + + nr_class and nr_feature are the number of classes and features, + respectively. nr_class = 2 for regression. + + The nr_feature*nr_class array w gives feature weights. We use one + against the rest for multi-class classification, so each feature + index corresponds to nr_class weight values. Weights are + organized in the following way + + +------------------+------------------+------------+ + | nr_class weights | nr_class weights | ... + | for 1st feature | for 2nd feature | + +------------------+------------------+------------+ + + If bias >= 0, x becomes [x; bias]. The number of features is + increased by one, so w is a (nr_feature+1)*nr_class array. The + value of bias is stored in the variable bias. + + The array label stores class labels. + +- Function: void cross_validation(const problem *prob, const parameter *param, int nr_fold, double *target); + + This function conducts cross validation. Data are separated to + nr_fold folds. Under given parameters, sequentially each fold is + validated using the model from training the remaining. Predicted + labels in the validation process are stored in the array called + target. + + The format of prob is same as that for train(). + +- Function: double predict(const model *model_, const feature_node *x); + + For a classification model, the predicted class for x is returned. + For a regression model, the function value of x calculated using + the model is returned. + +- Function: double predict_values(const struct model *model_, + const struct feature_node *x, double* dec_values); + + This function gives nr_w decision values in the array dec_values. + nr_w=1 if regression is applied or the number of classes is two. An exception is + multi-class svm by Crammer and Singer (-s 4), where nr_w = 2 if there are two classes. For all other situations, nr_w is the + number of classes. + + We implement one-vs-the rest multi-class strategy (-s 0,1,2,3,5,6,7) + and multi-class svm by Crammer and Singer (-s 4) for multi-class SVM. + The class with the highest decision value is returned. + +- Function: double predict_probability(const struct model *model_, + const struct feature_node *x, double* prob_estimates); + + This function gives nr_class probability estimates in the array + prob_estimates. nr_class can be obtained from the function + get_nr_class. The class with the highest probability is + returned. Currently, we support only the probability outputs of + logistic regression. + +- Function: int get_nr_feature(const model *model_); + + The function gives the number of attributes of the model. + +- Function: int get_nr_class(const model *model_); + + The function gives the number of classes of the model. + For a regression model, 2 is returned. + +- Function: void get_labels(const model *model_, int* label); + + This function outputs the name of labels into an array called label. + For a regression model, label is unchanged. + +- Function: const char *check_parameter(const struct problem *prob, + const struct parameter *param); + + This function checks whether the parameters are within the feasible + range of the problem. This function should be called before calling + train() and cross_validation(). It returns NULL if the + parameters are feasible, otherwise an error message is returned. + +- Function: int save_model(const char *model_file_name, + const struct model *model_); + + This function saves a model to a file; returns 0 on success, or -1 + if an error occurs. + +- Function: struct model *load_model(const char *model_file_name); + + This function returns a pointer to the model read from the file, + or a null pointer if the model could not be loaded. + +- Function: void free_model_content(struct model *model_ptr); + + This function frees the memory used by the entries in a model structure. + +- Function: void free_and_destroy_model(struct model **model_ptr_ptr); + + This function frees the memory used by a model and destroys the model + structure. + +- Function: void destroy_param(struct parameter *param); + + This function frees the memory used by a parameter set. + +- Function: void set_print_string_function(void (*print_func)(const char *)); + + Users can specify their output format by a function. Use + set_print_string_function(NULL); + for default printing to stdout. + +Building Windows Binaries +========================= + +Windows binaries are in the directory `windows'. To build them via +Visual C++, use the following steps: + +1. Open a dos command box and change to liblinear directory. If +environment variables of VC++ have not been set, type + +"C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat" + +You may have to modify the above command according which version of +VC++ or where it is installed. + +2. Type + +nmake -f Makefile.win clean all + + +MATLAB/OCTAVE Interface +======================= + +Please check the file README in the directory `matlab'. + +PYTHON Interface +================ + +Please check the file README in the directory `python'. + +Additional Information +====================== + +If you find LIBLINEAR helpful, please cite it as + +R.-E. Fan, K.-W. Chang, C.-J. Hsieh, X.-R. Wang, and C.-J. Lin. +LIBLINEAR: A Library for Large Linear Classification, Journal of +Machine Learning Research 9(2008), 1871-1874. Software available at +http://www.csie.ntu.edu.tw/~cjlin/liblinear + +For any questions and comments, please send your email to +cjlin@csie.ntu.edu.tw + + diff --git a/Bing/Src/LibLinear/blas/Makefile b/Bing/Src/LibLinear/blas/Makefile new file mode 100644 index 000000000..895fd244c --- /dev/null +++ b/Bing/Src/LibLinear/blas/Makefile @@ -0,0 +1,22 @@ +AR = ar rcv +RANLIB = ranlib + +HEADERS = blas.h blasp.h +FILES = dnrm2.o daxpy.o ddot.o dscal.o + +CFLAGS = $(OPTFLAGS) +FFLAGS = $(OPTFLAGS) + +blas: $(FILES) $(HEADERS) + $(AR) blas.a $(FILES) + $(RANLIB) blas.a + +clean: + - rm -f *.o + - rm -f *.a + - rm -f *~ + +.c.o: + $(CC) $(CFLAGS) -c $*.c + + diff --git a/Bing/Src/LibLinear/blas/blas.h b/Bing/Src/LibLinear/blas/blas.h new file mode 100644 index 000000000..558893a04 --- /dev/null +++ b/Bing/Src/LibLinear/blas/blas.h @@ -0,0 +1,25 @@ +/* blas.h -- C header file for BLAS Ver 1.0 */ +/* Jesse Bennett March 23, 2000 */ + +/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." + + - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ + +#ifndef BLAS_INCLUDE +#define BLAS_INCLUDE + +/* Data types specific to BLAS implementation */ +typedef struct { float r, i; } fcomplex; +typedef struct { double r, i; } dcomplex; +typedef int blasbool; + +#include "blasp.h" /* Prototypes for all BLAS functions */ + +#define FALSE 0 +#define TRUE 1 + +/* Macro functions */ +#define MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define MAX(a,b) ((a) >= (b) ? (a) : (b)) + +#endif diff --git a/Bing/Src/LibLinear/blas/blasp.h b/Bing/Src/LibLinear/blas/blasp.h new file mode 100644 index 000000000..745836db8 --- /dev/null +++ b/Bing/Src/LibLinear/blas/blasp.h @@ -0,0 +1,430 @@ +/* blasp.h -- C prototypes for BLAS Ver 1.0 */ +/* Jesse Bennett March 23, 2000 */ + +/* Functions listed in alphabetical order */ + +#ifdef F2C_COMPAT + +void cdotc_(fcomplex *dotval, int *n, fcomplex *cx, int *incx, + fcomplex *cy, int *incy); + +void cdotu_(fcomplex *dotval, int *n, fcomplex *cx, int *incx, + fcomplex *cy, int *incy); + +double sasum_(int *n, float *sx, int *incx); + +double scasum_(int *n, fcomplex *cx, int *incx); + +double scnrm2_(int *n, fcomplex *x, int *incx); + +double sdot_(int *n, float *sx, int *incx, float *sy, int *incy); + +double snrm2_(int *n, float *x, int *incx); + +void zdotc_(dcomplex *dotval, int *n, dcomplex *cx, int *incx, + dcomplex *cy, int *incy); + +void zdotu_(dcomplex *dotval, int *n, dcomplex *cx, int *incx, + dcomplex *cy, int *incy); + +#else + +fcomplex cdotc_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy); + +fcomplex cdotu_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy); + +float sasum_(int *n, float *sx, int *incx); + +float scasum_(int *n, fcomplex *cx, int *incx); + +float scnrm2_(int *n, fcomplex *x, int *incx); + +float sdot_(int *n, float *sx, int *incx, float *sy, int *incy); + +float snrm2_(int *n, float *x, int *incx); + +dcomplex zdotc_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy); + +dcomplex zdotu_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy); + +#endif + +/* Remaining functions listed in alphabetical order */ + +int caxpy_(int *n, fcomplex *ca, fcomplex *cx, int *incx, fcomplex *cy, + int *incy); + +int ccopy_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy); + +int cgbmv_(char *trans, int *m, int *n, int *kl, int *ku, + fcomplex *alpha, fcomplex *a, int *lda, fcomplex *x, int *incx, + fcomplex *beta, fcomplex *y, int *incy); + +int cgemm_(char *transa, char *transb, int *m, int *n, int *k, + fcomplex *alpha, fcomplex *a, int *lda, fcomplex *b, int *ldb, + fcomplex *beta, fcomplex *c, int *ldc); + +int cgemv_(char *trans, int *m, int *n, fcomplex *alpha, fcomplex *a, + int *lda, fcomplex *x, int *incx, fcomplex *beta, fcomplex *y, + int *incy); + +int cgerc_(int *m, int *n, fcomplex *alpha, fcomplex *x, int *incx, + fcomplex *y, int *incy, fcomplex *a, int *lda); + +int cgeru_(int *m, int *n, fcomplex *alpha, fcomplex *x, int *incx, + fcomplex *y, int *incy, fcomplex *a, int *lda); + +int chbmv_(char *uplo, int *n, int *k, fcomplex *alpha, fcomplex *a, + int *lda, fcomplex *x, int *incx, fcomplex *beta, fcomplex *y, + int *incy); + +int chemm_(char *side, char *uplo, int *m, int *n, fcomplex *alpha, + fcomplex *a, int *lda, fcomplex *b, int *ldb, fcomplex *beta, + fcomplex *c, int *ldc); + +int chemv_(char *uplo, int *n, fcomplex *alpha, fcomplex *a, int *lda, + fcomplex *x, int *incx, fcomplex *beta, fcomplex *y, int *incy); + +int cher_(char *uplo, int *n, float *alpha, fcomplex *x, int *incx, + fcomplex *a, int *lda); + +int cher2_(char *uplo, int *n, fcomplex *alpha, fcomplex *x, int *incx, + fcomplex *y, int *incy, fcomplex *a, int *lda); + +int cher2k_(char *uplo, char *trans, int *n, int *k, fcomplex *alpha, + fcomplex *a, int *lda, fcomplex *b, int *ldb, float *beta, + fcomplex *c, int *ldc); + +int cherk_(char *uplo, char *trans, int *n, int *k, float *alpha, + fcomplex *a, int *lda, float *beta, fcomplex *c, int *ldc); + +int chpmv_(char *uplo, int *n, fcomplex *alpha, fcomplex *ap, fcomplex *x, + int *incx, fcomplex *beta, fcomplex *y, int *incy); + +int chpr_(char *uplo, int *n, float *alpha, fcomplex *x, int *incx, + fcomplex *ap); + +int chpr2_(char *uplo, int *n, fcomplex *alpha, fcomplex *x, int *incx, + fcomplex *y, int *incy, fcomplex *ap); + +int crotg_(fcomplex *ca, fcomplex *cb, float *c, fcomplex *s); + +int cscal_(int *n, fcomplex *ca, fcomplex *cx, int *incx); + +int csscal_(int *n, float *sa, fcomplex *cx, int *incx); + +int cswap_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy); + +int csymm_(char *side, char *uplo, int *m, int *n, fcomplex *alpha, + fcomplex *a, int *lda, fcomplex *b, int *ldb, fcomplex *beta, + fcomplex *c, int *ldc); + +int csyr2k_(char *uplo, char *trans, int *n, int *k, fcomplex *alpha, + fcomplex *a, int *lda, fcomplex *b, int *ldb, fcomplex *beta, + fcomplex *c, int *ldc); + +int csyrk_(char *uplo, char *trans, int *n, int *k, fcomplex *alpha, + fcomplex *a, int *lda, fcomplex *beta, fcomplex *c, int *ldc); + +int ctbmv_(char *uplo, char *trans, char *diag, int *n, int *k, + fcomplex *a, int *lda, fcomplex *x, int *incx); + +int ctbsv_(char *uplo, char *trans, char *diag, int *n, int *k, + fcomplex *a, int *lda, fcomplex *x, int *incx); + +int ctpmv_(char *uplo, char *trans, char *diag, int *n, fcomplex *ap, + fcomplex *x, int *incx); + +int ctpsv_(char *uplo, char *trans, char *diag, int *n, fcomplex *ap, + fcomplex *x, int *incx); + +int ctrmm_(char *side, char *uplo, char *transa, char *diag, int *m, + int *n, fcomplex *alpha, fcomplex *a, int *lda, fcomplex *b, + int *ldb); + +int ctrmv_(char *uplo, char *trans, char *diag, int *n, fcomplex *a, + int *lda, fcomplex *x, int *incx); + +int ctrsm_(char *side, char *uplo, char *transa, char *diag, int *m, + int *n, fcomplex *alpha, fcomplex *a, int *lda, fcomplex *b, + int *ldb); + +int ctrsv_(char *uplo, char *trans, char *diag, int *n, fcomplex *a, + int *lda, fcomplex *x, int *incx); + +int daxpy_(int *n, double *sa, double *sx, int *incx, double *sy, + int *incy); + +int dcopy_(int *n, double *sx, int *incx, double *sy, int *incy); + +int dgbmv_(char *trans, int *m, int *n, int *kl, int *ku, + double *alpha, double *a, int *lda, double *x, int *incx, + double *beta, double *y, int *incy); + +int dgemm_(char *transa, char *transb, int *m, int *n, int *k, + double *alpha, double *a, int *lda, double *b, int *ldb, + double *beta, double *c, int *ldc); + +int dgemv_(char *trans, int *m, int *n, double *alpha, double *a, + int *lda, double *x, int *incx, double *beta, double *y, + int *incy); + +int dger_(int *m, int *n, double *alpha, double *x, int *incx, + double *y, int *incy, double *a, int *lda); + +int drot_(int *n, double *sx, int *incx, double *sy, int *incy, + double *c, double *s); + +int drotg_(double *sa, double *sb, double *c, double *s); + +int dsbmv_(char *uplo, int *n, int *k, double *alpha, double *a, + int *lda, double *x, int *incx, double *beta, double *y, + int *incy); + +int dscal_(int *n, double *sa, double *sx, int *incx); + +int dspmv_(char *uplo, int *n, double *alpha, double *ap, double *x, + int *incx, double *beta, double *y, int *incy); + +int dspr_(char *uplo, int *n, double *alpha, double *x, int *incx, + double *ap); + +int dspr2_(char *uplo, int *n, double *alpha, double *x, int *incx, + double *y, int *incy, double *ap); + +int dswap_(int *n, double *sx, int *incx, double *sy, int *incy); + +int dsymm_(char *side, char *uplo, int *m, int *n, double *alpha, + double *a, int *lda, double *b, int *ldb, double *beta, + double *c, int *ldc); + +int dsymv_(char *uplo, int *n, double *alpha, double *a, int *lda, + double *x, int *incx, double *beta, double *y, int *incy); + +int dsyr_(char *uplo, int *n, double *alpha, double *x, int *incx, + double *a, int *lda); + +int dsyr2_(char *uplo, int *n, double *alpha, double *x, int *incx, + double *y, int *incy, double *a, int *lda); + +int dsyr2k_(char *uplo, char *trans, int *n, int *k, double *alpha, + double *a, int *lda, double *b, int *ldb, double *beta, + double *c, int *ldc); + +int dsyrk_(char *uplo, char *trans, int *n, int *k, double *alpha, + double *a, int *lda, double *beta, double *c, int *ldc); + +int dtbmv_(char *uplo, char *trans, char *diag, int *n, int *k, + double *a, int *lda, double *x, int *incx); + +int dtbsv_(char *uplo, char *trans, char *diag, int *n, int *k, + double *a, int *lda, double *x, int *incx); + +int dtpmv_(char *uplo, char *trans, char *diag, int *n, double *ap, + double *x, int *incx); + +int dtpsv_(char *uplo, char *trans, char *diag, int *n, double *ap, + double *x, int *incx); + +int dtrmm_(char *side, char *uplo, char *transa, char *diag, int *m, + int *n, double *alpha, double *a, int *lda, double *b, + int *ldb); + +int dtrmv_(char *uplo, char *trans, char *diag, int *n, double *a, + int *lda, double *x, int *incx); + +int dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m, + int *n, double *alpha, double *a, int *lda, double *b, + int *ldb); + +int dtrsv_(char *uplo, char *trans, char *diag, int *n, double *a, + int *lda, double *x, int *incx); + + +int saxpy_(int *n, float *sa, float *sx, int *incx, float *sy, int *incy); + +int scopy_(int *n, float *sx, int *incx, float *sy, int *incy); + +int sgbmv_(char *trans, int *m, int *n, int *kl, int *ku, + float *alpha, float *a, int *lda, float *x, int *incx, + float *beta, float *y, int *incy); + +int sgemm_(char *transa, char *transb, int *m, int *n, int *k, + float *alpha, float *a, int *lda, float *b, int *ldb, + float *beta, float *c, int *ldc); + +int sgemv_(char *trans, int *m, int *n, float *alpha, float *a, + int *lda, float *x, int *incx, float *beta, float *y, + int *incy); + +int sger_(int *m, int *n, float *alpha, float *x, int *incx, + float *y, int *incy, float *a, int *lda); + +int srot_(int *n, float *sx, int *incx, float *sy, int *incy, + float *c, float *s); + +int srotg_(float *sa, float *sb, float *c, float *s); + +int ssbmv_(char *uplo, int *n, int *k, float *alpha, float *a, + int *lda, float *x, int *incx, float *beta, float *y, + int *incy); + +int sscal_(int *n, float *sa, float *sx, int *incx); + +int sspmv_(char *uplo, int *n, float *alpha, float *ap, float *x, + int *incx, float *beta, float *y, int *incy); + +int sspr_(char *uplo, int *n, float *alpha, float *x, int *incx, + float *ap); + +int sspr2_(char *uplo, int *n, float *alpha, float *x, int *incx, + float *y, int *incy, float *ap); + +int sswap_(int *n, float *sx, int *incx, float *sy, int *incy); + +int ssymm_(char *side, char *uplo, int *m, int *n, float *alpha, + float *a, int *lda, float *b, int *ldb, float *beta, + float *c, int *ldc); + +int ssymv_(char *uplo, int *n, float *alpha, float *a, int *lda, + float *x, int *incx, float *beta, float *y, int *incy); + +int ssyr_(char *uplo, int *n, float *alpha, float *x, int *incx, + float *a, int *lda); + +int ssyr2_(char *uplo, int *n, float *alpha, float *x, int *incx, + float *y, int *incy, float *a, int *lda); + +int ssyr2k_(char *uplo, char *trans, int *n, int *k, float *alpha, + float *a, int *lda, float *b, int *ldb, float *beta, + float *c, int *ldc); + +int ssyrk_(char *uplo, char *trans, int *n, int *k, float *alpha, + float *a, int *lda, float *beta, float *c, int *ldc); + +int stbmv_(char *uplo, char *trans, char *diag, int *n, int *k, + float *a, int *lda, float *x, int *incx); + +int stbsv_(char *uplo, char *trans, char *diag, int *n, int *k, + float *a, int *lda, float *x, int *incx); + +int stpmv_(char *uplo, char *trans, char *diag, int *n, float *ap, + float *x, int *incx); + +int stpsv_(char *uplo, char *trans, char *diag, int *n, float *ap, + float *x, int *incx); + +int strmm_(char *side, char *uplo, char *transa, char *diag, int *m, + int *n, float *alpha, float *a, int *lda, float *b, + int *ldb); + +int strmv_(char *uplo, char *trans, char *diag, int *n, float *a, + int *lda, float *x, int *incx); + +int strsm_(char *side, char *uplo, char *transa, char *diag, int *m, + int *n, float *alpha, float *a, int *lda, float *b, + int *ldb); + +int strsv_(char *uplo, char *trans, char *diag, int *n, float *a, + int *lda, float *x, int *incx); + +int zaxpy_(int *n, dcomplex *ca, dcomplex *cx, int *incx, dcomplex *cy, + int *incy); + +int zcopy_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy); + +int zdscal_(int *n, double *sa, dcomplex *cx, int *incx); + +int zgbmv_(char *trans, int *m, int *n, int *kl, int *ku, + dcomplex *alpha, dcomplex *a, int *lda, dcomplex *x, int *incx, + dcomplex *beta, dcomplex *y, int *incy); + +int zgemm_(char *transa, char *transb, int *m, int *n, int *k, + dcomplex *alpha, dcomplex *a, int *lda, dcomplex *b, int *ldb, + dcomplex *beta, dcomplex *c, int *ldc); + +int zgemv_(char *trans, int *m, int *n, dcomplex *alpha, dcomplex *a, + int *lda, dcomplex *x, int *incx, dcomplex *beta, dcomplex *y, + int *incy); + +int zgerc_(int *m, int *n, dcomplex *alpha, dcomplex *x, int *incx, + dcomplex *y, int *incy, dcomplex *a, int *lda); + +int zgeru_(int *m, int *n, dcomplex *alpha, dcomplex *x, int *incx, + dcomplex *y, int *incy, dcomplex *a, int *lda); + +int zhbmv_(char *uplo, int *n, int *k, dcomplex *alpha, dcomplex *a, + int *lda, dcomplex *x, int *incx, dcomplex *beta, dcomplex *y, + int *incy); + +int zhemm_(char *side, char *uplo, int *m, int *n, dcomplex *alpha, + dcomplex *a, int *lda, dcomplex *b, int *ldb, dcomplex *beta, + dcomplex *c, int *ldc); + +int zhemv_(char *uplo, int *n, dcomplex *alpha, dcomplex *a, int *lda, + dcomplex *x, int *incx, dcomplex *beta, dcomplex *y, int *incy); + +int zher_(char *uplo, int *n, double *alpha, dcomplex *x, int *incx, + dcomplex *a, int *lda); + +int zher2_(char *uplo, int *n, dcomplex *alpha, dcomplex *x, int *incx, + dcomplex *y, int *incy, dcomplex *a, int *lda); + +int zher2k_(char *uplo, char *trans, int *n, int *k, dcomplex *alpha, + dcomplex *a, int *lda, dcomplex *b, int *ldb, double *beta, + dcomplex *c, int *ldc); + +int zherk_(char *uplo, char *trans, int *n, int *k, double *alpha, + dcomplex *a, int *lda, double *beta, dcomplex *c, int *ldc); + +int zhpmv_(char *uplo, int *n, dcomplex *alpha, dcomplex *ap, dcomplex *x, + int *incx, dcomplex *beta, dcomplex *y, int *incy); + +int zhpr_(char *uplo, int *n, double *alpha, dcomplex *x, int *incx, + dcomplex *ap); + +int zhpr2_(char *uplo, int *n, dcomplex *alpha, dcomplex *x, int *incx, + dcomplex *y, int *incy, dcomplex *ap); + +int zrotg_(dcomplex *ca, dcomplex *cb, double *c, dcomplex *s); + +int zscal_(int *n, dcomplex *ca, dcomplex *cx, int *incx); + +int zswap_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy); + +int zsymm_(char *side, char *uplo, int *m, int *n, dcomplex *alpha, + dcomplex *a, int *lda, dcomplex *b, int *ldb, dcomplex *beta, + dcomplex *c, int *ldc); + +int zsyr2k_(char *uplo, char *trans, int *n, int *k, dcomplex *alpha, + dcomplex *a, int *lda, dcomplex *b, int *ldb, dcomplex *beta, + dcomplex *c, int *ldc); + +int zsyrk_(char *uplo, char *trans, int *n, int *k, dcomplex *alpha, + dcomplex *a, int *lda, dcomplex *beta, dcomplex *c, int *ldc); + +int ztbmv_(char *uplo, char *trans, char *diag, int *n, int *k, + dcomplex *a, int *lda, dcomplex *x, int *incx); + +int ztbsv_(char *uplo, char *trans, char *diag, int *n, int *k, + dcomplex *a, int *lda, dcomplex *x, int *incx); + +int ztpmv_(char *uplo, char *trans, char *diag, int *n, dcomplex *ap, + dcomplex *x, int *incx); + +int ztpsv_(char *uplo, char *trans, char *diag, int *n, dcomplex *ap, + dcomplex *x, int *incx); + +int ztrmm_(char *side, char *uplo, char *transa, char *diag, int *m, + int *n, dcomplex *alpha, dcomplex *a, int *lda, dcomplex *b, + int *ldb); + +int ztrmv_(char *uplo, char *trans, char *diag, int *n, dcomplex *a, + int *lda, dcomplex *x, int *incx); + +int ztrsm_(char *side, char *uplo, char *transa, char *diag, int *m, + int *n, dcomplex *alpha, dcomplex *a, int *lda, dcomplex *b, + int *ldb); + +int ztrsv_(char *uplo, char *trans, char *diag, int *n, dcomplex *a, + int *lda, dcomplex *x, int *incx); diff --git a/Bing/Src/LibLinear/blas/daxpy.c b/Bing/Src/LibLinear/blas/daxpy.c new file mode 100644 index 000000000..58f345a53 --- /dev/null +++ b/Bing/Src/LibLinear/blas/daxpy.c @@ -0,0 +1,49 @@ +#include "blas.h" + +int daxpy_(int *n, double *sa, double *sx, int *incx, double *sy, + int *incy) +{ + long int i, m, ix, iy, nn, iincx, iincy; + register double ssa; + + /* constant times a vector plus a vector. + uses unrolled loop for increments equal to one. + jack dongarra, linpack, 3/11/78. + modified 12/3/93, array(1) declarations changed to array(*) */ + + /* Dereference inputs */ + nn = *n; + ssa = *sa; + iincx = *incx; + iincy = *incy; + + if( nn > 0 && ssa != 0.0 ) + { + if (iincx == 1 && iincy == 1) /* code for both increments equal to 1 */ + { + m = nn-3; + for (i = 0; i < m; i += 4) + { + sy[i] += ssa * sx[i]; + sy[i+1] += ssa * sx[i+1]; + sy[i+2] += ssa * sx[i+2]; + sy[i+3] += ssa * sx[i+3]; + } + for ( ; i < nn; ++i) /* clean-up loop */ + sy[i] += ssa * sx[i]; + } + else /* code for unequal increments or equal increments not equal to 1 */ + { + ix = iincx >= 0 ? 0 : (1 - nn) * iincx; + iy = iincy >= 0 ? 0 : (1 - nn) * iincy; + for (i = 0; i < nn; i++) + { + sy[iy] += ssa * sx[ix]; + ix += iincx; + iy += iincy; + } + } + } + + return 0; +} /* daxpy_ */ diff --git a/Bing/Src/LibLinear/blas/ddot.c b/Bing/Src/LibLinear/blas/ddot.c new file mode 100644 index 000000000..a64a2808f --- /dev/null +++ b/Bing/Src/LibLinear/blas/ddot.c @@ -0,0 +1,50 @@ +#include "blas.h" + +double ddot_(int *n, double *sx, int *incx, double *sy, int *incy) +{ + long int i, m, nn, iincx, iincy; + double stemp; + long int ix, iy; + + /* forms the dot product of two vectors. + uses unrolled loops for increments equal to one. + jack dongarra, linpack, 3/11/78. + modified 12/3/93, array(1) declarations changed to array(*) */ + + /* Dereference inputs */ + nn = *n; + iincx = *incx; + iincy = *incy; + + stemp = 0.0; + if (nn > 0) + { + if (iincx == 1 && iincy == 1) /* code for both increments equal to 1 */ + { + m = nn-4; + for (i = 0; i < m; i += 5) + stemp += sx[i] * sy[i] + sx[i+1] * sy[i+1] + sx[i+2] * sy[i+2] + + sx[i+3] * sy[i+3] + sx[i+4] * sy[i+4]; + + for ( ; i < nn; i++) /* clean-up loop */ + stemp += sx[i] * sy[i]; + } + else /* code for unequal increments or equal increments not equal to 1 */ + { + ix = 0; + iy = 0; + if (iincx < 0) + ix = (1 - nn) * iincx; + if (iincy < 0) + iy = (1 - nn) * iincy; + for (i = 0; i < nn; i++) + { + stemp += sx[ix] * sy[iy]; + ix += iincx; + iy += iincy; + } + } + } + + return stemp; +} /* ddot_ */ diff --git a/Bing/Src/LibLinear/blas/dnrm2.c b/Bing/Src/LibLinear/blas/dnrm2.c new file mode 100644 index 000000000..e50cdf777 --- /dev/null +++ b/Bing/Src/LibLinear/blas/dnrm2.c @@ -0,0 +1,62 @@ +#include /* Needed for fabs() and sqrt() */ +#include "blas.h" + +double dnrm2_(int *n, double *x, int *incx) +{ + long int ix, nn, iincx; + double norm, scale, absxi, ssq, temp; + +/* DNRM2 returns the euclidean norm of a vector via the function + name, so that + + DNRM2 := sqrt( x'*x ) + + -- This version written on 25-October-1982. + Modified on 14-October-1993 to inline the call to SLASSQ. + Sven Hammarling, Nag Ltd. */ + + /* Dereference inputs */ + nn = *n; + iincx = *incx; + + if( nn > 0 && iincx > 0 ) + { + if (nn == 1) + { + norm = fabs(x[0]); + } + else + { + scale = 0.0; + ssq = 1.0; + + /* The following loop is equivalent to this call to the LAPACK + auxiliary routine: CALL SLASSQ( N, X, INCX, SCALE, SSQ ) */ + + for (ix=(nn-1)*iincx; ix>=0; ix-=iincx) + { + if (x[ix] != 0.0) + { + absxi = fabs(x[ix]); + if (scale < absxi) + { + temp = scale / absxi; + ssq = ssq * (temp * temp) + 1.0; + scale = absxi; + } + else + { + temp = absxi / scale; + ssq += temp * temp; + } + } + } + norm = scale * sqrt(ssq); + } + } + else + norm = 0.0; + + return norm; + +} /* dnrm2_ */ diff --git a/Bing/Src/LibLinear/blas/dscal.c b/Bing/Src/LibLinear/blas/dscal.c new file mode 100644 index 000000000..a0eca0c39 --- /dev/null +++ b/Bing/Src/LibLinear/blas/dscal.c @@ -0,0 +1,44 @@ +#include "blas.h" + +int dscal_(int *n, double *sa, double *sx, int *incx) +{ + long int i, m, nincx, nn, iincx; + double ssa; + + /* scales a vector by a constant. + uses unrolled loops for increment equal to 1. + jack dongarra, linpack, 3/11/78. + modified 3/93 to return if incx .le. 0. + modified 12/3/93, array(1) declarations changed to array(*) */ + + /* Dereference inputs */ + nn = *n; + iincx = *incx; + ssa = *sa; + + if (nn > 0 && iincx > 0) + { + if (iincx == 1) /* code for increment equal to 1 */ + { + m = nn-4; + for (i = 0; i < m; i += 5) + { + sx[i] = ssa * sx[i]; + sx[i+1] = ssa * sx[i+1]; + sx[i+2] = ssa * sx[i+2]; + sx[i+3] = ssa * sx[i+3]; + sx[i+4] = ssa * sx[i+4]; + } + for ( ; i < nn; ++i) /* clean-up loop */ + sx[i] = ssa * sx[i]; + } + else /* code for increment not equal to 1 */ + { + nincx = nn * iincx; + for (i = 0; i < nincx; i += iincx) + sx[i] = ssa * sx[i]; + } + } + + return 0; +} /* dscal_ */ diff --git a/Bing/Src/LibLinear/linear.cpp b/Bing/Src/LibLinear/linear.cpp new file mode 100644 index 000000000..1dc8056f1 --- /dev/null +++ b/Bing/Src/LibLinear/linear.cpp @@ -0,0 +1,2811 @@ +#include +#include +#include +#include +#include +#include +#include "linear.h" +#include "tron.h" +typedef signed char schar; +template static inline void swap(T& x, T& y) { T t=x; x=y; y=t; } +#ifndef min +template static inline T min(T x,T y) { return (x static inline T max(T x,T y) { return (x>y)?x:y; } +#endif +template static inline void clone(T*& dst, S* src, int n) +{ + dst = new T[n]; + memcpy((void *)dst,(void *)src,sizeof(T)*n); +} +#define Malloc(type,n) (type *)malloc((n)*sizeof(type)) +#define INF HUGE_VAL + +static void print_string_stdout(const char *s) +{ + fputs(s,stdout); + fflush(stdout); +} + +static void (*liblinear_print_string) (const char *) = &print_string_stdout; + +#if 1 +static void info(const char *fmt,...) +{ + char buf[BUFSIZ]; + va_list ap; + va_start(ap,fmt); + vsprintf(buf,fmt,ap); + va_end(ap); + (*liblinear_print_string)(buf); +} +#else +static void info(const char *fmt,...) {} +#endif + +class l2r_lr_fun: public function +{ +public: + l2r_lr_fun(const problem *prob, double *C); + ~l2r_lr_fun(); + + double fun(double *w); + void grad(double *w, double *g); + void Hv(double *s, double *Hs); + + int get_nr_variable(void); + +private: + void Xv(double *v, double *Xv); + void XTv(double *v, double *XTv); + + double *C; + double *z; + double *D; + const problem *prob; +}; + +l2r_lr_fun::l2r_lr_fun(const problem *prob, double *C) +{ + int l=prob->l; + + this->prob = prob; + + z = new double[l]; + D = new double[l]; + this->C = C; +} + +l2r_lr_fun::~l2r_lr_fun() +{ + delete[] z; + delete[] D; +} + + +double l2r_lr_fun::fun(double *w) +{ + int i; + double f=0; + double *y=prob->y; + int l=prob->l; + int w_size=get_nr_variable(); + + Xv(w, z); + + for(i=0;i= 0) + f += C[i]*log(1 + exp(-yz)); + else + f += C[i]*(-yz+log(1 + exp(yz))); + } + + return(f); +} + +void l2r_lr_fun::grad(double *w, double *g) +{ + int i; + double *y=prob->y; + int l=prob->l; + int w_size=get_nr_variable(); + + for(i=0;in; +} + +void l2r_lr_fun::Hv(double *s, double *Hs) +{ + int i; + int l=prob->l; + int w_size=get_nr_variable(); + double *wa = new double[l]; + + Xv(s, wa); + for(i=0;il; + feature_node **x=prob->x; + + for(i=0;iindex!=-1) + { + Xv[i]+=v[s->index-1]*s->value; + s++; + } + } +} + +void l2r_lr_fun::XTv(double *v, double *XTv) +{ + int i; + int l=prob->l; + int w_size=get_nr_variable(); + feature_node **x=prob->x; + + for(i=0;iindex!=-1) + { + XTv[s->index-1]+=v[i]*s->value; + s++; + } + } +} + +class l2r_l2_svc_fun: public function +{ +public: + l2r_l2_svc_fun(const problem *prob, double *C); + ~l2r_l2_svc_fun(); + + double fun(double *w); + void grad(double *w, double *g); + void Hv(double *s, double *Hs); + + int get_nr_variable(void); + +protected: + void Xv(double *v, double *Xv); + void subXv(double *v, double *Xv); + void subXTv(double *v, double *XTv); + + double *C; + double *z; + double *D; + int *I; + int sizeI; + const problem *prob; +}; + +l2r_l2_svc_fun::l2r_l2_svc_fun(const problem *prob, double *C) +{ + int l=prob->l; + + this->prob = prob; + + z = new double[l]; + D = new double[l]; + I = new int[l]; + this->C = C; +} + +l2r_l2_svc_fun::~l2r_l2_svc_fun() +{ + delete[] z; + delete[] D; + delete[] I; +} + +double l2r_l2_svc_fun::fun(double *w) +{ + int i; + double f=0; + double *y=prob->y; + int l=prob->l; + int w_size=get_nr_variable(); + + Xv(w, z); + + for(i=0;i 0) + f += C[i]*d*d; + } + + return(f); +} + +void l2r_l2_svc_fun::grad(double *w, double *g) +{ + int i; + double *y=prob->y; + int l=prob->l; + int w_size=get_nr_variable(); + + sizeI = 0; + for (i=0;in; +} + +void l2r_l2_svc_fun::Hv(double *s, double *Hs) +{ + int i; + int w_size=get_nr_variable(); + double *wa = new double[sizeI]; + + subXv(s, wa); + for(i=0;il; + feature_node **x=prob->x; + + for(i=0;iindex!=-1) + { + Xv[i]+=v[s->index-1]*s->value; + s++; + } + } +} + +void l2r_l2_svc_fun::subXv(double *v, double *Xv) +{ + int i; + feature_node **x=prob->x; + + for(i=0;iindex!=-1) + { + Xv[i]+=v[s->index-1]*s->value; + s++; + } + } +} + +void l2r_l2_svc_fun::subXTv(double *v, double *XTv) +{ + int i; + int w_size=get_nr_variable(); + feature_node **x=prob->x; + + for(i=0;iindex!=-1) + { + XTv[s->index-1]+=v[i]*s->value; + s++; + } + } +} + +class l2r_l2_svr_fun: public l2r_l2_svc_fun +{ +public: + l2r_l2_svr_fun(const problem *prob, double *C, double p); + + double fun(double *w); + void grad(double *w, double *g); + +private: + double p; +}; + +l2r_l2_svr_fun::l2r_l2_svr_fun(const problem *prob, double *C, double p): + l2r_l2_svc_fun(prob, C) +{ + this->p = p; +} + +double l2r_l2_svr_fun::fun(double *w) +{ + int i; + double f=0; + double *y=prob->y; + int l=prob->l; + int w_size=get_nr_variable(); + double d; + + Xv(w, z); + + for(i=0;i p) + f += C[i]*(d-p)*(d-p); + } + + return(f); +} + +void l2r_l2_svr_fun::grad(double *w, double *g) +{ + int i; + double *y=prob->y; + int l=prob->l; + int w_size=get_nr_variable(); + double d; + + sizeI = 0; + for(i=0;i p) + { + z[sizeI] = C[i]*(d-p); + I[sizeI] = i; + sizeI++; + } + + } + subXTv(z, g); + + for(i=0;iy[i]) +// To support weights for instances, use GETI(i) (i) + +class Solver_MCSVM_CS +{ + public: + Solver_MCSVM_CS(const problem *prob, int nr_class, double *C, double eps=0.1, int max_iter=100000); + ~Solver_MCSVM_CS(); + void Solve(double *w); + private: + void solve_sub_problem(double A_i, int yi, double C_yi, int active_i, double *alpha_new); + bool be_shrunk(int i, int m, int yi, double alpha_i, double minG); + double *B, *C, *G; + int w_size, l; + int nr_class; + int max_iter; + double eps; + const problem *prob; +}; + +Solver_MCSVM_CS::Solver_MCSVM_CS(const problem *prob, int nr_class, double *weighted_C, double eps, int max_iter) +{ + this->w_size = prob->n; + this->l = prob->l; + this->nr_class = nr_class; + this->eps = eps; + this->max_iter = max_iter; + this->prob = prob; + this->B = new double[nr_class]; + this->G = new double[nr_class]; + this->C = weighted_C; +} + +Solver_MCSVM_CS::~Solver_MCSVM_CS() +{ + delete[] B; + delete[] G; +} + +int compare_double(const void *a, const void *b) +{ + if(*(double *)a > *(double *)b) + return -1; + if(*(double *)a < *(double *)b) + return 1; + return 0; +} + +void Solver_MCSVM_CS::solve_sub_problem(double A_i, int yi, double C_yi, int active_i, double *alpha_new) +{ + int r; + double *D; + + clone(D, B, active_i); + if(yi < active_i) + D[yi] += A_i*C_yi; + qsort(D, active_i, sizeof(double), compare_double); + + double beta = D[0] - A_i*C_yi; + for(r=1;ry[i] == m + // alpha[i*nr_class+m] <= 0 if prob->y[i] != m + // If initial alpha isn't zero, uncomment the for loop below to initialize w + for(i=0;ix[i]; + QD[i] = 0; + while(xi->index != -1) + { + double val = xi->value; + QD[i] += val*val; + + // Uncomment the for loop if initial alpha isn't zero + // for(m=0; mindex-1)*nr_class+m] += alpha[i*nr_class+m]*val; + xi++; + } + active_size_i[i] = nr_class; + y_index[i] = (int)prob->y[i]; + index[i] = i; + } + + while(iter < max_iter) + { + double stopping = -INF; + for(i=0;i 0) + { + for(m=0;mx[i]; + while(xi->index!= -1) + { + double *w_i = &w[(xi->index-1)*nr_class]; + for(m=0;mvalue); + xi++; + } + + double minG = INF; + double maxG = -INF; + for(m=0;m maxG) + maxG = G[m]; + } + if(y_index[i] < active_size_i[i]) + if(alpha_i[(int) prob->y[i]] < C[GETI(i)] && G[y_index[i]] < minG) + minG = G[y_index[i]]; + + for(m=0;mm) + { + if(!be_shrunk(i, active_size_i[i], y_index[i], + alpha_i[alpha_index_i[active_size_i[i]]], minG)) + { + swap(alpha_index_i[m], alpha_index_i[active_size_i[i]]); + swap(G[m], G[active_size_i[i]]); + if(y_index[i] == active_size_i[i]) + y_index[i] = m; + else if(y_index[i] == m) + y_index[i] = active_size_i[i]; + break; + } + active_size_i[i]--; + } + } + } + + if(active_size_i[i] <= 1) + { + active_size--; + swap(index[s], index[active_size]); + s--; + continue; + } + + if(maxG-minG <= 1e-12) + continue; + else + stopping = max(maxG - minG, stopping); + + for(m=0;m= 1e-12) + { + d_ind[nz_d] = alpha_index_i[m]; + d_val[nz_d] = d; + nz_d++; + } + } + + xi = prob->x[i]; + while(xi->index != -1) + { + double *w_i = &w[(xi->index-1)*nr_class]; + for(m=0;mvalue; + xi++; + } + } + } + + iter++; + if(iter % 10 == 0) + { + info("."); + } + + if(stopping < eps_shrink) + { + if(stopping < eps && start_from_all == true) + break; + else + { + active_size = l; + for(i=0;i= max_iter) + info("\nWARNING: reaching max number of iterations\n"); + + // calculate objective value + double v = 0; + int nSV = 0; + for(i=0;i 0) + nSV++; + } + for(i=0;iy[i]]; + info("Objective value = %lf\n",v); + info("nSV = %d\n",nSV); + + delete [] alpha; + delete [] alpha_new; + delete [] index; + delete [] QD; + delete [] d_ind; + delete [] d_val; + delete [] alpha_index; + delete [] y_index; + delete [] active_size_i; +} + +// A coordinate descent algorithm for +// L1-loss and L2-loss SVM dual problems +// +// min_\alpha 0.5(\alpha^T (Q + D)\alpha) - e^T \alpha, +// s.t. 0 <= \alpha_i <= upper_bound_i, +// +// where Qij = yi yj xi^T xj and +// D is a diagonal matrix +// +// In L1-SVM case: +// upper_bound_i = Cp if y_i = 1 +// upper_bound_i = Cn if y_i = -1 +// D_ii = 0 +// In L2-SVM case: +// upper_bound_i = INF +// D_ii = 1/(2*Cp) if y_i = 1 +// D_ii = 1/(2*Cn) if y_i = -1 +// +// Given: +// x, y, Cp, Cn +// eps is the stopping tolerance +// +// solution will be put in w +// +// See Algorithm 3 of Hsieh et al., ICML 2008 + +#undef GETI +#define GETI(i) (y[i]+1) +// To support weights for instances, use GETI(i) (i) + +static void solve_l2r_l1l2_svc( + const problem *prob, double *w, double eps, + double Cp, double Cn, int solver_type) +{ + int l = prob->l; + int w_size = prob->n; + int i, s, iter = 0; + double C, d, G; + double *QD = new double[l]; + int max_iter = 1000; + int *index = new int[l]; + double *alpha = new double[l]; + schar *y = new schar[l]; + int active_size = l; + + // PG: projected gradient, for shrinking and stopping + double PG; + double PGmax_old = INF; + double PGmin_old = -INF; + double PGmax_new, PGmin_new; + + // default solver_type: L2R_L2LOSS_SVC_DUAL + double diag[3] = {0.5/Cn, 0, 0.5/Cp}; + double upper_bound[3] = {INF, 0, INF}; + if(solver_type == L2R_L1LOSS_SVC_DUAL) + { + diag[0] = 0; + diag[2] = 0; + upper_bound[0] = Cn; + upper_bound[2] = Cp; + } + + for(i=0; iy[i] > 0) + { + y[i] = +1; + } + else + { + y[i] = -1; + } + } + + // Initial alpha can be set here. Note that + // 0 <= alpha[i] <= upper_bound[GETI(i)] + for(i=0; ix[i]; + while (xi->index != -1) + { + double val = xi->value; + QD[i] += val*val; + w[xi->index-1] += y[i]*alpha[i]*val; + xi++; + } + index[i] = i; + } + + while (iter < max_iter) + { + PGmax_new = -INF; + PGmin_new = INF; + + for (i=0; ix[i]; + while(xi->index!= -1) + { + G += w[xi->index-1]*(xi->value); + xi++; + } + G = G*yi-1; + + C = upper_bound[GETI(i)]; + G += alpha[i]*diag[GETI(i)]; + + PG = 0; + if (alpha[i] == 0) + { + if (G > PGmax_old) + { + active_size--; + swap(index[s], index[active_size]); + s--; + continue; + } + else if (G < 0) + PG = G; + } + else if (alpha[i] == C) + { + if (G < PGmin_old) + { + active_size--; + swap(index[s], index[active_size]); + s--; + continue; + } + else if (G > 0) + PG = G; + } + else + PG = G; + + PGmax_new = max(PGmax_new, PG); + PGmin_new = min(PGmin_new, PG); + + if(fabs(PG) > 1.0e-12) + { + double alpha_old = alpha[i]; + alpha[i] = min(max(alpha[i] - G/QD[i], 0.0), C); + d = (alpha[i] - alpha_old)*yi; + xi = prob->x[i]; + while (xi->index != -1) + { + w[xi->index-1] += d*xi->value; + xi++; + } + } + } + + iter++; + if(iter % 10 == 0) + info("."); + + if(PGmax_new - PGmin_new <= eps) + { + if(active_size == l) + break; + else + { + active_size = l; + info("*"); + PGmax_old = INF; + PGmin_old = -INF; + continue; + } + } + PGmax_old = PGmax_new; + PGmin_old = PGmin_new; + if (PGmax_old <= 0) + PGmax_old = INF; + if (PGmin_old >= 0) + PGmin_old = -INF; + } + + info("\noptimization finished, #iter = %d\n",iter); + if (iter >= max_iter) + info("\nWARNING: reaching max number of iterations\nUsing -s 2 may be faster (also see FAQ)\n\n"); + + // calculate objective value + + double v = 0; + int nSV = 0; + for(i=0; i 0) + ++nSV; + } + info("Objective value = %lf\n",v/2); + info("nSV = %d\n",nSV); + + delete [] QD; + delete [] alpha; + delete [] y; + delete [] index; +} + + +// A coordinate descent algorithm for +// L1-loss and L2-loss epsilon-SVR dual problem +// +// min_\beta 0.5\beta^T (Q + diag(lambda)) \beta - p \sum_{i=1}^l|\beta_i| + \sum_{i=1}^l yi\beta_i, +// s.t. -upper_bound_i <= \beta_i <= upper_bound_i, +// +// where Qij = xi^T xj and +// D is a diagonal matrix +// +// In L1-SVM case: +// upper_bound_i = C +// lambda_i = 0 +// In L2-SVM case: +// upper_bound_i = INF +// lambda_i = 1/(2*C) +// +// Given: +// x, y, p, C +// eps is the stopping tolerance +// +// solution will be put in w +// +// See Algorithm 4 of Ho and Lin, 2012 + +#undef GETI +#define GETI(i) (0) +// To support weights for instances, use GETI(i) (i) + +static void solve_l2r_l1l2_svr( + const problem *prob, double *w, const parameter *param, + int solver_type) +{ + int l = prob->l; + double C = param->C; + double p = param->p; + int w_size = prob->n; + double eps = param->eps; + int i, s, iter = 0; + int max_iter = 1000; + int active_size = l; + int *index = new int[l]; + + double d, G, H; + double Gmax_old = INF; + double Gmax_new, Gnorm1_new; + double Gnorm1_init; + double *beta = new double[l]; + double *QD = new double[l]; + double *y = prob->y; + + // L2R_L2LOSS_SVR_DUAL + double lambda[1], upper_bound[1]; + lambda[0] = 0.5/C; + upper_bound[0] = INF; + + if(solver_type == L2R_L1LOSS_SVR_DUAL) + { + lambda[0] = 0; + upper_bound[0] = C; + } + + // Initial beta can be set here. Note that + // -upper_bound <= beta[i] <= upper_bound + for(i=0; ix[i]; + while(xi->index != -1) + { + double val = xi->value; + QD[i] += val*val; + w[xi->index-1] += beta[i]*val; + xi++; + } + + index[i] = i; + } + + + while(iter < max_iter) + { + Gmax_new = 0; + Gnorm1_new = 0; + + for(i=0; ix[i]; + while(xi->index != -1) + { + int ind = xi->index-1; + double val = xi->value; + G += val*w[ind]; + xi++; + } + + double Gp = G+p; + double Gn = G-p; + double violation = 0; + if(beta[i] == 0) + { + if(Gp < 0) + violation = -Gp; + else if(Gn > 0) + violation = Gn; + else if(Gp>Gmax_old && Gn<-Gmax_old) + { + active_size--; + swap(index[s], index[active_size]); + s--; + continue; + } + } + else if(beta[i] >= upper_bound[GETI(i)]) + { + if(Gp > 0) + violation = Gp; + else if(Gp < -Gmax_old) + { + active_size--; + swap(index[s], index[active_size]); + s--; + continue; + } + } + else if(beta[i] <= -upper_bound[GETI(i)]) + { + if(Gn < 0) + violation = -Gn; + else if(Gn > Gmax_old) + { + active_size--; + swap(index[s], index[active_size]); + s--; + continue; + } + } + else if(beta[i] > 0) + violation = fabs(Gp); + else + violation = fabs(Gn); + + Gmax_new = max(Gmax_new, violation); + Gnorm1_new += violation; + + // obtain Newton direction d + if(Gp < H*beta[i]) + d = -Gp/H; + else if(Gn > H*beta[i]) + d = -Gn/H; + else + d = -beta[i]; + + if(fabs(d) < 1.0e-12) + continue; + + double beta_old = beta[i]; + beta[i] = min(max(beta[i]+d, -upper_bound[GETI(i)]), upper_bound[GETI(i)]); + d = beta[i]-beta_old; + + if(d != 0) + { + xi = prob->x[i]; + while(xi->index != -1) + { + w[xi->index-1] += d*xi->value; + xi++; + } + } + } + + if(iter == 0) + Gnorm1_init = Gnorm1_new; + iter++; + if(iter % 10 == 0) + info("."); + + if(Gnorm1_new <= eps*Gnorm1_init) + { + if(active_size == l) + break; + else + { + active_size = l; + info("*"); + Gmax_old = INF; + continue; + } + } + + Gmax_old = Gmax_new; + } + + info("\noptimization finished, #iter = %d\n", iter); + if(iter >= max_iter) + info("\nWARNING: reaching max number of iterations\nUsing -s 11 may be faster\n\n"); + + // calculate objective value + double v = 0; + int nSV = 0; + for(i=0; il; + int w_size = prob->n; + int i, s, iter = 0; + double *xTx = new double[l]; + int max_iter = 1000; + int *index = new int[l]; + double *alpha = new double[2*l]; // store alpha and C - alpha + schar *y = new schar[l]; + int max_inner_iter = 100; // for inner Newton + double innereps = 1e-2; + double innereps_min = min(1e-8, eps); + double upper_bound[3] = {Cn, 0, Cp}; + + for(i=0; iy[i] > 0) + { + y[i] = +1; + } + else + { + y[i] = -1; + } + } + + // Initial alpha can be set here. Note that + // 0 < alpha[i] < upper_bound[GETI(i)] + // alpha[2*i] + alpha[2*i+1] = upper_bound[GETI(i)] + for(i=0; ix[i]; + while (xi->index != -1) + { + double val = xi->value; + xTx[i] += val*val; + w[xi->index-1] += y[i]*alpha[2*i]*val; + xi++; + } + index[i] = i; + } + + while (iter < max_iter) + { + for (i=0; ix[i]; + while (xi->index != -1) + { + ywTx += w[xi->index-1]*xi->value; + xi++; + } + ywTx *= y[i]; + double a = xisq, b = ywTx; + + // Decide to minimize g_1(z) or g_2(z) + int ind1 = 2*i, ind2 = 2*i+1, sign = 1; + if(0.5*a*(alpha[ind2]-alpha[ind1])+b < 0) + { + ind1 = 2*i+1; + ind2 = 2*i; + sign = -1; + } + + // g_t(z) = z*log(z) + (C-z)*log(C-z) + 0.5a(z-alpha_old)^2 + sign*b(z-alpha_old) + double alpha_old = alpha[ind1]; + double z = alpha_old; + if(C - z < 0.5 * C) + z = 0.1*z; + double gp = a*(z-alpha_old)+sign*b+log(z/(C-z)); + Gmax = max(Gmax, fabs(gp)); + + // Newton method on the sub-problem + const double eta = 0.1; // xi in the paper + int inner_iter = 0; + while (inner_iter <= max_inner_iter) + { + if(fabs(gp) < innereps) + break; + double gpp = a + C/(C-z)/z; + double tmpz = z - gp/gpp; + if(tmpz <= 0) + z *= eta; + else // tmpz in (0, C) + z = tmpz; + gp = a*(z-alpha_old)+sign*b+log(z/(C-z)); + newton_iter++; + inner_iter++; + } + + if(inner_iter > 0) // update w + { + alpha[ind1] = z; + alpha[ind2] = C-z; + xi = prob->x[i]; + while (xi->index != -1) + { + w[xi->index-1] += sign*(z-alpha_old)*yi*xi->value; + xi++; + } + } + } + + iter++; + if(iter % 10 == 0) + info("."); + + if(Gmax < eps) + break; + + if(newton_iter <= l/10) + innereps = max(innereps_min, 0.1*innereps); + + } + + info("\noptimization finished, #iter = %d\n",iter); + if (iter >= max_iter) + info("\nWARNING: reaching max number of iterations\nUsing -s 0 may be faster (also see FAQ)\n\n"); + + // calculate objective value + + double v = 0; + for(i=0; il; + int w_size = prob_col->n; + int j, s, iter = 0; + int max_iter = 1000; + int active_size = w_size; + int max_num_linesearch = 20; + + double sigma = 0.01; + double d, G_loss, G, H; + double Gmax_old = INF; + double Gmax_new, Gnorm1_new; + double Gnorm1_init; + double d_old, d_diff; + double loss_old, loss_new; + double appxcond, cond; + + int *index = new int[w_size]; + schar *y = new schar[l]; + double *b = new double[l]; // b = 1-ywTx + double *xj_sq = new double[w_size]; + feature_node *x; + + double C[3] = {Cn,0,Cp}; + + // Initial w can be set here. + for(j=0; jy[j] > 0) + y[j] = 1; + else + y[j] = -1; + } + for(j=0; jx[j]; + while(x->index != -1) + { + int ind = x->index-1; + x->value *= y[ind]; // x->value stores yi*xij + double val = x->value; + b[ind] -= w[j]*val; + xj_sq[j] += C[GETI(ind)]*val*val; + x++; + } + } + + while(iter < max_iter) + { + Gmax_new = 0; + Gnorm1_new = 0; + + for(j=0; jx[j]; + while(x->index != -1) + { + int ind = x->index-1; + if(b[ind] > 0) + { + double val = x->value; + double tmp = C[GETI(ind)]*val; + G_loss -= tmp*b[ind]; + H += tmp*val; + } + x++; + } + G_loss *= 2; + + G = G_loss; + H *= 2; + H = max(H, 1e-12); + + double Gp = G+1; + double Gn = G-1; + double violation = 0; + if(w[j] == 0) + { + if(Gp < 0) + violation = -Gp; + else if(Gn > 0) + violation = Gn; + else if(Gp>Gmax_old/l && Gn<-Gmax_old/l) + { + active_size--; + swap(index[s], index[active_size]); + s--; + continue; + } + } + else if(w[j] > 0) + violation = fabs(Gp); + else + violation = fabs(Gn); + + Gmax_new = max(Gmax_new, violation); + Gnorm1_new += violation; + + // obtain Newton direction d + if(Gp < H*w[j]) + d = -Gp/H; + else if(Gn > H*w[j]) + d = -Gn/H; + else + d = -w[j]; + + if(fabs(d) < 1.0e-12) + continue; + + double delta = fabs(w[j]+d)-fabs(w[j]) + G*d; + d_old = 0; + int num_linesearch; + for(num_linesearch=0; num_linesearch < max_num_linesearch; num_linesearch++) + { + d_diff = d_old - d; + cond = fabs(w[j]+d)-fabs(w[j]) - sigma*delta; + + appxcond = xj_sq[j]*d*d + G_loss*d + cond; + if(appxcond <= 0) + { + x = prob_col->x[j]; + while(x->index != -1) + { + b[x->index-1] += d_diff*x->value; + x++; + } + break; + } + + if(num_linesearch == 0) + { + loss_old = 0; + loss_new = 0; + x = prob_col->x[j]; + while(x->index != -1) + { + int ind = x->index-1; + if(b[ind] > 0) + loss_old += C[GETI(ind)]*b[ind]*b[ind]; + double b_new = b[ind] + d_diff*x->value; + b[ind] = b_new; + if(b_new > 0) + loss_new += C[GETI(ind)]*b_new*b_new; + x++; + } + } + else + { + loss_new = 0; + x = prob_col->x[j]; + while(x->index != -1) + { + int ind = x->index-1; + double b_new = b[ind] + d_diff*x->value; + b[ind] = b_new; + if(b_new > 0) + loss_new += C[GETI(ind)]*b_new*b_new; + x++; + } + } + + cond = cond + loss_new - loss_old; + if(cond <= 0) + break; + else + { + d_old = d; + d *= 0.5; + delta *= 0.5; + } + } + + w[j] += d; + + // recompute b[] if line search takes too many steps + if(num_linesearch >= max_num_linesearch) + { + info("#"); + for(int i=0; ix[i]; + while(x->index != -1) + { + b[x->index-1] -= w[i]*x->value; + x++; + } + } + } + } + + if(iter == 0) + Gnorm1_init = Gnorm1_new; + iter++; + if(iter % 10 == 0) + info("."); + + if(Gnorm1_new <= eps*Gnorm1_init) + { + if(active_size == w_size) + break; + else + { + active_size = w_size; + info("*"); + Gmax_old = INF; + continue; + } + } + + Gmax_old = Gmax_new; + } + + info("\noptimization finished, #iter = %d\n", iter); + if(iter >= max_iter) + info("\nWARNING: reaching max number of iterations\n"); + + // calculate objective value + + double v = 0; + int nnz = 0; + for(j=0; jx[j]; + while(x->index != -1) + { + x->value *= prob_col->y[x->index-1]; // restore x->value + x++; + } + if(w[j] != 0) + { + v += fabs(w[j]); + nnz++; + } + } + for(j=0; j 0) + v += C[GETI(j)]*b[j]*b[j]; + + info("Objective value = %lf\n", v); + info("#nonzeros/#features = %d/%d\n", nnz, w_size); + + delete [] index; + delete [] y; + delete [] b; + delete [] xj_sq; +} + +// A coordinate descent algorithm for +// L1-regularized logistic regression problems +// +// min_w \sum |wj| + C \sum log(1+exp(-yi w^T xi)), +// +// Given: +// x, y, Cp, Cn +// eps is the stopping tolerance +// +// solution will be put in w +// +// See Yuan et al. (2011) and appendix of LIBLINEAR paper, Fan et al. (2008) + +#undef GETI +#define GETI(i) (y[i]+1) +// To support weights for instances, use GETI(i) (i) + +static void solve_l1r_lr( + const problem *prob_col, double *w, double eps, + double Cp, double Cn) +{ + int l = prob_col->l; + int w_size = prob_col->n; + int j, s, newton_iter=0, iter=0; + int max_newton_iter = 100; + int max_iter = 1000; + int max_num_linesearch = 20; + int active_size; + int QP_active_size; + + double nu = 1e-12; + double inner_eps = 1; + double sigma = 0.01; + double w_norm, w_norm_new; + double z, G, H; + double Gnorm1_init; + double Gmax_old = INF; + double Gmax_new, Gnorm1_new; + double QP_Gmax_old = INF; + double QP_Gmax_new, QP_Gnorm1_new; + double delta, negsum_xTd, cond; + + int *index = new int[w_size]; + schar *y = new schar[l]; + double *Hdiag = new double[w_size]; + double *Grad = new double[w_size]; + double *wpd = new double[w_size]; + double *xjneg_sum = new double[w_size]; + double *xTd = new double[l]; + double *exp_wTx = new double[l]; + double *exp_wTx_new = new double[l]; + double *tau = new double[l]; + double *D = new double[l]; + feature_node *x; + + double C[3] = {Cn,0,Cp}; + + // Initial w can be set here. + for(j=0; jy[j] > 0) + y[j] = 1; + else + y[j] = -1; + + exp_wTx[j] = 0; + } + + w_norm = 0; + for(j=0; jx[j]; + while(x->index != -1) + { + int ind = x->index-1; + double val = x->value; + exp_wTx[ind] += w[j]*val; + if(y[ind] == -1) + xjneg_sum[j] += C[GETI(ind)]*val; + x++; + } + } + for(j=0; jx[j]; + while(x->index != -1) + { + int ind = x->index-1; + Hdiag[j] += x->value*x->value*D[ind]; + tmp += x->value*tau[ind]; + x++; + } + Grad[j] = -tmp + xjneg_sum[j]; + + double Gp = Grad[j]+1; + double Gn = Grad[j]-1; + double violation = 0; + if(w[j] == 0) + { + if(Gp < 0) + violation = -Gp; + else if(Gn > 0) + violation = Gn; + //outer-level shrinking + else if(Gp>Gmax_old/l && Gn<-Gmax_old/l) + { + active_size--; + swap(index[s], index[active_size]); + s--; + continue; + } + } + else if(w[j] > 0) + violation = fabs(Gp); + else + violation = fabs(Gn); + + Gmax_new = max(Gmax_new, violation); + Gnorm1_new += violation; + } + + if(newton_iter == 0) + Gnorm1_init = Gnorm1_new; + + if(Gnorm1_new <= eps*Gnorm1_init) + break; + + iter = 0; + QP_Gmax_old = INF; + QP_active_size = active_size; + + for(int i=0; ix[j]; + G = Grad[j] + (wpd[j]-w[j])*nu; + while(x->index != -1) + { + int ind = x->index-1; + G += x->value*D[ind]*xTd[ind]; + x++; + } + + double Gp = G+1; + double Gn = G-1; + double violation = 0; + if(wpd[j] == 0) + { + if(Gp < 0) + violation = -Gp; + else if(Gn > 0) + violation = Gn; + //inner-level shrinking + else if(Gp>QP_Gmax_old/l && Gn<-QP_Gmax_old/l) + { + QP_active_size--; + swap(index[s], index[QP_active_size]); + s--; + continue; + } + } + else if(wpd[j] > 0) + violation = fabs(Gp); + else + violation = fabs(Gn); + + QP_Gmax_new = max(QP_Gmax_new, violation); + QP_Gnorm1_new += violation; + + // obtain solution of one-variable problem + if(Gp < H*wpd[j]) + z = -Gp/H; + else if(Gn > H*wpd[j]) + z = -Gn/H; + else + z = -wpd[j]; + + if(fabs(z) < 1.0e-12) + continue; + z = min(max(z,-10.0),10.0); + + wpd[j] += z; + + x = prob_col->x[j]; + while(x->index != -1) + { + int ind = x->index-1; + xTd[ind] += x->value*z; + x++; + } + } + + iter++; + + if(QP_Gnorm1_new <= inner_eps*Gnorm1_init) + { + //inner stopping + if(QP_active_size == active_size) + break; + //active set reactivation + else + { + QP_active_size = active_size; + QP_Gmax_old = INF; + continue; + } + } + + QP_Gmax_old = QP_Gmax_new; + } + + if(iter >= max_iter) + info("WARNING: reaching max number of inner iterations\n"); + + delta = 0; + w_norm_new = 0; + for(j=0; j= max_num_linesearch) + { + for(int i=0; ix[i]; + while(x->index != -1) + { + exp_wTx[x->index-1] += w[i]*x->value; + x++; + } + } + + for(int i=0; i= max_newton_iter) + info("WARNING: reaching max number of iterations\n"); + + // calculate objective value + + double v = 0; + int nnz = 0; + for(j=0; jl; + int n = prob->n; + int nnz = 0; + int *col_ptr = new int[n+1]; + feature_node *x_space; + prob_col->l = l; + prob_col->n = n; + prob_col->y = new double[l]; + prob_col->x = new feature_node*[n]; + + for(i=0; iy[i] = prob->y[i]; + + for(i=0; ix[i]; + while(x->index != -1) + { + nnz++; + col_ptr[x->index]++; + x++; + } + } + for(i=1; ix[i] = &x_space[col_ptr[i]]; + + for(i=0; ix[i]; + while(x->index != -1) + { + int ind = x->index-1; + x_space[col_ptr[ind]].index = i+1; // starts from 1 + x_space[col_ptr[ind]].value = x->value; + col_ptr[ind]++; + x++; + } + } + for(i=0; il; + int max_nr_class = 16; + int nr_class = 0; + int *label = Malloc(int,max_nr_class); + int *count = Malloc(int,max_nr_class); + int *data_label = Malloc(int,l); + int i; + + for(i=0;iy[i]; + int j; + for(j=0;jeps; + int pos = 0; + int neg = 0; + for(int i=0;il;i++) + if(prob->y[i] > 0) + pos++; + neg = prob->l - pos; + + double primal_solver_tol = eps*max(min(pos,neg), 1)/prob->l; + + function *fun_obj=NULL; + switch(param->solver_type) + { + case L2R_LR: + { + double *C = new double[prob->l]; + for(int i = 0; i < prob->l; i++) + { + if(prob->y[i] > 0) + C[i] = Cp; + else + C[i] = Cn; + } + fun_obj=new l2r_lr_fun(prob, C); + TRON tron_obj(fun_obj, primal_solver_tol); + tron_obj.set_print_string(liblinear_print_string); + tron_obj.tron(w); + delete fun_obj; + delete C; + break; + } + case L2R_L2LOSS_SVC: + { + double *C = new double[prob->l]; + for(int i = 0; i < prob->l; i++) + { + if(prob->y[i] > 0) + C[i] = Cp; + else + C[i] = Cn; + } + fun_obj=new l2r_l2_svc_fun(prob, C); + TRON tron_obj(fun_obj, primal_solver_tol); + tron_obj.set_print_string(liblinear_print_string); + tron_obj.tron(w); + delete fun_obj; + delete C; + break; + } + case L2R_L2LOSS_SVC_DUAL: + solve_l2r_l1l2_svc(prob, w, eps, Cp, Cn, L2R_L2LOSS_SVC_DUAL); + break; + case L2R_L1LOSS_SVC_DUAL: + solve_l2r_l1l2_svc(prob, w, eps, Cp, Cn, L2R_L1LOSS_SVC_DUAL); + break; + case L1R_L2LOSS_SVC: + { + problem prob_col; + feature_node *x_space = NULL; + transpose(prob, &x_space ,&prob_col); + solve_l1r_l2_svc(&prob_col, w, primal_solver_tol, Cp, Cn); + delete [] prob_col.y; + delete [] prob_col.x; + delete [] x_space; + break; + } + case L1R_LR: + { + problem prob_col; + feature_node *x_space = NULL; + transpose(prob, &x_space ,&prob_col); + solve_l1r_lr(&prob_col, w, primal_solver_tol, Cp, Cn); + delete [] prob_col.y; + delete [] prob_col.x; + delete [] x_space; + break; + } + case L2R_LR_DUAL: + solve_l2r_lr_dual(prob, w, eps, Cp, Cn); + break; + case L2R_L2LOSS_SVR: + { + double *C = new double[prob->l]; + for(int i = 0; i < prob->l; i++) + C[i] = param->C; + + fun_obj=new l2r_l2_svr_fun(prob, C, param->p); + TRON tron_obj(fun_obj, param->eps); + tron_obj.set_print_string(liblinear_print_string); + tron_obj.tron(w); + delete fun_obj; + delete C; + break; + + } + case L2R_L1LOSS_SVR_DUAL: + solve_l2r_l1l2_svr(prob, w, param, L2R_L1LOSS_SVR_DUAL); + break; + case L2R_L2LOSS_SVR_DUAL: + solve_l2r_l1l2_svr(prob, w, param, L2R_L2LOSS_SVR_DUAL); + break; + default: + fprintf(stderr, "ERROR: unknown solver_type\n"); + break; + } +} + +// +// Interface functions +// +model* train(const problem *prob, const parameter *param) +{ + int i,j; + int l = prob->l; + int n = prob->n; + int w_size = prob->n; + model *model_ = Malloc(model,1); + + if(prob->bias>=0) + model_->nr_feature=n-1; + else + model_->nr_feature=n; + model_->param = *param; + model_->bias = prob->bias; + + if(param->solver_type == L2R_L2LOSS_SVR || + param->solver_type == L2R_L1LOSS_SVR_DUAL || + param->solver_type == L2R_L2LOSS_SVR_DUAL) + { + model_->w = Malloc(double, w_size); + model_->nr_class = 2; + model_->label = NULL; + train_one(prob, param, &model_->w[0], 0, 0); + } + else + { + int nr_class; + int *label = NULL; + int *start = NULL; + int *count = NULL; + int *perm = Malloc(int,l); + + // group training data of the same class + group_classes(prob,&nr_class,&label,&start,&count,perm); + + model_->nr_class=nr_class; + model_->label = Malloc(int,nr_class); + for(i=0;ilabel[i] = label[i]; + + // calculate weighted C + double *weighted_C = Malloc(double, nr_class); + for(i=0;iC; + for(i=0;inr_weight;i++) + { + for(j=0;jweight_label[i] == label[j]) + break; + if(j == nr_class) + fprintf(stderr,"WARNING: class label %d specified in weight is not found\n", param->weight_label[i]); + else + weighted_C[j] *= param->weight[i]; + } + + // constructing the subproblem + feature_node **x = Malloc(feature_node *,l); + for(i=0;ix[perm[i]]; + + int k; + problem sub_prob; + sub_prob.l = l; + sub_prob.n = n; + sub_prob.x = Malloc(feature_node *,sub_prob.l); + sub_prob.y = Malloc(double,sub_prob.l); + + for(k=0; ksolver_type == MCSVM_CS) + { + model_->w=Malloc(double, n*nr_class); + for(i=0;ieps); + Solver.Solve(model_->w); + } + else + { + if(nr_class == 2) + { + model_->w=Malloc(double, w_size); + + int e0 = start[0]+count[0]; + k=0; + for(; kw[0], weighted_C[0], weighted_C[1]); + } + else + { + model_->w=Malloc(double, w_size*nr_class); + double *w=Malloc(double, w_size); + for(i=0;iC); + + for(int j=0;jw[j*nr_class+i] = w[j]; + } + free(w); + } + + } + + free(x); + free(label); + free(start); + free(count); + free(perm); + free(sub_prob.x); + free(sub_prob.y); + free(weighted_C); + } + return model_; +} + +void cross_validation(const problem *prob, const parameter *param, int nr_fold, double *target) +{ + int i; + int *fold_start = Malloc(int,nr_fold+1); + int l = prob->l; + int *perm = Malloc(int,l); + + for(i=0;ibias; + subprob.n = prob->n; + subprob.l = l-(end-begin); + subprob.x = Malloc(struct feature_node*,subprob.l); + subprob.y = Malloc(double,subprob.l); + + k=0; + for(j=0;jx[perm[j]]; + subprob.y[k] = prob->y[perm[j]]; + ++k; + } + for(j=end;jx[perm[j]]; + subprob.y[k] = prob->y[perm[j]]; + ++k; + } + struct model *submodel = train(&subprob,param); + for(j=begin;jx[perm[j]]); + free_and_destroy_model(&submodel); + free(subprob.x); + free(subprob.y); + } + free(fold_start); + free(perm); +} + +double predict_values(const struct model *model_, const struct feature_node *x, double *dec_values) +{ + int idx; + int n; + if(model_->bias>=0) + n=model_->nr_feature+1; + else + n=model_->nr_feature; + double *w=model_->w; + int nr_class=model_->nr_class; + int i; + int nr_w; + if(nr_class==2 && model_->param.solver_type != MCSVM_CS) + nr_w = 1; + else + nr_w = nr_class; + + const feature_node *lx=x; + for(i=0;iindex)!=-1; lx++) + { + // the dimension of testing data may exceed that of training + if(idx<=n) + for(i=0;ivalue; + } + + if(nr_class==2) + { + if(model_->param.solver_type == L2R_L2LOSS_SVR || + model_->param.solver_type == L2R_L1LOSS_SVR_DUAL || + model_->param.solver_type == L2R_L2LOSS_SVR_DUAL) + return dec_values[0]; + else + return (dec_values[0]>0)?model_->label[0]:model_->label[1]; + } + else + { + int dec_max_idx = 0; + for(i=1;i dec_values[dec_max_idx]) + dec_max_idx = i; + } + return model_->label[dec_max_idx]; + } +} + +double predict(const model *model_, const feature_node *x) +{ + double *dec_values = Malloc(double, model_->nr_class); + double label=predict_values(model_, x, dec_values); + free(dec_values); + return label; +} + +double predict_probability(const struct model *model_, const struct feature_node *x, double* prob_estimates) +{ + if(check_probability_model(model_)) + { + int i; + int nr_class=model_->nr_class; + int nr_w; + if(nr_class==2) + nr_w = 1; + else + nr_w = nr_class; + + double label=predict_values(model_, x, prob_estimates); + for(i=0;inr_feature; + int n; + const parameter& param = model_->param; + + if(model_->bias>=0) + n=nr_feature+1; + else + n=nr_feature; + int w_size = n; + FILE *fp = fopen(model_file_name,"w"); + if(fp==NULL) return -1; + + char *old_locale = strdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, "C"); + + int nr_w; + if(model_->nr_class==2 && model_->param.solver_type != MCSVM_CS) + nr_w=1; + else + nr_w=model_->nr_class; + + fprintf(fp, "solver_type %s\n", solver_type_table[param.solver_type]); + fprintf(fp, "nr_class %d\n", model_->nr_class); + + if(model_->label) + { + fprintf(fp, "label"); + for(i=0; inr_class; i++) + fprintf(fp, " %d", model_->label[i]); + fprintf(fp, "\n"); + } + + fprintf(fp, "nr_feature %d\n", nr_feature); + + fprintf(fp, "bias %.16g\n", model_->bias); + + fprintf(fp, "w\n"); + for(i=0; iw[i*nr_w+j]); + fprintf(fp, "\n"); + } + + setlocale(LC_ALL, old_locale); + free(old_locale); + + if (ferror(fp) != 0 || fclose(fp) != 0) return -1; + else return 0; +} + +struct model *load_model(const char *model_file_name) +{ + FILE *fp = fopen(model_file_name,"r"); + if(fp==NULL) return NULL; + + int i; + int nr_feature; + int n; + int nr_class; + double bias; + model *model_ = Malloc(model,1); + parameter& param = model_->param; + + model_->label = NULL; + + char *old_locale = strdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, "C"); + + char cmd[81]; + while(1) + { + fscanf(fp,"%80s",cmd); + if(strcmp(cmd,"solver_type")==0) + { + fscanf(fp,"%80s",cmd); + int i; + for(i=0;solver_type_table[i];i++) + { + if(strcmp(solver_type_table[i],cmd)==0) + { + param.solver_type=i; + break; + } + } + if(solver_type_table[i] == NULL) + { + fprintf(stderr,"unknown solver type.\n"); + + setlocale(LC_ALL, old_locale); + free(model_->label); + free(model_); + free(old_locale); + return NULL; + } + } + else if(strcmp(cmd,"nr_class")==0) + { + fscanf(fp,"%d",&nr_class); + model_->nr_class=nr_class; + } + else if(strcmp(cmd,"nr_feature")==0) + { + fscanf(fp,"%d",&nr_feature); + model_->nr_feature=nr_feature; + } + else if(strcmp(cmd,"bias")==0) + { + fscanf(fp,"%lf",&bias); + model_->bias=bias; + } + else if(strcmp(cmd,"w")==0) + { + break; + } + else if(strcmp(cmd,"label")==0) + { + int nr_class = model_->nr_class; + model_->label = Malloc(int,nr_class); + for(int i=0;ilabel[i]); + } + else + { + fprintf(stderr,"unknown text in model file: [%s]\n",cmd); + setlocale(LC_ALL, old_locale); + free(model_->label); + free(model_); + free(old_locale); + return NULL; + } + } + + nr_feature=model_->nr_feature; + if(model_->bias>=0) + n=nr_feature+1; + else + n=nr_feature; + int w_size = n; + int nr_w; + if(nr_class==2 && param.solver_type != MCSVM_CS) + nr_w = 1; + else + nr_w = nr_class; + + model_->w=Malloc(double, w_size*nr_w); + for(i=0; iw[i*nr_w+j]); + fscanf(fp, "\n"); + } + + setlocale(LC_ALL, old_locale); + free(old_locale); + + if (ferror(fp) != 0 || fclose(fp) != 0) return NULL; + + return model_; +} + +int get_nr_feature(const model *model_) +{ + return model_->nr_feature; +} + +int get_nr_class(const model *model_) +{ + return model_->nr_class; +} + +void get_labels(const model *model_, int* label) +{ + if (model_->label != NULL) + for(int i=0;inr_class;i++) + label[i] = model_->label[i]; +} + +void free_model_content(struct model *model_ptr) +{ + if(model_ptr->w != NULL) + free(model_ptr->w); + if(model_ptr->label != NULL) + free(model_ptr->label); +} + +void free_and_destroy_model(struct model **model_ptr_ptr) +{ + struct model *model_ptr = *model_ptr_ptr; + if(model_ptr != NULL) + { + free_model_content(model_ptr); + free(model_ptr); + } +} + +void destroy_param(parameter* param) +{ + if(param->weight_label != NULL) + free(param->weight_label); + if(param->weight != NULL) + free(param->weight); +} + +const char *check_parameter(const problem *prob, const parameter *param) +{ + if(param->eps <= 0) + return "eps <= 0"; + + if(param->C <= 0) + return "C <= 0"; + + if(param->p < 0) + return "p < 0"; + + if(param->solver_type != L2R_LR + && param->solver_type != L2R_L2LOSS_SVC_DUAL + && param->solver_type != L2R_L2LOSS_SVC + && param->solver_type != L2R_L1LOSS_SVC_DUAL + && param->solver_type != MCSVM_CS + && param->solver_type != L1R_L2LOSS_SVC + && param->solver_type != L1R_LR + && param->solver_type != L2R_LR_DUAL + && param->solver_type != L2R_L2LOSS_SVR + && param->solver_type != L2R_L2LOSS_SVR_DUAL + && param->solver_type != L2R_L1LOSS_SVR_DUAL) + return "unknown solver type"; + + return NULL; +} + +int check_probability_model(const struct model *model_) +{ + return (model_->param.solver_type==L2R_LR || + model_->param.solver_type==L2R_LR_DUAL || + model_->param.solver_type==L1R_LR); +} + +void set_print_string_function(void (*print_func)(const char*)) +{ + if (print_func == NULL) + liblinear_print_string = &print_string_stdout; + else + liblinear_print_string = print_func; +} + diff --git a/Bing/Src/LibLinear/linear.h b/Bing/Src/LibLinear/linear.h new file mode 100644 index 000000000..22a356743 --- /dev/null +++ b/Bing/Src/LibLinear/linear.h @@ -0,0 +1,74 @@ +#ifndef _LIBLINEAR_H +#define _LIBLINEAR_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct feature_node +{ + int index; + double value; +}; + +struct problem +{ + int l, n; + double *y; + struct feature_node **x; + double bias; /* < 0 if no bias term */ +}; + +enum { L2R_LR, L2R_L2LOSS_SVC_DUAL, L2R_L2LOSS_SVC, L2R_L1LOSS_SVC_DUAL, MCSVM_CS, L1R_L2LOSS_SVC, L1R_LR, L2R_LR_DUAL, L2R_L2LOSS_SVR = 11, L2R_L2LOSS_SVR_DUAL, L2R_L1LOSS_SVR_DUAL }; /* solver_type */ + +struct parameter +{ + int solver_type; + + /* these are for training only */ + double eps; /* stopping criteria */ + double C; + int nr_weight; + int *weight_label; + double* weight; + double p; +}; + +struct model +{ + struct parameter param; + int nr_class; /* number of classes */ + int nr_feature; + double *w; + int *label; /* label of each class */ + double bias; +}; + +struct model* train(const struct problem *prob, const struct parameter *param); +void cross_validation(const struct problem *prob, const struct parameter *param, int nr_fold, double *target); + +double predict_values(const struct model *model_, const struct feature_node *x, double* dec_values); +double predict(const struct model *model_, const struct feature_node *x); +double predict_probability(const struct model *model_, const struct feature_node *x, double* prob_estimates); + +int save_model(const char *model_file_name, const struct model *model_); +struct model *load_model(const char *model_file_name); + +int get_nr_feature(const struct model *model_); +int get_nr_class(const struct model *model_); +void get_labels(const struct model *model_, int* label); + +void free_model_content(struct model *model_ptr); +void free_and_destroy_model(struct model **model_ptr_ptr); +void destroy_param(struct parameter *param); + +const char *check_parameter(const struct problem *prob, const struct parameter *param); +int check_probability_model(const struct model *model); +void set_print_string_function(void (*print_func) (const char*)); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBLINEAR_H */ + diff --git a/Bing/Src/LibLinear/train.c b/Bing/Src/LibLinear/train.c new file mode 100644 index 000000000..858229dab --- /dev/null +++ b/Bing/Src/LibLinear/train.c @@ -0,0 +1,401 @@ +#include +#include +#include +#include +#include +#include +#include "linear.h" +#define Malloc(type,n) (type *)malloc((n)*sizeof(type)) +#define INF HUGE_VAL + +#pragma warning(disable:4996) + +void print_null(const char *s) {} + +void exit_with_help() +{ + printf( + "Usage: train [options] training_set_file [model_file]\n" + "options:\n" + "-s type : set type of solver (default 1)\n" + " for multi-class classification\n" + " 0 -- L2-regularized logistic regression (primal)\n" + " 1 -- L2-regularized L2-loss support vector classification (dual)\n" + " 2 -- L2-regularized L2-loss support vector classification (primal)\n" + " 3 -- L2-regularized L1-loss support vector classification (dual)\n" + " 4 -- support vector classification by Crammer and Singer\n" + " 5 -- L1-regularized L2-loss support vector classification\n" + " 6 -- L1-regularized logistic regression\n" + " 7 -- L2-regularized logistic regression (dual)\n" + " for regression\n" + " 11 -- L2-regularized L2-loss support vector regression (primal)\n" + " 12 -- L2-regularized L2-loss support vector regression (dual)\n" + " 13 -- L2-regularized L1-loss support vector regression (dual)\n" + "-c cost : set the parameter C (default 1)\n" + "-p epsilon : set the epsilon in loss function of SVR (default 0.1)\n" + "-e epsilon : set tolerance of termination criterion\n" + " -s 0 and 2\n" + " |f'(w)|_2 <= eps*min(pos,neg)/l*|f'(w0)|_2,\n" + " where f is the primal function and pos/neg are # of\n" + " positive/negative data (default 0.01)\n" + " -s 11\n" + " |f'(w)|_2 <= eps*|f'(w0)|_2 (default 0.001)\n" + " -s 1, 3, 4, and 7\n" + " Dual maximal violation <= eps; similar to libsvm (default 0.1)\n" + " -s 5 and 6\n" + " |f'(w)|_1 <= eps*min(pos,neg)/l*|f'(w0)|_1,\n" + " where f is the primal function (default 0.01)\n" + " -s 12 and 13\n" + " |f'(alpha)|_1 <= eps |f'(alpha0)|,\n" + " where f is the dual function (default 0.1)\n" + "-B bias : if bias >= 0, instance x becomes [x; bias]; if < 0, no bias term added (default -1)\n" + "-wi weight: weights adjust the parameter C of different classes (see README for details)\n" + "-v n: n-fold cross validation mode\n" + "-q : quiet mode (no outputs)\n" + ); + exit(1); +} + +void exit_input_error(int line_num) +{ + fprintf(stderr,"Wrong input format at line %d\n", line_num); + exit(1); +} + +static char *line = NULL; +static int max_line_len; + +static char* readline(FILE *input) +{ + int len; + + if(fgets(line,max_line_len,input) == NULL) + return NULL; + + while(strrchr(line,'\n') == NULL) + { + max_line_len *= 2; + line = (char *) realloc(line,max_line_len); + len = (int) strlen(line); + if(fgets(line+len,max_line_len-len,input) == NULL) + break; + } + return line; +} + +void parse_command_line(int argc, char **argv, char *input_file_name, char *model_file_name); +void read_problem(const char *filename); +void do_cross_validation(); + +struct feature_node *x_space; +struct parameter param; +struct problem prob; +struct model* model_; +int flag_cross_validation; +int nr_fold; +double bias; + +int main(int argc, char **argv) +{ + char input_file_name[1024]; + char model_file_name[1024]; + const char *error_msg; + + parse_command_line(argc, argv, input_file_name, model_file_name); + read_problem(input_file_name); + error_msg = check_parameter(&prob,¶m); + + if(error_msg) + { + fprintf(stderr,"ERROR: %s\n",error_msg); + exit(1); + } + + if(flag_cross_validation) + { + do_cross_validation(); + } + else + { + model_=train(&prob, ¶m); + if(save_model(model_file_name, model_)) + { + fprintf(stderr,"can't save model to file %s\n",model_file_name); + exit(1); + } + free_and_destroy_model(&model_); + } + destroy_param(¶m); + free(prob.y); + free(prob.x); + free(x_space); + free(line); + + return 0; +} + +void do_cross_validation() +{ + int i; + int total_correct = 0; + double total_error = 0; + double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0; + double *target = Malloc(double, prob.l); + + cross_validation(&prob,¶m,nr_fold,target); + if(param.solver_type == L2R_L2LOSS_SVR || + param.solver_type == L2R_L1LOSS_SVR_DUAL || + param.solver_type == L2R_L2LOSS_SVR_DUAL) + { + for(i=0;i=argc) + exit_with_help(); + switch(argv[i-1][1]) + { + case 's': + param.solver_type = atoi(argv[i]); + break; + + case 'c': + param.C = atof(argv[i]); + break; + + case 'p': + param.p = atof(argv[i]); + break; + + case 'e': + param.eps = atof(argv[i]); + break; + + case 'B': + bias = atof(argv[i]); + break; + + case 'w': + ++param.nr_weight; + param.weight_label = (int *) realloc(param.weight_label,sizeof(int)*param.nr_weight); + param.weight = (double *) realloc(param.weight,sizeof(double)*param.nr_weight); + param.weight_label[param.nr_weight-1] = atoi(&argv[i-1][2]); + param.weight[param.nr_weight-1] = atof(argv[i]); + break; + + case 'v': + flag_cross_validation = 1; + nr_fold = atoi(argv[i]); + if(nr_fold < 2) + { + fprintf(stderr,"n-fold cross validation: n must >= 2\n"); + exit_with_help(); + } + break; + + case 'q': + print_func = &print_null; + i--; + break; + + default: + fprintf(stderr,"unknown option: -%c\n", argv[i-1][1]); + exit_with_help(); + break; + } + } + + set_print_string_function(print_func); + + // determine filenames + if(i>=argc) + exit_with_help(); + + strcpy(input_file_name, argv[i]); + + if(i max_index) + max_index = inst_max_index; + + if(prob.bias >= 0) + x_space[j++].value = prob.bias; + + x_space[j++].index = -1; + } + + if(prob.bias >= 0) + { + prob.n=max_index+1; + for(i=1;iindex = prob.n; + x_space[j-2].index = prob.n; + } + else + prob.n=max_index; + + fclose(fp); +} diff --git a/Bing/Src/LibLinear/tron.cpp b/Bing/Src/LibLinear/tron.cpp new file mode 100644 index 000000000..b54bedf18 --- /dev/null +++ b/Bing/Src/LibLinear/tron.cpp @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include "tron.h" + +#ifndef min +template static inline T min(T x,T y) { return (x static inline T max(T x,T y) { return (x>y)?x:y; } +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern double dnrm2_(int *, double *, int *); +extern double ddot_(int *, double *, int *, double *, int *); +extern int daxpy_(int *, double *, double *, int *, double *, int *); +extern int dscal_(int *, double *, double *, int *); + +#ifdef __cplusplus +} +#endif + +static void default_print(const char *buf) +{ + fputs(buf,stdout); + fflush(stdout); +} + +void TRON::info(const char *fmt,...) +{ + char buf[BUFSIZ]; + va_list ap; + va_start(ap,fmt); + vsprintf(buf,fmt,ap); + va_end(ap); + (*tron_print_string)(buf); +} + +TRON::TRON(const function *fun_obj, double eps, int max_iter) +{ + this->fun_obj=const_cast(fun_obj); + this->eps=eps; + this->max_iter=max_iter; + tron_print_string = default_print; +} + +TRON::~TRON() +{ +} + +void TRON::tron(double *w) +{ + // Parameters for updating the iterates. + double eta0 = 1e-4, eta1 = 0.25, eta2 = 0.75; + + // Parameters for updating the trust region size delta. + double sigma1 = 0.25, sigma2 = 0.5, sigma3 = 4; + + int n = fun_obj->get_nr_variable(); + int i, cg_iter; + double delta, snorm, one=1.0; + double alpha, f, fnew, prered, actred, gs; + int search = 1, iter = 1, inc = 1; + double *s = new double[n]; + double *r = new double[n]; + double *w_new = new double[n]; + double *g = new double[n]; + + for (i=0; ifun(w); + fun_obj->grad(w, g); + delta = dnrm2_(&n, g, &inc); + double gnorm1 = delta; + double gnorm = gnorm1; + + if (gnorm <= eps*gnorm1) + search = 0; + + iter = 1; + + while (iter <= max_iter && search) + { + cg_iter = trcg(delta, g, s, r); + + memcpy(w_new, w, sizeof(double)*n); + daxpy_(&n, &one, s, &inc, w_new, &inc); + + gs = ddot_(&n, g, &inc, s, &inc); + prered = -0.5*(gs-ddot_(&n, s, &inc, r, &inc)); + fnew = fun_obj->fun(w_new); + + // Compute the actual reduction. + actred = f - fnew; + + // On the first iteration, adjust the initial step bound. + snorm = dnrm2_(&n, s, &inc); + if (iter == 1) + delta = min(delta, snorm); + + // Compute prediction alpha*snorm of the step. + if (fnew - f - gs <= 0) + alpha = sigma3; + else + alpha = max(sigma1, -0.5*(gs/(fnew - f - gs))); + + // Update the trust region bound according to the ratio of actual to predicted reduction. + if (actred < eta0*prered) + delta = min(max(alpha, sigma1)*snorm, sigma2*delta); + else if (actred < eta1*prered) + delta = max(sigma1*delta, min(alpha*snorm, sigma2*delta)); + else if (actred < eta2*prered) + delta = max(sigma1*delta, min(alpha*snorm, sigma3*delta)); + else + delta = max(delta, min(alpha*snorm, sigma3*delta)); + + info("iter %2d act %5.3e pre %5.3e delta %5.3e f %5.3e |g| %5.3e CG %3d\n", iter, actred, prered, delta, f, gnorm, cg_iter); + + if (actred > eta0*prered) + { + iter++; + memcpy(w, w_new, sizeof(double)*n); + f = fnew; + fun_obj->grad(w, g); + + gnorm = dnrm2_(&n, g, &inc); + if (gnorm <= eps*gnorm1) + break; + } + if (f < -1.0e+32) + { + info("WARNING: f < -1.0e+32\n"); + break; + } + if (fabs(actred) <= 0 && prered <= 0) + { + info("WARNING: actred and prered <= 0\n"); + break; + } + if (fabs(actred) <= 1.0e-12*fabs(f) && + fabs(prered) <= 1.0e-12*fabs(f)) + { + info("WARNING: actred and prered too small\n"); + break; + } + } + + delete[] g; + delete[] r; + delete[] w_new; + delete[] s; +} + +int TRON::trcg(double delta, double *g, double *s, double *r) +{ + int i, inc = 1; + int n = fun_obj->get_nr_variable(); + double one = 1; + double *d = new double[n]; + double *Hd = new double[n]; + double rTr, rnewTrnew, alpha, beta, cgtol; + + for (i=0; iHv(d, Hd); + + alpha = rTr/ddot_(&n, d, &inc, Hd, &inc); + daxpy_(&n, &alpha, d, &inc, s, &inc); + if (dnrm2_(&n, s, &inc) > delta) + { + info("cg reaches trust region boundary\n"); + alpha = -alpha; + daxpy_(&n, &alpha, d, &inc, s, &inc); + + double std = ddot_(&n, s, &inc, d, &inc); + double sts = ddot_(&n, s, &inc, s, &inc); + double dtd = ddot_(&n, d, &inc, d, &inc); + double dsq = delta*delta; + double rad = sqrt(std*std + dtd*(dsq-sts)); + if (std >= 0) + alpha = (dsq - sts)/(std + rad); + else + alpha = (rad - std)/dtd; + daxpy_(&n, &alpha, d, &inc, s, &inc); + alpha = -alpha; + daxpy_(&n, &alpha, Hd, &inc, r, &inc); + break; + } + alpha = -alpha; + daxpy_(&n, &alpha, Hd, &inc, r, &inc); + rnewTrnew = ddot_(&n, r, &inc, r, &inc); + beta = rnewTrnew/rTr; + dscal_(&n, &beta, d, &inc); + daxpy_(&n, &one, r, &inc, d, &inc); + rTr = rnewTrnew; + } + + delete[] d; + delete[] Hd; + + return(cg_iter); +} + +double TRON::norm_inf(int n, double *x) +{ + double dmax = fabs(x[0]); + for (int i=1; i= dmax) + dmax = fabs(x[i]); + return(dmax); +} + +void TRON::set_print_string(void (*print_string) (const char *buf)) +{ + tron_print_string = print_string; +} diff --git a/Bing/Src/LibLinear/tron.h b/Bing/Src/LibLinear/tron.h new file mode 100644 index 000000000..4fe34a5c6 --- /dev/null +++ b/Bing/Src/LibLinear/tron.h @@ -0,0 +1,36 @@ +#ifndef _TRON_H +#define _TRON_H + +#pragma warning(disable:4996) + +class function +{ +public: + virtual double fun(double *w) = 0 ; + virtual void grad(double *w, double *g) = 0 ; + virtual void Hv(double *s, double *Hs) = 0 ; + + virtual int get_nr_variable(void) = 0 ; + virtual ~function(void){} +}; + +class TRON +{ +public: + TRON(const function *fun_obj, double eps = 0.1, int max_iter = 1000); + ~TRON(); + + void tron(double *w); + void set_print_string(void (*i_print) (const char *buf)); + +private: + int trcg(double delta, double *g, double *s, double *r); + double norm_inf(int n, double *x); + + double eps; + int max_iter; + function *fun_obj; + void info(const char *fmt,...); + void (*tron_print_string)(const char *buf); +}; +#endif diff --git a/Bing/Src/Objectness.cpp b/Bing/Src/Objectness.cpp new file mode 100644 index 000000000..01cbc9541 --- /dev/null +++ b/Bing/Src/Objectness.cpp @@ -0,0 +1,1118 @@ +#include "kyheader.h" +#include "Objectness.h" +#include "CmShow.h" + +#define Malloc(type,n) (type *)malloc((n)*sizeof(type)) +void print_null(const char *s) {} +const char* Objectness::_clrName[3] = {"MAXBGR", "HSV", "I"}; +const int CN = 21; // Color Number +const char* COLORs[CN] = {"'k'", "'b'", "'g'", "'r'", "'c'", "'m'", "'y'", + "':k'", "':b'", "':g'", "':r'", "':c'", "':m'", "':y'", + "'--k'", "'--b'", "'--g'", "'--r'", "'--c'", "'--m'", "'--y'" +}; + + +// base for window size quantization, R orientation channels, and feature window size (_W, _W) +Objectness::Objectness(DataSetVOC &voc, double base, int W, int NSS) + : _voc(voc) + , _base(base) + , _W(W) + , _NSS(NSS) + , _logBase(log(_base)) + , _minT(cvCeil(log(10.)/_logBase)) + , _maxT(cvCeil(log(500.)/_logBase)) + , _numT(_maxT - _minT + 1) + , _Clr(MAXBGR) +{ + setColorSpace(_Clr); +} + +Objectness::~Objectness(void) +{ +} + +void Objectness::setColorSpace(int clr) +{ + _Clr = clr; + _modelName = _voc.resDir + format("ObjNessB%gW%d%s", _base, _W, _clrName[_Clr]); + _trainDirSI = _voc.localDir + format("TrainS1B%gW%d%s/", _base, _W, _clrName[_Clr]); + _bbResDir = _voc.resDir + format("BBoxesB%gW%d%s/", _base, _W, _clrName[_Clr]); +} + +int Objectness::loadTrainedModel(string modelName) // Return -1, 0, or 1 if partial, none, or all loaded +{ + if (modelName.size() == 0) + modelName = _modelName; + CStr s1 = modelName + ".wS1", s2 = modelName + ".wS2", sI = modelName + ".idx"; + Mat filters1f, reW1f, idx1i, show3u; + if (!matRead(s1, filters1f) || !matRead(sI, idx1i)){ + printf("Can't load model: %s or %s\n", _S(s1), _S(sI)); + return 0; + } + + //filters1f = aFilter(0.8f, 8); + //normalize(filters1f, filters1f, p, 1, NORM_MINMAX); + + normalize(filters1f, show3u, 1, 255, NORM_MINMAX, CV_8U); + CmShow::showTinyMat(_voc.resDir + "Filter.png", show3u); + _tigF.update(filters1f); + _tigF.reconstruct(filters1f); + + _svmSzIdxs = idx1i; + CV_Assert(_svmSzIdxs.size() > 1 && filters1f.size() == Size(_W, _W) && filters1f.type() == CV_32F); + _svmFilter = filters1f; + + if (!matRead(s2, _svmReW1f) || _svmReW1f.size() != Size(2, _svmSzIdxs.size())){ + _svmReW1f = Mat(); + return -1; + } + return 1; +} + +void Objectness::predictBBoxSI(CMat &img3u, ValStructVec &valBoxes, vecI &sz, int NUM_WIN_PSZ, bool fast) +{ + const int numSz = _svmSzIdxs.size(); + const int imgW = img3u.cols, imgH = img3u.rows; + valBoxes.reserve(10000); + sz.clear(); sz.reserve(10000); + for (int ir = numSz - 1; ir >= 0; ir--){ + int r = _svmSzIdxs[ir]; + int height = cvRound(pow(_base, r/_numT + _minT)), width = cvRound(pow(_base, r%_numT + _minT)); + if (height > imgH * _base || width > imgW * _base) + continue; + + height = min(height, imgH), width = min(width, imgW); + Mat im3u, matchCost1f, mag1u; + resize(img3u, im3u, Size(cvRound(_W*imgW*1.0/width), cvRound(_W*imgH*1.0/height))); + gradientMag(im3u, mag1u); + + //imwrite(_voc.localDir + format("%d.png", r), mag1u); + //Mat mag1f; + //mag1u.convertTo(mag1f, CV_32F); + //matchTemplate(mag1f, _svmFilter, matchCost1f, CV_TM_CCORR); + + matchCost1f = _tigF.matchTemplate(mag1u); + + ValStructVec matchCost; + nonMaxSup(matchCost1f, matchCost, _NSS, NUM_WIN_PSZ, fast); + + // Find true locations and match values + double ratioX = width/_W, ratioY = height/_W; + int iMax = min(matchCost.size(), NUM_WIN_PSZ); + for (int i = 0; i < iMax; i++){ + float mVal = matchCost(i); + Point pnt = matchCost[i]; + Vec4i box(cvRound(pnt.x * ratioX), cvRound(pnt.y*ratioY)); + box[2] = cvRound(min(box[0] + width, imgW)); + box[3] = cvRound(min(box[1] + height, imgH)); + box[0] ++; + box[1] ++; + valBoxes.pushBack(mVal, box); + sz.push_back(ir); + } + } + //exit(0); +} + +void Objectness::predictBBoxSII(ValStructVec &valBoxes, const vecI &sz) +{ + int numI = valBoxes.size(); + for (int i = 0; i < numI; i++){ + const float* svmIIw = _svmReW1f.ptr(sz[i]); + valBoxes(i) = valBoxes(i) * svmIIw[0] + svmIIw[1]; + } + valBoxes.sort(); +} + +// Get potential bounding boxes, each of which is represented by a Vec4i for (minX, minY, maxX, maxY). +// The trained model should be prepared before calling this function: loadTrainedModel() or trainStageI() + trainStageII(). +// Use numDet to control the final number of proposed bounding boxes, and number of per size (scale and aspect ratio) +void Objectness::getObjBndBoxes(CMat &img3u, ValStructVec &valBoxes, int numDetPerSize) +{ + CV_Assert_(filtersLoaded() , ("SVM filters should be initialized before getting object proposals\n")); + vecI sz; + predictBBoxSI(img3u, valBoxes, sz, numDetPerSize, false); + predictBBoxSII(valBoxes, sz); + return; +} + +void Objectness::nonMaxSup(CMat &matchCost1f, ValStructVec &matchCost, int NSS, int maxPoint, bool fast) +{ + const int _h = matchCost1f.rows, _w = matchCost1f.cols; + Mat isMax1u = Mat::ones(_h, _w, CV_8U), costSmooth1f; + ValStructVec valPnt; + matchCost.reserve(_h * _w); + valPnt.reserve(_h * _w); + if (fast){ + blur(matchCost1f, costSmooth1f, Size(3, 3)); + for (int r = 0; r < _h; r++){ + const float* d = matchCost1f.ptr(r); + const float* ds = costSmooth1f.ptr(r); + for (int c = 0; c < _w; c++) + if (d[c] >= ds[c]) + valPnt.pushBack(d[c], Point(c, r)); + } + } + else{ + for (int r = 0; r < _h; r++){ + const float* d = matchCost1f.ptr(r); + for (int c = 0; c < _w; c++) + valPnt.pushBack(d[c], Point(c, r)); + } + } + + valPnt.sort(); + for (int i = 0; i < valPnt.size(); i++){ + Point &pnt = valPnt[i]; + if (isMax1u.at(pnt)){ + matchCost.pushBack(valPnt(i), pnt); + for (int dy = -NSS; dy <= NSS; dy++) for (int dx = -NSS; dx <= NSS; dx++){ + Point neighbor = pnt + Point(dx, dy); + if (!CHK_IND(neighbor)) + continue; + isMax1u.at(neighbor) = false; + } + } + if (matchCost.size() >= maxPoint) + return; + } +} + +void Objectness::gradientMag(CMat &imgBGR3u, Mat &mag1u) +{ + switch (_Clr){ + case MAXBGR: + gradientRGB(imgBGR3u, mag1u); break; + case G: + gradientGray(imgBGR3u, mag1u); break; + case HSV: + gradientHSV(imgBGR3u, mag1u); break; + default: + printf("Error: not recognized color space\n"); + } +} + +void Objectness::gradientRGB(CMat &bgr3u, Mat &mag1u) +{ + const int H = bgr3u.rows, W = bgr3u.cols; + Mat Ix(H, W, CV_32S), Iy(H, W, CV_32S); + + // Left/right most column Ix + for (int y = 0; y < H; y++){ + Ix.at(y, 0) = bgrMaxDist(bgr3u.at(y, 1), bgr3u.at(y, 0))*2; + Ix.at(y, W-1) = bgrMaxDist(bgr3u.at(y, W-1), bgr3u.at(y, W-2))*2; + } + + // Top/bottom most column Iy + for (int x = 0; x < W; x++) { + Iy.at(0, x) = bgrMaxDist(bgr3u.at(1, x), bgr3u.at(0, x))*2; + Iy.at(H-1, x) = bgrMaxDist(bgr3u.at(H-1, x), bgr3u.at(H-2, x))*2; + } + + // Find the gradient for inner regions + for (int y = 0; y < H; y++){ + const Vec3b *dataP = bgr3u.ptr(y); + for (int x = 2; x < W; x++) + Ix.at(y, x-1) = bgrMaxDist(dataP[x-2], dataP[x]); // bgr3u.at(y, x+1), bgr3u.at(y, x-1)); + } + for (int y = 1; y < H-1; y++){ + const Vec3b *tP = bgr3u.ptr(y-1); + const Vec3b *bP = bgr3u.ptr(y+1); + for (int x = 0; x < W; x++) + Iy.at(y, x) = bgrMaxDist(tP[x], bP[x]); + } + gradientXY(Ix, Iy, mag1u); +} + +void Objectness::gradientGray(CMat &bgr3u, Mat &mag1u) +{ + Mat g1u; + cvtColor(bgr3u, g1u, CV_BGR2GRAY); + const int H = g1u.rows, W = g1u.cols; + Mat Ix(H, W, CV_32S), Iy(H, W, CV_32S); + + // Left/right most column Ix + for (int y = 0; y < H; y++){ + Ix.at(y, 0) = abs(g1u.at(y, 1) - g1u.at(y, 0)) * 2; + Ix.at(y, W-1) = abs(g1u.at(y, W-1) - g1u.at(y, W-2)) * 2; + } + + // Top/bottom most column Iy + for (int x = 0; x < W; x++) { + Iy.at(0, x) = abs(g1u.at(1, x) - g1u.at(0, x)) * 2; + Iy.at(H-1, x) = abs(g1u.at(H-1, x) - g1u.at(H-2, x)) * 2; + } + + // Find the gradient for inner regions + for (int y = 0; y < H; y++) + for (int x = 1; x < W-1; x++) + Ix.at(y, x) = abs(g1u.at(y, x+1) - g1u.at(y, x-1)); + for (int y = 1; y < H-1; y++) + for (int x = 0; x < W; x++) + Iy.at(y, x) = abs(g1u.at(y+1, x) - g1u.at(y-1, x)); + + gradientXY(Ix, Iy, mag1u); +} + + +void Objectness::gradientHSV(CMat &bgr3u, Mat &mag1u) +{ + Mat hsv3u; + cvtColor(bgr3u, hsv3u, CV_BGR2HSV); + const int H = hsv3u.rows, W = hsv3u.cols; + Mat Ix(H, W, CV_32S), Iy(H, W, CV_32S); + + // Left/right most column Ix + for (int y = 0; y < H; y++){ + Ix.at(y, 0) = vecDist3b(hsv3u.at(y, 1), hsv3u.at(y, 0)); + Ix.at(y, W-1) = vecDist3b(hsv3u.at(y, W-1), hsv3u.at(y, W-2)); + } + + // Top/bottom most column Iy + for (int x = 0; x < W; x++) { + Iy.at(0, x) = vecDist3b(hsv3u.at(1, x), hsv3u.at(0, x)); + Iy.at(H-1, x) = vecDist3b(hsv3u.at(H-1, x), hsv3u.at(H-2, x)); + } + + // Find the gradient for inner regions + for (int y = 0; y < H; y++) + for (int x = 1; x < W-1; x++) + Ix.at(y, x) = vecDist3b(hsv3u.at(y, x+1), hsv3u.at(y, x-1))/2; + for (int y = 1; y < H-1; y++) + for (int x = 0; x < W; x++) + Iy.at(y, x) = vecDist3b(hsv3u.at(y+1, x), hsv3u.at(y-1, x))/2; + + gradientXY(Ix, Iy, mag1u); +} + +void Objectness::gradientXY(CMat &x1i, CMat &y1i, Mat &mag1u) +{ + const int H = x1i.rows, W = x1i.cols; + mag1u.create(H, W, CV_8U); + for (int r = 0; r < H; r++){ + const int *x = x1i.ptr(r), *y = y1i.ptr(r); + byte* m = mag1u.ptr(r); + for (int c = 0; c < W; c++) + m[c] = min(x[c] + y[c], 255); //((int)sqrt(sqr(x[c]) + sqr(y[c])), 255); + } +} + +void Objectness::trainObjectness(int numDetPerSize) +{ + CmTimer tm1("Train1"), tm2("Train 2"); + + //* Learning stage I + generateTrianData(); + tm1.Start(); + trainStageI(); + tm1.Stop(); + printf("Learning stage I takes %g seconds... \n", tm1.TimeInSeconds()); //*/ + + //* Learning stage II + tm2.Start(); + trainStateII(numDetPerSize); + tm2.Stop(); + printf("Learning stage II takes %g seconds... \n", tm2.TimeInSeconds()); //*/ + return; +} + +void Objectness::generateTrianData() +{ + const int NUM_TRAIN = _voc.trainNum; + const int FILTER_SZ = _W*_W; + vector> xTrainP(NUM_TRAIN), xTrainN(NUM_TRAIN); + vector szTrainP(NUM_TRAIN); // Corresponding size index. + const int NUM_NEG_BOX = 100; // Number of negative windows sampled from each image + +#pragma omp parallel for + for (int i = 0; i < NUM_TRAIN; i++) { + const int NUM_GT_BOX = (int)_voc.gtTrainBoxes[i].size(); + vector &xP = xTrainP[i], &xN = xTrainN[i]; + vecI &szP = szTrainP[i]; + xP.reserve(NUM_GT_BOX*4), szP.reserve(NUM_GT_BOX*4), xN.reserve(NUM_NEG_BOX); + Mat im3u = imread(format(_S(_voc.imgPathW), _S(_voc.trainSet[i]))); + + // Get positive training data + for (int k = 0; k < NUM_GT_BOX; k++){ + const Vec4i& bbgt = _voc.gtTrainBoxes[i][k]; + vector bbs; // bounding boxes; + vecI bbR; // Bounding box ratios + int nS = gtBndBoxSampling(bbgt, bbs, bbR); + for (int j = 0; j < nS; j++){ + bbs[j][2] = min(bbs[j][2], im3u.cols); + bbs[j][3] = min(bbs[j][3], im3u.rows); + Mat mag1f = getFeature(im3u, bbs[j]), magF1f; + flip(mag1f, magF1f, CV_FLIP_HORIZONTAL); + xP.push_back(mag1f); + xP.push_back(magF1f); + szP.push_back(bbR[j]); + szP.push_back(bbR[j]); + } + } + // Get negative training data + for (int k = 0; k < NUM_NEG_BOX; k++){ + int x1 = rand() % im3u.cols + 1, x2 = rand() % im3u.cols + 1; + int y1 = rand() % im3u.rows + 1, y2 = rand() % im3u.rows + 1; + Vec4i bb(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2)); + if (maxIntUnion(bb, _voc.gtTrainBoxes[i]) < 0.5) + xN.push_back(getFeature(im3u, bb)); + } + } + + const int NUM_R = _numT * _numT + 1; + vecI szCount(NUM_R); // Object counts of each size (combination of scale and aspect ratio) + int numP = 0, numN = 0, iP = 0, iN = 0; + for (int i = 0; i < NUM_TRAIN; i++){ + numP += xTrainP[i].size(); + numN += xTrainN[i].size(); + const vecI &rP = szTrainP[i]; + for (size_t j = 0; j < rP.size(); j++) + szCount[rP[j]]++; + } + vecI szActive; // Indexes of active size + for (int r = 1; r < NUM_R; r++){ + if (szCount[r] > 50) // If only 50- positive samples at this size, ignore it. + szActive.push_back(r-1); + } + matWrite(_modelName + ".idx", Mat(szActive)); + + Mat xP1f(numP, FILTER_SZ, CV_32F), xN1f(numN, FILTER_SZ, CV_32F); + for (int i = 0; i < NUM_TRAIN; i++) { + vector &xP = xTrainP[i], &xN = xTrainN[i]; + for (size_t j = 0; j < xP.size(); j++) + memcpy(xP1f.ptr(iP++), xP[j].data, FILTER_SZ*sizeof(float)); + for (size_t j = 0; j < xN.size(); j++) + memcpy(xN1f.ptr(iN++), xN[j].data, FILTER_SZ*sizeof(float)); + } + CV_Assert(numP == iP && numN == iN); + matWrite(_modelName + ".xP", xP1f); + matWrite(_modelName + ".xN", xN1f); +} + +Mat Objectness::getFeature(CMat &img3u, const Vec4i &bb) +{ + int x = bb[0] - 1, y = bb[1] - 1; + Rect reg(x, y, bb[2] - x, bb[3] - y); + Mat subImg3u, mag1f, mag1u; + resize(img3u(reg), subImg3u, Size(_W, _W)); + gradientMag(subImg3u, mag1u); + mag1u.convertTo(mag1f, CV_32F); + return mag1f; +} + +int Objectness::gtBndBoxSampling(const Vec4i &bbgt, vector &samples, vecI &bbR) +{ + double wVal = bbgt[2] - bbgt[0] + 1, hVal = (bbgt[3] - bbgt[1]) + 1; + wVal = log(wVal)/_logBase, hVal = log(hVal)/_logBase; + int wMin = max((int)(wVal - 0.5), _minT), wMax = min((int)(wVal + 1.5), _maxT); + int hMin = max((int)(hVal - 0.5), _minT), hMax = min((int)(hVal + 1.5), _maxT); + for (int h = hMin; h <= hMax; h++) for (int w = wMin; w <= wMax; w++){ + int wT = tLen(w) - 1, hT = tLen(h) - 1; + Vec4i bb(bbgt[0], bbgt[1], bbgt[0] + wT, bbgt[1] + hT); + if (DataSetVOC::interUnio(bb, bbgt) >= 0.5){ + samples.push_back(bb); + bbR.push_back(sz2idx(w, h)); + //if (bbgt[3] > hT){ + // bb = Vec4i(bbgt[0], bbgt[3] - hT, bbgt[0] + wT, bbgt[3]); + // CV_Assert(DataSetVOC::interUnio(bb, bbgt) >= 0.5); + // samples.push_back(bb); + // bbR.push_back(sz2idx(w, h)); + //} + //if (bbgt[2] > wT){ + // bb = Vec4i(bbgt[2] - wT, bbgt[1], bbgt[2], bbgt[1] + hT); + // CV_Assert(DataSetVOC::interUnio(bb, bbgt) >= 0.5); + // samples.push_back(bb); + // bbR.push_back(sz2idx(w, h)); + //} + //if (bbgt[2] > wT && bbgt[3] > hT){ + // bb = Vec4i(bbgt[2] - wT, bbgt[3] - hT, bbgt[2], bbgt[3]); + // CV_Assert(DataSetVOC::interUnio(bb, bbgt) >= 0.5); + // samples.push_back(bb); + // bbR.push_back(sz2idx(w, h)); + //} + } + } + return samples.size(); +} + +void Objectness::trainStateII(int numPerSz) +{ + loadTrainedModel(); + const int NUM_TRAIN = _voc.trainNum; + vector SZ(NUM_TRAIN), Y(NUM_TRAIN); + vector VAL(NUM_TRAIN); + +#pragma omp parallel for + for (int i = 0; i < _voc.trainNum; i++) { + const vector &bbgts = _voc.gtTrainBoxes[i]; + ValStructVec valBoxes; + vecI &sz = SZ[i], &y = Y[i]; + vecF &val = VAL[i]; + CStr imgPath = format(_S(_voc.imgPathW), _S(_voc.trainSet[i])); + predictBBoxSI(imread(imgPath), valBoxes, sz, numPerSz, false); + const int num = valBoxes.size(); + CV_Assert(sz.size() == num); + y.resize(num), val.resize(num); + for (int j = 0; j < num; j++){ + Vec4i bb = valBoxes[j]; + val[j] = valBoxes(j); + y[j] = maxIntUnion(bb, bbgts) >= 0.5 ? 1 : -1; + } + } + + const int NUM_SZ = _svmSzIdxs.size(); + const int maxTrainNum = 100000; + vector rXP(NUM_SZ), rXN(NUM_SZ); + for (int r = 0; r < NUM_SZ; r++){ + rXP[r].reserve(maxTrainNum); + rXN[r].reserve(1000000); + } + for (int i = 0; i < NUM_TRAIN; i++){ + const vecI &sz = SZ[i], &y = Y[i]; + vecF &val = VAL[i]; + int num = sz.size(); + for (int j = 0; j < num; j++){ + int r = sz[j]; + CV_Assert(r >= 0 && r < NUM_SZ); + if (y[j] == 1) + rXP[r].push_back(Mat(1, 1, CV_32F, &val[j])); + else + rXN[r].push_back(Mat(1, 1, CV_32F, &val[j])); + } + } + + Mat wMat(NUM_SZ, 2, CV_32F); + for (int i = 0; i < NUM_SZ; i++){ + const vecM &xP = rXP[i], &xN = rXN[i]; + if (xP.size() < 10 || xN.size() < 10) + printf("Warning %s:%d not enough training sample for r[%d] = %d. P = %d, N = %d\n", __FILE__, __LINE__, i, _svmSzIdxs[i], xP.size(), xN.size()); + for (size_t k = 0; k < xP.size(); k++) + CV_Assert(xP[k].size() == Size(1, 1) && xP[k].type() == CV_32F); + + Mat wr = trainSVM(xP, xN, L1R_L2LOSS_SVC, 100, 1); + CV_Assert(wr.size() == Size(2, 1)); + wr.copyTo(wMat.row(i)); + } + matWrite(_modelName + ".wS2", wMat); + _svmReW1f = wMat; +} + +void Objectness::meanStdDev(CMat &data1f, Mat &mean1f, Mat &stdDev1f) +{ + const int DIM = data1f.cols, NUM = data1f.rows; + mean1f = Mat::zeros(1, DIM, CV_32F), stdDev1f = Mat::zeros(1, DIM, CV_32F); + for (int i = 0; i < NUM; i++) + mean1f += data1f.row(i); + mean1f /= NUM; + for (int i = 0; i < NUM; i++){ + Mat tmp; + pow(data1f.row(i) - mean1f, 2, tmp); + stdDev1f += tmp; + } + pow(stdDev1f/NUM, 0.5, stdDev1f); +} + +vecD Objectness::getVector(const Mat &_t1f) +{ + Mat t1f; + _t1f.convertTo(t1f, CV_64F); + return (vecD)(t1f.reshape(1, 1)); +} + +void Objectness::illustrate() +{ + Mat xP1f, xN1f; + CV_Assert(matRead(_modelName + ".xP", xP1f) && matRead(_modelName + ".xN", xN1f)); + CV_Assert(xP1f.cols == xN1f.cols && xP1f.cols == _W*_W && xP1f.type() == CV_32F && xN1f.type() == CV_32F); + Mat meanP, meanN, stdDevP, stdDevN; + meanStdDev(xP1f, meanP, stdDevP); + meanStdDev(xN1f, meanN, stdDevN); + Mat meanV(_W, _W*2, CV_32F), stdDev(_W, _W*2, CV_32F); + meanP.reshape(1, _W).copyTo(meanV.colRange(0, _W)); + meanN.reshape(1, _W).copyTo(meanV.colRange(_W, _W*2)); + stdDevP.reshape(1, _W).copyTo(stdDev.colRange(0, _W)); + stdDevN.reshape(1, _W).copyTo(stdDev.colRange(_W, _W*2)); + normalize(meanV, meanV, 0, 255, NORM_MINMAX, CV_8U); + CmShow::showTinyMat(_voc.resDir + "PosNeg.png", meanV); + + FILE* f = fopen(_S(_voc.resDir + "PosNeg.m"), "w"); + CV_Assert(f != NULL); + fprintf(f, "figure(1);\n\n"); + PrintVector(f, getVector(meanP), "MeanP"); + PrintVector(f, getVector(meanN), "MeanN"); + PrintVector(f, getVector(stdDevP), "StdDevP"); + PrintVector(f, getVector(stdDevN), "StdDevN"); + PrintVector(f, getVector(_svmFilter), "Filter"); + fprintf(f, "hold on;\nerrorbar(MeanP, StdDevP, 'r');\nerrorbar(MeanN, StdDevN, 'g');\nhold off;"); + fclose(f); +} + +void Objectness::trainStageI() +{ + vecM pX, nX; + pX.reserve(200000), nX.reserve(200000); + Mat xP1f, xN1f; + CV_Assert(matRead(_modelName + ".xP", xP1f) && matRead(_modelName + ".xN", xN1f)); + for (int r = 0; r < xP1f.rows; r++) + pX.push_back(xP1f.row(r)); + for (int r = 0; r < xN1f.rows; r++) + nX.push_back(xN1f.row(r)); + Mat crntW = trainSVM(pX, nX, L1R_L2LOSS_SVC, 10, 1); + crntW = crntW.colRange(0, crntW.cols - 1).reshape(1, _W); + CV_Assert(crntW.size() == Size(_W, _W)); + matWrite(_modelName + ".wS1", crntW); +} + +// Training SVM with feature vector X and label Y. +// Each row of X is a feature vector, with corresponding label in Y. +// Return a CV_32F weight Mat +Mat Objectness::trainSVM(CMat &X1f, const vecI &Y, int sT, double C, double bias, double eps) +{ + // Set SVM parameters + parameter param; { + param.solver_type = sT; // L2R_L2LOSS_SVC_DUAL; + param.C = C; + param.eps = eps; // see setting below + param.p = 0.1; + param.nr_weight = 0; + param.weight_label = NULL; + param.weight = NULL; + set_print_string_function(print_null); + CV_Assert(X1f.rows == Y.size() && X1f.type() == CV_32F); + } + + // Initialize a problem + feature_node *x_space = NULL; + problem prob;{ + prob.l = X1f.rows; + prob.bias = bias; + prob.y = Malloc(double, prob.l); + prob.x = Malloc(feature_node*, prob.l); + const int DIM_FEA = X1f.cols; + prob.n = DIM_FEA + (bias >= 0 ? 1 : 0); + x_space = Malloc(feature_node, (prob.n + 1) * prob.l); + int j = 0; + for (int i = 0; i < prob.l; i++){ + prob.y[i] = Y[i]; + prob.x[i] = &x_space[j]; + const float* xData = X1f.ptr(i); + for (int k = 0; k < DIM_FEA; k++){ + x_space[j].index = k + 1; + x_space[j++].value = xData[k]; + } + if (bias >= 0){ + x_space[j].index = prob.n; + x_space[j++].value = bias; + } + x_space[j++].index = -1; + } + CV_Assert(j == (prob.n + 1) * prob.l); + } + + // Training SVM for current problem + const char* error_msg = check_parameter(&prob, ¶m); + if(error_msg){ + fprintf(stderr,"ERROR: %s\n",error_msg); + exit(1); + } + model *svmModel = train(&prob, ¶m); + Mat wMat(1, prob.n, CV_64F, svmModel->w); + wMat.convertTo(wMat, CV_32F); + free_and_destroy_model(&svmModel); + destroy_param(¶m); + free(prob.y); + free(prob.x); + free(x_space); + return wMat; +} + +// pX1f, nX1f are positive and negative training samples, each is a row vector +Mat Objectness::trainSVM(const vector &pX1f, const vector &nX1f, int sT, double C, double bias, double eps, int maxTrainNum) +{ + vecI ind(nX1f.size()); + for (size_t i = 0; i < ind.size(); i++) + ind[i] = i; + int numP = pX1f.size(), feaDim = pX1f[0].cols; + int totalSample = numP + nX1f.size(); + if (totalSample > maxTrainNum) + random_shuffle(ind.begin(), ind.end()); + totalSample = min(totalSample, maxTrainNum); + Mat X1f(totalSample, feaDim, CV_32F); + vecI Y(totalSample); + for(int i = 0; i < numP; i++){ + pX1f[i].copyTo(X1f.row(i)); + Y[i] = 1; + } + for (int i = numP; i < totalSample; i++){ + nX1f[ind[i - numP]].copyTo(X1f.row(i)); + Y[i] = -1; + } + return trainSVM(X1f, Y, sT, C, bias, eps); +} + +// Get potential bounding boxes for all test images +void Objectness::getObjBndBoxesForTests(vector> &_boxesTests, int numDetPerSize) +{ + const int TestNum = _voc.testSet.size(); + vecM imgs3u(TestNum); + vector> boxesTests; + boxesTests.resize(TestNum); + +#pragma omp parallel for + for (int i = 0; i < TestNum; i++){ + imgs3u[i] = imread(format(_S(_voc.imgPathW), _S(_voc.testSet[i]))); + boxesTests[i].reserve(10000); + } + + int scales[3] = {1, 3, 5}; + for (int clr = MAXBGR; clr <= G; clr++){ + setColorSpace(clr); + trainObjectness(numDetPerSize); + loadTrainedModel(); + CmTimer tm("Predict"); + tm.Start(); + +#pragma omp parallel for + for (int i = 0; i < TestNum; i++){ + ValStructVec boxes; + getObjBndBoxes(imgs3u[i], boxes, numDetPerSize); + boxesTests[i].append(boxes, scales[clr]); + } + + tm.Stop(); + printf("Average time for predicting an image (%s) is %gs\n", _clrName[_Clr], tm.TimeInSeconds()/TestNum); + } + + _boxesTests.resize(TestNum); + CmFile::MkDir(_bbResDir); +#pragma omp parallel for + for (int i = 0; i < TestNum; i++){ + CStr fName = _bbResDir + _voc.testSet[i]; + ValStructVec &boxes = boxesTests[i]; + FILE *f = fopen(_S(fName + ".txt"), "w"); + fprintf(f, "%d\n", boxes.size()); + for (size_t k = 0; k < boxes.size(); k++) + fprintf(f, "%g, %s\n", boxes(k), _S(strVec4i(boxes[k]))); + fclose(f); + + _boxesTests[i].resize(boxesTests[i].size()); + for (int j = 0; j < boxesTests[i].size(); j++) + _boxesTests[i][j] = boxesTests[i][j]; + } + + evaluatePerImgRecall(_boxesTests, "PerImgAllNS.m", 5000); + +#pragma omp parallel for + for (int i = 0; i < TestNum; i++){ + boxesTests[i].sort(false); + for (int j = 0; j < boxesTests[i].size(); j++) + _boxesTests[i][j] = boxesTests[i][j]; + } + evaluatePerImgRecall(_boxesTests, "PerImgAllS.m", 5000); +} + + +// Get potential bounding boxes for all test images +void Objectness::getObjBndBoxesForTestsFast(vector> &_boxesTests, int numDetPerSize) +{ + //setColorSpace(HSV); + trainObjectness(numDetPerSize); + loadTrainedModel(); + illustrate(); + + + const int TestNum = _voc.testSet.size(); + vecM imgs3u(TestNum); + vector> boxesTests; + boxesTests.resize(TestNum); + +#pragma omp parallel for + for (int i = 0; i < TestNum; i++){ + imgs3u[i] = imread(format(_S(_voc.imgPathW), _S(_voc.testSet[i]))); + boxesTests[i].reserve(10000); + } + + printf("Start predicting\n"); + CmTimer tm("Predict"); + tm.Start(); + +#pragma omp parallel for + for (int i = 0; i < TestNum; i++) + getObjBndBoxes(imgs3u[i], boxesTests[i], numDetPerSize); + + tm.Stop(); + printf("Average time for predicting an image (%s) is %gs\n", _clrName[_Clr], tm.TimeInSeconds()/TestNum); + + _boxesTests.resize(TestNum); + CmFile::MkDir(_bbResDir); + +#pragma omp parallel for + for (int i = 0; i < TestNum; i++){ + CStr fName = _bbResDir + _voc.testSet[i]; + ValStructVec &boxes = boxesTests[i]; + FILE *f = fopen(_S(fName + ".txt"), "w"); + fprintf(f, "%d\n", boxes.size()); + for (size_t k = 0; k < boxes.size(); k++) + fprintf(f, "%g, %s\n", boxes(k), _S(strVec4i(boxes[k]))); + fclose(f); + + _boxesTests[i].resize(boxesTests[i].size()); + for (int j = 0; j < boxesTests[i].size(); j++) + _boxesTests[i][j] = boxesTests[i][j]; + } + + evaluatePerImgRecall(_boxesTests, "PerImgAll.m", 5000); +} + + +void Objectness::getRandomBoxes(vector> &boxesTests, int num) +{ + const int TestNum = _voc.testSet.size(); + boxesTests.resize(TestNum); +#pragma omp parallel for + for (int i = 0; i < TestNum; i++){ + Mat imgs3u = imread(format(_S(_voc.imgPathW), _S(_voc.testSet[i]))); + int H = imgs3u.cols, W = imgs3u.rows; + boxesTests[i].reserve(num); + for (int k = 0; k < num; k++){ + int x1 = rand()%W + 1, x2 = rand()%W + 1; + int y1 = rand()%H + 1, y2 = rand()%H + 1; + boxesTests[i].push_back(Vec4i(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2))); + } + } + evaluatePerImgRecall(boxesTests, "PerImgAll.m", num); +} + +void Objectness::evaluatePerImgRecall(const vector> &boxesTests, CStr &saveName, const int NUM_WIN) +{ + vecD recalls(NUM_WIN); + vecD avgScore(NUM_WIN); + const int TEST_NUM = _voc.testSet.size(); + for (int i = 0; i < TEST_NUM; i++){ + const vector &boxesGT = _voc.gtTestBoxes[i]; + const vector &boxes = boxesTests[i]; + const int gtNumCrnt = boxesGT.size(); + vecI detected(gtNumCrnt); + vecD score(gtNumCrnt); + double sumDetected = 0, abo = 0; + for (int j = 0; j < NUM_WIN; j++){ + if (j >= (int)boxes.size()){ + recalls[j] += sumDetected/gtNumCrnt; + avgScore[j] += abo/gtNumCrnt; + continue; + } + + for (int k = 0; k < gtNumCrnt; k++) { + double s = DataSetVOC::interUnio(boxes[j], boxesGT[k]); + score[k] = max(score[k], s); + detected[k] = score[k] >= 0.5 ? 1 : 0; + } + sumDetected = 0, abo = 0; + for (int k = 0; k < gtNumCrnt; k++) + sumDetected += detected[k], abo += score[k]; + recalls[j] += sumDetected/gtNumCrnt; + avgScore[j] += abo/gtNumCrnt; + } + } + + for (int i = 0; i < NUM_WIN; i++){ + recalls[i] /= TEST_NUM; + avgScore[i] /= TEST_NUM; + } + + int idx[8] = {1, 10, 100, 1000, 2000, 3000, 4000, 5000}; + for (int i = 0; i < 8; i++){ + if (idx[i] > NUM_WIN) + continue; + printf("%d:%.3g,%.3g\t", idx[i], recalls[idx[i] - 1], avgScore[idx[i] - 1]); + } + printf("\n"); + + FILE* f = fopen(_S(_voc.resDir + saveName), "w"); + CV_Assert(f != NULL); + fprintf(f, "figure(1);\n\n"); + PrintVector(f, recalls, "DR"); + PrintVector(f, avgScore, "MABO"); + fprintf(f, "semilogx(1:%d, DR(1:%d));\nhold on;\nsemilogx(1:%d, DR(1:%d));\naxis([1, 5000, 0, 1]);\nhold off;\n", NUM_WIN, NUM_WIN, NUM_WIN, NUM_WIN); + fclose(f); +} + +void Objectness::illuTestReults(const vector> &boxesTests) +{ + CStr resDir = _voc.localDir + "ResIlu/"; + CmFile::MkDir(resDir); + const int TEST_NUM = _voc.testSet.size(); + for (int i = 0; i < TEST_NUM; i++){ + const vector &boxesGT = _voc.gtTestBoxes[i]; + const vector &boxes = boxesTests[i]; + const int gtNumCrnt = boxesGT.size(); + CStr imgPath = format(_S(_voc.imgPathW), _S(_voc.testSet[i])); + CStr resNameNE = CmFile::GetNameNE(imgPath); + Mat img = imread(imgPath); + Mat bboxMatchImg = Mat::zeros(img.size(), CV_32F); + + vecD score(gtNumCrnt); + vector bboxMatch(gtNumCrnt); + for (int j = 0; j < boxes.size(); j++){ + const Vec4i &bb = boxes[j]; + for (int k = 0; k < gtNumCrnt; k++) { + double mVal = DataSetVOC::interUnio(boxes[j], boxesGT[k]); + if (mVal < score[k]) + continue; + score[k] = mVal; + bboxMatch[k] = boxes[j]; + } + } + + for (int k = 0; k < gtNumCrnt; k++){ + const Vec4i &bb = bboxMatch[k]; + rectangle(img, Point(bb[0], bb[1]), Point(bb[2], bb[3]), Scalar(0), 3); + rectangle(img, Point(bb[0], bb[1]), Point(bb[2], bb[3]), Scalar(255, 255, 255), 2); + rectangle(img, Point(bb[0], bb[1]), Point(bb[2], bb[3]), Scalar(0, 0, 255), 1); + } + + imwrite(resDir + resNameNE + "_Match.jpg", img); + } +} + +void Objectness::evaluatePerClassRecall(vector> &boxesTests, CStr &saveName, const int WIN_NUM) +{ + const int TEST_NUM = _voc.testSet.size(), CLS_NUM = _voc.classNames.size(); + if (boxesTests.size() != TEST_NUM){ + boxesTests.resize(TEST_NUM); + for (int i = 0; i < TEST_NUM; i++){ + Mat boxes; + matRead(_voc.localDir + _voc.testSet[i] + ".dat", boxes); + Vec4i* d = (Vec4i*)boxes.data; + boxesTests[i].resize(boxes.rows, WIN_NUM); + memcpy(&boxesTests[i][0], boxes.data, sizeof(Vec4i)*boxes.rows); + } + } + + for (int i = 0; i < TEST_NUM; i++) + if ((int)boxesTests[i].size() < WIN_NUM){ + printf("%s.dat: %d, %d\n", _S(_voc.testSet[i]), boxesTests[i].size(), WIN_NUM); + boxesTests[i].resize(WIN_NUM); + } + + + // #class by #win matrix for saving correct detection number and gt number + Mat crNum1i = Mat::zeros(CLS_NUM, WIN_NUM, CV_32S); + vecD gtNums(CLS_NUM); { + for (int i = 0; i < TEST_NUM; i++){ + const vector &boxes = boxesTests[i]; + const vector &boxesGT = _voc.gtTestBoxes[i]; + const vecI &clsGT = _voc.gtTestClsIdx[i]; + CV_Assert((int)boxes.size() >= WIN_NUM); + const int gtNumCrnt = boxesGT.size(); + for (int j = 0; j < gtNumCrnt; j++){ + gtNums[clsGT[j]]++; + double maxIntUni = 0; + int* crNum = crNum1i.ptr(clsGT[j]); + for (int k = 0; k < WIN_NUM; k++) { + double val = DataSetVOC::interUnio(boxes[k], boxesGT[j]); + maxIntUni = max(maxIntUni, val); + crNum[k] += maxIntUni >= 0.5 ? 1 : 0; + } + } + } + } + + FILE* f = fopen(_S(_voc.resDir + saveName), "w"); { + CV_Assert(f != NULL); + fprintf(f, "figure(1);\nhold on;\n\n\n"); + vecD val(WIN_NUM), recallObjs(WIN_NUM), recallClss(WIN_NUM); + for (int i = 0; i < WIN_NUM; i++) + val[i] = i; + PrintVector(f, gtNums, "GtNum"); + PrintVector(f, val, "WinNum"); + fprintf(f, "\n"); + string leglendStr("legend("); + double sumObjs = 0; + for (int c = 0; c < CLS_NUM; c++){ + sumObjs += gtNums[c]; + memset(&val[0], 0, sizeof(double)*WIN_NUM); + int* crNum = crNum1i.ptr(c); + for (int i = 0; i < WIN_NUM; i++){ + val[i] = crNum[i]/(gtNums[c] + 1e-200); + recallClss[i] += val[i]; + recallObjs[i] += crNum[i]; + } + CStr className = _voc.classNames[c]; + PrintVector(f, val, className); + fprintf(f, "plot(WinNum, %s, %s, 'linewidth', 2);\n", _S(className), COLORs[c % CN]); + leglendStr += format("'%s', ", _S(className)); + } + for (int i = 0; i < WIN_NUM; i++){ + recallClss[i] /= CLS_NUM; + recallObjs[i] /= sumObjs; + } + PrintVector(f, recallClss, "class"); + fprintf(f, "plot(WinNum, %s, %s, 'linewidth', 2);\n", "class", COLORs[CLS_NUM % CN]); + leglendStr += format("'%s', ", "class"); + PrintVector(f, recallObjs, "objects"); + fprintf(f, "plot(WinNum, %s, %s, 'linewidth', 2);\n", "objects", COLORs[(CLS_NUM+1) % CN]); + leglendStr += format("'%s', ", "objects"); + leglendStr.resize(leglendStr.size() - 2); + leglendStr += ");"; + fprintf(f, "%s\nhold off;\nxlabel('#WIN');\nylabel('Recall');\ngrid on;\naxis([0 %d 0 1]);\n", _S(leglendStr), WIN_NUM); + fprintf(f, "[class([1,10,100,1000]);objects([1,10,100,1000])]\ntitle('%s')\n", _S(saveName)); + fclose(f); + printf("%-70s\r", ""); + } + evaluatePerImgRecall(boxesTests, CmFile::GetNameNE(saveName) + "_PerI.m", WIN_NUM); +} + +void Objectness::PrintVector(FILE *f, const vecD &v, CStr &name) +{ + fprintf(f, "%s = [", name.c_str()); + for (size_t i = 0; i < v.size(); i++) + fprintf(f, "%g ", v[i]); + fprintf(f, "];\n"); +} + +// Write matrix to binary file +bool Objectness::matWrite(CStr& filename, CMat& _M){ + Mat M; + _M.copyTo(M); + FILE* file = fopen(_S(filename), "wb"); + if (file == NULL || M.empty()) + return false; + fwrite("CmMat", sizeof(char), 5, file); + int headData[3] = {M.cols, M.rows, M.type()}; + fwrite(headData, sizeof(int), 3, file); + fwrite(M.data, sizeof(char), M.step * M.rows, file); + fclose(file); + return true; +} + +// Read matrix from binary file +bool Objectness::matRead(const string& filename, Mat& _M){ + FILE* f = fopen(_S(filename), "rb"); + if (f == NULL) + return false; + char buf[8]; + int pre = fread(buf,sizeof(char), 5, f); + if (strncmp(buf, "CmMat", 5) != 0) { + printf("Invalidate CvMat data file %s\n", _S(filename)); + return false; + } + int headData[3]; // Width, height, type + fread(headData, sizeof(int), 3, f); + Mat M(headData[1], headData[0], headData[2]); + fread(M.data, sizeof(char), M.step * M.rows, f); + fclose(f); + M.copyTo(_M); + return true; +} + +void Objectness::evaluatePAMI12(CStr &saveName) +{ + const int TEST_NUM = _voc.testSet.size(); + vector> boxesTests(TEST_NUM); + CStr dir = _voc.wkDir + "PAMI12/"; + const int numDet = 1853; + for (int i = 0; i < TEST_NUM; i++){ + FILE *f = fopen(_S(dir + _voc.testSet[i] + ".txt"), "r"); + double score; + boxesTests[i].resize(numDet); + for (int j = 0; j < numDet; j++){ + Vec4i &v = boxesTests[i][j]; + fscanf(f, "%d %d %d %d %g\n", &v[0], &v[1], &v[2], &v[3], &score); + } + fclose(f); + } + printf("Load data finished\r"); + //evaluatePerImgRecall(boxesTests, saveName, numDet); + evaluatePerClassRecall(boxesTests, saveName, numDet); +} + +void Objectness::evaluateIJCV13(CStr &saveName) +{ + const int TEST_NUM = _voc.testSet.size(); + vector> boxesTests(TEST_NUM); + CStr dir = _voc.wkDir + "IJCV13/"; + const int numDet = 10000; + for (int i = 0; i < TEST_NUM; i++){ + FILE *f = fopen(_S(dir + _voc.testSet[i] + ".txt"), "r"); + boxesTests[i].resize(numDet); + for (int j = 0; j < numDet; j++){ + Vec4i &v = boxesTests[i][j]; + fscanf(f, "%d, %d, %d, %d\n", &v[1], &v[0], &v[3], &v[2]); + } + fclose(f); + } + printf("Load data finished\r"); + evaluatePerImgRecall(boxesTests, saveName, numDet); + //evaluate(boxesTests, saveName, numDet); +} +float distG(float d, float delta) {return exp(-d*d/(2*delta*delta));} + +Mat Objectness::aFilter(float delta, int sz) +{ + float dis = float(sz-1)/2.f; + Mat mat(sz, sz, CV_32F); + for (int r = 0; r < sz; r++) + for (int c = 0; c < sz; c++) + mat.at(r, c) = distG(sqrt(sqr(r-dis)+sqr(c-dis)) - dis, delta); + return mat; +} + +// +//// Calculate the image gradient: center option as in VLFeat +//void Objectness::gradientMag3(CMat &img3f, Mat &mag1f) +//{ +// const int H = img3f.rows, W = img3f.cols; +// Mat Ix(H, W, CV_32F), Iy(H, W, CV_32F); +// +// // Left/right most column Ix +// for (int y = 0; y < H; y++){ +// Ix.at(y, 0) = vecDist(img3f.at(y, 1), img3f.at(y, 0)); +// Ix.at(y, W-1) = vecDist(img3f.at(y, W-1), img3f.at(y, W-2)); +// } +// +// // Top/bottom most column Iy +// for (int x = 0; x < W; x++) { +// Iy.at(0, x) = vecDist(img3f.at(1, x), img3f.at(0, x)); +// Iy.at(H-1, x) = vecDist(img3f.at(H-1, x), img3f.at(H-2, x)); +// } +// +// // Find the gradient for inner regions +// for (int y = 0; y < H; y++) +// for (int x = 1; x < W-1; x++) +// Ix.at(y, x) = 0.5f * vecDist(img3f.at(y, x+1), img3f.at(y, x-1)); +// for (int y = 1; y < H-1; y++) +// for (int x = 0; x < W; x++) +// Iy.at(y, x) = 0.5f * vecDist(img3f.at(y+1, x), img3f.at(y-1, x)); +// mag1f = abs(Ix) + abs(Iy); +//} +// +//// +//// Calculate the image gradient: center option as in VLFeat +//void Objectness::gradientMag1(CMat &img1f, Mat &mag1f) +//{ +// CV_Assert(img1f.type() == CV_32F); +// const int H = img1f.rows, W = img1f.cols; +// Mat Ix(H, W, CV_32F), Iy(H, W, CV_32F); +// +// // Left/right most column Ix +// for (int y = 0; y < H; y++){ +// Ix.at(y, 0) = img1f.at(y, 1) - img1f.at(y, 0); +// Ix.at(y, W-1) = img1f.at(y, W-1) - img1f.at(y, W-2); +// } +// +// // Top/bottom most column Iy +// for (int x = 0; x < W; x++) { +// Iy.at(0, x) = img1f.at(1, x) - img1f.at(0, x); +// Iy.at(H-1, x) = img1f.at(H-1, x) - img1f.at(H-2, x); +// } +// +// // Find the gradient for inner regions +// for (int y = 0; y < H; y++) +// for (int x = 1; x < W-1; x++) +// Ix.at(y, x) = 0.5f * (img1f.at(y, x+1) - img1f.at(y, x-1)); +// for (int y = 1; y < H-1; y++) +// for (int x = 0; x < W; x++) +// Iy.at(y, x) = 0.5f * (img1f.at(y+1, x) - img1f.at(y-1, x)); +// mag1f = abs(Ix) + abs(Iy); +//} diff --git a/Bing/Src/Objectness.h b/Bing/Src/Objectness.h new file mode 100644 index 000000000..6d997f0a9 --- /dev/null +++ b/Bing/Src/Objectness.h @@ -0,0 +1,116 @@ +#pragma once +#include "DataSetVOC.h" +#include "ValStructVec.h" +#include "FilterTIG.h" +class Objectness +{ +public: + // base for window size quantization, feature window size (W, W), and non-maximal suppress size NSS + Objectness(DataSetVOC &voc, double base = 2, int W = 8, int NSS = 2); + ~Objectness(void); + + // Load trained model. + int loadTrainedModel(string modelName = ""); // Return -1, 0, or 1 if partial, none, or all loaded + + // Get potential bounding boxes, each of which is represented by a Vec4i for (minX, minY, maxX, maxY). + // The trained model should be prepared before calling this function: loadTrainedModel() or trainStageI() + trainStageII(). + // Use numDet to control the final number of proposed bounding boxes, and number of per size (scale and aspect ratio) + void getObjBndBoxes(CMat &img3u, ValStructVec &valBoxes, int numDetPerSize = 120); + + // Training and testing on the dataset + void trainObjectness(int numDetPerSize = 100); + void getObjBndBoxesForTests(vector> &boxesTests, int numDetPerSize = 100); + void getObjBndBoxesForTestsFast(vector> &boxesTests, int numDetPerSize = 100); + void getRandomBoxes(vector> &boxesTests, int numD = 10000); + void evaluatePAMI12(CStr &saveName = "PlotMAMI12.m"); + void evaluateIJCV13(CStr &saveName = "IJCV13.m"); + void evaluatePerClassRecall(vector> &boxesTests, CStr &saveName = "Plot.m", const int numDet = 1000); + void evaluatePerImgRecall(const vector> &boxesTests, CStr &saveName, const int numDet = 1000); + void illuTestReults(const vector> &boxesTests); + void setColorSpace(int clr = MAXBGR); + + // Training SVM with feature vector X and label Y. + // Each row of X is a feature vector, with corresponding label in Y. + // Return a CV_32F weight Mat + static Mat trainSVM(CMat &X1f, const vecI &Y, int sT, double C, double bias = -1, double eps = 0.01); + + // pX1f, nX1f are positive and negative training samples, each is a row vector + static Mat trainSVM(const vector &pX1f, const vector &nX1f, int sT, double C, double bias = -1, double eps = 0.01, int maxTrainNum = 100000); + + // Write matrix to binary file + static bool matWrite(CStr& filename, CMat& M); + + // Read matrix from binary file + static bool matRead( const string& filename, Mat& M); + + enum {MAXBGR, HSV, G}; + + static void meanStdDev(CMat &data1f, Mat &mean1f, Mat &stdDev1f); + + void illustrate(); + + inline static float LoG(float x, float y, float delta) {float d = -(x*x+y*y)/(2*delta*delta); return -1.0f/((float)(CV_PI)*pow(delta, 4)) * (1+d)*exp(d);} // Laplacian of Gaussian + static Mat aFilter(float delta, int sz); + +private: // Parameters + const double _base, _logBase; // base for window size quantization + const int _W; // As described in the paper: #Size, Size(_W, _H) of feature window. + const int _NSS; // Size for non-maximal suppress + const int _maxT, _minT, _numT; // The minimal and maximal dimensions of the template + + int _Clr; // + static const char* _clrName[3]; + + DataSetVOC &_voc; // The dataset for training, testing + string _modelName, _trainDirSI, _bbResDir; + + vecI _svmSzIdxs; // Indexes of active size. It's equal to _svmFilters.size() and _svmReW1f.rows + Mat _svmFilter; // Filters learned at stage I, each is a _H by _W CV_32F matrix + FilterTIG _tigF; // TIG filter + Mat _svmReW1f; // Re-weight parameters learned at stage II. + +private: // Help functions + + bool filtersLoaded() {int n = _svmSzIdxs.size(); return n > 0 && _svmReW1f.size() == Size(2, n) && _svmFilter.size() == Size(_W, _W);} + + int gtBndBoxSampling(const Vec4i &bbgt, vector &samples, vecI &bbR); + + Mat getFeature(CMat &img3u, const Vec4i &bb); // Return region feature + + inline double maxIntUnion(const Vec4i &bb, const vector &bbgts) {double maxV = 0; for(size_t i = 0; i < bbgts.size(); i++) maxV = max(maxV, DataSetVOC::interUnio(bb, bbgts[i])); return maxV; } + + // Convert VOC bounding box type to OpenCV Rect + inline Rect pnt2Rect(const Vec4i &bb){int x = bb[0] - 1, y = bb[1] - 1; return Rect(x, y, bb[2] - x, bb[3] - y);} + + // Template length at quantized scale t + inline int tLen(int t){return cvRound(pow(_base, t));} + + // Sub to quantization index + inline int sz2idx(int w, int h) {w -= _minT; h -= _minT; CV_Assert(w >= 0 && h >= 0 && w < _numT && h < _numT); return h * _numT + w + 1; } + inline string strVec4i(const Vec4i &v) const {return format("%d, %d, %d, %d", v[0], v[1], v[2], v[3]);} + + void generateTrianData(); + void trainStageI(); + void trainStateII(int numPerSz = 100); + void predictBBoxSI(CMat &mag3u, ValStructVec &valBoxes, vecI &sz, int NUM_WIN_PSZ = 100, bool fast = true); + void predictBBoxSII(ValStructVec &valBoxes, const vecI &sz); + + // Calculate the image gradient: center option as in VLFeat + void gradientMag(CMat &imgBGR3u, Mat &mag1u); + + static void gradientRGB(CMat &bgr3u, Mat &mag1u); + static void gradientGray(CMat &bgr3u, Mat &mag1u); + static void gradientHSV(CMat &bgr3u, Mat &mag1u); + static void gradientXY(CMat &x1i, CMat &y1i, Mat &mag1u); + + static inline int bgrMaxDist(const Vec3b &u, const Vec3b &v) {int b = abs(u[0]-v[0]), g = abs(u[1]-v[1]), r = abs(u[2]-v[2]); b = max(b,g); return max(b,r);} + static inline int vecDist3b(const Vec3b &u, const Vec3b &v) {return abs(u[0]-v[0]) + abs(u[1]-v[1]) + abs(u[2]-v[2]);} + + //Non-maximal suppress + static void nonMaxSup(CMat &matchCost1f, ValStructVec &matchCost, int NSS = 1, int maxPoint = 50, bool fast = true); + + static void PrintVector(FILE *f, const vecD &v, CStr &name); + + vecD getVector(CMat &t1f); +}; + diff --git a/Bing/Src/ReadMe.txt b/Bing/Src/ReadMe.txt new file mode 100644 index 000000000..67bf68e9f --- /dev/null +++ b/Bing/Src/ReadMe.txt @@ -0,0 +1,49 @@ +Objectness +========== +BING Objectness proposal estimator linux/mac/windows version implementation, +runs at 1000 FPS. This code is under BSD License. +Objectness Proposal estimator运行代码,已经在linux/mac/windows下测试成功, +执行速度超过1000帧每秒。 + + +This is the 1000 FPS BING objectness linux version library for efficient +objectness proposal estimator following the CVPR 2014 paper BING, please +consider to cite and refer to this paper. + +@inproceedings{BingObj2014, + title={{BING}: Binarized Normed Gradients for Objectness Estimation at 300fps}, + author={Ming-Ming Cheng and Ziming Zhang and Wen-Yan Lin and Philip H. S. Torr}, + booktitle={IEEE CVPR}, + year={2014}, +} + +The original author Ming-Ming Cheng has already released the source code for +windows 64-bit platform. In this library, we intend to release the code for the +linux/mac/windows users. You can maintain the code with Qt Creator IDE. + +Please find the original windows code / FAQ / Paper from this link: +http://mmcheng.net/bing/ + +In order to make the code running as the original version in windows, you need +to download the images/annotations PASCAL VOC 2007 data from the website. +(http://pascallin.ecs.soton.ac.uk/challenges/VOC/voc2007/#testdata) + +We have tested the code, it produces the same accuracy results as the original windows +version, while it runs at 1111 FPS(frame per second) at Ubuntu 12.04 with a Dell T7600 +workstation computer, which has two Intel Xeon E5-2687W (3.1GHz, 1600MHz) and 64 GB +1600MHz DDR3 Memory. + +FAQ +1. To run the code, you have to install OpenCV in the your ubuntu linux system. +We specify the dependencies on opencv at +" +include_directories(/usr/local/include) +link_directories(/usr/local/lib) +" +2. You can use/debug/change the code with Qt Creator IDE on ubuntu/mac. + + +Author: Ming-Ming Cheng(程明明) removethisifyouarehuman-cmm.thu@gmail.com +Linux Author: Shuai Zheng (Kyle,郑帅) removethisifyouarehuman-szhengcvpr@gmail.com +Please find more information from http://kylezheng.org/objectness/ +Date: 19, February diff --git a/Bing/Src/ValStructVec.h b/Bing/Src/ValStructVec.h new file mode 100644 index 000000000..077ca3513 --- /dev/null +++ b/Bing/Src/ValStructVec.h @@ -0,0 +1,72 @@ +#pragma once + +/************************************************************************/ +/* A value struct vector that supports efficient sorting */ +/************************************************************************/ + +template +struct ValStructVec +{ + ValStructVec(){clear();} + inline int size() const {return sz;} + inline void clear() {sz = 0; structVals.clear(); valIdxes.clear();} + inline void reserve(int resSz){clear(); structVals.reserve(resSz); valIdxes.reserve(resSz); } + inline void pushBack(const VT& val, const ST& structVal) {valIdxes.push_back(make_pair(val, sz)); structVals.push_back(structVal); sz++;} + + inline const VT& operator ()(int i) const {return valIdxes[i].first;} // Should be called after sort + inline const ST& operator [](int i) const {return structVals[valIdxes[i].second];} // Should be called after sort + inline VT& operator ()(int i) {return valIdxes[i].first;} // Should be called after sort + inline ST& operator [](int i) {return structVals[valIdxes[i].second];} // Should be called after sort + + void sort(bool descendOrder = true); + const vector &getSortedStructVal(); + void append(const ValStructVec &newVals, int startV = 0); + + vector structVals; // struct values + +private: + int sz; // size of the value struct vector + vector> valIdxes; // Indexes after sort + bool smaller() {return true;}; + vector sortedStructVals; +}; + +template +void ValStructVec::append(const ValStructVec &newVals, int startV) +{ + int sz = newVals.size(); + for (int i = 0; i < sz; i++) + pushBack((float)((i+300)*startV)/*newVals(i)*/, newVals[i]); +} + +template +void ValStructVec::sort(bool descendOrder /* = true */) +{ + if (descendOrder) + std::sort(valIdxes.begin(), valIdxes.end(), std::greater>()); + else + std::sort(valIdxes.begin(), valIdxes.end(), std::less>()); +} + +template +const vector& ValStructVec::getSortedStructVal() +{ + sortedStructVals.resize(sz); + for (int i = 0; i < sz; i++) + sortedStructVals[i] = structVals[valIdxes[i].second]; + return sortedStructVals; +} + +/* +void valStructVecDemo() +{ + ValStructVec sVals; + sVals.pushBack(3, "String 3"); + sVals.pushBack(5, "String 5"); + sVals.pushBack(4, "String 4"); + sVals.pushBack(1, "String 1"); + sVals.sort(false); + for (int i = 0; i < sVals.size(); i++) + printf("%d, %s\n", sVals(i), _S(sVals[i])); +} +*/ \ No newline at end of file diff --git a/Bing/Src/kyheader.cpp b/Bing/Src/kyheader.cpp new file mode 100644 index 000000000..40da9c6d7 --- /dev/null +++ b/Bing/Src/kyheader.cpp @@ -0,0 +1,5 @@ +// kyheader.cpp : source file that includes just the standard includes +// Objectness.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "kyheader.h" diff --git a/Bing/Src/kyheader.h b/Bing/Src/kyheader.h new file mode 100644 index 000000000..11f95f75a --- /dev/null +++ b/Bing/Src/kyheader.h @@ -0,0 +1,110 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// +#pragma once +#pragma warning(disable: 4996) +#pragma warning(disable: 4995) +#pragma warning(disable: 4805) +#pragma warning(disable: 4267) + +#define _CRTDBG_MAP_ALLOC +#include +//#include + +//#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +#include +#include +using namespace std; + +// TODO: reference additional headers your program requires here +#include "LibLinear/linear.h" +#include + +#define CV_VERSION_ID CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION) +#ifdef _DEBUG +#define cvLIB(name) "opencv_" name CV_VERSION_ID "d" +#else +#define cvLIB(name) "opencv_" name CV_VERSION_ID +#endif + +#pragma comment( lib, cvLIB("core")) +#pragma comment( lib, cvLIB("imgproc")) +#pragma comment( lib, cvLIB("highgui")) +using namespace cv; +#ifdef WIN32 +/* windows stuff */ +#else +typedef unsigned long DWORD; +typedef unsigned short WORD; +typedef unsigned int UNINT32; +typedef bool BOOL; +typedef void *HANDLE; +typedef unsigned char byte; +#endif +typedef vector vecI; +typedef const string CStr; +typedef const Mat CMat; +typedef vector vecS; +typedef vector vecM; +typedef vector vecF; +typedef vector vecD; + +enum{CV_FLIP_BOTH = -1, CV_FLIP_VERTICAL = 0, CV_FLIP_HORIZONTAL = 1}; +#define _S(str) ((str).c_str()) +#define CHK_IND(p) ((p).x >= 0 && (p).x < _w && (p).y >= 0 && (p).y < _h) +#define CV_Assert_(expr, args) \ +{\ + if(!(expr)) {\ + string msg = cv::format args; \ + printf("%s in %s:%d\n", msg.c_str(), __FILE__, __LINE__); \ + cv::error(cv::Exception(CV_StsAssert, msg, __FUNCTION__, __FILE__, __LINE__) ); }\ +} + +// Return -1 if not in the list +template +static inline int findFromList(const T &word, const vector &strList) {size_t idx = find(strList.begin(), strList.end(), word) - strList.begin(); return idx < strList.size() ? idx : -1;} +template inline T sqr(T x) { return x * x; } // out of range risk for T = byte, ... +template inline T vecSqrDist(const Vec &v1, const Vec &v2) {T s = 0; for (int i=0; i inline T vecDist(const Vec &v1, const Vec &v2) { return sqrt(vecSqrDist(v1, v2)); } // out of range risk for T = byte, ... + +inline Rect Vec4i2Rect(Vec4i &v){return Rect(Point(v[0] - 1, v[1] - 1), Point(v[2], v[3])); } +#ifdef __WIN32 + #define INT64 long long +#else + #define INT64 long + typedef unsigned long UINT64; +#endif + +#define __POPCNT__ +#include +#include +#ifdef __WIN32 +# include +# define POPCNT(x) __popcnt(x) +# define POPCNT64(x) __popcnt64(x) +#endif +#ifndef __WIN32 +# define POPCNT(x) __builtin_popcount(x) +# define POPCNT64(x) __builtin_popcountll(x) +#endif + +#include "CmFile.h" +#include "CmTimer.h" + diff --git a/Bing/Src/main.cpp b/Bing/Src/main.cpp new file mode 100644 index 000000000..244afe9b5 --- /dev/null +++ b/Bing/Src/main.cpp @@ -0,0 +1,55 @@ +#include "kyheader.h" +#include "Objectness.h" +#include "ValStructVec.h" +#include "CmShow.h" + + +void RunObjectness(CStr &resName, double base, int W, int NSS, int numPerSz); + +void illutrateLoG() +{ + for (float delta = 0.5f; delta < 1.1f; delta+=0.1f){ + Mat f = Objectness::aFilter(delta, 8); + normalize(f, f, 0, 1, NORM_MINMAX); + CmShow::showTinyMat(format("D=%g", delta), f); + } + waitKey(0); +} + + + +int main(int argc, char* argv[]) +{ + //CStr wkDir = "D:/WkDir/DetectionProposals/VOC2007/Local/"; + //illutrateLoG(); + //RunObjectness("WinRecall.m", 2, 8, 2, 130); + //RunObjectness("WinRecall.m", 2, 8, 2, 130); + RunObjectness("WinRecall.m", 2, 8, 2, 130); + //RunObjectness("WinRecall.m", 2, 8, 2, 130); + //RunObjectness("WinRecall.m", 2, 8, 2, 130); + + return 0; +} + +void RunObjectness(CStr &resName, double base, int W, int NSS, int numPerSz) +{ + srand((unsigned int)time(NULL)); + DataSetVOC voc2007("/home/bittnt/BING/BING_beta1/VOC/VOC2007/"); + voc2007.loadAnnotations(); + //voc2007.loadDataGenericOverCls(); + + printf("Dataset:`%s' with %d training and %d testing\n", _S(voc2007.wkDir), voc2007.trainNum, voc2007.testNum); + printf("%s Base = %g, W = %d, NSS = %d, perSz = %d\n", _S(resName), base, W, NSS, numPerSz); + + Objectness objNess(voc2007, base, W, NSS); + + vector> boxesTests; + //objNess.getObjBndBoxesForTests(boxesTests, 250); + objNess.getObjBndBoxesForTestsFast(boxesTests, numPerSz); + //objNess.getRandomBoxes(boxesTests); + + //objNess.evaluatePerClassRecall(boxesTests, resName, 1000); + //objNess.illuTestReults(boxesTests); + //objNess.evaluatePAMI12(); + //objNess.evaluateIJCV13(); +} diff --git a/Bing/Src/xml2yaml.m b/Bing/Src/xml2yaml.m new file mode 100644 index 000000000..b78616577 --- /dev/null +++ b/Bing/Src/xml2yaml.m @@ -0,0 +1,22 @@ +%% Convert the file type of opencv xml annotations to yaml thus it can be read by opencv +% This functions relies on http://code.google.com/p/yamlmatlab/ +% The results needs to be further refined to deal with indentation problem + +function xml2yaml(wkDir) + fNs = dir([wkDir '*.xml']); + fNum = length(fNs); + for i = 1:fNum + [~, nameNE, ~] = fileparts(fNs(i).name); + %fprintf('%d/%d: %s\n', i, fNum, [wkDir nameNE]); + fPathN = [wkDir nameNE '.yaml']; + x=VOCreadxml([wkDir nameNE '.xml']); + if isfield(x.annotation, 'owner') + x.annotation = rmfield(x.annotation, 'owner'); + end + names = fieldnames(x.annotation.object); + if (strcmp(names{end}, 'bndbox')) + x.annotation.object = orderfields(x.annotation.object, names([end, 1:end-1])); + end + WriteYaml(fPathN, x); + end +end \ No newline at end of file diff --git a/Bing/Src/yml.m b/Bing/Src/yml.m new file mode 100644 index 000000000..cf842575b --- /dev/null +++ b/Bing/Src/yml.m @@ -0,0 +1,17 @@ +wkDir = 'D:/WkDir/DetectionProposals/VOC2007/Annotations/'; +xml2yaml(wkDir); +wkDir = 'D:\WkDir\DetectionProposals\ImageNet\ILSVRC2012_bbox_val_v3\val\'; +xml2yaml(wkDir); + +ImgNetDir = 'D:\WkDir\DetectionProposals\ImageNet\ILSVRC2012_bbox_train_v2\'; +d = dir(ImgNetDir); +isub = [d(:).isdir]; %# returns logical vector +nameFolds = {d(isub).name}'; +nameFolds(ismember(nameFolds,{'.','..'})) = []; +for i=1:length(nameFolds) + wkDir = [ImgNetDir nameFolds{i} '\']; + fprintf('%d/%d: %s\n', i, length(nameFolds), wkDir); + xml2yaml(wkDir); +end + + From 2558c3b5e18c85e94e9563df74a55fbb15d51ba5 Mon Sep 17 00:00:00 2001 From: agam1994 Date: Thu, 14 Jul 2016 11:47:39 +0530 Subject: [PATCH 10/14] Create fetch_bing_data.sh --- data/scripts/fetch_bing_data.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 data/scripts/fetch_bing_data.sh diff --git a/data/scripts/fetch_bing_data.sh b/data/scripts/fetch_bing_data.sh new file mode 100644 index 000000000..1c2e6e251 --- /dev/null +++ b/data/scripts/fetch_bing_data.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" && pwd )" +cd $DIR + +FILE=edge_box_data.tgz +URL = "c:/users/FileLocation" + +if [ -f $FILE ]; then + echo "File already exists. Checking md5..." + os=`uname -s` + if [ "$os" = "Linux" ]; then + checksum=`md5sum $FILE | awk '{ print $1 }'` + elif [ "$os" = "Darwin" ]; then + checksum=`cat $FILE | md5` + fi + if [ "$checksum" = "$CHECKSUM" ]; then + echo "Checksum is correct. No need to download." + exit 0 + else + echo "Checksum is incorrect. Need to download again." + fi +fi + +echo "Downloading Edge boxes for COCO train, val, and test-dev set..." + +wget $URL -O $FILE + +echo "Unzipping..." + +tar zxvf $FILE + +echo "Done. Please run this command again to verify that checksum = $CHECKSUM." From a6612734de7406ac771eac690add367166994f57 Mon Sep 17 00:00:00 2001 From: agam1994 Date: Thu, 14 Jul 2016 11:52:16 +0530 Subject: [PATCH 11/14] Update imdb.py --- lib/datasets/imdb.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/datasets/imdb.py b/lib/datasets/imdb.py index 1679aba84..d7c28e394 100644 --- a/lib/datasets/imdb.py +++ b/lib/datasets/imdb.py @@ -21,7 +21,8 @@ def __init__(self, name): self._num_classes = 0 self._classes = [] self._image_index = [] - self._obj_proposer = 'edge_box' + self._obj_proposer1 = 'edge_box' + self._obj_proposer2 = 'bing' self._roidb = None self._roidb_handler = self.default_roidb # Use this dict for storing dataset specific config options From 49ffa5b8517e97e7690d245f0c8b44f9ac0f14e5 Mon Sep 17 00:00:00 2001 From: agam1994 Date: Thu, 14 Jul 2016 12:00:45 +0530 Subject: [PATCH 12/14] Update pascal_voc.py --- lib/datasets/pascal_voc.py | 52 +++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/datasets/pascal_voc.py b/lib/datasets/pascal_voc.py index 3d63373e9..f1fc944ba 100644 --- a/lib/datasets/pascal_voc.py +++ b/lib/datasets/pascal_voc.py @@ -37,7 +37,8 @@ def __init__(self, image_set, year, devkit_path=None): self._image_ext = '.jpg' self._image_index = self._load_image_set_index() # Default to roidb handler - self._roidb_handler = self.edge_box_roidb + self._roidb_handler1 = self.edge_box_roidb + self._roib_handler2 = self.bing_roib self._salt = str(uuid.uuid4()) self._comp_id = 'comp4' @@ -138,6 +139,36 @@ def edge_box_roidb(self): print 'wrote ss roidb to {}'.format(cache_file) return roidb + + + def bing_roidb(self): + """ + Return the database of bing regions of interest. + Ground-truth ROIs are also included. + + This function loads/saves from/to a cache file to speed up future calls. + """ + cache_file = os.path.join(self.cache_path, + self.name + '_bing_roidb.pkl') + + if os.path.exists(cache_file): + with open(cache_file, 'rb') as fid: + roidb = cPickle.load(fid) + print '{} ss roidb loaded from {}'.format(self.name, cache_file) + return roidb + + if int(self._year) == 2007 or self._image_set != 'test': + gt_roidb = self.gt_roidb() + ss_roidb = self._load_bing_roidb(gt_roidb) + roidb = imdb.merge_roidbs(gt_roidb, ss_roidb) + else: + roidb = self._load_bing_roidb(None) + with open(cache_file, 'wb') as fid: + cPickle.dump(roidb, fid, cPickle.HIGHEST_PROTOCOL) + print 'wrote ss roidb to {}'.format(cache_file) + + return roidb + def rpn_roidb(self): if int(self._year) == 2007 or self._image_set != 'test': @@ -177,6 +208,25 @@ def _load_edge_box_roidb(self, gt_roidb): return self.create_roidb_from_box_list(box_list, gt_roidb) + def _load_bing_roidb(self, gt_roidb): + filename = os.path.abspath(os.path.join(cfg.DATA_DIR, + 'bing_data', + self.name + '.mat')) + assert os.path.exists(filename), \ + 'bing data not found at: {}'.format(filename) + raw_data = sio.loadmat(filename)['boxes'].ravel() + + box_list = [] + for i in xrange(raw_data.shape[0]): + boxes = raw_data[i][:, (1, 0, 3, 2)] - 1 + keep = ds_utils.unique_boxes(boxes) + boxes = boxes[keep, :] + keep = ds_utils.filter_small_boxes(boxes, self.config['min_size']) + boxes = boxes[keep, :] + box_list.append(boxes) + + return self.create_roidb_from_box_list(box_list, gt_roidb) + def _load_pascal_annotation(self, index): """ Load image and bounding boxes info from XML file in the PASCAL VOC From cc5acccca1884f1753c0db42564138842f5a9ff5 Mon Sep 17 00:00:00 2001 From: agam1994 Date: Thu, 14 Jul 2016 12:02:57 +0530 Subject: [PATCH 13/14] Update config.py --- lib/fast_rcnn/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/fast_rcnn/config.py b/lib/fast_rcnn/config.py index c3db065e7..7acdcb342 100644 --- a/lib/fast_rcnn/config.py +++ b/lib/fast_rcnn/config.py @@ -90,6 +90,7 @@ # Train using these proposals __C.TRAIN.PROPOSAL_METHOD = 'edge_box' +#_C.TRAIN>PROPASAL_METHOD = 'bing' # Make minibatches from images that have similar aspect ratios (i.e. both # tall and thin or both short and wide) in order to avoid wasting computation @@ -153,6 +154,7 @@ # Test using these proposals __C.TEST.PROPOSAL_METHOD = 'edge_box' +#_C.TRAIN>PROPASAL_METHOD = 'bing' ## NMS threshold used on RPN proposals __C.TEST.RPN_NMS_THRESH = 0.7 From a732e5b3d7e369017a06d43d413e91e959f3e817 Mon Sep 17 00:00:00 2001 From: agam1994 Date: Thu, 14 Jul 2016 12:04:52 +0530 Subject: [PATCH 14/14] Update eval_recall.py --- tools/eval_recall.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/eval_recall.py b/tools/eval_recall.py index 9ebc6ddb6..ad1273eab 100755 --- a/tools/eval_recall.py +++ b/tools/eval_recall.py @@ -18,6 +18,9 @@ def parse_args(): parser.add_argument('--method', dest='method', help='proposal method', default='edge_box', type=str) + parser.add_argument('--method', dest='method', + help='proposal method', + default='bing', type=str) parser.add_argument('--rpn-file', dest='rpn_file', default=None, type=str)