Skip to content
This repository was archived by the owner on Nov 17, 2023. It is now read-only.

[MXNet-1343][Fit API]Add CNN integration test for fit() API - #14405

Merged
nswamy merged 13 commits into
apache:fit-apifrom
abhinavs95:fit-api-test
Apr 3, 2019
Merged

nswamy merged 13 commits into
apache:fit-apifrom
abhinavs95:fit-api-test

Conversation

@abhinavs95

@abhinavs95 abhinavs95 commented Mar 12, 2019

Copy link
Copy Markdown
Contributor

Description

Add nightly integration tests for fit() API using CNN models.
This PR depends on the parent PR for fit() API #14346
JIRA epic: https://issues.apache.org/jira/projects/MXNET/issues/MXNET-1333

Checklist

Essentials

Please feel free to remove inapplicable items for your PR.

  • The PR title starts with MXNet-1343
  • Changes are complete (i.e. I finished coding on this PR)
  • All changes have test coverage:
  • Unit tests are added for small changes to verify correctness (e.g. adding a new operator)
  • Nightly tests are added for complicated/long-running ones (e.g. changing distributed kvstore)
  • Build tests will be added for build configuration changes (e.g. adding a new build option with NCCL)
  • Code is well-documented:
  • For user-facing API changes, API doc string has been updated.
  • For new C++ functions in header files, their functionalities and arguments are documented.
  • For new examples, README.md is added to explain the what the example does, the source of the dataset, expected performance on test set and reference to the original paper if applicable
  • Check the API doc at http://mxnet-ci-doc.s3-accelerate.dualstack.amazonaws.com/PR-$PR_ID/$BUILD_ID/index.html
  • To the my best knowledge, examples are either not affected by this change, or have been fixed to be compatible with this change

Changes

  • test_estimator_cnn_cpu: test on cpu using synthetic data on alexnet, resnet18_v1, FCN
  • test_estimator_cnn_gpu: test on gpu using MNIST dataset on resnet18_v1 and verify training accuracy

Comments

  • If this change is a backward incompatible change, why must this change be made.
  • Interesting edge cases to note here

Comment thread ci/docker/runtime_functions.sh Outdated
set -ex
cd /work/mxnet/tests/nightly/estimator
export PYTHONPATH=/work/mxnet/python/
python tests/nightly/estimator/test_estimator_cnn_gpu.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the test_estimator_cnn_gpu.py file path correct? The current shell location is already inside /work/mxnet/tests/nightly/estimator directory.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed!

Comment thread tests/nightly/JenkinsfileForBinaries Outdated
'estimator: CNN CPU': {
node(NODE_LINUX_CPU) {
ws('workspace/estimator-test-cnn-cpu') {
utils.unpack_and_init('gpu', mx_lib)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 'cpu' ??

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed!

trainers=trainer,
context=context)
# Call fit() to begin training
logging_handler = event_handler.LoggingHandler(est, model_name+'_log', model_name+'_log')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoggingHandler Class constructor says def __init__(self, estimator, file_name=None, file_location=None, ):, is file_location name correct?(e.g.: alexnet_log/alexnet_log). I think you have to provide file_location as a directory path or you can leave it empty since code takes care of it. Thanks!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing it out. Removing logging handler from integration tests for now as its undergoing changes. It will be covered in unit tests.

trainers=trainer,
context=context)
# Call fit() to begin training
logging_handler = event_handler.LoggingHandler(est, model_name+'_log', model_name+'_log')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

@karan6181

Copy link
Copy Markdown
Contributor

@mxnet-label-bot add [Gluon, pr-work-in-progress]

@marcoabreu marcoabreu added Gluon pr-work-in-progress PR is still work in progress labels Mar 13, 2019

@roywei roywei left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank for your contribution, as these tests are not running in PR checks, let's test them before merging.

context=context)
# Call fit() to begin training
est.fit(train_data=train_data,
# val_data=test_data,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add validation data here once #14442 merged

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in 810faef

dataset = gluon.data.dataset.ArrayDataset(mx.nd.random.uniform(shape=(batch_size, 1, 224, 224)),
mx.nd.zeros(batch_size))
loss = gluon.loss.SoftmaxCrossEntropyLoss()
net.initialize(mx.init.MSRAPrelu(), ctx=context)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use a more common initializer

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to Xavier initializer


def bilinear_kernel(in_channels, out_channels, kernel_size):
'''
Bilinear interpolation using transposed convolution

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reference for this implementation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added link to reference code

from mxnet.gluon.model_zoo import vision

def load_data_mnist(batch_size, resize=None, num_workers=None,
root=os.path.join('~', '.mxnet', 'datasets', 'mnist')):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove root, let's not keep the data under ~/.mxnet in nightly tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@nswamy nswamy changed the title [MXNet-1343][WIP][Fit API]Add CNN integration test for fit() API [MXNet-1343][Fit API]Add CNN integration test for fit() API Mar 19, 2019
context=context)
# Call fit() to begin training
est.fit(train_data=train_data,
val_data=train_data,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please create another random validation data and pass it here instead of using same train_data for both train and validation. Thanks!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@roywei roywei left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LTGM! let wait for CI back to normal. also try to run this locally to make sure it passes

@abhinavs95

Copy link
Copy Markdown
Contributor Author

@mxnet-label-bot update [Gluon, Test, pr-awaiting-merge]

@marcoabreu marcoabreu added pr-awaiting-merge Review and CI is complete. Ready to Merge Test and removed pr-work-in-progress PR is still work in progress labels Mar 26, 2019
val_dataset = gluon.data.dataset.ArrayDataset(mx.nd.random.uniform(shape=(batch_size, 3, 320, 480)),
mx.nd.zeros(shape=(batch_size, 320, 480)))
loss = gluon.loss.SoftmaxCrossEntropyLoss(axis=1)
net[-1].initialize(init.Constant(bilinear_kernel(num_classes, num_classes, 64)), ctx=context)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not get the net from directly from FCN method?, why split the logic?.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated logic, please have a look again

input_size = 224
lr = 0.001
# Set context
if mx.context.num_gpus() > 0:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use all GPUs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GPU test just runs 5 epochs on MNIST, I think 1 GPU is enough.

from mxnet.gluon.estimator import estimator, event_handler
from mxnet.gluon.model_zoo import vision

def load_data_mnist(batch_size, resize=None, num_workers=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you have we need 2 different files?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

combined tests into 1 file

Test estimator by doing one pass over each model with synthetic data
'''
models = ['resnet18_v1',
'alexnet',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think we need alexnet here since the fit is not very different than resnet.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed alexnet

set -ex
cd /work/mxnet/tests/nightly/estimator
export PYTHONPATH=/work/mxnet/python/
python test_estimator_cnn.py --type gpu

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the reason to run a python script instead of using nosetest and assert accuracy at the end?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are executing a single test here, running the python script suffices. We can shift to nosetests if we add more tests in the future.

utils.docker_run('ubuntu_nightly_gpu', 'nightly_tutorial_test_ubuntu_python3_gpu', true, '1500m')
}
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, This should be in nightly/Jenkinsfile and not the one for Binaries

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should work in either Jenkins file, I placed it in binaries since it contained similar existing nightly tests. I will keep your suggestion in mind and update with a follow up PR in case there are any issues with the current setup.

model_name = 'resnet18_v1'
batch_size = 128
num_epochs = 5
if mx.context.num_gpus() > 0:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not fallback to mx.cpu here since you want to test on gpu only in this test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not want the test to fail if GPU is not available, it should pass on either context.

@nswamy nswamy Apr 3, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we want it to fail and know if there is an issue, could you please change it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleted "Also use all the GPUs, so if we run this same code elsewhere we can make use of it without having to change this code."

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignore the comment on using all GPUs, we can do it as required.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated context to use GPU

epochs=num_epochs,
batch_size=batch_size)

assert est.train_stats['train_'+acc.name][num_epochs-1] > 0.75

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this only 75%?

@abhinavs95 abhinavs95 Apr 3, 2019

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After 5 epochs the training accuracy is ~85%. I have made it more strict by setting it to 80%. What do you think?

@nswamy
nswamy merged commit b1ef99a into apache:fit-api Apr 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Gluon pr-awaiting-merge Review and CI is complete. Ready to Merge Test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants