Рубрики
Без рубрики

Многоклассовая Классификация Изображений С Использованием Трансферного Обучения С Помощью PySpark

Демонстрация проблемы компьютерного зрения с возможностью объединения двух современных технологий: глубокого обучения с Apache Spark.

Автор оригинала: Mohammed Innat.

В этой статье мы продемонстрируем проблему компьютерного зрения с возможностью объединения двух современных технологий: Deep Learning с Apache Spark . Мы будем использовать мощь Конвейеров глубокого обучения для решения многоклассовой задачи классификации изображений.

Конвейеры глубокого обучения-это высокоуровневая платформа глубокого обучения, которая облегчает общие рабочие процессы глубокого обучения с помощью API конвейеров Spark MLlib. В настоящее время он поддерживает TensorFlow и Keras с помощью TensorFlow-backend.

Библиотека исходит из Databricks и использует Spark для своих двух самых сильных граней:

  • В духе Spark и Spark MLlib он предоставляет простые в использовании API-интерфейсы, которые обеспечивают глубокое обучение в очень немногих строках кода.
  • Он использует мощный распределенный движок Spark для масштабирования глубокого обучения на массивных наборах данных.

Трансфертное обучение

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

Конвейеры глубокого обучения предоставляют утилиты для выполнения обучения передаче изображений, что является одним из самых быстрых способов начать использовать глубокое обучение. Благодаря концепции Featurizer конвейеры глубокого обучения обеспечивают быстрое обучение передаче данных на Spark-кластере. Прямо сейчас он предоставляет следующие нейронные сети для обучения передаче:

  • Начало V3
  • Исключение
  • ResNet 50
  • VGG16
  • VGG 19

В демонстрационных целях мы будем работать только с моделью Inception V3 . Технические подробности этой модели вы можете прочитать здесь .

Следующий пример объединяет Inception V3 модель и мультиномиальную логистическую регрессию в Spark. Функция полезности из конвейеров глубокого обучения, называемая DeepImageFeaturizer , автоматически отслаивает последний слой предварительно обученной нейронной сети и использует выходные данные всех предыдущих слоев в качестве функций для алгоритма логистической регрессии.

Набор данных

Бенгальский алфавит имеет десять числовых цифр (графемы или символы, обозначающие числа от 0 до 9). Числа больше 9 записываются на бенгальском языке с использованием позиционной системы счисления 10.

Мы выбираем Numtab в качестве источника нашего набора данных. Это коллекция бенгальских рукописных цифровых данных. Набор данных содержит более 85 000 цифр от более чем 2700 участников. Но здесь мы не планируем работать со всем набором данных, а не выбирать случайным образом 50 изображений каждого класса.

Рис. 1: Каждая папка Содержит 50 изображений [ Классы (от 0 до 9) ]

Скриншот с 2019-07-22 23-50-38.png

Давайте посмотрим ниже, что у нас внутри каждой из десяти папок. Я переименовываю каждое изображение, показанное ниже, соответствующей метки класса в демонстрационных целях.

Рис. 2: Бенгальская Рукописная цифра

Скриншот с 2019-07-22 23-59-01.png

Сначала мы загружаем все изображения в Spark DataFrame. Затем мы строим модель и обучаем ее. После этого мы оценим производительность нашей обученной модели.

Загрузка изображений Наборы данных (от 0 до 9) содержат почти 500 рукописных цифр Бангла (по 50 изображений в каждом классе). Здесь мы вручную загружаем каждое изображение в spark data-frame с целевым столбцом. После загрузки всего набора данных мы случайным образом разделились на соотношение 8:2 для обучающего набора и финального тестового набора.

Наша цель состоит в том, чтобы обучить модель с помощью обучающего набора данных и, наконец, оценить производительность модели с помощью тестового набора данных.

# necessary import 
from pyspark.sql import SparkSession
from pyspark.ml.image import ImageSchema
from pyspark.sql.functions import lit
from functools import reduce

# create a spark session
spark = SparkSession.builder.appName('DigitRecog').getOrCreate()

# loaded image
zero = ImageSchema.readImages("0").withColumn("label", lit(0))
one = ImageSchema.readImages("1").withColumn("label", lit(1))
two = ImageSchema.readImages("2").withColumn("label", lit(2))
three = ImageSchema.readImages("3").withColumn("label", lit(3))
four = ImageSchema.readImages("4").withColumn("label", lit(4))
five = ImageSchema.readImages("5").withColumn("label", lit(5))
six = ImageSchema.readImages("6").withColumn("label", lit(6))
seven = ImageSchema.readImages("7").withColumn("label", lit(7))
eight = ImageSchema.readImages("8").withColumn("label", lit(8))
nine = ImageSchema.readImages("9").withColumn("label", lit(9))

dataframes = [zero, one, two, three,four,
             five, six, seven, eight, nine]
             
# merge data frame
df = reduce(lambda first, second: first.union(second), dataframes)

# repartition dataframe 
df = df.repartition(200)
# split the data-frame
train, test = df.randomSplit([0.8, 0.2], 42)

Здесь мы можем выполнять различные Исследовательские анализы данных на Spark DataFrame. Мы также можем просмотреть схему фрейма данных.

df.printSchema()

root
 |-- image: struct (nullable = true)
 |    |-- origin: string (nullable = true)
 |    |-- height: integer (nullable = false)
 |    |-- width: integer (nullable = false)
 |    |-- nChannels: integer (nullable = false)
 |    |-- mode: integer (nullable = false)
 |    |-- data: binary (nullable = false)
 |-- label: integer (nullable = false)

Мы также можем преобразовать Spark-DataFrame в Pandas-DataFrame с помощью .toP и as() .

Модельное обучение

Здесь мы объединяем Inception V3 модель и логистическую регрессию в Spark. DeepImageFeaturizer автоматически отслаивает последний слой предварительно обученной нейронной сети и использует выходные данные всех предыдущих слоев в качестве признаков для алгоритма логистической регрессии.

Поскольку логистическая регрессия является простым и быстрым алгоритмом, это обучение трансферному обучению может быстро сходиться.

from pyspark.ml.evaluation import MulticlassClassificationEvaluator
from pyspark.ml.classification import LogisticRegression
from pyspark.ml import Pipeline
from sparkdl import DeepImageFeaturizer

# model: InceptionV3
# extracting feature from images
featurizer = DeepImageFeaturizer(inputCol="image",
                                 outputCol="features",
                                 modelName="InceptionV3")
                                 
# used as a multi class classifier
lr = LogisticRegression(maxIter=5, regParam=0.03, 
                        elasticNetParam=0.5, labelCol="label")
                        
# define a pipeline model
sparkdn = Pipeline(stages=[featurizer, lr])
spark_model = sparkdn.fit(train) # start fitting or training

Оценка

Теперь пришло время оценить производительность модели. Теперь мы хотели бы оценить четыре оценочных показателя, такие как F1-score, Precision, Recall, Accuracy на тестовом наборе данных.

from pyspark.ml.evaluation import MulticlassClassificationEvaluator

# evaluate the model with test set
evaluator = MulticlassClassificationEvaluator() 
tx_test = spark_model.transform(test)

print('F1-Score ', evaluator.evaluate(tx_test, 
                                      {evaluator.metricName: 
                                      'f1'}))
                                      
print('Precision ', evaluator.evaluate(tx_test, 
                                     {evaluator.metricName:
                                     'weightedPrecision'}))
                                       
print('Recall ', evaluator.evaluate(tx_test, 
                                    {evaluator.metricName: 
                                    'weightedRecall'}))
                                    
print('Accuracy ', evaluator.evaluate(tx_test, 
                                      {evaluator.metricName: 
                                      'accuracy'}))

Вот мы и получаем результат. Это многообещающе до сих пор.

F1-Score   0.8111782234361806
Precision  0.8422058244785519
Recall     0.8090909090909091
Accuracy   0.8090909090909091

Матрица путаницы

Здесь мы подведем итоги работы классификационной модели с использованием матрицы путаницы.

import matplotlib.pyplot as plt
import numpy as np
import itertools

# function for plotting confusion matrix
def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.GnBu):
                          
              plt.imshow(cm, interpolation='nearest', cmap=cmap)
                  plt.title(title)
                  tick_marks = np.arange(len(classes))
                  plt.xticks(tick_marks, classes, rotation=45)
                  plt.yticks(tick_marks, classes)
                  fmt = '.2f' if normalize else 'd'
                  thresh = cm.max() / 2.
                  for i, j in itertools.product(range(cm.shape[0]), 
                      range(cm.shape[1])):
                      plt.text(j, i, format(cm[i, j], fmt),
                               horizontalalignment="center",
                               color="white" if cm[i, j] > thresh else "black")

                  plt.tight_layout()
                  plt.ylabel('True label')
                  plt.xlabel('Predicted label')

Для этого нам нужно сначала преобразовать Spark-DataFrame в Pandas-DataFrame , а затем вызвать матрицу путаницы с истинными и предсказанными метками.

from sklearn.metrics import confusion_matrix
y_true = tx_test.select("label")
y_true = y_true.toPandas()

y_pred = tx_test.select("prediction")
y_pred = y_pred.toPandas()

cnf_matrix = confusion_matrix(y_true, y_pred,labels=range(10))

Давайте визуализируем матрицу Путаницы

import seaborn as sns
sns.set_style("darkgrid")
plt.figure(figsize=(7,7))
plt.grid(False)

# call pre defined function
plot_confusion_matrix(cnf_matrix, classes=range(10))

Рис. 3: Матрица путаницы для 10 бенгальских цифр (от 0 до 9)

Скриншот с 2019-07-23 00-40-15.png

Классификационный отчет

Здесь мы также можем получить отчет о классификации каждого класса по матрице оценки.

from sklearn.metrics import classification_report
target_names = ["Class {}".format(i) for i in range(10)]
print(classification_report(y_true, y_pred, target_names = target_names))

Он будет гораздо лучше демонстрировать производительность модели для каждого предсказания метки класса.

               precision  recall   f1-score   support
     Class 0       1.00      0.92      0.96        13
     Class 1       0.57      1.00      0.73         8
     Class 2       0.64      1.00      0.78         7
     Class 3       0.88      0.70      0.78        10
     Class 4       0.90      1.00      0.95         9
     Class 5       0.67      0.83      0.74        12
     Class 6       0.83      0.62      0.71         8
     Class 7       1.00      0.80      0.89        10
     Class 8       1.00      0.80      0.89        20
     Class 9       0.70      0.54      0.61        13
     
   micro avg       0.81      0.81      0.81       110
   macro avg       0.82      0.82      0.80       110
weighted avg       0.84      0.81      0.81       110

Оценка ROC AUC

Давайте также найдем балльную точку ROC AUC этой модели. Я нашел следующий фрагмент кода из здесь .

from sklearn.metrics import roc_curve, auc, roc_auc_score
from sklearn.preprocessing import LabelBinarizer

def multiclass_roc_auc_score(y_test, y_pred, average="macro"):
    lb = LabelBinarizer()
    lb.fit(y_test)
    y_test = lb.transform(y_test)
    y_pred = lb.transform(y_pred)
    return roc_auc_score(y_test, y_pred, average=average)
    
print('ROC AUC score:', multiclass_roc_auc_score(y_true,y_pred))

Он забивает 0.901 .

Прогнозируемые Образцы

Давайте посмотрим на некоторые его предсказания, сравнение с реальной меткой.

# all columns after transformations
print(tx_test.columns)

# see some predicted output
tx_test.select('image', "prediction", "label").show()

И результат будет следующим

['image', 'label', 'features', 'rawPrediction', 'probability', 'prediction']
+------------------+----------+--------+
|       image      |prediction|  label |
+------------------+----------+--------+
|[file:/home/i...|       1.0|    1|
|[file:/home/i...|       8.0|    8|
|[file:/home/i...|       9.0|    9|
|[file:/home/i...|       1.0|    8|
|[file:/home/i...|       1.0|    1|
|[file:/home/i...|       1.0|    9|
|[file:/home/i...|       0.0|    0|
|[file:/home/i...|       2.0|    9|
|[file:/home/i...|       8.0|    8|
|[file:/home/i...|       9.0|    9|
|[file:/home/i...|       0.0|    0|
|[file:/home/i...|       4.0|    0|
|[file:/home/i...|       5.0|    9|
|[file:/home/i...|       1.0|    1|
|[file:/home/i...|       9.0|    9|
|[file:/home/i...|       9.0|    9|
|[file:/home/i...|       1.0|    1|
|[file:/home/i...|       1.0|    1|
|[file:/home/i...|       9.0|    9|
|[file:/home/i...|       3.0|    6|
+--------------------+----------+-----+
only showing top 20 rows

Конец примечания

Хотя мы использовали вес ImageNet , наша модель довольно многообещающе распознает рукописные цифры. Более того, мы также не выполняли никаких задач обработки изображений для лучшего обобщения. Кроме того, модель обучается на очень небольшом количестве данных по сравнению с набором данных ImageNet.

На очень высоком уровне каждое приложение Spark состоит из программы-драйвера, которая запускает различные параллельные операции в кластере. Программа-драйвер содержит основную функцию вашего приложения и определяет распределенные наборы данных в кластере, а затем применяет к ним операции.

Поскольку это автономное приложение, в котором мы сначала связали приложение с Spark, а затем импортировали пакеты Spark в нашу программу и создали SparkContext с помощью SparkSession . Хотя мы работали на одной машине, мы можем подключить одну и ту же оболочку к кластеру для параллельной обработки данных.

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

Исходный код : TL С PySpark

Что дальше?

Далее мы сделаем Распределенную настройку гиперпараметров с помощью Spark , а также попробуем пользовательскую Keras модель и некоторые новые сложные примеры

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

Скажи Привет: Электронная почта | сеть LinkedIn | Quora | GitHub | Средний | Твиттер | Инстаграм

Сопутствующие Технологии

  • Распределенный DL с Keras & PySpark — Elephas
  • Распределенная библиотека глубокого обучения для Apache Spark — BigDL
  • TensorFlow to Apache Spark clusters — TensorFlowOnSpark

Рекомендации