Не удалось найти правильный CNN

#python #tensorflow #keras

#python #тензорный поток #keras

Вопрос:

Я использую Keras Tensorflow в Colab и работаю над набором данных oxford_flowers102. Задача — классификация изображений. С довольно большим количеством категорий (102) и не так много изображений на класс. Я пытался создавать разные нейронные сети, начиная с простых и заканчивая более сложными, с увеличением изображения и без него, отсевом, настройкой гиперпараметров, настройкой размера пакета, настройкой оптимизатора, изменением размера изображения…. тем не менее, я не смог найти хороший CNN, который дает мне доступную val_accuracy и, наконец, хорошую точность тестирования. До сих пор моя максимальная val_accuracy, которую я смог получить, была низкой в 0,3 раза. Я почти уверен, что можно получить лучшие результаты, я как-то просто не нахожу правильную настройку CNN. Мой код до сих пор:

 import tensorflow as tf
from keras.models import Model
import tensorflow_datasets as tfds
import tensorflow_hub as hub

# update colab tensorflow_datasets to current version 3.2.0, 
# otherwise tfds.load will lead to error when trying to load oxford_flowers102 dataset

!pip install tensorflow_datasets --upgrade

# restart runtime

oxford, info = tfds.load("oxford_flowers102", with_info=True, as_supervised=True)

train_data=oxford['train']
test_data=oxford['test']
validation_data=oxford['validation']

IMG_SIZE = 224

def format_example(image, label):
  image = tf.cast(image, tf.float32)
  image = image*1/255.0
  image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE))
  return image, label

train = train_data.map(format_example)
validation = validation_data.map(format_example)
test = test_data.map(format_example)

BATCH_SIZE = 32
SHUFFLE_BUFFER_SIZE = 1000

train_batches = train.shuffle(SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE)
test_batches = test.batch(BATCH_SIZE)
validation_batches = validation.batch(BATCH_SIZE)
  

Первая модель, которую я попробовал:

 model = tf.keras.Sequential([
      tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(64, activation='relu'),
      tf.keras.layers.Dense(102)
  ])

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

history = model.fit(train_batches, validation_data=validation_batches, epochs=20)
  

Эпоха 20/20 32/32 [==============================] — 4s 127 мс / шаг —
потеря: 2.9830 — точность: 0.2686 — val_loss: 4.8426 — val_accuracy:
0.0637

Когда я запускаю его для большего количества эпох, он перевыполняется, val_loss увеличивается, val_accuracy не увеличивается.

Вторая модель (очень простая):

 model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(IMG_SIZE, IMG_SIZE, 3)),
  tf.keras.layers.Dense(128,activation='relu'),
  tf.keras.layers.Dense(102)
])

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

 history = model.fit(train_batches, validation_data=validation_batches, epochs=20)
  

Не работает вообще, потери остаются на уровне 4.6250.

Third model:

 model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)),
    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(128, activation='relu'),
    tf.keras.layers.Dense(102)
])

base_learning_rate = 0.0001

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

 history = model.fit(train_batches, validation_data=validation_batches, epochs=20)
  

Model overfits. Val_accuracy not above 0.15.

Я добавил в эту модель слои отсева (пробуя разные скорости), а также скорректировал ядра. Тем не менее, никаких реальных улучшений. Также пробовал adam optimizer.

Четвертая модель:

 model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(128, (3,3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)),
    tf.keras.layers.Dropout(0.4),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Conv2D(256, (3,3), activation='relu'),
    tf.keras.layers.Dropout(0.4),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dropout(0.4),
    tf.keras.layers.Dense(102)
])

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

history = model.fit(train_batches, validation_data=validation_batches, epochs=20)
  

Снова та же проблема, нет хорошей val_accuracy. Также попробовал это с оптимизатором RMSProp. Не удалось получить значение val_accuracy выше 0.2.

Пятая модель:

 model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Conv2D(64, (2,2), activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.GlobalAveragePooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(102)
])

base_learning_rate = 0.001

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

history = model.fit(train_batches, validation_data=validation_batches, epochs=250)
  

val_accuracy на самом высоком уровне около 0.3x. Также пробовал это с adam.

Когда я попробовал это с помощью transfer learning, используя Mobilenet, я сразу получил 0.7x в течение 10 эпох. Итак, я задавался вопросом, почему я не могу приблизиться к этому с помощью самодельного CNN? Я не ожидаю, что 0.8 или превзойдет Mobilenet. Но в чем моя ошибка? Как будет выглядеть самодельный CNN, с помощью которого я могу получить, скажем, 0,6-0,7 val_accuracy?

Комментарии:

1. Почему вы думаете, что вам нужно получить более высокую точность? Более того, каково наблюдение за потерей обучения и проверки?

2. Мои модели не самые лучшие. С лучшими моделями можно получить более высокую точность. Я прошу кого-нибудь, кто может показать мне лучшую архитектуру модели. Я вижу, что во многих моих случаях потери при обучении снижаются, в то время как потери при проверке увеличиваются из-за переобучения, поскольку изображения на класс довольно низкие.

3. Вот множество архитектур моделей, которые обеспечивают точность> 99% для этого набора данных. Многие из них основаны на повторных сетях, которые довольно просто реализовать с нуля, если вы хотите это сделать. paperswithcode.com/sota/… Как отмечалось в кратких описаниях, большинство, но не все, используют обучение передаче для достижения этих результатов

4. Я не хочу использовать transfer learning или использовать эти сложные модели. Я также не просил модели точности 0,99. Я попросил улучшить архитектуру моих моделей, чтобы получить 0.6x-0.7x, поскольку я уверен, что кто-нибудь в этой теме может довольно легко показать мне модель, с помощью которой я могу получить 0.6x-0.7x.

5. Там есть несколько моделей, которые обеспечивают хорошую производительность (> 95%) без переноса обучения с аффилированными документами.

Ответ №1:

Вы можете попробовать использовать некоторый предопределенный CNN с оптимизацией его параметров с помощью некоторых метаэвристических оптимизаторов, таких как Grey Wolf optimizer или PSO и т. Д….

Ответ №2:

Из вашего вопроса не совсем ясно: вы обеспокоены тем, что ваша архитектура модели уступает архитектуре, скажем, MobileNet, или что ваша производительность несопоставима с производительностью transfer learning с помощью MobileNet?

В ответ на первый, в целом, популярные архитектуры, такие как ResNet, MobileNet, AlexNet, являются очень умно созданными сетями и поэтому, вероятно, будут лучше представлять данные, чем определяемая вручную сеть, если вы сами не сделаете что-то очень умное.

В ответ на второе, чем сложнее становится модель, тем больше данных ей нужно для ее правильного обучения, чтобы она не соответствовала или не соответствовала данным. Это создает проблему для таких наборов данных, как ваш (с несколькими тысячами изображений), потому что сложному CNN сложно выучить значимые правила (ядра) для извлечения информации из изображений в целом без изучения правил запоминания ограниченного набора обучающих входных данных. В общем, вам нужна более крупная модель для более точных прогнозов, но это, в свою очередь, требует больше данных, которых иногда у вас нет. Я подозреваю, что если бы вы использовали неподготовленную мобильную сеть по сравнению с вашей неподготовленной сетью в наборе данных oxford flowers102, вы бы увидели такую же низкую производительность.

Введите обучение передаче. Путем предварительной подготовки относительно больших моделей на относительно огромных наборах данных (большинство из них предварительно обучаются в ImageNet, который содержит миллионы изображений), модель может научиться извлекать соответствующую информацию из произвольных изображений намного лучше, чем это было бы на меньшем наборе данных. Эти общие правила извлечения объектов применимы и к вашему меньшему набору данных, поэтому при небольшой настройке модель обучения передаче, вероятно, намного превзойдет любую модель, обученную исключительно на вашем наборе данных.

Комментарии:

1. Нет, я хочу сказать, что мои cnn не являются оптимальными. Однако мне не удалось создать лучшие. Вот почему я явно ищу кого-то, кто может показать мне конкретную архитектуру модели для этого набора данных, что приводит к повышению производительности. Поскольку я уверен, что есть лучшие, и я просто не могу «найти» один.

2. Без обучения передаче вы вряд ли добьетесь большего успеха. Но вы могли бы, например, скопировать архитектуру MobileNet вручную, если вы намерены определять архитектуру вручную. Существует смежная область исследований, называемая обучением с несколькими выстрелами, в которой модели обучаются хорошему выводу, учитывая только очень небольшой набор примеров, вместо этого вы можете попробовать эти архитектуры

3. Нет, я не хочу копировать архитектуру MobileNet вручную. Я хотел сказать, что я прошу кого-то, кто может показать мне лучшую архитектуру модели, поскольку я совершенно уверен, что это возможно, без обучения передаче.