Wie groß sollten Stapelgröße und Anzahl der Epochen sein, wenn ein Modell in Keras eingebaut wird?

73

Ich trainiere an 970 Proben und validiere an 243 Proben.

Wie groß sollten Stapelgröße und Anzahl der Epochen sein, wenn ein Modell in Keras angepasst wird, um val_acc zu optimieren? Gibt es eine Faustregel, die auf der Größe der Dateneingabe basiert?

pr338
quelle
7
Ich würde sagen, dass dies stark von Ihren Daten abhängt. Wenn Sie nur mit einer einfachen Aufgabe wie XOR-Klassifikatoren herumspielen, reichen einige hundert Epochen mit einer Stapelgröße von 1 aus, um eine Genauigkeit von 99,9% zu erreichen. Für MNIST habe ich meistens vernünftige Ergebnisse mit etwa 10 bis 100 für die Chargengröße und weniger als 100 Epochen erzielt. Ohne Details zu Ihrem Problem, Ihrer Architektur, Ihren Lernregeln / Kostenfunktionen, Ihren Daten usw. kann man dies nicht genau beantworten.
Daniel451
Gibt es eine Möglichkeit, alle Daten in jede Trainingsepoche einzubeziehen?
KRazzy R
1
@kRazzyR. Tatsächlich werden bei jedem Training alle Daten mit einer geteilten Charge berücksichtigt. Wenn Sie alle Daten in einem einzigen Vorgang einschließen möchten, verwenden Sie die Stapelgröße der Datenlänge.
Vivek Ananthan

Antworten:

66

Da Sie einen ziemlich kleinen Datensatz (~ 1000 Proben) haben, wären Sie wahrscheinlich sicher, wenn Sie eine Stapelgröße von 32 verwenden, was ziemlich Standard ist. Es wird keinen großen Unterschied für Ihr Problem machen, wenn Sie nicht an Hunderttausenden oder Millionen von Beobachtungen trainieren.

So beantworten Sie Ihre Fragen zu Chargengröße und Epochen:

Im Allgemeinen : Größere Chargen führen zu schnelleren Trainingsfortschritten, konvergieren jedoch nicht immer so schnell. Kleinere Losgrößen trainieren langsamer, aber kann schneller konvergieren. Es ist definitiv problemabhängig.

Im Allgemeinen verbessern sich die Modelle mit mehr Trainingsepochen bis zu einem gewissen Punkt. Sie werden anfangen, an Genauigkeit zu gewinnen, wenn sie konvergieren. Versuchen Sie etwas wie 50 und zeichnen Sie die Anzahl der Epochen (x-Achse) gegen die Genauigkeit (y-Achse). Sie werden sehen, wo es sich abflacht.

Was ist die Art und / oder Form Ihrer Daten? Handelt es sich um Bilder oder nur um Tabellendaten? Dies ist ein wichtiges Detail.

Lucas Ramadan
quelle
4
Die Stapelgröße sollte so groß wie möglich sein, ohne den Speicher zu überschreiten. Der einzige andere Grund für die Begrenzung der Stapelgröße besteht darin, dass Sie beim gleichzeitigen Abrufen des nächsten Stapels und Trainieren des Modells für den aktuellen Stapel möglicherweise Zeit damit verschwenden, den nächsten Stapel abzurufen (da dieser so groß ist und die Speicherzuweisung möglicherweise erheblich dauert Zeit), wenn das Modell die Anpassung an die aktuelle Charge abgeschlossen hat. In diesem Fall ist es möglicherweise besser, Chargen schneller abzurufen, um Ausfallzeiten des Modells zu verringern.
BallpointBen
4
Ich sehe oft Werte für die Chargengröße, die ein Vielfaches von 8 sind. Gibt es einen formalen Grund für diese Wahl?
Peter
Führt eine größere Epoche zu einer Überanpassung? Führt mehr Daten und weniger Epochen zu einer Unteranpassung?
Dom045
18

Tolle Antworten oben. Alle gaben gute Beiträge.

Im Idealfall ist dies die Reihenfolge der Chargengrößen, die verwendet werden sollen:

{1, 2, 4, 8, 16} - slow 

{ [32, 64],[ 128, 256] }- Good starters

[32, 64] - CPU

[128, 256] - GPU for more boost
Beltino Goncalves
quelle
1
Für mich waren diese Werte sehr schlecht. Am Ende habe ich für mein Modell eine Losgröße von 3000 verwendet, was weit mehr ist, als Sie hier vorgeschlagen haben.
Ian Rehwinkel
6
Hmm, gibt es eine Quelle, warum Sie dies als gegebene Tatsache angeben?
Markus
Hier ist eine zitierte Quelle, die diese Chargengrößen für ein CNN-Modell verwendet. Hoffe, das ist eine gute Verwendung für Sie. ~ Prost arxiv.org/pdf/1606.02228.pdf#page=3&zoom=150,0,125
Beltino Goncalves
1
Dies scheint eine grobe Vereinfachung zu sein. Die Stapelgröße hängt im Allgemeinen von der Komplexität Ihres Eingabesatzes pro Element sowie von der Speichermenge ab, mit der Sie arbeiten. Nach meiner Erfahrung erziele ich die besten Ergebnisse, wenn ich meine Chargengröße schrittweise skaliere. Für mich hatte ich das beste Glück, angefangen mit 1 zu haben und meine Stapelgröße jede nTrainingsstunde zu verdoppeln , nje nach Komplexität oder Größe des Datensatzes, bis ich die Speichergrenzen meiner Maschine erreicht habe, und dann weiter mit der größten zu trainieren Chargengröße so lange wie möglich möglich.
IanCZane
10

Ich benutze Keras, um eine nichtlineare Regression für Sprachdaten durchzuführen. Jede meiner Sprachdateien enthält Funktionen mit 25000 Zeilen in einer Textdatei, wobei jede Zeile 257 reelle Zahlen enthält. Ich verwende eine Stapelgröße von 100, Epoche 50, um das SequentialModell in Keras mit 1 versteckten Ebene zu trainieren . Nach 50 Trainingsepochen konvergiert es recht gut auf ein Tief val_loss.

tauseef_CuriousGuy
quelle
4

Ich habe Keras verwendet, um eine nichtlineare Regression für die Marktmixmodellierung durchzuführen. Ich habe die besten Ergebnisse mit einer Stapelgröße von 32 und Epochen = 100 erzielt, als ich ein sequentielles Modell in Keras mit 3 versteckten Ebenen trainiert habe. Im Allgemeinen ist eine Stapelgröße von 32 oder 25 gut, mit Epochen = 100, es sei denn, Sie haben einen großen Datensatz. Bei großen Datenmengen können Sie mit einer Chargengröße von 10 mit Epochen s / w 50 bis 100 arbeiten. Auch hier haben die oben genannten Zahlen für mich gut funktioniert.

fnatic9
quelle
5
Der Wert für die Chargengröße sollte (bevorzugt) in Potenzen von 2 sein. Stackoverflow.com/questions/44483233/…
Anurag Gupta
"Für große Datenmengen, Stapelgröße von 10 ..." ist das Verständnis nicht richtig, dass mehr die
Stapelgröße
-8

Epochen entsprechen Ihrem Wunsch, je nachdem, wann sich der Validierungsverlust nicht mehr weiter verbessert. So viel sollte Chargengröße sein:


# To define function to find batch size for training the model
# use this function to find out the batch size

    def FindBatchSize(model):
        """#model: model architecture, that is yet to be trained"""
        import os, sys, psutil, gc, tensorflow, keras
        import numpy as np
        from keras import backend as K
        BatchFound= 16

        try:
            total_params= int(model.count_params());    GCPU= "CPU"
            #find whether gpu is available
            try:
                if K.tensorflow_backend._get_available_gpus()== []:
                    GCPU= "CPU";    #CPU and Cuda9GPU
                else:
                    GCPU= "GPU"
            except:
                from tensorflow.python.client import device_lib;    #Cuda8GPU
                def get_available_gpus():
                    local_device_protos= device_lib.list_local_devices()
                    return [x.name for x in local_device_protos if x.device_type == 'GPU']
                if "gpu" not in str(get_available_gpus()).lower():
                    GCPU= "CPU"
                else:
                    GCPU= "GPU"

            #decide batch size on the basis of GPU availability and model complexity
            if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params <1000000):
                BatchFound= 64    
            if (os.cpu_count() <16) and (total_params <500000):
                BatchFound= 64  
            if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params <2000000) and (total_params >=1000000):
                BatchFound= 32      
            if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params >=2000000) and (total_params <10000000):
                BatchFound= 16  
            if (GCPU== "GPU") and (os.cpu_count() >15) and (total_params >=10000000):
                BatchFound= 8       
            if (os.cpu_count() <16) and (total_params >5000000):
                BatchFound= 8    
            if total_params >100000000:
                BatchFound= 1

        except:
            pass
        try:

            #find percentage of memory used
            memoryused= psutil.virtual_memory()
            memoryused= float(str(memoryused).replace(" ", "").split("percent=")[1].split(",")[0])
            if memoryused >75.0:
                BatchFound= 8
            if memoryused >85.0:
                BatchFound= 4
            if memoryused >90.0:
                BatchFound= 2
            if total_params >100000000:
                BatchFound= 1
            print("Batch Size:  "+ str(BatchFound));    gc.collect()
        except:
            pass

        memoryused= [];    total_params= [];    GCPU= "";
        del memoryused, total_params, GCPU;    gc.collect()
        return BatchFound
Anurag Gupta
quelle