3段階 Kaggle環境構築
先月よりKaggleに挑戦し始めました。 コンペに参加しながら計算環境について検討したので、これから始める方向けにまとめます。 環境構築に時間を掛けずに、アルゴリズムの検討に時間を掛けたいですね。
想定読者
- これからkaggleに挑戦する、もしくは挑戦し始めたくらいで計算環境が未整備
- WindowsコマンドプロンプトやLinuxターミナル(Bashなど)のコマンド実行方法がわかる
- コマンドを覚えている必要はない
- Windowsユーザー
- KaggleではPythonを使って挑戦する
- Pythonの使用経験は多少ある
この記事に書くこと/書かないこと
書くこと
- Kaggleに挑戦するにあたってオススメの計算環境,ツール
書かないこと
- Kaggleで使うべきアルゴリズム
- Kaggleの公式サイトの見方(有用な議論の発見の仕方など)
各環境の利用目的/導入方法概要
ローカルでの動作環境構築 → Google Colaboratoryの利用 → GCP(GCE: Google Compute Engine)上で環境構築の順でステップアップしながら整えていくのが良いと考えている。 それぞれの利用目的と導入方法の概要をまとめると次の通り。
※補足:Kaggle Kernelは、Commit時に再実行されたり、出力したファイルをCommitせずにローカルに持ってくる手軽な方法がなかったりして、ちょっと使いやすさで他に劣ると考えているためここでは紹介しない。
1. ローカル
利用目的
- Kaggle参加にあたって使うツール類やSubmitまでの手順に慣れる
- 軽い処理を気軽に試す
- 電気代だけで何時間でも動かせる環境として使う
導入方法
- Pythonディストリビューションを導入する
- AnacondaかWinPython
2. Google Colaboratory
利用目的
- ネットワーク越しの環境に慣れる(セッションがいつ切れても良いように実装する)
- GPU/TPUを使って計算する
導入方法
- ノートブックファイル,データを全てGoogle Driveに保存する
- Google ColaboratoryのGoogle Driveアクセス機能を使う
3. GCP(GCE: Google Compute Engine)
利用目的
- 処理時間(待ち時間)を短縮する
- 大量メモリを必要とする処理を行う
導入方法
構築方法
1. ローカル(Windows)
Windowsで機械学習用途でPythonを使うには、Pythonディストリビューション(便利ツールやライブラリがセットになったもの)を導入するのが圧倒的に楽である。
一番の有名どころはAnacondaだが、自分はWinPythonを使っている。
Anaconda
WinPython
Kaggleでよく使われるライブラリのうち、AnacondaやWinPythonに含まれないものは追加でインストールする。
WinPythonではXGBoostとLightGBMが含まれていなかったので追加する。
'WinPython Command Prompt.exe'を起動すると各コマンド(python
やpip
など)にPATHが通った状態でコマンドプロンプトが起動するので便利。
コマンドプロンプトが開いたら、次のようにするだけでインストールできる。
pip install xgboost pip install lightgbm
ここまででツールは揃った。
コーディングのエディタなどはそれぞれ好みがあると思うが、KaggleではJupyter notebookやその類似のものを使うことが多い。(Kaggleが提供しているKernelというツールや、後述するGoogle Colaboratoryもその一種。)Jupyter Notebookではグラフや文字列の出力をそのまま保存できるのでとても便利。
Web開発ではVisual Studio CodeやPyCharmを使うことが多いと思う。それらにもJupyter Notebook統合の機能があり、特にPyCharmのコード補完機能は優れている。が、自分はいまいち使いにくいと感じたので素のJupyter Notebookを使っている。
'Jupyter Notebook.exe'を起動すると勝手にブラウザが開いてJupyter Notebookが使える。
Jupyrter自体の使い方は検索するとたくさん出てくるので他に任せる。セルの実行と追加/削除のショートカットキーは覚えているかどうかで効率がかなり変わると思う。
2. Google Colaboratory
ローカル環境で動かすことに慣れたら、Google Colaboratory(以下Colab)で動かすことに慣れるようにする。 ColabはGoogleが提供するサービスでJupyter Notebookに似た操作感がある。(ただしショートカットキーが異なる。)
Colab使う際には、Google Drive(以下Drive)に.ipynbファイルを保存するのが一般的。また、Kaggleで使うデータもDriveに置くのが簡単。
Colabの画面から直接ファイルを新規作成したりファイルアップロードしたりもできるが、既定の場所に自動でファイルが作られてしまう。そのため、先にDriveにファイルを作っておいて、それを編集したほうがファイルが迷子にならずに済む。
まずはDrive上でそれっぽくフォルダを作る。(input,output,scriptフォルダを作るのが一般的のよう。)
ローカルのJupyter Notebookファイル(.ipynb)をDriveにアップロードしたら、右クリックメニューで「アプリで開く」→「Colaboratory」の順に選ぶと、Colabでそのファイルを開くことができる。 コピーではなくファイルそのものが開かれるので、編集結果は何もせずともそのまま反映される。
Colabの使い方はローカル環境で動かすJupyter Notebookと似ているが、クラウドで動いている点と、一定時間で接続が切れてしまう点が異なる。そのため、テストデータや出力結果の保存をどうするかが問題になる。
Colab上では、Driveとの連携のための特別パッケージを使うことができ、Driveのファイルの読み書きをスムーズに行うことができる。参考:ColaboratoryでのGoogle Driveへのマウントが簡単になっていたお話
私はいつも最初にDriveのマウントとカレントディレクトリの変更を実行している。 URLが表示されるのでそちらにアクセスするとGoogleアカウントとの連携画面に移動する。表示された通りに進めればOK。
# 自分のGoogle Driveにアクセスできるようにする # Google Driveのトップが "/content/drive/My Drive/"になる from google.colab import drive drive.mount('/content/drive') # 自分は"Kaggle/Santander/script"にノートブックファイルを配置しているので # 相対パスで扱いやすいようにos.chdir()でカレントディレクトリを変更する os.chdir("/content/drive/My Drive/Kaggle/Santander/script")
GPUやTPUが必要になったら、「ランタイムの切り替え」をすると使えるようになる。
ただし、Kaggle初心者がGPUやTPUの必要になる画像/音声データを使ったコンペに参加するのは、トライ・アンド・エラー回数が少なくなるので敷居が高めだと思う。
3. GCP(GCE: Google Compute Engine)
自分のようにノートPCしか無い人はデータとアルゴリズムによっては足りなくなる。Google Colabも12GBくらい使えるが、それ以上はエラーになってしまう。また、処理時間が掛かってしまい待ち時間が長くなってしまうケースというのがありうる。
そんな時にはクラウドサービス上で自分用のサーバーを建てて、その中でJupyter Notebookを動かすとよい。 特にGoogle Cloud PlatformのGoogle Compute Engineがオススメだ。 また、Kaggleが提供しているDockerコンテナが存在するので、それを使う方針で説明する。
GCEの選定理由
最初に悩むのが、どのクラウドサービスを使うかだと思う。クラウドサービスとして個人用で候補に上がるのはAWS EC2, MS Azure VM, GCPのGCEあたりだろう。Kaggle用としてはGCEを使うのがおすすめなので、手順としてはそれを前提とする。
GCEをおすすめする理由は、環境構築の手軽さとお金事情だ。
Microsoft AzureのVirtual Machine
GCE上の環境構築
まずはGCEのインスタンス(マシン)を用意する。
詳細手順は他の記事参考:GCP(Google Cloud Platform)での無料GCE(Google Compute Engine)インスタンス作成に任せるとして、ポイントは下記の通り。
- リージョンは料金表を見ながら安いところにする
- 自分はus-east1にしている
- CPU,メモリは後から変更できるので、ひとまず安いもので十分
- ディスクは30GB以上欲しい
- データを一時的に置いたりするため
- HDDで十分速い
- あまり大きな容量にすると停止中もお金がかかるので注意
- OSはUbuntuが何かと情報が多くて無難
- プリエンプティブのオン/オフのメニューは隠れているので探す
また、自分の場合は普通のインスタンスとプリエンプティブのインスタンスを1つずつ建てている。多くの人が使っているためか、プリエンプティブインスタンスが使えない事があったため。そのような状況を1週間で2回経験している。
GCEのインスタンスを作成すると自動で起動する。停止や再起動はブラウザから行える。
起動中のインスタンスにアクセスして環境を整えたりするのには、Cloud SDKを使うのがよい。Googleアカウントでログインすると、暗号化通信のためのあれこれを勝手にやってくれる。インストーラをダウンロードしてきて指示の通りに進める。
Cloud CLIがインストールできたら、コマンドプロンプトで起動しているGCEインスタンスにアクセスする。
このとき、今後のJupyterのアクセスのために毎回 "-- -L 18888:localhost:8888
" とオプションをつけるようにする。
(あとで説明する。)
gcloud compute ssh {インスタンス名} --zone {ゾーン名} -- -L {ローカル側ポート番号}:localhost:{リモートのポート番号} # 例) gcloud compute ssh instance-1 --zone us-east1-b -- -L 18888:localhost:8888
Dockerインストール
GCEで建てたマシンに地道に準に必要なものをインストールしたり、ローカル環境と同様にAnacondaを使っても良い。
しかし、LinuxマシンならDockerを使うのが便利。Kaggleが公式に提供しているDockerイメージを利用でき、Kaggle Kernelと同じライブラリが使えるようになる。個人的にKernelの操作性は微妙だと思っているが、ライブラリ類は揃っているしKernelコンペというものもあるので、同じ環境が揃うのは嬉しい。
※ ただしGPU利用版は未提供
Docker公式サイトに各ディストリビューションでのインストール方法が載っているのでその通りに実行していく。
日本語で読みたい場合は参考:Ubuntuにdockerをインストールする の「2. リポジトリからのインストール」「4. 一般ユーザでの実行」を実行して、一旦接続を切ってgcloud comute ssh {インスタンス名} --zone {ゾーン名} -- -L {ローカル側ポート番号}:localhost:{リモートのポート番号}
で接続しなおす(マシンの再起動は不要)。
Docker起動
次のコマンドでKaggle公式のDokerを起動する。
docker run --name kaggle -v $PWD:/tmp/working -w=/tmp/working -p 8888:8888 -itd kaggle/python jupyter notebook --no-browser --ip="0.0.0.0" --notebook-dir=/tmp/working --allow-root
オプションが長いので説明。爆速でKaggle環境を構築するに記載の手順ほぼそのままだが、デーモン起動する方が便利なのでその点を変えている。
--name kaggle
- kaggleという名前で起動する
docker stop kaggle
とすれば止まる、docker start kaggle
とすれば再び起動する
- kaggleという名前で起動する
-v $PWD:/tmp/working -w=/tmp/working
- dockerの中と外とでカレントディレクトリを共有する
- dockerを停止してもファイルが残るようになる
-p 8888:8888
- ポート8888番を8888番に転送する
-itd kaggle/python jupyter notebook --no-browser --ip="0.0.0.0" --notebook-dir=/tmp/working --allow-root
無事に起動しても何らかのエラーが出ても、コンソール上には何も表示されない。docker logs {コンテナ名}
コマンドで出力を確認し、http://{12桁の英数字}:8888/?token={長い英数字}
と表示されたら問題なくJupyterが起動している。
docker logs kaggle
# 出力例 [I 01:20:01.337 NotebookApp] The Jupyter Notebook is running at: [I 01:20:01.337 NotebookApp] http://3078d3d264c3:8888/?token=c7601ca8dd41f61e739373168c07bb232557a5de8a19357b [I 01:20:01.337 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). [C 01:20:01.338 NotebookApp] Copy/paste this URL into your browser when you connect for the first time, to login with a token: http://3078d3d264c3:8888/?token=c7601ca8dd41f61e739373168c07bb232557a5de8a19357b&token=c7601ca8dd41f61e739373168c07bb232557a5de8a19357b
Jupyterに接続
上の手順でhttp://{12桁の英数字}:8888/?token={長い英数字}
が無事に表示されたら、ローカル端末からGCEの上で動くJupyter Notebookにアクセスする。
表示されたURLの{12桁の数字}
の部分をlocalhost
に、ポート番号8888
を18888
に変えたものをブラウザに打ち込む。http://localhost:18888/?token={長い英数字}
自分はPuttyでのクリップボードへのコピー方法が最初分からなかったが、該当部分をマウスで選択するだけでいい。(ctrl-cは別の意味になるので)。
Jupyter Notebookの画面が開かれればOK!存分にKaggleを楽しめる。
なお、gcloud
コマンドで起動したコンソール画面(Puttyの画面)は閉じないこと。理由は下の補足参照。
うまくいかない場合は、
docker logs kaggle
でエラーが表示されていないか- ここまでの手順で
8888
と18888
を間違っていないか gcloud compute ssh
で開いた黒い画面を閉じていないか- (docker logsにエラーもアクセス履歴も何もないなら)
gcloud ssh
のときに-- -L 18888:localhost:8888
を忘れていないか
を確認する。
GCEのシャットダウン、再起動
無駄な課金を防ぐには、使わない時にはGCEのインスタンスをシャットダウンしておく必要がある。 (GCEではOSシャットダウン時はディスクのみ課金、サービスによって扱いが異なるので注意。)
ブラウザから強制的に止めてしまっても自分の環境では問題は起きていない。気になる人は念の為に次のコマンドで停止する。
docker stop kaggle # "kaggle"という名前のDockerコンテナの停止 = Jupyterが止まる sudo shutdown -h now # サーバーのシャットダウン
逆に停めていたサーバーを起動するときには、ブラウザから操作すればよい。
サーバーを起動するだけでは中のDockerコンテナまでは起動しないので明示的にコマンドで起動する。
毎回docker run
するのではなく、2回目以降はdocker start
する。
docker start kaggle # "kaggle"という名前のDockerコンテナの起動 # この後、docker logs kaggle でアクセスURL(token)を確認する
Google Cloudのスマホアプリからもステータスチェックや開始/停止できる。停止漏れの確認に使える。
データの保存先
軽いファイルの保存や出力結果をローカルで軽く確認したいときは、Jupyter Notebookのダウンロード機能、アップロード機能を使えばいい。
大きなファイルサイズのものはGoogle Cloud Storageにデータを保存しておくのがよい。アメリカに置けば5GBまで無料らしい。
GCEのマシンにはデフォルトでgsutil
というGoogle Cloud Storageを操作するためのツールがインストールされている。
ブラウザで操作しても良いが、大きなファイルサイズのデータは、これを使ってGoogle Cloud Storageとやりとりをすると非常に高速。詳細は他記事を参照。
スペック変更
マシンをシャットダウンしている間なら、CPUとメモリの量を変更できる。 データサイズとアルゴリズムによって必要なメモリは異なるので、動かしながら調整していくといい。
もともとGCEでは一度マシンを削除しないと変更できなかったらしくその時の情報が検索すると出てくる。しかし今はブラウザからクリックだけでできる。(スクリーンショットは載せてもすぐに変わりそうのため省略する)
補足1:gcloudコマンドのオプションとポートの関係
gcloudに接続するときのコマンドは下記の通り(再掲)
gcloud compute ssh {インスタンス名} --zone {ゾーン名} -- -L {ローカル側ポート番号}:localhost:{リモートのポート番号} # 例) gcloud compute ssh instance-1 --zone us-east1-b -- -L 18888:localhost:8888
この--
から後が、SSHポートフォワーディングの設定になっている。
上記の例ではlocalhost:18888
にアクセスするとSSHのトンネルを通って(つまり暗号化された状態で)サーバーの8888
番ポートにアクセスしたことになる。(サーバー上でlocalhost:8888
にアクセスしたのと同じになる。)
さらに、Docker起動時に-p 8888:8888
指定をしているので、Ubuntuの8888
ポートがDockerコンテナの8888
ポートに繋がる。
この仕組みを利用してローカルのブラウザからJupyterにアクセスしている。そのため、GCEのネットワーク設定を変えることなくJupyterにアクセスできるようになる。
ポートフォワーディングはPuttyの画面を開いている間だけ有効なので、Puttyの画面を閉じてしまうとブラウザからアクセスすることができなくなるので注意。
補足2:ネットワークファイアウォールの追加設定
補足1の通り、SSHポートフォワーディングを利用してサーバー(の中のDockerの)Jupyterにアクセスしている。そのためSSH用の22
番ポートだけ使えれば良い。
GCEではデフォルトで外部からの8888
番に対するアクセスは拒否されているが、内部からのアクセスは許容するdefault-allow-internal
というルールが付いている。
外部アクセス禁止かつJupyterの起動時にtokenを使っていれば、すぐさまセキュリティ上問題になる可能性は低いと思う。一方でroot権限で動いているJupyterからはどんな事でも出来てしまうので、万一不正アクセスされた場合には怖い。
そのため、GCEの「VPCネットワーク」→「ファイアウォールルール」で、内部外部を問わず8888
ポートへのアクセスを禁止しておくことを推奨する。
補足3:JupyterのPassword認証を使いたい / 起動ごとにtokenを調べるのが面倒 なとき
Jupyter Notebookの設定変更はjupyter_notebook_config.py
ファイルを書き換える方法が一般的だが、実は起動オプションだけで相当数の(一時的な)設定変更ができる。
参考:Jupyter Notebook公式
例えばtokenは使わず毎回同じパスワードで起動したいとする。
パスワードの生成方法はJupyterを導入しよう -リモート編-などを参考にして、下記オプションで起動すればjupyter_notebook_config.py
を変えることなく設定を反映させて起動できる。
# passwd()して"ubuntu"を変換したら'sha1:a0a28df801c9:7bab5ea21d39cf03bb54100dcaf8cf9664dc9ddb'になったとする --NotebookApp.token='' --NotebookApp.password='sha1:a0a28df801c9:7bab5ea21d39cf03bb54100dcaf8cf9664dc9ddb'
ただし、セキュリティとしては弱くなる。 補足2に書いた通り、万が一乗っ取られると危ない。補足2のファイアウォールルールの追加はセットで行うべきと思う。
まとめ
3段階でKaggleに挑戦するための環境を整えていく方法を紹介した。
それぞれに利点/欠点があるので、コンペの期限やお財布事情(無料トライアル枠の残高)などを見ながら使い分けていきたい。
この記事で記載できなかったこと
- GCP上でGPUを計算に使う環境の構築
- 現状ではCPU対応のDockerイメージしか公開されていない
- GCEのCUDAドライバ対応マシンイメージを使う + tensorflowなどをインストールし直す といった手順が必要なはずだが試せていない
- Dockerを使わずにGCP上で手軽に環境を整える方法
- 本来は何度もマシンの作成/削除を繰り返さないならDockerを使う必要はない
その他
本文中で紹介しなかった参考記事/動画