├── Config.lua ├── CreateLMDBs.lua ├── Data.lua ├── ImageNetClasses ├── LICENSE ├── Main.lua ├── Models ├── AlexNet.lua ├── AlexNet_BN.lua ├── CaffeRef_Model.lua ├── GoogLeNet_BN.lua ├── GoogLeNet_BN_Original.lua ├── GoogLeNet_CUDNN3.lua ├── GoogLeNet_Full.lua ├── GoogLeNet_Model.lua ├── Inception_ResNet_v2.lua ├── Inception_v3.lua ├── Inception_v4.lua ├── MattNet.lua ├── MattNet_BN.lua ├── Model.lua ├── NewModel.lua ├── NiN_Model.lua └── OverFeat_Model.lua ├── README.md ├── TestLMDB.lua └── ValidationLabels /Config.lua: -------------------------------------------------------------------------------- 1 | local ImageNetClasses = torch.load('./ImageNetClasses') 2 | for i=1001,#ImageNetClasses.ClassName do 3 | ImageNetClasses.ClassName[i] = nil 4 | end 5 | 6 | function Key(num) 7 | return string.format('%07d',num) 8 | end 9 | 10 | 11 | return 12 | { 13 | TRAINING_PATH = '/home/ehoffer/Datasets/ImageNet/train/', --Training images location 14 | VALIDATION_PATH = '/home/ehoffer/Datasets/ImageNet/validation/', --Validation images location 15 | VALIDATION_DIR = '/home/ehoffer/Datasets/ImageNet/LMDB/validation/', --Validation LMDB location 16 | TRAINING_DIR = '/home/ehoffer/Datasets/ImageNet/LMDB/train/', --Training LMDB location 17 | ImageMinSide = 256, --Minimum side length of saved images 18 | ValidationLabels = torch.load('./ValidationLabels'), 19 | ImageNetClasses = ImageNetClasses, 20 | Normalization = {'simple', 118.380948, 61.896913}, --Default normalization -global mean, std 21 | Compressed = true, 22 | Key = Key 23 | } 24 | -------------------------------------------------------------------------------- /CreateLMDBs.lua: -------------------------------------------------------------------------------- 1 | require 'image' 2 | require 'xlua' 3 | require 'lmdb' 4 | 5 | local gm = require 'graphicsmagick' 6 | local DataProvider = require 'DataProvider' 7 | local config = require 'Config' 8 | 9 | -------------------------------Settings---------------------------------------------- 10 | 11 | local PreProcess = function(Img) 12 | local im = image.scale(Img, '^' .. config.ImageMinSide) --minimum side of ImageMinSide 13 | 14 | if im:dim() == 2 then 15 | im = im:reshape(1,im:size(1),im:size(2)) 16 | end 17 | if im:size(1) == 1 then 18 | im=torch.repeatTensor(im,3,1,1) 19 | end 20 | if im:size(1) > 3 then 21 | im = im[{{1,3},{},{}}] 22 | end 23 | return im 24 | end 25 | 26 | 27 | local LoadImgData = function(filename) 28 | local img = gm.Image(filename):toTensor('float','RGB','DHW') 29 | if img == nil then 30 | print('Image is buggy') 31 | print(filename) 32 | os.exit() 33 | end 34 | img = PreProcess(img) 35 | if config.Compressed then 36 | return image.compressJPG(img) 37 | else 38 | return img 39 | end 40 | end 41 | 42 | function NameFile(filename) 43 | local name = paths.basename(filename,'JPEG') 44 | local substring = string.split(name,'_') 45 | 46 | if substring[1] == 'ILSVRC2012' then -- Validation file 47 | local num = tonumber(substring[3]) 48 | return config.ImageNetClasses.ClassNum2Wnid[config.ValidationLabels[num]] .. '_' .. num 49 | else -- Training file 50 | return name 51 | end 52 | 53 | end 54 | 55 | function LMDBFromFilenames(filenamesProvider,env) 56 | env:open() 57 | local txn = env:txn() 58 | local cursor = txn:cursor() 59 | for i=1, filenamesProvider:size() do 60 | local filename = filenamesProvider:getItem(i) 61 | local data = {Data = LoadImgData(filename), Name = NameFile(filename)} 62 | 63 | cursor:put(config.Key(i),data, lmdb.C.MDB_NODUPDATA) 64 | if i % 1000 == 0 then 65 | txn:commit() 66 | print(env:stat()) 67 | collectgarbage() 68 | txn = env:txn() 69 | cursor = txn:cursor() 70 | end 71 | xlua.progress(i,filenamesProvider:size()) 72 | end 73 | txn:commit() 74 | env:close() 75 | 76 | end 77 | 78 | 79 | local TrainingFiles = DataProvider.FileSearcher{ 80 | Name = 'TrainingFilenames', 81 | CachePrefix = config.TRAINING_DIR, 82 | MaxNumItems = 1e8, 83 | CacheFiles = true, 84 | PathList = {config.TRAINING_PATH}, 85 | SubFolders = true, 86 | Verbose = true 87 | } 88 | local ValidationFiles = DataProvider.FileSearcher{ 89 | Name = 'ValidationFilenames', 90 | CachePrefix = config.VALIDATION_DIR, 91 | MaxNumItems = 1e8, 92 | PathList = {config.VALIDATION_PATH}, 93 | Verbose = true 94 | } 95 | 96 | local TrainDB = lmdb.env{ 97 | Path = config.TRAINING_DIR, 98 | Name = 'TrainDB' 99 | } 100 | 101 | local ValDB = lmdb.env{ 102 | Path = config.VALIDATION_DIR, 103 | Name = 'ValDB' 104 | } 105 | 106 | TrainingFiles:shuffleItems() 107 | LMDBFromFilenames(ValidationFiles, ValDB) 108 | LMDBFromFilenames(TrainingFiles, TrainDB) 109 | -------------------------------------------------------------------------------- /Data.lua: -------------------------------------------------------------------------------- 1 | require 'xlua' 2 | require 'lmdb' 3 | 4 | 5 | local DataProvider = require 'DataProvider' 6 | local config = require 'Config' 7 | 8 | 9 | function ExtractFromLMDBTrain(data) 10 | require 'image' 11 | local reSample = function(sampledImg) 12 | local sizeImg = sampledImg:size() 13 | local szx = torch.random(math.ceil(sizeImg[3]/4)) 14 | local szy = torch.random(math.ceil(sizeImg[2]/4)) 15 | local startx = torch.random(szx) 16 | local starty = torch.random(szy) 17 | return image.scale(sampledImg:narrow(2,starty,sizeImg[2]-szy):narrow(3,startx,sizeImg[3]-szx),sizeImg[3],sizeImg[2]) 18 | end 19 | local rotate = function(angleRange) 20 | local applyRot = function(Data) 21 | local angle = torch.randn(1)[1]*angleRange 22 | local rot = image.rotate(Data,math.rad(angle),'bilinear') 23 | return rot 24 | end 25 | return applyRot 26 | end 27 | 28 | local wnid = string.split(data.Name,'_')[1] 29 | local class = config.ImageNetClasses.Wnid2ClassNum[wnid] 30 | local img = data.Data 31 | if config.Compressed then 32 | img = image.decompressJPG(img,3,'byte') 33 | end 34 | 35 | if math.min(img:size(2), img:size(3)) ~= config.ImageMinSide then 36 | img = image.scale(img, '^' .. config.ImageMinSide) 37 | end 38 | 39 | if config.Augment == 3 then 40 | img = rotate(0.1)(img) 41 | img = reSample(img) 42 | elseif config.Augment == 2 then 43 | img = reSample(img) 44 | end 45 | local startX = math.random(img:size(3)-config.InputSize[3]+1) 46 | local startY = math.random(img:size(2)-config.InputSize[2]+1) 47 | 48 | img = img:narrow(3,startX,config.InputSize[3]):narrow(2,startY,config.InputSize[2]) 49 | local hflip = torch.random(2)==1 50 | if hflip then 51 | img = image.hflip(img) 52 | end 53 | 54 | return img, class 55 | end 56 | 57 | function ExtractFromLMDBTest(data) 58 | require 'image' 59 | local wnid = string.split(data.Name,'_')[1] 60 | local class = config.ImageNetClasses.Wnid2ClassNum[wnid] 61 | local img = data.Data 62 | if config.Compressed then 63 | img = image.decompressJPG(img,3,'byte') 64 | end 65 | 66 | if (math.min(img:size(2), img:size(3)) ~= config.ImageMinSide) then 67 | img = image.scale(img, '^' .. config.ImageMinSide) 68 | end 69 | 70 | local startX = math.ceil((img:size(3)-config.InputSize[3]+1)/2) 71 | local startY = math.ceil((img:size(2)-config.InputSize[2]+1)/2) 72 | img = img:narrow(3,startX,config.InputSize[3]):narrow(2,startY,config.InputSize[2]) 73 | return img, class 74 | end 75 | 76 | function Keys(tensor) 77 | local tbl = {} 78 | for i=1,tensor:size(1) do 79 | tbl[i] = config.Key(tensor[i]) 80 | end 81 | return tbl 82 | end 83 | 84 | function EstimateMeanStd(DB, typeVal, numEst) 85 | local typeVal = typeVal or 'simple' 86 | local numEst = numEst or 10000 87 | local x = torch.FloatTensor(numEst ,unpack(config.InputSize)) 88 | local randKeys = Keys(torch.randperm(DB:size()):narrow(1,1,numEst)) 89 | DB:CacheRand(randKeys, x) 90 | local dp = DataProvider.Container{ 91 | Source = {x, nil} 92 | } 93 | return {typeVal, dp:normalize(typeVal)} 94 | end 95 | 96 | local TrainDB = DataProvider.LMDBProvider{ 97 | Source = lmdb.env({Path = config.TRAINING_DIR, RDONLY = true}), 98 | ExtractFunction = ExtractFromLMDBTrain 99 | } 100 | local ValDB = DataProvider.LMDBProvider{ 101 | Source = lmdb.env({Path = config.VALIDATION_DIR , RDONLY = true}), 102 | ExtractFunction = ExtractFromLMDBTest 103 | } 104 | 105 | 106 | 107 | return { 108 | ImageNetClasses = config.ImageNetClasses, 109 | ValDB = ValDB, 110 | TrainDB = TrainDB, 111 | } 112 | -------------------------------------------------------------------------------- /ImageNetClasses: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eladhoffer/ImageNet-Training/6bc23d9a5f7abe2b527977cb571e34dd893dc86b/ImageNetClasses -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Elad Hoffer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Main.lua: -------------------------------------------------------------------------------- 1 | require 'torch' 2 | require 'optim' 3 | require 'pl' 4 | require 'eladtools' 5 | require 'trepl' 6 | local DataProvider = require 'DataProvider' 7 | 8 | ---------------------------------------------------------------------- 9 | 10 | cmd = torch.CmdLine() 11 | cmd:addTime() 12 | cmd:text() 13 | cmd:text('Training a network on ILSVRC ImageNet task') 14 | cmd:text() 15 | cmd:text('==>Options') 16 | 17 | cmd:text('===>Model And Training Regime') 18 | cmd:option('-modelsFolder', './Models/', 'Models Folder') 19 | cmd:option('-network', 'AlexNet', 'Model file - must return valid network.') 20 | cmd:option('-LR', 0.01, 'learning rate') 21 | cmd:option('-LRDecay', 0, 'learning rate decay (in # samples)') 22 | cmd:option('-weightDecay', 5e-4, 'L2 penalty on the weights') 23 | cmd:option('-momentum', 0.9, 'momentum') 24 | cmd:option('-batchSize', 128, 'batch size') 25 | cmd:option('-optimization', 'sgd', 'optimization method') 26 | cmd:option('-seed', 123, 'torch manual random number generator seed') 27 | cmd:option('-epoch', -1, 'number of epochs to train, -1 for unbounded') 28 | cmd:option('-testonly', false, 'Just test loaded net on validation set') 29 | 30 | cmd:text('===>Platform Optimization') 31 | cmd:option('-threads', 8, 'number of threads') 32 | cmd:option('-type', 'cuda', 'float or cuda') 33 | cmd:option('-bufferSize', 5120, 'buffer size') 34 | cmd:option('-devid', 1, 'device ID (if using CUDA)') 35 | cmd:option('-nGPU', 1, 'num of gpu devices used') 36 | cmd:option('-constBatchSize', false, 'do not allow varying batch sizes - e.g for ccn2 kernel') 37 | 38 | cmd:text('===>Save/Load Options') 39 | cmd:option('-load', '', 'load existing net weights') 40 | cmd:option('-save', os.date():gsub(' ',''), 'save directory') 41 | cmd:option('-optState', false, 'Save optimization state every epoch') 42 | cmd:option('-checkpoint', 0, 'Save a weight check point every n samples. 0 for off') 43 | 44 | cmd:text('===>Data Options') 45 | cmd:option('-augment', 1, 'data augmentation level - {1 - simple mirror and crops, 2 +scales, 3 +rotations}') 46 | cmd:option('-estMeanStd', 'preDef', 'estimate mean and std. Options: {preDef, simple, channel, image}') 47 | cmd:option('-shuffle', true, 'shuffle training samples') 48 | 49 | 50 | opt = cmd:parse(arg or {}) 51 | opt.network = opt.modelsFolder .. paths.basename(opt.network, '.lua') 52 | opt.save = paths.concat('./Results', opt.save) 53 | torch.setnumthreads(opt.threads) 54 | torch.manualSeed(opt.seed) 55 | torch.setdefaulttensortype('torch.FloatTensor') 56 | 57 | if opt.type == 'cuda' then 58 | cutorch.setDevice(opt.devid) 59 | cutorch.manualSeed(opt.seed) 60 | end 61 | 62 | ---------------------------------------------------------------------- 63 | local config = require 'Config' 64 | 65 | -- Model + Loss: 66 | local model = require(opt.network) 67 | local loss = model.loss or nn.ClassNLLCriterion() 68 | local trainRegime = model.regime 69 | local normalization = model.normalization or config.Normalization 70 | 71 | config.InputSize = model.inputSize or {3, 224, 224} 72 | config.ImageMinSide = model.rescaleImgSize or config.ImageMinSide 73 | 74 | model = model.model or model --case of table model 75 | 76 | if paths.filep(opt.load) then 77 | model = torch.load(opt.load) 78 | print('==>Loaded Net from: ' .. opt.load) 79 | end 80 | 81 | local data = require 'Data' 82 | 83 | -- classes 84 | local classes = data.ImageNetClasses.ClassName 85 | 86 | -- This matrix records the current confusion across classes 87 | local confusion = optim.ConfusionMatrix(classes) 88 | 89 | local AllowVarBatch = not opt.constBatchSize 90 | 91 | ---------------------------------------------------------------------- 92 | 93 | 94 | -- Output files configuration 95 | os.execute('mkdir -p ' .. opt.save) 96 | os.execute('cp ' .. opt.network .. '.lua ' .. opt.save) 97 | 98 | cmd:log(opt.save .. '/Log.txt', opt) 99 | local netFilename = paths.concat(opt.save, 'Net') 100 | local logFilename = paths.concat(opt.save,'ErrorRate.log') 101 | local optStateFilename = paths.concat(opt.save,'optState') 102 | local Log = optim.Logger(logFilename) 103 | ---------------------------------------------------------------------- 104 | 105 | local TensorType = 'torch.FloatTensor' 106 | if opt.type =='cuda' then 107 | model:cuda() 108 | loss = loss:cuda() 109 | TensorType = 'torch.CudaTensor' 110 | end 111 | 112 | 113 | 114 | ---Support for multiple GPUs - currently data parallel scheme 115 | if opt.nGPU > 1 then 116 | local net = model 117 | model = nn.DataParallelTable(1) 118 | for i = 1, opt.nGPU do 119 | cutorch.setDevice(i) 120 | model:add(net:clone():cuda(), i) -- Use the ith GPU 121 | end 122 | cutorch.setDevice(opt.devid) 123 | end 124 | 125 | -- Optimization configuration 126 | local Weights,Gradients = model:getParameters() 127 | 128 | local savedModel --savedModel - lower footprint model to save 129 | if opt.nGPU > 1 then 130 | savedModel = model.modules[1]:clone('weight','bias','running_mean','running_std') 131 | else 132 | savedModel = model:clone('weight','bias','running_mean','running_std') 133 | end 134 | 135 | ---------------------------------------------------------------------- 136 | if opt.estMeanStd ~= 'preDef' then 137 | normalization = EstimateMeanStd(data.TrainDB, opt.estMeanStd) 138 | end 139 | 140 | if #normalization>0 then 141 | print '\n==> Normalization' 142 | if normalization[1] == 'simple' or normalization[1] == 'channel' then 143 | print(unpack(normalization)) 144 | else 145 | print(normalization[1]) 146 | end 147 | end 148 | 149 | print '\n==> Network' 150 | print(model) 151 | print('\n==>' .. Weights:nElement() .. ' Parameters') 152 | 153 | print '\n==> Loss' 154 | print(loss) 155 | 156 | if trainRegime then 157 | print '\n==> Training Regime' 158 | table.foreach(trainRegime, function(x, val) print(string.format('%012s',x), unpack(val)) end) 159 | end 160 | 161 | 162 | ------------------Optimization Configuration-------------------------- 163 | 164 | local optimState = { 165 | learningRate = opt.LR, 166 | momentum = opt.momentum, 167 | weightDecay = opt.weightDecay, 168 | learningRateDecay = opt.LRDecay, 169 | dampening = 0 170 | } 171 | 172 | local optimizer = Optimizer{ 173 | Model = model, 174 | Loss = loss, 175 | OptFunction = _G.optim[opt.optimization], 176 | OptState = optimState, 177 | Parameters = {Weights, Gradients}, 178 | Regime = trainRegime 179 | } 180 | 181 | ---------------------------------------------------------------------- 182 | local function Forward(DB, train) 183 | confusion:zero() 184 | 185 | local SizeData = DB:size() 186 | if not AllowVarBatch then SizeData = math.floor(SizeData/opt.batchSize)*opt.batchSize end 187 | local dataIndices = torch.range(1, SizeData, opt.bufferSize):long() 188 | if train and opt.shuffle then --shuffle batches from LMDB 189 | dataIndices = dataIndices:index(1, torch.randperm(dataIndices:size(1)):long()) 190 | end 191 | 192 | local numBuffers = 2 193 | local currBuffer = 1 194 | local BufferSources = {} 195 | for i=1,numBuffers do 196 | BufferSources[i] = DataProvider.Container{ 197 | Source = {torch.ByteTensor(),torch.IntTensor()} 198 | } 199 | end 200 | 201 | 202 | local currBatch = 1 203 | 204 | local BufferNext = function() 205 | currBuffer = currBuffer%numBuffers +1 206 | if currBatch > dataIndices:size(1) then BufferSources[currBuffer] = nil return end 207 | local sizeBuffer = math.min(opt.bufferSize, SizeData - dataIndices[currBatch]+1) 208 | BufferSources[currBuffer].Data:resize(sizeBuffer ,unpack(config.InputSize)) 209 | BufferSources[currBuffer].Labels:resize(sizeBuffer) 210 | DB:asyncCacheSeq(config.Key(dataIndices[currBatch]), sizeBuffer, BufferSources[currBuffer].Data, BufferSources[currBuffer].Labels) 211 | currBatch = currBatch + 1 212 | end 213 | 214 | local MiniBatch = DataProvider.Container{ 215 | Name = 'GPU_Batch', 216 | MaxNumItems = opt.batchSize, 217 | Source = BufferSources[currBuffer], 218 | TensorType = TensorType 219 | } 220 | 221 | 222 | local yt = MiniBatch.Labels 223 | local y = torch.Tensor() 224 | local x = MiniBatch.Data 225 | local NumSamples = 0 226 | local lossVal = 0 227 | local currLoss = 0 228 | 229 | BufferNext() 230 | 231 | while NumSamples < SizeData do 232 | DB:synchronize() 233 | MiniBatch:reset() 234 | MiniBatch.Source = BufferSources[currBuffer] 235 | if train and opt.shuffle then MiniBatch.Source:shuffleItems() end 236 | BufferNext() 237 | 238 | while MiniBatch:getNextBatch() do 239 | if #normalization>0 then MiniBatch:normalize(unpack(normalization)) end 240 | if train then 241 | y, currLoss = optimizer:optimize(x, yt) 242 | if opt.nGPU > 1 then 243 | model:syncParameters() 244 | end 245 | else 246 | y = model:forward(x) 247 | currLoss = loss:forward(y,yt) 248 | end 249 | lossVal = currLoss + lossVal 250 | if type(y) == 'table' then --table results - always take first prediction 251 | y = y[1] 252 | end 253 | confusion:batchAdd(y,yt) 254 | NumSamples = NumSamples + x:size(1) 255 | xlua.progress(NumSamples, SizeData) 256 | end 257 | 258 | if train and opt.checkpoint >0 and (currBatch % math.ceil(opt.checkpoint/opt.bufferSize) == 0) then 259 | print(NumSamples) 260 | confusion:updateValids() 261 | print('\nAfter ' .. NumSamples .. ' samples, current error is: ' .. 1-confusion.totalValid .. '\n') 262 | torch.save(netFilename .. '_checkpoint' .. '.t7', savedModel) 263 | end 264 | collectgarbage() 265 | end 266 | xlua.progress(NumSamples, SizeData) 267 | return(lossVal/math.ceil(SizeData/opt.batchSize)) 268 | end 269 | 270 | local function Train(Data) 271 | model:training() 272 | return Forward(Data, true) 273 | end 274 | 275 | local function Test(Data) 276 | model:evaluate() 277 | return Forward(Data, false) 278 | end 279 | 280 | ------------------------------ 281 | data.ValDB:threads() 282 | data.TrainDB:threads() 283 | 284 | 285 | if opt.testonly then opt.epoch = 2 end 286 | local epoch = 1 287 | 288 | while epoch ~= opt.epoch do 289 | local ErrTrain, LossTrain 290 | if not opt.testonly then 291 | print('\nEpoch ' .. epoch ..'\n') 292 | optimizer:updateRegime(epoch, true) 293 | LossTrain = Train(data.TrainDB) 294 | torch.save(netFilename .. '_' .. epoch .. '.t7', savedModel) 295 | if opt.optState then 296 | torch.save(optStateFilename .. '_epoch_' .. epoch .. '.t7', optimState) 297 | end 298 | confusion:updateValids() 299 | ErrTrain = (1-confusion.totalValid) 300 | print('\nTraining Loss: ' .. LossTrain) 301 | print('Training Classification Error: ' .. ErrTrain) 302 | end 303 | 304 | local LossVal = Test(data.ValDB) 305 | confusion:updateValids() 306 | local ErrVal = (1-confusion.totalValid) 307 | 308 | 309 | print('\nValidation Loss: ' .. LossVal) 310 | print('Validation Classification Error = ' .. ErrVal) 311 | 312 | if not opt.testonly then 313 | Log:add{['Training Error']= ErrTrain, ['Validation Error'] = ErrVal} 314 | Log:style{['Training Error'] = '-', ['Validation Error'] = '-'} 315 | Log:plot() 316 | end 317 | 318 | epoch = epoch + 1 319 | end 320 | -------------------------------------------------------------------------------- /Models/AlexNet.lua: -------------------------------------------------------------------------------- 1 | require 'cudnn' 2 | require 'cunn' 3 | local SpatialConvolution = cudnn.SpatialConvolution--lib[1] 4 | local SpatialMaxPooling = cudnn.SpatialMaxPooling--lib[2] 5 | 6 | -- from https://code.google.com/p/cuda-convnet2/source/browse/layers/layers-imagenet-1gpu.cfg 7 | -- this is AlexNet that was presented in the One Weird Trick paper. http://arxiv.org/abs/1404.5997 8 | local features = nn.Sequential() 9 | features:add(SpatialConvolution(3,64,11,11,4,4,2,2)) -- 224 -> 55 10 | features:add(cudnn.ReLU(true)) 11 | features:add(SpatialMaxPooling(3,3,2,2)) -- 55 -> 27 12 | features:add(SpatialConvolution(64,192,5,5,1,1,2,2)) -- 27 -> 27 13 | features:add(cudnn.ReLU(true)) 14 | features:add(SpatialMaxPooling(3,3,2,2)) -- 27 -> 13 15 | features:add(SpatialConvolution(192,384,3,3,1,1,1,1)) -- 13 -> 13 16 | features:add(cudnn.ReLU(true)) 17 | features:add(SpatialConvolution(384,256,3,3,1,1,1,1)) -- 13 -> 13 18 | features:add(cudnn.ReLU(true)) 19 | features:add(SpatialConvolution(256,256,3,3,1,1,1,1)) -- 13 -> 13 20 | features:add(cudnn.ReLU(true)) 21 | features:add(SpatialMaxPooling(3,3,2,2)) -- 13 -> 6 22 | 23 | local classifier = nn.Sequential() 24 | classifier:add(nn.View(256*6*6)) 25 | classifier:add(nn.Dropout(0.5)) 26 | classifier:add(nn.Linear(256*6*6, 4096)) 27 | classifier:add(nn.Threshold(0, 1e-6)) 28 | classifier:add(nn.Dropout(0.5)) 29 | classifier:add(nn.Linear(4096, 4096)) 30 | classifier:add(nn.Threshold(0, 1e-6)) 31 | classifier:add(nn.Linear(4096, 1000)) 32 | classifier:add(nn.LogSoftMax()) 33 | 34 | local model = nn.Sequential() 35 | 36 | model:add(features):add(classifier) 37 | 38 | return { 39 | model = model, 40 | regime = { 41 | epoch = {1, 19, 30, 44, 53 }, 42 | learningRate = {1e-2, 5e-3, 1e-3, 5e-4, 1e-4}, 43 | weightDecay = {5e-4, 5e-4, 0, 0, 0 } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Models/AlexNet_BN.lua: -------------------------------------------------------------------------------- 1 | 2 | require 'cudnn' 3 | require 'cunn' 4 | local SpatialConvolution = cudnn.SpatialConvolution--lib[1] 5 | local SpatialMaxPooling = cudnn.SpatialMaxPooling--lib[2] 6 | 7 | -- from https://code.google.com/p/cuda-convnet2/source/browse/layers/layers-imagenet-1gpu.cfg 8 | -- this is AlexNet that was presented in the One Weird Trick paper. http://arxiv.org/abs/1404.5997 9 | local features = nn.Sequential() 10 | features:add(SpatialConvolution(3,64,11,11,4,4,2,2)) -- 224 -> 55 11 | features:add(SpatialMaxPooling(3,3,2,2)) -- 55 -> 27 12 | features:add(cudnn.ReLU(true)) 13 | features:add(nn.SpatialBatchNormalization(64,nil,nil,false)) 14 | features:add(SpatialConvolution(64,192,5,5,1,1,2,2)) -- 27 -> 27 15 | features:add(SpatialMaxPooling(3,3,2,2)) -- 27 -> 13 16 | features:add(cudnn.ReLU(true)) 17 | features:add(nn.SpatialBatchNormalization(192,nil,nil,false)) 18 | features:add(SpatialConvolution(192,384,3,3,1,1,1,1)) -- 13 -> 13 19 | features:add(cudnn.ReLU(true)) 20 | features:add(nn.SpatialBatchNormalization(384,nil,nil,false)) 21 | features:add(SpatialConvolution(384,256,3,3,1,1,1,1)) -- 13 -> 13 22 | features:add(cudnn.ReLU(true)) 23 | features:add(nn.SpatialBatchNormalization(256,nil,nil,false)) 24 | features:add(SpatialConvolution(256,256,3,3,1,1,1,1)) -- 13 -> 13 25 | features:add(SpatialMaxPooling(3,3,2,2)) -- 13 -> 6 26 | features:add(cudnn.ReLU(true)) 27 | features:add(nn.SpatialBatchNormalization(256,nil,nil,false)) 28 | 29 | local classifier = nn.Sequential() 30 | classifier:add(nn.View(256*6*6)) 31 | classifier:add(nn.Dropout(0.5)) 32 | classifier:add(nn.Linear(256*6*6, 4096)) 33 | classifier:add(nn.Threshold(0, 1e-6)) 34 | classifier:add(nn.BatchNormalization(4096,nil,nil,false)) 35 | classifier:add(nn.Dropout(0.5)) 36 | classifier:add(nn.Linear(4096, 4096)) 37 | classifier:add(nn.Threshold(0, 1e-6)) 38 | classifier:add(nn.BatchNormalization(4096,nil,nil,false)) 39 | classifier:add(nn.Linear(4096, 1000)) 40 | classifier:add(nn.LogSoftMax()) 41 | 42 | local model = nn.Sequential() 43 | 44 | function fillBias(m) 45 | for i=1, #m.modules do 46 | if m:get(i).bias then 47 | m:get(i).bias:fill(0.1) 48 | end 49 | end 50 | end 51 | 52 | --fillBias(features) 53 | --fillBias(classifier) 54 | model:add(features):add(classifier) 55 | 56 | return model 57 | 58 | -------------------------------------------------------------------------------- /Models/CaffeRef_Model.lua: -------------------------------------------------------------------------------- 1 | require 'ccn2' 2 | require 'cunn' 3 | local model = nn.Sequential() 4 | model:add(nn.Transpose({1,4},{1,3},{1,2})) 5 | model:add(ccn2.SpatialConvolution(3, 96, 11, 4, 0, 1)) 6 | model:add(nn.ReLU()) 7 | model:add(ccn2.SpatialMaxPooling(3, 2)) 8 | model:add(ccn2.SpatialCrossResponseNormalization(5, 0.0001, 0.75)) 9 | model:add(ccn2.SpatialConvolution(96, 256, 5, 1, 2, 2)) 10 | model:add(nn.ReLU()) 11 | model:add(ccn2.SpatialMaxPooling(3, 2)) 12 | model:add(ccn2.SpatialCrossResponseNormalization(5, 0.0001, 0.75)) 13 | model:add(ccn2.SpatialConvolution(256, 384, 3, 1, 1, 1)) 14 | model:add(nn.ReLU()) 15 | model:add(ccn2.SpatialConvolution(384, 384, 3, 1, 1, 2)) 16 | model:add(nn.ReLU()) 17 | model:add(ccn2.SpatialConvolution(384, 256, 3, 1, 1, 2)) 18 | model:add(nn.ReLU()) 19 | model:add(ccn2.SpatialMaxPooling(3, 2)) 20 | model:add(nn.Transpose({4,1},{4,2},{4,3})) 21 | model:add(nn.View(9216)) 22 | model:add(nn.Linear(9216, 4096)) 23 | model:add(nn.ReLU()) 24 | model:add(nn.Dropout(0.5)) 25 | model:add(nn.Linear(4096, 4096)) 26 | model:add(nn.ReLU()) 27 | model:add(nn.Dropout(0.5)) 28 | model:add(nn.Linear(4096, 1000)) 29 | model:add(nn.LogSoftMax()) 30 | model:cuda() 31 | 32 | return model 33 | -------------------------------------------------------------------------------- /Models/GoogLeNet_BN.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | require 'cunn' 3 | require 'cudnn' 4 | 5 | local DimConcat = 2 6 | 7 | local SpatialConvolution = cudnn.SpatialConvolution 8 | local SpatialMaxPooling = cudnn.SpatialMaxPooling 9 | local SpatialAveragePooling = cudnn.SpatialAveragePooling 10 | local ReLU = cudnn.ReLU 11 | 12 | local BNInception = false 13 | 14 | ---------------------------------------Inception Modules------------------------------------------------- 15 | local Inception = function(nInput, n1x1, n3x3r, n3x3, dn3x3r, dn3x3, nPoolProj, type_pool,stride) 16 | local stride = stride or 1 17 | local InceptionModule = nn.Concat(DimConcat) 18 | 19 | if n1x1>0 then 20 | InceptionModule:add(nn.Sequential():add(SpatialConvolution(nInput,n1x1,1,1,stride,stride))) 21 | end 22 | 23 | if n3x3>0 and n3x3r>0 then 24 | local Module_3x3 = nn.Sequential() 25 | Module_3x3:add(SpatialConvolution(nInput,n3x3r,1,1)):add(ReLU(true)) 26 | 27 | if BNInception then 28 | Module_3x3:add(nn.SpatialBatchNormalization(n3x3r,nil,nil,false)) 29 | end 30 | 31 | Module_3x3:add(SpatialConvolution(n3x3r,n3x3,3,3,stride,stride,1,1)) 32 | InceptionModule:add(Module_3x3) 33 | end 34 | 35 | if dn3x3>0 and dn3x3r>0 then 36 | local Module_d3x3 = nn.Sequential() 37 | Module_d3x3:add(SpatialConvolution(nInput,dn3x3r,1,1)):add(ReLU(true)) 38 | 39 | if BNInception then 40 | Module_d3x3:add(nn.SpatialBatchNormalization(dn3x3r,nil,nil,false)) 41 | end 42 | 43 | Module_d3x3:add(SpatialConvolution(dn3x3r,dn3x3r,3,3,1,1,1,1)):add(ReLU(true)) 44 | 45 | if BNInception then 46 | Module_d3x3:add(nn.SpatialBatchNormalization(dn3x3r,nil,nil,false)) 47 | end 48 | 49 | Module_d3x3:add(SpatialConvolution(dn3x3r,dn3x3,3,3,stride,stride,1,1)) 50 | 51 | InceptionModule:add(Module_d3x3) 52 | end 53 | 54 | local PoolProj = nn.Sequential() 55 | if type_pool == 'avg' then 56 | PoolProj:add(SpatialAveragePooling(3,3,stride,stride,1,1)) 57 | elseif type_pool == 'max' then 58 | PoolProj:add(SpatialMaxPooling(3,3,stride,stride,1,1)) 59 | end 60 | if nPoolProj > 0 then 61 | PoolProj:add(SpatialConvolution(nInput, nPoolProj, 1, 1)) 62 | end 63 | 64 | 65 | InceptionModule:add(PoolProj) 66 | return InceptionModule 67 | end 68 | 69 | ----------------------------------------------------------------------------------------------------------- 70 | 71 | local Net = nn.Sequential() 72 | 73 | local model = nn.Sequential() 74 | model:add(SpatialConvolution(3,64,7,7,2,2,3,3)) --3x224x224 -> 64x112x112 75 | model:add(ReLU(true)) 76 | model:add(SpatialMaxPooling(3,3,2,2):ceil()) -- 64x112x112 -> 64x56x56 77 | model:add(nn.SpatialBatchNormalization(64,nil,nil,false)) 78 | 79 | model:add(SpatialConvolution(64,192,3,3,1,1,1,1)) -- 64x56x56 -> 192x56x56 80 | model:add(ReLU(true)) 81 | model:add(SpatialMaxPooling(3,3,2,2):ceil()) -- 192x56x56 -> 192x28x28 82 | model:add(nn.SpatialBatchNormalization(192,nil,nil,false)) 83 | 84 | 85 | --Inception(nInput, n1x1, n3x3r, n3x3, dn3x3r, dn3x3, nPoolProj, type_pool=['avg','max',nil]) 86 | 87 | model:add(Inception(192,64,64,64,64,96,32,'avg')) --(3a) 192x28x28 -> 256x28x28 88 | model:add(ReLU(true)) 89 | model:add(nn.SpatialBatchNormalization(256,nil,nil,false)) 90 | 91 | model:add(Inception(256,64,64,96,64,96,64,'avg')) --(3b) 256x28x28 -> 320x28x28 92 | model:add(ReLU(true)) 93 | model:add(nn.SpatialBatchNormalization(320,nil,nil,false)) 94 | 95 | model:add(Inception(320,0,128,160,64,96,0,'max',2)) --(3c) 320x28x28 -> 576x14x14 96 | model:add(ReLU(true)) 97 | model:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 98 | 99 | model:add(Inception(576,224,64,96,96,128,128,'avg')) --(4a) 576x14x14 -> 576x14x14 100 | model:add(ReLU(true)) 101 | model:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 102 | 103 | model:add(Inception(576,192,96,128,96,128,128,'avg')) --(4b) 576x14x14 -> 576x14x14 104 | model:add(ReLU(true)) 105 | model:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 106 | 107 | model:add(Inception(576,160,128,160,128,160,96,'avg')) --(4c) 576x14x14 -> 576x14x14 108 | model:add(ReLU(true)) 109 | model:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 110 | 111 | model:add(Inception(576,96,128,192,160,192,96,'avg')) --(4d) 576x14x14 -> 576x14x14 112 | model:add(ReLU(true)) 113 | model:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 114 | 115 | 116 | model:add(Inception(576,0,128,192,192,256,0,'max',2)) --(4e) 576x14x14 -> 1024x7x7 117 | model:add(ReLU(true)) 118 | model:add(nn.SpatialBatchNormalization(1024,nil,nil,false)) 119 | 120 | model:add(Inception(1024,352,192,320,160,224,128,'avg')) --(5a) 1024x7x7 -> 1024x7x7 121 | model:add(ReLU(true)) 122 | model:add(nn.SpatialBatchNormalization(1024,nil,nil,false)) 123 | 124 | model:add(Inception(1024,352,192,320,192,224,128,'max')) --(5b) 1024x7x7 -> 1024x7x7 125 | model:add(ReLU(true)) 126 | model:add(nn.SpatialBatchNormalization(1024,nil,nil,false)) 127 | 128 | --Classifier 129 | model:add(cudnn.SpatialConvolution(1024,1000,1,1)) 130 | model:add(SpatialAveragePooling(7,7)) 131 | model:add(nn.View(1000):setNumInputDims(3)) 132 | model:add(nn.LogSoftMax()) 133 | 134 | ----Classifier 135 | --model:add(SpatialAveragePooling(7,7)) 136 | --model:add(nn.View(1024):setNumInputDims(3)) 137 | --model:add(nn.Linear(1024,1000)) 138 | --model:add(nn.LogSoftMax()) 139 | 140 | 141 | 142 | return model 143 | -------------------------------------------------------------------------------- /Models/GoogLeNet_BN_Original.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | require 'cunn' 3 | require 'cudnn' 4 | require 'nngraph' 5 | 6 | local DimConcat = 2 7 | 8 | local SpatialConvolution = cudnn.SpatialConvolution 9 | local SpatialMaxPooling = cudnn.SpatialMaxPooling 10 | local SpatialAveragePooling = cudnn.SpatialAveragePooling 11 | local ReLU = cudnn.ReLU 12 | 13 | local BNInception = false 14 | 15 | ---------------------------------------Inception Modules------------------------------------------------- 16 | local Inception = function(nInput, n1x1, n3x3r, n3x3, dn3x3r, dn3x3, nPoolProj, type_pool,stride) 17 | local stride = stride or 1 18 | local InceptionModule = nn.Concat(DimConcat) 19 | 20 | if n1x1>0 then 21 | InceptionModule:add(nn.Sequential():add(SpatialConvolution(nInput,n1x1,1,1,stride,stride))) 22 | end 23 | 24 | if n3x3>0 and n3x3r>0 then 25 | local Module_3x3 = nn.Sequential() 26 | Module_3x3:add(SpatialConvolution(nInput,n3x3r,1,1)):add(ReLU(true)) 27 | 28 | if BNInception then 29 | Module_3x3:add(nn.SpatialBatchNormalization(n3x3r,nil,nil,false)) 30 | end 31 | 32 | Module_3x3:add(SpatialConvolution(n3x3r,n3x3,3,3,stride,stride,1,1)) 33 | InceptionModule:add(Module_3x3) 34 | end 35 | 36 | if dn3x3>0 and dn3x3r>0 then 37 | local Module_d3x3 = nn.Sequential() 38 | Module_d3x3:add(SpatialConvolution(nInput,dn3x3r,1,1)):add(ReLU(true)) 39 | 40 | if BNInception then 41 | Module_d3x3:add(nn.SpatialBatchNormalization(dn3x3r,nil,nil,false)) 42 | end 43 | 44 | Module_d3x3:add(SpatialConvolution(dn3x3r,dn3x3r,3,3,1,1,1,1)):add(ReLU(true)) 45 | 46 | if BNInception then 47 | Module_d3x3:add(nn.SpatialBatchNormalization(dn3x3r,nil,nil,false)) 48 | end 49 | 50 | Module_d3x3:add(SpatialConvolution(dn3x3r,dn3x3,3,3,stride,stride,1,1)) 51 | 52 | InceptionModule:add(Module_d3x3) 53 | end 54 | 55 | local PoolProj = nn.Sequential() 56 | if type_pool == 'avg' then 57 | PoolProj:add(SpatialAveragePooling(3,3,stride,stride,1,1)) 58 | elseif type_pool == 'max' then 59 | PoolProj:add(SpatialMaxPooling(3,3,stride,stride,1,1)) 60 | end 61 | if nPoolProj > 0 then 62 | PoolProj:add(SpatialConvolution(nInput, nPoolProj, 1, 1)) 63 | end 64 | 65 | 66 | InceptionModule:add(PoolProj) 67 | return InceptionModule 68 | end 69 | 70 | ----------------------------------------------------------------------------------------------------------- 71 | 72 | 73 | local part1 = nn.Sequential() 74 | part1:add(SpatialConvolution(3,64,7,7,2,2,3,3)) --3x224x224 -> 64x112x112 75 | part1:add(SpatialMaxPooling(3,3,2,2):ceil()) -- 64x112x112 -> 64x56x56 76 | part1:add(nn.SpatialBatchNormalization(64)) 77 | part1:add(ReLU(true)) 78 | part1:add(SpatialConvolution(64,192,3,3,1,1,1,1)) -- 64x56x56 -> 192x56x56 79 | part1:add(SpatialMaxPooling(3,3,2,2):ceil()) -- 192x56x56 -> 192x28x28 80 | part1:add(nn.SpatialBatchNormalization(192)) 81 | part1:add(ReLU(true)) 82 | 83 | 84 | --Inception(nInput, n1x1, n3x3r, n3x3, dn3x3r, dn3x3, nPoolProj, type_pool=['avg','max',nil]) 85 | part1:add(Inception(192,64,64,64,64,96,32,'avg')) --(3a) 192x28x28 -> 256x28x28 86 | part1:add(nn.SpatialBatchNormalization(256)) 87 | part1:add(ReLU(true)) 88 | part1:add(Inception(256,64,64,96,64,96,64,'avg')) --(3b) 256x28x28 -> 320x28x28 89 | part1:add(nn.SpatialBatchNormalization(320)) 90 | part1:add(ReLU(true)) 91 | part1:add(Inception(320,0,128,160,64,96,0,'max',2)) --(3c) 320x28x28 -> 576x14x14 92 | part1:add(nn.SpatialBatchNormalization(576)) 93 | part1:add(ReLU(true)) 94 | 95 | local part2 = nn.Sequential() 96 | part2:add(Inception(576,224,64,96,96,128,128,'avg')) --(4a) 576x14x14 -> 576x14x14 97 | part2:add(nn.SpatialBatchNormalization(576)) 98 | part2:add(ReLU(true)) 99 | part2:add(Inception(576,192,96,128,96,128,128,'avg')) --(4b) 576x14x14 -> 576x14x14 100 | part2:add(nn.SpatialBatchNormalization(576)) 101 | part2:add(ReLU(true)) 102 | part2:add(Inception(576,160,128,160,128,160,96,'avg')) --(4c) 576x14x14 -> 576x14x14 103 | part2:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 104 | part2:add(ReLU(true)) 105 | 106 | local part3 = nn.Sequential() 107 | part3:add(Inception(576,96,128,192,160,192,96,'avg')) --(4d) 576x14x14 -> 576x14x14 108 | part3:add(nn.SpatialBatchNormalization(576)) 109 | part3:add(ReLU(true)) 110 | part3:add(Inception(576,0,128,192,192,256,0,'max',2)) --(4e) 576x14x14 -> 1024x7x7 111 | part3:add(nn.SpatialBatchNormalization(1024,nil,nil,false)) 112 | part3:add(ReLU(true)) 113 | 114 | part3:add(Inception(1024,352,192,320,160,224,128,'avg')) --(5a) 1024x7x7 -> 1024x7x7 115 | part3:add(nn.SpatialBatchNormalization(1024)) 116 | part3:add(ReLU(true)) 117 | part3:add(Inception(1024,352,192,320,192,224,128,'max')) --(5b) 1024x7x7 -> 1024x7x7 118 | part3:add(nn.SpatialBatchNormalization(1024)) 119 | part3:add(ReLU(true)) 120 | 121 | --Classifier 122 | local mainClassifier = nn.Sequential() 123 | mainClassifier:add(nn.Dropout(0.5)) 124 | mainClassifier:add(SpatialAveragePooling(7,7)) 125 | mainClassifier:add(nn.View(1024):setNumInputDims(3)) 126 | mainClassifier:add(nn.Linear(1024,1000)) 127 | mainClassifier:add(nn.LogSoftMax()) 128 | 129 | local auxClassifier1 = nn.Sequential() 130 | auxClassifier1:add(cudnn.SpatialAveragePooling(5,5,3,3):ceil()) 131 | auxClassifier1:add(cudnn.SpatialConvolution(576,128,1,1)) 132 | auxClassifier1:add(cudnn.ReLU(true)) 133 | auxClassifier1:add(nn.View(128*4*4):setNumInputDims(3)) 134 | auxClassifier1:add(nn.Linear(128*4*4,768)) 135 | auxClassifier1:add(cudnn.ReLU(true)) 136 | auxClassifier1:add(nn.Dropout(0.5)) 137 | auxClassifier1:add(nn.Linear(768,1000)) 138 | auxClassifier1:add(nn.LogSoftMax()) 139 | 140 | local auxClassifier2 = auxClassifier1:clone() 141 | 142 | local input = nn.Identity()() 143 | local output1 = part1(input) 144 | local branch1 = auxClassifier1(output1) 145 | local output2 = part2(output1) 146 | local branch2 = auxClassifier2(output2) 147 | local mainBranch = mainClassifier(part3(output2)) 148 | local model = nn.gModule({input},{mainBranch,branch1,branch2}) 149 | 150 | local NLL = nn.ClassNLLCriterion() 151 | local loss = nn.ParallelCriterion(true):add(NLL):add(NLL,0.3):add(NLL,0.3) 152 | 153 | return {model = model, loss = loss} 154 | -------------------------------------------------------------------------------- /Models/GoogLeNet_CUDNN3.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | require 'cunn' 3 | require 'cudnn' 4 | require 'nngraph' 5 | 6 | local DimConcat = 2 7 | 8 | local SpatialConvolution = cudnn.SpatialConvolution 9 | local SpatialMaxPooling = cudnn.SpatialMaxPooling 10 | local SpatialAveragePooling = cudnn.SpatialAveragePooling 11 | local ReLU = cudnn.ReLU 12 | 13 | local BNInception = false 14 | --local ConvMode = { 15 | -- 'CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_GEMM', 16 | -- 'CUDNN_CONVOLUTION_BWD_DATA_ALGO_0', 17 | -- 'CUDNN_CONVOLUTION_BWD_FILTER_ALGO_0' 18 | -- } 19 | local ConvMode = { 20 | nil,--'CUDNN_CONVOLUTION_FWD_ALGO_DIRECT', 21 | 'CUDNN_CONVOLUTION_BWD_DATA_ALGO_0', 22 | 'CUDNN_CONVOLUTION_BWD_FILTER_ALGO_0' 23 | } 24 | local ConvModeFFT = { 25 | 'CUDNN_CONVOLUTION_FWD_ALGO_FFT', 26 | 'CUDNN_CONVOLUTION_BWD_DATA_ALGO_FFT', 27 | 'CUDNN_CONVOLUTION_BWD_FILTER_ALGO_FFT' 28 | } 29 | ---------------------------------------Inception Modules------------------------------------------------- 30 | local Inception = function(nInput, n1x1, n3x3r, n3x3, dn3x3r, dn3x3, nPoolProj, type_pool,stride) 31 | local stride = stride or 1 32 | local InceptionModule = nn.Concat(DimConcat) 33 | 34 | if n1x1>0 then 35 | InceptionModule:add(nn.Sequential():add(SpatialConvolution(nInput,n1x1,1,1,stride,stride):setMode(unpack(ConvMode)):fastest())) 36 | end 37 | 38 | if n3x3>0 and n3x3r>0 then 39 | local Module_3x3 = nn.Sequential() 40 | Module_3x3:add(SpatialConvolution(nInput,n3x3r,1,1):setMode(unpack(ConvMode)):fastest()):add(ReLU(true)) 41 | 42 | if BNInception then 43 | Module_3x3:add(nn.SpatialBatchNormalization(n3x3r,nil,nil,false)) 44 | end 45 | 46 | Module_3x3:add(SpatialConvolution(n3x3r,n3x3,3,3,stride,stride,1,1):setMode(unpack(ConvMode)):fastest()) 47 | InceptionModule:add(Module_3x3) 48 | end 49 | 50 | if dn3x3>0 and dn3x3r>0 then 51 | local Module_d3x3 = nn.Sequential() 52 | Module_d3x3:add(SpatialConvolution(nInput,dn3x3r,1,1):setMode(unpack(ConvMode)):fastest()):add(ReLU(true)) 53 | 54 | if BNInception then 55 | Module_d3x3:add(nn.SpatialBatchNormalization(dn3x3r,nil,nil,false)) 56 | end 57 | 58 | Module_d3x3:add(SpatialConvolution(dn3x3r,dn3x3r,3,3,1,1,1,1):setMode(unpack(ConvMode)):fastest()):add(ReLU(true)) 59 | 60 | if BNInception then 61 | Module_d3x3:add(nn.SpatialBatchNormalization(dn3x3r,nil,nil,false)) 62 | end 63 | 64 | Module_d3x3:add(SpatialConvolution(dn3x3r,dn3x3,3,3,stride,stride,1,1):setMode(unpack(ConvMode)):fastest()) 65 | 66 | InceptionModule:add(Module_d3x3) 67 | end 68 | 69 | local PoolProj = nn.Sequential() 70 | if type_pool == 'avg' then 71 | PoolProj:add(SpatialAveragePooling(3,3,stride,stride,1,1)) 72 | elseif type_pool == 'max' then 73 | PoolProj:add(SpatialMaxPooling(3,3,stride,stride,1,1)) 74 | end 75 | if nPoolProj > 0 then 76 | PoolProj:add(SpatialConvolution(nInput, nPoolProj, 1, 1):setMode(unpack(ConvMode)):fastest()) 77 | end 78 | 79 | 80 | InceptionModule:add(PoolProj) 81 | return InceptionModule 82 | end 83 | 84 | ----------------------------------------------------------------------------------------------------------- 85 | 86 | 87 | local part1 = nn.Sequential() 88 | part1:add(SpatialConvolution(3,64,7,7,2,2,3,3):setMode(unpack(ConvMode)):fastest()) --3x224x224 -> 64x112x112 89 | part1:add(SpatialMaxPooling(3,3,2,2):ceil()) -- 64x112x112 -> 64x56x56 90 | part1:add(nn.SpatialBatchNormalization(64)) 91 | part1:add(ReLU(true)) 92 | part1:add(SpatialConvolution(64,192,3,3,1,1,1,1):setMode(unpack(ConvMode)):fastest()) -- 64x56x56 -> 192x56x56 93 | part1:add(SpatialMaxPooling(3,3,2,2):ceil()) -- 192x56x56 -> 192x28x28 94 | part1:add(nn.SpatialBatchNormalization(192)) 95 | part1:add(ReLU(true)) 96 | 97 | 98 | --Inception(nInput, n1x1, n3x3r, n3x3, dn3x3r, dn3x3, nPoolProj, type_pool=['avg','max',nil]) 99 | part1:add(Inception(192,64,64,64,64,96,32,'avg')) --(3a) 192x28x28 -> 256x28x28 100 | part1:add(nn.SpatialBatchNormalization(256)) 101 | part1:add(ReLU(true)) 102 | part1:add(Inception(256,64,64,96,64,96,64,'avg')) --(3b) 256x28x28 -> 320x28x28 103 | part1:add(nn.SpatialBatchNormalization(320)) 104 | part1:add(ReLU(true)) 105 | part1:add(Inception(320,0,128,160,64,96,0,'max',2)) --(3c) 320x28x28 -> 576x14x14 106 | part1:add(nn.SpatialBatchNormalization(576)) 107 | part1:add(ReLU(true)) 108 | 109 | local part2 = nn.Sequential() 110 | part2:add(Inception(576,224,64,96,96,128,128,'avg')) --(4a) 576x14x14 -> 576x14x14 111 | part2:add(nn.SpatialBatchNormalization(576)) 112 | part2:add(ReLU(true)) 113 | part2:add(Inception(576,192,96,128,96,128,128,'avg')) --(4b) 576x14x14 -> 576x14x14 114 | part2:add(nn.SpatialBatchNormalization(576)) 115 | part2:add(ReLU(true)) 116 | part2:add(Inception(576,160,128,160,128,160,96,'avg')) --(4c) 576x14x14 -> 576x14x14 117 | part2:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 118 | part2:add(ReLU(true)) 119 | 120 | local part3 = nn.Sequential() 121 | part3:add(Inception(576,96,128,192,160,192,96,'avg')) --(4d) 576x14x14 -> 576x14x14 122 | part3:add(nn.SpatialBatchNormalization(576)) 123 | part3:add(ReLU(true)) 124 | part3:add(Inception(576,0,128,192,192,256,0,'max',2)) --(4e) 576x14x14 -> 1024x7x7 125 | part3:add(nn.SpatialBatchNormalization(1024,nil,nil,false)) 126 | part3:add(ReLU(true)) 127 | 128 | part3:add(Inception(1024,352,192,320,160,224,128,'avg')) --(5a) 1024x7x7 -> 1024x7x7 129 | part3:add(nn.SpatialBatchNormalization(1024)) 130 | part3:add(ReLU(true)) 131 | part3:add(Inception(1024,352,192,320,192,224,128,'max')) --(5b) 1024x7x7 -> 1024x7x7 132 | part3:add(nn.SpatialBatchNormalization(1024)) 133 | part3:add(ReLU(true)) 134 | 135 | --Classifier 136 | local mainClassifier = nn.Sequential() 137 | mainClassifier:add(nn.Dropout(0.7)) 138 | mainClassifier:add(SpatialAveragePooling(7,7)) 139 | mainClassifier:add(nn.View(1024):setNumInputDims(3)) 140 | mainClassifier:add(nn.Linear(1024,1000)) 141 | mainClassifier:add(nn.LogSoftMax()) 142 | 143 | local auxClassifier1 = nn.Sequential() 144 | auxClassifier1:add(cudnn.SpatialAveragePooling(5,5,3,3):ceil()) 145 | auxClassifier1:add(cudnn.SpatialConvolution(576,128,1,1):setMode(unpack(ConvMode)):fastest()) 146 | auxClassifier1:add(cudnn.ReLU(true)) 147 | auxClassifier1:add(nn.View(128*4*4):setNumInputDims(3)) 148 | auxClassifier1:add(nn.Linear(128*4*4,768)) 149 | auxClassifier1:add(cudnn.ReLU(true)) 150 | auxClassifier1:add(nn.Dropout(0.7)) 151 | auxClassifier1:add(nn.Linear(768,1000)) 152 | auxClassifier1:add(nn.LogSoftMax()) 153 | 154 | local auxClassifier2 = auxClassifier1:clone() 155 | 156 | local input = nn.Identity()() 157 | local output1 = part1(input) 158 | local branch1 = auxClassifier1(output1) 159 | local output2 = part2(output1) 160 | local branch2 = auxClassifier2(output2) 161 | local mainBranch = mainClassifier(part3(output2)) 162 | local model = nn.gModule({input},{mainBranch,branch1,branch2}) 163 | 164 | local NLL = nn.ClassNLLCriterion() 165 | local loss = nn.ParallelCriterion(true):add(NLL):add(NLL,0.3):add(NLL,0.3) 166 | 167 | return { 168 | model = model, 169 | loss = loss, 170 | regime = { 171 | epoch = {1, 10, 20, 30, 40 }, 172 | learningRate = {1e-1, 1e-2, 1e-3, 1e-4, 1e-5}, 173 | weightDecay = {5e-4, 5e-4, 0, 0, 0 } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /Models/GoogLeNet_Full.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | require 'cunn' 3 | require 'cudnn' 4 | require 'nngraph' 5 | 6 | local DimConcat = 2 7 | 8 | local SpatialConvolution = cudnn.SpatialConvolution 9 | local SpatialMaxPooling = cudnn.SpatialMaxPooling 10 | local SpatialAveragePooling = cudnn.SpatialAveragePooling 11 | local ReLU = cudnn.ReLU 12 | 13 | local BNInception = false 14 | 15 | ---------------------------------------Inception Modules------------------------------------------------- 16 | local Inception = function(nInput, n1x1, n3x3r, n3x3, dn3x3r, dn3x3, nPoolProj, type_pool,stride) 17 | local stride = stride or 1 18 | local InceptionModule = nn.Concat(DimConcat) 19 | 20 | if n1x1>0 then 21 | InceptionModule:add(nn.Sequential():add(SpatialConvolution(nInput,n1x1,1,1,stride,stride))) 22 | end 23 | 24 | if n3x3>0 and n3x3r>0 then 25 | local Module_3x3 = nn.Sequential() 26 | Module_3x3:add(SpatialConvolution(nInput,n3x3r,1,1)):add(ReLU(true)) 27 | 28 | if BNInception then 29 | Module_3x3:add(nn.SpatialBatchNormalization(n3x3r,nil,nil,false)) 30 | end 31 | 32 | Module_3x3:add(SpatialConvolution(n3x3r,n3x3,3,3,stride,stride,1,1)) 33 | InceptionModule:add(Module_3x3) 34 | end 35 | 36 | if dn3x3>0 and dn3x3r>0 then 37 | local Module_d3x3 = nn.Sequential() 38 | Module_d3x3:add(SpatialConvolution(nInput,dn3x3r,1,1)):add(ReLU(true)) 39 | 40 | if BNInception then 41 | Module_d3x3:add(nn.SpatialBatchNormalization(dn3x3r,nil,nil,false)) 42 | end 43 | 44 | Module_d3x3:add(SpatialConvolution(dn3x3r,dn3x3r,3,3,1,1,1,1)):add(ReLU(true)) 45 | 46 | if BNInception then 47 | Module_d3x3:add(nn.SpatialBatchNormalization(dn3x3r,nil,nil,false)) 48 | end 49 | 50 | Module_d3x3:add(SpatialConvolution(dn3x3r,dn3x3,3,3,stride,stride,1,1)) 51 | 52 | InceptionModule:add(Module_d3x3) 53 | end 54 | 55 | local PoolProj = nn.Sequential() 56 | if type_pool == 'avg' then 57 | PoolProj:add(SpatialAveragePooling(3,3,stride,stride,1,1)) 58 | elseif type_pool == 'max' then 59 | PoolProj:add(SpatialMaxPooling(3,3,stride,stride,1,1)) 60 | end 61 | if nPoolProj > 0 then 62 | PoolProj:add(SpatialConvolution(nInput, nPoolProj, 1, 1)) 63 | end 64 | 65 | 66 | InceptionModule:add(PoolProj) 67 | return InceptionModule 68 | end 69 | 70 | ----------------------------------------------------------------------------------------------------------- 71 | 72 | 73 | local part1 = nn.Sequential() 74 | part1:add(SpatialConvolution(3,64,7,7,2,2,3,3)) --3x224x224 -> 64x112x112 75 | part1:add(ReLU(true)) 76 | part1:add(SpatialMaxPooling(3,3,2,2):ceil()) -- 64x112x112 -> 64x56x56 77 | part1:add(nn.SpatialBatchNormalization(64,nil,nil,false)) 78 | part1:add(SpatialConvolution(64,192,3,3,1,1,1,1)) -- 64x56x56 -> 192x56x56 79 | part1:add(ReLU(true)) 80 | part1:add(SpatialMaxPooling(3,3,2,2):ceil()) -- 192x56x56 -> 192x28x28 81 | part1:add(nn.SpatialBatchNormalization(192,nil,nil,false)) 82 | 83 | 84 | --Inception(nInput, n1x1, n3x3r, n3x3, dn3x3r, dn3x3, nPoolProj, type_pool=['avg','max',nil]) 85 | part1:add(Inception(192,64,64,64,64,96,32,'avg')) --(3a) 192x28x28 -> 256x28x28 86 | part1:add(ReLU(true)) 87 | part1:add(nn.SpatialBatchNormalization(256,nil,nil,false)) 88 | part1:add(Inception(256,64,64,96,64,96,64,'avg')) --(3b) 256x28x28 -> 320x28x28 89 | part1:add(ReLU(true)) 90 | part1:add(nn.SpatialBatchNormalization(320,nil,nil,false)) 91 | part1:add(Inception(320,0,128,160,64,96,0,'max',2)) --(3c) 320x28x28 -> 576x14x14 92 | part1:add(ReLU(true)) 93 | part1:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 94 | 95 | local part2 = nn.Sequential() 96 | part2:add(Inception(576,224,64,96,96,128,128,'avg')) --(4a) 576x14x14 -> 576x14x14 97 | part2:add(ReLU(true)) 98 | part2:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 99 | part2:add(Inception(576,192,96,128,96,128,128,'avg')) --(4b) 576x14x14 -> 576x14x14 100 | part2:add(ReLU(true)) 101 | part2:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 102 | part2:add(Inception(576,160,128,160,128,160,96,'avg')) --(4c) 576x14x14 -> 576x14x14 103 | part2:add(ReLU(true)) 104 | part2:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 105 | 106 | local part3 = nn.Sequential() 107 | part3:add(Inception(576,96,128,192,160,192,96,'avg')) --(4d) 576x14x14 -> 576x14x14 108 | part3:add(ReLU(true)) 109 | part3:add(nn.SpatialBatchNormalization(576,nil,nil,false)) 110 | part3:add(Inception(576,0,128,192,192,256,0,'max',2)) --(4e) 576x14x14 -> 1024x7x7 111 | part3:add(ReLU(true)) 112 | part3:add(nn.SpatialBatchNormalization(1024,nil,nil,false)) 113 | 114 | 115 | part3:add(Inception(1024,352,192,320,160,224,128,'avg')) --(5a) 1024x7x7 -> 1024x7x7 116 | part3:add(ReLU(true)) 117 | part3:add(nn.SpatialBatchNormalization(1024,nil,nil,false)) 118 | part3:add(Inception(1024,352,192,320,192,224,128,'max')) --(5b) 1024x7x7 -> 1024x7x7 119 | part3:add(ReLU(true)) 120 | part3:add(nn.SpatialBatchNormalization(1024,nil,nil,false)) 121 | 122 | --Classifier 123 | local mainClassifier = nn.Sequential() 124 | mainClassifier:add(cudnn.SpatialConvolution(1024,1000,1,1)) 125 | mainClassifier:add(SpatialAveragePooling(7,7)) 126 | mainClassifier:add(nn.View(1000):setNumInputDims(3)) 127 | mainClassifier:add(nn.LogSoftMax()) 128 | 129 | local auxClassifier1 = nn.Sequential() 130 | auxClassifier1:add(cudnn.SpatialAveragePooling(5,5,3,3):ceil()) 131 | auxClassifier1:add(cudnn.SpatialConvolution(576,128,1,1)) 132 | auxClassifier1:add(cudnn.ReLU(true)) 133 | auxClassifier1:add(nn.View(128*4*4):setNumInputDims(3)) 134 | auxClassifier1:add(nn.Linear(128*4*4,768)) 135 | auxClassifier1:add(cudnn.ReLU(true)) 136 | auxClassifier1:add(nn.Linear(768,1000)) 137 | auxClassifier1:add(nn.LogSoftMax()) 138 | 139 | local auxClassifier2 = auxClassifier1:clone() 140 | 141 | local input = nn.Identity()() 142 | local output1 = part1(input) 143 | local branch1 = auxClassifier1(output1) 144 | local output2 = part2(output1) 145 | local branch2 = auxClassifier2(output2) 146 | local mainBranch = mainClassifier(part3(output2)) 147 | local model = nn.gModule({input},{mainBranch,branch1,branch2}) 148 | 149 | local NLL = nn.ClassNLLCriterion() 150 | local loss = nn.ParallelCriterion(true):add(NLL):add(NLL,0.3):add(NLL,0.3) 151 | 152 | return {model = model, loss = loss} 153 | -------------------------------------------------------------------------------- /Models/GoogLeNet_Model.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | require 'cunn' 3 | require 'cudnn' 4 | require 'ccn2' 5 | local opt = opt or {type = 'cuda', net='new'} 6 | local DimConcat = 2 7 | 8 | ---------------------------------------Inception Modules------------------------------------------------- 9 | local Inception = function(nInput, n1x1, n3x3r, n3x3, n5x5r, n5x5, nPoolProj) 10 | local InceptionModule = nn.DepthConcat(DimConcat) 11 | InceptionModule:add(nn.Sequential():add(nn.SpatialConvolutionMM(nInput,n1x1,1,1))) 12 | InceptionModule:add(nn.Sequential():add(nn.SpatialConvolutionMM(nInput,n3x3r,1,1)):add(nn.ReLU()):add(nn.SpatialConvolutionMM(n3x3r,n3x3,3,3,1,1,1))) 13 | InceptionModule:add(nn.Sequential():add(nn.SpatialConvolutionMM(nInput,n5x5r,1,1)):add(nn.ReLU()):add(nn.SpatialConvolutionMM(n5x5r,n5x5,5,5,1,1,2))) 14 | InceptionModule:add(nn.Sequential():add(cudnn.SpatialMaxPooling(3,3,1,1)):add(nn.SpatialConvolutionMM(nInput,nPoolProj,1,1))) 15 | return InceptionModule 16 | end 17 | 18 | local AuxileryClassifier = function(nInput) 19 | local C = nn.Sequential() 20 | C:add(cudnn.SpatialAveragePooling(5,5,3,3)) 21 | C:add(nn.SpatialConvolutionMM(nInput,128,1,1)) 22 | C:add(nn.ReLU()) 23 | C:add(nn.Reshape(128*4*4)) 24 | C:add(nn.Linear(128*4*4,1024)) 25 | C:add(nn.Dropout(0.7)) 26 | C:add(nn.Linear(1024,1000)) 27 | C:add(nn.LogSoftMax()) 28 | return C 29 | end 30 | ----------------------------------------------------------------------------------------------------------- 31 | 32 | local Net = nn.Sequential() 33 | 34 | local SubNet1 = nn.Sequential() 35 | SubNet1:add(nn.SpatialConvolutionMM(3,64,7,7,2,2,4)) 36 | SubNet1:add(nn.ReLU()) 37 | SubNet1:add(cudnn.SpatialMaxPooling(3,3,2,2)) 38 | --SubNet1:add(ccn2.SpatialResponseNormalization(3)) 39 | SubNet1:add(nn.SpatialConvolutionMM(64,64,1,1)) 40 | SubNet1:add(nn.ReLU()) 41 | SubNet1:add(nn.SpatialConvolutionMM(64,192,3,3,1,1,1)) 42 | SubNet1:add(nn.ReLU()) 43 | --SubNet1:add(ccn2.SpatialResponseNormalization(3)) 44 | SubNet1:add(nn.SpatialZeroPadding(1,1,1,1)) 45 | SubNet1:add(cudnn.SpatialMaxPooling(3,3,2,2)) 46 | 47 | 48 | 49 | SubNet1:add(Inception(192,64,96,128,16,32,32)) 50 | SubNet1:add(nn.ReLU()) 51 | SubNet1:add(Inception(256,128,128,192,32,96,64)) 52 | SubNet1:add(nn.ReLU()) 53 | SubNet1:add(nn.SpatialZeroPadding(1,1,1,1)) 54 | SubNet1:add(cudnn.SpatialMaxPooling(3,3,2,2)) 55 | SubNet1:add(Inception(480,192,96,208,16,48,64)) 56 | SubNet1:add(nn.ReLU()) 57 | 58 | 59 | 60 | local SubNet2 = nn.Sequential() 61 | SubNet2:add(SubNet1) 62 | SubNet2:add(Inception(512,160,112,224,24,64,64)) 63 | SubNet2:add(nn.ReLU()) 64 | SubNet2:add(Inception(512,128,128,256,24,64,64)) 65 | SubNet2:add(nn.ReLU()) 66 | SubNet2:add(Inception(512,112,144,288,32,64,64)) 67 | SubNet2:add(nn.ReLU()) 68 | 69 | 70 | 71 | Net:add(SubNet2) 72 | Net:add(Inception(528,256,160,320,32,128,128)) 73 | Net:add(nn.ReLU()) 74 | Net:add(nn.SpatialZeroPadding(1,1,1,1)) 75 | Net:add(cudnn.SpatialMaxPooling(3,3,2,2)) 76 | 77 | 78 | Net:add(Inception(832,256,160,320,32,128,128)) 79 | Net:add(nn.ReLU()) 80 | Net:add(Inception(832,384,192,384,48,128,128)) 81 | Net:add(nn.ReLU()) 82 | Net:add(cudnn.SpatialAveragePooling(7,7,1,1)) 83 | Net:add(nn.Dropout(0.4)) 84 | Net:add(nn.Reshape(1024)) 85 | Net:add(nn.Linear(1024,1000)) 86 | Net:add(nn.LogSoftMax()) 87 | 88 | local Classifier0 = nn.Sequential() 89 | Classifier0:add(SubNet1) 90 | Classifier0:add(AuxileryClassifier(512)) 91 | 92 | local Classifier1 = nn.Sequential() 93 | Classifier1:add(SubNet2) 94 | Classifier1:add(AuxileryClassifier(528)) 95 | 96 | -- 97 | --Net:cuda() 98 | ------ Loss: NLL 99 | --Net = Classifier0 100 | local loss = nn.ClassNLLCriterion() 101 | ---------------------------------------------------------------------- 102 | if opt.type == 'cuda' then 103 | Net:cuda() 104 | loss:cuda() 105 | end 106 | 107 | ---------------------------------------------------------------------- 108 | print '==> flattening Net parameters' 109 | 110 | -- Retrieve parameters and gradients: 111 | -- this extracts and flattens all the trainable parameters of the mode 112 | -- into a 1-dim vector 113 | --end 114 | 115 | local w,dE_dw = Net:getParameters() 116 | 117 | local t = torch.load('Weights') 118 | w:copy(t) 119 | -- 120 | --local t = torch.tic(); y = Net:forward(torch.rand(128,3,224,224):cuda()) ; cutorch.synchronize(); print(torch.tic()-t) 121 | --print(SubNet1.modules[9].output:size()) 122 | --print(y:size()) 123 | 124 | 125 | -- return package: 126 | return { 127 | Net = Net, 128 | Weights = w, 129 | Grads = dE_dw, 130 | Loss = loss 131 | } 132 | 133 | -------------------------------------------------------------------------------- /Models/Inception_ResNet_v2.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | 3 | local SpatialConvolution = nn.SpatialConvolution 4 | local ReLU = nn.ReLU 5 | local SpatialBatchNormalization = nn.SpatialBatchNormalization 6 | local SpatialMaxPooling = nn.SpatialMaxPooling 7 | local SpatialAveragePooling = nn.SpatialAveragePooling 8 | 9 | local function ConvBN(nInputPlane, nOutputPlane, kW, kH, dW, dH, padW, padH) 10 | local module = nn.Sequential() 11 | module:add(SpatialConvolution(nInputPlane, nOutputPlane, kW, kH, dW, dH, padW, padH)) 12 | module:add(SpatialBatchNormalization(nOutputPlane,1e-3,nil,true)) 13 | module:add(ReLU(true)) 14 | return module 15 | end 16 | 17 | local function Tower(tbl) 18 | local module = nn.Sequential() 19 | for i=1, #tbl do 20 | module:add(tbl[i]) 21 | end 22 | return module 23 | end 24 | 25 | local function Residual(m) 26 | local module = nn.Sequential() 27 | local cat = nn.ConcatTable():add(nn.Identity()):add(m) 28 | module:add(cat):add(nn.CAddTable()) 29 | return module 30 | end 31 | 32 | 33 | local function Stem() 34 | local module = nn.Sequential() 35 | module:add(ConvBN(3,32,3,3,2,2,0,0)) 36 | module:add(ConvBN(32,32,3,3,1,1,0,0)) 37 | module:add(ConvBN(32,64,3,3,1,1,1,1)) 38 | 39 | local cat1 = nn.Concat(2) 40 | cat1:add(SpatialMaxPooling(3,3,2,2,0,0)) 41 | cat1:add(ConvBN(64,96,3,3,2,2,0,0)) 42 | 43 | local cat2 = nn.Concat(2) 44 | cat2:add(Tower{ 45 | ConvBN(160,64,1,1,1,1,0,0), 46 | ConvBN(64,64,7,1,1,1,3,0), 47 | ConvBN(64,64,1,7,1,1,0,3), 48 | ConvBN(64,96,3,3,1,1,0,0) 49 | }) 50 | cat2:add(Tower{ 51 | ConvBN(160,64,1,1,1,1,0,0), 52 | ConvBN(64,96,3,3,1,1,0,0) 53 | }) 54 | 55 | local cat3 = nn.Concat(2) 56 | cat3:add(SpatialMaxPooling(3,3,2,2,0,0)) 57 | cat3:add(ConvBN(192,192,3,3,2,2,0,0)) 58 | 59 | module:add(cat1) 60 | module:add(cat2) 61 | module:add(cat3) 62 | 63 | return module 64 | end 65 | 66 | local function Reduction_A(nInputPlane,k,l,m,n) 67 | local module = nn.Concat(2) 68 | module:add(SpatialMaxPooling(3,3,2,2,0,0)) 69 | module:add(ConvBN(nInputPlane,n,3,3,2,2,0,0)) 70 | module:add(Tower{ 71 | ConvBN(nInputPlane,k,1,1,1,1,0,0), 72 | ConvBN(k,l,3,3,1,1,1,1), 73 | ConvBN(l,m,3,3,2,2,0,0) 74 | }) 75 | return module 76 | end 77 | 78 | local function Reduction_B(nInputPlane) 79 | local module = nn.Concat(2) 80 | module:add(SpatialMaxPooling(3,3,2,2,0,0)) 81 | module:add(Tower{ 82 | ConvBN(nInputPlane,256,1,1,1,1,0,0), 83 | ConvBN(256,384,3,3,2,2,0,0) 84 | }) 85 | module:add(Tower{ 86 | ConvBN(nInputPlane,256,1,1,1,1,0,0), 87 | ConvBN(256,256,3,3,2,2,0,0) 88 | }) 89 | module:add(Tower{ 90 | ConvBN(nInputPlane,256,1,1,1,1,0,0), 91 | ConvBN(256,288,3,3,1,1,1,1), 92 | ConvBN(288,256,3,3,2,2,0,0) 93 | }) 94 | return module 95 | end 96 | 97 | local function Inception_ResNet_A(nInputPlane) 98 | local inceptionModule = nn.Concat(2) 99 | inceptionModule:add(ConvBN(nInputPlane,32,1,1,1,1,0,0)) 100 | inceptionModule:add(Tower{ 101 | ConvBN(nInputPlane,32,1,1,1,1,0,0), 102 | ConvBN(32,32,3,3,1,1,1,1) 103 | }) 104 | inceptionModule:add(Tower{ 105 | ConvBN(nInputPlane,32,1,1,1,1,0,0), 106 | ConvBN(32,48,3,3,1,1,1,1), 107 | ConvBN(48,64,3,3,1,1,1,1) 108 | }) 109 | local preActivation = nn.Sequential() 110 | preActivation:add(ReLU(true)) 111 | preActivation:add(inceptionModule) 112 | preActivation:add(SpatialConvolution(128,256,1,1,1,1,0,0)) 113 | 114 | return Residual(preActivation) 115 | end 116 | 117 | local function Inception_ResNet_B(nInputPlane) 118 | local inceptionModule = nn.Concat(2) 119 | inceptionModule:add(ConvBN(nInputPlane,192,1,1,1,1,0,0)) 120 | inceptionModule:add(Tower{ 121 | ConvBN(nInputPlane,128,1,1,1,1,0,0), 122 | ConvBN(128,160,1,7,1,1,0,3), 123 | ConvBN(160,192,7,1,1,1,3,0) 124 | }) 125 | local preActivation = nn.Sequential() 126 | preActivation:add(ReLU(true)) 127 | preActivation:add(inceptionModule) 128 | preActivation:add(SpatialConvolution(384,896,1,1,1,1,0,0)) 129 | 130 | return Residual(preActivation) 131 | end 132 | 133 | local function Inception_ResNet_C(nInputPlane) 134 | local inceptionModule = nn.Concat(2) 135 | inceptionModule:add(ConvBN(nInputPlane,192,1,1,1,1,0,0)) 136 | inceptionModule:add(Tower{ 137 | ConvBN(nInputPlane,192,1,1,1,1,0,0), 138 | ConvBN(192,224,1,3,1,1,0,1), 139 | ConvBN(224,256,3,1,1,1,1,0) 140 | }) 141 | local preActivation = nn.Sequential() 142 | preActivation:add(ReLU(true)) 143 | preActivation:add(inceptionModule) 144 | preActivation:add(SpatialConvolution(448,1792,1,1,1,1,0,0)) 145 | 146 | return Residual(preActivation) 147 | end 148 | 149 | 150 | local model = Stem() 151 | model:add(ConvBN(384,256,1,1,1,1,0,0)) 152 | 153 | for i=1,5 do 154 | model:add(Inception_ResNet_A(256)) 155 | end 156 | 157 | model:add(Reduction_A(256,256,256,256,384)) 158 | 159 | for i=1,10 do 160 | model:add(Inception_ResNet_B(896)) 161 | end 162 | 163 | model:add(Reduction_B(896)) 164 | 165 | for i=1,5 do 166 | model:add(Inception_ResNet_C(1792)) 167 | end 168 | 169 | model:add(SpatialAveragePooling(8,8,1,1)) 170 | model:add(nn.View(-1):setNumInputDims(3)) 171 | model:add(nn.Dropout(0.2)) 172 | model:add(nn.Linear(1792, 1000)) 173 | model:add(nn.LogSoftMax()) 174 | 175 | return { 176 | model = model, 177 | rescaleImgSize = 384, 178 | InputSize = {3, 299, 299} 179 | } 180 | -------------------------------------------------------------------------------- /Models/Inception_v3.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | 3 | local function ConvBN(nInputPlane, nOutputPlane, kW, kH, dW, dH, padW, padH) 4 | local module = nn.Sequential() 5 | module:add(nn.SpatialConvolution(nInputPlane, nOutputPlane, kW, kH, dW, dH, padW, padH)) 6 | module:add(nn.SpatialBatchNormalization(nOutputPlane,1e-3,nil,true)) 7 | module:add(nn.ReLU(true)) 8 | return module 9 | end 10 | 11 | local function Pooling(poolType, ...) 12 | local pooler 13 | if poolType == 'max' then 14 | pooler = nn.SpatialMaxPooling(unpack({...})) 15 | 16 | else 17 | pooler = nn.SpatialAveragePooling(unpack({...})) 18 | 19 | end 20 | return pooler 21 | end 22 | 23 | local function Tower(tbl) 24 | local module = nn.Sequential() 25 | for i=1, #tbl do 26 | module:add(tbl[i]) 27 | end 28 | return module 29 | end 30 | 31 | local function Inception(tbl) 32 | local module = nn.Concat(2) 33 | for i=1, #tbl do 34 | module:add(tbl[i]) 35 | end 36 | return module 37 | end 38 | 39 | 40 | local model = nn.Sequential() 41 | model:add(ConvBN(3,32,3,3,2,2,0,0)) 42 | model:add(ConvBN(32,32,3,3,1,1,0,0)) 43 | model:add(ConvBN(32,64,3,3,1,1,1,1)) 44 | model:add(Pooling('max',3,3,2,2,0,0)) 45 | model:add(ConvBN(64,80,1,1,1,1,0,0)) 46 | model:add(ConvBN(80,192,3,3,1,1,0,0)) 47 | model:add(Pooling('max',3,3,2,2,0,0)) 48 | 49 | model:add(Inception{ 50 | Tower{ 51 | ConvBN(192,64,1,1,1,1,0,0) 52 | }, 53 | Tower{ 54 | ConvBN(192,48,1,1,1,1,0,0), 55 | ConvBN(48,64,5,5,1,1,2,2) 56 | }, 57 | Tower{ 58 | ConvBN(192,64,1,1,1,1,0,0), 59 | ConvBN(64,96,3,3,1,1,1,1), 60 | ConvBN(96,96,3,3,1,1,1,1) 61 | }, 62 | Tower{ 63 | Pooling('average',3,3,1,1,1,1), 64 | ConvBN(192,32,1,1,1,1,0,0) 65 | } 66 | }) 67 | 68 | model:add(Inception{ 69 | Tower{ 70 | ConvBN(256,64,1,1,1,1,0,0) 71 | }, 72 | Tower{ 73 | ConvBN(256,48,1,1,1,1,0,0), 74 | ConvBN(48,64,5,5,1,1,2,2) 75 | }, 76 | Tower{ 77 | ConvBN(256,64,1,1,1,1,0,0), 78 | ConvBN(64,96,3,3,1,1,1,1), 79 | ConvBN(96,96,3,3,1,1,1,1) 80 | }, 81 | Tower{ 82 | Pooling('average',3,3,1,1,1,1), 83 | ConvBN(256,64,1,1,1,1,0,0) 84 | } 85 | }) 86 | 87 | model:add(Inception{ 88 | Tower{ 89 | ConvBN(288,64,1,1,1,1,0,0) 90 | }, 91 | Tower{ 92 | ConvBN(288,48,1,1,1,1,0,0), 93 | ConvBN(48,64,5,5,1,1,2,2), 94 | }, 95 | Tower{ 96 | ConvBN(288,64,1,1,1,1,0,0), 97 | ConvBN(64,96,3,3,1,1,1,1), 98 | ConvBN(96,96,3,3,1,1,1,1) 99 | }, 100 | Tower{ 101 | Pooling('average',3,3,1,1,1,1), 102 | ConvBN(288,64,1,1,1,1,0,0) 103 | } 104 | }) 105 | 106 | model:add(Inception{ 107 | Tower{ 108 | ConvBN(288,384,3,3,2,2,0,0) 109 | }, 110 | Tower{ 111 | ConvBN(288,64,1,1,1,1,0,0), 112 | ConvBN(64,96,3,3,1,1,1,1), 113 | ConvBN(96,96,3,3,2,2,0,0) 114 | }, 115 | Tower{ 116 | Pooling('max',3,3,2,2,0,0) 117 | } 118 | }) 119 | 120 | model:add(Inception{ 121 | Tower{ 122 | ConvBN(768,192,1,1,1,1,0,0) 123 | }, 124 | Tower{ 125 | ConvBN(768,128,1,1,1,1,0,0), 126 | ConvBN(128,128,7,1,1,1,3,0), 127 | ConvBN(128,192,1,7,1,1,0,3) 128 | }, 129 | Tower{ 130 | ConvBN(768,128,1,1,1,1,0,0), 131 | ConvBN(128,128,1,7,1,1,0,3), 132 | ConvBN(128,128,7,1,1,1,3,0), 133 | ConvBN(128,128,1,7,1,1,0,3), 134 | ConvBN(128,192,7,1,1,1,3,0) 135 | }, 136 | Tower{ 137 | Pooling('average',3,3,1,1,1,1), 138 | ConvBN(768,192,1,1,1,1,0,0) 139 | } 140 | }) 141 | 142 | model:add(Inception{ 143 | Tower{ 144 | ConvBN(768,192,1,1,1,1,0,0) 145 | }, 146 | Tower{ 147 | ConvBN(768,160,1,1,1,1,0,0), 148 | ConvBN(160,160,7,1,1,1,3,0), 149 | ConvBN(160,192,1,7,1,1,0,3) 150 | }, 151 | Tower{ 152 | ConvBN(768,160,1,1,1,1,0,0), 153 | ConvBN(160,160,1,7,1,1,0,3), 154 | ConvBN(160,160,7,1,1,1,3,0), 155 | ConvBN(160,160,1,7,1,1,0,3), 156 | ConvBN(160,192,7,1,1,1,3,0) 157 | }, 158 | Tower{ 159 | Pooling('average',3,3,1,1,1,1), 160 | ConvBN(768,192,1,1,1,1,0,0) 161 | } 162 | }) 163 | 164 | model:add(Inception{ 165 | Tower{ 166 | ConvBN(768,192,1,1,1,1,0,0) 167 | }, 168 | Tower{ 169 | ConvBN(768,160,1,1,1,1,0,0), 170 | ConvBN(160,160,7,1,1,1,3,0), 171 | ConvBN(160,192,1,7,1,1,0,3) 172 | }, 173 | Tower{ 174 | ConvBN(768,160,1,1,1,1,0,0), 175 | ConvBN(160,160,1,7,1,1,0,3), 176 | ConvBN(160,160,7,1,1,1,3,0), 177 | ConvBN(160,160,1,7,1,1,0,3), 178 | ConvBN(160,192,7,1,1,1,3,0) 179 | }, 180 | Tower{ 181 | Pooling('average',3,3,1,1,1,1), 182 | ConvBN(768,192,1,1,1,1,0,0) 183 | } 184 | }) 185 | 186 | model:add(Inception{ 187 | Tower{ 188 | ConvBN(768,192,1,1,1,1,0,0) 189 | }, 190 | Tower{ 191 | ConvBN(768,192,1,1,1,1,0,0), 192 | ConvBN(192,192,7,1,1,1,3,0), 193 | ConvBN(192,192,1,7,1,1,0,3), 194 | }, 195 | Tower{ 196 | ConvBN(768,192,1,1,1,1,0,0), 197 | ConvBN(192,192,1,7,1,1,0,3), 198 | ConvBN(192,192,7,1,1,1,3,0), 199 | ConvBN(192,192,1,7,1,1,0,3), 200 | ConvBN(192,192,7,1,1,1,3,0) 201 | }, 202 | Tower{ 203 | Pooling('average',3,3,1,1,1,1), 204 | ConvBN(768,192,1,1,1,1,0,0) 205 | } 206 | }) 207 | 208 | model:add(Inception{ 209 | Tower{ 210 | ConvBN(768,192,1,1,1,1,0,0), 211 | ConvBN(192,320,3,3,2,2,0,0) 212 | }, 213 | Tower{ 214 | ConvBN(768,192,1,1,1,1,0,0), 215 | ConvBN(192,192,7,1,1,1,3,0), 216 | ConvBN(192,192,1,7,1,1,0,3), 217 | ConvBN(192,192,3,3,2,2,0,0) 218 | }, 219 | Tower{ 220 | Pooling('max',3,3,2,2,0,0) 221 | } 222 | }) 223 | 224 | model:add(Inception{ 225 | Tower{ 226 | ConvBN(1280,320,1,1,1,1,0,0) 227 | }, 228 | Tower{ 229 | ConvBN(1280,384,1,1,1,1,0,0), 230 | Inception{ 231 | Tower{ 232 | ConvBN(384,384,3,1,1,1,1,0) 233 | }, 234 | Tower{ 235 | ConvBN(384,384,1,3,1,1,0,1) 236 | } 237 | } 238 | }, 239 | Tower{ 240 | ConvBN(1280,448,1,1,1,1,0,0), 241 | ConvBN(448,384,3,3,1,1,1,1), 242 | Inception{ 243 | Tower{ 244 | ConvBN(384,384,3,1,1,1,1,0) 245 | }, 246 | Tower{ 247 | ConvBN(384,384,1,3,1,1,0,1) 248 | } 249 | } 250 | }, 251 | Tower{ 252 | Pooling('average',3,3,1,1,1,1), 253 | ConvBN(1280,192,1,1,1,1,0,0) 254 | } 255 | }) 256 | model:add(Inception{ 257 | Tower{ 258 | ConvBN(2048,320,1,1,1,1,0,0) 259 | }, 260 | Tower{ 261 | ConvBN(2048,384,1,1,1,1,0,0), 262 | Inception{ 263 | Tower{ 264 | ConvBN(384,384,3,1,1,1,1,0) 265 | }, 266 | Tower{ 267 | ConvBN(384,384,1,3,1,1,0,1) 268 | } 269 | } 270 | }, 271 | Tower{ 272 | ConvBN(2048,448,1,1,1,1,0,0), 273 | ConvBN(448,384,3,3,1,1,1,1), 274 | Inception{ 275 | Tower{ 276 | ConvBN(384,384,3,1,1,1,1,0) 277 | }, 278 | Tower{ 279 | ConvBN(384,384,1,3,1,1,0,1) 280 | } 281 | } 282 | }, 283 | Tower{ 284 | Pooling('max',3,3,1,1,1,1), 285 | ConvBN(2048,192,1,1,1,1,0,0) 286 | } 287 | }) 288 | 289 | 290 | model:add(Pooling('average',8,8,1,1,0,0)) 291 | model:add(nn.View(-1):setNumInputDims(3)) 292 | model:add(nn.Dropout(0.2)) 293 | model:add(nn.Linear(2048,1000)) 294 | model:add(nn.LogSoftMax()) 295 | 296 | 297 | return { 298 | model = model, 299 | rescaleImgSize = 384, 300 | InputSize = {3, 299, 299} 301 | } 302 | -------------------------------------------------------------------------------- /Models/Inception_v4.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | 3 | local SpatialConvolution = nn.SpatialConvolution 4 | local ReLU = nn.ReLU 5 | local SpatialBatchNormalization = nn.SpatialBatchNormalization 6 | local SpatialMaxPooling = nn.SpatialMaxPooling 7 | local SpatialAveragePooling = nn.SpatialAveragePooling 8 | 9 | local function ConvBN(nInputPlane, nOutputPlane, kW, kH, dW, dH, padW, padH) 10 | local module = nn.Sequential() 11 | module:add(SpatialConvolution(nInputPlane, nOutputPlane, kW, kH, dW, dH, padW, padH)) 12 | module:add(SpatialBatchNormalization(nOutputPlane,1e-3,nil,true)) 13 | module:add(ReLU(true)) 14 | return module 15 | end 16 | 17 | local function Tower(tbl) 18 | local module = nn.Sequential() 19 | for i=1, #tbl do 20 | module:add(tbl[i]) 21 | end 22 | return module 23 | end 24 | 25 | 26 | local function Stem() 27 | local module = nn.Sequential() 28 | module:add(ConvBN(3,32,3,3,2,2,0,0)) 29 | module:add(ConvBN(32,32,3,3,1,1,0,0)) 30 | module:add(ConvBN(32,64,3,3,1,1,1,1)) 31 | 32 | local cat1 = nn.Concat(2) 33 | cat1:add(SpatialMaxPooling(3,3,2,2,0,0)) 34 | cat1:add(ConvBN(64,96,3,3,2,2,0,0)) 35 | 36 | local cat2 = nn.Concat(2) 37 | cat2:add(Tower{ 38 | ConvBN(160,64,1,1,1,1,0,0), 39 | ConvBN(64,64,7,1,1,1,3,0), 40 | ConvBN(64,64,1,7,1,1,0,3), 41 | ConvBN(64,96,3,3,1,1,0,0) 42 | }) 43 | cat2:add(Tower{ 44 | ConvBN(160,64,1,1,1,1,0,0), 45 | ConvBN(64,96,3,3,1,1,0,0) 46 | }) 47 | 48 | local cat3 = nn.Concat(2) 49 | cat3:add(SpatialMaxPooling(3,3,2,2,0,0)) 50 | cat3:add(ConvBN(192,192,3,3,2,2,0,0)) 51 | 52 | module:add(cat1) 53 | module:add(cat2) 54 | module:add(cat3) 55 | 56 | return module 57 | end 58 | 59 | local function Reduction_A(nInputPlane,k,l,m,n) 60 | local module = nn.Concat(2) 61 | module:add(SpatialMaxPooling(3,3,2,2,0,0)) 62 | module:add(ConvBN(nInputPlane,n,3,3,2,2,0,0)) 63 | module:add(Tower{ 64 | ConvBN(nInputPlane,k,1,1,1,1,0,0), 65 | ConvBN(k,l,3,3,1,1,1,1), 66 | ConvBN(l,m,3,3,2,2,0,0) 67 | }) 68 | return module 69 | end 70 | 71 | local function Reduction_B(nInputPlane) 72 | local module = nn.Concat(2) 73 | module:add(SpatialMaxPooling(3,3,2,2,0,0)) 74 | module:add(Tower{ 75 | ConvBN(nInputPlane,192,1,1,1,1,0,0), 76 | ConvBN(192,192,3,3,2,2,0,0) 77 | }) 78 | module:add(Tower{ 79 | ConvBN(nInputPlane,256,1,1,1,1,0,0), 80 | ConvBN(256,256,1,7,1,1,0,3), 81 | ConvBN(256,320,7,1,1,1,3,0), 82 | ConvBN(320,320,3,3,2,2,0,0) 83 | 84 | }) 85 | return module 86 | end 87 | 88 | local function Inception_A(nInputPlane) 89 | local inceptionModule = nn.Concat(2) 90 | inceptionModule:add(Tower{ 91 | SpatialAveragePooling(3,3,1,1,1,1), 92 | ConvBN(nInputPlane,96,1,1,1,1,0,0), 93 | }) 94 | inceptionModule:add(ConvBN(nInputPlane,96,1,1,1,1,0,0)) 95 | inceptionModule:add(Tower{ 96 | ConvBN(nInputPlane,64,1,1,1,1,0,0), 97 | ConvBN(64,96,3,3,1,1,1,1) 98 | }) 99 | inceptionModule:add(Tower{ 100 | ConvBN(nInputPlane,64,1,1,1,1,0,0), 101 | ConvBN(64,96,3,3,1,1,1,1), 102 | ConvBN(96,96,3,3,1,1,1,1) 103 | }) 104 | 105 | return inceptionModule 106 | end 107 | 108 | local function Inception_B(nInputPlane) 109 | local inceptionModule = nn.Concat(2) 110 | inceptionModule:add(Tower{ 111 | SpatialAveragePooling(3,3,1,1,1,1), 112 | ConvBN(nInputPlane,128,1,1,1,1,0,0) 113 | }) 114 | inceptionModule:add(ConvBN(nInputPlane,384,1,1,1,1,0,0)) 115 | inceptionModule:add(Tower{ 116 | ConvBN(nInputPlane,192,1,1,1,1,0,0), 117 | ConvBN(192,224,1,7,1,1,0,3), 118 | ConvBN(224,256,7,1,1,1,3,0) 119 | }) 120 | inceptionModule:add(Tower{ 121 | ConvBN(nInputPlane,192,1,1,1,1,0,0), 122 | ConvBN(192,192,1,7,1,1,0,3), 123 | ConvBN(192,224,7,1,1,1,3,0), 124 | ConvBN(224,224,1,7,1,1,0,3), 125 | ConvBN(224,256,7,1,1,1,3,0) 126 | }) 127 | return inceptionModule 128 | end 129 | 130 | local function Inception_C(nInputPlane) 131 | local inceptionModule = nn.Concat(2) 132 | inceptionModule:add(Tower{ 133 | SpatialAveragePooling(3,3,1,1,1,1), 134 | ConvBN(nInputPlane,256,1,1,1,1,0,0) 135 | }) 136 | inceptionModule:add(ConvBN(nInputPlane,256,1,1,1,1,0,0)) 137 | inceptionModule:add(Tower{ 138 | ConvBN(nInputPlane,384,1,1,1,1,0,0), 139 | nn.Concat(2):add(ConvBN(384,256,3,1,1,1,1,0)):add(ConvBN(384,256,1,3,1,1,0,1)) 140 | }) 141 | inceptionModule:add(Tower{ 142 | ConvBN(nInputPlane,384,1,1,1,1,0,0), 143 | ConvBN(384,448,1,3,1,1,0,1), 144 | ConvBN(448,512,3,1,1,1,1,0), 145 | nn.Concat(2):add(ConvBN(512,256,3,1,1,1,1,0)):add(ConvBN(512,256,1,3,1,1,0,1)) 146 | }) 147 | return inceptionModule 148 | end 149 | 150 | 151 | local model = Stem() 152 | 153 | for i=1,4 do 154 | model:add(Inception_A(384)) 155 | end 156 | model:add(Reduction_A(384,192,224,256,384)) 157 | 158 | for i=1,7 do 159 | model:add(Inception_B(1024)) 160 | end 161 | 162 | model:add(Reduction_B(1024)) 163 | 164 | for i=1,3 do 165 | model:add(Inception_C(1536)) 166 | end 167 | 168 | model:add(SpatialAveragePooling(8,8,1,1)) 169 | model:add(nn.View(-1):setNumInputDims(3)) 170 | model:add(nn.Dropout(0.2)) 171 | model:add(nn.Linear(1536, 1000)) 172 | model:add(nn.LogSoftMax()) 173 | 174 | return { 175 | model = model, 176 | rescaleImgSize = 384, 177 | InputSize = {3, 299, 299} 178 | } 179 | -------------------------------------------------------------------------------- /Models/MattNet.lua: -------------------------------------------------------------------------------- 1 | 2 | require 'cudnn' 3 | require 'cunn' 4 | local SpatialConvolution = cudnn.SpatialConvolution 5 | local SpatialMaxPooling = cudnn.SpatialMaxPooling 6 | local ReLU = cudnn.ReLU 7 | 8 | local features = nn.Sequential() 9 | features:add(SpatialConvolution(3,96,7,7,2,2,2,2)) -- 224 -> 111 10 | features:add(ReLU(true)) 11 | features:add(SpatialMaxPooling(3,3,2,2)) -- 110 -> 55 12 | features:add(SpatialConvolution(96,256,5,5,2,2,1,1)) -- 55 -> 27 13 | features:add(ReLU(true)) 14 | features:add(SpatialMaxPooling(3,3,2,2)) -- 27 -> 13 15 | features:add(SpatialConvolution(256,384,3,3,1,1,1,1)) -- 13 -> 13 16 | features:add(ReLU(true)) 17 | features:add(SpatialConvolution(384,256,3,3,1,1,1,1)) -- 13 -> 13 18 | features:add(ReLU(true)) 19 | features:add(SpatialConvolution(256,256,3,3,1,1,1,1)) -- 13 -> 13 20 | features:add(ReLU(true)) 21 | features:add(SpatialMaxPooling(3,3,2,2)) -- 13 -> 6 22 | 23 | local classifier = nn.Sequential() 24 | classifier:add(nn.View(256*6*6)) 25 | classifier:add(nn.Dropout(0.5)) 26 | classifier:add(nn.Linear(256*6*6, 4096)) 27 | classifier:add(nn.Threshold(0, 1e-6)) 28 | classifier:add(nn.Dropout(0.5)) 29 | classifier:add(nn.Linear(4096, 4096)) 30 | classifier:add(nn.Threshold(0, 1e-6)) 31 | classifier:add(nn.Linear(4096, 1000)) 32 | classifier:add(nn.LogSoftMax()) 33 | 34 | local model = nn.Sequential() 35 | 36 | function fillBias(m) 37 | for i=1, #m.modules do 38 | if m:get(i).bias then 39 | m:get(i).bias:fill(0.1) 40 | end 41 | end 42 | end 43 | 44 | fillBias(features) 45 | fillBias(classifier) 46 | model:add(features):add(classifier) 47 | 48 | return model 49 | 50 | -------------------------------------------------------------------------------- /Models/MattNet_BN.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | require 'cudnn' 4 | require 'cunn' 5 | local SpatialConvolution = cudnn.SpatialConvolution 6 | local SpatialMaxPooling = cudnn.SpatialMaxPooling 7 | local ReLU = cudnn.ReLU 8 | 9 | local features = nn.Sequential() 10 | features:add(SpatialConvolution(3,96,7,7,2,2,2,2)) -- 224 -> 111 11 | features:add(ReLU(true)) 12 | features:add(SpatialMaxPooling(3,3,2,2)) -- 110 -> 55 13 | features:add(nn.SpatialBatchNormalization(0)) 14 | features:add(SpatialConvolution(96,256,5,5,2,2,1,1)) -- 55 -> 27 15 | features:add(ReLU(true)) 16 | features:add(SpatialMaxPooling(3,3,2,2)) -- 27 -> 13 17 | features:add(nn.SpatialBatchNormalization(0)) 18 | features:add(SpatialConvolution(256,384,3,3,1,1,1,1)) -- 13 -> 13 19 | features:add(ReLU(true)) 20 | features:add(nn.SpatialBatchNormalization(0)) 21 | features:add(SpatialConvolution(384,256,3,3,1,1,1,1)) -- 13 -> 13 22 | features:add(ReLU(true)) 23 | features:add(nn.SpatialBatchNormalization(0)) 24 | features:add(SpatialConvolution(256,256,3,3,1,1,1,1)) -- 13 -> 13 25 | features:add(ReLU(true)) 26 | features:add(SpatialMaxPooling(3,3,2,2)) -- 13 -> 6 27 | features:add(nn.SpatialBatchNormalization(0)) 28 | 29 | local classifier = nn.Sequential() 30 | classifier:add(nn.View(256*6*6)) 31 | classifier:add(nn.Dropout(0.5)) 32 | classifier:add(nn.Linear(256*6*6, 4096)) 33 | classifier:add(nn.Threshold(0, 1e-6)) 34 | classifier:add(nn.BatchNormalization(0)) 35 | classifier:add(nn.Dropout(0.5)) 36 | classifier:add(nn.Linear(4096, 4096)) 37 | classifier:add(nn.Threshold(0, 1e-6)) 38 | classifier:add(nn.BatchNormalization(0)) 39 | classifier:add(nn.Linear(4096, 1000)) 40 | classifier:add(nn.LogSoftMax()) 41 | 42 | local model = nn.Sequential() 43 | 44 | function fillBias(m) 45 | for i=1, #m.modules do 46 | if m:get(i).bias then 47 | m:get(i).bias:fill(0.1) 48 | end 49 | end 50 | end 51 | 52 | fillBias(features) 53 | fillBias(classifier) 54 | model:add(features):add(classifier) 55 | 56 | return model 57 | 58 | -------------------------------------------------------------------------------- /Models/Model.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | 3 | local opt = opt or {type = 'cuda', net='new'} 4 | 5 | if opt.type == 'cuda' then 6 | require 'cunn' 7 | end 8 | 9 | local InputMaps = 3 10 | local InputWidth = 221 11 | local InputHeight = 221 12 | 13 | local KernelSize = {7,7,3,3,3,3,1,1,1,1} 14 | local ConvStride = {2,1,1,1,1,1,1,1,1,1} 15 | local Padding = {0,0,1,1,1,1,0,0,0,0} 16 | local PoolSize = {3,2,1,1,1,3,1,1,1,1} 17 | local PoolStride= PoolSize 18 | local TValue = 0 19 | local TReplace = 0 20 | local Outputs = 1000 21 | --local FeatMaps = {InputMaps, 96,256,384,384,256,256,4096,4096, Outputs} 22 | local FeatMaps = {InputMaps, 96,256,512,512,1024,1024,4096,4096, Outputs} 23 | 24 | local LayerNum 25 | 26 | --------------Calculate size of feature maps - useful for linear layer flattening------------------------ 27 | SizeMap = {InputWidth} 28 | for i=2, #FeatMaps do 29 | SizeMap[i] = math.floor(math.ceil((SizeMap[i-1] - KernelSize[i-1] + 1 + 2*Padding[i-1]) / ConvStride[i-1]) / PoolStride[i-1]) 30 | end 31 | 32 | ----------------Create Model------------------------------------- 33 | model = nn.Sequential() 34 | 35 | ---------------Layer - Convolution + Max Pooling------------------ 36 | LayerNum = 1 37 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 38 | model:add(nn.Threshold(TValue, TReplace)) 39 | model:add(nn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 40 | 41 | 42 | ---------------Layer - Convolution + Max Pooling------------------ 43 | LayerNum = 2 44 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 45 | model:add(nn.Threshold(TValue, TReplace)) 46 | model:add(nn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 47 | 48 | ---------------Layer - Convolution ------------------ 49 | LayerNum = 3 50 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 51 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 52 | model:add(nn.Threshold(TValue, TReplace)) 53 | 54 | 55 | ---------------layer - convolution ------------------ 56 | LayerNum = 4 57 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 58 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 59 | model:add(nn.Threshold(TValue, TReplace)) 60 | 61 | 62 | ---------------layer - convolution ------------------ 63 | LayerNum = 5 64 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 65 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 66 | model:add(nn.Threshold(TValue, TReplace)) 67 | 68 | 69 | ---------------Layer - Convolution + Max Pooling------------------ 70 | LayerNum = 6 71 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 72 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 73 | model:add(nn.Threshold(TValue, TReplace)) 74 | model:add(nn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 75 | 76 | ---------------Layer - Fully connected ------------------ 77 | LayerNum = 7 78 | model:add(nn.Reshape(SizeMap[LayerNum]*SizeMap[LayerNum]*FeatMaps[LayerNum])) 79 | model:add(nn.Linear(SizeMap[LayerNum]*SizeMap[LayerNum]*FeatMaps[LayerNum], FeatMaps[LayerNum+1])) 80 | model:add(nn.Threshold(TValue, TReplace)) 81 | model:add(nn.Dropout()) 82 | ---------------Layer - Fully connected ------------------ 83 | LayerNum = 8 84 | model:add(nn.Linear(FeatMaps[LayerNum], FeatMaps[LayerNum+1])) 85 | model:add(nn.Threshold(TValue, TReplace)) 86 | model:add(nn.Dropout(0.5)) 87 | ---------------Layer - Fully connected classifier ------------------ 88 | LayerNum = 9 89 | model:add(nn.Linear(FeatMaps[LayerNum], FeatMaps[LayerNum+1])) 90 | 91 | 92 | ---------------Layer - Log Probabilities-------------------------- 93 | model:add(nn.LogSoftMax()) 94 | 95 | 96 | 97 | 98 | 99 | -- 100 | --if (opt.net ~= 'new') then 101 | -- print '==> Loaded Net' 102 | -- model = torch.load(opt.net); 103 | -- model = model:cuda() 104 | -- 105 | -- 106 | --else 107 | -- print '==> New Net' 108 | -- -- adjust all biases for threshold activation units 109 | -- local finput = model.modules[1].finput 110 | -- local fgradInput = model.modules[1].fgradInput 111 | -- for i,layer in ipairs(model.modules) do 112 | -- if layer.bias then 113 | -- layer.bias:fill(.01) 114 | -- end 115 | -- if layer.finput then 116 | -- layer.finput = finput 117 | -- end 118 | -- if layer.fgradInput then 119 | -- layer.fgradInput = fgradInput 120 | -- end 121 | -- end 122 | -- 123 | --end 124 | -- 125 | 126 | local w,dE_dw = model:getParameters() 127 | w:copy(torch.load('weights')) 128 | ---- Loss: NLL 129 | loss = nn.ClassNLLCriterion() 130 | ---------------------------------------------------------------------- 131 | 132 | if opt.type == 'cuda' then 133 | model:cuda() 134 | loss:cuda() 135 | end 136 | 137 | ---------------------------------------------------------------------- 138 | print '==> flattening model parameters' 139 | 140 | -- Retrieve parameters and gradients: 141 | -- this extracts and flattens all the trainable parameters of the mode 142 | -- into a 1-dim vector 143 | --end 144 | 145 | 146 | -- return package: 147 | return { 148 | Model = model, 149 | Weights = w, 150 | Grads = dE_dw, 151 | FeatMaps = FeatMaps, 152 | SizeMap = SizeMap, 153 | loss = loss 154 | } 155 | 156 | -------------------------------------------------------------------------------- /Models/NewModel.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | 3 | local opt = opt or {type = 'cuda', net='new'} 4 | 5 | if opt.type == 'cuda' then 6 | require 'cunn' 7 | end 8 | 9 | local InputMaps = 3 10 | local InputWidth = 221 11 | local InputHeight = 221 12 | 13 | local KernelSize = {7,7,3,3,3,3,1,1,1,1} 14 | local ConvStride = {2,1,1,1,1,1,1,1,1,1} 15 | local Padding = {0,0,1,1,1,1,0,0,0,0} 16 | local PoolSize = {3,2,1,1,1,3,1,1,5,1} 17 | local PoolStride= PoolSize 18 | local TValue = 0 19 | local TReplace = 0 20 | local Outputs = 1000 21 | local FeatMaps = {InputMaps, 96,256,512,512,1024,1024,4096,4096, Outputs} 22 | 23 | local LayerNum 24 | 25 | --------------Calculate size of feature maps - useful for linear layer flattening------------------------ 26 | SizeMap = {InputWidth} 27 | for i=2, #FeatMaps do 28 | SizeMap[i] = math.floor(math.ceil((SizeMap[i-1] - KernelSize[i-1] + 1 + 2*Padding[i-1]) / ConvStride[i-1]) / PoolStride[i-1]) 29 | end 30 | 31 | ----------------Create Model------------------------------------- 32 | model = nn.Sequential() 33 | 34 | ---------------Layer - Convolution + Max Pooling------------------ 35 | LayerNum = 1 36 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 37 | model:add(nn.Threshold(TValue, TReplace)) 38 | model:add(nn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 39 | 40 | 41 | ---------------Layer - Convolution + Max Pooling------------------ 42 | LayerNum = 2 43 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 44 | model:add(nn.Threshold(TValue, TReplace)) 45 | model:add(nn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 46 | 47 | ---------------Layer - Convolution ------------------ 48 | LayerNum = 3 49 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 50 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 51 | model:add(nn.Threshold(TValue, TReplace)) 52 | 53 | 54 | ---------------layer - convolution ------------------ 55 | LayerNum = 4 56 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 57 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 58 | model:add(nn.Threshold(TValue, TReplace)) 59 | 60 | 61 | ---------------layer - convolution ------------------ 62 | LayerNum = 5 63 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 64 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 65 | model:add(nn.Threshold(TValue, TReplace)) 66 | 67 | 68 | ---------------Layer - Convolution + Max Pooling------------------ 69 | LayerNum = 6 70 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 71 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 72 | model:add(nn.Threshold(TValue, TReplace)) 73 | model:add(nn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 74 | 75 | ---------------Layer - Fully connected ------------------ 76 | LayerNum = 7 77 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum],FeatMaps[LayerNum+1],KernelSize[LayerNum],KernelSize[LayerNum],ConvStride[LayerNum],ConvStride[LayerNum])) 78 | model:add(nn.Threshold(TValue, TReplace)) 79 | 80 | ---------------Layer - Fully connected ------------------ 81 | LayerNum = 8 82 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum],FeatMaps[LayerNum+1],KernelSize[LayerNum],KernelSize[LayerNum],ConvStride[LayerNum],ConvStride[LayerNum])) 83 | model:add(nn.Threshold(TValue, TReplace)) 84 | ---------------Layer - Fully connected classifier ------------------ 85 | LayerNum = 9 86 | model:add(nn.SpatialConvolutionMM(FeatMaps[LayerNum],FeatMaps[LayerNum+1],KernelSize[LayerNum],KernelSize[LayerNum],ConvStride[LayerNum],ConvStride[LayerNum])) 87 | model:add(nn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 88 | 89 | ---------------Layer - Log Probabilities-------------------------- 90 | LayerNum = 10 91 | model:add(nn.Reshape(FeatMaps[LayerNum])) 92 | model:add(nn.LogSoftMax()) 93 | 94 | 95 | 96 | 97 | 98 | 99 | if (opt.net ~= 'new') then 100 | print '==> Loaded Net' 101 | model = torch.load(opt.net); 102 | model = model:cuda() 103 | 104 | 105 | else 106 | print '==> New Net' 107 | -- adjust all biases for threshold activation units 108 | local finput = model.modules[1].finput 109 | local fgradInput = model.modules[1].fgradInput 110 | for i,layer in ipairs(model.modules) do 111 | if layer.bias then 112 | layer.bias:fill(.01) 113 | end 114 | if layer.finput then 115 | layer.finput = finput 116 | end 117 | if layer.fgradInput then 118 | layer.fgradInput = fgradInput 119 | end 120 | end 121 | 122 | end 123 | 124 | 125 | 126 | ---- Loss: NLL 127 | loss = nn.ClassNLLCriterion() 128 | ---------------------------------------------------------------------- 129 | 130 | if opt.type == 'cuda' then 131 | model:cuda() 132 | loss:cuda() 133 | end 134 | 135 | ---------------------------------------------------------------------- 136 | print '==> flattening model parameters' 137 | 138 | -- Retrieve parameters and gradients: 139 | -- this extracts and flattens all the trainable parameters of the mode 140 | -- into a 1-dim vector 141 | --end 142 | 143 | local w,dE_dw = model:getParameters() 144 | 145 | -- return package: 146 | return { 147 | model = model, 148 | Weights = w, 149 | Grads = dE_dw, 150 | FeatMaps = FeatMaps, 151 | SizeMap = SizeMap, 152 | loss = loss 153 | } 154 | 155 | -------------------------------------------------------------------------------- /Models/NiN_Model.lua: -------------------------------------------------------------------------------- 1 | require 'cunn' 2 | require 'cudnn' 3 | local model = nn.Sequential() 4 | 5 | -- Convolution Layers 6 | 7 | model:add(cudnn.SpatialConvolution(3, 96, 11,11,4,4)) 8 | model:add(cudnn.ReLU()) 9 | model:add(cudnn.SpatialConvolution(96, 96,1,1 )) 10 | model:add(cudnn.ReLU()) 11 | model:add(cudnn.SpatialConvolution(96,96, 1,1 )) 12 | model:add(cudnn.ReLU()) 13 | model:add(cudnn.SpatialMaxPooling(3, 3,2,2):ceil()) 14 | model:add(nn.Dropout(0.5)) 15 | model:add(cudnn.SpatialConvolution(96,256, 5,5,1,1,2,2 )) 16 | model:add(cudnn.ReLU()) 17 | model:add(cudnn.SpatialConvolution(256,256, 1,1 )) 18 | model:add(cudnn.ReLU()) 19 | model:add(cudnn.SpatialConvolution(256,256, 1,1 )) 20 | model:add(cudnn.ReLU()) 21 | model:add(cudnn.SpatialMaxPooling(3, 3,2,2):ceil()) 22 | model:add(nn.Dropout(0.5)) 23 | model:add(cudnn.SpatialConvolution(256,384, 3,3 ,1,1,1,1)) 24 | model:add(cudnn.ReLU()) 25 | model:add(cudnn.SpatialConvolution(384,384, 1,1 )) 26 | model:add(cudnn.ReLU()) 27 | model:add(cudnn.SpatialConvolution(384,384, 1,1 )) 28 | model:add(cudnn.ReLU()) 29 | model:add(cudnn.SpatialMaxPooling(3, 3,2,2):ceil()) 30 | model:add(nn.Dropout(0.5)) 31 | model:add(cudnn.SpatialConvolution(384,1024, 3,3,1,1,1,1 )) 32 | model:add(cudnn.ReLU()) 33 | model:add(cudnn.SpatialConvolution(1024,1024, 1,1 )) 34 | model:add(cudnn.ReLU()) 35 | model:add(cudnn.SpatialConvolution(1024,1000, 1,1 )) 36 | model:add(cudnn.ReLU()) 37 | 38 | model:add(cudnn.SpatialAveragePooling(6,6)) 39 | model:add(nn.View(1000)) 40 | model:add(nn.LogSoftMax()) 41 | 42 | return model 43 | 44 | -------------------------------------------------------------------------------- /Models/OverFeat_Model.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | require 'cudnn' 3 | 4 | local InputMaps = 3 5 | local InputWidth = 221 6 | local InputHeight = 221 7 | 8 | local KernelSize = {7,7,3,3,3,3,1,1,1,1} 9 | local ConvStride = {2,1,1,1,1,1,1,1,1,1} 10 | local Padding = {0,0,1,1,1,1,0,0,0,0} 11 | local PoolSize = {3,2,1,1,1,3,1,1,1,1} 12 | local PoolStride= PoolSize 13 | local TValue = 0 14 | local TReplace = 0 15 | local Outputs = 1000 16 | local FeatMaps = {InputMaps, 96,256,512,512,1024,1024,4096,4096, Outputs} 17 | 18 | local LayerNum 19 | 20 | --------------Calculate size of feature maps - useful for linear layer flattening------------------------ 21 | SizeMap = {InputWidth} 22 | for i=2, #FeatMaps do 23 | SizeMap[i] = math.floor(math.ceil((SizeMap[i-1] - KernelSize[i-1] + 1 + 2*Padding[i-1]) / ConvStride[i-1]) / PoolStride[i-1]) 24 | end 25 | 26 | ----------------Create Model------------------------------------- 27 | model = nn.Sequential() 28 | 29 | ---------------Layer - Convolution + Max Pooling------------------ 30 | LayerNum = 1 31 | model:add(cudnn.SpatialConvolution(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 32 | model:add(nn.Threshold(TValue, TReplace)) 33 | model:add(cudnn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 34 | 35 | 36 | ---------------Layer - Convolution + Max Pooling------------------ 37 | LayerNum = 2 38 | model:add(cudnn.SpatialConvolution(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 39 | model:add(nn.Threshold(TValue, TReplace)) 40 | model:add(cudnn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 41 | 42 | ---------------Layer - Convolution ------------------ 43 | LayerNum = 3 44 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 45 | model:add(cudnn.SpatialConvolution(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 46 | model:add(nn.Threshold(TValue, TReplace)) 47 | 48 | 49 | ---------------layer - convolution ------------------ 50 | LayerNum = 4 51 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 52 | model:add(cudnn.SpatialConvolution(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 53 | model:add(nn.Threshold(TValue, TReplace)) 54 | 55 | 56 | ---------------layer - convolution ------------------ 57 | LayerNum = 5 58 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 59 | model:add(cudnn.SpatialConvolution(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 60 | model:add(nn.Threshold(TValue, TReplace)) 61 | 62 | 63 | ---------------Layer - Convolution + Max Pooling------------------ 64 | LayerNum = 6 65 | model:add(nn.SpatialZeroPadding(1,1,1,1)) 66 | model:add(cudnn.SpatialConvolution(FeatMaps[LayerNum], FeatMaps[LayerNum+1], KernelSize[LayerNum], KernelSize[LayerNum], ConvStride[LayerNum], ConvStride[LayerNum])) 67 | model:add(nn.Threshold(TValue, TReplace)) 68 | model:add(cudnn.SpatialMaxPooling(PoolSize[LayerNum], PoolSize[LayerNum], PoolStride[LayerNum], PoolStride[LayerNum])) 69 | 70 | ---------------Layer - Fully connected ------------------ 71 | LayerNum = 7 72 | model:add(nn.View(SizeMap[LayerNum]*SizeMap[LayerNum]*FeatMaps[LayerNum])) 73 | model:add(nn.Linear(SizeMap[LayerNum]*SizeMap[LayerNum]*FeatMaps[LayerNum], FeatMaps[LayerNum+1])) 74 | model:add(nn.Threshold(TValue, TReplace)) 75 | 76 | ---------------Layer - Fully connected ------------------ 77 | LayerNum = 8 78 | model:add(nn.Dropout(0.5)) 79 | model:add(nn.Linear(FeatMaps[LayerNum], FeatMaps[LayerNum+1])) 80 | model:add(nn.Threshold(TValue, TReplace)) 81 | 82 | ---------------Layer - Fully connected classifier ------------------ 83 | LayerNum = 9 84 | model:add(nn.Linear(FeatMaps[LayerNum], FeatMaps[LayerNum+1])) 85 | 86 | 87 | ---------------Layer - Log Probabilities-------------------------- 88 | model:add(nn.LogSoftMax()) 89 | 90 | 91 | 92 | 93 | -- 94 | -- 95 | --local finput = model.modules[1].finput 96 | --local fgradInput = model.modules[1].fgradInput 97 | --for i,layer in ipairs(model.modules) do 98 | -- if layer.bias then 99 | -- layer.bias:fill(.01) 100 | -- end 101 | -- if layer.finput then 102 | -- layer.finput = finput 103 | -- end 104 | -- if layer.fgradInput then 105 | -- layer.fgradInput = fgradInput 106 | -- end 107 | --end 108 | -- 109 | -- 110 | --model.InputSize = InputWidth 111 | return model 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Deep Learning on ImageNet using Torch 2 | ===================================== 3 | This is a complete training example for Deep Convolutional Networks on the ILSVRC classification task. 4 | 5 | Data is preprocessed and cached as a LMDB data-base for fast reading. A separate thread buffers images from the LMDB record in the background. 6 | 7 | Multiple GPUs are also supported by using nn.DataParallelTable (https://github.com/torch/cunn/blob/master/docs/cunnmodules.md). 8 | 9 | This code allows training at 4ms/sample with the AlexNet model and 2ms for testing on a single GPU (using Titan Z with 1 active gpu) 10 | 11 | ## Dependencies 12 | * Torch (http://torch.ch) 13 | * "eladtools" (https://github.com/eladhoffer/eladtools) for optimizer. 14 | * "lmdb.torch" (http://github.com/eladhoffer/lmdb.torch) for LMDB usage. 15 | * "DataProvider.torch" (https://github.com/eladhoffer/DataProvider.torch) for DataProvider class. 16 | * "cudnn.torch" (https://github.com/soumith/cudnn.torch) for faster training. Can be avoided by changing "cudnn" to "nn" in models. 17 | 18 | To install all dependencies (assuming torch is installed) use: 19 | ```bash 20 | luarocks install https://raw.githubusercontent.com/eladhoffer/eladtools/master/eladtools-scm-1.rockspec 21 | luarocks install https://raw.githubusercontent.com/eladhoffer/lmdb.torch/master/lmdb.torch-scm-1.rockspec 22 | luarocks install https://raw.githubusercontent.com/eladhoffer/DataProvider.torch/master/dataprovider-scm-1.rockspec 23 | ``` 24 | 25 | ## Data 26 | * To get the ILSVRC data, you should register on their site for access: http://www.image-net.org/ 27 | * Extract all archives and configure the data location and save dir in **Config.lua**. You can also change the saved image size by editing the default value `ImageMinSide=256`. 28 | * LMDB records for fast read access are created by running **CreateLMDBs.lua**. 29 | It defaults to saving the compressed jpgs (about ~24GB for training data, ~1GB for validation data when smallest image dimension is 256). 30 | * To validate the LMDB configuration and test its loading speed, you can run **TestLMDBs.lua**. 31 | * All data related functions used for training are available at **Data.lua**. 32 | 33 | ## Model configuration 34 | Network model is defined by writing a .lua file in `Models` folder, and selecting it using the `network` flag. 35 | The model file must return a trainable network. It can also specify additional training options such optimization regime, input size modifications. 36 | 37 | e.g for a model file: 38 | ```lua 39 | local model = nn.Sequential():add(...) 40 | return --optional: you can also simply return model 41 | { 42 | model = model, 43 | regime = { 44 | epoch = {1, 19, 30, 44, 53 }, 45 | learningRate = {1e-2, 5e-3, 1e-3, 5e-4, 1e-4}, 46 | weightDecay = {5e-4, 5e-4, 0, 0, 0 } 47 | } 48 | } 49 | ``` 50 | Currently available in `Models` folder are: `AlexNet`, `MattNet`, `OverFeat`, `GoogLeNet`, `CaffeRef`, `NiN`. Some are available with a batch normalized version (denoted with `_BN`) 51 | 52 | 53 | ## Training 54 | You can start training using **Main.lua** by typing: 55 | ```lua 56 | th Main.lua -network AlexNet -LR 0.01 57 | ``` 58 | or if you have 2 gpus availiable, 59 | ```lua 60 | th Main.lua -network AlexNet -LR 0.01 -nGPU 2 -batchSize 256 61 | ``` 62 | A more elaborate example continuing a pretrained network and saving intermediate results 63 | ```lua 64 | th Main.lua -network GoogLeNet_BN -batchSize 64 -nGPU 2 -save GoogLeNet_BN -bufferSize 9600 -LR 0.01 -checkpoint 320000 -weightDecay 1e-4 -load ./pretrainedNet.t7 65 | ``` 66 | Buffer size should be adjusted to suit the used hardware and configuration. Default value is 5120 (40 batches of 128) which works well when using a non SSD drive and 16GB ram. Bigger buffer size allows better sample shuffling. 67 | 68 | ## Output 69 | Training output will be saved to folder defined with `save` flag. 70 | 71 | The complete netowork will be saved on each epoch as **Net_<#epoch>.t7** along with 72 | * A complete log **Log.txt** 73 | * Error rate summary **ErrorRate.log** and accompanying **ErrorRate.log.eps** graph 74 | 75 | ## Additional flags 76 | |Flag | Default Value |Description 77 | |:----------------|:--------------------:|:---------------------------------------------- 78 | |modelsFolder |./Models/ | Models Folder 79 | |network |AlexNet | Model file - must return valid network. 80 | |LR |0.01 | learning rate 81 | |LRDecay |0 | learning rate decay (in # samples) 82 | |weightDecay |5e-4 | L2 penalty on the weights 83 | |momentum |0.9 | momentum 84 | |batchSize |128, | batch size 85 | |optimization |'sgd' | optimization method 86 | |seed |123 | torch manual random number generator seed 87 | |epoch |-1 | number of epochs to train, -1 for unbounded 88 | |testonly |false | Just test loaded net on validation set 89 | |threads |8 | number of threads 90 | |type |'cuda' | float or cuda 91 | |bufferSize |5120 | buffer size 92 | |devid |1 | device ID (if using CUDA) 93 | |nGPU |1 | num of gpu devices used 94 | |constBatchSize |false | do not allow varying batch sizes - e.g for ccn2 kernel 95 | |load |'' | load existing net weights 96 | |save |time-identifier | save directory 97 | |optState |false | Save optimization state every epoch 98 | |checkpoint |0 | Save a weight check point every n samples. 0 for off 99 | |augment |1 | data augmentation level - {1 - simple mirror and crops, 2 +scales, 3 +rotations} 100 | |estMeanStd |preDef | estimate mean and std. Options: {preDef, simple, channel, image} 101 | |shuffle |true | shuffle training samples 102 | -------------------------------------------------------------------------------- /TestLMDB.lua: -------------------------------------------------------------------------------- 1 | require 'lmdb' 2 | require 'image' 3 | 4 | local config = require 'Config' 5 | local data = require 'Data' 6 | local TrainDB = data.TrainDB 7 | local ValDB = data.ValDB 8 | 9 | 10 | function BenchmarkDB(DB, Name, num, InputSize, visualize) 11 | local Num = num or 128 12 | config.InputSize = InputSize or {3, 224, 224} 13 | print('\n\n===> ', Name .. ' DB Benchmark, ' .. Num .. ' Items') 14 | local DataSetSize = DB:size() 15 | print('DB Size: ' .. DataSetSize) 16 | print('Sample Size: ', config.InputSize) 17 | 18 | local x = torch.FloatTensor(Num ,unpack(config.InputSize)) 19 | local y = torch.IntTensor(Num) 20 | 21 | 22 | print('\n==> Synchronous timing') 23 | local t, key 24 | 25 | key = Key(math.random(DataSetSize-Num)) 26 | t=torch.tic() 27 | DB:cacheSeq(key,Num ,x,y) 28 | t=torch.tic()-t 29 | print('1) Sequential Time: ' .. string.format('%04f',t/Num) .. ' Per sample') 30 | if visualize then image.display(x) end 31 | 32 | randKeys = Keys(torch.randperm(DataSetSize):narrow(1,1,Num)) 33 | t=torch.tic() 34 | DB:cacheRand(randKeys,x,y) 35 | t=torch.tic()-t 36 | print('2) Random Access Time: ' .. string.format('%04f',t/Num) .. ' Per sample') 37 | if visualize then image.display(x) end 38 | 39 | print('\n==> asynchronous timing') 40 | DB:threads() 41 | key = Key(math.random(DataSetSize-Num)) 42 | t=torch.tic() 43 | DB:asyncCacheSeq(key,Num ,x,y) 44 | print('1) Async Sequential Spawn Time: ' .. string.format('%04f',(torch.tic()-t)/Num) .. ' Per sample') 45 | DB:synchronize() 46 | t=torch.tic()-t 47 | print(' Async Sequential Complete Time: ' .. string.format('%04f',t/Num) .. ' Per sample') 48 | if visualize then image.display(x) end 49 | 50 | randKeys = Keys(torch.randperm(DataSetSize):narrow(1,1,Num)) 51 | t=torch.tic() 52 | DB:asyncCacheRand(randKeys,x,y) 53 | print('2) Async Random Spawn Time: ' .. string.format('%04f',(torch.tic()-t)/Num) .. ' Per sample') 54 | DB:synchronize() 55 | t=torch.tic()-t 56 | print(' Async Random Complete Time: ' .. string.format('%04f',t/Num) .. ' Per sample') 57 | if visualize then image.display(x) end 58 | end 59 | 60 | BenchmarkDB(TrainDB, 'Training') 61 | BenchmarkDB(ValDB, 'Validation') 62 | -------------------------------------------------------------------------------- /ValidationLabels: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eladhoffer/ImageNet-Training/6bc23d9a5f7abe2b527977cb571e34dd893dc86b/ValidationLabels --------------------------------------------------------------------------------