Test Driven Development per algoritmi stocastici?

3

questo è simile, ma non è lo stesso di questo post, la domanda più vicina che ho trovato su questo . Non vedo nemmeno quella risposta soddisfacente per la domanda posta in quel thread e tanto meno TDD. Se scrivo i miei test prima di scrivere il mio codice reale, come faccio a inventare casi "speciali" se non riesco ancora a eseguire il mio codice?

Stavo pensando a questo per il dominio di cose come le reti neurali e la programmazione genetica; Mentre per lo più posso evitare i test unitari sugli aspetti stocastici di NN, la programmazione genetica è una bestia completamente diversa. Gli algoritmi di selezione, ricombinazione, mutazione e accoppiamento dovrebbero avere determinate caratteristiche statistiche "corrette" nel contesto del mio programma. Nota che questo non è un caso di "test di non unità" perché se il mio programma non ha le proprietà statistiche giuste a ciascuno di questi livelli, ho un bug anche se il mio programma può sembrare che funzioni bene . Come faccio a testare qualsiasi Algoritmo evolutivo o algoritmo con requisiti stocastici simili?

EDIT: per qualche motivo la domanda suggester non funzionava correttamente, ma ho appena trovato questo nella barra laterale . La risposta principale parla di Mocks, ma come funzionerebbe in un ambiente di programmazione genetica, dove le stesse distribuzioni devono essere testate?

    
posta opa 30.05.2017 - 18:02
fonte

2 risposte

5

Onestamente, non penso che il vero TDD sia adatto per programmi pesantemente stocastici. Davvero onesto , non penso che sia una buona idea per nulla, ma mettendo da parte questo, renderai la vita più difficile di quanto non debba cercare di fare GP dove devi fallire i test prima di permetterti di scrivere qualsiasi codice.

Ci sono alcuni modi per fare un buon test unitario. Alcune cose sono ovvi tipi di test che potresti scrivere per qualsiasi programma. Non mi dilungherò su questo.

Uno dei trucchi specifici che userò per gli algoritmi randomizzati è capire quale distribuzione mi aspetto che i miei output abbiano, e poi scriverò un test che esegue la cosa un po 'di volte e controlla che la distribuzione dei risultati è abbastanza vicino a quello che mi aspettavo. Questi non sono veri e propri test unitari nel modo in cui li apprendi. Il mio test fallirà a volte solo perché possono accadere eventi improbabili. Quello che cerco è la fiducia, non la certezza. Se il mio test fallisce, guarderò i risultati effettivi. Sembrano che potrebbero essere stati legittimamente tratti dalla coda della mia distribuzione o no? Forse eseguirò la suite qualche altra volta per vedere se le cose tornano in linea.

Ovviamente puoi anche solo aggiustare il seed del tuo RNG, ma questo rende i tuoi test davvero fragili, come se cambiassi qualche aspetto di un algoritmo per richiedere un campione aggiuntivo dal generatore, tutto dopo quel cambiamento. Per questo motivo, è meglio utilizzare per testare aspetti di basso livello di un algoritmo in cui la quantità di codice coinvolta è piuttosto piccola.

Per lo più, quello che ho fatto in passato è non preoccuparmi troppo della copertura del test come parametro. Io uso test di alto livello come quelli statistici citati in precedenza, e debugano i livelli più bassi comunque. A volte, riesco a capire un modo per scrivere un buon test. Altre volte, faccio ciò che ho fatto a scuola prima di tentare di eseguire il debug di nuovi algoritmi di ottimizzazione stocastica: strumentare l'algoritmo con le istruzioni di stampa, stampare 50 pagine di output, registrarlo sul pavimento in laboratorio e gattonando con una copia stampata del codice sorgente andando, "OK, avrebbe dovuto generare un numero casuale qui, e se il numero fosse inferiore a 0.3, avrebbe dovuto fare bla bla ... ok, in realtà ha generato 0.46721, quindi vediamo, avrebbe dovuto farlo invece ... ok, sembra che funzionasse bene. " E lo faccio finché non sono convinto che il mio algoritmo sta facendo ciò che volevo che facesse.

    
risposta data 30.05.2017 - 18:23
fonte
1

TDD ti fa riflettere su cosa deve essere fatto e su come puoi testarlo. È un rompicoglo quando realizzi che il design deve cambiare a metà dello sviluppo e ora tutti i test devono essere regolati.

Per gli algoritmi genetici, ci sono molti che devono essere fatti prima che entri in gioco un singolo bit di entropia. Devi generare agenti. Vuoi testare che non generi un miliardo di agenti o zero agenti. Devi dare loro il DNA. Diciamo che è un dominio di ricerca del percorso e il loro DNA è costituito da [N, S, E, W]. Vuoi testare per assicurarti che il loro DNA non contenga altro che quelle 4 scelte. Hai bisogno di scoprire quando un agente naviga con successo il percorso / labirinto / obiettivo / cosa no. Si desidera verificare che il programma interrompa l'elaborazione dopo che raggiunge l'obiettivo. Scrivere i test prima ti fa pensare a queste cose e ti offre una bella lista di compiti da fare.

La natura intrinsecamente caotica degli algoritmi genetici entra in gioco quando vuoi che il tuo framework affronti con successo tutte le cose pazzesche che i piccoli agenti cercheranno di fare. Scrivi quali test puoi pensare, ma puoi scommettere che il tuo culo tornerà e scrivere più test una volta che gli agenti proveranno qualcosa a cui non avevi pensato. Come ... uscire dal bordo della mappa.

Inizia con la scrittura dei test. Questo è TDD. Ma non smetti di scrivere test e ti rendi conto che ci sarà un bel po 'di tempo nel mezzo in cui rispondi ai tuoi agenti che spezzano il tuo sistema. E ricorda che non stai provando a testare il comportamento emergente dei tuoi algoritmi genetici. Rilevare le condizioni finali dovrebbe essere una parte del tuo pacchetto di algoritmi genetici, testando che rileva con successo ciò che si suppone di trovare è l'obiettivo del test.

Per gli algoritmi stocastici in generale, si tenta di testare l'intero spazio di ricerca del possibile output che potrebbe produrre e si prende in giro la funzione rand () in modo da poterla percorrere attraverso l'intero spazio di ricerca. Se lo spazio di ricerca è ampio, non fingere di prendere tutto.

    
risposta data 24.06.2017 - 01:47
fonte