不用框架入门与进阶深度学习(1)-手写感知器

  • Post author:
  • Post category:其他


转自公众号-AI圈终身学习,

深度学习零基础入门与面试必会



致力于提供一个有情怀的集训互享开源平台,欢迎关注。


Neural Network



文集介绍

不用框架,代码手撸深度神经网络,系列文章。适合零基础入门,更适合进阶。系列文章,提前关注不迷路。适宜人群:

  • 深度学者初学者
  • 深度学习面试进阶者
  • 有意向转行AI的IT从业者
  • 对深度学习感兴趣的在校大学生

纸上得来终觉浅,文集所有代码地址:

https://github.com/AIGroup-Z/deep-neural-network

这是本文集暂定要写的内容:



前言

上篇文章我们解释了什么是深度学习,以及神经网络。当然您可能觉得一头雾水,那是非常正常的。本节接着介绍神经网络的基本组成单元-感知器。



一、感知器是什么?

如图,红色加粗部分就是一个感知器:

我们把它抠出来,就变成了这个样子:

感知器为框里的部分,它不包括输入层。因此,其组成如下:


  • 权重与偏置项

    一个感知器有多个输入



    (

    x

    1

    ,

    x

    2

    ,

    .

    .

    .

    ,

    x

    n

    x

    i

    R

    )

    (x_1, x_2, …,x_n|x_i \in \mathbb R)






    (



    x










    1


















    ,





    x










    2


















    ,




    .


    .


    .


    ,





    x










    n






















    x










    i





























    R


    )





    ,每个输入有对应的权重



    (

    w

    1

    ,

    w

    2

    ,

    .

    .

    .

    ,

    w

    n

    w

    i

    R

    )

    (w_1, w_2, …,w_n|w_i \in \mathbb R)






    (



    w










    1


















    ,





    w










    2


















    ,




    .


    .


    .


    ,





    w










    n






















    w










    i





























    R


    )





    , 此外有个偏置项



    b

    R

    b \in \mathbb R






    b













    R






  • 激活函数

    感知器有很多种激活函数可选,我们暂时选择

    阶跃函数f

    做为激活函数:

所以我们的感知器最后得到的输出结果是:





(2)

y

=

f

(

w

x

+

b

)

y=f(w\cdot x+b) \tag{2}






y




=








f


(


w













x




+








b


)







(



2



)






可能您看得有点晕,俗话说一行代码胜千言,接下来我们用感知器实现一个**与门(and)



或门(or)**函数。



二、动手实现感知器


2.1 任务与数据介绍

这一节我们实现一个and函数。and函数非常简单,只有当两个输入都为1的时候,它的输出才为1,真值表如下:




x

1

x_1







x










1























x

2

x_2







x










2























y

y






y




1 1 1
1 0 0
0 1 0
0 0 0

因此我们的训练数据如下:

# 数据准备
def get_and_training_dataset():
    x_train = [[0, 0], [0, 1], [1, 0], [1, 1]]
    y_train = [0, 0, 0, 1]
    return x_train, y_train

现在,我们有两个输入



x

1

x_1







x










1

























x

2

x_2







x










2





















,最终我们获得的权重值是



w

1

=

0.2

w

2

=

0.1

b

=

0.2

w_1=0.2;w_2=0.1;b=-0.2







w










1




















=








0


.


2






w










2




















=








0


.


1





b




=











0


.


2





,这个时候它就是and感知机。我们以输入



x

1

=

1

;

x

2

=

1

x_1=1;x_2=1







x










1




















=








1


;





x










2




















=








1





进行验证,其他输入请读者自己验算,结果如下:





(3)

y

=

f

(

w

x

+

b

)

=

f

(

w

1

x

1

+

w

2

x

2

+

b

)

=

f

(

0.2

1

+

0.1

1

0.2

)

=

f

(

0.1

)

=

1

\begin{aligned} y&=f(w\cdot x+b)\\ &=f(w_1x_1 + w_2x_2+b)\\ &=f(0.2*1+0.1*1-0.2)\\ &=f(0.1)\\ &=1\\ \end{aligned} \tag{3}
















y





















































=




f


(


w









x




+




b


)












=




f


(



w










1



















x










1




















+





w










2



















x










2




















+




b


)












=




f


(


0


.


2









1




+




0


.


1









1









0


.


2


)












=




f


(


0


.


1


)












=




1
























(



3



)






那么这个权重值是怎么来的呢?这是一种叫梯度下降的训练方式更新出来的,流程如下:

  • 第一步 初始化权重



    w

    i

    w_i







    w










    i





















    和偏置项



    b

    b






    b





    为0.

  • 第二步 迭代更新权重



    w

    i

    w_i







    w










    i





















    和偏置项



    b

    b






    b





    ,规则如下:





(4)

Δ

b

i

=

δ

(

y

y

^

)

Δ

w

i

=

δ

(

y

y

^

)

x

i

w

i

=

w

i

+

Δ

w

i

b

i

=

b

i

+

Δ

b

i

\begin{aligned} \Delta b_i=\delta (y- \widehat{y}) \\ \Delta w_i=\delta (y- \widehat{y})x_i \\ w_i=w_i + \Delta w_i\\ b_i=b_i + \Delta b_i \end{aligned} \tag{4}
















Δ



b










i




















=




δ


(


y

















y
























)








Δ



w










i




















=




δ


(


y

















y
























)



x










i

























w










i




















=





w










i




















+




Δ



w










i

























b










i




















=





b










i




















+




Δ



b










i








































(



4



)






其中



δ

\delta






δ





(读delta)叫学习率,



y

y






y





为正确的输出,



y

^

\widehat{y}














y



























(读y hat)为预测的输出。如果这些符号看不懂没关系,直接看下一节的代码就明白了。

为什么是这样的更新规则,我们留在下一节讲,这里您只需要知道流程即可。



2.2 代码实现

文集所有代码地址:

https://github.com/AIGroup-Z/deep-neural-network

import numpy as np

class Perceptron(object):
    def __init__(self, input_feature_num, activation=None):
        self.activation = activation if activation else self.sign
        self.w = [0.0] * input_feature_num
        self.b = 0.0

    def sign(self, z):
        # 阶跃激活函数:
        # sign(z) = 1 if z > 0 
        # sign(z) = 0 otherwise
        return int(z>0)
    
    def predict(self, x):
        # 预测输出函数
        # y_hat = f(wx + b)
        return self.activation(
            np.dot(self.w, x) + self.b)
    
    def fit(self, x_train, y_train, iteration, learning_rate):
        # 训练函数
        for _ in range(iteration):
            for x, y in zip(x_train, y_train):
                y_hat = self.predict(x)
                self._update_weights(x, y_hat, y, learning_rate)
    
    def _update_weights(self, x, y_hat, y, learning_rate):
        # 权重更新, 对照公式查看
        delta = y - y_hat
        self.w = np.add(self.w,
                        np.multiply(learning_rate * delta, x))
        self.b += learning_rate * delta
    
    def __str__(self):
        return 'weights: {}\tbias: {}'.format(self.w, self.b)

模型和数据我们都有了,接下来直接训练即可获得and感知器:

# 模型训练
x_train, y_train = get_and_training_dataset()
and_p = Perceptron(2)
and_p.fit(x_train, y_train, iteration=5, learning_rate=0.1)

最终预测输出如下:

# 预测数据
print('and 感知机权重:\n', and_p, '\n')
print('1 & 1 = %d' % and_p.predict([1, 1]))
print('1 & 0 = %d' % and_p.predict([1, 0]))
print('0 & 1 = %d' % and_p.predict([0, 1]))
print('0 & 0 = %d' % and_p.predict([0, 0]))



2.3 作业:实现一个or感知机

在这里(

https://github.com/AIGroup-Z/deep-neural-network

) 查看代码您会发现,我们在Jupyter Notebook上留了这个作业,你可以在我们的代码基础上实现它,以确认自己已经掌握了感知机。



三、结语

本节主要介绍了神经网络中的元单元-感知机,并且使用它做了一个与门与或门,不知道您觉得这节难度如何?好消息是恭喜你走出了深度学习的第一步,后面我们会介绍更加有趣的部分,并且将感知器用于实战当中,敬请期待。

参考资料:


如果有任何问题,你不是一个人。可以在公众号首页找到我们的组队学习群。

公众号修饰图fixed



版权声明:本文为u012891055原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。