Я новичок в глубоком обучении и пытаюсь создать модель классификации рукописных слов, я создал набор данных, который содержит 71 класс с 1000 изображений каждого класса.
Проблема в том, что я пытался создать модель CNN с разными комбинациями сверточных, максимальных пулов и плотных слоев, при этом также меняя оптимизатор, но точность остается УЖАСНОЙ.Вот мои результаты.
Это проблема модели, набора данных или моих параметров? Что ты посоветуешь?
Вот последняя модель, с которой я пробовал
model = Sequential([
Conv2D(32, kernel_size=(2, 2),activation = "relu", input_shape=(143, 75, 1)),
MaxPooling2D(pool_size=(3,3)),
Conv2D(64, kernel_size=(4, 4),activation = "relu"),
MaxPooling2D(pool_size=(9,9)),
Flatten(),
Dense(512, activation = "relu"),
Dense(128, activation = "sigmoid"),
Dense(71, activation = "softmax")
])
model.compile(optimizer=Nadam(learning_rate=0.01), loss = "categorical_crossentropy", metrics=["accuracy"])
Если ответ, который я написал, помог вам. Не могли бы вы пометить это как принятый ответ?
Проблема с вашей моделью заключается в размере вашего пула. Официальная документация Keras говорит об уровне пула
Понижает входные данные по его пространственным размерам (высоте и ширине), принимая максимальное значение в окне ввода (размер которого определяется параметром pool_size) для каждого канала ввода. Окно смещается шагами по каждому измерению.
По умолчанию слой пула имеет размер пула (2,2)
, что означает, что в окне матрицы из 4 элементов учитывается только максимальное значение.
Если мы напечатаем сводку вашей модели, мы получим
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 142, 74, 32) 160
max_pooling2d (MaxPooling2D (None, 47, 24, 32) 0
)
conv2d_1 (Conv2D) (None, 44, 21, 64) 32832
max_pooling2d_1 (MaxPooling (None, 4, 2, 64) 0
2D)
flatten (Flatten) (None, 512) 0
dense (Dense) (None, 512) 262656
dense_1 (Dense) (None, 128) 65664
dense_2 (Dense) (None, 71) 9159
=================================================================
Total params: 370,471
Trainable params: 370,471
Non-trainable params: 0
_________________________________________________________________
Таким образом, глядя на эти слои и их формы, можно увидеть большую разницу между выводом conv2d_1(Conv2D)
слоя и выходом max_pooling2d_1(MaxPooling2D)
слоя. Выходные формы меняются с (44,21,64)
на (4,2,64)
. Это связано с тем, что вы используете размер пула (9,9)
для своего слоя пула перед плотным слоем.
Чтобы понять влияние размера пула и объединения, рассмотрите приведенное ниже входное изображение размером (183,183,3)
.
Теперь, когда мы применяем максимальное 2D-объединение приведенного выше изображения с размером пула (2,2)
, мы получаем следующее изображение, пространственные размеры которого уменьшены до (91,91,3)
. Здесь размеры изображения уменьшились, но информация внутри изображения сохранена.
Теперь для того же входного изображения максимальным выходом пула для размера пула (3,3)
будет следующее изображение с размерами (61,61,3)
Здесь на картинке едва видно слово Потрясающе.
с размером пула (5,5)
мы получаем максимальный выход пула как
с пространственной размерностью (36,36,3)
. Здесь вы вообще не видите никакой информации.
Why is that ?
Поскольку белые пиксели равны 255, а черные пиксели равны 0, и когда вы делаете максимальный пул, вы всегда берете 255. Теперь, поскольку вы используете размер пула (9,9)
, вы учитываете больше белых пикселей вместе с черными в окне, и вы теряете полезную информацию, когда ваши пространственные размеры уменьшаются до (20,20,3)
, как и в случае с размером пула (5,5)
. (Здесь на изображении показан только эффект объединения. Когда вы добавляете слои Conv2D, выходные данные будут меняться в зависимости от значений фильтра.)
При этом ваша модель не сможет ничего узнать, несмотря на то, что вы изменили какие-либо другие компоненты, такие как оптимизаторы или функции потерь.
Итак, измените архитектуру модели на что-то вроде приведенного ниже и переобучите свою сеть.
model = Sequential([
Conv2D(32, kernel_size=(3, 3),activation = "relu", input_shape=(143, 75, 1)),
MaxPooling2D(),
Conv2D(64, kernel_size=(3, 3),activation = "relu"),
MaxPooling2D(),
Flatten(),
Dense(512, activation = "relu"),
Dense(128, activation = "relu"),
Dense(71, activation = "softmax")
])
model.compile(optimizer=tf.keras.optimizers.Nadam(learning_rate=0.01), loss = "categorical_crossentropy", metrics=["accuracy"])
P.S. Обычно размер ядра принимается равным (3,3) или (5,5) для слоя свертки. Например, когда у вас есть слой свертки, такой как Conv2D(64, kernel_size=(3, 3))
, у вас будет 64 фильтра, каждый размером (3,3). Кроме того, не забудьте нормализовать свои изображения, прежде чем передавать их модели.
Ваше здоровье !!!
Большое спасибо за полезную информацию!
Пожалуйста, отредактируйте вопрос, чтобы ограничить его конкретной проблемой с достаточной детализацией, чтобы найти адекватный ответ.