Для работы сверточных и других нейронных сетей текст необходимо
преобразовать в числовой формат. Машины не способны напрямую
интерпретировать символы или слова, поэтому вводимые данные должны быть
представлены в виде векторов или матриц чисел. В библиотеке ConvNetJS
это особенно важно, так как входные данные сети обычно подаются в виде
объектов типа Vol — многомерных массивов чисел с
определёнными размерами.
Первый подход заключается в представлении текста на уровне символов. Каждый символ преобразуется в уникальный индекс. Для этого строится словарь символов (alphabet), например:
var chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
var char_to_ix = {};
for(var i=0;i
После этого любой текст можно преобразовать в массив индексов:
var text = "hello";
var indices = [];
for(var i=0;i
Каждый индекс можно затем закодировать с помощью one-hot
векторов. Для ConvNetJS это означает создание объекта
Vol размером [length, 1, alphabet_size], где
length — длина строки, а alphabet_size —
количество уникальных символов:
var x = new convnetjs.Vol(length, 1, chars.length, 0.0);
for(var i=0;i
Каждый символ представлен в виде разреженного вектора, где единица стоит в позиции соответствующего индекса, а остальные элементы равны нулю. Этот метод позволяет нейронной сети распознавать закономерности на уровне последовательности символов.
Второй способ — представление текста на уровне слов. Сначала строится словарь слов и каждому слову присваивается уникальный индекс. В случае больших текстов часто применяются ограничения на частоту встречаемости слов, чтобы уменьшить размер словаря и снизить вычислительные затраты.
var word_to_ix = {};
var corpus = ["hello world", "deep learning"];
var index = 0;
for(var i=0;i
После этого каждое предложение кодируется как последовательность
индексов слов. Для подачи в ConvNetJS используется тот же принцип, что и
для символов — создание Vol объектов с one-hot
кодированием.
One-hot представление удобно для небольших словарей, но становится
громоздким при увеличении их размера. Более эффективным методом является
векторизация через embedding, когда каждому слову
сопоставляется плотный вектор фиксированной размерности. В ConvNetJS
можно реализовать embedding через слой fc с весами,
обучаемыми совместно с сетью:
var layer_defs = [];
layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:vocab_size});
layer_defs.push({type:'fc', num_neurons:embedding_dim, activation:'relu'});
Таким образом, каждый индекс слова подается на вход слоя
fc, который преобразует его в плотный вектор. Этот подход
уменьшает размерность входа и ускоряет обучение.
Тексты имеют разную длину, а сверточные сети в ConvNetJS требуют фиксированные размеры входа. Для решения этой задачи применяется padding: короткие тексты дополняются нулями до максимальной длины последовательности:
var maxlen = 20;
var x = new convnetjs.Vol(maxlen, 1, vocab_size, 0.0);
for(var i=0;i
Для длинных текстов используется тримминг, то есть усечение текста до заданной длины.
Хотя one-hot кодирование уже бинарное, при использовании embedding
или числовых представлений слов важно нормализовать значения, чтобы
избежать переобучения и ускорить сходимость. Наиболее простой способ —
масштабирование входных векторов до диапазона [0, 1] или
стандартное отклонение около единицы.
После преобразования текста в объекты Vol их можно
подавать в ConvNetJS как обычные входные данные. Для обработки
последовательностей применяются сверточные слои (conv),
полносвязные (fc) и рекуррентные подходы, если текст
требует учёта контекста. Преобразованные векторы символов или слов
формируют тензор размерности
[длина_последовательности, 1, размер_словаря],
который полностью совместим с API ConvNetJS.