我一直在使用带有Tensorflow的Keras将箭头的归一化60x60灰度图像分为4类,即方向,上,下,左,右。我创建了约1800张图像的数据集,几乎平均分布在上述类别中。
但是,分类存在问题。从我创建数据集的源开始,有两种类型的箭头,箭头形状1,
形状为1的箭头的精度尚可(约70%的验证精度),而形状为2的箭头的精度则很差。
我遍历了数据集,并且大约90%的数据集图像是箭头形状1。
这是否意味着缺少箭头形状2的转换数据是它无法对形状1和形状1进行分类的原因,因此增加形状2的数据集可以解决此问题吗?
如果为true,这不表示我的模型未能归纳吗?
此外,如果箭头颜色颠倒了,网络会受到此影响吗?
这是我用来训练数据的来源:
# -*- 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")
答案 0 :(得分:2)
这是否意味着缺少箭头形状2的转换数据是 无法对形状1进行分类的原因,因此 增加形状2的数据集可以解决此问题吗?
您的数据集分布非常重要,并且可能导致对特定类的偏见并且表现不如您预期。在您的情况下,形状2 的情况数比您的形状1 的情况少得多,因此在深度学习模型中会产生偏差,以某种方式假设所有向下箭头都必须像形状1,而不是形状2。解决方案?您已经知道答案:增加形状2的数据集或使形状1和形状2均匀分布在向下箭头类中。
如果为true,这不表示我的模型未能归纳吗?
您的图像数据集分布导致该模型无法很好地推广到该特定类(向下箭头)。如果您的模型在其他类上运行良好,则问题不在于您的模型,而是您的向下箭头类的数据集。
答案 1 :(得分:1)
试想一下,您的第一个图像是一只小猫,第二个是肥猫,例如加菲猫。猫的分布是我们无法改变的,但是我们需要检测所有的猫(即使猫被倒立或喷上粉红色)。
例如,如果我有1000只小猫,我可能会进行过滤,可能会过滤掉某些图像并增加了一些失真,并且效果使训练集更大。这称为数据增强。
如果最终您对它们的识别都很好,并且您已经训练了图像分类器的精度达到了大约98%,那么您不需要使肥猫图像的数量等于小猫图像的数量。数据集。
测试很重要。
注意:CNN应该擅长检测颜色反转的图像。这是因为他们使用了卷积技术。