Python中的一个简单的感知器

时间:2012-03-11 23:34:25

标签: python linear-regression perceptron

http://en.wikipedia.org/wiki/Perceptron#Example

我的问题是,当NAND只接受2个参数并返回1时,为什么每个向量中有3个输入值:

http://en.wikipedia.org/wiki/Sheffer_stroke#Definition

为方便起见粘贴代码:

th = 0.1
learning_rate = 0.1
weights = [0, 0, 0]
training_set = [((1, 0, 0), 1), ((1, 0, 1), 1), ((1, 1, 0), 1), ((1, 1, 1), 0)]

def sum_function(values):
    return sum(value * weights[index] for index, value in enumerate(values))

while True:
    print '-' * 60
    error_count = 0
    for input_vector, desired_output in training_set:
        print weights
        result = 1 if sum_function(input_vector) > th else 0
        error = desired_output - result
        if error != 0:
            error_count += 1
            for index, value in enumerate(input_vector):
                weights[index] += learning_rate * error * value
    if error_count == 0:
        break

4 个答案:

答案 0 :(得分:2)

这是因为你需要一个恒定输入的值。 - 也称为偏见。

如果你注意到你有三个权重,那么三元组中的第一个项目(似乎总是1)应该被视为“输入0”(偏见)。这是一个常数。

我建议您在youtube上查看这些视频:simple explanation of neural networks

希望这会有所帮助

答案 1 :(得分:1)

在这个问题中,我们正在尝试学习NAND功能。因此输入向量(a,b,a NAND b)所需输出是此输入组合是正确还是错误,即它是否是NAND功能的正确表示。

例如((1,1,1), 0)表示1 NAND 1 = 1错误,因此被归类为0(错误)。 ((1,1,0), 1)表示1 NAND 1 = 0是正确的,因此它被归类为1(正确)。

随着其他组合被添加为训练数据的一部分,分类器将学习NAND功能。以下是一些可以添加到训练数据中的元组。

((0,0,1),1)
((0,1,1),1)
((1,0,1),1)
((0,0,0),0)
((0,1,0),0)
((1,0,0),0)

答案 2 :(得分:0)

我的答案是Java,我刚刚进入Python,所以当我开始使用它时,我会更新这个答案。

boolean nand(boolean[] a) {
  boolean b = true
  if (a.length > 1) {
    b = a[0] && a[1];
    if (a.length > 2)
      for (int i = 2; i < a.length; i++)
        b &= a[i];
  }
  return !b;
}

用法(应该返回true):

nand(training_set[i][0]) == training_set[i][1]

修改

两年多以后,我回到这个问题添加到我的答案......

我在python中创建了一个迭代和递归的解决方案。我也尝试过递归编码高尔夫。我把它降到了106个字节。

实现

迭代

def nand(*a):
    if len(a) > 1:
        b = a[0] and a[1]
        if len(a) > 2:
            for i in range(2, len(a)):
                b = b and a[i]
        return not b
    return None

递归

def nand(*a):
    if len(a) < 2:
        return None
    elif len(a) == 2:
        return not (a[0] and a[1])
    else:
        return nand(*([a[0] and a[1]] + list(a[2:])))

递归(lambda)

nand=lambda*a:None if len(a)<2 else not(a[0]and a[1])if len(a)==2 else nand(*([a[0]and a[1]]+list(a[2:])))

结果

print nand(True,  True,  True)   #  ¬(1 ∧ 1 ∧ 1) == 0
print nand(True,  True,  False)  #  ¬(1 ∧ 1 ∧ 0) == 1
print nand(True,  False, True)   #  ¬(1 ∧ 0 ∧ 1) == 1
print nand(True,  False, False)  #  ¬(1 ∧ 0 ∧ 0) == 1
print nand(False, True,  True)   #  ¬(0 ∧ 1 ∧ 1) == 1
print nand(False, True,  False)  #  ¬(0 ∧ 1 ∧ 0) == 1
print nand(False, False, True)   #  ¬(0 ∧ 0 ∧ 1) == 1
print nand(False, False, False)  #  ¬(0 ∧ 0 ∧ 0) == 1

答案 3 :(得分:-1)

NAND可以根据您的需要采用尽可能多的参数。简单地将所有输入值放在一起并取消输出。

// 2 arguments
!(A & B)

// 3 arguments
!(A & B & C)

// n argument
!(A & B & ... & n)