
Julia入門~高速な動的型付け言語~【Fluxでの機械学習編】
2021.12.20
Fluxで機械学習編~Juliaに入門してみよう~
前回は、Julia と Jupyter Notebook を連携して、グラフ描画する方法を紹介しました。
今回は、Julia の機械学習フレームワーク「Flux」を紹介していきます!
※本記事で使用するのは、「Julia ver 1.5」です。
Fluxをインストールする

Flux は、Julia 向けに提供されている、機械学習フレームワーク。
Github の README を読むと、
Flux は100% Julia で書かれており、簡単に機械学習モデルを構築できる。
と、記載されています。
【Github:Flux】
https://github.com/FluxML/Flux.jl
ちなみに、今回は試しませんが、GPU コンピューティングもできるそうです。
機械学習フレームワークでは、なかなかの完成度と言えそうですね!
インストール
いつも通り、パッケージモードで追加します。
1 | (@v1.5) pkg> add Flux |
これだけで OK です。
本記事では、執筆時点で最新の「v 0.11.0」を使用しています。
Fluxを使ってみる!
それでは早速、Jupyter Notebook を立ち上げて、実際に触ってみましょう!
1 | $ jupyter notebook |
まずは、Flux を読み込みます。
そこそこ時間がかかりますが、気長に待ちましょう…
1 | using Flux |
基本演算 (勾配演算)
Julia は、数学演算に特化しているため、「勾配計算」も Flux と組み合わせれば、簡単に計算ができます。
1 2 3 4 5 6 | f(x) = 3x^2 + 2x + 1 df(x) = gradient(f, x)[1] # 一階微分 df/dx = 6x + 2 d2f(x) = gradient(df, x)[1] # 二階微分 d²f/dx² = 6 println(df(2)) # > 14 println(d2f(2)) # > 6 |
もちろん、多変数関数の微分もできますし、一度にまとめて計算することもできます。
1 2 3 4 5 | f(x, y) = sum((x .- y).^2) # f(x,y) = ∑(x-y)² println(gradient(f, [2, 1], [2, 0])) # df(2, 1) & df(2, 0) # > ([0, 2], [0, -2]) |
ただ、機械学習でのパラメータ数は、「何百・何千・何万」という単位ですので、いちいち計算してられませんね…。
一方の Flux では、パラメータを一つにまとめることができるので、手間が省けるのです。
1 2 3 4 5 6 7 8 9 | x = [2, 1] y = [2, 0] gs = gradient(params(x, y)) do f(x, y) end println(gs[x]) # > [0, 2] println(gs[y]) # > [0, -2] |
単純なモデルで試してみる
それでは、少し機械学習寄りのコードも書いてみましょう!
線分回帰モデルを試す
ここでは、シンプルな「線形回帰モデル」を定義していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | W = rand(2, 5) # 重み b = rand(2) # バイアス predict(x) = W*x .+ b function loss(x, y) ŷ = predict(x) sum((y .- ŷ).^2) # 二乗誤差 (Juliaでは最後の結果がreturnされる) end x, y = rand(5), rand(2) # 適当なデータ println("x = $(x)") println("y = $(y)") println("ŷ = $(predict(x))") println("loss = $(loss(x, y))") |
1 2 3 4 5 | # 出力例 x = [0.6147959006414276, 0.07791447535736151, 0.28634504031397356, 0.7806187614798725, 0.06985734225178786] y = [0.7047761745357362, 0.1583882051433998] ŷ = [1.6040926838038974, 1.2723395138879994] loss = 2.0496577020960767 |
上のコードを見ると、 .+ や .- という表記が気になるかもしれません。
これは、加減演算子が関数として定義されているためで、配列データなどを繰り返し計算するために、ドット . をつけています。
今はまだ、ランダムで初期化された「重み」と「バイアス」なので、誤差がかなり大きいですね…。
勾配降下法を実装する
誤差が大きいので、勾配を計算して、「勾配降下法」を実装してみます。
1 | gs = gradient(() -> loss(x, y), params(W, b)) |
この勾配の計算は、以下のような書き方でも、同じ意味になります。
1 2 3 | gs = gradient(params(W, b)) do loss(x, y) end |
次は、勾配降下法で、一度だけ重みを更新してみましょう!
1 2 3 4 | W̄ = gs[W] # Wについて勾配を計算 W .-= 0.1 .* W̄ # w ← w - η∇w println(loss(x, y)) |
1 2 | # 出力例 1.2596519626536098 |
しっかりと、誤差が小さくなっていますね!
コード量としては、かなり少ないのにもかかわらず、簡単に勾配計算ができてしまいました。
この線形回帰モデルのコードは、以下のとおり、たったこれだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using Flux W = rand(2, 5) # 重み b = rand(2) # バイアス predict(x) = W*x .+ b function loss(x, y) ŷ = predict(x) sum((y .- ŷ).^2) # 二乗誤差 (Juliaでは最後の結果がreturnされる) end x, y = rand(5), rand(2) # 適当なデータ # 勾配計算 gs = gradient(() -> loss(x, y), params(W, b)) # 勾配降下法 W̄ = gs[W] # Wについて勾配を計算 W .-= 0.1 .* W̄ # w ← w - η∇w |
とてもコンパクトですね!
層を定義してみる
機械学習といえば、ニューラルネットワークで、多層にしたモデルが一般的です。
それを、Flux で単純に実装していきましょう!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 2層構造のシンプルな全結合ニューラルネットワーク # In(5) - fc(3) - fc(2) W1 = rand(3, 5) b1 = rand(3) layer1(x) = W1 * x .+ b1 # Layer1の出力 W2 = rand(2, 3) b2 = rand(2) layer2(x) = W2 * x .+ b2 # Layer2の出力 model(x) = layer2(σ.(layer1(x))) # モデルの定義 (σはシグモイド関数) println(model(rand(5))) # > 例: [1.857204783239992, 1.8739117950968038] |
コード自体は、とてもシンプルで、実際に適切に動作します。
ただ、もし多層にしたくなったとき、少し面倒ですね…
これを回避するために、一つのアイデアとして、以下のように関数で全結合層を定義すると良いでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # 2層構造のシンプルな全結合ニューラルネットワーク # In(5) - fc(3) - fc(2) function linear(in, out) W = randn(out, in) b = randn(out) x -> W * x .+ b # xを引数とする無名関数を返す end linear1 = linear(5, 3) linear2 = linear(3, 2) model(x) = linear2(σ.(linear1(x))) println(model(rand(5))) println(linear1.W) # のようにパラメータもアクセス可能 |
かなりシンプルで、可読性に長けた形になりました!
ちなみFlux では、 Dense() という名前で、すでに全結合層が用意されています。
層を積み上げてみる
それでは、Flux に用意されている便利な機能を存分に使って、ネットワークを構築してみます。
例えば、3層のニューラルネットワークであれば、以下のコードだけでOKです。
1 2 3 4 5 6 | model2 = Chain( Dense(10, 5, σ), Dense(5, 2), softmax) println(model2(rand(10))) # > 例: Float32[0.7592539, 0.24074602] |
Flux では、モデルを単なる関数として扱える点が、大きな特徴です。
PyTorch なんかもそうですが、「パラメータアクセスができる関数」といったところでしょうか。
さいごに
今回は、Juila の機械学習フレームワーク Flux について、簡単に紹介しました。
「何かしらデータセットを学習させて…」といったことはしませんでしたが、Flux の使い勝手の良さが、少なからず伝わったかと思います。
ちなみに、公式ドキュメントでは、他にも充実した実装サンプルが掲載されています。
もし、興味を持った方は、ぜひ試してみてくださいね!
【 Flux 公式サイト】
https://fluxml.ai/Flux.jl/stable/
さて、今回で「高速な動的型付け言語 Julia に入門する」シリーズは終わりになります。
今後また、応用編として、Julia の記事を書くかもしれません。
その時をお楽しみに!
こちらの記事もオススメ!
書いた人はこんな人

- 「好きを仕事にするエンジニア集団」の(株)ライトコードです!
ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。
システム開発依頼・お見積もり大歓迎!
また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。
以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit
ライトコードの日常12月 1, 2023ライトコードクエスト〜東京オフィス歴史編〜
ITエンタメ10月 13, 2023Netflixの成功はレコメンドエンジン?
ライトコードの日常8月 30, 2023退職者の最終出社日に密着してみた!
ITエンタメ8月 3, 2023世界初の量産型ポータブルコンピュータを開発したのに倒産!?アダム・オズボーン