【Kubeflowのラズパイ包み】ラズパイにKubeflowをインストールして機械学習基盤化するとこまで

前回作ったkubernetesのラズパイ包みを、Kubeflowのラズパイ包みにして、機械学習基盤のおもちゃにする。

tkzs.hatenablog.com

まずはksonnetからのインストールから

ksonnetはkubernetesをjsonnetというJSON用のDSLを使った設定ファイル管理ツールっぽい。これを使ってKubeflowのデプロイなどの設定を行う。

Home ⋅ ksonnet

macOSならbrewで入れられるのだが、それ以外はバイナリからのビルドになる。

github.com

インストールにgolang必要そうなので、まずはそっちインストールから。

$ wget https://golang.org/dl/go1.10.1.linux-armv6l.tar.gz
$ sudo tar -C /usr/local -xzf go1.10.1.linux-armv6l.tar.gz
$ ls -l /usr/local/go
$ cat /usr/local/go/VERSION
$ sudo vi ~/.bashrc
$ source $HOME/.bashrc

次にksonnet。GitHubのリポジトリからバイナリを取ってきて、インストールし、パスを通す。

# Clone the ksonnet repo into your GOPATH
$ go get github.com/ksonnet/ksonnet

# Build and install binary under shortname `ks` into $GOPATH/bin
$ cd $GOPATH/src/github.com/ksonnet/ksonnet
$ make install
$ PATH=$PATH:$GOPATH/bin
$ ks version
ksonnet version: dev-2018-07-20T09:11:08+0000
jsonnet version: v0.10.0
client-go version: kubernetes-1.10.4

とりあえず入った。

ksコマンドは下記わかってればなんとかなる。

  • ks generate : componentsについてのmanifestを作成
  • ks apply : クラスタに実行可能なmanifestをあてる

ここから先はKubeflow v0.1のアナウンスを参考にする。

kubernetes.io

$ NAMESPACE=kubeflow
$ kubectl create namespace ${NAMESPACE}
$ VERSION=v0.1.3

# Initialize a ksonnet app. Set the namespace for it's default environment.
$ APP_NAME=my-kubeflow
$ ks init ${APP_NAME}
INFO Using context "kubernetes-admin@kubernetes" from kubeconfig file "/home/pi/.kube/config"
INFO Creating environment "default" with namespace "default", pointing to "version:v1.9.9" cluster at address "https://192.168.13.2:6443"
INFO Generating ksonnet-lib data at path '/home/pi/my-kubeflow/lib/ksonnet-lib/v1.9.9'

$ cd ${APP_NAME}
$ ks env set default --namespace ${NAMESPACE}

# Install Kubeflow components
$ ks registry add kubeflow github.com/kubeflow/kubeflow/tree/${VERSION}/kubeflow
$ ks pkg install kubeflow/core@${VERSION}
INFO Retrieved 22 files
$ ks pkg install kubeflow/tf-serving@${VERSION}
INFO Retrieved 5 files
$ ks pkg install kubeflow/tf-job@${VERSION}
INFO Retrieved 5 files

# Create templates for core components
$ ks generate kubeflow-core kubeflow-core
INFO Writing component at '/home/pi/my-kubeflow/components/kubeflow-core.jsonnet'

# Deploy Kubeflow
$ ks apply default -c kubeflow-core 
ERROR handle object: patching object from cluster: merging object with existing state: Get https://192.168.13.2:6443/api/v1/namespaces/kubeflow/configmaps/jupyterhub-config: net/http: TLS handshake timeout

最後のks applyでエラー吐くので、issueからWork aroundを見つけて対応。

github.com

$ ks show default -c kubeflow-core | kubectl apply -f 
service "k8s-dashboard" created
deployment "ambassador" created
service "ambassador" created
serviceaccount "ambassador" created
role "ambassador" created
rolebinding "ambassador" created
service "ambassador-admin" created
clusterrole "tf-job-dashboard" created
clusterrolebinding "tf-job-dashboard" created
clusterrole "tf-job-operator" created
clusterrolebinding "tf-job-operator" created
serviceaccount "jupyter-hub" created
role "jupyter-role" created
rolebinding "jupyter-role" created
configmap "jupyterhub-config" created
deployment "tf-job-dashboard" created
configmap "tf-job-operator-config" created
customresourcedefinition "tfjobs.kubeflow.org" created
deployment "tf-job-operator" created
statefulset "tf-hub" created
service "tf-hub-0" created
service "tf-hub-lb" created
service "tf-job-dashboard" created
serviceaccount "tf-job-dashboard" created
serviceaccount "tf-job-operator" created

眠すぎて、一旦とりあえず今日はここまで。モデルのServingとかは持ち越し。

events.linuxfoundation.org

KubeCon + CloudNativeCon EU 2018のセッションの資料を見ると、TF servingじゃなくてSeldon使えたり、TFじゃなくてsklearn使えるようになるっぽい。もう出来るようになっている?ぼちぼち試していく。

処理遅いしGKEでやりゃ良くね?みたいなことはコマンド打つ毎に考えるけど、それ言い出したらせっかくのラズパイ包み楽しくないから多少のことは我慢する。

参考

【Kubeのラズパイ包み】Rasberry Piを使ったKubernetes クラスタでの機械学習基盤構築

はじめに

機械学習基盤、もうちょいなんとかしたくて、勉強のためにKubernetesのオライリー本を買ったら、付録に「Rasberry Piを使ったKubernetes クラスタ構築」を見つけたので本体読み始める前に必要なもの揃えて構築してみました。この上で勉強すればいいかなって。

入門 Kubernetes

入門 Kubernetes

  • 作者: Kelsey Hightower,Brendan Burns,Joe Beda,松浦隼人
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2018/03/22
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

で、色んな方が既に実践されているので多いに参考にさせて頂きました。ありがとうございました。

developers.cyberagent.co.jp

qiita.com

色んな所でこのラズパイのkubernetes包みは紹介されているので、わざわざ記事にしなくても良いかなと思ったけど、そのままやったんじゃエラー吐いたから備忘録的に。

必要なモノ揃えて、 f:id:tkzs:20180720011759j:plain

組み立てる。

f:id:tkzs:20180720011841j:plain

機械学習基盤にしようとしてるけど、無線で全部つなげるっていう不安定さ、ホンマにいいんかなって気はするけど、まぁいいや。使ったRaspbianは下記。

$ lsb_relsease -a
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 9.4 (stretch)
Release:        9.4
Codename:       stretch

もろもろ準備

下ごしらえで3台のラズパイに下記を実施。

まずはネットワーク周りを確保したいが、 /etc/wpa_supplicant/wpa_supplicant.confを編集してWiFi有効化する方法だとなぜか反映されなかったので、

sudo raspi-config

でWiFi環境を設定しておいた。

ラズパイホスト名が同じraspberryになっていたのでk8s-master,k8s-node1, k8s-node2へ変更。

$ sudo apt-get update
$ sudo apt-get -y upgarade

$ sudo vi /etc/hosts
$ sudo vi /etc/hostname

さらにcgroupsの有効化するために。

$ cd /Volumes/boot
$ vi cmdline.txt

でcgroup_enable=cpuset cgroup_enable=memoryを追加。

$sudo apt-get install -y \
     apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     software-properties-common

$ sudo dphys-swapfile swapoff
$ sudo dphys-swapfile uninstall
$ sudo update-rc.d dphys-swapfile remove

Dockerのインストール

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ echo "deb [arch=armhf] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
     $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

$ sudo apt-get update
$ sudo apt-get -y install docker-ce

kubeadmのインストール

現時点でlatestであった1.11をインストールして進めるとkubeadm initの段階でエラーが発生したので、1.9.7を使っている。GKEと同じバージョン。

$ curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
$ echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

$ sudo apt-get update
$ sudo apt-get install -y kubelet=1.9.7-00 kubeadm=1.9.7-00 kubectl=1.9.7-00

ちなみにkubeadm v1.11でinitしようとすると

Jul 14 20:19:12 k8s-node1 kubelet[5447]: E0714 20:19:12.365501    5447 reflector.go:205] k8s.io/kubernetes/pkg/kubelet/kubelet.go:455: Failed to list v1.Service: Get https://192.168.13.7:6443/api/v1/services?limit=500&resourceVersion=0: dial tcp 192.168.13.7:6443: connect: connection refused

ってエラーが出たから下記のissueに従って変更。

github.com

masterのセットアップ

今回マスターが仕様するIPアドレスは192.168.13.7だったので、このアドレスを指定してノードをクラスタにする必要がある。そのための--apiserver-advertise-addressへの登録。initに成功したら素直に支持されたコマンドでconfigファイルをコピー。

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.13.7 --ignore-preflight-errors=cri

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join --token xxxxxx.xxxxxxxxxxxxx 192.168.13.7:6443 --discovery-token-ca-cert-hash xxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

nodeのセットアップ

ノード端末の方でもinit時に指定されていたコマンドでmasterに参加。

sudo kubeadm join --token xxxxxxxxxxxxxxxxxxxxxxxx 192.168.13.7:6443 --discovery-token-ca-cert-hash xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

とりあえずできた

ちゃんとレジストされているか確認。

$ kubectl get node
NAME         STATUS     ROLES     AGE       VERSION
k8s-master   NotReady   master    2h        v1.9.7
k8s-node1    Ready      <none>    1h        v1.9.7
k8s-node2    NotReady   <none>    1h        v1.9.7

できてた。

Pythonのクロージャ理解する

少し複雑なデコレータを実装したくなったけど、クロージャの挙動ちゃんと理解してないなと思いFluent Pythonで復習しました。
使ったのは第7章5節と6節です。

Fluent Python ―Pythonicな思考とコーディング手法

Fluent Python ―Pythonicな思考とコーディング手法

関数の外部で定義された非グローバルな変数うにどのようにアクセスしているか確認します。
例として挙がっていたのは値が除々に追加されているリストの平均値を計算するようなavg関数です。

まずはクラスを使って実装すると下記のようになります。

class Averager():


  def __init__(self):
    self.series = []

  def __call__(self, new_value):
    self.series.append(new_value)
    total = sum(self.series)
    return total/len(self.series)

if __name__ == "__main__":
  avg = Averager()
  print(avg(10))
  print(avg(11))
  print(avg(12))
実行結果:
10.0
10.5
11.0

このときavgはAveragerのインスタンス。
次は同様のものを関数型で実装してみる。

def make_averager():
  series = []

  def averager(new_value):
    series.append(new_value)
    total = sum(series)
    return total / len(series)

  return averager

if __name__ == "__main__":
  avg = make_averager()
  print(avg(10))
  print(avg(11))
  print(avg(12))
実行結果:
10.0
10.5
11.0

このときのavgは make_averager()の返り値であるaverager関数。
avg関数はseriesというaveragerの外で定義されている変数を参照している.

次に、totalやlen(series)を毎回計算するのは効率が悪いので、これまでの値の総和や要素数のみを保持するように書き換えます。

def make_averager():
  count = 0
  total = 0

  def averager(new_value):
    count += 1
    total += new_value
    return total / count

  return averager

if __name__ == "__main__":
  avg = make_averager()
  print(avg(10))
  print(avg(11))
  print(avg(12))

するとエラーがでる。

実行結果:
Traceback(most recent call last):
 ...
UnboundLocalError: local variable 'count' referenced before assignment

ここでcountとtotalはaveragerの中で再代入されているのでローカル変数扱いとなってしまいます。
参照はOk,再代入はできない。
けど、nonlocal宣言を使うとこのエラーを回避できる。

def make_averager():
  count = 0
  total = 0

  def averager(new_value):
    nonlocal count, total
    count += 1
    total += new_value
    return total / count

  return averager

if __name__ == "__main__":
  avg = make_averager()
  print(avg(10))
  print(avg(11))
  print(avg(12))
実行結果:
10.0
10.5
11.0

クロージャの挙動なんとなく理解できたんで、頑張ってデコレータの実装します。

機械学習工学研究会キックオフシンポジウムを振り返って

なんか最近こればっかやけど、機械学習工学研究会のキックオフシンポジウム行ってきました。

mlxse.connpass.com

企業の方、アカデミアの方など立場様々な方が参加されてそれぞれの視点から課題点を出されていて面白かった。有賀さんや久保さんなど企業の方々の講演はご自身達も仰っていたし会場やTwitter上でも「機械学習システム開発あるある」な感じだったが、「みんな共通認識持ってるんだね、じゃあここから議論しよう!」といったシンポジウムの意義を考えると素晴らしい課題定期だったなと。一方で、冒頭で杉山先生が「機械学習に実務で取り組んでいる方?」という質問への挙手が体感的には4割行かない程度だったところから、活発な議論がされるのは極々一部であり、マーケットにリテラシーが醸成されるのはまだまだこれからだなというところも感じられました。

いずれにせよ、運営されている方々、登壇者の皆様ありがとうございました。

印象に残った議論ポイントとその感想

要件定義難しい問題結構言われている

アクセンチュア工藤さん、Cloudera有賀さんの二人から同様に「期待値コントロール大事」とされていたり、パネルディスカッションでも「要件定義難しい」という議論がされていたりした。パネラーの皆様の反応見ると「PoC貧乏」はどこでも起きていて、どのように業務に適用するのかの要件定義無しにとりあえず一旦PoCで、ってなっているようで、これは乗り越えなきゃいけない課題なんだなと感じました。ただ議論を聞いていると

  1. システム開発の要件定義はそもそも難しい
  2. AIブームでMLへのリテラシーが低いユーザーがMLシステムの要件定義しているので難しい
  3. MLがそもそもPoC(概念検証)が挟まる「やってみないとわからない」状態で不確実性が高いためその後の業務要件定義難しい

あたりがごっちゃになって議論されているように思えた。特に話題になりがちであった同様の議論に「変えたい業務はなくて力試しされた」とか「運用設計が難しい」といった内容は単純に「リテラシーが低いから」と言えなくも無いような気がしています。一番強烈なのは、機械学習を使うことが目的化し、要求を満たすための選択肢に「機会学習を用いて」という条件がかかって狭まってしまい、なおさらわけわからん要求が出てきてしまうパターンがありますよね。

実業務でも「実際MVP作ってみると欲しかったのは機械学習やなくて、大量の画像を整理するのに便利なGUIやったんや!」みたいな話は経験したことあります。

じゃどうやって乗り越えるんや、で言うと、

1,2に対しては、個別のプロジェクトではいわゆるワークショップのような形で企画者、開発者、ユーザー、ドメインナレッジ担当、そして機械学習詳しい人を集めて、どのような問い(テーマ)だと機械学習で解決できるのか、難易度はどの程度か、ビジネスへのインパクトはどのようなものかを一緒になって考えていくことですね。ワークショップ形式が良いなと思う理由としては、昨今のAIブームで「とにかくAIでなんとかしなきゃ!」みたいな形でアイデアを出し、業務で使う際の制約を考慮することなくPoCに突っ込んでしまうことを、ユーザー含めて議論することで抑えることが出来るからかなと。

もうちょっと引いた目線で言うと、「AIでXXXを実現!」みたいに半ば広告ぽく世に放たれている事例を

  • どのようなテーマを
  • 機械学習で解ける問題として、どのように切り出して
  • どのようなデータに対して
  • どのような技術を用いて

解決したのかを解説することでユーザー含めた世の中のリテラシーの向上に貢献できるんですかね。Kaggleのコンペを非Kaggler、非MLエンジニア向けにざっくりした粒度で伝えるのなんてどうだろう、なんてことを妄想中。やってみるか。Kagglerにしばき回されそうですが。

しかしながら、そもそも論でAIガチャ*1を一回引いて上手く行って信用してもらえたところしかワークショップ開くだけの協力を貰えないなんてことも往々にしてあるので、難しいところ。「ワークショップ→MVP→PoC」の流れを業界のデファクトにしてしまいたい。。。

機械学習工学界隈で一番議論したいのは3ですよね。PoCを経なければいけないという不確実性のマネジメントについてはこれまでのソフトウェア工学の知見は応用できるでしょうし、実業務の中で現場の人間が頑張っているものを持ち寄って、そこから知見を抽出することでアカデミアにも貢献できるんじゃないかなと思っています。というか、ここくらいしか貢献できる部分ないなーという感じ、頑張る。

機械学習システムの基盤について

デプロイした後の機械学習システムの基盤についての議論がTwitter上では見られたなーって感じでした。実装まで同じじゃないとしても基本的な考え方はTFXにあるんだろうと。

TFX A TensorFlow-Based Production-Scale Machine Learning Platform

機械学習システム基盤はベースにどこまで各社工夫しますか、の世界ですよね。基盤だけあってもしょうがなくて、基盤きちんと回せる組織どうしましょうに興味あり。

そういいう意味で言うと、

Human-in-the-loop: The machine learning platform needs to expose simple user interfaces to make it easy for engineers to deploy and monitor the platform with minimal configuration. Furthermore, it also needs to help users with various levels of machine-learning expertise understand and analyze their data and models.
引用元:TFX A TensorFlow-Based Production-Scale Machine Learning Platform

が重要になってくるのかと思います。この辺りを支えるツール作りたい。
MLOpsな機械学習モデルの運用で変わってきそうな点ってドメインナレッジ担当者が積極的にシステムの挙動を確認して諸々判断せないかんとこだろうなと。で、なんの情報を誰に渡すのか、そこからどのような判断を下させるのか、はもろにドメインや適用先業務によって個性が出てくる部分であり標準化は難しそう。センス良く作り込むのはデータサイエンティストや機械学習エンジニアの腕の見せ所ではないかと思います。機械学習モデル、開発者、ドメインナレッジ担当者を橋渡しするようなコミュニケーションをデザインするとか絶対楽しいやん。このコミュニケーションツール作りたい。単なるボットとかじゃなくてイケてるやつ。

まとめ

  • 非機械学習者向けのKaggleソリューション解説
  • 機械学習システム基盤と組織をつなぐコミュニケーションツール作る

この二つやりたい。

【後編】機械学習工学研究会キックオフシンポジウムの前に読みたい記事や論文や本

昨日は分析官やっている人間が機会学習システムの課題感について全体感を把握するためにいくつか見直したけど、今日は開発プロセスや実行する組織、支える基盤についてフォーカスあてていこうと思う。もろもろ課題あるけど、実際どうやって機械学習システムって作るんだっけ?って視点。きっとソフトウェア工学のアカデミアの人とか、エンジニアから機械学習始めた方々は違った視点があるんだろうけど。

分析官として機会学習システムの開発やってて*1、従来のシステム開発とは違うんだろうなと思うのは、

  1. 機械学習モデリングの部分でPoC挟むからプロジェクト開始時に要件定義固めちゃうの難しい
  2. AIブームで機械学習が何をどこまでできるかわからん人多くて、これもやっぱりプロジェクト開始時に要件定義固めちゃうの怖い
  3. 運用に入ってからも「モデル再学習」というプログラムの変更なしにシステムの挙動が変わるイベント発生しがち

あたりですね。


1については例えば異物を排除するようなシステムを考える場合、異常検知の精度がめちゃくちゃ良ければ、業務適用時に完全自動化を目指すような形になるかもですし、精度そこそこなら、人間が実施している工程をサポートするようなシステムが求められるかもですし。この辺りはPoCの結果を見ながら「どのように業務適用させるか考えよう」になりがちです。最初に要件決めきらずに少しずつ完成形を目指していくのはきっとアジャイルな開発が向いているのだろうなと。

2については、今だけの一過性の話であって欲しいですが、机上で要件定義をしようとすると、企画者、ユーザー、ステークホルダーなどがそれぞれみんな異なるAIなるものを頭に思い描いているので、議論が噛み合わず要件が決まりきらなくなってしまいます。なのでたたき台となる具体的なプロトタイプを早く作って意見をすり合わせるのが重要かなと。

昨今のAIブームだと開発することにみんな熱中してて、3のような機械学習システムの真の魔物が運用時にいることにあまり注目されてないんですよね。日々のデータに合わせて機械学習モデルを再学習&更新するタイプのシステムだと運用って下記みたいなフローになるのではないかと思います。


f:id:tkzs:20180516173218p:plain


この時、従来のシステムと異なるのはデプロイ判定する場面が二つあり、それに合わせてループが二つあることかなと。特に再学習側のループはプログラムの変更無しにシステムの挙動が変わるので、「なんでこんな挙動になるんだ?」はデータを見てみないことにはわからないことも。さらに本番デプロイしてOKかどうかも全自動で判別できないこともあり、その場合にはデータのことよくわかってるビジネス担当とデータエンジニアや分析官で相談しながら対応しなければいけなかったり。適用する業務先によってこの辺はマチマチなので汎用的な解はないでしょうが、だからこそ難しい。

以上、3つの課題感に対して、この辺を上手いことやる方法がいわゆるアジャイル開発やDevOpsってものにあるんじゃないかなと感じていますが、どう機械学習システムに応用していいのかは模索中。

読んだ本達

エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング

エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング

「エンジニアリングとは不確実性を減らすこと」でありその概念や具体的な方法論について紹介されていて、不確実性が高くなりがちな機械学習システムの開発に役立つ考え方が多く参考になりました。

Effective DevOps ―4本柱による持続可能な組織文化の育て方

Effective DevOps ―4本柱による持続可能な組織文化の育て方

DevOpsのための4つの柱の1つ目がコラボレーションであり二つ目がアフィニティなのは、機械学習システムではより求められそうだなと。上記の図で再学習でのシステムの挙動の変化を掴むためにはステークホルダーで相談だ!みたいなシチュエーションがると言いましたが、この辺りをどのように組織として効果的に実施するのかはものすごく重要に思えます。これまでのDevOpsと比較して参加する人種が増えてくるところが大きな違いとチームの偉い人が言ってて、すごく納得感有る。

DevOps導入指南 Infrastructure as Codeでチーム開発・サービス運用を効率化する (DEV Engineer’s Books)

DevOps導入指南 Infrastructure as Codeでチーム開発・サービス運用を効率化する (DEV Engineer’s Books)

  • 作者: 河村聖悟,北野太郎,中山貴尋,日下部貴章,株式会社リクルートテクノロジーズ
  • 出版社/メーカー: 翔泳社
  • 発売日: 2016/10/14
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

組織論やプロセス論だけではなくて具体的なツールについても記載があり参考になりました。大事なのはモデル構築→デプロイ→再学習→デプロイといった流れを上手く支える基盤とコミュニケーションツールですが、機械学習システム向けってのはまだないですね。既存のものの応用でできるかどうかは、適用する業務によって変わるんじゃないかなって印象です。

まとめ

機会学習の急速な普及で、研究者でもエンジニアでもない立場の人間でも、どうやって実業務に運用しようか?を考える必要が出てきてます。立場が異なる方々とお話できる良い機会なので意味有る会話をさせて頂けるよう頭の中整理してみました。楽しみ。

*1:エンジニア出身じゃないから正直自信ないとこあるけど

【前編】機械学習工学研究会キックオフシンポジウムの前に読みたい記事や論文や本

機械学習をPoCから実際の本番環境への導入、プロダクトへの適用を考えると従来のITシステムに用いられてきた開発手法やソフトウェア工学的な手法では対応できない課題がたくさんあります。
じゃあそれについてどう対応しようか?を考えるのが機械学習工学だったりSoftware Engineering for Machine Learning(SE4ML)だったり、MLOpsだったりするわけですが、まぁ対象範囲が広いんですよ。ソフトウェア工学が対象としていた範囲全体に機械学習が関わったらだったらどうだろう?考えるわけですから。

で、日本では5月17日に機械学習工学研究会のキックオフシンポジウムが開かれます。

https://mlxse.connpass.com/event/80434/mlxse.connpass.com

この研究会自体、立ち上がったばかりでどこから具体的に手を付けていこうかから考えている段階ぽいですし、 参加者もそれぞれの持場で機械学習を頑張ってきた方々なので課題の全体像を把握されている方は少ないのではと思います。弊社もスポンサー企業としてポスター出しますが、実務の中で経験したもののベストプはこれってのを共有するのいでなんら学術的ではないです。


自分自身も分析官として深層学習使った画像識別やオーソドックスな機械学習を用いた需要予測系のシステム開発にいくいつか携わっただけで、まだまだ肌感ない領域多いですし、事前に整理しておきたいのでまとめます。

過去の機械学習工学研究会の活動

SE4ML meet-up 2017/11/8として実施されたもので全体感を掴むのは良いかも。まずは集まって課題感の共有って感じですが観点も興味ポイントも様々で面白い。工数見積、品質などの部分はいくつかプロジェクトをこなすと感覚的にできますが工学的じゃないですね。
mlxse.connpass.com

そもそもソフトウェア工学って?

機械学習側から機械学習工学に入る人にとってはそもそもソフトウェア工学ちゃんと勉強したことない人多いんじゃないでしょうか。今一緒にやってる出来るエンジニアがソフトウェア工学で博士取ってるんで毎回聞いて教えてもらえる恵まれた環境にあるのはホントありがたい。そのおおっさんに「とりあえず最初はコレがいいんじゃないっすか」って教えて貰ったのがこの本。研究ではなく実務に携わるという観点だとクセなく、全体感を知ることができておすすめです。

実践的ソフトウェア工学―実践現場から学ぶソフトウェア開発の勘所 (トップエスイー入門講座)

実践的ソフトウェア工学―実践現場から学ぶソフトウェア開発の勘所 (トップエスイー入門講座)

機械学習をサービスに載せる時の辛みって?

機械学習工学やソフトウェア工学ってソフトウェアやサービスを開発及び運用する際の辛みをエンジニアリングすることが目的だとすると、その対象である機械学習システムのしんどいところについて自分の業務以外の人達どうしてるんだろを知りたくなります。研究会なのでまずは論文から。

Machine Learning The High-Interest Credit Card of Technical Debt

Hidden Technical Debt in Machine Learning Systems


初出はGoogleが2014年のNIPSのワークショップで出した論文で、機械学習システム構築の課題感を書き表した古典です。今でも根本解決はされていない課題感が体系立てて書かれていて良いです。Pipeline JunglesやDead Experimental Codepathsなどデータサイエンティストが書いたコードは試行錯誤の結果で汚いよ的なことが書かれており、機械学習エンジニアや従来のエンジニアとの分業で分析官のコードをそのまま本番に載せるなが当たり前になりてきた昨今から見ると、かつてはGoogleもそうだったんだなと感じられて面白いです。

www.lucypark.kr
ACML-AIMLP Workshop で発表された機械学習版Joel Test。これに全部yesで答えられてもまだまだ上手く開発・運用できなさそう。

What’s your ML Test Score? A rubric for ML production systems

これもGoogle。機械学習システムについてのrubricとしてのテストを提供してくれている。テストの裏返しが課題感だとすると全体感を掴むのに良いのでは。

まとめ

ひとまず今日は課題感の方からまとめて見ました。明日は機械学習システム開発のプロセスや組織論の方から書こうかな。

自分の業務では全部把握は仕切れないので興味の範囲を広く持って研究会に参加したいです。

【論文読み】CVAE-GAN : Fine Grained Image Generation though Asymmetric Training

今回はクラス情報を持った画像を生成するためにVAEとGANを上手に組み合わせましたよというお話。
CVAE-GAN: Fine Grained Image Generation though Asymmetric Training


【感想】
・Mean feature matching のなるほど感
・Loss関数たくさん&そこにハイパラ設定せにゃならん
 →職人芸感満載、しかもepock数100kとか言われると自分の設定正しいかの検証無理。


【Abstruct】

  • あるIdentityを持った様々なカテゴリーの画像を生成したい
  • VAEとGANを組み合わせたモデルを提案する
  • しかし、ナイーブにはうまくいかない、なぜならばVAEの画像はぼやけるからCriminatorが簡単に偽物と判別できる

なので、

  • 本物のデータ群の平均の特徴量とのL2距離を損失関数として採用
  • 勾配消失が緩和される
  • Mean feature matching はモード崩壊を軽減するが、モード崩壊は完全には防げない。ここにVAEとGANの組み合わせが効く

【slideshareにスライド上げた】
https://www.slideshare.net/KazusaTaketoshi/cvaeganfinegrained-image-generation-through-asymmetric-training

【Githubにコード上げた】
ひとまず他人のコード借りて、改変したもので実装してみた。
https://github.com/tkazusa/CVAE-GAN