読者です 読者をやめる 読者になる 読者になる

お布団宇宙ねこ

Haskell ねこ

Haskell で『ゼロから作るDeep Learning』(3)

Deep Learning Haskell 読書メモ

『ゼロから作るDeep Learning – Pythonで学ぶディープラーニングの理論と実装』 の読書メモです。

今回は 「4.5.1 2層ニューラルネットワークのクラス」の手前まで。

4章 ニューラルネットワークの学習

学習

  • この章でいう学習とは、訓練データから最適なパラメータの値を自動で獲得すること
  • 機械学習ニューラルネットワーク(ディープラーニング)は、人の介入を極力避けてデータからパターンを見つけ出すことができる
    • 例えば、ゼロから数値を認識するアルゴリズムを考える代わりに、画像から特徴のパターンを機械学習で学習させる
    • この特徴のことを 特徴量 といい、有名なものとしては SIFT 、 SURF 、 HOG などが挙げられる
      • ただし、解く問題に応じた特徴量の設計が必要になることも
    • 機械学習の識別器として有名なのは SVM や KNN など
  • 一方で、ニューラルネットワークによる学習では、機械学習に必要な特徴量の設計は不要

訓練データとテストデータ

  • 訓練データ: 学習を行い、最適なパラメータを探索するのに使う
    • 教師データとも呼ばれる
  • テストデータ: 訓練データにより学習を行ったモデルの汎化能力を評価するのに使う
    • 訓練データには含まれていないデータで評価する
  • あるデータセットにだけ過度に対応した状態を 過学習 という

損失関数

  • ニューラルネットワークの学習では、指標(基準)を設け、それを手がかりに最適な重みパラメータを探す。この指標のことを 損失関数 と呼ぶ
  • 損失関数は、モデルがどれだけ訓練データに適合していないかというモデルの性能の悪さを示す指標である
  • 損失関数として有名なのは、 2乗和誤差交差エントロピー誤差
  • 損失関数はすべての訓練データを対象として求めるのが理想だが、データ量が膨大であるときは一部データを全体の近似として対象とする。このような学習手法を ミニバッチ学習 という
  • 認識精度を指標としないのは、パラメータの微分がほとんどの場所で 0 になるため
    • ある瞬間だけ変化するのではなく連続的に変化する指標が必要
    • 活性化関数を例に挙げると、シグモイド関数微分がそれにあたる

勾配

  • 勾配: すべての変数の偏微分をベクトルとしてまとめたもの
  • 勾配の結果にマイナスを付けて描画したとき、勾配の示す方向は各場所において関数の値を最も減らす方向となる
  • 勾配は損失関数が最小値を取る場所を探索するための手がかりとなる
    • 勾配はあくまで関数の値を最も減らす方向を示すだけであり、その方向が最小値を取るとは限らない(極小値や鞍点の可能性もある)
  • 勾配方向へ一定距離進むことを繰り返して関数の値を減らしていく手法を 勾配法 と呼ぶ
    • 厳密には最小値を探す場合を 勾配降下法 、最大値を探す場合を 勾配上昇法 という

ニューラルネットワークの学習

  • ニューラルネットワークの学習は 1.ミニバッチ学習 -> 2.勾配の算出 -> 3.パラメータの更新 -> 4. 1,2,3 の繰り返し という手順で行う
  • 上記手順は、無作為に選定したデータを用いていることから 確率的勾配降下法 (SGD) と呼ばれる

実践編

今回は無し

『デザインパターンとともに学ぶオブジェクト指向のこころ』を読んだ

読書メモ

デザインパターンとともに学ぶオブジェクト指向のこころ (Software patterns series)

デザインパターンとともに学ぶオブジェクト指向のこころ (Software patterns series)

なぜ読んだのか

最近、仕事でコードレビューを受けたときに「このコードはオブジェクト指向でないのでは? なんか関数型っぽい」と言われたことで Static おじさん?化の兆候に気がつき、なんとかせねばと思ったのがきっかけでした。

そもそも、何気なく触れていたであろうオブジェクト指向って一体何なんだっけという疑問を改めて解消するために読み始めました。

本書を選んだのは、チームメンバーがおすすめしていた本から選びました。 (教えていただきありがとうございました :pray: )

感想

オブジェクト指向について、本書では次のように説明しています。

オブジェクト指向は、オブジェクトという概念を中心に捉えたものの考え方です。このため、オブジェクトという観点からすべてのものごとを見ることになります。つまり、問題領域を機能に分解していくのではなく、オブジェクトに分解していくわけです。

– 1.6 オブジェクト指向パラダイム

また、オブジェクトについては

概念上の観点に基づいた場合、オブジェクトは責務を備えた実体であると定義できます。こういった責務によって、オブジェクトの振る舞いが定義されるのです。また、場合によっては、オブジェクトは特定の振る舞いを保持した実体であるとも考えられます。

– 8.2 オブジェクト : 従来からの考え方と新たな考え方

私は問題領域に存在するものを核に、その問題領域に存在する要求をメソッドとして肉付けしたものをオブジェクトとし、それらを扱うことをオブジェクト指向だと教わってきました。しかし、そのようなテクニックではすぐに設計が複雑化してしまい、変化に対応することが困難になることを指摘しています。オブジェクトをただの再利用可能な汎用モジュールとして定義するだけでは足りないというわけです。

本書は、変化に対応できるような柔軟な設計にするための道具として「共通性/可変性分析」や「デザインパターン」を用いた設計アプローチについての説明が主ですが、その説明を通してどのようにオブジェクト指向という考え方が使われているのかを知ることができました。また、デザインパターンの使い所についても、デザインパターンを適用するだけですべての問題が解決できるわけではないので、解決しようとしている問題に集中することが重要というのはなるほどなあという感じでした。デザインパターンはある問題に対する解決策の一例として見るべきだったのですね。

まとめ

一番の収穫は、今までの自分のオブジェクト指向の理解では不十分だったことを知れたことでした。旧来の考え方が間違っていたというよりも、問題に取り組むための視点を変えることでより柔軟な設計をすることができるという本書の説明の仕方にしている点も良かったです。

また、今までデザインパターンの本を読んできて腑に落ちていなかった点も、解決しようとしている問題についての比重が少なくデザインパターンを使う上での When , Why が曖昧だったのが原因なのかなと思ったのでした。このような視点を意識しつつ他の本ももう一度読み直してみたいです。

Haskell で『ゼロから作るDeep Learning』(2)

Deep Learning Haskell 読書メモ

『ゼロから作るDeep Learning – Pythonで学ぶディープラーニングの理論と実装』 の読書メモです。

今回は 「3.6 手書き数字認識」の手前まで。

3章 ニューラルネットワーク

ニューラルネットワークとは

  • パーセプトロンでは人力で重みを決めていくのに対して、ニューラルネットワークは適切な重みを自動で学習できる
  • ニューラルネットワークは入力層、中間層(隠れ層)、出力層で構成される
  • 前章の ニューロンは受け取った信号の総和を計算し、それがある値を超えたときのみに 1 を出力する というような動作は関数で表すことができる。このような関数を「活性化関数」と呼ぶ
  • 出力層では、重み付き入力信号とバイアスの総和を計算し、それを活性化関数に渡した結果が出力される

活性化関数

  • 前章のパーセプトロンで使われていた、閾値を境にして出力が切り替わる関数を「ステップ関数(階段関数)」と呼ばれる
  • 活性化関数としてステップ関数以外の関数を使うことでパーセプトロンからニューラルネットワークの世界へ進むことができる
  • ニューラルネットワークでよく使われる活性化関数として「シグモイド関数」と呼ばれる関数がある
  • ステップ関数とシグモイド関数にはいくつか共通点がある
    • 入力信号の重要度に応じて、重要であれば大きな値を、逆に重要でなければ小さな値を出力する
    • 出力信号の値は 0 から 1 の間
    • 非線形関数である
      • 何か入力に対して、出力が入力の定数倍になるような関数を線形関数と呼ぶので、そうではない関数のこと
  • 最近は ReLU 関数というのも使われる
    • 入力が 0 を超えるとその入力をそのまま出力し、 0 以下なら 0 を出力する関数

出力層の設計

  • ニューラルネットワークの出力層の活性化関数は、問題の種類によって変更する必要がある
    • 回帰問題なら恒等関数、分類問題ならソフトマックス関数
  • ソフトマックス関数の出力の総和は 1 になる(もちろん各出力は 0 から 1.0 の実数の間に収まる)
    • この性質のおかげでこの出力を確率として解釈することができる
    • 確率として解釈できるから分類問題に適している
    • しかし、各要素の大小関係はこの関数を適用しても変わらないので、推論(分類)のフェーズでは省略されるのが一般的
  • 出力層のニューロンの数は解く問題に応じて決める必要がある
    • たとえば、手描きの画像が数字の 0 から 9 のどれか当てる問題なら、ニューロンの数を 10 個に設定する

実践編

行列の計算をやってみる

hmatrix ライブラリを使うことでベクトルや行列の計算ができるようになります。 以下は書籍で使われている PythonNumPy ライブラリとの比較です。

行列の生成

// Python
import numpy as np
A = np.array([1,2],[3,4])
B = np.array([5,6],[7,8])

// Haskell
// `R` は `Double` の型シノニムです。
import Numeric.LinearAlgebra
let a = (2><2) [1,2,3,4] :: Matrix R
let b = (2><2) [5,6,7,8] :: Matrix R

行列の次元数

// Python
A.shape

// Haskell
size a

行列の積

// Python
np.dot(A,B)

// Haskell
a <> b

例として、書籍 p.57 のニュートラルネットワークの内積を hmatrix を使って計算してみます。

*Main Numeric.LinearAlgebra> let x = (1><2) [1,2] :: Matrix R
*Main Numeric.LinearAlgebra> size x
(1,2)
*Main Numeric.LinearAlgebra> let w = (2><3) [1,3,5,2,4,6] :: Matrix R
*Main Numeric.LinearAlgebra> print w
(2><3)
 [ 1.0, 3.0, 5.0
 , 2.0, 4.0, 6.0 ]
*Main Numeric.LinearAlgebra> size w
(2,3)
*Main Numeric.LinearAlgebra> let y = x <> w
*Main Numeric.LinearAlgebra> print y
(1><3)
 [ 5.0, 11.0, 17.0 ]

活性化関数のグラフを描画してみる

グラフ描画には今回 Chart というライブラリを使いました。実際にコードを書くときにはパッケージのドキュメントを見ても使い方がよくわからなかったので、こちらの Wiki を見ながらやりました。

そして、書いたコードから出力されたグラフが以下。

f:id:ku00:20170225112708p:plain

参考文献

書いたコード

GitHub - ku00/deep-learning-practice

Haskell で『ゼロから作るDeep Learning』(1)

Haskell Deep Learning 読書メモ

『ゼロから作るDeep Learning – Pythonで学ぶディープラーニングの理論と実装』の読書メモです。

www.oreilly.co.jp

この書籍のサンプルプログラムは Python で書かれていますが、表題の通り自分は Haskell で書いていきます。

今回は、2章全部です。

2章 パーセプトロン

パーセプトロンとは

  • パーセプトロンとは、複数の信号を受け取ってひとつの信号を出力するアルゴリズムのこと
  • 信号を入出力するものを「ニューロン」や「ノード」と呼ぶ
  • 入力信号が送られるときには重みが乗算される
    • 入力(x) -> 重み(w) -> 出力(y)
  • ニューロンは受け取った信号の総和を計算し、それがある値を超えたときのみに 1 を出力する
    • そのある値を「閾値」と呼ぶ
    • 閾値を超えて 1 を出力することを「ニューロンが発火する」と表現することもある

論理回路パーセプトロンで表現する

  • 論理回路 AND・NAND・OR はパーセプトロンを使って表現することができる
  • 信号の総和の計算に「バイアス」を加えることで、ニューロンの発火のしやすさを調整できる
    • 重みはその信号の重要度を調整するために使う
    • 両者をまとめて「重み」と呼ぶこともある
  • 論理回路 XOR は AND などと同じような構造のパーセプトロンでは表現できない
    • 2次元グラフに描画したときに、出力する値の境界を1本の直線で分けることができない
  • XOR はパーセプトロンの層を重ねることで表現できる

参考文献

書いたコード

今回は、論理回路(AND・NAND・OR・XOR)を hmatrix というライブラリを使って実装しました。

deep-learning-practice/Gate.hs at master · ku00/deep-learning-practice · GitHub

2016年振り返り

2016年をざっくり振り返ります。

仕事

今年は個人的に下半期の密度が高かったように感じました。

下半期は おいちゃん(@inouetakuya) と二人三脚で頑張りつつ、11月頃には ペパカレ のメンター的な役割もこなしたりいろいろやっていました。

周りに支えてもらいながらガシガシ開発した結果、いい感じの Gem も作ることができました。

github.com

やってる様子は下記のインタビュー記事でも確認できますので是非。

employment.en-japan.com

プライベート

イベント

去年は3つほどしか行ってませんでしたが、今年は毎月何かしらのイベントに行っていました。

原因は μ's ファイナルライブによる μ's ロスだったのだと思います。 (9人全員のイベントに参加することができたのは本当に運が良かった...)

来年も9人全員のイベントに顔を出せるかは分かりませんが運とお金があるうちは追い続けていきたいですね。

以下参加したイベントです。

Haskell

上半期で すごいHaskellたのしく学ぼう! を読了して(遅い)、下半期は AOJ を Haskell で解くなどしてました。

Haskell と少しは仲良くなれた気がしますがまだ実用レベルには達してないので、来年はその辺りを視野に入れて勉強していきたいです。

AOJ で解いた問題のコード

github.com

AOJ を解いたときのブログ

ku00.hatenablog.com

その他

  • 数年ぶりにウォークマンを購入
  • スクフェスAC で人生初のアーケード体験
    • まだ12回くらいしかやってないけど EXTREME フルコンできそう
  • スクフェスで Rank 300
    • 始めたのがラブライブ!のアニメ1期の放送終了後くらいだったのでだいたい3年半くらいやってる
    • 動体視力はだいぶ鍛えられた

f:id:ku00:20161231195216p:plain

来年の抱負

Gem を作ったことで Ruby という言語に対する意識もだいぶ変わってきてより深く知ろうとする意欲が湧いたので、やっぱりアウトプットは大事だなと実感しつつこういった活動は継続していきたいと思いました。

Haskell は実用レベルで何か作って、最終的に仕事に組み込めるように頑張ります 💪

そんな感じで来年もバーンとやってこ。

「久保ユリカ クリスマスイベント2016」に行ってきた

イベント 声優 久保ユリカ

久保ユリカ クリスマスイベント2016」の昼の部に行ってきました。久保ユリカさんのイベントは今回が初めてでした。会場はいつもの EX THEATER ROPPONGI 。

クリスマス仕様に装飾された部屋のセットと共に adidas のジャージ姿の久保さんが現れたときは「あ、これ自分の好きなグタグタやるゆるい感じのイベントだ...!」と確信したのでした。ジャージは黒か赤で迷ってそうですが、赤だと某ラジオ番組と勘違いする人がいるだろうからと黒にしたそうです。

一人でドレミの歌にのせて音程を合わせるゲームから始まり、一人チェキ撮影、絵描きコーナー、カラオケコーナー、一人黒ひげ危機一髪、など非常に久保さんらしい内容でした。今振り返るとあれはほぼ胃痛ラジオだったのでは...?

カラオケコーナーでは久保さんの歌いたい曲を1番だけ歌いまくるという主旨のものだったのですが、ファイナルライブぶりの「SUNNY DAY SONG」や「Snow halation」が聴けたので本当にありがとうございましたという感想しかなかったです。

最後のライブコーナーでは、 3rd シングルの「ありがとうの時間」と「Happy Cuty My Snow Man」の2曲を披露してくれました。久保さんソロの生歌を聴けたこともそうですし、シングルの中で一番好きな「ありがとうの時間」を生で聴けてよかったです。

ファーストアルバムの発売も決定したみたいですし、今後もいろいろな久保ユリカさんの歌声を聴けるのが楽しみです。

(そういえば絵描きコーナーで久保さんが描いていた三森すずこさんの似顔絵はいつ掲示されるんですかね?)


【久保ユリカ】「ありがとうの時間」MV short ver.


【久保ユリカ】3rdシングル c/w 「Happy Cuty My Snow Man」 試聴動画

Stack を使って Scotty 入門してみた

Haskell Scotty Programming

Haskell の Web フレームワークである Scotty を触ってみました。

Yesod で使えるなら Scotty でも同じようにできるだろうと思って今回も Stack を使ってみました。

Hello World 的なものを表示するまで

プロジェクトを新規作成してから setup までやっておきます。

stack new hello-scotty
cd hello-scotty
stack setup

次に、依存ライブラリとして Scotty を cabal ファイルに追記します。

executable hello-scotty-exe の段落に追記するのがポイントです。

( library ではありません)

hello-scotty.cabal

...

executable hello-scotty-exe
  hs-source-dirs:      app
  main-is:             Main.hs
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  build-depends:       base
                     , scotty
                     , hello-scotty
  default-language:    Haskell2010

...

そして stack build

$ stack build

ansi-terminal-0.6.2.3: configure
ansi-terminal-0.6.2.3: build
base-compat-0.9.1: configure
base-compat-0.9.1: build
auto-update-0.1.4: configure
auto-update-0.1.4: build
appar-0.1.4: configure
appar-0.1.4: build

...
Completed 67 action(s).

終わったら次は Scotty の README に載っているサンプルをそのままコピペしましょう。

Haskell のコードを試すときは src ディレクトリ以下にファイルを置いてそれを stack ghci で読み込むようにしてますが、今回はちゃんとしたアプリケーションなので app/Main.hs に書いていきます。

app/Main.hs

{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty

import Data.Monoid (mconcat)

main = scotty 3000 $ do
    get "/:word" $ do
        beam <- param "word"
        html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]

あとはサーバを起動するだけです。 stack exec で実行します。デフォルトだと [プロジェクト名]-exe が実行ファイル名になります。

$ stack exec hello-scotty-exe

Setting phasers to stun... (port 3000) (ctrl-c to quit)

見れました。

f:id:ku00:20170109113731p:plain

実はテンプレートがあった

Yesod のときは「テンプレート」というものを使って簡単にセットアップできたのですが、調べたら Scotty のものもあったという...。

(Yesod のは 公式のクイックスタート にも載っています )

github.com

使い方は簡単で、 stack new でプロジェクト名の後に使いたいテンプレート名を入れるだけです。

$ stack new template-hello-scotty scotty-hello-world

Downloading template "scotty-hello-world" to create project "template-hello-scotty" in template-hello-scotty/ ...
Looking for .cabal or package.yaml files to use to init the project.
Using cabal packages:
- template-hello-scotty/template-hello-scotty.cabal
...

生成されたファイルも最低限という印象。

f:id:ku00:20170109113735p:plain

まとめ

Stack を使うと一通りのことをやってくれるので本当に便利ですね。また、 Yesod と比べると Scotty は依存ライブラリがそこまで多くないのでセットアップに時間がかからないです。

さて、次からは本格的なの作っていくぞ。

参考文献