Skip to content

Commit

Permalink
refactored code, added cmdline arg capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
dionysio committed Jan 31, 2016
1 parent 86e2ebd commit 0356da3
Show file tree
Hide file tree
Showing 7 changed files with 1,004 additions and 972 deletions.
63 changes: 63 additions & 0 deletions cnnmrf.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
-- -*- coding: utf-8 -*-
require 'torch'
require 'paths'

paths.dofile('mylib/helper.lua')

-----------------------------------------
-- Parameters
-----------------------------------------



cmd = torch.CmdLine()

cmd:option('-content_name', 'potrait1', "The content image located in folder 'data/content'")
cmd:option('-style_name', 'picasso', "The style image located in folder 'data/style'")
cmd:option('-ini_method', 'image', "Initial method, set to 'image' to use the content image as the initialization; set to 'random' to use random noise.")
cmd:option('-type', 'transfer', 'transfer|syn')
cmd:option('-max_size',384, "Maximum size of the image. Larger image needs more time and memory.")
cmd:option('-backend','cudnn', "Use cudnn' for CUDA-enabled GPUs or 'clnn' for OpenCL.")
cmd:option('-mode','speed', "Try 'speed' if you have a GPU with more than 4GB memory, and try 'memory' otherwise. The 'speed' mode is significantly faster (especially for synthesizing high resolutions) at the cost of higher GPU memory. ")

cmd:option('-num_res',3, "Number of resolutions. Notice the lowest resolution image should be larger than the patch size otherwise it won't synthesize.")
cmd:option('-num_iter',{100, 100, 100}, "Number of iterations for each resolution.")
cmd:option('-mrf_layers',{12, 21}, "The layers for MRF constraint. Usualy layer 21 alone already gives decent results. Including layer 12 may improve the results but at significantly more computational cost.")
cmd:option('-mrf_weight',{1e-4, 1e-4}, "Weight for each MRF layer. Higher weights leads to more style faithful results.")
cmd:option('-mrf_patch_size',{3, 3}, "The patch size for MRF constraint. This value is defined seperately for each MRF layer.")
cmd:option('-target_num_rotation',0, 'To matching objects of different poses. This value is shared by all MRF layers. The total number of rotational copies is "2 * mrf_num_rotation + 1"')
cmd:option('-target_num_scale',0, 'To matching objects of different scales. This value is shared by all MRF layers. The total number of scaled copies is "2 * mrf_num_scale + 1"')
cmd:option('-target_sample_stride',{2, 2}, "Stride to sample mrf on style image. This value is defined seperately for each MRF layer.")
cmd:option('-mrf_confidence_threshold',{0, 0}, "Threshold for filtering out bad matching. Default value 0 means we keep all matchings. This value is defined seperately for all layers.")
cmd:option('-source_sample_stride',{2, 2}, "Stride to sample mrf on synthesis image. This value is defined seperately for each MRF layer. This settings is relevant only for syn setting.")

cmd:option('-content_layers',{21}, "The layers for content constraint")
cmd:option('-content_weight',2e1, "The weight for content constraint. Increasing this value will make the result more content faithful. Decreasing the value will make the method more style faithful. Notice this value should be increase (for example, doubled) if layer 12 is included for MRF constraint.")
cmd:option('-tv_weight',1e-3, "TV smoothness weight")
cmd:option('-scaler', 2, "Relative expansion from example to result. This settings is relevant only for syn setting.")

cmd:option('-gpu_chunck_size_1',256, "Size of chunks to split feature maps along the channel dimension. This is to save memory when normalizing the matching score in mrf layers. Use large value if you have large gpu memory. As reference we use 256 for Titan X, and 32 for Geforce GT750M 2G.")
cmd:option('-gpu_chunck_size_2',16, "Size of chuncks to split feature maps along the y dimension. This is to save memory when normalizing the matching score in mrf layers. Use large value if you have large gpu memory. As reference we use 16 for Titan X, and 2 for Geforce GT750M 2G.")

-- fixed parameters
cmd:option('-target_step_rotation', math.pi/24)
cmd:option('-target_step_scale', 1.05)
cmd:option('-output_folder', 'data/result/trans/MRF/')

cmd:option('-proto_file', 'data/models/VGG_ILSVRC_19_layers_deploy.prototxt')
cmd:option('-model_file', 'data/models/VGG_ILSVRC_19_layers.caffemodel')
cmd:option('-gpu', 0, 'Zero-indexed ID of the GPU to use')
cmd:option('-nCorrection', 25)
cmd:option('-print_iter', 10)
cmd:option('-save_iter', 10)

params = cmd:parse(arg)

local wrapper = nil
if params.type == 'transfer' then
wrapper = require 'transfer_CNNMRF_wrapper'
else
wrapper = require 'syn_CNNMRF_wrapper'
end

wrapper.main(params)
46 changes: 36 additions & 10 deletions mylib/helper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,17 @@ function computeBB(width, height, alpha)
local x0 = width / 2
local y0 = height / 2

x1r = x0+(x1-x0)*math.cos(alpha)+(y1-y0)*math.sin(alpha)
y1r = y0-(x1-x0)*math.sin(alpha)+(y1-y0)*math.cos(alpha)
local x1r = x0+(x1-x0)*math.cos(alpha)+(y1-y0)*math.sin(alpha)
local y1r = y0-(x1-x0)*math.sin(alpha)+(y1-y0)*math.cos(alpha)

x2r = x0+(x2-x0)*math.cos(alpha)+(y2-y0)*math.sin(alpha)
y2r = y0-(x2-x0)*math.sin(alpha)+(y2-y0)*math.cos(alpha)
local x2r = x0+(x2-x0)*math.cos(alpha)+(y2-y0)*math.sin(alpha)
local y2r = y0-(x2-x0)*math.sin(alpha)+(y2-y0)*math.cos(alpha)

x3r = x0+(x3-x0)*math.cos(alpha)+(y3-y0)*math.sin(alpha)
y3r = y0-(x3-x0)*math.sin(alpha)+(y3-y0)*math.cos(alpha)
local x3r = x0+(x3-x0)*math.cos(alpha)+(y3-y0)*math.sin(alpha)
local y3r = y0-(x3-x0)*math.sin(alpha)+(y3-y0)*math.cos(alpha)

x4r = x0+(x4-x0)*math.cos(alpha)+(y4-y0)*math.sin(alpha)
y4r = y0-(x4-x0)*math.sin(alpha)+(y4-y0)*math.cos(alpha)
local x4r = x0+(x4-x0)*math.cos(alpha)+(y4-y0)*math.sin(alpha)
local y4r = y0-(x4-x0)*math.sin(alpha)+(y4-y0)*math.cos(alpha)

-- print(x1r .. ' ' .. y1r .. ' ' .. x2r .. ' ' .. y2r .. ' ' .. x3r .. ' ' .. y3r .. ' ' .. x4r .. ' ' .. y4r)
if alpha > 0 then
Expand Down Expand Up @@ -139,15 +139,15 @@ function computeBB(width, height, alpha)
end

function computegrid(width, height, block_size, block_stride, flag_all)
coord_block_y = torch.range(1, height - block_size + 1, block_stride)
local coord_block_y = torch.range(1, height - block_size + 1, block_stride)
if flag_all == 1 then
if coord_block_y[#coord_block_y] < height - block_size + 1 then
local tail = torch.Tensor(1)
tail[1] = height - block_size + 1
coord_block_y = torch.cat(coord_block_y, tail)
end
end
coord_block_x = torch.range(1, width - block_size + 1, block_stride)
local coord_block_x = torch.range(1, width - block_size + 1, block_stride)
if flag_all == 1 then
if coord_block_x[#coord_block_x] < width - block_size + 1 then
local tail = torch.Tensor(1)
Expand All @@ -156,4 +156,30 @@ function computegrid(width, height, block_size, block_stride, flag_all)
end
end
return coord_block_x, coord_block_y
end

function preprocess(img)
local mean_pixel = torch.Tensor({103.939, 116.779, 123.68})
local perm = torch.LongTensor{3, 2, 1}
img = img:index(1, perm):mul(256.0)
mean_pixel = mean_pixel:view(3, 1, 1):expandAs(img)
img:add(-1, mean_pixel)
return img
end

-- Undo the above preprocessing.
function deprocess(img)
local mean_pixel = torch.Tensor({103.939, 116.779, 123.68})
mean_pixel = mean_pixel:view(3, 1, 1):expandAs(img)
img = img + mean_pixel:float()
local perm = torch.LongTensor{3, 2, 1}
img = img:index(1, perm):div(256.0)
return img
end

function run_tests(run_type, list_params)
local wrapper = run_type
for i_test = 1, #list_params do
wrapper.run_test(table.unpack(list_params[i_test]))
end
end
2 changes: 1 addition & 1 deletion mylib/mrf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ function MRFMM:updateGradInput(input, gradOutput)
end

-- local timer_AFT = torch.Timer()
max_response, max_id = torch.max(self.response, 1)
local max_response, max_id = torch.max(self.response, 1)
-- local t_aft = timer_AFT:time().real

-- local t_match = timer_MATCH:time().real
Expand Down
25 changes: 5 additions & 20 deletions run_syn.lua
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
require 'torch'
require 'nn'
require 'image'
require 'paths'

paths.dofile('mylib/myoptimizer.lua')
paths.dofile('mylib/tv.lua')
paths.dofile('mylib/mrf.lua')
paths.dofile('mylib/helper.lua')

syn_CNNMRF_wrapper = require 'syn_CNNMRF_wrapper'

-----------------------------------------
-- parameters:
-- Parameters:
-----------------------------------------
-- content_name: the content image located in folder "data/content". Notice for free synthesis this image is only used for initialization (and only when "ini_method" is set to "image")
-- style_name: the style image located in folder "data/style"
Expand All @@ -23,11 +14,11 @@ syn_CNNMRF_wrapper = require 'syn_CNNMRF_wrapper'

-- mrf_layers: the layers for MRF constraint. Usualy layer 21 alone already gives decent results. Including layer 12 may improve the results but at significantly more computational cost.
-- mrf_weight: weight for each MRF layer. Default value 1e-4. For free texture synthesis it can be seen as the "learning rate" in gradient decent.
-- mrf_patch_size: the patch size for MRF constraint. By default value 3. This value is defined seperately for each MRF layer.
-- mrf_patch_size: the patch size for MRF constraint. Default value 3. This value is defined seperately for each MRF layer.
-- mrf_num_rotation: To matching objects of different poses. Default value 0. This value is shared by all MRF layers. The total number of rotatoinal copies is "2 * mrf_num_rotation + 1"
-- mrf_num_scale: To matching objects of different scales. Default value 0. This value is shared by all MRF layers. The total number of scaled copies is "2 * mrf_num_scale + 1"
-- mrf_sample_stride: stride to sample mrf on style image. Default value 2. This value is defined seperately for each MRF layer. This value is defined for each MRF layer.
-- mrf_synthesis_stride: stride to sample mrf on synthesis image. Default value 2. This value is defined seperately for each MRF layer. This value is defined for each MRF layer.
-- mrf_sample_stride: stride to sample mrf on style image. Default value 2. This value is defined seperately for each MRF layer.
-- mrf_synthesis_stride: stride to sample mrf on synthesis image. Default value 2. This value is defined seperately for each MRF layer.
-- mrf_confidence_threshold: threshold for filtering out bad matching. Default value 0 -- means we keep all matchings. This value is defined seperately for all layers.

-- tv_weight: TV smoothness weight. Default value 1e-3.
Expand Down Expand Up @@ -55,10 +46,4 @@ local list_params = {
{'2', '2', 'random', 384, 2, 3, {100, 100, 100}, {12, 21}, {1e-4, 1e-4}, {3, 3}, 1, 1, {2, 2}, {2, 2}, {0, 0}, 1e-3, 'memory', 256, 16, 'cudnn'},
}

for i_test = 1, #list_params do
local state = syn_CNNMRF_wrapper.state(list_params[i_test][1], list_params[i_test][2], list_params[i_test][3], list_params[i_test][4], list_params[i_test][5], list_params[i_test][6], list_params[i_test][7], list_params[i_test][8], list_params[i_test][9], list_params[i_test][10], list_params[i_test][11], list_params[i_test][12], list_params[i_test][13], list_params[i_test][14], list_params[i_test][15], list_params[i_test][16], list_params[i_test][17], list_params[i_test][18], list_params[i_test][19], list_params[i_test][20], list_params[i_test][21])
collectgarbage()
end


do return end
run_tests(require 'syn_CNNMRF_wrapper', list_params)
22 changes: 3 additions & 19 deletions run_trans.lua
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
require 'torch'
require 'nn'
require 'image'
require 'paths'

paths.dofile('mylib/myoptimizer.lua')
paths.dofile('mylib/tv.lua')
paths.dofile('mylib/content.lua')
paths.dofile('mylib/mrf.lua')
paths.dofile('mylib/helper.lua')

transfer_CNNMRF_wrapper = require 'transfer_CNNMRF_wrapper'

-----------------------------------------
-- Parameters
-- Parameters:
-----------------------------------------
-- content_name: the content image located in folder "data/content"
-- style_name: the style image located in folder "data/style"
Expand Down Expand Up @@ -77,12 +67,6 @@ local list_params = {
{'0', '0', 'image', 384, 3, {100, 100, 100}, {12, 21}, {1e-4, 1e-4}, {3, 3}, 3, 3, {2, 2}, {2, 2}, {0, 0}, {23}, 2e1, 1e-3, 'speed', 256, 16, 'cudnn'},
{'1', '1', 'image', 384, 3, {100, 100, 100}, {12, 21}, {1e-4, 1e-4}, {3, 3}, 3, 3, {2, 2}, {2, 2}, {0, 0}, {23}, 0.5e1, 1e-3, 'speed', 256, 16, 'cudnn'},
{'potrait1', 'picasso', 'image', 384, 3, {100, 100, 100}, {12, 21}, {1e-4, 1e-4}, {3, 3}, 1, 1, {2, 2}, {2, 2}, {0, 0}, {23}, 2e1, 1e-3, 'memory', 256, 16, 'clnn'},
}

for i_test = 1, #list_params do
local state = transfer_CNNMRF_wrapper.state(list_params[i_test][1], list_params[i_test][2], list_params[i_test][3], list_params[i_test][4], list_params[i_test][5], list_params[i_test][6], list_params[i_test][7], list_params[i_test][8], list_params[i_test][9], list_params[i_test][10], list_params[i_test][11], list_params[i_test][12], list_params[i_test][13], list_params[i_test][14], list_params[i_test][15], list_params[i_test][16], list_params[i_test][17], list_params[i_test][18], list_params[i_test][19], list_params[i_test][20], list_params[i_test][21])
collectgarbage()
end

}

do return end
run_tests(require 'transfer_CNNMRF_wrapper', list_params)
Loading

0 comments on commit 0356da3

Please sign in to comment.