【问题标题】:CNN Arrow image classifier on differently shaped arrows不同形状箭头上的 CNN 箭头图像分类器
【发布时间】:2018-12-07 12:59:19
【问题描述】:

我一直在使用 Keras 和 Tensorflow 将一个归一化的 60x60 灰度箭头图像分类为 4 个类别,即方向、上、下、左、右。我创建了一个包含约 1800 张图像的数据集,几乎均等地分布在上述类别中。

但是,分类存在问题。从我创建数据集的源中,有两种类型的箭头,箭头形状 1,

和箭头形状 2.

对于形状像 1 的箭头来说准确度还可以(大约 70% 的验证准确度),但对于像数字 2 这样的箭头来说,就很糟糕了。

我浏览了我的数据集,大约 90% 的数据集图像是箭头形状 1。

这是否意味着缺少箭头形状 2 的训练数据是它无法像形状 1 一样分类它们的原因,因此增加形状 2 的数据集可以解决这个问题?

如果为真,那是否意味着我的模型无法泛化?

另外,如果箭头颜色反了,网络会不会受到影响?

这是我用来训练数据的来源:

# -*- coding:utf-8 -*-
import cv2
import numpy as np
import os
from random import shuffle
import glob


train_dir = "images\\cropped\\traindata"
test_dir = "images\\cropped\\testdata"
MODEL_NAME = "ARROWS.model"

img_size = 60


# Importing the Keras libraries and packages
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Activation
from keras.layers import BatchNormalization
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import adam
from keras.callbacks import TensorBoard
from keras import backend as K

from tensorflow import Session, ConfigProto, GPUOptions
gpuoptions = GPUOptions(allow_growth=True)
session = Session(config=ConfigProto(gpu_options=gpuoptions))
K.set_session(session)
classifier = Sequential()

classifier.add(Conv2D(32, (3,3), input_shape=(img_size, img_size, 1)))
classifier.add(BatchNormalization())
classifier.add(Activation("relu"))

classifier.add(Conv2D(32, (3,3)))
classifier.add(BatchNormalization())
classifier.add(Activation("relu"))
classifier.add(MaxPooling2D(pool_size=(2, 2)))
classifier.add(Dropout(0.25))
#classifier.add(Dropout(0.25))

classifier.add(Conv2D(64, (3,3), padding='same'))
classifier.add(BatchNormalization())
classifier.add(Activation("relu"))
classifier.add(MaxPooling2D(pool_size=(2, 2)))
classifier.add(Dropout(0.25))
#classifier.add(Dropout(0.25))

classifier.add(Flatten())
classifier.add(Dense(128))
classifier.add(BatchNormalization())
classifier.add(Activation("relu"))
classifier.add(Dropout(0.5))


classifier.add(Dense(4))
classifier.add(BatchNormalization())
classifier.add(Activation("softmax"))


classifier.compile(optimizer = adam(lr=1e-6), loss = 'categorical_crossentropy', metrics = ['accuracy'])

train_datagen = ImageDataGenerator(rotation_range=12)

test_datagen = ImageDataGenerator(rotation_range=12)

training_set = train_datagen.flow_from_directory('images/cropped/traindata',
                                                 color_mode="grayscale",
                                                 target_size = (img_size, img_size),
                                                 batch_size = 32,
                                                 class_mode = 'categorical', shuffle=True)

test_set = test_datagen.flow_from_directory('images/cropped/testdata',
                                            color_mode="grayscale",
                                            target_size = (img_size, img_size),
                                            batch_size = 32,
                                            class_mode = 'categorical', shuffle=True)

with open("class_indices.txt", "w") as indices_fine:  # Log debug data to file
    indices_fine.write(str(classifier.summary()))
    indices_fine.write("\n")
    indices_fine.write("training_set indices:\n"+str(training_set.class_indices))
    indices_fine.write("test_set indices:\n"+str(test_set.class_indices))


tbCallBack = TensorBoard(log_dir='./log', histogram_freq=0, write_graph=True, write_images=True)
classifier.fit_generator(training_set,steps_per_epoch = 8000,epochs = 15,validation_data = test_set,validation_steps = 2000, shuffle=True, callbacks=[tbCallBack])

classifier.save("arrow_classifier_keras_gray.h5")

【问题讨论】:

    标签: python tensorflow machine-learning keras conv-neural-network


    【解决方案1】:

    这是否意味着缺少箭头形状 2 的训练数据是 原因是它不能像形状 1 那样对它们进行分类,因此 增加形状 2 的数据集可以解决这个问题吗?

    您的数据集分布非常重要,可能会导致偏向某个特定类别并且无法按预期执行。在您的情况下,shape 2 的案例数量远小于您的 shape 1,因此在您的深度学习模型中产生偏见,以某种方式假设所有向下箭头都必须像形状1,而不是形状2。解决方案?你已经知道答案了:增加形状 2 的数据集使形状 1 和形状 2 在向下箭头类中均匀分布

    如果为真,那是否意味着我的模型无法泛化?

    您的图像数据集分布导致模型无法很好地概括该特定类(向下箭头)。如果您的模型在其他类上运行良好,则问题不在于您的模型,而在于您的向下箭头类的数据集。

    【讨论】:

    • 感谢您的回答。我还想知道训练图像的颜色是否被反转(我的数据集中的一些图像与样本图像的颜色相反),这会影响训练结果吗?
    • 确实如此。它们应该是相似的。
    • 谢谢你的回答:)
    【解决方案2】:

    想象一下,您的第一张图片是一只小猫,第二张是一只肥猫,比如加菲猫。猫的分布是我们无法改变的,但我们需要检测所有的猫(即使猫倒置或喷成粉红色)。

    我会做的是,例如,如果我有 1000 只小猫,我可能会对一些图像进行过滤,添加一些失真,从而使训练集更大。这称为数据增强。

    如果最后你能很好地识别它们并且你已经训练了你的图像分类器,那么你不需要让肥猫图像的数量等于小猫图像的数量,假设在这方面的准确率约为 98%数据集。

    测试很重要。

    注意:CNN 应该擅长检测颜色反转的图像。这是因为他们使用了卷积技术。

    【讨论】:

    • 感谢您的回答。不幸的是,我接受了另一个答案,因为它发布得更快。
    • 别担心,很高兴你喜欢@Dashadower 的答案
    猜你喜欢
    • 2011-04-30
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 2015-07-05
    • 2018-09-10
    • 2016-07-04
    • 1970-01-01
    相关资源
    最近更新 更多