O'Reilly Japan - ゼロから作るDeep Learning P.58ページからを参考に、フォワード処理を実装。

utils.rb

require 'bundler'
Bundler.require

require 'pycall/import'
include PyCall::Import
pyimport 'numpy', as: :np

def identity_function(x)
  x 
end

def sigmoid(x)
  1 / (1 + np.exp.(-1 * x))
end

-xが以下のエラーで動かなかったので-1 * xにした。

~/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/pycall-0.1.0.alpha.20170317/lib/pycall/pyobject_wrapper.rb:174:in `method_missing': undefined method `-@' for array([ 0.3,  0.7,  1.1]):PyCall::PyObject (NoMethodError)
Did you mean?  -

neuralnet.rb

require 'bundler'
Bundler.require

require 'pycall/import'
include PyCall::Import
pyimport 'numpy', as: :np

require './utils'

def init_network
  network = {}
  network[:W1] = np.array.([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
  network[:b1] = np.array.([0.1, 0.2, 0.3])
  network[:W2] = np.array.([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
  network[:b2] = np.array.([0.1, 0.2])
  network[:W3] = np.array.([[0.1, 0.3], [0.2, 0.4]])
  network[:b3] = np.array.([0.1, 0.2])
  network
end

def forward(network, x)
  w1, w2, w3 = network[:W1], network[:W2], network[:W3]
  b1, b2, b3 = network[:b1], network[:b2], network[:b3]

  a1 = np.dot.(x, w1) + b1
  z1 = sigmoid(a1)
  a2 = np.dot.(z1, w2) + b2
  z2 = sigmoid(a2)
  a3 = np.dot.(z2, w3) + b3
  y = identity_function(a3)

  y
end

network = init_network
x = np.array.([1.0, 0.5])
y = forward(network, x)
p y # array([ 0.31682708,  0.69627909])

普通に動いて楽しい。

ソース

https://github.com/tnantoka/hello-pycall