Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
vadimkantorov committed Aug 31, 2016
1 parent d3002b1 commit 261daad
Show file tree
Hide file tree
Showing 24 changed files with 2,376 additions and 0 deletions.
29 changes: 29 additions & 0 deletions corloc.lua
@@ -0,0 +1,29 @@
dofile('opts.lua')
dofile('util.lua')
dofile('dataset.lua')

opts.SCORES_FILES = #arg >= 1 and arg or {opts.PATHS.SCORES_PATTERN:format('trainval')}

loaded = hdf5_load(opts.SCORES_FILES[1], {'subset', 'rois', 'labels', 'output'})
outputs = {}

for i = 1, #opts.SCORES_FILES do
outputs_i = hdf5_load(opts.SCORES_FILES[i], 'outputs')
for output_field, scores in pairs(outputs_i) do
outputs[output_field] = {}
for exampleIdx = 1, #scores do
outputs[output_field][exampleIdx] = (outputs[output_field][exampleIdx] or scores[exampleIdx]:clone():zero()):add(scores[exampleIdx]:div(#opts.SCORES_FILES))
end
end
end

res = {training_MAP = dataset_tools.meanAP(loaded.output, loaded.labels)}
for output_field, scores in pairs(outputs) do
res[output_field] = {by_class = {}, _mean = corloc(dataset[loaded.subset], {scores, loaded.rois})}
for classLabelInd, classLabel in ipairs(classLabels) do
res[output_field].by_class[classLabels[classLabelInd]] = corloc(dataset[loaded.subset], {scores, loaded.rois}, classLabelInd)
end
end

json_save(opts.PATHS.CORLOC, res)
print('result in ' .. opts.PATHS.CORLOC)
10 changes: 10 additions & 0 deletions dataset.lua
@@ -0,0 +1,10 @@
if opts.DATASET == 'VOC2007' or opts.DATASET == 'VOC2012' then
dataset_tools = dofile('pascal_voc.lua')
classLabels = dataset_tools.classLabels
numClasses = dataset_tools.numClasses
end

dataset = torch.load(opts.PATHS.DATASET_CACHED)

dofile('parallel_batch_loader.lua')
dofile('example_loader.lua')
47 changes: 47 additions & 0 deletions detection_mAP.lua
@@ -0,0 +1,47 @@
dofile('opts.lua')
dofile('util.lua')
dofile('dataset.lua')
threads = require 'threads'

overlap_threshold = 0.4
score_threshold = 1e-3 / (2 * 5)
output_field = 'output_prod'
local subset = 'test'

opts.SCORES_FILES = #arg >= 1 and arg or {opts.PATHS.SCORES_PATTERN:format(subset)}
rois = hdf5_load(opts.SCORES_FILES[1], 'rois')

scores = {}
for i = 1, #opts.SCORES_FILES do
scores_i = hdf5_load(opts.SCORES_FILES[i], 'outputs/' .. output_field)
for exampleIdx = 1, #scores_i do
scores[exampleIdx] = (scores[exampleIdx] or scores_i[exampleIdx]:clone():zero()):add(scores_i[exampleIdx]:div(#opts.SCORES_FILES))
end
end

local detrespath = dataset_tools.package_submission(opts.PATHS.DATA, dataset, opts.DATASET, subset, 'comp4_det', rois, scores, nms_mask(rois, scores, overlap_threshold, score_threshold))
local opts = opts

if dataset['test'].objectBoxes == nil then
print('detection mAP cannot be computed for ' .. opts.DATASET .. '. Quitting.')
print('VOC submission saved in ' .. detrespath)
os.exit(0)
end

res = {[output_field] = {_mean = nil, by_class = {}}}
APs = torch.FloatTensor(numClasses):zero()

jobQueue = threads.Threads(numClasses)
for classLabelInd, classLabel in ipairs(classLabels) do
jobQueue:addjob(function()
os.execute(('matlab -nodisplay -nojvm -nosplash -r "classLabel = \'%s\'; cd(\'%s\'); addpath(\'VOCcode\'); VOCinit; VOCopts.testset = \'%s\'; VOCopts.detrespath = \'%s\'; [rec, prec, ap] = VOCevaldet_fast(VOCopts, \'comp4\', classLabel, false); dlmwrite(sprintf(VOCopts.detrespath, \'resu4\', classLabel), ap); quit;"'):format(classLabel, paths.dirname(opts.PATHS.VOC_DEVKIT_VOCYEAR), subset, detrespath))
return tonumber(io.open(detrespath:format('resu4', classLabel)):read('*all'))
end, function(ap) res[output_field].by_class[classLabel] = ap; APs[classLabelInd] = ap; end)
end
jobQueue:synchronize()
os.execute('[ -t 1 ] && reset')

res[output_field]._mean = APs:mean()

json_save(opts.PATHS.DETECTION_MAP, res)
print('result in ' .. opts.PATHS.DETECTION_MAP)
124 changes: 124 additions & 0 deletions example_loader.lua
@@ -0,0 +1,124 @@
local ExampleLoader, parent = torch.class('ExampleLoader')

function ExampleLoader:__init(dataset, example_loader_opts, channel_order, rgb_pixel_means)
self.scales = {{608, 800}, {496, 656}, {400, 544}, {720, 960}, {864, 1152}}
--self.scales = {{608, 800}, {368, 480}, {432, 576}, {528, 688}, {656, 864}, {912, 1200}}

self.channel_order = {3, 2, 1} -- BGR because we use Caffe-derived models
self.rgb_pixel_means = {122.7717, 115.9465, 102.9801}
self.example_loader_opts = example_loader_opts
self.dataset = dataset
end

local function table2d(I, J, elem_generator)
local res = {}
for i = 1, I do
res[i] = {}
for j = 1, J do
res[i][j] = elem_generator(i, j)
end
end
return res
end

local function subtract_mean(dst, src, channel_order, rgb_pixel_means)
for c = 1, 3 do
dst[c]:copy(src[channel_order[c]]):add(-rgb_pixel_means[channel_order[c]])
end
end

local function rescale(img, max_height, max_width)
--local height_width = math.max(dhw_rgb:size(3), dhw_rgb:size(2))
--local im_scale = target_height_width / height_width
local scale_factor = max_height / img:size(2)
if torch.round(img:size(3) * scale_factor) > max_width then
scale_factor = math.min(scale_factor, max_width / img:size(3))
end

return image.scale(img, math.min(max_width, img:size(3) * scale_factor), math.min(max_height, img:size(2) * scale_factor))
end

local function flip(images_j, rois_j)
image.hflip(images_j, images_j)
rois_j:select(2, 1):mul(-1):add(images_j:size(3))
rois_j:select(2, 3):mul(-1):add(images_j:size(3))

local tmp = rois_j:select(2, 1):clone()
rois_j:select(2, 1):copy(rois_j:select(2, 3))
rois_j:select(2, 3):copy(tmp)
end

local function insert_dummy_dim1(...)
for _, tensor in ipairs({...}) do
tensor:resize(1, unpack(tensor:size():totable()))
end
end

function ExampleLoader:makeBatchTable(batchSize, isTrainingPhase)
local o = self:getPhaseOpts(isTrainingPhase)
local num_jittered_copies = isTrainingPhase and 2 or (1 + (o.hflips and 2 or 1) * o.numScales)

return table2d(batchSize, num_jittered_copies, function() return {torch.FloatTensor(), torch.FloatTensor(), torch.FloatTensor()} end)
end

function ExampleLoader:loadExample(exampleIdx, isTrainingPhase)
local o = self:getPhaseOpts(isTrainingPhase)

local labels_loaded = self.dataset[o.subset]:getLabels(exampleIdx)
local rois_loaded = self.dataset[o.subset]:getProposals(exampleIdx)
local jpeg_loaded = self.dataset[o.subset]:getJpegBytes(exampleIdx)
local scales = o.scales or self.scales
local channel_order, rgb_pixel_means = self.channel_order, self.rgb_pixel_means

local scale_inds = isTrainingPhase and {0, torch.random(1, o.numScales)} or torch.range(0, o.numScales):totable()
local hflips = isTrainingPhase and (o.hflips and torch.random(0, 1) or 0) or (o.hflips and 2 or 0) -- 0 is no_flip, 1 is do_flip, 2 is both
local rois_perm = isTrainingPhase and torch.randperm(rois_loaded:size(1)) or torch.range(1, rois_loaded:size(1))

return function(indexInBatch, batchTable)
image = image or require 'image'
local img_original = image.decompressJPG(jpeg_loaded, 3, 'byte')
local height_original, width_original = img_original:size(2), img_original:size(3)

local rois_scale0 = rois_loaded:index(1, rois_perm:sub(1, math.min(rois_loaded:size(1), o.numRoisPerImage)):long())
rois_scale0[1]:copy(torch.FloatTensor{0, 0, width_original - 1, height_original - 1, 0.0}:sub(1, rois_scale0:size(2)))

for j, scale_ind in ipairs(scale_inds) do
local images, rois, labels = unpack(batchTable[indexInBatch][j])

local img_scaled = scale_ind == 0 and img_original:clone() or rescale(img_original, scales[scale_ind][1], scales[scale_ind][2])
local width_scaled, height_scaled = img_scaled:size(3), img_scaled:size(2)

subtract_mean(images:resize(img_scaled:size()), img_scaled, channel_order, rgb_pixel_means)
rois:cmul(rois_scale0, torch.FloatTensor{{width_scaled / width_original, height_scaled / height_original, width_scaled / width_original, height_scaled / height_original, 1.0}}:narrow(2, 1, rois_scale0:size(2)):contiguous():expandAs(rois_scale0))
labels:resize(labels_loaded:size()):copy(labels_loaded)

if hflips == 1 then
flip(images, rois)
elseif scale_ind ~= 0 and hflips == 2 then
local jj = #batchTable[indexInBatch] - j + 2
local images_flipped, rois_flipped, labels_flipped = unpack(batchTable[indexInBatch][jj])
images_flipped:resizeAs(images):copy(images)
rois_flipped:resizeAs(rois):copy(rois)
labels_flipped:resizeAs(labels):copy(labels)
flip(images_flipped, rois_flipped)
insert_dummy_dim1(images_flipped, rois_flipped, labels_flipped)
end

insert_dummy_dim1(images, rois, labels)
end

collectgarbage()
end
end

function ExampleLoader:getNumExamples(isTrainingPhase)
return self.dataset[self:getSubset(isTrainingPhase)]:getNumExamples()
end

function ExampleLoader:getPhaseOpts(isTrainingPhase)
return isTrainingPhase and self.example_loader_opts['training'] or self.example_loader_opts['evaluate']
end

function ExampleLoader:getSubset(isTrainingPhase)
return self:getPhaseOpts(isTrainingPhase).subset
end

0 comments on commit 261daad

Please sign in to comment.