haskell

haskellでtensorflowを使う 2 〜 variable

かきかけの記事

haskellとpythonでtensorflowを使って同じことをするコードを書いて比較します。前回の記事はこちら

基本的にこのブログのサンプルコードを勝手に写経しているだけです。

前回はconstantとplaceholderを使った単純な計算を書きました。今回はvariableを使って単純な線形モデルを書いてみます。それにしてもhaskellのtensoflowのimportを書くのが大変すぎる。別のモジュールで同じ関数エクスポートしてるし。何か理由があるのだろうか…

variable

python

# python
import tensorflow as tf

w = tf.Variable([3], dtype=tf.float32)
b = tf.Variable([1], dtype=tf.float32)
x = tf.placeholder(dtype=tf.float32)
linear = w * x + b

y = tf.placeholder(dtype=tf.float32)
squared_deltas = tf.square(linear - y)
loss = tf.reduce_sum(squared_deltas)

train = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  for i in range(1000):
    sess.run(train, {x:[1,2,3,4], y:[4,9,14,19]})
  print(sess.run([w,b]))

'''output:
[array([ 4.99999475], dtype=float32), array([-0.99998516], dtype=float32)]
'''

haskell

{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Control.Monad (replicateM_)
import Data.Vector (Vector)
import qualified Data.Vector as V
import qualified TensorFlow.Core as TF
import qualified TensorFlow.GenOps.Core as TF hiding (placeholder)
import qualified TensorFlow.Ops as TF hiding (initializedVariable)
import qualified TensorFlow.Variable as TF
import qualified TensorFlow.Session as TF
import qualified TensorFlow.Minimize as TF

runVariable :: Vector Float -> Vector Float -> IO (Float, Float)
runVariable xIn yIn = TF.runSession $ do
    let xSize = fromIntegral $ V.length xIn
        ySize = fromIntegral $ V.length yIn
    (w :: TF.Variable Float) <- TF.initializedVariable 3
    (b :: TF.Variable Float) <- TF.initializedVariable 1
    (x :: TF.Tensor TF.Value Float) <- TF.placeholder [xSize]
    let linearModel = ((TF.readValue w) `TF.mul` x) `TF.add` (TF.readValue b)
    (y :: TF.Tensor TF.Value Float) <- TF.placeholder [ySize]
    let loss = TF.reduceSum $ TF.square (linearModel `TF.sub` y)
    trainStep <- TF.minimizeWith (TF.gradientDescent 0.01) loss [w,b]
    let trainWithFeeds = \xF yF -> TF.runWithFeeds
            [ TF.feed x xF
            , TF.feed y yF
            ]
            trainStep
    replicateM_ 1000
        (trainWithFeeds (TF.encodeTensorData [xSize] xIn) (TF.encodeTensorData [ySize] yIn))
    (TF.Scalar w_learned, TF.Scalar b_learned) <- TF.run (TF.readValue w, TF.readValue b)
    return (w_learned, b_learned)

main :: IO ()
main = do
    res <- runVariable [1.0, 2.0, 3.0, 4.0] [4.0, 9.0, 14.0, 19.0]
    print res

{- output:
(4.9999948,-0.99998516)
-}

コメントを残す

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