haskell

haskellでtensorflowを使う 1 〜 constant, placeholder

tensorflowのhaskell用バインディングのインストール方法は前の記事に書きました。githubにもあります。

ここでは、この英語のブログをほぼ丸パクリしてpythonとhaskellでそれぞれ同じコードを書いてみます。

constant

python

# python3, tensorflow1.2.1
import tensorflow as tf

a = tf.constant(3.0, dtype=tf.float32)
b = tf.constant(4.0, dtype=tf.float32)
sum_ = tf.add(a, b)

with tf.Session() as sess:
  print(sess.run(sum_))

'''output:
7.0
'''

haskell

-- ghc8.0.2, tensorflow1.3
{-# LANGUAGE OverloadedLists #-}
module Main where
import Data.Vector (Vector)
import qualified TensorFlow.Ops as TF --(constant, add)
import qualified TensorFlow.Session as TF --(runSession, run)

calc :: IO (Vector Float)
calc = TF.runSession $ do
    let a = TF.constant [1] [3 :: Float]
    let b = TF.constant [1] [4 :: Float]
    let sum_ = a `TF.add` b
    TF.run sum_

main :: IO ()
main = do
    print =<< calc

{- output:
[7.0]
-}

placeholder

python

import tensorflow as tf

x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
adderNode = tf.add(x, y)

with tf.Session() as sess:
  res1 = sess.run(adderNode, {x: 3, y: 4.5})
  res2 = sess.run(adderNode, {x: 2.7, y: 8.9})
  print(res1, res2)

'''output:
7.5 11.6
'''

haskell

{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Data.Vector (Vector)
import qualified Data.Vector as V
import qualified TensorFlow.Core as TF --(Tensor, Value, feed, encodeTensorData)
import qualified TensorFlow.Ops as TF --(constant, add, placeholder)
import qualified TensorFlow.Session as TF --(runSession, run, runWithFeeds)

runPH :: Vector Float -> Vector Float -> IO (Vector Float)
runPH in1 in2 = TF.runSession $ do
    (x :: TF.Tensor TF.Value Float) <- TF.placeholder [1]
    (y :: TF.Tensor TF.Value Float) <- TF.placeholder [1]
    let add_ = x `TF.add` y
        runStep = \xFeed yFeed -> TF.runWithFeeds
            [ TF.feed x xFeed
            , TF.feed y yFeed
            ]
            add_
    runStep (TF.encodeTensorData [1] in1) (TF.encodeTensorData [1] in2)

main :: IO ()
main = do
    res1 <- runPH [3.0] [4.5]
    res2 <- runPH [2.7] [8.9]
    print res1 V.++ res2

{- output:
[7.5,11.599999]
-}

まとめ

  • constantを使う場合はpythonと似ている書き方ができるので比較的わかりやすい。
  • placeholderを使うと、feedを与える計算を自分で定義する必要があるらしく(15〜19行目のrunStepの定義)、コードが複雑になる。
  • あとplaceholderを関数内で定義した場合の挙動もよくわからない。
  • haskellでtensorflowはめんどくさい... が、もう少し頑張る。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です