Spiegazione degli incorporamenti di posizione per i trasformatori di visione |  di Skylar Jean Callis |  Febbraio 2024

 | Intelligenza-Artificiale

Questo articolo fa parte di una raccolta che esamina in modo approfondito il funzionamento interno di Vision Transformers. Ciascuno di questi articoli è disponibile anche come Jupyter Notebook con codice eseguibile. Gli altri articoli della serie sono:

Sommario

L’attenzione è tutto ciò di cui hai bisogno¹ afferma che i trasformatori, a causa della loro mancanza di ricorrenza o convoluzione, non sono in grado di apprendere informazioni sull’ordine di un insieme di token. Senza incorporamento di posizione, i trasformatori sono invarianti rispetto all’ordine dei token. Per le immagini, ciò significa che le parti di un’immagine possono essere codificate senza influire sull’output previsto.

Diamo un’occhiata a un esempio di ordine delle patch su questa pixel art Montagna al tramonto di Luis Zuno (@ansimuz)³. L’opera d’arte originale è stata ritagliata e convertita in un’immagine a canale singolo. Ciò significa che ogni pixel ha un valore compreso tra zero e uno. Le immagini a canale singolo vengono generalmente visualizzate in scala di grigi; tuttavia, lo visualizzeremo con una combinazione di colori viola perché è più facile da vedere.

mountains = np.load(os.path.join(figure_path, 'mountains.npy'))

H = mountains.shape(0)
W = mountains.shape(1)
print('Mountain at Dusk is H =', H, 'and W =', W, 'pixels.')
print('\n')

fig = plt.figure(figsize=(10,6))
plt.imshow(mountains, cmap='Purples_r')
plt.xticks(np.arange(-0.5, W+1, 10), labels=np.arange(0, W+1, 10))
plt.yticks(np.arange(-0.5, H+1, 10), labels=np.arange(0, H+1, 10))
plt.clim((0,1))
cbar_ax = fig.add_axes((0.95, .11, 0.05, 0.77))
plt.clim((0, 1))
plt.colorbar(cax=cbar_ax);
#plt.savefig(os.path.join(figure_path, 'mountains.png'), bbox_inches='tight')

Mountain at Dusk is H = 60 and W = 100 pixels.
Output del codice (immagine per autore)

Possiamo dividere questa immagine in porzioni di dimensione 20. (Per una spiegazione più approfondita sulla suddivisione delle immagini in porzioni, vedere la Articolo sui trasformatori di visione.)

P = 20
N = int((H*W)/(P**2))
print('There will be', N, 'patches, each', P, 'by', str(P)+'.')
print('\n')

fig = plt.figure(figsize=(10,6))
plt.imshow(mountains, cmap='Purples_r')
plt.clim((0,1))
plt.hlines(np.arange(P, H, P)-0.5, -0.5, W-0.5, color='w')
plt.vlines(np.arange(P, W, P)-0.5, -0.5, H-0.5, color='w')
plt.xticks(np.arange(-0.5, W+1, 10), labels=np.arange(0, W+1, 10))
plt.yticks(np.arange(-0.5, H+1, 10), labels=np.arange(0, H+1, 10))
x_text = np.tile(np.arange(9.5, W, P), 3)
y_text = np.repeat(np.arange(9.5, H, P), 5)
for i in range(1, N+1):
plt.text(x_text(i-1), y_text(i-1), str(i), color='w', fontsize='xx-large', ha='center')
plt.text(x_text(2), y_text(2), str(3), color='k', fontsize='xx-large', ha='center');
#plt.savefig(os.path.join(figure_path, 'mountain_patches.png'), bbox_inches='tight')

There will be 15 patches, each 20 by 20.
Output del codice (immagine per autore)

L’affermazione è che i trasformatori di visione non sarebbero in grado di distinguere l’immagine originale da una versione in cui le patch erano state codificate.

np.random.seed(21)
scramble_order = np.random.permutation(N)
left_x = np.tile(np.arange(0, W-P+1, 20), 3)
right_x = np.tile(np.arange(P, W+1, 20), 3)
top_y = np.repeat(np.arange(0, H-P+1, 20), 5)
bottom_y = np.repeat(np.arange(P, H+1, 20), 5)

scramble = np.zeros_like(mountains)
for i in range(N):
t = scramble_order(i)
scramble(top_y(i):bottom_y(i), left_x(i):right_x(i)) = mountains(top_y

Fonte: towardsdatascience.com

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *