diff --git a/ImageClassification/CIFAR10/All_CNN/readme.md b/ImageClassification/CIFAR10/All_CNN/readme.md index 246acee..002baec 100644 --- a/ImageClassification/CIFAR10/All_CNN/readme.md +++ b/ImageClassification/CIFAR10/All_CNN/readme.md @@ -13,7 +13,7 @@ The trained weights file can be downloaded from AWS ### neon version -The model weight file above has been generated using neon version tag [v1.4.0]((https://github.com/NervanaSystems/neon/releases/tag/v1.4.0). +The model weight file above has been generated using neon version tag [v2.3.0]((https://github.com/NervanaSystems/neon/releases/tag/v2.3.0). It may not work with other versions. ### Performance diff --git a/ImageClassification/CIFAR10/All_CNN/test.sh b/ImageClassification/CIFAR10/All_CNN/test.sh index af3c27f..a6dc2f8 100755 --- a/ImageClassification/CIFAR10/All_CNN/test.sh +++ b/ImageClassification/CIFAR10/All_CNN/test.sh @@ -24,7 +24,7 @@ echo "Downloading weights file from ${WEIGHTS_URL}" curl -o $WEIGHTS_FILE $WEIGHTS_URL 2> /dev/null python -u $TEST_SCRIPT -i ${EXECUTOR_NUMBER} -vvv \ - --model_file $WEIGHTS_FILE --no_progress_bar | tee output.dat 2>&1 + --model_file $WEIGHTS_FILE --no_progress_bar 2>&1 | tee output.dat rc=$? if [ $rc -ne 0 ];then exit $rc diff --git a/ImageClassification/CIFAR10/DeepResNet/readme.md b/ImageClassification/CIFAR10/DeepResNet/readme.md index a7a2216..dcc80ff 100644 --- a/ImageClassification/CIFAR10/DeepResNet/readme.md +++ b/ImageClassification/CIFAR10/DeepResNet/readme.md @@ -24,10 +24,10 @@ Training this model with the options described below should be able to achieve a accuracy using only mean subtraction, random cropping, and random flips. ## Instructions -This script was tested with [neon version 1.5.0](https://github.com/NervanaSystems/neon/tree/v1.5.0). +This script was tested with [neon version 2.2.0](https://github.com/NervanaSystems/neon/tree/v2.2.0). Make sure that your local repo is synced to this commit and run the [installation procedure](http://neon.nervanasys.com/docs/latest/installation.html) before proceeding. -Commit SHA for v1.5.0 is `8a5b2c45784499cd3aba3c322ea10b3661c2a2a9` +Commit SHA for v2.2.0 is `5843e7116d880dfc59c8fb558beb58dd2ef421d0` This example uses the `DataLoader` module to load the images for consumption while applying random cropping, flipping, and shuffling. To use the DataLoader, the script will generate PNG files from diff --git a/ImageClassification/CIFAR10/DeepResNet/resnet_cifar10.py b/ImageClassification/CIFAR10/DeepResNet/resnet_cifar10.py index 133a651..91adec8 100644 --- a/ImageClassification/CIFAR10/DeepResNet/resnet_cifar10.py +++ b/ImageClassification/CIFAR10/DeepResNet/resnet_cifar10.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ---------------------------------------------------------------------------- +import numpy as np from neon.util.argparser import NeonArgparser from neon.initializers import Kaiming, IdentityInit from neon.layers import Conv, Pooling, GeneralizedCost, Affine, Activation @@ -20,63 +21,59 @@ from neon.optimizers import GradientDescentMomentum, Schedule from neon.transforms import Rectlin, Softmax, CrossEntropyMulti, Misclassification from neon.models import Model -from neon.data import ImageLoader, ImageParams, DataLoader from neon.callbacks.callbacks import Callbacks import os +from neon.data.dataloader_transformers import OneHot, TypeCast, BGRMeanSubtract +from neon.data.aeon_shim import AeonDataLoader + +def wrap_dataloader(dl, dtype=np.float32): + dl = OneHot(dl, index=1, nclasses=10) + dl = TypeCast(dl, index=0, dtype=dtype) + dl = BGRMeanSubtract(dl, index=0) + return dl + +def config(manifest_filename, manifest_root, batch_size, subset_pct): + image_config = {"type": "image", + "height": 32, + "width": 32} + label_config = {"type": "label", + "binary": False} + augmentation = {"type": "image", + "crop_enable": True} + + return {'manifest_filename': manifest_filename, + 'manifest_root': manifest_root, + 'batch_size': batch_size, + 'subset_fraction': float(subset_pct/100.0), + 'etl': [image_config, label_config], + 'augmentation': [augmentation]} + + +def make_train_config(manifest_filename, manifest_root, batch_size, subset_pct=100): + train_config = config(manifest_filename, manifest_root, batch_size, subset_pct) + train_config['augmentation'][0]['center'] = False + train_config['augmentation'][0]['flip_enable'] = True + train_config['shuffle_enable'] = True + train_config['shuffle_manifest'] = True + + return wrap_dataloader(AeonDataLoader(train_config)) + + +def make_val_config(manifest_filename, manifest_root, batch_size, subset_pct=100): + val_config = config(manifest_filename, manifest_root, batch_size, subset_pct) + return wrap_dataloader(AeonDataLoader(val_config)) + # parse the command line arguments (generates the backend) parser = NeonArgparser(__doc__) parser.add_argument('--depth', type=int, default=9, help='depth of each stage (network depth will be 6n+2)') args = parser.parse_args() - -def extract_images(out_dir, padded_size): - ''' - Save CIFAR-10 dataset as PNG files - ''' - import numpy as np - from neon.data import load_cifar10 - from PIL import Image - dataset = dict() - dataset['train'], dataset['val'], _ = load_cifar10(out_dir, normalize=False) - pad_size = (padded_size - 32) // 2 if padded_size > 32 else 0 - pad_width = ((0, 0), (pad_size, pad_size), (pad_size, pad_size)) - - for setn in ('train', 'val'): - data, labels = dataset[setn] - - img_dir = os.path.join(out_dir, setn) - ulabels = np.unique(labels) - for ulabel in ulabels: - subdir = os.path.join(img_dir, str(ulabel)) - if not os.path.exists(subdir): - os.makedirs(subdir) - - for idx in range(data.shape[0]): - im = np.pad(data[idx].reshape((3, 32, 32)), pad_width, mode='mean') - im = np.uint8(np.transpose(im, axes=[1, 2, 0]).copy()) - im = Image.fromarray(im) - path = os.path.join(img_dir, str(labels[idx][0]), str(idx) + '.png') - im.save(path, format='PNG') - # setup data provider -train_dir = os.path.join(args.data_dir, 'train') -test_dir = os.path.join(args.data_dir, 'val') -if not (os.path.exists(train_dir) and os.path.exists(test_dir)): - extract_images(args.data_dir, 40) - -# setup data provider -shape = dict(channel_count=3, height=32, width=32) -train_params = ImageParams(center=False, flip=True, **shape) -test_params = ImageParams(**shape) -common = dict(target_size=1, nclasses=10) - -train = DataLoader(set_name='train', repo_dir=train_dir, media_params=train_params, - shuffle=True, **common) -test = DataLoader(set_name='val', repo_dir=test_dir, media_params=test_params, **common) - +train = make_train_config(args.manifest['train'], args.manifest_root, args.batch_size) +test = make_val_config(args.manifest['val'], args.manifest_root, args.batch_size) def conv_params(fsize, nfm, stride=1, relu=True): return dict(fshape=(fsize, fsize, nfm), strides=stride, padding=(1 if fsize > 1 else 0), diff --git a/ImageClassification/CIFAR10/DeepResNet/resnet_eval.py b/ImageClassification/CIFAR10/DeepResNet/resnet_eval.py index 8528515..9c1687c 100644 --- a/ImageClassification/CIFAR10/DeepResNet/resnet_eval.py +++ b/ImageClassification/CIFAR10/DeepResNet/resnet_eval.py @@ -15,24 +15,50 @@ # ---------------------------------------------------------------------------- import os +import numpy as np from neon.util.argparser import NeonArgparser from neon.util.persist import load_obj from neon.transforms import Misclassification, CrossEntropyMulti from neon.optimizers import GradientDescentMomentum from neon.layers import GeneralizedCost from neon.models import Model -from neon.data import DataLoader, ImageParams + +from neon.data.dataloader_transformers import OneHot, TypeCast, BGRMeanSubtract +from neon.data.aeon_shim import AeonDataLoader # parse the command line arguments (generates the backend) parser = NeonArgparser(__doc__) args = parser.parse_args() -# setup data provider -test_dir = os.path.join(args.data_dir, 'val') -shape = dict(channel_count=3, height=32, width=32) -test_params = ImageParams(center=True, flip=False, **shape) -common = dict(target_size=1, nclasses=10) -test_set = DataLoader(set_name='val', repo_dir=test_dir, media_params=test_params, **common) +def wrap_dataloader(dl, dtype=np.float32): + dl = OneHot(dl, index=1, nclasses=10) + dl = TypeCast(dl, index=0, dtype=dtype) + dl = BGRMeanSubtract(dl, index=0) + return dl + +def config(manifest_filename, manifest_root, batch_size, subset_pct): + image_config = {"type": "image", + "height": 32, + "width": 32} + label_config = {"type": "label", + "binary": False} + augmentation = {"type": "image", + "crop_enable": True, + "center": True, + "flip_enable": False} + + return {'manifest_filename': manifest_filename, + 'manifest_root': manifest_root, + 'batch_size': batch_size, + 'subset_fraction': float(subset_pct/100.0), + 'etl': [image_config, label_config], + 'augmentation': [augmentation]} + +def make_val_config(manifest_filename, manifest_root, batch_size, subset_pct=100): + val_config = config(manifest_filename, manifest_root, batch_size, subset_pct) + return wrap_dataloader(AeonDataLoader(val_config)) + +test_set = make_val_config(args.manifest["val"], args.manifest_root, batch_size=args.batch_size) model = Model(load_obj(args.model_file)) cost = GeneralizedCost(costfunc=CrossEntropyMulti()) diff --git a/ImageClassification/CIFAR10/DeepResNet/test.sh b/ImageClassification/CIFAR10/DeepResNet/test.sh index 8f0591c..48a78ac 100755 --- a/ImageClassification/CIFAR10/DeepResNet/test.sh +++ b/ImageClassification/CIFAR10/DeepResNet/test.sh @@ -23,14 +23,14 @@ WEIGHTS_FILE=${WEIGHTS_URL##*/} echo "Downloading weights file from ${WEIGHTS_URL}" curl -o $WEIGHTS_FILE $WEIGHTS_URL 2> /dev/null -python -u $TEST_SCRIPT -i ${EXECUTOR_NUMBER} -vvv --model_file $WEIGHTS_FILE --no_progress_bar -w /usr/local/data/CIFAR10/macrobatches | tee output.dat 2>&1 +python -u $TEST_SCRIPT -i ${EXECUTOR_NUMBER} -vvv --model_file $WEIGHTS_FILE --manifest val:/data/CIFAR/val-index.csv --manifest_root /data/CIFAR -b gpu -z 32 --no_progress_bar 2>&1 | tee output.dat rc=$? if [ $rc -ne 0 ];then exit $rc fi # get the top-1 misclass -top1=`tail -n 1 output.dat | sed "s/.*Accuracy: //" | sed "s/ \% (Top-1).*//"` +top1=`cat output.dat | sed -n "s/.*Accuracy: \(.*\) \% (Top-1).*/\1/p"` top1pass=0 top1pass=`echo $top1'>'85 | bc -l` diff --git a/ImageClassification/ILSVRC2012/Alexnet/alexnet_neon.py b/ImageClassification/ILSVRC2012/Alexnet/alexnet_neon.py index 057c951..e77b30a 100644 --- a/ImageClassification/ILSVRC2012/Alexnet/alexnet_neon.py +++ b/ImageClassification/ILSVRC2012/Alexnet/alexnet_neon.py @@ -27,16 +27,52 @@ alexnet_neon.py -w --test_only \ --model_file """ - +import numpy as np from neon.util.argparser import NeonArgparser from neon.initializers import Constant, Gaussian from neon.layers import Conv, Dropout, Pooling, GeneralizedCost, Affine, LRN from neon.optimizers import GradientDescentMomentum, MultiOptimizer, Schedule from neon.transforms import Rectlin, Softmax, CrossEntropyMulti, TopKMisclassification from neon.models import Model -from neon.data import ImageLoader from neon.callbacks.callbacks import Callbacks +from neon.data.dataloader_transformers import OneHot, TypeCast, BGRMeanSubtract +from neon.data.aeon_shim import AeonDataLoader + +def wrap_dataloader(dl, dtype=np.float32): + dl = OneHot(dl, index=1, nclasses=1000) + dl = TypeCast(dl, index=0, dtype=dtype) + dl = BGRMeanSubtract(dl, index=0) + return dl + +def common_config(subset_pct, manifest_filename, manifest_root, batch_size): +# cache_root = get_data_cache_or_nothing('i1k-cache/') + image_config = {"type": "image", + "height": 224, + "width": 224} + label_config = {"type": "label", + "binary": False} + augmentation = {"type": "image", + "scale": [0.875, 0.875], + "crop_enable": True} + + return {'manifest_filename': manifest_filename, + 'manifest_root': manifest_root, + 'batch_size': batch_size, + 'subset_fraction': float(subset_pct/100.0), + 'etl': [image_config, label_config], + 'augmentation': [augmentation]} + +def make_train_config(subset_pct, manifest_filename, manifest_root, batch_size): + train_config = common_config(subset_pct, manifest_filename, manifest_root, batch_size) + train_config['shuffle_enable'] = True + train_config['shuffle_manifest'] = True + return wrap_dataloader(AeonDataLoader(train_config)) + +def make_val_config(subset_pct, manifest_filename, manifest_root, batch_size): + val_config = common_config(subset_pct, manifest_filename, manifest_root, batch_size) + return wrap_dataloader(AeonDataLoader(val_config)) + # parse the command line arguments (generates the backend) parser = NeonArgparser(__doc__) parser.add_argument('--subset_pct', type=float, default=100, @@ -49,14 +85,8 @@ if args.model_file is None: raise ValueError('To test model, trained weights need to be provided') -# setup data provider -img_set_options = dict(repo_dir=args.data_dir, - inner_size=224, - subset_pct=args.subset_pct) -train = ImageLoader(set_name='train', scale_range=(256, 256), - shuffle=True, **img_set_options) -test = ImageLoader(set_name='validation', scale_range=(256, 256), - do_transforms=False, **img_set_options) +train = make_train_config(args.subset_pct, args.manifest["train"], args.manifest_root, batch_size=args.batch_size) +val = make_val_config(args.subset_pct, args.manifest["val"], args.manifest_root, batch_size=args.batch_size) init_g1 = Gaussian(scale=0.01) init_g2 = Gaussian(scale=0.005) @@ -105,15 +135,15 @@ # configure callbacks valmetric = TopKMisclassification(k=5) -callbacks = Callbacks(model, eval_set=test, metric=valmetric, **args.callback_args) +callbacks = Callbacks(model, eval_set=val, metric=valmetric, **args.callback_args) if args.model_file is not None: - model.load_params(args.model_file) + model.load_params(args.model_file, load_states=False) if not args.test_only: cost = GeneralizedCost(costfunc=CrossEntropyMulti()) model.fit(train, optimizer=opt, num_epochs=args.epochs, cost=cost, callbacks=callbacks) -mets = model.eval(test, metric=valmetric) +mets = model.eval(val, metric=valmetric) print 'Validation set metrics:' print 'LogLoss: %.2f, Accuracy: %.1f %% (Top-1), %.1f %% (Top-5)' % (mets[0], (1.0-mets[1])*100, diff --git a/ImageClassification/ILSVRC2012/Alexnet/readme.md b/ImageClassification/ILSVRC2012/Alexnet/readme.md index 10c3233..7175be7 100644 --- a/ImageClassification/ILSVRC2012/Alexnet/readme.md +++ b/ImageClassification/ILSVRC2012/Alexnet/readme.md @@ -16,7 +16,7 @@ The model run script is included below [alexnet_neon.py](./alexnet_neon.py). ### Trained weights The trained weights file can be downloaded from AWS using the following link: [trained Alexnet model weights][S3_WEIGHTS_FILE] -[S3_WEIGHTS_FILE]: https://s3-us-west-1.amazonaws.com/nervana-modelzoo/alexnet/alexnet.p +[S3_WEIGHTS_FILE]: https://s3-us-west-1.amazonaws.com/nervana-modelzoo/alexnet/alexnet_fused_conv_bias.p ### Performance This model is acheiving 58.6% top-1 and 81.1% top-5 accuracy on the validation @@ -33,8 +33,7 @@ Note there has been some changes to the format of the mean data subtraction; users with the old format may be prompted to run an update script before proceeding. -This script was tested with the [neon release v1.4.0](https://github.com/NervanaSystems/neon/tree/v1.4.0) -(commit SHA bc196cb). +This script was tested with the [neon release v2.3.0](https://github.com/NervanaSystems/neon/tree/v2.3.0). Make sure that your local repo is synced to this commit and run the [installation procedure](http://neon.nervanasys.com/docs/latest/installation.html) before proceeding. diff --git a/ImageClassification/ILSVRC2012/Alexnet/test.sh b/ImageClassification/ILSVRC2012/Alexnet/test.sh index e81fb41..f8113b7 100755 --- a/ImageClassification/ILSVRC2012/Alexnet/test.sh +++ b/ImageClassification/ILSVRC2012/Alexnet/test.sh @@ -22,7 +22,7 @@ WEIGHTS_FILE=${WEIGHTS_URL##*/} echo "Downloading weights file from ${WEIGHTS_URL}" curl -o $WEIGHTS_FILE $WEIGHTS_URL 2> /dev/null -python -u alexnet_neon.py --test_only -i ${EXECUTOR_NUMBER} -w /usr/local/data/I1K/macrobatches/ -vvv --model_file $WEIGHTS_FILE --no_progress_bar | tee output.dat 2>&1 +python -u alexnet_neon.py --test_only -i ${EXECUTOR_NUMBER} -w /data/i1k-extracted/ --manifest_root /data/i1k-extracted --manifest train:/data/i1k-extracted/train-index.csv --manifest val:/data/i1k-extracted/val-index.csv -vvv --model_file $WEIGHTS_FILE --no_progress_bar -z 256 2>&1 | tee output.dat rc=$? if [ $rc -ne 0 ];then exit $rc diff --git a/ImageClassification/ILSVRC2012/Googlenet/googlenet_neon.py b/ImageClassification/ILSVRC2012/Googlenet/googlenet_neon.py index fe815de..ee75662 100644 --- a/ImageClassification/ILSVRC2012/Googlenet/googlenet_neon.py +++ b/ImageClassification/ILSVRC2012/Googlenet/googlenet_neon.py @@ -18,6 +18,7 @@ """ import os +import numpy as np from neon.util.argparser import NeonArgparser from neon.layers import Conv, Pooling, MergeBroadcast, BranchNode @@ -28,7 +29,35 @@ from neon.optimizers import GradientDescentMomentum, MultiOptimizer from neon.transforms import Rectlin, Softmax, CrossEntropyMulti, TopKMisclassification from neon.models import Model -from neon.data import ImageLoader + +from neon.data.dataloader_transformers import OneHot, TypeCast, BGRMeanSubtract +from neon.data.aeon_shim import AeonDataLoader + +def wrap_dataloader(dl, dtype=np.float32): + dl = OneHot(dl, index=1, nclasses=1000) + dl = TypeCast(dl, index=0, dtype=dtype) + dl = BGRMeanSubtract(dl, index=0) + return dl + +def common_config(subset_pct, manifest_filename, manifest_root, batch_size): + image_config = {"type": "image", + "height": 224, + "width": 224} + label_config = {"type": "label", + "binary": False} + augmentation = {"type": "image", + "scale": [0.875, 0.875]} + + return {'manifest_filename': manifest_filename, + 'manifest_root': manifest_root, + 'batch_size': batch_size, + 'subset_fraction': float(subset_pct/100.0), + 'etl': [image_config, label_config], + 'augmentation': [augmentation]} + +def make_val_config(subset_pct, manifest_filename, manifest_root, batch_size): + val_config = common_config(subset_pct, manifest_filename, manifest_root, batch_size) + return wrap_dataloader(AeonDataLoader(val_config)) parser = NeonArgparser(__doc__) parser.add_argument('--subset_pct', type=float, default=100, @@ -38,10 +67,7 @@ args = parser.parse_args() # setup data provider -img_set_options = dict(repo_dir=args.data_dir, inner_size=224, - subset_pct=args.subset_pct) -test = ImageLoader(set_name='validation', scale_range=(256, 256), - do_transforms=False, **img_set_options) +val = make_val_config(args.subset_pct, args.manifest['val'], args.manifest_root, args.batch_size) init1 = Xavier(local=False) initx = Xavier(local=True) @@ -122,16 +148,16 @@ def aux_branch(bnode): weights=[1, 0., 0.]) # We only want to consider the CE of the main path assert os.path.exists(args.model_file), 'script requires the trained weights file' -model.load_params(args.model_file) -model.initialize(test, cost) +model.load_params(args.model_file, load_states=False) +model.initialize(val, cost) print 'running speed benchmark...' -model.benchmark(test, cost, opt) +model.benchmark(val, cost, opt) print '\nCalculating performance on validation set...' -test.reset() -mets = model.eval(test, metric=valmetric) +val.reset() +mets = model.eval(val, metric=valmetric) print 'Validation set metrics:' print 'LogLoss: %.2f, Accuracy: %.1f %% (Top-1), %.1f %% (Top-5)' % (mets[0], (1.0-mets[1])*100, diff --git a/ImageClassification/ILSVRC2012/Googlenet/readme.md b/ImageClassification/ILSVRC2012/Googlenet/readme.md index 66e30cd..62665c6 100644 --- a/ImageClassification/ILSVRC2012/Googlenet/readme.md +++ b/ImageClassification/ILSVRC2012/Googlenet/readme.md @@ -14,7 +14,7 @@ The model run script is included here [googlenet_neon.py](./googlenet_neon.py). The trained weights file can be downloaded from AWS using the following link: [trained googlenet model weights][S3_WEIGHTS_FILE]. -[S3_WEIGHTS_FILE]: https://s3-us-west-1.amazonaws.com/nervana-modelzoo/googlenet/googlenet.p +[S3_WEIGHTS_FILE]: https://s3-us-west-1.amazonaws.com/nervana-modelzoo/googlenet/googlenet_fused_conv_bias.p ### Performance This model is acheiving 64% top-1 and 85.5% top-5 accuracy on the validation data set. @@ -26,7 +26,7 @@ During training, the images were randomly cropped and flipped horizontally but s To run the model, first the ImageNet data set needs to be uploaded and converted to the format compatible with neon (see [instructions](http://neon.nervanasys.com/docs/latest/datasets.html#imagenet)). Note there has been some changes to the format of the mean data subtraction; users with the old format may be prompted to run an update script before proceeding. -This script works with the [neon commit SHA 66846b409](https://github.com/NervanaSystems/neon/commit/66846b4097d256e176cd76559dfa4e0bc54ab6dc). Make sure that your local repo is synced to this commit and run the [installation procedure](http://neon.nervanasys.com/docs/latest/installation.html) before proceeding. +This script works with the [neon release v2.3.0](https://github.com/NervanaSystems/neon/tree/v2.3.0). Make sure that your local repo is synced to this commit and run the [installation procedure](http://neon.nervanasys.com/docs/latest/installation.html) before proceeding. If neon is installed into a `virtualenv`, make sure that it is activated before running the commands below. Also, the commands below use the GPU backend by default so add `-b cpu` if you are running on a system without a compatible GPU. diff --git a/ImageClassification/ILSVRC2012/Googlenet/test.sh b/ImageClassification/ILSVRC2012/Googlenet/test.sh index 530a750..fbca2ed 100755 --- a/ImageClassification/ILSVRC2012/Googlenet/test.sh +++ b/ImageClassification/ILSVRC2012/Googlenet/test.sh @@ -22,7 +22,7 @@ WEIGHTS_FILE=${WEIGHTS_URL##*/} echo "Downloading weights file from ${WEIGHTS_URL}" curl -o $WEIGHTS_FILE $WEIGHTS_URL 2> /dev/null -python -u googlenet_neon.py --test_only -i ${EXECUTOR_NUMBER} -w /usr/local/data/I1K/macrobatches/ -vvv --model_file $WEIGHTS_FILE --no_progress_bar | tee output.dat 2>&1 +python -u googlenet_neon.py --test_only -i ${EXECUTOR_NUMBER} -w /data/i1k-extracted --manifest_root /data/i1k-extracted --manifest val:/data/i1k-extracted/val-index.csv -vvv --model_file $WEIGHTS_FILE --no_progress_bar 2>&1 | tee output.dat rc=$? if [ $rc -ne 0 ];then exit $rc diff --git a/ImageClassification/ILSVRC2012/VGG/readme.md b/ImageClassification/ILSVRC2012/VGG/readme.md index 1c69957..5b54a2d 100644 --- a/ImageClassification/ILSVRC2012/VGG/readme.md +++ b/ImageClassification/ILSVRC2012/VGG/readme.md @@ -7,8 +7,8 @@ The model run script is included here [vgg_neon.py](./vgg_neon.py). This script ### Trained weights The trained weights file can be downloaded from AWS using the following links: -[VGG_D.p]( https://s3-us-west-1.amazonaws.com/nervana-modelzoo/VGG/VGG_D.p) and [VGG_E.p][S3_WEIGHTS_FILE]. -[S3_WEIGHTS_FILE]: https://s3-us-west-1.amazonaws.com/nervana-modelzoo/VGG/VGG_E.p +[VGG_D.p]( https://s3-us-west-1.amazonaws.com/nervana-modelzoo/VGG/VGG_D_fused_conv_bias.p) and [VGG_E.p][S3_WEIGHTS_FILE]. +[S3_WEIGHTS_FILE]: https://s3-us-west-1.amazonaws.com/nervana-modelzoo/VGG/VGG_E_fused_conv_bias.p ## Performance @@ -95,7 +95,7 @@ The batch size is set to 64 in the examples above because with larger batch size ### Version compatibility -Neon version: commit SHA [e7ab2c2e2](https://github.com/NervanaSystems/neon/commit/e7ab2c2e27f113a4d36d17ba8c79546faed7d916). +Neon version: v2.3.0 (https://github.com/NervanaSystems/neon/tree/v2.3.0). ## Citation diff --git a/ImageClassification/ILSVRC2012/VGG/test.sh b/ImageClassification/ILSVRC2012/VGG/test.sh index 3778627..46f3c0b 100755 --- a/ImageClassification/ILSVRC2012/VGG/test.sh +++ b/ImageClassification/ILSVRC2012/VGG/test.sh @@ -22,7 +22,8 @@ WEIGHTS_FILE=${WEIGHTS_URL##*/} echo "Downloading weights file from ${WEIGHTS_URL}" curl -o $WEIGHTS_FILE $WEIGHTS_URL 2> /dev/null -python -u vgg_neon.py --test_only -i ${EXECUTOR_NUMBER} -w /usr/local/data/I1K/macrobatches/ -vvv --model_file $WEIGHTS_FILE --no_progress_bar -z 64 --vgg_version E | tee output.dat 2>&1 +python -u vgg_neon.py --test_only -i ${EXECUTOR_NUMBER} -w /data/i1k-extracted -vvv --manifest_root /data/i1k-extracted --manifest val:/data/i1k-extracted/val-index.csv --model_file $WEIGHTS_FILE --no_progress_bar -z 64 --vgg_version E 2>&1 | tee output.dat + rc=$? if [ $rc -ne 0 ];then exit $rc diff --git a/ImageClassification/ILSVRC2012/VGG/vgg_neon.py b/ImageClassification/ILSVRC2012/VGG/vgg_neon.py index 6faf18f..94a6bfd 100644 --- a/ImageClassification/ILSVRC2012/VGG/vgg_neon.py +++ b/ImageClassification/ILSVRC2012/VGG/vgg_neon.py @@ -20,7 +20,7 @@ K. Simonyan, A. Zisserman arXiv:1409.1556 """ - +import numpy as np from neon.util.argparser import NeonArgparser from neon.backends import gen_backend from neon.initializers import Constant, GlorotUniform, Xavier @@ -28,9 +28,44 @@ from neon.optimizers import GradientDescentMomentum, Schedule, MultiOptimizer from neon.transforms import Rectlin, Softmax, CrossEntropyMulti, TopKMisclassification from neon.models import Model -from neon.data import ImageLoader from neon.callbacks.callbacks import Callbacks +from neon.data.dataloader_transformers import OneHot, TypeCast, BGRMeanSubtract +from neon.data.aeon_shim import AeonDataLoader + +def wrap_dataloader(dl, dtype=np.float32): + dl = OneHot(dl, index=1, nclasses=1000) + dl = TypeCast(dl, index=0, dtype=dtype) + dl = BGRMeanSubtract(dl, index=0) + return dl + +def common_config(subset_pct, manifest_filename, manifest_root, batch_size, scale): + image_config = {"type": "image", + "height": 224, + "width": 224} + label_config = {"type": "label", + "binary": False} + augmentation = {"type": "image", + "scale": scale, + "crop_enable": True} + + return {'manifest_filename': manifest_filename, + 'manifest_root': manifest_root, + 'batch_size': batch_size, + 'subset_fraction': float(subset_pct/100.0), + 'etl': [image_config, label_config], + 'augmentation': [augmentation]} + +def make_train_config(subset_pct, manifest_filename, manifest_root, batch_size, scale): + train_config = common_config(subset_pct, manifest_filename, manifest_root, batch_size, scale) + train_config['shuffle_enable'] = True + train_config['shuffle_manifest'] = True + return wrap_dataloader(AeonDataLoader(train_config)) + +def make_val_config(subset_pct, manifest_filename, manifest_root, batch_size, scale): + val_config = common_config(subset_pct, manifest_filename, manifest_root, batch_size, scale) + return wrap_dataloader(AeonDataLoader(val_config)) + # parse the command line arguments parser = NeonArgparser(__doc__) parser.add_argument('--vgg_version', default='D', choices=['D', 'E'], @@ -41,12 +76,11 @@ help='skip fitting - evaluate metrics on trained model weights') args = parser.parse_args() -img_set_options = dict(repo_dir=args.data_dir, inner_size=224, - subset_pct=args.subset_pct) -train = ImageLoader(set_name='train', scale_range=(256, 384), - shuffle=True, **img_set_options) -test = ImageLoader(set_name='validation', scale_range=(256, 256), do_transforms=False, - shuffle=False, **img_set_options) +# Training set has different scale configuration (256, 384) than testing set (256, 256). Why? +# Commenting it out gives the folowing runtime error: +# RuntimeError: Unable to create internal loader object: value for 'scale' out of range +#train = make_train_config(args.subset_pct, args.manifest["train"], args.manifest_root, batch_size=args.batch_size, scale=[0.875, 0.583]) +val = make_val_config(args.subset_pct, args.manifest["val"], args.manifest_root, batch_size=args.batch_size, scale=[0.875, 0.875]) init1 = Xavier(local=True) initfc = GlorotUniform() @@ -83,10 +117,10 @@ # configure callbacks top5 = TopKMisclassification(k=5) -callbacks = Callbacks(model, eval_set=test, metric=top5, **args.callback_args) +callbacks = Callbacks(model, eval_set=val, metric=top5, **args.callback_args) -model.load_params(args.model_file) -mets=model.eval(test, metric=TopKMisclassification(k=5)) +model.load_params(args.model_file, load_states=False) +mets=model.eval(val, metric=TopKMisclassification(k=5)) print 'Validation set metrics:' print 'LogLoss: %.2f, Accuracy: %.1f %% (Top-1), %.1f %% (Top-5)' % (mets[0], (1.0-mets[1])*100,