深度学习基础01-感知器

参考自:参考文档

1、相关概念

1、感知器即为神经网络的一个神经元
2、构造图:
在这里插入图片描述
其中x为输入值
w为权值(其中w0为偏置项)
从weighted sum到step function的过程称为激活函数
最终结果为输出

3、感知器迭代训练
感知器训练算法:将权重项和偏置项初始化为0,然后,利用下面的感知器规则迭代的修改wi和b,直到训练完成。
在这里插入图片描述
其中:
在这里插入图片描述
在这里插入图片描述
每次从训练数据中取出一个样本的输入向量,使用感知器计算其输出,再根据上面的规则来调整权重。每处理一个样本就调整一次权重。经过多轮迭代后(即全部的训练数据被反复处理多轮),就可以训练出感知器的权重,使之实现目标函数。

提出问题:

1、为什么需要w矩阵
感知机可以如下理解,寻找一个超平面,在该平面的两侧分别标记为两类,即+1和-1。以二维图展示如下:以x1+x2-2=0直线分割成两部分,直线上面为正,下面为负。
在这里插入图片描述
w为x1和x2的系数,根据系数不断调整此线性函数可以决定出正负边界
另外,w也可以理解为每个x的权重,即每个x对最终结果影响的大小

2、激活函数的意义?

线性变换太简单(只是加权偏移),限制了对复杂任务的处理能力。没有激活函数的神经网络就是一个线性回归模型。激活函数做的非线性变换可以使得神经网络处理非常复杂的任务。例如,我们希望我们的神经网络可以对语言翻译和图像分类做操作,这就需要非线性转换。同时,激活函数也使得反向传播算法变的可能。因为,这时候梯度和误差会被同时用来更新权重和偏移。没有可微分的线性函数,这就不可能了。

简而言之就是加入非线性的因素,解决线性函数无法解决的问题,比如本次实现and函数,其无法使用线性进行模拟,但是可以使用线性函数计算的结果,加上激活函数来进行分类。

2、预先知识

(1)Python lambda:
x,y:x+y 意思为 输入x,y 输出(x+y)
(2)Python3中对上述式子进行了修改
输入的x,y改为了x_y 其中x_y[0] 为x,x_y[1]为y
(3)Python 中reduce取自:functools
含义:

from functools import reduce

def add(x, y) :            # 两数相加
    return x + y
sum1 = reduce(add, [1,2,3,4,5])   # 计算列表和:1+2+3+4+5
sum2 = reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函数
print(sum1)
print(sum2)

reduce可以有三个参数,第三个是初始值

def reduce(function, sequence, initial=None):

3、实现感知器

根据上述公式,我们可以发现,感知器是根据预期结果与判断结果输出的差值进行不断更新的

1、首先初始化感知器,将其输入值和激活函数进行定义(注意激活函数的类型)

    def __init__(self, input_num, activator):
        '''
        初始化感知器,设置输入参数的个数,以及激活函数。
        激活函数的类型为double -> double
        '''
        self.activator = activator
        # 权重向量初始化为0
        self.weights = [0.0 for _ in range(input_num)]
        # 偏置项初始化为0
        self.bias = 0.0

2、通过输入值、预期结果、迭代次数和学习速率对感知器进行训练

    def train(self, input_vecs, labels, iteration, rate):
        '''
        输入训练数据:一组向量、与每个向量对应的label;以及训练轮数、学习率
        '''
        for i in range(iteration):
            self._one_iteration(input_vecs, labels, rate)

3、定义每次迭代函数(通过输入值、输出值、学习率更新权重及偏置项)即实现上述一中的第三点

    def _update_weights(self, input_vec, output, label, rate):
        '''
        按照感知器规则更新权重
        '''
        # 把input_vec[x1,x2,x3,...]和weights[w1,w2,w3,...]打包在一起
        # 变成[(x1,w1),(x2,w2),(x3,w3),...]
        # 然后利用感知器规则更新权重
        delta = label - output
        self.weights = map(
            lambda x_w: x_w[1] + rate * delta * x_w[0],
            zip(input_vec, self.weights))
        # 更新bias
        self.bias += rate * delta

4、输出训练结果(偏置项及权重)

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

5、利用训练好的网络进行使用,输入值然后将其进行输出

    def predict(self, input_vec):
        '''
        输入向量,输出感知器的计算结果
        '''
        # 把input_vec[x1,x2,x3...]和weights[w1,w2,w3,...]打包在一起
        # 变成[(x1,w1),(x2,w2),(x3,w3),...]
        # 然后利用map函数计算[x1*w1, x2*w2, x3*w3]
        # 最后利用reduce求和
        return self.activator(
            reduce(lambda a_b:a_b[0]+a_b[1],
                   map(lambda x_w:x_w[0]*x_w[1],
                       zip(input_vec, self.weights))
                , 0.0) + self.bias)

4、自己实现的感知器

# Python TR
# Time:2021/1/5 9:52 下午
#object表示Perceptron继承自object
from functools import reduce

class self_Perceptron(object):
    #需要初始化激活函数、weights、偏置项
    def __init__(self,input_num,activation):

        self.weights = [0.0 for _ in range(input_num)]
        self.activation = activation
        self.bias = 0.0
    def __str__(self):
        return "weights:\t%s\nbias:\t%f\n" % (list(self.weights), self.bias)
    def add_num(self,a,b):
        return a+b
    def multi_num(self,a,b):
        return a*b
    def predict(self,input_vec):
        multi = map(self.multi_num,input_vec,self.weights)#将两个向量中的对应元素相乘
        res = reduce(self.add_num,multi,0.0)#求向量中的所有元素的和
        return self.activation(res+self.bias)
    def train(self,input_vec,labels,iters,rate):
        for i in range(iters):
            self.train_once(input_vec,labels,rate)
    def train_once(self,input_vec,labels,rate):
        samples = zip(input_vec,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):
        delta = label-output
        for i in range(len(self.weights)):
            self.weights[i] = self.weights[i]+rate*delta*input_vec[i]
        self.bias = self.bias+delta*rate
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值