Skip to content

Commit 624c919

Browse files
authored
Merge branch 'master' into master
2 parents 52292c5 + 7c1bdf3 commit 624c919

File tree

214 files changed

+23889
-16581
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

214 files changed

+23889
-16581
lines changed

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
# Changelog
22

3+
## v1.30.0 (2019-06-25)
4+
5+
### Features
6+
7+
* add TensorFlow 1.13 support
8+
* add git_config and git_clone, validate method
9+
10+
### Bug fixes and other changes
11+
12+
* add pytest.mark.local_mode annotation to broken tests
13+
14+
## v1.29.0 (2019-06-24)
15+
16+
### Features
17+
18+
* network isolation mode in training
19+
20+
### Bug fixes and other changes
21+
22+
* Integrate black into development process
23+
* moving not canary TFS tests to local mode
24+
325
## v1.28.3 (2019-06-20)
426

527
### Bug fixes and other changes

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ TensorFlow SageMaker Estimators
173173

174174
By using TensorFlow SageMaker Estimators, you can train and host TensorFlow models on Amazon SageMaker.
175175

176-
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``.
176+
Supported versions of TensorFlow: ``1.4.1``, ``1.5.0``, ``1.6.0``, ``1.7.0``, ``1.8.0``, ``1.9.0``, ``1.10.0``, ``1.11.0``, ``1.12.0``, ``1.13.1``.
177177

178178
Supported versions of TensorFlow for Elastic Inference: ``1.11.0``, ``1.12.0``.
179179

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.28.4.dev0
1+
1.30.1.dev0

buildspec-release.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ phases:
99
# run linters
1010
- tox -e flake8,pylint
1111

12+
# run format verification
13+
- tox -e black-check
14+
1215
# run package and docbuild checks
1316
- tox -e twine
1417
- tox -e sphinx

buildspec.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ phases:
1414
- tox -e twine
1515
- tox -e sphinx
1616

17+
# run format verification
18+
- tox -e black-check
19+
1720
# run unit tests
1821
- AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_SESSION_TOKEN=
1922
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI= AWS_DEFAULT_REGION=

doc/conf.py

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,51 +28,65 @@ def __getattr__(cls, name):
2828
return MagicMock()
2929

3030

31-
MOCK_MODULES = ['tensorflow', 'tensorflow.core', 'tensorflow.core.framework', 'tensorflow.python',
32-
'tensorflow.python.framework', 'tensorflow_serving', 'tensorflow_serving.apis',
33-
'numpy', 'scipy', 'scipy.sparse']
31+
MOCK_MODULES = [
32+
"tensorflow",
33+
"tensorflow.core",
34+
"tensorflow.core.framework",
35+
"tensorflow.python",
36+
"tensorflow.python.framework",
37+
"tensorflow_serving",
38+
"tensorflow_serving.apis",
39+
"numpy",
40+
"scipy",
41+
"scipy.sparse",
42+
]
3443
sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
3544

36-
project = u'sagemaker'
45+
project = u"sagemaker"
3746
version = pkg_resources.require(project)[0].version
3847

3948
# Add any Sphinx extension module names here, as strings. They can be extensions
4049
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
41-
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest',
42-
'sphinx.ext.intersphinx', 'sphinx.ext.todo',
43-
'sphinx.ext.coverage', 'sphinx.ext.autosummary',
44-
'sphinx.ext.napoleon']
50+
extensions = [
51+
"sphinx.ext.autodoc",
52+
"sphinx.ext.doctest",
53+
"sphinx.ext.intersphinx",
54+
"sphinx.ext.todo",
55+
"sphinx.ext.coverage",
56+
"sphinx.ext.autosummary",
57+
"sphinx.ext.napoleon",
58+
]
4559

4660
# Add any paths that contain templates here, relative to this directory.
47-
templates_path = ['_templates']
61+
templates_path = ["_templates"]
4862

49-
source_suffix = '.rst' # The suffix of source filenames.
50-
master_doc = 'index' # The master toctree document.
63+
source_suffix = ".rst" # The suffix of source filenames.
64+
master_doc = "index" # The master toctree document.
5165

52-
copyright = u'%s, Amazon' % datetime.now().year
66+
copyright = u"%s, Amazon" % datetime.now().year
5367

5468
# The full version, including alpha/beta/rc tags.
5569
release = version
5670

5771
# List of directories, relative to source directory, that shouldn't be searched
5872
# for source files.
59-
exclude_trees = ['_build']
73+
exclude_trees = ["_build"]
6074

61-
pygments_style = 'default'
75+
pygments_style = "default"
6276

6377
autoclass_content = "both"
64-
autodoc_default_flags = ['show-inheritance', 'members', 'undoc-members']
65-
autodoc_member_order = 'bysource'
78+
autodoc_default_flags = ["show-inheritance", "members", "undoc-members"]
79+
autodoc_member_order = "bysource"
6680

67-
if 'READTHEDOCS' in os.environ:
68-
html_theme = 'default'
81+
if "READTHEDOCS" in os.environ:
82+
html_theme = "default"
6983
else:
70-
html_theme = 'haiku'
84+
html_theme = "haiku"
7185
html_static_path = []
72-
htmlhelp_basename = '%sdoc' % project
86+
htmlhelp_basename = "%sdoc" % project
7387

7488
# Example configuration for intersphinx: refer to the Python standard library.
75-
intersphinx_mapping = {'http://docs.python.org/': None}
89+
intersphinx_mapping = {"http://docs.python.org/": None}
7690

7791
# autosummary
7892
autosummary_generate = True

doc/overview.rst

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,65 @@ For more `information <https://boto3.amazonaws.com/v1/documentation/api/latest/r
8484
# Deletes the SageMaker model
8585
mxnet_predictor.delete_model()
8686
87+
Git Support
88+
~~~~~~~~~~~
89+
If you have your training scripts in your GitHub repository, you can use them directly without the trouble to download
90+
them to local machine. Git support can be enabled simply by providing ``git_config`` parameter when initializing an
91+
estimator. If Git support is enabled, then ``entry_point``, ``source_dir`` and ``dependencies`` should all be relative
92+
paths in the Git repo. Note that if you decided to use Git support, then everything you need for ``entry_point``,
93+
``source_dir`` and ``dependencies`` should be in a single Git repo.
94+
95+
Here are ways to specify ``git_config``:
96+
97+
.. code:: python
98+
99+
# Specifies the git_config parameter
100+
git_config = {'repo': 'https://github.com/username/repo-with-training-scripts.git',
101+
'branch': 'branch1',
102+
'commit': '4893e528afa4a790331e1b5286954f073b0f14a2'}
103+
104+
# Alternatively, you can also specify git_config by providing only 'repo' and 'branch'.
105+
# If this is the case, the latest commit in the branch will be used.
106+
git_config = {'repo': 'https://github.com/username/repo-with-training-scripts.git',
107+
'branch': 'branch1'}
108+
109+
# Only providing 'repo' is also allowed. If this is the case, latest commit in
110+
# 'master' branch will be used.
111+
git_config = {'repo': 'https://github.com/username/repo-with-training-scripts.git'
112+
113+
The following are some examples to define estimators with Git support:
114+
115+
.. code:: python
116+
117+
# In this example, the source directory 'pytorch' contains the entry point 'mnist.py' and other source code.
118+
# and it is relative path inside the Git repo.
119+
pytorch_estimator = PyTorch(entry_point='mnist.py',
120+
role='SageMakerRole',
121+
source_dir='pytorch',
122+
git_config=git_config,
123+
train_instance_count=1,
124+
train_instance_type='ml.c4.xlarge')
125+
126+
# In this example, the entry point 'mnist.py' is all we need for source code.
127+
# We need to specify the path to it in the Git repo.
128+
mx_estimator = MXNet(entry_point='mxnet/mnist.py',
129+
role='SageMakerRole',
130+
git_config=git_config,
131+
train_instance_count=1,
132+
train_instance_type='ml.c4.xlarge')
133+
134+
# In this example, besides entry point and other source code in source directory, we still need some
135+
# dependencies for the training job. Dependencies should also be paths inside the Git repo.
136+
pytorch_estimator = PyTorch(entry_point='mnist.py',
137+
role='SageMakerRole',
138+
source_dir='pytorch',
139+
dependencies=['dep.py', 'foo/bar.py'],
140+
git_config=git_config,
141+
train_instance_count=1,
142+
train_instance_type='ml.c4.xlarge')
143+
144+
When Git support is enabled, users can still use local mode in the same way.
145+
87146
Training Metrics
88147
~~~~~~~~~~~~~~~~
89148
The SageMaker Python SDK allows you to specify a name and a regular expression for metrics you want to track for training.
@@ -268,6 +327,7 @@ Currently, the following algorithms support incremental training:
268327
- Object Detection
269328
- Semantic Segmentation
270329
330+
271331
Using SageMaker AlgorithmEstimators
272332
-----------------------------------
273333

doc/using_tf.rst

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -443,20 +443,10 @@ After a TensorFlow estimator has been fit, it saves a TensorFlow SavedModel in
443443
the S3 location defined by ``output_path``. You can call ``deploy`` on a TensorFlow
444444
estimator to create a SageMaker Endpoint.
445445

446-
SageMaker provides two different options for deploying TensorFlow models to a SageMaker
447-
Endpoint:
446+
Your model will be deployed to a TensorFlow Serving-based server. The server provides a super-set of the
447+
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_.
448448

449-
- The first option uses a Python-based server that allows you to specify your own custom
450-
input and output handling functions in a Python script. This is the default option.
451-
452-
See `Deploying to Python-based Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_python.rst>`_ to learn how to use this option.
453-
454-
455-
- The second option uses a TensorFlow Serving-based server to provide a super-set of the
456-
`TensorFlow Serving REST API <https://www.tensorflow.org/serving/api_rest>`_. This option
457-
does not require (or allow) a custom python script.
458-
459-
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to use this option.
449+
See `Deploying to TensorFlow Serving Endpoints <https://github.com/aws/sagemaker-python-sdk/blob/master/src/sagemaker/tensorflow/deploying_tensorflow_serving.rst>`_ to learn how to deploy your model and make inference requests.
460450

461451

462452
SageMaker TensorFlow Docker containers

examples/cli/host/script.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ def model_fn(model_dir):
1212
:param: model_dir The directory where model files are stored.
1313
:return: a model (in this case a Gluon network)
1414
"""
15-
symbol = mx.sym.load('%s/model.json' % model_dir)
16-
outputs = mx.symbol.softmax(data=symbol, name='softmax_label')
17-
inputs = mx.sym.var('data')
18-
param_dict = gluon.ParameterDict('model_')
15+
symbol = mx.sym.load("%s/model.json" % model_dir)
16+
outputs = mx.symbol.softmax(data=symbol, name="softmax_label")
17+
inputs = mx.sym.var("data")
18+
param_dict = gluon.ParameterDict("model_")
1919
net = gluon.SymbolBlock(outputs, inputs, param_dict)
20-
net.load_params('%s/model.params' % model_dir, ctx=mx.cpu())
20+
net.load_params("%s/model.params" % model_dir, ctx=mx.cpu())
2121
return net
2222

2323

examples/cli/train/download_training_data.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33

44
def download_training_data():
5-
gluon.data.vision.MNIST('./data/training', train=True)
6-
gluon.data.vision.MNIST('./data/training', train=False)
5+
gluon.data.vision.MNIST("./data/training", train=True)
6+
gluon.data.vision.MNIST("./data/training", train=False)
77

88

99
if __name__ == "__main__":

examples/cli/train/script.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ def train(channel_input_dirs, hyperparameters, **kwargs):
1515
ctx = mx.cpu()
1616

1717
# retrieve the hyperparameters we set in notebook (with some defaults)
18-
batch_size = hyperparameters.get('batch_size', 100)
19-
epochs = hyperparameters.get('epochs', 10)
20-
learning_rate = hyperparameters.get('learning_rate', 0.1)
21-
momentum = hyperparameters.get('momentum', 0.9)
22-
log_interval = hyperparameters.get('log_interval', 100)
18+
batch_size = hyperparameters.get("batch_size", 100)
19+
epochs = hyperparameters.get("epochs", 10)
20+
learning_rate = hyperparameters.get("learning_rate", 0.1)
21+
momentum = hyperparameters.get("momentum", 0.9)
22+
log_interval = hyperparameters.get("log_interval", 100)
2323

24-
training_data = channel_input_dirs['training']
24+
training_data = channel_input_dirs["training"]
2525

2626
# load training and validation data
2727
# we use the gluon.data.vision.MNIST class because of its built in mnist pre-processing logic,
@@ -35,8 +35,9 @@ def train(channel_input_dirs, hyperparameters, **kwargs):
3535
# Collect all parameters from net and its children, then initialize them.
3636
net.initialize(mx.init.Xavier(magnitude=2.24), ctx=ctx)
3737
# Trainer is for updating parameters with gradient.
38-
trainer = gluon.Trainer(net.collect_params(), 'sgd',
39-
{'learning_rate': learning_rate, 'momentum': momentum})
38+
trainer = gluon.Trainer(
39+
net.collect_params(), "sgd", {"learning_rate": learning_rate, "momentum": momentum}
40+
)
4041
metric = mx.metric.Accuracy()
4142
loss = gluon.loss.SoftmaxCrossEntropyLoss()
4243

@@ -61,32 +62,34 @@ def train(channel_input_dirs, hyperparameters, **kwargs):
6162

6263
if i % log_interval == 0 and i > 0:
6364
name, acc = metric.get()
64-
logger.info('[Epoch %d Batch %d] Training: %s=%f, %f samples/s' %
65-
(epoch, i, name, acc, batch_size / (time.time() - btic)))
65+
logger.info(
66+
"[Epoch %d Batch %d] Training: %s=%f, %f samples/s"
67+
% (epoch, i, name, acc, batch_size / (time.time() - btic))
68+
)
6669

6770
btic = time.time()
6871

6972
name, acc = metric.get()
70-
logger.info('[Epoch %d] Training: %s=%f' % (epoch, name, acc))
73+
logger.info("[Epoch %d] Training: %s=%f" % (epoch, name, acc))
7174

7275
name, val_acc = test(ctx, net, val_data)
73-
logger.info('[Epoch %d] Validation: %s=%f' % (epoch, name, val_acc))
76+
logger.info("[Epoch %d] Validation: %s=%f" % (epoch, name, val_acc))
7477

7578
return net
7679

7780

7881
def save(net, model_dir):
7982
# save the model
80-
y = net(mx.sym.var('data'))
81-
y.save('%s/model.json' % model_dir)
82-
net.collect_params().save('%s/model.params' % model_dir)
83+
y = net(mx.sym.var("data"))
84+
y.save("%s/model.json" % model_dir)
85+
net.collect_params().save("%s/model.params" % model_dir)
8386

8487

8588
def define_network():
8689
net = nn.Sequential()
8790
with net.name_scope():
88-
net.add(nn.Dense(128, activation='relu'))
89-
net.add(nn.Dense(64, activation='relu'))
91+
net.add(nn.Dense(128, activation="relu"))
92+
net.add(nn.Dense(64, activation="relu"))
9093
net.add(nn.Dense(10))
9194
return net
9295

@@ -99,13 +102,18 @@ def input_transformer(data, label):
99102
def get_train_data(data_dir, batch_size):
100103
return gluon.data.DataLoader(
101104
gluon.data.vision.MNIST(data_dir, train=True, transform=input_transformer),
102-
batch_size=batch_size, shuffle=True, last_batch='discard')
105+
batch_size=batch_size,
106+
shuffle=True,
107+
last_batch="discard",
108+
)
103109

104110

105111
def get_val_data(data_dir, batch_size):
106112
return gluon.data.DataLoader(
107113
gluon.data.vision.MNIST(data_dir, train=False, transform=input_transformer),
108-
batch_size=batch_size, shuffle=False)
114+
batch_size=batch_size,
115+
shuffle=False,
116+
)
109117

110118

111119
def test(ctx, net, val_data):

0 commit comments

Comments
 (0)