我正在尝试在 Haskell 中构建一个感知器单元来学习 bool And 和 Or 函数,如 Mitchell 的书中所示。
我很确定我的梯度下降是正确的,但我正在努力验证它是否真正学习了算法。我有三个问题,发布在下面的代码之间。
(i) 我的梯度下降实现正确吗?
(ii) 如果是这样,它是否学习了“最佳”权重?
(iii) 如何验证权重是否正确学习。 oor 和 aand 是当您将 bool 对插入书中给出的权重时的值,但我认为 sgn 阈值将适用于这些值?如果这是正确的评估假设,那么米切尔解决方案会猜测相同的 and 和 or 函数。我学习的和和或函数(在ans1、ans2中评估)是否不正确?
import System.Random
-- for generating random initial weights
randomList :: Int -> [Double]
randomList seed = randoms (mkStdGen seed) :: [Double]
dotProd x y = foldr (+) 0 $ zipWith (*) x y
gdHelper [] _ del_w _ _ = del_w
gdHelper (x:xs) (t:ts) y@(weight:weights) w nu = gdHelper xs ts del_w w nu
where del_w = zipWith (+) y (map (*asdf) x)
asdf = nu * (t - o)
o = dotProd w x
gd _ _ _ w _ 0 = w
gd xs ts ws w nu n = gd xs ts [0,0,0] w2 nu (n-1)
where w2 = zipWith (+) w delW
delW = gdHelper xs ts ws w nu
-- initial weights
w = map (/20) $ take 3 $ randomList 30
trainingData = [([1,1],1),([1,-1],-1),([-1,1],-1),([-1,-1],-1)]
andData = map (1:) (map fst trainingData)
andOuts = map snd trainingData
orOuts = [1,1,1,-1]
gdand = gd andData andOuts [0,0,0] w 0.02 10000
gdor = gd andData orOuts [0,0,0] w 0.01 10000
ans1 = map (dotProd gdand) andData
ans2 = map (dotProd gdor) andData
-- trying to verify this from the book
aand = map (dotProd [-0.8,0.5,0.5]) andData
oor = map (dotProd [-0.3,0.5,0.5]) andData
来自米切尔:
编辑: 接下来,假设我想为 bool 值输入的数据复制新的 bool 值和或或。替换下面的代码,几何图保持不变。 (w1 = w2 = 1/2,截距为原始值的 1/2)。然而,由于数据已被缩放(按 1/2)和平移(按 (1/2,1/2)),并且我的算法现在学习了错误的函数。 `andData = map (1:) [[x,y] | x <- [0,1], y <- [0,1]]
andData = map (1:) [[x,y] | x <- [0,1], y <- [0,1]]
andOuts = [0,0,0,1]
orOuts = [0,1,1,1]
oor = map (dotProd [-0.5,1,1]) andData
aand = map (dotProd [-1.5,1,1]) andData
最佳答案
我怀疑书中有一个拼写错误:OR 的阈值应该是 0.3,而不是 -0.3。进行更改后,我通过以下方式验证感知器是否正确:
> map signum aand == andOuts
True
> map signum oor == orOuts
True
> map signum ans1 == andOuts
True
> map signum ans2 == orOuts
True
前两个验证固定版本的书的重量是否合适;后两者验证您通过梯度下降学到的权重是否合适。
关于haskell - 如何正确实现和验证感知器和梯度下降来学习 Haskell 中的基本 bool 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55838580/