В качестве предисловия оговорюсь, что на Хабре я впервые, решил представить свою дебют на этой платформе, так сказать. Речь здесь не пойдёт о рисовании картин с использованием AI и графических паттернов. Скорее наоборот, превращение классического изобразительного исксства в многочисленную последовательность нейронных сетей в итоговым кодом в заключительном виде. Расскажу предысторию. В начале этого года, случайным образом, попало в моё поле зрения одно заманчивое словосочетание - digital art. И так как я в теме crypto уже давненько, я не смел не поинтересоваться, каким образом искусство (будь то живопись или музыка) коррелирует с криптой, и как это происходит (и для чего))) на просторах блокчейна. В итоге ознакомления с этой идеей, и не только идеей, но и инфраструктурой NFT (Non-Fungible-Token, невзаимозаменяемый цифровой актив), я с радостью обнаружил что уже хочу создать что-то подобное, но в своём, авторском исполнении. Парой слов опишу, что зверёк по имени НФТ это хэшированное изображение в любом формате, записанное в сети блокчейн в формате, являющегося аналогом ERC-721 в сети Ethereum (для тех кто ещё не в курсе темы). Задуманному быть конечно, но сказать легко, а вот сделать - труднее. Особенно, когда делаешь что-то впервые. Начал я с изучения подобных платформ на просторах всемирной паутины, начиная с крупнейших маркетплейсов opensea.io, makersplace.com, и не очень крупных, pixeos.art, ghostmarket.io и много много других.
Кроме маркетплейсов, я обнаружил чисто minting-платформы, как правило тематические, т.е. они занимаются только созданием NFT карточек и как-правило одного направления. Криптокотики всякие (с них всё и началось!), Криптопанки и прочая фауна. Нашлось кроме всего пару аутсайдеров, которые вовсе создавали неформатные NFT, с прицелом на автоматическое масштабирование за счёт пользователей, к примеру на одной из платформ за NFT контент принимаются уникальные ссылки в интернете, на другой - регистрируются домены, а заодно и снимок с NFT. Не буду сильно углубляться в обозревание ежедневно растущего формата цифровых активов NFT, а лучше наконец-то перейду к своей задумке.
Задумка была очень простая - любые начинающие или маститые художники (как digital, так и классические, с полотнами и красками -прим. автора) регистрируются на моей платформе, сканируют и заливают свой контент, после чего получают бесплатно цифровую копию своего произведения в виде NFT-токена. Условную бесплатность таких преобразований может обеспечить блокчейны с почти 0 стоимостью транзакций, к примеру Binance Smart Chain.
Платформа позиционируется на крупных и не очень маркетплейсах, что по сути является бесконечной выставкой арт-изделий для исходного создателя на мировом рынке картин! Чем не мечта для автора произведений, отдельных галерей разных художников? Мечтать не вредно, как говориться. Рынок этот растёт не по годам, а по месяцам по моим наблюдениям, что можно заметить на знаменитом мониторинге dappradar.com Если отбросить пока все аспекты юридического и маркетингово характера, а оставить лишь техническую область решения поставленной задачи, всё равно лбом бьёшься об реальность существующей (и будущей, глаза боятся :() конкуренции.. Поэтому было решено сделать не просто платформу с названием N, а платформу со своим, уникальным оттенком как в арт, так и в техно смысле. Немного подумав было решено внедрить в процесс вышеописанного алгоритма искусственный интеллект. Это даст платформе во-первых свой уникальный почерк, свою фишку, во-вторых уникальную особенность самостоятельно оценивать стиль написания, применяемые техники прорисовки и качество написания графического произведения. Вплоть до уровня профессионализма самого художника, даже если проходя мимо, взял случайно кисть маэстро и намалевал сходу что-то непонятное. Как это воплотить при помощи существующих библиотек AI? Легко, потребуются лишь века на обучение нашего машинального эксперта.. Это в идеале, а для запуска платформы я рассчитывал сделать это за пару месяцев, что было не лишено оптимизма, как показала практика.
Ну теперь обо всём по-порядку..
Во-первых, необходимо сразу было встать на путь истинный (лучший) и выбрать самую наработанную и в то же время не требующую чрезмерных ресурсов платформу. Выбор пал на использование tensors, исходя из поставленной задачи и многогранности дальнейших ответвлений. В итоге были отобраны 2 наиболее развитые библиотеки TensorFlow 2х и PyTorch (библиотеки AI от Facebook). Сделал бинарный классификатор на Python 3.x, что заняло совсем немного времени, и началось самое интересное - процесс первичного обучения.
from torch.utils.data import Dataset, DataLoader
import argparse
from skimage import io
from skimage.color import gray2rgb, rgba2rgb
from skimage.util import img_as_ubyte
import numpy as np
import albumentations
import torch, os
import random, time, pickle
from tqdm import tqdm
from effnetv2 import effnetv2_s
import matplotlib.pyplot as plt
from PIL import Image
Image.MAX_IMAGE_PIXELS = 512**3
print("Start with parameters:")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
# папка с исходными данными / source folder with data
parser.add_argument('--data_folder', type=str, default='data')
# число эпох обучения / number epoches
parser.add_argument('--num_epochs', type=int, default=150)
# файл для сохранения весов лучшей модели / best weights file
parser.add_argument('--best_weights', type=str, default='./best_weights.pth')
# файл для сохранения весов модели на последней итерации обучения / last weights file
parser.add_argument('--last_weights', type=str, default='./last_weights.pth')
# файл визуализации тренировки / visualization of training process
parser.add_argument('--viz_file', type=str, default='./train_val_learn.png')
# коэффициент обучения / learning rate
parser.add_argument('--lr', type=float, default=1e-4)
# размер партти для обучения / batch size
parser.add_argument('--batch_size', type=str, default=4)
# размер изображения при обучении / image size
parser.add_argument('--image_size', type=int, default=528)
# парсинг параметров / parsing of parameters
opt = parser.parse_args()
print(opt)
Во-вторых, необходимо как следует обучить созданный скрипт, в идеале эпох десять (эпоха - цикл обучения, где за исходных массив берём 10000 экземпляров каждого класса). Здесь кроется самое зёрнышко всей затеи, чем качественней будут исходные данные и сам процесс, тем правильней будет дальнейшая оценка вводныхданных, меньше процент ошибок. А вводные данные в моём случае - реальные произведения искусства. Не могу даже представить, сколько стилей написания картин существует в современном арте. А техники написания, инструменты (кисть, карандаш, мозайка, уголь, пиксели наконец), а школы современного и классического исксусства, а состояние исходного макета? Оригинал, копия, репродукция и прочие нюансы. По самым приблизительным расчётам, такой набор обучающих циклов будет достигать сотни, если не тысячи, и годы по времени их претворения, дальнейшего тестирования.. Я решил для тестовой версии программы модуля использовать лишь 3 простых шага: 1) отфильтровать фото это или не фото (скан с полотна, цифровое произведение, иное), 2) отфильтровать по признаку наличия цветности или его отсутствия (цветное или ч.б), 3) отсортировать по признаку наличия на изображении живой материи или её отсутствия (наличие людей, животных, растений). Была реализована модель EfficientNetV2 на рабочем разрешении 528х528px Сеть может быть обучена в 3 -х вариантах. В моём варианте сеть была обучена в варианте small.
файл effnetv2.py - описывает структуру модели на pytorch
crt_ftable.py - скрипт, который запускается первым для генерации таблиц обучения, валидации и классов
Данные должны быть в папке data. в подпапке photo - фото, в подпапке nphoto - не фото
Скрипт train.py - главный скрипт для обучения, все его параметры описаны внутри
Скрипт eval.py - скрипт для демострации "раскладки" файлов из папки input в папку output
last_weights.pth - это веса модели, сохраненные на последней эпохи
best_weights.pth - веса, при которых достигалась наименьшая ошибка по валидации.
Достигнута точность модели на валидации в 98%. Задачи обучения и валидации проходили последовательно, сначала прогонялся массив фото-нефото, потом цвет-нецвет и в завершении живое-неживое. Про мелкие баги и сбои я решил не освещать, но скажу сразу что столкнулся с игнором скрипта многих типов картинок tif, png и прочие в самом начале, пришлось добавлять форматы для исходных файлов вручную.
Продолжение следует..