Ce este un codificator automat?
Un Autoencoder este un instrument pentru învățarea 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 pentru a ignora zgomotul semnalului. Este un instrument excelent pentru recrearea unei intrări.
În cuvinte simple, mașina ia, să zicem o imagine și poate produce o imagine strâns legată. Intrarea în acest tip de rețea neuronală nu este etichetată, 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, autoencoderii pot fi folosiți pentru a produce modele de învățare generative . De exemplu, rețeaua neuronală poate fi antrenată cu un set de fețe și apoi poate produce fețe noi.
În acest tutorial TensorFlow Autoencoder, veți afla:
- Ce este un codificator automat?
- Cum funcționează codificatorul automat?
- Exemplu de autocoder stivuit
- Construiți un codificator automat cu TensorFlow
- Preprocesare imagine
- Setați Estimatorul setului de date
- Construiți rețeaua
Cum funcționează codificatorul automat?
Scopul unui autoencoder este de a produce o aproximare a intrării, concentrându-se doar pe caracteristicile esențiale. S-ar putea să vă gândiți de ce să nu învățați cum să copiați și să inseraț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 modalități de reprezentare a datelor, diferită 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ă. Diferența ușoară 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 codificator . 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 minimizând funcția de pierdere. Modelul este penalizat dacă ieșirea de reconstrucție este diferită de intrare.
Concret, imaginați-vă o imagine cu o dimensiune de 50x50 (adică 250 pixeli) și o rețea neuronală cu un singur strat ascuns compus din o sută de neuroni. Învățarea se face pe o hartă a caracteristicilor 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 autocoder stivuit
În acest tutorial Autoencoder, veți afla 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 reduce dimensiunea acestuia, apoi ajunge la straturile de reconstrucție. Obiectivul este de a produce o imagine de ieșire la fel de aproape ca originalul. Modelul trebuie să învețe o modalitate de a-și îndeplini sarcina sub un set de constrângeri, adică cu o dimensiune mai mică.
În zilele noastre, autoencoderii din Deep Learning sunt utilizați în principal pentru a denisa o imagine. Imaginați-vă o imagine cu zgârieturi; un om este încă capabil să recunoască conținutul. Ideea decodării autoencoderului este de a adăuga zgomot la imagine pentru a forța rețeaua să învețe tiparul din spatele datelor.
Cealaltă familie utilă de Autoencoder Deep Learning este autoencoder variațional. Acest tip de rețea poate genera imagini noi. Imaginați-vă că antrenați o rețea cu imaginea unui bărbat; o astfel de rețea poate produce fețe noi.
Construiți un codificator automat cu TensorFlow
În acest tutorial, veți învăța cum să construiți un codificator automat stivuit pentru a reconstrui o imagine.
Veți utiliza setul de date CIFAR-10 care conține 60000 de imagini color 32x32. 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
- Pisică
- Cerb
- Câine
- Broască
- Cal
- Navă
- Camion
Trebuie să descărcați imaginile din acest URL https://www.cs.toronto.edu/~kriz/cifar.html și să le dezarhivați. Dosarul pentru-10-batches-py conține cinci loturi de date cu 10000 de imagini fiecare într-o ordine aleatorie.
Înainte de a vă construi și instrui modelul, trebuie să aplicați unele prelucrări de date. Veți proceda după cum urmează:
- Importați 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
Preprocesare imagine
Pasul 1) Importați datele.
Potrivit site-ului oficial, puteți încărca datele cu următorul cod. Codul Autoencoder va încărca datele într-un dicționar cu datele și eticheta . Rețineți că codul este o funcție.
import numpy as npimport tensorflow as tfimport pickledef unpickle(file):import picklewith 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 într-o scară de gri. Adică, cu o singură dimensiune contra trei pentru imaginea culorilor. Majoritatea rețelei neuronale funcționează numai cu o singură dimensiune de intrare.
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 face o buclă peste fișiere și o puteți atașa la date.
Când se termină acest pas, convertiți datele culorilor într-un format de scară de gri. După cum puteți vedea, forma datelor este de 50000 și 1024. Cei 32 * 32 pixeli sunt acum aplatizați până în 2014.
# Load the data into memorydata, labels = [], []## Loop over the bfor 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 mașina Windows, calea ar putea fi filename = '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 doar pe imagini de cal. 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 coloane așa cum se arată în pasul de mai jos al exemplului TensorFlow Autoencoder.
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 de reprezentare a imaginilor. Veți avea nevoie de această funcție pentru a imprima imaginea reconstruită din codificatorul automat.
O modalitate ușoară de a imprima imagini este de a utiliza 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 inlineimport matplotlibimport matplotlib.pyplot as pltdef plot_image(image, shape=[32, 32], cmap = "Greys_r"):plt.imshow(image.reshape(shape), cmap=cmap,interpolation="nearest")plt.axis("off")
Funcția are 3 argumente:
- Imagine: intrarea
- Formă: listă, dimensiunea imaginii
- Cmap: alegeți harta culorilor. În mod implicit, gri
Puteți încerca să trasați prima imagine din setul de date. Ar trebui să vezi un bărbat pe un cal.
plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")
Setați Estimatorul setului de date
Bine, acum că setul de date este gata de utilizare, puteți începe să utilizați Tensorflow. Înainte de a construi modelul, să folosim estimatorul Dataset al Tensorflow pentru a alimenta rețeaua.
Veți construi un set de date cu estimatorul TensorFlow. Pentru a-ți reîmprospăta mintea, trebuie să folosești:
- from_tensor_slices
- repeta
- lot
Codul complet pentru a construi setul 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 alimentare a imaginii către rețea este egal cu dimensiunea lotului.
pentru detalii, vă rugăm să consultați tutorialul despre regresia liniară.
După aceea, trebuie să creați iteratorul. Fără această linie de cod, nu vor trece date 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 om pe un cal).
Setați dimensiunea lotului la 1, deoarece doriți să alimentați setul de date cu o singură imagine. Puteți vedea dimensiunea datelor cu print (sess.run (caracteristici) .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 singură imagine poate merge la funcția plot_image ().
## Parametersn_inputs = 32 * 32BATCH_SIZE = 1batch_size = tf.placeholder(tf.int64)# using a placeholderx = tf.placeholder(tf.float32, shape=[None,n_inputs])## Datasetdataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()## Print the imagewith tf.Session() as sess:# feed the placeholder with datasess.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)
Construiți rețeaua
Este timpul să construim rețeaua. Veți antrena un codificator automat stivuit, adică o rețea cu mai multe straturi ascunse.
Rețeaua dvs. va avea un strat de intrare cu 1024 puncte, adică 32x32, forma imaginii.
Blocul codificator va avea un strat ascuns superior cu 300 de neuroni, un strat central cu 150 de neuroni. Blocul decodorului este simetric față de codificator. 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 învățare profundă.
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
- Evaluează modelul
În secțiunea anterioară, ați învățat cum să creați o conductă pentru a alimenta modelul, deci nu mai este nevoie să creați încă o dată setul de date. Veți construi un autoencoder cu patru straturi. Folosiți inițializarea Xavier. Aceasta este o tehnică pentru a seta greutățile 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.
Pasul 1) Definiți parametrii
Primul pas implică definirea numărului de neuroni din fiecare strat, rata de învățare și hiperparametrul regulatorului.
Înainte de aceasta, importați funcția parțial. Este o metodă mai bună de a defini parametrii straturilor dense. Codul de mai jos definește valorile arhitecturii autoencoderului. Așa cum am enumerat anterior, autoencoderul are două straturi, cu 300 de neuroni în primele straturi și 150 în straturile a doua. 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## Encodern_hidden_1 = 300n_hidden_2 = 150 # codings## Decodern_hidden_3 = n_hidden_1n_outputs = n_inputslearning_rate = 0.01l2_reg = 0.0001
Tehnica de inițializare Xavier este apelată cu obiectul xavier_initializer din estimatorul contrib. În același estimator, puteți adăuga regulatorul cu l2_regularizer
## Define the Xavier initializationxav_init = tf.contrib.layers.xavier_initializer()## Define the L2 regularizerl2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)
Pasul 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 folosește activarea ELU, inițializarea Xavier și regularizarea L2.
## Create the dense layerdense_layer = partial(tf.layers.dense,activation=tf.nn.elu,kernel_initializer=xav_init,kernel_regularizer=l2_regularizer)
Pasul 3) Definiți arhitectura
Dacă priviți imaginea arhitecturii, observați 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 punct între caracteristicile matricei de intrare și matricile care conțin cele 300 de greutăți. După ce produsul dot este calculat, ieșirea merge la funcția de activare Elu. Ieșirea devine intrarea următorului strat, de aceea o folosiți pentru a calcula ascuns_2 și așa mai departe. Înmulțirea matricilor 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 mulhidden_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)
Pasul 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 ieșirea 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 prezise. 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. Folosiți optimizatorul Adam pentru a calcula gradienții. Funcția obiectivă este de a minimiza pierderile.
## Optimizeloss = tf.reduce_mean(tf.square(outputs - features))optimizer = tf.train.AdamOptimizer(learning_rate)train = optimizer.minimize(loss)
Încă o setare înainte de a antrena modelul. Doriți să utilizați o dimensiune a lotului de 150, adică să alimentați conducta cu 150 de imagini fiecare iterație. Trebuie să calculați manual numărul de iterații. Acest lucru este banal de făcut:
Dacă doriți să transmiteț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ă ieșirea este 33:
BATCH_SIZE = 150### Number of batches : length dataset / batch sizen_batches = horse_x.shape[0] // BATCH_SIZEprint(n_batches)33
Pasul 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 până la greutăți optimizate.
Sunteți deja familiarizați cu codurile pentru a antrena un model în Tensorflow. O mică diferență constă în transmiterea datelor î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 scade). Instruirea durează de la 2 la 5 minute, în funcție de hardware-ul mașinii.
## Set paramsn_epochs = 100## Call Saver to save the model and re-use it later during evaluationsaver = tf.train.Saver()with tf.Session() as sess:sess.run(tf.global_variables_initializer())# initialise iterator with train datasess.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 shownprint("\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.45510 Train MSE: 1672.67620 Train MSE: 1514.70930 Train MSE: 1404.311840 Train MSE: 1425.05850 Train MSE: 1479.063160 Train MSE: 1609.525970 Train MSE: 1482.322380 Train MSE: 1445.703590 Train MSE: 1453.8597Model saved in path: ./model.ckpt
Pasul 6) Evaluează modelul
Acum că aveți modelul instruit, este timpul să îl evaluați. Trebuie să importați testul de test 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 mașină Windows, 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 utiliza valoarea pixelilor acestei imagini și veți vedea dacă codificatorul poate reconstrui aceeași imagine după micșorarea a 1024 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
- image_number: indicați ce imagine să importați
Funcția este împărțită în trei părți:
- Remodelați imaginea la dimensiunea corectă, adică 1, 1024
- Alimentează modelul cu imaginea nevăzută, codifică / decodează imaginea
- Imprimați imaginea reală și reconstituită
def reconstruct_image(df, image_number = 1):## Part 1: Reshape the image to the correct dimension i.e 1, 1024x_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 imagewith 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 imageoutputs_val = outputs.eval()print(outputs_val.shape)fig = plt.figure()# Plot realax1 = fig.add_subplot(121)plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r")# Plot estimatedax2 = 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 arăta imaginea reconstituită numărul treisprezece
reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckptModel restored.(1, 1024)
rezumat
Scopul principal al unui codificator automat este de a comprima datele de intrare, apoi de a le decomprima într-o ieșire care seamănă cu 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
- layer_dens (): pentru a face multiplicarea matricei
puteți defini funcția de pierdere și optimizarea cu:
loss = tf.reduce_mean(tf.square(outputs - features))optimizer = tf.train.AdamOptimizer(learning_rate)train = optimizer.minimize(loss)
Ultima rulați o sesiune pentru a antrena modelul.