Autoencoder în TensorFlow cu Exemplu
Ce este Autoencoder în Deep Learning?
An Autocoder este un instrument de învățare eficientă a codificării datelor într-o manieră nesupravegheată. Este un tip de rețea neuronală artificială care vă ajută să învățați reprezentarea seturilor de date pentru reducerea dimensionalității prin antrenarea rețelei neuronale să ignore zgomotul semnalului. Este un instrument excelent pentru a recrea o intrare.
Cu cuvinte simple, aparatul preia, să spunem o imagine, și poate produce o imagine strâns legată. Intrarea în acest tip de rețea neuronală este neetichetată, ceea ce înseamnă că rețeaua este capabilă să învețe fără supraveghere. Mai precis, intrarea este codificată de rețea pentru a se concentra doar pe cea mai critică caracteristică. Acesta este unul dintre motivele pentru care codificatorul automat este popular pentru reducerea dimensionalității. În plus, autoencodere pot fi folosite pentru a produce modele de învățare generativă. De exemplu, rețeaua neuronală poate fi antrenată cu un set de fețe și apoi poate produce fețe noi.
Cum funcționează TensorFlow Autoencoder?
Scopul unui autoencoder este de a produce o aproximare a intrării concentrându-se doar pe caracteristicile esențiale. Vă puteți gândi de ce să nu învățați pur și simplu cum să copiați și să lipiți intrarea pentru a produce rezultatul. De fapt, un autoencoder este un set de constrângeri care forțează rețeaua să învețe noi moduri de a reprezenta datele, diferite de simpla copiere a ieșirii.
Un autoencoder tipic este definit cu o intrare, o reprezentare internă și o ieșire (o aproximare a intrării). Învățarea are loc în straturile atașate reprezentării interne. De fapt, există două blocuri principale de straturi care arată ca o rețea neuronală tradițională. Ușoară diferență este că stratul care conține ieșirea trebuie să fie egal cu intrarea. În imaginea de mai jos, intrarea originală intră în primul bloc numit encoder. Această reprezentare internă comprimă (reduce) dimensiunea intrării. În al doilea bloc are loc reconstrucția intrării. Aceasta este faza de decodare.

Modelul va actualiza greutățile reducând la minimum funcția de pierdere. Modelul este penalizat dacă rezultatul de reconstrucție este diferit de intrare.
Concret, imaginați-vă o imagine cu o dimensiune de 50×50 (adică, 250 de pixeli) și o rețea neuronală cu un singur strat ascuns compus din o sută de neuroni. Învățarea se face pe o hartă de caracteristici care este de două ori mai mică decât intrarea. Înseamnă că rețeaua trebuie să găsească o modalitate de a reconstrui 250 de pixeli cu doar un vector de neuroni egal cu 100.
Exemplu de codificare automată stivuită
În acest tutorial Autoencoder, veți învăța cum să utilizați un autoencoder stivuit. Arhitectura este similară cu o rețea neuronală tradițională. Intrarea merge la un strat ascuns pentru a fi comprimat sau pentru a-i reduce dimensiunea, apoi ajunge la straturile de reconstrucție. Obiectivul este de a produce o imagine de ieșire cât mai apropiată de originală. Modelul trebuie să învețe o modalitate de a-și îndeplini sarcina sub un set de constrângeri, adică cu o dimensiune inferioară.
În zilele noastre, Autoencoders în Invatare profunda sunt utilizate în principal pentru dezgomotul unei imagini. Imaginați-vă o imagine cu zgârieturi; un om este încă capabil să recunoască conținutul. Ideea dezgomotului autoencoderului este de a adăuga zgomot imaginii pentru a forța rețeaua să învețe modelul din spatele datelor.
Cealaltă familie utilă de Autoencoder Deep Learning este autoencoderul variațional. Acest tip de rețea poate genera imagini noi. Imaginează-ți că antrenezi o rețea cu imaginea unui bărbat; o astfel de rețea poate produce fețe noi.
Cum să construiți un codificator automat cu TensorFlow
În acest tutorial, veți învăța cum să construiți un autoencoder stivuit pentru a reconstrui o imagine.
Veți folosi Set de date CIFAR-10 care conține 60000 de imagini color 32×32. Setul de date Autoencoder este deja împărțit între 50000 de imagini pentru antrenament și 10000 pentru testare. Există până la zece clase:
- Avion
- Auto
- Pasăre
- Pisica
- Cerb
- Câine
- Broască
- Cal
- Navă
- Camion
Trebuie să descărcați imaginile de la această adresă URL https://www.cs.toronto.edu/~kriz/cifar.html și să o dezarhivați. Dosarul for-10-batches-py conține cinci loturi de date cu 10000 de imagini fiecare într-o ordine aleatorie.
Înainte de a vă construi și antrena modelul, trebuie să aplicați o anumită prelucrare a datelor. Veți proceda după cum urmează:
- Importă datele
- Convertiți datele în format alb-negru
- Adăugați toate loturile
- Construiți setul de date de antrenament
- Construiți un vizualizator de imagine
Preprocesarea imaginii
Pasul 1) Importați datele
Conform site-ului oficial, puteți încărca datele cu următorul cod. Codul Autoencoder va încărca datele într-un dicționar cu de date si etichetă. Rețineți că codul este o funcție.
import numpy as np import tensorflow as tf import pickle def unpickle(file): import pickle with open(file, 'rb') as fo: dict = pickle.load(fo, encoding='latin1') return dict
Pasul 2) Convertiți datele în format alb-negru
Pentru simplitate, veți converti datele în tonuri de gri. Adică, cu o singură dimensiune față de trei pentru imaginea în culori. Majoritatea rețelei neuronale funcționează doar cu o intrare de dimensiune.
def grayscale(im): return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)
Pasul 3) Adăugați toate loturile
Acum că ambele funcții sunt create și setul de date încărcat, puteți scrie o buclă pentru a adăuga datele în memorie. Dacă verificați cu atenție, fișierul de dezarhivare cu datele se numește data_batch_ cu un număr de la 1 la 5. Puteți să treceți peste fișiere și să îl adăugați la date.
Când acest pas este finalizat, convertiți datele de culori într-un format de scară de gri. După cum puteți vedea, forma datelor este 50000 și 1024. Cei 32*32 pixeli sunt acum aplatizați în 2014.
# Load the data into memory data, labels = [], [] ## Loop over the b for i in range(1, 6): filename = './cifar-10-batches-py/data_batch_' + str(i) open_data = unpickle(filename) if len(data) > 0: data = np.vstack((data, open_data['data'])) labels = np.hstack((labels, open_data['labels'])) else: data = open_data['data'] labels = open_data['labels'] data = grayscale(data) x = np.matrix(data) y = np.array(labels) print(x.shape) (50000, 1024)
Notă: Schimbați „./cifar-10-batches-py/data_batch_” la locația reală a fișierului dvs. De exemplu pentru Windows mașină, calea ar putea fi nume de fișier = „E:\cifar-10-batches-py\data_batch_” + str(i)
Pasul 4) Construiți setul de date de antrenament
Pentru a face antrenamentul mai rapid și mai ușor, veți antrena un model numai pe imaginile cailor. Caii sunt clasa a șaptea în datele de pe etichetă. După cum se menționează în documentația setului de date CIFAR-10, fiecare clasă conține 5000 de imagini. Puteți imprima forma datelor pentru a confirma că există 5.000 de imagini cu 1024 de coloane, așa cum se arată în mai jos TensorFlow Exemplu de pas al codificatorului automat.
horse_i = np.where(y == 7)[0] horse_x = x[horse_i] print(np.shape(horse_x)) (5000, 1024)
Pasul 5) Construiți un vizualizator de imagine
În cele din urmă, construiți o funcție pentru a reprezenta imaginile. Veți avea nevoie de această funcție pentru a imprima imaginea reconstruită din autoencoder.
O modalitate ușoară de a imprima imagini este să utilizați obiectul imshow din biblioteca matplotlib. Rețineți că trebuie să convertiți forma datelor de la 1024 la 32*32 (adică formatul unei imagini).
# To plot pretty figures %matplotlib inline import matplotlib import matplotlib.pyplot as plt def plot_image(image, shape=[32, 32], cmap = "Greys_r"): plt.imshow(image.reshape(shape), cmap=cmap,interpolation="nearest") plt.axis("off")
Funcția ia 3 argumente:
- Imagine: Intrarea
- Modela: lista, dimensiunea imaginii
- Cmap:alege harta culorilor. Implicit, gri
Puteți încerca să trasați prima imagine din setul de date. Ar trebui să vezi un bărbat pe cal.
plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")
Setați estimatorul setului de date
În regulă, acum că setul de date este gata de utilizare, puteți începe să utilizați Tensorflow. Înainte de a construi modelul, să folosim estimatorul de set de date al Tensorflow pentru a alimenta rețeaua.
Veți construi un set de date cu estimatorul TensorFlow. Pentru a vă împrospăta mintea, trebuie să utilizați:
- din_slice_tensor
- repeta
- lot
Codul complet pentru construirea setului de date este:
dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)
Rețineți că, x este un substituent cu următoarea formă:
- [None,n_inputs]: Setați la None, deoarece numărul de fluxuri de imagini în rețea este egal cu dimensiunea lotului.
pentru detalii, consultați tutorialul de pe regresie liniara.
După aceea, trebuie să creați iteratorul. Fără această linie de cod, nicio dată nu va trece prin conductă.
iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()
Acum că conducta este gata, puteți verifica dacă prima imagine este aceeași ca înainte (adică, un bărbat pe cal).
Setați dimensiunea lotului la 1 deoarece doriți să alimentați setul de date doar cu o singură imagine. Puteți vedea dimensiunea datelor cu print(sess.run(features).shape). Este egal cu (1, 1024). 1 înseamnă că o singură imagine cu 1024 este alimentată fiecare. Dacă dimensiunea lotului este setată la două, atunci două imagini vor trece prin conductă. (Nu modificați dimensiunea lotului. În caz contrar, va genera o eroare. Doar o imagine la un moment dat poate merge la funcția plot_image().
## Parameters n_inputs = 32 * 32 BATCH_SIZE = 1 batch_size = tf.placeholder(tf.int64) # using a placeholder x = tf.placeholder(tf.float32, shape=[None,n_inputs]) ## Dataset dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size) iter = dataset.make_initializable_iterator() # create the iterator features = iter.get_next() ## Print the image with tf.Session() as sess: # feed the placeholder with data sess.run(iter.initializer, feed_dict={x: horse_x, batch_size: BATCH_SIZE}) print(sess.run(features).shape) plot_image(sess.run(features), shape=[32, 32], cmap = "Greys_r") (1, 1024)
Construiește rețeaua
Este timpul să construim rețeaua. Veți antrena un autoencoder stivuit, adică o rețea cu mai multe straturi ascunse.
Rețeaua dvs. va avea un singur strat de intrare cu 1024 de puncte, adică 32×32, forma imaginii.
Blocul codificator va avea un strat ascuns superior cu 300 de neuroni, un strat central cu 150 de neuroni. Blocul decodor este simetric față de encoder. Puteți vizualiza rețeaua în imaginea de mai jos. Rețineți că puteți modifica valorile straturilor ascunse și centrale.

Construirea unui autoencoder este foarte asemănătoare cu orice alt model de deep learning.
Veți construi modelul urmând acești pași:
- Definiți parametrii
- Definiți straturile
- Definiți arhitectura
- Definiți optimizarea
- Rulați modelul
- Evaluați modelul
În secțiunea anterioară, ați învățat cum să creați o conductă pentru a alimenta modelul, deci nu este nevoie să creați încă o dată setul de date. Veți construi un autoencoder cu patru straturi. Folosești inițializarea Xavier. Aceasta este o tehnică pentru a seta ponderile inițiale egale cu varianța atât a intrării, cât și a ieșirii. În cele din urmă, utilizați funcția de activare elu. Regularizați funcția de pierdere cu regulatorul L2.
Pas 1) Definiți parametrii
Primul pas presupune definirea numărului de neuroni din fiecare strat, a ratei de învățare și a hiperparametrului regulatorului.
Înainte de aceasta, importați parțial funcția. Este o metodă mai bună de a defini parametrii straturilor dense. Codul de mai jos definește valorile arhitecturii autoencoder. După cum s-a enumerat mai înainte, autoencoderul are două straturi, cu 300 de neuroni în primele straturi și 150 în al doilea. Valorile lor sunt stocate în n_hidden_1 și n_hidden_2.
Trebuie să definiți rata de învățare și hiperparametrul L2. Valorile sunt stocate în learning_rate și l2_reg
from functools import partial ## Encoder n_hidden_1 = 300 n_hidden_2 = 150 # codings ## Decoder n_hidden_3 = n_hidden_1 n_outputs = n_inputs learning_rate = 0.01 l2_reg = 0.0001
Tehnica de inițializare Xavier este apelată cu obiectul xavier_initializer din contribuția estimatorului. În același estimator, puteți adăuga regulatorul cu l2_regularizer
## Define the Xavier initialization xav_init = tf.contrib.layers.xavier_initializer() ## Define the L2 regularizer l2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)
Pas 2) Definiți straturile
Toți parametrii straturilor dense au fost setați; puteți împacheta totul în variabila dense_layer utilizând obiectul parțial. dense_layer care utilizează activarea ELU, inițializarea Xavier și regularizarea L2.
## Create the dense layer dense_layer = partial(tf.layers.dense, activation=tf.nn.elu, kernel_initializer=xav_init, kernel_regularizer=l2_regularizer)
Pas 3) Definiți arhitectura
Dacă te uiți la imaginea arhitecturii, observi că rețeaua stivuiește trei straturi cu un strat de ieșire. În codul de mai jos, conectați straturile corespunzătoare. De exemplu, primul strat calculează produsul punctual dintre caracteristicile matricei de intrare și matricele care conțin cele 300 de ponderi. După ce produsul punctual este calculat, rezultatul trece la funcția de activare Elu. Ieșirea devine intrarea următorului strat, de aceea îl folosiți pentru a calcula hidden_2 și așa mai departe. Înmulțirea matricelor este aceeași pentru fiecare strat deoarece utilizați aceeași funcție de activare. Rețineți că ultimul strat, ieșirile, nu aplică o funcție de activare. Are sens, deoarece aceasta este intrarea reconstruită
## Make the mat mul hidden_1 = dense_layer(features, n_hidden_1) hidden_2 = dense_layer(hidden_1, n_hidden_2) hidden_3 = dense_layer(hidden_2, n_hidden_3) outputs = dense_layer(hidden_3, n_outputs, activation=None)
Pas 4) Definiți optimizarea
Ultimul pas este construirea optimizatorului. Utilizați eroarea pătrată medie ca funcție de pierdere. Dacă vă amintiți tutorialul despre regresia liniară, știți că MSE este calculată cu diferența dintre rezultatul prezis și eticheta reală. Aici, eticheta este caracteristica deoarece modelul încearcă să reconstruiască intrarea. Prin urmare, doriți media sumei diferenței pătratului dintre ieșirea și intrarea prezisă. Cu TensorFlow, puteți codifica funcția de pierdere după cum urmează:
loss = tf.reduce_mean(tf.square(outputs - features))
Apoi, trebuie să optimizați funcția de pierdere. Utilizați Adam Optimizer pentru a calcula gradienții. Funcția obiectivă este de a minimiza pierderea.
## Optimize loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)
Încă o setare înainte de antrenamentul modelului. Doriți să utilizați o dimensiune de lot de 150, adică să alimentați conducta cu 150 de imagini la fiecare iterație. Trebuie să calculați manual numărul de iterații. Acest lucru este banal de făcut:
Dacă doriți să treceți 150 de imagini de fiecare dată și știți că există 5000 de imagini în setul de date, numărul de iterații este egal cu . În python puteți rula următoarele coduri și vă asigurați că rezultatul este 33:
BATCH_SIZE = 150 ### Number of batches : length dataset / batch size n_batches = horse_x.shape[0] // BATCH_SIZE print(n_batches) 33
Pas 5) Rulați modelul
Nu în ultimul rând, antrenează modelul. Antrenezi modelul cu 100 de epoci. Adică, modelul va vedea de 100 de ori imaginile la greutăți optimizate.
Sunteți deja familiarizat cu codurile pentru a antrena un model în Tensorflow. Ușoară diferență este să canalizați datele înainte de a rula antrenamentul. În acest fel, modelul se antrenează mai repede.
Sunteți interesat să imprimați pierderea după zece epoci pentru a vedea dacă modelul învață ceva (adică pierderea este în scădere). Antrenamentul durează între 2 și 5 minute, în funcție de hardware-ul mașinii dvs.
## Set params n_epochs = 100 ## Call Saver to save the model and re-use it later during evaluation saver = tf.train.Saver() with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # initialise iterator with train data sess.run(iter.initializer, feed_dict={x: horse_x, batch_size: BATCH_SIZE}) print('Training...') print(sess.run(features).shape) for epoch in range(n_epochs): for iteration in range(n_batches): sess.run(train) if epoch % 10 == 0: loss_train = loss.eval() # not shown print("\r{}".format(epoch), "Train MSE:", loss_train) #saver.save(sess, "./my_model_all_layers.ckpt") save_path = saver.save(sess, "./model.ckpt") print("Model saved in path: %s" % save_path) Training... (150, 1024) 0 Train MSE: 2934.455 10 Train MSE: 1672.676 20 Train MSE: 1514.709 30 Train MSE: 1404.3118 40 Train MSE: 1425.058 50 Train MSE: 1479.0631 60 Train MSE: 1609.5259 70 Train MSE: 1482.3223 80 Train MSE: 1445.7035 90 Train MSE: 1453.8597 Model saved in path: ./model.ckpt
Pas 6) Evaluați modelul
Acum că ai pregătit modelul, este timpul să-l evaluezi. Trebuie să importați setul de testare din fișierul /cifar-10-batches-py/.
test_data = unpickle('./cifar-10-batches-py/test_batch') test_x = grayscale(test_data['data']) #test_labels = np.array(test_data['labels'])
NOTĂ: Pentru o Windows mașină, codul devine test_data = unpickle(r”E:\cifar-10-batches-py\test_batch”)
Puteți încerca să imprimați imaginile 13, care este un cal
plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")
Pentru a evalua modelul, veți folosi valoarea pixelului acestei imagini și veți vedea dacă codificatorul poate reconstrui aceeași imagine după micșorarea cu 1024 de pixeli. Rețineți că definiți o funcție pentru a evalua modelul pe diferite imagini. Modelul ar trebui să funcționeze mai bine doar la cai.
Funcția ia două argumente:
- df: importați datele de testare
- imagine_number: indicați ce imagine să importați
Funcția este împărțită în trei părți:
- Reforma imaginea la dimensiunea corectă, adică 1, 1024
- Alimentați modelul cu imaginea nevăzută, codificați/decodificați imaginea
- Tipăriți imaginea reală și reconstruită
def reconstruct_image(df, image_number = 1): ## Part 1: Reshape the image to the correct dimension i.e 1, 1024 x_test = df[image_number] x_test_1 = x_test.reshape((1, 32*32)) ## Part 2: Feed the model with the unseen image, encode/decode the image with tf.Session() as sess: sess.run(tf.global_variables_initializer()) sess.run(iter.initializer, feed_dict={x: x_test_1, batch_size: 1}) ## Part 3: Print the real and reconstructed image # Restore variables from disk. saver.restore(sess, "./model.ckpt") print("Model restored.") # Reconstruct image outputs_val = outputs.eval() print(outputs_val.shape) fig = plt.figure() # Plot real ax1 = fig.add_subplot(121) plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r") # Plot estimated ax2 = fig.add_subplot(122) plot_image(outputs_val, shape=[32, 32], cmap = "Greys_r") plt.tight_layout() fig = plt.gcf()
Acum că funcția de evaluare este definită, puteți vedea imaginea reconstruită numărul treisprezece
reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckpt Model restored. (1, 1024)
Rezumat
- Scopul principal al unui autoencoder este de a comprima datele de intrare și apoi de a le decomprima într-o ieșire care arată îndeaproape ca datele originale.
- Arhitectura unui autoencoder simetric cu un strat pivot numit stratul central.
- Puteți crea codificatorul automat folosind:
Parțial: pentru a crea straturile dense cu setarea tipică:
tf.layers.dense, activation=tf.nn.elu, kernel_initializer=xav_init, kernel_regularizer=l2_regularizer
strat_dens(): pentru a face înmulțirea matricei
loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)