专栏首页Python爬虫与数据分析入门机器学习(一)-----------------------感知器

入门机器学习(一)-----------------------感知器

一、什么是深度学习?

在人工智能领域,有一个方法叫机器学习。在机器学习方法中有一类算法叫神经网络:

如下图:

(神经元)

(神经元之间的连接)

Layer L1 : 输入层 Layer L2: 隐藏层

Layer L3: 输出层

图(一)中的每个圆圈都是一个神经元, 连接每个神经元之间的连线是神经元之间的连接。上面的神经元被分成了3层,层与层之间的神经元有连接, 而同一层之间的神经元是没有连接。最左边的(Layer L1)为输入层, 负责接收输入数据;中间的层也就(Layer L2)为隐藏层;最右边的的层(Layer L3)为输出层,可以从该层获取神经网络的输出数据。

输入层与输出层之间的都是隐藏层,层数(大于2)的神经网络叫深度神经网络。而深度学习,就是使用深层架构(深度神经网络)的机器学习方法。

深层网络与浅层网络之间的联系

深层网络在表达上要直观明了一些。只有一个隐藏层的神经网络也能拟合函数,但是在这一个隐藏层中就需要很多的神经元才能将所要表达的展示出来。而深层网络可以用很少的神经元(相对单隐层)就可以拟合同样的函数。所以在拟合函数的时候,就有单隐层(浅而宽)多隐层(深而窄)俩种方法来拟合了。但相对来说深层网络更节省资源,并且不容易训练,对于深层网络需要大量的数据,以及很多技巧才能训练出来一个较好的深层网络。

二、感知器(神经元)

感知器——神经网络的组成单元(神经元

感知器定义:

公式打不了,所以直接截图了,很尴尬了,)

例子:用感知器实现and函数

设计一个感知器,让它实现and运算。and是一个二元函数(带有两个参数X1和X2),真值表如下:

X1

X2

y

0

0

0

0

1

0

1

0

0

1

1

1

0 表示false, 1表示true。

令W1 = 0.5; W2=0.5;b = -0.8, 而激活函数 f 就是前面写出来的阶跃函数,此时的感知器就相当于and函数。

将上面的真值表代入公式(一),计算得出输出,可以验证第一行:

y = f(w*X + b)

= f(W1X1 + W2X2 + b)

= f(0.5*0+0.5*0-0.8)

=f(-0.8) =0

即当X1,X2都为0时,y为0。

例子:用感知器实现or函数

设计一个感知器,让它实现or运算。or是一个二元函数(带有两个参数X1和X2),真值表如下:

X1

X2

y

0

0

0

0

1

1

1

0

1

1

1

1

0 表示false, 1表示true。

令W1 = 0.5; W2=0.5;b = -0.3 可以验证第二行:

y = f(w*X + b)

= f(W1X1 + W2X2 + b)

= f(0.5*0+0.5*1-0.8)

=f(0.2) =1

即当X1=0, X2=1时,y为1。

三、感知器的其他应用

感知器不仅仅可以实现简单的不二运算,它还可以拟合线性函数,任何的线性分类线性回归问题都可以用感知器来解决。前面的布尔运算可以看作是二分类问题, 即给定一个输入,输出0(属于0这个类别)或输出1(属于1这个类别)。如下面所示,and运算是一个线性分类问题,即可以用一条直线把分类0(false,红叉表示)和分类1(true,绿点表示)分开。但是不可以进行异或运算。

四、感知器的训练

获得权重项和偏置项:

利用感知器训练算法:将权重项和偏置项初始化为0, 然后利用感知器规则迭代更新wi和b, 直到训练完成。

其中

wi是输入xi对应的权重项,b是偏置项(可以把b看作是值永远为1的输入xb所对应的权重),t是样本的实际值,一般为label, 而y是感知器的输出值,他是有公式1计算出来的。yita是学习率,控制每一步权重的更新幅度(或者说是步长)。

每次从训练数据中取出一个样本的输入向量X, 使用感知器计算其输出y, 在根据感知器规则来进行多次的迭代更新,得到最终的权重。

最后上代码:

感知器类:

# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time    : 2019/4/25 15:57
# @Author  : xhh
# @Desc    : 机器学习入门--感知器(cell)
# @File    : test_perceptorn.py
# @Software: PyCharm
from __future__ import print_function
from functools import reduce

class VectorOp(object):
    """
    实现向量计算操作
    """
    @staticmethod
    def dot(x, y):
        """
        计算两个向量的内积
        1、首先把x[x1, x2, x3...] 和y[y1, y2, y3...]按元素相乘
        2、变成[x1*y1, x2*y2,x3*y3]
        3、然后利用reduce求和
        :param y:
        :return:
        """
        return reduce(lambda a, b: a + b,VectorOp.element_multiply(x, y), 0.0)

    @staticmethod
    def element_multiply(x, y):
        """
        将两个向量x和y按元素相乘
        1、首先把x[x1, x2, x3...]和y[y1, y2, y3...]打包在一起
        2、变成[(x1,y1),(x2, y2),(x3,y3),...]
        3、然后利用map 函数计算[x1*y1, x2*y2, x3*y3]
        :param y:
        :return: 返回列表集合
        """
        return list(map(lambda x_y: x_y[0] * x_y[1], zip(x, y)))

    @staticmethod
    def element_add(x, y):
        """
        将两个向量x和y按元素相加
        1、首先把x[x1, x2, x3...]和y[y1, y2, y3...]打包在一起
        2、变成[(x1,y1),(x2, y2),(x3,y3),...]
        3、然后利用map 函数计算[x1+y1, x2+y2, x3+y3]
        :param y:
        :return: 返回一个列表
        """
        return list(map(lambda x_y: x_y[0] + x_y[1], zip(x, y)))

    @staticmethod
    def scala_multiply(v, s):
        """
        将向量v中的每个元素和标量s相乘
        :param s: 标量s
        :return: 返回map
        """
        return map(lambda e: e * s, v)

class Perceptron(object):
    def __init__(self, input_num, activator):
        """
        初始化感知器,设置输入参数的个数,以及激活函数。
        激活函数的类型为double —> double
        :param input_num:
        :param activator:
        """
        self.activator = activator
        # 设置权重向量初始化为0
        self.weights = [0.0]*input_num
        # 偏置项初始化为0
        self.bias = 0.0

    def __str__(self):
        """
        打印学习到的权重、偏置项
        :return:
        """
        return 'weight\t:%s\nbias\t:%f\n'%(self.weights, self.bias)

    def predict(self, input_vec):
        """
        输入向量,输出感知器的计算结果
        1、计算输入的向量input_vec[x1, x2, x3...]和权重weights[w1, w2, w3,...]的内积
        2、然后加上bias
        :param input_vec:
        :return:
        """
        return self.activator(
            VectorOp.dot(input_vec, self.weights)+self.bias)

    def train(self, input_vecs, labels, iteration, rate):
        """
        输入训练数据:一组向量、以及每个向量对应的label;以及训练数和学习率
        :param input_vecs: 输入的向量
        :param labels: 每个向量的标签
        :param iteration: 迭代次数
        :param rate: 学习率
        :return:
        """
        for i in range(iteration):
            self._one_iteration(input_vecs, labels, rate)

    def _one_iteration(self, input_vecs, labels, rate):
        """
        每迭代一次,把所有的训练数据过一遍
        1、把输入和输出打包在一起,生成样本列表[(input, label),...]
        2、而每个训练样本(samples)都是(input_vec, label)
        :param input_vecs: 输入向量
        :param labels: 向量对应的标签
        :param rate: 学习率
        :return:
        """
        samples = zip(input_vecs, labels)
        # 对每个样本,感知感知器的规则更新权重
        for (input_vec,label) in samples:
            # 计算感知器在当前权重下的输出
            output = self.predict(input_vec)
            # 更新权重
            self._update_weights(input_vec, output, label, rate)


    def _update_weights(self, input_vec, output, label, rate):
        """
        按照感知器规则更新权重
        1、首先计算本次更新的delta
        2、然后把input_vec[x1, x2, x3,...]向量中的每个值乘上delta
        3、最后再把权重更新按元素加到原先的weights[w1, w2, w3,...]上
        :param output: 输入向量
        :param label: 输出向量
        :param rate: 学习率
        :return:
        """
        delta = label - output
        self.weights = VectorOp.element_add(
            self.weights, VectorOp.scala_multiply(input_vec, rate * delta))
        # 更新bias
        self.bias += rate * delta

and函数的实现:

def f(x):
    """
    定义激活函数
    :param x:
    :return:
    """
    return 1 if x > 0 else 0

def get_training_dataset():
    """
    基于and真值表构建训练数据
    :return:
    """
    # 构建训练数据, 输入向量的列表
    input_vecs = [[1, 1],[0, 0], [1, 0], [0, 1]]
    # 期望的输出列表
    # [1, 1]—> 1, [0, 0] —>0, [1, 0] —>0, [0, 1] —>0
    labels = [1, 0, 0, 0]
    return input_vecs, labels

def train_and_perceptron():
    """
    使用and真值表训练感知器
    :return:
    """
    # 创建感知器,输入参数个数为2(and是一个二元函数),激活函数为f
    p = Perceptron(2, f)
    # 训练,迭代10轮, 学习速率为0.1
    input_vecs, labels =get_training_dataset()
    p.train(input_vecs, labels, 10, 0.1)
    # 返回训练好的感知器
    return p

测试写好的感知器:

if __name__ == '__main__':
    # 训练感知器
    and_perception = train_and_perceptron()
    # 打印训练获得权重
    print(and_perception)
    # 测试
    print('1 and 1 = %d' % and_perception.predict([1, 1]))
    print('0 and 0 = %d' % and_perception.predict([0, 0]))
    print('1 and 0 = %d' % and_perception.predict([1, 0]))
    print('0 and 1 = %d' % and_perception.predict([0, 1]))

运行结果:

到此,感知器就写完了,是参考别的来理解,学习的,把自己的学习过程记下来~~~~

大家可以关注我和我小伙伴的公众号~~~这里有我和我的小伙伴不定时的更新一些python技术资料哦!!大家也可以留言,讨论一下技术问题,希望大家多多支持,关注一下啦,谢谢大家啦~~

本文分享自微信公众号 - Python爬虫scrapy(python_scrapy),作者:疯子

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Scrapy爬取知乎------获取用户主页信息

    新建一个scrapy项目,scrapy startproject zhihuspider

    andrew_a
  • Scrapy爬取知乎------模拟登录

    从今天开始更新关于爬取知乎的一系列文章,最近一直在优化代码,奈何代理IP有用的都是要钱的,所以已经不知道怎么优化了,发出来大家也参考参考,顺便提点意见。

    andrew_a
  • 爬虫爬取智联招聘的职位信息(基础)

    简单爬取智联招聘的内容,爬之前在网上找关于这方面的代码,最后发现都不行,智联现在的招聘信息都是js加载,直接请求响应不到响应的内容,只能使用selenium,通...

    andrew_a
  • 课时39:类与对象:拾遗

    Python的特性其实还支持另外一种很流行的编程模式:Mixin.【扩展阅读】Mixin编程机制(https://fishc.com.cn/forum.php?...

    py3study
  • Python重启深信服设备

    为防止隧道检测脚本异常,另外编写监控监测脚本的脚本配合定时任务来定时监控,如果异常,重新拉起。

    KaliArch
  • Python面向对象基础

    当把number属性变成私有属性__number之后,无法直接访问得到,只能通过get_number和set_number两个函数访问__number属性。

    职场亮哥
  • Python【3】:格式化 输出 whi

    py3study
  • CSS检查工具-CKStyle

    HTML5学堂:CSS代码存在压缩工具、检查工具以及重排属性的工具。今天推荐给大家CKStyle这个工具,顺便也来看看其他的一些工具。 各类CSS检查工具 首先...

    HTML5学堂
  • ​Python 中的数字到底是什么?

    花下猫语:在 Python 中,不同类型的数字可以直接做算术运算,并不需要作显式的类型转换。但是,它的“隐式类型转换”可能跟其它语言不同,因为 Python 中...

    Python猫
  • python面向对象

    面向对象(Object Oriented,OO)其是以对象模型为基础进行的抽象过程,并在应用过程中形成了描述自己的抽象概念定义,包括对象、类、封装、继承以及多...

    老雷PHP全栈开发

扫码关注云+社区

领取腾讯云代金券