Amazon Web Services ブログ

Amazon SageMaker を使用して Word-Pronunciation シーケンスツーシーケンスモデルを作成する

Amazon SageMaker seq2seq は、シーケンス ツー シーケンスタスクで、最新鋭のエンコーダーデコーダーアーキテクチャ (アテンションメカニズムなど) を利用するための非常に単純な方法を提供します。あなたがすべきことは、recordio-protobuf 形式のシーケンスデータと、JSON 形式のボキャブラリマッピングファイルを用意して、それを Amazon Simple Storage Service (Amazon S3) にアップロードすることのみです。その後は、Amazon SageMaker の内蔵アルゴリズムが、あなたに代わって、ディープラーニング (DL) アーキテクチャの構築とトレーニングを行います。

このブログポストでは、あなたに SageMaker seq2seq を習熟してもらうために、サンプルの Amazon SageMaker Word-Pronunciation ノートブックを使って手順に沿って説明します。英語の場合、単語の発音をスペルに基づいてデコードするために、暗黙的ではあるものの複雑なルールがあります。私たちは、アルファベット文字のシーケンスをソース入力として、そしてそれらに対応する音素のシーケンスをターゲット出力として使って、ルールをモデル化します。このモデルの種類は、シーケンス ツー シーケンスと呼ばれます。

seq2seq モデルの用途は、単語と発音の関係に留まりません。他の使用例としては、英語の文章からドイツ語の文章、テキストからサマリ、テキストからタイトル、質問から回答などが挙げられます。このブログポストでは、Amazon SageMaker を使用して、独自のシーケンスデータをデプロイして、独自のカスタム seq2seq モデルを開発する方法について紹介します。

Amazon SageMaker seq2seq は、Apache MXNet を使用した seq2seq モデリングのフレームワークである、Sockeye パッケージをベースにしています。詳細については、この AWS ブログを参照してください。 ただしそこでは、Amazon SageMaker を効果的に機能させるために、異なる入力データ形式が使われており、いくつかのハイパーパラメーターについては名前が変更されています。

データ: カーネギーメロン大学の発音辞書 (cmudict-0.7b)

このブログポストでは、カーネギーメロン大学の発音辞書 (cmudict-0.7b)のデータを使用します。ボキャブラリの単語を音素のシーケンスにマッピングする表音辞書は、テキスト読み上げシステムでは非常に重要です。オリジナルのローデータは、以下のリンク先にあります。

データセット: http://www.speech.cs.cmu.edu/cgi-bin/cmudict

cmudict-0.7b は北米英語の発音辞書であり、134,000 以上の単語-発音のペアが収録されています。私たちのシーケンス ツー シーケンスタスクでこのデータセットを使用することの利点の 1 つは、私たちが結果を、定量的および定性的に、容易に検証することができるということです。

単語-発音のペアのシーケンスは、次の例のようになっています。

ソース: ACKNOWLEDGEMENT
ターゲット: AE0 K N AA1 L IH0 JH M AH0 N T

この例では、ソースの単語の「Acknowledgement」はアルファベットの 15 文字で構成され、対応するターゲットの発音は、11 音素で構成されています。データセットには、「Acknowledgement」よりもはるかに長い文字と音素のシーケンスを持つ単語があったり、はるかに短い単語があったりします。データセット内の単語と音素の最大長は、それぞれ、34 と 32 です。

このブログポストでは、cmudict-0.7b データセットを使って seq2seq モデルをトレーニングすることによって、モデルが入力文字のシーケンスから音素のシーケンスを予測することができるようにする方法について紹介します。

サンプルの Amazon SageMaker Word Pronunciation の例は、ここにあります。

あなたのノートブックインスタンスに SageMaker-Seq2Seq-word-pronunciation.ipynb をアップロードします。また、 create_vocab_proto.py および record_pb2.py も使用します。これは SageMaker-Seq2Seq-word-pronunciation.ipynb が、これら 2 つの Python スクリプトを呼び出すからです。 

データセットの前処理

seq2seq モデルは、ソースシーケンスとそのペアとなるターゲットシーケンスという、2 つのタイプのシーケンスデータを受け付けます。私たちの例では、ソースとターゲットは、それぞれ、単語とそれに対応する発音です。各単語はアルファベット文字シーケンスであり、各発音は音素のシーケンスです。またこのモデルでは、人間が読むことができるシーケンスをマシンが読み取ることができるシーケンスにトークン化するために、文字列から整数にマッピングすることも必要になります。

Amazon SageMaker seq2seq には、vocab.src.json、vocab.trg.json、train.rec、および val.rec の 4 つの入力ファイルが必要です。vocab.src.json と vocab.trg.json は、json 形式の文字列から整数へのボキャブラリマッピングです。train.rec と val.rec は、それぞれ、トレーニングおよび検証データのトークン化されたソース-ターゲットペアを含んでいる recordio-protobuf ファイルです。私たちは、下記のファイルを生成します。

ボキャブラリファイル

下の例に示すように、データセットをダウンロードした後、アルファベット文字と音素を数字にトークン化します。

Source:['A', 'C', 'K', 'N', 'O', 'W', 'L', 'E', 'D', 'G', 'E', 'M', 'E', 'N', 'T']
Target:['AE0', 'K', 'N', 'AA1', 'L', 'IH0', 'JH', 'M', 'AH0', 'N', 'T']

Source:[14 34 61 64 66 88 62 38 36 49 38 63 38 64 78]
Target:[18 61 64 16 62 53 60 63 21 64 78]

文字 A は 14 に、C は 34 に、K は 61 に、N は 64に、… マッピングされます。この文字列から整数へのマッピングが、JSON ファイルで使われるボキャブラリになります。この例では、ソースシーケンスとターゲットシーケンスのそれぞれに対して、合同文字列・整数マッピング (K = 61 や N = 64 など) を作成し、vocab.src.json と vocab.trg.json を生成するために使用します。次の例は、これを示しています。

vocab_dict =

	{
 '<pad>': 0,'<unk>': 1,'<s>': 2,'</s>': 3,'0': 4,'1': 5,'2': 6,
 '3': 7,'4': 8,'5': 9,'6': 10,'7': 11,'8': 12,'9': 13,'A': 14,
 'AA0': 15,'AA1': 16,'AA2': 17,'AE0': 18,'AE1': 19,'AE2': 20,
 'AH0': 21,'AH1': 22,'AH2': 23,'AO0': 24,'AO1': 25,'AO2': 26,
 'AW0': 27,'AW1': 28,'AW2': 29,'AY0': 30,'AY1': 31,'AY2': 32,
 'B': 33,'C': 34,'CH': 35,'D': 36,'DH': 37,'E': 38,'EH0': 39,
 'EH1': 40,'EH2': 41,'ER0': 42,'ER1': 43,'ER2': 44,'EY0': 45,
 'EY1': 46,'EY2': 47,'F': 48,'G': 49,'H': 50,'HH': 51,'I': 52,
 'IH0': 53,'IH1': 54,'IH2': 55,'IY0': 56,'IY1': 57,'IY2': 58,
 'J': 59,'JH': 60,'K': 61,'L': 62,'M': 63,'N': 64,'NG': 65,
 'O': 66,'OW0': 67,'OW1': 68,'OW2': 69,'OY0': 70,'OY1': 71,
 'OY2': 72,'P': 73,'Q': 74,'R': 75,'S': 76,'SH': 77,'T': 78,
 'TH': 79,'U': 80,'UH0': 81,'UH1': 82,'UH2': 83,'UW0': 84,
 'UW1': 85,'UW2': 86,'V': 87,'W': 88,'X': 89,'Y': 90,'Z': 91,
 'ZH': 92
	}

この例では、93 個の文字-音素セットがマッピングされています。あなたは最初の 4 つのインデックスが特殊文字 (<pad> はパッド、<unk> は不明な文字、<s> はシーケンスの始まり、</s> はシーケンスの終わり) として使われていることに気付いたと思います。Amazon SageMaker seq2seq は、この入力形式を受け付けます。したがって、私たち独自のボキャブラリマッピングは、4 のインデックス番号で始まる必要があります。

PAD_SYMBOL = "<pad>" #0
UNK_SYMBOL = "<unk>" #1
BOS_SYMBOL = "<s>" #2
EOS_SYMBOL = "</s>" #3

VOCAB_SYMBOLS = [PAD_SYMBOL, UNK_SYMBOL, BOS_SYMBOL, EOS_SYMBOL]
vocab_dict[PAD_SYMBOL] = 0
vocab_dict[UNK_SYMBOL] = 1
vocab_dict[BOS_SYMBOL] = 2
vocab_dict[EOS_SYMBOL] = 3

これは、ソースとターゲットの JSON ボキャブラリファイルを生成する方法を示しています。

import json
with open('vocab.src.json', 'w') as fp:
    json.dump(vocab_dict, fp, indent=4, ensure_ascii=False)
        
with open('vocab.trg.json', 'w') as fp:
    json.dump(vocab_dict, fp, indent=4, ensure_ascii=False)

これで、vocab.src.json と vocab.trg.json が作成されました。

 recordio-protobuf ファイル

次に、トレーニングおよび検証データの recordio-protobuf ファイルを作成します。recordio-protobuf は、Amazon SageMaker のアルゴリズムが受け付ける標準のデータ I/O 形式です。ノートブックには、「write_to_file」と呼ばれるヘルパー関数が用意されています。

file_type = 'train'
output_file = "train.rec"
write_to_file(trainX, trainY, file_type, output_file)
file_type = 'validation'
output_file = "val.rec"
write_to_file(valX, valY, file_type, output_file)

write_to_file は、ソースシーケンスのスタック (たとえば、trainX <numpy array>) と、そのペアとなるターゲットシーケンス (たとえば、trainY <numpy array>) を入力として受け取り、1 つの出力 protobuf ファイル (たとえば、train.rec) を生成します。 シーケンスのスタックは、下の例に示すような形式です。

Stack of tokenized source sequence
	[array([36, 80, 36, 14, 75]) array([62, 52, 62, 14])
 	array([88, 38, 52, 64, 49, 14, 75, 78]) array([… …]
	
Stack of tokenized target sequence	
	[array([36, 85, 36, 42]) array([62, 57, 62, 21])
 	array([88, 31, 65, 49, 15, 75, 78]) array([… …]

recordio-protobuf は、データを小さなサイズに圧縮します。これでデータ転送に必要な時間が短縮されます。私たちの write_to_file ヘルパー関数は、以下のリンク先にある、create_vocab_proto.py と record_pb2.py からいくつかのサブ関数を借用しています。

vocab.src.json、vocab.trg.json、train.rec、および val.rec が作成できたら、それらを Amazon S3 バケットにアップロードする準備ができたことになります。

4 つのファイルを Amazon S3 にアップロードします。

S3 バケットとフォルダープレフィックスを指定します。S3 バケットのリージョンは、ノートブックならびにトレーニングおよび推論をホストしているインスタンスのリージョンと同一である必要があります。フォルダープレフィックスには、「seq2seq/word-pronunciation」という名前を付けます。

# S3 bucket and prefix
bucket = '<your_s3_bucket_name_here>'
prefix = 'seq2seq/word-pronunciation'  
# i.e.'<your_s3_bucket>/seq2seq/word-pronunciation'

train.rec は train フォルダー、val.rec は validation フォルダー、そして 2 つのボキャブラリファイルは vocab フォルダーにアップロードします。

def upload_to_s3(bucket, prefix, channel, file):
    s3 = boto3.resource('s3')
    data = open(file, "rb")
    key = prefix + "/" + channel + '/' + file
    s3.Bucket(bucket).put_object(Key=key, Body=data)

upload_to_s3(bucket, prefix, 'train', 'train.rec') 
#/<your s3 bucket>/seq2seq/word-pronunciation/train/train.rec
upload_to_s3(bucket, prefix, 'validation', 'val.rec') 
#/<your s3 bucket>/seq2seq/word-pronunciation/validation/val.rec 
upload_to_s3(bucket, prefix, 'vocab', 'vocab.src.json') 
#/<your s3 bucket>/seq2seq/word-pronunciation/vocab/vocab.src.json
upload_to_s3(bucket, prefix, 'vocab', 'vocab.trg.json') 
#/<your s3 bucket>/seq2seq/word-pronunciation/vocab/vocab.trg.json

下のスクリーンショットは、Amazon S3 内のトレーニングデータファイル (train.rec) を示しています。

下のスクリーンショットは、Amazon S3 内の検証データファイル (val.rec) を示しています。

下のスクリーンショットは、Amazon S3 内のボキャブラリデータファイル (vocab.src.json および vocab.trg.json) を示しています。

Word Pronunciation モデルのトレーニング

: ml.p2.xlarge トレーニングインスタンスの場合、トレーニングは約 2 時間かかります。

最初に、Docker コンテナーから内蔵トレーニングイメージを取得します。このトレーニングイメージには、私たちのシーケンスツーシーケンスタスクで使用するエンコーダー-デコーダーモデルアーキテクチャが含まれています。ここで魔法が起きます。

containers = {'us-west-2': '433757028032.dkr.ecr.us-west-2.amazonaws.com/seq2seq:latest',
              'us-east-1': '811284229777.dkr.ecr.us-east-1.amazonaws.com/seq2seq:latest',
              'us-east-2': '825641698319.dkr.ecr.us-east-2.amazonaws.com/seq2seq:latest',
              'eu-west-1': '685385470294.dkr.ecr.eu-west-1.amazonaws.com/seq2seq:latest'}
container = containers[region_name]
print('Using SageMaker Seq2Seq container: {} ({})'.format(container, region_name))

その後、ファイルの場所、インスタンスのトレーニングに関する指示、およびその他のハイパーパラメーターなど、すべてのトレーニングパラメーターをトレーニングジョブに渡す辞書を作成します。

job_name = 'seq2seq-wrd-phn-p2-xlarge-' + strftime("%Y-%m-%d-%H-%M", gmtime())
print("Training job", job_name)

create_training_params = \
{
    "AlgorithmSpecification": {
        "TrainingImage": container,
        "TrainingInputMode": "File"
    },
    "RoleArn": role,
    "OutputDataConfig": {
        "S3OutputPath": "s3://{}/{}/".format(bucket, prefix)
    },
    "ResourceConfig": {
        # Seq2Seq does not support multiple machines. 現在、これは単一マシン、複数の GPU のみをサポートしています
        "InstanceCount": 1,
        "InstanceType": "ml.p2.xlarge", # We suggest one of ["ml.p2.16xlarge", "ml.p2.8xlarge", "ml.p2.xlarge"]
        "VolumeSizeInGB": 50
    },
    "TrainingJobName": job_name,
    "HyperParameters": {
        # Please refer to the documentation for complete list of parameters
        "max_seq_len_source": str(source_sequence_length),
        "max_seq_len_target": str(target_sequence_length),
        "optimized_metric": "bleu", 
        "batch_size": "64", # Please use a larger batch size (256 or 512) if using ml.p2.8xlarge or ml.p2.16xlarge
        "checkpoint_frequency_num_batches": "1000",
        "rnn_num_hidden": "512",
        "num_layers_encoder": "1",
        "num_layers_decoder": "1",
        "num_embed_source": "512",
        "num_embed_target": "512",
        "checkpoint_threshold": "3",
        #"max_num_batches": "2100"
        # Training will stop after 2100 iterations/batches.
        # This is just for demo purposes. より優れたモデルが必要な場合、上記のパラメーターを削除します。
    },
    "StoppingCondition": {
        "MaxRuntimeInSeconds": 48 * 3600
    },
    "InputDataConfig": [
        {
            "ChannelName": "train",
            "DataSource": {
                "S3DataSource": {
                    "S3DataType": "S3Prefix",
                    "S3Uri": "s3://{}/{}/train/".format(bucket, prefix),
                    "S3DataDistributionType": "FullyReplicated"
                }
            },
        },
        {
            "ChannelName": "vocab",
            "DataSource": {
                "S3DataSource": {
                    "S3DataType": "S3Prefix",
                    "S3Uri": "s3://{}/{}/vocab/".format(bucket, prefix),
                    "S3DataDistributionType": "FullyReplicated"
                }
            },
        },
        {
            "ChannelName": "validation",
            "DataSource": {
                "S3DataSource": {
                    "S3DataType": "S3Prefix",
                    "S3Uri": "s3://{}/{}/validation/".format(bucket, prefix),
                    "S3DataDistributionType": "FullyReplicated"
                }
            },
        }
    ]
}

sagemaker_client = boto3.Session().client(service_name='sagemaker')
sagemaker_client.create_training_job(**create_training_params) 

seq2seq モデル内には、エンコーダーとデコーダーの 2 つのブロックが存在します。各ブロックは、埋め込み型および (複数の) 再帰型ニューラルネットワークレイヤーで構成されています。これらのレイヤーに対応する指示は、前にカバーした“HyperParameters”キーに含まれています (すなわち、“rnn_num_hidden”: “512”、“num_layers_encoder”: “1”、“num_layers_decoder”: “1”、“num_embed_source”: “512”、“num_embed_target”: “512”)。また、ルオンその他の論文で解説されているアテンションメカニズムは、concat として、SageMaker seq2seq モデルにデフォルトで実装済みです。パラメーター「rnn_attention_type」のデフォルト値は mlp ですが、ルオンその他の論文では、concat と呼ばれています。同様に、この論文では、値 bilineargeneral と呼ばれています。

「InputDataConfig」を見てください。そこでは、すべての入力ファイルの場所が指示されています。

トレーニングを開始したら、以下のコマンドを実行してトレーニングステータスを監視します。

### ステータスのチェックは「Completed (完了)」のメッセージが表示されるまで継続してください。###

status = sagemaker_client.describe_training_job(TrainingJobName=job_name)['TrainingJobStatus']
print(status)
# if the job failed, determine why
if status == 'Failed':
    message = sagemaker_client.describe_training_job(TrainingJobName=job_name)['FailureReason']
    print('Training failed with the following error: {}'.format(message))
    raise Exception('Training job failed') 

「InProgress」を返してきた場合、トレーニングは継続中です。ml.p2.xlarge トレーニングインスタンスの場合、以前示したパラメーターだと、約 2 時間かかります。「Completed」が返されると、トレーニングは正常終了しています。Amazon S3 バケットには、出力モデルアーティファクト (model.tar.gz) が含まれています。

model.tar.gz の内容は、次のとおりです。

symbol.json はモデル構造ファイルです。また、params.best はモデルウェイトです。decode.source と decode.target は、トークン化されたソースおよびターゲットシーケンスの説明が行ごとに付けられているテキストファイルです。これらは検証データセットから作成されたものです。「bleu_sample_size」パラメーターを使用すれば、decode.source と decode.target のサンプルのサイズを選択することができます。一連の decode.output.XXXXX は、チェックポイントごとの予測出力の追跡ファイルです。metrics ファイルは、トレーニングおよび検証精度の変化の追跡ファイルです。

推論のホスト

ここで、トレーニング済みのモデルを使用して推論を実行します。3 つのステップで実行します。最初に、トレーニングの出力から Amazon SageMaker モデルを作成します。

%%time

sage = boto3.client('sagemaker')

info = sage.describe_training_job(TrainingJobName=job_name)
model_name=job_name
model_data = info['ModelArtifacts']['S3ModelArtifacts']

print(model_name)
print(model_data)

primary_container = {
    'Image': container,
    'ModelDataUrl': model_data
}

create_model_response = sage.create_model(
    ModelName = model_name,
    ExecutionRoleArn = role,
    PrimaryContainer = primary_container)

print(create_model_response['ModelArn'])

次に、エンドポイント構成を作成します。エンドポイント構成にも、モデルをホストする場合に使われる EC2 推論インスタンスのタイプと数に関する情報が含まれています。私たちはこの例をホストするために無料利用枠の ml.m4.xlarge CPU インスタンスを使用していますが、より安定した、リクエストをより高速に処理できる ml.p2xlarge GPU インスタンスをお勧めします。

from time import gmtime, strftime

endpoint_config_name = 'Seq2SeqEndpointConfig-' + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
print(endpoint_config_name)
create_endpoint_config_response = sage.create_endpoint_config(
    EndpointConfigName = endpoint_config_name,
    ProductionVariants=[{
        'InstanceType':'ml.m4.xlarge', #####
        'InitialInstanceCount':1,
        'ModelName':model_name,
        'VariantName':'AllTraffic'}])

print("Endpoint Config Arn: " + create_endpoint_config_response['EndpointConfigArn'])

最後に、検証可能で、本番アプリケーションに導入することができるエンドポイントを作成します。初めてエンドポイントをセットアップする場合、約 10~15 分かかります。エンドポイントのセットアップが済んだら、追加の遅れを招くことなく、後続するリクエスト用に使用することができます。

%%time
import time

endpoint_name = 'Seq2SeqEndpoint-' + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
print(endpoint_name)
create_endpoint_response = sage.create_endpoint(
    EndpointName=endpoint_name,
    EndpointConfigName=endpoint_config_name)
print(create_endpoint_response['EndpointArn'])

resp = sage.describe_endpoint(EndpointName=endpoint_name)
status = resp['EndpointStatus']
print("Status: " + status)

# wait until the status has changed
sage.get_waiter('endpoint_in_service').wait(EndpointName=endpoint_name)

# print the status of the endpoint
endpoint_response = sage.describe_endpoint(EndpointName=endpoint_name)
status = endpoint_response['EndpointStatus']
print('Endpoint creation ended with EndpointStatus = {}'.format(status))

if status != 'InService':
    raise Exception('Endpoint creation failed.')

ここで、推論が実行される様子を示します。私たちは、「tapeworm」と「tapdance」という単語がオリジナルの cmudict-0.7b データセットには入っていなかったことを知っています。また、言うまでもありませんが、「supercalifragilistic」や「expialidocious」などの単語も入っていませんでした。

words_infr = ["car",
        "cat",
        "tapeworm",
        "tapdance",
        "supercalifragilistic",
        "expialidocious"]

payload = {"instances" : []}
for word_infr in words_infr:
    
    payload["instances"].append({"data" : " ".join(list(word_infr.upper()))})

response = runtime.invoke_endpoint(EndpointName=endpoint_name, 
                                   ContentType='application/json', 
                                   Body=json.dumps(payload))

response = response["Body"].read().decode("utf-8")
response = json.loads(response)
print(response)

ここに推論の結果を示します。

'car': 'K AA1 R'
'cat': 'K AE1 T'
'tapeworm': 'T EY1 P W ER2 M'
'tapdance': 'T AE1 P D AE2 N S'
'supercalifragilistic': 'S UW2 P ER0 K AE2 L AH0 F R AE1 JH AH0 L IH2 S T IH0 K' 
'expialidocious': 'EH2 K S P IY2 AH0 L AH0 D OW1 SH AH0 S'

まとめ

Amazon SageMaker seq2seq は、トークンのシーケンスを入力とし、別のトークンのシーケンスを出力として生成する、監修済みのラーニングアルゴリズムです。私たちはエンドツーエンドのサンプルノートブックを手順に沿って説明してきました。私たちは cmudict-0.7b データセットを使って単語発音モデルをトレーニングし、推論をホストしました。あなたは異なるハイパーパラメーターセットを使った場合の予測精度の変化を調べたいと思っているかもしれません。あるいは、プラグアンドプレイ型のソリューションを必要としているのなら、発言をアプリケーションに素早く統合することができる API 主導型のサービスである Amazon Polly を調べてください。Amazon Polly はレキシコンをサポートしているので、単語の発音は容易にカスタマイズすることができます。

あなたは、独自のペアのシーケンスデータを用いてカスタム seq2seq モデル (テキストの要約、Q&A モデリング、テキストからのタイトル生成、機械翻訳など) を開発することができるようになりました。あなたは、train.rec、val.rec、vocab.src.json、および vocab.trg.json を生成して、それらを Amazon S3 にアップロードし、トレーニングを実行することができるようになりました。Amazon SageMaker ノートブックには、UEDIN の Machine Translation Group が提供する言語データに基づく英語・ドイツ語機械翻訳モデルの作成に役立つサンプルの seq2seq が付属しています。 サンプルのノートブックを調べることもお勧めします。あるいは、現在プレビュー中のニューラルマシン翻訳サービスである Amazon Translate を使ってみてください。


その他の参考資料

このポストでは、NMT の概要を示した後、Sockeye を使って、最小限の NMT モデルを注意深くトレーニングする方法を紹介しています


今回のブログ投稿者について

Tatsuya Arai Ph.D. は、Amazon Machine Learning Solutions Lab チームでディープラーニングデータサイエンティストになったバイオメディカルエンジニアです。  彼は AI の真の民主化を信じており、AI のパワーはコンピューターサイエンティストや数学者の専用とすべきではないと考えています。

Orchid Majumder は、SageMaker Algorithms チームのソフトウェアエンジニアです。以前彼は、Amazon India Seller Experience チームのソフトウェアエンジニアとして働いていました。彼は余暇には、フィクションを読んだり、クリケットを見たりすることを好んでいます。

Saurabh Gupta は、AWS ディープラーニングの応用科学者です。Saurabh はカリフォルニア大学サンディエゴ校で AI と Machine Learning の修士号を取得しました。現在、Amazon SageMaker の自然言語処理アルゴリズムの構築に携わっています。

David Arpin は AWS の AI Platforms Selection Leader で、データサイエンスチームと製品管理を統率してきた経歴があります。

Sunil Mallya は AWS Deep Learning チームのシニアソリューションズアーキテクトです。彼は、お客様のビジネスを拡大するために機械学習と深層学習のソリューション構築を支援しています。プライベートな時間には、料理、セーリング、RC 自動運転カーの製作を楽しんでいます。