Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >神经网络模型解决分类问题的思考方式

神经网络模型解决分类问题的思考方式

原创
作者头像
人工智能的秘密
发布于 2017-12-25 12:17:20
发布于 2017-12-25 12:17:20
2.4K0
举报

回顾

昨天介绍了神经网络的基本模型结构,可分类为前向传播神经网络,循环神经网络(RNN);介绍了神经网络中,梯度下降的原理推导,以小球下坡作为实例阐述梯度下降;分析了神经网络模型解决机器学习问题,与传统的机器学习算法的异同;并初步介绍了手写字分类的背景知识,欢迎参考:

深度学习|神经网络模型简介和梯度下降求解

下面,通过经典的手写字数据集来进一步认识神经网络模型解决分类问题的思考方式,原理,代码实现,通过这篇您学到如下重要的知识,这些是入门深度学习必须要掌握的理论和工具:

  1. 拿到一个分类任务后,通过神经网络模型求解的思维方式
  2. 神经网络前向传播原理
  3. SGD 的实现原理(包括代码)
  4. 反向传播的代码实现(接下来几天详细推送反向传播的原理)
  5. 评估分类结果精确度的方法
  6. 如何设定与某个问题相关的特定神经网络

神经网络模型求解手写字分类的核心代码

2.1 手写字分类问题解决步骤

手写字分类可以分解为2类子问题,第一,把图像分解为连续的按位分开的单个数字图像,例如,将图像

分解为如下的6个图像:

然后,接下来对每个小图像,建立神经网络模型学习,建立的NN模型如下,先初步解释下为什么是这样,因为每个小图像的像素为:28 by 28 = 784,共784个像素点,每个像素点看做一个特征,对应一个输入神经元,至于中间的隐含层的个数,为15个,至于如何构造隐含层,隐含层的意义是什么,会在接下来谈,输出层为10个神经元,是因为0~9共10个数字。

2.2 训练神经网络

训练神经网络的过程,就是求解所有神经元的权重参数,每层网络的偏置量,这样就可以进行手写字的分类预测了,输入小图像5后,经过这套网络,可以得出数字分类为5吗?

2.3 梯度下降求权重参数和偏置量

昨天推导了梯度下降求权重参数和偏置量的过程,接下来,看看神经网络模型,求解手写字分类的详细过程。

2.4 代码实现

模块实现SGD的前向神经网络的学习算法,主函数为 SGD,里面涉及到后向传播求梯度的技术,详细研究这些代码对于深刻理解神经网络模型做分类任务有重大帮助。

下面写的这些代码,带有详细的注释,建立 Network 类,里面的方法用深蓝色字体加粗,注释用红色字体标注。

import random

import numpy as np

class Network(object):

     def __init__(self, sizes):

        """

        参数,sizes : 神经网络的结构尺寸,是tuple,比如(3,2,1),

        输入层为3个神经元,

        中间层为2个神经元,

        输出层为1个神经元

        类内全局:sizes

        biases:隐含层,输出层的偏置量

        weights:各个神经元的权重参数,[[15 by 784],[10 by 15]]

        """

        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:])]

    def feedforward(self, a):

"""

       前向传播

        a 是输入

        返回神经网络的输出: sigmoid(w*a + b)

        """

        for b, w in zip(self.biases, self.weights):

            a = sigmoid(np.dot(w, a)+b)

        return a

    def SGD(self, training_data, epochs, mini_batch_size, eta,

            test_data=None):      

"""

        采用 mini-batch SGD 训练神经网络

        training_data : [(x,y)],x 代表训练的输入, y 代表输出

        epochs:比如,迭代100次为一波

        mini_batch_size:批梯度下降,一次迭代,采用的样本个数,比如为10个样本

        eta : 学习率

        """

        if test_data: n_test = len(test_data)

        n = len(training_data)

        for j in range(epochs):

            random.shuffle(training_data)

            mini_batches = [

                training_data[k:k+mini_batch_size]

                for k in xrange(0, n, mini_batch_size)]

            for mini_batch in mini_batches:

                self.update_mini_batch(mini_batch, eta)

            if test_data:

                print ("Epoch {0}: {1} / {2}".format(

                    j, self.evaluate(test_data), n_test))

            else:

                print ("Epoch {0} complete".format(j))

    def update_mini_batch(self, mini_batch, eta):

"""

        更新神经网络的权重(类内全局参数weights)和偏置量(类内全局参数:biases),

        使用后传播的梯度下降方法,这个方法的核心是后传播算法backprop

        mini_batch:[(x,y)],x是输入,y是输出

        """ 

        nabla_b = [np.zeros(b.shape) for b in self.biases]

        nabla_w = [np.zeros(w.shape) for w in self.weights]

        for x, y in mini_batch:

            delta_nabla_b, delta_nabla_w = self.backprop(x, y)

            nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]

            nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]

        self.weights = [w-(eta/len(mini_batch))*nw

                        for w, nw in zip(self.weights, nabla_w)]

        self.biases = [b-(eta/len(mini_batch))*nb

                       for b, nb in zip(self.biases, nabla_b)]

    def backprop(self, x, y): """ 通过后向传播得出偏置量和权重参数的梯度方向,         返回值 ,biases:每层的偏置量的梯度         weights:每层神经元的权重参数         """         nabla_b = [np.zeros(b.shape) for b in self.biases]         nabla_w = [np.zeros(w.shape) for w in self.weights] # 前向传播         activation = x         activations = [x] # 分层存储每层的激活节点         zs = [] # 分层存储每层的 Z 向量         for b, w in zip(self.biases, self.weights):             z = np.dot(w, activation)+b             zs.append(z)             activation = sigmoid(z)             activations.append(activation) # 后向传播         delta = self.cost_derivative(activations[-1], y) * \             sigmoid_prime(zs[-1])         nabla_b[-1] = delta         nabla_w[-1] = np.dot(delta, activations[-2].transpose()) # L = 1 表示最后一层神经元, L = 2 倒数第二层神经元         for layer in range(2, self.num_layers):             z = zs[-layer]             sp = sigmoid_prime(z)             delta = np.dot(self.weights[-layer+1].transpose(), delta) * sp             nabla_b[-layer] = delta             nabla_w[-layer] = np.dot(delta, activations[-layer-1].transpose())         return (nabla_b, nabla_w)

    def evaluate(self, test_data):

"""

        输出层中,输出值最大的神经元对应的索引为分类,比如神经元5的激活值

        最大,则认为输入的图像为5 

        """

        test_results = [(np.argmax(self.feedforward(x)), y)

                        for (x, y) in test_data]

        return sum(int(x == y) for (x, y) in test_results)

    def cost_derivative(self, output_activations, y):

        """

        成本函数的导数

        """ 

        return (output_activations-y)

def sigmoid(z):

"""The sigmoid 函数."""

    return 1.0/(1.0+np.exp(-z))

def sigmoid_prime(z):

"""sigmoid 函数的导数"""

    return sigmoid(z)*(1-sigmoid(z))

以上就是前向神经网络的后向传播梯度下降求解的完整代码。

附:

手写字的数据集下载,请参考:http://yann.lecun.com/exdb/mnist/

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
TensorFlow从0到1 | 第十一章 74行Python实现手写体数字识别
到目前为止,我们已经研究了梯度下降算法、人工神经网络以及反向传播算法,他们各自肩负重任: 梯度下降算法:机器自学习的算法框架; 人工神经网络:“万能函数”的形式表达; 反向传播算法:计算人工神经网络梯度下降的高效方法; 基于它们,我们已经具备了构建具有相当实用性的智能程序的核心知识。它们来之不易,从上世纪40年代人工神经元问世,到80年代末反向传播算法被重新应用,历经了近半个世纪。然而,实现它们并进行复杂的数字手写体识别任务,只需要74行Python代码(忽略空行和注释)。要知道如果采用编程的方法(非学习的
用户1332428
2018/03/08
1.2K0
TensorFlow从0到1  | 第十一章 74行Python实现手写体数字识别
反向传播算法原理推导及代码实现
《实例》阐述算法,通俗易懂,助您对算法的理解达到一个新高度。包含但不限于:经典算法,机器学习,深度学习,LeetCode 题解,Kaggle 实战。期待您的到来! 01 — 回顾 昨天,分析了手写字数据集分类的原理,利用神经网络模型,编写了SGD算法的代码,分多个epochs,每个 epoch 又对 mini_batch 样本做多次迭代计算,详细的过程,请参考: 这其中,非常重要的一个步骤,便是利用反向传播(BP)算法求权重参数的梯度,偏置量的梯度。下面根据以下几个问题展开BP算法: 什么是BP算法? 为什
企鹅号小编
2018/02/12
1.1K0
反向传播算法原理推导及代码实现
连载 | 深度学习入门第六讲
1.6 实现我们的网络来分类数字 好吧,现在让我们写一个学习如何识别手写数字的程序,使用随机梯度下降算法和 MNIST训练数据。我们需要做的第一件事情是获取 MNIST 数据。如果你是一个 git 用戶,那么你能够 通过克隆这本书的代码仓库获得数据, git clone https://github.com/mnielsen/neural-networks-and-deep-learning.git 如果你不使用 git,也可以从这里下载数据和代码。 顺便提一下,当我在之前描述 MNIST 数据时,我
用户1107453
2018/06/21
4360
神经网络中 BP 算法的原理与 Python 实现源码解析
最近这段时间系统性的学习了BP算法后写下了这篇学习笔记,因为能力有限,若有明显错误,还请指出。 目录 1、什么是梯度下降和链式求导法则 2、神经网络的结构 3、BP算法中的执行流程(前向传递和逆向更新) 4、输出层和隐藏层权重以及偏置更新的推导 5、Python 实现源码解析 6、手写数字识别实例 7、训练神经网络中有哪些难点(TODO) 梯度下降和链式求导法则 假设
用户1332428
2018/03/08
2K0
神经网络中 BP 算法的原理与 Python 实现源码解析
《neural network and deep learning》题解——ch03 再看手写识别问题题解与源码分析
http://blog.csdn.net/u011239443/article/details/77649026
小爷毛毛_卓寿杰
2019/02/13
4590
《neural network  and deep learning》题解——ch03 再看手写识别问题题解与源码分析
《neural network and deep learning》题解——ch02 Network源码分析
http://blog.csdn.net/u011239443/article/details/75008380
小爷毛毛_卓寿杰
2019/02/13
1.5K0
《neural network and deep learning》题解——ch03 其他技术(momentun,tanh)
http://blog.csdn.net/u011239443/article/details/77848503
小爷毛毛_卓寿杰
2019/02/13
4920
《neural network and deep learning》题解——ch03 其他技术(momentun,tanh)
小白也能看懂的BP反向传播算法之Surpass Backpropagation
上篇文章小白也能看懂的BP反向传播算法之Further into Backpropagation中,我们小试牛刀,将反向传播算法运用到了一个两层的神经网络结构中!然后往往实际中的神经网络拥有3层甚至更多层的结构,我们接下来就已一个三层的神经网络结构为例,分析如何运用动态规划来优化反向传播时微分的计算!
desperate633
2018/08/23
8690
TensorFlow从0到1 - 11 - 74行Python实现手写体数字识别
到目前为止,我们已经研究了梯度下降算法、人工神经网络以及反向传播算法,他们各自肩负重任: 梯度下降算法:机器自学习的算法框架; 人工神经网络:“万能函数”的形式表达; 反向传播算法:计算人工神经网络梯度下降的高效方法; 基于它们,我们已经具备了构建具有相当实用性的智能程序的核心知识。它们来之不易,从上世纪40年代人工神经元问世,到80年代末反向传播算法被重新应用,历经了近半个世纪。然而,实现它们并进行复杂的手写体数字识别任务,只需要74行Python代码(忽略空行和注释)。要知道如果采用编程的方法(非学习
袁承兴
2018/04/11
1.8K0
TensorFlow从0到1 - 11 - 74行Python实现手写体数字识别
李理:从Image Caption Generation理解深度学习(part II)
本系列文章面向程序员,希望通过Image Caption Generation,一个有意思的具体任务,深入浅出地介绍深度学习的知识,涉及到很多深度学习流行的模型,如CNN,RNN/LSTM,Attention等。本文为第二篇。 作者李理,MDCC 2016 移动开发者大会人工智能与机器人专场的出品人,邀请人工智能一线专家担任演讲嘉宾,从无人驾驶、智能机器人、智能应用开发实战等方面解读人工智能技术的内涵及其对移动开发工作的影响。 大会目前火热报名中,门票6.8折优惠即将结束,倒计时2天!(票务详情链接,欲购从
用户1737318
2018/06/06
9140
《neural network and deep learning》题解——ch03 如何选择神经网络的超参数
http://blog.csdn.net/u011239443/article/details/77748116
小爷毛毛_卓寿杰
2019/02/13
4430
《neural network and deep learning》题解——ch03 如何选择神经网络的超参数
取代Python?Rust凭什么
【导语】Rust 也能实现神经网络?在前一篇帖子中,作者介绍了MNIST数据集以及分辨手写数字的问题。在这篇文章中,他将利用前一篇帖子中的代码,通过Rust实现一个简单的神经网络。其目标是探索用Rust实现数据科学工作流程的性能以及人工效率。
AI科技大本营
2019/09/09
1.2K0
取代Python?Rust凭什么
前馈神经网络——深度学习之神经网络核心原理与算法
因上几次读者反映,公式代码有乱码和不规整的问题,小编有改善哟,这篇文章开始亲们会看到效果的哟~
用户1332428
2018/07/30
1.2K0
前馈神经网络——深度学习之神经网络核心原理与算法
BAT面试题49:推导下反向传播Backpropagation
神经网络每个神经元的连接关系,用符合如何表达呢? 下面定义一种表达方式,如下图所示,含有一个隐含层的神经网络,图中标出的w的含义为:第三层的第2个神经元与第二层的第4个神经元间的权重参数。
double
2019/03/07
2.7K0
神经网络学习(十三)卷积神经网络的MATLAB实现
系列博客是博主学习神经网络中相关的笔记和一些个人理解,仅为作者记录笔记之用,不免有很多细节不对之处。博主用Numpy实现了一个小巧的深度学习框架kitorch,可以方便实现CNN: MNIST例子。请不要再私信我要matlab的代码了。
全栈程序员站长
2022/11/08
1.6K0
神经网络学习(十三)卷积神经网络的MATLAB实现
小白都能看懂的神经网络教程:从原理到优化如此简单
一位来自普林斯顿的华人小哥Victor Zhou,写了篇神经网络入门教程,在线代码网站Repl.it联合创始人Amjad Masad看完以后,给予如是评价。
量子位
2019/04/23
2.3K1
小白都能看懂的神经网络教程:从原理到优化如此简单
神经网络算法
20 世纪五、六⼗年代,科学家 Frank Rosenblatt其受到 Warren McCulloch 和 Walter Pitts早期的⼯作的影响,发明了感知机(Perceptrons)。
foochane
2019/05/23
9080
神经网络算法
数据科学 IPython 笔记本 四、Keras(上)
深度学习允许由多层组成的计算模型,来学习具有多个抽象级别的数据表示。这些方法极大地改进了语音识别,视觉对象识别,物体检测,以及药物发现和基因组学等许多其他领域的最新技术。
ApacheCN_飞龙
2022/05/07
1.8K0
数据科学 IPython 笔记本 四、Keras(上)
机器学习Hello World:波士顿房价预测(线性回归模型)
虽然之前接触过一些深度学习的知识,了解了一些理论知识,但是其实做出来的东西都是一些浅层的应用(只会把现成的模型进行迁移学习),而且很多时候都是知其然不知其所以然。现在决定好好学一学。
灯珑LoGin
2022/10/31
5.3K1
机器学习Hello World:波士顿房价预测(线性回归模型)
从基本原理到梯度下降,小白都能看懂的神经网络教程
神经元:神经元是神经网络的基本单元,类似于生物体内的神经元。一个神经元接收一些输入,做一个简单的计算,然后产生一个输出。
七条猫
2024/10/14
1570
从基本原理到梯度下降,小白都能看懂的神经网络教程
推荐阅读
相关推荐
TensorFlow从0到1 | 第十一章 74行Python实现手写体数字识别
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档