深度学习入门2—神经网络

第3章 神经网络

上一章(感知机)学习的感知机可以表示很多复杂的函数,但是其涉及的输入与输出的权重是由人工进行的,即根据真值表人工决定权重。
神经网络解决的问题:自动数据中学习到合适的权重参数(权重、偏置)

3.1 参数

基本参数与感知机一样。

  • w:输入权重,用于控制各个输入信号的重要性

  • b:激活偏置,用于控制神经元被激活的容易程度

加权信号的总和为:y = b+w1x1 + … + wnxn。如果总和超过0,则输出1,否则输出0,这是一种分情况的操作,可以有很多种操作

为了简化,将所有操作用一个函数表示,即h(x),那么 y = h(b+w1x1 + … + wnxn)

输入信号的综合会被函数h(x)转换,转换后的值就是输出y

3.2 激活函数

激活函数作用:加入非线性因素,非线性变换让网络储存信息大大增加,神经网络才能具备分层的非线性映射学习能力。(线性表达能力有限,经过多层网络叠加最后仍然可变换为线性,与1层线性网络无差别,对于增加网络深度无意义)

a=w1x1+w2x2+b,输出A=f(a) (神经网络运算可以作为矩阵运算打包进行)

阶跃函数f(a):两种取值,a>0,f(a)=1, 被激活; a<0,f(a)=0, 不激活。

其他激活函数f(a):f(a)的取值由激活函数而定。(激活是感知机里的概念,神经网络中的激活函数只是引用了名称,输出是一个数值,流动的是连续的实数值信号,决定输出值输入值如何变换)

感知机与神经网络信号关联:感知机中神经元之间流动的是0 或 1的二元信号,而神经网络中流动的是连续的实数值信号。

激活函数关联:

不同点:平滑性上有差异。

相同点:输入信号越重要,输出的值越大; 输出信号的值都在0到1之间; 且二者均为非线性函数。

sigmoid函数

sigmoid函数是一条平滑的曲线,输出随着输入发生连续性的变化

sigmoid函数的平滑性对神经网络的学习具有重要意义

sigmoid函数可以返回 0.731…、0.880 … 等实数(这一点和刚才的平滑性有关)

softmax函数特征:输出值为0~1之间的实数,总和为1,因此输出可看做为概率。

一般神经网络只把输出值最大神经元所对应的类别作为识别结果,使用softmax函数后不会改变最大神经元的判断,且指数函数运算计算量大,因此神经网络进行分类一般忽略输出层的softmax函数(推理阶段)。

求解机器学习问题分为学习和推理:

学习(训练):算法从已知的数据学习模型,调整合适的参数

推理(分类):学习得到的模型对未知数据进行推理

最终推理可舍掉softmax函数,但学习时需用到softmax函数。

ReLU函数

输入大于0,直接输出该值;输入小于等于0,输出0。

输出层所用激活函数:一般情况,回归问题(恒等函数、将输入原样输出)、二元分类(sigmoid函数)、多元分类(softmax函数)。

分类问题:数据属于哪一个类别(区分图像是男/女) 回归问题:根据某个输入预测一个(连续的)数值问题(根据一个人的图像预测体重)

阶跃函数:
def step_function(x):
    return np.array(x > 0, dtype=np.int)    # 大于0则1  小于0则0

sigmoid函数:
def sigmoid(x):
    return 1 / (1 + np.exp(-x))     # 一直都在0~1范围内,输入越大输出越大

relu函数:
def relu(x):
    return np.maximum(0, x)   # 输入大于0,直接输出该值;输入小于等于0,输出0

3.3 神经网络的计算

多维数组运算

矩阵的乘积:np.dot(A, B)

A和B必须保持在对应维度的元素个数一致

A[x,a] · B[a,y] => C[x,y]

神经网络的内积、传播

使用 Y=np.dot(A, B) 矩阵的乘积可以一次性完成 Y 的计算,不需单独计算 Y 的每一个元素,这种实现十分重要。

输入 -> 第1层神经元

输入写入矩阵 X (x1,x2,x3…),权重写入矩阵 W1(w1,w2,w3…),偏置写入矩阵 B1(b1,b2,b3…)。

则第1层的加权和矩阵 A1= XW1+ B1,假设使用激活函数为sigmoid函数,被激活函数转换后的信号用 Z1 表示。

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

第1层神经元 -> 第2层神经元

将转换后的信号Z1(z1,z2,z3…)作为新的输入。

A2 = np.dot(Z1, W2) + B2
Z2 = sigmoid(A2)

将输入神经元到输出神经元的过程中,对应的权重 W 作为将输入 X 作为另一个矩阵。

第2层神经元 -> 输出层(激活函数假设用恒等函数identify_function)

A3 = np.dot(Z2, W3) + B3
Y = identify_function(A3)

输出层的神经元数量

对于分类问题:输出层神经元数量一般设置为类别的数量。例如识别数字(10分类)问题,神经元数量设置为10个。某个神经元 y 输出值最大,则表明神经网络预测的是 y 对应的类别。

3.4 手写数字识别

使用神经网络解决问题 和 求解机器学习问题的步骤一样,即 有 训练阶段 和 预测阶段两个步骤。

  • 训练阶段即 使用训练数据进行 权重参数的学习

  • 预测阶段即 使用训练阶段学习到的参数,对输入数据进行预测。

(1) 数据介绍

  • 数据集:Mnist手写数字图像集,由0到9的数字图像构成,训练集:6万张,测试集:1万张

  • 图像数据:28pt x 28pt 的灰度图像(1通道),各像素取值:0~255,都有正确的数字标签

**Pickle模块:**可以将程序运行中的对象保存为文件。如果加载保存过的pickle文件(.pkl),可以立刻复原之前程序运行中的对象。其实pickle文件就是保存的字典对象。在模型训练完后,可以利用pickle将模型参数保存为pickle文件,然后在测试阶段,再使用pickle加载这个模型参数文件,就可以立刻得到原本训练好的模型。

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
# load_mnist是用来读取minist数据的函数,返回了训练数据 和 测试数据;有三个参数:
# normalize:是否将输入图像的像素数据正规化为0.0 ~ 1.0的值
# flatten:是否将输入图像展开为一维数组(False就是1x28x28的三维数组,True就是784的一维数组)
# one_hot_label:是否将 标签 保存为 one-hot表示 数组

数据读取结果:

x_test:10000 x 784 的二维数组

t_test:10000 x 1 的二维数组(或者说一维数组?)

(2)神经网络的推理过程

一个图片一个图片进行测试,一个图片数据是784维的一维数组,所以输入层有784个神经元,由于数字标签有0~9十种类别,所以输出层有10个神经元。此外,这个神经网络有2个隐藏层,分别有50个、100个神经元(这个数字可以自己设置)

三个步骤:

  • 获取测试数据:get_data

  • 利用已经训练好的模型参数 来 初始化 网络模型的参数:init_network

  • 利用模型对测试数据 进行 预测:predict

init_network中,会读入保存在pickle文件sample_weight.pkl中学习到的权重参数,这个pkl文件 以 字典变量的形式保存了 权重和偏置参数

在该例子中,load_mnist函数的参数normalize参数设置为True,在读取数据时,函数内部会进行转换,将图像的各个像素值 除以255,使得数据的值 在0.0~1.0的范围内

这种把数据限定到某个范围内的处理叫做 正规化

对神经网络的输入数据进行 某种既定的转换 叫做 预处理

这里,对输入图像进行正规化 就是 一种预处理。

预处理在神经网络(深度学习)中非常实用,可以提高识别性能 和 学习效率

很多预处理都会 考虑到数据的整体分布;比如,利用数据整体的均值 或 标准差 来 移动数据,使数据整体以0为中心分布;或者进行正规化,把数据的延展控制在一定范围内 等等…

(3)批处理(batch)

批处理可以加快计算机的运算速度,批处理一次性计算大型数据 要 比 分开逐步计算各个小型数组 的 速度更快。

当打包多张图片数据时,比如打包一百张图片一起来预测。 则输入为 100x784

在预测阶段的数据处理过程为:

100x784 * 784x50 * 50x100 * 100x10 -> 100x10 :100个元素个数为10的数组,是一个二维数组

每次输入100张图片数据,输出是100组预测得分,这种打包式的输入数据成为 批(batch)

批处理只是改变了输入数据,在预测阶段predict的完全不需要改变的,因为np.array数组完全适应各种维度的计算过程

只预测一个图片时:

	y = predict(network, x[i])   

批处理预测图片时:(batch_size为批处理大小,用于设置一次性处理的图片数量)

	x_batch = x[i:i+batch_size]
	y_batch = predict(network, x_batch)     (batch_size x 10)

计算预测正确的数量时的代码也要变:

p = np.argmax(y_batch, axis=1)    # (100,)   从第二个维度对应的数字集合(10个)里面找到最大值对应的索引
tmp = np.argmax(y_batch, axis=0)  # (10,)    从第一个维度对应的数字集合(100个)里面找到最大值对应的索引
accuracy_cnt += np.sum(p == t[i:i+batch_size])

如果您觉得有收获的话可以点个赞支持一下(#^ ○ ^#) 谢谢!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值