我使用了深度神经网络(VGG16)对纹理图像进行分类。由于必须对网络进行预训练以识别对象图像,因此我必须从头开始训练整个网络,以获取良好的准确性。经过培训,我获得了90%的验证准确性。据我所知,keras通过检查图像概率向量中具有最高值的类别是否是正确的类别来计算准确性。我进行了同样的操作来计算测试数据的准确性,令人惊讶的是,该准确性非常低,仅为30%。我认为测试数据不同于验证数据。因此,我以与keras相同的方式重新计算了验证数据的准确性,准确性约为30%。 请注意,训练模型后,我保存了模型的权重。之后,我创建了一个新模型,加载了权重并进行了编译:
vgg16_model = VGG16(weights=None, include_top=False, input_shape=(224,224,3))
model = Sequential()
model.add(vgg16_model)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(classesNb, activation='softmax'))
model.load_weights(trainedModelsDir + modelName)
model.compile(loss='categorical_crossentropy', optimizer= optimizers.sgd(lr = 1e-4, momentum = 0.9),
metrics = ['accuracy'])
model.save(compiledModelsDir + modelName)
之后,我计算了测试/验证数据的准确性:
global cpArray
classesProbabilities =[]
model = load_model(compiledModelsDir +'model1.h5')
classIdx = -1
crrctPred = 0
for subdir, dirs, files in sorted(os.walk(splittedDatasetDir +'val/')):
for imageName in sorted(files):
imagePath = subdir + os.sep + imageName
img = image.load_img(imagePath, target_size=(224,224))
img = image.img_to_array(img)
img = np.expand_dims(img, axis=0)
img = preprocess_input(img)
y=model.predict(img)[0]
classesProbabilities.append(y)
if y[classIdx] == np.amax(y):
crrctPred += 1
cpArray = np.array(classesProbabilities)
classIdx += 1
classAcc = crrctPred / len(classesProbabilities)
我将sorted
设置为具有与类概率向量相同的顺序的类(我在训练期间使用了flow_from_directory
,该训练以字母顺序从目录中获取类),并设置了{{ 1}}到-1,因此循环从0开始。
另请注意,我正在使用的数据集非常小(用于训练的250个数据集,用于测试的125个数据集和用于验证的125个数据集)。
我认为在将权重加载到新创建的模型中并再次进行预测后,训练模型时的预测可能会略有不同。那么,这是错误的根源吗?我还注意到,错误分类的样本被归类为与真实类别相似。但是,这很奇怪,因为准确性很低。