かきかけの記事
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)
-}