В прошлом году я смотрел видео из Стэнфордского курса CS231n, основополагающего курса машинного обучения Фей-Фей Ли, Джастина Джонсона и Андрея Карпати.

Курс посвящен распознаванию изображений со ссылкой на Google Image Search. В домашних заданиях используются стандартные наборы данных, такие как символы notMNIST. Мне не нравилось выполнять все те же упражнения, что и всем остальным - я хотел заниматься своим делом. Я пытаюсь выучить китайский язык и построил Pingtype, который помогает мне добавлять пробелы между словами, пиньинь, буквальный и параллельный переводы. Почему бы не создать лучший китайский OCR?

Вот окончательный результат: 15 миллионов файлов PNG 28x28, содержащих 52 835 символов. В сжатом виде - 9,98 ГБ; 13,48 ГБ без сжатия.



Остальная часть статьи описывает, как я это сделал, почему на это ушел год и чему я научился на этом пути.

Скрипты, которые я использовал, доступны здесь:



Шаг 1. Приобретите шрифты

Дата: 2017–06–19

Скрипт: Скачать Chinese Fonts.scpt

Есть отличный веб-сайт под названием Chinese Font Design с большой коллекцией шрифтов. Я написал парсер, чтобы запустить wget и загрузить их все. Примерно через 5 часов у меня была папка размером 15 ГБ, полная файлов RAR, ZIP и 7z.

Шаг 2. Распакуйте архивы

Дата: 2017–06–20

Утилита архивирования не любит разные наборы символов и дает имена вроде «Œƒ∂¶≥¨∫⁄.ttf». Вместо этого я использовал Unarchiver и указал набор символов (обычно BIG5 или GB2312). Это дает правильные китайские имена файлов, например «恅 隋 閉 窪 .ttf». Извлеченные данные занимают еще 15 ГБ.

Шаг 3. Преобразование в TTF

Дата: 2017–06–21

Некоторые шрифты были TTF, некоторые - TTC, а другие - OTF. Я использовал fontforge, чтобы преобразовать все в TTF.

Тогда у меня было 11,82 ГБ из 1304 файлов TTF. С этим было трудно справиться, поэтому я разделил его на 6 подпапок по ~ 220 файлов TTF или 2,16 ГБ в каждой.

Шаг 4. Извлеките символы

Дата: 2017–06–21

Какие персонажи мне нужны? Это усложняется из-за радикалов и двухбайтовых символов. Я использовал словарь Pingtype, чтобы получить 75617 символов, которые на самом деле находятся в моих источниках данных, сделав китайский75617.txt.

Затем я использовал hb-view от Harfbuzz, чтобы получить PNG для каждого из этих символов. Я написал сценарий для чтения каждого символа из файла и экспорта его в папку для этого шрифта.

Мой внутренний SSD был заполнен, поэтому я использовал офисный MacBook Pro 2012 и внешний диск емкостью 2 ТБ. К сожалению, на этом компьютере есть только USB 2, поэтому запись файлов шла медленно. Прошло 3 месяца.

Извлечение продолжалось до 2017–09–28.

PNG использует более 300 МБ на шрифт, всего 450 ГБ.

Открытие папки шрифтов в Finder занимает 19 секунд, даже при подключении через USB 3 к моему обычному ноутбуку, MacBook Pro Retina 2014. Мне нужно было вручную проверить каждую папку, чтобы удалить пустые глифы. Это было слишком медленно.

Шаг 5. Купите твердотельный накопитель большего размера

Я понял, что мне нужно лучшее оборудование, если я когда-нибудь собираюсь разбирать эти данные. Срок действия AppleCare моего ноутбука подходил к концу в марте 2018 года, поэтому я решил подождать. Незадолго до истечения гарантии я отправил его на новую батарею (ошибка PPT004) и замену экрана (несколько застрявших пикселей), а в качестве бонуса получил китайскую клавиатуру, потому что аккумулятор приклеен к верхнему корпусу. Это полезно, когда местным друзьям нужно печатать.

Retina нужно было отправить на неделю, поэтому я решил купить запасной MacBook Air 2013 с твердотельным накопителем емкостью 256 ГБ и совместимым слотом, чтобы получить доступ к Retina. Это стоило полмесяца зарплаты, но для работы мне нужен компьютер.

Я также заказал SSD на 2 ТБ для своего Retina в penguinestore на eBay (elliotxp на Taobao), который стоил больше месячной зарплаты.

Со всем моим блестящим новым оборудованием я начал копировать файлы на свой внутренний SSD. Поскольку данные настолько фрагментированы на множество маленьких файлов, копирование каждой папки Glyphs1-Glyphs6 заняло целый день. По крайней мере, таков был план.

Копируя Glyphs3, я пошел отдохнуть, а когда вернулся, мой компьютер был на экране входа в систему. Мышь не двигалась. Я попытался подключиться по SSH со своего запасного ноутбука, но он не смог подключиться. Подождав 10 минут, я решил выключить и снова включить питание. Загрузился до значка мигающая папка. SSD поджарился.

Я владел им меньше месяца и еще не написал отзывов на eBay, поэтому на следующий день отправил SSD обратно в Шанхай компанией FedEx и получил возмещение. Он тоже не мог это исправить. Однако запаса больше нет, поэтому я снова использую свои старые 512 ГБ. После стирания моего старого SSD у меня было много свободного места, поэтому я решил завершить этот проект, прежде чем восстанавливать резервную копию моих файлов.

Шаг 6. Удалите дубликаты

Из 75617 файлов PNG большинство пустые. Обычно около 40–50 тыс. Файлов представляют собой изображения-заполнители, пустой квадрат. Остальные 30 тысяч - это полезные глифы.

Однако не все пустые квадраты равны! meiryo использует изображение 288x416, Microsoft Jhenghei использует изображение 126x373. Они также не пустые - в качестве заполнителя обычно используется изображение квадрата.

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

moveDuplicateGlyphs.sh - это сценарий, который использует find, stat и uniq для получения наиболее распространенного размера в папке, а затем перемещает все файлы с другим размером во вложенную папку. Я пробовал сравнивать хеши md5, но это было слишком медленно. Даже если сопоставление по размеру файла может привести к потере нескольких подлинных символов, это приемлемая потеря для увеличения скорости обработки. Команды лаконичны и достаточно полезны, поэтому я скопирую их здесь.

mostCommonSize = `find« $ thisFolder »-maxdepth 1! -имя "." -exec stat -f «% z» {} + | сортировать | uniq -c | sort -r | голова -n 1 | cut -d «« -f 2`;

найти «$ thisFolder» -maxdepth 1 -type f! -size «$ mostCommonSize» c -exec mv ‘{}’ «$ thisFolder / NotDuplicates /» \;

Данные сейчас всего 140 ГБ.

Шаг 7. Удалите другие дубликаты вручную

Дата: 2018–05–28

Иногда встречаются другие повторяющиеся глифы, например «?» значки, а также пустые глифы. Я мог бы повторно запустить moveDuplicateGlyphs.sh, но рискую потерять хорошие данные, поэтому решил сделать это вручную.

Я открыл каждую папку шрифтов, отсортированную по размеру, и посмотрел, совпадают ли изображения и размеры. Если нет, то я выбрал дубликаты и удалил их. Перемещение 50 000 объектов в корзину занимает несколько минут. С очисткой корзины также возникает проблема, когда в ней более 80 000 элементов (это работает, просто на это уходит несколько часов, а не минут). Чтобы обойти это, я рекомендую перезапускать Finder через каждые 2 или 3 шрифта.

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

Из шрифтов, которые я храню, есть 15 867 622 файла глифов.

Шаг 8. Переместите глифы в папки с символами

Дата: 2018–05–30

Вместо 6 папок от Glyphs1 до Glyphs6 с вложенными папками для каждого шрифта и именами файлов, представляющими символ, более полезно иметь по одной папке для каждого символа с именами файлов, представляющими шрифт.

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

moveNotDuplicates1ToCharacters.sh для moveNotDuplicates6ToCharacters.sh

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

Шаг 9. Обрежьте пробелы

Дата: 04.06.2018 по 06.08.2018

Многие PNG содержат много пробелов вокруг символа. Часто размеры изображения одинаковы для каждого символа в шрифте, но мы хотим стандартизировать размер, чтобы сделать глифы 28x28 пикселей для каждого шрифта. Лучше сделать изображение как можно большим, поэтому мы удалим пробелы.

trimPngs.sh - это скрипт, который для обрезки использует команду convert imagemagick.

Для запуска этого сценария на запасном ноутбуке потребовалось 4 дня, и мне нужно было удалить обработанные глифы на полпути, потому что твердотельный накопитель емкостью 256 ГБ был заполнен.

Данные теперь 133 ГБ.

Шаг 10. Заполните пробелы, чтобы получились квадраты

Дата: с 2018-06-11 по 2018-06-16

Если персонаж уже квадратный, это прекрасно. Если нет, мы должны добавить пробел, чтобы сделать его квадратным. Для этого я написал еще один сценарий.

padPngs.sh использует imagemagick, чтобы узнать, больше ли ширина или высота, и устанавливает максимальный размер.

На запуск потребовалось 5 дней, а также потребовалось освободить место на полпути.

Данные еще 133 ГБ.

Шаг 11. Уменьшите масштаб до 28 x 28

Дата: с 2018-06-19 по 2016-06-22.

Загрузить 133 ГБ непросто. Даже Mega предлагает только 50 ГБ в качестве уровня бесплатного пользования, и весь этот проект работает с нулевым бюджетом. Мне также не нужны полноразмерные глифы для машинного обучения, только 28x28 PNG, такие как набор данных notMNIST. На выполнение этого шага ушло 3 дня.

resizePngs.sh использует imagemagick для масштабирования PNG.

Объем данных теперь составляет всего 16,32 ГБ.

Шаг 12. Сожмите и загрузите

Наконец, с помощью быстрой команды tar czf я получил набор данных!

MacOS сообщает, что его размер составляет 9,98 ГБ, а на Google Диске - только 9,2 ГБ. Есть 15 867 622 файла глифов.

Общий размер всех шагов в этом процессе:

15 ГБ (загруженные архивы)
15 ГБ (извлеченные файлы шрифтов)
11,82 ГБ (TTF)
450 ГБ (глифы)
140 ГБ (без дубликатов)
133 ГБ (Обрезка)
133 ГБ (Pad)
16,32 ГБ (масштаб)
9,98 ГБ (архив для загрузки)

Итого: 924,12 Гб.

Кодирование, ручная проверка, время: 3 дня.
Время работы скрипта: 3 месяца, 19 дней.

Вот пара графиков с данными, чтобы дать вам представление о масштабе.

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

Было бы интересно попытаться провести машинное обучение на этих данных, потому что существует много категорий (50 КБ), но относительно мало примеров для каждой категории (обычно 400–1200 файлов PNG). Увеличение данных может дать больше примеров, но для этого потребуется еще больше места на диске.

Заключение

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

Сделал бы я это снова? Возможно нет. Потеря внутреннего SSD на 2 ТБ была болезненной, и я думаю, что это было связано с фрагментацией большого количества маленьких файлов.

Я надеюсь, что набор данных будет полезен другим. Apple использует машинное обучение для своего метода распознавания китайского почерка, но у них всего 30 тыс. Символов вместо моего набора данных из 52 тыс. Символов.

Пожалуйста, дайте мне знать, используете ли вы эти данные или изучаете китайский язык - я хотел бы подробнее рассказать о том, как я пробовал и не мог учить. Музыка и комиксы были для меня гораздо полезнее, чем учебники или карточки; метод обучения интервальное повторение на моем iPod называется Shuffle. Я также начинаю изучать 台 語 / Minnan / Taiwanese / Hokkien.

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

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

Об авторе

Питер Буркимшер проработал в Гаосюне, Тайвань, 4 года, работая в InfoFab и OSE, производителе карт памяти microSD.

Электронная почта, Github, LinkedIn

Мне нравится кодировать и строить графики на такие международные темы, как локализация и лайки в Facebook. Я изучал разработку электронных систем, но у меня был больше опыта работы с программным обеспечением. В настоящее время я ищу работу в Новой Зеландии или Канаде, возможно, в Австралии, чтобы я мог иммигрировать и обосноваться. Свяжитесь со мной, если в вашей компании есть открытые вакансии!

Подробнее откуда это взялось

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

Следите за нашей публикацией, чтобы увидеть больше историй о продуктах и ​​дизайне, представленных командой Journal.