├── .github
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── NOTICE
├── README.md
├── amazon_forecast_tutorial
├── common
│ ├── data
│ │ └── item-demand-time.csv
│ ├── images
│ │ ├── amazon_forecast.png
│ │ └── forecast_workflow.png
│ └── util
│ │ ├── __init__.py
│ │ ├── fcst_utils.py
│ │ └── notebook_utils.py
└── forecast_electricityusagedata.ipynb
├── autogluon
└── tabular-prediction
│ └── AutoGluon-Tabular-with-SageMaker
│ ├── AutoGluon_Tabular_SageMaker.ipynb
│ ├── README.md
│ ├── container-inference
│ ├── Dockerfile.inference
│ └── build_push_inference.sh
│ ├── container-training
│ ├── Dockerfile.training
│ ├── build_push_training.sh
│ ├── inference.py
│ └── train.py
│ ├── setup.sh
│ └── utils
│ └── ag_utils.py
├── autopilot
└── autopilot_customer_churn.ipynb
├── distributed_training
├── Dockerfile
├── README.md
├── build_and_push.sh
├── dist-training-profile.ipynb
├── e2e_mask_rcnn_R_50_FPN_1x_16GPU_4bs.yaml
├── e2e_mask_rcnn_R_50_FPN_1x_32GPU_4bs.yaml
├── e2e_mask_rcnn_R_50_FPN_1x_64GPU_4bs.yaml
├── e2e_mask_rcnn_R_50_FPN_1x_8GPU_4bs.yaml
├── images
│ ├── .ipynb_checkpoints
│ │ └── sm_debugger_insights-checkpoint.png
│ ├── sm_debugger_insights.png
│ ├── sm_debugger_nav.png
│ ├── sm_debugger_sys_util.png
│ ├── smdataparallel_horovod.png
│ └── smdataparallel_pytorchddp.png
├── train_pytorch_single_maskrcnn.py
├── train_pytorch_smdataparallel_maskrcnn.py
└── upload_coco2017_to_s3.sh
├── docs
├── 404.html
├── _print
│ ├── about
│ │ ├── featured-background.jpg
│ │ ├── featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_1920x1080_fill_q75_catmullrom_bottom.jpg
│ │ └── featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_960x540_fill_q75_catmullrom_bottom.jpg
│ └── docs
│ │ ├── ai-services
│ │ ├── images
│ │ │ ├── rekognition
│ │ │ │ ├── celeb.png
│ │ │ │ ├── compare-face.png
│ │ │ │ ├── moderation.png
│ │ │ │ ├── ppe.png
│ │ │ │ ├── rek-obj.png
│ │ │ │ └── text.png
│ │ │ └── textract
│ │ │ │ └── textract.png
│ │ └── picture.png
│ │ └── お客様事例集
│ │ └── picture.png
├── about
│ ├── _print
│ │ └── index.html
│ ├── featured-background.jpg
│ ├── featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_1920x1080_fill_q75_catmullrom_bottom.jpg
│ ├── featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_960x540_fill_q75_catmullrom_bottom.jpg
│ └── index.html
├── blog
│ ├── 2018
│ │ ├── 10
│ │ │ └── 06
│ │ │ │ ├── easy-documentation-with-docsy
│ │ │ │ ├── featured-sunset-get.png
│ │ │ │ ├── featured-sunset-get_hu69849a7cdb847c2393a7b3a7f6061c86_387442_250x125_fill_catmullrom_center_2.png
│ │ │ │ ├── featured-sunset-get_hu69849a7cdb847c2393a7b3a7f6061c86_387442_600x300_fill_catmullrom_smart1_2.png
│ │ │ │ ├── featured-sunset-get_hu69849a7cdb847c2393a7b3a7f6061c86_387442_640x0_resize_catmullrom_2.png
│ │ │ │ └── index.html
│ │ │ │ └── the-second-blog-post
│ │ │ │ └── index.html
│ │ └── 01
│ │ │ └── 04
│ │ │ └── another-great-release
│ │ │ └── index.html
│ ├── _print
│ │ └── index.html
│ ├── index.html
│ ├── news
│ │ ├── _print
│ │ │ └── index.html
│ │ ├── index.html
│ │ └── page
│ │ │ └── 1
│ │ │ └── index.html
│ ├── page
│ │ └── 1
│ │ │ └── index.html
│ └── releases
│ │ ├── _print
│ │ └── index.html
│ │ ├── index.html
│ │ └── page
│ │ └── 1
│ │ └── index.html
├── community
│ ├── _print
│ │ └── index.html
│ └── index.html
├── css
│ ├── prism.css
│ └── swagger-ui.css
├── docs
│ ├── _print
│ │ └── index.html
│ ├── ai-services
│ │ ├── _print
│ │ │ └── index.html
│ │ ├── images
│ │ │ ├── _print
│ │ │ │ └── index.html
│ │ │ ├── index.html
│ │ │ ├── rekognition
│ │ │ │ ├── _print
│ │ │ │ │ └── index.html
│ │ │ │ ├── celeb.png
│ │ │ │ ├── compare-face.png
│ │ │ │ ├── index.html
│ │ │ │ ├── moderation.png
│ │ │ │ ├── ppe.png
│ │ │ │ ├── rek-obj.png
│ │ │ │ └── text.png
│ │ │ └── textract
│ │ │ │ ├── _print
│ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ └── textract.png
│ │ ├── index.html
│ │ ├── picture.png
│ │ ├── pubref1
│ │ │ └── index.html
│ │ ├── table-data
│ │ │ ├── _print
│ │ │ │ └── index.html
│ │ │ ├── forecast
│ │ │ │ ├── _print
│ │ │ │ │ └── index.html
│ │ │ │ └── index.html
│ │ │ ├── fraud
│ │ │ │ ├── _print
│ │ │ │ │ └── index.html
│ │ │ │ └── index.html
│ │ │ ├── index.html
│ │ │ └── personalize
│ │ │ │ ├── _print
│ │ │ │ └── index.html
│ │ │ │ └── index.html
│ │ ├── text
│ │ │ ├── _print
│ │ │ │ └── index.html
│ │ │ ├── comprehend
│ │ │ │ ├── _print
│ │ │ │ │ └── index.html
│ │ │ │ └── index.html
│ │ │ ├── index.html
│ │ │ ├── polly
│ │ │ │ ├── _print
│ │ │ │ │ └── index.html
│ │ │ │ └── index.html
│ │ │ └── translate
│ │ │ │ ├── _print
│ │ │ │ └── index.html
│ │ │ │ └── index.html
│ │ └── voice
│ │ │ ├── _print
│ │ │ └── index.html
│ │ │ ├── index.html
│ │ │ └── transcribe
│ │ │ ├── _print
│ │ │ └── index.html
│ │ │ └── index.html
│ ├── examples
│ │ ├── _print
│ │ │ └── index.html
│ │ └── index.html
│ ├── index.html
│ ├── ml-services
│ │ ├── _print
│ │ │ └── index.html
│ │ ├── index.html
│ │ ├── sagemaker-dive-deep
│ │ │ ├── _print
│ │ │ │ └── index.html
│ │ │ └── index.html
│ │ └── sagemaker-tutorial
│ │ │ ├── _print
│ │ │ └── index.html
│ │ │ └── index.html
│ ├── usecase
│ │ ├── _print
│ │ │ └── index.html
│ │ ├── image
│ │ │ └── index.html
│ │ ├── index.html
│ │ ├── nlp
│ │ │ └── index.html
│ │ └── table-data
│ │ │ └── index.html
│ ├── usecases
│ │ ├── _print
│ │ │ └── index.html
│ │ ├── image
│ │ │ └── index.html
│ │ ├── index.html
│ │ ├── nlp
│ │ │ └── index.html
│ │ └── table-data
│ │ │ └── index.html
│ ├── お客様事例集
│ │ ├── _print
│ │ │ └── index.html
│ │ ├── index.html
│ │ ├── picture.png
│ │ └── pubref1
│ │ │ └── index.html
│ └── 参考になりそうな外部記事
│ │ ├── _print
│ │ └── index.html
│ │ ├── index.html
│ │ └── parameter-reference
│ │ └── index.html
├── examples
│ ├── _print
│ │ └── index.html
│ └── index.html
├── favicons
│ ├── android-144x144.png
│ ├── android-192x192.png
│ ├── android-36x36.png
│ ├── android-48x48.png
│ ├── android-72x72.png
│ ├── android-96x96.png
│ ├── apple-touch-icon-180x180.png
│ ├── favicon-1024.png
│ ├── favicon-16x16.png
│ ├── favicon-256.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── pwa-192x192.png
│ ├── pwa-512x512.png
│ ├── tile150x150.png
│ ├── tile310x150.png
│ ├── tile310x310.png
│ └── tile70x70.png
├── featured-background.jpg
├── featured-background.png
├── featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_1920x1080_fill_q75_catmullrom_top.jpg
├── featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_960x540_fill_q75_catmullrom_top.jpg
├── featured-background_hu8a39ca4bb86027cf9971f48ddb45157c_1460964_1920x1080_fill_catmullrom_top_2.png
├── featured-background_hu8a39ca4bb86027cf9971f48ddb45157c_1460964_960x540_fill_catmullrom_top_2.png
├── index.html
├── index.xml
├── js
│ ├── main.min.2698ba6d60966a95b30f3160f89208b4219c5535421f52ee6147801ad45cc471.js
│ ├── prism.js
│ ├── swagger-ui-bundle.js
│ └── swagger-ui-standalone-preset.js
├── robots.txt
├── scss
│ ├── main.min.7a701bfef5f2c2e872654520afd482ce033f034b72dfa66f90c8b5638e0febec.css
│ ├── main.min.b31ffd97dd6798655a172c11b526e2c16608629dbeabd6fe8bf1f609994e0818.css
│ └── main.min.c63ec56da86340c64de55b0b9c654a2beea1e27d957474a842892958b79a4a75.css
├── search
│ └── index.html
├── sitemap.xml
└── webfonts
│ ├── fa-brands-400.eot
│ ├── fa-brands-400.svg
│ ├── fa-brands-400.ttf
│ ├── fa-brands-400.woff
│ ├── fa-brands-400.woff2
│ ├── fa-regular-400.eot
│ ├── fa-regular-400.svg
│ ├── fa-regular-400.ttf
│ ├── fa-regular-400.woff
│ ├── fa-regular-400.woff2
│ ├── fa-solid-900.eot
│ ├── fa-solid-900.svg
│ ├── fa-solid-900.ttf
│ ├── fa-solid-900.woff
│ └── fa-solid-900.woff2
├── edge_inference
└── greengrass-ml-inference
│ ├── .gitignore
│ ├── README.md
│ ├── build_mnist_classifier.ipynb
│ ├── greengrass_ml_inference.ipynb
│ ├── image
│ ├── AWS-Architecture-Icons-Deck_For-Dark-BG_20200911.pptx
│ ├── image01.png
│ ├── image02.png
│ ├── image03.png
│ ├── image04.png
│ ├── image05.png
│ ├── image06.png
│ ├── image07.png
│ ├── image08.png
│ ├── image09.png
│ ├── image10.png
│ ├── image11.png
│ ├── image12.png
│ ├── image13.png
│ ├── image14.png
│ └── image15.png
│ └── src
│ ├── classifier_train.py
│ └── ggv2
│ └── components
│ ├── artifacts
│ ├── com.example.IoTPublisher
│ │ ├── 1.0.0
│ │ │ ├── Dockerfile
│ │ │ └── IoTPublisher.py
│ │ └── 1.0.1
│ │ │ ├── Dockerfile
│ │ │ ├── IoTPublisher.py
│ │ │ └── classifier
│ │ │ ├── compiled.meta
│ │ │ ├── compiled.params
│ │ │ ├── compiled.so
│ │ │ ├── compiled_model.json
│ │ │ ├── dlr.h
│ │ │ ├── libdlr.so
│ │ │ └── manifest
│ ├── com.example.Publisher
│ │ └── 1.0.0
│ │ │ └── publisher.py
│ └── com.example.Subscriber
│ │ └── 1.0.0
│ │ ├── classifier.h5
│ │ └── subscriber.py
│ └── recipes
│ ├── com.example.Publisher-1.0.0.yaml
│ └── com.example.Subscriber-1.0.0.yaml
├── hpo_pytorch_mnist
├── input.html
├── mnist.py
└── pytorch_mnist.ipynb
├── life-science
├── BreastCancerPrediction_R.ipynb
└── covid19-built-in-image-classification.ipynb
├── mlops
└── sagemaker-pipelines
│ └── sagemaker-pipelines-sample
│ ├── .gitignore
│ ├── README.md
│ ├── media
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ └── 7.png
│ ├── postprocess
│ └── postprocess.py
│ ├── preprocess
│ └── preprocess.py
│ └── sagemaker-pipelines-sample.ipynb
├── model-deployment
├── TF2-model-deploy.ipynb
├── paddleocr.ipynb
└── pytorch-deeplab.ipynb
├── nlp_amazon_review
├── BlazingText
│ └── blazingtext.ipynb
└── GluonNLP_BERT
│ ├── gluonnlp_bert.ipynb
│ └── src
│ ├── bert
│ ├── data
│ │ ├── __init__.py
│ │ └── transform.py
│ └── model
│ │ ├── __init__.py
│ │ └── classification.py
│ └── train_and_deploy.py
├── package-lock.json
├── package.json
├── sagemaker-experiments
└── pytorch_mnist
│ ├── figures
│ └── experiments-overview.jpg
│ ├── pytorch_mnist.ipynb
│ └── src
│ ├── mnist_deploy.py
│ └── mnist_train.py
├── sagemaker_processing
├── Feature_engineering_with_RAPIDS_on_SageMaker_Processing
│ ├── Feature_engineering_with_RAPIDS_on_SageMaker_Processing.ipynb
│ └── container
│ │ └── Dockerfile
└── processing_with_bring_your_own_container_for_beginner
│ ├── 0_data_preparation.ipynb
│ ├── 1_preprocess.ipynb
│ ├── container
│ ├── Dockerfile
│ └── preprocess_code
│ │ └── preprocess.py
│ ├── media
│ ├── 0_data_preparation.png
│ ├── 1_preprocess.png
│ └── README.md
│ └── preprocess_script
│ └── preprocess.py
├── step-functions-data-science-sdk
├── model-train-and-evaluate
│ └── step_functions_mlworkflow_scikit_learn_data_processing_and_model_evaluation.ipynb
└── model-train-evaluate-compare
│ ├── step_functions_mlworkflow_scikit_learn_data_processing_and_model_evaluation_with_experiments.ipynb
│ └── studio_step_functions_mlworkflow_scikit_learn_data_processing_and_model_evaluation_with_experiments.ipynb
├── tensorflow2_training_and_serving
├── mnist.py
└── tensorflow2_training_and_serving.ipynb
├── workshop
└── lab_bring-your-own-model
│ ├── img
│ └── sagemaker-data-model.png
│ ├── pytorch
│ └── pytorch.ipynb
│ └── tensorflow
│ ├── cnn_mnist_after.py
│ ├── cnn_mnist_before.py
│ └── tensorflow.ipynb
└── xgboost_customer_churn
├── xgboost_customer_churn.ipynb
└── xgboost_customer_churn_neo.ipynb
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | *Issue #, if available:*
2 |
3 | *Description of changes:*
4 |
5 |
6 | By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 |
10 | # Packages #
11 | ############
12 | # it's better to unpack these files and commit the raw source
13 | # git has its own built in compression methods
14 | *.7z
15 | *.dmg
16 | *.gz
17 | *.iso
18 | *.jar
19 | *.rar
20 | *.tar
21 | *.zip
22 |
23 | # Logs and databases #
24 | ######################
25 | *.log
26 | *.sql
27 | *.sqlite
28 |
29 | # OS generated files #
30 | ######################
31 | .DS_Store
32 | .DS_Store?
33 | ._*
34 | .Spotlight-V100
35 | .Trashes
36 | ehthumbs.db
37 | Thumbs.db
38 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4 | opensource-codeofconduct@amazon.com with any additional questions or comments.
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4 | documentation, we greatly value feedback and contributions from our community.
5 |
6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7 | information to effectively respond to your bug report or contribution.
8 |
9 |
10 | ## Reporting Bugs/Feature Requests
11 |
12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13 |
14 | When filing an issue, please check [existing open](https://github.com/aws-samples/amazon-sagemaker-examples-jp/issues), or [recently closed](https://github.com/aws-samples/amazon-sagemaker-examples-jp/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already
15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16 |
17 | * A reproducible test case or series of steps
18 | * The version of our code being used
19 | * Any modifications you've made relevant to the bug
20 | * Anything unusual about your environment or deployment
21 |
22 |
23 | ## Contributing via Pull Requests
24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25 |
26 | 1. You are working against the latest source on the *master* branch.
27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29 |
30 | To send us a pull request, please:
31 |
32 | 1. Fork the repository.
33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34 | 3. Ensure local tests pass.
35 | 4. Commit to your fork using clear commit messages.
36 | 5. Send us a pull request, answering any default questions in the pull request interface.
37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38 |
39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41 |
42 |
43 | ## Finding contributions to work on
44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/aws-samples/amazon-sagemaker-examples-jp/labels/help%20wanted) issues is a great place to start.
45 |
46 |
47 | ## Code of Conduct
48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
50 | opensource-codeofconduct@amazon.com with any additional questions or comments.
51 |
52 |
53 | ## Security issue notifications
54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
55 |
56 |
57 | ## Licensing
58 |
59 | See the [LICENSE](https://github.com/aws-samples/amazon-sagemaker-examples-jp/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
60 |
61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
62 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | amazon-sagemaker-examples-jp
2 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Archived
2 | ---
3 | # Amazon SageMaker Examples JP
4 | **サンプルコードの対象範囲を広げて、[こちらのリポジトリ](https://github.com/aws-samples/aws-ml-jp) に移行しました。**
5 |
6 | [Amazon SageMaker Examples](https://github.com/awslabs/amazon-sagemaker-examples) の日本語訳や、オリジナルのサンプルコードのためのレポジトリです。
7 | AWS 目黒オフィスで SageMaker 体験ハンズオンを定期的に開催しています [[connpass](https://awsj-ml.connpass.com/)]。
8 |
9 | Japanese translation of [Amazon SageMaker Examples](https://github.com/awslabs/amazon-sagemaker-examples) and other original sample codes, which will be used in Amazon SageMaker hands-on workshops in Japan.
10 |
11 | ## Notice
12 |
13 | 現在、SageMaker Python SDK v2 に合わせてサンプルコードの改修を行っています。改修済みのものを master branch で公開しています。改修していないものを legacy branch で公開しています。改修のリクエストなどは [issue](https://github.com/aws-samples/amazon-sagemaker-examples-jp/issues) からご連絡ください。
14 |
15 | ## License
16 |
17 | This library is licensed under the Apache 2.0 License.
18 |
--------------------------------------------------------------------------------
/amazon_forecast_tutorial/common/images/amazon_forecast.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/amazon_forecast_tutorial/common/images/amazon_forecast.png
--------------------------------------------------------------------------------
/amazon_forecast_tutorial/common/images/forecast_workflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/amazon_forecast_tutorial/common/images/forecast_workflow.png
--------------------------------------------------------------------------------
/amazon_forecast_tutorial/common/util/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | from .fcst_utils import *
3 | from .notebook_utils import *
4 |
5 |
--------------------------------------------------------------------------------
/amazon_forecast_tutorial/common/util/fcst_utils.py:
--------------------------------------------------------------------------------
1 | import time
2 | import json
3 | import gzip
4 |
5 | import boto3
6 | import botocore.exceptions
7 |
8 | import pandas as pd
9 | import matplotlib.pyplot as plt
10 |
11 | import util.notebook_utils
12 |
13 |
14 | def wait_till_delete(callback, check_time = 5, timeout = None):
15 |
16 | elapsed_time = 0
17 | while timeout is None or elapsed_time < timeout:
18 | try:
19 | out = callback()
20 | except botocore.exceptions.ClientError as e:
21 | # When given the resource not found exception, deletion has occured
22 | if e.response['Error']['Code'] == 'ResourceNotFoundException':
23 | print('Successful delete')
24 | return
25 | else:
26 | raise
27 | time.sleep(check_time) # units of seconds
28 | elapsed_time += check_time
29 |
30 | raise TimeoutError( "Forecast resource deletion timed-out." )
31 |
32 |
33 | def wait(callback, time_interval = 10):
34 |
35 | status_indicator = util.notebook_utils.StatusIndicator()
36 |
37 | while True:
38 | status = callback()['Status']
39 | status_indicator.update(status)
40 | if status in ('ACTIVE', 'CREATE_FAILED'): break
41 | time.sleep(time_interval)
42 |
43 | status_indicator.end()
44 |
45 | return (status=="ACTIVE")
46 |
47 |
48 | def load_exact_sol(fname, item_id, is_schema_perm=False):
49 | exact = pd.read_csv(fname, header = None)
50 | exact.columns = ['item_id', 'timestamp', 'target']
51 | if is_schema_perm:
52 | exact.columns = ['timestamp', 'target', 'item_id']
53 | return exact.loc[exact['item_id'] == item_id]
54 |
55 |
56 | def get_or_create_iam_role( role_name ):
57 |
58 | iam = boto3.client("iam")
59 |
60 | assume_role_policy_document = {
61 | "Version": "2012-10-17",
62 | "Statement": [
63 | {
64 | "Effect": "Allow",
65 | "Principal": {
66 | "Service": "forecast.amazonaws.com"
67 | },
68 | "Action": "sts:AssumeRole"
69 | }
70 | ]
71 | }
72 |
73 | try:
74 | create_role_response = iam.create_role(
75 | RoleName = role_name,
76 | AssumeRolePolicyDocument = json.dumps(assume_role_policy_document)
77 | )
78 | role_arn = create_role_response["Role"]["Arn"]
79 | print("Created", role_arn)
80 | except iam.exceptions.EntityAlreadyExistsException:
81 | print("The role " + role_name + " exists, ignore to create it")
82 | role_arn = boto3.resource('iam').Role(role_name).arn
83 |
84 | print("Attaching policies")
85 |
86 | iam.attach_role_policy(
87 | RoleName = role_name,
88 | PolicyArn = "arn:aws:iam::aws:policy/AmazonForecastFullAccess"
89 | )
90 |
91 | iam.attach_role_policy(
92 | RoleName=role_name,
93 | PolicyArn='arn:aws:iam::aws:policy/AmazonS3FullAccess',
94 | )
95 |
96 | print("Waiting for a minute to allow IAM role policy attachment to propagate")
97 | time.sleep(60)
98 |
99 | print("Done.")
100 | return role_arn
101 |
102 |
103 | def delete_iam_role( role_name ):
104 | iam = boto3.client("iam")
105 | iam.detach_role_policy( PolicyArn = "arn:aws:iam::aws:policy/AmazonS3FullAccess", RoleName = role_name )
106 | iam.detach_role_policy( PolicyArn = "arn:aws:iam::aws:policy/AmazonForecastFullAccess", RoleName = role_name )
107 | iam.delete_role(RoleName=role_name)
108 |
109 |
110 | def plot_forecasts(fcsts, exact, freq = '1H', forecastHorizon=24, time_back = 80):
111 | p10 = pd.DataFrame(fcsts['Forecast']['Predictions']['p10'])
112 | p50 = pd.DataFrame(fcsts['Forecast']['Predictions']['p50'])
113 | p90 = pd.DataFrame(fcsts['Forecast']['Predictions']['p90'])
114 | pred_int = p50['Timestamp'].apply(lambda x: pd.Timestamp(x))
115 | fcst_start_date = pred_int.iloc[0]
116 | fcst_end_date = pred_int.iloc[-1]
117 | time_int = exact['timestamp'].apply(lambda x: pd.Timestamp(x))
118 | plt.plot(time_int[-time_back:],exact['target'].values[-time_back:], color = 'r')
119 | plt.plot(pred_int, p50['Value'].values, color = 'k')
120 | plt.fill_between(p50['Timestamp'].values,
121 | p10['Value'].values,
122 | p90['Value'].values,
123 | color='b', alpha=0.3);
124 | plt.axvline(x=pd.Timestamp(fcst_start_date), linewidth=3, color='g', ls='dashed')
125 | plt.axvline(x=pd.Timestamp(fcst_end_date), linewidth=3, color='g', ls='dashed')
126 | plt.xticks(rotation=30)
127 | plt.legend(['Target', 'Forecast'], loc = 'lower left')
128 |
129 |
130 | def extract_gz( src, dst ):
131 |
132 | print( f"Extracting {src} to {dst}" )
133 |
134 | with open(dst, 'wb') as fd_dst:
135 | with gzip.GzipFile( src, 'rb') as fd_src:
136 | data = fd_src.read()
137 | fd_dst.write(data)
138 |
139 | print("Done.")
140 |
141 |
--------------------------------------------------------------------------------
/amazon_forecast_tutorial/common/util/notebook_utils.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import io
3 | import ipywidgets
4 |
5 |
6 | widget_table = {}
7 |
8 | def create_text_widget( name, placeholder, default_value="" ):
9 |
10 | if name in widget_table:
11 | widget = widget_table[name]
12 | if name not in widget_table:
13 | widget = ipywidgets.Text( description = name, placeholder = placeholder, value=default_value )
14 | widget_table[name] = widget
15 | display(widget)
16 |
17 | return widget
18 |
19 |
20 | class StatusIndicator:
21 |
22 | def __init__(self):
23 | self.previous_status = None
24 | self.need_newline = False
25 |
26 | def update( self, status ):
27 | if self.previous_status != status:
28 | if self.need_newline:
29 | sys.stdout.write("\n")
30 | sys.stdout.write( status + " ")
31 | self.need_newline = True
32 | self.previous_status = status
33 | else:
34 | sys.stdout.write(".")
35 | self.need_newline = True
36 | sys.stdout.flush()
37 |
38 | def end(self):
39 | if self.need_newline:
40 | sys.stdout.write("\n")
41 |
42 |
--------------------------------------------------------------------------------
/autogluon/tabular-prediction/AutoGluon-Tabular-with-SageMaker/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # AutoGluon Tabular with Amazon SageMaker
6 |
7 | [AutoGluon](https://github.com/awslabs/autogluon) automates machine learning tasks enabling you to easily achieve strong predictive performance in your applications. With just a few lines of code, you can train and deploy high-accuracy deep learning models on tabular, image, and text data.
8 | This example shows how to use AutoGluon-Tabular with Amazon SageMaker by creating custom containers.
--------------------------------------------------------------------------------
/autogluon/tabular-prediction/AutoGluon-Tabular-with-SageMaker/container-inference/Dockerfile.inference:
--------------------------------------------------------------------------------
1 | ARG REGISTRY_URI
2 | FROM ${REGISTRY_URI}
3 |
4 | RUN pip install autogluon
5 | RUN pip install PrettyTable
6 |
7 | # Defines inference.py as script entrypoint
8 | ENV SAGEMAKER_PROGRAM inference.py
9 |
--------------------------------------------------------------------------------
/autogluon/tabular-prediction/AutoGluon-Tabular-with-SageMaker/container-inference/build_push_inference.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Get account
4 | account=${1}
5 |
6 | # Get the region defined in the current configuration
7 | region=${2:-us-east-1}
8 |
9 | # The name of our algorithm
10 | algorithm_name=${3:-sagemaker-autogluon-inference}
11 |
12 | uri_prefix=${4}
13 | fullname="${uri_prefix}/${algorithm_name}:latest"
14 |
15 | # Get the registry id
16 | registry_id=${5}
17 | registry_uri=${6}
18 |
19 | # If the repository doesn't exist in ECR, create it.
20 | aws ecr describe-repositories --region ${region} --repository-names "${algorithm_name}" > /dev/null 2>&1
21 | if [ $? -ne 0 ]
22 | then
23 | aws ecr create-repository --region ${region} --repository-name "${algorithm_name}" > /dev/null
24 | fi
25 |
26 | # Get the login command from ECR and execute it directly
27 | $(aws ecr get-login --region ${region} --no-include-email)
28 | $(aws ecr get-login --registry-ids ${registry_id} --region ${region} --no-include-email)
29 |
30 | # Build the docker image, tag with full name and then push it to ECR
31 | docker build -t ${algorithm_name} -f container-inference/Dockerfile.inference . --build-arg REGISTRY_URI=${registry_uri}
32 | docker tag ${algorithm_name} ${fullname}
33 | docker push ${fullname}
34 |
--------------------------------------------------------------------------------
/autogluon/tabular-prediction/AutoGluon-Tabular-with-SageMaker/container-training/Dockerfile.training:
--------------------------------------------------------------------------------
1 | ARG REGISTRY_URI
2 | FROM ${REGISTRY_URI}
3 |
4 | RUN pip install autogluon
5 | RUN pip install PrettyTable
6 | RUN pip install bokeh
7 |
8 | RUN apt-get update \
9 | && apt-get install -y --no-install-recommends graphviz libgraphviz-dev pkg-config \
10 | && rm -rf /var/lib/apt/lists/* \
11 | && pip install pygraphviz
12 |
13 | ENV PATH="/opt/ml/code:${PATH}"
14 |
15 | # Copies the training code inside the container
16 | COPY container-training/train.py /opt/ml/code/train.py
17 | COPY container-training/inference.py /opt/ml/code/inference.py
18 |
19 | # Install seaborn for plot
20 | RUN pip install seaborn
21 |
22 | # this environment variable is used by the SageMaker PyTorch container to determine our user code directory.
23 | ENV SAGEMAKER_SUBMIT_DIRECTORY /opt/ml/code
24 |
25 | # Defines train.py as script entrypoint
26 | ENV SAGEMAKER_PROGRAM train.py
27 |
--------------------------------------------------------------------------------
/autogluon/tabular-prediction/AutoGluon-Tabular-with-SageMaker/container-training/build_push_training.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Get account
4 | account=${1}
5 |
6 | # Get the region defined in the current configuration
7 | region=${2:-us-east-1}
8 |
9 | # The name of our algorithm
10 | algorithm_name=${3:-sagemaker-autogluon-training}
11 |
12 | uri_prefix=${4}
13 | fullname="${uri_prefix}/${algorithm_name}:latest"
14 |
15 | # Get the registry id
16 | registry_id=${5}
17 | registry_uri=${6}
18 |
19 | # If the repository doesn't exist in ECR, create it.
20 | aws ecr describe-repositories --region ${region} --repository-names "${algorithm_name}" > /dev/null 2>&1
21 | if [ $? -ne 0 ]
22 | then
23 | aws ecr create-repository --region ${region} --repository-name "${algorithm_name}" > /dev/null
24 | fi
25 |
26 | # Get the login command from ECR and execute it directly
27 | $(aws ecr get-login --region ${region} --no-include-email)
28 | $(aws ecr get-login --registry-ids ${registry_id} --region ${region} --no-include-email)
29 |
30 | # Build the docker image, tag with full name and then push it to ECR
31 | docker build -t ${algorithm_name} -f container-training/Dockerfile.training . --build-arg REGISTRY_URI=${registry_uri}
32 | docker tag ${algorithm_name} ${fullname}
33 | docker push ${fullname}
34 |
--------------------------------------------------------------------------------
/autogluon/tabular-prediction/AutoGluon-Tabular-with-SageMaker/container-training/inference.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os
3 | import argparse
4 | import logging
5 | import warnings
6 | import time
7 | import json
8 | import subprocess
9 | import copy
10 |
11 | warnings.filterwarnings('ignore', category=FutureWarning)
12 |
13 | import numpy as np
14 | import pandas as pd
15 | import pickle
16 | from io import StringIO
17 | from timeit import default_timer as timer
18 | from itertools import islice
19 | from collections import Counter
20 |
21 | with warnings.catch_warnings():
22 | warnings.filterwarnings('ignore', category=DeprecationWarning)
23 | from prettytable import PrettyTable
24 | from autogluon import TabularPrediction as task
25 |
26 | def make_str_table(df):
27 | table = PrettyTable(['index']+list(df.columns))
28 | for row in df.itertuples():
29 | table.add_row(row)
30 | return str(table)
31 |
32 | def take(n, iterable):
33 | "Return first n items of the iterable as a list"
34 | return list(islice(iterable, n))
35 |
36 | def preprocess(df, columns, target):
37 | features = copy.deepcopy(columns)
38 | features.remove(target)
39 | first_row_list = df.iloc[0].tolist()
40 |
41 | if set(first_row_list) >= set(features):
42 | df.drop(0, inplace=True)
43 | if len(first_row_list) == len(columns):
44 | df.columns = columns
45 | if len(first_row_list) == len(features):
46 | df.columns = features
47 |
48 | return df
49 |
50 | # ------------------------------------------------------------ #
51 | # Hosting methods #
52 | # ------------------------------------------------------------ #
53 |
54 | def model_fn(model_dir):
55 | """
56 | Load the gluon model. Called once when hosting service starts.
57 | :param: model_dir The directory where model files are stored.
58 | :return: a model (in this case a Gluon network) and the column info.
59 | """
60 | print(f'Loading model from {model_dir} with contents {os.listdir(model_dir)}')
61 | net = task.load(model_dir, verbosity=True)
62 | with open(f'{model_dir}/code/columns.pkl', 'rb') as f:
63 | column_dict = pickle.load(f)
64 | return net, column_dict
65 |
66 |
67 | def transform_fn(models, data, input_content_type, output_content_type):
68 | """
69 | Transform a request using the Gluon model. Called once per request.
70 | :param models: The Gluon model and the column info.
71 | :param data: The request payload.
72 | :param input_content_type: The request content type. ('text/csv')
73 | :param output_content_type: The (desired) response content type. ('text/csv')
74 | :return: response payload and content type.
75 | """
76 | start = timer()
77 | net = models[0]
78 | column_dict = models[1]
79 |
80 | # text/csv
81 | if input_content_type == 'text/csv':
82 |
83 | # Load dataset
84 | columns = column_dict['columns']
85 | df = pd.read_csv(StringIO(data), header=None)
86 | df_preprosessed = preprocess(df, columns, net.label_column)
87 | ds = task.Dataset(df=df_preprosessed)
88 |
89 | try:
90 | predictions = net.predict(ds)
91 | except:
92 | try:
93 | predictions = net.predict(ds.fillna(0.0))
94 | warnings.warn('Filled NaN\'s with 0.0 in order to predict.')
95 | except Exception as e:
96 | response_body = e
97 | return response_body, output_content_type
98 |
99 | # Print prediction counts, limit in case of regression problem
100 | pred_counts = Counter(predictions.tolist())
101 | n_display_items = 30
102 | if len(pred_counts) > n_display_items:
103 | print(f'Top {n_display_items} prediction counts: '
104 | f'{dict(take(n_display_items, pred_counts.items()))}')
105 | else:
106 | print(f'Prediction counts: {pred_counts}')
107 |
108 | # Form response
109 | output = StringIO()
110 | pd.DataFrame(predictions).to_csv(output, header=False, index=False)
111 | response_body = output.getvalue()
112 |
113 | # If target column passed, evaluate predictions performance
114 | target = net.label_column
115 | if target in ds:
116 | print(f'Label column ({target}) found in input data. '
117 | 'Therefore, evaluating prediction performance...')
118 | try:
119 | performance = net.evaluate_predictions(y_true=ds[target],
120 | y_pred=predictions,
121 | auxiliary_metrics=True)
122 | print(json.dumps(performance, indent=4, default=pd.DataFrame.to_json))
123 | time.sleep(0.1)
124 | except Exception as e:
125 | # Print exceptions on evaluate, continue to return predictions
126 | print(f'Exception: {e}')
127 | else:
128 | raise NotImplementedError("content_type must be 'text/csv'")
129 |
130 | elapsed_time = round(timer()-start,3)
131 | print(f'Elapsed time: {round(timer()-start,3)} seconds')
132 |
133 | return response_body, output_content_type
134 |
--------------------------------------------------------------------------------
/autogluon/tabular-prediction/AutoGluon-Tabular-with-SageMaker/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | sudo -n true
4 | if [ $? -eq 0 ]; then
5 | echo "The user has root access."
6 | else
7 | echo "The user does not have root access. Everything required to run the notebook is already installed and setup. We are good to go!"
8 | exit 0
9 | fi
10 |
11 | # Do we have GPU support?
12 | nvidia-smi > /dev/null 2>&1
13 | if [ $? -eq 0 ]; then
14 | # check if we have nvidia-docker
15 | NVIDIA_DOCKER=`rpm -qa | grep -c nvidia-docker2`
16 | if [ $NVIDIA_DOCKER -eq 0 ]; then
17 | # Install nvidia-docker2
18 | #sudo pkill -SIGHUP dockerd
19 | sudo yum -y remove docker
20 | sudo yum -y install docker-17.09.1ce-1.111.amzn1
21 |
22 | sudo /etc/init.d/docker start
23 |
24 | curl -s -L https://nvidia.github.io/nvidia-docker/amzn1/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo
25 | sudo yum install -y nvidia-docker2-2.0.3-1.docker17.09.1.ce.amzn1
26 | sudo cp daemon.json /etc/docker/daemon.json
27 | sudo pkill -SIGHUP dockerd
28 | echo "installed nvidia-docker2"
29 | else
30 | echo "nvidia-docker2 already installed. We are good to go!"
31 | fi
32 | fi
33 |
34 | # This is common for both GPU and CPU instances
35 |
36 | # check if we have docker-compose
37 | docker-compose version >/dev/null 2>&1
38 | if [ $? -ne 0 ]; then
39 | # install docker compose
40 | pip install docker-compose
41 | fi
42 |
43 | # check if we need to configure our docker interface
44 | SAGEMAKER_NETWORK=`docker network ls | grep -c sagemaker-local`
45 | if [ $SAGEMAKER_NETWORK -eq 0 ]; then
46 | docker network create --driver bridge sagemaker-local
47 | fi
48 |
49 | # Notebook instance Docker networking fixes
50 | RUNNING_ON_NOTEBOOK_INSTANCE=`sudo iptables -S OUTPUT -t nat | grep -c 169.254.0.2`
51 |
52 | # Get the Docker Network CIDR and IP for the sagemaker-local docker interface.
53 | SAGEMAKER_INTERFACE=br-`docker network ls | grep sagemaker-local | cut -d' ' -f1`
54 | DOCKER_NET=`ip route | grep $SAGEMAKER_INTERFACE | cut -d" " -f1`
55 | DOCKER_IP=`ip route | grep $SAGEMAKER_INTERFACE | cut -d" " -f12`
56 |
57 | # check if both IPTables and the Route Table are OK.
58 | IPTABLES_PATCHED=`sudo iptables -S PREROUTING -t nat | grep -c 169.254.0.2`
59 | ROUTE_TABLE_PATCHED=`sudo ip route show table agent | grep -c $SAGEMAKER_INTERFACE`
60 |
61 | if [ $RUNNING_ON_NOTEBOOK_INSTANCE -gt 0 ]; then
62 |
63 | if [ $ROUTE_TABLE_PATCHED -eq 0 ]; then
64 | # fix routing
65 | sudo ip route add $DOCKER_NET via $DOCKER_IP dev $SAGEMAKER_INTERFACE table agent
66 | else
67 | echo "SageMaker instance route table setup is ok. We are good to go."
68 | fi
69 |
70 | if [ $IPTABLES_PATCHED -eq 0 ]; then
71 | sudo iptables -t nat -A PREROUTING -i $SAGEMAKER_INTERFACE -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 169.254.0.2:9081
72 | echo "iptables for Docker setup done"
73 | else
74 | echo "SageMaker instance routing for Docker is ok. We are good to go!"
75 | fi
76 | fi
77 |
--------------------------------------------------------------------------------
/distributed_training/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG region
2 |
3 | FROM 763104351884.dkr.ecr.${region}.amazonaws.com/pytorch-training:1.8.1-gpu-py36-cu111-ubuntu18.04
4 |
5 | RUN pip install ninja yacs cython matplotlib tqdm opencv-python pybind11==2.5.0 'git+https://github.com/NVIDIA/dllogger'
6 |
7 | RUN pip --no-cache-dir --no-cache install 'git+https://github.com/NVIDIA/cocoapi#egg=pycocotools&subdirectory=PythonAPI'
8 |
9 | RUN cd /root && \
10 | rm -rf apex && \
11 | git clone https://github.com/NVIDIA/apex && \
12 | cd apex && \
13 | python setup.py install --cuda_ext --cpp_ext
14 |
15 | RUN cd /root && \
16 | rm -rf DeepLearningExamples && \
17 | git clone --recursive https://github.com/HerringForks/DeepLearningExamples.git && \
18 | cd DeepLearningExamples/PyTorch/Segmentation/MaskRCNN/pytorch/ && \
19 | python setup.py build develop
20 |
--------------------------------------------------------------------------------
/distributed_training/README.md:
--------------------------------------------------------------------------------
1 | # Amazon SageMakerで大型学習ジョブのコスト最適化
2 |
3 |
4 | データ量が増えてきて、深層学習モデルの学習に時間がかかりすぎていませんか?
5 |
6 | このノートブックでは、深層学習モデルの学習にかかる時間とコストを最適化する手順を、SageMaker Data Parallel LibraryとSageMaker Debuggerを使いながらご紹介します。
7 |
8 | SageMaker Data Parallelism Libraryは、AWS上での分散学習実行に最適化されているため、HorovodやPyTorch DDPなどの他の分散学習フレームワークに比べて並列化効率がより高いことが実証されています。詳細は、[論文](https://www.amazon.science/publications/herring-rethinking-the-parameter-server-at-scale-for-the-cloud)を参照してください。
9 |
10 | 今回は、例としてMask RCNNモデルに[COCO2017データセット](https://cocodataset.org/#home)を分散学習していく過程を紹介します。
11 |
12 | なお、このノートブックはSageMaker Studio上のPython 3 (PyTorch 1.6 Python 3.6 GPU Optimized)環境で動作確認をしております。
13 |
14 | 他のフレームワークやモデルでの分散学習のスクリプトは[こちら](https://github.com/HerringForks/DeepLearningExamples)を参照してください。
15 |
16 |
17 | ## 学習時間と課金額のトレードオフでトータルコスト最適化を考える
18 |
19 | SageMaker上で分散学習を実施することで、学習時間と課金額のトレードオフがコントロールできるようになります。具体的には、約11%の金額増加で約86%も学習時間を短縮できる 、といった例が挙げられます。こちらのトレードオフを詳しくみてみましょう。
20 |
21 | インスタンスの使用料金をPドル/時、学習にかかる時間をT時間、並列化効率(インスタンス x個で学習時間がx倍にどれくらい近くなるか)をS%として、1個のインスタンス(またはGPU)からN個のインスタンス(またはGPU)に分散学習する場合を考えてみましょう。
22 |
23 | 学習にかかる時間はT時間から(T/N)/S時間に減り、インスタンス使用料金はT * Pドルから(T/N)/S * P * N = T/S * Pドルへ(S = 1、すなわち並列化効率100%とならない限りは)増加します。並列化効率が十分高ければ、大幅な学習時間短縮を少ない金額の増加で買うことができる 、というわけです。コストを時間と課金額の組み合わせと捉えると、分散学習が1つのコスト最適化のツールとなり、かつ並列化効率がそのトレードオフを決定する重要な要因であることがご理解いただけると思います。
24 | また、学習時間に制限があり、データ量が増える中で時間内に学習を終える必要があるかもしれません。その際にも、並列化効率が鍵となり、どのくらいの課金額の増加でどのくらいの学習時間短縮が狙えるか調査することが大切になってきます。
25 |
26 | 例えば、ml.p3.2xlargeインスタンスで24時間学習に時間を取られている場合、8つのインスタンスに90%の並列化効率で分散学習が実現できれば、時間と課金額は以下のように変化します。
27 |
28 | 分散学習なしでは24 * 3.825 = 91.8ドル(us-west-2リージョンで[SageMaker Savings Plan](https://aws.amazon.com/about-aws/whats-new/2021/04/amazon-sagemaker-announces-a-price-reduction-in-instances-and-sagemaker-savings-plan/)を使用しない場合)の課金と24時間というコストが発生します。
29 |
30 | 上記の条件で分散学習をすると、24/0.9 * 3.825 = 102ドルの課金と24/8/0.9 = 3.33時間というコストになります。
31 |
32 | この場合、最初に記載したように約11%の金額増加で約86%の学習時間短縮が期待されます。どちらのトータルコストが良いかどうかは、ビジネス上で深層学習のモデル学習時間短縮がどれくらい重要かによります。しかし、モデルを何度も再学習する必要に迫られる中で、これからデータ量が増えていくことが予測されるならば、分散学習を1つの選択肢として持っておくのは悪くないかもしれません。
--------------------------------------------------------------------------------
/distributed_training/build_and_push.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # This script shows how to build the Docker image and push it to ECR to be ready for use
3 | # by SageMaker.
4 | # The argument to this script is the image name. This will be used as the image on the local
5 | # machine and combined with the account and region to form the repository name for ECR.
6 | # set region
7 |
8 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
9 |
10 | if [ "$#" -eq 3 ]; then
11 | region=$1
12 | image=$2
13 | tag=$3
14 | else
15 | echo "usage: $0 $1 $2 "
16 | exit 1
17 | fi
18 |
19 | # Get the account number associated with the current IAM credentials
20 | account=$(aws sts get-caller-identity --query Account --output text)
21 |
22 | if [ $? -ne 0 ]
23 | then
24 | exit 255
25 | fi
26 |
27 |
28 | fullname="${account}.dkr.ecr.${region}.amazonaws.com/${image}:${tag}"
29 |
30 | # If the repository doesn't exist in ECR, create it.
31 | aws ecr describe-repositories --region ${region} --repository-names "${image}" > /dev/null 2>&1
32 | if [ $? -ne 0 ]; then
33 | echo "creating ECR repository : ${fullname} "
34 | aws ecr create-repository --region ${region} --repository-name "${image}" > /dev/null
35 | fi
36 |
37 | $(aws ecr get-login --no-include-email --region ${region} --registry-ids 763104351884)
38 | docker build ${DIR}/ -t ${image} -f ${DIR}/Dockerfile --build-arg region=${region}
39 | docker tag ${image} ${fullname}
40 |
41 | # Get the login command from ECR and execute it directly
42 | $(aws ecr get-login --region ${region} --no-include-email)
43 | docker push ${fullname}
44 | if [ $? -eq 0 ]; then
45 | echo "Amazon ECR URI: ${fullname}"
46 | else
47 | echo "Error: Image build and push failed"
48 | exit 1
49 | fi
--------------------------------------------------------------------------------
/distributed_training/e2e_mask_rcnn_R_50_FPN_1x_16GPU_4bs.yaml:
--------------------------------------------------------------------------------
1 | MODEL:
2 | META_ARCHITECTURE: "GeneralizedRCNN"
3 | WEIGHT: "catalog://ImageNetPretrained/MSRA/R-50"
4 | BACKBONE:
5 | CONV_BODY: "R-50-FPN"
6 | OUT_CHANNELS: 256
7 | RPN:
8 | USE_FPN: True
9 | ANCHOR_STRIDE: (4, 8, 16, 32, 64)
10 | PRE_NMS_TOP_N_TRAIN: 2000
11 | PRE_NMS_TOP_N_TEST: 1000
12 | POST_NMS_TOP_N_TEST: 1000
13 | FPN_POST_NMS_TOP_N_TEST: 1000
14 | ROI_HEADS:
15 | USE_FPN: True
16 | ROI_BOX_HEAD:
17 | POOLER_RESOLUTION: 7
18 | POOLER_SCALES: (0.25, 0.125, 0.0625, 0.03125)
19 | POOLER_SAMPLING_RATIO: 2
20 | FEATURE_EXTRACTOR: "FPN2MLPFeatureExtractor"
21 | PREDICTOR: "FPNPredictor"
22 | ROI_MASK_HEAD:
23 | POOLER_SCALES: (0.25, 0.125, 0.0625, 0.03125)
24 | FEATURE_EXTRACTOR: "MaskRCNNFPNFeatureExtractor"
25 | PREDICTOR: "MaskRCNNC4Predictor"
26 | POOLER_RESOLUTION: 14
27 | POOLER_SAMPLING_RATIO: 2
28 | RESOLUTION: 28
29 | SHARE_BOX_FEATURE_EXTRACTOR: False
30 | MASK_ON: True
31 | DATASETS:
32 | TRAIN: ("coco_2017_train",)
33 | TEST: ("coco_2017_val",)
34 | DATALOADER:
35 | SIZE_DIVISIBILITY: 32
36 | SOLVER:
37 | BASE_LR: 0.01
38 | WEIGHT_DECAY: 0.0001
39 | STEPS: (4320, 5760)
40 | MAX_ITER: 1000
41 | IMS_PER_BATCH: 64
42 | WARMUP_FACTOR: 0.001
43 | WARMUP_ITERS: 1000
44 | TEST:
45 | IMS_PER_BATCH: 64
46 |
47 |
--------------------------------------------------------------------------------
/distributed_training/e2e_mask_rcnn_R_50_FPN_1x_32GPU_4bs.yaml:
--------------------------------------------------------------------------------
1 | MODEL:
2 | META_ARCHITECTURE: "GeneralizedRCNN"
3 | WEIGHT: "catalog://ImageNetPretrained/MSRA/R-50"
4 | BACKBONE:
5 | CONV_BODY: "R-50-FPN"
6 | OUT_CHANNELS: 256
7 | RPN:
8 | USE_FPN: True
9 | ANCHOR_STRIDE: (4, 8, 16, 32, 64)
10 | PRE_NMS_TOP_N_TRAIN: 2000
11 | PRE_NMS_TOP_N_TEST: 1000
12 | POST_NMS_TOP_N_TEST: 1000
13 | FPN_POST_NMS_TOP_N_TEST: 1000
14 | ROI_HEADS:
15 | USE_FPN: True
16 | ROI_BOX_HEAD:
17 | POOLER_RESOLUTION: 7
18 | POOLER_SCALES: (0.25, 0.125, 0.0625, 0.03125)
19 | POOLER_SAMPLING_RATIO: 2
20 | FEATURE_EXTRACTOR: "FPN2MLPFeatureExtractor"
21 | PREDICTOR: "FPNPredictor"
22 | ROI_MASK_HEAD:
23 | POOLER_SCALES: (0.25, 0.125, 0.0625, 0.03125)
24 | FEATURE_EXTRACTOR: "MaskRCNNFPNFeatureExtractor"
25 | PREDICTOR: "MaskRCNNC4Predictor"
26 | POOLER_RESOLUTION: 14
27 | POOLER_SAMPLING_RATIO: 2
28 | RESOLUTION: 28
29 | SHARE_BOX_FEATURE_EXTRACTOR: False
30 | MASK_ON: True
31 | DATASETS:
32 | TRAIN: ("coco_2017_train",)
33 | TEST: ("coco_2017_val",)
34 | DATALOADER:
35 | SIZE_DIVISIBILITY: 32
36 | SOLVER:
37 | BASE_LR: 0.02
38 | WEIGHT_DECAY: 0.0001
39 | STEPS: (4320, 5760)
40 | MAX_ITER: 1000
41 | IMS_PER_BATCH: 128
42 | WARMUP_FACTOR: 0.001
43 | WARMUP_ITERS: 1000
44 | TEST:
45 | IMS_PER_BATCH: 64
46 |
47 |
--------------------------------------------------------------------------------
/distributed_training/e2e_mask_rcnn_R_50_FPN_1x_64GPU_4bs.yaml:
--------------------------------------------------------------------------------
1 | MODEL:
2 | META_ARCHITECTURE: "GeneralizedRCNN"
3 | WEIGHT: "catalog://ImageNetPretrained/MSRA/R-50"
4 | BACKBONE:
5 | CONV_BODY: "R-50-FPN"
6 | OUT_CHANNELS: 256
7 | RPN:
8 | USE_FPN: True
9 | ANCHOR_STRIDE: (4, 8, 16, 32, 64)
10 | PRE_NMS_TOP_N_TRAIN: 2000
11 | PRE_NMS_TOP_N_TEST: 1000
12 | POST_NMS_TOP_N_TEST: 1000
13 | FPN_POST_NMS_TOP_N_TEST: 1000
14 | ROI_HEADS:
15 | USE_FPN: True
16 | ROI_BOX_HEAD:
17 | POOLER_RESOLUTION: 7
18 | POOLER_SCALES: (0.25, 0.125, 0.0625, 0.03125)
19 | POOLER_SAMPLING_RATIO: 2
20 | FEATURE_EXTRACTOR: "FPN2MLPFeatureExtractor"
21 | PREDICTOR: "FPNPredictor"
22 | ROI_MASK_HEAD:
23 | POOLER_SCALES: (0.25, 0.125, 0.0625, 0.03125)
24 | FEATURE_EXTRACTOR: "MaskRCNNFPNFeatureExtractor"
25 | PREDICTOR: "MaskRCNNC4Predictor"
26 | POOLER_RESOLUTION: 14
27 | POOLER_SAMPLING_RATIO: 2
28 | RESOLUTION: 28
29 | SHARE_BOX_FEATURE_EXTRACTOR: False
30 | MASK_ON: True
31 | DATASETS:
32 | TRAIN: ("coco_2017_train",)
33 | TEST: ("coco_2017_val",)
34 | DATALOADER:
35 | SIZE_DIVISIBILITY: 32
36 | SOLVER:
37 | BASE_LR: 0.04
38 | WEIGHT_DECAY: 0.0001
39 | STEPS: (4320, 5760)
40 | MAX_ITER: 1500
41 | IMS_PER_BATCH: 256
42 | WARMUP_FACTOR: 0.001
43 | WARMUP_ITERS: 1000
44 | TEST:
45 | IMS_PER_BATCH: 64
46 |
47 |
--------------------------------------------------------------------------------
/distributed_training/e2e_mask_rcnn_R_50_FPN_1x_8GPU_4bs.yaml:
--------------------------------------------------------------------------------
1 | MODEL:
2 | META_ARCHITECTURE: "GeneralizedRCNN"
3 | WEIGHT: "catalog://ImageNetPretrained/MSRA/R-50"
4 | BACKBONE:
5 | CONV_BODY: "R-50-FPN"
6 | OUT_CHANNELS: 256
7 | RPN:
8 | USE_FPN: True
9 | ANCHOR_STRIDE: (4, 8, 16, 32, 64)
10 | PRE_NMS_TOP_N_TRAIN: 2000
11 | PRE_NMS_TOP_N_TEST: 1000
12 | POST_NMS_TOP_N_TEST: 1000
13 | FPN_POST_NMS_TOP_N_TEST: 1000
14 | ROI_HEADS:
15 | USE_FPN: True
16 | ROI_BOX_HEAD:
17 | POOLER_RESOLUTION: 7
18 | POOLER_SCALES: (0.25, 0.125, 0.0625, 0.03125)
19 | POOLER_SAMPLING_RATIO: 2
20 | FEATURE_EXTRACTOR: "FPN2MLPFeatureExtractor"
21 | PREDICTOR: "FPNPredictor"
22 | ROI_MASK_HEAD:
23 | POOLER_SCALES: (0.25, 0.125, 0.0625, 0.03125)
24 | FEATURE_EXTRACTOR: "MaskRCNNFPNFeatureExtractor"
25 | PREDICTOR: "MaskRCNNC4Predictor"
26 | POOLER_RESOLUTION: 14
27 | POOLER_SAMPLING_RATIO: 2
28 | RESOLUTION: 28
29 | SHARE_BOX_FEATURE_EXTRACTOR: False
30 | MASK_ON: True
31 | DATASETS:
32 | TRAIN: ("coco_2017_train",)
33 | TEST: ("coco_2017_val",)
34 | DATALOADER:
35 | SIZE_DIVISIBILITY: 32
36 | SOLVER:
37 | BASE_LR: 0.005
38 | WEIGHT_DECAY: 0.0001
39 | STEPS: (4320, 5760)
40 | MAX_ITER: 1000
41 | IMS_PER_BATCH: 32
42 | WARMUP_FACTOR: 0.001
43 | WARMUP_ITERS: 1000
44 | TEST:
45 | IMS_PER_BATCH: 64
46 |
47 |
--------------------------------------------------------------------------------
/distributed_training/images/.ipynb_checkpoints/sm_debugger_insights-checkpoint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/distributed_training/images/.ipynb_checkpoints/sm_debugger_insights-checkpoint.png
--------------------------------------------------------------------------------
/distributed_training/images/sm_debugger_insights.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/distributed_training/images/sm_debugger_insights.png
--------------------------------------------------------------------------------
/distributed_training/images/sm_debugger_nav.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/distributed_training/images/sm_debugger_nav.png
--------------------------------------------------------------------------------
/distributed_training/images/sm_debugger_sys_util.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/distributed_training/images/sm_debugger_sys_util.png
--------------------------------------------------------------------------------
/distributed_training/images/smdataparallel_horovod.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/distributed_training/images/smdataparallel_horovod.png
--------------------------------------------------------------------------------
/distributed_training/images/smdataparallel_pytorchddp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/distributed_training/images/smdataparallel_pytorchddp.png
--------------------------------------------------------------------------------
/distributed_training/upload_coco2017_to_s3.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # credit of https://github.com/awslabs/amazon-sagemaker-examples/blob/master/advanced_functionality/distributed_tensorflow_mask_rcnn/prepare-s3-bucket.sh
3 |
4 | if [ "$#" -ne 2 ]; then
5 | echo "usage: $0 " # TODO: fix usage message to reflect that bucket prefix is also required
6 | exit 1
7 | fi
8 |
9 | S3_BUCKET=$1
10 | S3_PREFIX=$2
11 |
12 | # Stage directory must be on EBS volume with 100 GB available space
13 | STAGE_DIR=$HOME/SageMaker/coco-2017-$(date +"%Y-%m-%d-%H-%M-%S")
14 |
15 | echo "Create stage directory: $STAGE_DIR"
16 | mkdir -p $STAGE_DIR
17 |
18 | # wget -O $STAGE_DIR/train2017.zip http://images.cocodataset.org/zips/train2017.zip
19 | aws s3 cp s3://fast-ai-coco/train2017.zip $STAGE_DIR/train2017.zip
20 | echo "Extracting $STAGE_DIR/train2017.zip"
21 | unzip -o $STAGE_DIR/train2017.zip -d $STAGE_DIR | awk 'BEGIN {ORS="="} {if(NR%1000==0)print "="}'
22 | echo "Done."
23 | rm $STAGE_DIR/train2017.zip
24 |
25 | # wget -O $STAGE_DIR/val2017.zip http://images.cocodataset.org/zips/val2017.zip
26 | aws s3 cp s3://fast-ai-coco/val2017.zip $STAGE_DIR/val2017.zip
27 | echo "Extracting $STAGE_DIR/val2017.zip"
28 | unzip -o $STAGE_DIR/val2017.zip -d $STAGE_DIR | awk 'BEGIN {ORS="="} {if(NR%1000==0)print "="}'
29 | echo "Done."
30 | rm $STAGE_DIR/val2017.zip
31 |
32 | # wget -O $STAGE_DIR/annotations_trainval2017.zip http://images.cocodataset.org/annotations/annotations_trainval2017.zip
33 | aws s3 cp s3://fast-ai-coco/annotations_trainval2017.zip $STAGE_DIR/annotations_trainval2017.zip
34 | unzip -o $STAGE_DIR/annotations_trainval2017.zip -d $STAGE_DIR
35 | rm $STAGE_DIR/annotations_trainval2017.zip
36 |
37 | echo "`date`: Uploading extracted files to s3://$S3_BUCKET/$S3_PREFIX [ eta 12 minutes ]"
38 | aws s3 cp --recursive $STAGE_DIR s3://$S3_BUCKET/$S3_PREFIX | awk 'BEGIN {ORS="="} {if(NR%100==0)print "="}'
39 | echo "Done."
40 |
41 | echo "Delete stage directory: $STAGE_DIR"
42 | rm -rf $STAGE_DIR
43 | echo "Success."
--------------------------------------------------------------------------------
/docs/_print/about/featured-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/about/featured-background.jpg
--------------------------------------------------------------------------------
/docs/_print/about/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_1920x1080_fill_q75_catmullrom_bottom.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/about/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_1920x1080_fill_q75_catmullrom_bottom.jpg
--------------------------------------------------------------------------------
/docs/_print/about/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_960x540_fill_q75_catmullrom_bottom.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/about/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_960x540_fill_q75_catmullrom_bottom.jpg
--------------------------------------------------------------------------------
/docs/_print/docs/ai-services/images/rekognition/celeb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/docs/ai-services/images/rekognition/celeb.png
--------------------------------------------------------------------------------
/docs/_print/docs/ai-services/images/rekognition/compare-face.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/docs/ai-services/images/rekognition/compare-face.png
--------------------------------------------------------------------------------
/docs/_print/docs/ai-services/images/rekognition/moderation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/docs/ai-services/images/rekognition/moderation.png
--------------------------------------------------------------------------------
/docs/_print/docs/ai-services/images/rekognition/ppe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/docs/ai-services/images/rekognition/ppe.png
--------------------------------------------------------------------------------
/docs/_print/docs/ai-services/images/rekognition/rek-obj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/docs/ai-services/images/rekognition/rek-obj.png
--------------------------------------------------------------------------------
/docs/_print/docs/ai-services/images/rekognition/text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/docs/ai-services/images/rekognition/text.png
--------------------------------------------------------------------------------
/docs/_print/docs/ai-services/images/textract/textract.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/docs/ai-services/images/textract/textract.png
--------------------------------------------------------------------------------
/docs/_print/docs/ai-services/picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/docs/ai-services/picture.png
--------------------------------------------------------------------------------
/docs/_print/docs/お客様事例集/picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/_print/docs/お客様事例集/picture.png
--------------------------------------------------------------------------------
/docs/about/featured-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/about/featured-background.jpg
--------------------------------------------------------------------------------
/docs/about/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_1920x1080_fill_q75_catmullrom_bottom.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/about/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_1920x1080_fill_q75_catmullrom_bottom.jpg
--------------------------------------------------------------------------------
/docs/about/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_960x540_fill_q75_catmullrom_bottom.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/about/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_960x540_fill_q75_catmullrom_bottom.jpg
--------------------------------------------------------------------------------
/docs/blog/2018/10/06/easy-documentation-with-docsy/featured-sunset-get.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/blog/2018/10/06/easy-documentation-with-docsy/featured-sunset-get.png
--------------------------------------------------------------------------------
/docs/blog/2018/10/06/easy-documentation-with-docsy/featured-sunset-get_hu69849a7cdb847c2393a7b3a7f6061c86_387442_250x125_fill_catmullrom_center_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/blog/2018/10/06/easy-documentation-with-docsy/featured-sunset-get_hu69849a7cdb847c2393a7b3a7f6061c86_387442_250x125_fill_catmullrom_center_2.png
--------------------------------------------------------------------------------
/docs/blog/2018/10/06/easy-documentation-with-docsy/featured-sunset-get_hu69849a7cdb847c2393a7b3a7f6061c86_387442_600x300_fill_catmullrom_smart1_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/blog/2018/10/06/easy-documentation-with-docsy/featured-sunset-get_hu69849a7cdb847c2393a7b3a7f6061c86_387442_600x300_fill_catmullrom_smart1_2.png
--------------------------------------------------------------------------------
/docs/blog/2018/10/06/easy-documentation-with-docsy/featured-sunset-get_hu69849a7cdb847c2393a7b3a7f6061c86_387442_640x0_resize_catmullrom_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/blog/2018/10/06/easy-documentation-with-docsy/featured-sunset-get_hu69849a7cdb847c2393a7b3a7f6061c86_387442_640x0_resize_catmullrom_2.png
--------------------------------------------------------------------------------
/docs/blog/news/page/1/index.html:
--------------------------------------------------------------------------------
1 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/blog/news/
--------------------------------------------------------------------------------
/docs/blog/page/1/index.html:
--------------------------------------------------------------------------------
1 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/blog/
--------------------------------------------------------------------------------
/docs/blog/releases/page/1/index.html:
--------------------------------------------------------------------------------
1 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/blog/releases/
--------------------------------------------------------------------------------
/docs/css/prism.css:
--------------------------------------------------------------------------------
1 | /* PrismJS 1.21.0
2 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp+go+java+markdown+python+scss+sql+toml+yaml&plugins=toolbar+copy-to-clipboard */
3 | /**
4 | * prism.js default theme for JavaScript, CSS and HTML
5 | * Based on dabblet (http://dabblet.com)
6 | * @author Lea Verou
7 | */
8 |
9 | code[class*="language-"],
10 | pre[class*="language-"] {
11 | color: black;
12 | background: none;
13 | text-shadow: 0 1px white;
14 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
15 | font-size: 1em;
16 | text-align: left;
17 | white-space: pre;
18 | word-spacing: normal;
19 | word-break: normal;
20 | word-wrap: normal;
21 | line-height: 1.5;
22 |
23 | -moz-tab-size: 4;
24 | -o-tab-size: 4;
25 | tab-size: 4;
26 |
27 | -webkit-hyphens: none;
28 | -moz-hyphens: none;
29 | -ms-hyphens: none;
30 | hyphens: none;
31 | }
32 |
33 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
34 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
35 | text-shadow: none;
36 | background: #b3d4fc;
37 | }
38 |
39 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
40 | code[class*="language-"]::selection, code[class*="language-"] ::selection {
41 | text-shadow: none;
42 | background: #b3d4fc;
43 | }
44 |
45 | @media print {
46 | code[class*="language-"],
47 | pre[class*="language-"] {
48 | text-shadow: none;
49 | }
50 | }
51 |
52 | /* Code blocks */
53 | pre[class*="language-"] {
54 | padding: 1em;
55 | margin: .5em 0;
56 | overflow: auto;
57 | }
58 |
59 | :not(pre) > code[class*="language-"],
60 | pre[class*="language-"] {
61 | background: #f5f2f0;
62 | }
63 |
64 | /* Inline code */
65 | :not(pre) > code[class*="language-"] {
66 | padding: .1em;
67 | border-radius: .3em;
68 | white-space: normal;
69 | }
70 |
71 | .token.comment,
72 | .token.prolog,
73 | .token.doctype,
74 | .token.cdata {
75 | color: slategray;
76 | }
77 |
78 | .token.punctuation {
79 | color: #999;
80 | }
81 |
82 | .token.namespace {
83 | opacity: .7;
84 | }
85 |
86 | .token.property,
87 | .token.tag,
88 | .token.boolean,
89 | .token.number,
90 | .token.constant,
91 | .token.symbol,
92 | .token.deleted {
93 | color: #905;
94 | }
95 |
96 | .token.selector,
97 | .token.attr-name,
98 | .token.string,
99 | .token.char,
100 | .token.builtin,
101 | .token.inserted {
102 | color: #690;
103 | }
104 |
105 | .token.operator,
106 | .token.entity,
107 | .token.url,
108 | .language-css .token.string,
109 | .style .token.string {
110 | color: #9a6e3a;
111 | /* This background color was intended by the author of this theme. */
112 | background: hsla(0, 0%, 100%, .5);
113 | }
114 |
115 | .token.atrule,
116 | .token.attr-value,
117 | .token.keyword {
118 | color: #07a;
119 | }
120 |
121 | .token.function,
122 | .token.class-name {
123 | color: #DD4A68;
124 | }
125 |
126 | .token.regex,
127 | .token.important,
128 | .token.variable {
129 | color: #e90;
130 | }
131 |
132 | .token.important,
133 | .token.bold {
134 | font-weight: bold;
135 | }
136 | .token.italic {
137 | font-style: italic;
138 | }
139 |
140 | .token.entity {
141 | cursor: help;
142 | }
143 |
144 | div.code-toolbar {
145 | position: relative;
146 | }
147 |
148 | div.code-toolbar > .toolbar {
149 | position: absolute;
150 | top: .3em;
151 | right: .2em;
152 | transition: opacity 0.3s ease-in-out;
153 | opacity: 0;
154 | }
155 |
156 | div.code-toolbar:hover > .toolbar {
157 | opacity: 1;
158 | }
159 |
160 | /* Separate line b/c rules are thrown out if selector is invalid.
161 | IE11 and old Edge versions don't support :focus-within. */
162 | div.code-toolbar:focus-within > .toolbar {
163 | opacity: 1;
164 | }
165 |
166 | div.code-toolbar > .toolbar .toolbar-item {
167 | display: inline-block;
168 | }
169 |
170 | div.code-toolbar > .toolbar a {
171 | cursor: pointer;
172 | }
173 |
174 | div.code-toolbar > .toolbar button {
175 | background: none;
176 | border: 0;
177 | color: inherit;
178 | font: inherit;
179 | line-height: normal;
180 | overflow: visible;
181 | padding: 0;
182 | -webkit-user-select: none; /* for button */
183 | -moz-user-select: none;
184 | -ms-user-select: none;
185 | }
186 |
187 | div.code-toolbar > .toolbar a,
188 | div.code-toolbar > .toolbar button,
189 | div.code-toolbar > .toolbar span {
190 | color: #bbb;
191 | font-size: .8em;
192 | padding: 0 .5em;
193 | background: #f5f2f0;
194 | background: rgba(224, 224, 224, 0.2);
195 | box-shadow: 0 2px 0 0 rgba(0,0,0,0.2);
196 | border-radius: .5em;
197 | }
198 |
199 | div.code-toolbar > .toolbar a:hover,
200 | div.code-toolbar > .toolbar a:focus,
201 | div.code-toolbar > .toolbar button:hover,
202 | div.code-toolbar > .toolbar button:focus,
203 | div.code-toolbar > .toolbar span:hover,
204 | div.code-toolbar > .toolbar span:focus {
205 | color: inherit;
206 | text-decoration: none;
207 | }
208 |
209 |
--------------------------------------------------------------------------------
/docs/docs/ai-services/images/rekognition/celeb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/docs/ai-services/images/rekognition/celeb.png
--------------------------------------------------------------------------------
/docs/docs/ai-services/images/rekognition/compare-face.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/docs/ai-services/images/rekognition/compare-face.png
--------------------------------------------------------------------------------
/docs/docs/ai-services/images/rekognition/moderation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/docs/ai-services/images/rekognition/moderation.png
--------------------------------------------------------------------------------
/docs/docs/ai-services/images/rekognition/ppe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/docs/ai-services/images/rekognition/ppe.png
--------------------------------------------------------------------------------
/docs/docs/ai-services/images/rekognition/rek-obj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/docs/ai-services/images/rekognition/rek-obj.png
--------------------------------------------------------------------------------
/docs/docs/ai-services/images/rekognition/text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/docs/ai-services/images/rekognition/text.png
--------------------------------------------------------------------------------
/docs/docs/ai-services/images/textract/textract.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/docs/ai-services/images/textract/textract.png
--------------------------------------------------------------------------------
/docs/docs/ai-services/picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/docs/ai-services/picture.png
--------------------------------------------------------------------------------
/docs/docs/お客様事例集/picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/docs/お客様事例集/picture.png
--------------------------------------------------------------------------------
/docs/favicons/android-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/android-144x144.png
--------------------------------------------------------------------------------
/docs/favicons/android-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/android-192x192.png
--------------------------------------------------------------------------------
/docs/favicons/android-36x36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/android-36x36.png
--------------------------------------------------------------------------------
/docs/favicons/android-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/android-48x48.png
--------------------------------------------------------------------------------
/docs/favicons/android-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/android-72x72.png
--------------------------------------------------------------------------------
/docs/favicons/android-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/android-96x96.png
--------------------------------------------------------------------------------
/docs/favicons/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/favicon-1024.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/favicon-16x16.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/favicon-256.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/favicon-32x32.png
--------------------------------------------------------------------------------
/docs/favicons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/favicon.ico
--------------------------------------------------------------------------------
/docs/favicons/pwa-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/pwa-192x192.png
--------------------------------------------------------------------------------
/docs/favicons/pwa-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/pwa-512x512.png
--------------------------------------------------------------------------------
/docs/favicons/tile150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/tile150x150.png
--------------------------------------------------------------------------------
/docs/favicons/tile310x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/tile310x150.png
--------------------------------------------------------------------------------
/docs/favicons/tile310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/tile310x310.png
--------------------------------------------------------------------------------
/docs/favicons/tile70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/favicons/tile70x70.png
--------------------------------------------------------------------------------
/docs/featured-background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/featured-background.jpg
--------------------------------------------------------------------------------
/docs/featured-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/featured-background.png
--------------------------------------------------------------------------------
/docs/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_1920x1080_fill_q75_catmullrom_top.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_1920x1080_fill_q75_catmullrom_top.jpg
--------------------------------------------------------------------------------
/docs/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_960x540_fill_q75_catmullrom_top.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/featured-background_hu376e1fbab6ce6c455a2b3aa5c258c0d9_496231_960x540_fill_q75_catmullrom_top.jpg
--------------------------------------------------------------------------------
/docs/featured-background_hu8a39ca4bb86027cf9971f48ddb45157c_1460964_1920x1080_fill_catmullrom_top_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/featured-background_hu8a39ca4bb86027cf9971f48ddb45157c_1460964_1920x1080_fill_catmullrom_top_2.png
--------------------------------------------------------------------------------
/docs/featured-background_hu8a39ca4bb86027cf9971f48ddb45157c_1460964_960x540_fill_catmullrom_top_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/featured-background_hu8a39ca4bb86027cf9971f48ddb45157c_1460964_960x540_fill_catmullrom_top_2.png
--------------------------------------------------------------------------------
/docs/js/main.min.2698ba6d60966a95b30f3160f89208b4219c5535421f52ee6147801ad45cc471.js:
--------------------------------------------------------------------------------
1 | (function($){'use strict';$(function(){$('[data-toggle="tooltip"]').tooltip();$('[data-toggle="popover"]').popover();$('.popover-dismiss').popover({trigger:'focus'})});function bottomPos(element){return element.offset().top+element.outerHeight();}
2 | $(function(){var promo=$(".js-td-cover");if(!promo.length){return}
3 | var promoOffset=bottomPos(promo);var navbarOffset=$('.js-navbar-scroll').offset().top;var threshold=Math.ceil($('.js-navbar-scroll').outerHeight());if((promoOffset-navbarOffset) ';a.href='#'+heading.id;heading.insertAdjacentElement('beforeend',a);heading.addEventListener('mouseenter',function(){a.style.visibility='initial';});heading.addEventListener('mouseleave',function(){a.style.visibility='hidden';});}});});}(jQuery));;(function($){'use strict';var Search={init:function(){$(document).ready(function(){$(document).on('keypress','.td-search-input',function(e){if(e.keyCode!==13){return}
6 | var query=$(this).val();var searchPage="https://aws-samples.github.io/amazon-sagemaker-examples-jp/search/?q="+query;document.location=searchPage;return false;});});},};Search.init();}(jQuery));;
--------------------------------------------------------------------------------
/docs/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
--------------------------------------------------------------------------------
/docs/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/text/comprehend/
7 | 2021-03-09T14:31:16+09:00
8 |
9 |
10 |
11 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/table-data/forecast/
12 | 2021-03-09T14:31:16+09:00
13 |
14 |
15 |
16 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/images/rekognition/
17 | 2021-03-08T17:41:31+09:00
18 |
19 |
20 |
21 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/voice/transcribe/
22 | 2021-03-09T14:31:16+09:00
23 |
24 |
25 |
26 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/images/
27 | 2021-03-08T11:24:33+09:00
28 |
29 |
30 |
31 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/usecases/table-data/
32 | 2021-03-04T13:20:16+09:00
33 |
34 |
35 |
36 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ml-services/sagemaker-tutorial/
37 | 2021-03-04T13:20:16+09:00
38 |
39 |
40 |
41 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/usecases/
42 | 2021-03-04T13:20:16+09:00
43 |
44 |
45 |
46 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/
47 | 2021-03-09T14:31:16+09:00
48 |
49 |
50 |
51 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/table-data/personalize/
52 | 2021-03-09T14:31:16+09:00
53 |
54 |
55 |
56 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/images/textract/
57 | 2021-03-08T19:18:54+09:00
58 |
59 |
60 |
61 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/text/translate/
62 | 2021-03-09T14:31:16+09:00
63 |
64 |
65 |
66 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/text/
67 | 2021-03-08T19:18:54+09:00
68 |
69 |
70 |
71 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/usecases/image/
72 | 2021-03-04T13:20:16+09:00
73 |
74 |
75 |
76 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/usecases/nlp/
77 | 2021-03-04T13:20:16+09:00
78 |
79 |
80 |
81 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ml-services/sagemaker-dive-deep/
82 | 2021-03-04T13:20:16+09:00
83 |
84 |
85 |
86 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/table-data/fraud/
87 | 2021-03-09T14:39:53+09:00
88 |
89 |
90 |
91 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/text/polly/
92 | 2021-03-09T14:31:16+09:00
93 |
94 |
95 |
96 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/table-data/
97 | 2021-03-08T19:18:54+09:00
98 |
99 |
100 |
101 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ml-services/
102 | 2021-03-04T13:20:16+09:00
103 |
104 |
105 |
106 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/ai-services/voice/
107 | 2021-03-08T19:18:54+09:00
108 |
109 |
110 |
111 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/docs/
112 | 2021-03-04T13:20:16+09:00
113 |
114 |
115 |
116 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/blog/news/
117 | 2021-02-06T20:24:17+09:00
118 |
119 |
120 |
121 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/blog/releases/
122 | 2021-02-06T20:24:17+09:00
123 |
124 |
125 |
126 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/blog/2018/10/06/easy-documentation-with-docsy/
127 | 2021-02-06T20:24:17+09:00
128 |
129 |
130 |
131 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/blog/2018/10/06/the-second-blog-post/
132 | 2021-02-06T20:24:17+09:00
133 |
134 |
135 |
136 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/blog/2018/01/04/another-great-release/
137 | 2021-02-06T20:24:17+09:00
138 |
139 |
140 |
141 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/about/
142 | 2021-02-06T20:24:17+09:00
143 |
144 |
145 |
146 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/
147 | 2021-03-08T11:24:33+09:00
148 |
149 |
150 |
151 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/blog/
152 | 2021-03-04T13:20:16+09:00
153 |
154 |
155 |
156 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/examples/
157 | 2021-03-04T13:20:16+09:00
158 |
159 |
160 |
161 | https://aws-samples.github.io/amazon-sagemaker-examples-jp/search/
162 | 2021-02-06T20:24:17+09:00
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/docs/webfonts/fa-brands-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-brands-400.eot
--------------------------------------------------------------------------------
/docs/webfonts/fa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-brands-400.ttf
--------------------------------------------------------------------------------
/docs/webfonts/fa-brands-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-brands-400.woff
--------------------------------------------------------------------------------
/docs/webfonts/fa-brands-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-brands-400.woff2
--------------------------------------------------------------------------------
/docs/webfonts/fa-regular-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-regular-400.eot
--------------------------------------------------------------------------------
/docs/webfonts/fa-regular-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-regular-400.ttf
--------------------------------------------------------------------------------
/docs/webfonts/fa-regular-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-regular-400.woff
--------------------------------------------------------------------------------
/docs/webfonts/fa-regular-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-regular-400.woff2
--------------------------------------------------------------------------------
/docs/webfonts/fa-solid-900.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-solid-900.eot
--------------------------------------------------------------------------------
/docs/webfonts/fa-solid-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-solid-900.ttf
--------------------------------------------------------------------------------
/docs/webfonts/fa-solid-900.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-solid-900.woff
--------------------------------------------------------------------------------
/docs/webfonts/fa-solid-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/docs/webfonts/fa-solid-900.woff2
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 | ec2-key-pair.pem
131 | *.npy
132 |
133 |
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/README.md:
--------------------------------------------------------------------------------
1 | # greengrass-ml-inference
2 | * 本コンテンツは AWS IoT Greengrass(v2) 上で動く ML 推論アプリを開発、デプロイするハンズオンです。
3 | * EC2 を 4 台、それぞれ開発機、ステージング機、本番機 2 台をエッジデバイスとして扱います。
4 | * ML モデルの作成は [build_mnist_dcgan_and_classifier.ipynb](./build_mnist_dcgan_and_classifier.ipynb) で行っていますが、モデル自体はこのリポジトリにすでに含まれているため改めて動かす必要はありません。
5 | * [greengrass_ml_inference.ipynb](greengrass_ml_inference.ipynb)ですべて動作が完結するように記載しているため、詳細は[greengrass_ml_inference.ipynb](greengrass_ml_inference.ipynb)をご参照ください。
6 | * notebook を実行する環境には下記ポリシーがアタッチされていることを前提としています。
7 | * AmazonEC2FullAccess
8 | * AmazonSSMFullAccess
9 | * AmazonS3FullAccess
10 | * IAMFullAccess
11 | * AWSGreengrassFullAccess
12 | * AWSIoTFullAccess
13 | * AmazonEC2ContainerRegistryFullAccess
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/AWS-Architecture-Icons-Deck_For-Dark-BG_20200911.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/AWS-Architecture-Icons-Deck_For-Dark-BG_20200911.pptx
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image01.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image02.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image03.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image04.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image05.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image06.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image07.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image08.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image09.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image10.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image11.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image12.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image13.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image14.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/image/image15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/image/image15.png
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/classifier_train.py:
--------------------------------------------------------------------------------
1 | import tensorflow as tf
2 | import numpy as np
3 | import os
4 | from keras.models import Model,Sequential,load_model
5 | from keras.layers import Input,Conv2D,LeakyReLU,Dense,Reshape,Flatten,Dropout,BatchNormalization,Conv2DTranspose,MaxPool2D
6 | from keras.activations import sigmoid
7 | from keras.datasets import fashion_mnist
8 | from keras.optimizers import Adam
9 | import argparse, json
10 | from distutils.util import strtobool
11 |
12 | MODEL_FILE_NAME = 'classifier.h5'
13 |
14 | def classifier():
15 | inputs = Input(shape=(28,28,1))
16 | x = Conv2D(64, (3,3),padding='same')(inputs)
17 | x = BatchNormalization()(x)
18 | x = LeakyReLU(0.2)(x)
19 | x = MaxPool2D(pool_size=(2, 2))(x) # 14x14
20 | x = Conv2D(64, (3,3),padding='same')(x)
21 | x = BatchNormalization()(x)
22 | x = LeakyReLU(0.2)(x)
23 | x = MaxPool2D(pool_size=(2, 2))(x) # 7x7
24 | x = Conv2D(128, (3,3),padding='same')(x)
25 | x = BatchNormalization()(x)
26 | x = LeakyReLU(0.2)(x)
27 | x = MaxPool2D(pool_size=(2, 2))(x)
28 | x = Conv2D(128, (3,3),padding='same')(x)
29 | x = BatchNormalization()(x)
30 | x = LeakyReLU(0.2)(x)
31 | x = MaxPool2D(pool_size=(2, 2))(x)
32 | x = Flatten()(x)
33 | x = Dense(128)(x)
34 | x = LeakyReLU(0.2)(x)
35 | x = BatchNormalization()(x)
36 | x = Dropout(0.5)(x)
37 | x = Dense(10, activation='softmax')(x)
38 | model = Model(inputs=inputs, outputs=x)
39 | model.summary()
40 | return model
41 |
42 | def train(train_x,train_y,valid_x,valid_y,epochs,model_dir,increment,base_dir):
43 | if increment:
44 | model = load_model(os.path.join(base_dir, MODEL_FILE_NAME))
45 | else:
46 | model = classifier()
47 | model.compile(optimizer=Adam(lr=0.0001),metrics=['accuracy'],loss="categorical_crossentropy")
48 | model.fit(train_x,train_y,batch_size=16,epochs=epochs,validation_data=(valid_x,valid_y))
49 |
50 | save_model_path = os.path.join(model_dir, MODEL_FILE_NAME)
51 | model.save(save_model_path)
52 |
53 | return model
54 |
55 | def _parse_args():
56 | parser = argparse.ArgumentParser()
57 | parser.add_argument('--model_dir', type=str)
58 | parser.add_argument('--sm-model-dir', type=str, default=os.environ.get('SM_MODEL_DIR'))
59 | parser.add_argument('--train', type=str, default=os.environ.get('SM_CHANNEL_TRAIN'))
60 | parser.add_argument('--hosts', type=list, default=json.loads(os.environ.get('SM_HOSTS')))
61 | parser.add_argument('--current-host', type=str, default=os.environ.get('SM_CURRENT_HOST'))
62 | parser.add_argument('--epochs', type=int, default=2)
63 | parser.add_argument('--increment', type=strtobool ,default=False)
64 |
65 | return parser.parse_known_args()
66 |
67 | def load_training_data(base_dir):
68 | X = np.load(os.path.join(base_dir, 'train_X.npy'))
69 | y = np.load(os.path.join(base_dir, 'train_y.npy'))
70 | # shuffle and split
71 | shuffle_index = np.random.choice(np.arange(X.shape[0]), X.shape[0], replace=False)
72 | train_X = X[shuffle_index[0:50000]]
73 | train_y = y[shuffle_index[0:50000]]
74 | valid_X = X[shuffle_index[50000:]]
75 | valid_y = y[shuffle_index[50000:]]
76 |
77 | return train_X, train_y, valid_X, valid_y
78 |
79 | if __name__ == "__main__":
80 | args, unknown = _parse_args()
81 | print(args)
82 | train_X, train_y, valid_X, valid_y = load_training_data(args.train)
83 | model = train(train_X, train_y, valid_X, valid_y,args.epochs,args.sm_model_dir,args.increment,args.train)
84 |
85 | exit()
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.0/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8.10-slim-buster
2 |
3 | RUN apt-get update; \
4 | apt-get install -y cmake \
5 | ; \
6 | rm -rf /var/lib/apt/lists/*
7 |
8 | RUN python3 -m pip install awsiotsdk numpy tensorflow-cpu==2.4.1 Pillow
9 | WORKDIR /app
10 |
11 | COPY ./IoTPublisher.py /app/IoTPublisher.py
12 | COPY ./test_X.npy /app/test_X.npy
13 | COPY ./classifier.h5 /app/classifier.h5
14 |
15 | CMD ["python3", "/app/IoTPublisher.py"]
16 |
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.0/IoTPublisher.py:
--------------------------------------------------------------------------------
1 | from time import sleep
2 | import datetime,json
3 | from awsiot.greengrasscoreipc import connect
4 | from awsiot.greengrasscoreipc.model import (
5 | QOS,
6 | PublishToIoTCoreRequest
7 | )
8 | import tensorflow as tf
9 | from PIL import Image
10 | import os, sys
11 | import numpy as np
12 | import signal
13 | from logging import getLogger
14 | logger = getLogger(__name__)
15 |
16 | os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
17 |
18 | TIMEOUT = 10
19 | INTERVAL = 60
20 |
21 | ipc_client = connect()
22 |
23 | test_X = np.load('/app/test_X.npy')
24 |
25 | classifier_model = tf.keras.models.load_model('/app/classifier.h5')
26 |
27 | topic = "inference/result"
28 |
29 | def signal_handler(signal, frame):
30 | logger.info(f"Received {signal}, exiting")
31 | sys.exit(0)
32 |
33 | # Register SIGTERM for shutdown of container
34 | signal.signal(signal.SIGTERM, signal_handler)
35 | signal.signal(signal.SIGINT, signal_handler)
36 |
37 | cnt = 0
38 | while True:
39 |
40 | idx = np.random.randint(0,test_X.shape[0])
41 | img_array = test_X[idx:idx+1,:,:,:]
42 |
43 | pred_y = np.argmax(classifier_model.predict(img_array))
44 |
45 | result = 'anomaly' if pred_y % 2 == 0 else 'normal'
46 |
47 | cnt = cnt + 1
48 | message = {
49 | "timestamp": str(datetime.datetime.now()),
50 | "message": result,
51 | "counter": str(cnt),
52 | "component_version" : "1.0.0"
53 | }
54 |
55 | request = PublishToIoTCoreRequest(topic_name=topic, qos=QOS.AT_LEAST_ONCE, payload=bytes(json.dumps(message), "utf-8"))
56 | operation = ipc_client.new_publish_to_iot_core()
57 | operation.activate(request)
58 | future = operation.get_response()
59 | future.result(TIMEOUT)
60 |
61 | logger.info("publish")
62 | sleep(INTERVAL)
63 |
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8.10-slim-buster
2 |
3 | RUN apt-get update; \
4 | apt-get install -y cmake traceroute\
5 | ; \
6 | rm -rf /var/lib/apt/lists/*
7 |
8 | RUN python3 -m pip install awsiotsdk numpy dlr Pillow
9 | WORKDIR /app
10 |
11 | COPY ./IoTPublisher.py /app/IoTPublisher.py
12 | COPY ./test_X.npy /app/test_X.npy
13 | COPY ./classifier/ /app/classifier/
14 |
15 | CMD ["python3", "/app/IoTPublisher.py"]
16 |
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/IoTPublisher.py:
--------------------------------------------------------------------------------
1 | from time import sleep
2 | import dlr, datetime, json, os, sys, signal
3 | from awsiot.greengrasscoreipc import connect
4 | from awsiot.greengrasscoreipc.model import (
5 | QOS,
6 | PublishToIoTCoreRequest
7 | )
8 | import numpy as np
9 | from logging import getLogger
10 | logger = getLogger(__name__)
11 |
12 | os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
13 |
14 | # メッセージに thing_name を入れるために thing_name を環境変数から取得する
15 | THING_NAME = os.environ.get('AWS_IOT_THING_NAME')
16 |
17 | TIMEOUT = 10
18 |
19 | ipc_client = connect()
20 |
21 | INTERVAL = 60
22 |
23 | neo_dir = '/app/classifier'
24 | classifier_neo = dlr.DLRModel(neo_dir, 'cpu', 0)
25 |
26 | test_X = np.load('/app/test_X.npy')
27 |
28 | topic = "inference/result"
29 |
30 | def signal_handler(signal, frame):
31 | logger.info(f"Received {signal}, exiting")
32 | sys.exit(0)
33 |
34 | # Register SIGTERM for shutdown of container
35 | signal.signal(signal.SIGTERM, signal_handler)
36 | signal.signal(signal.SIGINT, signal_handler)
37 |
38 | cnt = 0
39 | while True:
40 | idx = np.random.randint(0,test_X.shape[0])
41 | img_array = test_X[idx:idx+1,:,:,:]
42 |
43 | pred_y = np.argmax(classifier_neo.run(test_X[0,:,:,:].reshape(1,1,28,28))[0])
44 |
45 | result = 'anomaly' if pred_y % 2 == 0 else 'normal'
46 |
47 | cnt = cnt + 1
48 | message = {
49 | "timestamp": str(datetime.datetime.now()),
50 | "message": result,
51 | "counter": str(cnt),
52 | "component_version" : "1.0.1",
53 | "thing_name" : THING_NAME
54 | }
55 |
56 | request = PublishToIoTCoreRequest(topic_name=topic, qos=QOS.AT_LEAST_ONCE, payload=bytes(json.dumps(message), "utf-8"))
57 | operation = ipc_client.new_publish_to_iot_core()
58 | operation.activate(request)
59 | future = operation.get_response()
60 | future.result(TIMEOUT)
61 |
62 | logger.info("publish")
63 | sleep(INTERVAL)
64 |
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/classifier/compiled.meta:
--------------------------------------------------------------------------------
1 | {
2 | "Requirements": {
3 | "TargetDevice": "ML_C5",
4 | "TargetDeviceType": "cpu"
5 | },
6 | "Compilation": {
7 | "CreatedTime": 1628746271.076939
8 | },
9 | "Model": {
10 | "Inputs": [
11 | {
12 | "name": "input_1",
13 | "shape": [
14 | 1,
15 | 1,
16 | 28,
17 | 28
18 | ],
19 | "dtype": "float32"
20 | }
21 | ],
22 | "Outputs": [
23 | {
24 | "dtype": "float32",
25 | "shape": [
26 | 1,
27 | 10
28 | ],
29 | "name": "output_0"
30 | }
31 | ]
32 | }
33 | }
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/classifier/compiled.params:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/classifier/compiled.params
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/classifier/compiled.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/classifier/compiled.so
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/classifier/libdlr.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/classifier/libdlr.so
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.IoTPublisher/1.0.1/classifier/manifest:
--------------------------------------------------------------------------------
1 | {"algorithm": "blake2s", "files": [{"name": "compiled.meta", "hash": "e41fb375831ba8663cf904fefa79af3bd2572c252ba68cb108366ccf17ce176d"}, {"name": "compiled.params", "hash": "a64bce4a955cd89a6e930c76f7e86c996a91605d12dd37c7e85ed4e4b72b4efd"}, {"name": "compiled.so", "hash": "22118fffbddc22059cbb5f343267ab130ef0d89d31fe07c5b691748b5eef724a"}, {"name": "compiled_model.json", "hash": "303da711e43da5a46afc86b8b906dd94211c500dd054dcd44d069b6ce29f295a"}, {"name": "dlr.h", "hash": "32244b9d4939516f5fcb29d01569f6040320174f220a2fa40f96210ad7cc8ec0"}, {"name": "libdlr.so", "hash": "291cb1f05749cc203bdebb03eb06a4d904780791c6c9f5ded6c6f2a21f9eda3e"}]}
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.Publisher/1.0.0/publisher.py:
--------------------------------------------------------------------------------
1 | from time import sleep
2 | import datetime,json
3 | import awsiot.greengrasscoreipc
4 | from awsiot.greengrasscoreipc.model import (
5 | PublishToTopicRequest,
6 | PublishMessage,
7 | JsonMessage
8 | )
9 | from PIL import Image
10 | import os, sys
11 | import numpy as np
12 | from logging import getLogger
13 | logger = getLogger(__name__)
14 |
15 | os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
16 |
17 | logger.info(f'argv:{sys.argv}')
18 |
19 | test_X_path = os.path.join(sys.argv[1],'test_X.npy')
20 | test_X = np.load(test_X_path)
21 |
22 | logger.info('start publisher...')
23 |
24 | TIMEOUT = 10
25 | interval = 60
26 |
27 | ipc_client = awsiot.greengrasscoreipc.connect()
28 |
29 | topic = "my/topic"
30 |
31 | logger.info('start loop')
32 |
33 | while True:
34 | # generate and save image file
35 | idx = np.random.randint(0,test_X.shape[0])
36 | file_name = '/tmp/' + datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=9))).strftime('%Y%m%d%H%M%S') + '.png'
37 | Image.fromarray(((test_X[idx,:,:,0]*127.5)+127.5).astype(np.uint8)).save(file_name)
38 |
39 | message = {"file_name": file_name }
40 | message_json = json.dumps(message).encode('utf-8')
41 |
42 | request = PublishToTopicRequest()
43 | request.topic = topic
44 | publish_message = PublishMessage()
45 | publish_message.json_message = JsonMessage()
46 | publish_message.json_message.message = message
47 | request.publish_message = publish_message
48 | operation = ipc_client.new_publish_to_topic()
49 | operation.activate(request)
50 | future = operation.get_response()
51 | future.result(TIMEOUT)
52 |
53 | logger.info(f'publish message: {message_json}')
54 | sleep(interval)
55 |
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.Subscriber/1.0.0/classifier.h5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.Subscriber/1.0.0/classifier.h5
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/artifacts/com.example.Subscriber/1.0.0/subscriber.py:
--------------------------------------------------------------------------------
1 | import time, json, sys, os
2 | import awsiot.greengrasscoreipc
3 | import awsiot.greengrasscoreipc.client as client
4 | from awsiot.greengrasscoreipc.model import (
5 | SubscribeToTopicRequest,
6 | SubscriptionResponseMessage
7 | )
8 | import tensorflow as tf
9 | import numpy as np
10 | from PIL import Image
11 | from logging import getLogger
12 | logger = getLogger(__name__)
13 |
14 | os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
15 |
16 | logger.info(f'argv:{sys.argv}')
17 |
18 | model_path = os.path.join(sys.argv[1],'classifier.h5')
19 |
20 | logger.info('start subscriber...')
21 |
22 | TIMEOUT = 10
23 |
24 | logger.info('start to load model')
25 | model = tf.keras.models.load_model(model_path)
26 |
27 | ipc_client = awsiot.greengrasscoreipc.connect()
28 |
29 | class StreamHandler(client.SubscribeToTopicStreamHandler):
30 | def __init__(self):
31 | super().__init__()
32 |
33 | def on_stream_event(self, event: SubscriptionResponseMessage) -> None:
34 | message_string = event.json_message.message
35 | file_path = message_string['file_name']
36 | logger.info(f'recieved message: {file_path}')
37 | img = Image.open(file_path)
38 | img = (np.array(img).reshape(1,28,28,1)-127.5)/127.5
39 | pred_y = np.argmax(model.predict(img))
40 | with open('/tmp/Greengrass_Subscriber.log', 'a') as f:
41 | f.write(f'{file_path}\n')
42 | f.write(f'{img.shape}\n')
43 | f.write(f'{pred_y}\n')
44 | f.write('even\n') if pred_y % 2 == 0 else f.write('odd\n')
45 | # 処理済ファイルを削除
46 | os.remove(file_path)
47 |
48 | def on_stream_error(self, error: Exception) -> bool:
49 | return True
50 |
51 | def on_stream_closed(self) -> None:
52 | pass
53 |
54 | topic = "my/topic"
55 |
56 | request = SubscribeToTopicRequest()
57 | request.topic = topic
58 | handler = StreamHandler()
59 | operation = ipc_client.new_subscribe_to_topic(handler)
60 | future = operation.activate(request)
61 | while True:
62 | time.sleep(1)
63 |
64 | operation.close()
65 |
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/recipes/com.example.Publisher-1.0.0.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | RecipeFormatVersion: '2020-01-25'
3 | ComponentName: com.example.Publisher
4 | ComponentVersion: '1.0.0'
5 | ComponentDescription: A component that publishes messages.
6 | ComponentPublisher: Amazon
7 | ComponentConfiguration:
8 | DefaultConfiguration:
9 | accessControl:
10 | aws.greengrass.ipc.pubsub:
11 | 'com.example.Publisher:pubsub:1':
12 | policyDescription: Allows access to publish to all topics.
13 | operations:
14 | - 'aws.greengrass#PublishToTopic'
15 | resources:
16 | - '*'
17 | Manifests:
18 | - Lifecycle:
19 | Install:
20 | Timeout: 600
21 | Script: python3 -m pip install pip & pip3 install awsiotsdk numpy Pillow -U
22 | Run: python3 {artifacts:path}/publisher.py {artifacts:path}
23 |
--------------------------------------------------------------------------------
/edge_inference/greengrass-ml-inference/src/ggv2/components/recipes/com.example.Subscriber-1.0.0.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | RecipeFormatVersion: '2020-01-25'
3 | ComponentName: com.example.Subscriber
4 | ComponentVersion: '1.0.0'
5 | ComponentDescription: A component that subscribes to messages.
6 | ComponentPublisher: Amazon
7 | ComponentConfiguration:
8 | DefaultConfiguration:
9 | accessControl:
10 | aws.greengrass.ipc.pubsub:
11 | 'com.example.Subscriber:pubsub:1':
12 | policyDescription: Allows access to publish to all topics.
13 | operations:
14 | - 'aws.greengrass#SubscribeToTopic'
15 | resources:
16 | - '*'
17 | Manifests:
18 | - Lifecycle:
19 | Install:
20 | Timeout: 600
21 | Script: python3 -m pip install pip & pip3 install awsiotsdk numpy tensorflow-cpu==2.4.1 Pillow -U
22 | Run: python3 {artifacts:path}/subscriber.py {artifacts:path}
23 |
--------------------------------------------------------------------------------
/hpo_pytorch_mnist/mnist.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import json
3 | import logging
4 | import os
5 | import sys
6 | import torch
7 | import torch.distributed as dist
8 | import torch.nn as nn
9 | import torch.nn.functional as F
10 | import torch.optim as optim
11 | import torch.utils.data
12 | import torch.utils.data.distributed
13 | from torchvision import datasets, transforms
14 |
15 | logger = logging.getLogger(__name__)
16 | logger.setLevel(logging.DEBUG)
17 | logger.addHandler(logging.StreamHandler(sys.stdout))
18 |
19 |
20 | # Based on https://github.com/pytorch/examples/blob/master/mnist/main.py
21 | class Net(nn.Module):
22 | def __init__(self):
23 | super(Net, self).__init__()
24 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
25 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
26 | self.conv2_drop = nn.Dropout2d()
27 | self.fc1 = nn.Linear(320, 50)
28 | self.fc2 = nn.Linear(50, 10)
29 |
30 | def forward(self, x):
31 | x = F.relu(F.max_pool2d(self.conv1(x), 2))
32 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
33 | x = x.view(-1, 320)
34 | x = F.relu(self.fc1(x))
35 | x = F.dropout(x, training=self.training)
36 | x = self.fc2(x)
37 | return F.log_softmax(x, dim=1)
38 |
39 | def _get_train_data_loader(batch_size, training_dir, is_distributed, **kwargs):
40 | logger.info("Get train data loader")
41 | train_tensor = torch.load(os.path.join(training_dir, 'training.pt'))
42 | dataset = torch.utils.data.TensorDataset(train_tensor[0], train_tensor[1])
43 |
44 | train_sampler = torch.utils.data.distributed.DistributedSampler(dataset) if is_distributed else None
45 | return torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=train_sampler is None,
46 | sampler=train_sampler, **kwargs)
47 |
48 | def _get_test_data_loader(test_batch_size, training_dir, **kwargs):
49 | logger.info("Get test data loader")
50 | test_tensor = torch.load(os.path.join(training_dir, 'test.pt'))
51 | dataset = torch.utils.data.TensorDataset(test_tensor[0], test_tensor[1])
52 | return torch.utils.data.DataLoader(
53 | dataset,
54 | batch_size=test_batch_size,
55 | shuffle=True, **kwargs)
56 |
57 |
58 | def _average_gradients(model):
59 | # Gradient averaging.
60 | size = float(dist.get_world_size())
61 | for param in model.parameters():
62 | dist.all_reduce(param.grad.data, op=dist.reduce_op.SUM)
63 | param.grad.data /= size
64 |
65 |
66 | def train(args):
67 | is_distributed = len(args.hosts) > 1 and args.backend is not None
68 | logger.debug("Distributed training - {}".format(is_distributed))
69 | use_cuda = args.num_gpus > 0
70 | logger.debug("Number of gpus available - {}".format(args.num_gpus))
71 | kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
72 | device = torch.device("cuda" if use_cuda else "cpu")
73 |
74 | if is_distributed:
75 | # Initialize the distributed environment.
76 | world_size = len(args.hosts)
77 | os.environ['WORLD_SIZE'] = str(world_size)
78 | host_rank = args.hosts.index(args.current_host)
79 | os.environ['RANK'] = str(host_rank)
80 | dist.init_process_group(backend=args.backend, rank=host_rank, world_size=world_size)
81 | logger.info('Initialized the distributed environment: \'{}\' backend on {} nodes. '.format(
82 | args.backend, dist.get_world_size()) + 'Current host rank is {}. Number of gpus: {}'.format(
83 | dist.get_rank(), args.num_gpus))
84 |
85 | # set the seed for generating random numbers
86 | torch.manual_seed(args.seed)
87 | if use_cuda:
88 | torch.cuda.manual_seed(args.seed)
89 |
90 | train_loader = _get_train_data_loader(args.batch_size, args.data_dir, is_distributed, **kwargs)
91 | test_loader = _get_test_data_loader(args.test_batch_size, args.data_dir, **kwargs)
92 |
93 | logger.debug("Processes {}/{} ({:.0f}%) of train data".format(
94 | len(train_loader.sampler), len(train_loader.dataset),
95 | 100. * len(train_loader.sampler) / len(train_loader.dataset)
96 | ))
97 |
98 | logger.debug("Processes {}/{} ({:.0f}%) of test data".format(
99 | len(test_loader.sampler), len(test_loader.dataset),
100 | 100. * len(test_loader.sampler) / len(test_loader.dataset)
101 | ))
102 |
103 | model = Net().to(device)
104 | if is_distributed and use_cuda:
105 | # multi-machine multi-gpu case
106 | model = torch.nn.parallel.DistributedDataParallel(model)
107 | else:
108 | # single-machine multi-gpu case or single-machine or multi-machine cpu case
109 | model = torch.nn.DataParallel(model)
110 |
111 | optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)
112 |
113 | for epoch in range(1, args.epochs + 1):
114 | model.train()
115 | for batch_idx, (data, target) in enumerate(train_loader, 1):
116 | data, target = data.to(device), target.to(device)
117 | optimizer.zero_grad()
118 | output = model(data)
119 | loss = F.nll_loss(output, target)
120 | loss.backward()
121 | if is_distributed and not use_cuda:
122 | # average gradients manually for multi-machine cpu case only
123 | _average_gradients(model)
124 | optimizer.step()
125 | if batch_idx % args.log_interval == 0:
126 | logger.info('Train Epoch: {} [{}/{} ({:.0f}%)] Loss: {:.6f}'.format(
127 | epoch, batch_idx * len(data), len(train_loader.sampler),
128 | 100. * batch_idx / len(train_loader), loss.item()))
129 | test(model, test_loader, device)
130 | save_model(model, args.model_dir)
131 |
132 |
133 | def test(model, test_loader, device):
134 | model.eval()
135 | test_loss = 0
136 | correct = 0
137 | with torch.no_grad():
138 | for data, target in test_loader:
139 | data, target = data.to(device), target.to(device)
140 | output = model(data)
141 | test_loss += F.nll_loss(output, target, size_average=False).item() # sum up batch loss
142 | pred = output.max(1, keepdim=True)[1] # get the index of the max log-probability
143 | correct += pred.eq(target.view_as(pred)).sum().item()
144 |
145 | test_loss /= len(test_loader.dataset)
146 | logger.info('Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
147 | test_loss, correct, len(test_loader.dataset),
148 | 100. * correct / len(test_loader.dataset)))
149 |
150 |
151 | def model_fn(model_dir):
152 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
153 | model = torch.nn.DataParallel(Net())
154 | with open(os.path.join(model_dir, 'model.pth'), 'rb') as f:
155 | model.load_state_dict(torch.load(f))
156 | return model.to(device)
157 |
158 |
159 | def save_model(model, model_dir):
160 | logger.info("Saving the model.")
161 | path = os.path.join(model_dir, 'model.pth')
162 | # recommended way from http://pytorch.org/docs/master/notes/serialization.html
163 | torch.save(model.cpu().state_dict(), path)
164 |
165 |
166 | if __name__ == '__main__':
167 | parser = argparse.ArgumentParser()
168 |
169 | # Data and model checkpoints directories
170 | parser.add_argument('--batch-size', type=int, default=64, metavar='N',
171 | help='input batch size for training (default: 64)')
172 | parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N',
173 | help='input batch size for testing (default: 1000)')
174 | parser.add_argument('--epochs', type=int, default=10, metavar='N',
175 | help='number of epochs to train (default: 10)')
176 | parser.add_argument('--lr', type=float, default=0.01, metavar='LR',
177 | help='learning rate (default: 0.01)')
178 | parser.add_argument('--momentum', type=float, default=0.5, metavar='M',
179 | help='SGD momentum (default: 0.5)')
180 | parser.add_argument('--seed', type=int, default=1, metavar='S',
181 | help='random seed (default: 1)')
182 | parser.add_argument('--log-interval', type=int, default=100, metavar='N',
183 | help='how many batches to wait before logging training status')
184 | parser.add_argument('--backend', type=str, default=None,
185 | help='backend for distributed training (tcp, gloo on cpu and gloo, nccl on gpu)')
186 |
187 | # Container environment
188 | parser.add_argument('--hosts', type=list, default=json.loads(os.environ['SM_HOSTS']))
189 | parser.add_argument('--current-host', type=str, default=os.environ['SM_CURRENT_HOST'])
190 | parser.add_argument('--model-dir', type=str, default=os.environ['SM_MODEL_DIR'])
191 | parser.add_argument('--data-dir', type=str, default=os.environ['SM_CHANNEL_TRAINING'])
192 | parser.add_argument('--num-gpus', type=int, default=os.environ['SM_NUM_GPUS'])
193 |
194 | train(parser.parse_args())
195 |
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 |
132 | DKD2e_data_sets.zip
133 | Data sets/*
134 | raw_data/*
135 |
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/README.md:
--------------------------------------------------------------------------------
1 | # sagemaker-pipelines-sample
2 |
3 | ※ SageMaker **Studio** Notebook を前提としており、カーネルは Python3(Data Science) をご利用ください。
4 | ※ confirms this notebook works under data science kernel on SageMaker **Studio** notebook
5 |
6 | SageMaker Pipelines のサンプルコードです。
7 | [sagemaker-pipelines-sample.ipynb](./sagemaker-pipelines-sample.ipynb)を開いてご利用ください。
8 |
9 | SageMaker Pipelines の一通りの機能を利用することができます。
10 |
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/1.png
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/2.png
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/3.png
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/4.png
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/5.png
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/6.png
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/media/7.png
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/postprocess/postprocess.py:
--------------------------------------------------------------------------------
1 | import json, pickle, tarfile, os, argparse
2 | import numpy as np
3 | import xgboost
4 |
5 | from sklearn.metrics import roc_auc_score
6 |
7 | def arg_parse():
8 | parser = argparse.ArgumentParser()
9 | parser.add_argument('--thistime-train-model-dir', type=str, default=None)
10 | parser.add_argument('--lasttime-train-model-dir', type=str, default=None)
11 | parser.add_argument('--input-data-dir', type=str, default=None)
12 | parser.add_argument('--output-dir', type=str, default=None)
13 | parser.add_argument('--output-file', type=str, default='evaluation.json')
14 |
15 | args, _ = parser.parse_known_args()
16 | return args
17 |
18 | def predict(input_model_dir:str, test_x):
19 | model_path = os.path.join(input_model_dir, 'model.tar.gz')
20 | with tarfile.open(model_path) as tar:
21 |
22 | def is_within_directory(directory, target):
23 |
24 | abs_directory = os.path.abspath(directory)
25 | abs_target = os.path.abspath(target)
26 |
27 | prefix = os.path.commonprefix([abs_directory, abs_target])
28 |
29 | return prefix == abs_directory
30 |
31 | def safe_extract(tar, path=".", members=None, *, numeric_owner=False):
32 |
33 | for member in tar.getmembers():
34 | member_path = os.path.join(path, member.name)
35 | if not is_within_directory(path, member_path):
36 | raise Exception("Attempted Path Traversal in Tar File")
37 |
38 | tar.extractall(path, members, numeric_owner=numeric_owner)
39 |
40 |
41 | safe_extract(tar, path=".")
42 | model = pickle.load(open("xgboost-model", "rb"))
43 | pred_y = model.predict(test_x)
44 | return pred_y
45 |
46 | if __name__ == "__main__":
47 | args = arg_parse()
48 |
49 | test_csv_path = os.path.join(args.input_data_dir,'test.csv')
50 | test = np.loadtxt(test_csv_path, delimiter=',')
51 | test_x = xgboost.DMatrix(test[:,1:])
52 | answer_y = test[:,0]
53 |
54 | thistime_train_model_pred_y = predict(args.thistime_train_model_dir, test_x)
55 | lasttime_train_model_pred_y = predict(args.lasttime_train_model_dir, test_x)
56 |
57 | thistime_train_model_auc = roc_auc_score(answer_y,thistime_train_model_pred_y)
58 | lasttime_train_model_auc = roc_auc_score(answer_y,lasttime_train_model_pred_y)
59 |
60 |
61 | report_dict = {
62 | 'classification_metrics': {
63 | 'thistime_train_model_auc': {
64 | 'value': thistime_train_model_auc,
65 | },
66 | 'lasttime_train_model_auc': {
67 | 'value': lasttime_train_model_auc,
68 | },
69 | 'model_change':1 if thistime_train_model_auc > lasttime_train_model_auc else 0
70 | },
71 | 'detail_result':{
72 | 'thistime_train_model_pred_y': thistime_train_model_pred_y.tolist(),
73 | 'lasttime_train_model_pred_y': lasttime_train_model_pred_y.tolist(),
74 | 'answer_y': answer_y.tolist()
75 | }
76 | }
77 | print(report_dict)
78 |
79 | eval_result_path = os.path.join(args.output_dir, args.output_file)
80 | print(f'output save : {eval_result_path}')
81 | with open(eval_result_path, "w") as f:
82 | f.write(json.dumps(report_dict))
83 | print('post process done.')
84 | exit()
85 |
--------------------------------------------------------------------------------
/mlops/sagemaker-pipelines/sagemaker-pipelines-sample/preprocess/preprocess.py:
--------------------------------------------------------------------------------
1 | # churn データの前処理スクリプト
2 | # 前処理内容は下記と同じ
3 | # https://github.com/aws-samples/amazon-sagemaker-examples-jp/blob/master/xgboost_customer_churn/xgboost_customer_churn.ipynb
4 | # State, Area Code, VMail Plan などをダミー変数化するところは、全ての週が分けたデータに入っているか不透明だったため、ハードコーディングでダミー変数化する
5 |
6 | import pandas as pd
7 | import numpy as np
8 | import argparse
9 | from sklearn.model_selection import train_test_split
10 | import os
11 | from glob import glob
12 |
13 | def arg_parse():
14 | parser = argparse.ArgumentParser()
15 | parser.add_argument('--raw-data-input-dir', type=str, default=None)
16 | parser.add_argument('--pre-processed-train-data-input-dir', type=str, default=None)
17 | parser.add_argument('--pre-processed-valid-data-input-dir', type=str, default=None)
18 | parser.add_argument('--pre-processed-test-data-input-dir', type=str, default=None)
19 | parser.add_argument('--train-output-dir', type=str, default=None)
20 | parser.add_argument('--valid-output-dir', type=str, default=None)
21 | parser.add_argument('--test-output-dir', type=str, default=None)
22 | parser.add_argument('--merge' , action='store_true')
23 | args, _ = parser.parse_known_args()
24 | return args
25 |
26 | if __name__=='__main__':
27 | args = arg_parse()
28 | # csv ファイルの読み込み
29 | # 複数ファイルが raw_input_dir に配置されたら全て縦に concat する
30 | df_list = []
31 | for csv_file in glob(args.raw_data_input_dir+'/*.csv'):
32 | tmp_df = pd.read_csv(csv_file)
33 | df_list.append(tmp_df)
34 | df = pd.concat(df_list,axis=0)
35 |
36 | # 不要カラムの除去
37 | df = df.drop(['Phone','Day Charge', 'Eve Charge', 'Night Charge', 'Intl Charge'], axis=1)
38 |
39 | # Area Code のダミー変数化
40 | df['Area Code'] = df['Area Code'].astype(object)
41 | area_code_list = ['415', '408', '510']
42 | for area_code in area_code_list:
43 | df[area_code] = df['Area Code'].map(lambda x: 1 if x==area_code else 0)
44 | df = df.drop(['Area Code'],axis=1)
45 |
46 | # State のダミー変数化
47 | states_list = ['KS', 'OH', 'NJ', 'OK', 'AL', 'MA', 'MO', 'LA', 'WV', 'IN', 'RI', 'IA', 'MT', 'NY', 'ID', 'VT', 'VA', 'TX', 'FL', 'CO', 'AZ', 'SC', 'NE', 'WY', 'HI', 'IL', 'NH', 'GA', 'AK', 'MD', 'AR', 'WI', 'OR', 'MI', 'DE', 'UT', 'CA', 'MN', 'SD', 'NC', 'WA', 'NM', 'NV', 'DC', 'KY', 'ME', 'MS', 'TN', 'PA', 'CT', 'ND']
48 | for state in states_list:
49 | df[state] = df['State'].map(lambda x: 1 if x==state else 0)
50 | df = df.drop(['State'],axis=1)
51 |
52 | # Int'l Plan のダミー変数化
53 | intl_plan_list = ['yes','no']
54 | for intl_plan in intl_plan_list:
55 | df[f'intl_plan{intl_plan}'] = df["Int'l Plan"].map(lambda x: 1 if x==intl_plan else 0)
56 | df = df.drop(["Int'l Plan"],axis=1)
57 |
58 | # Vmail Plan のダミー変数化
59 | vmail_plan_list = ['yes','no']
60 | for vmail_plan in vmail_plan_list:
61 | df[f'vmail_plan{vmail_plan}'] = df["VMail Plan"].map(lambda x: 1 if x==vmail_plan else 0)
62 | df = df.drop(["VMail Plan"],axis=1)
63 |
64 | # churn? の 1/0 化 (xgboost のデータ入力仕様)
65 | df['y'] = df['Churn?'].map(lambda x: 1 if x=='True.' else 0)
66 | df = df.drop(['Churn?'], axis=1)
67 |
68 | # 予測したいカラムを最初に持ってくる (xgboost のデータ入力仕様)
69 | df = pd.concat([df.iloc[:,-1],df.iloc[:,:-1]],axis=1)
70 | train_df, valid_df, test_df = np.split(df.sample(frac=1, random_state=42), [int(0.7 * len(df)), int(0.9 * len(df))])
71 |
72 | # 過去の前処理済データをマージ
73 | if args.merge:
74 | # train
75 | lasttime_train_input_path = os.path.join(args.pre_processed_train_data_input_dir, 'train.csv')
76 | lasttime_train_df = pd.read_csv(lasttime_train_input_path, header=None, names=df.columns.tolist())
77 | train_df = pd.concat([train_df,lasttime_train_df],axis=0)
78 | # valid
79 | lasttime_valid_input_path = os.path.join(args.pre_processed_valid_data_input_dir, 'valid.csv')
80 | lasttime_valid_df = pd.read_csv(lasttime_valid_input_path, header=None, names=df.columns.tolist())
81 | valid_df = pd.concat([valid_df,lasttime_valid_df],axis=0)
82 | # test
83 | lasttime_test_input_path = os.path.join(args.pre_processed_test_data_input_dir, 'test.csv')
84 | lasttime_test_df = pd.read_csv(lasttime_test_input_path, header=None, names=df.columns.tolist())
85 | test_df = pd.concat([test_df,lasttime_test_df],axis=0)
86 |
87 | train_output_path = os.path.join(args.train_output_dir, 'train.csv')
88 | valid_output_path = os.path.join(args.valid_output_dir, 'valid.csv')
89 | test_output_path = os.path.join(args.test_output_dir, 'test.csv')
90 |
91 | train_df.to_csv(train_output_path, header=False, index=False)
92 | valid_df.to_csv(valid_output_path, header=False, index=False)
93 | test_df.to_csv(test_output_path, header=False, index=False)
94 |
95 | exit()
--------------------------------------------------------------------------------
/model-deployment/pytorch-deeplab.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# PyTorch DeepLab の学習済みモデルを SageMaker でデプロイする\n",
8 | "\n",
9 | "PyTorch Hub で公開されている [DeepLab V3 のモデル](https://pytorch.org/hub/pytorch_vision_deeplabv3_resnet101/)をダウンロードしてデプロイします。このノートブックでは、モデルのSageMaker への持ち込み方法を知るため、以下のステップでデプロイします。\n",
10 | "\n",
11 | "1. PyTorch Hub からモデルをダウンロードし、S3 に保存します。\n",
12 | "1. ダウンロードしたモデルで推論を行うためのコードを作成します。\n",
13 | "1. S3 に保存したモデルを指定して、SageMaker にデプロイします。\n",
14 | "\n",
15 | "実際には、推論コードの中でPyTorch Hub からモデルをダウンロードできるため、1をスキップする方法も可能です。\n",
16 | "\n",
17 | "\n",
18 | "## 1. PyTorch Hub からのモデルダウンロード\n",
19 | "\n",
20 | "`torch.hub`でモデルをダウンロードし、パラメータの情報のみ保存します。保存したファイルは `tar.gz` の形式にして S3 にアップロードします。"
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": null,
26 | "metadata": {},
27 | "outputs": [],
28 | "source": [
29 | "import torch\n",
30 | "import os\n",
31 | "os.makedirs('model',exist_ok=True)\n",
32 | "model = torch.hub.load('pytorch/vision:v0.10.0', 'deeplabv3_resnet101', pretrained=True, progress=False)\n",
33 | "path = './model/model.pth'\n",
34 | "torch.save(model.cpu().state_dict(), path)"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {},
41 | "outputs": [],
42 | "source": [
43 | "!tar cvzf model.tar.gz -C ./model ."
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {},
50 | "outputs": [],
51 | "source": [
52 | "import sagemaker\n",
53 | "sagemaker_session = sagemaker.Session()\n",
54 | "model_path = sagemaker_session.upload_data(\"model.tar.gz\", key_prefix =\"pytorch_deeplab_model\")"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "model_path"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "metadata": {},
69 | "source": [
70 | "## 2. 推論コードの作成\n",
71 | "\n",
72 | "アップロードしたモデルを読み込んで推論を実行するコードを作成します。モデルの読み込みは `model_fn` で、推論の実行は `transform_fn`で実装します。\n",
73 | "PyTorch ではモデルのパラメータ以外にシンボルの情報が必要なので、PyTorch Hub から呼び出して利用します。各関数の実装は[公式の利用方法](https://pytorch.org/hub/pytorch_vision_deeplabv3_resnet101/)を参考にしています。"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": null,
79 | "metadata": {},
80 | "outputs": [],
81 | "source": [
82 | "%%writefile deploy.py\n",
83 | "\n",
84 | "from io import BytesIO\n",
85 | "import json\n",
86 | "import numpy as np\n",
87 | "import os\n",
88 | "import torch\n",
89 | "import torch.nn as nn\n",
90 | "import torch.nn.functional as F\n",
91 | "\n",
92 | "from PIL import Image\n",
93 | "from torchvision import transforms \n",
94 | "\n",
95 | "def model_fn(model_dir):\n",
96 | " model = torch.hub.load('pytorch/vision:v0.10.0', 'deeplabv3_resnet101', pretrained=False, progress=False)\n",
97 | " with open(os.path.join(model_dir, \"model.pth\"), \"rb\") as f:\n",
98 | " model.load_state_dict(torch.load(f), strict=False)\n",
99 | " model.eval() # for inference\n",
100 | " return model\n",
101 | "\n",
102 | "def transform_fn(model, request_body, request_content_type, response_content_type):\n",
103 | " \n",
104 | " input_data = np.load(BytesIO(request_body))\n",
105 | " preprocess = transforms.Compose([\n",
106 | " transforms.ToTensor(),\n",
107 | " transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n",
108 | " ])\n",
109 | " \n",
110 | " input_tensor = preprocess(input_data)\n",
111 | " input_batch = input_tensor.unsqueeze(0)\n",
112 | " prediction = model(input_batch)\n",
113 | " return json.dumps(prediction['out'].tolist())"
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "metadata": {},
119 | "source": [
120 | "## 3. デプロイと推論"
121 | ]
122 | },
123 | {
124 | "cell_type": "code",
125 | "execution_count": null,
126 | "metadata": {},
127 | "outputs": [],
128 | "source": [
129 | "from sagemaker.pytorch.model import PyTorchModel\n",
130 | "\n",
131 | "deeplab_model=PyTorchModel(model_data=model_path, \n",
132 | " role=sagemaker.get_execution_role(), \n",
133 | " entry_point='deploy.py', \n",
134 | " framework_version='1.8.1',\n",
135 | " py_version='py3')"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "metadata": {},
142 | "outputs": [],
143 | "source": [
144 | "predictor=deeplab_model.deploy(instance_type='ml.m4.xlarge', initial_instance_count=1)"
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": null,
150 | "metadata": {},
151 | "outputs": [],
152 | "source": [
153 | "!wget https://github.com/pytorch/hub/raw/master/images/dog.jpg"
154 | ]
155 | },
156 | {
157 | "cell_type": "code",
158 | "execution_count": null,
159 | "metadata": {},
160 | "outputs": [],
161 | "source": [
162 | "import matplotlib.pyplot as plt\n",
163 | "from PIL import Image\n",
164 | "import numpy as np\n",
165 | "from torchvision import transforms\n",
166 | "from skimage.segmentation import mark_boundaries\n",
167 | "\n",
168 | "input_image = Image.open(\"dog.jpg\").convert('RGB')\n",
169 | "w, h = input_image.size\n",
170 | "\n",
171 | "input_image = input_image.resize((150, 100))\n",
172 | "np_input_image = np.array(input_image)\n",
173 | "predictor.deserializer = sagemaker.deserializers.JSONDeserializer()\n",
174 | "predictions = predictor.predict(np_input_image)\n",
175 | "\n",
176 | "# create a color pallette, selecting a color for each class\n",
177 | "palette = torch.tensor([2 ** 25 - 1, 2 ** 15 - 1, 2 ** 21 - 1])\n",
178 | "colors = torch.as_tensor([i for i in range(21)])[:, None] * palette\n",
179 | "colors = (colors % 255).numpy().astype(\"uint8\")\n",
180 | "label_map = np.array(predictions[0]).argmax(0)\n",
181 | "\n",
182 | "# # plot the semantic segmentation predictions of 21 classes in each color\n",
183 | "r = Image.fromarray(label_map.astype(np.uint8))\n",
184 | "r.putpalette(colors)\n",
185 | "r = Image.blend(r.convert('RGBA'), input_image.convert('RGBA'), 0.5) \n",
186 | "\n",
187 | "plt.rcParams['figure.figsize'] = [12, 8]\n",
188 | "plt.imshow(r)"
189 | ]
190 | },
191 | {
192 | "cell_type": "markdown",
193 | "metadata": {},
194 | "source": [
195 | "最後に不要なエンドポイントを削除します。"
196 | ]
197 | },
198 | {
199 | "cell_type": "code",
200 | "execution_count": null,
201 | "metadata": {},
202 | "outputs": [],
203 | "source": [
204 | "predictor.delete_endpoint()"
205 | ]
206 | },
207 | {
208 | "cell_type": "code",
209 | "execution_count": null,
210 | "metadata": {},
211 | "outputs": [],
212 | "source": []
213 | }
214 | ],
215 | "metadata": {
216 | "instance_type": "ml.t3.medium",
217 | "kernelspec": {
218 | "display_name": "Python 3 (PyTorch 1.6 Python 3.6 CPU Optimized)",
219 | "language": "python",
220 | "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/pytorch-1.6-cpu-py36-ubuntu16.04-v1"
221 | },
222 | "language_info": {
223 | "codemirror_mode": {
224 | "name": "ipython",
225 | "version": 3
226 | },
227 | "file_extension": ".py",
228 | "mimetype": "text/x-python",
229 | "name": "python",
230 | "nbconvert_exporter": "python",
231 | "pygments_lexer": "ipython3",
232 | "version": "3.6.13"
233 | }
234 | },
235 | "nbformat": 4,
236 | "nbformat_minor": 4
237 | }
238 |
--------------------------------------------------------------------------------
/nlp_amazon_review/GluonNLP_BERT/src/bert/data/__init__.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | # pylint: disable=wildcard-import
21 | """BERT data."""
22 | from . import transform
23 |
--------------------------------------------------------------------------------
/nlp_amazon_review/GluonNLP_BERT/src/bert/data/transform.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | # Copyright 2018 The Google AI Language Team Authors and DMLC.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | """BERT dataset transform."""
16 | from __future__ import absolute_import
17 |
18 | __all__ = ['BERTDatasetTransform']
19 |
20 | import numpy as np
21 |
22 | import os
23 | from gluonnlp.data import BERTSentenceTransform
24 |
25 | class BERTDatasetTransform:
26 | """Dataset transformation for BERT-style sentence classification or regression.
27 |
28 | Parameters
29 | ----------
30 | tokenizer : BERTTokenizer.
31 | Tokenizer for the sentences.
32 | max_seq_length : int.
33 | Maximum sequence length of the sentences.
34 | labels : list of int , float or None. defaults None
35 | List of all label ids for the classification task and regressing task.
36 | If labels is None, the default task is regression
37 | pad : bool, default True
38 | Whether to pad the sentences to maximum length.
39 | pair : bool, default True
40 | Whether to transform sentences or sentence pairs.
41 | label_dtype: int32 or float32, default float32
42 | label_dtype = int32 for classification task
43 | label_dtype = float32 for regression task
44 | """
45 |
46 | def __init__(self,
47 | tokenizer,
48 | max_seq_length,
49 | class_labels=None,
50 | label_alias=None,
51 | pad=True,
52 | pair=True,
53 | has_label=True):
54 | self.class_labels = class_labels
55 | self.has_label = has_label
56 | self._label_dtype = 'int32' if class_labels else 'float32'
57 | if has_label and class_labels:
58 | self._label_map = {}
59 | for (i, label) in enumerate(class_labels):
60 | self._label_map[label] = i
61 | if label_alias:
62 | for key in label_alias:
63 | self._label_map[key] = self._label_map[label_alias[key]]
64 | self._bert_xform = BERTSentenceTransform(
65 | tokenizer, max_seq_length, pad=pad, pair=pair)
66 |
67 | def __call__(self, line):
68 | """Perform transformation for sequence pairs or single sequences.
69 |
70 | The transformation is processed in the following steps:
71 | - tokenize the input sequences
72 | - insert [CLS], [SEP] as necessary
73 | - generate type ids to indicate whether a token belongs to the first
74 | sequence or the second sequence.
75 | - generate valid length
76 |
77 | For sequence pairs, the input is a tuple of 3 strings:
78 | text_a, text_b and label.
79 |
80 | Inputs:
81 | text_a: 'is this jacksonville ?'
82 | text_b: 'no it is not'
83 | label: '0'
84 | Tokenization:
85 | text_a: 'is this jack ##son ##ville ?'
86 | text_b: 'no it is not .'
87 | Processed:
88 | tokens: '[CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP]'
89 | type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1
90 | valid_length: 14
91 | label: 0
92 |
93 | For single sequences, the input is a tuple of 2 strings: text_a and label.
94 | Inputs:
95 | text_a: 'the dog is hairy .'
96 | label: '1'
97 | Tokenization:
98 | text_a: 'the dog is hairy .'
99 | Processed:
100 | text_a: '[CLS] the dog is hairy . [SEP]'
101 | type_ids: 0 0 0 0 0 0 0
102 | valid_length: 7
103 | label: 1
104 |
105 | Parameters
106 | ----------
107 | line: tuple of str
108 | Input strings. For sequence pairs, the input is a tuple of 3 strings:
109 | (text_a, text_b, label). For single sequences, the input is a tuple
110 | of 2 strings: (text_a, label).
111 |
112 | Returns
113 | -------
114 | np.array: input token ids in 'int32', shape (batch_size, seq_length)
115 | np.array: valid length in 'int32', shape (batch_size,)
116 | np.array: input token type ids in 'int32', shape (batch_size, seq_length)
117 | np.array: classification task: label id in 'int32', shape (batch_size, 1),
118 | regression task: label in 'float32', shape (batch_size, 1)
119 | """
120 | if self.has_label:
121 | input_ids, valid_length, segment_ids = self._bert_xform(line[:-1])
122 | label = line[-1]
123 | # map to int if class labels are available
124 | if self.class_labels:
125 | label = self._label_map[label]
126 | label = np.array([label], dtype=self._label_dtype)
127 | return input_ids, valid_length, segment_ids, label
128 | else:
129 | return self._bert_xform(line)
130 |
--------------------------------------------------------------------------------
/nlp_amazon_review/GluonNLP_BERT/src/bert/model/__init__.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | # pylint: disable=wildcard-import
21 | """BERT model."""
22 | from . import classification
23 |
--------------------------------------------------------------------------------
/nlp_amazon_review/GluonNLP_BERT/src/bert/model/classification.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | """BERT models."""
20 |
21 | __all__ = ['BERTClassifier', 'BERTRegression']
22 |
23 | from mxnet.gluon import HybridBlock
24 | from mxnet.gluon import nn
25 |
26 | class BERTRegression(HybridBlock):
27 | """Model for sentence (pair) regression task with BERT.
28 |
29 | The model feeds token ids and token type ids into BERT to get the
30 | pooled BERT sequence representation, then apply a Dense layer for
31 | regression.
32 |
33 | Parameters
34 | ----------
35 | bert: BERTModel
36 | Bidirectional encoder with transformer.
37 | dropout : float or None, default 0.0.
38 | Dropout probability for the bert output.
39 | prefix : str or None
40 | See document of `mx.gluon.Block`.
41 | params : ParameterDict or None
42 | See document of `mx.gluon.Block`.
43 | """
44 |
45 | def __init__(self, bert, dropout=0.0, prefix=None, params=None):
46 | super(BERTRegression, self).__init__(prefix=prefix, params=params)
47 | self.bert = bert
48 | with self.name_scope():
49 | self.regression = nn.HybridSequential(prefix=prefix)
50 | if dropout:
51 | self.regression.add(nn.Dropout(rate=dropout))
52 | self.regression.add(nn.Dense(1))
53 |
54 | def hybrid_forward(self, F, inputs, token_types, valid_length=None):
55 | # pylint: disable=arguments-differ
56 | """Generate the unnormalized score for the given the input sequences.
57 |
58 | Parameters
59 | ----------
60 | inputs : NDArray, shape (batch_size, seq_length)
61 | Input words for the sequences.
62 | token_types : NDArray, shape (batch_size, seq_length)
63 | Token types for the sequences, used to indicate whether the word belongs to the
64 | first sentence or the second one.
65 | valid_length : NDArray or None, shape (batch_size)
66 | Valid length of the sequence. This is used to mask the padded tokens.
67 |
68 | Returns
69 | -------
70 | outputs : NDArray
71 | Shape (batch_size, num_classes)
72 | """
73 | _, pooler_out = self.bert(inputs, token_types, valid_length)
74 | return self.regression(pooler_out)
75 |
76 |
77 | class BERTClassifier(HybridBlock):
78 | """Model for sentence (pair) classification task with BERT.
79 |
80 | The model feeds token ids and token type ids into BERT to get the
81 | pooled BERT sequence representation, then apply a Dense layer for
82 | classification.
83 |
84 | Parameters
85 | ----------
86 | bert: BERTModel
87 | Bidirectional encoder with transformer.
88 | num_classes : int, default is 2
89 | The number of target classes.
90 | dropout : float or None, default 0.0.
91 | Dropout probability for the bert output.
92 | prefix : str or None
93 | See document of `mx.gluon.Block`.
94 | params : ParameterDict or None
95 | See document of `mx.gluon.Block`.
96 | """
97 |
98 | def __init__(self,
99 | bert,
100 | num_classes=2,
101 | dropout=0.0,
102 | prefix=None,
103 | params=None):
104 | super(BERTClassifier, self).__init__(prefix=prefix, params=params)
105 | self.bert = bert
106 | with self.name_scope():
107 | self.classifier = nn.HybridSequential(prefix=prefix)
108 | if dropout:
109 | self.classifier.add(nn.Dropout(rate=dropout))
110 | self.classifier.add(nn.Dense(units=num_classes))
111 |
112 | def hybrid_forward(self, F, inputs, token_types, valid_length=None):
113 | # pylint: disable=arguments-differ
114 | """Generate the unnormalized score for the given the input sequences.
115 |
116 | Parameters
117 | ----------
118 | inputs : NDArray, shape (batch_size, seq_length)
119 | Input words for the sequences.
120 | token_types : NDArray, shape (batch_size, seq_length)
121 | Token types for the sequences, used to indicate whether the word belongs to the
122 | first sentence or the second one.
123 | valid_length : NDArray or None, shape (batch_size)
124 | Valid length of the sequence. This is used to mask the padded tokens.
125 |
126 | Returns
127 | -------
128 | outputs : NDArray
129 | Shape (batch_size, num_classes)
130 | """
131 | _, pooler_out = self.bert(inputs, token_types, valid_length)
132 | return self.classifier(pooler_out)
133 |
--------------------------------------------------------------------------------
/nlp_amazon_review/GluonNLP_BERT/src/train_and_deploy.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import mxnet as mx
3 | import json
4 | import sys
5 | import os
6 | import gluonnlp as nlp
7 | from mxnet import gluon, autograd
8 | from mxnet.gluon import nn
9 | from bert import data, model
10 | import sys
11 |
12 | import logging
13 | logging.basicConfig(level=logging.INFO)
14 |
15 |
16 | try:
17 | num_cpus = int(os.environ['SM_NUM_CPUS'])
18 | num_gpus = int(os.environ['SM_NUM_GPUS'])
19 | except KeyError:
20 | num_gpus = 0
21 |
22 | ctx = mx.gpu() if num_gpus > 0 else mx.cpu()
23 | bert_base, vocabulary = nlp.model.get_model('bert_12_768_12',
24 | dataset_name='wiki_multilingual_uncased',
25 | pretrained=True, ctx=ctx, use_pooler=True,
26 | use_decoder=False, use_classifier=False)
27 |
28 | # The maximum length of an input sequence
29 | max_len = 128
30 |
31 |
32 | if __name__ == '__main__':
33 |
34 |
35 | # Receive hyperparameters passed via create-training-job API
36 | parser = argparse.ArgumentParser()
37 |
38 | parser.add_argument('--batch-size', type=int, default=32)
39 | parser.add_argument('--epochs', type=int, default=1)
40 | parser.add_argument('--learning-rate', type=float, default=5e-6)
41 | parser.add_argument('--log-interval', type=float, default=4)
42 |
43 | parser.add_argument('--model-dir', type=str, default=os.environ['SM_MODEL_DIR'])
44 | parser.add_argument('--train', type=str, default=os.environ['SM_CHANNEL_TRAIN'])
45 | parser.add_argument('--current-host', type=str, default=os.environ['SM_CURRENT_HOST'])
46 | parser.add_argument('--hosts', type=list, default=json.loads(os.environ['SM_HOSTS']))
47 |
48 | args = parser.parse_args()
49 |
50 | # Set hyperparameters after parsing the arguments
51 | batch_size = args.batch_size
52 | lr = args.learning_rate
53 | log_interval = args.log_interval
54 | num_epochs = args.epochs
55 | current_host = args.current_host
56 | hosts = args.hosts
57 | model_dir = args.model_dir
58 | training_dir = args.train
59 |
60 | # Setting for distributed training
61 | if len(hosts) == 1:
62 | kvstore = 'device' if num_gpus > 0 else 'local'
63 | else:
64 | kvstore = 'dist_device_sync' if num_gpus > 0 else 'dist_sync'
65 |
66 |
67 |
68 | # Load pre-trained bert model and vocabulary
69 | # and define the classification model (add classifier and loss function on bert)
70 | bert_classifier = model.classification.BERTClassifier(bert_base, num_classes=2, dropout=0.1)
71 | # only need to initialize the classifier layer.
72 | bert_classifier.classifier.initialize(init=mx.init.Normal(0.02), ctx=ctx)
73 | bert_classifier.hybridize(static_alloc=True)
74 | loss_function = mx.gluon.loss.SoftmaxCELoss()
75 | loss_function.hybridize(static_alloc=True)
76 |
77 | # Data loading
78 | field_separator = nlp.data.Splitter('\t')
79 | data_train_raw = nlp.data.TSVDataset(filename=os.path.join(training_dir,'train.tsv'),
80 | field_separator=field_separator)
81 |
82 | # Use the vocabulary from pre-trained model for tokenization
83 | bert_tokenizer = nlp.data.BERTTokenizer(vocabulary, lower=True)
84 |
85 | # The labels for the two classes [(0 : Negative) or (1 : Poistive)]
86 | all_labels = ["0", "1"]
87 |
88 | # whether to transform the data as sentence pairs.
89 | # for single sentence classification, set pair=False
90 | # for regression task, set class_labels=None
91 | # for inference without label available, set has_label=False
92 | pair = False
93 | transform = data.transform.BERTDatasetTransform(bert_tokenizer, max_len,
94 | class_labels=all_labels,
95 | has_label=True,
96 | pad=True,
97 | pair=pair)
98 | data_train = data_train_raw.transform(transform)
99 |
100 |
101 | # The FixedBucketSampler and the DataLoader for making the mini-batches
102 | train_sampler = nlp.data.FixedBucketSampler(lengths=[int(item[1]) for item in data_train],
103 | batch_size=batch_size,
104 | shuffle=True)
105 | bert_dataloader = mx.gluon.data.DataLoader(data_train, batch_sampler=train_sampler)
106 |
107 | trainer = mx.gluon.Trainer(bert_classifier.collect_params(), 'adam',
108 | {'learning_rate': lr, 'epsilon': 1e-9},
109 | kvstore=kvstore)
110 |
111 | # Collect all differentiable parameters
112 | # `grad_req == 'null'` indicates no gradients are calculated (e.g. constant parameters)
113 | # The gradients for these params are clipped later
114 | params = [p for p in bert_classifier.collect_params().values() if p.grad_req != 'null']
115 | grad_clip = 1
116 |
117 | # For evaluation with accuracy
118 | metric = mx.metric.Accuracy()
119 |
120 | # Training loop
121 | for epoch_id in range(num_epochs):
122 | metric.reset()
123 | step_loss = 0
124 | for batch_id, (token_ids, valid_length, segment_ids, label) in enumerate(bert_dataloader):
125 | with mx.autograd.record():
126 |
127 | # Load the data to the CPU or GPU
128 | token_ids = token_ids.as_in_context(ctx)
129 | valid_length = valid_length.as_in_context(ctx)
130 | segment_ids = segment_ids.as_in_context(ctx)
131 | label = label.as_in_context(ctx)
132 |
133 | # Forward computation
134 | # Loss is weighte by 10 for negaive (0) and 1 for positive(1)
135 | out = bert_classifier(token_ids, segment_ids, valid_length.astype('float32'))
136 | ls = loss_function(out, label).mean()
137 |
138 | # And backwards computation
139 | ls.backward()
140 |
141 | # Gradient clipping
142 | trainer.allreduce_grads()
143 | nlp.utils.clip_grad_global_norm(params, 1)
144 | trainer.update(1)
145 |
146 | step_loss += ls.asscalar()
147 | metric.update([label], [out])
148 |
149 | # Printing vital information
150 | if (batch_id + 1) % (log_interval) == 0:
151 | print('[Epoch {} Batch {}/{}] loss={:.4f}, lr={:.7f}, acc={:.3f}'
152 | .format(epoch_id, batch_id + 1, len(bert_dataloader),
153 | step_loss / log_interval,
154 | trainer.learning_rate, metric.get()[1]))
155 | step_loss = 0
156 |
157 |
158 | if current_host == hosts[0]:
159 | bert_classifier.export('%s/model'% model_dir)
160 |
161 |
162 | def model_fn(model_dir):
163 | """
164 | Load the gluon model. Called once when hosting service starts.
165 |
166 | :param: model_dir The directory where model files are stored.
167 | :return: a model (in this case a Gluon network)
168 | """
169 |
170 | bert_tokenizer = nlp.data.BERTTokenizer(vocabulary, lower=True)
171 | bert_classifier = gluon.SymbolBlock.imports(
172 | '%s/model-symbol.json' % model_dir,
173 | ['data0', 'data1', 'data2'],
174 | '%s/model-0000.params' % model_dir,
175 | )
176 | return {"net": bert_classifier, "tokenizer": bert_tokenizer}
177 |
178 |
179 | def transform_fn(net, data, input_content_type, output_content_type):
180 | """
181 | Transform a request using the Gluon model. Called once per request.
182 |
183 | :param net: The Gluon model.
184 | :param data: The request payload.
185 | :param input_content_type: The request content type.
186 | :param output_content_type: The (desired) response content type.
187 | :return: response payload and content type.
188 | """
189 | # we can use content types to vary input/output handling, but
190 | # here we just assume json for both
191 | bert_classifier = net["net"]
192 | bert_tokenizer = net["tokenizer"]
193 |
194 | # Assume one line of text
195 | parsed = json.loads(data)
196 | logging.info("Received_data: {}".format(parsed))
197 | tokens = bert_tokenizer(parsed)
198 | logging.info("Tokens: {}".format(tokens))
199 | token_ids = bert_tokenizer.convert_tokens_to_ids(tokens)
200 | valid_length = len(token_ids)
201 | segment_ids = mx.nd.zeros([1, valid_length])
202 |
203 | output = bert_classifier(mx.nd.array([token_ids]),
204 | segment_ids,
205 | mx.nd.array([valid_length]).astype('float32'))
206 | response_body = json.dumps(output.asnumpy().tolist()[0])
207 | return response_body, output_content_type
208 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "amazon-sagemaker-examples-jp",
3 | "lockfileVersion": 2,
4 | "requires": true,
5 | "packages": {}
6 | }
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/sagemaker-experiments/pytorch_mnist/figures/experiments-overview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/sagemaker-experiments/pytorch_mnist/figures/experiments-overview.jpg
--------------------------------------------------------------------------------
/sagemaker-experiments/pytorch_mnist/src/mnist_deploy.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import os
3 |
4 | import sys
5 | import torch
6 | import torch.nn as nn
7 | import torch.nn.functional as F
8 |
9 |
10 | # Based on https://github.com/pytorch/examples/blob/master/mnist/main.py
11 | class Net(nn.Module):
12 | def __init__(self):
13 | super(Net, self).__init__()
14 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
15 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
16 | self.conv2_drop = nn.Dropout2d()
17 | self.fc1 = nn.Linear(320, 50)
18 | self.fc2 = nn.Linear(50, 10)
19 |
20 | def forward(self, x):
21 | x = F.relu(F.max_pool2d(self.conv1(x), 2))
22 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
23 | x = x.view(-1, 320)
24 | x = F.relu(self.fc1(x))
25 | x = F.dropout(x, training=self.training)
26 | x = self.fc2(x)
27 | return F.log_softmax(x, dim=1)
28 |
29 |
30 | def model_fn(model_dir):
31 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
32 | model = torch.nn.DataParallel(Net())
33 | with open(os.path.join(model_dir, 'model.pth'), 'rb') as f:
34 | model.load_state_dict(torch.load(f))
35 | return model.to(device)
36 |
--------------------------------------------------------------------------------
/sagemaker-experiments/pytorch_mnist/src/mnist_train.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import json
3 | import logging
4 | import os
5 | import sys
6 | import torch
7 | import torch.distributed as dist
8 | import torch.nn as nn
9 | import torch.nn.functional as F
10 | import torch.optim as optim
11 | import torch.utils.data
12 | import torch.utils.data.distributed
13 | from torchvision import datasets, transforms
14 |
15 | logger = logging.getLogger(__name__)
16 | logger.setLevel(logging.DEBUG)
17 | logger.addHandler(logging.StreamHandler(sys.stdout))
18 |
19 |
20 | # Based on https://github.com/pytorch/examples/blob/master/mnist/main.py
21 | class Net(nn.Module):
22 | def __init__(self):
23 | super(Net, self).__init__()
24 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
25 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
26 | self.conv2_drop = nn.Dropout2d()
27 | self.fc1 = nn.Linear(320, 50)
28 | self.fc2 = nn.Linear(50, 10)
29 |
30 | def forward(self, x):
31 | x = F.relu(F.max_pool2d(self.conv1(x), 2))
32 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
33 | x = x.view(-1, 320)
34 | x = F.relu(self.fc1(x))
35 | x = F.dropout(x, training=self.training)
36 | x = self.fc2(x)
37 | return F.log_softmax(x, dim=1)
38 |
39 | def _get_train_data_loader(batch_size, training_dir, is_distributed, **kwargs):
40 | logger.info("Get train data loader")
41 | train_tensor = torch.load(os.path.join(training_dir, 'training.pt'))
42 | dataset = torch.utils.data.TensorDataset(train_tensor[0], train_tensor[1])
43 | train_sampler = torch.utils.data.distributed.DistributedSampler(dataset) if is_distributed else None
44 | return torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=train_sampler is None,
45 | sampler=train_sampler, **kwargs)
46 |
47 | def _get_test_data_loader(test_batch_size, training_dir, **kwargs):
48 | logger.info("Get test data loader")
49 | test_tensor = torch.load(os.path.join(training_dir, 'test.pt'))
50 | dataset = torch.utils.data.TensorDataset(test_tensor[0], test_tensor[1])
51 | return torch.utils.data.DataLoader(
52 | dataset,
53 | batch_size=test_batch_size,
54 | shuffle=True, **kwargs)
55 |
56 |
57 | def _average_gradients(model):
58 | # Gradient averaging.
59 | size = float(dist.get_world_size())
60 | for param in model.parameters():
61 | dist.all_reduce(param.grad.data, op=dist.reduce_op.SUM)
62 | param.grad.data /= size
63 |
64 |
65 | def train(args):
66 | is_distributed = len(args.hosts) > 1 and args.backend is not None
67 | logger.debug("Distributed training - {}".format(is_distributed))
68 | use_cuda = args.num_gpus > 0
69 | logger.debug("Number of gpus available - {}".format(args.num_gpus))
70 | kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
71 | device = torch.device("cuda" if use_cuda else "cpu")
72 |
73 | if is_distributed:
74 | # Initialize the distributed environment.
75 | world_size = len(args.hosts)
76 | os.environ['WORLD_SIZE'] = str(world_size)
77 | host_rank = args.hosts.index(args.current_host)
78 | os.environ['RANK'] = str(host_rank)
79 | dist.init_process_group(backend=args.backend, rank=host_rank, world_size=world_size)
80 | logger.info('Initialized the distributed environment: \'{}\' backend on {} nodes. '.format(
81 | args.backend, dist.get_world_size()) + 'Current host rank is {}. Number of gpus: {}'.format(
82 | dist.get_rank(), args.num_gpus))
83 |
84 | # set the seed for generating random numbers
85 | torch.manual_seed(args.seed)
86 | if use_cuda:
87 | torch.cuda.manual_seed(args.seed)
88 |
89 | train_loader = _get_train_data_loader(args.batch_size, args.data_dir, is_distributed, **kwargs)
90 | test_loader = _get_test_data_loader(args.test_batch_size, args.data_dir, **kwargs)
91 |
92 | logger.debug("Processes {}/{} ({:.0f}%) of train data".format(
93 | len(train_loader.sampler), len(train_loader.dataset),
94 | 100. * len(train_loader.sampler) / len(train_loader.dataset)
95 | ))
96 |
97 | logger.debug("Processes {}/{} ({:.0f}%) of test data".format(
98 | len(test_loader.sampler), len(test_loader.dataset),
99 | 100. * len(test_loader.sampler) / len(test_loader.dataset)
100 | ))
101 |
102 | model = Net().to(device)
103 | if is_distributed and use_cuda:
104 | # multi-machine multi-gpu case
105 | model = torch.nn.parallel.DistributedDataParallel(model)
106 | else:
107 | # single-machine multi-gpu case or single-machine or multi-machine cpu case
108 | model = torch.nn.DataParallel(model)
109 |
110 | optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)
111 |
112 | for epoch in range(1, args.epochs + 1):
113 | model.train()
114 | for batch_idx, (data, target) in enumerate(train_loader, 1):
115 | data, target = data.to(device), target.to(device)
116 | optimizer.zero_grad()
117 | output = model(data)
118 | loss = F.nll_loss(output, target)
119 | loss.backward()
120 | if is_distributed and not use_cuda:
121 | # average gradients manually for multi-machine cpu case only
122 | _average_gradients(model)
123 | optimizer.step()
124 | if batch_idx % args.log_interval == 0:
125 | logger.info('Train Epoch: {} [{}/{} ({:.0f}%)] Loss: {:.6f}'.format(
126 | epoch, batch_idx * len(data), len(train_loader.sampler),
127 | 100. * batch_idx / len(train_loader), loss.item()))
128 | test(model, test_loader, device)
129 | save_model(model, args.model_dir)
130 |
131 |
132 | def test(model, test_loader, device):
133 | model.eval()
134 | test_loss = 0
135 | correct = 0
136 | with torch.no_grad():
137 | for data, target in test_loader:
138 | data, target = data.to(device), target.to(device)
139 | output = model(data)
140 | test_loss += F.nll_loss(output, target, size_average=False).item() # sum up batch loss
141 | pred = output.max(1, keepdim=True)[1] # get the index of the max log-probability
142 | correct += pred.eq(target.view_as(pred)).sum().item()
143 |
144 | test_loss /= len(test_loader.dataset)
145 | logger.info('Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
146 | test_loss, correct, len(test_loader.dataset),
147 | 100. * correct / len(test_loader.dataset)))
148 |
149 |
150 | def model_fn(model_dir):
151 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
152 | model = torch.nn.DataParallel(Net())
153 | with open(os.path.join(model_dir, 'model.pth'), 'rb') as f:
154 | model.load_state_dict(torch.load(f))
155 | return model.to(device)
156 |
157 |
158 | def save_model(model, model_dir):
159 | logger.info("Saving the model.")
160 | path = os.path.join(model_dir, 'model.pth')
161 | # recommended way from http://pytorch.org/docs/master/notes/serialization.html
162 | torch.save(model.cpu().state_dict(), path)
163 |
164 |
165 | if __name__ == '__main__':
166 | parser = argparse.ArgumentParser()
167 |
168 | # Data and model checkpoints directories
169 | parser.add_argument('--batch-size', type=int, default=64, metavar='N',
170 | help='input batch size for training (default: 64)')
171 | parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N',
172 | help='input batch size for testing (default: 1000)')
173 | parser.add_argument('--epochs', type=int, default=10, metavar='N',
174 | help='number of epochs to train (default: 10)')
175 | parser.add_argument('--lr', type=float, default=0.01, metavar='LR',
176 | help='learning rate (default: 0.01)')
177 | parser.add_argument('--momentum', type=float, default=0.5, metavar='M',
178 | help='SGD momentum (default: 0.5)')
179 | parser.add_argument('--seed', type=int, default=1, metavar='S',
180 | help='random seed (default: 1)')
181 | parser.add_argument('--log-interval', type=int, default=100, metavar='N',
182 | help='how many batches to wait before logging training status')
183 | parser.add_argument('--backend', type=str, default=None,
184 | help='backend for distributed training (tcp, gloo on cpu and gloo, nccl on gpu)')
185 |
186 | # Container environment
187 | parser.add_argument('--hosts', type=list, default=json.loads(os.environ['SM_HOSTS']))
188 | parser.add_argument('--current-host', type=str, default=os.environ['SM_CURRENT_HOST'])
189 | parser.add_argument('--model-dir', type=str, default=os.environ['SM_MODEL_DIR'])
190 | parser.add_argument('--data-dir', type=str, default=os.environ['SM_CHANNEL_TRAINING'])
191 | parser.add_argument('--num-gpus', type=int, default=os.environ['SM_NUM_GPUS'])
192 |
193 | train(parser.parse_args())
194 |
--------------------------------------------------------------------------------
/sagemaker_processing/Feature_engineering_with_RAPIDS_on_SageMaker_Processing/container/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM continuumio/miniconda3:4.8.2
2 |
3 | RUN conda install -c rapidsai -c nvidia -c conda-forge -c defaults rapids=0.16 python=3.7 cudatoolkit=10.1 boto3
4 |
5 | ENV PYTHONUNBUFFERED=TRUE
6 | ENTRYPOINT ["python3"]
7 |
--------------------------------------------------------------------------------
/sagemaker_processing/processing_with_bring_your_own_container_for_beginner/0_data_preparation.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# 画像で機械学習するための準備(処理時間1分以内)\n",
8 | "* Amazon SageMaker はあまり関係ありません\n",
9 | "\n",
10 | "\n",
11 | "* このノートブックで行うこと\n",
12 | " 1. yan lecun 様の[サイト](http://yann.lecun.com/exdb/mnist/)より mnist のデータセットをノートブックインスタンスにダウンロード\n",
13 | " 2. バイナリデータから画像データを1枚ずつ png ファイルに出力\n",
14 | " 3. バイナリデータからラベルデータを npy ファイルに出力\n",
15 | " 4. zip ファイルに固めて S3 にアップロード \n",
16 | " zip ファイルに固める理由はバラバラの画像ファイルだと転送速度が遅くなるため、固めて転送して演算するコンピューティングリソースで解凍する"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | ""
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import sagemaker\n",
33 | "print(f'Current sagemaker Version ={sagemaker.__version__}')"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "上記セルを実行して、SageMaker Python SDK Version が 1.xx.x の場合、以下のセルのコメントアウトを解除してから実行してください。実行が完了したら、上にあるメニューから [Kernel] -> [Restart] を選択してカーネルを再起動してください。\n",
41 | "\n",
42 | "再起動が完了したら、このノートブックの一番上のセルから再度実行してください。その場合、以下のセルを実行する必要はありません。"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": null,
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "# pip install -U --quiet \"sagemaker==2.20.0\""
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "## 各種設定"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {},
65 | "outputs": [],
66 | "source": [
67 | "name = ''"
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": null,
73 | "metadata": {},
74 | "outputs": [],
75 | "source": [
76 | "import urllib.request, gzip, numpy as np, sagemaker, datetime, yaml, os, shutil\n",
77 | "from matplotlib import pyplot as plt\n",
78 | "from PIL import Image\n",
79 | "from tqdm import tqdm\n",
80 | "\n",
81 | "url_base = 'http://yann.lecun.com/exdb/mnist/'\n",
82 | "key_file = {\n",
83 | " 'train_img':'train-images-idx3-ubyte.gz',\n",
84 | " 'train_label':'train-labels-idx1-ubyte.gz',\n",
85 | " 'test_img':'t10k-images-idx3-ubyte.gz',\n",
86 | " 'test_label':'t10k-labels-idx1-ubyte.gz'\n",
87 | "}\n",
88 | "# 様々な識別子を一意にするためにタイムスタンプを利用する\n",
89 | "timestamp = datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=9))).strftime('%Y%m%d%H%M%S')\n",
90 | "print(f'timestamp: {timestamp}')"
91 | ]
92 | },
93 | {
94 | "cell_type": "markdown",
95 | "metadata": {},
96 | "source": [
97 | "## データをノートブックインスタンスにダウンロード"
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {},
104 | "outputs": [],
105 | "source": [
106 | "%%time\n",
107 | "\n",
108 | "dataset_dir = './mnist/' #画像ファイルとラベルを保存するディレクトリ\n",
109 | "\n",
110 | "os.makedirs(dataset_dir, exist_ok=True)\n",
111 | "\n",
112 | "for v in key_file.values():\n",
113 | " file_path = dataset_dir + '/' + v\n",
114 | " # データのダウンロード\n",
115 | " urllib.request.urlretrieve(url_base + v, file_path)"
116 | ]
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": null,
121 | "metadata": {},
122 | "outputs": [],
123 | "source": [
124 | "!ls {dataset_dir}"
125 | ]
126 | },
127 | {
128 | "cell_type": "markdown",
129 | "metadata": {},
130 | "source": [
131 | "## mnistのバイナリデータを numpy 配列にする\n",
132 | "ついでにラベルデータを事前に one-hot encoding しておく"
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {},
139 | "outputs": [],
140 | "source": [
141 | "%%time\n",
142 | "\n",
143 | "file_path = dataset_dir + key_file['train_img']\n",
144 | "with gzip.open(file_path, 'rb') as f:\n",
145 | " train_x = np.frombuffer(f.read(), np.uint8, offset=16).reshape(-1,28,28)\n",
146 | "file_path = dataset_dir + key_file['train_label']\n",
147 | "with gzip.open(file_path, 'rb') as f:\n",
148 | " train_y = np.frombuffer(f.read(), np.uint8, offset=8)\n",
149 | "train_y = np.identity(10)[train_y]\n",
150 | "\n",
151 | "\n",
152 | "file_path = dataset_dir + key_file['test_img']\n",
153 | "with gzip.open(file_path, 'rb') as f:\n",
154 | " test_x = np.frombuffer(f.read(), np.uint8, offset=16).reshape(-1,28,28)\n",
155 | "file_path = dataset_dir + key_file['test_label']\n",
156 | "with gzip.open(file_path, 'rb') as f:\n",
157 | " test_y = np.frombuffer(f.read(), np.uint8, offset=8)\n",
158 | "test_y = np.identity(10)[test_y]"
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {},
164 | "source": [
165 | "## numpy array を 1 枚ずつ png ファイルに出力する\n",
166 | "* [前処理](1_preprocess_kick.ipynb)で hist 平坦化したのち、再度 npy ファイルに変換するため"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {},
173 | "outputs": [],
174 | "source": [
175 | "%%time\n",
176 | "\n",
177 | "# ローカルへ保存\n",
178 | "base_dir = './dataset/'\n",
179 | "train_x_dir = base_dir + 'train_x/'\n",
180 | "test_x_dir = base_dir + 'test_x/'\n",
181 | "\n",
182 | "os.makedirs(train_x_dir, exist_ok=True)\n",
183 | "os.makedirs(test_x_dir, exist_ok=True)\n",
184 | "\n",
185 | "for i in tqdm(range(train_x.shape[0])):\n",
186 | " Image.fromarray(train_x[i,:,:]).save(train_x_dir + str(i).zfill(5) + \".png\")\n",
187 | "\n",
188 | "for i in tqdm(range(test_x.shape[0])):\n",
189 | " Image.fromarray(test_x[i,:,:]).save(test_x_dir + str(i).zfill(5) + \".png\")\n",
190 | "\n",
191 | "np.save(base_dir + 'train_y.npy',train_y)\n",
192 | "np.save(base_dir + 'test_y.npy',test_y)"
193 | ]
194 | },
195 | {
196 | "cell_type": "code",
197 | "execution_count": null,
198 | "metadata": {},
199 | "outputs": [],
200 | "source": [
201 | "!ls -l {base_dir}"
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": null,
207 | "metadata": {},
208 | "outputs": [],
209 | "source": [
210 | "!ls -l {base_dir}train_x | tail -n5"
211 | ]
212 | },
213 | {
214 | "cell_type": "code",
215 | "execution_count": null,
216 | "metadata": {},
217 | "outputs": [],
218 | "source": [
219 | "!ls -l {base_dir}test_x | tail -n5"
220 | ]
221 | },
222 | {
223 | "cell_type": "markdown",
224 | "metadata": {},
225 | "source": [
226 | "## zip ファイルに固める\n",
227 | "* 前処理をする際に zip ファイルに固めたほうが S3 から前処理を行うコンテナへの転送効率が高い(細切れのファイルだと転送に時間がかかる)\n",
228 | "* 解凍処理も前処理に含める"
229 | ]
230 | },
231 | {
232 | "cell_type": "code",
233 | "execution_count": null,
234 | "metadata": {},
235 | "outputs": [],
236 | "source": [
237 | "zip_file = shutil.make_archive('./dataset', 'zip', root_dir='./dataset/')\n",
238 | "print(zip_file)"
239 | ]
240 | },
241 | {
242 | "cell_type": "markdown",
243 | "metadata": {},
244 | "source": [
245 | "## S3 にアップロードする際、一意の URI を指定したいため、設定ファイルの名前を取得"
246 | ]
247 | },
248 | {
249 | "cell_type": "markdown",
250 | "metadata": {},
251 | "source": [
252 | "## SageMaker SDK を利用して 作成した dataset.zip を S3 にアップロード\n",
253 | "* 通常 S3 にアップロードをする際は [boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#client) や [aws cli](https://aws.amazon.com/jp/cli/) を利用する\n",
254 | "* SageMaker SDK はデータサイエンティストのための SDK で boto3 や aws cli などの学習コストを増やさないよう, SageMaker で完結させられる = S3 にアップロードできる機能も持っている\n",
255 | "* upload_data メソッドを利用することで SageMaker のデフォルトバケット(sagemaker-{region}-{account} に 1 行のコードでアップロードできる"
256 | ]
257 | },
258 | {
259 | "cell_type": "code",
260 | "execution_count": null,
261 | "metadata": {},
262 | "outputs": [],
263 | "source": [
264 | "# S3 に dataset.zip をアップロード\n",
265 | "prefix = f'sagemaker-handson-{name}/dataset-{timestamp}'\n",
266 | "zip_dataset_s3_uri = sagemaker.session.Session().upload_data(path=zip_file, key_prefix=prefix)"
267 | ]
268 | },
269 | {
270 | "cell_type": "code",
271 | "execution_count": null,
272 | "metadata": {},
273 | "outputs": [],
274 | "source": [
275 | "# アップロード先などを次のノートブックに引き継ぐため yaml に出力\n",
276 | "with open(\"./setting.yaml\", mode='w') as f:\n",
277 | " f.write('name: ' + name +'\\n')\n",
278 | " f.write('zip_dataset_s3_uri: ' + zip_dataset_s3_uri + '\\n')\n",
279 | " f.write('timestamp: ' + timestamp + '\\n')\n",
280 | "\n",
281 | "with open('./setting.yaml', 'r') as yml:\n",
282 | " config = yaml.load(yml)\n",
283 | "print(config)"
284 | ]
285 | },
286 | {
287 | "cell_type": "code",
288 | "execution_count": null,
289 | "metadata": {},
290 | "outputs": [],
291 | "source": []
292 | }
293 | ],
294 | "metadata": {
295 | "instance_type": "ml.t3.medium",
296 | "kernelspec": {
297 | "display_name": "conda_python3",
298 | "language": "python",
299 | "name": "conda_python3"
300 | },
301 | "language_info": {
302 | "codemirror_mode": {
303 | "name": "ipython",
304 | "version": 3
305 | },
306 | "file_extension": ".py",
307 | "mimetype": "text/x-python",
308 | "name": "python",
309 | "nbconvert_exporter": "python",
310 | "pygments_lexer": "ipython3",
311 | "version": "3.6.10"
312 | }
313 | },
314 | "nbformat": 4,
315 | "nbformat_minor": 4
316 | }
317 |
--------------------------------------------------------------------------------
/sagemaker_processing/processing_with_bring_your_own_container_for_beginner/container/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.7-slim-buster
2 |
3 | RUN pip3 install scikit-image numpy
4 | ENV PYTHONUNBUFFERED=TRUE
5 |
6 | ENTRYPOINT ["python3"]
--------------------------------------------------------------------------------
/sagemaker_processing/processing_with_bring_your_own_container_for_beginner/container/preprocess_code/preprocess.py:
--------------------------------------------------------------------------------
1 | import argparse, os, zipfile
2 | from glob import glob
3 | from PIL import Image
4 | import pandas as pd
5 | import numpy as np
6 |
7 |
8 | def hist_flatten(nparray):
9 | hist,bins = np.histogram(nparray.flatten(),256,[0,256])
10 | cdf = hist.cumsum()
11 | cdf_normalized = cdf * hist.max()/ cdf.max()
12 | cdf_m = np.ma.masked_equal(cdf,0)
13 | cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
14 | cdf = np.ma.filled(cdf_m,0).astype('uint8')
15 | return cdf[nparray]
16 |
17 | cdf = hist.cumsum()
18 |
19 | if __name__=='__main__':
20 | parser = argparse.ArgumentParser()
21 | parser.add_argument('--hist-flatten', type=bool, default=False)
22 | args, _ = parser.parse_known_args()
23 |
24 | print('Received arguments {}'.format(args))
25 |
26 | input_data_path = os.path.join('/opt/ml/processing/input', 'img.zip')
27 |
28 | print(f'decompress {input_data_path}')
29 | with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
30 | existing_zip.extractall()
31 | train_x = np.zeros((len(glob('/opt/ml/processing/input/img/train_x/*.png')),28,28))
32 | test_x = np.zeros((len(glob('/opt/ml/processing/input/img/test_x/*.png')),28,28))
33 |
34 | for i,img_file in enumerate(sorted(glob('/opt/ml/processing/input/img/train_x/*.png'))):
35 | img = np.array(Image.open(img_file))
36 | if args.hist_flatten:
37 | img = hist_flatten(img)
38 | img = img/255.
39 | train_x[i,:,:] = img
40 | for i,img_file in enumerate(sorted(glob('/opt/ml/processing/input/img/test_x/*.png'))):
41 | img = np.array(Image.open(img_file))
42 | if args.hist_flatten:
43 | img = hist_flatten(img)
44 | img = img/255.
45 | test_x[i,:,:] = img
46 |
47 | train_features_output_path = '/opt/ml/processing/train/train_x.npy'
48 | test_features_output_path = '/opt/ml/processing/test/train_x.npy'
49 |
50 | print(f'train_x save: {train_features_output_path}')
51 | np.save('/opt/ml/processing/train/train_x.npy', train_x)
52 | print(f'test_x save: {test_features_output_path}')
53 | np.save('/opt/ml/processing/test/test_x.npy', test_x)
54 |
--------------------------------------------------------------------------------
/sagemaker_processing/processing_with_bring_your_own_container_for_beginner/media/0_data_preparation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/sagemaker_processing/processing_with_bring_your_own_container_for_beginner/media/0_data_preparation.png
--------------------------------------------------------------------------------
/sagemaker_processing/processing_with_bring_your_own_container_for_beginner/media/1_preprocess.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/sagemaker_processing/processing_with_bring_your_own_container_for_beginner/media/1_preprocess.png
--------------------------------------------------------------------------------
/sagemaker_processing/processing_with_bring_your_own_container_for_beginner/media/README.md:
--------------------------------------------------------------------------------
1 | # Amazon SageMaker Processing を独自コンテナで動かすハンズオン
2 |
3 | ## 概要
4 | 本ハンズオンは Amazon SageMaker Processing を独自コンテナで動かすハンズオンです。
5 |
6 | Amazon SageMaker Processing には Scikit-learn や Apache Spark が利用可能な 組み込みコンテナを予め用意していますが、
7 | 組み込みコンテナだけでは不足する時のために、自身で Docker イメージを用意しして Amazon SageMaker Processing を動かすための仕組みも用意しており、
8 | その独自の Docker イメージを準備して、動かすことが体験できるハンズオンです。
9 |
10 | ## 構成
11 |
12 | このハンズオンは二段階の構成を取ってます。
13 |
14 | 1. [0_data_preparation.ipynb](./0_data_preparation.ipynb)
15 | このノートブックは SageMaker があまり関係ありませんが、[mnist のデータ](http://yann.lecun.com/exdb/mnist/)を画像化(png)し、zip 圧縮したものを Amazon S3 に保存する処理が入っています。次のノートブックを実行するためのデータ準備処理のみが記載されています。
16 | 2. [1_preprocess.ipynb](./1_preprocess.ipynb)
17 | Amazon SageMaker Processing を実際に動かすノートブックです。実行する処理は、先のノートブックで Amazon S3 に保存したデータを、zip 解凍し、輝度のヒストグラム平坦化の前処理を行ったあと、numpy ファイル( `.npyファイル`)に保存する処理を行います。これらの処理を行うために、画像を扱うために scikit-image をインストールした Docker イメージをビルドし、 Amazon Elastic Container Registry にプッシュし、 Amazon SageMaker Processing でビルドした Docker Image を用いた処理を行います。
--------------------------------------------------------------------------------
/sagemaker_processing/processing_with_bring_your_own_container_for_beginner/preprocess_script/preprocess.py:
--------------------------------------------------------------------------------
1 | import argparse, os, zipfile
2 | from glob import glob
3 | from skimage import io
4 | import numpy as np
5 | import shutil
6 |
7 | def hist_flatten(nparray):
8 | hist,bins = np.histogram(nparray.flatten(),256,[0,256])
9 | cdf = hist.cumsum()
10 | cdf_normalized = cdf * hist.max()/ cdf.max()
11 | cdf_m = np.ma.masked_equal(cdf,0)
12 | cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
13 | cdf = np.ma.filled(cdf_m,0).astype('uint8')
14 | return cdf[nparray]
15 |
16 | if __name__=='__main__':
17 | parser = argparse.ArgumentParser()
18 | parser.add_argument('--hist-flatten', type=bool, default=False)
19 | parser.add_argument('--input-dir', type=str, default=None)
20 | parser.add_argument('--output-train-dir', type=str, default=None)
21 | parser.add_argument('--output-test-dir', type=str, default=None)
22 |
23 | args, _ = parser.parse_known_args()
24 |
25 | print('Received arguments {}'.format(args))
26 |
27 | input_data_path = os.path.join(args.input_dir, 'dataset.zip')
28 |
29 | print(f'decompress {input_data_path}')
30 | with zipfile.ZipFile(input_data_path) as existing_zip:
31 | existing_zip.extractall(args.input_dir)
32 | train_x = np.zeros((len(glob(args.input_dir + '/train_x/*.png')),28,28,1)).astype('float32')
33 | test_x = np.zeros((len(glob(args.input_dir + '/test_x/*.png')),28,28,1)).astype('float32')
34 |
35 | for i,img_file in enumerate(sorted(glob(args.input_dir + '/train_x/*.png'))):
36 | img = io.imread(img_file)
37 | if args.hist_flatten:
38 | img = hist_flatten(img)
39 | img = img/255.
40 | train_x[i,:,:,0] = img
41 | for i,img_file in enumerate(sorted(glob(args.input_dir + '/test_x/*.png'))):
42 | img = io.imread(img_file)
43 | if args.hist_flatten:
44 | img = hist_flatten(img)
45 | img = img/255.
46 | test_x[i,:,:,0] = img
47 |
48 | train_x_output_path = os.path.join(args.output_train_dir, 'train_x.npy')
49 | train_y_output_path = os.path.join(args.output_train_dir, 'train_y.npy')
50 | test_x_output_path = os.path.join(args.output_test_dir, 'test_x.npy')
51 | test_y_output_path = os.path.join(args.output_test_dir, 'test_y.npy')
52 |
53 | print(f'train_x save: {train_x_output_path}')
54 | np.save(train_x_output_path, train_x)
55 | print(f'train_y save: {train_y_output_path}')
56 | shutil.copyfile(args.input_dir + '/train_y.npy', train_y_output_path)
57 |
58 | print(f'test_x save: {test_x_output_path}')
59 | np.save(test_x_output_path, test_x)
60 | print(f'train_y save: {test_y_output_path}')
61 | shutil.copyfile(args.input_dir + '/test_y.npy', test_y_output_path)
62 |
--------------------------------------------------------------------------------
/tensorflow2_training_and_serving/mnist.py:
--------------------------------------------------------------------------------
1 | # Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License"). You
4 | # may not use this file except in compliance with the License. A copy of
5 | # the License is located at
6 | #
7 | # http://aws.amazon.com/apache2.0/
8 | #
9 | # or in the "license" file accompanying this file. This file is
10 | # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 | # ANY KIND, either express or implied. See the License for the specific
12 | # language governing permissions and limitations under the License.
13 | """Convolutional Neural Network Estimator for MNIST, built with tensorflow.keras.layers."""
14 |
15 | import numpy as np
16 | import tensorflow as tf
17 | import os,json,argparse
18 | from tensorflow.keras.layers import *
19 | from tensorflow.keras.models import *
20 | from tensorflow.keras.optimizers import Adam
21 | from tensorflow.keras.losses import categorical_crossentropy
22 |
23 |
24 | def model():
25 | model = Sequential()
26 | model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
27 | model.add(MaxPooling2D((2, 2)))
28 | model.add(Conv2D(64, (3, 3), activation='relu'))
29 | model.add(MaxPooling2D((2, 2)))
30 | model.add(Conv2D(64, (3, 3), activation='relu'))
31 | model.add(Flatten())
32 | model.add(Dense(64, activation='relu'))
33 | model.add(Dense(10, activation='softmax'))
34 | model.compile(optimizer=Adam(lr=0.0001),metrics=['accuracy'],loss="categorical_crossentropy")
35 | return model
36 |
37 | def _load_mnist_data(base_dir, x, y):
38 | x_data = np.load(os.path.join(base_dir, x)).reshape(-1,28,28,1)
39 | y_data = np.identity(10)[np.load(os.path.join(base_dir, y))]
40 | return x_data, y_data
41 |
42 | def _parse_args():
43 |
44 | parser = argparse.ArgumentParser()
45 | parser.add_argument('--model_dir', type=str)
46 | parser.add_argument('--sm-model-dir', type=str, default=os.environ.get('SM_MODEL_DIR'))
47 | parser.add_argument('--training', type=str, default=os.environ.get('SM_CHANNEL_TRAINING'))
48 | parser.add_argument('--hosts', type=list, default=json.loads(os.environ.get('SM_HOSTS')))
49 | parser.add_argument('--current-host', type=str, default=os.environ.get('SM_CURRENT_HOST'))
50 | parser.add_argument('--epochs', type=int, default=os.environ.get('SM_CURRENT_HOST'))
51 | parser.add_argument('--batch-size', type=int, default=os.environ.get('SM_CURRENT_HOST'))
52 |
53 |
54 | return parser.parse_known_args()
55 |
56 |
57 | if __name__ == "__main__":
58 | args, unknown = _parse_args()
59 |
60 | x_train, y_train = _load_mnist_data(args.training, 'train_data.npy', 'train_labels.npy')
61 | x_valid, y_valid = _load_mnist_data(args.training,'eval_data.npy', 'eval_labels.npy' )
62 |
63 | # Create the Estimator
64 | mnist_classifier = model()
65 | # training
66 | mnist_classifier.fit(
67 | x_train,
68 | y_train,
69 | batch_size=args.batch_size,
70 | epochs=args.epochs,
71 | validation_data=(x_valid,y_valid)
72 | )
73 |
74 | save_model_path = os.path.join(args.sm_model_dir, '000000001')
75 |
76 | if args.current_host == args.hosts[0]:
77 | mnist_classifier.save(save_model_path)
78 |
--------------------------------------------------------------------------------
/workshop/lab_bring-your-own-model/img/sagemaker-data-model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/amazon-sagemaker-examples-jp/5b5c15433de3add68919f26016d744cc119e363e/workshop/lab_bring-your-own-model/img/sagemaker-data-model.png
--------------------------------------------------------------------------------
/workshop/lab_bring-your-own-model/tensorflow/cnn_mnist_after.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | """Convolutional Neural Network Estimator for MNIST, built with tf.layers."""
15 |
16 | from __future__ import absolute_import
17 | from __future__ import division
18 | from __future__ import print_function
19 |
20 | import numpy as np
21 | import tensorflow as tf
22 |
23 | tf.logging.set_verbosity(tf.logging.INFO)
24 |
25 | def serving_input_fn():
26 | inputs = {'x': tf.placeholder(tf.float32, [None, 28, 28], name="input_layer")}
27 | return tf.estimator.export.ServingInputReceiver(inputs, inputs)
28 |
29 | def parse_args():
30 | import argparse, os
31 | parser = argparse.ArgumentParser()
32 | parser.add_argument('--train', type=str, default=os.environ['SM_CHANNEL_TRAIN'])
33 | parser.add_argument('--test', type=str, default=os.environ['SM_CHANNEL_TEST'])
34 | parser.add_argument('--model_dir', type=str)
35 | parser.add_argument('--sm-model-dir', type=str, default=os.environ['SM_MODEL_DIR'])
36 | parser.add_argument('--training-steps', type=int, default=20)
37 | args, _ = parser.parse_known_args()
38 | return args
39 |
40 |
41 | def cnn_model_fn(features, labels, mode):
42 | """Model function for CNN."""
43 | # Input Layer
44 | # Reshape X to 4-D tensor: [batch_size, width, height, channels]
45 | # MNIST images are 28x28 pixels, and have one color channel
46 | input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])
47 |
48 | # Convolutional Layer #1
49 | # Computes 32 features using a 5x5 filter with ReLU activation.
50 | # Padding is added to preserve width and height.
51 | # Input Tensor Shape: [batch_size, 28, 28, 1]
52 | # Output Tensor Shape: [batch_size, 28, 28, 32]
53 | conv1 = tf.layers.conv2d(
54 | inputs=input_layer,
55 | filters=32,
56 | kernel_size=[5, 5],
57 | padding="same",
58 | activation=tf.nn.relu)
59 |
60 | # Pooling Layer #1
61 | # First max pooling layer with a 2x2 filter and stride of 2
62 | # Input Tensor Shape: [batch_size, 28, 28, 32]
63 | # Output Tensor Shape: [batch_size, 14, 14, 32]
64 | pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
65 |
66 | # Convolutional Layer #2
67 | # Computes 64 features using a 5x5 filter.
68 | # Padding is added to preserve width and height.
69 | # Input Tensor Shape: [batch_size, 14, 14, 32]
70 | # Output Tensor Shape: [batch_size, 14, 14, 64]
71 | conv2 = tf.layers.conv2d(
72 | inputs=pool1,
73 | filters=64,
74 | kernel_size=[5, 5],
75 | padding="same",
76 | activation=tf.nn.relu)
77 |
78 | # Pooling Layer #2
79 | # Second max pooling layer with a 2x2 filter and stride of 2
80 | # Input Tensor Shape: [batch_size, 14, 14, 64]
81 | # Output Tensor Shape: [batch_size, 7, 7, 64]
82 | pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
83 |
84 | # Flatten tensor into a batch of vectors
85 | # Input Tensor Shape: [batch_size, 7, 7, 64]
86 | # Output Tensor Shape: [batch_size, 7 * 7 * 64]
87 | pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])
88 |
89 | # Dense Layer
90 | # Densely connected layer with 1024 neurons
91 | # Input Tensor Shape: [batch_size, 7 * 7 * 64]
92 | # Output Tensor Shape: [batch_size, 1024]
93 | dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
94 |
95 | # Add dropout operation; 0.6 probability that element will be kept
96 | dropout = tf.layers.dropout(
97 | inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
98 |
99 | # Logits layer
100 | # Input Tensor Shape: [batch_size, 1024]
101 | # Output Tensor Shape: [batch_size, 10]
102 | logits = tf.layers.dense(inputs=dropout, units=10)
103 |
104 | predictions = {
105 | # Generate predictions (for PREDICT and EVAL mode)
106 | "classes": tf.argmax(input=logits, axis=1),
107 | # Add `softmax_tensor` to the graph. It is used for PREDICT and by the
108 | # `logging_hook`.
109 | "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
110 | }
111 | if mode == tf.estimator.ModeKeys.PREDICT:
112 | return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
113 |
114 | # Calculate Loss (for both TRAIN and EVAL modes)
115 | loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
116 |
117 | # Configure the Training Op (for TRAIN mode)
118 | if mode == tf.estimator.ModeKeys.TRAIN:
119 | optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
120 | train_op = optimizer.minimize(
121 | loss=loss,
122 | global_step=tf.train.get_global_step())
123 | return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)
124 |
125 | # Add evaluation metrics (for EVAL mode)
126 | eval_metric_ops = {
127 | "accuracy": tf.metrics.accuracy(
128 | labels=labels, predictions=predictions["classes"])}
129 | return tf.estimator.EstimatorSpec(
130 | mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
131 |
132 | def main(unused_argv):
133 | args = parse_args()
134 | train_dir = args.train
135 | test_dir = args.test
136 | model_dir = args.model_dir
137 | sm_model_dir = args.sm_model_dir
138 | training_steps = args.training_steps
139 |
140 | #def main(unused_argv):
141 | # Load training and eval data
142 | #mnist = tf.contrib.learn.datasets.load_dataset("mnist")
143 | #train_data = mnist.train.images # Returns np.array
144 | #train_labels = np.asarray(mnist.train.labels, dtype=np.int32)
145 | #eval_data = mnist.test.images # Returns np.array
146 | #eval_labels = np.asarray(mnist.test.labels, dtype=np.int32)
147 |
148 | import os
149 | train_data = np.load(os.path.join(train_dir, 'image.npy')).astype(np.float32) * 1./255
150 | train_labels = np.load(os.path.join(train_dir, 'label.npy')).astype(np.int32)
151 | eval_data = np.load(os.path.join(test_dir, 'image.npy')).astype(np.float32) * 1./255
152 | eval_labels = np.load(os.path.join(test_dir, 'label.npy')).astype(np.int32)
153 | # Create the Estimator
154 |
155 | mnist_classifier = tf.estimator.Estimator(
156 | model_fn=cnn_model_fn, model_dir=model_dir)
157 |
158 | #mnist_classifier = tf.estimator.Estimator(
159 | # model_fn=cnn_model_fn, model_dir="/tmp/mnist_convnet_model")
160 |
161 | # Set up logging for predictions
162 | # Log the values in the "Softmax" tensor with label "probabilities"
163 | tensors_to_log = {"probabilities": "softmax_tensor"}
164 | logging_hook = tf.train.LoggingTensorHook(
165 | tensors=tensors_to_log, every_n_iter=50)
166 |
167 | # Train the model
168 | train_input_fn = tf.compat.v1.estimator.inputs.numpy_input_fn(
169 | x={"x": train_data},
170 | y=train_labels,
171 | batch_size=100,
172 | num_epochs=None,
173 | shuffle=True)
174 | mnist_classifier.train(
175 | input_fn=train_input_fn,
176 | steps=training_steps, #default:20000
177 | hooks=[logging_hook])
178 |
179 | # Evaluate the model and print results
180 | #eval_input_fn = tf.compat.v1.estimator.inputs.numpy_input_fn(
181 | # x={"x": eval_data}, y=eval_labels, num_epochs=1, shuffle=False)
182 | #eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
183 | #print(eval_results)
184 |
185 | # Evaluate the model and print results
186 | eval_input_fn = tf.compat.v1.estimator.inputs.numpy_input_fn(
187 | x={"x": eval_data}, y=eval_labels, num_epochs=1, shuffle=False)
188 | eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
189 | print(eval_results)
190 |
191 | mnist_classifier.export_savedmodel(sm_model_dir, serving_input_fn)
192 |
193 | if __name__ == "__main__":
194 | tf.app.run()
195 |
--------------------------------------------------------------------------------
/workshop/lab_bring-your-own-model/tensorflow/cnn_mnist_before.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | """Convolutional Neural Network Estimator for MNIST, built with tf.layers."""
15 |
16 | from __future__ import absolute_import
17 | from __future__ import division
18 | from __future__ import print_function
19 |
20 | import numpy as np
21 | import tensorflow as tf
22 |
23 | tf.logging.set_verbosity(tf.logging.INFO)
24 |
25 |
26 | def cnn_model_fn(features, labels, mode):
27 | """Model function for CNN."""
28 | # Input Layer
29 | # Reshape X to 4-D tensor: [batch_size, width, height, channels]
30 | # MNIST images are 28x28 pixels, and have one color channel
31 | input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])
32 |
33 | # Convolutional Layer #1
34 | # Computes 32 features using a 5x5 filter with ReLU activation.
35 | # Padding is added to preserve width and height.
36 | # Input Tensor Shape: [batch_size, 28, 28, 1]
37 | # Output Tensor Shape: [batch_size, 28, 28, 32]
38 | conv1 = tf.layers.conv2d(
39 | inputs=input_layer,
40 | filters=32,
41 | kernel_size=[5, 5],
42 | padding="same",
43 | activation=tf.nn.relu)
44 |
45 | # Pooling Layer #1
46 | # First max pooling layer with a 2x2 filter and stride of 2
47 | # Input Tensor Shape: [batch_size, 28, 28, 32]
48 | # Output Tensor Shape: [batch_size, 14, 14, 32]
49 | pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
50 |
51 | # Convolutional Layer #2
52 | # Computes 64 features using a 5x5 filter.
53 | # Padding is added to preserve width and height.
54 | # Input Tensor Shape: [batch_size, 14, 14, 32]
55 | # Output Tensor Shape: [batch_size, 14, 14, 64]
56 | conv2 = tf.layers.conv2d(
57 | inputs=pool1,
58 | filters=64,
59 | kernel_size=[5, 5],
60 | padding="same",
61 | activation=tf.nn.relu)
62 |
63 | # Pooling Layer #2
64 | # Second max pooling layer with a 2x2 filter and stride of 2
65 | # Input Tensor Shape: [batch_size, 14, 14, 64]
66 | # Output Tensor Shape: [batch_size, 7, 7, 64]
67 | pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
68 |
69 | # Flatten tensor into a batch of vectors
70 | # Input Tensor Shape: [batch_size, 7, 7, 64]
71 | # Output Tensor Shape: [batch_size, 7 * 7 * 64]
72 | pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])
73 |
74 | # Dense Layer
75 | # Densely connected layer with 1024 neurons
76 | # Input Tensor Shape: [batch_size, 7 * 7 * 64]
77 | # Output Tensor Shape: [batch_size, 1024]
78 | dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
79 |
80 | # Add dropout operation; 0.6 probability that element will be kept
81 | dropout = tf.layers.dropout(
82 | inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
83 |
84 | # Logits layer
85 | # Input Tensor Shape: [batch_size, 1024]
86 | # Output Tensor Shape: [batch_size, 10]
87 | logits = tf.layers.dense(inputs=dropout, units=10)
88 |
89 | predictions = {
90 | # Generate predictions (for PREDICT and EVAL mode)
91 | "classes": tf.argmax(input=logits, axis=1),
92 | # Add `softmax_tensor` to the graph. It is used for PREDICT and by the
93 | # `logging_hook`.
94 | "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
95 | }
96 | if mode == tf.estimator.ModeKeys.PREDICT:
97 | return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
98 |
99 | # Calculate Loss (for both TRAIN and EVAL modes)
100 | loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
101 |
102 | # Configure the Training Op (for TRAIN mode)
103 | if mode == tf.estimator.ModeKeys.TRAIN:
104 | optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
105 | train_op = optimizer.minimize(
106 | loss=loss,
107 | global_step=tf.train.get_global_step())
108 | return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)
109 |
110 | # Add evaluation metrics (for EVAL mode)
111 | eval_metric_ops = {
112 | "accuracy": tf.metrics.accuracy(
113 | labels=labels, predictions=predictions["classes"])}
114 | return tf.estimator.EstimatorSpec(
115 | mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
116 |
117 |
118 | def main(unused_argv):
119 | # Load training and eval data
120 | mnist = tf.contrib.learn.datasets.load_dataset("mnist")
121 | train_data = mnist.train.images # Returns np.array
122 | train_labels = np.asarray(mnist.train.labels, dtype=np.int32)
123 | eval_data = mnist.test.images # Returns np.array
124 | eval_labels = np.asarray(mnist.test.labels, dtype=np.int32)
125 |
126 | # Create the Estimator
127 | mnist_classifier = tf.estimator.Estimator(
128 | model_fn=cnn_model_fn, model_dir="/tmp/mnist_convnet_model")
129 |
130 | # Set up logging for predictions
131 | # Log the values in the "Softmax" tensor with label "probabilities"
132 | tensors_to_log = {"probabilities": "softmax_tensor"}
133 | logging_hook = tf.train.LoggingTensorHook(
134 | tensors=tensors_to_log, every_n_iter=50)
135 |
136 | # Train the model
137 | train_input_fn = tf.compat.v1.estimator.inputs.numpy_input_fn(
138 | x={"x": train_data},
139 | y=train_labels,
140 | batch_size=100,
141 | num_epochs=None,
142 | shuffle=True)
143 | mnist_classifier.train(
144 | input_fn=train_input_fn,
145 | steps=20000,
146 | hooks=[logging_hook])
147 |
148 | # Evaluate the model and print results
149 | eval_input_fn = tf.compat.v1.estimator.inputs.numpy_input_fn(
150 | x={"x": eval_data}, y=eval_labels, num_epochs=1, shuffle=False)
151 | eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
152 | print(eval_results)
153 |
154 |
155 | if __name__ == "__main__":
156 | tf.app.run()
157 |
--------------------------------------------------------------------------------