Bygg en hjärna på 10 minuter med Nvidia

  • July 09, 2025

Bygg en hjärna på 10 minuter med Nvidia

Idag ska vi bygga en mycket enkel hjärna. Inte en sci-fi-robot-hjärna, utan ett grundläggande neuralt nätverk som kan lära sig att känna igen bilder av kläder – specifikt med hjälp av Fashion MNIST-datamängden. Vårt mål? Att få en maskin att titta på en suddig gråskalebild och säga: ”Det där är en sneaker.”

Vi kommer att arbeta i TensorFlow och Keras, två populära bibliotek för djupinlärning i Python. Denna genomgång är inspirerad av NVIDIAs Deep Learning Institute.

Perceptronen, utvecklad av Frank Rosenblatt 1958, representerar en av de tidigaste milstolparna i neurala nätverks historia. Det var en enkel, enkelskiktad neural modell utformad för att efterlikna hur hjärnan lär sig genom trial and error. Även om dess kapacitet var begränsad (den misslyckades med att lösa problem som XOR), lade denna grundläggande forskning grunden för dagens djupinlärningssystem. Dokumentären fungerar som en påminnelse om hur tidiga ambitioner inom AI banade väg för de kraftfulla modeller vi bygger idag.


1. Kontrollera hårdvaran

Först kontrollerar vi om datorn är utrustad för djupinlärning genom att låta TensorFlow lista fysiska GPU-enheter. De kan fungera som turboladdare för träning av neurala nätverk. En CPU kan också göra jobbet, men skillnaden kan likna ett lopp mellan en häst och ett litet barn.

import tensorflow as tf
tf.config.list_physical_devices('GPU')

Om vi får ett svar som visar en GPU har vi tur. Träningen går snabbare.


2. Laddar datamängden

Vi ska nu ta oss an en utmaning som hade verkat nästan omöjlig för några decennier sedan: att träna en dator att känna igen bilder med hjälp av datorseende. Specifikt handlar vår uppgift om att identifiera olika typer av kläder i datamängden Fashion MNIST .

Inspirerade av hur människor lär sig genom trial and error, kommer vi att simulera denna process genom att använda digitala flashcards. Den artificiella hjärnan – vårt neurala nätverk – kommer att gissa vilka klädesplagg som visas, och vi kommer att korrigera den genom att ange de faktiska etiketterna. Med tiden lär den sig av både sina misstag och framgångar.

Precis som elever inför ett prov håller vi undan data för att bedöma generalisering till exempel som inte användes för att anpassa vikterna. Bra valideringsresultat hjälper till att upptäcka överanpassning men bevisar inte mänsklig förståelse eller resonemang. Behåll en separat testmängd för slutlig utvärdering när valideringsresultat används för att justera modellen.

Datan vi använder för att lära modellen kallas training dataset, medan den reserverade datan för testning kallas validation dataset. Eftersom Fashion MNIST är en välkänd datamängd, inkluderar TensorFlow den som standard. Så låt oss ladda den och se hur den ser ut.

fashion_mnist = tf.keras.datasets.fashion_mnist
(train_images, train_labels), (valid_images, valid_labels) = fashion_mnist.load_data()

3. Visualisera ett urval

Innan vi ber ett neuralt nätverk att skilja mellan en sneaker och en tröja, är det bra att säkerställa att vi, som människor, faktiskt kan tolka datan själva.

Datamängden ger oss train_images och train_labels. Tänk på train_images som frågorna vi ställer till vår modell – vad den ser – och train_labels som de motsvarande svaren. Inom datavetenskap kallas dessa svar vanligtvis för labels.

För att bättre förstå indata kan vi visualisera en exempelbild med hjälp av Matplotlib, ett populärt plottningsbibliotek i Python.

import matplotlib.pyplot as plt
data_idx = 69
plt.figure()
plt.imshow(train_images[data_idx], cmap='gray')
plt.colorbar()
plt.grid(False)
plt.show()

Detta visar oss en exempelbild. I detta fall, föremål #69. När du tittar på den kanske du säger, "Det där ser ut som ett falliskt föremål."

Och du har förmodligen rätt, men det är faktiskt ett par byxor:

train_labels[data_idx]  # Output: 1

Etikett 1 motsvarar "byxor". Bra jobbat, människa. Här har vi en utmärkt tabell för att hjälpa oss att se de olika kategorierna. 


4. Definiera modellen

Neuroner är de väsentliga enheterna som utgör ett neuralt nätverk. I biologisk mening skickar neuroner elektriska signaler när de får rätt typ av stimulus, detta hjälper dig att skilja mellan rött och gult till exempel. Artificiella neuroner gör något liknande, förutom att de arbetar med siffror – när du matar in vissa värden, producerar de ett numeriskt resultat.

Du kan tänka dig att skapa en neuron i tre huvudsteg:

  • Först definierar vi dess struktur (detta är dess arkitektur).

  • Därefter tränar vi den med data.

  • Slutligen bedömer vi hur väl den presterar.

Bygga strukturen

Biologiska neuroner använder ett system som liknar morsekod för att skicka information. De tar emot signaler via sina dendriter, och om insignalen uppfyller rätt villkor skickar de en puls längs axonen till neuronens terminaler.

Man tror att både tidpunkten och sekvensen av dessa pulser bidrar till att förmedla information. De flesta artificiella neurala nätverk replikerar ännu inte denna tidsmässiga komplexitet. Istället modellerar de beteendet med matematiska ekvationer.

Hur matematiken fungerar

Datorer hanterar information som sekvenser av 0 och 1, medan människor och djur fungerar med mer kontinuerliga insignaler. Tidiga artificiella neuroner försökte imitera biologiska med hjälp av en linjär regressionsfunktion: y = mx + b. Här är x insignalen (liknar signaler som går in i dendriter), och y utsignalen (som impulsen som lämnar terminalerna). När systemet ser mer data och förutsägelser, justerar det värdena för m och b för att förbättra noggrannheten.

Neuroner behöver ofta bearbeta många insignaler samtidigt. I vårt exempel kommer vi att behandla varje pixel i en bild – var och en med ett värde mellan 0 (svart) och 255 (vitt) – som en separat insignal. Var och en av dessa insignaler får sin egen vikt (liknar vårt m), och dessa vikter betecknas med w. Så pixel ett har w0, pixel två har w1, och så vidare. Detta förvandlar vår ekvation till något i stil med: y = w0x0 + w1x1 + w2x2 + ... + b.

Varje bild är 28 pixlar bred och 28 pixlar hög, så varje utdataneuron har 784 indatavikter. Varje pixel bidrar genom sin motsvarande vikt. Med tio utdataneuroner har hela modellen 7 840 vikter plus tio biasvärden.

 

Vi har använt en enkel ekvation, y = mx + b, som ger oss ett enda nummer som utdata. Men saken är – vi försöker känna igen typer av kläder, inte bara mata ut ett nummer. Så hur förvandlar vi ett enkelt nummer till ett beslut som ”Det här är en T-shirt” eller ”Det där är en sneaker”?

En enkel lösning är en utdataneuron för varje klädtyp. Fashion MNIST har tio kategorier, så vi använder tio neuroner. Varje neuron ger ett rått klassvärde, en logit. Den största logiten bestämmer den förutsagda klassen; en logit är inte i sig en sannolikhet.

Vi kan enkelt skapa den här typen av inställning med Keras, ett högnivå-API som nu är en del av TensorFlow. Vi kommer att använda dess Sequential API, som låter oss organisera vår modell som en serie staplade lager. Tänk på lager som bearbetningssteg som tar indata och omvandlar den till förutsägelser.

Modellen vi ska skapa har två lager:

  • Ett Flatten-lager, som tar vår 28×28-bild och omformar den till en enda lista med 784 värden.

  • Ett Dense-lager, som innehåller 10 neuroner. Varje neuron har en egen vikt för varje indatapixel och ett biasvärde. Varje neuron beräknar ett rått klassvärde, en logit, snarare än en sannolikhet.

Vi kommer också att specificera en input_shape på (28, 28), vilket matchar pixeldimensionerna för varje bild.

number_of_classes = 10
model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(number_of_classes)
])

Verifierar modellen

För att säkerställa att vår modell har den struktur vi tror den har, kan vi anropa dess summary -metod. Så här ser utdatan ut:

Låt oss förklara varifrån siffran – 7 850 – kommer ifrån. Varje 28×28 bild har 784 pixlar. För varje av de 10 utdataneuroner (som representerar de 10 klasserna) behöver vi en unik vikt för varje av dessa 784 ingångar. Det är 784 * 10 = 7,840 vikter. De ytterligare 10 parametrarna är bias – en för varje utdataneuron – vilket ger totalt 7,840 + 10 = 7,850. Dessa bias fungerar som b i ekvationen y = mx + b, vilket gör att varje neuron kan justera sin aktiveringsbaslinje oberoende.

I akademisk litteratur visualiseras modellarkitekturer ibland som nod-länkdiagram. Även om sådana diagram fungerar för små nätverk, blir de otympliga med moderna modeller. Diagrammet som refereras här representerar endast en liten del av vår modell: 28 ingångsnoder överst (som representerar en rad i bilden) och 10 utgångsneuroner längst ner. I verkligheten skulle vi ha 784 ingångar – en för varje pixel.

Varje punkt representerar antingen en ingång eller en neuron, och varje anslutande linje är en vikt – en av de 7 840 inlärbara parametrarna.

Slutligen finns det ett annat sätt att visuellt verifiera vår modell: du kan plotta den. Var dock varnad – när nätverk blir komplexa blir dessa diagram mer abstrakt konst än användbara verktyg.

Model: "sequential"
Lager (typ) Utdataform Antal parametrar
flatten (Flatten) (None, 784) 0
dense (Dense) (None, 10)  7,850
 Total params: 7,850 (30.66 KB)
 Trainable params: 7,850 (30.66 KB)
 Non-trainable params: 0 (0.00 B)

5. Initiera träning

Före träning kompilerar vi modellen med en förlustfunktion och en optimerare.

Vi har byggt en modell – men hur hjälper vi den att förbättras? Tänk dig det som att ge en elev ett prov och ett svarsblad. Vi behöver ett sätt att utvärdera hur långt ifrån de korrekta svaren modellens svar är. Det är vad loss gör: den beräknar skillnaden mellan modellens förutsägelse och den faktiska etiketten, så den vet hur den ska justera sina interna inställningar.

För klassificeringsproblem som vårt kommer vi att använda en specifik typ av förlustfunktion som kallas SparseCategoricalCrossentropy. Här är vad varje del av namnet berättar:

  • Sparse – Istället för att använda one-hot-kodade etiketter (där varje klass representeras av en vektor med en etta och resten nollor), fungerar den här funktionen med heltalsetiketter (t.ex. 0 till 9). Så våra kategorier indexeras numeriskt.

  • Categorical – Den är byggd för klassificeringsuppgifter, där vi förutsäger en kategori snarare än ett kontinuerligt värde.

  • Cross-entropy – Detta straffar förutsägelser som ger den korrekta klassen mycket låg sannolikhet. Förlusten är icke-negativ och växer mot positiv oändlighet när sannolikheten närmar sig noll. Lägre förlust är bättre.

Denna förlustfunktion passar bra för vår modell eftersom den utvärderar alla tio utdataneuroner samtidigt. Om flera neuroner starkt signalerar att deras klass är den korrekta, griper denna funktion in och säger: ”Tyvärr, gott folk – bara en av er kan ha rätt.”

För att gå bortom bara förlust kan vi inkludera andra metrics– som accuracy– för att ge oss en bättre bild av prestandan. Ibland kan förlusten vara låg (vilket tyder på goda förutsägelser i genomsnitt), men den faktiska noggrannheten kan vara eftersläpande. Mått hjälper till att lyfta fram den skillnaden.

model.compile(
    optimizer='adam',
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=['accuracy']
)
  • adam: En populär optimerare som anpassar inlärningshastigheter adaptivt.

  • SparseCategoricalCrossentropy: Används när våra etiketter är heltal (0-9), inte one-hot-vektorer.

  • from_logits=True – Detta talar om för funktionen att modellens utdata är i rå poängform (logits) och ännu inte har omvandlats till sannolikheter. Förlustfunktionen hanterar den omvandlingen internt.

6. Träna modellen

Här kommer den spännande delen – där vår modell får träna och testa sig själv. Fit-metoden i TensorFlow är det som får detta att hända. Den låter modellen lära sig av träningsdatan och även testa sig själv med hjälp av valideringsdatan.

Inom maskininlärningsjargongen representerar en epoch en fullständig genomgång av hela träningsdatamängden. Det är som en elev som går igenom alla sina övningskort en gång. Precis som människor ofta behöver repetera materialet flera gånger gynnas modellen av att se träningsexemplen flera gånger.

Vid slutet av varje epok pausar modellen sin studiesession och tar en snabb frågesport med hjälp av valideringsdatauppsättningen. Detta hjälper oss att mäta hur mycket den faktiskt lär sig kontra hur mycket den bara memorerar. Dags att se den arbeta och bli smartare!

history = model.fit(
    train_images, train_labels,
    epochs=5,
    validation_data=(valid_images, valid_labels)
)

Så, hur presterade vår modell? Kanske ett stabilt B-minus? Låt oss ge den en paus – den arbetade bara med 10 neuroner, medan den mänskliga hjärnan har miljarder som aktiveras samtidigt.

Vi kan förvänta oss att modellens noggrannhet hamnar runt 80 %, även om den siffran inte är fast. Resultatet kan variera något på grund av hur träningsbilderna (våra digitala flashcards) blandades och den slumpmässiga initieringen av modellens vikter vid träningsstarten. En viss slumpmässighet är inbakad i varje körning, så inga två träningspass är helt identiska.


7. Göra förutsägelser

Nu när träningen är klar kan vi granska förutsägelser. Exemplen nedan använder träningsbilder och är därför en demonstration, inte en oberoende utvärdering. Vi använder predict -metoden, som låter oss se modellens förutsägelser på vilken bild som helst, oavsett om den kommer från träningsdatauppsättningen eller är helt ny.

Tänk på att Keras alltid förväntar sig indata i omgångar – även om det bara är en bild. Så, för att göra en förutsägelse på en enskild bild, måste vi fortfarande skicka den som en omgång med ett objekt.

Vi granskar förutsägelser för de första 10 träningsbilderna. De råa utdata är logits: relativa klassvärden, inte kalibrerade sannolikheter. Softmax omvandlar logitvektorn till sannolikheter som summerar till ett, men garanterar inte kalibrering.

Vi visar indatabilden och ett stapeldiagram över logits. Jämför värdena med varandra: det högsta värdet ger den förutsagda klassen. En negativ logit betyder inte i sig att klassen är osannolik eller felaktig; samma konstant kan läggas till alla logits utan att softmax-sannolikheterna förändras.

Du kan ändra värdet data_idx för att se förutsägelser för olika exempel. Hur korrekt tycker du att det är? När den gör misstag, är de förståeliga?

plt.imshow(train_images[data_idx], cmap='gray')
plt.show()

predictions = model.predict(train_images[data_idx:data_idx+1])
plt.bar(range(10), predictions.flatten())
plt.xticks(range(10))
plt.show()

print("correct answer:", train_labels[data_idx])

Diagrammet jämför värden för de 10 kategorierna. Helst motsvarar den högsta stapeln den rätta klassen. I detta exempel var det en sneaker.

Helst är stapeln för klass 7 högst. Det betyder att modellen väljer sneaker som förutsagd klass; själva stapelhöjden är inte en sannolikhet.

Boom. Det var en sneaker.


Slutsats

Och det, kära lyssnare, är hur man bygger en hjärna på 10 minuter. Den är inte medveten, den drömmer inte, men den känner igen skor.

Vi använde:

  • TensorFlow och Keras för modellbyggande

  • Fashion MNIST för data

  • Matplotlib för visualisering

Viktigare är att vi såg hela flödet: ladda data, visualisera, bygga en modell, träna den och kontrollera dess förutsägelser.

I praktiken är detta bara början. Bättre modeller skulle använda djupare lager, dropout för regularisering och datanormalisering. Men om du förstod detta, förstår du kärnan i maskininlärning.

Maskinen förändrade inte världen ännu, men kanske blev din just lite smartare.

 

Lämna en kommentar

Observera att kommentarer måste godkännas innan de publiceras.