Скрытые функции вариационного автоэнкодера (VAE)

Aug 20 2020

Я новичок в DL и работаю над VAE для биомедицинских изображений. Мне нужно извлечь соответствующие функции из сканирования CT. Итак, я создал сначала автоэнкодер, а затем VAE. Я сомневаюсь, что не знаю, из какого слоя я могу извлечь особенности. Моя личная идея состоит в том, чтобы использовать функции, извлеченные слоями, которые вычисляют среднее значение и дисперсию (до уловки с повторной параметризацией), но я думаю, что для этой цели подходит и слой перед ними. Я оставил здесь код части кодировщика:

class Sampling(tf.keras.layers.Layer):
    """Uses (z_mean, z_log_var) to sample z, the vector encoding a digit."""
    def call(self, inputs):
        z_mean, z_log_var = inputs
        batch = tf.shape(z_mean)[0]
        dim = tf.shape(z_mean)[1]
        epsilon = tf.keras.backend.random_normal(shape=(batch, dim))
        return z_mean + tf.exp(0.5 * z_log_var) * epsilon

def Encoder():
    inp = tf.keras.Input(shape=(32,256,256,1)) # prima era 64

    #enc = tf.keras.layers.Conv3D(8, (2,2,2), activation = 'relu', padding = 'same')(inp)
    #enc = tf.keras.layers.MaxPooling3D((2,2,2), padding = 'same')(enc)
 
    enc = tf.keras.layers.Conv3D(16, (2,2,2), activation = 'relu', padding = 'same')(inp)
    enc = tf.keras.layers.MaxPooling3D((2,2,2), padding = 'same')(enc)
 
    enc = tf.keras.layers.Conv3D(32, (2,2,2), activation = 'relu', padding = 'same')(enc)
    enc = tf.keras.layers.MaxPooling3D((2,2,2), padding = 'same')(enc)
 
    enc = tf.keras.layers.Conv3D(64, (2,2,2), activation = 'relu', padding = 'same')(enc)
    enc = tf.keras.layers.MaxPooling3D((2,2,2), padding = 'same') (enc)

    enc = tf.keras.layers.Conv3D(32, (2,2,2), activation = 'relu', padding = 'same')(enc)
    enc = tf.keras.layers.MaxPooling3D((2,2,2), padding = 'same') (enc)
    #enc = tf.keras.layers.Flatten()(enc)
    enc = tf.keras.layers.Conv3D(16, (2,2,2), activation = 'relu', padding = 'same')(enc)
    enc = tf.keras.layers.MaxPooling3D((2,2,2), padding = 'same') (enc)
    '''
    # conv 2D 
    code = tf.keras.layers.Reshape((8,8,96)) (enc)
    code = tf.keras.layers.Conv2D(96,(2,2), activation = 'relu', padding = 'same')(code)
    code = tf.keras.layers.MaxPooling2D((2,2), padding = 'same') (code)
    '''
    
    # latentent code vae
    latent_code = tf.keras.layers.Flatten()(enc)
    latent_code = tf.keras.layers.Dense(256, activation='relu')(latent_code)
    latent_mu = tf.keras.layers.Dense(32, activation='relu')(latent_code) # èprima era 10
    latent_sigma = tf.keras.layers.Dense(32, activation='relu')(latent_code) # prima era 10
    # Reparameterization trick
    #z = tf.keras.layers.Lambda(sample_z, output_shape=(128,), name='z')([latent_mu, latent_sigma])
    z = Sampling()([latent_mu, latent_sigma])
    encoder = tf.keras.Model(inp, [latent_mu, latent_sigma, z ], name = 'encoder')
    
    #encoder = tf.keras.Model(inp, enc)#[latent_mu, latent_sigma, z ], name = 'encoder')
    return encoder
```

Ответы

4 Tim Aug 20 2020 at 02:47

Более ранние уровни нейронной сети изучают больше низкоуровневых функций, в то время как более глубокие слои изучают более сложные абстрактные функции (см. Рисунок из Albawi et al, 2017 ).

Автоэнкодеры состоят из двух сетевых кодировщиков, которые кодируют данные в терминах некоторых скрытых переменных (обычно с меньшей размерностью, следовательно, они могут использоваться для уменьшения размерности ) и декодера, который преобразует скрытое представление обратно в исходное представление данных.

Вы можете использовать любой слой из автоэнкодера, в зависимости от ваших потребностей. Поскольку автокодеры обычно симметричны, обычно для генерации функций вы должны брать слои из кодировщика или его вывода. Если вы хотите использовать автоэнкодер для уменьшения размерности, вам лучше взять выходной сигнал кодировщика с меньшим размером (см. Рисунок ниже из статьи Windrim et al, 2019 ).

С другой стороны, вы можете использовать автоэнкодер так же, как любую другую нейронную сеть для обучения передачи . В таком случае вы должны обучить автоэнкодер, а затем извлечь какой-то его слой в качестве функций для другого алгоритма. В таком случае, если вам нужны объекты более низкого уровня, вы должны использовать более ранние слои. Если вам нужны более абстрактные функции, вы бы взяли более высокие уровни.

Используя пример из первого изображения, вы возьмете первый слой сети, обученный на человеческих лицах, и воспользуетесь им для извлечения некоторых основных форм и краев из изображений, отличных от человеческих лиц. С другой стороны, если вам нужно обнаруживать лица, вам понадобятся более глубокие слои сети.

1 partizanos Dec 17 2020 at 12:27

Добавление к подробному ответу @Tim:

VAE z latent - это стохастический z, то есть выборки будут разными для одного и того же $x_i$образец. В идеальном случае вы скрытое представление ($\mu$ или z) будут содержать значимую информацию, это те, которые я бы извлек (кстати, в тензорном потоке вы можете извлечь несколько слоев;)). $\sigma$ установлено, чтобы действовать как шумовая составляющая.

Чтобы убедиться, что то, что вы извлекаете, полезно, вы можете сделать тест на интерпретируемость.

Функции ввода Ct-сканирования - это пиксели, которые у вас есть, НО есть ли другая информация, которую вы не используете? Например, поскольку вы не даете явных ярлыков, у вас есть сканированное изображение больного пациента? Или вы могли бы выбрать 10 изображений вручную с какой-либо конкретной функцией, чтобы немного интерпретировать, какие нейроны запускаются в скрытом пространстве? Если да, то вы можете провести тест корреляции. Это может быть простая диаграмма Неймана Пирсона или двухмерная гистограмма, показывающая, насколько коррелированы признаки. В этом случае вы хотите получить некоторое представление о том, что используется в модели для принятия решения.

К сожалению, это легко для кошек / документов и сложнее для более сложных наборов данных, но это то, что вам нужно сделать, чтобы у вас не было машины черного ящика. Удачи!