《Neural Networks and Deep Learning》读书笔记系列:1.识别手写字

《Neural networks and deep learning》概览 最近阅读了《Neural networks and deep learning》这本书(online book,还没出版),算是读得比较仔细,前面几章涉及的内容比较简单,我着重看了第三章《Improving the way neural networks learn》,涉及深度神经网络优化和训练的各种技术,对第三章做了详细的笔记(同时参考了其他资料,以后读到其他相关的论文资料也会补充或更改),欢迎有 阅读详情

深度学习笔记系列之识别手写字


Neural Networks and Deep Learning[1] 是由 Michael Nielsen[2] 编写的开源书籍,这本书主要讲的是如何掌握神经网络的核心概念,包括现代技术的深度学习,为你将来使⽤神经网络和深度学习打下基础,以下是我的读书笔记。

神经网络是一门重要的机器学习技术,它通过模拟人脑的神经网络来实现人工智能的目的,所以其也是深度学习的基础,了解它之后自然会受益颇多,本章主要是以识别手写字这个问题来贯穿整篇,那么,人类的视觉系统和神经网络到底在识别一个目标的时候,主要区别在哪?

  • 人类视觉系统:通过数十亿年不断地进化与学习,最终能够极好地适应理解视觉世界的任务,从而无意识地就可以对目标进行判断识别

  • 神经网络:通过提供的样本来推断出识别某种目标的规则,作为判断标准

本章的主要内容是介绍神经网络的基本概念以及引入一个识别手写数字的例子来加深我们的理解,你将了解到:

  • 两个重要的人工神经元:感知器和 S 型神经元

  • 神经⽹络的架构

  • ⼀个简单的分类⼿写数字的⽹络

  • 标准的神经网络学习算法:随机梯度下降算法

感知器

1943 年,心理学家 McCulloch 和数学家 Pitts 发表了《A logical calculus of the ideas immanent in nervous activity[3]》,其中提出了抽象的神经元模型 MP,但是在这个模型中权重都是要求提前设置好才可以输出目标值,所以很遗憾,它不可以学习,但这不影响此模型给后来者带来的影响,比如感知器:

感知器是 Frank Rosenblatt 提出的一个由两层神经元组成的人工神经网络,它的出现在当时可是引起了轰动,因为感知器是首个可以学习的神经网络

感知器的工作方式如下所示:

02

 分别表示三个不同的二进制输入,output 则是一个二进制输出,对于多种输入,可能有的输入成立有的不成立,在这么多输入的影响下,该如何判断输出 output 呢?Rosenblatt 引入了权重来表示相应输入的重要性。

对于 个输入,每个输入都有对应的权重 ,最后的输出 output 由每个输入与其对应的权重相乘之和与阈值之差 来决定,如下:

03

假设 且 和 对应权重和输⼊的向量,即:

那么感知器的规则可以重写为:

04

这就是感知器的数学模型,是不是就像一个逻辑回归模型?只要将感知器输出规则替换为( ),后面我们会知道这称之为激活函数,其实这种感知器叫做线性单元。

它的出现让我们可以设计学习算法,从而实现自动调整人工神经元的权重和偏置,与此同时 output 也会随之改变,这就是学习!如果你有兴趣可以看我用python写的一个感知器自动学习实现与非门,代码在**nndl_chapter01[4]**。

说句题外话,由于感知器是单层神经网络,它只能实现简单的线性分类任务,所以它无法对异或问题进行分类,异或的真值表如下:




000
011
101
110

可以看出来,异或问题是线性不可分的,不信你画个坐标轴试试看,那么问题来了?怎么解决,大部分都能很快地想出解决方案,既然感知器可以实现线性分类,也就是说实现与非门是没有问题的,逻辑上来说我们可以实现任何逻辑功能(比如四个与非门实现异或),但前提是为感知器加入一个隐藏层,意思就是多了一个隐藏层的神经网络之后,就可以解决异或问题。

可是在当时是没办法对多层神经网络(包括异或逻辑)进行训练的,因为计算量太大了,Minsky 在 1969 年出版了一本叫《Perceptron》的书详细说明了这个问题。

遇到问题,就解决问题,两层神经网络的作用,是可以对非线性进行分类的,我们的先人并未止步,直到反向传播(Backpropagation,BP)算法的出现解决了计算量太大的问题。

感知器,终于可以多层了。

S 型神经元

前面提到,神经网络可以通过样本的学习来调整人工神经元的权重和偏置,从而使输出的结果更加准确,那么怎样给⼀个神经⽹络设计这样的算法呢?

05

以数字识别为例,假设⽹络错误地把⼀个9的图像分类为8,我们可以让权重和偏置做些⼩的改动,从而达到我们需要的结果9,这就是学习。对于感知器,我们知道,其返还的结果不是 0 就是 1,很可能出现这样一个情况,我们好不容易将一个目标,比如把9的图像分类为8调整回原来正确的分类,可此时的阈值和偏置会造成其他样本的判断失误,这样的调整不是一个好的方案。

所以,我们需要 S 型神经元,因为 S 型神经元返回的是[0,1]之间的任何实数,这样的话权重和偏置的微⼩改动只会引起输出的微⼩变化,此时的 output 可以表示为 ,而 就是 S 型函数,S 型函数中 S 指的是 Sigmoid 函数,定义如下:

其中 表达式为:

那么⼀个具有输⼊ ,权重为 ,和偏置 b 的 S 型神经元的输出是:

上面说过,感知器的激活函数只会输出两个值,分别是0或1,让我们把目光投向 S 型神经元,假设此时 是一个很大的正数,那么此时 output 将无限接近于 1,反之,若 是一个很大的负数,那么此时 output 将无限接近于 0,从极端情况来看,是不是很像 S 型神经元呢?

S 型神经元的输出是[0,1]之间的任何实数,那么这个分类模型该如何判断分类结果呢?其实很简单,我们可以定义一个数值,比如:

  •  输出 0

  •  输出 1

神经⽹络的架构

看下面一个四层神经网络,这种类型的多层⽹络有时被称为多层感知器或者MLP,如下图:

06

需要记住以下几个概念:

  • ⽹络中最左边的称为输⼊层,其中的神经元称为输⼊神经元

  • 中间得称之为隐藏层,图中有两个隐藏层

  • 最右边称之为输出层

  • 上⼀层的输出作为下⼀层的输⼊,信息总是向前传播,从不反向回馈:前馈神经网络

  • 有回路,其中反馈环路是可⾏的:递归神经网络

⼀个简单的分类⼿写数字的⽹络

对于这六个数字504192,我们该如何实现一个分类⼿写数字的⽹络呢,可以将其分解为两个小问题:

  • 504192 是连续在一起的图像,首先可以将其分割成 6 个小图像,比如5 0 ...等

  • 再对分割开的小图像进行分类,比如识别 5 我们将使⽤⼀个三层神经⽹络来识别单个数字:

07

由于训练数据由 的⼿写数字的图像组成,所以:

  • 输入层有 784 个神经元,因为 ,输⼊像素是灰度级的,值为 0:0 表⽰⽩⾊,值为 1:0 表⽰⿊⾊,中间数值表⽰逐渐暗淡的灰⾊

  • 隐藏层⽤ n 来表⽰神经元的数量,我们将给 n 实验不同的数值。⽰例中⽤⼀个⼩的隐藏层来说明,仅仅包含 个神经元

  • ⽹络的输出层包含有 10 个神经元,如果第一个输出神经元被激活,那么数字就是 0,以此类推,从 0 到 9

一个分类⼿写数字的⽹络,大概就可以这样实现。

随机梯度下降算法

分类方案已经确定了,接下来第一步就是获取样本,我们将使⽤MNIST[5]数据集,其包含有数以万计的连带着正确分类器的⼿写数字的扫描图像,下载好建立这样的目录结构,使用jupyter notebook开始吧,如果没有,请自行检索教程安装,代码目录如下:

pylab
└── datasets
    └── MNIST_data
        ├── t10k-images-idx3-ubyte.gz
        ├── t10k-labels-idx1-ubyte.gz
        ├── train-images-idx3-ubyte.gz
        └── train-labels-idx1-ubyte.gz

然后使用TensorFlow来读取数据,看看下载的数据集到底是什么样子,可以在mnist_data.ipynb中添加如下代码:

from matplotlib import pyplot as plt
from tensorflow.examples.tutorials.mnist.input_data import read_data_sets


mnist = read_data_sets("../datasets/MNIST_data/", one_hot=True)


查看一些基本信息:

print("Training data size: %s" % mnist.train.num_examples)
print("Validating data size: %s" % mnist.validation.num_examples)
print("Testing data size: %s" % mnist.test.num_examples)


# 每张图片是长度为784的一维数组
print(len(mnist.train.images[0]))


def display_digit(image):
    image = image.reshape([28,28])
    plt.imshow(image, cmap=plt.get_cmap('gray_r'))
    plt.show()


print("样本真实数字为:%s" % list(mnist.train.labels[1]).index(1))
# 显示图像
display_digit(mnist.train.images[1])


# Output
# Training data size: 55000
# Validating data size: 5000
# Testing data size: 10000
# 784
# 样本真实数字为:3

可以看到显示如下图像:

08

通过代码,我们知道,每个图像被分割成 784 个值存于一维数组中,看作⼀个 维的向量,每个向量就代表图像中单个像素的灰度值,假设我们用 表示 output,也就是当我们输入一组样本数据 x,那么 y 就是我们需要的结果,怎么从 x 得到 y 呢,我们需要一个函数 。

感知器为什么可以学习,因为它可以调整 和 来实现 output 的改变,这里,我们同样需要一个算法来让我们找到权重和偏置,从而使得 可以拟合样本输入的 x,为了量化我们如何实现这个⽬标,我们定义⼀个代价函数(有时被称为损失或⽬标函数):

  • w 表⽰所有的⽹络中权重的集合

  • b 是所有的偏置

  • n 是训练输⼊数据的个数

  • a 是表⽰当输⼊为 x 时输出的向量,可以理解为 output

训练模型的过程就是优化代价函数的过程,Cost Function(代价函数) 越小,就代表模型拟合的越好,所以我们的目的是找出最⼩化权重和偏置的代价函数 ,其实这个就是我们平常用来评价回归算法的均方误差,也就是MSE。

现在我们的目标很清晰,为了找出合适的权重和偏置值,我们需要让代价函数的值接近于 0,在这个条件下我们就可以找出合适的权重和偏置值,我们将采⽤称为梯度下降的算法来达到这个⽬的。

下面是我的推导过程:

20190513120212

实现数字分类模型

终于,掌握了基本的概念,我们可以通过实战来实现一个数字分类模型,来看看,前面我们掌握的知识是怎么运用于实际的。

书籍作者很贴心地实现了模型代码,仓库见neural-networks-and-deep-learning 官方 git 仓库[6],接下来我们一起来看看具体的实现代码吧。

首先是实现一个Network类,

#!/usr/bin/env python


import random


import numpy as np




class Network(object):


    def __init__(self, sizes):
        """
        初始化
        :param sizes:
            如果想要初始化一个层数为3,里面神经元数量分别为:2,3,1 的神经网络,那么 sizes = [2,3,1]
        """
        self.num_layers = len(sizes)
        self.sizes = sizes
        self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
        self.weights = [np.random.randn(y, x)
                        for x, y in zip(sizes[:-1], sizes[1:])]


前面已经说了 S 型神经元,那么此时激活函数实现如下,更加具体的代码请参考network.py[7]:

def sigmoid(z):
    """The sigmoid function."""
    return 1.0/(1.0+np.exp(-z))

代码已经准备就绪,下面可以开始进行模型训练:

import mnist_loader, network


training_data, validation_data, test_data = mnist_loader.load_data_wrapper()


net = network.Network([784, 30, 10])
net.SGD(list(training_data), 30, 10, 3.0, test_data=list(test_data))


# Output
Epoch 0: 9023 / 10000
Epoch 1: 9222 / 10000
Epoch 2: 9312 / 10000
Epoch 3: 9312 / 10000
Epoch 4: 9383 / 10000
Epoch 5: 9421 / 10000
Epoch 6: 9432 / 10000
Epoch 7: 9421 / 10000
Epoch 8: 9454 / 10000
Epoch 9: 9447 / 10000

看结果,十次迭代后,轻轻松松突破 94%

参考

  • 文中涉及代码[8]

  • Neural Networks and Deep Learning[9]

  • Neural Networks and Deep Learning 中文版[10]

  • 神经网络浅讲:从神经元到深度学习[11]

  • neural-networks-and-deep-learning 官方 git 仓库[12]

参考资料

[1]

Neural Networks and Deep Learning: http://neuralnetworksanddeeplearning.com/index.html

[2]

Michael Nielsen: http://michaelnielsen.org/

[3]

A logical calculus of the ideas immanent in nervous activity: http://cns-pc62.bu.edu/cn550/Readings/mcculloch-pitts-43.pdf

[4]

nndl_chapter01: https://github.com/howie6879/pylab/blob/master/pylab/books/nndl/chapter01/chapter01.ipynb

[5]

MNIST: http://yann.lecun.com/exdb/mnist/

[6]

neural-networks-and-deep-learning 官方git仓库: https://github.com/mnielsen/neural-networks-and-deep-learning

[7]

network.py: https://github.com/mnielsen/neural-networks-and-deep-learning/blob/master/src/network.py

[8]

文中涉及代码: https://github.com/howie6879/pylab/blob/master/pylab/books/nndl/chapter01/chapter01.ipynb

[9]

Neural Networks and Deep Learning: http://neuralnetworksanddeeplearning.com/index.html

[10]

Neural Networks and Deep Learning 中文版: https://github.com/zhanggyb/nndl

[11]

神经网络浅讲:从神经元到深度学习: http://www.cnblogs.com/subconscious/p/5058741.html

[12]

neural-networks-and-deep-learning 官方git仓库: https://github.com/mnielsen/neural-networks-and-deep-learning

如果你喜欢且支持本篇文章,为什么不点好看且转发让更多的朋友看到呢?

点击阅读原文,查看博文地址。

往期推荐:

神经网络基础

如何用Python创建一个简单的神经网络

不论微信钉钉还是什么软件,我写了个通用的消息监控处理机器人

【教程&工具】微信同步文章到Bear

【小工具】极客时间&GitChat专栏下载脚本

我的Chrome浏览器插件

oh-my-zsh: 让终端飞

JupyterLab:程序员的笔记本神器

如何实现一个Python爬虫框架

[程序员福利] 获取Lynda视频课程免费账户

Sanic中文教程合集:免费下载

Neural Networks and Deep Learning阅读笔记(1)手写字符识别 Neural Networks and Deep Learning阅读笔记(1)手写字符识别 刚开始开始学习深度学习,找了一本比较简单的书来看看,顺便记个笔记。我是那种不记笔记估计看完一页忘一页的人╮(╯▽╰)╭嘻嘻嘻 emmm这篇笔记就是我自己的碎碎念啦,不严谨而且中英文随便换着用 第一章手写字符识别,通过这个简单的例子讲了神经网络的一些基本概念,包括神经元、感知器、随机梯度下降等。(好绝望,这... 阅读详情

相关推荐

[学习笔记] Neuron Networks and Deep Learning

   文章内容是基于Micheal Nielsen在 http://neuralnetworksanddeeplearning.com 上提供教程《Neural networks and Deep learning》进行的个人学习理解。方便自己温故而知新,加深理解。此文仅为学习笔记,请辩证地进行阅读,还请多多指教。

huberd的博客 716

神经网络

0 绪论 应用范围 模式识别最优化问题计算自动控制信号处理图像处理人工智能 1 基本概念 1.1 神经元模型 MP模型 思想:神经细胞的工作方式处于兴奋或抑制。基于此,引入硬极限函数。 神经元之间的信号连接强度取决于突触状态,在MP模型中,神经元的每个突出的活动前度用一个固定的实数即权值来模拟,每个神经元模型都可以从数十个甚至上百个其他神经元接收信息,产生

wbin91 1343

Neural networks and deep learning 概览

Neural networks and deep learning 概览

qq_44894516的博客 274

TensorFlow官方教程《Neural Networks and Deep Learning》译(第一章)

– 更新中 译自:Neural Networks and Deep Learning 成果预展示 如果你能坚持阅读完本章, 你可以获得如下的成果: 上图中的命令行窗口输出为: Epoch 0: 9095 / 10000 Epoch 1: 9213 / 10000 Epoch 2: 9299 / 10000 Epoch 3: 9358 / 10000 ... Epoch 27

萧萧的专栏 1万+

读书笔记--Neural Networks and Deep Learning(CH1)

第一章:使用神经网络识别手写数字1.1 感知器20世纪五、六十年代由科学家 Frank Rosenblatt 发明,感知器是一种“人工神经元”。上图为一个简单的感知器 输入:x1 x2 x3 权重(表⽰相应输⼊对于输出重要性的实数):w1 w2 w3 输出:0或1 阈值:和权重一样,阈值是一个实数,一个神经元的参数用更精确的代数形式表示为下图: 为了简化感知器的数学描述,我们做两个变动。

忧郁一休 1795

Neural Networks and Deep Learning之中文翻译-第一章 用神经网络识别手写数字

Neural Networks and Deep Learning之中文翻译-第一章 用神经网络识别手写数字

wangchongttg的博客 1255

Neural Networks and Deep Learning第三周

Overview of Neural Network回顾第一周的neural network,第一个neural network是z,第二个是theta,上一个传入下一个。拿单层神经网络来说,样本的值x1,x2...xn是input layer,是输入层;hidden layer是function layer,负责把input layer的值进行处理,然后传入output layer。传出来的值就...

gaoyishu91的博客 692

Neural Networks and Deep Learning 1

本章我做的矩阵乘法的地方与这本书后面刚好相反,我这地方答题用的矩阵乘相当于书本中交换转置相乘 目录 目录 Ch 01 Using neural nets to recognize handwritten digits Sigmoid neurons A simple network to classify handwritten digits Learning with gradi...

我的博客 563

Neural Networks and Deep Learning习题解答--神经网络结构

神经网络与深度学习习题解答 Neural Networks and Deep Learning(作者 Michael Nielsen)书中第二章Using neural nets to recognize handwritten digits的A simple network to classify handwritten digits一节,该节简单说明了神经网络原理并给出一些启发式的思考。该节...

剑启郁兰的博客 3774

neural-networks-and-deep-learning书籍源代码

neural-networks-and-deep-learning书籍的一些demo,使用python2编写,有需要可以下载

Neural Networks and Deep Learning的手写数字识别python3代码

Neural Networks and Deep Learning的手写数字识别例程的python3版本,亲自在python shell下修改仿真后,测试无bug

Neural Networks and Deep Learning

Neural Networks and Deep Learning Neural Networks and Deep Learning What this book is about On the exercises and problems Using neural nets to recognize handwritten digits Percept

凌风探梅的专栏 1995

深度学习(花书)代码和笔记

深度学习(花书)代码和笔记:一份深度学习的笔记(英文),以及相关的代码

Neural Networks and Deep Learning 的MNIST数据可视化

Neural Networks and Deep Learning中我有跟着作者一直阅读这本书,但是后来看到了第三章 可以觉得内容有点冗长,总结了一下,我自己过去一周阅读第三章花费了不少时间,但是收获不是很多(因为第三章的内容在第一第二章已经提过),后来甚至老师在提出希望我每十天总结一篇学习汇报的时候 我无从下手 于是我就去和别人讨论自己的问题, 总结自己的问题 首先,第一第二章对于初学者来书真是圣书,一下子带你写一个可以识别数字的神经网络,注意这里只是神经网络,而非实现其背后的目的-识别数字,而背后要自己

yyx3040的博客 379

NeuralNetworksAndDeepLearning

NeuralNetworksAndDeepLearning中英文混合版

基于深度学习网络(deep learning network)的手写体识别matlab代码

基于深度学习网络(deep learning network)的手写体识别matlab代码

Neural Networks and Deep Learning CH1

CHAPTER 1 Using neural nets to recognize handwritten digitsPerceptrons Sigmoid neurons The architecture of neural networks A simple network to classify handwritten digits Learning with gradient descen

渐近自由 811

别再只盯着YOLOv8了!手把手带你用PaddleDetection的PP-YOLOE+搞定你的第一个检测项目

本文介绍了PP-YOLOE+在目标检测领域的优势与应用实践,对比YOLOv8展示其在精度、速度和部署便利性上的突破。通过详细的代码示例和实战教程,帮助开发者快速上手PaddleDetection工具链,实现产业级目标检测项目,提升开发效率。

weixin_42701915的博客 184
上一篇: 【小工具】一键隐藏/显示MacOS的应用图标
下一篇: 反向传播算法如何工作
老胡的储物柜
博客等级 码龄12年 1141粉丝 284原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值