|
Tack vare NumSharps utmärkta nya array slicing-möjligheter är .NET-gemenskapen ett steg närmare att ha en kraftfull öppen källkodsplattform för maskininlärning. Python är ett maskininlärningsspråk delvis för att det har fantastiska bibliotek som NumPy och TensorFlow. Men C#-utvecklare har också ett stort behov av kraftfulla open source-bibliotek för maskininlärning och datavetenskap. NumSharp, NumPy C#-porten från SciSharp STACK-organisationen, har nyligen tagit ett stort steg framåt genom att fullt ut implementera slicing-funktioner, vilket möjliggör skapandet av godtyckliga delmängder av N-dimensionella arrayer som effektiva vyer av rådata. Detta gör det till ett användbart verktyg för att använda C# för maskininlärning tillsammans med TensorFlow.NET.
Vad är det stora problemet?
Om du inte har använt NumPy vet du förmodligen inte hur bra slicing är. Python-arrayer tillåter att returnera en skiva av en array genom att indexera en serie element, enligt följande: a[start:stop:step]. Men först med NumPys komplexa arrayimplementation blir slicing en verkligt kraftfull datamanipulationsteknik, utan vilken maskininlärning eller datavetenskap skulle vara otänkbart. Lyckligtvis, för dem som inte kan eller vill byta till Python för maskininlärning (vilket jag också skapade), för NumSharp med sig denna funktion till .NET-världen. Som en av utvecklarna på NumSharp har jag introducerat dig till några viktiga användningsfall för slicing med exempelkodsnuttar i C#. Observera att indexering inte kan göras i C# på samma sätt som i Python på grund av skillnader i språkets syntax. Vi bestämde oss dock för att behålla Python-syntaxen för slice-definitioner, så vi använde strängar för att indexera slices i C#. Kolla in det här exemplet för att se hur nära NumSharp är NumPy.
Klipp ut kolumnen från matrisen i Python/NumPyNär koden skrivs i C# med NumSharp är den nästan identisk. Observera att skivor indexeras något annorlunda med strängar som parametrar för indexeraren.
Skär ut kolumner från en matris i C#/NumSharpSom du kan se har NumSharp-teamet lagt ner mycket arbete på att göra koden så lik Python som möjligt. Detta är mycket viktigt eftersom befintlig Python-kod som är beroende av NumPy nu enkelt kan porteras till C#.
Användningsfall: Använd flera vyer av samma data
Att kunna skicka endast lokala delar av den underliggande datan (dvs. små bitar av stora bilder) in och ut ur funktioner utan kopiering är avgörande för körningsprestanda, särskilt för stora datamängder. Skivor indexeras med lokala koordinater, så din algoritm behöver inte känna till den globala strukturen av dina data, vilket effektivt förenklar ditt liv och säkerställer maximal prestanda eftersom onödig duplicering undviks.
Användningsområden: Glesa vyer och rekursiv slicing
En gles vy av en matris kan skapas genom att specificera steg bortom början och slutet av snittintervallet. Så vitt jag vet kan inte ens C# 8.0 med den nya array-slice-syntaxen göra detta. Denna funktion blir mycket viktig när man hanterar sammanflätad data. Du kan designa din algoritm för att hantera kontinuerlig data och förse den med glesa skivor som efterliknar kontinuerliga datakällor, vilket minimerar algoritmens komplexitet.
Slicing kan slicas vidare, vilket är en mycket viktig funktion om du arbetar med högdimensionell data. Detta hjälper också till att minska algoritmens komplexitet, eftersom du kan minska datans dimension genom att rekursivt skära.
Användningsfall: Effektivt bearbeta högdimensionell data
Om du behöver tänka på en array av data som en volym och arbeta med dess delar utan att behöva göra otroliga koordinattransformationsberäkningar, då är .reshape() din vän. Alla arrayer som skapas av eller skärningsoperationer är .reshape(), bara en vy av originaldatan. När du itererar, läser eller skriver element till en vy, får du tillgång till den råa dataarrayen. NumSharp utför transparent lämpliga indextransformationer åt dig, så att du kan indexera skivor med relativa koordinater.
Användningsfall: Vänd på ordningen på elementen utan extra kostnad
Skivor som använder negativa steg vänder faktiskt på ordningen på skivorna. Fördelen med det är att det inte behöver kopiera eller räkna upp data för detta, precis som IEnumerable.Reverse(). Skillnaden är att vyn (resultatet av operationen a["::-1"]) visar data i omvänd ordning, och du kan indexera till den inverterade sekvensen utan att räkna upp den.
Användningsfall: Minska komplexiteten genom att minska dimensionerna
När man arbetar med högdimensionell data kan algoritmerna för dessa data också bli mycket komplexa. Vid användning kan vilken högdimensionell volym som helst matas ut. När ToString()s NumSharp-metod NDArray använde jag hur enkel och vacker algoritmen har blivit genom att systematiskt och rekursivt dela ND-volymer i (N-1)D-volymer, etc. Denna dela-och-härska-metod returnerar lågdimensionella delvolymer genom att skära upp intervallsymbolerna med hjälp av NumSharps indexsymboler. Intervallsymbol vs. indexsymbolRäckviddssymbolen ["start:stopp:steg"] låter dig komma åt ett delområde av en given volym med samma dimension. Så även om du bara tar bort en kolumn i 2D-matrisen, får du ändå en 2D-matris med bara en kolumn. Här är en kort C#-kod som visar detta:
Skär kolumnen med intervallsymbolen
Indexsymbolen ger dig en (N-1) dimensionell skiva på den angivna platsen för den N-dimensionella föräldravolymen. Så att klippa ut en kolumn från en 2D-matris med indexsymboler ger dig en 1D-vektor:
Skär kolumner med indexsymboler
Om du inte har sett skillnaden vid en snabb blick, här är de två skivdefinitionerna ovan, sida vid sida, ange[":2:3"] vs index[":,2"], som har stor påverkan på resultaten. En fullständig referens till den nya slice-symbolen finns på NumSharp-wikin.
Not: <T>ArraySlice
När jag implementerade slicing av n-dimensionella vyer drog jag slutsatsen att det kunde vara intressant för många andra områden i .NET, så jag delade upp det i mitt eget fristående bibliotek som heter SliceAndDice. Det är en lättviktig wrapper för att indexera vilken C#-datastruktur som helst (såsom ArraySlice<T>), och låter dig använda samma omstrukturering, slicing och visningsmekanismer utan alla andra tunga numeriska beräkningar. Det krävs bara några hundra rader kod för att uppnå utmärkta slicing-möjligheter! T[]IList<T>
Wraparound
NumSharp har nyligen fått samma slicing- och visningsmekanism, vilket utan tvekan gör NumPy till ett av de viktigaste biblioteken i Pythons maskininlärningsekosystem. SciSharp STACK är en open source-organisation bestående av ett fåtal skickliga utvecklare som har arbetat mycket hårt för att föra samma funktionalitet till .NET-världen. NumSharps senaste förbättringar är en viktig hörnsten för att uppnå detta. Original:Inloggningen med hyperlänken är synlig.
|