Come trasformare input ed estrarre output utili in una rete neurale?


9

Quindi ho cercato di capire le reti neurali da quando mi sono imbattuto nel blog di Adam Geitgey sull'apprendimento automatico. Ho letto il più possibile sull'argomento (che posso capire) e credo di comprendere tutti i concetti generali e alcuni dei meccanismi (nonostante sia molto debole in matematica), neuroni, sinapsi, pesi, funzioni di costo, backpropagation ecc. Tuttavia, non sono stato in grado di capire come tradurre i problemi del mondo reale in una soluzione di rete neurale.

Ad esempio, Adam Geitgey fornisce a titolo esemplificativo un sistema di previsione dei prezzi delle abitazioni in cui viene fornito un set di dati contenente il numero di camere da letto , Sq. piedi , quartiere e prezzo di vendita è possibile addestrare una rete neurale per essere in grado di prevedere il prezzo di una casa. Tuttavia si ferma a corto di implementare effettivamente una possibile soluzione nel codice. Il più vicino che ottiene, a titolo di esempio, è una funzione di base che dimostra come implementare i pesi:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
  price = 0

  # a little pinch of this
  price += num_of_bedrooms * 1.0

  # and a big pinch of that
  price += sqft * 1.0

  # maybe a handful of this
  price += neighborhood * 1.0

  # and finally, just a little extra salt for good measure
  price += 1.0

  return price 

Altre risorse sembrano concentrarsi maggiormente sulla matematica e l'unico esempio di codice di base che ho potuto capire che capisco (cioè che non è un po 'tutto il canto, tutta la base di codice di classificazione delle immagini danzanti) è un'implementazione che addestra una rete neurale per essere un XOR gate che si occupa solo di 1 e 0.

Quindi c'è una lacuna nella mia conoscenza che non riesco proprio a colmare. Se torniamo al problema della previsione del prezzo della casa , come si fa a rendere i dati adatti all'alimentazione in una rete neurale? Per esempio:

  • Numero di camere da letto: 3
  • Sq. piedi: 2000
  • Quartiere: Normaltown
  • Prezzo di vendita: $ 250.000

Puoi semplicemente inserire 3 e 2000 direttamente nella rete neurale perché sono numeri? O hai bisogno di trasformarli in qualcos'altro? Allo stesso modo, che dire del valore di Normaltown , che è una stringa, come si fa a tradurlo in un valore che può comprendere una rete neurale? Puoi semplicemente scegliere un numero, come un indice, purché sia ​​coerente in tutti i dati?

La maggior parte degli esempi di reti neurali che ho visto passare tra i livelli sono da 0 a 1 o da -1 a 1. Quindi alla fine dell'elaborazione, come si trasforma il valore di output in qualcosa di utilizzabile come $ 185.000 ?

So che l'esempio di previsione del prezzo della casa probabilmente non è un problema particolarmente utile dato che è stato enormemente semplificato in soli tre punti dati. Ma sento solo che se potessi superare questo ostacolo e scrivere un'app estremamente semplice che si allena usando dati pseudo nella vita reale e sputa una risposta pseudo nella vita reale di quanto avrò rotto il retro e sarei in grado di calciare e approfondire ulteriormente l'apprendimento automatico.

Risposte:


10

Questa è una buona domanda che ho affrontato con me stesso quando ho provato a scrivere un ANN.

Di seguito è una buona soluzione per tutti gli usi, ed è quella che ho implementato nel mio codice per cercare di prevedere dati numerici ben educati. Se i tuoi dati non sono ben educati (cioè irti di valori anomali), potrebbe essere necessario fare più lavoro per normalizzare gli input e gli output. Alcuni dei metodi più avanzati sono descritti qui .

Nota: suppongo che tu stia usando f (x) = tanh (x) come funzione di attivazione. Se non lo sei, dovresti comunque essere in grado di ragionare su come normalizzare i tuoi dati dopo aver letto questo.

Come preparare i dati di input:

L'idea di base è che si desidera che una variazione significativa in ciascun parametro di input sia riflessa da una variazione significativa nell'attivazione del neurone in cui vengono immessi gli input. Osservando un diagramma della derivata della funzione di actiavtion tanh (x), vedrai che la regione con pendenza significativa si trova a una distanza di uno o due dall'origine. Ciò significa che se l'input per la funzione di attivazione è 2000 o 3000 (valori di x per i quali la derivata è trascurabilmente piccola), l'output dell'attivazione sarà quasi identico ... quindi lo stato del neurone sarà indipendente dalla differenza tra 2000 e 3000 e la tua rete non produrrà mai alcuna potenza predittiva dai valori in quell'intervallo.

Quindi, se vuoi inserire il metraggio quadrato della casa in un neurone, devi normalizzare il metraggio quadrato in modo che la rete possa distinguere tra 2000 e 3000. Un modo per farlo in modo che tutte le variazioni significative nel tuo i dati vengono "notati" dal neurone per normalizzare gli input .

  • Raccogli tutti i valori del metraggio quadrato (dal tuo set di allenamento) e calcola la media e la deviazione standard. Memorizza la deviazione media e standard --- avrai bisogno di queste informazioni per normalizzare i nuovi valori di metraggio quadrato durante il test.

  • Normalizza il vettore dei valori di metraggio quadrati sottraendo la media e quindi dividendo il risultato per la deviazione standard (tutte le operazioni dal punto di vista dell'elemento ovviamente). La sottrazione della media centra i dati all'origine e la divisione per la deviazione standard assicura che la maggior parte di essi sia compresa tra -1 e 1, dove l'output del neurone è più sensibile al suo input. Questo si chiama normalizzazione del punteggio z perché ogni valore di input viene sostituito dal suo punteggio z .

  • Fai quanto sopra per ogni variabile di input.

Ora, quando metti ciascun valore di input attraverso un neurone, l'output del neurone è un'attivazione tra -1 e 1 (guarda l'immagine di tanh (x)). Poiché questo è già nell'intervallo "sensibile" della funzione di attivazione, non è necessario preoccuparsi di modificare l'output dei neuroni del livello di input prima di inviarli al primo livello nascosto. Dai semplicemente a tutti i neuroni del livello nascosto le uscite del livello precedente direttamente : saranno in grado di gestirli bene.

Quando raggiungi l'ultimo strato (i neuroni di output), ciò che ottieni è di nuovo un'altra attivazione tra -1 e 1. Devi riconvertirlo in un valore per la casa in questione , se quel valore verrà usato come una previsione in un set di test o per calcolare l'errore durante l'allenamento. Indipendentemente da ciò, devi solo essere coerente e utilizzare la stessa procedura di de-normalizzazione durante l'addestramento e i test. Un modo di pensarci è: quando il neurone / i in uscita restituisce 1, ciò significa che la rete sta restituendo il valore massimo possibile della casa come previsione. Quale dovrebbe essere il valore più alto che la rete può stimare? L'approccio giusto qui dipende semplicemente dalla tua applicazione. Questo è quello che ho fatto:

  • Calcola la media della variabile di output [the / each] e memorizzala.
  • Calcola la deviazione massima della variabile di output dalla media. Pitone:MaxDev = max([abs(DataPoint-numpy.mean(TrainingData)) for DataPoint in TrainingData])
  • Quando la rete restituisce output (s) tra -1 e 1, moltiplica l'output per MaxDeve aggiungilo alla media.

Due controlli rapidi di base che puoi fare per vedere se il tuo schema di normalizzazione-rinormalizzazione è adatto (queste sono condizioni necessarie, ma forse non sufficienti):

  1. Se tutti i valori di input sono nella media (ad es. Numero medio di camere da letto, piedi quadrati medi, ecc.), L'output della rete è uguale alla media della variabile di output (ad es. Valore della casa)? (Dovrebbe essere.)
  2. Se tutti i valori di input sono insolitamente alti / bassi, anche l'output della rete è insolitamente alto / basso? (Funziona solo se tutti gli input sono positivamente correlati all'output ... se alcuni di essi sono correlati inversamente, dovrai pensare un po 'di più).

Osservare che lo schema qui presentato soddisfa queste due condizioni.

Si noti che questo schema consentirebbe alla rete di prevedere solo i valori della casa all'interno dell'intervallo dei valori della casa nel set di dati di addestramento. A seconda dell'applicazione, questo comportamento può essere desiderabile o indesiderabile.

Ad esempio: potresti voler rendere impossibile per la tua rete prevedere valori casa negativi. Pensa a come lo faresti. De-normalizzare l'output in modo che -1 sia mappato su 0.

Se non vuoi impostare alcun limite sui valori che la tua rete può prevedere, puoi eseguire l'output della rete attraverso una funzione che mappa l'intervallo [-1,1] su tutti i numeri reali ... come arctanh (x)! Fintanto che lo fai durante l'allenamento, la tua rete regolerà i suoi pesi per adattarlo.

Spero sia stato utile. Fammi sapere se hai ulteriori domande. A proposito, il mio modulo ANN è in Python, quindi potrei avere consigli specifici sulla lingua.


Questo è stato molto utile! Ogni blog / tutorial che incontro sembra evitare (quasi deliberatamente) di descrivere questo processo, ma sì, tutto ha un senso. Ci vorrà un po 'per digerire correttamente, ma tornerò se avrò delle domande di follow-up. Molto obbligato!
David,

Quindi un paio di domande. Se il mio Mq. I dati di allenamento dei piedi erano {2000, 800, 850, 550, 2000}, quindi i miei input z-score per {1900, 1500, 600} sarebbero (se ho calcolato correttamente) {1.0496, 0.4134, -1.0177}. Quindi uno di questi valori è> 1 e uno è <-1, cosa farei con quelli? Inserirli nei nodi del livello di input indipendentemente o arrotondarli a 1 e -1? Perché 1900 e 600 producono questi valori quando rientrano nell'intervallo 550 - 2000? È solo un trucco dei dati perché esiste un set di dati così piccolo?
David

0andthemaximum

Ricorda che gli input non devono essere rigorosamente compresi tra 1 e -1. Tutto ciò che serve per gli input è che la maggior parte dei dati si trova in quell'intervallo. Un valore maggiore o minore di uno indica che il punto è più di una deviazione standard rispetto alla media, quindi quel punto è più vicino all'estremità superiore dei dati. Dovrebbe essere un po 'raro che i tuoi dati vadano al di fuori di [-1, 1], ancora più raro che vadano al di fuori di [-2, 2] ed estremamente rari al di fuori di [-3, 3]. Guarda tanh (x) e vedrai che l'intervallo sensibile non è solo strettamente compreso tra -1 e 1, ma va un po 'oltre.
Marko Bakić,

Per quanto riguarda la denormalizzazione dell'output, quella denormalizzazione min-max è ciò che ho fatto nella mia implementazione e la tua interpretazione è corretta, ma non è necessario che tu lo faccia. Potresti far sì che 1 corrisponda al doppio del valore massimo della casa, in questo modo la tua rete sarebbe in grado di prevedere i valori della casa al di sopra di quello su cui l'hai addestrato.
Marko Bakić,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.