Küsimus:
Närvivõrgu nurkandmete kodeerimine
Ari Herman
2016-06-11 10:09:25 UTC
view on stackexchange narkive permalink

Koolitan närvivõrku (üksikasjad pole olulised), kus sihtandmed on nurkade vektor (vahemikus 0 kuni 2 * pi). Otsin nõu, kuidas neid andmeid kodeerida. Siin on see, mida ma praegu proovin (piiratud eduga):

1) 1-of-C kodeerimine: ma panen seadistatud võimalikud nurgad umbes 1000 diskreetseks nurgaks ja näitan siis konkreetset nurka, pannes a 1 vastavas indeksis. Selle probleem seisneb selles, et võrk õpib lihtsalt kõiki 0-sid väljastama (kuna see on peaaegu täpselt õige).

2) Lihtne skaleerimine: ma muutsin võrkude väljundivahemiku ([0,1]) [0,2 * pi]. Siin on probleemiks see, et nurkadel on loomulikult ümmargune topoloogia (st 0,0001 ja 2 * pi on tegelikult üksteise kõrval). Seda tüüpi kodeerimise korral see teave kaob.

Kõik ettepanekud oleksid teretulnud!

Kui kasutate Softmaxi väljundkihti, ei tohiks teil olla probleeme kõigi nullide väljaandmisega - mida peaksite tavaliselt tegema, kui kasutate katagoorilist (st 1-C-st väljundit) väljundit.
Puhtalt spekulatiivne kodeerimisidee (ma pole seda näinud ega katsetanud, aga pole ka vaadanud) on teie nurga ($ \ theta $) kodeerimine paarina: $ \ theta \ mapsto (\ sin (\ theta), \ cos (\ teeta)) $.Ma arvan, et see oleks siis pidev kaart, mille kõik väärtused, nagu $ 0 $ ja $ 2 \ pi $ asuvad üksteise lähedal. Ma arvan, et võiksin sellest demo koostada ja seda proovida.
ma olen sellele veel mõelnud ja arvan, et see võib tegelikult kõik teie kaotuse funktsioonis olla.Ma tahan proovida hunnikut asju.Tegin demo, kuid ei lõpetanud sellega katseid.Eksperimentaalse toetusega üksikasjalik vastus oodatakse kunagi homme.(Pista mind, kui ma seda ei tee)
Ma ei kasuta praegu softmaxi kihti ja tõenäoliselt on see probleem.Ma rakendan seda täna, kui mul on võimalus!Teie (cos, pat) idee on väga huvitav ja mulle meeldib eriti, et see seab selle vahemiku automaatselt [-1,1] -ni (hea, kui töötate tanh-aktiveerimisfunktsiooniga).Ootan huviga teie tulemusi1
Kiire värskendus: proovisin rakendada softmaxi kihti ja mul pole ikka veel õnne.Ma arvan, et küsimus on selles, et selle probleemi jaoks on oluline, et andmete "nurk" oleks kuidagi kodeeringus esindatud.Kategoorilise kodeerimise korral kaotatakse sihtandmete topoloogia.Seega näeb viga 0,5 * pi ja 0,05 * pi võrgu jaoks välja sama (see näeb mõlemat valede kategooriatena).
Neli vastused:
Lyndon White
2016-06-12 20:39:47 UTC
view on stackexchange narkive permalink

Sissejuhatus

Mulle tundub see küsimus tõesti huvitav, eeldan, et keegi on selle kohta paberi välja pannud, kuid see on minu vaba päev, nii et ma ei taha minna viiteid taga ajama.

Nii et võiksime seda pidada väljundi esituseks / kodeeringuks, mida ma selles vastuses teen. Jään jätkuvalt arvama, et on olemas parem viis, kus saate lihtsalt kasutada veidi teistsugust kadumisfunktsiooni. (Võib-olla summa ruutude erinevustest, kasutades lahutamise moodulit 2 $ \ pi $).

Aga edasi tegeliku vastusega.

Meetod

Pakun, et nurk $ \ teeta $ on esindatud väärtuste paarina, selle siinus ja koosinus.

Seega on kodeerimisfunktsioon: $ \ qquad \ qquad \ quad \ theta \ mapsto (\ sin (\ theta), \ cos (\ theta)) $
ja dekodeerimise funktsioon on: $ \ qquad (y_1, y_2) \ mapsto \ arctan \! 2 (y_1, y_2) $
Kui arctan2 on pöördpuutuja, säilitades suuna kõigis kvadrantides)

Teoreetiliselt võite ekvivalentselt töötada otse nurkadega, kui teie tööriist kasutab kihifunktsioonina toetust atan2 (võttes täpselt 2 sisendit ja tekitades ühe väljundi). TensorFlow teeb seda nüüd ja toetab sellel gradientlaskumist, ehkki see pole mõeldud selleks kasutamiseks. Uurisin out = atan2 (sigmoid (ylogit), sigmoid (xlogit)) kaotusfunktsiooniga min ((pred - out) ^ 2, (pred - out - 2pi) ^ 2) . Leidsin, et see treenis palju halvemini kui outs = tanh (ylogit) , outc = tanh (xlogit)) koos kadumisfunktsiooniga 0.5 ((sin (pred) - outs) ^ 2 + (cos (pred) - outc) ^ 2 . Mis ma arvan võib seostada gradiendi katkematusega atan2

Minu testimisel käivitatakse see eeltöötlusfunktsioonina

Selle hindamiseks määrasin ülesanne:

Mustvalge pilt, mis tähistab ühte joont tühjal taustal. Väljenda, millise nurga all see rida on positiivse x-telje suhtes

Rakendasin funktsiooni, mis genereeris need pildid juhuslikult, juhuslike nurkadega joontega (NB: selle postituse varasemates versioonides kasutati juhuslikke nõlvu, mitte juhuslikke nurki. Tänud @Ari Hermanile selle välja märkimise eest. See on nüüd fikseeritud) Ehitasin ülesande täitmise hindamiseks mitu närvivõrku. Täielikud üksikasjad rakendamise kohta on selles Jupyteri märkmikus. Kood on kõik Julias ja ma kasutan Mocha närvivõrgu teeki.

Võrdluseks esitan selle alternatiivsete meetodite abil, mis võimaldavad suurendada skaalat väärtuseni 1.1.ja 500 prügikasti paigutamise ning pehme siltiga softmaxi kasutamisega. Ma pole viimasega eriti rahul ja tunnen, et vajan näpistama. Seetõttu proovin ma erinevalt teistest ainult 1000 korduse korral, võrreldes kahe teise, mida käidi 1000 ja 10 000 korral.

Eksperimentaalne seadistamine

Piltide hind oli 101 dollarit \ times101 $ pikslit, kusjuures joon on keskel ja läheb servani. Pildil ei olnud müra jne. Valgel taustal oli lihtsalt must joon.

Iga raja kohta 1000 koolitus ja juhuslikult genereeriti 1000 katsepilti.

Hindamisvõrgustikul oli üks varjatud kiht laiusega 500. Varjatud kihis kasutati sigmoidseid neuroneid.

Selle koolitas Stochastic Gradient Decent, fikseeritud õppemääraga 0,01, ja fikseeritud impulss 0,9.

Reguleerimist ega väljalangemist ei kasutatud. Samuti ei olnud mingit konvolutsiooni vms. Lihtne võrk, mis loodetavasti viitab sellele, et need tulemused üldistavad

Neid parameetreid on testkoodis väga lihtne kohandada ja ma julgustada inimesi seda tegema. (ja otsige testist vigu).

Tulemused

Minu tulemused on järgmised:

  | | 500 prügikasti | skaalal 0-1 | Patt / Cos | skaalal 0-1 | Patt / Cos || | 1000 Iter | 1000 Iter | 1000 iterit 10 000 Iter | 10 000 iter |
| ------------------------ | -------------- | --------- ------- | -------------- | ---------------- | ---------- ---- || tähenda_viga | 0,4711263342 | 0,2225284486 | 2.099914718 | 0,1085846429 | 2.1036656318 || std (vead) | 1.1881991421 | 0,4878383767 | 1.485967909 | 0,2807570442 | 1.4891605068 || miinimum (vead) 1.83E-006 | 1.82E-005 | 9.66E-007 | 1.92E-006 | 5.82E-006 || mediaan (vead) | 0,0512168533 | 0,1291033982 | 1,8440767072 | 0,0562908143 | 1,8491085947 || maksimaalne (vead) 6.0749693965 | 4.9283551248 | 6.2593307366 | 3.735884823 | 6.2704853962 || täpsus | 0,00% | 0,00% | 0,00% | 0,00% | 0,00% || täpsus_punkti001 | 2,10% | 0,30% | 3,70% | 0,80% | 12,80% || täpsus_punkti01 | 21,90% | 4,20% | 37,10% | 8,20% | 74,60% || täpsus_punkti1 | 59,60% | 35,90% | 98,90% | 72,50% | 99,90% |  

Kui viitan veale, on see närvivõrgu väljastatava nurga ja tegeliku nurga vahe absoluutväärtus. Nii et keskmine viga (näiteks) on selle erinevuse 1000 testjuhtumi keskmine. Ma ei ole kindel, et ma ei peaks seda uuesti skaleerima, tehes vea näiteks $ \ frac {7 \ pi} {4} $ olema võrdne veaga $ \ frac {\ pi} {4} $).

Esitan ka täpsust erinevatel detailsuse tasemetel. Täpsus on testjuhtumite osa, mille see eemaldati. Nii et täpsus_to_punkt01 tähendab, et see loeti õigeks, kui väljund oli tegeliku nurga all 0,01. Ükski esitus ei saavutanud ideaalseid tulemusi, kuid see pole üldse üllatav, arvestades ujukoma matemaatika toimimist. / p>

Kui vaatate selle postituse ajalugu, näete, et tulemustel on natuke müra, iga kord, kui ma seda kordan, on see veidi erinev. Kuid üldine väärtuste järjekord ja skaala jäävad samaks; võimaldades meil seega teha mõned järeldused.

Arutelu

Softmaxiga ühendamine toimib kõige halvemini, kuna ma ütlesin, et ma pole kindel, et ma pole rakenduses midagi keerutanud. See toimib siiski marginaalselt üle arvamise määra. kui see lihtsalt aimaks, saaksime keskmise vea $ \ pi $

sin / cos-kodeering toimiks oluliselt paremini kui skaleeritud 0-1-kodeering. Parandus on sel määral, et 1000 koolituse korral it / it / sin / cos toimib enamiku mõõdikute puhul umbes 3 korda paremini kui skaleerimine 10 000 iteratsiooni korral.

Ma arvan, et osaliselt on see seotud üldistuse parandamisega, kuna mõlemad said keskmise ruudu vea üsna sarnaseks treeningkomplekt, vähemalt üks kord tehti 10 000 kordust.

Selle ülesande parimal võimalikul täitmisel on kindlasti ülempiir, arvestades, et nurk võib olla enam-vähem mis tahes tegelik arv, kuid mitte kõik sellised inglid toodavad erinevaid jooni eraldusvõimega $ 101 \ times101 $ pikslit. Nii et kuna näiteks nurgad 45.0 ja 45.0000001 on mõlemad selle eraldusvõimega seotud sama pildiga, ei saa ükski meetod kunagi mõlemat täiesti õigeks.

Samuti tundub tõenäoline, et absoluutsel skaalal sellest esitusest kaugemale liikumiseks on parem närvivõrk orki on vaja. Selle asemel, et eksperimentaalses seadistuses ülalkirjeldatud väga lihtne olla.

Järeldus.

Tundub, et siin uuritud esituste põhjal on sin / cos-esitus kõige parem. See on loogiline, kuna sellel on ringis liikumisel sujuv väärtus. Mulle meeldib ka see, et pöördvõimalust saab teha arctan2 abil, mis on elegantne.

Usun, et esitatud ülesanne on võrgu jaoks mõistlik väljakutse esitamiseks piisav. Kuigi ma arvan, et tegelikult õpitakse lihtsalt kõverat sobitama väärtusele $ f (x) = \ frac {y1} {y2} x $, nii et võib-olla on see liiga lihtne. Ja võib-olla halvem võib see olla paaristatud esinduse eelistamine. Ma arvan, et see pole, aga siin on juba hilja, nii et mul võib olla midagi vahele jäänud. Kutsun teid uuesti minu koodi üle vaatama. Soovitage täiustusi või alternatiivseid ülesandeid.

See on kindlasti kõige põhjalikum vastus, mida olen pinu vahetamisel saanud.Kuna ma pole Juliaga tuttav, on mul raske teie koodi uurida ... seega proovin selle asemel teie tulemusi Pythoni abil korrata.Postitan mulle leiud hiljem täna või homme.
Kuigi ma ei olnud üllatunud, et sidestamine kehvasti toimis, olin ma üllatunud, mil määral (0,1) skaleerimine oli (cos, sin) meetodil parem.Märkasin, et lõite oma näited, valides juhuslikult liinide tõusu ja jooksu.Ma arvan, et see tekitaks jooni, mille nurgad ei ole ühtlaselt jaotatud, kuid mille kalle on.Kas on võimalik, et sellepärast toimis (cos, sin) meetod nii palju paremini?Mis juhtuks, kui muudaksite sihtmärgid taniks (nurk) ...?
sul on juhusliku kalde vs juhusliku nurga suhtes õigus.kuid ma ei usu, et `tan (nurk)` sihtimine nii hästi läheb, arvestades, et tan pole kõigi nurkade jaoks määratletud (nt $ \ pi / 4 $).Käivitan selle uuesti juhuslikult genereeritud nurkadega ja redigeerin postitusi.
Julia ja numpy vahel ning Mocha ja Caffe vahel peaks olema üks-ühele lähedane kaart, kui soovite seda tõesti täiendada.Kas on mõni kindel osa koodist, mida on raske lugeda?Julia peaks olema kergesti mõistetav keel.Nii et võib-olla olen teinud midagi imelikku.
Lõpuks lugesin teie koodi ja kõik näib olevat õige.Siiski tahtsin kirjutada oma versiooni, sest see on tavaliselt õpetlik.Minu teostus erineb teie omast veidi, seega on huvitav tulemusi võrrelda.Postitan need järgmise paari tunni jooksul.
Teil on õigus, mille mõistmiseks on ümberkirjutamine (ja ümbertegemine) suurepärane viis aru saada, kuidas midagi tegelikult töötab.Hakkasin koodi näpistama, et teha juhuslikke nurki, mitte juhuslikke nõlvu, kuid see on WIP ja ma pidin natuke tööd tegema.Mul on huvitav näha ka teie tulemusi.
@AriHerman kood ja tabel on nüüd uuendatud.Näete, et juhusliku kalde muutmine juhusliku nurga jaoks on parema toimimise saavutanud, eriti skaleeritud lähenemise puhul, kuid mitte nii, et ühtegi järeldust muuta.
Aitäh Ari ja Lyndon kasulike kommentaaride eest.@LyndonWhite, mainisite, et te arvate, et mõne muu kadumisfunktsiooni kasutamine oleks parem lähenemisviis - kas "arctan2" kasutamine on otsene kaotusfunktsioonina mõttekas?
Kaardipruuni ei saa kasutada otseselt kaotusfunktsioonina (see ei kaota mingit kaotustunnet) ja nagu mu eile tehtud muudatused leidsid, et see töötas halvasti aktiveerimisfunktsioonina (või väljundfunktsioonina sõltuvalt määratlusest)
Kuidas logit tuleb?kuidas ma saan logiti veenduda.
airalcorn2
2018-09-14 23:12:17 UTC
view on stackexchange narkive permalink

Siin on veel üks Pythoni rakendus, milles võrreldakse Lyndon White pakutavat kodeeringut ühendatud lähenemisviisiga. Allolev kood andis järgmise väljundi:

  Treeningu suurus: 100
Treeninguperioodid: 100
Kodeerimine: cos_sin
Testiviga: 0.017772154610047136
Kodeerimine: binnitud
Testiviga: 0,043398792553251526

Treeningu suurus: 100
Treeninguperioodid: 500
Kodeerimine: cos_sin
Testiviga: 0,015376604917819397
Kodeerimine: binnitud
Testiviga: 0,032942592915322394

Treeningu suurus: 1000
Treeninguperioodid: 100
Kodeerimine: cos_sin
Testiviga: 0,007544091937411164
Kodeerimine: binnitud
Testiviga: 0.012796594492198667

Treeningu suurus: 1000
Treeninguperioodid: 500
Kodeerimine: cos_sin
Testiviga: 0,0038051515079569097
Kodeerimine: binnitud
Testiviga: 0,006180633805557207
 

Nagu näete, on binnitud lähenemine selle mänguasjaülesande puhul suurepäraselt toimiv, kuid kodeering $ (\ sin (\ theta), \ cos (\ theta)) $ toimib paremini kõigis treeningkonfiguratsioonides, mõnikord märkimisväärse varuga . Kahtlustan, et konkreetse ülesande keerukamaks muutudes muutuvad Lyndon White'i $ (\ sin (\ theta), \ cos (\ theta)) $ esinduse kasutamise eelised selgemaks.

  import matplotlib.pyplot plt-ks
impordi numpy nimega np
impordi tõrvik
impordi tõrvik.nn nimega nn
impordi tõrvik.utils.data

device = torch.device ("cuda: 0", kui torch.cuda.is_available () muu "cpu")


klassi võrk (nn. moodul):
    def __init __ (ise, sisendi_suurus, peidetud_suurus, num_out)
        super (Net, ise) .__ init __ ()
        ise.fc1 = nn. Lineaarne (sisendi_suurus, peidetud_suurus)
        self.sigmoid = nn. Sigmoid ()
        self.fc2 = nn. Lineaarne (varjatud_suurus, arv_väljas)

    def edasi (ise, x):
        välja = ise.fc1 (x)
        välja = ise. sigmoid (välja)
        välja = ise.fc2 (välja)
        tagasi tulema


def gen_train_image (nurk, külg, paksus):
    pilt = np.zeros ((külg, külg))
    (x_0, y_0) = (külg / 2, külg / 2)
    (c, s) = (np.cos (nurk), np.sin (nurk))
    y jaoks vahemikus (külg):
        x jaoks vahemikus (külg):
kui (abs ((x - x_0) * c + (y - y_0) * s) < paksus / 2) ja (
                    - (x - x_0) * s + (y - y_0) * c > 0):
                pilt [x, y] = 1

    tagastage image.flatten ()


def gen_andmed (num_näidised, külg, num_bins, paksus):
    nurgad = 2 * np.pi * np.juhuslik.ühtlane (suurus = num_näidised)
    X = [gen_train_image (nurk, külg, paksus) nurga all nurkades]
    X = np. Virna (X)

    y = {"cos_sin": [], "binned": []}
    bin_size = 2 * np.pi / num_bins
    nurk nurkades:
        idx = int (nurk / prügikasti suurus)
        y ["binned"]. lisa (idx)
        y ["cos_sin"]. lisa (np.array ([np.cos (nurk), np.sin (nurk)]))

    enc jaoks y-s:
        y [enc] = np. virn (y [enc])

    tagasipöördumine (X, y, nurgad)


def get_model_stuff (rongi_y, sisendi_suuruse, peidetud_suuruse, väljundi_suuruse,
                    õppimise määr, hoog):
    võrgud = {}
    optimeerijad = {}

    enc jaoks rongis_y:
        net = Net (sisend_suurus, peidetud_suurus, väljundsuurused [enc])
        võrgud [enc] = net.to (seade)
        optimeerijad [enc] = torch.optim.SGD (net.parameters (), lr = learning_rate,
                                          impulss = impulss)

    kriteeriumid = {"binned": nn.CrossEntropyLoss (), "cos_sin": nn.MSELoss ()}
    tootlus (võrgud, optimeerijad, kriteeriumid)


def get_train_loaders (rong_X, rong_y, partii_suurus):
    rong_X_tensor = tõrvik. Tensor (rong_X)

    rongilaadurid = {}

    enc jaoks rongis_y:
        kui enc == "binned":
            rongi_y_tensor = taskulamp.tensor (rongi_y [enc], dtype = taskulamp.pikk)
        muu:
            train_y_tensor = taskulamp.tensor (rongi_y [enc], dtype = torch.float)

        andmekogum = torch.utils.data.TensorDataset (rong_X_tensor, rong_y_tensor)
        train_loader = torch.utils.data.DataLoader (andmekogum = andmekogum,
                                                   partii_suurus = partii_suurus,
                                                   segamine = tõene)
        rongilaadurid [enc] = rongilaadurid

    tagasirongi laadurid


def show_image (pilt, külg):
img = plt.imshow (np.reshape (pilt, (külg, külg)), interpolatsioon = "lähim",
                     cmap = "hallid")
    plt.show ()


def main ():
    külg = 101
    sisendi_suurus = külg ** 2
    paksus = 5,0
    varjatud_suurus = 500
    õppimise_hind = 0,01
    hoog = 0,9
    num_bins = 500
    bin_size = 2 * np.pi / num_bins
    pool_bin_size = bin_size / 2
    partii_suurus = 50
    output_sizes = {"binned": num_bins, "cos_sin": 2}
    num_test = 1000

    (test_X, test_y, test_angles) = gen_andmed (num_test, side, num_bins,
                                             paksus)

    num_train jaoks [100, 1000]:

        (rongi_X, rongi_a, rongi_anglid) = gen_andmed (num_train, side, num_bins,
                                                    paksus)
        train_loaders = get_train_loaders (rong_X, rong_a, partii_suurus)

        ajastute jaoks [100, 500]:

            (võrgud, optimeerijad, kriteeriumid) = get_model_stuff (rongi_y, sisendi_suurus,
                                                             hidden_size, output_sizes,
                                                             õppimise määr, hoog)

            enc jaoks rongis_y:
                optimeerija = optimeerijad [enc]
                net = võrgud [enc]
                kriteerium = kriteeriumid [enc]

                ajastu vahemikus (epohhid):
                    (i, (images, ys)) loendis (rongi laadurid [enc]):
                        optizer.zero_grad ()

                        väljundid = net (pildid. seadmesse)
                        kaotus = kriteerium (väljundid, ys.to (seade))
                        kaotus. tagasi ()
                        optizer.step ()


            print ("Koolituse suurus: {0}". formaat (num_train))
            print ("Treeninguperioodid: {0}". formaat (epohhid))
            enc jaoks rongis_y:
                net = võrgud [enc]
                preds = net (tõrvik. tensor (test_X, dtype = tõrvik. float). seadmele)
                kui enc == "binned":
                    pred_bins = np.array (preds.argmax (dim = 1) .detach (). cpu (). numpy (),
dtype = np. float)
                    pred_angles = bin_size * pred_bins + half_bin_size
                muu:
                    pred_angles = torch.atan2 (preds [:, 1], preds [:, 0]). eraldage (). cpu (). numpy ()
                    pred_angles [pred_angles < 0] = pred_angles [pred_angles < 0] + 2 * np.pi

                print ("Kodeerimine: {0}". formaat (enc))
                print ("Testiviga: {0}". formaat (np.abs (pred_angles - test_angles) .mean ()))

            print ()


kui __nimi__ == "__main__":
    peamine ()
 
Ari Herman
2016-06-13 14:54:21 UTC
view on stackexchange narkive permalink

Siin on minu Pythoni versioon teie katsest. Hoidsin paljusid teie rakenduse üksikasju samana, eelkõige kasutan sama pildisuurust, võrgukihi suurusi, õppimiskiirust, hoogu ja edukuse mõõdikuid.

Igal testitud võrgul on üks peidetud kiht (suurus = 500) logistiliste neuronitega. Väljuvad neuronid on kas lineaarsed või pehmed, nagu märgitud. Kasutasin 1000 treeningkujutist ja 1000 testpilti, mis genereeriti iseseisvalt, juhuslikult (nii et võib olla kordusi). Treening koosnes 50 kordusest treeningukomplekti kaudu.

2,3, ..., 500] - idx) ** 2) kus idx on õigele nurgale vastav indeks). Kood on allpool; siin on minu tulemused:

(cos, sin) kodeeringu testiviga:

1000 treeningkujutist, 1000 testpilti, 50 iteratsiooni, lineaarne väljund

  • Keskmine: 0,0911558142071

  • Mediaan: 0,0429723541743

  • Miinimum: 2,77769843793e -06

  • Maksimaalne: 6,2608513539

  • Täpsus 0,1-ni: 85,2%

  • Täpsus 0,01: 11,6%

  • Täpsus 0,001: 1,0%

Kontrollviga [-1,1] kodeering:

1000 treeningkujutist, 1000 testpilti, 50 iteratsiooni, lineaarne väljund

  • Keskmine: 0,234181700523

  • Mediaan: 0,17460197307

  • Miinimum: 0,000473665840258

  • Maksimaalne: 6,00637777237

  • Täpsus 0,1: 29,9%

  • Täpsus 0,01: 3,3%

  • Täpsus 0,001: 0,1%

1/500 kodeeringu testiviga:

1000 treeningut pilti, 1000 testpilti, 50 iteratsiooni, softmaxi väljund

  • Keskmine: 0,0298767021922

  • Mediaan: 0,00388858079174

  • Miinimum: 4,08712407829e-06

  • Maksimaalne: 6,2784479965

  • Täpsus 0,1: 99,6%

  • Täpsus 0,01: 88,9%

  • Täpsus 0,001: 13,5%

Gaussi kodeeringu testiviga:

1000 treeningpilti, 1000 testpilti, 50 iteratsiooni, softmaxi väljund

  • keskmine: 0,0296905377463
  • mediaan: 0,00365867335107
  • miinimum: 4,08712407829e-06
  • maksimaalne: 6,2784479965
  • täpsus väärtuseni 0,1: 99,6%
  • Täpsus 0,01: 90,8%
  • Täpsus 0,001: 14,3%

Ma ei saa aru, miks meie tulemused näivad olevat vastuolu üksteisega, kuid tundub, et see on väärt täiendavat uurimist.

  # - * - kodeerimine: utf-8 - * - "" "Loodud 13. juuni 16 16:59:53 2016 @ autor: Ari" "" numpy import savetxt, loadtxt, ümmargune, null, sin, cos, arctan2, klamber, pi, tanh, exp, arange, punkt, välimine, massiiv, kuju, nullid_like, ümberkujundamine, keskmine, mediaan, max, minfrom numpy.random import rand, shuffleimport matplotlib.pyplot as plt ############ Funktsioonid ############ Annab B&W pildi joonest, mis on kujutatud kahendvektorina, mille pikkus on laius * heightdef gen_train_image (nurk, laius, kõrgus , paksus): pilt = nullid ((kõrgus, laius)) x_0, y_0 = laius / 2, kõrgus / 2 c, s = cos (nurk), sin (nurk) y jaoks vahemikus (kõrgus): x vahemikus (laius): kui abs ((x-x_0) * c + (y-y_0) * s) < paksus / 2 ja - (x-x_0) * s + (y-y_0) * c > 0: pilt [x , y] = 1 return image.flatten () # Kuva treeningpildi def display_image (pilt, kõrgus, laius): img = plt.imshow (ümber kujundama (pilt, (kõrgus, laius)), interpoleerimine = 'lähim', cmap = "Hallid") plt. show () # Activation functiondef sigmoid (X): return 1.0 / (1 + exp (-clip (X, -50,100))) # Tagastab määratud meetodi abil kodeeritud nurga ("binned", "scaled", "cossin", " gaussian ") def encode_angle (nurk, meetod): if method ==" binned ": # 1/500 kodeeriv X = null (500) X [int (ümmargune (250 * (nurk / pi + 1)))% 500] = 1 elif-meetod == "gaussian": # Lekkiv binnitud kodeering
X = massiiv ([i jaoks i vahemikus (500)]) idx = 250 * (nurk / pi + 1) X = exp (-pi * (X-idx) ** 2) elif meetod == "skaleeritud": # Skaleeritud [-1,1] kodeerivaks X = massiiv ([nurk / pi]) elif meetod == "cossin": # Oxinaboxi (cos, sin) kodeeriv X = massiiv ([cos (nurk), sin (nurk) ]) else: pass return X # Annab vastuseks dekodeeritud nurga, kasutades määratud meetoddef decode_angle (X, method): kui method == "binned" või method == "gaussian": # 1/500 või gaussian kodeering M = max (X) i jaoks vahemikus (len (X)): kui abs (X [i] -M) < 1e-5: nurk = pi * i / 250 - pi murd # nurk = pi * punkt (massiiv ([i i jaoks vahemik (500)]), X) / 500 # Keskmistav elif-meetod == "skaleeritud": # Skaleeritud [-1,1] kodeerimisnurgani = pi * X [0] elif-meetod == "cossin": # Oksinaboksi ( cos, sin) kodeerimisnurk = arktaan2 (X [1], X [0]) else: läbige tagasipöördenurk # treenige ja testige närvivõrku määratud nurga kodeerimise meetodiga def test_kodeerimise_metho d (rongi_pildid, rongi_anglid, testi_pildid, testi_anglid, meetod, arvu_numbrid, alfa = 0,01, alfa_bias = 0,0001, impulss = 0,9, hid_layer_size = 500): num_train, in_layer_size = kuju (train_images) num_test = len (test_angles) kui meetod = binned ": out_layer_size = 500 elif meetod ==" gaussian ": out_layer_size = 500 elif meetod ==" scaled ": out_layer_size = 1 elif method ==" cossin ": out_layer_size = 2 else: pass # Esialgsed kaalud ja eelarvamused IN_HID = rand (in_layer_size, hid_layer_size) - 0,5 # IN - > Peidetud kaalud HID_OUT = rand (hid_layer_size, out_layer_size) - 0,5 # HID --> OUT kaalud BIAS1 = rand (hid_layer_size) - 0,5 # Bias varjatud kihi BI jaoks - 0,5 # eelarvamus väljundkihi jaoks # algkaalu ja eelarvamuste värskendused IN_HID_del = nullide sarnane (IN_HID) HID_OUT_del = nullide sarnane (HID_OUT) BIAS1_del = nullide sarnane (BIAS1) BIAS2_del = nullide sarnane (BIAS2) # rong
j jaoks vahemikus (arvude_numbrid): i jaoks vahemikus (arv_treen): # Hankige treeningnäide IN = rongi_pildid [i] TARGET = kodeerimisnurk (rongi_numbrid [i], meetod) # Edasi ja arvutage veaderivaadid HID = sigmoid (punkt ( IN, IN_HID) + BIAS1) kui method == "binned" või method == "gaussian": # Kasutage softmax OUT = exp (clip (punkt (HID, HID_OUT) + BIAS2, -100,100)) OUT = OUT / summa ( OUT) dACT2 = OUT - TARGET elif meetod == "cossin" või method == "scaled": # Lineaarne OUT = punkt (HID, HID_OUT) + BIAS2 dACT2 = OUT-TARGET else: print ("Vale kodeerimismeetod") dHID_OUT = välimine (HID, dACT2) dACT1 = punkt (dACT2, HID_OUT.T) * HID * (1-HID) dIN_HID = väline (IN, DACT1) dBIAS1 = dACT1 dBIAS2 = dACT2 # Värskendage kaaluvärskendusi IN_HID_del = impulss * IN_HID_del + (1-hetk) * dIN_HID HID_OUT_del = impulss * HID_OUT_del + (1-impulss) * dHID_OUT BIAS1_del = impulss * BIAS1_del + (1-impulss) * dBIAS1 BIAS2_del = impulss * BIAS2_del + (1-impulss) * dBIAS__ IN DIDIDIDID - = alpha * dIN_HID BIAS1 - = alfa_bias * dBIAS1 BIAS2 - = alfa_bias * dBIAS2 # Test test_errors = nullid (num_test) nurgad = nullid (num_test) target_angles = nullid (num_test) täpsus_to_point001 = 0 täpsus_to_point01 = 0 täpsus (num_test): # Hankige koolitusnäide IN = test_images [i] target_angle = test_angles [i] # Edasi HID = sigmoid (punkt (IN, IN_HID) + BIAS1), kui method == "binned" või method == "gaussian" : OUT = exp (klipp (punkt (HID, HID_OUT) + BIAS2, -100,100)) OUT = OUT / summa (OUT) elif meetod == "cossin" või meetod == "skaleeritud": OUT = punkt (HID, HID_OUT ) + BIAS2
# Dekodeeri väljundnurk = dekodeeri_nurk (OUT, meetod) # Arvutusvigade viga = abs (nurga-sihtmärgi_nurk) test_vead [i] = vea nurgad [i] = nurk sihtnurgad [i] = sihtnurk, kui viga < 0.1: täpsuse_punkti1 + = 1 vea < 0,01: accuracy_to_point01 + = 1, kui vea < 0,001: accuracy_to_point001 + = 1 # Arvuta ja tagastamise tulemused accuracy_to_point1 = 100,0 * accuracy_to_point1 / num_test accuracy_to_point01 = 100,0 * accuracy_to_point01 / num_test accuracy_to_point001 = 100,0 * accuracy_to_point001 / num_test tagasipöördumise keskmine (test_errors), mediaan (testi_vead), min (testi_vead), max (testi_vead), täpsuse_punkti1, täpsuse_punkti01, täpsuse_punkti001 # ebaharilike tulemuste kuvamise_tulemused (tulemused, meetod): MEAN, MEDIAN, MIN, MAX, ACC1, ACC01, ACC001 = tulemused, kui meetod == "binned ": print (" 1/500 kodeeringu testiviga: ") elif meetod ==" gaussian ": p rint ("Gaussi kodeeringu testiviga:") elif method == "scaled": print ("Test-error for [-1,1] encoding:") elif method == "cossin": print ("Test error for ( cos, sin) kodeerimine: ") else: pass print (" ----------- ") print (" Mean: "+ str (MEAN)) print (" Mediaan: "+ str (MEDIAN) ) print ("Miinimum:" + str (MIN)) print ("Maximum:" + str (MAX)) print ("Täpsus 0,1:" + str (ACC1) + "%") print ("Täpsus 0,01: "+ str (ACC01) +"% ") print (" Täpsus 0,001: "+ str (ACC001) +"% ") print (" \ n \ n ") ############# Kujutise parameetrid ############################# Looge koolituse ja testide andmed ############### num_train = 1000num_test = 1000test_images = [] test_angles = [] train_images = [] train_angles = [] i-le vahemikus (num_train): nurk = pi * (2 * rand () - 1) rongi_angles.append (nurk)
image = gen_train_image (nurk, laius, kõrgus, paksus) train_images.append (pilt) i vahemikus (num_test): nurk = pi * (2 * rand () - 1) test_angles.append (nurk) image = gen_train_image (nurk , laius, kõrgus, paksus) test_images.append (pilt) train_angles, train_images, test_angles, test_images = massiiv (train_angles), massiiv (train_images), massiiv (test_angles), array (test_images) ########## ################## Hindage kodeerimisskeeme ######################### # 50 # Rong koos cos-iga, sin-kodeerimismeetod = "cossin" tulemused1 = test_encoding_method (rongi kujutised, rongi_anglid, test_images, test_angles, meetod, number_iters) kuva_tulemused (results1, meetod) # Scaleeritud kodeerimismeetodiga rong = scaled "results3 = test_encodim_method ( , test_images, test_angles, method, num_iters) display_results (results3, method) # Binned encodingmetode = "binned" results2 = test_encoding_method (train_images, train_angles, test_images, test_angles, method, num_iters) display_resu lts (results2, method) # Rong gaussian kodeerimismeetodiga = "gaussian" results4 = test_encoding_method (rongi_pildid, rongi_anglid, test_pildid, test_anglid, meetod, num_ iterid) display_results (tulemused4, meetod)  
Lahe, võtmel erinev.Iga pildi osas treenite ainult üks kord.Koolitan iga pildi jaoks 1000 korda ehk 10 000 korda.Mitu kordust, kuigi koolitusandmed on normaalsed, eriti kui treenitakse suhteliselt väikestel andmehulkadel (ja selle õppimiseks kulus mul ainult üks avaldamata alamkraaditöö, aga see on teine lugu). Seda öeldes peaksin lisama oma tabelisse ühe iteri veeru.see oleks informatiivne
Ma arvan, et sarnaste (kuid mitte identsete) piltide treenimine sarnaste sihtmärkidega mõjutab seda võrku sarnaselt.Kui see on tõsi, peaks hästi töötama, kui lihtsalt suurendada juhuslike piltide arvu, millele treenitakse, pigem kordada väiksema treeningkomplekti abil.Kas tahate öelda, et see pole nii?
See on sarnane, kuid selle näiteülesande puhul pole probleemi, et lõpuks kuvate kõik võimalikud pildid, nii et teie test kattub teie rongiga, nii et üldistamise testimine ei toimi. Veelgi olulisem on see, et kui teete 100 000 treeningkujutist, mis on <1000 * 1000 treeningkujutist * kordused.
Teil on õigus, ma lahendan selle probleemi.Minu koodiga on veelgi olulisem probleem: kasutan logistilisi neuroneid, mis ei ole võimelised tootma negatiivseid väärtusi, mida (cos, sin) esindus nõuab.Jah!Vaatan oma koodi üle ja postitan nii kiiresti kui võimalik.
Võib-olla (kui te pole seda veel teinud) võiksite olla huvitatud [Graident Check] (https://youtu.be/KgZ4ZTTfKO8) tegemisest, mis tasub närvivõrkude juurutamisel nullist, kuna seda on väga lihtne tehaväike viga ja teie võrk töötab endiselt enamasti. Re: Neuron: jah, mul on sigmoidse varjatud kihi peal lineaarne väljundkiht
@Oxinabox Vabandame, et nii kaua postitamiseks kulus.Minu kood on vähem tõhus kui teie ja seda pole veel käivitatud.Kuid minu esialgsed tulemused näivad teie omadega vastuolus olevat.Sain 99% täpsuse (ühe kümnendkohani), kasutades kategoorilist kodeeringut ja ainult 50 000 pildi * iteratsiooni.Programm peaks täna hiljem lõppema, nii et loodetavasti saan täna õhtul postitada.Samuti, kui olete huvitatud nurkandmete kodeerimise küsimusest lähemalt, saatke mulle e-kiri: ari.j.herman@gmail.com;Jätkan selle kallal töötamist kogu suve.
Olen uued tulemused postitanud.Seekord kasutasin lineaarse väljundi neuroneid võrkude jaoks, mis kasutavad "skaleeritud" ja "sin, cos" kodeeringut.Kasutan ka nüüd pilte, millel on jooned, mis väljuvad keskelt ühes suunas, nii et see sarnaneb rohkem teie omadega.
Ma arvan, et tean, mis on minu Binned väljundites valesti, kasutan FindMaxi leidmiseks pigem maksimumi leidmiseks Find, otsing ei leia maksimumi, vaid pigem esimene null, nii et see on vale, kuna see leiab alati esimese sissekandeole nulla nulliga softmaxi all. Teie meetod seevastu ei leia ka maksimumi, vaid leiab kaalutud keskmise nurga, mis on kas suurepärane või mitte nii hea idee.Suurepärane, kui selle tipuks on ainult üks nurk - see võimaldab saada täpsema täpsuse, kui prügikastid pakuvad, mitte nii hea, kui on 2+ piiki.
Üldiselt on meie tulemused nõus, välja arvatud binnitud, ja nagu ma oma postituses ütlesin, ei olnud ma liiga kindel oma binnitud lähenemisviisi õigsuses ja näen viimast kommentaari, mida tean nüüd, et minu kombineeritud lähenemine oli vale. Ma värskendan oma ja postitan mingil hetkel uuesti.
Ma mängisin mõttega kasutada kaalutud keskmist (ja mul on rida, mis seda teeb, kuid see on kommenteeritud).Usun, et minu kood ON leida maksimumi ... kas saaksite mind viidata konkreetsele kohale, millele viite?
Nii et sa tegid, ma ei näinud, et kaalutud keskmist joont oleks kommenteeritud.
@AriHerman - läbib mõlemad koodid ja otsib lahknevusi - pole kindel, et märkasite seda - kuid kasutate 100 x 100 mõõtmeid, mitte 101 x 101. Proovin kiireks portimiseks - https://github.com/johndpope/Bresenham-Line närvivõrguga.
DerekG
2019-10-19 01:01:04 UTC
view on stackexchange narkive permalink

Teine võimalus nurga kodeerimiseks on kahe väärtuse komplekt:

y1 = max (0, teeta)

y2 = max (0, -teeta)

teeta_out = y1 - y2

Sellel oleks arctan2-ga sarnane probleem, kuna gradient on teeta = 0 määratlemata. Mul pole aega võrku koolitada ja teiste kodeeringutega võrrelda, kuid selles artiklistehnika tundus küllaltki edukas.

See näib olevat vastus, mis on segatud ühe postituse teise küsimusega.See sait töötab natuke teisiti kui foorum.Siin peaksid vastused keskenduma algsele küsimusele vastamisele.Ja kui teil on veel mõni küsimus või kommentaar - see tuleks sellisena postitada.


See küsimus ja vastus tõlgiti automaatselt inglise keelest.Algne sisu on saadaval stackexchange-is, mida täname cc by-sa 3.0-litsentsi eest, mille all seda levitatakse.
Loading...