你如何正确地实现和验证感知器和梯度下降,以学习Haskell中的基本布尔函数?

How do you properly implement and verify a perceptron & gradient descent to learn basic Boolean functions in Haskell?

提问人: 提问时间:4/25/2019 更新时间:4/26/2019 访问量:150

问:

我正在尝试在 Haskell 中构建一个感知器单元来学习布尔 And 和 Or 函数,就像 Mitchell 的书中一样。

我很确定我的梯度下降是正确的,但我正在努力验证它是否真的学习了 alrogithm。我有三个问题,张贴在下面的代码之间。

(i) 我的梯度下降实现是否正确?

(ii) 如果是这样,它是否使用了“最佳”权重?

(iii) 如何验证是否正确学习了权重。当您将布尔对代入书中给出的权重时,oor 和 aand 是值,但我认为 sgn 阈值会适用于这些值吗?如果这是正确的评估假设,那么 Mitchells 解决方案猜测相同的 和 和 或函数。我的学习/或函数(在 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 

来自米切尔:

[1]: https://i.stack.imgur.com/XVRAn.png

编辑: 接下来,假设我想复制新的布尔值和 Or 以获取布尔值输入的数据。替换以下代码,几何图片保持不变。(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
Haskell 机器学习 神经网络 布尔逻辑 感知器

评论


答:

0赞 Daniel Wagner 4/25/2019 #1

我怀疑书中有一个错别字: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

前两个验证了书籍重量的固定版本是否合适;后两者验证您通过梯度下降学到的权重是否合适。

评论

0赞 4/26/2019
假设我想复制布尔值输入上的 And 和 Or。几何图片保持不变。(w1 = w2 = 1/2,截距为原始值的 1/2)。但是,数据已经缩放(按 1/2)和按(按 (1/2,1/2))进行转换,我们现在学习了错误的函数。(cs.cmu.edu/~tom/10601_fall2012/hw/hw3_solutions.pdf)andData = map (1:) [[x,y] | x <- [0,1], y <- [0,1]] orOuts = [0,1,1,1] aand = map (dotProd [-1.5,1,1]) andDataandData = map (1:) [[x,y] | x <- [0,1], y <- [0,1]] andOuts = [0,0,0,1] oor = map (dotProd [-0.5,1,1]) andData