Commit f5cf2e14 authored by Yuxin Wu's avatar Yuxin Wu

Use clip(0, 1) in svhn-dorefa to match alexnet-dorefa (fix #920)

parent 83cd2cf1
__If you meet any unexpected problems when running the code, or want to report bugs, please STOP here__. Go to the # If you meet any unexpected problems when running the code, or want to report bugs, please STOP here. Go to the following link instead and fill out the information there:
following link instead and fill out the information there:
https://github.com/tensorpack/tensorpack/issues/new?template=unexpected-problems---bugs.md https://github.com/tensorpack/tensorpack/issues/new?template=unexpected-problems---bugs.md
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# File: svhn-digit-dorefa.py # File: svhn-digit-dorefa.py
# Author: Yuxin Wu # Author: Yuxin Wu
import os
import argparse import argparse
import tensorflow as tf import tensorflow as tf
...@@ -23,14 +24,11 @@ This is our attempt to reproduce it on tensorpack. ...@@ -23,14 +24,11 @@ This is our attempt to reproduce it on tensorpack.
Accuracy: Accuracy:
With (W,A,G)=(1,1,4), can reach 3.1~3.2% error after 150 epochs. With (W,A,G)=(1,1,4), can reach 3.1~3.2% error after 150 epochs.
With the GaussianDeform augmentor, it will reach 2.8~2.9%
(we are not using this augmentor in the paper).
With (W,A,G)=(1,2,4), error is 3.0~3.1%. With (W,A,G)=(1,2,4), error is 3.0~3.1%.
With (W,A,G)=(32,32,32), error is about 2.9%. With (W,A,G)=(32,32,32), error is about 2.3%.
Speed: Speed:
30~35 iteration/s on 1 TitanX Pascal. (4721 iterations / epoch) With quantization, 60 batch/s on 1 1080Ti. (4721 batch / epoch)
To Run: To Run:
./svhn-digit-dorefa.py --dorefa 1,2,4 ./svhn-digit-dorefa.py --dorefa 1,2,4
...@@ -61,11 +59,13 @@ class Model(ModelDesc): ...@@ -61,11 +59,13 @@ class Model(ModelDesc):
logger.info("Binarizing weight {}".format(v.op.name)) logger.info("Binarizing weight {}".format(v.op.name))
return fw(v) return fw(v)
def cabs(x): def nonlin(x):
return tf.minimum(1.0, tf.abs(x), name='cabs') if BITA == 32:
return tf.nn.relu(x)
return tf.clip_by_value(x, 0.0, 1.0)
def activate(x): def activate(x):
return fa(cabs(x)) return fa(nonlin(x))
image = image / 256.0 image = image / 256.0
...@@ -103,7 +103,7 @@ class Model(ModelDesc): ...@@ -103,7 +103,7 @@ class Model(ModelDesc):
.tf.nn.dropout(0.5 if is_training else 1.0) .tf.nn.dropout(0.5 if is_training else 1.0)
.Conv2D('conv6', 512, 5, padding='VALID') .Conv2D('conv6', 512, 5, padding='VALID')
.apply(fg).BatchNorm('bn6') .apply(fg).BatchNorm('bn6')
.apply(cabs) .apply(nonlin)
.FullyConnected('fc1', 10)()) .FullyConnected('fc1', 10)())
tf.nn.softmax(logits, name='output') tf.nn.softmax(logits, name='output')
...@@ -133,7 +133,7 @@ class Model(ModelDesc): ...@@ -133,7 +133,7 @@ class Model(ModelDesc):
def get_config(): def get_config():
logger.auto_set_dir() logger.set_logger_dir(os.path.join('train_log', 'svhn-dorefa-{}'.format(args.dorefa)))
# prepare dataset # prepare dataset
d1 = dataset.SVHNDigit('train') d1 = dataset.SVHNDigit('train')
...@@ -145,9 +145,6 @@ def get_config(): ...@@ -145,9 +145,6 @@ def get_config():
imgaug.Resize((40, 40)), imgaug.Resize((40, 40)),
imgaug.Brightness(30), imgaug.Brightness(30),
imgaug.Contrast((0.5, 1.5)), imgaug.Contrast((0.5, 1.5)),
# imgaug.GaussianDeform( # this is slow but helpful. only use it when you have lots of cpus
# [(0.2, 0.2), (0.2, 0.8), (0.8,0.8), (0.8,0.2)],
# (40,40), 0.2, 3),
] ]
data_train = AugmentImageComponent(data_train, augmentors) data_train = AugmentImageComponent(data_train, augmentors)
data_train = BatchData(data_train, 128) data_train = BatchData(data_train, 128)
......
...@@ -18,14 +18,10 @@ __all__ = ['COCODetection', 'COCOMeta'] ...@@ -18,14 +18,10 @@ __all__ = ['COCODetection', 'COCOMeta']
class _COCOMeta(object): class _COCOMeta(object):
# handle the weird (but standard) split of train and val
INSTANCE_TO_BASEDIR = { INSTANCE_TO_BASEDIR = {
'train2014': 'train2014',
'val2014': 'val2014',
'valminusminival2014': 'val2014', 'valminusminival2014': 'val2014',
'minival2014': 'val2014', 'minival2014': 'val2014',
'test2014': 'test2014',
'train2017': 'train2017',
'val2017': 'val2017',
} }
def valid(self): def valid(self):
...@@ -54,10 +50,9 @@ COCOMeta = _COCOMeta() ...@@ -54,10 +50,9 @@ COCOMeta = _COCOMeta()
class COCODetection(object): class COCODetection(object):
def __init__(self, basedir, name): def __init__(self, basedir, name):
assert name in COCOMeta.INSTANCE_TO_BASEDIR.keys(), name
self.name = name self.name = name
self._imgdir = os.path.realpath(os.path.join( self._imgdir = os.path.realpath(os.path.join(
basedir, COCOMeta.INSTANCE_TO_BASEDIR[name])) basedir, COCOMeta.INSTANCE_TO_BASEDIR.get(name, name)))
assert os.path.isdir(self._imgdir), self._imgdir assert os.path.isdir(self._imgdir), self._imgdir
annotation_file = os.path.join( annotation_file = os.path.join(
basedir, 'annotations/instances_{}.json'.format(name)) basedir, 'annotations/instances_{}.json'.format(name))
......
...@@ -78,8 +78,9 @@ _C.MODE_FPN = False ...@@ -78,8 +78,9 @@ _C.MODE_FPN = False
# dataset ----------------------- # dataset -----------------------
_C.DATA.BASEDIR = '/path/to/your/COCO/DIR' _C.DATA.BASEDIR = '/path/to/your/COCO/DIR'
_C.DATA.TRAIN = ['train2014', 'valminusminival2014'] # i.e., trainval35k _C.DATA.TRAIN = ['train2014', 'valminusminival2014'] # i.e. trainval35k, AKA train2017
_C.DATA.VAL = 'minival2014' # For now, only support evaluation on single dataset # For now, only support evaluation on single dataset
_C.DATA.VAL = 'minival2014' # AKA val2017
_C.DATA.NUM_CATEGORY = 80 # 80 categories. _C.DATA.NUM_CATEGORY = 80 # 80 categories.
_C.DATA.CLASS_NAMES = [] # NUM_CLASS (NUM_CATEGORY+1) strings, to be populated later by data loader. The first is BG. _C.DATA.CLASS_NAMES = [] # NUM_CLASS (NUM_CATEGORY+1) strings, to be populated later by data loader. The first is BG.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment