ML(Knet ...) of julia (3)
とあるページを見ていたらNICTな方の研究成果が公表されてた。研究の成果を皆が分かち合えるように、アプリになってた。血税が還元されたのね。
上記はただ使う人用だけど、 みんなの自動翻訳@TexTra®とは こちらは、皆さまのご協力をお願いしますって言う基盤だな。献血みたいに善意で脳汁を提供して下さいって呼びかけ。
解説が出てた。
Google翻訳より高性能? 「日本の自動翻訳がすごい理由」をNICT隅田氏が解説
なる程、AIなんだね。みんなで鍛えれば、強くなるって頷ける事です。
grad, update
前回まででKnetのハロワは終わったかと思っていたら、一番重要な部分を見ていなかった。
loss(w,x,ygold) = nll(predict(w,x),ygold) lossgradient = grad(loss) function train(w, dtrn; lr=.5, epochs=10) for epoch=1:epochs for (x,y) in dtrn g = lossgradient(w, x, y) update!(w,g;lr=lr) end end return w end
ここに出て来る、gradとupdateだ。特に水晶玉ことwの更新方向を決めるgradって関数ね。方向を間違うと、正しい玉にならないから、超重要な部分だ。
Julia1.0のDeepLearningフレームワークFlux.jl入門
OPTIMIZER 入門 ~線形回帰からAdamからEveまで
gradってのは微分機能があるそうだ。最初に、maxima で、記号微分をしてみる。
(base) cent:tmp$ maxima Maxima 5.41.0 http://maxima.sourceforge.net using Lisp SBCL 1.4.0-0.1.el7.bootstrap (%i1) diff(4*x^2 - 8*x, x); (%o1) 8 x - 8
導関数が求まった。(これぐらいは、暗算だよな)
julia> f(x) = 4x^2 - 8x f (generic function with 1 method) julia> g = grad(f) (::getfield(AutoGrad, Symbol("#gradfun#8")){getfield(AutoGrad, Symbol("##gradfun#6#7")){typeof(f),Int64,Bool}}) (generic function with 1 method) julia> g(0) -8 julia> g(1) 0 julia> g(2) 8
juliaに元の関数fを定義。その導関数gをgradで得る。gに色々な値を入れると、運が良ければ、極が見つかる。
julia> f(x) = sin(x) f (generic function with 1 method) julia> g = grad(f) (::getfield(AutoGrad, Symbol("#gradfun#8")){getfield(AutoGrad, Symbol("##gradfun#6#7")){typeof(f),Int64,Bool}}) (generic function with 1 method) julia> g(0) 1.0 julia> g(pi/2) 6.123233995736766e-17
このgradは、数学関数の導関数も知っている。sinの微分はcosだよな。AutoGradってパッケージにおいて、精一杯拡張中だ。
math.jl
@primitive sin(x),dy (dy.*(cos.(x)))
マクロの取り扱いは、macro.jlに置いてある。これがスラスラと理解出来るようになりたいものだ。
findmax ...
前回、maxなデータを格納してるindexを知りたいって事で、ソースに当たった。 そこからの繋がりで、CartesianIndexなんてのに出会ったけど、これは何?
解説が出てた。キーになる技術なのね。aの配列内で一番大きいのを探す一般的なやつ
julia> a 10-element Array{Float32,1}: -7.1254435 0.22731692 2.8133056 -2.7228057 -1.0171373 -6.212217 9.294174 -0.19751328 2.4435027 0.03542471 julia> findall(isequal(maximum(a)),a) 1-element Array{Int64,1}: 7 julia> findall(x->x==maximum(a), a) 1-element Array{Int64,1}: 7 julia> findall(a .== maximum(a)) 1-element Array{Int64,1}: 7
2番目の方法が馴染みだな。まあ色々。色々ついでに、argmax,findfirst,findlast等の変形版もあるとか。
notebook
相変わらずのハロワだけでは進化が無いと思って、tutorailを見ると、なんとまあノートブックで例が提供されてた。ノートブックって余り好きでは無いんだよな。理由は、emacsみたいにキーボードのコンビネーションが使えないから。
emacs hoge.jl して、編集して、C-c C-b するだけで、画面が割れてjuliaのREPLが動き出し、そこにhoge.jlを送り込んで実行してくれる。こんな楽な環境はありませんで。
ぼやいていても始まらないので、tutorialへ移動して、jupyter-notebook したよ。 適当に一冊のノートをクリック。裏でjuliaのエンジンが起動するはずなんだけど、始動失敗で何度もトライしてる。ご主人様に忖度してるのか。
しょうがないので、condaをupdate、それからIJuliaもupdate。これで、やっと動いた。 気持ち悪いけど(何時またエンストするやら)、使えるからいいか。
この際、キーボードバインディングを調べておくか。ググったら、Esc h ってのを紹介された。 一覧が確認出来る。オイラーはCELLの移動だけって事で、vi風のjkだけを記憶に留めておこう。願わくば、アクティブなCELLが画面中央に来て欲しいんだけど、それはかなわぬ夢みたいだ。
そうそう、思い出した事がある。julia docのHomeページ等、左側に目次が出て来て、右側は 指定されたコンテンツが表示される。
目次を畳んで、大きく別の所を見るのがものすごく不便。左右の境界付近にある細いバーをマウスでぐりぐりしなきゃならん。年寄りは手を出すな風の最悪UIだと思うぞ。
ある日、ふとしたはずみでipadを使ってアクセスしてみたんだ。そしたらなかなか快適だった。 左側の目次部分が指で簡単にスライド出来る。目的の所でタップするだけで、右側に展開出来る。
これってMSの陰謀で、タッチパネルのパソコンを使ってくださいって事だ。そしてみんなそれに同調してる。全く困ったものだのう。
で、julia docなら、PDFが提供されてるので、それを落としてきてブラウザーで見るのが正解。左側に出て来るindexの制御が楽でよい。巷に溢れてるMS陰謀のWebをPDFに変換して手元に持ってくるツールって無いものかしらん。
Tutorial / 23.learning
In[1]: using Knet, Plots, Statistics, LinearAlgebra, Random Base.argmax(a::KnetArray) = argmax(Array(a)) Base.argmax(a::AutoGrad.Value) = argmax(value(a)) ENV["COLUMNS"] = 72 Info: Recompileing stale cache file ... @ Base loading.jl:1184 Out[1]: 72
このようにOut[1]みたいのが有れば、処理が終わったんだなあと認識出来るけど、
In[2]: nclude(Knet.dir("data/mnist.jl")) xtrn, ytrn, xtst, ytst = mnist() ARRAY = Array{Float32} xtrn, xtst = ARRAY(mat(xtrn)), ARRAY(mat(xtst)) onehot(y) = (m=ARRAY(zeros(maximum(y),length(y))); for i in 1:length(y); m[y[i],i]=1; end; m) ytrn, ytst = onehot(ytrn), onehot(ytst); Info: Loading MNIST... @ Main /home/sakae/.julia/...
この例は、いつまで経ってもOut[2]相当が出てこない。これって上記の評価の結果無しなんで、Out相当を作れないんだな。全く紛らわしいな。まあ、勘に頼って下さいって事だな。
あるいは自衛策で、入力の最後の所に、println("Done")とかの目印を入れる、done=trueを入れておいて、強制的にOutを生成するとかだな。
そして、つらつら見てたら構造体の例が出て来た。
struct Foo w b end Foo(x::Int, y::Int) = Foo(randn(y,x), zeros(y)) aa = Foo(3,2) (m::Foo)(x) = m.w * x .+ m.b x = [1,2,3] y = aa(x)
(m:Foo)(x)の所の説明が、turn Foo instances into callable objects ってなってて、目から鱗ですよ。こういう使い方も出来るのね。
julia> aa.w 2x3 Array{Float64,2}: 0.382856 -2.08847 1.40517 -0.617714 -2.08643 -0.229582 julia> aa.b 2-element Array{Float64,1}: 0.0 0.0 julia> y 2-element Array{Float64,1}: 0.4214164786338359 -5.479325022184515
CNN
Convolutional Neural Networkとは何か
tutorialにもCNNが置いてあるけど、CPUしか持っていないオイラーは重くてしょうがないので、眺めて終わりにする。
RNN
RNN:時系列データを扱うRecurrent Neural Networksとは
そして更に重いの。
word2vec,doc2vec
これも豪華な設備が無いと動かせないので、冒頭で挙げたipadから使う翻訳屋さんを使ってみた。
日本語から英語に翻訳はいいんだけど、音声でやり取りするって事は、毛唐と対面して会話って事だよね。ipadを間に置いてお互いの母国語でしゃべりたい。が、実現が面倒。日本語から英語に翻訳されたら、それを受けて英語から日本語って流れになって欲しい。それが出来ないのね。
いちいち設定を変えないといけない。面倒。日本人が日本語から英語用のipadを持ってる。外人が、英語から日本語へのiphoneを持ってるってシチエーションならいいけどね。
速く何とかしてください。少なくとも、オリンピックが開かれるまでには。
from scrach
Scikit-learn
そしてJuliaである。何とpython語のやつをjuliaでやっちゃうという離れ業。
しかけは、pythonのscikitライブラリィーをPyCall.jlを使って呼び出してしまえって方法。 面白い試みだな。
これ、例の一部
julia> using ScikitLearn julia> # This model requires scikit-learn. See # http://scikitlearnjl.readthedocs.io/en/latest/models/#installation @sk_import linear_model: LogisticRegression PyObject <class 'sklearn.linear_model.logistic.LogisticRegression'> julia> model = LogisticRegression(fit_intercept=true) PyObject LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, l1_ratio=None, max_iter=100, multi_class='warn', n_jobs=None, penalty='l2', random_state=None, solver='warn', tol=0.0001, verbose=0, warm_start=False) julia> fit!(model, X, y) /home/sakae/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning. FutureWarning) /home/sakae/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:469: FutureWarning: Default multi_class will be changed to 'auto' in 0.22. Specify the multi_class option to silence this warning. "this warning.", FutureWarning) PyObject LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, l1_ratio=None, max_iter=100, multi_class='warn', n_jobs=None, penalty='l2', random_state=None, solver='warn', tol=0.0001, verbose=0, warm_start=False) julia> accuracy = sum(predict(model, X) .== y) / length(y) 0.96 julia> println("accuracy: $accuracy") accuracy: 0.96
https://scikit-learn.org/stable/auto_examples/index.htmlにあるやつを、julia語に翻訳してみるのも一興かと。
そんな事より、 Choosing the right estimatorこのフローチャートを見て、最適な解決法を探らないかい。