深度学习理论基础10-实现一个3层神经网络

首先,这是一张本节的神经网络懵逼图全貌图!

可以看出,这图显示的元素非常乱七八糟丰富。我会逐个字母逐个数字的告诉你这是什么,那是什么。

等我说完了,以及你知道这些字母是什么的时候,我们将一起实现它。

第0层:这是输入层,1代表偏置神经元。x是输入,而且它们都被按照顺序编了号。

第0层与第1层之间:w是权重,括号里的1代表当前层数。

    w右下角的11代表右边层的第1个神经元与左边层的第1个神经元。

    w右下角的12代表右边层的第1个神经元与左边层的第2个神经元。

为什么左边的数字代表右边的神经元序号,而右边的数字反而代表左边的神经元序号呢?

因为权重与右边的层才是一对。这一对构成一层网络。w当然先把主子的序号放前面。

那如果序列超过9怎么表示呢?

扫描二维码关注公众号,回复: 4721474 查看本文章

这些表示方法只在本节有效,老夫保证不会超过9的。

第1层:a就是输出x*权重w+偏置b,括号的数字是当前层,右下角是序号。h是激活函数。z是激活函数返回的结果。

后面几层的工作也是大同小异。

注意,最后一层,输出层的激活函数与隐藏层的有些不同。用σ表示的。稍微我会提到这个函数的不同。

为了实现这个神经网络,下面先打一个草稿:

准备工作:

    1.准备好所需的函数工具:隐藏层激活函数,输出层激活函数,矩阵乘积函数

    2.得到每一层的偏置和权重。

第一层: 

    3.得到a1:输入数据及第1层权重的积乘+第1层偏置

    4.得到z1:把a1带入激活函数,返回z1

第二层:

    5.得到a2:z1及第2层权重的积乘+第2层偏置

    6.得到z2:把a2带入激活函数,返回z2

第三层:

    7.得到a3:z2及第3层权重的积乘+第3层偏置

    8.得到z3:把a3带入激活函数,返回z3

接下来逐步的实现这些

第1步:准备好所需的激活函数

#隐藏层激活函数
def sigmoid_function(x):
    return 1/(1+np.exp(-x))


#输出层激活函数
def identity_function(x):
    return x


#矩阵乘积函数
def mattrix_dot(A,B):
    return np.dot(A,B)

第2步.得到每一层的偏置和权重。

#得到偏置量和权重
def get_init_data():
    # 第0层偏置量
    b1=np.array([0.1,0.2,0.3])
    # 第1层偏置量
    b2=np.array([0.1,0.2])
    # 第2层偏置量
    b3=np.array([0.1,0.2])
    # 第1层权重
    W1=np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
    # 第2层权重
    W2=np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
    # 第3层权重
    W3=np.array([[0.1, 0.3], [0.2, 0.4]])
    return b1,b2,b3,W1,W2,W3

这些数据都是我们自己乱编的,所以这个神经网络暂时还做不了什么神奇的事情。

下面在main主函数里,实现三层网络需要做的事

def main():
    b1, b2,b3, W1, W2, W3=get_init_data()
    #输入层数据
    x1,x2=[1.0, 0.5]
    x=np.array([x1,x2])
    #第1层
    a1=mattrix_dot(x, W1)+b1 # 第3步:得到a1:输入数据及第1层权重的积乘+第1层偏置
    z1=sigmoid_function(a1) # 第4步:得到z1:把a1带入激活函数,返回z1
    #第2层
    a2=mattrix_dot(z1, W2)+b2 # 第3步:得到a2:z1及第2层权重的积乘+第2层偏置
    z2=sigmoid_function(a2) # 第4步:得到z2:把a2带入激活函数,返回z2
    #第3层
    a3=mattrix_dot(z2, W3)+b3 # 第3步:得到a3:z2及第3层权重的积乘+第3层偏置
    z3=identity_function(a3) # 第4步:得到z3:把a3带入激活函数,返回z3
    print(z3) #输出[0.31682708 0.69627909]

可以看到。实现这个复杂的神经网络,代码却并不复杂。这得益于numpy模块带来的便捷。

另外值得吐槽的是,输出层的激活函数identity_function()太'精简'了。

即便这样,人家也有个好听的名字---'恒等函数'。

恒等函数会将输入按原样输出,对于输入的信息,不加以任何改动地直接输出。

输出层通常根据其用途选择不同的激活函数。

在 回归问题上,通常选择恒等函数,在分类问题上,通常选择softmax()函数。

下一节《输出层的设计》会提到softmax()函数。

--------结语--------

午餐吃什么呢?

汉堡+可乐不错。

猜你喜欢

转载自blog.csdn.net/qq_40878431/article/details/85447562