Python 斯坦福大学狗数据集的准确性非常差
我试图在斯坦福大学的狗数据集上训练一个模型,对120种狗进行分类,但我的代码表现得很奇怪 我从中下载了图像数据 然后运行以下代码,将每个品种文件夹拆分为训练和测试文件夹:Python 斯坦福大学狗数据集的准确性非常差,python,python-3.x,tensorflow,neural-network,tensorflow2.0,Python,Python 3.x,Tensorflow,Neural Network,Tensorflow2.0,我试图在斯坦福大学的狗数据集上训练一个模型,对120种狗进行分类,但我的代码表现得很奇怪 我从中下载了图像数据 然后运行以下代码,将每个品种文件夹拆分为训练和测试文件夹: dataset_dict = {} source_path = 'C:/Users/visha/Downloads/stanford_dogs/dataset' dir_root = os.getcwd() dataset_folders = [x for x in os.listdir(os.path.join(dir_ro
dataset_dict = {}
source_path = 'C:/Users/visha/Downloads/stanford_dogs/dataset'
dir_root = os.getcwd()
dataset_folders = [x for x in os.listdir(os.path.join(dir_root, source_path)) if os.path.isdir(os.path.join(dir_root, source_path, x))]
for category in dataset_folders:
dataset_dict[category] = {'source_path': os.path.join(dir_root, source_path, category),
'train_path': create_folder(new_path='C:/Users/visha/Downloads/stanford_dogs/train',
folder_type='train',
data_class=category),
'validation_path': create_folder(new_path='C:/Users/visha/Downloads/stanford_dogs/validation',
folder_type='validation',
data_class=category)}
dataset_folders = [x for x in os.listdir(os.path.join(dir_root, source_path)) if os.path.isdir(os.path.join(dir_root, source_path, x))]
for key in dataset_dict:
print("Splitting Category {} ...".format(key))
split_data(source_path=dataset_dict[key]['source_path'],
train_path=dataset_dict[key]['train_path'],
validation_path=dataset_dict[key]['validation_path'],
split_size=0.7)
经过一些图像增强后,我通过网络输入图像,并在最后一层使用sigmoid激活和分类熵损失
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import RMSprop
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(150, 150, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(120, activation='softmax')
])
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
TRAINING_DIR = 'C:/Users/visha/Downloads/stanford_dogs/train'
train_datagen = ImageDataGenerator(rescale=1./255,rotation_range=40,width_shift_range=0.2,height_shift_range=0.2,
shear_range=0.2,zoom_range=0.2,horizontal_flip=True,fill_mode='nearest')
train_generator = train_datagen.flow_from_directory(TRAINING_DIR,
batch_size=10,
class_mode='categorical',
target_size=(150, 150))
VALIDATION_DIR = 'C:/Users/visha/Downloads/stanford_dogs/validation'
validation_datagen = ImageDataGenerator(rescale=1./255, rotation_range=40,width_shift_range=0.2, height_shift_range=0.2,
shear_range=0.2,zoom_range=0.2,horizontal_flip=True,fill_mode='nearest')
validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,
batch_size=10,
class_mode='categorical',
target_size=(150, 150))
history = model.fit(train_generator,
epochs=10,
verbose=1,
validation_data=validation_generator)
但代码并没有按预期的那样工作。10个历元后的val_精度约为4.756。对于验证数据,不应进行任何图像增强,只需重新缩放即可。在来自目录的验证流中,设置shuffle=False。请注意,斯坦福狗数据集非常困难。为了达到合理的精度,您需要一个更复杂的模型。我建议您考虑使用MultEnEnter模型进行转移学习。下面的代码显示了如何做到这一点
base_model=tf.keras.applications.mobilenet.MobileNet( include_top=False,
input_shape=(150,150,3) pooling='max', weights='imagenet',dropout=.4)
x=base_model.output
x=keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
x = Dense(1024, activation='relu')(x)
x=Dropout(rate=.3, seed=123)(x)
output=Dense(120, activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=output)
model.compile(Adamax(lr=.001),loss='categorical_crossentropy',metrics=
['accuracy'] )
我忘了提到Mobilenet是针对像素值在-1到+1范围内的图像进行训练的。所以在ImageDataGenerator中包含代码
preprocessing_function=tf.keras.applications.mobilenet.preprocess_input
这会缩放像素,因此不需要代码
rescale=1./255
或另设
rescale=1/157.5-1
这将重新缩放-1和+1之间的值