【Google Cloud Platform】初めてやるクラウドでの機械学習③

[【Google Cloud Platform】初めてやるクラウドでの機械学習①](http://qiita.com/yujiG/items/36a31d0795b2c2709476)
[【Google Cloud Platform】初めてやるクラウドでの機械学習②](http://qiita.com/yujiG/items/ddd83c60a8ba8f70de1d)

これまでは、クラウドの登録〜チュートリアルの解説、クラウドでの学習の実践を行いました。
今回はクラウドでの学習結果を用いて予測をしましょう。:thinking:

#読み込みと再学習
再読み込みにはグーグルのストレージ上にあるパスを指定して、restoreするだけで復活出来る
あとは前回と同じように保存すればok

restoreの指定先はローカルでも大丈夫だ。

ちなみに本当は最初に学習したファイルと再学習用のファイルの中身は違うものでないと意味がないのでお気をつけて
（もう一個ファイル用意するのめんどくさかった・・・）

```predict.py
# -*- coding: utf-8 -*-

import tensorflow as tf
import tensorflow.contrib.slim as slim

# CSVをparse(トレーニング用)
filename_queue = tf.train.string_input_producer(["ローカルのパス/sazae_train.csv"])
reader = tf.TextLineReader()
key, value = reader.read(filename_queue)
output1, output2, output3, input1, input2 = tf.decode_csv(value, record_defaults=[[1], [1], [1], [1.0], [1.0]])
inputs = tf.stack([input1, input2])
output = tf.stack([output1,output2,output3])

# Batch作成
inputs_batch, output_batch = tf.train.shuffle_batch([inputs, output], 3, capacity=60, min_after_dequeue=40)
# NNの生成
hiddens = slim.stack(inputs_batch, slim.fully_connected, [2,4], activation_fn=tf.sigmoid, scope="hidden")
prediction = slim.fully_connected(hiddens, 3, activation_fn=tf.nn.softmax, scope="output")
# 誤差の計算
loss = slim.losses.softmax_cross_entropy(prediction, output_batch)
# 重みの更新オペレーション
train_op = slim.optimize_loss(loss, slim.get_or_create_global_step(), learning_rate=0.01, optimizer='Adam')
# リセット
init_op = tf.initialize_all_variables()

# トレーニング関数
def run_training():
  with tf.Session() as sess:
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)
    saver = tf.train.Saver()
  # ミニバッチ処理ループ
    try:
      sess.run(init_op)

      # ここで保存した学習結果の再読み込みをしています
      saver.restore(sess, "gs://ストレージ名/ジョブ名/train/checkpoint-1999")

      for i in range(10):
            _, t_loss = sess.run([train_op, loss])
            pre, kati, te = sess.run([prediction, output_batch, inputs_batch])
            # print t_loss
            print pre
            print te
            print kati
            print ''
            if (i + 1) % 9 == 0:
                saver.save(sess, 'どこに保存するか指定してね')
    finally:
      coord.request_stop()
      coord.join(threads)

def main(_):
  run_training()

if __name__ == '__main__':
  tf.app.run()

```

補足ですが、`_, t_loss = sess.run([train_op, loss])`をコメントアウトすれば、再学習（重みの更新）をしないので、手元にあるファイルを学習モデルに突っ込んで結果を得るだけ、なんてこともできる。:boy:

#restoreの注意点
チェックポイントごとでストレージに保存される際、ファイルに名は別の名前で保存されるように
`指定した名前` + `-1999`みたいな形で保存される
restoreする時に`-1999`を忘れてエラーになったりするぞ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150607/65102c2c-a3c2-3ed9-09ae-9a97484b427f.png)

#クラウドで再読み込みと再保存
クラウドで再読み込みと再保存はとても簡単で、最初にデプロイした時みたいにトレーニングジョブを送信する形で実行して、実行するファイルにrestoreを書き込むだけ！:yum:ちょろい

クラウドで実行するのでcsvファイルはクラウドに存在するのを使ってね

```predict.py
# -*- coding: utf-8 -*-

import tensorflow as tf
import tensorflow.contrib.slim as slim

# CSVをparse(トレーニング用)
filename_queue = tf.train.string_input_producer(["gs://ストレージ名/sazae_train.csv"])
reader = tf.TextLineReader()
key, value = reader.read(filename_queue)
output1, output2, output3, input1, input2 = tf.decode_csv(value, record_defaults=[[1], [1], [1], [1.0], [1.0]])
inputs = tf.stack([input1, input2])
output = tf.stack([output1,output2,output3])

# Batch作成
inputs_batch, output_batch = tf.train.shuffle_batch([inputs, output], 3, capacity=60, min_after_dequeue=40)
# NNの生成
hiddens = slim.stack(inputs_batch, slim.fully_connected, [2,4], activation_fn=tf.sigmoid, scope="hidden")
prediction = slim.fully_connected(hiddens, 3, activation_fn=tf.nn.softmax, scope="output")
# 誤差の計算
loss = slim.losses.softmax_cross_entropy(prediction, output_batch)
# 重みの更新オペレーション
train_op = slim.optimize_loss(loss, slim.get_or_create_global_step(), learning_rate=0.01, optimizer='Adam')
# リセット
init_op = tf.initialize_all_variables()

# トレーニング関数
def run_training():
  with tf.Session() as sess:
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)
    saver = tf.train.Saver()
  # ミニバッチ処理ループ
    try:
      sess.run(init_op)

      # 保存した学習結果の再読み込み
      saver.restore(sess, "gs://ストレージ名/ジョブ名/train/checkpoint-1999")

      for i in range(10):
            _, t_loss = sess.run([train_op, loss])
            pre, kati, te = sess.run([prediction, output_batch, inputs_batch])
            if (i + 1) % 9 == 0:
                checkpoint_file = os.path.join(FLAGS.train_dir, 'checkpoint')
                saver.save(sess, checkpoint_file, global_step=i)
    finally:
      coord.request_stop()
      coord.join(threads)

def main(_):
  run_training()

if __name__ == '__main__':
  tf.app.run()

```

いつものように実行場所で実行してください。

```jikkou
# 移動
cd ~/google-cloud-ml/samples/mnist/deployable/

# 前準備色々
JOB_NAME=mnist_deployable_${USER}_$(date +%Y%m%d_%H%M%S)
PROJECT_ID=`gcloud config list project --format "value(core.project)"`
TRAIN_BUCKET=gs://${PROJECT_ID}-ml
TRAIN_PATH=${TRAIN_BUCKET}/${JOB_NAME}
gsutil rm -rf ${TRAIN_PATH}

#　送信
gcloud ml-engine jobs submit training ${JOB_NAME} --module-name=trainer.predict_cl --package-path=trainer --staging-bucket="${TRAIN_BUCKET}" --region=us-central1 -- --train_dir="${TRAIN_PATH}/train"
```

#もう終わり
以上でGoogle Cloud Machine Learningの基礎的な使い方を終了します。
自分の勉強結果をまとめるという側面も兼ねてqiitaを書きましたが、最終的に感じた事は
「自分用のGPUハイスペックマシンを買って、ローカルで全部やれ」だと思います。

クラウドでやると、エラーになるまでが遅すぎ、エラーの確認めんどくさすぎ、勝手にアップデートしすぎ
何より、tensorflowのリファレンスかと思いきや、クラウドに送信する用の仕様というのがイライラする。
まあ、色々起こります。

逆に企業でこれ使ってる人いるの:thinking:と疑問に思いますね。

でもまあ、慣れればローカルと同じように使えるので大規模な奴は今度クラウドでやてみようかなと思いました。