Python_ML-Day06: 神经网络

Python_ML-Day06: 神经网络

1.感知机
    - 有n个输入数据,通过权重与各数据之间的计算和,比较激活函数结果,得出输出
    - 应用:很容易解决与、或、非问题

2.神经网络
    - 定义:
        1. 在机器学习和认知科学领域,人工神经网络(artificial neural network,
        缩写ANN),简称神经网络(:neural network,缩写NN)或类神经网络,是一
        种模仿生物神经网络的结构和功能的计算模型,用于对函数进行估计或近似
    - 神经网络的种类:
        1. 基础神经网络:单层感知器,线性神经网络,BP神经网络,Hopfield神经网络等
        2. 进阶神经网络:玻尔兹曼机,受限玻尔兹曼机,递归神经网络等
        3. 深度神经网络:深度置信网络,卷积神经网络,循环神经网络,LSTM网络等
    - 神经网络的特点
        1. 输入向量的维度和输入神经元的个数相同
        2. 每个连接都有个权值
        3. 同一层神经元之间没有连接
        4. 由输入层,隐层,输出层组成
        5. 第N层与第N-1层的所有神经元连接,也叫全连接
    - 神经网络的组成
        1. 结构(Architecture)例如,神经网络中的变量可以是神经元连接的权重
        2. 激活函数(Activity Rule)大部分神经网络模型具有一个短时间尺度的动力学规则,来定义神经元如何根据其他神经元的活动来改变自己的激励值。
        3. 学习规则(Learning Rule)学习规则指定了网络中的权重如何随着时间推进而调整。(反向传播算法)
    - 神经网络多分类
        1. 某一个样本,属于全部分类的每一个具体类的概率
    - SoftMax回归
        - 将 全连接层输出的值,转化成概率值
        - 公式: Si = e^xi / (e^x1 + e^x2 + ... +e^xi + ...)
    - 损失计算-交叉熵
        1. 衡量真实值与预测值之间差异的大小。 差异越大,损失越大
        2. 求所有样本损失的平局值
        3. 公式:
            - Hy` = y1`log(y1) + y2`log(y2) + ... + yn`log(yn)
            - 共有n个目标值  y` 代表真实值  y代表预测值   yn` 代表第n个目标的真实概率, yn表示第n个目标预测的概率
    - 计算 SoftMax、交叉熵
        1. 计算logits和labels之间的交叉损失熵
        2. 公式:
            - tf.nn.softmax_cross_entropy_with_logits(labels=None, logits=None,name=None)
        3. 参数说明:
            - labels:真实目标值
            - logits: 样本加权之后的值
            - return: 返回损失值列表
    - 计算张量的尺寸的元素平均值
        1. 公式:
            - tf.reduce_mean(input_tensor)
    - 反向传播算法[梯度下降]
        1. 公式:
            - tf.train.GradientDescentOptimizer(learning_rate)
        2. 参数说明
            - learning_rate:学习率
            - minimize(loss):最小化损失
            - return:梯度下降op
    - one-hot编码
        1. tf.one_hot(indices,
            depth,
            on_value=None,
            off_value=None,
            axis=None,
            dtype=None,
            name=None):
        2. 参数说明:
            - indices 数据集标签
            - depth 类别数
    - 准确性计算
        1. equal_list = tf.equal(tf.argmax(y, 1), tf.argmax(y_label, 1))
        2. accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

3.获取数据集
    - from tensorflow.examples.tutorials.mnist import input_data
    - mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
    - mnist.train.images  # 全部的特征值
    - mnist.train.labels    # 全部的目标值
    - mnist.train.next_batch(50)    # 50个一批次的特征值batch[0]和目标值batch[1]

4.单层[全连接层]神经网络 实现手写数字识别案例分析
    - 步骤:
        1. 准备数据,定义数据占位符
        2. 建立模型 随机初始化权重,偏置
            - y_predict = tf.matmul(x,w) + b
            - x: 输入  w:权重[784,10]   b:偏置 [10]
        3. 计算交叉损失loss
        4. 梯度下降优化
        5. 每次迭代,观察准确率的变化
    - 缺点
        参数太多,在cifar-10的数据集中,只有32*32*3,就会
        有这么多权重,如果说更大的图片,比如200*200*3就需
        要120000多个,这完全是浪费
        没有利用像素之间位置信息,对于图像识别任务来说,
        每个像素与周围的像素都是联系比较紧密的。
        层数限制

5.深层的神经网络
    - 解释:
        深度学习网络与更常见的单一隐藏层神经网络的区别在于深度,深度学
        习网络中,每一个节点层在前一层输出的基础上学习识别一组特定的特征。
        随着神经网络深度增加,节点所能识别的特征也就越来越复杂。
    - 卷积神经网络
        1. 神经网络(neural networks)的基本组成包括输入层、隐藏层、输出层。
        而卷积神经网络的特点在于隐藏层分为卷积层和池化层
        (pooling layer,又叫下采样层)。
        2. 卷积层:通过在原始图像上平移来提取特征,每一个特征就是一个特征映射
        3  池化层:通过特征后稀疏参数来减少学习的参数,降低网络的复杂度,(最大池化和平均池化)
    - 卷积层
        1. Filter定义一个过滤器[权重矩阵],根据一定的步长x,y 去观察图片[与图片对应位置的像素矩阵相乘],得到一个数值
        2. F: 过滤器[权重矩阵]大小: 1*1, 3*3, 5*5
        3. S:步长:移动的像素数量
        4. k: 定义多个过滤器去观察
        5. P: 移动的时候,超边了,怎么办?
            - VALID[不越界]:判断要移出图片区域了,就不移动了,直接停止观察
            - SAME[0填充]:判断要移出图片区域了,直接超过,多余的那部分,用0填充。
        6. API介绍
            - 计算给定4-D input和filter张量的2维卷积
            - tf.nn.conv2d(input, filter, strides=, padding=, name=None)
            - 参数说明:
                1. input:给定的输入张量,具有[batch,heigth,width,channel],类型为float32,64
                2. filter:指定过滤器的大小,[filter_height, filter_width, in_channels, out_channels]
                3. strides:strides = [1, stride, stride, 1],步长
                4. padding:“SAME”, “VALID”,使用的填充算法的类型,使用“SAME”。其中”VALID”表示滑动超出部分舍弃,“SAME”表示填充,使得变化后height,width一样大
    - 计算输出体积大小
        1. 确定输入体积大小[图片的长H1,宽W1和维度D1]
            - H1 * W1 * D1
        2. 四个超参数
            - Filter的数量K
            - Filter的大小F
            - 步长S
            - 零填充大小P
        3. 计算输出体积
            - H2 = (H1 - F + 2P)/S + 1
            - W2 = (W1 - F + 2P)/S + 1
            - D2 = K
    - 激活函数
        1. 增加网络非线性分割的能力
        2. sigmoid 和 ReLU
            - 第一,采用sigmoid等函数,反向传播求误差梯度时,计算量相对大,而采用Relu激活函数,整个过程的计算量节省很多
            - 第二,对于深层网络,sigmoid函数反向传播时,很容易就会出现梯度消失的情况(求不出权重和偏置)
        3. tf.nn.relu(features,name=None)
            - features:卷积后加上偏置的结果
            - return:结果
        4. 结果会使数据量变得很大
    - 池化层(Pooling)
        1. Pooling层主要的作用是特征提取,通过去掉Feature Map中不重要的样本,进一步减少参数数量。
        2. Pooling的方法很多,最常用的是Max Pooling。
        3. 输入上执行最大池数: tf.nn.max_pool(value, ksize=, strides=, padding=,name=None)
            - 参数说明
                1. value:4-D Tensor形状[batch, height, width, channels]
                2. ksize:池化窗口大小,[1, ksize, ksize, 1]
                3. strides:步长大小,[1,strides,strides,1]
                4. padding:“SAME”, “VALID”,使用的填充算法的类型,使用“SAME”
    - 全连接层
        1. 前面的卷积和池化相当于做特征工程,后面的全连接相当于做特征加权。最后的全连接层在整个卷积神经网络中起到“分类器”的作用
        2.
    - 自定义卷积案例分析
6.源码
    import os
    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data

    FLAGS = tf.app.flags.FLAGS
    tf.app.flags.DEFINE_string("data_dir", "./data", "手写图片路径")


    def getDataSets(batch_size):
        """
        获取数据集
        :return:
        """
        mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
        # print(mnist.train.images[0])
        # print("-------")
        # print(mnist.train.labels[0])
        batch = mnist.train.next_batch(batch_size)
        # print("-------")
        # print(batch[1][0])
        return batch[0], batch[1]


    def imageAnalyzer(is_train):
        """
        手写数字识别案例
        :return:
        """
        with tf.variable_scope("getData"):
            # 获取真实的数据
            img_batch, label_batch = getDataSets(50)
            # 1.占位符,在运行的时候,实时的提供数据
            x = tf.placeholder(tf.float32, [None, 28 * 28])
            y_true = tf.placeholder(tf.int32, [None, 10])
        with tf.variable_scope("init_weight_bias"):
            # 2.随机初始化权重,偏置 [None, 784] * [784 * 10] + [10] = [None, 10]
            weight = tf.Variable(tf.random_normal(shape=[28 * 28, 10], mean=0, stddev=1.0))
            bias = tf.Variable(tf.constant(0.0, tf.float32, [10]))
        with tf.variable_scope("GradientDescentOptimizer"):
            # 开始计算 y_predict
            y_predict = tf.matmul(x, weight) + bias
            # 计算交叉损失的平均值
            loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y_predict, labels=y_true))
            # 梯度下降
            train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
        with tf.variable_scope("reduce_mean"):
            # 评估模型, 计算准确率mean
            equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1))
            mean = tf.reduce_mean(tf.cast(equal_list, tf.float32))
        # 开启会话,进行训练
        init_op = tf.global_variables_initializer()
        # 收集tensor
        tf.summary.scalar("losses", loss)  # 单个数字变量收集
        tf.summary.scalar("mean", mean)  # 单个数字变量收集
        tf.summary.histogram("weight", weight)  # 收集高纬度变量
        tf.summary.histogram("bias", bias)  # 收集高纬度变量

        # 合并
        merged_op = tf.summary.merge_all()
        # 定义一个保存模型的实例
        saver = tf.train.Saver(var_list=None, max_to_keep=5)

        with tf.Session() as sess:
            sess.run(init_op)
            filewriter = tf.summary.FileWriter('./test/', sess.graph)
            # 运行时,占位符要赋值
            if is_train:
                for i in range(2000):
                    dit = {x: img_batch, y_true: label_batch}
                    sess.run(train_op, feed_dict=dit)
                    # 运行合并的merge_op
                    summary = sess.run(merged_op, feed_dict=dit)
                    filewriter.add_summary(summary, i)
                    print("第{}次运行,准确率为:{}".format(i, sess.run(mean, feed_dict=dit)))
                saver.save(sess, "./ckpt/model")
            else:
                # 加载模型,覆盖模型当中随机定义的参数,从检查点开始运行
                if os.path.exists("./ckpt/checkpoint"):
                    saver.restore(sess, "./ckpt/model")
                mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
                for i in range(100):
                    x_test, y_test = mnist.test.next_batch(1)
                    pre = tf.argmax(sess.run(y_predict, feed_dict={x: x_test, y_true: y_test}), 1).eval()
                    tr = tf.argmax(y_test, 1).eval()
                    print("第{}张图片,真实是{},预测是{},是否准确{}".format(
                        i,
                        tr,
                        pre,
                        tr == pre
                    ))


    def init_weight(shape):
        w = tf.Variable(tf.random_normal(shape=shape, mean=0.0, stddev=1))
        return w


    def init_bias(shape):
        b = tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=shape))
        return b


    def model():
        """
        卷积神经网络
        :return:
        """
        # 占位符
        x = tf.placeholder(dtype=tf.float32, shape=[None, 28 * 28])
        y_true = tf.placeholder(dtype=tf.int32, shape=[None, 10])
        with tf.variable_scope("conv-1"):
            # 随机初始化权重,以及偏置
            # x --> [None,28,28,1]   输出[None,28,28,32]
            # w --> [5, 5, 1, 32]
            conv1_w = init_weight([5, 5, 1, 32])
            conv1_b = init_bias([32])
            # 卷积-1
            x_reshape = tf.reshape(x, [-1, 28, 28, 1])
            # 激活函数
            relu_1 = tf.nn.relu(tf.nn.conv2d(x_reshape, conv1_w, strides=[1, 1, 1, 1], padding="SAME", name="C1_NN") + conv1_b)
            # 池化
            pool_1 = tf.nn.max_pool(value=relu_1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
        with tf.variable_scope("conv-2"):
            # 随机初始化权重,以及偏置 pool_1 [None, 14,14, 32]
            conv2_w = init_weight([5, 5, 32, 64])
            conv2_b = init_bias([64])
            relu_2 = tf.nn.relu(tf.nn.conv2d(pool_1, conv2_w, strides=[1, 1, 1, 1], padding="SAME", name="C1_NN") + conv2_b)
            # 池化
            pool_2 = tf.nn.max_pool(value=relu_2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
        with tf.variable_scope("fc-1"):
            # 全连接
            fc_w = init_weight([7*7*64, 10])
            fc_b = init_bias([10])
            x_fc_reshape = tf.reshape(pool_2, [-1, 7 * 7 * 64])
            y_predict = tf.matmul(x_fc_reshape, fc_w) + fc_b
        return x, y_true, y_predict


    if __name__ == '__main__':
        # 获取真实的数据
        mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
        x, y_true, y_predict = model()
        # 梯度下降求解
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y_predict, labels=y_true))
        # 梯度下降
        train_op = tf.train.GradientDescentOptimizer(0.0001).minimize(loss)
        # 评估模型, 计算准确率mean
        equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1))
        mean = tf.reduce_mean(tf.cast(equal_list, tf.float32))
        init_op = tf.global_variables_initializer()
        with tf.Session() as sess:
            sess.run(init_op)
            for i in range(2000):
                # 取出真实存在的特征值和目标值
                mnist_x, mnist_y = mnist.train.next_batch(50)
                dit = {x: mnist_x, y_true: mnist_y}
                sess.run(train_op, feed_dict=dit)
                print("第{}次运行,准确率为:{}".format(i, sess.run(mean, feed_dict=dit)))



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值