Monday, 27 November 2017

Effektiv Bevegelig Gjennomsnittsfilter


For tiden utvikler jeg et grafisk LCD-system for å vise temperaturer, strømmer, spenninger, kraft og energi i et varmepumpsystem. Bruken av en grafisk LCD betyr at halvparten av min SRAM og .75 av min blits har blitt brukt opp av en skjermbuffer og strenger. Jeg viser for øyeblikket min maks gjennomsnittlige energikilder Ved midnatt når det daglige bildet tilbakestilles, kontrollerer systemet om forbruket for dagen er over eller under forrige minimum eller maksimum og lagrer verdien. Gjennomsnittet beregnes ved å dele det kumulative energiforbruket etter antall dager. Jeg vil gjerne vise det daglige gjennomsnittet i løpet av den siste uken og måneden 4 uker for enkelhet, dvs. et rullende gjennomsnitt. For øyeblikket innebærer dette å opprettholde en rekke verdier for de siste 28 dagene og beregne et gjennomsnitt over hele oppsettet for månedlige og siste 7 dager for ukentlig. I utgangspunktet gjorde jeg dette ved hjelp av en rekke flyter som energien er i skjemaet 12 12kWh, men dette brukte 28 4 byte 112 byte 5 4 av SRAM jeg ikke min d har bare et enkelt desimalpunkt, så jeg endret til å bruke uint16t og multiplisere tallet med 100 Dette betyr at 12 12 er representert som 1212, og jeg deler med 100 for visning. Størrelsen på arrayet er nå nede til 56 bytes mye bedre. Det er ingen trivial måte å redusere figuren ned til en uint8t som jeg kan se jeg kunne tolerere tapet av et desimal 12 1kWh i stedet for 12 12kWh, men forbruket er ofte høyere enn 25 5kWh 255 er den høyeste verdien representeres av et 8-bit usignert heltall Forbruket har aldri vært under 10 0kWh eller over 35 0kWh, så tenkelig at jeg kunne trekke 10 fra de lagrede figurene, men jeg vet at en dag vil vi overskride disse grensene. Jeg testet koden for å pakke 9-biters verdier i en matrise Dette gir et område på 0-51 2kWh og bruker totalt 32 byte. Det er ganske sakte å få tilgang til en tabell som dette, særlig når du må iterere over alle verdier for å beregne et gjennomsnitt. Så mitt spørsmål er - er det en mer effektiv måte på ca. lculating et glidende gjennomsnitt med tre vinduer - levetid, 28 dager og 7 dager Effektivitet betyr mindre når det gjelder SRAM bruk, men uten straff av stor kode Kan jeg unngå å lagre alle verdier. Skrevet Mar 7 14 på 8 32. Jeg har tenkt og du har rett, slik at jeg teknisk sett gjør svaret mitt feil Jeg investerer litt mer tid og tålmodighet i det Kanskje noe ut av boksen Jeg vil gi deg beskjed hvis jeg kommer opp med noe Vi gjør noe slikt mye på arbeidsplassen min La meg spør deg om Beklager om forvirringen Aditya Somani Mar 8 14 på 17 15. er det en mer effektiv måte å beregne et glidende gjennomsnitt på med 28 dager og 7 dager som trenger å huske 27 dages historie. Du kan få nær nok til å lagre 11 verdier i stedet for 28 verdier, kanskje noe som. Med andre ord, i stedet for å lagre hver eneste detalj hver dag de siste 27 dagene, en butikk 7 eller så verdier av detaljert daglig informasjon for de siste 7 eller så dagene, og også b lagre 4 eller så oppsummerte verdier av total eller gjennomsnittlig informasjon ation for hver av de siste 4 eller så ukene. Jeg har i hovedsak en rekke verdier som dette. Ovenstående matrise er forenklet, jeg samler 1 verdi per millisekund i min virkelige kode og jeg må behandle utdataene på en algoritme jeg skrev for å finne nærmeste topp før et tidspunkt i tiden min logikk feiler fordi i mitt eksempel over er 0 36 den virkelige toppen, men min algoritme vil se bakover og se det siste nummeret 0 25 som toppen, da det er en reduksjon til 0 24 før det. Målet er å ta disse verdiene og bruke en algoritme til dem som vil glatte dem ut litt, slik at jeg har mer lineære verdier, det vil si at resultatene mine skal være svingete, ikke ektey. Jeg har blitt fortalt å søke et eksponentielt bevegelig gjennomsnittsfilter til mine verdier Hvordan kan jeg gjøre dette? Det er veldig vanskelig for meg å lese matematiske ligninger. Jeg behandler mye bedre med kode. Hvordan behandler jeg verdier i mitt array, bruker en eksponentiell glidende gjennomsnittlig beregning for å jevne dem ut. asked 8. februar 12 på 20 27.To beregne en eksponentiell flytende averag e du trenger å holde noen stat rundt og du trenger en tuningsparameter Dette krever en liten klasse forutsatt at du bruker Java 5 eller nyere. Installer med nedbrytingsparameteren du vil ha, må innstille skal være mellom 0 og 1 og bruk deretter gjennomsnittlig til filter. Når du leser en side om noen matematisk tilbakevending, er alt du virkelig trenger å vite når du slår det til kode, at matematikere liker å skrive indekser i arrays og sekvenser med abonnementer. De har også noen andre notater, men det hjelper ikke. EMA er ganske enkel, da du bare trenger å huske en gammel verdi, ingen kompliserte state arrays required. answered 8. februar 12 på 20 42. TKKocheran Ganske mye Er det ikke bra når ting kan være enkelt Hvis du starter med en ny sekvens, får du en ny averager Merk at de første parvilkårene i gjennomsnittssekvensen vil hoppe rundt litt på grunn av grenseeffekter, men du får de med andre bevegelige gjennomsnitt også. En god fordel er at du kan pakke den bevegelige gjennomsnittlige logikken inn i ave rager og eksperimentere uten å forstyrre resten av programmet for mye Donal Fellows 9. februar 12 på 0 06. Jeg har det vanskelig å forstå dine spørsmål, men jeg vil prøve å svare uansett.1 Hvis algoritmen din fant 0 25 i stedet for 0 36 , så er det feil Det er feil fordi det går ut fra en monotonisk økning eller reduksjon som alltid går opp eller alltid går ned Med mindre du er gjennomsnittlig ALLE dataene dine, er datapunktene dine --- som du presenterer dem --- ikke-lineære Hvis du virkelig Ønsker du å finne den maksimale verdien mellom to poeng i tid, skar du arrayet fra tmin til tmax og finn maksimalt for det subarray.2 Nå er begrepet bevegelige gjennomsnitt veldig enkle å forestille at jeg har følgende liste 1 4, 1 5, 1 4, 1 5, 1 5 Jeg kan glatte det ut ved å ta gjennomsnittet av to tall 1 45, 1 45, 1 45, 1 5 Legg merke til at det første nummeret er gjennomsnittet av 1 5 og 1 4 sekund og først tallene den andre nye listen er gjennomsnittet av 1 4 og 1 5 tredje og andre gamle liste den tredje nye listen gjennomsnittet på 1 5 og 1 4 fjerde og tredje og så videre kunne jeg ha gjort det tre eller fire år, eller n Legg merke til hvordan dataene er mye glattere En god måte å se glidende gjennomsnitt på jobben er å gå til Google Finance, velg et lagerforsøk Tesla Motors ganske flyktig TSLA og klikk på technicals nederst i diagrammet Velg Moving Average med en gitt periode, og eksponentiell glidende gjennomsnitt for å sammenligne forskjellene. Eksponentielt glidende gjennomsnitt er bare en annen utbygging av dette, men veier de eldre dataene mindre enn de nye dataene dette er en måte å forvirre utjevning mot baksiden. Les Wikipedia-oppføringen. Så dette er mer en kommentar enn et svar, men den lille kommentaren-boksen var bare for liten Lykke til. Hvis du har problemer med matematikken, vil du kan gå med et enkelt bevegelige gjennomsnittssted i stedet for eksponentiell Så utdataene du får, vil være de siste x-vilkårene delt med x Ikke-testet pseudokode. Merk at du må håndtere start - og sluttdelene av dataene, siden du tydeligvis ikke kan teste den siste 5 vilkår når Du er på ditt andre datapunkt. Det finnes også flere effektive måter å beregne denne glidende gjennomsnittlige summen - eldste nyeste, men dette er for å få konseptet om hva som skjer over. Besvart 8. februar 12 kl 20 41. Jeg har nylig lært om skrider i svaret på dette innlegget og lurte på hvordan jeg kunne bruke dem til å beregne et glidende gjennomsnittsfilter mer effektivt enn det jeg foreslo i dette innlegget ved hjelp av konvoluttfiltre. Dette er hva jeg har så langt. Det tar en oversikt over det opprinnelige oppsettet da ruller den med nødvendig mengde og summerer kjerneverdiene for å beregne gjennomsnittet. Jeg er klar over at kantene ikke håndteres riktig, men jeg kan ta vare på det etterpå. Det er en bedre og raskere måte. Målet er å filtrere store flytpunktsrammer opp til 5000x5000 x 16 lag i størrelse, en oppgave som er ganske treg på. Merk at jeg leter etter 8-nabo-tilkobling, det er et 3x3 filter tar gjennomsnittet av 9 piksler 8 rundt fokuspunktet og tildeler den verdien til piksel i det nye image. EDIT Forklaring på hvordan jeg ser dette working. use stridetricks å generere en matrise som 0,1,2, 1,2,3, 2,3,4 som tilsvarer den øverste raden i filterkjernen. Rull langs loddretten akse for å få den midterste raden i kjernen 10,11,12,11,12,13,13,14,15 og legg den til arrayet jeg fikk i 1.Repeat for å få den nederste raden i kjernen 20,21, 22, 21,22,23, 22,23,24 På dette punktet tar jeg summen av hver rad og deler den med antall elementer i filteret, noe som gir meg gjennomsnittet for hver piksel, skiftet med 1 rad og 1 col, og med noen rariteter rundt kantene, men jeg kan ta vare på det senere. Hva jeg håpet på, er en bedre bruk av stridetricks for å få de 9 verdiene eller summen av kjernelementene direkte, for hele spekteret, eller det noen kan overbevise meg om en annen mer effektiv metode. Skrevet 8. februar kl. 18 05. For hva det er verdt, her er hvordan du gjør det ved hjelp av fancy stridende triks Jeg skulle legge inn dette i går, men ble distrahert av det virkelige arbeidet. Paul spiser begge har gode implementeringer ved hjelp av ulike andre måter å gjøre dette på. Bare for å fortsette ting fra det tidligere spørsmålet, skjønte jeg at jeg d postet den N-dimensjonale ekvivalenten. Du kommer ikke til å være i stand til å slå av funksjonene for 1D-arrayer, men bør slå om. Hvis du prøver å få et flerdimensjonalt bevegelig vindu, risikerer du at minneoppblåsing oppstår når du ved et uhell lager en kopi av matrisen. Mens det første rullende oppsettet bare er et syn på minnet av det opprinnelige matrisen, kan noen mellomliggende trinn som kopierer matrisen, vil lage en kopi som er størrelsesorden større enn den opprinnelige matrisen din. La oss si at du re arbeider med et 100x100 original array. Utsikten over det for en filterstørrelse på 3,3 vil være 98x98x3x3, men bruk Det samme minnet som originalen. Imidlertid vil noen kopier bruke mengden minne som en full 98x98x3x3-serie ville. Basisk er bruk av galte triks, bra for når du vil vektorisere flytte vinduoperasjoner på en enkelt akse av en ndarray Det gjør det veldig enkelt å beregne ting som en bevegelig standardavvik, osv. med svært lite overhead Når du vil begynne å gjøre dette langs flere akser, er det mulig, men du er vanligvis bedre med mer spesialiserte funksjoner Slik som etc. At hvilken som helst grad, så er det hvordan du gjør det. Så det vi får når vi gjør b rollingwindow a, er filtsize et 8x8x3x3 array, som faktisk er en visning i samme minne som den originale 10x10-serien. Vi kunne bare ha så enkelt brukt forskjellig filterstørrelse langs forskjellige akser eller bare operert langs utvalgte akser av et N-dimensjonalt array, dvs. filtsize 0,3,0,3 på en 4-dimensjonal array ville gi oss en 6-dimensjonal visning. Vi kan da bruke en vilkårlig Fungerer til siste akse gjentatte ganger for å effektivt beregne ting i et bevegelig vindu. Men fordi vi lagrer midlertidige arrayer som er mye større enn vår opprinnelige matrise på hvert trinn av gjennomsnitt eller std eller hva som helst, er dette ikke noe minneverdig. Det er s også ikke å være te Rribly fast, enten. Den tilsvarende for ndimage er bare. Dette vil håndtere en rekke grenseforhold, gjør uskarphet på plass uten å kreve en midlertidig kopi av arrayet, og vær veldig rask. Strekktricks er en god måte å bruke en funksjon på. til et bevegelig vindu langs en akse, men de er ikke en god måte å gjøre det langs flere akser, som regel. Bare min 0 02, i alle fall. Veldig bra sett. Forskjellige triks er en god måte å bruke en funksjon på et bevegelig vindu langs en akse, men de er ikke en god måte å gjøre det langs flere akser, vanligvis og selvfølgelig er din forklaring på minneoppblåsingen viktig. En slags oppsummering fra svaret ditt er i hvert fall ikke for langt, den quarenteed fangsten er allerede i scipy Takk spise 9 februar 11 på 16 37. Takk, Joe, for dette svaret I rullende vindkast burde hvis ikke har returnert rollingwindowlastaxis i stedet for rullendevind unutbu 12 februar 11 kl 16 47. Jeg er ikke kjent nok med Python å skrive ut kode for det, men de to beste wa ys for å øke hastigheten på konvoluttene er å enten skille filteret eller bruke Fourier-transformen. Separert filterkonvolusjon er OMN, hvor M og N er antall piksler i bildet og filteret. Siden gjennomsnittlig filtrering med en 3-ved-3 kjernen tilsvarer å filtrere først med en 3-i-1-kjernen og deretter en 1-for-3-kjernen, kan du få 3 3 3 3,30 hastighetsforbedring ved sammenhengende konvolusjon med to 1-d-kjerner, dette blir tydeligvis bedre etter hvert som kjernen blir større Du kan fortsatt være i stand til å bruke stride triks her, selvfølgelig. Fourier Transform conv A, B er ekvivalent med ifft fft En fft B dvs konvolusjon i direkte plass blir en multiplikasjon i Fourier plass, hvor A er ditt bilde og B er din filter Siden den elementvise versjonen av Fourier-transformasjonene krever at A og B har samme størrelse, er B en serie med størrelse A med kjernen midt i bildet og nuller overalt. For å plassere en 3-ved-3 kjernen i midten av en matrise, må du kanskje pute A til od d-størrelse Avhengig av implementeringen av Fourier-transformasjonen, kan dette være mye raskere enn konvolusjonen, og hvis du bruker det samme filteret flere ganger, kan du forhåndsberegne fft B som lagrer ytterligere 30 av beregningstiden. ansvaret 9. februar kl. 15 27.For det det er verdt, i python, implementeres disse i og henholdsvis Joe Kington 9 februar 11 på 15 44. Jonas Cool Den separerte filtertilnærming fungerer fint, som du sier det sparer mer tid som kjernestørrelsen øker For en 5000x5000 array, med en 11x11 kjernestørrelse, får jeg 7 7s for 2d convolution ved hjelp av og 2s for to 1d-omdreininger ved hjelp av For din andre løsning, hva er B Benjamin 9. februar kl. 16 02. En ting jeg er sikker på må bli løst er visningsarmen b. Den har noen elementer fra ikke-allokert minne, slik at du får krasjer. Gi den nye beskrivelsen av algoritmen din, det første som trenger å fikse, er at du strever utenfor tildelingen av a. Fordi jeg m Fortsatt ikke helt grep metoden, og det virker t Å være enklere måter å løse problemet på, jeg skal bare sette dette her. Som bare virker som den enkle tilnærmingen Den eneste uønskede operasjonen er at den har allokert og befolket B bare én gang. Alt tillegg, divisjon og indeksering må gjøres uansett Hvis du har 16 band, trenger du bare å tildele B en gang hvis du har til hensikt å lagre et bilde. Selv om dette ikke er noe hjelp, kan det klargjøre hvorfor jeg ikke forstår problemet, eller i det minste tjene som referanse til tid speedups av andre metoder Dette kjører i 2 6 sek på min laptop på en 5k x 5k rekke float64 s, 0 5 hvorav er opprettelsen av B. answered Feb 8 11 på 19 31. Det er ikke så klart danner din spørsmålet, men jeg antar nå at du vil forbedre betydelige denne typen gjennomsnitt. Nå, hvilken type ytelsesforbedringer du faktisk ville forvente. Oppdatere Først og fremst, en advarsel koden i sin nåværende tilstand, tilpasser seg ikke til kjerneformen Men det er ikke min primære bekymring akkurat nå uansett ideen er der allikevel hvordan man skal tilpasse seg riktig. Jeg har nettopp valgt den nye formen på en 4D A intuitivt, for meg er det veldig fornuftig å tenke på et 2D kjernesenter for å være sentrert til hver rutenett av original 2D A. Men det 4D-forming kan egentlig ikke være den beste jeg tror det virkelige problemet her er resultatet av summering. En bør for å kunne finne best mulig rekkefølge av 4D A inorder for å fullt ut utnytte maskinens cache-arkitektur. Men den ordren er kanskje ikke den samme for små arrays som samarbeider med maskinens cache og de større, som ikke minst er så grei. Oppdatering 2 Her er en litt modifisert versjon av mf. Det er klart at det er bedre å omforme til en 3D-array først og deretter i stedet for å summere bare gjøre punktprodukt har dette fordelen, så den kjernen kan være vilkårlig. Det er imidlertid fortsatt litt 3 ganger langsommere på min maskin enn Pauls oppdaterte funksjon. Ansatt 8. februar kl. 19 kl 19.

No comments:

Post a Comment