Tensorflow CNN 实现的准确性差

     2023-03-12     198

关键词:

【中文标题】Tensorflow CNN 实现的准确性差【英文标题】:Poor accuracy in Tensorflow CNN implementation 【发布时间】:2018-06-15 18:07:52 【问题描述】:

我正在尝试在 Tensorflow 中实现一个 5 层深度卷积神经网络,其中 3 个卷积层后跟 2 个全连接层。我目前的实现如下。

def deepnn(x):

    x_image = tf.reshape(x, [-1, FLAGS.img_width, FLAGS.img_height, FLAGS.img_channels])
    img_summary = tf.summary.image('Input_images', x_image)

    with tf.variable_scope('Conv_1'):
        W_conv1 = weight_variable([5, 5, FLAGS.img_channels, 32])
        tf.add_to_collection('decay_weights',W_conv1)
        b_conv1 = bias_variable([32])
        h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1,2) + b_conv1)
        h_pool1 = avg_pool_3x3(h_conv1)

    with tf.variable_scope('Conv_2'):
        W_conv2 = weight_variable([5, 5, 32, 32])
        tf.add_to_collection('decay_weights',W_conv2)
        b_conv2 = bias_variable([32])
        h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2,2) + b_conv2)
        h_pool2 = avg_pool_3x3(h_conv2)

    with tf.variable_scope('Conv_3'):
        W_conv3 = weight_variable([5, 5, 32, 64])
        tf.add_to_collection('decay_weights',W_conv3)
        b_conv3 = bias_variable([64])
        h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3,2) + b_conv3)
        h_pool3 = max_pool_3x3(h_conv3)

    with tf.variable_scope('FC_1'):
        h_pool3_flat = tf.reshape(h_pool3,[-1,4*4*64])
        W_fc1 = weight_variable([4*4*64,64])
        tf.add_to_collection('decay_weights',W_fc1)
        b_fc1 = bias_variable([64])
        h_fc1 = tf.nn.relu(tf.matmul(h_pool3_flat,W_fc1) + b_fc1)

    with tf.variable_scope('FC_2'):
        W_fc2 = weight_variable([64, FLAGS.num_classes])
        tf.add_to_collection('decay_weights',W_fc2)
        b_fc2 = bias_variable([FLAGS.num_classes])
        y_fc2 = tf.matmul(h_fc1, W_fc2) + b_fc2

    with tf.variable_scope('softmax'):
        y_conv = tf.nn.softmax(y_fc2)

    return y_conv, img_summary

def conv2d(x, W,p):
    output = tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='VALID', name='convolution')
    return tf.pad(output, tf.constant([[0,0],[p, p,],[p, p],[0,0]]), "CONSTANT")


def avg_pool_3x3(x):
    output = tf.nn.avg_pool(x, ksize=[1, 3, 3, 1],
                          strides=[1, 2, 2, 1], padding='VALID', name='pooling')
    return tf.pad(output, tf.constant([[0,0],[0, 1,],[0, 1],[0,0]]), "CONSTANT")

def max_pool_3x3(x):
    output = tf.nn.max_pool(x, ksize=[1, 3, 3, 1],
                          strides=[1, 2, 2, 1], padding='VALID', name='pooling2')
    return tf.pad(output, tf.constant([[0,0],[0, 1], [0, 1],[0,0]]), "CONSTANT")

def weight_variable(shape):
    weight_init = tf.random_uniform(shape, -0.05,0.05)
    return tf.Variable(weight_init, name='weights')

def bias_variable(shape):
    bias_init = tf.random_uniform(shape, -0.05,0.05)
    return tf.Variable(bias_init, name='biases')


def main(_):
    tf.reset_default_graph()

    dataset = pickle.load(open('dataset.pkl', 'rb'),encoding='latin1')
    train_dataset = dataset[0]

    learning_rate = 0.01
    current_validation_acc = 1

    with tf.variable_scope('inputs'):
        x = tf.placeholder(tf.float32, [None, FLAGS.img_width * FLAGS.img_height * FLAGS.img_channels])
        y_ = tf.placeholder(tf.float32, [None, FLAGS.num_classes])


    y_conv, img_summary = deepnn(x)


    with tf.variable_scope('softmax_loss'):
        softmax_loss = tf.reduce_mean(tf.negative(tf.log(tf.reduce_sum(tf.multiply(y_conv,y_),1))))

    tf.add_to_collection('losses', softmax_loss)
    loss = tf.add_n(tf.get_collection('losses'), name='total_loss')

    train_step = tf.train.MomentumOptimizer(learning_rate,FLAGS.momentum).minimize(loss)
    correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name='accuracy')
    loss_summary = tf.summary.scalar('Loss', loss)
    acc_summary = tf.summary.scalar('Accuracy', accuracy)

由于某些未知原因,该模型似乎没有将其准确率提高到 10% 以上。我一直在用头撞墙试图找出原因。我正在使用 softmax 损失成本函数(如 here 所述)和动量优化器。使用的数据集是GTSRB dataset。

虽然我可以添加各种深度学习功能(例如自适应学习率等)来提高准确性,但我怀疑为什么基本的 CNN 模型表现如此糟糕。

有什么明显的东西可以解释为什么它没有按预期学习吗?或者,有什么我可以尝试帮助诊断问题的吗?

任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

我正在使用 softmax 损失成本函数和动量优化器。

我相信至少有一个问题是损失。这个表达式不是交叉熵损失:

# WRONG!
tf.reduce_mean(tf.negative(tf.log(tf.reduce_sum(tf.multiply(y_conv,y_),1)))

查看this question 中的正确公式。无论如何,您应该简单地使用tf.nn.softmax_cross_entropy_with_logits(并从y_conv 中删除softmax,因为损失函数本身会应用softmax)。

PS。 CNN 架构在我看来还不错,使用正确的超参数应该可以达到 60%-70%。

【讨论】:

我尝试实现的 softmax 损失函数(参见 here)与 softmax 交叉熵不同。即便如此,代入 Tensorflow softmax 交叉熵函数也能提供非常相似的准确度。【参考方案2】:

有几点应该有所帮助:

    正如另一个答案中提到的,损失函数不正确;使用tf.nn.softmax_cross_entropy_with_logits。 从更简单的模型开始是一种很好的做法,尤其是在开始使用深度学习/张量流时。你没有告诉我们你有多少个班级,但我们假设你有 10 个班级。几乎任何简单模型的表现都应该好于 10%,因此这表明存在根本性错误。错误的做法是进一步阐述你的模型;正确的做法是简化为逻辑回归(这只是一个矩阵乘法,然后是一个 softmax 层)并检查性能。这样你就可以将网络架构与优化和损失函数分开(部分无论如何)。然后从那里构建复杂性。 您的数据:您还没有描述数据,尽管我们非常喜欢神经网络的力量(我们喜欢!),但理解和深思熟虑地预处理数据很重要。例如,当对颜色通道进行一些预处理时,通常会发现著名的 SVHN 数据集(谷歌街景门牌号)更容易分类。如果您阅读许多计算机视觉论文的细则,就会发现类似的数据预处理。也许这里不是这种情况,但简化您的网络以更好地理解数据(上述项目)应该会有所帮助。 最后,这不太可能导致您的问题,但是您为什么要照原样使用tf.pad?您可能会发现使用padding=SAME 比使用padding=VALID 更容易,从而无需调用tf.pad。 毕竟,使用tensorboard 来帮助分析性能以及如何改进。值得学习它的麻烦:https://www.tensorflow.org/get_started/summaries_and_tensorboard。

【讨论】:

对数据进行预处理确实会产生巨大的影响(大约 50-60% 的准确率),但是,我认为即使没有预处理,网络也应该表现得相当好?我正在使用 GTSRB 交通标志数据集。关于填充,padding=VALID 选项用于调整每个卷积层的输出大小,以匹配我知道的另一个模型。我会尝试建立你提到的图层。有 43 个类,所以随机猜测会产生大约 2% 的准确率。【参考方案3】:

我认为你的模型有点简单。 当我尝试使用更多参数的模型时,如下所示, 测试准确率为 86%。

W_conv2 = weight_variable([5, 5, 32, 64]) # 特征图 32=>64 b_conv2 = 偏差变量([64]) w_conv3 = weight_variable([5, 5, 64, 128]) # 特征图 64=>128 b_conv3 = 偏差变量([128]) W_fc1 = weight_variable([4*4*128,2048]) # 特征图 64=>2048 b_fc1 = bias_variable([2048])

这种卷积层的设计灵感来自 VGG-16 网络。在 VGG-16 网络中,特征图的数量通过每一层卷积层增加一倍。 特征图的数量取决于任务,但我认为这种设计原则对于交通标志识别任务很有用。

如果你对我的实验感兴趣,请参考我的 github repo。 https://github.com/satojkovic/DeepTrafficSign/tree/sof_test

【讨论】:

【参考方案4】:

最好使用:

with tf.variable_scope('Conv_1'):
        W_conv1 = weight_variable([3,3, FLAGS.img_channels, 32])
        W_conv1_2 = weight_variable([3,3, 32, 32])

而不是:

with tf.variable_scope('Conv_1'):
        W_conv1 = weight_variable([5, 5, FLAGS.img_channels, 32])

您的网络丢失的有限信息较少。

更喜欢比较正统的参数,比如

output = tf.nn.max_pool(input, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID', name=identifier)

结束:

output = tf.nn.max_pool(x, ksize=[1, 3, 3, 1],
                          strides=[1, 2, 2, 1], padding='VALID', name='pooling2')

这也将阻止您使用常量填充。 旁注:我认为你应该用不同于零的东西填充,我认为它会增加噪音...... 最后一个提示,我认为你的学习率太高了,从更像 1e-3,1e-4 的东西开始

使用 AdamOptimizer,它可以创造奇迹......它在查看误差空间时基本上具有第二个数量级,这使其比基本的 MomentumOptimizer 具有优势。

祝你好运

【讨论】:

【参考方案5】:

你假设data_format = "NWHC"

x_image = tf.reshape(x, [-1, FLAGS.img_width, FLAGS.img_height, FLAGS.img_channels])

但仅支持"NHWC"(默认)和"NCHW"

【讨论】:

如何在 TensorFlow 中计算 CNN 的准确度

】如何在TensorFlow中计算CNN的准确度【英文标题】:HowtocomputeaccuracyofCNNinTensorFlow【发布时间】:2017-07-2506:40:51【问题描述】:我是TensorFlow新手。我正在用自己的数据集进行二进制分类。但是我不知道如何计算准确性。谁能帮我做... 查看详情

tensorflow CNN 模型的 model.evaluate 和 model.predict 之间的准确性差异巨大

】tensorflowCNN模型的model.evaluate和model.predict之间的准确性差异巨大【英文标题】:Hugedifferencebetweeninaccuracybetweenmodel.evaluateandmodel.predictfortensorflowCNNmodel【发布时间】:2020-10-1419:45:56【问题描述】:我将ImageDataGenerator(validation_split 查看详情

第三节,tensorflow使用cnn实现手写数字识别(代码片段)

...括以下几块内容[1]:导入数据,即测试集和验证集[2]:引入tensorflow启动InteractiveSession(比session更灵活)[3]:定义两个初始化w和b的函数,方便后续操作[4]:定义卷积和池化函数,这里卷积采用pad 查看详情

基于tensorflow+opencv实现cnn自定义图像分类

摘要:本篇文章主要通过Tensorflow+Opencv实现CNN自定义图像分类案例,它能解决我们现实论文或实践中的图像分类问题,并与机器学习的图像分类算法进行对比实验。本文分享自华为云社区《​​Tensorflow+Opencv实现CNN自定义图像分... 查看详情

tensorflow实现cnn案例笔记(代码片段)

本文收集了各个资源的TensorFlow实现CNN案例,为了方便学习,如对版权有冒犯,敬请告知及时删除~目录CNN知识图谱:案例1案例2案例3案例4 Tensorflow和CNN: Tensorflow——卷积神经网络(CNN)卷积神经网络... 查看详情

tensorflow实战-tensorflow实现卷积神经网络cnn-第5章

第5章-TensorFlow实现卷积神经网络CNN5.1卷积神经网络简介卷积神经网络CNN最初是为了解决图像识别等问题设计的,当然现在的应用已经不限于图像和视频,也可以用于时间序列信号,比如音频信号、文本数据等。在深度学习出现之... 查看详情

tensorflow实现cnn中的维度问题

使用TensorFlow实现cnn,其中tf.nn.conv2d(input_tensor…)input_tensor的格式要求是[batch,in_height,in_width,in_channels]但是python中四维矩阵是[batch,in_channels,in_height,in_width]使用transpose即可 查看详情

tensorflow实现cnn中的维度问题

使用TensorFlow实现cnn,其中tf.nn.conv2d(input_tensor…)input_tensor的格式要求是[batch,in_height,in_width,in_channels]但是python中四维矩阵是[batch,in_channels,in_height,in_width]使用transpose即可 查看详情

tensorflow实现的一个最基本cnn

原理可以参考https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/以及《神经网络与深度学习》上代码:importtensorflowastffromtqdmimporttqdm_notebookfromtensorflow.examples.tutorials.mnistimportinput_data"""thecnnwe 查看详情

pytorch实现卷积神经网络cnn

Pytorch是torch的Python版本,对TensorFlow造成很大的冲击,TensorFlow无疑是最流行的,但是Pytorch号称在诸多性能上要优于TensorFlow,比如在RNN的训练上,所以Pytorch也吸引了很多人的关注。之前有一篇关于TensorFlow实现的CNN可以用来做对比... 查看详情

使用 Tensorflow 2.0 实现 CNN 模型

】使用Tensorflow2.0实现CNN模型【英文标题】:implementaCNNmodelusingTensorlow2.0【发布时间】:2020-03-1417:54:13【问题描述】:由于我是这个领域的新手,我在项目中面临很多错误。请帮我解决这些问题。提前致谢请下载下面的文件并在jup... 查看详情

tensorflow实战之cnn实现对鸡蛋的分类

本文标签:TensorFlowTensorFlow实战之CNN3.1问题分析为了评估N个鸡蛋中是否有圈养鸡蛋,我们利用卷积神经网络(CNN)让计算机学习圈养鸡蛋和土鸡蛋图片的特征,然后根据鸡蛋的图片将其分类。通过对图片的预处理,将其转化为32*... 查看详情

基于tensorflow+opencv实现cnn自定义图像分类(代码片段)

摘要:本篇文章主要通过Tensorflow+Opencv实现CNN自定义图像分类案例,它能解决我们现实论文或实践中的图像分类问题,并与机器学习的图像分类算法进行对比实验。本文分享自华为云社区《Tensorflow+Opencv实现CNN自... 查看详情

Tensorflow:损失减少,但准确度稳定

】Tensorflow:损失减少,但准确度稳定【英文标题】:Tensorflow:lossdecreasing,butaccuracystable【发布时间】:2017-09-1521:18:43【问题描述】:我的团队正在Tensorflow中训练一个CNN,用于对损坏/可接受的部分进行二元分类。我们通过修改cifar... 查看详情

tensorflow训练自己的数据集实现cnn图像分类

利用卷积神经网络训练图像数据分为以下几个步骤读取图片文件产生用于训练的批次定义训练的模型(包括初始化参数,卷积、池化层等参数、网络)训练1 读取图片文件1defget_files(filename):2class_train=[]3label_train=[]4fortrain_classin... 查看详情

android+tensorflow+cnn+mnist手写数字识别实现

SyncHere  查看详情

android+tensorflow+cnn+mnist手写数字识别实现

SyncHere  查看详情

tensorflow中使用cnn实现mnist手写体识别

  本文参考YannLeCun的LeNet5经典架构,稍加ps得到下面适用于本手写识别的cnn结构,构造一个两层卷积神经网络,神经网络的结构如下图所示:  输入-卷积-pooling-卷积-pooling-全连接层-Dropout-Softmax输出    第一层卷积利用5*... 查看详情