Spätestens wenn mit etwas größeren Datenmengen trainiert wird stellt sich bei einer unserer Methoden ein neues Problem dar. Während die mean-Methode ohne Probleme durchläuft bricht die CNN-Methode aufgrund mangelnden Arbeitsspeicher ab. %beschwert sich die CNN-Methode, dass nicht genug Arbeitsspeicher vorhanden ist.
...
...
@@ -22,6 +22,32 @@ Die Daten müssen bei der CNN-Methode also nur stückweise in den Arbeitsspeiche
Ein möglicher Ansatz ist die rohen Daten nur schrittweise einzulesen und diese dann erst dem word2vec model zu übergeben um daraus einen Vektor zu machen. Dafür wird eine Funktion geschrieben, welche dann der fit Methode des eigentlichen machine learning models als Datensatz-parameter übergeben wird. Dabei wird in der Funktion die batchsize berücksichtigt, sodass stets die gewünschte Menge an Daten gleichzeitig in das model geladen werden.
Um dies jedoch zu erfüllen müssen die Daten nach ihren Nutzen in verschiedene Dateien aufgeteilt werden. Dementsprechend eine Trainings-, Validierungs- und Test-Datei.
\begin{lstlisting}[label={lst:Aufteilung}]
val = open('val.json','w',encoding='utf8')
test = open('test.json','w',encoding='utf8')
train = open('train.json','w',encoding='utf8')
i = 0
for line in open(corpus_path,encoding="utf8"):
if(i<3): train.write(line)
elif(i==3): val.write(line)
else:
i = -1
test.write(line)
i += 1
val.close()
test.close()
train.close()
\end{lstlisting}
Das Aufteilen wird durch ein einfaches Zählen und Sortieren gelöst. Dabei zählt eine Variable, hier \lstinline{i}{}, hoch und je nachdem welchen Wert diese Variable hat werden die Daten in die entsprechende Datei sortiert. Das Ziel ist eine 60-20-20 Aufteilung der Daten. Dafür werden bei den Werten \lstinline{0, 1}{} und \lstinline{2}{} die Daten in die Trainingsdatei geschrieben und dementsprechend bei den Werten \lstinline{3}{} und \lstinline{4}{} in die Validierungs-, bzw.\@ Testdatei.
Wenn in die Testdatei geschrieben wird, wird auch gleichzeitig die Zählervariable zurückgesetzt, sodass mit den gleichen Werten von vorne begonnen werden kann. Hier wurde sich bewusst für ein Zurücksetzen der Variable entschieden und gegen ein kontinuierliches Hochzählen und der Sortierung durch Modulo: Auf diese Weise werden bedenkenlos Overflow- und Signifikanzprobleme verhindert ohne einen deutlichen Verlust der Lesbarkeit des Codes hinnehmen zu müssen. \wip{Da der genutzte Datensatz nur etwas über 8 Millionen Einträge besitzt und mit Ganzzahlen gearbeitet wird wären beide Probleme zu vernachlässigen gewesen.}
Diese Art der Aufteilung ist jedoch nur bedenkenlos einzusetzen in diesem Projekt, da die Daten ohnehin unabhängig sind und ebenfalls unsortiert vorliegen. Aus diesen Gründen sind die drei Datensätze auch ohne extra shuffle zufällig genug.
\wip{Überleitung zum Generator? Oder das Aufteilen der Daten in eigenes Kapitel?}
Zunächst ein wenig overhead, bevor wir dann die entsprechende Datei zeilenweise durchgehen. Die Zeile 7 mit \lstinline{while True:}{}ist notwendig um die Funktion dem Keras model als Parameter zu übergeben.
Zunächst ein wenig overhead, bevor wir dann die entsprechende Datei zeilenweise durchgehen. Die Zeile 7 mit \lstinline{while True:}{}wird dabei vom Keras Modell erwartet, denn das Trainieren soll nicht mitten in einer Epoche enden, weil das Ende der Trainingsdatendatei erreicht wurde.
@@ -99,11 +125,11 @@ Zu Beginn initialisieren wir eine Zähler-variable auf 0, welche wir später fü
continue
y = float(json_line["stars"])
if y < 3:
yData = [0,0,1]
yData = 0
elif y == 3:
yData = [0,1,0]
yData = 1
else:
yData = [1,0,0]
yData = 2
\end{lstlisting}
Anschließend wird quasi identisch \wip{zu der anderen Methode (Ref?)}der rohe Datensatz ausgelesen und entsprechend in nutzbare x und y Daten umgewandelt.
\begin{lstlisting}
...
...
@@ -119,8 +145,7 @@ Anschließend wird quasi identisch \wip{zu der anderen Methode (Ref?)}der rohe D
i = -1
i += 1
\end{lstlisting}
Als nächstes werden die Daten den entsprechenden Listen angehangen. Dabei wird die zu Beginn besprochene Zähler variable genutzt um die ersten 3 Einträge dem Trainingsset, der nächste dem Validierungsset und abschließend dem Testset zugeordnet, bevor der Zähler wieder zurückgesetzt wird. Dadurch erfolgt die zuvor erwähnte 60-20-20 Aufteilung.\\
Diese Art der Aufteilung ist aber nur bedenkenlos einzusetzen in diesem Projekt, da die Daten ohnehin unabhängig sind und ebenfalls unsortiert vorliegen. Aus diesen Gründen sind die drei Datensätze auch ohne extra shuffle zufällig genug.
Als nächstes werden die Daten den entsprechenden Listen angehangen. Das vorgehen hier orientiert sich dabei an der zuvor besprochenen Aufteilung aus aus dem Code-Schnipsel \ref{lst:Aufteilung}.
@@ -173,15 +198,14 @@ Diese Datasets müssen aber zunächst erstellt werden. Dafür geben wir zum eine
Für das appenden der Daten im Folgenden Verlauf müssen die Datasets stets um die entsprechende Größe resized werden. Anschließend werden die neuen Felder entsprechend aufgefüllt und zu guter Letzt wieder die buffer-listen resetted.\\
Das Auslesen der Daten erfolgt letztlich ähnlich wie bei dem anderen vorgestellten Generator:
Die Hauptunterschiede sind dabei das hier entsprechend anfallende zugreifen des passenden Datasets, das Wegfallen der word2vec Überführung und der zusätzliche check ob \lstinline{batch_size}{} über das Ende der Datasets gehen würde.\\
Die Hauptunterschiede sind dabei das hier entsprechend anfallende Zugreifen des passenden Datasets, das Wegfallen der word2vec Überführung und der zusätzliche check ob \lstinline{batch_size}{} über das Ende der Datasets gehen würde.\\
Der Vorteil bei diesem Vorgehen ist eine bessere Trainingszeit und vor allem eine bessere Validierungszeit gegenüber dem zuvor besprochenen Generator. Jedoch braucht diese Variante ein vielfaches mehr Festplattenspeicher und zwar so viel wie in der zuvor berechneten Gleichung \ref{eq:430GB}:
Das Erstellen dieser Datenmengen benötigt aber auch entsprechende Zeit. Dieses Vorgehen lohnt sich also besonders, wenn das Word2Vec Modell nicht mehr oder nur noch selten verändert wird und somit häufig auf dem gleichen Modell trainiert werden kann.