是猪猪呀zzz 2022-05-02 18:13 采纳率: 0%
浏览 100
已结题

这个是卷积神经网络中的那种模型啊?

这是在github上找到的对图像进行二分类的代码,我修改了部分内容,然后想问一下大家,这个是卷积神经网络中的那种模型啊?我学的不够深入,分不清楚。



import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()


def cnn_inference(images, batch_size, n_classes):
    
    # TensorFlow中的变量作用域机制:
    #       tf.variable_scope(<scope_name>): 指定命名空间
    #       tf.get_variable(<name>, <shape>, <dtype>, <initializer>): 创建一个变量

    # 第一层的卷积层conv1,卷积核(weights)的大小是 3*3, 输入的channel(管道数/深度)为3, 共有16个
    with tf.variable_scope('conv1') as scope:
        # tf.truncated_normal_initializer():weights初始化生成截断正态分布的随机数,stddev标准差
        weights = tf.get_variable('weights',
                                  shape=[3, 3, 3, 16],
                                  dtype=tf.float32,
                                  initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
        biases = tf.get_variable('biases',
                                 shape=[16],
                                 dtype=tf.float32,
                                 initializer=tf.constant_initializer(0.1))   # 初始化为常数,通常偏置项biases就是用它初始化的

        # strides = [1, y_movement, x_movement, 1], 每个维度的滑动窗口的步幅,一般首末位置固定都为1
        # padding = 'SAME', 是考虑边界, 不足时用0去填充周围
        # padding = 'VALID', 不考虑边界, 不足时舍弃不填充周围
        # weights(卷积核)的大小是 3*3, 数量为16
        # strides(滑动步长)是[1,1,1,], 即卷积核在图片上卷积时分别向x、y方向移动为1个单位
        # 由于padding='SAME'考虑边界,最后得到16张图且每张图得到16个 200*200 的feature map(特征图)
        # conv(最后输出的结果)是shape为[16,200,200,16]的4维张量(矩阵/向量)
        # 用weights卷积核对images图片进行卷积
        conv = tf.nn.conv2d(images, weights, strides=[1, 1, 1, 1], padding='SAME')
        pre_activation = tf.nn.bias_add(conv, biases)      # 加入偏差,biases向量与矩阵的每一行进行相加, shape不变
        conv1 = tf.nn.relu(pre_activation, name='conv1')   # 在conv1的命名空间里,用relu激活函数非线性化处理

    # 第一层的池化层pool1和规范化norm1(特征缩放)
    with tf.variable_scope('pooling1_lrn') as scope:
        # 对conv1池化得到feature map
        pool1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],
                               padding='SAME', name='pooling1')
        # lrn():局部响应归一化, 一种防止过拟合的方法, 增强了模型的泛化能力,
        norm1 = tf.nn.lrn(pool1, depth_radius=4, bias=1.0, alpha=0.001/9.0,
                          beta=0.75, name='norm1')

    # 第二层的卷积层cov2,卷积核(weights)的大小是 3*3, 输入的channel(管道数/深度)为16, 共有16个
    with tf.variable_scope('conv2') as scope:
        weights = tf.get_variable('weights',
                                  shape=[3, 3, 16, 16],  # 这里的第三位数字16需要等于上一层的tensor维度
                                  dtype=tf.float32,
                                  initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
        biases = tf.get_variable('biases',
                                 shape=[16],
                                 dtype=tf.float32,
                                 initializer=tf.constant_initializer(0.1))
        conv = tf.nn.conv2d(norm1, weights, strides=[1, 1, 1, 1], padding='SAME')
        pre_activation = tf.nn.bias_add(conv, biases)
        conv2 = tf.nn.relu(pre_activation, name='conv2')

    # 第二层的池化层pool2和规范化norm2(特征缩放)
    with tf.variable_scope('pooling2_lrn') as scope:
        # 这里选择了先规范化再池化
        norm2 = tf.nn.lrn(conv2, depth_radius=4, bias=1.0, alpha=0.001/9.0,
                          beta=0.75, name='norm2')
        pool2 = tf.nn.max_pool(norm2, ksize=[1, 2, 2, 1], strides=[1, 1, 1, 1],
                               padding='SAME', name='pooling2')

    # 第三层为全连接层local3
    # 连接所有的特征, 将输出值给分类器 (将特征映射到样本标记空间), 该层映射出256个输出
    with tf.variable_scope('local3') as scope:
        # 将pool2张量铺平, 再把维度调整成shape(shape里的-1, 程序运行时会自动计算填充)
        # 参考:https://blog.csdn.net/csdn0006/article/details/106238909/
        reshape = tf.reshape(pool2, shape=[batch_size, -1])

        dim = reshape.get_shape()[1].value            # 获取reshape后的列数
        weights = tf.get_variable('weights',
                                  shape=[dim, 256],   # 连接256个神经元
                                  dtype=tf.float32,
                                  initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
        biases = tf.get_variable('biases',
                                 shape=[256],
                                 dtype=tf.float32,
                                 initializer=tf.constant_initializer(0.1))
        # 矩阵相乘再加上biases,用relu激活函数非线性化处理
        local3 = tf.nn.relu(tf.matmul(reshape, weights) + biases, name='local3')

    # 第四层为全连接层local4
    # 连接所有的特征, 将输出值给分类器 (将特征映射到样本标记空间), 该层映射出512个输出
    with tf.variable_scope('local4') as scope:
        weights = tf.get_variable('weights',
                                  shape=[256, 512],  # 再连接512个神经元
                                  dtype=tf.float32,
                                  initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
        biases = tf.get_variable('biases',
                                 shape=[512],
                                 dtype=tf.float32,
                                 initializer=tf.constant_initializer(0.1))
        # 矩阵相乘再加上biases,用relu激活函数非线性化处理
        local4 = tf.nn.relu(tf.matmul(local3, weights) + biases, name='local4')

    # 第五层为输出层(回归层): softmax_linear
    # 将前面的全连接层的输出,做一个线性回归,计算出每一类的得分,在这里是2类,所以这个层输出的是两个得分。
    with tf.variable_scope('softmax_linear') as scope:
        weights = tf.get_variable('weights',
                                  shape=[512, n_classes],
                                  dtype=tf.float32,
                                  initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
        biases = tf.get_variable('biases',
                                 shape=[n_classes],
                                 dtype=tf.float32,
                                 initializer=tf.constant_initializer(0.1))

        # softmax_linear的行数=local4的行数,列数=weights的列数=bias的行数=需要分类的个数
        # 经过softmax函数用于分类过程中,它将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解
        # 这里local4与weights矩阵相乘,再矩阵相加biases
        softmax_linear = tf.add(tf.matmul(local4, weights), biases, name='softmax_linear')

    # 这里没做归一化和交叉熵。真正的softmax函数放在下面的losses()里面和交叉熵结合在一起了,这样可以提高运算速度。
    # 图片列表中的每张图片分别被每个分类取到的概率,
    return softmax_linear


def losses(logits, labels):
    
    with tf.variable_scope('loss') as scope:
        # label与神经网络输出层的输出结果做对比,得到损失值(这做了归一化和交叉熵处理)
        cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels, name='loss_per_eg')
        loss = tf.reduce_mean(cross_entropy, name='loss')  # 求得batch的平均loss(每批有16张图)
    return loss


def training(loss, learning_rate):
   
    with tf.name_scope('optimizer'):
        # tf.train.AdamOptimizer():
        # 除了利用反向传播算法对权重和偏置项进行修正外,也在运行中不断修正学习率。
        # 根据其损失量学习自适应,损失量大则学习率越大,进行修正的幅度也越大;
        #                     损失量小则学习率越小,进行修正的幅度也越小,但是不会超过自己所设定的学习率。
        optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)    # 使用AdamOptimizer优化器来使loss朝着变小的方向优化

        global_step = tf.Variable(0, name='global_step', trainable=False)  # 全局步数赋值为0

        # loss:即最小化的目标变量,一般就是训练的目标函数,均方差或者交叉熵
        # global_step:梯度下降一次加1,一般用于记录迭代优化的次数,主要用于参数输出和保存
        train_op = optimizer.minimize(loss, global_step=global_step)   # 以最大限度地最小化loss

    return train_op


def evaluation(logits, labels):
    
    with tf.variable_scope('accuracy') as scope:
        correct = tf.nn.in_top_k(logits, labels, 1)   
        correct = tf.cast(correct, tf.float16)        # 转换格式为浮点数
        accuracy = tf.reduce_mean(correct)            # 计算当前批的平均准确率
    return accuracy


  • 写回答

6条回答 默认 最新

  • 大米粥哥哥 2022-05-02 18:47
    关注

    没看出来是哪种出名模型. 应该就是随便写的一个模型吧

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月7日
  • 赞助了问题酬金20元 5月2日
  • 创建了问题 5月2日

悬赏问题

  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 用matlab 设计一个不动点迭代法求解非线性方程组的代码
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试