Саморазвитие

Решение задачи классификации с помощью нейронной сети и Python

Время прочтения: 4 мин.

Задача классификации встречается довольно часто, но при решении каждой конкретной задачи встречаются свои сложности. Поэтому сегодня мы посмотрим, можно ли решить задачу классификации не с помощью стандартных методов машинного обучения, а с помощью нейронной сети и при этом получить хороший результат классификации. На входе имеем результаты работы нейронной сети, которая определяла объекты, находящиеся на изображении с камеры – 12 классов изображений и 35 типов объектов, которые были найдены на изображениях.

Задача:

1. Подготовить данные для работы нейронной сети.

2. Обучить нейронную сеть определять класс изображения по найденным объектам.

3. Проверить обученную нейронную сеть на тестовой выборке.

Для решения данной задачи будем использовать библиотеки tensorflow, pandas и numpy.

Сначала достанем из имени файла название класса и отсортируем записи в таблице.

data = pd.read_csv(os.path.join(inPath, 'data.csv'), sep=';', encoding='UTF-8')

for i in range(len(data)):
    data.iat[i, 0] = data.iat[i, 0].split("\\")[-1]
    data.iat[i, 0] = data.iat[i, 0].split(".")[0]
    c1 = data.iat[i, 0].split("_")
    k1 = len(c1)
    data.iat[i, 0] = ''
    for j in range(len(c1) - 1):
        data.iat[i, 0] += c1[j]
        if j != len(c1) - 2:
            data.iat[i, 0] += '_'

data = data.sort_values(by=['filename'])

Также нормализуем значения из выборки и заполним пустые ячейки нулями.

data_copy = data.copy()
del data_copy['filename']
data_copy[data_copy == 1] = 0.33
data_copy[data_copy == 2] = 0.66
data_copy[data_copy >= 3] = 1
data_copy = data_copy.fillna(0)
data_copy.insert(0, 'filename', data['filename'])

Следующий шаг – заменить имя класса на числовой вектор из 0 и 1. Вектор будет содержать одну 1 и одиннадцать 0 и показывать вероятность принадлежности к конкретному классу. А чтобы разделить выборку, считаем количество записей, относящихся к каждому классу, и делим данные в соотношении 60/40 соответственно.

Теперь необходимо построить модель нейронной сети. На вход ей будет подаваться 35 чисел – нормированное количество объектов на изображении, на выходе будет 12 чисел – вероятность принадлежности к каждому классу. Используем наиболее распространенную функцию активации «relu» и функцию потерь MSE (среднюю квадратическую ошибку), при которой нейронная сеть выдает лучший результат. Также добавим слой Dropout, чтобы предотвратить переобучение модели.

model = keras.Sequential([
layers.Dense(35, activation='relu'),
    layers.Dense(70, activation='relu'),
    layers.Dense(70, activation='relu'),
    layers.Dropout(0.1),
    layers.Dense(105, activation='relu'),
    layers.Dense(70, activation='relu'),
    layers.Dense(35, activation='relu'),
    layers.Dense(12)])

optimizer = tf.optimizers.Adam()
model.compile(loss=tf.keras.losses.MSE, optimizer=optimizer, metrics=['accuracy'])
history = model.fit(train_data, train_names, epochs=1000)

Построим графики обучения нашей модели – график потерь (Model loss) и график точности (Model accuracy). По вертикали изменение параметра, по горизонтали – количество эпох обучения. Как видно из графиков, Потери приближаются к 0, а точность приближается к 1.

plt.plot(history.history['accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.show()

plt.plot(history.history['loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.show()

Чтобы использовать модель в дальнейшем сохраним ее в специальном формате h5.

model.save('model.h5')

После обучения модели, проверим ее на тестовой выборке. Получаем следующие результаты:

Получаем, что правильно классифицировали 90% всех случаев. Класс pomeschenie_pered_htsk содержал меньше всего объектов, поэтому нейронная сеть не смогла определить его на тестовой выборке.

Что предпринималось, чтобы улучшить результат работы нейронной сети?

  1. Нормализация чисел исходной таблицы в диапазон [0; 1]. При исходных данных процент верно определенных классов был меньше.
  2. Изменение параметров нейронной сети (выбор оптимизатора, выбор функции потерь, изменение количества Dense слоев, изменение количества нейронов на каждом слое).
  3. Изменение количества выходных нейронов. Если нейронная сеть на выходе выдает только одно число – класс изображения, то процент верно определенных классов меньше.

Вывод: задачу классификации можно также успешно решать с помощь нейронной сети – главное подготовить исходные данные и настроить параметры нейронной сети.

Советуем почитать