Skip to content

Commit

Permalink
Fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
mrastegari authored and Mohammad Rastegari committed Aug 15, 2016
1 parent 8bf097b commit 8a96d94
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 24 deletions.
31 changes: 24 additions & 7 deletions README.md
@@ -1,12 +1,12 @@
##XNOR-Net: ImageNet Classification Using Binary Convolutional Neurl Networks.
##XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks.

This is the Torch 7.0 implementation of XNOR-Net: ImageNet Classification Using Binary Convolutional Neurl Networks.
This is the Torch 7.0 implementation of XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks.

### Citation
```bash
@inproceedings{rastegariECCV16,
Author = {Mohammad Rastegari and Vicente Ordonez and Joseph Redmon and Ali Farhadi},
Title = {XNOR-Net: ImageNet Classification Using Binary Convolutional Neurl Networks},
Title = {XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks},
Booktitle = {ECCV},
Year = {2016}
}
Expand All @@ -15,19 +15,36 @@ This is the Torch 7.0 implementation of XNOR-Net: ImageNet Classification Using
### Requirements
This software is implemented on top of the implementation of [ImageNet-multiGPU](https://github.com/soumith/imagenet-multiGPU.torch) and has all the same requirements.

Download the cache files from [here](https://s3-us-west-2.amazonaws.com/ai2-vision/xnornet/cache.tar) and run:
```bash
tar -xvf ./cache.tar
```

### Training Binary Weight Network
You just need to run this:

```bash
th main.lua -data [path to ImageNet dataset] -nGPU 1 -batchSize 128 -netType alexnet -binaryWeight -dropout 0.1
```
### Training XNOR-Networks
```bash
th main.lua -data /mnt/raid00/data/imagenet2012/ -nGPU 4 -batchSize 800 -netType alexnetxnor -binaryWeight -optimType adam -epochSize 1500
th main.lua -data [path to ImageNet dataset] -nGPU 4 -batchSize 800 -netType alexnetxnor -binaryWeight -optimType adam -epochSize 1500
```
### Trained Models
To use the trained models use the option `-retrain`
To use the trained models use the option `-retrain [path to the trained model file]` and `-testOnly`

[Binary-Weight-Network(BWN)](https://s3-us-west-2.amazonaws.com/ai2-vision/xnornet/alexnet_BWN.t7)

[XNOR-Network](https://s3-us-west-2.amazonaws.com/ai2-vision/xnornet/alexnet_XNOR.t7)

If you use the same image pre-processing as [here](https://github.com/soumith/imagenet-multiGPU.torch) by
```bash
find . -name "*.JPEG" | xargs -I {} convert {} -resize "256^>" {}
```
then the accuracies for top-1 should be:

alexnet_BWN %56.8

alexnet_XNOR %43.3

### License
By downloading this software you acknowledged that you agreed on the terms and conditions in the `SOFTWARE-LICENSE-AGREEMENT.lic`
By downloading this software you acknowledged that you agreed on the terms and conditions in the `SOFTWARE-LICENSE-AGREEMENT.lic`
29 changes: 22 additions & 7 deletions donkey.lua
Expand Up @@ -56,10 +56,14 @@ local mean,std
-- function to load the image, jitter it appropriately (random crops etc.)
local trainHook = function(self, path)
if string.find(path,"/mnt/raid00/data/imagenet2012") then
path = string.gsub(path ,"/mnt/raid00/data/imagenet2012",opt.data)
end
collectgarbage()
opt.testMode = false
local excep, input = pcall(loadImage,path);
if not excep then
print('ERROR: image can not be loaded!!!')
input = torch.Tensor(3,opt.imageSize,opt.imageSize):fill(mean[1]);
end
local iW = input:size(3)
Expand Down Expand Up @@ -87,9 +91,13 @@ if paths.filep(trainCache) then
print('Loading train metadata from cache')
trainLoader = torch.load(trainCache)
trainLoader.sampleHookTrain = trainHook
assert(trainLoader.paths[1] == paths.concat(opt.data, 'train'),
'cached files dont have the same path as opt.data. Remove your cached files at: '
.. trainCache .. ' and rerun the program')
--assert(trainLoader.paths[1] == paths.concat(opt.data, 'train'),
-- 'cached files dont have the same path as opt.data. Remove your cached files at: '
-- .. trainCache .. ' and rerun the program')
if trainLoader.paths[1] ~= paths.concat(opt.data, 'train') then
trainLoader.paths[1] = paths.concat(opt.data, 'train');
end
else
print('Creating train metadata')
trainLoader = dataLoader{
Expand Down Expand Up @@ -122,11 +130,15 @@ end
-- function to load the image
testHook = function(self, path)
if string.find(path,"/mnt/raid00/data/imagenet2012") then
path = string.gsub(path ,"/mnt/raid00/data/imagenet2012",opt.data)
end
collectgarbage()
opt.testMode = true
local excep, input = pcall(loadImage,path);
if not excep then
input = torch.CudaTensor(3,opt.imageSize,opt.imageSize):fill(mean[1]);
print('ERROR: image can not be loaded!!!')
input = torch.Tensor(3,opt.imageSize,opt.imageSize):fill(mean[1]);
end
local oH = sampleSize[2]
local oW = sampleSize[3]
Expand All @@ -147,9 +159,12 @@ if paths.filep(testCache) then
print('Loading test metadata from cache')
testLoader = torch.load(testCache)
testLoader.sampleHookTest = testHook
assert(testLoader.paths[1] == paths.concat(opt.data, 'val'),
'cached files dont have the same path as opt.data. Remove your cached files at: '
.. testCache .. ' and rerun the program')
--assert(testLoader.paths[1] == paths.concat(opt.data, 'val'),
-- 'cached files dont have the same path as opt.data. Remove your cached files at: '
-- .. testCache .. ' and rerun the program')
if testLoader.paths[1] ~= paths.concat(opt.data, 'val') then
testLoader.paths[1] = paths.concat(opt.data, 'val');
end
else
print('Creating test metadata')
testLoader = dataLoader{
Expand Down
9 changes: 6 additions & 3 deletions main.lua
Expand Up @@ -43,9 +43,12 @@ paths.dofile('test.lua')


epoch = opt.epochNumber

for i=1,opt.nEpochs do
if opt.testOnly then
test()
else
for i=1,opt.nEpochs do
train()
test()
epoch = epoch + 1
end
end
end
5 changes: 1 addition & 4 deletions model.lua
Expand Up @@ -36,10 +36,7 @@ else
loadParams(model,saved_model);
end
end

debugger.enter()


--debugger.enter()
-- This is useful for fitting ResNet-50 on 4 GPUs, but requires that all
-- containers override backwards to call backwards recursively on submodules
if opt.shareGradInput then
Expand Down
3 changes: 2 additions & 1 deletion opts.lua
Expand Up @@ -16,7 +16,7 @@ function M.parse(arg)
cmd:text('Options:')
------------ General options --------------------

cmd:option('-cache', '/mnt/raid00/' .. os.getenv('USER') ..'/NNExpLog/imagenet1k/', 'subdirectory in which to save/log experiments')
cmd:option('-cache', './cache/', 'subdirectory in which to save/log experiments')
cmd:option('-data', './imagenet/imagenet_raw_images/256', 'Home of ImageNet dataset')
cmd:option('-dataset', 'imagenet', 'Dataset Name: imagenet |cifar')
cmd:option('-manualSeed', 2, 'Manually set RNG seed')
Expand All @@ -41,6 +41,7 @@ function M.parse(arg)
cmd:option('-weightDecay', 0, 'weight decay')
cmd:option('-shareGradInput', true, 'Sharing the gradient memory')
cmd:option('-binaryWeight', false, 'Sharing the gradient memory')
cmd:option('-testOnly', false, 'Sharing the gradient memory')
---------- Model options ----------------------------------
cmd:option('-netType', 'alexnet', 'Options: alexnet | overfeat | alexnetowtbn | vgg | googlenet | resnet')
cmd:option('-optimType', 'sgd', 'Options: sgd | adam')
Expand Down
2 changes: 1 addition & 1 deletion test.lua
Expand Up @@ -28,7 +28,7 @@ function test()
if opt.binaryWeight then
binarizeConvParms(convNodes)
end

top1Sum = 0
top5Sum = 0
loss = 0
Expand Down
2 changes: 1 addition & 1 deletion util.lua
Expand Up @@ -82,7 +82,7 @@ function updateBinaryGradWeight(convNodes)
local m = convNodes[i].weight:norm(1,4):sum(3):sum(2):div(n):expand(s);
m[convNodes[i].weight:le(-1)]=0;
m[convNodes[i].weight:ge(1)]=0;
m:add(1/(n)):mul(1-1/s[2]);
m:add(1/(n)):mul(1-1/s[2]):mul(n);
convNodes[i].gradWeight:cmul(m)--:cmul(mg)
end
if opt.nGPU >1 then
Expand Down

0 comments on commit 8a96d94

Please sign in to comment.