Funzionalità latenti di Variational Autoencoder (VAE).
Sono nuovo di DL e sto lavorando su VAE per le immagini biomediche. Devo estrarre caratteristiche rilevanti dalla TAC. Quindi ho creato prima un autoencoder e dopo un VAE. Il mio dubbio è che non so da quale livello posso estrarre le caratteristiche. La mia idea personale è quella di utilizzare feature estratte da layer che calcolano la media e la varianza (prima del trucco della riparametrizzazione), ma penso che anche il layer prima di questi sia adatto allo scopo. Ho lasciato qui il codice della parte encoder:
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
```
Risposte
Gli strati precedenti della rete neurale apprendono più funzionalità di basso livello, mentre gli strati più profondi apprendono funzionalità più complicate e astratte (vedi figura da Albawi et al, 2017 ).

Gli autocodificatori sono costituiti da due reti codificatore che codifica i dati in termini di alcune variabili latenti (solitamente di dimensionalità inferiore, quindi possono essere utilizzate per la riduzione della dimensionalità ) e decodificatore che trasforma la rappresentazione latente nella rappresentazione iniziale dei dati.
Puoi utilizzare qualsiasi livello dall'autoencoder, a seconda delle tue esigenze. Poiché gli autoencoder sono generalmente simmetrici, di solito per la generazione di funzionalità si prendono i livelli dall'encoder o viene emesso. Se si desidera utilizzare l'autoencoder per la riduzione della dimensionalità, si preferisce prendere l'output dell'encoder che ha dimensioni inferiori (vedere la figura sotto dall'articolo di Windrim et al, 2019 ).

D'altra parte, è possibile utilizzare l'autoencoder allo stesso modo di qualsiasi altra rete neurale per trasferire l'apprendimento . In tal caso, addestreresti l'autoencoder e quindi ne estrarrai alcuni livelli come funzionalità per altri algoritmi. In tal caso, se desideri funzionalità di livello inferiore, prenderesti i livelli precedenti. Se volessi caratteristiche più astratte, prenderesti livelli più alti.
Usando l'esempio della prima immagine, prenderesti il primo strato di rete addestrato sui volti umani e lo useresti per estrarre alcune forme e bordi di base da immagini diverse dai volti umani. D'altra parte, se avessi bisogno di rilevare i volti, prenderesti strati più profondi della rete.
Aggiungendo alla risposta elaborata di @Tim:
VAE z latente è stocastico z, il che significa che i campioni saranno diversi per lo stesso$x_i$campione. Nel caso ideale la rappresentazione latente ($\mu$o z) conterrà informazioni significative, queste sono quelle che estrarrei (tra l'altro in tensorflow puoi estrarre più livelli;)).$\sigma$è stabilito per fungere da componente di rumore.
Per assicurarti che ciò che estrai sia utile, quello che puoi fare è un test di interpretabilità.
Le funzioni di input Ct-scan sono i pixel che hai, MA ci sono altre informazioni che non stai usando? Ad esempio, visto che non date etichette esplicite, avete un'immagine scannerizzata di un paziente malato? Oppure potresti selezionare a mano 10 immagini con qualche caratteristica specifica per interpretare un po' quali neuroni vengono attivati nello spazio latente? In tal caso, ciò che puoi fare è un test di correlazione. Questo può essere semplice come neyman pearson o un istogramma 2d che mostra quanto sono correlate le caratteristiche. Quello che vuoi ottenere in questo caso è un senso di ciò che viene utilizzato dal modello per decidere.
Sfortunatamente questo è facile per gatti/documenti e più difficile per set di dati più complessi, ma è qualcosa che devi fare per non avere una macchina scatola nera. Buona fortuna!