我一直在使用 Keras 和 Tensorflow 将箭头的标准化 60x60 灰度图像分为 4 个类别:方向、上、下、左、右。我创建了大约 1800 张图像的数据集,几乎均匀地分布在上述类别中。
但是,分类存在问题。从我创建数据集的源中,有两种类型的箭头,箭头形状 1,
对于形状如 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/