Введение в вариационные автоэнкодеры и их применение Биоинформатика / метагеномический анализ

Автоэнкодеры, как правило, стремятся изучить представление данных в низкоразмерном формате. Одним из основных преимуществ автоэнкодеров является то, что они способны изучать гораздо более сложные более низкие измерения, тогда как разложения, подобные PCA, ограничены своей линейной природой. Не стесняйтесь взглянуть на мою статью об автокодировщиках.



Как обычно, речь пойдет о приложении в области биоинформатики.

Вариационные автоэнкодеры

В отличие от обычных автокодировщиков (AE), вариационные автокодировщики (VAE) принадлежат к семейству генеративных моделей. Это связано с тем, что VAE изучают скрытое распределение входных данных. Таким образом, они могут восстанавливать новые точки данных с учетом новых точек из этих распределений. Однако генеративный аспект VAE не часто используется, поскольку GAN намного лучше справляются с этой задачей.

Одно из основных значений VAE - это способность изучать различные распределения данных (аналогичные гауссовым смесям). Это может помочь в кластеризации данных, демонстрирующих различные базовые распределения.

Необходимый импорт в Python

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

import torch
from torch.nn import functional as F
from torch import nn, optim
from torch.utils.data import DataLoader
from torch.utils.data.dataset import TensorDataset
import numpy as np
from tqdm import tqdm, trange
import seaborn as sns
import umap
import matplotlib.pyplot as plt

Архитектура VAE

Подобно AE, у нас есть этап узкого места, за которым следует реконструкция. Более формально у нас есть кодировщик и декодер. Обратите внимание на скрытое представление VL и следующие переменные sigma и mu. Реконструкция генерируется на основе этих параметров распределения. Наш полный класс VAE будет выглядеть, как показано ниже.

Уловка с повторной параметризацией

Обратите внимание, что у нас есть sigma и mu для передачи градиентов. Другими словами, мы должны настроить VAE на изучение правильных sigma и mu с учетом входного набора данных. Мы достигаем этого с помощью уловки повторной параметризации. То есть;

decoder_input = mu + epsilon * e ^ std

Обратите внимание, что в тот момент, когда мы выбрали e^std, мы говорим о логарифмической дисперсии. Отсюда и терминология в коде logvar.

Функции активации и потери

Обратите внимание, что мы используем активацию RELU во многих местах. Однако мы выбрали softplus при logvar скрытой переменной. Это потому, что логарифмическая дисперсия всегда больше нуля. В окончательной реконструкции мы используем sigmoid, поскольку размеры наших входных данных находятся в диапазоне от 0 до 1.

Наша функция потерь состоит из двух частей. Потеря реконструкции (RL) и KL-дивергенция (KLD). В частности, мы используем KLD, чтобы гарантировать, что изученные распределения как можно ближе к нормальному распределению (или гауссовскому, или другому распределению, которое нам нравится). Вы можете прочитать больше здесь".

Реконструкция - старая добрая ошибка среднего квадрата. В зависимости от приложения это может отличаться. Например, для черно-белых изображений (MNIST) можно использовать двоичную кроссентропию.

Наконец, мы можем искать гиперпараметры с правильным весом для RL и KLD, которые поддерживают лучшую кластеризацию (или биннинг и т. Д.).

Запуск примера с PyTorch

Давайте рассмотрим следующий набор данных Metagenomics из одной из моих недавних статей. Длинные чтения моделировались с помощью приложения SimLoRD.

Теперь набор данных был векторизован с помощью следующего инструмента;



Загрузчик данных может быть сконструирован следующим образом;

Функция для тренировки ВАЭ;

Инициализация;

data = LOAD DATA
truth = LOAD GROUND TRUTH # for visualization
device = "cuda" if torch.cuda.is_available() else "cpu"
model = VAE(data.shape[1], 8).to(device)
optimizer = optim.Adam(model.parameters(), lr=1e-2200)

Обучение;

train_loader = make_data_loader(data, batch_size=1024, drop_last=True, shuffle=True, device=device)
epochs = 50
train(model, train_loader, epochs, device)

Получение скрытых представлений;

with torch.no_grad():
    model.eval()
    data = LOAD DATA
    data = torch.from_numpy(data).float().to(device)
    em, _ = model.encode(data)

Визуализируйте;

import random
sidx = random.sample(range(len(data)), 10000) # just use 10000
em_2d = umap.UMAP().fit_transform(em.cpu().numpy()[sidx])
plt.figure(figsize=(10,10))
sns.scatterplot(x=em_2d.T[0], y=em_2d.T[1], hue=truth[sidx])
plt.legend(bbox_to_anchor=(1.05, 1))

Метагеномика Биннинг

После обучения VAE мы можем получить скрытые представления. В этом примере я использовал UMAP для проецирования выборки из 10000 операций чтения в 2D для визуализации. Выглядело это примерно так.

На первый взгляд, мы можем видеть капли точек данных то тут, то там. Можно легко использовать такой инструмент, как HDBSCAN, чтобы извлечь из этого плотные кластеры.

Заключительные замечания

Первоначальная идея использования VAE для биннинга была представлена ​​ВАМБ для биннинга сборок. VAMB часто требует большого количества контигов (›10000 или около того). Это потому, что вам всегда нужно больше данных, чтобы лучше работать в глубоком обучении. Учитывая все эти проблемы и возможности, мы разработали наш собственный инструмент LRBinner для объединения метагеномических чтений. Там у нас всегда миллионы прочтений. Полный инструмент LRBinner намного сложнее, чем то, что я представил в этой статье. Но интуиция и идеи остались прежними. Мы также использовали другой алгоритм кластеризации. Если вам интересно, посмотрите ниже.



Полную версию Jupyter Notebook можно найти здесь. Оригинальный пример кода PyTorch находится здесь.

Надеюсь, вам понравилась эта статья. Хорошего дня!