はじめに
2019年5月にAWS主催で開催されたAmazon SageMaker 機械学習エンジニア向け体験ハンズオンが、一般に公開されています。
SageMakerを含むAI/MLサービスに興味がわいてきたので、専門知識-データアナリティクスと、機械学習の試験勉強も兼ねてハンズオンを実施したのですが、SageMakerのバージョンが1.xx時代のもので、今は2.xxにバージョンが上がっているため、このまま実施するとあちこちでエラーとなり、どはまりします。
このSageMakerハンズオンを実施する皆様が、私のようにはまらないように、本記事を投稿させていただきます。
ビルトインアルゴリズムを利用したハンズオン
1. 学習の実行でAttributeErroreエラーが発生
学習の実行で、AttributeError: 'Series' object has no attribute 'as_matrix' が発生します。
train_instance_count has been renamed in sagemaker>=2.
See: https://sagemaker.readthedocs.io/en/stable/v2.html for details.
train_instance_type has been renamed in sagemaker>=2.
See: https://sagemaker.readthedocs.io/en/stable/v2.html for details.
AttributeError Traceback (most recent call last)
<ipython-input-4-906e26861145> in <module>
17
18 # automatically upload the training data to S3 and run the training job
---> 19 rcf.fit(rcf.record_set(taxi_data.value.as_matrix().reshape(-1,1)))
~/anaconda3/envs/python3/lib/python3.6/site-packages/pandas/core/generic.py in __getattr__(self, name)
5139 if self._info_axis._can_hold_identifiers_and_holds_name(name):
5140 return self[name]
-> 5141 return object.__getattribute__(self, name)
5142
5143 def __setattr__(self, name: str, value) -> None:
AttributeError: 'Series' object has no attribute 'as_matrix'
以下に対策が記載されていたので、参考にします。
https://zenn.dev/jinwatanabe/articles/5eb172b0ea2587
Python3.7では、pandasでas_matrix()メソッドが非推奨になっています。故に使えない。
以下のようにas_matrix()をvaluesに変更することで動くようになります。
具体的には、以下のas_matrix()をvaluesに変更します。
rcf.fit(rcf.record_set(taxi_data.value.as_matrix().reshape(-1,1)))
↓
rcf.fit(rcf.record_set(taxi_data.value.values.reshape(-1,1)))
上記以外にも推論実行のところにもas_matrix() があるので、valuesに差し替えてください。
修正後に再実行すると、最初に以下のメッセージは出力されますが、SageMakerのバージョン違いのようなので、(結果的には)無視してOKのようです。このメッセージは今後もずっと出力されます。
train_instance_count has been renamed in sagemaker>=2.
See: https://sagemaker.readthedocs.io/en/stable/v2.html for details.
train_instance_type has been renamed in sagemaker>=2.
See: https://sagemaker.readthedocs.io/en/stable/v2.html for details.
Defaulting to the only supported framework/algorithm version: 1. Ignoring framework/algorithm version: 1.
Defaulting to the only supported framework/algorithm version: 1. Ignoring framework/algorithm version: 1.
2.異常を検知するデータの用意でAttributeErrorが発生
異常を検知するデータの用意で、以下のAttributeError: can't set attribute エラーが発生しました。text/csvがcontent_typeとして指定ができないエラーです。これはSageMakerのバージョンが違うことより、構文が異なるため発生しています。
AttributeError Traceback (most recent call last)
<ipython-input-10-6baf8918ddf5> in <module>
1 from sagemaker.predictor import csv_serializer, json_deserializer
2
----> 3 rcf_inference.content_type = 'text/csv'
4 rcf_inference.serializer = csv_serializer
5 rcf_inference.accept = 'application/json'
AttributeError: can't set attribute
このため、以下の構文を
from sagemaker.predictor import csv_serializer, json_deserializer
rcf_inference.content_type = 'text/csv'
rcf_inference.serializer = csv_serializer
rcf_inference.accept = 'application/json'
rcf_inference.deserializer = json_deserializer
SageMaker 2.xxに対応した以下の構文へ差し替えて、再度実行してください。
from sagemaker.serializers import CSVSerializer
from sagemaker.deserializers import JSONDeserializer
rcf_inference.serializer=CSVSerializer()
rcf_inference.deserializer=JSONDeserializer()
この後の「RCFの応用ならびに改善(オプション)」を実行する場合も、上記の修正を実施してください。
具体的には以下の箇所を
from sagemaker.predictor import csv_serializer, json_deserializer
rcf_inference = rcf.deploy(
initial_instance_count=1,
instance_type='ml.m4.xlarge',
)
rcf_inference.content_type = 'text/csv'
rcf_inference.serializer = csv_serializer
rcf_inference.accept = 'appliation/json'
rcf_inference.deserializer = json_deserializer
以下と差し替えてください。
from sagemaker.deserializers import JSONDeserializer
from sagemaker.serializers import CSVSerializer
rcf_inference = rcf.deploy(
initial_instance_count=1,
instance_type='ml.m4.xlarge',
serializer=CSVSerializer(),
deserializer=JSONDeserializer()
)
Deep Learningフレームワークを利用したハンズオン
こちらのハンズオンでもエラーが発生しました。
1.モデルの学習でValueErrorが発生
モデルの学習で、ValueError: framework_version or py_version was None, yet image_uri was also None のエラーが発生しました。
ValueError Traceback (most recent call last)
<ipython-input-3-7583fa72b5e5> in <module>
7 chainer_estimator = Chainer(entry_point='chainer_mnist.py', role=role,
8 train_instance_count=1, train_instance_type=instance_type,
----> 9 hyperparameters={'epochs': 3, 'batch_size': 128})
10
11 chainer_estimator.fit({'train': train_input, 'test': test_input})
~/anaconda3/envs/chainer_p36/lib/python3.6/site-packages/sagemaker/chainer/estimator.py in __init__(self, entry_point, use_mpi, num_processes, process_slots_per_host, additional_mpi_options, source_dir, hyperparameters, framework_version, py_version, image_uri, **kwargs)
129 :class:`~sagemaker.estimator.EstimatorBase`.
130 """
--> 131 validate_version_or_image_args(framework_version, py_version, image_uri)
132 if py_version == "py2":
133 logger.warning(
~/anaconda3/envs/chainer_p36/lib/python3.6/site-packages/sagemaker/fw_utils.py in validate_version_or_image_args(framework_version, py_version, image_uri)
590 if (framework_version is None or py_version is None) and image_uri is None:
591 raise ValueError(
--> 592 "framework_version or py_version was None, yet image_uri was also None. "
593 "Either specify both framework_version and py_version, or specify image_uri."
594 )
ValueError: framework_version or py_version was None, yet image_uri was also None. Either specify both framework_version and py_version, or specify image_uri.
framework_versionとpy_versionが指定されていないのが原因のようなので、
Chainerにframework_versionと、py_versionを明示的に指定すればOKです。
具体的には、以下の箇所を
import subprocess
from sagemaker.chainer.estimator import Chainer
instance_type = 'ml.m4.xlarge'
chainer_estimator = Chainer(entry_point='chainer_mnist.py', role=role,
train_instance_count=1, train_instance_type=instance_type,
hyperparameters={'epochs': 3, 'batch_size': 128})
chainer_estimator.fit({'train': train_input, 'test': test_input})
# Keep the job name for checking training loss later
training_job = chainer_estimator.latest_training_job.name
以下に変更します。train_instance_type=instance_typeに、framework_versionと、py_versionを追加しています。
import subprocess
from sagemaker.chainer.estimator import Chainer
instance_type = 'ml.m4.xlarge'
chainer_estimator = Chainer(entry_point='chainer_mnist.py', role=role,
train_instance_count=1, train_instance_type=instance_type,
framework_version='5.0.0',
py_version='py3',
hyperparameters={'epochs': 3, 'batch_size': 128})
chainer_estimator.fit({'train': train_input, 'test': test_input})
py_version="py3"
# Keep the job name for checking training loss later
training_job = chainer_estimator.latest_training_job.name
最後に
SageMaker 2.xxに対応したハンズオン資料もアップして欲しいですね。今度AWSに開催してもらうよう、相談をしてみようかな。
AWSもAzureも、操作画面やサービスがどんどん変更されるため、手順を作成してもすぐに使えなくなるのは困りものですね…。オンプレのときのように、最低3年間は後方互換を保持するようにしてくれるとありがたいのですが、考え方がオッサン過ぎますでしょうか。
画面が変わるだけならまだしも、今回のようにスクリプトが動きもしないのはどうにかして欲しいですよね。SageMakerのバージョンを1.xxにダウングレードしようとしましたが、結果的にできませんでした。
続いてTranScribeやComprehendも触ってみる予定です。SageMakerの深い勉強はもっと先になりそうです。
それでわ。