よくわかんないけどMicrosoft AzureでChainer動かしてみた

# はじめに
**よくわかんないけど，まぁ動けばいいや**がテーマです．

で，クラウドコンピューティングについて調べる機会がありまして．
Amazon Web Service(AWS)，Google Cloud Platform(GCP)，Microsoft Azureの3つやったら
どれがいいんやか？ということで昔AWS試したことがあったんでAzureやってみました．
やってみたのでメモ程度に．
GCPにしなかった理由は後程．

##こんな人向け
クラウドコンピューティング入門者かつchainerやってる人
GPUマシン持ってないけど，買うつもりもない，クラウドで出来たらなーって人

ちなみに，今回はGPU使ってません．
一番安いインスタンスには(たぶん)GPUオプションがなかったからです．
→違っていたらコメント下さい．修正します．

#比較
2018/08/21に**30分**かけて上の3つについて調べました．
キーワードは，無料でどれだけの期間使えるのか，演算資源をどれだけ使えるのか．
期限は全部12ヵ月でした．

| 名称   | ストレージ | 無料提供|
|:-----------|:------------|:------------|
| AWS　　| 25GB(無期限)　　　 | インスタンス稼働時間(750時間) |
| GCP　　| 30GB(無期限) 　　　| クレジット(＄300) |
| Azure　| 64*2GB(12ヵ月) 　　　| クレジット(22,500円)，インスタンス稼働時間(750時間) |

本当はもっといろんな項目で比較，検討できるんでしょうけど，
個人的に大事だったのは一番右の"無料提供"．
で，書いてないですが，機械学習に関してはAzureが一番無料で提供されているものが多かったです．
自分の印象では．

#環境構築
まずは[Microsoft Azure公式](https://azure.microsoft.com/ja-jp/)からSignInしましょう．
Microsoftアカウント持ってない人は作りましょう．

##リソースの作成
ここから画像いっぱい貼りますが，サイズとか一切考えていないのでご注意ください．
まずは左上の“リソースの作成”->"Ubuntu Server"を選択．
人気順に出てくるとは思いますが，出てなかったら検索窓に打って検索です．
![step0.JPG](https://qiita-image-store.s3.amazonaws.com/0/165289/bcee3f0a-27f0-cc95-1019-65625a97e448.jpeg)

##1.基本-基本設定の構成
*名前：インスタンスの名前．ほとばしるネーミングセンスが求められます．
*ユーザ名：SSHとかでログインするときに必要になる
*認証の種類：SSHとかでログインするときに必要になる．好みでどうぞ．
*パスワード：認証の種類をパスワードにすると出てきます．公開鍵の人は鍵に関するボックスが出てきた気がします．
*Azure Active Directoryでログインする：しない．よくわかんない．
*リソースグループ：新規作成．
*場所：米国東部(デフォルト)
![step1.JPG](https://qiita-image-store.s3.amazonaws.com/0/165289/f0d89578-19c4-c01d-82a9-3edfaa8a9061.jpeg)
これで"OK"押します．

**2.サイズ-仮想マシンのサイズ選択
今回はテストなので一番金額の安い一番上のやつを選んでみました．
![step2.JPG](https://qiita-image-store.s3.amazonaws.com/0/165289/d75411f3-0785-80ef-0e30-a75185a18b77.jpeg)
これで"選択"押します．

**3.設定-完了
上の方は入力するところがなかったのでスクロールバーを下げます．
*パブリック受信ポートを選択：HTTP,HTTPS,SSHを選択．なんとなくです．SSHだけでも良かったです．
*診断ストレージアカウント・必要な設定の構成
->ストレージアカウントの選択：新規作成
->ストレージアカウントの作成：*名前：新規作成しましょう．ここもほとばしるネーミングセンスがいります．
![step3.JPG](https://qiita-image-store.s3.amazonaws.com/0/165289/4b6480e8-cb5c-aa17-9a16-80df12362661.jpeg)
ストレージアカウントの作成に"OK"して設定も"OK"押します．

**4.概要-Ubuntu Server 18.04.LTS
なんだか勝手に作成できるか診断してくれるようです．
![step4.JPG](https://qiita-image-store.s3.amazonaws.com/0/165289/b2960101-7e8a-d53c-4447-9761195da2da.jpeg)
"OK"押すしかありません．
ちなみに，持っているクレジットを超えるサーバを立てようとするとエラー吐きます．
これでリソースの作成は終わりです．

##インスタンスへアクセス
インスタンスへアクセスして環境を整えましょう．
自分は[Tera Term](https://ja.osdn.net/projects/ttssh2/)を使ってSSH接続しました．
ここは各々お好みでどうぞ．
ユーザ名は1.基本-基本設定で打ち込んだやつです．
パスワードor公開鍵も同様です．
IPアドレスは，ホーム->インスタンス名->概要，で表示される"パブリックIPアドレス"です．
動的に与えられるのでインスタンスを"開始"したり"停止"したりするたびに切り替わります(たぶん)．
もし僕のサーバに繋がってしまったらそっと閉じて下さい．
![step5.JPG](https://qiita-image-store.s3.amazonaws.com/0/165289/57ba8c5e-8679-30ff-d7fa-5fdfd330e7de.jpeg)
これでアクセスできましたね(たぶん)．

##chianerのインストール
ここで1つ白状しますが，本当はjupyter notebookを使いたかった．
なので，[この記事](https://qiita.com/cafedrip/items/f944f72016ced4ff4361)を参考にしてanacondaいれました．
ちなみに，jupyter notebookはなぜかアクセスできませんでした(悔しい)．
というわけで，anacondaを入れて下さい．
入れた人は

```
conda install chainer
```

嫌な人は

```
pip install numpy
pip install chainer
```

でいいのではないでしょうか．

#MNISTを使ってAEを訓練
ここまでで超基本的な環境の構築ができた(はず)なのでここから深層学習していきます．
おなじみのMNISTデータセットを使って自己符号化器(Autoencoder,AE)を訓練します．
コードは文末に添付しておきます．
出力はエポックが進むだけ，MNISTデータセットでLossが下がってても面白くないので，学習の様子は確認しません．
先に出力結果を載せます．
![step8.JPG](https://qiita-image-store.s3.amazonaws.com/0/165289/70cdb7e2-e4a7-88ad-848b-4aadea98121e.jpeg)

さて問題はコードの編集です．
SSH接続でCUI操作．そうviコマンドによるviを使った編集．
あぁ，怖い．
[この記事](https://7ka.org/ubuntu_terminal_vim/)を参考に，編集モードへのコマンドの切り替えと保存の方法をマスターしましょう．
幸い貼り付けは使えます．
と、いうわけでこんな感じでディレクトリ作って，ファイル作ってviで編集しましょう．

```
mkdir test
cd test
touch test_mnist.py
vi test_mnist.py
```

編集が終わったら実行するだけ．

```
python test_mnist.py
```

PYTHONパスが通ってればこれでオッケーですね．


##コード
コードです．
動けばいいやって感じなので，物足りない人はチューニングして下さい．
旧時代の人間なので，trainerとかupdatorとか使~~い~~えません．

```test_mnist.py
import numpy as np
import chainer
from chainer import links as L
from chainer import functions as F

class test(chainer.Chain):
    def __init__(self):
        super(test, self).__init__(
            l1 = L.Linear(784, 100),
            l2 = L.Linear(100, 784),
        )
    def __call__(self, x):
        h = F.relu(self.l1(x))
        return self.l2(h)

ae = test()
opt = chainer.optimizers.Adam()
opt.use_cleargrads()
opt.setup(ae)

train,  test = chainer.datasets.get_mnist(ndim=1)
train_len = len(train)
train_data, train_label = train._datasets

for i in range(0,100):
    perm = np.random.permutation(train_len)
    print('epoch :',i)
    for j in range(0, train_len, 200):
        x = chainer.Variable(np.asarray(train_data[perm[j:j+200]], dtype=np.float32))
        """
        1.forward
        """
        z = ae(x)
        """
        2.backward
        """
        l_ae = chainer.functions.mean_squared_error(x, z)
        ae.cleargrads()
        l_ae.backward()
        """
        3.update
        """
        opt.update()
```

#おわりに
***よくわかんないけど動いたわ***ということで目的は達成です．
ふぅ．
自己満足で書かせていただきました．
今後(12ヵ月の無料期間)はしっかりと有効活用していきたいですね．
Azure Machine Learning Studioにも興味ありますね．