神经网络基础详解

   日期:2020-11-10     浏览:90    评论:0    
核心提示:神经网络基础1、感知机:计算机模拟大脑经行信息处理的过程。有n个输入数据,通过权重与各数据之间的计算和,比较激活函数结果,得出输出。解决分类问题。http://playground.tensorflow.org

相信喜欢机器学习、深度学习的小伙伴对神经网络这个词肯定不陌生,那么什么是神经网络呢?它可以用来做什么呢?怎么做呢?今天好好总结一下。

一、神经网络是什么?

是一种模仿生物神经网络的结构和功能的数学模型或计算模型。神经网络由大量的人工神经元联结进行计算。大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自适应系统。现代神经网络是一种非线性统计性数据建模工具,常用来对输入和输出间复杂的关系进行建模,或用来探索数据的模式。
典型的网络结构为:

至于输入层是什么,隐藏层是什么,输出层是什么,怎么输入,怎么输出,下面会写。先了解了神经网络的基本结构。

二、神经网络可以用来做什么

举2个栗子
猫狗分类:有一大堆猫、狗照片,把每一张照片送进一个机器里,机器需要判断这幅照片里的东西是猫还是狗。
手写数字识别:将手写的图片读入到机器中,机器自动判定这个数字是什么。
简单地说,就是对图片的一个识别和一个简单的分类。
为了更方便理解神经网络,在介绍神经网络之前先来介绍一下感知机。

三、感知机

感知机:计算机模拟大脑经行信息处理的过程。有n个输入数据,通过权重与各数据之间的计算和,比较激活函数结果,得出输出。解决分类问题。
其结构如下图,是不是和线性回归比较像,线性回归是y=w1x1+w2x2+……+wnxn+b。而感知机和它及其类似,感知机通过输出来判定是哪一类。

为了简单理解,我们先来看一个例子。

假设给定两个特征x1,x2,设置权重w1=1,w2=1,设置阈值为1.5,那么计算后可知(0,1)、(1,0)的结果为1,小于1.5,(0,0)的结果为0,小于1.5,(1,1)的结果为2,大于1.5,所以就把四个样本点分为了2类,其中的黑线就为分类线,但是很显然这个线是不唯一的,那如何来确定呢,继续看。

好了,上面我们已经用感知机解决了一个简单的二分类问题,那么肯定大家有疑问,如果我要解决三类、四类、更多类的问题怎么办呢?
当然是要画两条线了,但是两条线是怎么画出来的呢?用两个感知机!


有两个感知机也就意味着有了两个权重,有了两个输出,即有了两条线

多分类,需要多个感知机即可。如果想要更形象的了解是如何进行分类的,可以来玩一下这个网站
好了,到现在感知机的内容算是结束了。明白了吧。

但是感知机和我们的神经网络有什么关系呢?我们要讲的是神经网络啊,别急!

感知机是神经网络的基础,简单地说,神经网络就是由多个感知机运算组成的。其实感知机就是神经元。

四、神经网络


神经网络的结构:输入层、隐藏层、输出层。
神经网络的特点:

  • 输入向量的维度的输入神经元的个数相同
  • 每个连接层都有个权值
  • 同一层神经元之间没有连接
  • 由输入层、隐层、输出层组成
  • 第N层和N-1层的所有神经元连接,也叫全连接。

4.1神经网络工作流程

大家都知道神经网络进行图片分类很厉害,但是图片怎么输入呢,我们之前不都是直接输入的特征吗?
图片的特征就是像素。打开图片属性可以查看像素。
来看张图片,这是minist手写数据集中的一张。MINIST数据集中的每一张图片有28*28像素点组成,即有28 * 28=724个像素点,每个像素点的值区间在0~255之间。也就是说对这样一张图片进行识别需要784个特征,x1,x2,x3……x784。也就是说输入层有784个元素。下面确定全连接层(输出层),因为数字有10类,所以最后要分成10类(0,1,2……9),所以全连接层有10个元素。至此,已经确定了输入层和输出层。


那么中间层怎么确定呢?不急,下面说。我们先掠过中间层。建立好一个简单的模型。那么通过计算可以知道,需要有784*10个权重。也就是说需要7840个神经元。最后还有10个偏置。


那么输出的10个结果是什么样的呢?机器是不能直接输出判断的结果1,2,3的,而是输出的概率。在哪一个位置输出的概率大,则认为这张图片是什么数字。这就需要用到softmax。

4.2 softmax选择器

加上softmax后的结构如下图。

假设我们有一个数组,V,Vi表示V中的第i个元素,那么这个元素的softmax值为:
也就是说,是该元素的指数,与所有元素指数和的比值。这就是softmax的公式。
举个例子:假设一些x1,x2,x3经过中间层、输出层,输出的3个数字分别为20,120,40,那么我们可以带入到softmax公式中计算(ps:此处算出来的数都是我编的,主要是为了方便理解)
S1=e20/( e20+e120+e40)=0.2
S2=e120/( e20+e120+e40)=0.3
S3=e40/( e20+e120+e40)=0.5
计算出来的概率值和应该为1。

至此,我们已经得到了概率值。
那么有了概率之后,怎么来反映到标签呢?用one-hot编码。

4.3 one-hot编码

One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。
One-Hot编码是分类变量作为二进制向量的表示。这首先要求将分类值映射到整数值。然后,每个整数值被表示为二进制向量,除了整数的索引之外,它都是零值,它被标记为1。
内部很繁琐,如果想详细了解,请百度。
下面举个栗子帮助理解:
比如我们要手写识别的数字1,我们需要将真实值转化为one-hot编码。则将1转化为了[0,1,0,0,0,0,0,0,0,0]。同理2可以转化为[0,0,1,0,0,0,0,0,0,0]
那么现在总结一下,我们完成了哪些工作:我们有了输入,有了输出(概率),有了真实值。下面的问题是,如何将输出和真实值联系在一起。
这就需要用到交叉熵损失

4.4交叉熵损失

交叉熵是什么:交叉熵刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近。

比如说我们softmax后的结果为[0.11,0.22,0.13,0.14……0.12],对应的真实值one-hot编码是[0,1,0,0,0,0,0,0,0,0]。那么代入公式为H(y)=-(0log(0.11)+1log(0.22)+……)
实质就是衡量两者的的差的大小。我们希望得到的是如果softmax后的结果为[0,1,0,0,0,0,0,0,0,0],那怎么最后得到的结果就是-1log1=0(因为其余项都是0),也就是如果交叉熵为0,那么预测百分之百正确。
所以我们需要做的就是提高1类别对应的softmax后的那个数中的概率。我们希望把[0.11,0.22,0.13,0.14……0.12]中0.22那个位置的概率提高到1,从而把该标签判定为1。
下面就是让将交叉熵损失尽可能的小,需要通过不断更新权重,下面就要介绍到反向传播算法了。

4.5 反向传播算法

反向传播的作用:前向传递输入信号直至输出产生误差,反向传播误差信息更新权重矩阵,使得交叉熵最小。
反向传播算法的内部是复杂的,先了解这么多,一会在代码中介绍。

我们还要知道,神经网络是以矩阵的方式计算的。
如下图,输入层中的手写图片张数由实际确定,所以为None,但是像素是785,所以输入层的矩阵为[None,784],又知道最后输出的是10个结果,所以权重的个数为784*10,最后一层的矩阵为[None,10],还要记得有偏置,有10个。这便是神经网络的计算流程。

代码

from tensorflow.examples.tutorials.mnist import input_data#tensorflow自带数据集
import tensorflow as tf
#实现一个简单的神经网络识别手写数字(无中间层)
def full_connected():
    mnist=input_data.read_data_sets("Mnist",one_hot=True)#下载数据集并保存在Mnist文件中
#1、建立占位符,x[None,784],y_true[None,10]
    with tf.variable_scope("data"):
        x=tf.placeholder(tf.float32,[None,784])
        y_true=tf.placeholder(tf.float32,[None,10])
#2、建立一个全连接层的神经网络 w[784,10],b[10]
    with tf.variable_scope("fc_model"):
        #随机初始化权重和样本
        weight=tf.Variable(tf.random_normal([784,10],mean=0.0,stddev=1.0),name="w")#随机初始化w
        bias=tf.Variable(tf.constant(0.0,shape=[10]))#注意,bias为一维数组,就是10个数,所以定义shape=[10]
        y_predict=tf.matmul(x,weight)+bias#预测的结果 [None,784]*[784,10]+[10]=[None,10]
#3、求出样本的损失值,然后求平均值
    with tf.variable_scope("soft_cross"):
        loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))#tf.nn.softmax_cross_entropy_with_logits可计算交叉熵损失
#4、反向传播(梯度下降)
    with tf.variable_scope("optimizer"):
        train_op=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
#5、计算准确率
    with tf.variable_scope("acc"):
        equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))#equal_list为一个列表,即y_true与y_predict同则为1,否则为0,最后的equal_list是一个类似[0,0,0,0,1,1……]的列表
        accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))#把equal_list转化为float类型,并求平均值,即为准确率
#定义初始化变量op
    init_op=tf.global_variables_initializer()
    with tf.Session() as sess:
        sess.run(init_op)
        for i in range(200):
            mnist_x,mnist_y=mnist.train.next_batch(50)#每次取出50个值进行训练
            sess.run(train_op,feed_dict={ x:mnist_x,y_true:mnist_y})#注意,一定要用feed_dict,因为前面使用了占位符
            print("训练第%d步,准确率为:%f" %(i,sess.run(accuracy,feed_dict={ x:mnist_x,y_true:mnist_y})))
    return None
if __name__=="__main__":
    full_connected()

在tensoboard中进行可视化完整代码

from tensorflow.examples.tutorials.mnist import input_data#tensorflow自带数据集
import tensorflow as tf
def full_connected():
    mnist=input_data.read_data_sets("Mnist",one_hot=True)#下载数据集并保存在Mnist文件中
#1、建立占位符,x[None,784],y_true[None,10]
    with tf.variable_scope("data"):
        x=tf.placeholder(tf.float32,[None,784])
        y_true=tf.placeholder(tf.float32,[None,10])
#2、建立一个全连接层的神经网络 w[784,10],b[10]
    with tf.variable_scope("fc_model"):
        #随机初始化权重和样本
        weight=tf.Variable(tf.random_normal([784,10],mean=0.0,stddev=1.0),name="w")#随机初始化w
        bias=tf.Variable(tf.constant(0.0,shape=[10]))#注意,bias为一维数组,就是10个数,所以定义shape=[10]
        y_predict=tf.matmul(x,weight)+bias#预测的结果 [None,784]*[784,10]+[10]=[None,10]
#3、求出样本的损失值,然后求平均值
    with tf.variable_scope("soft_cross"):
        loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))#tf.nn.softmax_cross_entropy_with_logits可计算交叉熵损失
#4、反向传播(梯度下降)
    with tf.variable_scope("optimizer"):
        train_op=tf.train.GradientDescentOptimizer(0.2).minimize(loss)
#5、计算准确率
    with tf.variable_scope("acc"):
        equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))#equal_list为一个列表,即y_true与y_predict同则为1,否则为0,最后的equal_list是一个类似[0,0,0,0,1,1……]的列表
        accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))#把equal_list转化为float类型,并求平均值,即为准确率
#定义初始化变量op
    init_op=tf.global_variables_initializer()   
#在tensorboard中可视化-------------------------------------------- 
#收集变量(单个数字)
    tf.summary.scalar("losses",loss)
    tf.summary.scalar("acc",accuracy)
#收集变量(多维度变量)
    tf.summary.histogram("weights",weight)
    tf.summary.histogram("bias",bias)
#合并变量
    merged=tf.summary.merge_all()
#tensorboard进行可视化-------------------------------------------- 
        with tf.Session() as sess:
        sess.run(init_op)
        filewriter=tf.summary.FileWriter("路径",graph=sess.graph)#建立event文件并写入
        for i in range(200):#200为迭代步数
            mnist_x,mnist_y=mnist.train.next_batch(50)
            sess.run(train_op,feed_dict={ x:mnist_x,y_true:mnist_y})
            #写入每步训练值
            summary=sess.run(merged,feed_dict={ x:mnist_x,y_true:mnist_y})
            filewriter.add_summary(summary,i)
            print("训练第%d步,准确率为:%f" %(i,sess.run(accuracy,feed_dict={ x:mnist_x,y_true:mnist_y})))
    return None
if __name__=="__main__":
    full_connected()

可视化结果

测试代码

FLAGS=tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('f', '', 'kernel')
tf.app.flags.DEFINE_integer("is_train",1, "指定程序是预测还是训练")
def full_connected():
    mnist=input_data.read_data_sets("Mnist",one_hot=True)#下载数据集并保存在Mnist文件中
#1、建立占位符,x[None,784],y_true[None,10]
    with tf.variable_scope("data"):
        x=tf.placeholder(tf.float32,[None,784])
        y_true=tf.placeholder(tf.float32,[None,10])
#2、建立一个全连接层的神经网络 w[784,10],b[10]
    with tf.variable_scope("fc_model"):
        #随机初始化权重和样本
        weight=tf.Variable(tf.random_normal([784,10],mean=0.0,stddev=1.0),name="w")#随机初始化w
        bias=tf.Variable(tf.constant(0.0,shape=[10]))#注意,bias为一维数组,就是10个数,所以定义shape=[10]
        y_predict=tf.matmul(x,weight)+bias#预测的结果 [None,784]*[784,10]+[10]=[None,10]
#3、求出样本的损失值,然后求平均值
    with tf.variable_scope("soft_cross"):
        loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))#tf.nn.softmax_cross_entropy_with_logits可计算交叉熵损失
#4、反向传播(梯度下降)
    with tf.variable_scope("optimizer"):
        train_op=tf.train.GradientDescentOptimizer(0.2).minimize(loss)
#5、计算准确率
    with tf.variable_scope("acc"):
        equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))#equal_list为一个列表,即y_true与y_predict同则为1,否则为0,最后的equal_list是一个类似[0,0,0,0,1,1……]的列表
        accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))#把equal_list转化为float类型,并求平均值,即为准确率
        
        
        
#定义初始化变量op
    init_op=tf.global_variables_initializer()   
#创建一个saver
    saver=tf.train.Saver()
    with tf.Session() as sess:
        sess.run(init_op)
        if FLAGS.is_train==1:     
            for i in range(200):
                mnist_x,mnist_y=mnist.train.next_batch(50)#每次取出50个值进行训练
                sess.run(train_op,feed_dict={ x:mnist_x,y_true:mnist_y})#注意,一定要用feed_dict,因为前面使用了占位符
                print("训练第%d步,准确率为:%f" %(i,sess.run(accuracy,feed_dict={ x:mnist_x,y_true:mnist_y})))          
#保存模型 
            saver.save(sess,"路径/model")
    
        else:
            saver.restore(sess,"路径/model")
            for i in range(20):
                x_test,y_test=mnist.test.next_batch(1)
                print("第%d张图片,手写数字的目标是%d,预测结果是%d" %(i,sess.run(tf.argmax(y_test,1)),sess.run(tf.argmax(sess.run(y_predict,feed_dict={ x:x_test,y_true:y_test}),1))))

    return None
if __name__=="__main__":
    full_connected()
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服