python - 不同形状箭头上的 CNN 箭头图像分类器

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

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

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

和箭头形状2。enter image description here

对于形状如 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")

最佳答案

Does that mean that the lack of traning data for arrow shape 2 is the reason that it cannot classify them as well as shape 1, and therefore increasing the dataset for shape 2 resolve this issue?

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

If true, doesn't that mean that my model has failed to generalize?

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

关于python - 不同形状箭头上的 CNN 箭头图像分类器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53670078/

相关文章:

python - 蜘蛛 = cls(*args, **kwargs) 类型错误 : __init__() got an unexpected keyword argument '_job'

python - 将 TensorFlow 教程转换为使用我自己的数据

machine-learning - 我应该对回归问题进行归一化还是标准化?

python - 将随机森林预测作为列添加到测试文件中

python - 使用递归查找列表中第二小的数字

python - Steam FileUploader 发布请求 : Missing SteamID

python - 在 Linux 中禁用网络摄像头的自动对焦

tensorflow - tensorflow 或pytorch中的分区矩阵乘法

tensorflow - 如何修改 Tensorflow Sequence2Sequence 模型以实现双向 LSTM 而不是单向 LSTM?

linux - 属性错误 : module 'tensorflow.python.summary.summary' has no attribute 'scalar'