sagemakerで簡易電力予測ページを作ってみた

前回エンドポイント作るまではできたけどそこからどうやってそのエンドポイントを使ったらいいかわからず1日うーーーんってやってたらできたので記事にしてみました。

できたもの

FireShot Capture 36 - 消費電力予測 - http___localhost_8000_.png
作ったものはすごくシンプルでこのフォームに好きな数字を入れて送信ボタンを押下したら

電力予測結果.png
こんな感じで予測消費電力が返って来るっていうもの

ハマったとこ

このページ自体はflaskを使っていて
フォーム作ったりフォームの内容をPOSTして〜ってところは
色々調べていたらできたのですがハマったのは
どうやったら予測消費電力が返って来るか、というところ
読解力が乏しいので色んな記事やら読んでも理解できず……
AWSのブログにlambdaにこうやったら使えるよっていうのが
書いてあったのでそれを使ってみることに…

import boto3

sagemaker = boto3.client('sagemaker-runtime')
result = sagemaker.invoke_endpoint(
      EndpointName='test',
      Body=pre_data
    )

でもデータの形をどうすればいいかわからず(モデル作成はcsvファイルでやってました)
配列を渡したり適当にオブジェクトにしたりcsvに変換してs3に落としてみたり….色々やっていたのですがずっとエラーが出っ放しでした。
特に出てたエラーが

Received client error (400) from model with message "unable to evaluate payload provided". See https://us-east-1.console.aws.amazon.com/cloudwatch/~~~ (Service: AmazonSageMakerRuntime; Status Code: 424; Error Code: ModelError; Request ID: null)

全然意味がわかんないしCloudWatch見ても訳がわからん状態でした。
色々調べてたらsagemaker.invoke_endpointの引数にContentType='text/csv'って入れたらいいよってここに書いてあったので入れたけど結局データの形をどうしたらいいかわからずまたエラー

Invalid type for parameter Body, value: [12, 0, 12, 12.0, 0], type: <class 'list'>, valid types: <class 'bytes'>, <class 'bytearray'>, file-like object

エラーを読んでみるとfile-like objectにしろって書いてある…
でもfile-like objectが何かわからないで調べていたら

ファイルオブジェクトには実際には 3 種類あります: 生の バイナリーファイル、バッファされた バイナリーファイル、そして テキストファイル です。

ってここにありました。
テキストファイルってことは、モデル作るときcsvだったしカンマ区切りか!って思ってカンマ区切りでデータを送ったら

from flask import Flask, render_template, request, redirect
import json
import boto3

app = Flask(__name__)
@app.route('/')
def index():
  return render_template('/sagemaker.html')

@app.route('/predict', methods=['POST'])
def predict():
  if request.method == 'POST':
    month = request.form['month']
    week = request.form['week']
    time = request.form['time']
    temp = request.form['temp']
    weather = request.form['weather']
    pre_data_str = month + "," + week + "," + time + "," + temp + "," + weather
    sagemaker = boto3.client('sagemaker-runtime', region_name='us-east-1')
    result = sagemaker.invoke_endpoint(
      ContentType='text/csv',
      EndpointName='test',
      Body=pre_data_str
    )
    result_body = json.load(result['Body'])
    pre = int(float(result_body['predictions'][0]['score']))
    return render_template('/predict.html', predict=pre)
  else:
    return redirect('/')

if __name__ == '__main__':
  app.run(port=8000, debug=True)

いけました!
わからんすぎて本当に投げそうになったけど最後まで頑張ってよかったです。

これを次はlambdaで使ってみて、その後カスタムでやってみようと思います。

続きを読む

SageMakerでlinear learnerを使うときにハマったのでメモ

sageMakerを使ってみていてジョブの作成時にめちゃめちゃハマったのでメモ
(ハマった部分だけ記載しているので他の部分は割愛します)

とりあえずデフォルトで用意されている学習法を使ってみようと思い今回はliner learnerを選択。
トレーニングデータは自前で用意していました。

Kobito.yVk02D.png

それで今回ハマったのはチャネルの作り方とトレーニングデータの作り方。
もともと作成していたトレーニングデータは1~5列目に説明変数、6列目に目的変数を記載していました。
コンテンツタイプにtext/csv;label_size=<num><num>に目的変数が記載してある列番号書いとけばいいのかなって思ったのでtext/csv;label_size=6ってしてジョブを作成していたのですが何度やってもfailed…
ヘッダつけてるからダメなのかなって思ってヘッダ消したけどやっぱダメでした。
結局AWSのドキュメント見て気づいたのですが
コンテンツタイプをtext/csvにしてトレーニングデータの1列目に目的変数を記載してねって書いてあったのでトレーニングデータを書き換えることで無事にジョブが通りました。

まだモデル作成等はやっていないのでこれからやります。

追記

記事書いた直後にモデル作成とかもやったのですがモデル、エンドポイントの作成では特にハマることなくできました
ただエンドポイントを作成してどうやって使ったらいいのか全くわからない……
どなたかわかる方がいらっしゃいましたらご享受お願いします

追記2

エンドポイント作成して実際に使うことができましたので記事にしました
やったね

続きを読む

カテゴリー 未分類 | タグ