我在閱讀perceptrons並試圖在haskell中實現一個。算法似乎正在工作,只要我可以測試。我將在某個時候完全重寫代碼,但在此之前,我想提出一些在編寫代碼時出現的問題。與Haskell的行爲不一致
當返回完整的神經元時,可以訓練神經元。 let neuron = train set [1,1]
的作品,但如果我改變火車功能返回一個不完整的神經元沒有輸入,或嘗試模式匹配,並只創建一個不完整的神經元,代碼將陷入無休止的循環。
tl; dr當返回完整的神經元時一切正常,但當返回可咖啡神經元時,代碼會陷入循環。
module Main where
import System.Random
type Inputs = [Float]
type Weights = [Float]
type Threshold = Float
type Output = Float
type Trainingset = [(Inputs, Output)]
data Neuron = Neuron Threshold Weights Inputs deriving Show
output :: Neuron -> Output
output (Neuron threshold weights inputs) =
if total >= threshold then 1 else 0
where total = sum $ zipWith (*) weights inputs
rate :: Float -> Float -> Float
rate t o = 0.1 * (t - o)
newweight :: Float -> Float -> Weights -> Inputs -> Weights
newweight t o weight input = zipWith nw weight input
where nw w x = w + (rate t o) * x
learn :: Neuron -> Float -> Neuron
learn [email protected](Neuron tr w i) t =
let o = output on
in Neuron tr (newweight t o w i) i
converged :: (Inputs -> Neuron) -> Trainingset -> Bool
converged n set = not $ any (\(i,o) -> output (n i) /= o) set
train :: Weights -> Trainingset -> Neuron
train w s = train' s (Neuron 1 w)
train' :: Trainingset -> (Inputs -> Neuron) -> Neuron
train' s n | not $ converged n set
= let (Neuron t w i) = train'' s n
in train' s (Neuron t w)
| otherwise = n $ fst $ head s
train'' :: Trainingset -> (Inputs -> Neuron) -> Neuron
train'' ((a,b):[]) n = learn (n a) b
train'' ((a,b):xs) n = let
(Neuron t w i) = learn (n a) b
in
train'' xs (Neuron t w)
set :: Trainingset
set = [
([1,0], 0),
([1,1], 1),
([0,1], 0),
([0,0], 0)
]
randomWeights :: Int -> IO [Float]
randomWeights n =
do
g <- newStdGen
return $ take n $ randomRs (-1, 1) g
main = do
w <- randomWeights 2
let (Neuron t w i) = train w set
print $ output $ (Neuron t w [1,1])
return()
編輯:根據意見,指定多一點。
與上面的代碼運行,我得到: perceptron: <<loop>>
但通過編輯的主要方法:
main = do
w <- randomWeights 2
let neuron = train w set
print $ neuron
return()
(注意let neuron
和打印行),一切正常,輸出爲:
Neuron 1.0 [0.71345896,0.33792675] [1.0,0.0]
1)「變更時無限循環」和「不一致行爲」是什麼? 2)你是否可以減少(或者至少評論)你的例子,以隔離令你困惑的小部分,如果你確實有人更有可能迴應並且正確地解決你在迴應中的困惑。 – 2010-07-22 20:43:32
這會很方便地顯示你所期望的代碼,以及做你不期望的改變。 – intoverflow 2010-07-22 21:58:26
這個問題不是用w來重新綁定w嗎? 「讓a = a;打印一個」總是會成爲一個無限循環。 – jrockway 2010-07-23 05:37:52