Perceptron

定义

为了理解神经网络,我们应该先理解神经网络的组成单元——神经元。神经元也叫做感知器。感知器算法在上个世纪50-70年代很流行,也成功解决了很多问题。并且,感知器算法也是非常简单的。
参考

  • 感知机的输入是多维样本:x_1,x_2,\dots,x_n
  • 样本的每一个维度对应一个权重:w_1,w_2,\dots,w_n
  • Perceptron对输入样本经过一次线性变化:y = w_1*x_2+w_2*x_2,\dots,w_n*x_n+b
    简记为:y=\sum_{i=1}^{n}{w_i*x_i}+b,其中b是一个偏置项常数。
  • 后再跟一次激非线性活函数:\sigma(y),其中\sigma(y)= \begin{cases}1 & y>0 \\ 0 & \text { otherwise }\end{cases}

代码

使用Perceptron模拟实现逻辑与和逻辑或

首先定义Perceptron类

from functools import reduce


class Perceptron:
    def __init__(self, input_dim, activator) -> None:
        """
        Initialize the perceptron, including the dimensions of input parameters and the activation function used
        """
        self.activator = activator
        # According to the number of input parameters, initialize the corresponding weight vector
        self.weights = [0.0 for _ in range(input_dim)]
        # initialize the corresponding bias
        self.bias = 0.0

    def __str__(self):
        """
        return the learned weights and bia to the sys.stdout
        """
        return f"weights:\t{self.weights}\nbias:\t{self.bias}"

    def train(self, input_values, labels, iterations, lr):
        """
        training the perceptron's weights and bias:
            need input_values(train_set), labels(groud_truth), iterations(epoch), lr(learning rate)
        """
        for i in range(iterations):
            print(f"EPOCH {i}")
            print(f"Before\t{str(self)}", end="\n")
            self._train_one_epoch(input_values, labels, lr)
            print(f"After\t{str(self)}")

    def _train_one_epoch(self, input_values, labels, lr):
        """
        All data is trained once and called an epoch.
        """
        for data, label in zip(input_values, labels):
            # Computes the output of an input sample given the current weights of the perceptron
            output = self.predict(data)
            # updates weights
            self._update_weights(data, label, output, lr)

    def predict(self, data):
        """
        Computes the perceptron's predict for the data.
        """
        return self.activator(
            reduce(lambda x, y: x + y, map(lambda a, b: a * b, self.weights, data))
            + self.bias
        )

    def _update_weights(self, data, label, output, lr):
        """
        update the weights and bias of perceptron according the target rule.
        """
        self.weights = list(
            map(lambda x, y: y + lr * (label - output) * x, data, self.weights)
        )
        self.bias += lr * (label - output)
  • 这里更新权重和偏置的过程按照如下规则(个人理解为机器学习的优化目标函数):
    w_i^{t+1} = w_i^{t} + \lambda\Delta w_i^{t}\\b^{t+1}=b^t+\Delta b^t
    \Delta w_i^t =(y-\hat{y}) x_i \\ \Delta b^t=(y-\hat{y})

定义训练过程

  • 这里使用符号函数作为激活函数
def sign(x):
    """
    Next, we use this perceptron class to implement the and function.
    """
    # define sign activate function
    return 1 if x > 0 else 0


def get_training_dataset():
    """
    construct training set based on 'and' oprands true table.
    """
    # datas = [[1, 1], [0, 0], [1, 0], [0, 1]]
    # labels = [1, 0, 0, 0]
    datas = [[1, 1], [0, 0], [1, 0], [0, 1]]
    labels = [1, 0, 1, 1]
    return datas, labels


def train_perceptron(iterations, lr):
    p = Perceptron(input_dim=2, activator=sign)
    p.train(*get_training_dataset(), iterations=iterations, lr=lr)
    return p

测试

if __name__ == "__main__":

    perceptron = train_perceptron(10, 0.1)
    # test and
    # print(f"1 and 1 ={perceptron .predict([1, 1])}")
    # print(f"0 and 0 ={perceptron .predict([0, 0])}")
    # print(f"1 and 0 = {perceptron .predict([1, 0])}")
    # print(f"0 and 1 = {perceptron .predict([0, 1])}")
    # test or
    print(f"1 and 1 ={perceptron .predict([1, 1])}")
    print(f"0 and 0 ={perceptron .predict([0, 0])}")
    print(f"1 and 0 = {perceptron .predict([1, 0])}")
    print(f"0 and 1 = {perceptron .predict([0, 1])}")
···

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容