ConvNetJS — это библиотека на JavaScript для реализации нейронных сетей, включая сверточные и полностью связанные сети. Она изначально создавалась для обработки изображений, но обладает достаточной гибкостью для работы с последовательными данными, включая текст, с применением подходов word embeddings.
Word embeddings позволяют преобразовать слова в векторы фиксированной размерности, сохраняя семантические и синтаксические свойства. В отличие от one-hot кодирования, embeddings создают компактное и непрерывное представление, где близкие по смыслу слова имеют похожие векторы.
Инициализация матрицы весов Каждое уникальное
слово словаря представляется вектором длины D.
var vocab_size = 10000; // размер словаря
var embed_size = 50; // размерность embedding
var W = new convnetjs.Vol(1, 1, vocab_size, 0); // случайная инициализация
convnetjs.Vol используется для хранения данных и
градиентов; в данном случае вектор слов инициализируется случайными
значениями.
Выбор embedding для конкретного слова Каждое слово кодируется индексом в словаре. Чтобы получить его embedding:
var wordIndex = 123; // индекс слова
var embeddingVector = W.w[wordIndex]; // извлечение вектора
Этот вектор затем подается на вход сети.
Обучение embeddings При обучении нейронной сети
веса матрицы W обновляются через backpropagation. Таким
образом, embeddings адаптируются к задаче, например, классификации
текста.
ConvNetJS не имеет встроенного слоя для рекуррентных сетей, но можно использовать 1D сверточные слои для работы с последовательностями слов. Каждое предложение преобразуется в матрицу: строки — слова, столбцы — элементы embedding.
var sentence = [12, 45, 78, 34]; // индексы слов
var inputVol = new convnetjs.Vol(sentence.length, embed_size, 1);
for(var i=0;i<sentence.length;i++) {
for(var j=0;j<embed_size;j++) {
inputVol.w[i*embed_size + j] = W.w[sentence[i]][j];
}
}
Свертки позволяют выявлять локальные паттерны в последовательности.
Например, биграммы и триграммы можно распознавать с помощью фильтров
размерности (filter_size, embedding_size).
var layer_def = [];
layer_def.push({type:'input', out_sx:sentence.length, out_sy:embed_size, out_depth:1});
layer_def.push({type:'conv', sx:3, filters:16, stride:1, pad:0, activation:'relu'});
layer_def.push({type:'pool', sx:2, stride:2});
layer_def.push({type:'fc', num_neurons:32, activation:'relu'});
layer_def.push({type:'softmax', num_classes:5}); // для классификации на 5 классов
ConvNetJS предоставляет Trainer для обучения с
использованием SGD или Adagrad:
var net = new convnetjs.Net();
net.makeLayers(layer_def);
var trainer = new convnetjs.SGDTrainer(net, {
learning_rate:0.01, momentum:0.9, batch_size:10, l2_decay:0.001
});
Каждое предложение подается на вход в виде Vol, а целевой класс задается индексом. Во время обучения embeddings обновляются автоматически через обратное распространение ошибки.
Для улучшения качества можно инициализировать матрицу W
предобученными векторами (например, GloVe или Word2Vec), а затем
замораживать или тонко настраивать их в процессе обучения.
// предположим, что pretrainedEmbeddings — массив векторов
for(var i=0;i<vocab_size;i++) {
W.w[i] = pretrainedEmbeddings[i];
}
Эта стратегия позволяет сети быстрее обучаться и улучшает способность к обобщению на малых данных.
Vol для хранения
embeddings и градиентов.Объединение embeddings с простыми сверточными архитектурами в ConvNetJS предоставляет эффективный инструмент для решения задач классификации текста, анализа тональности и других NLP-задач.