Автор оригинала: 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) ]
Давайте посмотрим ниже, что у нас внутри каждой из десяти папок. Я переименовываю каждое изображение, показанное ниже, соответствующей метки класса в демонстрационных целях.
Рис. 2: Бенгальская Рукописная цифра
Сначала мы загружаем все изображения в 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)
Классификационный отчет
Здесь мы также можем получить отчет о классификации каждого класса по матрице оценки.
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
Рекомендации
- Databricks: Руководство по глубокому обучению
- Apache Spark: Машинное обучение PySpark