FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

ゼロから作るDeep Learning ③ のPython実装をRubyで作り直してみる(ステップ1/ステップ2)

ゼロから作るDeep Learning ❸ ―フレームワーク編

ゼロから作るDeep Learning ❸ ―フレームワーク編

  • 作者:斎藤 康毅
  • 発売日: 2020/04/20
  • メディア: 単行本(ソフトカバー)

ゼロから作るDeep Learning ③を買った。昨年のQiitaでも自分でビルドシステムを作ってみた通り、こういうプラットフォームを作る話は大好きだ。さっそくステップ1から読み始めているが、ステップ60まであって非常に分厚いし、なかなか一気読みはつらい。

しかも実装が多分に含まれているので、これを理解しなければどうにも読破した気にはならない。かといってPythonを写経してもあまり面白くないので、似たような系統のスクリプトRubyを使ってプラットフォームを再実装することはできないだろうかと思いやってみることにした。

本書はPythonを使ってDezeroというオリジナルのディープラーニングフレームワークを実装している。これをRubyに移していくという訳だ。と言ってもPythonの大量のライブラリにはどうにも勝てそうにない気がするのだが、できるところまで頑張っていこう。

  • ステップ1:変数クラスの宣言

Dezeroの最初のステップではまず変数を格納するVariableクラスを作っている。これはRubyでも簡単だ。単純にVariableクラスを作って値を格納するためのdataメンバを追加した。

  • step01.rb
#!/usr/bin/env ruby

class Variable
  def initialize(data)
    @data = data
  end

  attr_accessor :data
end

テストを作って確認する。データを格納してそれを表示する。

data = [1.0]
x = Variable.new(data)
puts(x.data)

x.data = [2.0]
puts(x.data)
1.0
2.0

できた!まずは準備完了だ。

  • ステップ2:関数クラスの宣言

変数のためのVariableクラスができたら、次は関数のためのFunctionクラスを作る。Functionクラスをインスタンス化してできたオブジェクトは、A = Function()とかやるとA(x)でその関数を呼び出せるようになっているのだが、Rubyで同じことをする仕組みが分からない。仕方が無いのでcallメソッドを作って代用した。

  • step02.rb
class Function
  def call(input)
    x = input.data
    y = x.map{|i| i ** 2}
    output = Variable.new(y)
    return output
  end

  def forward(x)
    raise NotImplementedError
  end
end

上記の関数だと、A = Function.new()した後にA.call([2.0])として呼び出すことで関数を実行できる。

FunctionをオーバーライドしてSquareを作った。

class Square < Function
  def forward(x)
    return x.map{|i| i ** 2}
  end
end

これで関数呼び出しを行う。テストを作って実行した。

x = Variable.new([10])
f = Function.new()
y = f.call(x)
puts(y.class)
puts(y.data)

f2 = Square.new()
y2 = f2.call(x)
puts(y2.class)
puts(y2.data)
Variable
100
Variable
100

上手く行っている。