2017-06-12 1 views
0

Ich versuche, den ETH Food-101-Datensatz mit Hilfe von Quescenet in Caffe2 zu klassifizieren. Mein Modell wird aus dem Modell Zoo importiert und I aus zwei Arten von Änderungen an dem Modell:Food101 SqueezeNet Caffe2 Anzahl der Iterationen

1) Ändern der Abmessungen der letzten Schicht 101 gibt

2) die Bilder aus der Datenbank haben, sind in NHWC Form und ich habe einfach die Abmessungen der Gewichte umgedreht. (Ich habe vor, dies zu ändern)

Der Datensatz Food101 hat 75.000 Bilder für das Training und ich verwende derzeit eine Losgröße von 128 und eine Lernrate von -0,01 mit einem Gamma von 0,999 und Schrittgröße von 1. Was ich bemerkte ist, dass die Genauigkeit für die ersten 2000 Iterationen des Netzwerks um 1/128 schwankte und dies etwa eine Stunde dauerte.

Ich habe alle Gewichte zu model.params hinzugefügt, damit sie während des Gradientenabfalls aktualisiert werden können (außer für Daten) und alle Gewichte als Xavier reinitialisiert und auf konstant gestellt werden. Ich würde erwarten, dass die Genauigkeit in den ersten hundert bis tausend Iterationen relativ schnell wächst und dann mit zunehmender Anzahl der Iterationen abnimmt. In meinem Fall bleibt das Lernen konstant um 0.

Wenn ich mir die Gradientendatei anschaue, finde ich, dass der Durchschnitt in der Größenordnung von 10^-6 mit einer Standardabweichung von 10^-7 liegt. Dies erklärt die langsame Lernrate, aber ich war nicht in der Lage, den Gradienten viel höher zu starten.

Dies sind die Gradienten Statistiken für die erste Faltung nach einigen Iterationen

Min  Max   Avg  Sdev 
-1.69821e-05 2.10922e-05 1.52149e-06 5.7707e-06 
-1.60263e-05 2.01478e-05 1.49323e-06 5.41754e-06 
-1.62501e-05 1.97764e-05 1.49046e-06 5.2904e-06 
-1.64293e-05 1.90508e-05 1.45681e-06 5.22742e-06 

Hier werden die Kernteile meines Codes sind:

#init_path is path to init_net protobuf 
#pred_path is path to pred_net protobuf 
def main(init_path, pred_path): 
    ws.ResetWorkspace() 
    data_folder = '/home/myhome/food101/' 
    #some debug code here 
    arg_scope = {"order":"NCHW"} 
    train_model = model_helper.ModelHelper(name="food101_train", arg_scope=arg_scope) 
    if not debug: 
      data, label = AddInput(
        train_model, batch_size=128, 
        db=os.path.join(data_folder, 'food101-train-nchw-leveldb'), 
        db_type='leveldb') 
    init_net_def, pred_net_def = update_squeeze_net(init_path, pred_path) 
    #print str(init_net_def) 
    train_model.param_init_net.AppendNet(core.Net(init_net_def)) 
    train_model.net.AppendNet(core.Net(pred_net_def)) 
    ws.RunNetOnce(train_model.param_init_net) 
    add_params(train_model, init_net_def) 
    AddTrainingOperators(train_model, 'softmaxout', 'label') 
    AddBookkeepingOperators(train_model) 

    ws.RunNetOnce(train_model.param_init_net) 
    if debug: 
      ws.FeedBlob('data', data) 
      ws.FeedBlob('label', label) 
    ws.CreateNet(train_model.net) 

    total_iters = 10000 
    accuracy = np.zeros(total_iters) 
    loss = np.zeros(total_iters) 
    # Now, we will manually run the network for 200 iterations. 
    for i in range(total_iters): 
      #try: 
      conv1_w = ws.FetchBlob('conv1_w') 
      print conv1_w[0][0] 
      ws.RunNet("food101_train") 
      #except RuntimeError: 
      #  print ws.FetchBlob('conv1').shape 
      #  print ws.FetchBlob('pool1').shape 
      #  print ws.FetchBlob('fire2/squeeze1x1_w').shape 
      #  print ws.FetchBlob('fire2/squeeze1x1_b').shape 
      #softmax = ws.FetchBlob('softmaxout') 
      #print softmax[i] 
      #print softmax[i][0][0] 
      #print softmax[i][0][:5] 
      #print softmax[64*i] 
      accuracy[i] = ws.FetchBlob('accuracy') 
      loss[i] = ws.FetchBlob('loss') 
      print accuracy[i], loss[i] 

Meine add_params Funktion initialisiert die Gewichte wie folgt

Ich finde, dass meine Verlustfunktion schwankt, wenn ich th. Verwende Das ganze Trainingssatz, aber wenn ich nur einen Stapel benutze und mehrmals darüber iteriere, finde ich, dass die Verlustfunktion nur sehr langsam abfällt.

Antwort

1

Während SqueezeNet 50x weniger Parameter als AlexNet hat, ist es immer noch ein sehr großes Netzwerk. The original paper erwähnt keine Trainingszeit, aber die SqueezeNet-basierte SQ benötigte 22 Stunden um mit zwei Titan X Grafikkarten zu trainieren - und das war mit einigen der vortrainierten Gewichte! Ich habe Ihren Code nicht im Detail behandelt, aber was Sie beschreiben, ist das erwartete Verhalten - Ihr Netzwerk kann auf dem einzelnen Stapel lernen, nur nicht so schnell, wie Sie es erwartet haben.

Ich schlage vor, so viele Gewichte wie möglich wiederzuverwenden, anstatt sie neu zu initialisieren, genau wie die Macher von SQ. Dies wird als Transfer-Lernen bezeichnet und funktioniert, da viele der Funktionen niedrigerer Ebene (Linien, Kurven, Grundformen) in einem Bild unabhängig vom Inhalt des Bilds gleich sind und die Gewichte für diese Ebenen nicht gespeichert werden um sie von Grund auf neu zu lernen.

+0

Danke für die Antwort Jeff. Das Problem entpuppte sich mit der Art und Weise, wie ich den Gradientenabfall berechnete. Ich hatte den Gewichtungssummenabstieg ihres Tutorials kopiert, aber nachdem ich etwas mehr gelesen habe, scheint es, dass für größere Netzwerke eine anspruchsvollere Form des Abstiegs benötigt wird. Der Wechsel zu Adam hat den Unterschied gemacht und der letzte Schicht-Trainingsvorschlag hat dir geholfen, das Training zu beschleunigen. Vielen Dank! – Shaun

Verwandte Themen