わくわく技術ブログ

プログラミング・統計・機械学習

3段階 Kaggle環境構築

先月よりKaggleに挑戦し始めました。 コンペに参加しながら計算環境について検討したので、これから始める方向けにまとめます。 環境構築に時間を掛けずに、アルゴリズムの検討に時間を掛けたいですね。

想定読者

  • これからkaggleに挑戦する、もしくは挑戦し始めたくらいで計算環境が未整備
  • WindowsコマンドプロンプトLinuxターミナル(Bashなど)のコマンド実行方法がわかる
    • コマンドを覚えている必要はない
  • Windowsユーザー
    • Mac/Linuxユーザーも、後半の手順は同様に参考にしてもらえれば
  • KaggleではPythonを使って挑戦する
    • Pythonの使用経験は多少ある

この記事に書くこと/書かないこと

書くこと

  • Kaggleに挑戦するにあたってオススメの計算環境,ツール

書かないこと

  • Kaggleで使うべきアルゴリズム
  • Kaggleの公式サイトの見方(有用な議論の発見の仕方など)

各環境の利用目的/導入方法概要

ローカルでの動作環境構築 → Google Colaboratoryの利用 → GCP(GCE: Google Compute Engine)上で環境構築の順でステップアップしながら整えていくのが良いと考えている。 それぞれの利用目的と導入方法の概要をまとめると次の通り。

※補足:Kaggle Kernelは、Commit時に再実行されたり、出力したファイルをCommitせずにローカルに持ってくる手軽な方法がなかったりして、ちょっと使いやすさで他に劣ると考えているためここでは紹介しない。

1. ローカル

利用目的

  • Kaggle参加にあたって使うツール類やSubmitまでの手順に慣れる
  • 軽い処理を気軽に試す
  • 電気代だけで何時間でも動かせる環境として使う

導入方法

2. Google Colaboratory

利用目的

  • ネットワーク越しの環境に慣れる(セッションがいつ切れても良いように実装する)
  • GPU/TPUを使って計算する

導入方法

3. GCP(GCE: Google Compute Engine)

利用目的

  • 処理時間(待ち時間)を短縮する
  • 大量メモリを必要とする処理を行う

導入方法

  • Kaggle提供のDockerイメージを利用する
  • Jupyter NotebookにSSHポートフォワーディングを利用してアクセスする
  • 適宜スペックを変更する

構築方法

1. ローカル(Windows)

Windows機械学習用途でPythonを使うには、Pythonディストリビューション(便利ツールやライブラリがセットになったもの)を導入するのが圧倒的に楽である。

一番の有名どころはAnacondaだが、自分はWinPythonを使っている。

  • Anaconda

    • 機械学習用途で圧倒的人気
    • Pythonの複数バージョンを併用できる
      • ただしKaggle用途では単一バージョンで良さそう
    • △ (defaultでは)隠しフォルダにインストールされるので全体像が見えにくい
    • △ Anaconda独自管理ツールを併用する
      • conda コマンド
        • pipと機能が重複する
      • Anaconda利用者向けの情報を探す必要がある
  • WinPython

    • 独自ツールは含まれない
      • 一般的な管理ツール(pipなど)を使う
      • Web開発などでPython経験があれば慣れた方法が使える
    • ポータブル
    • Pythonバージョンは固定
      • 使いたいバージョンのWinPythonをダウンロードする

Kaggleでよく使われるライブラリのうち、AnacondaやWinPythonに含まれないものは追加でインストールする。

WinPythonではXGBoostとLightGBMが含まれていなかったので追加する。 'WinPython Command Prompt.exe'を起動すると各コマンド(pythonpipなど)に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フォルダを作るのが一般的のよう。)

Driveでのフォルダ構成

ローカルの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をおすすめする理由は、環境構築の手軽さとお金事情だ。

  • GCP(Google Cloud Platform)のGCE(Google Compute Engine)

    • プリエンプティブインスタンスにするととても安い
      • 24時間以内に必ず終了するインスタンスのこと
        • × 24時間で必ず停止する、それ以外にも勝手に停止することがある
        • ○ 長時間の利用には向かないが、止め忘れで課金されるリスクが低い
    • 無料トライアルの300ドルが使える
    • 管理画面が(AWSよりは)わかりやすい
    • スペックの変更が細かく可能
      • CPUは2coreだけどメモリは30GB みたいな設定ができる
  • AWS(Amazon Web Service)のEC2(Elastic Compute Cloud)

    • クラウドと比較して圧倒的に人気
      • 情報量が多い
    • Spotインスタンスはかなり安い
      • 稼働保証がないかわりに安くできる
        • △ 料金はこちらで指定して、オークションで買うような形式。少々面倒。
        • ○ 稼働時間に直接制限がない
        • × 停止(シャットダウン)しておくことができず削除になってしまう
    • 無料トライアルでは低スペックマシンしか使えない
    • 管理画面がわかりにくい
      • リージョンごとに画面を切り替える必要がある
        • Kaggleは安いリージョン(米国など)を使うのがおすすめだが、東京リージョンを既に使っている人は一覧性が低くなる
          • 高スペックマシンを使うことが多いと思うのでリスクになる
  • Microsoft AzureのVirtual Machine

    • 管理画面などの機能面は悪くない
    • GCP GCEのプリエンプティブインスタンスAWS EC2のSpotインスタンスのような割安プランが無い
    • 無料トライアル2ヶ月目以降は用途が限定される
      • 本番利用不可 など
      • 建てられるVMの性能も制限あり

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とすれば再び起動する
  • -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
    • kaggle/python(Kaggleの提供するコンテナ)でjupyterコマンドを実行する
    • デーモンとして起動する(sshが切れても勝手に終わらないようにする)
    • --ip="0.0.0.0"
      • 外部から(どこからでも)繋がるように
    • --allow-root dockerを使うとrootでの実行になるので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に、ポート番号888818888に変えたものをブラウザに打ち込む。http://localhost:18888/?token={長い英数字}

自分はPuttyでのクリップボードへのコピー方法が最初分からなかったが、該当部分をマウスで選択するだけでいい。(ctrl-cは別の意味になるので)。

Jupyter Notebookの画面が開かれればOK!存分にKaggleを楽しめる。 なお、gcloudコマンドで起動したコンソール画面(Puttyの画面)は閉じないこと。理由は下の補足参照。

うまくいかない場合は、

  • docker logs kaggleでエラーが表示されていないか
  • ここまでの手順で888818888を間違っていないか
  • 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指定をしているので、Ubuntu8888ポートがDockerコンテナの8888ポートに繋がる。 この仕組みを利用してローカルのブラウザからJupyterにアクセスしている。そのため、GCEのネットワーク設定を変えることなくJupyterにアクセスできるようになる。

ポートフォワーディングはPuttyの画面を開いている間だけ有効なので、Puttyの画面を閉じてしまうとブラウザからアクセスすることができなくなるので注意。

Jupyter Notebookへのアクセスとポート番号

補足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に挑戦するための環境を整えていく方法を紹介した。

  1. ローカルで動かす
  2. Google Colaboratoryを使う
  3. Google Compute Engine上で動かす

それぞれに利点/欠点があるので、コンペの期限やお財布事情(無料トライアル枠の残高)などを見ながら使い分けていきたい。

この記事で記載できなかったこと

  1. GCP上でGPUを計算に使う環境の構築
    • 現状ではCPU対応のDockerイメージしか公開されていない
    • GCEのCUDAドライバ対応マシンイメージを使う + tensorflowなどをインストールし直す といった手順が必要なはずだが試せていない
  2. Dockerを使わずにGCP上で手軽に環境を整える方法
    • 本来は何度もマシンの作成/削除を繰り返さないならDockerを使う必要はない

その他

本文中で紹介しなかった参考記事/動画

Coursera Introduction to Deep Learningコースの受講感想

Introduction to Deep Learningコースをほぼ修了したので感想です。

www.coursera.org

「ほぼ修了」と書いたのは、レビュー結果待ち状態のものがあるからです。あと自分が他の人のレビューもしないといけないのですが、まぁ大体終わったということで。

以前、Stanford大学のMachine Learningコースを受講しました。

Coursera Machine Learningコースの受講感想 - わくわくとオーボエ

この講義はその続きではないのですが、自分の場合は続きとして受けても問題なさそうだと判断してこれを選んでいます。

長くなったのでまとめから

  • 扱いは「上級」だがあくまで「Introduction」の範囲
    • ITエンジニア向けの初級から中級本くらいの内容
  • 複数講師なので、テーマごとに聞きやすさが違う(教師なし学習は聞きにくい)
  • 50時間くらいかかった
  • 演習問題を解きたい & 英語学習を兼ねられる にメリットを感じるなら受けても良い
    • 難易度、時間、費用的には、日本の書籍で十分学習できる範囲
  • 次コースの"How to Win a Data Science Competition: Learn from Top Kagglers"に必要かと思い受けたが怪しい気がしている
    • 実際どうだったかは受けてから書く

コース情報

主催、講師

ロシアのNational Research University Higher School of Economics(国立研究大学高等経済学院)が主催している講座。 Advanced Machine Learningという専門講座に含まれる最初のコース。

先生は4名。分野ごとにバトンタッチ。

カリキュラム

全部で6週を想定したオンライン講義で、示されている所要時間を合計すると約38時間です。

おおよその内容は次の通り。

難易度は「上級」。

また受講の前提知識として以下が記述されています

その他

残念ながら字幕に日本語はありません(2019年2月末時点)

英語字幕はかなりよく出来ています(後述の通り教師なし学習の部分を除く)

学習実績

時間

このコースの学習の途中から、アプリで学習時間の実績をつけるようにしました。

途中からだったのとタイマーをつけるのを忘れたりしたせいではっきりしないのですが、オプション課題を除いて50時間くらいで最終課題の完成まで行けたと思います。コース想定が38時間(オプション課題込み)なので、だいぶ掛かってしまったと思う。

時間の掛かった理由は2つ。ノートをとる時間と、英語の発音です。

ノートをとる時間

前回受けた講義(Stanford大学 Machine Learning)では、講義スライド(講師の書き込みあり)がPDFでダウンロードできたほか、講義内容をまとめ直したものも閲覧できます。また、もともと無料講義なので必要になったら受け直すことも自由にできるものです。

一方でこのIntroduction to Deep Learningコースでは、ダウンロード資料などは用意されていません。さらに有料講座で月ごとに課金のため、ずっと講座を聴けるようにしておくのも現実的ではなく。 そのため、各講義動画ごとに内容を自分で残しておかないと、何の話をしていたかも分からなくなってしまいます。

ノートは話の内容が分かっていれば書くのは大変ではない…かと思いきや、意外と大変です。というのも、英語から日本語へ翻訳するコストが自然に掛かってしまうためです。(英語のままメモに残せば書くコストは減りますが読むコストが上がります。) 講義スライドは分かりやすいものの情報量が少なめなので、スライドのスクリーンショットを手元に残すだけでは足りないかと思います。

英語の発音

英語の講義なので、発音の分かりやすさと字幕の精度には慎重になってコースを選択したつもりでした。(事前に複数本の動画をお試し視聴した) ただ、講師が4人もいるとは思わず。。

4人のうち、教師なし学習を担当している方の話す速度と発音がちょっと…。字幕も間違っていたり[INAUDIBLE]となっていたりが目立ちました。 そのため、自分の能力では5分の視聴に1時間近く掛けるペースになりました。

他の3人の講師については聞き取りやすい発音です。その中でも特にCNNの担当の講師がゆっくりはっきり綺麗な発音でした。

内容理解

上に書いたとおり、教師なし学習については英語理解がむずかしく、ぼんやりした理解度です。それ以外はちゃんと動画を見て分からない部分はネットで少し検索したりすれば、問題なく理解できました。

感想

内容の広さ,深さ

書籍「ゼロから作るディープラーニング」は手元にあったので適宜参照しながら進めました。このコースの方がやや詳しめ(深め)ですが、コースのCNNまでの内容がおおよそこの本の内容をキュっとまとめた感じでしょうか。コースとしてはTensorflow/Kerasを使って実装することに主眼が置かれているものの、途中のオプション課題でNumpyのみでニューラルネットワークを作るというのがあり、近しいものを感じます。

教師なし学習とRNNについては、書籍を持っていないので目次を見る限りではありますが「ゼロから作るディープラーニング2」と7割くらい重なっていそうです。書籍にあるAttentionというものは、「このコースでは触れない」と途中の動画で言っていました。(Advanced Deep Learningの残りの6コースの中で扱うそうです。)

"Introduction to Deep Learning"というタイトルからするに浅く広くの学習を目指しているのでしょう。この分野の全容を知るわけではありませんが、おおよそ名前通りのコースだと感じます。

難易度「上級」について

このコースだけではなく、7コース合わせて「上級」表示がされているような気がします。上述の通り、ゼロから作る~という書籍とレベル感として近いです。基礎の部分が省略されたのを踏まえて、中級くらいじゃないでしょうか。

ただ、この内容の後に6コース、総計216時間の講座が後ろに控えていると思うと、それらの後半は間違いなく「上級」でしょう。

演習

環境構築のハードルの低さ:◎

コース用のGitHubリポジトリがあり、そこを参照すると演習に必要なライブラリとバージョン、それからGoogle Colabを使う時に追加で必要な補助記述などが書かれています。ローカルで作業する人向けに、Anacondaの導入方法も。 ここに書いてあるとおりにColabを利用すれば(少なくとも今の時点では)何も問題なく作業を進めることができました。Tensorflowのバージョンが新しくなった時にWeek 2の課題を更新しているらしく、そういった点でも安心して演習に取り組めます。

内容:△、方式:○

演習は全体に穴埋め方式です。全体の流れは実装されていて、1行から10行程度までの穴埋めが多数ありコメントで方針が示されています。 これはもう少し全体に生徒の記述量を増やしても良いかなと思いました。

新たに解きたい問題があったとして、全部自力(もちろんKerasなどは使う)で組めるようになったかというと、怪しいです。ただ、今回のコードをベースに実装すれば良いと思うので、ちゃんと考えながら読んだという点では意味はあると思いました。

オプション課題と最終課題の2回、ペアレビューとして他の人のソースコードを読む機会があります。Pythonは書き方がばらつきにくいと言われていますが、それでも色々書き方は出てきます。また、動作確認用に組んだネットワークにも個人差が出てきます。いくつもの結果、ちょっと失敗例に近いようなものも含めて見ることが出来るのは参考になりました。 講師が違うからか、それぞれ課題側にも個人差があってそれも同様です。

ミニクイズ

講義動画の途中で、四択のミニクイズが出されます。このコースでは解説したことをクイズに出すのではなく、クイズに出したことを解説する順になっています。これが意外と理解の助けになりました。

誰にオススメするか?

選ぶとしたら、「締め切りと演習問題があったほうが学習に取り組みやすい」かつ「英語の勉強も兼ねたらラッキーくらいに思う」人でしょうか。

入門者ではなく、理論を突き進めたい人でもなく。あくまでIntroductionの範疇かつ普通のペースでやったら修了までに時間もお金もかかるので、それでいて巷に溢れる良書を退けてこのコースを勧めたくなる人は絞られると思います。

自分の場合は次の"How to Win a Data Science Competition: Learn from Top Kagglers"に期待をしていて、その前段として受けたという側面が強いです。ただ、KaggleでDeep Learningが主流かというとそうではないのではと気づき。有用だったかどうかは、そちらを修了する頃にまとめたいと思います。

アジャイルサムライを読んだ感想

書籍 アジャイルサムライ を読みました。

www.ohmsha.co.jp

とても有名な本なので評価は検索すればたくさん出てきますが、例によって自分の感想を。

一言:「実践は大変」

とても平易なというか、砕けた口調で書かれた本です。中高生でも難なく読めるでしょう。 ただその中身を真面目に考えると、とてもとても「大変」なことを書いています。

今、意図的に「難しい」ではなく「大変」という言葉を使いました。「辛い」と書いてもいいかもしれません。

恐らく、著者が想定していない「難しい」ポイントは「各国の法律の違い」くらいでしょう。そういう意味で、日本のIT業界でこの本のようなことがどのくらいの企業で可能なのかは、ちょっと自分にはわかりません。 ただ、その壁を除いたとしても大変です。

顧客の参加

この本は自分なりに整理すると次の3つの部分に別れます。

  1. チームの在り方
  2. 計画と実績評価の方法
  3. 導入すべき開発技術

このうち開発技術については、ユニットテストを書くとか、CIの仕組みを導入しておくとか、開発者サイドでの効率化の話です。
一方それ以外の部分では、 顧客の関わり方 がキーポイントになります。 アジャイルその時本当に必要なもの を見つめて 機敏(Agile)に動く ということでしょうから当然といえば当然なわけですが、本当に何度も顧客という言葉が出てきます。

日本語だと「お客様」という丁寧な言い方をしますが、今ここで必要なのは、もっとクールで対等な表現なのでしょう。顧客でもまだ違う気がします。 少なくともお客様は神様ではなく チームのメンバーとして積極的に関わってもらわないと失敗します。崇めてお気持ちを察するだけでは機敏には動けません。

開発チームがそういう状況を作るという意味では開発方法論なのでしょうが、 顧客に当たる人こそ読むべき本 という印象でした。

そして、日本社会で今の所あまり一般的ではない状況を強いるという点で、本人たちの意識次第ではあるけど大変だと思います。

現実の直視

「進捗どうですか?」と聞かれたときには基本的には、「進んでたらいいな」という期待があるわけです。すると現実がどうであれ良い返事を返したくなってしまいます。 「元気?」と聞かれたらとりあえず元気だと答えるように。

一方筆者は、たとえ進捗が0でデモするべきものがなくても、顧客とのデモの日程は延期しないほうが良いと述べています。何も進んでいないことを顧客に説明するだけでなく、そういう場を設けることでチームの意識ができると。 難しくはないけど大変なことです。。

評価は実績で

現実をより正しく捉えるために、「80%完了」といった途中での実績評価は許していません。たしかに、残り20%と思っていたら大きな問題を抱えるかもしれません。 そして、 完了基準はテストまで完了していること というのも繰り返しでています。 厳格にやり通すのはなかなか辛いかもしれないなと。

責任

  • 顧客は 何を優先し何を諦めるか を自ら決めなくてはならない
  • 開発者は 顧客の要求変化 に応えなければならない

これらは一定の権限さえあれば経験も技術も不要でしょうが、決断力や覚悟が必要です。

積極的な顧客なら今もやっているのでしょうが、平凡なサラリーマン同士が集まったら惰性で動くのが見えます。

誰に読んでほしいか

途中に書きましたが、 顧客に読んでほしい と思いました。
最近でもアジャイル開発要員を○○人増員しますといったニュースが出ていました。でもこの本を読んだら、開発会社だけが頑張る問題ではないと強く感じました。

それから、 経営者 にも読んで欲しいです。
アジャイルを採用したら開発コストが下がるみたいな発想は、そもそも見る視点が違うのだと理解できるかと。

日本語版のいいところ

日本語版には訳注として 訳者の経験則 がチラホラ入っています。

例えばユーザーストーリーの見積もりについて、筆者は「1, 3, 5 で十分」と書いていますが、訳者は「1, 2, 3, 5, 8」を使っているそうです。筆者の経験だけでなく訳者の経験も入っているのは、翻訳本の良いところですね。

ここまで書きましたが..

書籍には、 アジャイルに決まったルールがあるわけではない とも書かれています。
著者のアジャイル観がこの本には詰まっているわけですが、他の人のアジャイル観も知りたいところです。

導入した大企業とかの社員の声も聞いてみたいところですが、そういう知り合いがいないのが残念。

Coursera Machine Learningコースの受講感想

Coursera Machine Learningコース https://www.coursera.org/learn/machine-learning を修了しました。

世の中に感想はあふれていますが、人それぞれだと思うので自分の感想とどんな人にオススメするかをまとめました。

受講前の筆者の前提知識/能力

  • SI企業勤務プログラマー
  • 理系の大学院修士卒なので数式耐性はついている
  • 機械学習は完全素人ではなくて、「ゼロから作る Deep Learning」等の書籍を かる~く流し読み したりしている。ただし、 実装はしていない
  • 英語は集中して聞けばある程度は分かる。

受講のきっかけと前評判

Qiitaか何かの 機械学習を学ぶならコレ! みたいな記事で知る。

検索をしてみると、Coursera Machine Learningコースは色々な記事で「とても良い」との評判であることを知る。

今の自分のレベルに合っているかは分からなかったが、有名かつ評判の良いものなら時間のあるときにとりあえず受けてみようと思いたつ。

ついでに英語のリスニング練習になったらいいなとも。

感想

良かった点

次の2点がこのコースの良い点だと思う

  • 確実に 「自分で考えながら実装する」工程を踏める
    • 一人では「ふむふむなるほど~」といって数式を流し読むか、よくて写経。答えが広がっているのを写すより、講義資料などをコードに落とす方が時間がかかるが理解が進んだと感じる。
  • 本質でない実装は省ける
    • 機械学習で何を試すにも、データの用意や読み込み,結果の可視化が必要になる。これらは業務上必要ではあるが、ツールの使い方を調べれば良いだけでもある。それらが先に準備されていて、学習対象のアルゴリズムの実装に集中できるのは手間が省けて良い。
  • 講師の考える 「大事なポイント」がわかる
    • 書籍では紙面の都合で「第○章を参照」みたいになってしまうことも、動画の授業なので「○○でも触れたが、こういう時には××するのが大事だ!」みたいに繰り返し教えてくれる。
  • 機械学習技術者のための教養の範囲を抜けないようになっている
    • プログラミングの学習時には教養としてデータ構造やアルゴリズムの実装を学びます。それの機械学習版くらいの内容という感触。深煎りしないようにかなり気をつけた講義だった。

Machine Learningコースというよりは、Courseraの利点かもしれない。(他コースを受講したことがないので)

(自分にとって)いまいちだと思った点

無料のコースなので、不満を言いたいわけではないものの..

  • 日本語字幕があるとはいえ辛い
    • 動画の数式を見ながら日本語の字幕を追うのは思ったよりも難しい。字幕が映像と少しずれてくる事が多いので尚更。誤訳らしきところもあるので、英語だけで理解できる人とはやはり受講のしやすさはかなり違うと思う。
    • 「きれいな英語」との評判だが、受験のリスニング問題みたいなものを想像していたらさすがに違った。
  • かなりの時間を費やす
    • 「約55時間で修了」のコース。丁寧なぶんだけ、時間を多く使ってしまう。個人的にはもう一回り早くて良いと感じた。

その他

  • PythonでもRでもなくMatLab/Octaveなのがちょっと…」という声もあるが、その点は大きな問題ではないと思う。どちらかというと、PythonのNumPyやMatplotlibはMatLabを参考に作られてるんじゃないかと思う。(CやJavaしか触ったことないとエッってなると思う。)
  • 同じCoursera内の他の講義の紹介とかあっても良いのではと思った。似た名前の講座が多くて選びにくいので。
  • ちょっと古い講義なので、その分は勘案して見たほうが良いと思う。「ここまでの内容を理解していたら、シリコンバレーでフルタイムで働く多数の人間よりも効率良く問題に適用できる」とか途中で仰ってますがさすがに今はお世辞にしても違うのでは。
  • リスニング練習になったかは疑問。

誰にオススメするか

次のような人が受けるととても効率が良いと思う。

  • 英語だけでもなんとなく話が分かる
  • 少なくとも高校理系の数学知識がある、できれば大学1年次レベルの知識がある
  • 機械学習は概念的なことは何となく理解しているけど、どういう数学が裏あるのか知らない

逆に、これらにあまり当てはまらない人には必ずしも勧めない。英語も数学も分からないので見るのは苦痛だろうし、機械学習のことを数式レベルである程度理解していたら、日本語の書籍を見て実装をしたほうが時間効率としては良い。

自分は時間があったから最後まで受けたし、受けてみないと向き不向きも分からないわけだが、人生における時間の割り振り方というのは難しいので、これがベストな解になる人はそこまで多くないのではないかと思う。(とはいえ、大きく後悔する人も少ないと思う。)

プログラミングコンテスト中に浮動小数点数で悩んだ話

※ 2019/02/11 に https://wkwkhautbois.wordpress.com/ に投稿した内容の再掲です。

久しぶりの投稿です。 CodeIQやPaizaは今まで何度か挑戦したことがありました。先日、「みんなのプロコン2019」 なるコンテストがAtCoderで開かれるということを知り、アカウントを作り初めてAtCoderに挑戦しました。

AtCoderのアカウント自体を作ったばかりで使い方が分からずバタバタしたり、「え、Python3.4なの?(ちょっと古くない?)」とか焦ったりしながら挑戦する中で、掛け算 , 割り算浮動小数 でハマったのでまとめます。

ハマったこと

C問題「 When I hit my pocket… 」を解いていたときのこと。 入力例3の入力を試すも、微妙に計算結果が合わない。

このときの使用言語はPython3。 出力の際に、最後に

print('%d' % x)

のようにしていた。最初は

print(x)

としていたが、浮動小数点の書式で出力されてしまったので上記のようにしていた。 思えばこのときすぐに気づくべきだった。。

すると、小さい数字では上手くいくのに大きな数字になると微妙に値がずれる現象が発生した。 具体的には、 48518828981938099 が出力されてほしいのに、 48518828981938096 が出力された。 おかしいなと思い、試しにExcelで計算をしてみた。すると、Pythonのときとも違う値が出てきた。

そこで、浮動小数点演算になっている可能性に気づいた。 しかし、偶数のときと奇数のときで場合分けをしていて、整数以外でてこないはず…どこで?

整数演算の結果の型

Pythonは除算の演算子の意味が、Python2とPython3で異なることが、破壊的変更なので結構有名。

Python2: 3 / 2 → 1
Python3: 3 / 2 → 1.5 、3 // 2 → 1

それから、Python3では全ての整数がint型で、Python2のlong型相当になっている。

ここまで知っていたが、一つ知らなかったことがあった。 6÷2のように、 割り切れる演算 のときの結果はどうなるのか? つまり、次のようなときにどういう結果になるか?

if a % 2 == 0:
    b = a / 2
else:    
    b = (a - 1) / 2

このとき、bは常に浮動小数点数(float)になる。 実行コストを考えてみれば当たり前で、いちいち割り切れるかどうか判断してintとfloatを分けるはずもなく。 ただ、浮動小数点数であっても結果が整数(に極めて近い小数)だったら問題になることは今までなくて気にしたことがなかった。

というわけで、除算の演算子を”/”から”//”に変えて一段落。

あれ、Excelは?

Excelでの結果がPython浮動小数点数演算になっていたときと違った。 どうやらExcelでは内部的に全て浮動小数点数で扱っているようで、大きな数の乗算で誤差がでてくる。

セルに直接

=348728501 * 139130667

と入力してみたり、各セルに入力して

=A1 * B1

みたいにしてみたりしたが、どうも計算誤差が出てしまう。

上の計算は、正しくは 48,518,828,946,040,167 なのだが、Excelでは 48,518,828,946,040,200 になる。 33大きい 。表示形式を「通貨」にしてもダメだった。お金の計算はもう少し慎重にしてほしい。

Javascript:整数型の存在しない言語

Javascriptでは数値は全て浮動小数点数で扱われるということを思い出した。 それで問題になったことはあまり聞いたことがないが、どうなるかNode.js 8で上記の計算を試してみると、 48,518,828,946,040,170 になった。こんどは 3だけ大きい 。 Node.jsで競技プログラミングに参加するのは避ける方が懸命のようだ。あるいは、対処法がある??

なお、整数演算が安全にできる範囲は定数で取得することができて、 手元の環境でも確認したが Number.MAX_SAFE_INTEGER は9,007,199,254,740,991 だった。なるほど確かにそれを超えていた。

[参考] qiita.com

Pythonのfloatでの演算

Python3で小数に変換してから掛け合わせて、整数として表示すると、 48,518,828,946,040,168 になる。これまたNode.jsともExcelともちょっと違って 差は1 。ここで差がなかったら、プログラミングコンテスト中に気づくこともなかったかもしれないから逆にラッキーか。 各言語(ツール)の結果の差は、浮動小数点数の内部表現の違いからくるのだろうか?CPUが浮動小数点数演算の回路を持っているからそれに依存するのが速いのだと思っていたけど、違うのだろうか?

学んだこと

スクリプト言語では動的に型付けされることもあって、あまり強くは型について意識していませんでした。それが便利なわけですがど、数値演算なら誤差に、文字列なら不用意な変換やら何やらに悩むことがあり、気をつける必要があると改めて学びました。

あと、5000兆円を手に入れたときにはExcelJavascriptを利用したアプリで資産管理しないようが良さそうです。気をつけましょう。

スーパーフライデー?

フライが安くなる日 というのはなんとなく見えている
それ以外で思うことをなんとなくツラツラと書く。

IT企業の普段の業務

って多くの場合、(他社の)業務の効率化だと思うんですよね。
IT企業というのは主語が大きいけど、売上高を基準としていわゆるWeb系のベンチャー企業を除けば、
「貴社の業務を効率化」とか「その仕事引き受けます」みたいな文言は付いていることが多いような。

勤務時間を減らす策

作業効率を上げて早く帰りましょうとは言うものの、
思いつく範囲で、効果の示せる効率化なんてすでにやっていますよね。
やらない理由もないですよね。

「テストが手動で効率が悪い」「エクセル方眼紙が…」「PCスペックが…」みたいな話はあるかもしれないけど、
それが変わらないというのは、管理者レベルの人たちがそれを変えることによって「効率化できる」と思ってないからだと思うんですよね。
だから、首相とかが何を言おうとも、そういう方向の変化は起きない気がする。

じゃあどうするのか

業務時間を短くする圧力だけは高まっていく。

コンサルに頼るのが一番の解決策なのかなーとぼんやり思っている。
コンサルという職種は口が上手いだけな人も多そうで好きではなかったのだが(というか今もあれだが)、
外からそれらしき事を経営層に吹き込むことができるという点では素晴らしい。
同じことを説明するのにも、社内の下っ端からの意見より、高い金の対価として外部からもらった意見の方が信じる気になりやすいだろう。

本当は

こんな諦め気味な書き込みをしてしまう時点でダメとか言われそうな気がする。
でも、上の話に戻ってしまうけど、効率化しようとして効率化できるなら、すでにやってると思う。
違うのかな。

仕事の活用方法

大学時代の友人と飲み…ではなくて焼肉に行ってきた。(・ω・)オイシカッタ

とりとめもない話をしたのだけど、そのときの話題のひとつが、
「仕事ってプライベートに何か活かせたりするの?」
だった。

業界も職種も全然違う人なので、単純に興味で聞いたんだと思うけど、自分にとっては新鮮な発想だった。

仕事とプライベートを「切り離す」という話はよく聞く。その方が効率が上がるからという理由を話す人もいれば、業務外でPCに触りたくないみたいな人もいる。

逆に、家でもコーディングしてます、それが趣味ですからという人もいる。
自分はどちらかというとこちらか。ただ、資格勉強したりとかもするし、その時のモチベーションの1つは「業務で活かせる」だ。

「仕事をプライベートに活かす」という話は聞かない。結果的にそうなっている時もよくあるのだろうが、そういう表現は聞かない。
業務内容が趣味と一緒ですというのと、大きな違いがあるわけではないけど、発想がちょっと新鮮だった。
改めて自分の業務を振り返ってみると、ちょっと違う世界になるかもしれない。

こういう、ちょっとした気づきのもとをもらうことが多い。