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って関数ね。方向を間違うと、正しい玉にならないから、超重要な部分だ。

AutoGrad

誤差逆伝播法のコンパクトな説明

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

Word2Vecとは

Word2Vecをざっくり理解する

これも豪華な設備が無いと動かせないので、冒頭で挙げたipadから使う翻訳屋さんを使ってみた。

日本語から英語に翻訳はいいんだけど、音声でやり取りするって事は、毛唐と対面して会話って事だよね。ipadを間に置いてお互いの母国語でしゃべりたい。が、実現が面倒。日本語から英語に翻訳されたら、それを受けて英語から日本語って流れになって欲しい。それが出来ないのね。

いちいち設定を変えないといけない。面倒。日本人が日本語から英語用のipadを持ってる。外人が、英語から日本語へのiphoneを持ってるってシチエーションならいいけどね。

速く何とかしてください。少なくとも、オリンピックが開かれるまでには。

from scrach

Deep Learning のための Julia

Juliaで数値計算

物理で使う数値計算 :Julia 語による 簡単数値

Scikit-learn

scikit-learn

Scikit-learnを用いた機械学習のページ

scikit-learn: Python での機械学習

PythonサンプルをJuliaで書き換えてみる

そしてJuliaである。何とpython語のやつをjuliaでやっちゃうという離れ業。

ScikitLearn.jl

しかけは、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このフローチャートを見て、最適な解決法を探らないかい。

darknet

Darknet: Open Source Neural Networks in C

Darknetという人工知能が超簡単で凄いと聞いたので試したら大変なことになった