Skip to content

S3 Estimator and Image Classification #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 31 commits into from

Conversation

ragavvenkatesan
Copy link

This PR sets up the SDK for S3 algorithms to come in and this brings in image classification.

.gitignore Outdated
@@ -20,3 +20,5 @@ examples/tensorflow/distributed_mnist/data
doc/_build
**/.DS_Store
venv/
*.rec
*~
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this symbol?

Copy link
Author

Choose a reason for hiding this comment

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

It was added from a sync pull I made on the original repo. Not mine.

intended to be instantiated directly. This is difference from the base class
because this class handles S3 data"""

"""Base class for Amazon first-party Estimator implementations. This class isn't intended
Copy link
Contributor

Choose a reason for hiding this comment

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

Duplicate doc

"""Initialize an AmazonAlgorithmEstimatorBase.

Args:
algortihm (str): Use one of the supported algorithms
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo/

Copy link
Author

Choose a reason for hiding this comment

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

Where is the typo? I don't see.

Copy link
Contributor

Choose a reason for hiding this comment

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

algortihm

@@ -45,4 +49,5 @@ def validate(value):

isint = istype(int)
isbool = istype(bool)
isstr = istype(str)
Copy link
Contributor

Choose a reason for hiding this comment

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

These validations are gone. The pull request itself is stating there are conflicts, can you please update your branch to fix the conflicts?

Refer to this PR: 54b3830#diff-0bb270a0ed6827421dc5669020eb6427 to check what the changes to the hyperparameters are.

Copy link
Author

Choose a reason for hiding this comment

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

I need some of these validations. @orchidmajumder, what is a solution to this?

Copy link
Contributor

@orchidmajumder orchidmajumder left a comment

Choose a reason for hiding this comment

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

Mostly looked into syntactic issues. Need comments on semantics from Owen/Marcio.

Copy link
Author

@ragavvenkatesan ragavvenkatesan left a comment

Choose a reason for hiding this comment

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

@iquintero Conflicts removed.

"""Initialize an AmazonAlgorithmEstimatorBase.

Args:
algortihm (str): Use one of the supported algorithms
Copy link
Author

Choose a reason for hiding this comment

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

Where is the typo? I don't see.

@@ -45,4 +49,5 @@ def validate(value):

isint = istype(int)
isbool = istype(bool)
isstr = istype(str)
Copy link
Author

Choose a reason for hiding this comment

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

I need some of these validations. @orchidmajumder, what is a solution to this?

Copy link
Contributor

@iquintero iquintero left a comment

Choose a reason for hiding this comment

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

The unit tests failed :( It looks like there are some import errors and possibly flake8 errors too.

More importantly, please look into the changes to the hyperparameter class as the type validations are no longer required and instead you should declare the data type. I have left an example below.

@@ -16,7 +16,7 @@

import numpy as np
from scipy.sparse import issparse

import json
Copy link
Contributor

Choose a reason for hiding this comment

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

Please maintain the import order:

1.- python built in libraries
2.- 3rd party imports
3.- local library imports (from sagemaker...)

Copy link
Contributor

Choose a reason for hiding this comment

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

this still needs to be fixed. import json should go before the numpy import.

Also, please maintain the alphabetical order of the imports when you change it.

import io
import json
import struct
....

intended to be instantiated directly. This is difference from the base class
because this class handles S3 data"""

mini_batch_size = hp('mini_batch_size', (validation.isint, validation.gt(0)))
Copy link
Contributor

Choose a reason for hiding this comment

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

please look at #54 we intentionally removed these type validations: isint() isbool() etc. In favor of declaring a specific type for the hp.

So this should be

hp('mini_batch_size', validation.gt(0), data_type=int)

This applies to every hp declaration in this PR.

Copy link
Contributor

@iquintero iquintero left a comment

Choose a reason for hiding this comment

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

There are a lot of cases where the alignment is not consistent. I didn't want to list every single one but please go through it and review them.

Some examples are in the docstrings where each line is aligned differently. In some cases you have:

param_name (str)

some others are:

param_name ...(long space..) (str)

The original comments have not been addressed yet either. Everything is minor changes but they do add up. Once you change that this should be ready to merge.

"""Initialize an AmazonAlgorithmEstimatorBase.

Args:
algortihm (str): Use one of the supported algorithms
Copy link
Contributor

Choose a reason for hiding this comment

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

algortihm

@@ -16,7 +16,7 @@

import numpy as np
from scipy.sparse import issparse

import json
Copy link
Contributor

Choose a reason for hiding this comment

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

this still needs to be fixed. import json should go before the numpy import.

Also, please maintain the alphabetical order of the imports when you change it.

import io
import json
import struct
....

@@ -35,8 +34,18 @@ def __call__(self, array):
return buf


class record_deserializer(object):
class file_to_image_serializer(object):
Copy link
Contributor

Choose a reason for hiding this comment

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

Keep one naming convention. FileToImageSerializer

Copy link
Author

Choose a reason for hiding this comment

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

I am using this because the other methods are also in this convention.. Refer numpy_to_recod_serializer. ..


class record_deserializer(object):
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here.

RecordDeserializer

Copy link
Author

Choose a reason for hiding this comment

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

Again, I am maintaining this because of the other methods... refer
response_deseiralizer.

@@ -47,6 +56,14 @@ def __call__(self, stream, content_type):
stream.close()


class response_deserializer(object):
Copy link
Contributor

Choose a reason for hiding this comment

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

ResponseDeserializer

@@ -0,0 +1,65 @@
# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Copy link
Contributor

Choose a reason for hiding this comment

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

2017-2018

might as well :P

@@ -63,6 +64,13 @@ def test_init(sagemaker_session):
assert pca.num_components == 55


def test_s3_init(sagemaker_session):
Copy link
Contributor

Choose a reason for hiding this comment

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

I think all the tests you've added here should go on their own file. This way we have a better organized test suite. This existing file is meant to test the AmazonEstimator. you should create a file to test your new estimators. The content of the tests is fine just split it into its own file.

Copy link
Author

Choose a reason for hiding this comment

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

The test I wrote tests the AmazonS3Estimator, which is on the same module as AmazonEstimator, which is why I think that this belongs on this file. I have a serparate test for image classification tests.

mini_batch_size (int or None): The size of each mini-batch to use when training. If None, a
default value will be used.
"""
default_mini_batch_size = 32
Copy link
Contributor

Choose a reason for hiding this comment

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

why dont you make 32 the default value for mini_batch_size in the method signature?

def fit(self, s3set, mini_batch_size=32, distribution='ShardedByS3Key', **kwargs):

then you don't even have to do this whole thing. and you can just set it as
self.mini_batch_size = mini_batch_size

Copy link
Author

Choose a reason for hiding this comment

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

Two reasosn why: 1. Its a protocol used in the other alogrithms. 2. We want to make this a must supply parameter for user. If I assume a default and it fails because of memory error, it becomes a customer error, which is wrong.

The implementation of :meth:`~sagemaker.predictor.RealTimePredictor.predict` in this
`RealTimePredictor` requires a `x-image` as input.

``predict()`` returns """
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this sentence is also incomplete. predict() returns <>... ?

checkpoint_frequency = hp('checkpoint_frequency', (ge(1),),
'checkpoint_frequency should be an integer greater-than 1', int)
num_layers = hp('num_layers', (isin(18, 34, 50, 101, 152, 200, 20, 32, 44, 56, 110),),
'num_layers should be in the set [18, 34, 50, 101, 152, 200, 20, 32, 44, 56, 110]', int)
Copy link
Contributor

Choose a reason for hiding this comment

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

just a suggestion but maybe putting these in ascending order would make it easier for users to reason about? Or is there a reason why they are seemingly in a random order?

Copy link
Author

Choose a reason for hiding this comment

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

Again, I don't want to because this is a logic that is used in the docs also. There is a reason why it is in this order and users familiar with this algorithm will find this ordering comfortable.

@laurenyu
Copy link
Contributor

closing due to inactivity. feel free to reopen (or maybe create a new PR, given all the merge conflicts) if work on this resumes.

@laurenyu laurenyu closed this Aug 27, 2018
apacker pushed a commit to apacker/sagemaker-python-sdk that referenced this pull request Nov 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants