scikit-learnとTensorFlowによる実践機械学習
以前Tensorflowの本を探してた事を覚えてた編集さんが、「最近Tensorflowの本を出したので良かったら読んで見てください」と言って献本してもらった本。
今の自分がTensorflowについて学べる本がこの世に存在するとは思えないのだけれど、この本の評判は機械学習の本としてそこそこ良さそうで、ちょっと気になっては居た。
今年前半は小難しい本を読んでばかり居たのでここらで息抜きに軽く普通の本も読みたいと思ってた所なので、読んで見る事にする。
なお、私はたぶんそもそもに対象読者じゃない気がするので、このブログのポストを読む時はそのへんは差し引いてください。
開幕の前提にいまいち同意出来ない
この本は、プログラマのツールボックスに新しく機械学習を追加しよう、という前提で書かれている。 でもこの前提がもはや成立しないんじゃないか。
これは機械学習を、まるでサービス開発の一手法として必要に応じて使ったり使わなかったり出来るもの、という前提で書かれている。 一方でそういう態度でうまくやってる企業って存在するのか? ゼロでは無いかもしれないが、このアプローチは凄く失敗する事が多いやり方で、失敗してる所ばかりという印象でいる。少なくとも自分の所に相談に来る所はこのパターンで失敗してる所が大半。
一方で機械学習をうまく活用出来てる所は、専門のチームがあって研究に近い領域でやってる所ばかりに思う。 Google BrainもPFNも、サービス開発のおまけとして機械学習なんてやってない。 リクルートもクックパッドも機械学習は専門のチームがやってる。
なんかコンサルとかがこういうの煽ってるが、事実と異なるという事がそろそろ結論として出てるんじゃないかなぁ、と著者を見たらコンサルだった…
まぁ序盤だけで難癖つけてもしょーもないので読んで行こう。
第一章 機械学習の現状
現状といいつつ、現状の話はあまりなく、教師あり学習とは何か、教師無し学習とは何か、バッチ学習とは、ぶらぶらぶら、って感じ。
何も知らない人向けに書かれているような内容だが、全体的に要るのか?という事が多い。
例えばここでモデルベースとインスタンスベースの学習、みたいな言葉とかが出てくるが、こういった事をここに載ってるのだけ学ぶ事にいまいち意味が分からない。 網羅的な内容からは程遠いが、良く使う物にフォーカスしてる訳でも無く、この中途半端な物を頑張って学ぶ意義とは?という気になる。
モデルの違いはやり方の違い
読んでいていまいち納得出来ない事として、線形回帰時代のやり方を前提にしている所。
モデルとは複雑さと表現能力が違うだけで、他の部分は一緒です、だからまずは基本的な事を線形回帰で作ってみて、スコアを見てから必要に応じてより複雑なモデルに変えていけば良い、と思ってそうな気がする。
一方で最初からLightGBMを使おうという場合、「どうやったらフィーチャーエンジニアリングを学習させられるか」という事に頭を使うのが基本的な考え方だと思う。 何かやってみてうまく行かない時に、どうして上手く行かないかを理解して、どうやったらそれらを学習していけるか、という所を頑張る訳だ。
この、手でやれば解決しそうな事をどう学習で解決出来るか、というのは、SVM世代には無かった思考方法だと思ってて、そこには考え方やプロジェクトの進め方のレベルで大きく違いがある。
だからまず線形回帰から初めて徐々にモデルを複雑にしていく、というのは同意出来ない。 線形回帰に食わせるデータとGradient Boostに食わせるデータはまるで違うし、その結果としてのデータ整形も、学習させる環境もまるで違ってくる。
こういう本が欲しいという気持ちは分かる
機械学習について、最初からいろんな言葉を説明していき、目次を見ると後半には流行りのモデルをいろいろ説明してくれそうだ。 これでブラックボックス的ではあっても実用的なシステムを作れるようになるに違いない!
たぶんそういう欲求に応える為に書かれた本だと思う。
だがそれってそもそも無理がある気がする。 昔、 データ分析を用いたサービス開発とは、データと問題を理解する過程であるで同じような事を書いたが、 問題設定を固定してモデルをだんだん複雑な物に置き換える、というのは実際の開発プロセスとは大分違うと思うんだよなぁ。
一章の出来はいまいちなのだと思う
なんのかんのと理由をつけた所で、読むのに時間がかかる割にはそれだけの有用性が無い、という事で、一章の出来はいまいちだと思う。 長さだけの価値が無い。これならそもそも一章をとっぱらって2章から始めるか、一章をつけるにせよ内容を1/3くらいに削って、本書で扱う範囲に限定する方がいいんじゃないかなぁ。
ただ、しょせん一章は一章に過ぎないので、本全体の評価を下すにはまだ早い気もする。
という事で、もうちょっと良い内容な事を期待して先を読む。
2章 エンドツーエンドの機械学習プロジェクト
開幕の主要な8ステップが全く同意出来なくてひどい。一応不動産の仕事してた事あるんだが…
お前はデータを可視化するだけで正しく問題を設計出来ると思ってるのか!可視化もモデルも、データをより深く理解する為の手法に過ぎないんじゃないのか!?
という気がしてくるが、読まずに文句言うのもどうかと思うので読んでいこう。
2.2.1 問題の枠組みを明らかにする
ここの内容が一番現実と離れてる所じゃないか。
手持ちのデータで行える、現在のビジネスでやりたい、機械学習の問題を、なんと上司に聞くと最初に教えてもらえる!
そんな訳あるかっ!
データを理解する前に出来る事なんて分からない。 だが目的が無いと何をするべきかは分からない。 このニワトリと卵をどう解決するか、というのが機械学習チームの腕の見せ所じゃないのかねぇ。
ただ、既に組織が十分に機械学習を活用していて、その一部だけを追加したり置き換えたりする場合にはこれに似たシチュエーションはある。
そういう場合も大抵は最初に考えていたやる事と最終的に実際にやる事は違う物だけど、それでも現在の機械学習のチームが一般に抱えてる問題よりは大分問題は単純だ。
とりあえず入門として、特殊で単純なケースを取りあげるのは、そう断ってあればわからんでも無い。
完全初心者向けの環境設定の話
2.3から、virtualenvとかJupyterの使い方とかの話が長々と続く…
やはり完全に機械学習素人向けに書かれている気がする。 一方で実際にやるなら、そのチームのAWS側がどうなってるか、とかそういうのが大切になるよなぁ。
この「問題設定の所では組織が既に機械学習を十分に使ってて、自分の所には凄く簡単な問題が来る」という前提をとりつつ、「環境構築では何も無い所で自分で機械学習の勉強をしていけるようにしよう」という前提に立つのは、いまいち同意出来ないなぁ。 典型的な読者がそうとは思えない。
この完全初心者が順番に進めていけるが、よむと実践的な事が出来る、という目標は野心的に過ぎるんじゃないかなぁ。
関係ないけど、magicを「魔法のコマンド」と訳すのはどうなのか?何を指してるのか一瞬分からなかったが。
フィーチャーエンジニアリング
データを可視化してどんなフィーチャーを作るか、みたいな話がその後に続くが、 自分が仕事でやった時はこの辺を人間がやらずにどう学習させるか、でいろいろ工夫した。
この2章のやり方では、人間が分かってる関係しか作れないと思うのだが、 それは昨今の機械学習の強力さとは遠いと思うのだよな。
フィーチャーエンジニアリングは今でも重要だと思うが、それはモデルを通じてやっていく事で、最初にこうやって決めてしまっては昨今のモデルの強力さを引き出し切れないと思う。 それでは多くの問題でスペシャリストが適当に作ったルールベースの結果(つまり既存のロジック)に勝てない。
ちなみにこの本では11個の属性でやってるが、我らは同じような不動産の問題を5万個の属性でやってた。 当然フィーチャーの組み合わせとかを2.4.3のように手動で試すなんて事は現実的じゃない。
やっぱり勉強の為に、最初に線形回帰でこうやって長々と話をするのは効率悪いと思うんだよなぁ。 皆は最初からLightGBMで始めるし、それに合わせたノウハウがある。 確かにそれは入門者にはずっと分かりにくいのでどう本という形で提示したらいいのかは分からないが…
reshapeとかはいまいち解説が無い
データ整形は結構この本で力を入れてるのかと思ってたが、reshapeする所とかに意外と説明が無い。 セットアップとかJupyterの使い方よりそっちが要るんじゃないのか?
pandasとnumpyとcsr matrixの間を大した説明も無く行ったり来たりするが、 これについていける人でJupyterの使い方を知らない人が本当に居るのか?そうは思えないが。
scikit-learnとかTensorflowに詳しくなりたいなぁと思う層にはこんなもんで良いと思うが、やっぱりターゲットはその辺に絞るべきじゃないかねぇ、この本。
scikit-learnの入門としてはなかなか良い
scikit-learnってもともとクリーンでドキュメントも良く書けてるので、あんまり本で勉強する必要性は感じないが、 2章の後半はscikit-learnの入門としては悪くないと思った。
ただ、実際の機械学習のプロジェクトの難しさが覆い隠されてしまっていて、 その辺にこの本の位置づけの難しさを感じる。
こんなあっさりスコアが出る事は基本的には無いので、そこで頑張るのが時間の大半なのに、それが無いんだよなぁ。
そこでプレゼンテーションとかドキュメントがどうとか言われても、いかにも空虚な感じがする。
ただ自分はそんな事は知ってるので、scikit learnの入門として流し読みする分には悪くなかった。
2章を読み終わっての感想
機械学習の世の中の入門書に感じるのと同じような不満を感じた。 探索的なプロセスが一番難しいのに、そこ以外の所にページの大半を割く。
ただ、この探索的プロセスの話を本でするのは難しいので、そこの話をしないのは、それが分かるようになってれば一つの選択とも思う。
また、なんというか、6年くらい前の機械学習の流行の初期の頃を思い出した。 小さなデータでトレーニングもすぐ終わって、フィーチャーの数も人間が簡単に確認できるくらい小さい。 昔はこんなだったなぁ…みたいな。 Andrew NgのCourseraのコースとか思い出すね。
ただ、昔のやり方をまず学ぶのが入門に良いか、というと、自分はそうは思わない。 だからこの本も入門に良い気はしない。 中途半端に全体像を示してるフリをするより、基本的な事だけ教えて全体像はもっと進んだ本でやれ、とやるか、基本的な事は既知としてもっとリアリティある設定で全体的な事を語る方が良いと思う。 ただリアリティある設定だと究極的には「プロジェクトの状況次第で全然違う」という結論しか出ないので、本にするのは難しいだろうねぇ。
3章 Classification
confusion matrixとかprecision-recallとかROCの話だが、これがなかなか良く書けてる。
使ってるモデルが何なのかはSGDClassifierと言ってるだけなので何か分からないが、なんかscikit-learnのドキュメントを読むとSVMっぽい?
これをRandomForestに置き換えてみよう、とか言ってやったりするが、何と比較してるのかさっぱりわからんのはひどい。
だがclassificationで良くやる周辺の雑用のコードが一通り載ってるのは役には立つだろう。 2章までよりはずっと良いね。
numpyの解説が全然無い
Jupyterのインストール方法とか使い方はだらだらページを割くくせに、3.6とかでnumpyのブロードキャストとかバンバン使ってる所ではまったく解説が無い。
この辺の取捨選択はいまいち良く何を考えてるのか分からないなぁ。 このコードが分かる人はいかにもデータ分析やってきた人だと思うのだけれど。
ここまでの印象だとこの本はモデルとかの本体じゃなくて、その周辺のコードを学ぶのに良い本を目指していると思っているのだが、 それならこのnumpyとかの扱いって結構重要なトピックだと思うんだよなぁ。
まぁ本家のマニュアル見れば分かるでしょ、と言われるとそうなんだけど、 それを言ったらscikit-learnもわかるしなぁ。
3章読み終わっての感想
1章はろくでもなく、2章もひどい所が多かったが、3章はそれらと比べるとずっと良かった。 clastificationについての、そう悪くない入門になってる。
2章まではこの本の存在意義がさっぱり分からなかったが、3章を見ていると、この本は機械学習のコアの部分の「周辺の雑用コード」のレシピ集のような物なんじゃないか、と思うようになった。
確かにこういう類のコードは、既にどっかにある奴を持ってくる、とかが多いし、 無い場合はリファレンス読みながら自分で書くが、これが結構面倒だ。 という事で動く事が分かってる典型的なコードがある事には意味があるし、 こうやって全体的なシナリオの中で見せる事であとから「あー、あのコードこの辺にあったな」と思い出しやすい気もする。
一方で、コード以外の部分の解説は前時代的で役に立たない。 これはモデルの違いがどれほど作業のワークフローや作業内容自体を変えてきたか、という事を思い知らされるという点で興味深いが、これで入門してしまう人は随分無駄な事を学ぶ事になるだろう。
この本は理論的な解説が中途半端で、その辺いまいち立ち位置が分からない。 SGDCLassifierが何故スコアが出ないのか、という話をしてRandomForestをつかったりするが、SGDClassifierがどういう分類器かをちゃんと説明しない。
ググった所、デフォルトはlinearのSVMらしいが、 解説はいまいちそれを理解してないように見える。ただ解説自体がほとんど無いので、理解した上で隠してるのかは良く分からない。
個人的な印象としては、classificationをちゃんと勉強するのはこの次の本にまかせて、とりあえずモデルの所はブラックボックスとして回りで必要な事を覚える、という感じで使うのが良い本に思う。 その時モデル自体の解説とか改善案とかは無視する必要があって、それはその辺分かる人にアドバイスもらいながら読むのが良いかもしれない。
社内で新人とかがこの周辺の作業を開始する時に、この本を読みながらやってもらうが今の時代に合わない所は適当に補足する、みたいな。
自分としては正直著者が自分よりわかってる気は全然しないので勉強になるとは全く思わ無いが、この辺のコードが必要になった時に過去のipynbをごそごそするよりこの本見よう、という気がする程度には使いみちは感じた。 3章は大分印象が改善されたので4章以降でもっと良くなるのを期待して読んで行こう。
4章 線形回帰とかロジスティック回帰とか
何故か唐突に4章で線形回帰の話が始まる。 しかもgrad descentだけじゃなくて逆行列求める方法とかも解説してる。なんで?
多項式回帰とかも出てくるが使わなくない?バイアス=バリアンス分析の話とかをしたいのだろうが、全体的に、ちゃんと理屈を説明しないくせに使わない事をダラダラと列挙する。
そのあとlogistic回帰の話になるが、対数尤度とかが突然ロスとして出てきて、何故これをロスとするのか、それがどういう意味があるのかとかは全然解説しない。 何を伝えたいのか良く分からない章だなぁ。
トピック的にはAndrewのCourseraのコースに似てるよな。 scikit-learnを使って書籍でああいう内容をする、というのは、一つ需要のある形かもしれない。
だがあのコースは2012年とかだし、実践も他でやってくれ、というスタンスは明確だった。 基礎的なモデルの理屈をちゃんと説明する、という内容だった。
この本は、理屈はあんまり説明しなくて、代わりに実際の運用的な話を混ぜてくる。 いまいち実体験に基づいたものに見えないが、 この
- scikit-learnの入門
- 機械学習の入門
- 実際にシステム作る為のコード
の3つを混ぜる、というのが本書の目指した物なのだろうな。 タイトルや序文などからは機械学習の入門をやる気には見えないのが意外だった。
最尤推定とかの大きな枠組み無く個々のモデルの話を表面だけやるので、あんまりこれで基礎を学んでその後さらに進んだ本で勉強、という感じにはなってないのが、線形回帰やロジスティック回帰の話を長々された時に感じる違和感に繋がってる気がする。
交差エントロピーの話などもこれでは全然分からないような書き方で、より進んだモデルを考える時の為に簡単はモデルで理屈を説明する、という感じにもなってないし、いまいちここでロジスティック回帰やってる理由が分からないよなぁ。
4章読み終わり
良くある機械学習の入門書の劣化コピーたいな内容で、いまいちだった。 回帰と分類の話をしたかったんだろうが、中をあんまり説明しないので、 簡単過ぎて実用的では無いモデルで説明する意義が良く分からない。 多項式回帰とかPRMLパクっただけで全く必要性を感じないし、自分の印象はあまり良く無い。
4章はあまり実際の運用的な事も何も無くなってる。
ただ良くある入門的な機械学習のトピックのPythonコードが揃ってるので、 他の本で勉強した人が実際にscikit-learnで勉強した事を試してみるには手頃なコード集にはなってる気がする。
5章、SVM
SVMは機械学習でもっとも人気のあるモデルの一つであり、機械学習に関心を持つ人なら使いこなせなければならない、で始まる時点で読む気の失せる章だな…
この本を2018年に出すとか、正気を疑うものがあるな…
ただscikit-learnのコードはなかなか手軽でいいね。 こういう感じでよくある機械学習のアルゴリズムが試せます!というのは悪い話じゃない気がする。
SVMは使い方のアドバイスがあんまりないな
何故か理屈は細かく説明されているSVMだが、例えば非線形回帰の話をしている5.3では「非線形回帰にはカーネル化されたSVMを使え、二次多項式カーネルの例を示す」みたいな事が書いてあるが、 どういう時にどのカーネルを使うか、という選び方について何も書いてない。
これは揚げ足取りじゃなくてSVMとGBDT系の比較をする時にポイントになる所だと思うんだよねぇ。 SVMを使うというなら、このカーネルをどうやって選べばいいかについても何か言わないと、実践の場で使えない。 逆にそこの難しさこそがSVMを使うかGBDT使うかを分ける所な訳で、 実践する時のアルゴリズムの選択に影響を与える訳じゃん。 実践、ってまさにこうしたモデルのどれを使うべきかを選ぶアートの事では無いのかね? 1章や2章でそういう話を偉そうにしてたのはなんだったのか。
5.4 SVMの内部の話とPRMLの復習
自分はSVMのこのへんの理解度が低いので、この説明だけ読んでも良く分からない。
という事でみんな大好きPRMLを軽く復習しておく。
PRML6章、dual representationの復習
まず6.1で線形回帰のdual representationという話をしている。
p293の式6.2からそれを最小にするパラメータは6.3という別のパラメータに置き換える事が出来る。
この形に置き換えると基底がKという行列の形でしか入らず、逆にこのKを決めると6.7式のようにコストをaの関数とする事が出来る。
さて、これはxに何らかの変換を行った物をファイとして、これの積としてKを出しているが、逆にある種のKを決めると、それを構成するファイが存在する、という事が知られている。
そこで問題を適切に表す基底の変換を考える代わりに、カーネルを決める事で暗黙のうちに基底を決めるのと同じ事をしている、とみなせるようになる。
つまり、
- カーネルを決める
- 6.7式を最小化するaを求める
- aから元のpredictionの式を出してpredictionを行う(式6.9)
というのがカーネル法の基本だな。 カーネルの構成はいくつかの元になる関数の合成が許されている、という話だった気がする。まぁここはいいか。
PRML7章のSVMを復習
カーネル法では を全サンプルに対して行う必要があるので計算量的にいまいち。
という事で、サポートベクトルとのペアだけ求めれば良い、というSVMという物が便利な事がある。
まずは普通の線形モデルを少し変えて、マージンが最大になる分離平面を考える、というモデルを考える。 ひとたびこの平面が出来たら、あとはこの平面のどちらにあるか、で分類を行う。
式としてはマージンはp327の7.2式のようになり、これを最大化するパラメータを求める、という問題になる。
この時点では単なる線形回帰の親戚みたいな物だが、解としてはシューンタッカーの定理で解くような物となり、 いわゆる相補スラック性条件が出てくる。 で、predictionに効くサンプルと無関係なサンプルに分かれて、この効くサンプルがサポートベクターな訳だ。
で、この最大化問題をdualな表現に直すと、7.10みたくなるので、6章と同じようにカーネル関数決めてaを求める問題に帰着出来る。 手順としては
- カーネル関数を決める
- maximum margin classifierの最大化問題のdual表現を、1のカーネルとトレーニングセットを使って求める。この時少数のサポートベクターだけが残る
- aとカーネル関数を使って、新しいサンプルに対してのpredictionを行う
よし、あらすじはだいたい思い出した。 元の本に戻ろう。
5.4.3までのあらすじ
5.4.1でmaximum margine classifierの話をする。
そして5.4.2でこのobjectiveを求める話をしたあとに、これをソフトマージンの問題に拡張する。 話の筋は追いにくいが、分かってから読めば何を言ってるかは分かる。
5.4.3で唐突にquadratic programmingの問題なのでできあえのソルバーで解ける、とかいう話が挟まる。ただそれじゃカーネルトリック使えない訳だが、なんでこんなの挟んだんだろ?
まぁいい。 で、本題の5.4.4の双対問題に入る。
5.4.4 双対問題
突然導出を知りたい奴は付録Cを読め、と言って、dualなobjectiveが書いてある。 なんじゃそりゃ。
付録Cを見ると、さっきPRMLで見たのと同じようにキューンタッカー定理を使ってdualな問題に置き換える計算がある。 なんか唐突にサポートベクターがどうの、という説明があって初見殺しな感じがあるが、分かってる人が見れば分かる。
カーネルの話はこの先らしい。随分1節の長さが短いな。
5.4.5 カーネル
で、5.4.5でカーネルの話が出てくるが、これまで基底の変換、つまりPRMLで言う所のファイを出さずに話をしていたので、式5-6ても無かったのに、唐突に式5-8のような変換を行って式5-6を考える。
うーん、これは分かりにくいな。PRMLの方が線形モデルの頃から基底への変換をずっとあらわに書いてくれてたおかげで分かりやすい。
で、式5-9でごにょごにょ分かりにくい事を言ってるが、ようするに変換を計算しないでカーネルの計算だけすれば良い、という事を凄くわかりにくく書いてある。
その後に元のpredictionをどう出すか、 という所でwやファイをあらわに求めなくても、 predictionの関数はカーネル関数で書く事が出来る事が述べられている。
5.4 雑感
なんかあらすじは悪くないのに、凄く説明が分かりにくい。 これ、ひょっとして和訳が良くないのかな? 誤訳があるとかじゃないのだが、ストーリーが凄く分かりにくい。 各文で何をやってるかが、分かってる人にしか分からないように書かれてる気がする。
一番重要な所はカーネルトリックの所だと思うが、なんか話の途中でカーネル関数を列挙したあと、突然次の話に移っちゃうんだよな。
これ、本当はファイの変換をしたあとにmaximum margin classifierを解く問題と、同じだがより簡単ないくつかのカーネルのセットがある、という話なのに、そこの話をなんかもにょっと話すんだよなぁ。 式5-9の計算をしてるのだからその事を著者が分かってないとも思え無いのだが、なんかファイの話をあんまり真面目に説明してないままKが出てきてしまうので、 一体なんの話をしてるのか分からなくなってしまう。
さらに追い打ちを掛けるように、突然「あとひとつだけ、片付けておかなければならない問題が残されている」とかいい始めてpredictionの仕方を解説してしまうのだが、その前に何を片付けたのかをちゃんと教えてよ、と思ってしまう。
片付けたのはカーネルを定義する事でxに変換を加えたのと同じ効果を、xを実際に変換する事無くmaximum marginの分離平面を求める方法と、その為に使えるカーネルの説明を終えたのだよな。それが凄く分かりにくい。
5章読み終わり
SVMの解説は随分詳細で力が入ってるな、と思った。 一方で理論的な解説が多くて、実際に使う時の話は凄く少ない。 しかも理論の解説は不自然に分かりにくい。
個人的には理論の説明は他の本で学び、サンプルコード周辺だけ参考にするのが良いと思った。
理論をやりたいのか中を分からないまま使わせたいのか、いまいち立ち位置がはっきりしない本だなぁ。
6章 決定木
ちょうどこの前勉強会でadaboostとgradient boostの当番で、関連論文もソースもかなり読んだので、流石にこの辺でわからないことは無かろう、とは思うが読んで行く。
最後まで読んでみた。凡庸で普通の解説だったが、フィーチャー間の相互作用を扱えるってあたりはもっと強調されてもいいんじゃないか。
また、カーネルとか考えたりしなくていいから、とりあえず使ってみるのに準備が要らない事も、もっと機械学習のプロジェクトのライフサイクルとかまで含めて語ってもいいと思うんだが…
ただ、決定木は重要なのに解説しない入門書が多い中、この本はまぁまぁちゃんと解説してるので、トピックの選択は評価出来る。
7章 アンサンブル学習とランダムフォレスト
おや、boosting推しじゃないの?とちょっと意外なタイトルだな。
VotingClassifierを使うコードはなかなか美しいね。scikit-learnはこの辺良いよな。
7.2と7.3 Baggingの解説がなかなか長いな。OOB検証って知らなかったので勉強になった。
7.4からランダムフォレスト。 ランダムフォレストの詳しい解説って本で見たの初めてかもしれない。 自分は既に結構知ってるので悪くない印象だが、もうちょっとツリーの作り方は具体的に話しても良い気はした。
ただランダムフォレストは結構良い事多いので、ちゃんと扱ってるのは好印象。
7.5 ブースティング
みんな大好きブースティング。
adaboost
adaboostはびっくりする程数式が無いな。SVMとの違いは何なの? 最後のpredict時にどうアンサンブルしてるかも意味の分からない説明。
と思ったら途中から数式でまた説明し始めた。なんじゃこりゃ。whereだけ訳さず残ってるし。 その後の「すると、すへてのインスタンスの重みが正規化される」とか何を言ってるのか良く分からない。
これは訳が悪そうだなぁ。adaboost知らない人が、良く理解しないまま誤訳したっぽいな。ひどい話だ。
7.5.1を最後まで読んだ。 式の意味とか全然解説しないのかぁ。 なんかやっぱりSVMとくらべていまいち力が入ってない気がするが何故だろう?
まぁgradient boostingが詳しければそれで良いが。
Gradient Boosting
なんじゃこりゃ!?俺の知ってるgradient boostingと全然違うんだが。
さっきも挙げた、自分の書いたメモを見直そう。
ふんふん、だいたい思い出したぞ。 上のメモでリンク貼ってるFriedman 2001を読むのが良さそうだな。ちょうど手元のタブレットに入ってたので、読んで見る。
あー、これはいわゆるLS_Boostか。 二乗誤差がクライテリアの時のGradient boostの一つ。Friedman 2001の4.1だね。なるほど。
という事で本文に戻る。あれ?LS_Boostの話をしたあとはGradientBoostingRegressorクラスを使う話だけになってる。 理論の解説これだけ!? 現状最強でとりあえずここかは始めるGradient Boostingの解説が? scikit-learnのGradient Boostは確かヒストグラムが無いので、その辺もXGBoostやLightGBMへの言及ないとダメなんじゃない?
うーむ、7.5を最後まて読んだが、これ、著者がgradient boosting全然理解してないな…
これは良くない。 実践編と言われたら、普通はGradient BoostingとCNNをどう使っていくか、という話が期待されると思うのだが、 線形回帰やSVMの話は長々としながらGradient Boostingの話は全然しないとは! 必要なのは逆でしょ!
Gradient Boostingは汎用なロスに対して使える強力なブースティングアルゴリズムな事、汎関数の最適化のクライテリアがそのまま決定木のsplitのクライテリアになる事、この決定木のsplitのクライテリアがヒストグラムを用いて高速に実行出来る形になってる事から高速な事など、このアルゴリズムを他と比較する上で知っておかないといけない事が全然書いてない。
どうせGBを説明しないなら、他の使わないアルゴリズムの解説も無い方がいいだろう。理屈は説明しません、ブラックボックスとして使え、という態度でもっと短くするべきだ。
また、とりあえずどれを使うべきか、という話も無い。理屈はおいといてgradient boostingでしょ、というのを言わないと、読んだ人分からないじゃん!むしろこの書き方だとSVMの方が良く見えちゃうよ!
フィーチャーの相関が自然と学習出来る、とか、ロバストだ、とか、 そういう実務の上でのメリットみたいなのも全然書いてない。実践編とは何なのか。
なんでこんな事になってしまっているのか?
何故Gradient boostingの説明がこんなになってしまったのだろうか? 自分の予想としては、この著者はPRMLは一応は読んでいて、でも論文とかは理解出来ないくらいの理解度なんじゃないか。
だからPRMLに無いGradient boostingは、その重要性にも関わらず理論的な話が出来ない。 adaboostはPRMLにあるので、それを要約して書く事は出来る。
一方でこの要約は分かりにくい。例えばadaboostはPRMLならその理論的な背景が割とちゃんと解説されているが、この本はその辺をすべてカットしてしまって、天から式が降ってくるだけで、その解釈も一言二言触れるだけだ。 だからこの本は、PRMLよりも難しくなってしまっている。ただ理解する気がなければ、短いので読み終わりやすいとは思うが。
あと、著者は昔結構頑張って機械学習の勉強をして、最近のはあんまり真面目に勉強してないんじゃないか。 だから線形回帰とかSVMとかは結構難しい事まで長々と書くが、最近流行るようになったGradient boostingはちゃんと深く理解してないので、きっとどっかで見かけたLS_Boostの解説だけ引き写して終わりにしてるんじゃないか。
でも実践と言うなら本来はboostingが最重要で、むしろFriedman 2000とFreidman 2001の内容のレベルでちゃんと解説した方が良い。逆にSVMとかの方を解説をサボってブラックボックスとして使えばいい、って態度の方がずっと現場では困らないと思うのだが。
少なくとも上でリンクした自分の勉強会用のノートはFriedman 2000や2001を現在の視点からまとめ直して、XGBoostとかの話もちゃんとしているぞ。まぁ難度はずっと高いからあれじゃダメだろうが。
7章を読み終わって
Gradient boostingの理論的な解説がほとんど無いに等しい、というのは、本書全体の意義に関わる所で、擁護のしようが無いと思う。実践を名乗るならXGBoostやLightGBMにも触れておくべきだろうが、それも無い。
ただ6章の決定木の解説が結構しっかりしてて、7章のランダムフォレストも結構ちゃんと書かれてるので、ランダムフォレストをちゃんと勉強する事が出来る本にはなってると思う。 自分はランダムフォレストの本って初めて見たのでそこは評価出来る。 実際boostingよりランダムフォレストの方が良いスコアな事はちょこちょこ見かけるので、自分はむしろもっとランダムフォレスト使うべきかもしれない。
あとGradient boostingを使うコードとパラメータの説明はあるので、とりあえず使ってみるのに必要なコード例としての役割は果たしていると思う。
理論的な解説の不満はおいといても、この本は実際に使う時のアドバイスみたいなのが欠けてる気がする。 いろいろなアルゴリズムを紹介しているが、どういう時にどれを使うべきかが分からない。 とりあえず理屈はおいといて使ってみよう、という本だというなら、そこが必要だと思うのだが。
どうせなら割り切って、いろんなモデルとその使うコードをただカタログとして集めて、それらのベンチマークの比較とかするだけの本の方が好感が持てるなぁ。
関係ないがFactorization machine無いのかね? SVMよりは流行ってると思うのだが。
8章 次元削減
唐突にPCAの話が始まる。 しかも何故か長くて、svdを使って実装してみせる。 なんで最重要のGradient BoostingはほとんどブラックボックスでPCAは真面目にやるの!? それこそscikit-learnでブラックボックスとして使えばいいと思うのだが。
だいたいこの説明ではXを特異値分解するというのがどういう事かも、そのVを掛けるとどうして目的の射影になるかも分からない。 ちゃんと理解出来るような説明にはなってないが、理屈に結構なページをさく。いまいち何がしたいのか良く分からない。
そもそもにembedingとかボトルネックみたいなのは良くやるにせよ、この手の非ニューラルネットな次元圧縮って学習の高速化のためにやるかな? 結構数万フィーチャーくらいならそのままLightGBMに食わせると思うが。
なんとなくコンサルが頭の中だけで考えた正しい機械学習のやり方、感が強いなぁ。
関係ないが、どうせならt-SNEとかやらんのかね?あんま詳しくないので説明してくれてたら喜んで読むんだが。
8.5でLLEという物の説明が始まった。これは初耳なので真面目に読んでみよう。
なるほど、すべてのサンプルに対し、それぞれのk近傍の線形和でなるべく自身を再現するような重みを計算し、今度は低い次元でなるべくそれを再現する点の関係を求めるのか。 一意にきまるのか良く分からないが、まぁそれっぽければいいのだろう。
お、最後にその他の手法を並べてる所でt-SNEの名前があるな。全然優劣は判定出来ないが。
全体的に必要性の良く分からない章だった。機械学習の教科書の目次を真似してるだけにしか見えない。
ただコードは全部ついてるので、コード例とその解説としての価値はあると思った。 理屈の解説はなんであるのか良く分からなかった。
9章TensorFlow
9章は突然良い内容になる。 これ書いた人はなかなかTensorFlow良く分かってるな。
ただよそのサンプルを持ってくるんじゃなくて、ちゃんと自分での実装を見せてそれを提供されている物に置き換えていく。 そうそう、入門はこうやらないとね。
compute_gradientsの話ももうちょっとちゃんとした方が分かりやすいとは思うが、こういう話し方するという事はこの辺は理解した上でやらない方が良いと判断したのだろう。 自分は同意しないが一つの選択だよな。
9.8 モデルの保存と復元はいまいち
Saverはつくる時にデフォルトグラフを全部取り込む。 で保存する。 だから作るタイミングが重要で、 この辺はちゃんと説明しないと試行錯誤の時にハマる。
一応その旨書いてあるが、この書き方では知らない人には伝わらないと思うので読者は注意のこと。
こういう既に動くと分かってるものを動かす時と現場で試行錯誤してる時ではハマりどころが違う。 この辺実践編を名乗ってるんだから、現場で試行錯誤する時の事は補って欲しいところ。
9.9 TensorBoardとsummary
この辺はあんま詳しくないので真面目に読むと、scalarのあたりの和訳が良く分からない。以下のように書いてある。
「第一行は、グラフ内に、MSEを評価してサマリと呼ばれるTensorBoard互換のログのバイナリ列に書き込む。」
ん?なんか分かりにくいな。
本家のドキュメントを読むと、 これはprotocol bufferの形式があって、それのscalarを返すって事か。
つまりグラフ内に、MSEを評価して決められたprotobufの形式のバイナリ列を返すようなノードを追加する、という事かね。
tf.summary.scalarのソースを軽く追ってみる
ソースもちらっと読んだがREGISTER_OPから先を追うのはちょっと大変だな。本家のREGISTER_OPのドキュメントを読もう。
ふむふむ、つまりREGISTER_KERNEL_BUILDERを追えばいいのね。 こういう時にZipSourceCodeReadingは正規表現が使えるので便利だ。
あれ?WriteScalarSummaryしか引っかからない。 ScalarSummaryがあると予想してたのだが。
と思ったらsummary_op.ccの方に改行ありで書いてあった。よしよし。 実装はSummaryScalarOpだな。
コードを読むとSummaryクラスのオブジェクトをスタックに置いてadd_valueというのを呼んでる。
Summaryクラスはぱっと見無さそうだが、これはprotfbufの自動生成かな。
C++のprotobufのAPIなんて知らんがな、とpythonとgolangしか読んだ事無いが、C++の公式ドキュメントを読むか。
ふむふむ、だいたい合ってそうだな。やはりこのSummaryはprotobufが生成するクラスだな。
summary_tensorというのをallocateして、Summary protobufに書き込んだ物をこのテンソルに文字列として吐き出す、という事か。
では本文に戻ろう。たぶんこのテンソルをファイルに書き出す感じになってると思う。
うむ、本文のサンプルコードを見るとmse_summaryをevalして結果をsummaryのFileWriterにadd_summaryしてるね。 だいたい予想通り。
お、TensorBoardの理解がちょっと深まったな。ようするにこれはSummaryのprotobufを可視化するツールなんだな。 Summary の定義を見ていけば何が出来るかがだいたい分かるのか。おしゃれだね。
そのあとJupyterから見たければshow_graphって関数使え、とリンクが書いてあるが、スマホからは開けなかった。家帰ってタブレットなりPCなりから見てみよう。 いくつかやり方知ってるがどれもいまいちなので決定版があるなら知っておきたい。
9.11 モジュール性
お、ノードの名前が自動で振られていく話がある。この辺ちゃんと書いているのは偉いね。分かってないとハマりがちなので。
get_variableもちゃんと説明してる。 この辺はちゃんと使ってた経験あるんだな、というのが伝わってきて好印象。
9章はなかなか良かった
9章読み終わったので感想。 TensorFlowはびっくりするほど内容が良かった。 これ、著者は実務ではTensorFlowしか使った事無くてscikit-learnはドキュメントとかサンプル読んだだけで語ってるだろ…
なんにせよ、TensorFlowのまともな解説のある本というのは他に見た事無いので、これは貴重な本だと思う。 分かりやすいという感じでは無いが、必要な事がちゃんと書いてあるので、入門する人は読んでおくと良いだろう。
自分のレベルではあまり学ぶ事は無かったが、よくある入門を動かしてみました、よりは大分実践的な内容だった。 世の中にあるTensorFlowの本の中では難しい方に属すかもしれない(といっても非常に入門的な話に留まるが)。
という事で自分向けでは無かったが、9章は花丸をあげよう(偉そう)
10章 人工ニューラルネット
最初に生物の脳の話が出てくるが、もうこの話題は要らないと思うんだよなぁ。 最初の数回は珍しくもあったが、今となっては脳の素人が脳のうんちくを語るみっともない場という感じに成り下がってしまっている。
コネクショニズムとか歴史の話が思いのほか長いな。
FeatureColumnって何?
10.2のTF Learnのコードを見ていたら、infer_real_valued_columns_from_inputというのが出てくる。 自分は知らないが、説明も無い。
本家の説明を読んでもFeaturColumnを返す、と書いてあるがこのFeatureColumnがなんなのかの説明にたどり着けない。
自分はTF Learnは軽く見た事があるくらいで使った事は無い。だから全然知らない。
どうしよっかなぁ。この辺使うくらいならkeras使うからあんま興味無いんだがなぁ。
とやる気なくぐぐってたら公式ドキュメン発見。
なるほど、ようするにinputが実数連続値かカテゴリカルな変数かとかを表す物か。
sparseな場合はembedingにするかone hot vectorにするかとかをこのレイヤで選ぶらしい。 embedingというからにはトレーニングしたい気もするが、その辺もやってくれるんだろうな。
それにしてもこの解説が無いって酷くない?
ただTF Learnはこうしてみると悪くないね。 keras使うまでも無い事やりたい時はこれでいいかもしらん。
10.3 素のTensorFlowのFFニューラルネット
自力で実装して、同じ処理をするtf.layers.denseなどを紹介する、という進め方。 なかなか良いね。
sparse_softmax_cross_entropy_with_logitとsoftmax_cross_entropy_with_logitの違いもちゃんと解説されていて偉い。
ただ何故かin_top_kの解説が無いので本家のドキュメントで引数を確認しておく。 この辺の簡単なAPIの解説をサボるのはいまいちと思うんだよなぁ。 余計な事はくどくど説明するのだからこういうのも全部解説してよ…
10章読み終わり
層の数を増やす意義とかも、なかなか良く書けている。 実際はこう単純でも無いが、 これは著者がもっと詳しいけれど簡単に書いた、という内容なので、そう悪い印象では無い。
10章もニューラルネットの実践入門としてはなかなか良い内容だと思う。 9章も10章も良い内容だね。
11章 深層ニューラルネットのトレーニング
reluファミリーの説明はなかなか詳しい。 ちゃんとおすすめを言ってるのは偉いね。前半とは偉い違いだ。 素のreluの過小評価という気はするが、この辺は好みの差の範囲だろう。
11.1.3 バッチ正規化
バッチノーマライゼーションの解説は、これで実装しろ、って言われてもほとんどの人には辛かろう。 移動平均の扱いなどはstyle transferとか別の応用をする時には割と重要になる所なので、もうちょっと内部解説が欲しい気はする。
一方でブラックボックスとして使うならこれくらいでいいのかもしれない。
前半の使わないアルゴリズムでは細かい理屈を説明するのに、こういう今必修の要素の解説がどこからか持ってきた程度なのは、力の入れ具合としてはいまいちな気がする。
あとget_collectionの説明は前には無かった気がするが、説明してもいいんじゃないか? この辺はいまいちかな。ただ及第点はとれてる気はする。
11.1.4 勾配クリッピングにcompute_gradsの解説が!
compute_gradsとapply_gradsは自分でいろいろ試す時には必要となるので、これがちゃんと解説されてるのは評価高いね。
ただ、こうやって個々の所でちょこちょこ出されると全体像は分かりにくい気がする。 題材の提示の仕方は利点もあるが問題点の方が大きいんじゃないかなぁ。
11.2.1のget_tensor_by_nameの解説の日本語が分からない
Transfer Learningの所で、get_tensor_by_nameの解説があり、
「テンソルの名前は、それを出力する:0に続くオペレーションの名前である」
という説明をしているが、日本語の意味が良く分からない。 たぶんテンソルの名前は、そのテンソルを生成する時に渡した名前に:0をつけた物になる、という事を言いたいんだろうが。
元の文がどういう物かはいまいち想像出来ないが、これはたぶん誤訳なんだろうな。 こういう時は訳者の名前をチェックする。 監訳者が下田倫大さん、訳者は長尾高弘さんか。
ここまでの所、和訳はいまいちという印象。
add_to_collectionの説明がある!
この辺は割と良く使うのにちゃんと解説してる本は見た事無かったので、 このTransfer Learningの節の印象は良い。
ただTransfer Learningについてはいまいちオリジナルの論文とかおすすめの話は無い気がする。 Global Average Pooling使うとかその辺はどこかで言及されてて欲しいが、もっと後なのか?
11.2.2 他のフレームワークのモデルの再利用
理屈の上ではこんな感じで出来るのは言われなくても分かってる、という感じの内容だが、実際にやった事は無いので「へー」と思った。
tf.VariableはAssignというsuffixの名前で代入用のグラフを暗黙に追加している、 というのが面白い。kernelとはなんぞや?という気もするが、Wの所っぽいね。 その辺は説明してくれてもバチは当たらんと思うけれど。
和訳の「また、各代入演算の第2入力のハンドルも〜」はたぶん誤訳じゃないかね。 「また〜ハンドルも」ではなくて「そして〜ハンドルを」な気がする。
簡単な所の誤訳はどうでもいいが、 こういうややこしい細かい所はあまり自信が持てなくて困るな。
せっかくなのでこの辺のコード確認しておくか、としばらくAssignなどのグラフを追加する所を探したが見つけられず。修行が足りん…
間のレイヤはfreezeする話もよく書けている
11.2.3の前半のレイヤはトレーニングしない為の説明はよく書けている。
いわゆるbottleneckを共通化する為にget_collection使ってoptimizerのminimizeのvar_listに渡す、という例が書いてある。
こういうのは実践的で(・∀・)イイネ!!
stop_gradientの解説もあって、説明は不十分だが存在を示すだけでもちゃんと分かる人は自分で調べられるだろうから意義はあると思う。
やはり前半のSVMとかの解説との違いはなんだったんだ、という気がするが。 むしろこっちをちゃんと説明してくれよ、みんな使うんだから…
11.2.4のbottleneckのコードはコピペ題材としてはディスクに保存する物にして欲しいが、まぁその位は自分で書け、という事は出来る。 オンメモリ版もテストで使うのであって損は無いし。
11.2.5 transfer learningの層の決め方はどうだろう?
現在だといわゆるInceptionモジュールがあるので、切って良いレイヤと切っちゃいけないレイヤがあるから、この内容はいまいちに思う。 VGGくらいならこれでもいいんだが。
むしろ本書執筆時点の定番モデルとそのつなぎ方を説明して、将来はまた違うモデルがあるだろうからこの辺を調べろ、みたいな書き方をする方がいいと思うんだよねぇ。
その他も軽く読む
11.2.7の教師なしプレトレーニングは紹介するのは正しいと思うが、こんな説明で自分で出来る気はしない。 この辺はいまいち経験に基づいて話してるようには見えないが…
Optimizerはさすがに学ぶ事も無いと思うので飛ばし読み。内容は悪くは無さそう。
dropoutとかl1, l2 regularizationは結構良く書けてるな。
11.4.4 重み上限正則化が良い内容
weightsの最大値をクリッピングするコードの例がある。 これはTensorFlowではちょっと頑張らないと実装出来ないのだが、その話がちゃんとあって偉い。
これはWGANとかで使うので、割と重要度は高いと思うのだ。
本書の説明は使う分には十分だがAPIの説明があまり無いので一応確認しておく。 kernel_regularizerは公式ドキュメントは意味が分からないのでソースを読むと、最終的には_handle_weight_regularizationに来るっぽい。
なるほど、kernel_regularizerで渡した関数をweightのvariableを作る時に渡して、 この中でweightを引数にこの渡された関数を呼び出し、それをlossに加えるのか。
class Layerはそのうちコード読み実況やりたいね。
で、本文のコードに戻るとロスは別段無いのでNoneを返し、でもそこでclippingのopを作ってコレクションに追加しておいて、それらをsess.runの所で取り出して呼んでいる訳だね。
こういう実践的なコード例がちゃんとあるのは偉い。
なんかその後の解説の和訳が変だな。
regularizerを正則化器とは言わないだろ。少なくともこの文脈で器は変だ。
その後の「しかし」も意味が分かりにくい。なんか理解せずに訳してないか?
その後にmax_normのcollectionに追加してるのに、それを「重み上限クリッピングオペレーションのコレクションに」とか書いてある。 そこはキーの名前なんだから和訳しちゃダメだろう。
接続詞とかが変なので凄く読みにくい。 せっかく良い解説なのに、中を理解せずに直訳してるっぽいなぁ。 こういう翻訳や監訳はろくでもないね。
11章もなかなか良かった
11章を読み終わったので感想を。
この章もなかなか実際に使う時に必要になる事が良く書かれていて、しかも公式ドキュメントに無い事がちゃんと書かれている。 著者はちゃんとTensorFlow使ってるな、というのが伝わってきて好印象。
論文などを紹介する時はabstractを鵜呑みにしすぎるきらいはあるが、好みの範囲と言えそう。
和訳は何箇所か酷い所がある。 全体的には読めるのだけど、他であまり解説が無い所で間違える傾向があって非常に残念。 こういう仕事をしちゃいけないよなぁ。
12章 分散TensorFlow
おぉ、分散の話がある。これは凄いな。期待。
TensorFlowってデフォルトで全GPUメモリ使うんだっけ?(A. 使う気がした)
自分の記憶では確かgpu0しか使われなかった記憶があるのだが、12.1.2には全GPUボードのメモリが使われる、と書いてある。 本当かね?
と読んでいくと12.1.3にplacementの話があって、手動で配置しないとGPU 0しか使われないと書いてある。 うーん、これなら12.1.2でCUDA_VISIBLE_DEVICESを指定してる所の説明は、ちょっとミスリーディングに見えるが、、、
ああ、そうか。メモリを起動時に確保しちゃうのか。ロードは増え無いがメモリだけ抑えられちゃう、という事か。確かそんな挙動だった気がしてきた。なるほど。
動的配置関数
へー、こんなのあったんだ。知らなんだ。 この本を読んでて初めて「個人的に興味があって知りたい事だが知らなかった事」に当たった気がする(^_^;)
ただこれの実装方法はどうしたらいいのか良く分からんね。 そこまで解説されてたら素晴らしかったんだが。
12.1.4の並列実行の解説が素晴らしい
この評価キューと依存関係の話は自分もどこかで読んだ気がするしソースも読んだが、そんなにそこらじゅうにある解説、という訳じゃない。 この本にはその解説があって偉い。
こういうちょっとぐぐって持ってきただけ、よりももうちょっとちゃんと理解して自分の言葉で解説してる解説は印象良いよね。
ただCはGPU 0の評価キューに入ると言ってるが、図ではGPU 1になってないか?まぁいいけど。
その後にちゃんとcontrol_dependenciesの話もある。偉い。
12.2 複数のサーバーの複数のデバイス
ここは何度か公式ドキュメントは読んだが、ついに試したことは無く今まで来てしまった所なので姿勢を正して読む。
論文などでは言及されてたparameter serverなどの構成の実際のコードの話がある。これは素晴らしいな。
ただいまいち日本語が分かりにくい部分があるので、まず公式ドキュメントとyoutubeを見る事から始める。
TF Dev Summitのyoutube動画
ゆとりなのでまずは動画から見る。 これ。2017年のTF Dev Summitだとか。
2016年にペーパーがあるとか。これもあとで見よう。
Inception v3でどうするか、という話をしてる。 そうそう、これが知りたいんだよね。 去年こんな発表あったのか。知らなんだ。
11:06 別のマシンからpsタスクに同じ変数名の変数作ると共有される!そうだったのか!なるほど!
13:22 おお、replica_device_setterにps_strategyなんてオプションがあって、greedyなんて指定出来るのか。
このスピーカーはなかなか本物のTensorFlow devだなぁ。このレベルの人にはめったにお目にかかれない。 Derek Murrayか。
23:40 high level APIはこれだけじゃ良く使い方が分からんな。
なかなかいい動画だったが、これだけでは実際にInception v3をどうトレーニングしたらいいかはやってみないと分からないな。 apply_gradsもpsサーバーに置かなきゃいけないんだよね?たぶん。
ドキュメントの方もちらっと見たがそれ以上の事は書いてない。 ペーパーもちらっと探したが見つからない。youtubeコメントにも参考文献にも書いてないし…
まぁいいか。本に戻ろう。
replica_device_setter
12.2.4の複数のパラメータサーバーへのシャーディングの所。 シャーディングとは何かの説明無くカタカナで使うのは、良くない気がする。 キーの名前とか和訳しちゃいけない所は和訳するくせにこういう所は説明しないの、翻訳どうなの…
ただ内容は悪くない。本家のドキュメントよりも詳しい。
TensorFlowのclusterは、psとworkerという物を区別してるのね。 replica_device_setterの所で、変数だけpsに置かれてオペレーションはworkerに作られる、とあるが、 これは一般的な話なのかreplica_device_setterの話なのかが分かりにくいな。 公式ドキュメントを見るとreplica_device_setterの話のように見えるが、良く分からないので軽くコードを確認しておこう。
最終的には
_ReplicaDeviceChooser
のdevice_functionが返されるっぽい。 このメソッドはopを引数にdeviceを表す文字列を返す模様。へー、tf.deviceにはこんな機能があるのか。
で、self._ps_opsに入ってるopならpsを、そうでなければworkerを返す模様。 ps_opsはSTANDARD_PS_OPSか。 これは29行目で定義されてて、Variableっぽいものが並んでる。
なるほど、だいたい挙動は理解出来たが、これではapply_gradsがpsに入らないから多分ダメだな。
リソースコンテナ
12.2.5にリソースコンテナという物の解説がある。分散セッションでは変数が共有されるのは公式の動画でもやってたが、その1段詳しい説明だね。
なるほど、こういう感じになってるのか。 GCPはマネッジドなTensorFlowクラスタを普通に使わせてくれたらいいのになぁ。 MLEnginみたいなのじゃなくて。
それにしてもmy_problem_1というキーなのに説明を「問題1」としてしまうのは分かりにくいよなぁ。 その後ではmy_problem_1という名前のコンテナ、と言ってて、それなら最初からそれで統一してよ…という気になる。
12.2.6 キューの話もなかなか良い
キューは言及されてるのは良く見るが、実際にどう使うのかは知らなかったので、なかなか勉強になった。 便利そう。
TensorFlowは実際の大規模機械学習のサービスを作れそうな作りだよね。 一方でこの機能をちゃんと使いこなしてシステム作れる人は世界にもほとんど居ないだろう。 だいたいは単発GPUインスタンスを複数並べて処理出来る範囲の事しかしない(それすらも本当に一握りのトップ企業しか出来てないが)。
Googleが2015年の時点でここに辿り着いていたのは驚きに値するな。
12.2.7 グラフからのデータのロード
TFRecordはいまいち使いにくくて、公式ドキュメントを読んでもいまいちありがたみが分からず、 いつもkerasか自分でnumpy食わせるかでいいか、と思ってた。
そんな認識で12.2.7を読んだら、なかなか良く書けていて分かりやすかった。 なるほど、こう使う物なのか。 逆に分散環境じゃなければこれまで自分がやってた通りnumpy食わす方が良さそうだな。
IOとかもすべてグラフに統合して分散コンピューティングするの、なかなかかっこいいな。
その後のstring_input_producerは日本語の説明が固すぎて凄く読みにくいので、公式ドキュメントを読む。
なるほど、文字列ごとにQueRunnerを作るのか。start_que_runnersで取り出すというのがC言語っぽくて分かりにくいAPIだが。
なんかこの辺の和訳は間違ってはいないのだが何を言いたいか凄く分かりにくいな。 訳者はちゃんと理解して訳してるのかなぁ。
実際のコードは無いの?
実践編というのだからInception v3の分散版のコードが見たい訳だが、さぁ、実装だ、と思って12.3.4.4まで進むと、演習問題の解答を見ろ、と言う。
で、解答を見るとこちらのノートブックを見ろと言う。
ワクテカしながら最後まで見ると、「Exercise solution. Comming soon」ってなってる(2018年9月25日現在)
なんじゃそりゃ〜! ここまでどうでもいいサンプルコードはだらだら載せてきておいて、一番実践で大切なInception v3の分散の仕方のコードは無いのかよっ!
これ、前自分でデータ並列のコード書いて動かした事があるのだが、全然早くならなくて、何が悪かったのか知りたかったんだけど…
そしてここまでいろいろ書くんだからモデル並列のコードもちゃんと出せよなぁ。 というより著者は本当にこれ書いた事あるのかね?
12章はなかなか悪くなかった
最後にコードが無いのは本当にガッカリだが、内容自体は悪くない。 調べてみるとだいたい本家に似たような情報はあるが、以前自分がこの分野に興味持って軽く調べた範囲ではたどり着けなかった事もそれなりに載ってて、トピックの選択も適切だった。
日本語が何を言いたいか分かりにくい事は多くソース読んだり公式ドキュメント見た方が分かりやすい物も多かったが、 それらを調べる起点となっては居たので役に立たない訳では無い。
TensorFlowの分散の話としては、手に入る中では一番良くまとまってる文書という事になるんじゃないかなぁ。
ただソースが無いのは本当にガッカリだ。 本の提供する内容としてガッカリというのもあるが、この本が実際にコードを動かして確認した上で書かれていない部分が凄く多い、というのが露呈してしまっているのが残念。
「ホワイトペーパーにそう書いてあるのは知ってるが試したらなんか全然違う結果なんだけど?」とか、「なんか試そうとしたがどう書いたら良いか良く分からなかった」とかそういうのに対する答えが欲しいんだがなぁ。
ただそれでも世の中にある類書よりは遥かにマシだし、この本の中でも12章は良く勉強になった所なので、評価はする。
本の内容からは離れて。 TensorFlowは分散実行のフレームワークとして凄く良く出来ている。 明らかにまだ業界の大多数の人たちはこの水準で作業出来てなくて、MPIとかを使って作り込むかこういうレベルでの分散は諦めるかどちらかを選択している。
最初から分散実行のフレームワークとして完成した形で出てきたのは、 社内のレベルの高さを表しているよな。
一方でこの本の作者がサンプルを作れなかったり、自分が以前一日くらい掛けて書いた時にも並列にしたつもりがなんかうまく動かなかったり(GPUが一つしかつかわれなかった)、実際に動くシステムを作るのは結構たいへん。 この辺はAWS CLIとか使って、ばこんとクラスタ立ち上げてServer側も全部joinまでして待って、クライアントから使えるようなスクリプト群などは誰かが整備すれば世界中に広まると思うんだよなぁ。
そのうち誰かがやるとは思うが、次そういう機会があって誰もやってなかったら自分でやってもいい気がする。 AmazonがMXNet推しでGoogleはML Enginとかの形でつかわせたがるので、やるクラウドベンダが居ないんだよなぁ。 Azure でやればいいのにね。
13章、畳み込みニューラルネットワーク
さすがに序盤は流し読みでいいかなぁ。知らない事も無かろう。
最後まで読んだ。トピックはなかなか正しい気がする。 ただ個々のモデルはこれでは良く分からない。なんというか、Qiitaとか解説ブログみたいな駄目さだな。
あとどれを使うべきか、というブラックボックスとして使う方法に関しての記述がすくないのがマイナス点。 どのモデルのどのレイヤをGlobal Avereage Poolingにつなぐのがベストプラクティスでコードはこうなります、というのが無いととりあえずのアンチョコとして使えないじゃん、と思う。
という訳で13章の評価はいまいち、という感じだけど、類書のもっと酷いポエムみたいなのが書かれてるだけ、よりは大分マシではある。
14章 RNN
14.2 TensorFlowでのRNNの手実装
序盤はもはや見飽きた感じの凡庸で分かるはずの無い、例のRNNの説明が繰り返されてるだけで、またか…と思って読んでいたら、14.2はなかなか良く書けている。 Tensorflowで自力でRNN実装する、という奴。
そうそう、こういうのはやった方が良いよね。
と思って14.2を読むと、一タイムステップしかやってないのか。 それはどうなんだ?冒頭で任意の長さのシーケンスが扱える、と言っておいて2つの長さ固定では無いか。
ここから拡張していく、という話かもしれないので続きを読もう。
14.2.1 static_rnnの話
和訳が、BasicRNNCellを解説中で基本セル、と和訳してしまってる…こういうの酷いなぁ。
で、static_rnnの説明はいまいち良く分からないのでソースコードを読むと、昔見た時より随分長くなってる。 最初のコメントの使い方を見るだけで意味は分かるが、一応_rnn_stepも一通り読む。
それにしてもこの本、BasicRNNCellとかその上のLayerRNNCellとか全然解説しないよなぁ。なんでだろう?使うだけと割り切るなら理屈よりこの辺説明する方が実践的と思うのだが。 解説を見ると簡単にはソースコード読んでそうなのにね。
難しすぎる所を言葉で解説するのは良いが、BasicRNNCellくらいなら普通に解説していいんじゃないか。そしてstatic_rnnもdocstringのコード例くらいは転記して良いんじゃないか(というかそれが無いと読んでも分からんだろう)。
placeholderを一つにする話
で、入力のplace holderがタイムステップごとに別に用意するのは辛いのでunstackとかtransposeとかを使って一つにする、という話がある。
n_inputsは一つの入力のフィーチャーの次元か。さっきは3だった物。
で、これを1, 0, 2の順番に置き換えるのかな。 タイムステップのリストになる訳だ。 で、各要素は何かというとインスタンスのリストになってる訳だな。
unstackはソースコードのdocstringを読むと、デフォルトはaxis 0の軸を展開してこの次元は消えるとあるので、タイムステップごとのリストになる訳だ。
14.2.2 dynamic_rnnの話
いまいちこのソースでは何をやってるのか分からないのでdynamic_rnnのソースを頑張って読む。昔読んだ時より大分複雑になってるな…
ただdynamic_rnnのcontrol_flow_ops.while_loop呼び出しまでたどり着いたので、わかった気になってやや満足。 ちゃんと結果のグラフを見ないとしっかりわかったとは言えないだろうが、旅先なんでこんなもので。
14.2.3で可変長の話をしている
本文の構成はいまいち分かりにくいな。ようするに、
- 2タイムステップの話
- Nタイムステップ、ただし固定の定数の話
- 可変長のタイムステップの話
という順番で進んでいるのだな。
この章の構成が分かりにくいので、その時その時でどの話をしているかわかりにくいが。これは原文もこうなのか訳のせいなのかは分からないな。
とにかく長さを別のplace holderで渡すコードがちゃんとあるのは評価したい。
14.3 RNNの訓練
この節はなかなかコードが良いな。 書いた人はちゃんとわかってるのが伝わってくる。解説の日本語はたまに何がいいたいのか分からないが(たとえば「みなさんがすでによく知ってる単純な例が使える」ってどういう意味?)、ソースがクリアなのでソースを読めば基本的な事は分かるので構わないか。
ただ14.3の冒頭の説明と14.3.1があんま関係ないのがちょっと残念だな。 これたぶん14.3.2以降の話だよね。
MNISTをあえてRNNでやるのは入門で良くあるけど、このコードはこれまで見た中では一番解説に良いな。
14.3.2 時系列データの話
中のニューロンの数だけアウトプットの次元が増える訳だが、最後に必要なのは一つなのでどうしよう?という話をしている。
あれ?これまではどうしてたっけ、確かニューロンは5を指定してたよな、と最初の手作りのコードを見ると、そもそもYのラベルデータは無いのか。 なるほど。ただフォワードパスを計算してただけか。 これは面白い進め方だね。
なんか章構成は良く練られているが、本文の解説からそれが伝わって来ないな。これ原文もこうなのか?信じがたいが。
MNISTのコードを見直す
さて、一つ前のMNISTの時はロスも計算してたので同じ問題があるはずだよな。 どうしていたか確認してみよう。
ニューロンの数は150と言っている。 そして最後にtf.layers.denseにつなげて10次元にしてるのか。なるほど。
OutputProjectionWrapperの所の解説を読む
日本語は何を言いたいのか分かりにくいが、ニューロンの後ろにactivation無しの全結合層をつなげるらしいな。 ようするにWのmatmulか。
説明は分かりにくいが、OutputProjetionWrapperを読むとソースは短かくてわかりやすい。 Linearを最後につけるだけ、stateはそのまま素通ししている。 これはソース書いた方が早いんじゃない?と思うが、かたくなにフレームワークのソースやコメントのサンプルは転載しないよなぁ。
X_batchとy_batchのサンプルも載せてよ、とは思うが、ロスのあたりのコードはなかなかクリアで良い。 サンプルコードの出来が良いね。
そのあと公式ソースのdocstringにあるように、reshapeで直接やる方法も載ってる。この順番も正しい。
DeviceCellWrapperのコード例
こういうのがあるのは良いと思うのだが、これってどれくらい効くのかね? セル間の転送が結構多いので早くなるかどうかの結果も教えて欲しいのだが。
ただこういうやったかどうかは怪しいがとりあえずこう書けば出来る、みたいな記述も中を理解する為のヒントにはなるので良いと思う。 本書を読むだけで分かるかはちょっと怪しいが、途中ちゃんとソースも読んでる人は理解は深まる。
DropoutWrapperも自分は知らなかったので勉強になった。間を抜くドロップアウトか。なるほど。 簡単そうと思ってソースを確認したらdocstringが長い。いろいろ調べた論文があるようで、それに従って実装してるらしい。まぁそこまでは興味無いからいいや。
14章は悪くなかった
平凡な内容ではあるが、良く理解した上で説明する内容を選んで話をしているように見える。 和訳はこの辺いまいち分からずにただ文を訳してると思われる部分が散見されてちょっとガッカリだが、割と大切な所はソースで表現されているので、困りはしない。 ただ自分は献本されたから日本語版読んでるが、自分で買うからこれなら英語版を買うだろうなぁ。
seq2seqなどもあえて解説しないのは良いと思う。この章はRNN使う時の実践ガイドとしてはこれまで見た中では一番良く書けてると思った。 ただすごく良い、という訳でも無い。 あくまで悪くない、くらい。
15章 オートエンコーダー
なんでオートエンコーダーなんてやるの?というのはさっぱり分からないが、何故かオートエンコーダーの章があって、しかも無駄に詳細だったりする。 Goodfellow本は生成モデルの為にこの辺ちゃんとやるのは文脈として理解出来るが、なんでこの本でこんなのやるのか?というのは、目次を見ても良く分からないな。
とりあえず読んでいこう。
スタックオートエンコーダーがなかなか良い
相変わらずなんでこんな事やってるのかはさっぱり分からないが、15.3.3の、層を部分的にトレーニングする所のTensorflowのコードはなかなか良い。 どこかから持ってきて終わり、じゃなくて、ちゃんと自分で考えて書く感じなので、TensforFlowの良い練習になる。 minimizeにvar_list渡したり。 研究者はこの辺ちゃんと出来る必要るよな。
この著者はなかなかちゃんと理解してて偉い。 TensorFlowの本のほとんどはTensorFlowを全くわかってない奴が書いてるという恐ろしい現状があるからなぁ。
VAEの話は意味が分からず
唐突に始まるVAEの話は、理論の解説はしないでコードが出てくる。 昔元論文をそれなりに理解したがもう忘れた、くらいのステータスの自分が読んでさっぱり分からんのだから、この解説は普通は分からんのだろう。 なんかもっとEM法みたいな枠組みだよな、確か。
このコードだけ提示する意義も良く分からないよなぁ。 Goodfellow本は今後の生成モデルの研究をしていくであろう読者向けにそこまでの内容をまとめる、という事で意味があったが。
VAEはまだモデルを持ってくるだけで生成モデルとして何か意味のある応用が出来る、という段階には来ていない。 だからこれだけを動かしてみる事に応用的意義は無い。 さらにオートエンコーダーも生成モデルの研究というコンテキストから切り離すとなんの為にやってるのかさっぱり分からない。
正直何も考えずにGoodfellow本からトピックをパクった結果こんな意味不明な章が出来てしまったんじゃないか、と勘ぐってしまう。 なんにせよ、TensorFlowの演習問題としては手頃だが、読む価値は無い章だった。
16章 強化学習
この章はここまでの内容で唯一、私がほとんど知らないという内容になる。 ここまで知らない人は読んでも分からんだろ、という説明が多かったのであまり読むのも気が進まないが、 駄目元で一応読んでみよう。
16.6 方策勾配法まで読んだ
ここまでの所、思いのほか分かりやすい。 gym.makeがどういう理屈で今作ってるのをCartPoleだと認識してるかは良く分からなかったが、名前のprefixが一致とかなのかなぁ。
16.6からは良く分からない所が出てきたのでメモをとりつつ読んで行こう。
16.6の、yを作る所の理屈が分から無い、 「私たちは選ばれた行動を考えられる最良の行動であるかのように扱っているので」という説明の意味が良く分からないが、ここは割と重要な所に思う。
例えばactionが0の確率が0.7だった時に、「1 - 実際にとったアクションの値」をyとしている訳だ。 でもこれが考えられる最良の行動であるかのように扱ってるとはどういう意味だろう?
割り引き現在価値で見た時に、ある行動に対してコストが定義出来る訳だ。 その行動が良いか悪いかはコストに依る。 そこで良い行動の時にはyが正解となり、悪い行動の時には1-yが正解になるのだよな。
そこで、まずyを正解としてgradを計算して、1-y が正解の時にはこのgradをマイナスにしてそれをgradとみなすのだよな。 説明の日本語は何が言いたいのか良く分からないが、コードは理解出来た。
追記: 数ページ先の全体のコードを解説している所では「選択された行動がベストだというふひをして勾配の計算をする」とちゃんと解説されてる。なんでここの説明がこんな変なのかは良く分からず。
次の「これは、勾配ベクトルごとにひとつずつのプレースホルダーが必要だということである」は自分には良く分からなかった。 そこはsess.runをどう走らせるか、という問題だよな。
ただAIGymがTesorFlowの外にあるので、いったんホスト側に戻ってくる必要があるのは間違いない。 そして報酬の計算をしたあとそれを渡さないといけないのは間違いないだろう。
感覚的には割り引いた報酬のリストがプレースホルダーであれば、apply_gradsはグラフ上で表現出来る気がするが、 ここではそうはせずに個々のgradに対する変更はホスト側で実装し、その結果をfeed dictに食わせる、と言う事にしようと言ってるんだろうな。解説は良く分からんが、やる事は分かるのでまぁ良かろう。
あとのコードの「勾配と高度のスコアを掛けて…」というコメントがあるが、高度ってなんだろう? ここで掛けるのは報酬の割引現在価値だよな。
コードを読むとやはりrewardを掛けてる。 うーん、まぁ日本語が何言いたかったか推測しても無意味だからいいか。
16.6はなかなか分かりやすかった
日本語的に意味が分からない所はちょこちょこあったが、強化学習で報酬からどうgradientsを作って学習していくかの基本的アイデアは理解出来た。 強化学習まったく知らない自分がこの位理解出来たのだから、なかなか知らない人向けに良い解説になってると思う。
また、TensorFlow的にはまぁまぁ難しいコードが必要だが、それがちゃんと提示されてて偉い。 TensorFlowの勉強にもなるし、似たような事やってみたい人にも参考になるだろう。 この本を読んでいくだけでこのコードが理解出来るかは自分には分からないが(自分は読む前からかなり詳しかったので)。
自分がTensorFlowやる時知っておいた方がいい、と思う事は、ここまででだいたい尽くされてるかなぁ。あ、Severのあたりはいまいちか。でもそれ以外はだいたいこんなもんで良いと思う。
TensorFlow以外の部分の知識も要求されるのは良し悪しだが、自分がこれまで見た文書や本の中では唯一必要な事が一通り入っている物なので、他の選択肢は無いので、現時点ではこれを読むのが良いのかもしれない。
16.7でベルマン方程式の話が!
昔経済学で勉強したベルマン方程式が出てきて、ちょっと驚く。 こんな所でも使われていたのか。 そもそもにエージェントが利益最大化を目指して行動する、って経済学っぽいから、数学が同じになるのも言われてみれば当然か。
16.8のTD学習とQ学習
式16-4の、s’とかrとかが何なのかいまいち良く分からない。 こういうの、真面目に読む気失せるよなぁ。
気を取り直してちゃんと考えよう。 s地点の価値を、それまでのs地点の価値と今回の行動で移動したs’地点の価値、及び遷移で得られた報酬の平均としてるように見えるが、ガンマはなんだろう?割引率か。
ふむ。 では式16-5はなんだろう?
s’は今回のアクションの結果たどり着いた所か。
ようするに、ある状態sの価値は、その周辺の試行による観測を平均していけば、長期的には本当の平均になる、という事だよな。
で、sにおけるあるアクションaの価値も、やはり一回やってみた結果を足し合わせていけばやがて本当の期待値になる、と言ってる訳だ。
周囲の値の収束を前提に自身の値が収束するので、相当収束は遅そうだし本当に収束するのかも良く分からないが、loopy BPとかと同じようなもんだよな。
実際コード例を見てるとloopy BPと凄く似てる。 なるほど。強化学習ってこういう感じか。 意外と分かるな。
16.9 DQN
Qを推定する為の関数を、DNNで置き換える。おぉ、なるほど、これは行けそうな気がするね!
とアイデアに感動して実際の実装の解説に進むと、また日本語が良く分からない。 trainableじゃない変数を「訓練できない変数」と訳したりするのを見かけるだけに、自分が理解出来ない所を頑張って読もう、という気力がわかないのだよな…
気を取り直して少し頑張ってみよう。 DNNのトレーニングを考えるのだから、 ようするにロスが理解出来れば概ね理解出来る。
まずコード例では、DNNは状態を入力として、各アクションの期待値を返す。
で、トレーニングとしての一回の教師データを考えよう。 一つのexampleは、
- その時の状態
- アクション
- 結果の報酬
の組になるのだろうな。 で、状態は画像データ、アクションはpolicyを元に決めるのだろうが、それはこの時点では未定。 結果の報酬はアクション取った後にずっと続けていって終わった段階で割り引いて計算する。 つまりこのアクションは覚えておいて、 プレイの最中はQネットワークをフォワードパスとして実行していって、 training opはこの時の結果に対して結果の報酬と予想の報酬の差分で作るのだろうな。
結果の報酬は後から割り引いて計算するので、place holderとして降ってくると思っておけば良いのだろう。 これを計算する時に別のフォワードパスの実行がたぶんあるのがややこしいが。 (追記:これは少し誤りがあった。後述)
で、この報酬がyとして降ってくるとすると、我らのDNNの結果の誤差はどう定義出来るだろうか?
我々としては、DNNに対して、stateとアクションの組で期待Q値が出せる。 これと降ってくる報酬の差が誤差だな。
うむ、小細工は入ってるがそういうコードになっている。
報酬の所のコードを見る
さて、報酬はplace holderで来ていたので、そこの計算を確認する。
すると、y_valはrewardにcontinesとmax_next_q_valueを掛けた物を割り引いてる。 あれ?予想と違うな。
コードを確認すると、このrewardsはactionを取った時に直接得られる物だ。 式16-5を見直してみよう。これはrに相当するものだな。
で、そこに次のステートのQの最大値を足す訳か。
コードを確認すると、next_q_valuesはtarget_q_valuesに次のstate を食わせてevalしてる。 このtarget_q_valuesはもう一つのDNNと言ってた奴だよな。一応確認しておこう。>正しかった
意外なのはゲームが終わってるかどうかをここで使う事だな。 ゲームが終わってるという事実は正しいQの値を伝えてるので、推測のQの値をこの場合だけは修正してるのね。
つまり、y_valは終わった後に巻き戻るのでは無くて、いつも1ステップでしか見てないのだな。ああ、TD学習、という奴だっけ。16.8でやったね。なるほど。
さて、これではどう学習が進むか少し考えてみよう。 まず、最初の段階では1ステップ分の未来だけでほとんどの価値が更新される。 ただ、終わりの所が偶然サンプルで当たると、そこは少なくなってるはず。
すると2周目は、一周目であたった一つ前は、次の次が終わりという情報を活かせる。 これってでも、凄い伝わるのに時間がかかるな。
まぁ最初のうちはすぐ死ぬからいいのか。 だんだんと長生きしていくようになると、そこまでの道中は割とちゃんと学習されてる訳だよな。
2つのネットワークの意義を考える
ターゲットの環境はしばらく固定してオンライントレーニングの方を学習すると、どういう意義があるだろう?
実際にどういう報酬が取れたかは環境から得られる訳だ。 このオンラインの方のネットワークは何に使ってるか、とコードを見ると、policy を考えるのに使ってるんだな。
ようするにtargetという固定されたルールの元で、でも現実とtargetとの差分をいろいろ探す事で、より良い現実のネットワークを作ろうとする訳だ。 より良い現実を反映したネットワークを元に行動していって、その結果より多くの現実を知っていく。
この現実の認知とその差分のズレをあまりに高速になおしてしまうと、振動するみたいな挙動になる事があるのだろうな。 だから行動の改善と世界の認識を同時には変えずに、一旦は世界の認識を固定した上で行動の改善をしばらく追求し、ある程度行動の改善が進んだら世界の認識をアップデートする訳か。
イメージはつかめた。
16章、なかなか良かった
読み終わったので感想を。 当初は自分の知らない分野だから分からないだろうな、と諦め気味で読み始めたのだが、 思ったよりもエッセンスは学べた。 日本語の解説は意味の分からない事も多かったが、コードは割と良く書けていたので、最終的な内容は理解出来たと思う。
16章のコードもTensorFlowのレベルはなかなか高い。 これだけスラスラ書けるTensorFlow使いもそんな会った事無いレベル。 これをちゃんと本にしたのは偉いな。
終盤は監訳者や翻訳者の評価は一貫して下がり続けたが、著者の評価は割と持ち直した。 まぁまぁ出すに値する本になってると思う。
全体の感想
はしがき等から、基本は理解している人が実際に活用する為の本かと思ったが、 あんまり使う方にフォーカスが当たってるようにも思えなかった。
使うだけなら最近は全く必要ないモデルの話が延々と続くし、一方でとりあえず使う為のハウツーに掛けてる。 とりあえずLightGBMに突っ込んでおけば良い、みたいなシチュエーションでも、LightGBMなどの話が全然無い。GBDTの話はscikit-learnのが一応あるけど、scikit-learnのGBDTはヒストグラムが無いのだよね…
Transfer Learningでも、とりあえずInception V3持ってきてここの層からGlobal Average Poolingにつなげ、みたいな話が無い。 ブラックボックスで使う為の情報が無い。
8章までの内容はひどい。読む価値は無いと思う。 モデルの良し悪しの判断がないでダラダラと同じような事をするモデルが紹介されている。 しかも使う為の情報は無いくせにどこかから持ってきたかのような薄っぺらい理屈の説明がだらだらある。 こういう、目次だけ読んだ人間を騙すような内容はろくでもないなぁ、と思った。 ただ、scikit-learnのコード例を探す用くらいの価値はある。
9章からは一転して内容はかなり良くなる。 前半はなんだったんだ、という位。
TensorFlowを結講ちゃんと分かった上で、必要な題材がちゃんと選ばれていて、ちょっとTensorFlowでは書くのが面倒な事もちゃんと自力で書いている。 TensorFlowのコード例としてはこれまで見た文書、オンラインコース、本の中でもっとも良く書けているし、分量も多い。
途中途中に論文のabstractや解説ブログの内容をただ持ってきただけのような理論解説が挟まって、これの出来は悪い。 ただ、原典への参照はあるし、一度この辺勉強した事あれば、思い出すのに役に立つ程度の内容ではある。とりあえず前半ほどのひどい内容とは雲泥の差。
全体的に、理論の説明は他の本を参照して、それらをどうTensorFlowで書くか、という視点で読むと良いと思う。
特に単純にはtrain_opが作れないケースでの学習方法をこれだけちゃんと扱ってる本は、自分は初めて見た。 単にどっかにあるサンプル持ってきただけ、よりはだいぶちゃんと書かれている。
以前読んだ「詳解ディープラーニング」という凄い酷い本と比べると雲泥の差。
後半は理屈の解説はいまいちというか悪いと言えてしまうけど、ソースコードは素晴らしいので後半は総合的には良い、と言えると思う。
全体的にフレームワークのソースコードやドキュメントの引用があまり無い。 だからAPIの使い方の解説はいまいちな物が多い。 これは公式ドキュメントも合わせて読む方が良いと思う。 著者は明らかにコードも少なくとも上の方はちゃんと読んでるのになんでその辺解説しないのかは良く分からなかったが、 少なくとも何かの意図を持った選択なのだろうけど、 自分はTensorFlowのソースを読みながら理解した場所は結講あるし、そうしないと分からない所はまぁまぁあるでしょう。 その結果、読者への要求は少し不要に多くなってしまってると思う。
後半のソースの解説の日本語の文章は出来が悪い。 最初は解説が悪いのかと思ってたが、ソースの提示は割とちゃんと構成を考えて行われている事から、これは和訳がひどいんじゃないか、と予想する。原文が悪かったら訳者と監訳者には濡れ衣すみません。 ただ後半は明らかな誤訳や文脈が通ってない直訳みたいな文があるので、訳の品質が低いのはほぼ間違い無いと思う。 原文の解説がいいかは知らないけれど。
後半の内容が素晴らしいだけに、後半の訳がいまいちなのはとてもがっかりした。
個人的には、中途半端に機械学習の本の体裁を取らずに、素直にTensorFlowレシピ集として出してくれたらもっと良かったのにな、と思った。
それでも業界のひどい本ばかりの現状においては、十分に良い本と言えます。 8章まではコード眺めるだけくらいにして、9章から読むと良い本です。 理論の解説は分からない所は別の本読みましょう。