Проблема классификации нескольких классов с использованием нейронной сети
Описание Проекта
Вдохновение
От производства овощей до доставки несколько стандартных операций выполняются вручную. Например, сбор и сортировка овощей. Поэтому мы решили решить эту проблему, используя глубокую нейронную архитектуру, разработав модель, которая может обнаруживать и классифицировать овощи. Эта модель может быть реализована в различных типах устройств, а также может решать другие проблемы, связанные с идентификацией овощей, например, автоматическая маркировка овощей без участия человека.
Набор данных
Выбран набор данных овощей, содержащий 21 000 изображений:
- обучающий набор содержит 15 000 примеров
- тестовый набор содержит 3000 примеров
- набор проверки содержит 3000 примеров
Овощи должны быть разделены на 15 различных типов:
- Бин
- Горькая тыква
- Бутылочная тыква
- Бринжал
- Капуста
- стручковый перец
- Морковь
- Цветная капуста
- Огурец
- Папайя
- Картофель
- тыква
- Редька
- Помидор
Запрос на цитирование
Проект исходит из этого исследования. Вы можете получить доступ к этой исследовательской статье, чтобы получить представление от авторов.
Вы можете получить доступ к этому набору данных через Kaggle.
Примечание
Существуют абсолютно превосходные методы машинного обучения или глубокого обучения для решения этой проблемы, но для того, чтобы помочь всем специалистам по данным лучше понять нейронную сеть. Я использовал нейронную сеть в этой реализации, и я мог бы предоставить больше решений для решения этой проблемы после того, как изучу другие типы методов машинного обучения. Надеюсь, это поможет вам в изучении нейронной сети.
Предварительная обработка данных
Сначала нам нужно предварительно обработать данные для ввода в модель. В отличие от структурированных данных, хранящихся в таблице, изображение является разновидностью неструктурированных данных. Способ предварительной обработки отличается от структурированного. Обычно мы играем с Pandas со структурированными данными. Но для того, чтобы получить файл изображения, нам нужно получить доступ к пути их хранения на компьютере.
Итак, сначала мы импортируем связанные библиотеки:
# import library import os import numpy as np
Доступ к файлу изображения
Затем мы получаем доступ к файлу вместе с каталогом. Помните, что для упрощения процесса реализации настоятельно рекомендуется поместить папку с кодом и файлом изображения в один и тот же каталог.
# Dir:(one example) Vegetable Image/train/Pumpkin/12345.jpg fileDirVege = 'Vegetable Images' vege_dataset = os.listdir(fileDirVege) # [train,test.validation] vege_train = [] # list: data for training set vege_test = [] # list: data for test set vege_validation = [] # list: data for validation set for typedir in vege_dataset: if(not r'.' in typedir): # typeDirName: Vegetable Image/train typeDirName = os.path.join(fileDirVege,typedir) # vegedir: a list of 15 kinds of vegetables vegedir=os.listdir(typeDirName) for v in vegedir: if v != '.DS_Store': # Note to remove this # vegeDirName: Vegetable Image/train/Pumpkin vegeDirName = os.path.join(typeDirName,v) # vedir: a list of all the jpg file for one type of vegetable vedir = np.array(os.listdir(vegeDirName)) for vegetable in vedir: # access each image one by one if(vegetable[-3:]=='jpg'): fn=os.path.join(vegeDirName,vegetable) if typedir == 'train': vege_train.append(fn) elif typedir == 'test': vege_test.append(fn) else: vege_validation.append(fn)
Обработка изображений и маркировка
Способ, которым компьютер решает задачу, заключается в обработке числовых данных. Итак, нам нужно преобразовать изображение в числовое представление.
Перед преобразованием мы можем немного обработать изображение. Чтобы сократить время вычислений, мы можем изменить изображение RGB на уровень серого. И поскольку размеры изображений не равны, нам также нужно изменить их размер до одинакового размера. Здесь мы используем библиотеку Python Pillow для ее обработки.
Затем, после предварительной обработки данных, данные изображения сохраняются в массиве NumPy в числовом виде. И здесь мы получаем доступ к файлу, следуя пути к файлу, чтобы получить метку изображения.
# image manipulation from PIL import Image # label the data def label(path): img, labels = [], [] l1 = os.listdir(path) for i in l1: # in order to get the class (label) if i != '.DS_Store': l2 = os.listdir(path+'/'+i) for j in l2: image = Image.open(path+'/'+i+'/'+j) image.convert('L') # RGB to Gray level image = image.resize(size = (28,28)) # Normalizing img.append(np.array(image).flatten()) # Store in numerical way labels.append(i) return np.array(img), labels
Разделить набор данных
Поскольку этот набор данных уже разделен на наборы для обучения, тестирования и проверки, мы можем легко получить и сохранить все файлы в связанном наборе, обратившись к разным папкам:
# Split Dataset X_train, y_train = label("Vegetable Images/train") X_test, y_test = label("Vegetable Images/test") X_val, y_val = label("Vegetable Images/validation")
Метка хранится в строке, и нам нужно преобразовать ее в число:
from sklearn.preprocessing import LabelEncoder le = LabelEncoder() le.fit(y_train) y_train = le.fit_transform(y_train) le.fit(y_test) y_test = le.fit_transform(y_test) le.fit(y_val) y_val = le.fit_transform(y_val)
Обучите модель
Построить модель
Теперь все было готово. Мы собираемся внедрить модель обучения. Здесь TensorFlow используется для построения нейронной сети.
# Build the model import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense model =Sequential([ tf.keras.Input(shape=(X_train.shape[1]),), Dense(512, activation = 'relu', name = "L1"), Dense(256, activation = 'relu', name = "L2"), Dense(128, activation = 'relu', name = "L3"), Dense(64, activation = 'relu', name = "L4"), Dense(15, activation = 'linear', name = "L5") ], name = 'Vege Recognition') model.summary()
Входная форма — это количество объектов для ввода (не записей!). И Dense представляет каждый слой в модели NN. Число обозначает количество нейронов в каждом слое. И выходной слой всегда 15, так как мы хотим классифицировать их по 15 категориям. Так как это мультиклассовые задачи, мы используем активацию Softmax в выходных слоях. Результатом слоя softmax является набор вероятностей отнесения примера к каждому классу. Затем он выбирает класс с наибольшей вероятностью. И выход - предсказание примеров.
Количество слоев и нейронов не уникально. Вы можете попробовать с другими значениями. И отрегулируйте параметры в соответствии с точностью обучения и проверки.
Ниже приведено краткое описание модели:
Оптимизация модели и перекрестная проверка
Перекрестная проверка является эффективным методом проверки проблемы переобучения. Как правило, переобучение может быть связано с тем, что нашего набора данных недостаточно или наша модель слишком сложна. Поэтому, если ваша модель имеет высокую точность обучения, но низкую точность проверки, ваша модель страдает от проблемы переобучения. Нам нужно проверить и предотвратить это, чтобы гарантировать производительность нашей модели.
model.compile( loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), #softmax layer optimizer=tf.keras.optimizers.Adam(0.001), # Adam optimizer metrics=['acc']) history = model.fit(X_train, y_train, epochs = 100, validation_data = (X_val, y_val))
Затем мы наносим точность и потери в каждую эпоху.
import matplotlib.pyplot as plt plt.subplot(2,1,1) plt.title("Accuracy") plt.plot(history.history["acc"], color="blue", label="train") plt.plot(history.history["val_acc"], color="red", label="validation") plt.legend(loc="best") plt.subplot(2,1,2) plt.title("Loss/Contrastive Loss") plt.plot(history.history["loss"], color="blue", label="train") plt.plot(history.history["val_loss"], color="red", label="validation") plt.legend(loc="best") plt.tight_layout() plt.show()
И результат показан ниже. Мы видим, что и проверка, и точность обучения идеально высоки. Таким образом, наша модель не страдает от проблемы переобучения.
Тестовая модель
Затем мы тестируем модель, делая прогноз для тестового набора. Поскольку существует 3000 тестовых примеров, завершение всего процесса может занять больше времени.
# Test the model y_pred = [] for i in range(X_test.shape[0]): v = X_test[i] # fit the num of features, remember your input shape! prediction = model.predict(v.reshape(1,2352)) # calculate the probability for each class p = tf.nn.softmax(prediction) # Choose the class with highest probability y_hat = np.argmax(p) y_pred.append(y_hat) y_pred = np.array(y_pred)
Оценить модель
Наконец, мы оцениваем модель, вычисляя точность, точность/отзыв, F1-оценку и отображая матрицу путаницы.
# Model Evaluation from sklearn.metrics import accuracy_score, confusion_matrix, classification_report, ConfusionMatrixDisplay acc = accuracy_score(y_pred,y_test) # accuracy cm = confusion_matrix(y_test,y_pred) # Confusion Matrix cm_display = ConfusionMatrixDisplay(confusion_matrix = cm) # Demo the evaluation print('Accuracy:',acc) print(classification_report(y_test,y_pred)) # Precision/Recall/F1-Score cm_display.plot() plt.show()
Точность модели составляет 85,8%, что можно считать идеальной моделью.
Вот и все о сегодняшней статье, буду рад, если моя статья вам понравится! И я также буду рад любым комментариям/обсуждениям о других превосходных алгоритмах для решения этой проблемы, поскольку я также изучаю область науки о данных! Спасибо за ваше чтение! Весь код доступен в моем GitHub.