FC2ブログ

子供の落書き帳 Remix

15/4/13:ひと月に一度更新するブログになってしまっている

TortoiseSVNでファイルシステム形式が違って失敗 (version 1.9→1.10)
2018/08/25(土) 00:04:36

TortoiseSVNでチェックアウトに失敗した。
以下のエラーメッセージが出てきた。


Unable to connect to a repository at URL
'file:///Z:/hogehoge/repository/trunk'
リポジトリ 'file:///Z:/hogehoge/repository/trunk' を開けませんでした
期待されるファイルシステム形式は 1 から '7' の間ですが、実際の形式は '8' です


ネットを見ると「TortoiseSVNとSubversionのバージョンが違うのが原因である」と書いてある。
しかし確認してみると、以下の通りで、別に違っていない。

TortoiseSVN 1.9.5, Build 27581 - 64 Bit , 2016/11/26 09:18:58
Subversion 1.9.5, -release

TortoiseSVNを更新すると、自動的にSubversionのほうも更新される。
バージョンを以下の通りに更新してから再度チェックアウトすると、上手く行った。

TortoiseSVN 1.10.1, Build 28295 - 64 Bit , 2018/07/15 12:14:12
ipv6 enabled
Subversion 1.10.2, -release

Subversion リリースノートをを見てみると、以下のようなことが書いてある。
「Subversion 1.10では新たなファイルシステムが導入された。それはLZ4 圧縮形式であり、ファイルシステム形式8で表わされる。また、デフォルトではファイルシステム形式8が使われる」
問題のリポジトリは、チームのメンバーが(TortoiseSVN 1.10を使って)新規に作成したものだった。
Apache Subversion 1.10 Release Notes
Subversion 1.10 リリースノート(アルファ)


うーん、よく分からないけど、次のようなことが起きていたんじゃないかな?

チームの人がリポジトリを新規作成、デフォルトのファイルシステム形式8が使われる
→俺のパソコンからチェックアウトしようとする
→俺のTortoiseSVN 1.9でサポートしているファイルシステム形式は1~7なのに、範囲外の8が使われていたのでエラー


  1. 2018/08/25(土) 00:04:36|
  2. プログラミング
  3. | トラックバック:0
  4. | コメント:0

Developers Summit 2018 Summer 感想。データサイエンスを学んだ一日
2018/08/05(日) 21:39:15

2018年7月27日に開催されたDevelopers Summit 2018 Summerに参加しました。

講演関連資料は以下。
Developers Summit 2018 Summer、講演関連資料まとめ:CodeZine(コードジン)
業務がすごく暇……えーと、多忙ではなかったので、さっさと有給休暇を申請して出かけてきた。

なお、2018年2月のデブサミ2018の感想はこちら。
Developers Summit 2018 感想。ここでしか聞けない講演がたくさんあった 子供の落書き帳 Remix

【A-1】 AIを支えるGPUコンピューティングの今


【イベントページ】こちら

【スライド】未公開
NVIDIA Japan Presentations on SlideShare の中に上がるでしょう
【感想】
深層学習をやる上でNVIDIAはよくお世話になるものの、NVIDIAの話は聞いたことが無かったので貴重な機会だった。
CPUとGPUを比較して見てみると、トランジスタの数はそれほど変わらない。
しかし演算機の数はGPUのほうが数倍多い。これは同じような計算を大量に並行して実行することに特化しているためである。
1世代前のTesla P100と比べても、Tesla V100はかなりの性能向上がなされているらしい。


【B-4】 「教えて!goo」3000万件のQAデータから、世界初の長文生成AIが生まれるまで~AIによる恋愛相談の裏側~


【イベントページ】こちら
参考リンク:
恋愛のお悩みにお答えします | 教えて!gooのAIオシエル
「教えて!goo」 恋愛相談カテゴリーへのAI導入開始のお知らせ | gooプレスリリース (2016年9月6日)
【スライド】未公開
【感想】
factoid:答えが一意に定まる単純なQ&A
例:「富士山の高さは?」「本能寺の変は何年に起きた?」とか
こちらはIBMのワトソンがクイズ番組で人間に勝つなど、すでに高い精度が出ている。
non-factoid:答えが多様、複雑、長文となるQA
例:教えてgooやその他質問系のサイトの多くの投稿
こちらは難易度が高く、精度の良い結果はまだ出ていない

長文に一貫性をもたせて、回答が支離滅裂になってしまわないよう、回答文を作るときは構成を固定している。
「共感、結論、理由、励まし、名言」の構成にしている
30000件回答して、good17%という率は、他のユーザと比べてもそんなに引けを取らない。

講演の中で、実際の質問と回答の例が登場したが、質問と回答の内容ががイマイチ噛み合ってないように見えた。まだ改善の余地があるのかもしれない。

【C-5】 人脈の情報はどうやって蓄積されるのか?Sansan/Eight のデータエンジニアリング


【イベントページ】こちら
【スライド】未公開
【感想】

具体的なデータ分析/機械学習の技術の話ではなく、やや抽象的なデータの考え方・捉え方の話。
3点あって、

1:取り扱いは慎重に
個人情報、機微な情報か機微でない情報か
公知の情報から価値を生み出すのは難しい。一方で、機微な情報は高い価値を持つかもしれないが、収集が難しい。
取り扱うデータによって、どこに力点を入れるか、使い分けを意識する

2:構造の複雑さに注意
単純なイベントログは時系列で構造が簡単。一方で、基幹系などの構造化されたデータは取り回しが難しい。
データ構造が違うと適用できる手法も違ってくる。(やろうとしている分析手法があっても、構造のとり方次第ではその手法が使えないかもしれない)
構造の複雑さはその後の処理に影響している
sansanの名刺データはそれなりに複雑

3:フェーズにおけるユーザ価値
データを収拾・蓄積する方法は、データの種別によって分かれる
 無料で手に入る公開データ(気象庁から過去の気温データを取るとか)
 有料で手に入れる
 金を払ってみんなにアンケートを取って(新しい製品の感想などはこれが必要)
 ゲームのログはみんなの行動が蓄積されてくる など…
出口(価値提供の相手)をどっちにするかが大事
入手先と出口(価値提供の相手)が同じとは限らない
(ゲームのログを見て新たな施策を打つ場合は価値提供の相手がゲームのユーザで、入手先と等しい。
一方、気象庁からデータを集めてきて、そこから新たなサービスを開発したとしても、おそらくその価値提供の相手は気象庁ではないだろう)

実務でデータ分析を扱っているわけではないからすぐに役立つというものではないが、
データを扱う際には留意しておきたいと思った。
また、名刺データ(個人情報のかたまり)を、個人情報を保護しながらどうやって性格に認識処理するか、という観点の話もあり、なかなか興味深かった。

【A-7】意外と知らない?!GitHubの新機能を紹介します


【イベントページ】こちら
【スライド】Developers Summit 2018 0727 - Speaker Deck
【感想】

普段はGit / GitHubをほとんど使っていないので、発表内容を書いたとしてもスライドの丸写しになってしまう……
スライドを見るのが一番わかり易いと思う。
最近半年、1年の間に新たな機能が多く開発され、長足の進歩を遂げたことに驚いた。

講演者が口頭で補足説明していたが、GitHubには「ユーザが嫌な思いをしないようにするための機能を開発する部署」があるというのがすごいと思った。
・Issueを保護状態(特定ユーザのみ書き込み可能)
・ユーザをブロック
などの機能を開発しるらしい。

新機能をの情報を追いかけるためには、以下のサイトを見ると良いとのこと。
The GitHub Blog (日本語版)
The GitHub Blog (英語版)
The GitHub Blog changelig(英語。細かい変更に関しても記載してあるので、機能追加を網羅したい人向け)

【B-8】Kaggleで描く成長戦略~個人編・組織編~


【イベントページ】こちら
【スライド】
【感想】

kaggleやってる人の話って聞いたことなかったな、どんなものだろう、と思ったので聞きに行った。
ちなみに俺自身は、kaggle登録、kernel上で触ってみるまではやったけどsubmitはしたことない、という状態である。
参考:kaggle初心者はカーネルを読むだけでも勉強になったよ 子供の落書き帳 Remix

競技で上位に入れば賞金は入ることがあるけど、それは続ける理由にはならない。
(それは確かにそうだ。賞金がもらえるのはごく一握りの数人だけだし、GCPとかAWSで動かそうとしたら費用もかなり掛かる)
「単純に上位に入るのが面白いから(ネトゲと同じ感覚)」「成績を上げるためにデータ分析の新しい手法を習得できるから」あたりがkagglerがkaggleを続ける理由であるらしい。
そういう意味では、モチベーションの源泉は競技プログラミングと似ている。

下の記録ツイートが講演者に拾われて「お、こうまとめてくれると嬉しいですねぇ」みたいなことを言われたので思わず照れた。



このツイートを受けて口頭で補足説明していた部分があり、資料には出てこないので書いておく。
kagglerが在籍している全社基盤部分の部署とは別に、それぞれの事業領域の中にもデータ分析担当者がいて、各事業をよく知った上でデータを分析して施策を考えている。
その分析に対してkaggglerの人たちが真っ先に考えるのは、まずその目指すべき指標・評価値が適切かどうかということ。不適切な評価値を設定してしまうと、それをハックされかねない。
(筆者注:例を挙げると、オウンドメディアに対して施策を打つ上でPVを成果指標にしてしまうと、「じゃあページをたくさん分割すればPVが増える」という施策が出てきてしまうかもしれないが、それが本当に望ましいのか、ということ。)


実のところ、俺自身が最も印象に残ったのはkaggle自体の話ではなく、組織の作り方の話であった。
資料終盤で「データ分析・機械学習に関する組織図」という図がある。
そこにはいくつかに分かれた「データ分析・機械学習の部門」が、それぞれの役割を担っている姿が書かれている。
DeNAではkagglerを成績に応じて採用します、というニュースが広まったため、DeNAの機械学習チームってのはkagglerばっかりなのかと思っていた。
しかし実際にはそうではなく、「実装が得意な人の組織」や「研究開発を担当する組織」もいる。

ひとくちに「データ分析・機械学習」と一括りにするのではなく、各人の得意分野・専門分野に応じて組織を細分化し、そこに対応して担当業務を割り振っているわけだ。
「データサイエンティストを○人にしまーす」と言っている企業は多いけど、DeNAはそこにとどまらず抜きんでている。


アルゴリズムの勉強や、実データの分析やってみるのとは別に、kaggleも挑戦したいな……
うーん。やることが一杯でなかなか大変だ。
  1. 2018/08/05(日) 21:39:15|
  2. プログラミング
  3. | トラックバック:0
  4. | コメント:0

scikit-learnとTensorFlowによる実践機械学習 輪読会7章
2018/07/29(日) 21:45:58

2018/06/15(金)に、scikit-learnとTensorFlowによる実践機械学習輪読会#7で発表してきた。

scikit-learnとTensorFlowによる実践機械学習/原題:Hands-On Machine Learning with Scikit-Learn and TensorFlow」の7章の説明を担当した。資料はこちら!



前回の担当は4章の一部でした。こちらもあわせてどうぞ。
scikit-learnとTensorFlowによる実践機械学習 輪読会4章 子供の落書き帳 Remix

発表を担当した動機


以下2点の動機により、この章の発表をした。

・ランダムフォレストについてはあまり理解していなかったので、発表を通じて自分の理解を深めようと思ったため。
・kaggleなどで一般的に使われているxgboostやlightGBMが勾配ブースティングの手法なので、これらのライブラリが何をやっているのか押さえておいたほうが良いのかなと思った

前者に関してはバッチリ。発表するとなると単に参加するよりも何倍も本を読み込まなければならない。大変なのは確かだけど、その分知識が身についた。
後者に関しては、xgboostの方式をちゃんと理解するところまでは行っていない。

Extra-Treeの方式が分からない



スライドにも書いたが、Extra-Tree(Extremely Randomized Tree)の方式が分からなかった。
なぜなら、色々調べていると、参考サイトによって計算方法が微妙に異なっているからだ。

scikit-learn公式を見てみよう。
1.11. Ensemble methods - scikit-learn 0.19.2 documentation の文章を訳すと、以下のようになる。

Extremely Randomized Treeでは、乱数は分割が計算される方法に関してさらに一歩進んでいます。ランダムフォレストの場合と同様に、特徴量のランダムなサブセットが使用されますが、最も識別可能なしきい値を探す代わりに、特徴量ごとにランダムにしきい値が選び出され、これらのランダムに生成されたしきい値のうち最良のものが分割ルールとして選択されます。

(特徴量サブセットの中の)各特徴量について、ランダムにしきい値を決める。一度それらを全部試してみて、一番うまく分割できたものを選ぶ。「うまく分割できた」というのは具体的にいえば、候補の中でコスト関数が最小となるものである。

ところが、ネットを調べてみると他のサイトでは違ったことを書いている。

各splitで、対象変数X_iと閾値θ_jのいずれも完全にランダムに決める
(合成変量とアンサンブル:回帰森と加法モデルの要点 p.74)

(決定木の分岐をするときに)分岐関数候補をランダムに K 個選択
分岐関数の決定方法は、一般的には2つの方法が取られる

単純にランダム選択 ( K=1 ) Extremely Randomized Trees[ P. Geurts 06 ]
(Random Forestsとその応用(PDF) pp.15-16)

分岐関数の決定を完全にランダムに
ランダムフォレストの基礎と最新動向(PDF)

これを読む限り「それぞれの特徴量に対して試してみてから最良のものを選ぶ」とは書いていない。特徴量(X_i)をランダムに選択して、閾値(θ_j)をランダムに選択して、その条件で分岐させてしまう、というふうに読める。

一体どっちが正しいんだろうか。
色々探したけど、前者のscikit-learn公式と同様の説明を書いているところが見当たらない。
っていうことは後者だろうか。でも後者だと分岐のしかたが全くランダムなので、「良い分岐」になる確証が全く無い。そんな完全ランダムな分岐のしかたで、うまく分類できるのか? が疑問だ。


ここまで来たらscikit-learnのコードを追ってみるか、元々の論文に当たるかをしないと分からない気がする。


AdaBoost



ブースティングの中でも一般的なアルゴリズムらしいが、なかなか複雑だった。一通りサッと本を読んだだけだと、中身を把握しづらい。
理解できたら、なかなか興味深い手法だと思ったので、どこかで一回まとめてみたい。

ここでは手法の詳細は解説しないが、この動画の説明が、分かりやすくて良かったので大変オススメ。英語だけどスライドにだいたいの説明は書いてあり、説明の図も豊富なので、見る価値は十分ある。
(61) Ensembles (4): AdaBoost - YouTube

なお、Python 機械学習プログラミングのほうには、一回の反復処理を具体的に書いてあって、詳細な説明がされている。合わせて読むと良いだろう。


gradient boosting(勾配ブースティング)のlearning_rateは何を意味するか



scikit-learnとTensorFlowによる実践機械学習の本では、「個々の木の影響力を調整する」とだけ書いてあって、いまいち分かりにくい。(p.197)

scikit-learnの解説を見てみよう。
sklearn.ensemble.GradientBoostingRegressor関数の説明のほうを見ると、「それぞれの木の寄与率を、learning_rate倍に縮めます」としか書いていない。いまいちよく分からない。

ところが、同じscikit-learnの公式ドキュメントでもアンサンブル法の説明のところを見ると、数学的な定式化も含めて詳細に書いてある。こっちを読めば良かったんだ!

各ステップの関数を足す前に、learning_rateを掛け合わせている。これによって学習速度を下げて、過学習を抑えている。勾配ブースティングに対するこの操作は「Shrinkage(収縮)」と呼ばれているようだ。


以下、輪読会のときにいただいたコメント。

●learning_rateが大きいと、外れ値に対して値を合わせに行ってしまう。つまり外れ値を学習して過学習に陥る。learning_rateが小さければ『値を合わせに行く割合』が小さくなるので、過学習に陥りにくくなるのではないか。

●learning_rateが小さいと、学習するには多数の木を使う必要がある。そのため、1回の学習に時間がかかる。「パラメータを色々変えながらグリッドサーチで良いパラメータを見つけたい」というようなときは、learning_rateを大きくして、学習時間を短くしたほうが良い。
参考:Python 勾配ブースティングにおけるパラメータと調整方法について - CRUNKYおいしい

以上。それでは。
  1. 2018/07/29(日) 21:45:58|
  2. プログラミング
  3. | トラックバック:0
  4. | コメント:0

Numpyのスライスによる要素取り出し、booleanによるインデックス指定について
2018/07/21(土) 17:46:28

きっかけ


scikit-learnとTensorFlowによる実践機械学習の輪読会に参加して読み進めている。

その中によく分からないコードがあったので、調査をしてまとめた。


動作が分からなかったコードがこれだ



handson-ml/06_decision_trees.ipynb at master | ageron/handson-ml | GitHubの[7]である。
(このソースコード自体は決定木について扱っている。しかし分からなかった部分は決定木に直接関係するものではなく、単なるNumpyのコードである)


from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data[:, 2:]
y = iris.target

X[(X[:, 1]==X[:, 1][y==1].max()) & (y==1)] # widest Iris-Versicolor flower

# => array([[4.8, 1.8]])


扱っているのは、機械学習でよく登場するiris(アヤメ)のデータセットだ。Xにはアヤメの「花弁の長さ」「花弁の幅」が2次元配列の形で入っている。yは各アヤメの品種を表す。
やっている処理は、本によれば「ある特定の品種(versicolor)のデータのうち、花弁の幅が最大のものを探し出すと、花弁の長さが4.8、花弁の幅が1.8である」らしい。しかし、どうしてこのコードでそれが出てくるのか分からなかった。

調べてみると、以下の3つの要素が組み合わさっている式だと分かった。順に説明する。

(A) X[:, 1] で特定行だけを抽出する



変数のあとに[]をつけて、その中で要素のインデックスを指定している。この方法の正式名称はスライス(スライシング)という。

2次元配列Xに対してX[:, 1]と書くと、行列の2列めだけを抽出する。

1つ目の次元(=行方向)に関しては何も条件を入れず、全ての要素を抽出している。「:」は全ての要素を表わす。
2つ目の次元(=列方向)については0始まりのインデックスで1の位置だけを抽出している。(つまり左から2番目の列である)

元の例はちょっとサイズが大きいので、小さい2次元配列の例でやってみよう。行列の2列めだけを抽出しているのが分かる。


import numpy as np
X1 = np.arange(12).reshape(3,4)

X1
# => array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])

X1[:,1]
# => array([1, 5, 9])


(B) 上記のスライシングで、末尾の, :は省略してもよい




NumPyの公式ページにはこう書いてある。


If the number of objects in the selection tuple is less than N , then : is assumed for any subsequent dimensions.
拙訳:
選択に用いたタプルの中のオブジェクト数がNより小さい場合、後に続く全て次元に関して「:」があるものと見なされる。
Indexing -- NumPy v1.14 Manual



例えば、2次元配列Xに対してX[1:3]と指定すると、X[1:3, :]と指定したと見なされる、ということだ。


X1[1:3]
# => array([[ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])


実際には2次元の使用例が多いが、2次元配列に限らず、一般の多次元配列に対しても同様である。
例えば、Numpyの例では3次元配列に対して適用している。



# Numpy公式より引用:

x = np.array([[[1],[2],[3]], [[4],[5],[6]]])
x.shape
# => (2, 3, 1)
x[1:2]
# => array([[[4],
# [5],
# [6]]])


上の例で、x[1:2]はx[1:2, :, :]と書いたのと同じになる。

(C) X[条件式]と書くと、条件を満たすものだけを抽出できる



Numpy公式ページでは「Boolean array indexing」という名前で載っている。


X2 = np.arange(9)
np.random.shuffle(X2)

X2
# => array([5, 3, 0, 2, 1, 4, 8, 7, 6])

boolean_array = [True, False, True, False, True, False, True, False, True]
X2[boolean_array]
# => array([5, 0, 1, 8, 6])

X2[X2 < 5]
# => array([3, 0, 2, 1, 4])

X3 = X2.reshape(3,3)

X3
# => array([[5, 3, 0],
[2, 1, 4],
[8, 7, 6]])

X3[X3<3]
# => array([0, 2, 1])
# 注意:元の配列が2次元であっても、1次元配列に展開されることに注意!


参考文献



これらのページはとても参考になった。
(A),(B) NumPy配列ndarrayのスライスによる部分配列の選択と代入 | note.nkmk.me
(C) NumPy配列ndarrayから条件を満たす要素・行・列を抽出、削除 | note.nkmk.me



以上を踏まえて、もう一度読み解いてみると、こうなる



最後に、元のコードがどういう理屈で「ある特定の品種(versicolor)のデータのうち、花弁の幅が最大のもの」を抽出したのか、整理しておく。(元のコードに興味のない人は、これ以降は読まなくて良い。)

元々のコードを再度掲載しておく。

X[(X[:, 1]==X[:, 1][y==1].max()) & (y==1)]


少しずつ順番に見ていこう。
X[:, 1]は(A)で書いたとおり、「行列の2行目」だけを取り出す。
2次元配列Xの1行目には花弁の長さ、2行目には花弁の幅が入っているので、2行目の花弁の幅だけがが抽出される。

次にX[:, 1][y==1] だ。[y==1]はTrueとFalseの配列なので、それを指定すると(C)のBoolean array indexingによって条件を満たすものだけを取り出す。
日本語で書くと「y(品種)が1であるアヤメの花弁の幅」だけを抽出している。

X[:, 1][y==1].max()は上記のうちの最大値である。この値は1.8なので、分かりやすいように式を置き換えてしまおう。


X[(X[:, 1]==X[:, 1][y==1].max()) & (y==1)]

X[(X[:, 1]==1.8) & (y==1)]


ここまでくればあとはほぼ同じである。
X[:, 1]==1.8は「花弁の幅が」1.8かどうかのTrue/Falseの配列である。

(X[:, 1]==1.8) & (y==1) は
「y(品種)が1、かつXが1.8」のところだけがTrueであとがFalseの配列である。

最後に、これをXのインデックスに指定するとX[(X[:, 1]==1.8) & (y==1)] となり、これで
「ある特定の品種(1 = versicolor)のデータのうち、花弁の幅が最大のもの」が指定できた。

  1. 2018/07/21(土) 17:46:28|
  2. プログラミング
  3. | トラックバック:0
  4. | コメント:0

DLLAB DAY 2018 ハッカソン部門感想 #dllab
2018/07/17(火) 01:02:30

6月21日、DLLAB DAY 2018(ハッカソン) @ 丸の内KITTEに参加してきた。

最初に言ってしまうと、あんまり満足の行く内容ではなかったので、以下の文章はけっこう批判的である。
このイベントはカンファレンス部門とハッカソン部門に分かれていた。
カンファレンスに参加者として登録したのは254人、ハッカソン部門に登録したのは64人であり、ハッカソンの状況を知る人は少ない。
ハッカソンのほうに参加して感想を書いている人はそれほど多くないようだったので、書いておく価値もあるだろうと思う。

概要



まず、どんなイベントか概要を書こう。
Preferred NetworksとMicrosoftが中心となって作った、DLLABというコミュニティがある。
公式ページには「ディープラーニングに関連する、開発事例や最新技術動向を情報発信するコミュニティ」と書かれている。
そのDLLABの一周年を記念して、東京駅のすぐそばのKITTEで開催されたのが今回の「DLLAB DAY 2018」である。「深層学習を使いこなす日」と銘打っている。
イベントの公式ページ DEEP LEARNING LAB | DLLAB DAY 2018

前述の通り、参加者は「カンファレンス部門」と「ハッカソン部門」に分かれる。
午前中に基調講演があり、これは両部門の参加者とも聴講できる。
昼休みを挟んで13:00~17:40までが別々になる。
カンファレンス部門の参加者は講演を聴く。(同じ時間に3つの講演が同時進行する)
ハッカソン部門の人は別室に移動となり、そこでハッカソンを行う。
なお、ハッカソンは更に「CV(Computer Vision)」と「NLP(Natural Language Processing)」の2つに分かれている。俺はCVに参加した。
運営が事前に、4~5人の組で1つのチームになるようにメンバー編成していた。

17:40以降は懇親会であり、再びカンファレンスとハッカソンの参加者が一緒になる。食べ物・飲み物が提供された。

事前課題


自分にとって不利な情報を隠すのはフェアじゃないと思うのでちゃんと書いとこう。
事前課題が与えられたが、あまりちゃんとやらなかった。
事前課題の中では、MNISTやCIFAR10をchainerでCNNを使って解くやり方を説明している。
ザッと目を通したが、自分の環境上で動かしたのは一部だけにとどまった。
直前にやり始めて時間が足りなかったこと、「chainerのtutorialは以前やったから大体分かるだろう」と考えたのがその理由である。


期間中に起きたこと、行動



課題は当日発表された。githubにも上がっている。
GitHub - DeepLearningLab/PotatoChips-Classification
説明資料はこちら。Deep Learning Lab Day 2018 - Hackathon Presentation
ポテトチップスの分類である。パッケージの画像から、その種類を当てる分類タスクであるが、画像がそっくりの物があり、そんなに簡単ではなさそう。

最初は講師の指示のもと、Dockerを使って全チーム一斉に環境構築……のはずだが、ここで問題が発生した。
Dockerを展開するのに必要な領域が不足していて、先に何チームかが環境を構築した時点でそれ以外のチームが構築できなくなったのである。
幸い、自分のチームは少しだけ早くDockerコマンドを打っていたので、ここでつまづくことはなかった。
(その後、運営スタッフが設定を変更したらしく、最終的には全てのチームが環境構築できた。自分自身は被害がなかったので、この点については不満を感じていない。しかし、懇親会で話をしたら「ハッカソン終了の30分前まで環境が構築できなかった」チームもあるらしい。)

画像分類ということで、まずはVGG16の転移学習を作ってみるのが良いかなという相談をチーム内でした。
運営側はchainerを使うと良いよという話をしていた(注:Preferred NetworksとMicrosoftのコミュニティによるイベントである)。
しかし、5人チームのうち1人は、Keras+Tensorflowの方が慣れているというので、それでコードを書き始めた。
俺はCNNのコーディングは殆どやっていなかったので、運営におとなしく従ってchainerで取り掛かった。
もう1人も同様にchainerで書き始めた。
5人のうち残り2人は、最初に自己紹介した感じではあまり深層学習の経験がないようだった。
特にチーム内で教え合うようなこともなかったので、おそらく何をすればいいか分からない手持ち無沙汰な状態だったと思う。
(リーダーシップを取る人がいなかったので、役割分担が全く無く、個人がめいめいに作業する形になったことは反省している。)

自分自身は1から転移学習のコードを書き上げる能力は無いので、
「chainer VGG16 転移学習」などのキーワードでググって、出てきたページからコピーペーストをして、何とか無理やりコードを書いた。
しかし、切り貼りのしかたを間違えたらしく、よくわからないエラーに悩まされ続けて終わった。
Kerasで書いていたチームメイトもコードがどこか間違えていたらしく、動くことは動いたものの学習が全くできていなかった。
最終的にはKerasの結果を提出した。

我々のチームは実質的に成果なしだったが、
全体で見れば最終的に何らかの学習モデルを提出できたチームが大半であった。
VGGとかResnetなどの転移学習で書いたチームもあるし、全結合の3層MLPで提出したところもあったと思う。

途中から「ハッカソン、こんなに放置されるんか……」という境地に陥った。
「今回のイベントはハッカソンなんだから、教えてもらうもんじゃない、参加者が能動的に動くものなんだ。
手取り足取り教えてほしけりゃハンズオンのセミナーに行けよ」と言われてしまえば確かにその通りなのだが。
(注:俺はハッカソン形式のイベントに初めて参加した)

事前予告との相違点



Dockerの環境構築失敗は予想外のアクシデントだったので、致し方ない部分もあると思う。
しかしながら、事前予告と実際とで異なっている点が2点あった。

connpassのページでは

運営側から提供するもの
・課題、ベースとなるNNモデル

と書いてある。しかし実際には、ベースとなるNNモデルは提供されなかった。

そして、connpassを通じて送られてくるメールには

・また、本番の課題ですが、イベント数日前に公開予定です。

と書いてあった。しかし実際には、課題は本番開始時に公開された。


特に問題なのは1点目だと思っている。
なぜなら、「入力から出力まで正しく動くニューラルネットワークのソースコード」があれば、
あとは機械学習のアルゴリズム部分の改良に専念できたからである。
しかし実際には「0からコードを書いてね」だったので、
「入力データを読み込み、機械学習のアルゴリズムに入力できるように変換する」部分を間違って書いてはエラーになる、ということを自分は繰り返してしまった。

(実際には上記の部分も必要であり、重要である。それは間違いない。
しかし、例えばkaggleのコンペの期間は数ヶ月あるが、今回のハッカソンの期間は4時間程度である。
しかもその4時間の中に環境構築の時間も含まれている。
時間の短さを考えれば、この部分は正解を与えておき、調査や試行錯誤やミス修正に要する時間を省くべきではなかったか。)

疑問に思った点


そろそろ収拾がつかなくなってきたので走り書き。

connpass説明より

・17-18時は各チームの成果発表(2分ずつ)、その後、専門家からベストプラクティスを紹介いただきます。

→正解例のコードはgist上のを見せてもらったけど、
「中身の説明はしませんので、各自で読んでください」だったのでそれは「紹介」なのか?

もし運営側がこの記事を見ていたら、お願いがあります。
正解例のコード、確かgistのプライベートリポジトリだったと思うのですが、URLを資料の所に置いてもらえませんでしょうか。
URLをメモったのですが、間違ってPCの電源を落としてしまってメモを無くしました。



- Example から一歩進んで、実際に深層学習を使う方法を学ぶことができる

→今回は何を学んだというのだろう……

コードをコピペして繋ぎ合わせる力を学んだ、とかですかね……?
(繋ぎ合わせるの結局失敗したけど)

ハッカソンはハンズオンではないので、「教えてくれる人がいて、教材があって、そこから学ぶ」ではない。
「何も教えないので勝手にやって」で学ぶとしたら……他のチームメイトから学ぶ、ということだろうか?




事前課題から比べて、難易度が一気に高くなったな、と思った。
より具体的に言うと、機械学習アルゴリズムの手前の段階が必要だということである。

chainerだとget_mnist関数を使って一発でMNISTのデータをロードできる。
他の深層学習フレームワークもほぼ同様である(たぶん)。
また深層学習以外では、scikit-learnにはload_irisなどの関数があり、サンプルデータを関数1つでロードすることができる。
これらは大変便利ではあるのだが、慣れすぎてしまうと、いざ他のデータを入力すると苦労する羽目になる。
機械学習モデルに入力する前の段階も、ちゃんとできるようにならなきゃいかんな……と、今回のイベントで痛感した。



最後に一つ。
Dockerによる環境構築失敗に対して
「色々と(トラブルが)ありましたが、進めますね」という言い方が何度かあったことである。
金を返せなどと要求するつもりは別に無い。
せめて「ご迷惑をおかけしました、すみません」という一言が欲しかったと思うのである。、
そういう台詞はついぞ聞くことが無かったし、無かったせいで心象がより一層悪くなってしまったので、今こうして書いている。

参加費との釣り合い



無料~低価格のイベントならば、「ま、しょうがないか」と納得することもできた。
どうにも釈然としないのは、このイベントの参加費が10000円だったからであろう。

PyConとかRubyKaigiとかに出たことなかった俺には
イベント一発で1万円は余裕の過去最高金額であった。
scikit-learnとTensolFlowの本を買うときもいくぶん躊躇してたけど、その2倍以上する。
俺は個人的にイベントに申し込みしていて、会社から費用を出してもらっていないので、つまり自腹である。
自腹を切って行った結果がこれか……!!
(余談であるが、「会社から費用を出してもらった」「上司に『勉強しに行ってこい』と言われて申し込んだ」という人も多く、普段俺が行くような勉強会とは客層がやや違っていたように思う。)


ブレインパッドとかキカガクとかのハンズオンセミナーで手取り足取り教えてもらおうとすれば、
1万円なんてものでは済まない。
(機械学習による問題解決実践 (データサイエンティスト入門研修) | データ活用人材育成サービス by BrainPad:2日216000円)
(ディープラーニング ハンズオンセミナー | 株式会社キカガク:3日216000円)
それに比べりゃ遥かに安いと思うべきなのか。

ちなみに、dllabのイベントがいつも高額というわけではない。このイベントの次の週にもイベントがあった。
Microsoft Machine Learning Meetup - connpass
この参加費は500円である。……ちきしょー。
ええ、分かってます。
普段は品川のマイクロソフト本社で開催するから会場費がかからないんですよね。
それと比べて今回のDLLAB DAY 2018は東京駅近くの会場を借りたから会場費がかかっています。そのためには参加費を上げる必要があったんですよね。

ハッカソン参加者の感想レポート


他のハッカソン参加者の感想レポートを見つけたので、最後に貼っておきます。

DLLAB DAY 2018 ハッカソンに参加してきた - OKKAH NET
DLLAB DAY 2018行ってきました | 彌冨 仁研究室
DLLAB Dayのハッカソンに参加してきたよ(実装編) - テキトー
  1. 2018/07/17(火) 01:02:30|
  2. プログラミング
  3. | トラックバック:0
  4. | コメント:0
次のページ

FC2Ad