深度学习之神经网络(第一节)

感知机

在这里插入图片描述
在这里插入图片描述
如上图所示,这里的神经网络是模拟人的神经网络的工作方式所提出的一种理念。
感知机简单来说就是在收集了数据进行处理后由感知机得出结果,就像人喝水,由温觉感受器去感觉水温,然后得出结论要不要喝?

感知机与逻辑回归的关系

在这里插入图片描述
在这里插入图片描述
由上图我们可以看到,当只有一个感知机时,这不就跟逻辑回归一样吗,只是逻辑回归里叫sigmod,以0.5为阈值。上图所示,与或问题好解决,只需要一个感知机就行,如与问题,当w1和w2等于1时,右上角的点的目标值是2,而我阈值假设是1.5,那么大于1.5的是一个类,小于1.5的是另一个类,那么一定能找到一条直线能将(1,1)这个点与其他三个点分开!!如果要解决异或问题,也就是相同为0,不同为1,很明显(0,0)和(1,1)为同类,(0,1)与(1,0)为同类,这时,光凭w1,w2所构成的一条直线是不能将其成功划分的,那么我们就考虑用两条线!!!这时就要增加一个感知机!!到这也许你还是很懵逼,那么我们就直观来感受一下,请点击下面链接!动态感受分类
这个网站就是感受一下如何将右图中的两种原点准确分类!
当只有一个感知机时,最后的分类情况如下:
在这里插入图片描述
我们再看看两个感知机的情况,很明显有两条白线,离最终分类结果又近了一步。
在这里插入图片描述
下面来看看三个感知机,这是中间是个三角形,也就是三条白线线将其分割成最终结果。
在这里插入图片描述

神经网络

神经网络的发展

在这里插入图片描述
在这里插入图片描述

神经网络的特点

在这里插入图片描述
在这里插入图片描述

神经网络的组成

在这里插入图片描述
在这里插入图片描述
输出结果时,并不是直接得到该样本是属于啥类,而是会算出该样本属于所有类别的概率,取最大,这一点又和朴素贝叶斯相似。

浅层人工神经网络模型

在这里插入图片描述
由上图,我们回忆一下,逻辑回归针对二分类问题,也就是是与不是的问题,用的是sigmod(激活函数)。而神经网络是针对多分类问题,利用softmax来得出某样本属于各个类别的概率,关注最大概率的那个。然后策略与优化后面再说!

Mnist数据集神经网络分析

在这里插入图片描述
这个手写的1我们要怎么识别?简单来说就是把这张图数字化,变成以像素来看待的,空白地方计为零,其他地方非零。然后经过大量图片的训练后,将此图传进去,即可判断!!
再来复习一下one-hot编码:

在这里插入图片描述
在这里插入图片描述
再三强调一定要记住神经网络最后的结果是所有分类都有,然后我们利用one-hot编码来进行标记,每一横行都是一个样本,在所属分类下记为1即可。
one-hotAPI介绍
在这里插入图片描述
获取数据
在这里插入图片描述

SoftMax回归

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

损失计算-交叉熵损失公式

在这里插入图片描述
在这里插入图片描述

相关API

全连接-从输入直接到输出

在这里插入图片描述

SoftMax计算、交叉熵

在这里插入图片描述

损失值列表平均值计算

在这里插入图片描述

损失下降API

在这里插入图片描述

准确性计算

equal_list = tf.equal(tf.argmax(y, 1), tf.argmax(y_label, 1))
accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))
在这里插入图片描述
在这里插入图片描述
成功为1,失败为0

Mnist数据集神经网络案例

这里就拿识别手写数字举例!
在这里插入图片描述
在这里插入图片描述
这个数据集里的图片都是28个像素*28个像素的,也就是784个特征,None代指若干个样本,也就是若干行。然后数字是从0~9,一拱十个数字,也就是十个类别。如上图,我这就只举了一层,也就是输入之后经过一层感知机就输出了。特征值是[none,784],
目标值是[none,10],目标值为什么是10列?因为是[none,10]是用的one-hot编码,初始化w是[784,10],这样一来,[none,784]矩阵乘[784,10]=[none,10]。
示例代码:

FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_integer("is_train", 1, "指定程序是预测还是训练")
def full_connected():

    # 获取真实的数据
    mnist = input_data.read_data_sets("./data/mnist/input_data/", one_hot=True)

    # 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.int32, [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")

        bias = tf.Variable(tf.constant(0.0, shape=[10]))

        # 预测None个样本的输出结果matrix [None, 784]* [784, 10] + [10] = [None, 10]
        y_predict = tf.matmul(x, weight) + bias

    # 3、求出所有样本的损失,然后求平均值
    with tf.variable_scope("soft_cross"):

        # 求平均交叉熵损失
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict))

    # 4、梯度下降求出损失
    with tf.variable_scope("optimizer"):

        train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # 5、计算准确率
    with tf.variable_scope("acc"):
   ##这里y_true里面依然有占位符,我们在后面的会话里给他赋值
        equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1))

        # equal_list  None个样本   [1, 0, 1, 0, 1, 1,..........]
        accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

    # 收集变量 单个数字值收集
    tf.summary.scalar("losses", loss)
    tf.summary.scalar("acc", accuracy)

    # 高纬度变量收集
    tf.summary.histogram("weightes", weight)
    tf.summary.histogram("biases", bias)

    # 定义一个初始化变量的op
    init_op = tf.global_variables_initializer()

    # 定义一个合并变量de op
    merged = tf.summary.merge_all()

    # 创建一个saver
    saver = tf.train.Saver()

    # 开启会话去训练
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)

        # 建立events文件,然后写入
        filewriter = tf.summary.FileWriter("./tmp/summary/test/", graph=sess.graph)

        if FLAGS.is_train == 1:

            # 迭代步数去训练,更新参数预测
            for i in range(2000):

                # 取出真实存在的特征值和目标值
                mnist_x, mnist_y = mnist.train.next_batch(50)

                # 运行train_op训练
                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})))

            # 保存模型
            saver.save(sess, "./tmp/ckpt/fc_model")
        else:
            # 加载模型
            saver.restore(sess, "./tmp/ckpt/fc_model")

            # 如果是0,做出预测
            for i in range(100):

                # 每次测试一张图片 [0,0,0,0,0,1,0,0,0,0]
                x_test, y_test = mnist.test.next_batch(1)

                print("第%d张图片,手写数字图片目标是:%d, 预测结果是:%d" % (
                    i,
                    tf.argmax(y_test, 1).eval(),
                    tf.argmax(sess.run(y_predict, feed_dict={x: x_test, y_true: y_test}), 1).eval()
                ))
    return None

深层的神经网络

在这里插入图片描述

卷积神经网络

全连接神经网络的缺点
在这里插入图片描述
也就是说当中间层多了起来,就没法搞了,于是引入下面的卷积神经网络!!!
卷积神经网络的发展历史
在这里插入图片描述
卷积神经网络错误率
在这里插入图片描述

卷积神经网络的结构分析

卷积层

在这里插入图片描述
conv是卷积层,relu是激活函数,pool是池化层。
在这里插入图片描述
数据变化
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面我们来举一个计算卷积层的例子:
初始要识别的图片是55的,通道数1,也就是黑白图片,然后我们设一个33的过滤器(也称之为权重),然后将过滤器放在image的左上角,然后我们知道图片的像素就是特征值,而过滤器是权重,那么当过滤器放在图片左上角时,该过滤器会压着image左上角的九个元素,也是1个33的矩阵,那么我们就可以用这个矩阵乘权重,就会得出来一个值,我们就把他填入feature map得左上角第一个位置,然后filter水平向右移动,又压着新的九个像素,我们再做乘法,把得出的结果填入feature map的第一行第二列。。。然后过滤器再向右移,到头之后又向下移,反正要把图片扫描完!!(这个例子步长为1)
在这里插入图片描述
下面举个例子步长为2:
在这里插入图片描述
道理跟步长为1的一样,最后我们要的是feature map!!也就是卷积之后的这个结果。
卷积层的零填充
我们在移动filter时,有时候不能刚好扫描完图片,那么会超出几个像素,这时有两个策略,第一个是为了不越界,我就少扫描一部分,但这样不够准确。第二个方案是零填充,就是在filter越过图片时,用零去填充图片,因为0乘任何数都为零,所以不会对最终结果造成影响。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上图,我们来计算一下图片28
28,有32个filter时(32组不同权重),每个filter33,步长为1,零填充为1,那么我们最终的输出结果是多少?H2=(28-3+2)/1+1=28,w2=28,然后高等于过滤器数,然后最终的矩阵为[28,28,32],然后对比输入的[28,28,1],就好像将[28,28,1]堆叠了32个一样,所以形象的称为卷积。
多通道图片-外围补充与多Filter
在这里插入图片描述
当识别的图片是彩色时,通道数为3,假设有一个filter,这里面有三个3
3的权重,每个33权重扫描一个图片,只要保证输出结果只有一个就行,因为一个filter对应一个输出output,那么我怎么能保证输出是一个33呢??很简单,将上图每一组权重与自己压着的33的部分相乘,会得到一个值,将这三组权重得到得这个值相加填入最终的33得feature map对应的位置!就想上图所示得样子,最终结果绿框圈起来得-1就是3组权重与分别与自己压着得3*3矩阵相乘并求和而得来的!!
卷积API
在这里插入图片描述

激活函数-Relu

在这里插入图片描述
为什么要这个激活函数而不用sigmod?
在这里插入图片描述
在这里插入图片描述
如上图,这里搞了两层神经元,右边是我加了激活函数所得到的分类图片,如果不加激活函数,是达不到这个效果的,我们就记住以下结论:增加激活函数可以增加网络的非线性分割能力
在这里插入图片描述

池化层(Pooling)计算

在这里插入图片描述
在这里插入图片描述
如上图所示,池化就相当于特征抽取,上图44矩阵是卷积后的结果,我们知道卷积后的数据会变复杂,那么我们一定要对他进行池化处理,这样最终的输出结果会简单一些,也就是去除冗余,上图我们把44矩阵分成了四块,最终结果取得分别是四块中最大的,由它去代表自己所在块得特征。
在这里插入图片描述

Full Connected层(全连接层)

在这里插入图片描述

Mnist数字识别卷积实现

这里我们手动设置有几个卷积层,用的图还是上面那个简单神经网络的28*28的图,具体如何设置请看下图。
在这里插入图片描述
实现代码:

# 定义一个初始化权重的函数
def weight_variables(shape):
    w = tf.Variable(tf.random_normal(shape=shape, mean=0.0, stddev=1.0))
    return w


# 定义一个初始化偏置的函数
def bias_variables(shape):
    b = tf.Variable(tf.constant(0.0, shape=shape))
    return b


def model():
    """
    自定义的卷积模型
    :return:
    """
    # 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.int32, [None, 10])

    # 2、一卷积层 卷积: 5*5*1,32个,strides=1 激活: tf.nn.relu 池化
    with tf.variable_scope("conv1"):
        # 随机初始化权重, 偏置[32]
        w_conv1 = weight_variables([5, 5, 1, 32])

        b_conv1 = bias_variables([32])

        # 对x进行形状的改变[None, 784]  [None, 28, 28, 1]
        x_reshape = tf.reshape(x, [-1, 28, 28, 1])

        # [None, 28, 28, 1]-----> [None, 28, 28, 32]
        x_relu1 = tf.nn.relu(tf.nn.conv2d(x_reshape, w_conv1, strides=[1, 1, 1, 1], padding="SAME") + b_conv1)

        # 池化 2*2 ,strides2 [None, 28, 28, 32]---->[None, 14, 14, 32]
        x_pool1 = tf.nn.max_pool(x_relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 3、二卷积层卷积: 5*5*32,64个filter,strides=1 激活: tf.nn.relu 池化:
    with tf.variable_scope("conv2"):
        # 随机初始化权重,  权重:[5, 5, 32, 64]  偏置[64]
        w_conv2 = weight_variables([5, 5, 32, 64])

        b_conv2 = bias_variables([64])

        # 卷积,激活,池化计算
        # [None, 14, 14, 32]-----> [None, 14, 14, 64]
        x_relu2 = tf.nn.relu(tf.nn.conv2d(x_pool1, w_conv2, strides=[1, 1, 1, 1], padding="SAME") + b_conv2)

        # 池化 2*2, strides 2, [None, 14, 14, 64]---->[None, 7, 7, 64]
        x_pool2 = tf.nn.max_pool(x_relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 4、全连接层 [None, 7, 7, 64]--->[None, 7*7*64]*[7*7*64, 10]+ [10] =[None, 10]
    with tf.variable_scope("conv2"):

        # 随机初始化权重和偏置
        w_fc = weight_variables([7 * 7 * 64, 10])

        b_fc = bias_variables([10])

        # 修改形状 [None, 7, 7, 64] --->None, 7*7*64]
        x_fc_reshape = tf.reshape(x_pool2, [-1, 7 * 7 * 64])

        # 进行矩阵运算得出每个样本的10个结果
        y_predict = tf.matmul(x_fc_reshape, w_fc) + b_fc

    return x, y_true, y_predict


def conv_fc():
    # 获取真实的数据
    mnist = input_data.read_data_sets("./data/mnist/input_data/", one_hot=True)

    # 定义模型,得出输出
    x, y_true, y_predict = model()

    # 进行交叉熵损失计算
    # 3、求出所有样本的损失,然后求平均值
    with tf.variable_scope("soft_cross"):
        # 求平均交叉熵损失# 求平均交叉熵损失
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict))

    # 4、梯度下降求出损失
    with tf.variable_scope("optimizer"):
        train_op = tf.train.GradientDescentOptimizer(0.0001).minimize(loss)

    # 5、计算准确率
    with tf.variable_scope("acc"):
        equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1))

        # equal_list  None个样本   [1, 0, 1, 0, 1, 1,..........]
        accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

    # 定义一个初始化变量的op
    init_op = tf.global_variables_initializer()

    # 开启回话运行
    with tf.Session() as sess:
        sess.run(init_op)

        # 循环去训练
        for i in range(1000):

            # 取出真实存在的特征值和目标值
            mnist_x, mnist_y = mnist.train.next_batch(50)

            # 运行train_op训练
            sess.run(train_op, feed_dict={x: mnist_x, y_true: mnist_y})

            print("训练第%d步,准确率为:%f" % (i, sess.run(accuracy, feed_dict={x: mnist_x, y_true: mnist_y})))


    return None

以上是我们自己设定的神经网络结构,下面介绍几个现成的神经网络结构。
LeNet:1986年(这个就太老了)
在这里插入图片描述
AlexNet:2012年
在这里插入图片描述
GoogleNet:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值