Neuralt nätverk för klassificering med Tensorflow

Källnod: 1570297

Denna artikel publicerades som en del av Data Science Blogathon

I den här artikeln ska jag bygga neurala nätverksmodeller med TensorFlow för att lösa ett klassificeringsproblem. Låt oss tillsammans utforska hur vi kan närma oss ett klassificeringsproblem i Tensorflow. Men först vill jag se till att vi kan svara på dessa frågor:

är neuralt nätverk?

Huvudsyftet med ett neuralt nätverk är att försöka hitta sambandet mellan funktioner i en datamängd, och det består av en uppsättning algoritmer som efterliknar den mänskliga hjärnans arbete. En "neuron" i ett neuralt nätverk är en matematisk funktion som samlar in och klassificerar information enligt en specifik arkitektur.

Vad är klassificering?

Klassificeringsproblem innebär att förutsäga om något tillhör en klass eller inte. Med andra ord, medan vi gör det försöker vi se att något är det ena eller det andra.

Typer av klassificering

  • Anta att du vill förutsäga om en person har diabetes eller inte. Om du står inför den här typen av situation finns det två möjligheter, eller hur? Det kallas det Binär klassificering.
  • Anta att du vill identifiera om ett foto är av en leksak, en person eller en katt, eller hur? det här kallas Flerklassig klassificering eftersom det finns fler än två alternativ.
  • Anta att du vill bestämma vilka kategorier som ska tilldelas en artikel. Om så är fallet kallas det Multi-label klassificering, eftersom en artikel kan ha mer än en kategori tilldelad. Låt oss ta vår förklaring genom den här artikeln. Vi kan tilldela kategorier som "Deep Learning, TensorFlow, Classification" etc. till den här artikeln

Nu kan vi gå vidare eftersom vi har en gemensam förståelse för problemet vi kommer att arbeta med. Så det är dags för kodning. Jag hoppas att du skriver ner dem med mig för det enda sättet att bli bättre, göra färre misstag är att skriva mer kod.

Vi börjar med att importera bibliotek som vi kommer att använda:

importera numpy som np importera pandor som pd importera matplotlib.pyplot som plt importera tensorflow som tf print(tf.__version__)

Skapa en datamängd

Det är dags att skapa en datauppsättning att arbeta med:

från sklearn.datasets importera make_circles samples = 1000 X, y = make_circles(samples, brus = 0.03, random_state = 42)

Vi har skapat en del data, låt oss få mer information om det.

print(X >>[[ 0.75424625 0.23148074] [-0.75615888 0.15325888] [-0.81539193 0.17328203] ... [-0.13690036 -0.81001183]0.67036156 -0.76750154 -0.28105665 0.96382443] [ XNUMX XNUMX]]
print(y) >> [1 1 1 1 0 1 1 1 1 0]

Okej, vi har sett vår datauppsättning mer detaljerat, men vi vet fortfarande ingenting om det, eller hur? Det är därför här ett viktigt steg är att bli ett med data, och visualisering är det bästa sättet att göra detta.

cirkel = pd.DataFrame({ 'X0' : X[:, 0], 'X1' : X[:, 1], 'etikett' : y}) circle.head()
Neuralt nätverk för klassificering med Tensorflow-datahuvud

Här uppstår en fråga, vilken typ av etiketter har vi att göra med?

circle.label.value_counts() >> 1 500 0 500 Namn: etikett, dtype: int64

Ser ut som vi har att göra med ett binärt klassificeringsproblem, eftersom vi har 2 etiketter (0 och 1).

plt.scatter(X[:,0], X[:,1], c = y, cmap = plt.cm.RdYlBu)
Neuralt nätverk för klassificering med Tensorflow-spridningsdiagram

Som jag nämnde ovan är det bästa sättet att få en med data visualisering. Nu säger tomten sig själv att vilken typ av modell vi behöver bygga. Vi kommer att bygga en modell som kan skilja blå prickar från röda prickar.

Innan vi bygger någon modell för neurala nätverk måste vi kontrollera formerna på våra in- och utdatafunktioner. de måste vara samma!

print(X.shape, y.shape) print(len(X), len(y)) >> (1000, 2) (1000,) 1000 1000

Vi har samma mängd värden för varje funktion, men formen på X är annorlunda? Varför? Låt oss kolla upp det.

X[0], y[0] >> (array([0.75424625, 0.23148074]), 1)

Okej, vi har 2 X-funktioner för 1 år. Så vi kan gå vidare utan problem.

Steg i modellering av neurala nätverk för klassificering med Tensorflow

I TensorFlow finns det fasta steg för att skapa en modell:

  • Skapa en modell – sätt ihop lagren i ett neuralt nätverk med hjälp av funktionell eller sekventiell API
  • Sammanställa en modell – definiera hur en modells prestanda ska mätas och hur den ska förbättras (förlustfunktion och optimerare)
  • Anpassa ett lägel – låta en modell hitta mönster i datan

Vi kommer att använda Sequential API. Så, låt oss börja

tf.random.set_seed(42)
model_1 = tf.keras.Sequential([tf.keras.layers.Dense(1)])

model_1.compile(loss = tf.keras.losses.BinaryCrossentropy(),

#vi använder Binär som förlustfunktion, eftersom vi arbetar med 2 klasser

 optimizer = tf.keras.optimizers.SGD(), #SGD står för Stokastisk Gradient Descent Metrics = ['precision']) model_1.fit(X, y, epoker = 5)
>> Epok 1/5 32/32 [==========================================] - 1s 1ms/steg - förlust: 2.8544 - noggrannhet: 0.4600 Epok 2/5 32/32 [==========================================] - 0s 2ms/steg - förlust : 0.7131 - noggrannhet: 0.5430 Epok 3/5 32/32 [================================================================================================== - förlust: 0 - noggrannhet: 2 Epok 0.6973/0.5090 4/5 [================================================] - 32s 32ms /steg - förlust: 0 - noggrannhet: 2 Epok 0.6950/0.5010 5/5 [=========================================== 32s 32ms/steg - förlust: 0 - noggrannhet: 1

Modellens noggrannhet är ungefär 50% vilket i princip betyder att modellen bara gissar, låt oss försöka träna den längre

model_1.fit(X, y, epoker = 200, verbose = 0) #vi sätter verbose = 0 för att ta bort träningsprocedur ) model_1.evaluate(X, y)
>> 32/32 [===============================] - 0s 1ms/steg - förlust: 0.6935 - noggrannhet: 0.5000 [0.6934829950332642, 0.5]

Även efter 200 epoker presterar den fortfarande som den gissar. Nästa steg är att lägga till fler lager och träna längre.

tf.random.set_seed(42)
model_2 = tf.keras.Sequential([ tf.keras.layers.Dense(1), tf.keras.layers.Dense(1) ]) model_2.compile(loss = tf.keras.losses.BinaryCrossentropy(), optimizer = tf.keras.optimizers.SGD(), metrics = ['noggrannhet']) model_2.fit(X, y, epoker = 100, verbose = 0)
 model_2.evaluate(X,y)
>> 32/32 [===============================] - 0s 1ms/steg - förlust: 0.6933 - noggrannhet: 0.5000 [0.6933314800262451, 0.5]

Ändå är det inte ens en liten förändring, det verkar som att något är fel.

Förbättring av modellen för neurala nätverk för klassificering med Tensorflow

Det finns olika sätt att förbättra en modell i olika skeden:

  • Skapa en modell – lägg till fler lager, öka antalet dolda enheter (neuroner), ändra aktiveringsfunktionerna för varje lager
  • Sammanställa en modell – prova olika optimeringsfunktioner, använd till exempel Adam() istället för SGD().
  • Montering av en modell – vi skulle kunna öka antalet epoker

Låt oss försöka lägga till fler neuroner och försök Adam Optimizer

tf.random.set_seed(42)
model_3 = tf.keras.Sequential([ tf.keras.layers.Dense(100), # lägg till 100 täta neuroner tf.keras.layers.Dense(10), # lägg till ytterligare ett lager med 10 neuroner tf.keras.layers.Dense (1) ]) model_3.compile(loss=tf.keras.losses.BinaryCrossentropy(), optimizer=tf.keras.optimizers.Adam(), metrics=['precision']) model_3.fit(X, y, epoker =100, verbose=0)
model_3.evaluate(X,y) >> 32/32 [===============================] - 0s 1ms/steg - förlust: 0.6980 - noggrannhet: 0.5080 [0.6980254650115967, 0.5080000162124634]

Blir fortfarande inte bättre! Låt oss visualisera data för att se vad som går fel.

Visualisera den neurala nätverksmodellen

För att visualisera vår modells förutsägelser kommer vi att skapa en funktion plot_decision_boundary() som:

  • Tar in en tränad modell, funktioner och etiketter
  • Skapa ett meshgrid av de olika X-värdena.
  • Gör förutsägelser över meshgrid.
  • Ritar förutsägelserna med linje.

Notera:  Denna funktion har anpassats från två resurser:

CS231n Tillverkad med grunderna i ML 

def plot_decision_boundary(modell, X, y): # Definiera axelgränserna för plotten och skapa ett meshgrid x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1 y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1 xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np .linspace(y_min, y_max, 100)) # Skapa X-värden (vi ska förutsäga alla dessa) x_in = np.c_[xx.ravel(), yy.ravel()] # Gör förutsägelser med hjälp av den tränade model y_pred = model.predict(x_in) # Kontrollera om det finns flera klasser
 if len(y_pred[0]) > 1: print("gör flerklassklassificering...") # Vi måste omforma våra förutsägelser för att göra dem redo för att plotta y_pred = np.argmax(y_pred, axis=1).reshape( xx.shape) else: print("gör binär klassificering...") y_pred = np.round(y_pred).reshape(xx.shape) # Plotta beslutsgräns plt.contourf(xx, yy, y_pred, cmap=plt. cm.RdYlBu, alfa=0.7) plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.RdYlBu) plt.xlim(xx.min( ), xx.max()) plt.ylim(yy.min(), yy.max()) plot_decision_boundary(modell_3, X, y)
beslutsgräns

Här är det! Återigen visar visualisering oss vad som är fel och vad vi ska göra? Vår modell försöker rita en rät linje genom data, men vår data kan inte separeras med en rät linje. Är det något som går miste om vårt klassificeringsproblem? Vad det är?

Detta är icke-linjäritet! Vi behöver några icke-linjära linjer. Du kan bli förvirrad nu, om du tror att du inte såg den typen av funktion tidigare har du fel, för det har du. Låt oss se dem visuellt. Visualisering fungerar alltid bättre!

Det finns några aktiveringsfunktioner i Neural Network som vi kan använda, som ReLu, Sigmoid. Låt oss skapa lite leksakstensor och kontrollera dessa funktioner på den.

Aktiveringsfunktioner för neurala nätverk

A = tf.cast(tf.range(-12,12), tf.float32) print(A) >> tf.Tensor( [-12. -11. -10. -9. -8. -7. - 6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.], form=(24,), dtype=float32)

Låt oss se hur vår leksakstensor ser ut?

plt.plot(A)
Aktiveringsfunktioner för neurala nätverk

Det ser ut så här, en rak linje! 

Låt oss nu återskapa aktiveringsfunktioner för att se vad de gör med vår tensor?

Sigmoid:

def sigmoid(x): return 1 / (1 + tf.exp(-x)) sigmoid(A) plt.plot(sigmoid(A))
sigmoid-funktion

En icke rak linje!

ReLu:

Låt oss nu kolla vad ReLu gör? Relu ändrar alla negativa värden till 0 och positiva värden förblir desamma.

def relu(x): return tf.maximum(0,x) plt.plot(relu(A))
ReLu

Ännu en icke rak linje!

Nu har du sett icke-linjära aktiveringsfunktioner, och det är dessa som kommer att fungera för oss, modellen kan inte lära sig något på en icke-linjär datauppsättning med linjära aktiveringsfunktioner! Om du har lärt dig detta är det dags att dela upp vår data i tränings- och testset och bygga starka modeller.

X_train, y_train = X[:800], y[:800] X_test, y_test = X[800:], y[800:] X_train.shape, X_test.shape >>((800, 2), (200, 2) ))

 

Bra, nu har vi tränings- och testset, låt oss modellera träningsdatan och utvärdera vad vår modell har lärt sig på testsetet.

tf.random.set_seed(42)
model_4 = tf.keras.Sequential([ tf.keras.layers.Dense(4, activation = 'relu'), #vi kanske rättar till "tf.keras.activations.relu" också tf.keras.layers.Dense(4 , activation = 'relu'), tf.keras.layers.Dense(1, activation = 'sigmoid') ]) model_4.compile( loss= tf.keras.losses.binary_crossentropy, optimizer = tf.keras.optimizers.Adam( lr = 0.01), metrics = ['noggrannhet']) model_4.fit(X_train, y_train, epoker = 25, verbose = 0)

Utvärdera modellen

förlust, noggrannhet = model_4.evaluate(X_test, y_test) print(f' Modellförlust på testset: {loss}') print(f' Modellnoggrannhet på testset: {100*exakthet}')
>> 7/7 [===============================] - 0s 2ms/steg - förlust: 0.1247 - noggrannhet: 1.0000 Modellförlust på testset: 0.1246885135769844 Modellnoggrannhet på testset: 100.0

Voila! 100% noggrannhet! låt oss se detta resultat visuellt

plt.figure(figsize=(12, 6)) plt.subplot(1, 2, 1) plt.title("Train") plot_decision_boundary(model_4, X=X_train, y=y_train) plt.subplot(1, 2, 2) plt.title("Test") plot_decision_boundary(model_4, X=X_test, y=y_test) plt.show()
binärt neuralt nätverk för klassificering med Tensorflow

Med bara några få justeringar förutsäger vår modell nu de blå och röda cirklarna nästan perfekt.

Slutsats

Låt oss ta en kort titt på vad vi pratar om i den här artikeln. Tillsammans tittade vi på hur man kan närma sig en klassificeringsuppgift i det neurala nätverket med TensorFlow. Vi skapade 3 modeller på det första sättet som kom att tänka på, och med hjälp av visualisering insåg vi var vi hade fel, vi utforskade linjäritet, icke-linjäritet, och slutligen lyckades vi bygga en generaliserad modell. Det jag försökte visa med alla dessa koder och stegen jag följde var att ingenting är 100 procent korrekt eller fixat, allt fortsätter att förändras varje dag. För att gissa vilket problem du sannolikt kommer att möta i vilken typ av data och för att se vilka kombinationer som leder till ett bättre resultat, behöver du bara skriva mycket mer kod och få erfarenhet.

Jag hoppas att artikeln var lite till hjälp för dig och gav några bidrag.

Medierna som visas i den här artikeln ägs inte av Analytics Vidhya och används efter författarens gottfinnande

Källa: https://www.analyticsvidhya.com/blog/2021/11/neural-network-for-classification-with-tensorflow/

Tidsstämpel:

Mer från Analys Vidhya