Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Über- und Unteranpassung

Ansicht auf TensorFlow.org Quelle auf GitHub anzeigen Notizbuch herunterladen

Wie immer verwendet der Code in diesem Beispiel die tf.keras API, über die Sie im TensorFlow Keras-Handbuch mehr erfahren können.

In beiden vorherigen Beispielen - Klassifizierung von Text und Vorhersage der Kraftstoffeffizienz - haben wir gesehen, dass die Genauigkeit unseres Modells in Bezug auf die Validierungsdaten nach dem Training für eine Reihe von Epochen ihren Höhepunkt erreichen und dann stagnieren oder abnehmen würde.

Mit anderen Worten, unser Modell würde sich übermäßig an die Trainingsdaten anpassen . Es ist wichtig zu lernen, wie man mit Überanpassung umgeht. Obwohl es oft möglich ist, eine hohe Genauigkeit des Trainingssatzes zu erzielen, möchten wir wirklich Modelle entwickeln, die sich gut auf einen Testsatz (oder Daten, die sie zuvor noch nicht gesehen haben) verallgemeinern lassen.

Das Gegenteil von Überanpassung ist Unteranpassung . Eine Unteranpassung tritt auf, wenn die Testdaten noch verbessert werden können. Dies kann verschiedene Gründe haben: Wenn das Modell nicht leistungsfähig genug ist, überreguliert ist oder einfach nicht lange genug trainiert wurde. Dies bedeutet, dass das Netzwerk die relevanten Muster in den Trainingsdaten nicht gelernt hat.

Wenn Sie jedoch zu lange trainieren, beginnt das Modell, Muster aus den Trainingsdaten, die sich nicht auf die Testdaten verallgemeinern lassen, zu überanpassen und zu lernen. Wir müssen ein Gleichgewicht finden. Es ist eine nützliche Fähigkeit, zu verstehen, wie man für eine angemessene Anzahl von Epochen trainiert, wie wir weiter unten untersuchen werden.

Um eine Überanpassung zu vermeiden, besteht die beste Lösung darin, vollständigere Trainingsdaten zu verwenden. Der Datensatz sollte den gesamten Bereich der Eingaben abdecken, die das Modell voraussichtlich verarbeiten wird. Zusätzliche Daten können nur dann nützlich sein, wenn sie neue und interessante Fälle abdecken.

Ein Modell, das auf vollständigeren Daten trainiert ist, lässt sich natürlich besser verallgemeinern. Wenn dies nicht mehr möglich ist, besteht die nächstbeste Lösung darin, Techniken wie die Regularisierung zu verwenden. Diese beschränken die Menge und Art der Informationen, die Ihr Modell speichern kann. Wenn es sich ein Netzwerk nur leisten kann, eine kleine Anzahl von Mustern zu speichern, wird es durch den Optimierungsprozess gezwungen, sich auf die bekanntesten Muster zu konzentrieren, die eine bessere Chance haben, gut zu verallgemeinern.

In diesem Notizbuch werden wir einige gängige Regularisierungstechniken untersuchen und sie verwenden, um ein Klassifizierungsmodell zu verbessern.

Konfiguration

Importieren Sie vor dem Start die erforderlichen Pakete:

import tensorflow as tf

from tensorflow.keras import layers
from tensorflow.keras import regularizers

print(tf.__version__)
2.3.0

!pip install -q git+https://github.com/tensorflow/docs

import tensorflow_docs as tfdocs
import tensorflow_docs.modeling
import tensorflow_docs.plots
WARNING: You are using pip version 20.2.2; however, version 20.2.3 is available.
You should consider upgrading via the '/tmpfs/src/tf_docs_env/bin/python -m pip install --upgrade pip' command.

from  IPython import display
from matplotlib import pyplot as plt

import numpy as np

import pathlib
import shutil
import tempfile

logdir = pathlib.Path(tempfile.mkdtemp())/"tensorboard_logs"
shutil.rmtree(logdir, ignore_errors=True)

Der Higgs-Datensatz

Das Ziel dieses Tutorials ist nicht die Teilchenphysik, also bleiben Sie nicht bei den Details des Datensatzes. Es enthält 11 000 000 Beispiele mit jeweils 28 Merkmalen und eine Bezeichnung für eine binäre Klasse.

gz = tf.keras.utils.get_file('HIGGS.csv.gz', 'http://mlphysics.ics.uci.edu/data/higgs/HIGGS.csv.gz')
Downloading data from http://mlphysics.ics.uci.edu/data/higgs/HIGGS.csv.gz
2816409600/2816407858 [==============================] - 195s 0us/step

FEATURES = 28

Mit der Klasse tf.data.experimental.CsvDataset können tf.data.experimental.CsvDataset Datensätze ohne Zwischendekomprimierungsschritt direkt aus einer gzip-Datei gelesen werden.

ds = tf.data.experimental.CsvDataset(gz,[float(),]*(FEATURES+1), compression_type="GZIP")

Diese CSV-Reader-Klasse gibt eine Liste von Skalaren für jeden Datensatz zurück. Die folgende Funktion packt diese Liste von Skalaren in ein Paar (feature_vector, label) um.

def pack_row(*row):
  label = row[0]
  features = tf.stack(row[1:],1)
  return features, label

TensorFlow ist am effizientesten, wenn große Datenmengen verarbeitet werden.

Anstatt also jede Zeile einzeln von Umpacken einen neuen machen Dataset , die Chargen von 10000-Beispiele nimmt, gilt die pack_row Funktion zu jeder Charge und teilt sich dann die Chargen in einzelne Datensätze nach oben zurück:

packed_ds = ds.batch(10000).map(pack_row).unbatch()

Schauen Sie sich einige der Datensätze dieser neuen packed_ds .

Die Funktionen sind nicht perfekt normalisiert, dies reicht jedoch für dieses Lernprogramm aus.

for features,label in packed_ds.batch(1000).take(1):
  print(features[0])
  plt.hist(features.numpy().flatten(), bins = 101)
tf.Tensor(
[ 0.8692932  -0.6350818   0.22569026  0.32747006 -0.6899932   0.75420225
 -0.24857314 -1.0920639   0.          1.3749921  -0.6536742   0.9303491
  1.1074361   1.1389043  -1.5781983  -1.0469854   0.          0.65792954
 -0.01045457 -0.04576717  3.1019614   1.35376     0.9795631   0.97807616
  0.92000484  0.72165745  0.98875093  0.87667835], shape=(28,), dtype=float32)

png

Um dieses Tutorial relativ kurz zu halten, verwenden Sie nur die ersten 1000 Proben zur Validierung und die nächsten 10 000 zur Schulung:

N_VALIDATION = int(1e3)
N_TRAIN = int(1e4)
BUFFER_SIZE = int(1e4)
BATCH_SIZE = 500
STEPS_PER_EPOCH = N_TRAIN//BATCH_SIZE

Die Methoden Dataset.skip und Dataset.take machen dies einfach.

Verwenden Sie gleichzeitig die Dataset.cache Methode, um sicherzustellen, dass der Loader die Daten in jeder Epoche nicht erneut aus der Datei lesen muss:

validate_ds = packed_ds.take(N_VALIDATION).cache()
train_ds = packed_ds.skip(N_VALIDATION).take(N_TRAIN).cache()
train_ds
<CacheDataset shapes: ((28,), ()), types: (tf.float32, tf.float32)>

Diese Datensätze geben einzelne Beispiele zurück. Verwenden Sie die .batch Methode, um .batch mit einer geeigneten Größe für das Training zu erstellen. .shuffle .repeat dem .shuffle auch daran, den Trainingssatz zu .shuffle und zu .repeat .

validate_ds = validate_ds.batch(BATCH_SIZE)
train_ds = train_ds.shuffle(BUFFER_SIZE).repeat().batch(BATCH_SIZE)

Überanpassung demonstrieren

Der einfachste Weg, eine Überanpassung zu verhindern, besteht darin, mit einem kleinen Modell zu beginnen: Ein Modell mit einer kleinen Anzahl lernbarer Parameter (die durch die Anzahl der Schichten und die Anzahl der Einheiten pro Schicht bestimmt wird). Beim Deep Learning wird die Anzahl der lernbaren Parameter in einem Modell häufig als "Kapazität" des Modells bezeichnet.

Intuitiv hat ein Modell mit mehr Parametern mehr "Speicherkapazität" und kann daher leicht eine perfekte wörterbuchähnliche Zuordnung zwischen Trainingsbeispielen und ihren Zielen erlernen, eine Zuordnung ohne Verallgemeinerungskraft, aber dies wäre nutzlos, wenn Vorhersagen getroffen werden auf zuvor nicht sichtbaren Daten.

Denken Sie immer daran: Deep-Learning-Modelle passen sich in der Regel gut an die Trainingsdaten an, aber die eigentliche Herausforderung ist die Verallgemeinerung, nicht die Anpassung.

Wenn das Netzwerk jedoch nur über begrenzte Speicherressourcen verfügt, kann es die Zuordnung nicht so einfach erlernen. Um den Verlust zu minimieren, muss es komprimierte Darstellungen lernen, die mehr Vorhersagekraft haben. Wenn Sie Ihr Modell zu klein machen, kann es gleichzeitig nur schwer an die Trainingsdaten angepasst werden. Es besteht ein Gleichgewicht zwischen "zu viel Kapazität" und "zu wenig Kapazität".

Leider gibt es keine magische Formel, um die richtige Größe oder Architektur Ihres Modells zu bestimmen (in Bezug auf die Anzahl der Ebenen oder die richtige Größe für jede Ebene). Sie müssen mit einer Reihe verschiedener Architekturen experimentieren.

Um eine geeignete Modellgröße zu finden, beginnen Sie am besten mit relativ wenigen Ebenen und Parametern. Erhöhen Sie dann die Größe der Ebenen oder fügen Sie neue Ebenen hinzu, bis sich die Rendite des Validierungsverlusts verringert.

Beginnen Sie mit einem einfachen Modell, das nur layers.Dense verwendet. layers.Dense als Basis, erstellen Sie dann größere Versionen und vergleichen Sie diese.

Trainingsverfahren

Viele Modelle trainieren besser, wenn Sie die Lernrate während des Trainings schrittweise reduzieren. Verwenden Sie optimizers.schedules , um die Lernrate im Laufe der Zeit zu reduzieren:

lr_schedule = tf.keras.optimizers.schedules.InverseTimeDecay(
  0.001,
  decay_steps=STEPS_PER_EPOCH*1000,
  decay_rate=1,
  staircase=False)

def get_optimizer():
  return tf.keras.optimizers.Adam(lr_schedule)

Der obige Code legt einen schedules.InverseTimeDecay InverseTimeDecay verringert die Lernrate hyperbolisch auf die Hälfte der Basisrate bei 1000 Epochen, 1/3 bei 2000 Epochen und so weiter.

step = np.linspace(0,100000)
lr = lr_schedule(step)
plt.figure(figsize = (8,6))
plt.plot(step/STEPS_PER_EPOCH, lr)
plt.ylim([0,max(plt.ylim())])
plt.xlabel('Epoch')
_ = plt.ylabel('Learning Rate')

png

Jedes Modell in diesem Tutorial verwendet dieselbe Trainingskonfiguration. Richten Sie diese also wiederverwendbar ein, beginnend mit der Liste der Rückrufe.

Das Training für dieses Tutorial dauert viele kurze Epochen. Um das Protokollierungsrauschen zu reduzieren, verwenden Sie tfdocs.EpochDots das einfach a druckt . für jede Epoche und einen vollständigen Satz von Metriken alle 100 Epochen.

Als nächstes schließen Sie callbacks.EarlyStopping , um lange und unnötige Trainingszeiten zu vermeiden. Beachten Sie, dass dieser Rückruf so eingestellt ist, dass er die val_binary_crossentropy und nicht den val_loss . Dieser Unterschied wird später wichtig sein.

Verwenden Sie callbacks.TensorBoard , um TensorBoard-Protokolle für das Training zu erstellen.

def get_callbacks(name):
  return [
    tfdocs.modeling.EpochDots(),
    tf.keras.callbacks.EarlyStopping(monitor='val_binary_crossentropy', patience=200),
    tf.keras.callbacks.TensorBoard(logdir/name),
  ]

In ähnlicher Weise verwendet jedes Modell dieselben Model.compile und Model.fit Einstellungen:

def compile_and_fit(model, name, optimizer=None, max_epochs=10000):
  if optimizer is None:
    optimizer = get_optimizer()
  model.compile(optimizer=optimizer,
                loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
                metrics=[
                  tf.keras.losses.BinaryCrossentropy(
                      from_logits=True, name='binary_crossentropy'),
                  'accuracy'])

  model.summary()

  history = model.fit(
    train_ds,
    steps_per_epoch = STEPS_PER_EPOCH,
    epochs=max_epochs,
    validation_data=validate_ds,
    callbacks=get_callbacks(name),
    verbose=0)
  return history

Winziges Modell

Beginnen Sie mit dem Training eines Modells:

tiny_model = tf.keras.Sequential([
    layers.Dense(16, activation='elu', input_shape=(FEATURES,)),
    layers.Dense(1)
])
size_histories = {}
size_histories['Tiny'] = compile_and_fit(tiny_model, 'sizes/Tiny')
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 16)                464       
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 17        
=================================================================
Total params: 481
Trainable params: 481
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/summary_ops_v2.py:1277: stop (from tensorflow.python.eager.profiler) is deprecated and will be removed after 2020-07-01.
Instructions for updating:
use `tf.profiler.experimental.stop` instead.
WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0030s vs `on_train_batch_end` time: 0.0237s). Check your callbacks.

Epoch: 0, accuracy:0.4851,  binary_crossentropy:0.7694,  loss:0.7694,  val_accuracy:0.5020,  val_binary_crossentropy:0.7430,  val_loss:0.7430,  
....................................................................................................
Epoch: 100, accuracy:0.5922,  binary_crossentropy:0.6288,  loss:0.6288,  val_accuracy:0.5730,  val_binary_crossentropy:0.6331,  val_loss:0.6331,  
....................................................................................................
Epoch: 200, accuracy:0.6069,  binary_crossentropy:0.6215,  loss:0.6215,  val_accuracy:0.5820,  val_binary_crossentropy:0.6277,  val_loss:0.6277,  
....................................................................................................
Epoch: 300, accuracy:0.6131,  binary_crossentropy:0.6165,  loss:0.6165,  val_accuracy:0.6040,  val_binary_crossentropy:0.6208,  val_loss:0.6208,  
....................................................................................................
Epoch: 400, accuracy:0.6213,  binary_crossentropy:0.6111,  loss:0.6111,  val_accuracy:0.5980,  val_binary_crossentropy:0.6179,  val_loss:0.6179,  
....................................................................................................
Epoch: 500, accuracy:0.6344,  binary_crossentropy:0.6045,  loss:0.6045,  val_accuracy:0.6250,  val_binary_crossentropy:0.6092,  val_loss:0.6092,  
....................................................................................................
Epoch: 600, accuracy:0.6408,  binary_crossentropy:0.5985,  loss:0.5985,  val_accuracy:0.6170,  val_binary_crossentropy:0.6068,  val_loss:0.6068,  
....................................................................................................
Epoch: 700, accuracy:0.6454,  binary_crossentropy:0.5941,  loss:0.5941,  val_accuracy:0.6380,  val_binary_crossentropy:0.6033,  val_loss:0.6033,  
....................................................................................................
Epoch: 800, accuracy:0.6571,  binary_crossentropy:0.5907,  loss:0.5907,  val_accuracy:0.6350,  val_binary_crossentropy:0.6023,  val_loss:0.6023,  
....................................................................................................
Epoch: 900, accuracy:0.6568,  binary_crossentropy:0.5879,  loss:0.5879,  val_accuracy:0.6390,  val_binary_crossentropy:0.6022,  val_loss:0.6022,  
....................................................................................................
Epoch: 1000, accuracy:0.6592,  binary_crossentropy:0.5860,  loss:0.5860,  val_accuracy:0.6410,  val_binary_crossentropy:0.6006,  val_loss:0.6006,  
....................................................................................................
Epoch: 1100, accuracy:0.6674,  binary_crossentropy:0.5833,  loss:0.5833,  val_accuracy:0.6310,  val_binary_crossentropy:0.6020,  val_loss:0.6020,  
....................................................................................................
Epoch: 1200, accuracy:0.6681,  binary_crossentropy:0.5814,  loss:0.5814,  val_accuracy:0.6300,  val_binary_crossentropy:0.6013,  val_loss:0.6013,  
....................................................................................................
Epoch: 1300, accuracy:0.6711,  binary_crossentropy:0.5798,  loss:0.5798,  val_accuracy:0.6430,  val_binary_crossentropy:0.5985,  val_loss:0.5985,  
....................................................................................................
Epoch: 1400, accuracy:0.6723,  binary_crossentropy:0.5781,  loss:0.5781,  val_accuracy:0.6440,  val_binary_crossentropy:0.5984,  val_loss:0.5984,  
....................................................................................................
Epoch: 1500, accuracy:0.6723,  binary_crossentropy:0.5773,  loss:0.5773,  val_accuracy:0.6490,  val_binary_crossentropy:0.5969,  val_loss:0.5969,  
....................................................................................................
Epoch: 1600, accuracy:0.6710,  binary_crossentropy:0.5762,  loss:0.5762,  val_accuracy:0.6620,  val_binary_crossentropy:0.5953,  val_loss:0.5953,  
....................................................................................................
Epoch: 1700, accuracy:0.6757,  binary_crossentropy:0.5744,  loss:0.5744,  val_accuracy:0.6510,  val_binary_crossentropy:0.5956,  val_loss:0.5956,  
....................................................................................................
Epoch: 1800, accuracy:0.6771,  binary_crossentropy:0.5734,  loss:0.5734,  val_accuracy:0.6560,  val_binary_crossentropy:0.5947,  val_loss:0.5947,  
....................................................................................................
Epoch: 1900, accuracy:0.6780,  binary_crossentropy:0.5723,  loss:0.5723,  val_accuracy:0.6550,  val_binary_crossentropy:0.5942,  val_loss:0.5942,  
....................................................................................................
Epoch: 2000, accuracy:0.6794,  binary_crossentropy:0.5716,  loss:0.5716,  val_accuracy:0.6590,  val_binary_crossentropy:0.5930,  val_loss:0.5930,  
....................................................................................................
Epoch: 2100, accuracy:0.6777,  binary_crossentropy:0.5707,  loss:0.5707,  val_accuracy:0.6560,  val_binary_crossentropy:0.5938,  val_loss:0.5938,  
....................................................................................................
Epoch: 2200, accuracy:0.6817,  binary_crossentropy:0.5699,  loss:0.5699,  val_accuracy:0.6480,  val_binary_crossentropy:0.5942,  val_loss:0.5942,  
....................................................................................................
Epoch: 2300, accuracy:0.6796,  binary_crossentropy:0.5696,  loss:0.5696,  val_accuracy:0.6540,  val_binary_crossentropy:0.5922,  val_loss:0.5922,  
....................................................................................................
Epoch: 2400, accuracy:0.6823,  binary_crossentropy:0.5695,  loss:0.5695,  val_accuracy:0.6530,  val_binary_crossentropy:0.5919,  val_loss:0.5919,  
....................................................................................................
Epoch: 2500, accuracy:0.6848,  binary_crossentropy:0.5688,  loss:0.5688,  val_accuracy:0.6530,  val_binary_crossentropy:0.5943,  val_loss:0.5943,  
....................................................................................................
Epoch: 2600, accuracy:0.6837,  binary_crossentropy:0.5683,  loss:0.5683,  val_accuracy:0.6580,  val_binary_crossentropy:0.5920,  val_loss:0.5920,  
....................................................................................................
Epoch: 2700, accuracy:0.6867,  binary_crossentropy:0.5687,  loss:0.5687,  val_accuracy:0.6560,  val_binary_crossentropy:0.5938,  val_loss:0.5938,  
....................................................................................................
Epoch: 2800, accuracy:0.6874,  binary_crossentropy:0.5671,  loss:0.5671,  val_accuracy:0.6550,  val_binary_crossentropy:0.5922,  val_loss:0.5922,  
....................................................................................................
Epoch: 2900, accuracy:0.6814,  binary_crossentropy:0.5666,  loss:0.5666,  val_accuracy:0.6590,  val_binary_crossentropy:0.5907,  val_loss:0.5907,  
.......................................................

Überprüfen Sie nun, wie das Modell funktioniert hat:

plotter = tfdocs.plots.HistoryPlotter(metric = 'binary_crossentropy', smoothing_std=10)
plotter.plot(size_histories)
plt.ylim([0.5, 0.7])
(0.5, 0.7)

png

Kleines Modell

Um zu sehen, ob Sie die Leistung des kleinen Modells übertreffen können, trainieren Sie nach und nach einige größere Modelle.

Probieren Sie zwei versteckte Ebenen mit jeweils 16 Einheiten aus:

small_model = tf.keras.Sequential([
    # `input_shape` is only required here so that `.summary` works.
    layers.Dense(16, activation='elu', input_shape=(FEATURES,)),
    layers.Dense(16, activation='elu'),
    layers.Dense(1)
])
size_histories['Small'] = compile_and_fit(small_model, 'sizes/Small')
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_2 (Dense)              (None, 16)                464       
_________________________________________________________________
dense_3 (Dense)              (None, 16)                272       
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 17        
=================================================================
Total params: 753
Trainable params: 753
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0034s vs `on_train_batch_end` time: 0.0481s). Check your callbacks.

Epoch: 0, accuracy:0.4760,  binary_crossentropy:0.7078,  loss:0.7078,  val_accuracy:0.4700,  val_binary_crossentropy:0.6948,  val_loss:0.6948,  
....................................................................................................
Epoch: 100, accuracy:0.6241,  binary_crossentropy:0.6134,  loss:0.6134,  val_accuracy:0.5950,  val_binary_crossentropy:0.6196,  val_loss:0.6196,  
....................................................................................................
Epoch: 200, accuracy:0.6435,  binary_crossentropy:0.5975,  loss:0.5975,  val_accuracy:0.6290,  val_binary_crossentropy:0.6116,  val_loss:0.6116,  
....................................................................................................
Epoch: 300, accuracy:0.6636,  binary_crossentropy:0.5827,  loss:0.5827,  val_accuracy:0.6310,  val_binary_crossentropy:0.6020,  val_loss:0.6020,  
....................................................................................................
Epoch: 400, accuracy:0.6742,  binary_crossentropy:0.5730,  loss:0.5730,  val_accuracy:0.6500,  val_binary_crossentropy:0.5945,  val_loss:0.5945,  
....................................................................................................
Epoch: 500, accuracy:0.6822,  binary_crossentropy:0.5670,  loss:0.5670,  val_accuracy:0.6470,  val_binary_crossentropy:0.5919,  val_loss:0.5919,  
....................................................................................................
Epoch: 600, accuracy:0.6864,  binary_crossentropy:0.5631,  loss:0.5631,  val_accuracy:0.6510,  val_binary_crossentropy:0.5909,  val_loss:0.5909,  
....................................................................................................
Epoch: 700, accuracy:0.6928,  binary_crossentropy:0.5596,  loss:0.5596,  val_accuracy:0.6600,  val_binary_crossentropy:0.5910,  val_loss:0.5910,  
....................................................................................................
Epoch: 800, accuracy:0.6965,  binary_crossentropy:0.5564,  loss:0.5564,  val_accuracy:0.6620,  val_binary_crossentropy:0.5898,  val_loss:0.5898,  
....................................................................................................
Epoch: 900, accuracy:0.7008,  binary_crossentropy:0.5544,  loss:0.5544,  val_accuracy:0.6480,  val_binary_crossentropy:0.5921,  val_loss:0.5921,  
...............................................

Mittleres Modell

Versuchen Sie nun 3 versteckte Ebenen mit jeweils 64 Einheiten:

medium_model = tf.keras.Sequential([
    layers.Dense(64, activation='elu', input_shape=(FEATURES,)),
    layers.Dense(64, activation='elu'),
    layers.Dense(64, activation='elu'),
    layers.Dense(1)
])

Und trainieren Sie das Modell mit denselben Daten:

size_histories['Medium']  = compile_and_fit(medium_model, "sizes/Medium")
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_5 (Dense)              (None, 64)                1856      
_________________________________________________________________
dense_6 (Dense)              (None, 64)                4160      
_________________________________________________________________
dense_7 (Dense)              (None, 64)                4160      
_________________________________________________________________
dense_8 (Dense)              (None, 1)                 65        
=================================================================
Total params: 10,241
Trainable params: 10,241
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0037s vs `on_train_batch_end` time: 0.0511s). Check your callbacks.

Epoch: 0, accuracy:0.4852,  binary_crossentropy:0.6982,  loss:0.6982,  val_accuracy:0.4830,  val_binary_crossentropy:0.6815,  val_loss:0.6815,  
....................................................................................................
Epoch: 100, accuracy:0.7123,  binary_crossentropy:0.5315,  loss:0.5315,  val_accuracy:0.6540,  val_binary_crossentropy:0.5983,  val_loss:0.5983,  
....................................................................................................
Epoch: 200, accuracy:0.7796,  binary_crossentropy:0.4328,  loss:0.4328,  val_accuracy:0.6590,  val_binary_crossentropy:0.6763,  val_loss:0.6763,  
...................................................

Großes Modell

Als Übung können Sie ein noch größeres Modell erstellen und sehen, wie schnell die Überanpassung beginnt. Als nächstes fügen wir diesem Benchmark ein Netzwerk hinzu, das viel mehr Kapazität hat, weit mehr als das Problem rechtfertigen würde:

large_model = tf.keras.Sequential([
    layers.Dense(512, activation='elu', input_shape=(FEATURES,)),
    layers.Dense(512, activation='elu'),
    layers.Dense(512, activation='elu'),
    layers.Dense(512, activation='elu'),
    layers.Dense(1)
])

Trainieren Sie das Modell erneut mit denselben Daten:

size_histories['large'] = compile_and_fit(large_model, "sizes/large")
Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_9 (Dense)              (None, 512)               14848     
_________________________________________________________________
dense_10 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_11 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_12 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_13 (Dense)             (None, 1)                 513       
=================================================================
Total params: 803,329
Trainable params: 803,329
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0038s vs `on_train_batch_end` time: 0.0571s). Check your callbacks.

Epoch: 0, accuracy:0.5119,  binary_crossentropy:0.7993,  loss:0.7993,  val_accuracy:0.4630,  val_binary_crossentropy:0.7125,  val_loss:0.7125,  
....................................................................................................
Epoch: 100, accuracy:1.0000,  binary_crossentropy:0.0021,  loss:0.0021,  val_accuracy:0.6640,  val_binary_crossentropy:1.8146,  val_loss:1.8146,  
....................................................................................................
Epoch: 200, accuracy:1.0000,  binary_crossentropy:0.0001,  loss:0.0001,  val_accuracy:0.6630,  val_binary_crossentropy:2.4702,  val_loss:2.4702,  
............................

Zeichnen Sie die Trainings- und Validierungsverluste auf

Die durchgezogenen Linien zeigen den Trainingsverlust und die gestrichelten Linien zeigen den Validierungsverlust (denken Sie daran: Ein geringerer Validierungsverlust zeigt ein besseres Modell an).

Wenn Sie ein größeres Modell bauen, erhalten Sie mehr Leistung. Wenn diese Leistung jedoch nicht eingeschränkt wird, kann es leicht zu einer Anpassung an das Trainingsset kommen.

In diesem Beispiel kann normalerweise nur das "Tiny" -Modell eine Überanpassung insgesamt vermeiden, und jedes der größeren Modelle passt die Daten schneller an. Dies wird für das "large" Modell so schwerwiegend, dass Sie den Plot auf eine Protokollskala umstellen müssen, um wirklich zu sehen, was passiert.

Dies ist offensichtlich, wenn Sie die Validierungsmetriken zeichnen und mit den Trainingsmetriken vergleichen.

  • Es ist normal, dass es einen kleinen Unterschied gibt.
  • Wenn sich beide Metriken in die gleiche Richtung bewegen, ist alles in Ordnung.
  • Wenn die Validierungsmetrik zu stagnieren beginnt, während sich die Trainingsmetrik weiter verbessert, sind Sie wahrscheinlich kurz vor einer Überanpassung.
  • Wenn die Validierungsmetrik in die falsche Richtung geht, passt das Modell eindeutig über.
plotter.plot(size_histories)
a = plt.xscale('log')
plt.xlim([5, max(plt.xlim())])
plt.ylim([0.5, 0.7])
plt.xlabel("Epochs [Log Scale]")
Text(0.5, 0, 'Epochs [Log Scale]')

png

Ansicht in TensorBoard

Diese Modelle haben alle während des Trainings TensorBoard-Protokolle geschrieben.

Öffnen Sie einen eingebetteten TensorBoard-Viewer in einem Notizbuch:


# Load the TensorBoard notebook extension
%load_ext tensorboard

# Open an embedded TensorBoard viewer
%tensorboard --logdir {logdir}/sizes

Sie können die Ergebnisse einer früheren Ausführung dieses Notizbuchs auf TensorBoard.dev anzeigen .

TensorBoard.dev ist eine verwaltete Erfahrung zum Hosten, Verfolgen und Teilen von ML-Experimenten mit allen.

Es ist auch in einem <iframe> :

display.IFrame(
    src="https://tensorboard.dev/experiment/vW7jmmF9TmKmy3rbheMQpw/#scalars&_smoothingWeight=0.97",
    width="100%", height="800px")

Wenn Sie TensorBoard-Ergebnisse freigeben möchten, können Sie die Protokolle auf TensorBoard.dev hochladen, indem Sie Folgendes in eine Codezelle kopieren.

tensorboard dev upload --logdir  {logdir}/sizes

Strategien zur Vermeidung von Überanpassung

Bevor Sie mit dem Inhalt dieses Abschnitts beginnen, kopieren Sie die Trainingsprotokolle aus dem obigen "Tiny" -Modell, um sie als Vergleichsgrundlage zu verwenden.

shutil.rmtree(logdir/'regularizers/Tiny', ignore_errors=True)
shutil.copytree(logdir/'sizes/Tiny', logdir/'regularizers/Tiny')
PosixPath('/tmp/tmpnnkr5005/tensorboard_logs/regularizers/Tiny')
regularizer_histories = {}
regularizer_histories['Tiny'] = size_histories['Tiny']

Gewichtsregulierung hinzufügen

Sie kennen vielleicht das Razor-Prinzip von Occam: Bei zwei Erklärungen für etwas ist die Erklärung, die am wahrscheinlichsten richtig ist, die "einfachste", die die geringste Menge an Annahmen macht. Dies gilt auch für Modelle, die von neuronalen Netzen gelernt werden: Bei einigen Trainingsdaten und einer Netzwerkarchitektur gibt es mehrere Sätze von Gewichtungswerten (mehrere Modelle), die die Daten erklären könnten, und einfachere Modelle passen weniger wahrscheinlich als komplexe.

Ein "einfaches Modell" ist in diesem Zusammenhang ein Modell, bei dem die Verteilung der Parameterwerte weniger Entropie aufweist (oder ein Modell mit insgesamt weniger Parametern, wie wir im obigen Abschnitt gesehen haben). Ein üblicher Weg, um eine Überanpassung zu verringern, besteht darin, die Komplexität eines Netzwerks einzuschränken, indem seine Gewichte nur gezwungen werden, kleine Werte anzunehmen, wodurch die Verteilung der Gewichtswerte "regelmäßiger" wird. Dies wird als "Gewichtsregulierung" bezeichnet und erfolgt durch Hinzufügen von Kosten, die mit großen Gewichten verbunden sind, zur Verlustfunktion des Netzwerks. Diese Kosten gibt es in zwei Varianten:

  • L1-Regularisierung , bei der die hinzugefügten Kosten proportional zum absoluten Wert der Gewichtskoeffizienten sind (dh zu der sogenannten "L1-Norm" der Gewichte).

  • L2-Regularisierung , bei der die hinzugefügten Kosten proportional zum Quadrat des Wertes der Gewichtskoeffizienten sind (dh zu der sogenannten quadratischen "L2-Norm" der Gewichte). Die L2-Regularisierung wird im Zusammenhang mit neuronalen Netzen auch als Gewichtsabfall bezeichnet. Lassen Sie sich nicht von dem anderen Namen verwirren: Der Gewichtsabfall entspricht mathematisch genau der L2-Regularisierung.

Die L1-Regularisierung drückt die Gewichte gegen genau Null, was ein spärliches Modell fördert. Die L2-Regularisierung bestraft die Gewichtungsparameter, ohne sie spärlich zu machen, da die Strafe für kleine Gewichte auf Null geht. Ein Grund, warum L2 häufiger ist.

In tf.keras wird die Weight-Regularisierung hinzugefügt, indem Weight-Regularizer-Instanzen als Schlüsselwortargumente an Layer übergeben werden. Fügen wir jetzt die L2-Gewichtsregulierung hinzu.

l2_model = tf.keras.Sequential([
    layers.Dense(512, activation='elu',
                 kernel_regularizer=regularizers.l2(0.001),
                 input_shape=(FEATURES,)),
    layers.Dense(512, activation='elu',
                 kernel_regularizer=regularizers.l2(0.001)),
    layers.Dense(512, activation='elu',
                 kernel_regularizer=regularizers.l2(0.001)),
    layers.Dense(512, activation='elu',
                 kernel_regularizer=regularizers.l2(0.001)),
    layers.Dense(1)
])

regularizer_histories['l2'] = compile_and_fit(l2_model, "regularizers/l2")
Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_14 (Dense)             (None, 512)               14848     
_________________________________________________________________
dense_15 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_16 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_17 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_18 (Dense)             (None, 1)                 513       
=================================================================
Total params: 803,329
Trainable params: 803,329
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0039s vs `on_train_batch_end` time: 0.0601s). Check your callbacks.

Epoch: 0, accuracy:0.5034,  binary_crossentropy:0.7595,  loss:2.2567,  val_accuracy:0.5360,  val_binary_crossentropy:0.6737,  val_loss:2.0767,  
....................................................................................................
Epoch: 100, accuracy:0.6562,  binary_crossentropy:0.5978,  loss:0.6212,  val_accuracy:0.6240,  val_binary_crossentropy:0.5912,  val_loss:0.6144,  
....................................................................................................
Epoch: 200, accuracy:0.6610,  binary_crossentropy:0.5914,  loss:0.6147,  val_accuracy:0.6480,  val_binary_crossentropy:0.5813,  val_loss:0.6055,  
....................................................................................................
Epoch: 300, accuracy:0.6794,  binary_crossentropy:0.5768,  loss:0.5998,  val_accuracy:0.6730,  val_binary_crossentropy:0.5780,  val_loss:0.6009,  
....................................................................................................
Epoch: 400, accuracy:0.6843,  binary_crossentropy:0.5685,  loss:0.5914,  val_accuracy:0.6760,  val_binary_crossentropy:0.5798,  val_loss:0.6027,  
....................................................................................................
Epoch: 500, accuracy:0.6971,  binary_crossentropy:0.5602,  loss:0.5856,  val_accuracy:0.6600,  val_binary_crossentropy:0.5855,  val_loss:0.6107,  
................................................................................................

l2(0.001) bedeutet , dass jeder Koeffizient der Wichtungsmatrix in der Schicht hinzuzufügen , wird 0.001 * weight_coefficient_value**2 bis zum Totalverlust des Netzes.

Deshalb überwachen wir die binary_crossentropy direkt. Weil diese Regularisierungskomponente nicht eingemischt ist.

Das gleiche "Large" Modell mit einer L2 Regularisierungsstrafe schneidet also viel besser ab:

plotter.plot(regularizer_histories)
plt.ylim([0.5, 0.7])
(0.5, 0.7)

png

Wie Sie sehen können, ist das regulierte Modell "L2" jetzt viel wettbewerbsfähiger als das Modell "Tiny" . Dieses "L2" -Modell ist auch viel widerstandsfähiger gegen Überanpassung als das "Large" -Modell, auf dem es basiert, obwohl es die gleiche Anzahl von Parametern aufweist.

Mehr Info

Bei dieser Art der Regularisierung sind zwei wichtige Dinge zu beachten.

Erstens: Wenn Sie Ihre eigene Trainingsschleife schreiben, müssen Sie das Modell unbedingt nach seinen Regularisierungsverlusten fragen.

result = l2_model(features)
regularization_loss=tf.add_n(l2_model.losses)

Zweitens: Bei dieser Implementierung werden die Gewichtsstrafen zum Verlust des Modells addiert und anschließend ein Standardoptimierungsverfahren angewendet.

Es gibt einen zweiten Ansatz, bei dem der Optimierer stattdessen nur für den Rohverlust ausgeführt wird. Während der Anwendung des berechneten Schritts wendet der Optimierer dann auch einen gewissen Gewichtsabfall an. Dieser "entkoppelte Gewichtsabfall" tritt bei Optimierern wie optimizers.FTRL und optimizers.AdamW .

Dropout hinzufügen

Dropout ist eine der effektivsten und am häufigsten verwendeten Regularisierungstechniken für neuronale Netze, die von Hinton und seinen Studenten an der Universität von Toronto entwickelt wurde.

Die intuitive Erklärung für Dropout lautet: Da sich einzelne Knoten im Netzwerk nicht auf die Ausgabe der anderen verlassen können, muss jeder Knoten Funktionen ausgeben, die für sich nützlich sind.

Dropout, das auf eine Ebene angewendet wird, besteht aus dem zufälligen "Herausfallen" (dh auf Null gesetzt) ​​einer Reihe von Ausgabemerkmalen der Ebene während des Trainings. Angenommen, eine bestimmte Schicht hätte normalerweise während des Trainings einen Vektor [0,2, 0,5, 1,3, 0,8, 1,1] für eine bestimmte Eingabestichprobe zurückgegeben. Nach dem Anwenden von Dropout hat dieser Vektor einige zufällig verteilte Nulleinträge, z. B. [0, 0,5, 1,3, 0, 1,1].

Die "Abbrecherquote" ist der Bruchteil der Merkmale, die auf Null gesetzt werden. Sie wird normalerweise zwischen 0,2 und 0,5 eingestellt. Zur Testzeit fallen keine Einheiten aus, sondern die Ausgabewerte der Ebene werden um einen Faktor verkleinert, der der Abbrecherquote entspricht, um die Tatsache auszugleichen, dass mehr Einheiten aktiv sind als zur Trainingszeit.

In tf.keras Sie Dropout in einem Netzwerk über die Dropout-Ebene einführen, die unmittelbar zuvor auf die Ausgabe der Ebene angewendet wird.

Fügen wir zwei Dropout-Ebenen in unser Netzwerk ein, um zu sehen, wie gut sie die Überanpassung reduzieren:

dropout_model = tf.keras.Sequential([
    layers.Dense(512, activation='elu', input_shape=(FEATURES,)),
    layers.Dropout(0.5),
    layers.Dense(512, activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(512, activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(512, activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(1)
])

regularizer_histories['dropout'] = compile_and_fit(dropout_model, "regularizers/dropout")
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_19 (Dense)             (None, 512)               14848     
_________________________________________________________________
dropout (Dropout)            (None, 512)               0         
_________________________________________________________________
dense_20 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_21 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_22 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_3 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_23 (Dense)             (None, 1)                 513       
=================================================================
Total params: 803,329
Trainable params: 803,329
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0045s vs `on_train_batch_end` time: 0.0648s). Check your callbacks.

Epoch: 0, accuracy:0.4955,  binary_crossentropy:0.8108,  loss:0.8108,  val_accuracy:0.4970,  val_binary_crossentropy:0.6725,  val_loss:0.6725,  
....................................................................................................
Epoch: 100, accuracy:0.6590,  binary_crossentropy:0.5943,  loss:0.5943,  val_accuracy:0.6730,  val_binary_crossentropy:0.5780,  val_loss:0.5780,  
....................................................................................................
Epoch: 200, accuracy:0.6894,  binary_crossentropy:0.5594,  loss:0.5594,  val_accuracy:0.6820,  val_binary_crossentropy:0.5753,  val_loss:0.5753,  
....................................................................................................
Epoch: 300, accuracy:0.7231,  binary_crossentropy:0.5111,  loss:0.5111,  val_accuracy:0.6830,  val_binary_crossentropy:0.6013,  val_loss:0.6013,  
.....................
plotter.plot(regularizer_histories)
plt.ylim([0.5, 0.7])
(0.5, 0.7)

png

Aus dieser Darstellung geht hervor, dass beide Regularisierungsansätze das Verhalten des "Large" Modells verbessern. Aber dies übertrifft immer noch nicht einmal die "Tiny" -Basislinie.

Versuchen Sie als nächstes beide zusammen und sehen Sie, ob das besser ist.

Kombinierter L2 + Ausfall

combined_model = tf.keras.Sequential([
    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
                 activation='elu', input_shape=(FEATURES,)),
    layers.Dropout(0.5),
    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
                 activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
                 activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
                 activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(1)
])

regularizer_histories['combined'] = compile_and_fit(combined_model, "regularizers/combined")
Model: "sequential_6"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_24 (Dense)             (None, 512)               14848     
_________________________________________________________________
dropout_4 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_25 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_5 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_26 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_6 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_27 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_7 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_28 (Dense)             (None, 1)                 513       
=================================================================
Total params: 803,329
Trainable params: 803,329
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0041s vs `on_train_batch_end` time: 0.0627s). Check your callbacks.

Epoch: 0, accuracy:0.5101,  binary_crossentropy:0.7867,  loss:0.9452,  val_accuracy:0.5440,  val_binary_crossentropy:0.6681,  val_loss:0.8258,  
....................................................................................................
Epoch: 100, accuracy:0.6491,  binary_crossentropy:0.6032,  loss:0.6321,  val_accuracy:0.6660,  val_binary_crossentropy:0.5830,  val_loss:0.6116,  
....................................................................................................
Epoch: 200, accuracy:0.6667,  binary_crossentropy:0.5912,  loss:0.6171,  val_accuracy:0.6850,  val_binary_crossentropy:0.5687,  val_loss:0.5946,  
....................................................................................................
Epoch: 300, accuracy:0.6718,  binary_crossentropy:0.5828,  loss:0.6106,  val_accuracy:0.6840,  val_binary_crossentropy:0.5667,  val_loss:0.5945,  
....................................................................................................
Epoch: 400, accuracy:0.6750,  binary_crossentropy:0.5770,  loss:0.6067,  val_accuracy:0.6870,  val_binary_crossentropy:0.5534,  val_loss:0.5832,  
....................................................................................................
Epoch: 500, accuracy:0.6733,  binary_crossentropy:0.5752,  loss:0.6071,  val_accuracy:0.6910,  val_binary_crossentropy:0.5526,  val_loss:0.5846,  
....................................................................................................
Epoch: 600, accuracy:0.6895,  binary_crossentropy:0.5634,  loss:0.5976,  val_accuracy:0.7060,  val_binary_crossentropy:0.5466,  val_loss:0.5809,  
....................................................................................................
Epoch: 700, accuracy:0.6876,  binary_crossentropy:0.5590,  loss:0.5940,  val_accuracy:0.6860,  val_binary_crossentropy:0.5502,  val_loss:0.5852,  
....................................................................................................
Epoch: 800, accuracy:0.6921,  binary_crossentropy:0.5594,  loss:0.5956,  val_accuracy:0.6990,  val_binary_crossentropy:0.5496,  val_loss:0.5858,  
....................................................................................................
Epoch: 900, accuracy:0.6900,  binary_crossentropy:0.5603,  loss:0.5975,  val_accuracy:0.7000,  val_binary_crossentropy:0.5393,  val_loss:0.5765,  
....................................................................................................
Epoch: 1000, accuracy:0.6946,  binary_crossentropy:0.5592,  loss:0.5975,  val_accuracy:0.6750,  val_binary_crossentropy:0.5564,  val_loss:0.5947,  
....................................................................................................
Epoch: 1100, accuracy:0.7000,  binary_crossentropy:0.5476,  loss:0.5872,  val_accuracy:0.7030,  val_binary_crossentropy:0.5460,  val_loss:0.5856,  
....................................................................................................
Epoch: 1200, accuracy:0.7045,  binary_crossentropy:0.5474,  loss:0.5879,  val_accuracy:0.6860,  val_binary_crossentropy:0.5480,  val_loss:0.5886,  
...........
plotter.plot(regularizer_histories)
plt.ylim([0.5, 0.7])
(0.5, 0.7)

png

Dieses Modell mit der "Combined" Regularisierung ist offensichtlich das bisher beste.

Ansicht in TensorBoard

Diese Modelle zeichneten auch TensorBoard-Protokolle auf.

Kopieren Sie Folgendes in eine Codezelle, um einen eingebetteten Tensorboard-Viewer in einem Notizbuch zu öffnen:

%tensorboard --logdir {logdir}/regularizers

Sie können die Ergebnisse einer früheren Ausführung dieses Notizbuchs auf TensorDoard.dev anzeigen .

Es ist auch in einem <iframe> :

display.IFrame(
    src="https://tensorboard.dev/experiment/fGInKDo8TXes1z7HQku9mw/#scalars&_smoothingWeight=0.97",
    width = "100%",
    height="800px")

Dies wurde hochgeladen mit:

tensorboard dev upload --logdir  {logdir}/regularizers

Schlussfolgerungen

Um es noch einmal zusammenzufassen: Hier sind die häufigsten Möglichkeiten, um eine Überanpassung in neuronalen Netzen zu verhindern:

  • Holen Sie sich mehr Trainingsdaten.
  • Reduzieren Sie die Kapazität des Netzwerks.
  • Gewichtsregulierung hinzufügen.
  • Dropout hinzufügen.

Zwei wichtige Ansätze, die in diesem Handbuch nicht behandelt werden, sind:

  • Datenerweiterung
  • Chargennormalisierung

Denken Sie daran, dass jede Methode für sich helfen kann, aber oft kann die Kombination noch effektiver sein.

# MIT License
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.