├── puppy.jpg ├── figures ├── loss2.png ├── l2_loss2.png ├── accuracy3.png └── cross_entropy2.png ├── LICENSE-MIT ├── Contributing.md ├── preprocess.py ├── train.py ├── model.py ├── recipe_resnet50_imagenet.md ├── Code-Of-Conduct.md ├── README.md └── inference.ipynb /puppy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/ml-reproducibility-guidelines/master/puppy.jpg -------------------------------------------------------------------------------- /figures/loss2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/ml-reproducibility-guidelines/master/figures/loss2.png -------------------------------------------------------------------------------- /figures/l2_loss2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/ml-reproducibility-guidelines/master/figures/l2_loss2.png -------------------------------------------------------------------------------- /figures/accuracy3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/ml-reproducibility-guidelines/master/figures/accuracy3.png -------------------------------------------------------------------------------- /figures/cross_entropy2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/ml-reproducibility-guidelines/master/figures/cross_entropy2.png -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2018 Oath Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | First, thanks for taking the time to contribute to our project! The following information provides a guide for making contributions. 3 | 4 | ## Code of Conduct 5 | 6 | By participating in this project, you agree to abide by the [Oath Code of Conduct](Code-of-Conduct.md). Everyone is welcome to submit a pull request or open an issue to improve the documentation, add improvements, or report bugs. 7 | 8 | ## How to Ask a Question 9 | 10 | If you simply have a question that needs an answer, [create an issue](https://help.github.com/articles/creating-an-issue/), and label it as a question. 11 | 12 | ## How To Contribute 13 | 14 | ### Report a Bug or Request a Feature 15 | 16 | If you encounter any bugs while using this software, or want to request a new feature or enhancement, feel free to [create an issue](https://help.github.com/articles/creating-an-issue/) to report it, make sure you add a label to indicate what type of issue it is. 17 | 18 | ### Contribute Code 19 | - The following line must be included in your pull request: 20 | > I confirm that this contribution is made under the terms of the license found in the root directory of this repository's source tree and that I have the authority necessary to make this contribution on behalf of its copyright owner. 21 | 22 | Pull requests are welcome for bug fixes. If you want to implement something new, please [request a feature first](#report-a-bug-or-request-a-feature) so we can discuss it. 23 | 24 | #### Creating a Pull Request 25 | Please follow [best practices](https://github.com/trein/dev-best-practices/wiki/Git-Commit-Best-Practices) for creating git commits. 26 | 27 | When your code is ready to be submitted, you can [submit a pull request](https://help.github.com/articles/creating-a-pull-request/) to begin the code review process. 28 | -------------------------------------------------------------------------------- /preprocess.py: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Oath Inc. 2 | // Licensed under the terms of the MIT license. Please see LICENSE file in project root for terms. 3 | 4 | from __future__ import absolute_import 5 | from __future__ import division 6 | from __future__ import print_function 7 | 8 | import tensorflow as tf 9 | 10 | _NUM_CHANNELS = 3 11 | _DEFAULT_IMAGE_SIZE = 224 12 | _RESIZE_SIDE_MIN = 256 13 | 14 | 15 | def _parse_function(example_proto, output_height, output_width, is_training=False, 16 | resize_side_min=_RESIZE_SIDE_MIN): 17 | """Parse TF Records and preprocess image and labels 18 | """ 19 | 20 | # parse the TFRecord 21 | feature_map = { 22 | "image/encoded": tf.FixedLenFeature((), tf.string, default_value=""), 23 | "image/format": tf.FixedLenFeature((), tf.string, default_value=""), 24 | "image/class/label": tf.VarLenFeature(tf.int64), 25 | "image/height": tf.FixedLenFeature((), tf.int64, default_value=0), 26 | "image/width": tf.FixedLenFeature((), tf.int64, default_value=0), 27 | "image/object/bbox/xmin": tf.VarLenFeature(tf.float32), 28 | "image/object/bbox/ymin": tf.VarLenFeature(tf.float32), 29 | "image/object/bbox/xmax": tf.VarLenFeature(tf.float32), 30 | "image/object/bbox/ymax": tf.VarLenFeature(tf.float32), 31 | } 32 | features = tf.parse_single_example(example_proto, feature_map) 33 | 34 | # parse bounding box 35 | xmin = tf.expand_dims(features['image/object/bbox/xmin'].values, 0) 36 | ymin = tf.expand_dims(features['image/object/bbox/ymin'].values, 0) 37 | xmax = tf.expand_dims(features['image/object/bbox/xmax'].values, 0) 38 | ymax = tf.expand_dims(features['image/object/bbox/ymax'].values, 0) 39 | 40 | bbox = tf.concat([ymin, xmin, ymax, xmax], 0) 41 | bbox = tf.expand_dims(bbox, 0) 42 | bbox = tf.transpose(bbox, [0, 2, 1]) 43 | 44 | # ImageNet preprocessing 45 | from official.resnet import imagenet_preprocessing 46 | image = imagenet_preprocessing.preprocess_image( 47 | image_buffer=features["image/encoded"], 48 | bbox=bbox, 49 | output_height=output_height, 50 | output_width=output_width, 51 | num_channels=_NUM_CHANNELS, 52 | is_training=is_training) 53 | 54 | # convert labels to dense 55 | labels = tf.sparse_tensor_to_dense(features["image/class/label"]) 56 | 57 | return image, labels 58 | 59 | 60 | def train_parse_function(example_proto): 61 | return _parse_function(example_proto, 62 | _DEFAULT_IMAGE_SIZE, 63 | _DEFAULT_IMAGE_SIZE, 64 | is_training=True) 65 | 66 | 67 | def eval_parse_function(example_proto): 68 | return _parse_function(example_proto, 69 | _DEFAULT_IMAGE_SIZE, 70 | _DEFAULT_IMAGE_SIZE, 71 | is_training=False) 72 | 73 | 74 | -------------------------------------------------------------------------------- /train.py: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Oath Inc. 2 | // Licensed under the terms of the MIT license. Please see LICENSE file in project root for terms. 3 | 4 | from __future__ import absolute_import 5 | from __future__ import division 6 | from __future__ import print_function 7 | 8 | import os, sys 9 | from glob import glob 10 | 11 | import tensorflow as tf 12 | 13 | tf.logging.set_verbosity(tf.logging.INFO) 14 | 15 | tf.app.flags.DEFINE_string('dataset_directory', '/tmp/', 16 | 'Dataset directory') 17 | tf.app.flags.DEFINE_string('output_directory', '/tmp/', 18 | 'Output data directory') 19 | tf.app.flags.DEFINE_string('models_repository', '/tmp', 20 | 'Path to tensorflow/models repository') 21 | tf.app.flags.DEFINE_integer('num_gpus', 4, 22 | 'Number of GPU for distributed training') 23 | tf.app.flags.DEFINE_integer('batch_size', 256, 24 | 'Total batch size') 25 | 26 | FLAGS = tf.app.flags.FLAGS 27 | 28 | 29 | from model import model_fn 30 | 31 | 32 | def dataset_input_fn(filenames, batch_size, is_training): 33 | """ 34 | """ 35 | from preprocess import train_parse_function, eval_parse_function 36 | 37 | dataset = tf.data.TFRecordDataset(filenames) 38 | parse_function = train_parse_function if is_training else eval_parse_function 39 | dataset = dataset.map(parse_function, num_parallel_calls=32) 40 | dataset = dataset.batch(batch_size) 41 | dataset = dataset.prefetch(256) 42 | if is_training is True: 43 | dataset = dataset.repeat() 44 | 45 | return dataset 46 | 47 | 48 | 49 | def main(argv): 50 | """ 51 | """ 52 | 53 | # add path to tensorflow/models repository 54 | sys.path.append(FLAGS.models_repository) 55 | 56 | distribution_strategy = tf.contrib.distribute.MirroredStrategy(num_gpus=FLAGS.num_gpus) 57 | 58 | run_config = tf.estimator.RunConfig( 59 | train_distribute=distribution_strategy) 60 | 61 | # learning rate schedule 62 | lr_boundaries = [500000, 1000000] 63 | lr_values = [0.01, 0.001, 0.0001] 64 | 65 | estimator = tf.estimator.Estimator( 66 | model_fn=model_fn, 67 | model_dir=FLAGS.output_directory, 68 | params={'weight_decay': 1e-4, 69 | 'lr_boundaries': lr_boundaries, 70 | 'lr_values': lr_values}, 71 | config=run_config) 72 | 73 | batch_size_per_gpu = FLAGS.batch_size // FLAGS.num_gpus 74 | 75 | def train_input_fn(): 76 | train_filenames = glob(os.path.join(FLAGS.dataset_directory, "train*")) 77 | return dataset_input_fn(train_filenames, batch_size_per_gpu, True) 78 | 79 | def eval_input_fn(): 80 | eval_filenames = glob(os.path.join(FLAGS.dataset_directory, "validation*")) 81 | return dataset_input_fn(eval_filenames, 50, False) 82 | 83 | train_spec = tf.estimator.TrainSpec(input_fn=train_input_fn, max_steps=2000000) 84 | eval_spec = tf.estimator.EvalSpec(input_fn=eval_input_fn, steps=2000, 85 | start_delay_secs=600, 86 | throttle_secs=1800) 87 | 88 | tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec) 89 | 90 | if __name__ == "__main__": 91 | tf.app.run() -------------------------------------------------------------------------------- /model.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from __future__ import division 3 | from __future__ import print_function 4 | 5 | import tensorflow as tf 6 | 7 | 8 | def model_fn(features, labels, mode, params): 9 | """ 10 | """ 11 | from official.resnet import resnet_model 12 | 13 | tf.summary.image('images', features, max_outputs=6) 14 | 15 | features = tf.cast(features, tf.float32) 16 | 17 | model = resnet_model.Model( 18 | resnet_size=50, 19 | bottleneck=True, 20 | num_classes=1000, 21 | num_filters=64, 22 | kernel_size=7, 23 | conv_stride=2, 24 | first_pool_size=3, 25 | first_pool_stride=2, 26 | block_sizes=[3, 4, 6, 3], 27 | block_strides=[1, 2, 2, 2], 28 | final_size=2048, 29 | resnet_version=2, 30 | data_format=None, 31 | dtype=tf.float32) 32 | 33 | logits = model(features, mode == tf.estimator.ModeKeys.TRAIN) 34 | logits = tf.cast(logits, tf.float32) 35 | 36 | predictions = { 37 | 'classes': tf.argmax(logits, axis=1) + 1, 38 | 'probabilities': tf.nn.softmax(logits, name='softmax_tensor') 39 | } 40 | 41 | if mode == tf.estimator.ModeKeys.PREDICT: 42 | return tf.estimator.EstimatorSpec( 43 | mode=mode, 44 | predictions=predictions, 45 | export_outputs={ 46 | 'predict': tf.estimator.export.PredictOutput(predictions) 47 | }) 48 | 49 | # calculate loss 50 | onehot_labels = tf.one_hot(tf.squeeze(labels - 1), 1000) 51 | cross_entropy = tf.losses.softmax_cross_entropy( 52 | onehot_labels=onehot_labels, logits=logits) 53 | 54 | tf.identity(cross_entropy, name='cross_entropy') 55 | tf.summary.scalar('cross_entropy', cross_entropy) 56 | 57 | def exclude_batch_norm(name): 58 | return 'batch_normalization' not in name 59 | loss_filter_fn = exclude_batch_norm 60 | 61 | # add weight decay 62 | l2_loss = params['weight_decay'] * tf.add_n( 63 | [tf.nn.l2_loss(tf.cast(v, tf.float32)) for v in tf.trainable_variables() 64 | if loss_filter_fn(v.name)]) 65 | tf.summary.scalar('l2_loss', l2_loss) 66 | 67 | loss = cross_entropy + l2_loss 68 | 69 | if mode == tf.estimator.ModeKeys.TRAIN: 70 | 71 | global_step = tf.train.get_or_create_global_step() 72 | 73 | learning_rate = tf.train.piecewise_constant(global_step, 74 | params['lr_boundaries'], params['lr_values']) 75 | 76 | tf.identity(learning_rate, name='learning_rate') 77 | tf.summary.scalar('learning_rate', learning_rate) 78 | 79 | optimizer = tf.train.MomentumOptimizer( 80 | learning_rate=learning_rate, 81 | momentum=0.9) 82 | 83 | minimize_op = optimizer.minimize(loss, global_step) 84 | 85 | update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) 86 | train_op = tf.group(minimize_op, update_ops) 87 | 88 | eval_metric_ops = None 89 | 90 | else: 91 | 92 | train_op = None 93 | 94 | accuracy = tf.metrics.accuracy(labels, predictions['classes']) 95 | 96 | tf.identity(accuracy[1], name='train_accuracy') 97 | tf.summary.scalar('train_accuracy', accuracy[1]) 98 | 99 | eval_metric_ops = {'accuracy': accuracy} 100 | 101 | 102 | return tf.estimator.EstimatorSpec( 103 | mode=mode, 104 | predictions=predictions, 105 | loss=loss, 106 | train_op=train_op, 107 | eval_metric_ops=eval_metric_ops) -------------------------------------------------------------------------------- /recipe_resnet50_imagenet.md: -------------------------------------------------------------------------------- 1 | # Train ResNet-50 on ImageNet 2 | 3 | We provide below the recipe to train a ResNet-50 [model](https://www.cv-foundation.org/openaccess/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html) on the ImageNet dataset and achieve 74.05% single crop accuracy on the validation set. This recipe was based on models that were previously trained in [TensorFlow](https://github.com/tensorflow/models/tree/master/official/resnet) and [Caffe](https://github.com/KaimingHe/deep-residual-networks). 4 | 5 | ## Data 6 | 7 | ### Raw data 8 | 9 | #### Description 10 | 11 | The ImageNet dataset contains ~14M images that are classified into ~21K categories from the WordNet hierarchy. The classification task in the ImageNet Large Scale Visual Recognition Competition (ILSVRC) uses a subset of 1000 categories with ~1M associated images for training. Each image has a single label associated, and a bounding box with the object location may be available. 12 | 13 | #### Path 14 | Information on how to download ImageNet can be found on the dataset [website](http://image-net.org/). You need to sign up for an account in order to access the data. 15 | 16 | ### Data Processing Methods 17 | 18 | #### Description 19 | 20 | Images are downloaded and processed into the TFRecord format. The training data is sharded into 1024 training files with names `train-0????-of-01024` and 128 validation files with names `validation-0????-of-00128`. The classes are randomly distributed within each file. Data processing may take up to half a day. 21 | 22 | #### Code 23 | We follow the data processing methods from the Inception [guide](https://github.com/tensorflow/models/tree/master/research/inception#getting-started). We ran the code using commit `bd56a06d2815e3dc2914fc8ce2fa1ea60e19d324`. 24 | 25 | #### Path 26 | The processed data can be found in HDFS at `hdfs:/projects/ml/data/imagenet_bbox`. Contact the author for permissions and access. 27 | 28 | ## Training 29 | 30 | ### Optimization Methods 31 | 32 | #### Description 33 | We use the ResNet-50 architecture and the softmax loss. 34 | 35 | #### Code 36 | We ran our experiments using git commit `24b236fdb6ca449eb52e8f816e039e0d634015a5`. The code is written using TensorFlow and uses its high level [APIs](https://www.tensorflow.org/guide/estimators). After cloning the repository you can train the model by running 37 | 38 | ``` 39 | python train.py \ 40 | --dataset_directory=/path/to/data \ 41 | --output_directory=/path/to/output \ 42 | --models_repository=/path/to/repo 43 | ``` 44 | 45 | where 46 | 47 | * `dataset_directory` points to the training data. We expect a directory with the training and validation files with patterns `train-0????-of-01024` and `validation-0????-of-00128`. 48 | * `output_directory` is the directory where model checkpoints and logs are written. 49 | * `models_repository` points to the directory where you have cloned the TensorFlow models [repository](https://github.com/tensorflow/models) which contains the code to build the ResNet architecture. We use version `v1.10.0`. 50 | 51 | You can visualize the training by running TensorBoard `tensorboard --logdir /path/to/outputs`, where `logdir` points to the parent directory of `output_directory`. 52 | 53 | #### Hyperparameters 54 | 55 | We use the following hyperparameters: 56 | 57 | * Optimizer 58 | * Stochastic gradient descent (SGD) with momentum 0.9 59 | * Synchronized SGD across 4 GPUs 60 | * Batch size: 256, e.g. 64 per GPU 61 | * Learning rate starts at 0.1, decayed by a factor of 10 after 150000, 300000, 400000, and 450000 iterations 62 | * Regularization 63 | * Weight decay: 0.0001 64 | * Data augmentation 65 | * crop a distorted bounding box around the object (see [code](preprocess.py\#L59-L66) for details). 66 | * randomly flip the image left to right 67 | * resize the image to 224 x 224 x 3 68 | * subtract mean value in R, G, B channels (see [code](preprocess.py\#L59-L66) for values). 69 | 70 | #### Dynamics 71 | Training takes ~24 hours. You can visualize below the evolution of the total, cross-entropy, and l2 losses. 72 | 73 | ![loss](figures/loss2.png) 74 | ![cross_entropy_loss](figures/cross_entropy2.png) 75 | ![l2_loss](figures/l2_loss2.png) 76 | 77 | #### Outputs 78 | 79 | The model checkpoints and TensorFlow logs can be found on HDFS at `hdfs://projects/ml/recipe/resnet50_imagenet`. 80 | 81 | ### Performance metrics 82 | 83 | #### Target metrics 84 | 85 | During evaluation we resize the image such that the minimum edge, and run inference using the 224 x 224 x 3 center crop. The top-1 single crop accuracy is 74.0% after 500K iterations. 86 | 87 | #### Code 88 | 89 | The accuracy is computed by the training script automatically. It can be read using TensorBoard as shown below. 90 | 91 | ![accuracy_validation_set](figures/accuracy3.png) 92 | 93 | ## Inference 94 | 95 | #### Code 96 | We provide a [notebook](inference.ipynb) that provides an example of how to run inference on sample images. 97 | 98 | #### Timing information 99 | We measure the model latency using the inference notebook. We used a p3.2xlarge instance on AWS which has an NVIDIA GPU V100. The latency including preprocessing is 11ms with a batch size of 1. Note that the inference code doesn't run on a CPU because the channel ordering is NCHW and the max pooling operation only supports NHWC on a CPU device. We use TensorFlow v1.8. 100 | 101 | #### Serialization 102 | Not applicable. The model was trained for research purposes and is not deployed to production. 103 | 104 | ## Miscellaneous 105 | 106 | * Performance is 2\% below published results. We plan on running the training code from the TensorFlow models repository to determine whether there is a discrepancy in the code or in the training data 107 | * Using 8 GPUs did not increase the throughput. It is worth determining the bottleneck in the data pipeline in order to further parallelize the code and decrease the training time. The Stanford DAWN Deep Learning [Benchmark](https://dawn.cs.stanford.edu/benchmark/) provides relevant pointers regarding state-of-the-art training times for ImageNet. 108 | -------------------------------------------------------------------------------- /Code-Of-Conduct.md: -------------------------------------------------------------------------------- 1 | # Oath Open Source Code of Conduct 2 | 3 | ## Summary 4 | This Code of Conduct is our way to encourage good behavior and discourage bad behavior in our open source community. We invite participation from many people to bring different perspectives to support this project. We pledge to do our part to foster a welcoming and professional environment free of harassment. We expect participants to communicate professionally and thoughtfully during their involvement with this project. 5 | 6 | Participants may lose their good standing by engaging in misconduct. For example: insulting, threatening, or conveying unwelcome sexual content. We ask participants who observe conduct issues to report the incident directly to the project's Response Team at opensource-conduct@oath.com. Oath will assign a respondent to address the issue. We may remove harassers from this project. 7 | 8 | This code does not replace the terms of service or acceptable use policies of the websites used to support this project. We acknowledge that participants may be subject to additional conduct terms based on their employment which may govern their online expressions. 9 | 10 | ## Details 11 | This Code of Conduct makes our expectations of participants in this community explicit. 12 | * We forbid harassment and abusive speech within this community. 13 | * We request participants to report misconduct to the project’s Response Team. 14 | * We urge participants to refrain from using discussion forums to play out a fight. 15 | 16 | ### Expected Behaviors 17 | We expect participants in this community to conduct themselves professionally. Since our primary mode of communication is text on an online forum (e.g. issues, pull requests, comments, emails, or chats) devoid of vocal tone, gestures, or other context that is often vital to understanding, it is important that participants are attentive to their interaction style. 18 | 19 | * **Assume positive intent.** We ask community members to assume positive intent on the part of other people’s communications. We may disagree on details, but we expect all suggestions to be supportive of the community goals. 20 | * **Respect participants.** We expect participants will occasionally disagree. Even if we reject an idea, we welcome everyone’s participation. Open Source projects are learning experiences. Ask, explore, challenge, and then respectfully assert if you agree or disagree. If your idea is rejected, be more persuasive not bitter. 21 | * **Welcoming to new members.** New members bring new perspectives. Some may raise questions that have been addressed before. Kindly point them to existing discussions. Everyone is new to every project once. 22 | * **Be kind to beginners.** Beginners use open source projects to get experience. They might not be talented coders yet, and projects should not accept poor quality code. But we were all beginners once, and we need to engage kindly. 23 | * **Consider your impact on others.** Your work will be used by others, and you depend on the work of others. We expect community members to be considerate and establish a balance their self-interest with communal interest. 24 | * **Use words carefully.** We may not understand intent when you say something ironic. Poe’s Law suggests that without an emoticon people will misinterpret sarcasm. We ask community members to communicate plainly. 25 | * **Leave with class.** When you wish to resign from participating in this project for any reason, you are free to fork the code and create a competitive project. Open Source explicitly allows this. Your exit should not be dramatic or bitter. 26 | 27 | ### Unacceptable Behaviors 28 | Participants remain in good standing when they do not engage in misconduct or harassment. To elaborate: 29 | * **Don't be a bigot.** Calling out project members by their identity or background in a negative or insulting manner. This includes, but is not limited to, slurs or insinuations related to protected or suspect classes e.g. race, color, citizenship, national origin, political belief, religion, sexual orientation, gender identity and expression, age, size, culture, ethnicity, genetic features, language, profession, national minority statue, mental or physical ability. 30 | * **Don't insult.** Insulting remarks about a person’s lifestyle practices. 31 | * **Don't dox.** Revealing private information about other participants without explicit permission. 32 | * **Don't intimidate.** Threats of violence or intimidation of any project member. 33 | * **Don't creep.** Unwanted sexual attention or content unsuited for the subject of this project. 34 | * **Don't disrupt.** Sustained disruptions in a discussion. 35 | * **Let us help.** Refusal to assist the Response Team to resolve an issue in the community. 36 | 37 | We do not list all forms of harassment, nor imply some forms of harassment are not worthy of action. Any participant who *feels* harassed or *observes* harassment, should report the incident. Victim of harassment should not address grievances in the public forum, as this often intensifies the problem. Report it, and let us address it off-line. 38 | 39 | ### Reporting Issues 40 | If you experience or witness misconduct, or have any other concerns about the conduct of members of this project, please report it by contacting our Response Team at opensource-conduct@oath.com who will handle your report with discretion. Your report should include: 41 | * Your preferred contact information. We cannot process anonymous reports. 42 | * Names (real or usernames) of those involved in the incident. 43 | * Your account of what occurred, and if the incident is ongoing. Please provide links to or transcripts of the publicly available records (e.g. a mailing list archive or a public IRC logger), so that we can review it. 44 | * Any additional information that may be helpful to achieve resolution. 45 | 46 | After filing a report, a representative will contact you directly to review the incident and ask additional questions. If a member of the Oath Response Team is named in an incident report, that member will be recused from handling your incident. If the complaint originates from a member of the Response Team, it will be addressed by a different member of the Response Team. We will consider reports to be confidential for the purpose of protecting victims of abuse. 47 | 48 | ### Scope 49 | Oath will assign a Response Team member with admin rights on the project and legal rights on the project copyright. The Response Team is empowered to restrict some privileges to the project as needed. Since this project is governed by an open source license, any participant may fork the code under the terms of the project license. The Response Team’s goal is to preserve the project if possible, and will restrict or remove participation from those who disrupt the project. 50 | 51 | This code does not replace the terms of service or acceptable use policies that are provided by the websites used to support this community. Nor does this code apply to communications or actions that take place outside of the context of this community. Many participants in this project are also subject to codes of conduct based on their employment. This code is a social-contract that informs participants of our social expectations. It is not a terms of service or legal contract. 52 | 53 | ## License and Acknowledgment. 54 | This text is shared under the [CC-BY-4.0 license](https://creativecommons.org/licenses/by/4.0/). This code is based on a study conducted by the [TODO Group](https://todogroup.org/) of many codes used in the open source community. If you have feedback about this code, contact our Response Team at the address listed above. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Training Recipes for Reproducible Machine Learning Models 2 | 3 | > Technical documentation guidelines to improve the reproduciblity of machine learning models. 4 | 5 | Did you build a machine learning model and want to make sure you're not the only one who knows how to train it? This repository contains guidelines for how to write technical documentation that makes it easier for others to reproduce the results of your model. 6 | 7 | ## Table of Contents 8 | - [Background](#background) 9 | - [Usage](#usage) 10 | - [Data](#data) 11 | - [Training](#training) 12 | - [Contribute](#contribute) 13 | - [License](#license) 14 | 15 | ## Background 16 | 17 | Reproducing the results of a machine learning model is notoriously difficult. This is particularly true in the deep learning community, where high-dimensional, over-parameterized non-convex optimization problems require multiple heuristics to converge to local minima with good performance. Hence, if the optimization or source of training data are not properly documented, it can take considerable experimentation to achieve the expected results. 18 | 19 | We propose the training recipe, a technical document whose aim is to provide sufficient information for a researcher to train a model and achieve a target performance without requiring any external help. We recommend to write training recipes for models that are deployed to production, models that are published, or models that reproduce results from academic papers. As we are well aware that writing technical documentation can be cumbersome, we provide simple guidelines that make it possible to produce the recipe in a timely fashion. We recommend to write the recipe as a markdown document and to review it with a Github pull request. 20 | 21 | ## Usage 22 | 23 | Here are the components of the training recipe: 24 | - Data 25 | - Raw Data 26 | - Data Processing Methods 27 | - Training 28 | - Optimization Methods 29 | - Performance Metrics 30 | - Inference 31 | 32 | The next section will provide a checklist of critical items for each of these and will explain the rationale for their importance. 33 | 34 | ### Data 35 | 36 | #### Raw Data 37 | 38 | **Description** 39 | 40 | Describe the data, labels, as well as additional available meta-data. It is important to understand the data schema when adding new data samples. Furthermore, while developing machine learning models one may identify biases or peculiar behaviors that can be caused by how the training data was generated. Information about its source makes it possible to verify hypotheses and make necessary adjustments. 41 | 42 | **Path** 43 | 44 | Provide information about how to access the raw data, e.g. a website, a set of Hive tables, an Hadoop Distributed File System (HDFS) or S3 URI, etc... Make sure that you respect the data governance if access is restricted. 45 | 46 | #### Data Processing Methods 47 | 48 | **Description** 49 | 50 | Describe the data processing pipeline. The raw dataset is often in a format that is not appropriate for running the model training script directly. Here are some examples of common data processing methods: 51 | 52 | * The data is image URLs and images are downloaded. 53 | * The data and labels are contained in separate Hive tables which are joined. 54 | * The data is split into training, validation, and test sets. As performance is evaluated on the test set and is the ultimate metric to determine reproducibility, it is critical to have detailed information on how to build the test set. 55 | * The class distribution is highly skewed and the dataset is balanced in order for the classifier to better learn the rare classes. 56 | * For natural language data a dictionary of fixed size is computed and words are mapped to indices. 57 | 58 | **Code** 59 | 60 | Provide the code and instructions to run the data processing script. Include the git commit SHA-1 hash. 61 | 62 | **Path** 63 | 64 | Include a link to the processed data. It makes it possible to train the model without running the preprocessing scripts which may take a long time. Note that data governance such as GDPR may not allow to keep a cache of the processed data and therefore the dataset should be reprocessed whenever we train a new model. Make sure that you respect the data governance if you can provide a link and access is restricted. 65 | 66 | ### Training 67 | 68 | #### Optimization Methods 69 | 70 | **Description** 71 | 72 | Describe the model architecture and the loss function. 73 | 74 | **Code** 75 | 76 | Provide the code and instructions to run the training script. Include the git commit SHA-1 hash. 77 | 78 | **Hyperparameters** 79 | 80 | Provide details about the optimization hyperparameters, such as 81 | 82 | * Batch size 83 | * Number of GPUs 84 | * Optimizer information and learning rate schedule, e.g. stochastic gradient descent, momentum, Adam, RMSProp, etc... 85 | * Location of the pre-trained model (if the model is fine-tuned) 86 | * Data augmentation methods 87 | 88 | **Dynamics** 89 | Describe the training dynamics, such as the total training time, the evolution of the loss function on the training and validation sets, or the evolution of other relevant metrics such as accuracy. As training a model to completion may take several days, the dynamics provide a way to get earlier feedback about whether we are "on track" to reproduce performance. 90 | 91 | **Outputs** 92 | 93 | Provide a link to the trained model, e.g. URL, HDFS or S3 URI, etc... 94 | 95 | #### Performance metrics 96 | 97 | **Target metrics** 98 | Provide target metrics, such as top-K accuracy, mean average precision, BLEU score, etc... 99 | 100 | **Code** 101 | 102 | Provide the code and instructions to run the evaluation script. Include the git commit SHA-1 hash. 103 | 104 | #### Inference 105 | 106 | **Code** 107 | 108 | Provide an example of how to run the model on a new data sample. This demonstrates how to combine the data processing steps and model inference, which is helpful for model deployment. It also makes it possible to explore the model's predictions interactively and get insight into its performance beyond the metrics provided above. We recommend using Jupyter Notebooks to show examples on how to run the inference. 109 | 110 | **Timing information** 111 | 112 | Provide timing information along with relevant details such as the hardware (e.g. NVIDIA Tesla V100, Intel Core i7, ...), batch size, software version, etc... Having access to these numbers makes it easier to plan for capacity and discuss product integrations. 113 | 114 | **Serialization** 115 | 116 | Provide the code and instructions to serialize the model. Include the git commit SHA-1. Note that this is only required for models that are deployed to production in a format that differs from the output of the training script, e.g. ONNX, TFLite. 117 | 118 | 119 | #### Miscellaneous 120 | 121 | This section contains additional relevant information such as academic papers, experimental journal and notes detailing the experiments performed to reach the best performance, list of action items to improve the model, the code, etc... 122 | 123 | ## Example 124 | 125 | Please refer to the training [recipe](recipe_resnet50_imagenet.md) for an example of how to train a ResNet-50 model on ImageNet. 126 | 127 | ## Contribute 128 | 129 | Please refer to [the contributing.md file](Contributing.md) for information about how to get involved. We welcome issues, questions, and pull requests. Pull Requests are welcome. 130 | 131 | ## Maintainers 132 | Pierre Garrigues: garp@oath.com 133 | 134 | ## License 135 | 136 | This project is licensed under the terms of the [MIT](LICENSE-MIT) open source license. 137 | -------------------------------------------------------------------------------- /inference.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Inference notebook for the ResNet-50 model trained on ImageNet\n", 8 | "\n", 9 | "This notebook demonstrates inference with a ResNet-50 model trained on the ImageNet dataset. In this notebook you will be able to run inference on some sample images and measure the latency of the model\n", 10 | "\n", 11 | "## First let's set some variables\n", 12 | "\n", 13 | "Fill in below the values for the path to your code and modle checkpoint, which GPU you will be using (specify -1 to use the CPU). You can refer to the training recipe to access a checkpoint if you haven't trained the model yourself." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stderr", 23 | "output_type": "stream", 24 | "text": [ 25 | "/home/ubuntu/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n", 26 | " from ._conv import register_converters as _register_converters\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "# specify the gpu to use\n", 32 | "import os\n", 33 | "os.environ['CUDA_VISIBLE_DEVICES'] = '0'\n", 34 | "\n", 35 | "# path to tensorflow/models repository\n", 36 | "import sys\n", 37 | "sys.path.append(\"/ebs/code/models/\")\n", 38 | "\n", 39 | "import tensorflow as tf\n", 40 | "import numpy as np" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 2, 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "name": "stdout", 50 | "output_type": "stream", 51 | "text": [ 52 | "loading checkpoint ./output-v4/model.ckpt-500000\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "CHECKPOINT_PATH = \"./output-v4/\"\n", 58 | "# select checkpoint# selec \n", 59 | "checkpoint_file = os.path.join(CHECKPOINT_PATH, 'checkpoint')\n", 60 | "with open(checkpoint_file,'r') as chkf:\n", 61 | " last_chkpnt = chkf.readline().split(' ')[1][1:-2]\n", 62 | " last_chkpnt = os.path.join(CHECKPOINT_PATH, last_chkpnt)\n", 63 | " print(\"loading checkpoint\", last_chkpnt)" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "## Load the model" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 3, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "from official.resnet import resnet_model\n", 80 | "from preprocess import preprocess_for_eval, _DEFAULT_IMAGE_SIZE, _RESIZE_SIDE_MIN\n", 81 | "\n", 82 | "image_data = tf.placeholder(tf.string)\n", 83 | "\n", 84 | "features = preprocess_for_eval(image_data, _DEFAULT_IMAGE_SIZE, _DEFAULT_IMAGE_SIZE, _RESIZE_SIDE_MIN)\n", 85 | "features = tf.expand_dims(features, 0)\n", 86 | "\n", 87 | "model = resnet_model.Model(\n", 88 | " resnet_size=50,\n", 89 | " bottleneck=True,\n", 90 | " num_classes=1000,\n", 91 | " num_filters=64,\n", 92 | " kernel_size=7,\n", 93 | " conv_stride=2,\n", 94 | " first_pool_size=3,\n", 95 | " first_pool_stride=2,\n", 96 | " block_sizes=[3, 4, 6, 3],\n", 97 | " block_strides=[1, 2, 2, 2],\n", 98 | " final_size=2048,\n", 99 | " resnet_version=2,\n", 100 | " data_format=None,\n", 101 | " dtype=tf.float32)\n", 102 | "\n", 103 | "logits = model(features, False)\n" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 4, 109 | "metadata": {}, 110 | "outputs": [ 111 | { 112 | "name": "stdout", 113 | "output_type": "stream", 114 | "text": [ 115 | "INFO:tensorflow:Restoring parameters from ./output-v4/model.ckpt-500000\n" 116 | ] 117 | } 118 | ], 119 | "source": [ 120 | "sess = tf.Session()\n", 121 | "saver = tf.train.Saver()\n", 122 | "saver.restore(sess, last_chkpnt)" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 5, 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [ 131 | "# load imagenet information\n", 132 | "\n", 133 | "with open(\"/ebs/code/models/research/inception/inception/data/imagenet_lsvrc_2015_synsets.txt\", \"r\") as fh:\n", 134 | " synsets = [l.strip() for l in fh]\n", 135 | " \n", 136 | "with open(\"/ebs/code/models/research/inception/inception/data/imagenet_metadata.txt\", \"r\") as fh:\n", 137 | " synset2name = dict([l.strip().split(\"\\t\") for l in fh])\n" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": {}, 143 | "source": [ 144 | "## Run inference on sample images\n", 145 | "\n", 146 | "Modify the filename below to try out the model on some sample images. We will show the topK predictions of the model." 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 6, 152 | "metadata": {}, 153 | "outputs": [], 154 | "source": [ 155 | "IMAGE_FILENAME = \"./puppy.jpg\"" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 7, 161 | "metadata": {}, 162 | "outputs": [ 163 | { 164 | "data": { 165 | "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSgBBwcHCggKEwoKEygaFhooKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKP/AABEIAlgDIAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APoEVoZAaAE70AKKAFFAC0AFIAoAWgAoAKACgBRQMWgAFAC0AFABQAUAFABQAUAFABQAUAFABQAUAFABQAooAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKBhQIKBhQIKBoKACgGFAgoAKACgYUCCgAoAKAENAAKAFNACUAFABQAUAFABQAUAFABQAhoAKACgAoAKAG0AFABQAUAFArCGgLBQMQ0AFABQA0mgAzTAQmgAoAQ0AIaACgBKADNADc0gE3UABagCzTEIaBgKBC0AAoAWgApALQMKBBQMKAFFAC0AAoAWgAoAKACgAoAKACgAoAKACgAoAKACgAoAWgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAA5oAWgYYoAWgAoASgBaACgBKAA0AJQAUAFABQAUCCgYUAFAmIaACgEFA2FAgoAKACgAoAKACgAoAKAENABQAlACUAFACUAFAC5oAQmgBCaAEoAWgBpNABmgBM0wEzQAmaADNABQAlAAaAEpAITQAwmgBM0AJmgC7TEIaAAUAKKAFoAKQBQMWgQUDCgBRQAUAKKAFoAKACgAoAKAENACigAoAKACgAoAKACgAoAXFABQAUAFABQAUAFABQAUAFAC4oASgAoAKACgBRQCA0DDvQAtABQAUAFABQAUAFABQAUAJigAoASgBcUAGKAsJQIKBhQAGgTEoBBQNhQIKACgAoASgAzQAZoAKACgBDQAlABQAUAGaAEzQAZoAQ0AFACGgBKAEJoATNABmgBM0AJmgBKACgAFAATQAZoAaTQAhNADCaAG5oAQmkBoVQBigQYoABQAtAwpALigAoAKACgBRQAtAAKAFoAKACgAoAKACgAoAKACgAoAKACgAoAKAFoAKACgAoAKACgBRQAYoAMUDsGKBC0AJigdgxQIKAACgAxQNBigAxQAtABQAUAFABQAUAFABQAUAFABQAmKAFoAKAEoEJQNAaAEoAKACgGFAhM0AGaAEzQAlABQAUALQAZoAKAEoAM0AJmgBM0AFA7CUBYM0BYTNAhM5oADQA00AJmgBM0AFACZoAM0AGaADNACE0AJuoAaTQA0mgBpNK4DCaLgIWoEalUMKACgBaACkAUALQAUAFAC4oAKAFoAWgAoAKACgAoAKACgAoAKACgAoAKACgBcUAGKACgAoAKAsFABQAooHYKAsLQFgxQAUBYKBCUBcKBhQIWge4UAGKADFABigAxQAYoGGKADFAgoGFABQIKACgAxQAUAFABQAlAWEoADQAlACE0CuJmgLiZoAM0AGaAEzQAZoAM0ABNAADQAZoAM0AGaACgBKAEoHYSgQmaAuITQFwoAbmgA3UANLCgBC1ADd1ABuoATdQAbqADdQAbqAELZoAQmgBM0ANJpXAjZqAsRlqQWGl6AsbdWAUAAoAWkAUALigAoAKACgBRQAtAAKAFoAKACgAoAKACgAoAKACgAoAKACgBcUAFABQAUAFAWCgYuKBBigewAUALigAoC4poASgLhigVgxQAYoGGKADFAAKAFoAKACgAoGFABQAUriEIpjDFABigQUAAoAU0AJQAUAJmgYmaBCUAA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\n", 166 | "text/plain": [ 167 | "" 168 | ] 169 | }, 170 | "metadata": { 171 | "image/jpeg": { 172 | "width": 500 173 | } 174 | }, 175 | "output_type": "display_data" 176 | }, 177 | { 178 | "name": "stdout", 179 | "output_type": "stream", 180 | "text": [ 181 | "15.06\tLabrador retriever\n", 182 | "13.18\tChesapeake Bay retriever\n", 183 | "9.48\tSamoyed, Samoyede\n", 184 | "9.25\tthatch, thatched roof\n", 185 | "8.81\tschipperke\n" 186 | ] 187 | } 188 | ], 189 | "source": [ 190 | "from IPython.display import Image, display\n", 191 | "display(Image(filename=IMAGE_FILENAME, width=500))\n", 192 | "\n", 193 | "with open(IMAGE_FILENAME, \"rb\") as fh:\n", 194 | " x = fh.read()\n", 195 | "r = sess.run([logits], feed_dict={image_data: x})\n", 196 | "l = r[0].flatten()\n", 197 | "\n", 198 | "for i in np.argsort(l)[::-1][:5]:\n", 199 | " print('%.2f\\t%s' % (l[i], synset2name[synsets[i+1]]))" 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": {}, 205 | "source": [ 206 | "## Measure the model latency\n", 207 | "\n", 208 | "We measure how long it takes to run inference on the model with a batch size of 1. This scenario is close to how the model is deployed in production. In order to benchmark performance on the CPU, you can set the CUDA_VISIBLE_DEVICES environment variable to -1.\n", 209 | "\n", 210 | "Measurements on an AWS p3.2xlarge machine\n", 211 | "* GPU: avg time = 11ms (+/- 0ms)" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 8, 217 | "metadata": {}, 218 | "outputs": [ 219 | { 220 | "name": "stdout", 221 | "output_type": "stream", 222 | "text": [ 223 | "avg time = 11ms (+/- 0ms)\n" 224 | ] 225 | } 226 | ], 227 | "source": [ 228 | "from time import time as now\n", 229 | "\n", 230 | "num_steps = 20\n", 231 | "num_steps_burn_in = 5\n", 232 | "\n", 233 | "durations = []\n", 234 | "for i in range(num_steps + num_steps_burn_in):\n", 235 | " start_time = now()\n", 236 | " _ = sess.run([logits], feed_dict={image_data: x})\n", 237 | " duration = now() - start_time\n", 238 | " if i >= num_steps_burn_in:\n", 239 | " durations.append(duration)\n", 240 | "durations = np.array(durations)\n", 241 | "\n", 242 | "print(\"avg time = %dms (+/- %dms)\" % (1000*durations.mean(), 1000*durations.std()))" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": null, 248 | "metadata": {}, 249 | "outputs": [], 250 | "source": [] 251 | } 252 | ], 253 | "metadata": { 254 | "kernelspec": { 255 | "display_name": "Environment (conda_tensorflow_p36)", 256 | "language": "python", 257 | "name": "conda_tensorflow_p36" 258 | }, 259 | "language_info": { 260 | "codemirror_mode": { 261 | "name": "ipython", 262 | "version": 3 263 | }, 264 | "file_extension": ".py", 265 | "mimetype": "text/x-python", 266 | "name": "python", 267 | "nbconvert_exporter": "python", 268 | "pygments_lexer": "ipython3", 269 | "version": "3.6.6" 270 | } 271 | }, 272 | "nbformat": 4, 273 | "nbformat_minor": 2 274 | } 275 | --------------------------------------------------------------------------------