Google Colaboratory で機械学習させる際のインフラ整備

Google Colaboratory で機械学習を行う際に、3点詰まったので解決策をまとめておきます。

# 問題と(解決策)
1. [Colabが90分ごとに落ちる](#Colabが90分ごと落ちないようにする)（Auto Refresh）
2. [学習データの読み込み、容量問題](#学習データの読み込み)（Google Driveをマウント）
3. [自動削除された学習済みモデルがゴミ箱にたまり続ける、容量問題](#ゴミ箱を定期的に自動で空にするプログラムの作成)（Google Apps Script）

## Colabが90分ごとに落ちないようにする
コラボは一回12時間使用可能ですが、操作しないと90分で落ちてしまいます。その時は[この記事](https://qiita.com/enmaru/items/2770df602dd7778d4ce6)を参考にGoogle Chrome拡張機能の[Auto Refresh](https://chrome.google.com/webstore/detail/auto-refresh/ifooldnmmcmlbdennkpdnlnbgbmfalko?hl=ja)を入れましょう。この記事に追加する形で一点だけ注意があり、ノートブックの出力を非公開にしておきましょう。そうしないと2回目以降の再読み込みでも手動で再読み込みボタンをクリックする必要があります。Colabのタブから`編集→ノートブックの設定→このノートブックを保存する際にコードセルの出力を除外するにチェック→保存`で設定可能です。

## 学習データの読み込み
データセットをColabにアップロードするのには

- wget
- file upload
- Google Drive をマウント（おそらく一番高速）

という方法が考えられます。
　5GBのデータセットをtfrecord化した17GBのデータセットを用いたいので、今回はできるだけ高速に読み込みが完了するGoogle Driveを使います。無料でドライブを使っている人は容量は**15GB**です。機械学習するにはこれが意外と小さいです。これに収めるため、tfrecordを.tar.gzに圧縮して6~7GBにしてアップロードします。

最終的に完成した疑似コードはこのようになります。
![psuedcode.png](https://qiita-image-store.s3.amazonaws.com/0/322417/925b3aae-64ed-9100-b121-26e81f581657.png)

　始めのブロックで現在Chromeにログインしているアカウントのドライブをマウントします。
ドライブのルートディレクトリは`/content/gdrive/My Drive`になります。

```
from google.colab import drive
drive.mount('/content/gdrive')
```
実行するとこのような画面になるはずです。青いリンク先にとびましょう。
![mount1.png](https://qiita-image-store.s3.amazonaws.com/0/322417/3409db78-2ac2-10ed-68eb-0cd0b7d1588e.png)
マウントするGoogleアカウントを選択します。許可する権限に問題がなければ許可ボタンを押します。遷移先の文字列をコピーし、`Enter your authorized code:` の箇所に張り付けてEnterを押します。これでマウント完了です。
　２ブロック目のコード`!tar -zxf "/content/gdrive/My Drive/path/to/tfrecord.tar.gz"`で、ドライブ上の圧縮データセットを、ドライブ外のColab上のディレクトリ`/content/`以下に展開します。これで15GB以上のデータセットをColab上で使用可能です。
　５ブロック目のコードでは、データセットのパスと学習中のモデルを保存するパスを設定しています。
またモデルは直近の２つだけ保存し、それより古いものは自動的に削除されるようにします。モデルファイルは一回数GB近く必要なので、15GB制限に収めるため削除しています。
　**しかし！**、pythonプログラムでモデルを削除しただけでは容量問題は解決しません。削除されたファイルはゴミ箱に送られます。そして**ゴミ箱の容量も併せて15GBに収める必要があります**。そこで自動的にゴミ箱を空にするプログラムが必要になります。

## ゴミ箱を定期的に自動で空にするプログラムの作成
### ゴミ箱を空にするプログラムの作成
Google Apps ScriptでGoogle Driveのゴミ箱を自動で空にするプログラムを作成します。まずはChromeに拡張機能として[Google Apps Script](https://chrome.google.com/webstore/detail/google-apps-script/eoieeedlomnegifmaghhjnghhmcldobl?hl=ja)をここから入れます。
ドライブ上の任意のディレクトリで、`右クリック→その他→Google Apps Script`で新規スクリプトを開きます。でてきた場所に次のプログラムを書きます。

```
function Trash() {
  //ゴミ箱を完全に空にする
  Drive.Files.emptyTrash();
}
```
保存します。名前は適当につけましょう（私はtutorialという名前にして進めます）。次にGoogle Drive API v2を有効にします。[この記事](https://qiita.com/TakashiHamada/items/d932b1c7ed991b575109)に画像津付きで書かれてるのでそちらを参考にしても構いません。上部タブの`リソース→Google の拡張サービス...`をクリックします。Drive APIの場所までスクロールし、右端のボタンをクリックしてONにします。
　次に上部タブの`リソース→Cloud Platform プロジェクト...`をクリックします。"このスクリプトが現在関連付けられているプロジェクト:"のリンクをクリックします。遷移先の検索枠に、driveと打ち込み、出てきた候補内の`Google Drive API`をクリックします。遷移先で有効にするボタンをクリックします。これで設定は完了です。
　ひとまず実行してみましょう。実行は先ほどTrash()関数を定義したGoogle Apps Script上のGUIで行います。虫アイコンの隣の再生アイコンを押しましょう。実行許可を求められるので許可ボタンを押して進みます。安全でないという警告ページは左下の`詳細→安全ではないページへ遷移`で進めます。これで実行完了です。ゴミ箱の中が空になったと思います。
### 定期実行
再生ボタンの隣の時計アイコンを押します。遷移先でトリガーを追加、または新しいトリガーを作成、をクリックします。画像のような形で設定して、下にスクロールして保存を押します。これで15分起きに自動でゴミ箱を空にするプログラムが動きます。
![timer.png](https://qiita-image-store.s3.amazonaws.com/0/322417/08c55fba-a9f5-4d94-e3fc-bb0ce9ec2b5a.png)
以上です。お疲れさまでした。
## 参考サイト
[Google Colaboratoryの90分セッション切れ対策【自動接続】](https://qiita.com/enmaru/items/2770df602dd7778d4ce6)
[Google app script + REST API v2でファイルを完全削除またはゴミ箱を空にする](https://qiita.com/TakashiHamada/items/d932b1c7ed991b575109)