Потери при проверке и точность проверки не меняются во время обучения

#python #tensorflow #machine-learning #keras #deep-learning

#python #тензорный поток #машинное обучение #keras #глубокое обучение

Вопрос:

Я написал программу-классификатор лиц с. Tensorflow В этом проекте сначала у меня было только 2 лица, поэтому я использовал binary_crossentropy функцию потерь. Когда я решил добавить больше лиц, я переключился с binary_crossentropy на categorical_crossentropy .

Мой код:

 import tensorflow as tf
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D


import pickle

pickle_in = open("/content/gdrive/My Drive/Deep Learning/Yüz Tanıma/X.pickle","rb")
X = pickle.load(pickle_in)

pickle_in = open("/content/gdrive/My Drive/Deep Learning/Yüz Tanıma/y.pickle","rb")
y = pickle.load(pickle_in)

X = X/255.0

model = Sequential()

model.add(Conv2D(128, (4, 4), input_shape=X.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, (4, 4)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Dense(128))
model.add(Activation('relu'))

model.add(Dense(128))
model.add(Activation('relu'))


model.add(Flatten())  

model.add(Dropout(0.4))

model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

model.fit(X, y, batch_size=32, epochs=20,validation_split=0.3)

model.save("/content/gdrive/My Drive/Deep Learning/Yüz Tanıma/model.h5")
 

И вот мой журнал обучения:

 Epoch 1/20
1728/1728 [==============================] - 30s 13ms/step - loss: 0.0000e 00 - accuracy: 0.4833 - val_loss: 0.0000e 00 - val_accuracy: 0.4826
Epoch 2/20
1728/1728 [==============================] - 22s 13ms/step - loss: 0.0000e 00 - accuracy: 0.4847 - val_loss: 0.0000e 00 - val_accuracy: 0.4826
Epoch 3/20
1728/1728 [==============================] - 22s 13ms/step - loss: 0.0000e 00 - accuracy: 0.4827 - val_loss: 0.0000e 00 - val_accuracy: 0.4826
 

Как вы можете видеть, мои val_loss и val_accuracy не меняются. Что не так с моим кодом и как я могу это исправить?

Ответ №1:

Ответ был бы более точным, если бы было предоставлено больше информации о данных.

Для начала, вы использовали категориальную кросс-энтропию в качестве функции потерь, а Сигмоид — в качестве активации последнего слоя, что отчасти противоречиво (сигмоид означает, что вы классифицируете между 2 классами, а категориальная кросс-энтропия — это то, что вы используете, когда у вас более 2 классов). Либо измените свои потери на двоичную кросс-энтропию, если вы хотите использовать сигмоид (что означает, что у вас есть 2 класса), либо вам следует изменить свою сигмоиду на функцию softmax, если вы хотите классифицировать более 2 классов.

Кроме того, вы должны использовать flatten после последнего слоя CNN и перед первым плотным слоем (это превращает карту объектов (матрицу) в вектор, который является правильной формой ввода для плотных слоев.

Наконец, после выполнения всех этих действий вы можете поиграть со своими гиперпараметрами (скорость обучения, размер пакета и т. Д.), Чтобы посмотреть, сможете ли вы получить некоторый прирост точности.

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

1. Спасибо за ответ. Я изменил функцию активации на softmax, но она дает тот же результат

2. Тогда, я думаю, потребуется немного больше информации, чтобы убедиться, что вы все делаете правильно, например, какие данные, сколько данных вы используете для обучения, каково соотношение данных в каждом классе и тому подобное…

3. Я превращаю фотографии в массив numpy, изменяю размер до 50,50 после сброса в случайном порядке в X.pickle, и каждый класс (лицо) имеет идентификационный номер 0,1,2 в Y pickle с тем же индексом, что и номера индексов фотографий в X.pickle. 2 лицо имеет 12k фото, но третий класс имеет 1k фото.

4. Тогда данные кажутся мне нормальными (по крайней мере, на данный момент), вы когда-нибудь горячо кодировали свои метки? насколько я знаю, TensorFlow ожидает, что метки будут однократно закодированы, вы можете использовать что-то вроде этого — y = tf.keras.utils.to_categorical(y) . Другое дело, можете ли вы сделать значение параметра input_shape более явным, что-то вроде — input_shape = (X.shape[1], X.shape[2], 3) , здесь «3» в конце означает 3 канала (я предполагаю, что ваши изображения имеют цвет RGB).

5. Я пробовал оба. y = tf.keras.utils.to_categorical(y) возвращает массивные ошибки. Метод ввода формы дает тот же результат, что и тот же