Научите, как создать интерфейсный инструмент распознавания интеллектуальных значков.

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

Привет~ Я фронтенд-ученик Фэн (@Malpor), сегодня я представляю вам хардкорный интеллектуальный учебник по внешнему интерфейсу, который действительно научит вас использовать машинное обучение для создания чистого интеллектуального инструмента распознавания бегущих значков внешнего интерфейса. И прикрепите полный код, давайте вместе испытаем очарование интерфейсного интеллекта~

задний план

Текущие библиотеки интерфейсных компонентов используют Iconfont для управления иконками.Со временем появляется все больше и больше иконок, и названия иконок также разнообразны, что трудно ограничить. Когда разработчик восстанавливает эскиз дизайна, он часто просит человеческую плоть найти соответствующую иконку из сотен иконок. Иногда не удается найти даже дизайнера, что приводит к повторному добавлению иконок.

Недавно было обнаружено, что на официальном сайте AntDesign есть функция поиска иконок по изображению, пользователи могут щелкнуть/перетащить/вставить скриншот иконки в черновик дизайна или любое изображение для загрузки, а затем они могут искать значки с наивысшей степенью соответствия:AntDesign Icon,Статьи разработчиков функций

v2-fee8f94fbfe1885a713cd6fbb854385a_b.gif

Эта функция очень хорошо решает проблемы, упомянутые выше, но все же есть некоторые недостатки:

  • Скриншот предпочтительно квадратный или снижение скорости распознавания после растяжения (объяснено позже).
  • Распознаются только значки AntDesign.

Чтобы решить эти проблемы, мы решили сами создать интерфейсный инструмент для распознавания иконок. Следующее будет основано на библиотеке компонентов с открытым исходным кодом нашей команды.Cloud DesignНапример, я научу вас, как создать эксклюзивный инструмент для распознавания иконок. (полный код в конце статьи)

Введение в терминологию

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

машинное обучение

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

так,Машинное обучение — это не конкретный алгоритм, а общий термин для многих алгоритмов.

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

Сверточная нейронная сеть CNN

Сверточные нейронные сети (CNN) представляют собой класс нейронных сетей с прямой связью (Feedforward Neural Networks) с глубокими структурами, которые включают сверточные вычисления и чаще всего используются для анализа визуальных изображений.

CNN может эффективно уменьшить размер большого объема данных до небольшого объема данных и сохранить функции изображения, что очень подходит для обработки данных изображения. Даже если изображение перевернуто, повернуто или преобразовано, его можно эффективно распознать, и оно часто используется для решения следующих задач: поиск классификации изображений, мониторинг целевого позиционирования, распознавание лиц и т. д.

Начать

Мы хотим идентифицировать значок, который относится к классической проблеме «классификации изображений» в машинном обучении. CNN (Сверточная нейронная сеть) может эффективно идентифицировать значки, но не может адаптироваться к растянутым и деформированным сценам. Поскольку при вводе модели изображение должно быть преобразовано в квадратный размер, неправильный размер снимка экрана приведет к тому, что изображение будет растянуто и деформировано, что снизит скорость распознавания и даже ошибки распознавания.

截屏2021-03-21 下午10.36.41.png

Есть два распространенных решения:

1. Чистое машинное обучение: адаптируйте модель к деформированным изображениям, добавляя образцы различных растянутых состояний.

2. Машинное обучение + обработка изображений: используйте алгоритмы обработки изображений, чтобы обрезать данные, чтобы изображение было близко к квадрату.

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

截屏2021-03-21 下午10.38.04.png

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

генерация выборки

Учебные образцы для классификации изображений — это все изображения, а наши значки отображаются на странице с помощью шрифта iconfont. Естественно подумать об использовании образца страницы + скриншота Puppeteer для создания образца. Но скорость скриншота очень низкая, а пользоваться сервисом Faas не хочется, поэтому я подумал о локально сгенерированном методе:

Во-первых, вручную преобразуйте CSS-часть библиотеки иконок в js:

截屏2021-03-21 下午10.40.28.png

Это рисует значок в виде текста на холсте и использует алгоритм изображения для обрезки окружающего белого пространства:

// 用离屏 canvas 绘制图标
offscreenCtx.font = `20px NextIcon`;
offscreenCtx.fillText(labelMap[labelName]);

// 用 getImageData 获取图片数据,计算需裁剪的坐标
const { x, y, width: w, height: h } = getCutPosition(canvasSize, canvasSize, offscreenCtx.getImageData(0, 0, canvasSize, canvasSize).data);

// 计算需裁剪的坐标
function getCutPosition(width, height, imgData) {
  let lOffset = width; let rOffset = 0; let tOffset = height; let bOffset = 0;
  // 遍历像素,获取最小的非空白矩形区域
  for (let i = 0; i < width; i++) {
    for (let j = 0; j < height; j++) {
      const pos = (i + width * j) * 4;
      if (notEmpty(imgData[pos], imgData[pos + 1], imgData[pos + 2], imgData[pos + 3])) {
        // 调整 lOffset、rOffset、tOffset、bOffset
        // 略
      }
    }
  }
  
  // 如果形状不是正方形,将其扩展为正方形
  const r = (rOffset - lOffset) / (bOffset - tOffset);
  if (r !== 1) {
    // 略
  }

  return { x: lOffset, y: tOffset, width: rOffset - lOffset, height: bOffset - tOffset };
}

// 阈值 0 - 255
const d = 5;
// 判断是否非空白像素
function notEmpty(r, g, b, a) {
  return r < 255 - d && g < 255 - d && b < 255 - d;
}

// 用 canvas 裁剪 & 缩放图像,导出为 base64
ctx.drawImage(offscreenCanvas, x, y, w, h, 0, 0, 96, 96);
canvas.toDataURL('image/jpeg');

截屏2021-03-21 下午10.42.59.png

Логика создания картинки закончена. Измените его, пройдитесь по другим значкам и разным размерам шрифта, и вы сможете получить полный пример:

const fontStep = 1;
const fontSize = [20, 96];

labels.map((labelName) => {
  // 遍历不同的字号绘制图标
  for (let i = fontSize[0]; i <= fontSize[1]; i += fontStep) {
    // ...before
    offscreenCtx.font = `${i}px NextIcon`;
    // 其它逻辑
  }
});

Загрузите данные в виде json через blob:

const resultData = /* 生成全量数据 */;

const aLink = document.createElement('a');
const blob = new Blob([JSON.stringify(resultData, null, 2)], { type : 'application/json' });
aLink.download = 'icon.json';
aLink.href = URL.createObjectURL(blob);
aLink.click();

Таким образом получается большой json, содержащий десятки тысяч (350 иконок, около 70 изображений на категорию) образцов изображений, который выглядит так:

[
  {
    "name": "smile",
    "data": [
      {
        "url": "data:image/jpeg;base64,/9j/4AA...IkB//9k=",
        "size": 20
      },
      {
        "url": "data:image/jpeg;base64,/9j/4AA...JAf//Z",
        "size": 21
      },
      ...
    ]
  },
]

Наконец, напишите простую узловую программу, разделите образцы каждой классификации в соответствии с соотношением 70 % обучающего набора, 20 % проверочного набора и 10 % тестового набора и сохраните их в виде файлов изображений.

--- train
  |-- smile
    |-- smile_3.jpg
    |-- smile_7.jpg
  |-- cry
    |-- cry_2.jpg
    |-- cry_8.jpg
  ...
--- validation
  |-- smile
  |-- cry
  ...
--- test
  |-- smile
  |-- cry
  ...

Таким образом, мы получаем полную обучающую выборку, а скорость генерации очень высока, и для одного запуска требуется всего около 1 минуты. Затем упакуйте три каталога вместе в zip-файл, потому что следующее обучение поддерживает только формат zip.

обучение модели

Существует много видов инструментов машинного обучения, в качестве внешнего интерфейса я, наконец, решил использоватьPipcookтренировать.

PipcookПроект представляет собой набор инструментов с открытым исходным кодом, который позволяет веб-разработчикам лучше использовать машинное обучение для открытия и ускорения предыдущей интеллектуальной эпохи!

Инструкции по установке и обучению Pipcook см. на официальном сайте (Связь) достаточно, обратите внимание, что в настоящее время поддерживается толькоMac & Linux, Windows временно недоступна (Windows можно обучить с помощью Tensorflow.js).

Напишите элемент конфигурации pipcook:

{
  "plugins": {
    "dataCollect": {
      "package": "@pipcook/plugins-image-classification-data-collect",
      "params": {
        "url": "file://绝对路径,指向上一步打包的文件.zip"
      }
    },
    "dataAccess": {
      "package": "@pipcook/plugins-pascalvoc-data-access"
    },
    "dataProcess": {
      "package": "@pipcook/plugins-tfjs-image-classification-process",
      "params": {
        "resize": [224, 224]
      }
    },
    "modelDefine": {
      "package": "@pipcook/plugins-tfjs-mobilenet-model-define",
      "params": {}
    },
    "modelTrain": {
      "package": "@pipcook/plugins-image-classification-tfjs-model-train",
      "params": {
        "batchSize": 64,
        "epochs": 12
      }
    },
    "modelEvaluate": {
      "package": "@pipcook/plugins-image-classification-tfjs-model-evaluate"
    }
  }
}

Начните тренироваться с помощью инструмента Cli, входящего в состав Pipcook:

$ pipcook run 上面写的配置项.json

Видя успех слов эпохи и итерации, обучение успешно начинается.

...
ℹ [job] running modelTrain start
ℹ start loading plugin @pipcook/plugins-image-classification-tfjs-model-train
ℹ @pipcook/plugins-image-classification-tfjs-model-train plugin is loaded
ℹ Epoch 0/12 start
ℹ Iteration 0/303 result --- loss: 5.969481468200684 accuracy: 0
ℹ Iteration 30/303 result --- loss: 5.65574312210083 accuracy: 0.015625
ℹ Iteration 60/303 result --- loss: 5.293442726135254 accuracy: 0.0625
ℹ Iteration 90/303 result --- loss: 4.970404624938965 accuracy: 0.03125
...

На обучение более 20 000 сэмплов на моем Mac с указанными выше параметрами уходит около двух часов, в этот период ресурсы процессора компьютера будут заняты, поэтому мне нужно найти свободное время для обучения. Если вы хотите остановиться посередине, бесполезно использовать Ctrl + C, вам нужно использовать его сначалаpipcook job listПросмотрите список задач, затем используйтеpipcook job stop <jobId>прекратить обучение.

Время обучения связано с: объемом данных выборки, эпохами и размером партии.

/* =============== Через два часа... =============== */

После обучения вы можете увидеть окончательный коэффициент потерь (чем меньше, тем лучше) и точность (чем больше, тем лучше):

...
ℹ [job] running modelEvaluate start
ℹ start loading plugin @pipcook/plugins-image-classification-tfjs-model-evaluate
ℹ @pipcook/plugins-image-classification-tfjs-model-evaluate plugin is loaded
ℹ Evaluate Result: loss: 0.05339580587460659 accuracy: 0.9850694444444444
...

Если коэффициент потерь больше 0,2, а коэффициент точности ниже 0,8, эффект обучения не очень хороший, необходимо настроить параметры или образцы, а затем повторить обучение.

При этом pipcook создаст выходную папку в той же директории, что и элемент конфигурации json, в которой находятся нужные нам модели:

output
  |-- logs    # 训练日志文件夹
  |-- model   # 模型文件夹,里面两个文件就是最终需要的产物
      |-- weights.bin
      |-- model.json
  |-- metadata.json    # 元信息
  |-- package.json     # 项目信息
  |-- index.js         # 默认入口文件
  |-- boapkg.js        # 辅助文件

использование модели

Поскольку используемый плагин Pipcook вызывает Tensorflow.js внизу для обучения, модель можно запускать непосредственно на странице внешнего интерфейса.

Сначала мы генерируемmodel.jsonа такжеweights.binСохраните его в том же каталоге. затем найтиmetadata.jsonсерединаoutput.datasetПоле, представляющее собой строку Json, найденную после десериализацииlabelArrayзначение свойства и сохраните его:

// 目前这个顺序是随机生成的,和样本生成时的顺序不一样,不要混淆了
const labelArray = ["col-before","h1","solidDown","add-test",...];

Готово, просто напишите еще немного кода Tensorflow.js для идентификации.

import * as tf from '@tensorflow/tfjs';

const modelUrl = 'model.json 的访问地址';
// 加载模型
model = await tf.loadLayersModel(modelUrl);

// 对输入图像裁剪
const { x, y, width: w, height: h } = getCutPosition(imgW, imgH, offscreenCtx.getImageData(0, 0, imgW, imgH).data, 'white');
ctx.drawImage(offscreenCanvas, x, y, w, h, 0, 0, cutSize, cutSize);

// 图像转化为 tensor
const imgTensor = tf.image
  .resizeBilinear(tf.browser.fromPixels(canvas), [224, 224])
  .reshape([1, 224, 224, 3]);
  
// 模型识别
const pred = model.predict(imgTensor).arraySync()[0];

// 找出相似度最高的 5 项
const result = pred.map((score, i) => ({ score, label: labelArray[i] }))
  .sort((a, b) => b.score - a.score)
  .slice(0, 5);

ты закончил

Mar-21-2021 23-20-30.gif

Теперь вы можете начать испытывать возможности распознавания значков и пользоваться удобством, которое дает машинное обучение. Это чистый front-end инструмент, не требующий дополнительных back-end сервисов, который можно развернуть на статическом сайте, он очень подходит для сцены поиска иконок на сайте библиотеки компонентов. Нет проблем, если у команды есть собственная библиотека значков, если вы будете следовать инструкциям, вы сможете обучить эксклюзивную модель.

Полный код смотрите по адресу:GitHub.com/карта потока или/icon…

Суммировать

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

Если у вас есть какие-либо вопросы, вы можете указать их в комментариях, и вы можете испытать обмен ~

Общая проблема

  • Что делать, если в библиотеке значков есть новые/измененные значки? A: Модель необходимо переобучить.

использованная литература

Стэнфордский курс машинного обучения

«Огромные значки Tensorflow.js, распознавание на уровне миллисекунд! 》

Официальный сайт Tensorflow.js

Официальный сайт Пипкука

Узнайте больше о машинном обучении в одной статье

Статья для понимания сверточной нейронной сети CNN

Присоединяйтесь к нам

Мы являемся командой TXD (технологии опыта) Alibaba Cloud, и мы ищем переднего плана и дизайнеров.Набор 22-й школы для стажеров также идет полным ходом.Заинтересованные студенты могут связаться со мной для получения дополнительной информации:zhaoye.zzy@alibaba-inc.com

mmexport1616514992052.jpg