神经网络

什么是神经网络

用图来表示神经网络的话,如图
在这里插入图片描述
我们把最左边的一列称为输入层,最右边的一列称为输出层,中间的一列称为中间层。中间层有时也称为隐藏层。“隐藏”一词的意思是,隐藏层的神经元(和输入层、输出层不同)肉眼看不见。另外,本书中把输入层到输出层依次称为第 0 层、第 1 层、第 2 层(层号之所以从 0 开始,是为了方便后面基于 Python 进行实现)。图 3-1 中,第 0 层对应输入层,第 1 层对应中间层,第 2 层对应输出层。
回顾感知机
感知机接收 x1 和 x2 两个输入信号,输出 y。
在这里插入图片描述
则公式如下
在这里插入图片描述
b 是被称为偏置的参数,用于控制神经元被激活的容易程度;而 w1 和 w2 是表示各个信号的权重的参数,用于控制各个信号的重要性。,我们可以将b当成其中一个输入,则
在这里插入图片描述
这个感知机将 x1、x2 、1 三个信号作为神经元的输入,将其和各自的权重相乘后,传送至下一个神经元。在下一个神经元中,计算这些加权信号的总和。如果这个总和超过 0,则输出 1,否则输出 0。则我们可以将它转化为h(x)的函数x=b+w1x1+w2x2
在这里插入图片描述
在这里插入图片描述

激活函数

刚才登场的 h(x)函数会将输入信号的总和转换为输出信号,这种函数一般称为激活函数,激活函数是连接感知机和神经网络的桥梁。

sigmoid 函数

公式:
在这里插入图片描述
比如,向 sigmoid 函数输入 1.0 或 2.0 后,就会有某个值被输出,类似 h(1.0) = 0.731 …、h(2.0) = 0.880 … 这样。

阶跃函数的实现

阶跃函数,当输入超过 0 时,输出 1,否则输出 0。可以像下面这样简单地实现阶跃函数。

import numpy as np
import matplotlib.pyplot as plt
def step_function(x):
        y = x > 0
        return y.astype(np.int)

测试阶跃函数

x = np.arange(-5.0, 5.0, 0.1)
print(step_function(x))
y = step_function(x)
plt.plot(x,y)
plt.ylim(-0.1,1.1)
plt.show()

结果如下:对数组 x、y 进行绘图,
在这里插入图片描述

sigmoid 函数的实现

下面,我们来实现 sigmoid 函数。

def sigmod_function(x):
    y = 1/(1+np.exp(-x))


x = np.arange(-5.0, 5.0, 0.1)
print(sigmod_function(x))
y = sigmod_function(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)  # 指定y轴的范围
plt.show()

在这里插入图片描述
[0.00669285 0.00739154 0.00816257 0.0090133 0.0099518 0.01098694
0.01212843 0.01338692 0.01477403 0.0163025 0.01798621 0.01984031
0.02188127 0.02412702 0.02659699 0.02931223 0.03229546 0.03557119
0.03916572 0.04310725 0.04742587 0.05215356 0.05732418 0.06297336
0.06913842 0.07585818 0.0831727 0.09112296 0.09975049 0.10909682
0.11920292 0.13010847 0.14185106 0.15446527 0.16798161 0.18242552
0.19781611 0.21416502 0.23147522 0.24973989 0.26894142 0.2890505
0.31002552 0.33181223 0.35434369 0.37754067 0.40131234 0.42555748
0.450166 0.47502081 0.5 0.52497919 0.549834 0.57444252
0.59868766 0.62245933 0.64565631 0.66818777 0.68997448 0.7109495
0.73105858 0.75026011 0.76852478 0.78583498 0.80218389 0.81757448
0.83201839 0.84553473 0.85814894 0.86989153 0.88079708 0.89090318
0.90024951 0.90887704 0.9168273 0.92414182 0.93086158 0.93702664
0.94267582 0.94784644 0.95257413 0.95689275 0.96083428 0.96442881
0.96770454 0.97068777 0.97340301 0.97587298 0.97811873 0.98015969
0.98201379 0.9836975 0.98522597 0.98661308 0.98787157 0.98901306
0.9900482 0.9909867 0.99183743 0.99260846]

通过图像与结果可以看出通过sigmod函数结果大量集中在<0.1与大于0.9的范围之内。

ReLU 函数

ReLU 函数在输入大于 0 时,直接输出该值;在输入小于等于 0 时,输出 0。
ReLU 函数可以表示为下面的式。

用python实现

def relu(x):
    return np.maximum(0,x)

在这里插入图片描述

[0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.1 0.2 0.3
 0.4 0.5 0.6 0.7 0.8 0.9 1.  1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.  2.1
 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.  3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9
 4.  4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9]

神经网络

多维数组
简单地讲,多维数组就是“数字的集合”,数字排成一列的集合、排成长方形的集合、排成三维状或者(更加一般化的)N 维状的集合都称为多维数组。下面我们就用 NumPy 来生成多维数组,先从前面介绍过的一维数组开始。

import numpy as np
A = np.array([1,2,3,4,5])
print(A)
print(np.ndim(A))#维度
print(A.shape)#包含元素

数组的维数可以通过 np.dim() 函数获得。此外,数组的形状可以通过实例变量 shape获得。在上面的例子中,A 是一维数组,由 4 个元素构成。注意,这里的 A.shape 的结果是个元组(tuple)。这是因为一维数组的情况下也要返回和多维数组的情况下一致的结果。例如,二维数组时返回的是元组 (4,3),三维数组时返回的是元组 (4,3,2),因此一维数组时也同样以元组的形式返回结果。下面我们来生成一个二维数组。

神经网络的内积

用矩阵来实现简单的神经网络,这个神经网络省略了偏置和激活函数,只有权重。
在这里插入图片描述
代码实现

import numpy as np
X = np.array([1,3])
print(X.shape)
W = np.array([[1,2,3],[2,3,4]])
print(W.shape)
Y = np.dot(X,W)
print(Y)

3 层神经网络的实现

现在我们来进行神经网络的实现。这里我们以下图 3 层神经网络为对象,实现从输入到输出的(前向)处理。在代码实现方面,使用上一节介绍的 NumPy 多维数组。巧妙地使用 NumPy 数组,可以用很少的代码完成神经网络的前向处理。
在这里插入图片描述
3 层神经网络:输入层(第 0 层)有 2 个神经元,第 1 个隐藏层(第 1 层)有 3 个神经元,第 2 个隐藏层(第 2 层)有 2 个神经元,输出层(第 3 层)有 2 个神经元
各层的神经元传导如下增加了表示偏置的神经元“1”。
在这里插入图片描述
在这里插入图片描述
这个运算和上一节进行的运算是一样的。W1 是 2 × 3 的数组,X 是元素个数为 2 的一维数组。这里,W1 和 X 的对应维度的元素个数也保持了一致。

import numpy as np
X = np.array([1.0, 0.5])
W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
B1 = np.array([0.1, 0.2, 0.3])#添加偏置项(偏置项的意义在于满足特定结果)

print(W1.shape) # (2, 3)
print(X.shape) # (2,)
print(B1.shape) # (3,)

A1 = np.dot(X, W1) + B1
print(A1)

接下来,我们观察第 1 层中激活函数的计算过程。如果把这个计算过程用图来表示的话,则如图
在这里插入图片描述
从输入层到第 1 层的信号传递
隐藏层的加权和(加权信号和偏置的总和)用 a 表示,被激活函数转换后的信号用 z表示。此外,图中 h() 表示激活函数,这里我们使用的是 sigmoid 函数。

Z1 = sigmoid(A1)

print(A1) # [0.3, 0.7, 1.1]
print(Z1) # [0.57444252, 0.66818777, 0.75026011]

然后Z1作为第二层的输入
在这里插入图片描述

A2 = np.dot(Z1, W2) + B2
Z2 = sigmod_function(A2)
print(A2)
print(Z2)
#[0.51615984 1.21402696]
#[0.62624937 0.7710107 ]

最后是第 2 层到输出层的信号传递。输出层的实现也和之前的实现基本相同。不过,最后的激活函数和之前的隐藏层有所不同。

A3 = np.dot(Z2, W3) + B3
Y = identity_function(A3) # 或者Y = A3
print(A3)
print(Y)

这里我们定义了 identity_function() 函数(也称为“恒等函数”),并将其作为输出层的激活函数。恒等函数会将输入按原样输出,因此,这个例子中没有必要特意定义 identity_function()。这里这样实现只是为了和之前的流程保持统一。另外,输出层的激活函数用 σ() 表示,不同于隐藏层的激活函数 h()(σ 读作 sigma)。
在这里插入图片描述

整理代码

import numpy as np
from project_for_test.Logical_circuit.Activation_function import *
def identity_function(x):
    return x
def init_network():
    network = {}
    network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
    network['b1'] = np.array([0.1, 0.2, 0.3])
    network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
    network['b2'] = np.array([0.1, 0.2])
    network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])
    network['b3'] = np.array([0.1, 0.2])

    return network

def forward(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']

    a1 = np.dot(x, W1) + b1
    z1 = sigmod_function(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmod_function(a2)
    a3 = np.dot(z2, W3) + b3
    y = identity_function(a3)

    return y

network = init_network()
x = np.array([1.0, 0.5])
y = forward(network, x)
print(y) # [ 0.31682708 0.69627909]

这里定义了 init_network() 和 forward() 函数。init_network() 函数会进行权重和偏置的初始化,并将它们保存在字典变量 network 中。这个字典变量 network 中保存了每一层所需的参数(权重和偏置)。forward() 函数中则封装了将输入信号转换为输出信号的处理过程。
另外,这里出现了 forward(前向)一词,它表示的是从输入到输出方向的传递处理。后面在进行神经网络的训练时,我们将介绍后向(backward,从输出到输入方向)的处理。
至此,神经网络的前向处理的实现就完成了。通过巧妙地使用 NumPy 多维数组,我们高效地实现了神经网络。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值