Komprese obrazu pomoc� neuronov� s��� a metody zp�tn�ho ���en� sign�lu v programu SNNS

Luk� Zapletal, Univerzita Palack�ho v Olomouci, 24. ��jna 2005

Abstract

I have examined capabilities of SNNS package (Stuttgart Neural Network Simulator) and it`s interface in Python language by creating short script that was able to simulate compression of a picture with the Backpropagation method. The three layered net (64-16-64 units) learned blocks of 8x8 pixels and the image was reconstructed back and written to disk. I have investigated the image quality then.

�vod

Program SNNS disponuje krom� vlastn�ho j�dra na pr�ci s neuronov�mi s�t�mi (kter� je naps�no v jazyce C) a u�ivatelsk�ho rozhran� (pro X Window System) tak� jednoduch�m rozhran�m v jazyce Python. Jazyk Python je objektov� orientovan� jazyk, kter� je pro rychlost v�voje, kterou nab�z� velmi p�ehledn� syntaxe, mezi program�tory vysoce obl�ben. D�ky pln� podpo�e OOP je vhodn� zejm�na na prototypov�n� budouc�ch aplikac�, ale jazyk s�m (tedy jeho "interpret") na tom nen� v�konov� �patn� - to d�ky snadn�mu vytv��en� modul� v jazyce C.

Zaujala m� jedna p��m� aplikace neuronov�ch s�t� pro kompresi obrazu. Je velmi snadn� na pochopen� i na implementaci, ov�em nedosahuje ani zdaleka takov�ch �spor a kvality, jako zn�m�j�� metody (JPEG a podobn�). Jako testovac� obr�zek jsem zvolil fotku v�vojov�ho t�mu Beerfox - jak jsme �ertovn� nazvali slo�en� n�kolika student� katedry informatiky p�i jednom ro�n�kov�m projektu. Fotografie byla p�evedena do stup�� �ed�, ka�d� pixel byl tedy reprezentov�n ��slem v intervalu <0, 255>

Pokusn� obr�zek

Komprese obrazu pomoc� neuronov� s�t� je jednoduch�. Sta�� vytvo�it s�� o n vstupn�ch, n v�stupn�ch neuronech a m neuronech ve skryt� vrstv�. Typicky se vol� konfigurace 64-16-64. Obr�zek se rozd�l� do �vercov�ch blok� o velikosti 8 pixel� (v��ka i ���ka tedy mus� b�t celo��seln� d�liteln� 8) a z�sk�me tak p blok�. T�chto p blok� (vzork�) o 64 (8 * 8) pixelech (��slech) pak p�edkl�d�me s�ti a zvolenou metodou Backpropagation se ji sna��me nau�it "na identitu". To znamen�, �e na do v�stupn� i vstupn� vrstvy kop�rujeme stejn� vzorek.

Popsan� s�� m� jednoduchou topologii, jako aktiva�n� funkci jsem volil hyperbolometrick� tangens. Proto bylo t�eba v�echna ��sla p�ev�st z intervalu <0, 255> do intervalu re�ln�ch ��sel <-1, 1>, co� jsem provedl jednoduchou line�rn� funkc�. K dan� funkci (p��mce) bylo snadn� naj�t funkci inverzn�, tedy funci pro zp�tn� p�evod zp�t na hodnotu stupn� �edi. To jsem vyu�il p�i fin�ln�m ode�ten� v�sledku z v�stupn� vrstvy a p�eveden� zp�t na obrazov� body.

Jakmile chyba dos�hne ur�it� akceptovateln� �rovn�, sta�� postupn� p�edlo�it s�ti v�echny bloky a ��st v�sledky aktiva�n�ch funkc� skryt� vrstvy a zapisovat je nap��klad do souboru. Neuron� ve skryt� vrstv� ale nen� 64, n�br� 16! To je �spora 1:4. Dal�� �spory se dos�hne kvantizac� re�ln�ch ��sel (nap��klad t��bitov� nebo �ty�bitov�). Re�ln� lze obr�zek komprimovat asi na jednu desetinu p�vodn� velikosti.

Sestaven� s�t�

Neuronovu s�� jsem jist� mohl vytvo�it ru�n�, ale vybral jsem si pon�kud slo�it�j�� p��klad o 64 vstupn�ch a v�stupn�ch a 16-ti skryt�ch neuronech. Proto jsem s�� vytvo�il programov�, pomoc� rozhran� pro jakzyk Python, kter� bal�k SNNS nab�z�. Pop��u nyn� prvn� f�zi skriptu train.py (html verze).

Nejprve je s�� inicializov�na.

krui.setLearnFunc('BackpropBatch')
krui.setUpdateFunc('Topological_Order')
krui.setUnitDefaults(1,0,krui.INPUT,0,1,'Act_TanH','Out_Identity')

Vid�me, �e je nastavena metoda d�vkov�ho zp�tn�ho ���en� sign�lu (viz n��e), metoda propagace je nastavena na norm�ln� (tedy topologickou - pro na�e ��ely sta�� prost� ���en� sign�lu), aktiva�n� funkce je inicializov�na ve t�et�m p��kazu.

pos = [0,0,0]
inputs = []
for i in range(1, vnejsi_vrstvy + 1) :
	pos[0] = i
	num = krui.createDefaultUnit()
	inputs.append(num)
	krui.setUnitName(num,'Input_%i' % i)
	krui.setUnitPosition(num, pos)

V prvn� f�zi se vytvo�� vstupn� vrstva, v�echny neurony jsou o��slov�ny a pojmenov�ny Input_X, kde X je cel� ��slo od 1 do 64. Pot� je vytvo�eny skryt� vrstva o 16 neuronech Hidden_1 a� Hidden_16 a v�echny jsou propojeny se v�emi vstupn�mi neurony. Stejn�m zp�sobem pak v�stupn� vrstva se 64 elementy.

krui.deleteAllPatterns()
patset = krui.allocNewPatternSet()
for block in im:
	for i in xrange(vnejsi_vrstvy) :
		krui.setUnitActivation(inputs[i], pix2real(block[i]))
		krui.setUnitActivation(outputs[i], pix2real(block[i]))
	krui.newPattern()

Nakonec jsou vytvo�eny pomoc� SNNS API vzorky (konkr�tn� obr�zek jich m�l 770) a m��e se p�ej�t k vlastn�mu u�en�. V�imn�te si, �e jednotliv� ��sla reprezentuj�c� intenzitu bodu jsou p�evedena na re�ln� ��sla pomoc� funkce pix2real.

while i < pruch_1:
	res = krui.learnAllPatterns(0.3, 0.1)

U�en� NS je pak, jak je vidno, jednoduch�. Skript po nau�en� zap��e s�� i vzorky do soubor� .net a .pat ve form�tu pro program SNNS. Bylo nutn� experimentovat s r�zn�m nastaven�m, co� se d� pohodln� prov�d�t pomoc� SNNS GUI, p��padn� n�sledovn�kem JavaNNS napsan�m v Jave (viz obr�zek). V�sledky m��en� pop��u n��e.

Rozhran� JavaNNS

Volba metody a nastaven� parametr�

Volba metody m� pochopiteln� na danou �lohu markantn� vliv. V m�m p��pad� jsem zvolil metodu Backpropagation, co� bylo ov�em tak� zad�n�m �lohy. Bal�k SNNS nab�z� hned n�kolik variant zp�tn�ho ���en� sign�lu, av�ak j� si musel zvolit metodu Batch-Backpropagation. A to z prost�ho d�vodu.

Pokud bych toti� pou�il jednoduchou metodu zp�tn�ho ���en� (nebo jakoukoliv jej� vylep�enou variantu), nikdy by se mi nepoda�ilo sn��it chybu v�ce ne� o 15 procent. Proto�e je nutn� neuronovu s�� nau�it v�em vzork�m (tedy v�em obr�zkov�m blok�m o velikosti 8x8 pixel�), nen� mo�no upravovat v�hy po ka�d�m kroku jednoho cyklu.

A to p�esn� metoda Backpropagation d�l�. Hned v prvn�ch f�z�ch u�en� se chyba zastavuje na ur�it� hodnot�, p�es kterou se ji� nedostane. �e�en�m je pou�it� d�vkov�ho zp�tn�ho ���en� sign�lu (Batch-Backpropagation). Vzorec pro v�po�et nov�ch vah se v�bec neli��, rozd�l je pouze v tom, kdy dojde k vlastn� �prav� synaptick�ch vah. P�i oby�ejn� metod� k tomu doch�z� v ka�d�m kroku jednoho cyklu, u d�vkov� verze a� na konci cyklu. N�sleduj�c� obr�zek ilustruje chybu p�i u�en� u metody Batch-Backpropagation.

Graf chyby

�ernou barvou je zaznamen�n pr�b�h s koeficientem u�en� 0,5; mod�e je koeficient 2,5 a �ervenou pak koeficient 0,01. Je patrn�, �e p�i vysok�m koeficientu u�en� jsou odchylky vy��� a chyba se sni�uje velmi rychle. P�i n�zk�m koeficientu je pak k��vka hladk� a chyba se sni�uje pomalu. U�en� s vysok�m koeficientem m� tedy v z�v�ru ur�itou rezervu - s�� se nen� schopna nau�it "do detailu".

Ide�ln� by tedy bylo koeficient heuristicky m�nit. Nejlep��ch v�sledk� jsem dosahoval s kombinac� koeficient� 0,3 a 0,03. S prvn�m koeficientem jsem u�en� zah�jil (2000 cykl�), s druh�m pak "doladil" (1500 cykl�). V�sledn� graf je n�sleduj�c�.

Graf chyby

Poda�ilo se mi sn��it chybu t�m�� na setinu p�vodn� (n�hodn� inicializovan�) s�t�, co� by m�lo b�t dost na to, aby bylo mo�no po p�evodu re�ln�ch ��sel zp�t do intervalu <0, 255> obr�zek zrekonstruovat natolik, aby bylo patrn�, co na n�m je.

Praktick� v�sledky

Skript na�te obr�zek ve form�tu SGI RGB (aby nebyly vy�adov�ny ��dn� z�vislosti), zpracuje a v�sledek ulo�� zp�t do stejn�ho form�tu (ve stupn�ch �edi). Tento form�t na�te nap��klad program GIMP nebo utilita display z bal�ku ImageMagick.

Srovnejme tedy p�vodn� obr�zek

Pokusn� obr�zek

s v�sledkem po 35 kroc�ch,

V�sledn� obr�zek

po 350 kroc�ch

V�sledn� obr�zek

a kone�n� po 3500 kroc�ch.

V�sledn� obr�zek

Dal�� prodlu�ov�n� u�en� nem�lo na kvalitu obr�zku praktick� vliv a k�ivka chyby z�st�vala na ur�it� hodnot�. Zaj�mav� bylo, �e p�i dan� konfiguraci s�� nem�la ��dn� tendence k p�eu�en�.

Z�v�r

Jak vid�me, tato metoda nem� praktick�ho vyu�it�. Komprese je sice dosta�uj�c�, ale kvalita v�sledn�ho obr�zku je velmi n�zk�. Tak� doba komprese je prakticky ne�nosn� (3500 krok� cca 30 vte�in na procesoru Pentium-M 1,4 Ghz). Jedin�, co by se dalo vyzdvihnout je doba dekomprese, kter� je pom�rn� rychl�.

Literatura