Комментарии 6
Как раз только начал увлекаться всей этой дистрибутивной семантикой и текстовым анализом, так что за StringDistances.jl и Embeddings.jl отдельное спасибо! Думал набросать сюда результаты в виде туториала — теперь не придется особо углубляться в описание пакетов
В StringDistances.jl, в целом, всё хорошо. Но когда размерность сравниваемых списков строк становится большой, придётся делать внешние оптимизации (сортировки и пр.) и, иногда, просто выдёргивать код из библиотеки. Впрочем, то же верно и для обычных Distances.jl. Если же есть множественные сравнения со списками >10^4, то надо хранить промежуточные результаты. Например, в косинусной мере, предварительно подсчитанные нормы для списка векторов, ускоряют вычисление на порядок. Но да, формулу надо разобрать на части.
Embeddings.jl позиционируется как унифицированная библиотека. Но Transformers.jl — более совершенный метод векторизации. И в состав Embedings не входит. К слову, работа по его интеграции технически не сложная. Но вопрос — кто бы за это взялся. Авторы Transformers, когда писали свой пакет, не ориентировались на Embedings.jl вообще. Потому, некоторые части надо немного переписать, а не просто обернуть (подгрузка наборов данных). Но зато, эту работу вполне может осилить начинающий в Julia.
Ну и, в очередной раз обращаю внимание на то, что все Embeddings очень прожорливы к оперативной памяти. 16ГБ — минимально рекомендуемы размер для экспериментов. Меньше — уже будут возникать проблемы. Либо словари будут маленькими, либо перед запуском, надо выгружать всё, включая браузеры.
Ну и на счёт статей, в целом, думаю, что эту статью можно было бы разбить на 4-5 фрагментиков по пакетам отдельно, но методичка нужна сейчас, а времени на подготовку отдельных мелких заметок надо затратить сильно больше. Пока об NLP писать не буду.
Но зато, эту работу вполне может осилить начинающий в Julia.Насколько начинающий? +.+
Embeddings по структуре довольно простая:
https://github.com/JuliaText/Embeddings.jl/tree/master/src
Собственно, надо реализовать их интерфейс и обернуть код, который я привёл выше в секции Transformers.jl. С этого можно и начать. Дальше, надо будет аккуратно в load_embeddings(BERT)
вписать код загрузки наборов данных.
#use wordpiece and tokenizer from pretrain
const wordpiece = pretrain"bert-uncased_L-12_H-768_A-12:wordpiece"
const tokenizer = pretrain"bert-uncased_L-12_H-768_A-12:tokenizer"
const vocab = Vocabulary(wordpiece)
const bert_model = gpu(
FromScratch ? create_bert() : pretrain"bert-uncased_L-12_H-768_A-12:bert_model"
)
Flux.testmode!(bert_model)
Ну и, надо поковыряться с lazy-активацией библиотеки Transformers. В общем-то, думаю, всё. Математики там точно нет. Если что, думаю, что товарищи из Transformers помогут.
Напрямую в строке — только зная индекс начала UNICODE-символа. Но можно преобразовать её в массив, после чего работать с символами позиционно.
julia> str = "строка"
"строка"
julia> str[2] # пытаемся взять второй байт, а он - часть первого символа
ERROR: StringIndexError("строка", 2)
Stacktrace:
[1] string_index_err(::String, ::Int64)
julia> collect(eachindex(str)) # получаем все допустимые индексы
6-element Array{Int64,1}:
1
3
5
7
9
11
Однако, можно сделать:
julia> ar = collect("строка")
6-element Array{Char,1}:
'с'
'т'
'р'
'о'
'к'
'а'
julia> ar[2:4]
3-element Array{Char,1}:
'т'
'р'
'о'
Есть пакет https://github.com/JuliaString/Strs.jl и целая группа пакетов для работы со строками https://github.com/JuliaString
julia> using Strs
[ Info: Precompiling Strs [7bddbee9-b4ee-5d4f-bf0b-c84b4398bbf6]
julia> str = Str("строка")
"строка"
julia> str[1]
'с': Unicode U+0441 (category Ll: Letter, lowercase)
julia> str[2:3]
"тр"
Julia NLP. Обрабатываем тексты