【问题标题】:A simple perceptron in PythonPython中的一个简单的感知器
【发布时间】:2012-03-28 10:27:18
【问题描述】:

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

【问题讨论】:

    标签: python linear-regression perceptron


    【解决方案1】:

    这是因为您需要一个常量输入值。 - 也称为偏差。

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

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

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      在这个问题中,我们正在尝试学习 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)
      

      【讨论】:

        【解决方案3】:

        我的答案是用 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
        

        【讨论】:

          【解决方案4】:

          NAND 可以接受任意数量的参数。只需将所有输入值与一起并否定输出。

          // 2 arguments
          !(A & B)
          
          // 3 arguments
          !(A & B & C)
          
          // n argument
          !(A & B & ... & n)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-08-22
            • 2014-08-09
            • 2018-07-05
            • 2019-09-28
            • 2021-04-07
            • 2021-03-11
            • 2013-08-20
            • 1970-01-01
            相关资源
            最近更新 更多