Commit 5e2c7309 authored by Yuxin Wu's avatar Yuxin Wu

resnet readme

parent 775f5c9a
ImageNet training code coming soon. ## imagenet-resnet.py
ImageNet training code of pre-activation ResNet. It follows the setup in
[fb.resnet.torch](https://github.com/facebook/fb.resnet.torch) and get similar performance (with much fewer lines of code),
| Model (WIP) | Top 5 Error | Top 1 Error |
|:-------------------|-------------|------------:|
| ResNet 18 | 10.67% | 29.50% |
| ResNet 50 | 7.13% | 24.12% |
## load-resnet.py ## load-resnet.py
...@@ -24,8 +32,7 @@ The per-pixel mean used here is slightly different from the original. ...@@ -24,8 +32,7 @@ The per-pixel mean used here is slightly different from the original.
## cifar10-resnet.py ## cifar10-resnet.py
Reproduce the results in paper "Deep Residual Learning for Image Recognition", [http://arxiv.org/abs/1512.03385](http://arxiv.org/abs/1512.03385) Reproduce pre-activation ResNet on CIFAR10.
with the variants proposed in "Identity Mappings in Deep Residual Networks", [https://arxiv.org/abs/1603.05027](https://arxiv.org/abs/1603.05027) on CIFAR10.
The train error shown here is a moving average of the error rate of each batch in training. The train error shown here is a moving average of the error rate of each batch in training.
The validation error here is computed on test set. The validation error here is computed on test set.
......
...@@ -22,11 +22,9 @@ Training code of Pre-Activation version of ResNet on ImageNet. ...@@ -22,11 +22,9 @@ Training code of Pre-Activation version of ResNet on ImageNet.
Mainly follow the setup in fb.resnet.torch Mainly follow the setup in fb.resnet.torch
""" """
NR_GPU = 4
TOTAL_BATCH_SIZE = 256 TOTAL_BATCH_SIZE = 256
BATCH_SIZE = TOTAL_BATCH_SIZE / NR_GPU
INPUT_SHAPE = 224 INPUT_SHAPE = 224
DEPTH = None
class Model(ModelDesc): class Model(ModelDesc):
def _get_input_vars(self): def _get_input_vars(self):
...@@ -93,7 +91,7 @@ class Model(ModelDesc): ...@@ -93,7 +91,7 @@ class Model(ModelDesc):
50: ([3,4,6,3], bottleneck), 50: ([3,4,6,3], bottleneck),
101: ([3,4,23,3], bottleneck) 101: ([3,4,23,3], bottleneck)
} }
defs, block_func = cfg[34] defs, block_func = cfg[DEPTH]
with argscope(Conv2D, nl=tf.identity, use_bias=False, with argscope(Conv2D, nl=tf.identity, use_bias=False,
W_init=variance_scaling_initializer(mode='FAN_OUT')): W_init=variance_scaling_initializer(mode='FAN_OUT')):
...@@ -231,22 +229,29 @@ def eval_on_ILSVRC12(model_file, data_dir): ...@@ -231,22 +229,29 @@ def eval_on_ILSVRC12(model_file, data_dir):
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--gpu', help='comma separated list of GPU(s) to use.') # nargs='*' in multi mode parser.add_argument('--gpu', help='comma separated list of GPU(s) to use.')
parser.add_argument('--data', help='ILSVRC dataset dir') parser.add_argument('--data', help='ILSVRC dataset dir')
parser.add_argument('--load', help='load model') parser.add_argument('--load', help='load model')
parser.add_argument('-d', '--depth', help='resnet depth',
type=int, default=18, choices=[18, 34, 50, 101])
parser.add_argument('--eval', action='store_true') parser.add_argument('--eval', action='store_true')
args = parser.parse_args() args = parser.parse_args()
DEPTH = args.depth
if args.gpu: if args.gpu:
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu
if args.eval: if args.eval:
BATCH_SIZE = 128 # something that can run on one gpu
eval_on_ILSVRC12(args.load, args.data) eval_on_ILSVRC12(args.load, args.data)
sys.exit() sys.exit()
logger.auto_set_dir() assert args.gpu is not None, "Need to specify a list of gpu for training!"
NR_GPU = len(args.gpu.split(','))
BATCH_SIZE = TOTAL_BATCH_SIZE / NR_GPU
logger.auto_set_dir()
config = get_config() config = get_config()
if args.load: if args.load:
config.session_init = SaverRestore(args.load) config.session_init = SaverRestore(args.load)
if args.gpu: config.nr_tower = NR_GPU
config.nr_tower = len(args.gpu.split(','))
SyncMultiGPUTrainer(config).train() SyncMultiGPUTrainer(config).train()
...@@ -86,8 +86,8 @@ class Model(ModelDesc): ...@@ -86,8 +86,8 @@ class Model(ModelDesc):
.GlobalAvgPooling('gap') .GlobalAvgPooling('gap')
.FullyConnected('fc1000', 1000, nl=tf.identity)()) .FullyConnected('fc1000', 1000, nl=tf.identity)())
prob = tf.nn.softmax(fc1000, name='prob') prob = tf.nn.softmax(fc1000, name='prob')
nr_wrong = tf.reduce_sum(prediction_incorrect(fc1000, label), name='wrong-top1') nr_wrong = prediction_incorrect(fc1000, label, name='wrong-top1')
nr_wrong = tf.reduce_sum(prediction_incorrect(fc1000, label, 5), name='wrong-top5') nr_wrong = prediction_incorrect(fc1000, label, 5, name='wrong-top5')
def get_inference_augmentor(): def get_inference_augmentor():
# load ResNet mean from Kaiming: # load ResNet mean from Kaiming:
...@@ -136,18 +136,20 @@ def eval_on_ILSVRC12(params, data_dir): ...@@ -136,18 +136,20 @@ def eval_on_ILSVRC12(params, data_dir):
model=Model(), model=Model(),
input_var_names=['input', 'label'], input_var_names=['input', 'label'],
session_init=ParamRestore(params), session_init=ParamRestore(params),
output_var_names=['prob', 'wrong-top1', 'wrong-top5'] output_var_names=['wrong-top1', 'wrong-top5']
) )
pred = SimpleDatasetPredictor(pred_config, ds) pred = SimpleDatasetPredictor(pred_config, ds)
acc1, acc5 = RatioCounter(), RatioCounter() acc1, acc5 = RatioCounter(), RatioCounter()
for o in pred.get_result(): for o in pred.get_result():
batch_size = o[0].shape[0] batch_size = o[0].shape[0]
acc1.feed(o[1], batch_size) acc1.feed(o[0].sum(), batch_size)
acc5.feed(o[2], batch_size) acc5.feed(o[1].sum(), batch_size)
print("Top1 Error: {}".format(acc1.ratio)) print("Top1 Error: {}".format(acc1.ratio))
print("Top5 Error: {}".format(acc5.ratio)) print("Top5 Error: {}".format(acc5.ratio))
def name_conversion(caffe_layer_name): def name_conversion(caffe_layer_name):
""" Convert a caffe parameter name to a tensorflow parameter name as
defined in the above model """
# beginning & end mapping # beginning & end mapping
NAME_MAP = {'bn_conv1/beta': 'conv0/bn/beta', NAME_MAP = {'bn_conv1/beta': 'conv0/bn/beta',
'bn_conv1/gamma': 'conv0/bn/gamma', 'bn_conv1/gamma': 'conv0/bn/gamma',
...@@ -190,7 +192,7 @@ if __name__ == '__main__': ...@@ -190,7 +192,7 @@ if __name__ == '__main__':
parser.add_argument('--gpu', help='comma separated list of GPU(s) to use.') # nargs='*' in multi mode parser.add_argument('--gpu', help='comma separated list of GPU(s) to use.') # nargs='*' in multi mode
parser.add_argument('--load', required=True, parser.add_argument('--load', required=True,
help='.npy model file generated by tensorpack.utils.loadcaffe') help='.npy model file generated by tensorpack.utils.loadcaffe')
parser.add_argument('--depth', help='resnet depth', required=True, type=int, choices=[50, 101, 152]) parser.add_argument('-d', '--depth', help='resnet depth', required=True, type=int, choices=[50, 101, 152])
parser.add_argument('--input', help='an input image') parser.add_argument('--input', help='an input image')
parser.add_argument('--eval', help='ILSVRC dir to run validation on') parser.add_argument('--eval', help='ILSVRC dir to run validation on')
......
...@@ -8,7 +8,8 @@ import time ...@@ -8,7 +8,8 @@ import time
from ..utils import logger from ..utils import logger
try: try:
import gym import gym
gym.undo_logger_setup() # TODO
#gym.undo_logger_setup()
# https://github.com/openai/gym/pull/199 # https://github.com/openai/gym/pull/199
# not sure does it cause other problems # not sure does it cause other problems
__all__ = ['GymEnv'] __all__ = ['GymEnv']
......
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