Tensorflow验证集上的准确性非常低

时间:2020-08-22 16:27:32

标签: python tensorflow machine-learning computer-vision

我正在使用“ here

建立“张量流”模型,以将图像分类为不同的犬种。

这就是我创建数据集的方式

url = 'http://vision.stanford.edu/aditya86/ImageNetDogs/images.tar'

dataset = tf.keras.utils.get_file("Images", url, untar=True, cache_dir='.', cache_subdir='')
dataset_path = pathlib.Path(dataset)
image_count = len(list(dataset_path.glob('*/*.jpg')))

total_ds = tf.data.Dataset.list_files(str(dataset_path/'*/*'), shuffle = False)
total_ds = total_ds.shuffle(image_count, reshuffle_each_iteration = False)

class_names = np.array(sorted([item.name for item in dataset_path.glob('*') if item.name != "LICENSE.txt"]))

val_size = int(image_count * 0.2)
train_ds = total_ds.skip(val_size) #Training Set
val_ds   = total_ds.take(val_size) #Validation Set

batch_size = 32
img_height = 180
img_width = 180

def get_label(file_path):
  # convert the path to a list of path components
  parts = tf.strings.split(file_path, os.path.sep)
  # The second to last is the class-directory
  one_hot = parts[-2] == class_names
  # Integer encode the label
  return tf.argmax(one_hot)

def decode_img(img):
    # convert the compressed string to a 3D uint8 tensor
    img = tf.image.decode_jpeg(img, channels=3)
    # resize the image to the desired size
    return tf.image.resize(img, [img_height, img_width])

def process_path(file_path):
     label = get_label(file_path)
     # load the raw data from the file as a string
     img = tf.io.read_file(file_path)
     img = decode_img(img)
     return img, label

AUTOTUNE = tf.data.experimental.AUTOTUNE

train_ds = train_ds.map(process_path, num_parallel_calls=AUTOTUNE)
val_ds = val_ds.map(process_path, num_parallel_calls=AUTOTUNE)

那之后,我正在做以下事情

 normalization_layer = layers.experimental.preprocessing.Rescaling(1./255)

 def configure_for_performance(ds):
     ds = ds.cache()
     ds = ds.shuffle(buffer_size=1000)
     ds = ds.batch(batch_size)
     ds = ds.prefetch(buffer_size=AUTOTUNE)
     ds = ds.map(lambda x,y: (normalization_layer(x), y))
     return ds

 train_ds = configure_for_performance(train_ds)
 val_ds = configure_for_performance(val_ds)

此后,如下所示编译并训练模型

  num_classes = 120

  model = tf.keras.Sequential([
  layers.Conv2D(16, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(128, activation='sigmoid'),
  layers.Dropout(0.2),
  layers.Dense(num_classes)
  ]) 

  model.compile(optimizer='adam',
          loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
          metrics=['accuracy'])

  epochs=20
  history = model.fit(
       train_ds,
       validation_data=val_ds,
       epochs=epochs
       )

训练后,我得到了很高的训练准确度(aroung 94-95%),但是我得到的验证准确性却很低(大约8-10%)。

我在做什么错,我在网上搜索,有人说应该在拆分数据之前对数据集进行洗牌,但是我已经做到了。我被困在这里,尝试改变激活方式,神经元数量,隐藏层数量...但是没有运气。

此外,如果我添加正则化,那么两种准确性都将下降到10%左右(添加了具有4个隐藏层的正则化,每层包含512个神经元)。

如果有人可以向我解释我在做什么错,那将非常有帮助。

0 个答案:

没有答案