Skip to content
Snippets Groups Projects
Commit 06ea5ba6 authored by Joel Vongehr's avatar Joel Vongehr
Browse files

idk why this pull needed a merge

parents 3275cbef 5153a47f
Branches
No related tags found
No related merge requests found
......@@ -19,7 +19,7 @@ Dies könnte mit 8GB RAM etwas knapp werden, jedoch stellt es bei 16GB gar kein
Das Problem ist recht deutlich. Viele Personen hätten auf ihrem privaten PC vermutlich nicht einmal genug Festplattenspeicher für diese Datenmenge, geschweige denn Arbeitsspeicher. \\
Die Daten müssen bei der CNN-Methode also nur stückweise in den Arbeitsspeicher geladen werden, dann wird mit diesen trainiert und anschließend werden sie wieder aus dem Arbeitsspeicher gelöscht um Platz für die nächsten Daten zu machen. Dabei gibt es wieder verschiedene Ansätze.
\subsubsection{Erster Generator}
\subsubsection{Erster Generator}\label{subsubsec:simpleGen}
%Erster Ansatz, sehr lange validierungszeit
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.
\begin{lstlisting}
......
......@@ -9,3 +9,4 @@
\input{silas/gensim.tex}
\input{silas/w2vMean.tex}
\input{silas/w2vCNN.tex}
......@@ -72,7 +72,7 @@ print (nr_of_reviews))
Das Programm liefert \lstinline{8021122} zurück.
\subsubsection{Reviewlänge}
\subsubsection{Reviewlänge}\label{subsubsec:reviewlength}
\begin{lstlisting}[inputencoding=latin1,caption={Programm zur ermittlung der Reviewlänge},label={list:rev_len}]
import json
import numpy as np
......
\subsection{Word2Vec mit Gensim}
\subsection{Word2Vec mit Gensim}\label{subsection:gensim}
Für das Trainieren des Word2Vec-Modells
wird in dieser Arbeit die Open-Source-Library Gensim verwendet.
......
\subsection{Word2Vec-CNN-Modell}
Ein \noteable{convolutional neural network}, kurz CNN, ist in der Lage,
lokale Muster in einer Sequenz zu erlernen und diese später
wiederzuerkennen, auch wenn diese an einer anderen Stelle auftreten.
In diesem Modell wird eine Reihe an Wortvektoren an das CNN übergeben, das Extrahieren der Merkmale wird somit Teil des Optimierungsproblems.
\subsubsection{Implementierung}
Aufgrund des sehr hohen Speicherbedarfs wird der im Kapitel \ref{subsubsec:simpleGen} geschriebene Generator
verwendet.
Hierfür muss jedoch zunächst die Funktion \lstinline{getSentenceVectorCNN} implementiert werden.
\begin{lstlisting}[caption={Datentransformation},label={list:getSentenceVector}]
import numpy as np
from gensim import utils
from w2v_yelp_model import getWordVecMode
model_path = "full_yelp_w2v_model"
modelW2V = getWordVecModel(model_path)
def getSentenceVectorCNN(sentence):
split = utils.simple_preprocess(sentence)
wordVecs = np.zeros((72,100))
i=0
for word in split:
if i == 72: break
try:
wordVecs[i] = modelW2V.wv[word]
i += 1
except:
pass
if np.all(wordVecs[5:]==0):
raise Exception('not enough words found in w2v model')
return wordVecs
\end{lstlisting}
Zuerst wird in Zeile 5 die im Listing \ref{list:gw2v} geschriebene Funktion
\lstinline{getWordVecMode} aufgerufen, um das Word2Vec-Modell erhalten.
Die Funktion \lstinline{getSentenceVectorCNN} in Zeile 7 nimmt eine Rezension entgegen und
transformiert diese in eine für das CNN verarbeitbare Form.
\wip{genauer erklären?}
Dafür wird die Rezension in Zeile 8 tokenisiert, sodass in der variable
\lstinline{split} eine Liste der durch die Funktion \lstinline{utils.simple_preprocess}
vorverarbeiteten Wörter gespeichert ist.
Danach wird in Zeile 9 das Numpy-Array wordVecs mit Nullen initialisiert.
Dieses Numpy-Array speichert die ersten 72 Wortvektoren der Rezension,
die Zahl 72 wurde aufgrund des im Kapitel \ref{subsubsec:reviewlength} berechneten
Median der Reviewlänge gewählt.
Die for-Schleife in Zeile 11 durchläuft alle Wörter der Liste split und fügt diese,
falls sie im word2Vec-Modell vertreten sind, in das \lstinline{wordVecs} Array ein.
Sind mehr als 72 Wörter in der Liste \lstinline{Split} wird die Schleife abgebrochen,
wenn das Array vollständig gefüllt ist.
Sollten sich weniger als 72 Wörter in der Liste befinden,
so ist das Array bereits mit Nullen initialisiert.
Dies kann als \noteable{Truncating} und \noteable{Padding} bezeichnet werden und
ist notwendig,
da das CNN eine feste Dimension der Eingangsdaten benötigt.
Anschließend wird in Zeile 18 geprüft, ob weniger als 5 Wortvektoren in dem Array
stehen, ist dies der Fall, wird eine Exception geworfen.
\ No newline at end of file
......@@ -175,6 +175,7 @@ confusion_matrix(Y_test,y_pred,normalize='true')
\end{lstlisting}
\wip{Tabelle auswerten}
\begin{table}[ht]
\def\arraystretch{1.3}
\begin{center}
\begin{tabular}{*{4}{R}}
- &Negativ & Neutral & Positiv\\
......@@ -190,6 +191,7 @@ von $85.7\%$, betrachtet man jedoch die Konfusionsmatrix in Tabelle \ref{tab:con
sieht man das dort bloß $27\%$ der neutralen Rezensionen richtig klassifiziert wurden.
\wip{Tabellenreferenz ???}
\begin{table}[ht]
\def\arraystretch{1.3}
\begin{center}
\begin{tabular}{*{4}{R}}
- &Negativ & Neutral & Positiv\\
......
No preview for this file type
......@@ -74,7 +74,7 @@
}
\newcolumntype{R}{>{\collectcell\ApplyGradient}c<{\endcollectcell}}
\renewcommand{\arraystretch}{1.5}
%\renewcommand{\arraystretch}{1.5}
\setlength{\fboxsep}{3mm} % box size
\setlength{\tabcolsep}{5pt}
%-----------------------
......
......@@ -13,6 +13,7 @@ if __name__ == '__main__':
pathSilas = "G:\\ml\\"
path = pathSilas
data_path ="E:\\downloads\\yelp_dataset\\yelp_dataset\\yelp_academic_dataset_review.json"
#data_path = "D:\\ml\\data\\sample1.json"
def getSentenceVectorCNN(sentence):
split = utils.simple_preprocess(sentence)
......@@ -34,7 +35,7 @@ if __name__ == '__main__':
import json
i = 0
with h5py.File(path + "w2vCNN.hdf5", "w") as hf:
chunkSize = 10**4
chunkSize = 10E3
trainChunk = int(chunkSize * 0.6)
valTestChunk = int(chunkSize * 0.2)
xTrain = []
......@@ -122,40 +123,39 @@ if __name__ == '__main__':
i += 1
index +=1
XTrain.resize(XTrain.shape[0]+trainChunk, axis=0)
XTrain[-trainChunk:] = xTrain
#XTrain.resize(XTrain.shape[0]+trainChunk, axis=0)
#XTrain[-trainChunk:] = xTrain
YTrain.resize(YTrain.shape[0]+trainChunk, axis=0)
YTrain[-trainChunk:] = yTrain
#YTrain.resize(YTrain.shape[0]+trainChunk, axis=0)
#YTrain[-trainChunk:] = yTrain
XVal.resize(XVal.shape[0]+valTestChunk, axis=0)
XVal[-valTestChunk:] = xVal
#XVal.resize(XVal.shape[0]+valTestChunk, axis=0)
#XVal[-valTestChunk:] = xVal
YVal.resize(YVal.shape[0]+valTestChunk, axis=0)
YVal[-valTestChunk:] = yVal
#YVal.resize(YVal.shape[0]+valTestChunk, axis=0)
#YVal[-valTestChunk:] = yVal
XTest.resize(XTest.shape[0]+valTestChunk, axis=0)
XTest[-valTestChunk:] = xTest
#XTest.resize(XTest.shape[0]+valTestChunk, axis=0)
#XTest[-valTestChunk:] = xTest
YTest.resize(YTest.shape[0]+valTestChunk, axis=0)
YTest[-valTestChunk:] = yTest
#YTest.resize(YTest.shape[0]+valTestChunk, axis=0)
#YTest[-valTestChunk:] = yTest
#%%
import h5py
def hdf5Generator(filePath, batch_size, dataSet):
def hdf5Generator(filePath, batch_size, dataSet,loop=True):
with h5py.File(filePath, 'r') as hf:
L = len(hf["X" + dataSet])
while True:
batch_start = 0
batch_end = batch_size
while batch_start < L:
limit = min(batch_end, L)
X = hf["X" + dataSet][batch_start:limit]
Y = hf["Y" + dataSet][batch_start:limit]
while batch_end < L:
X = hf["X" + dataSet][batch_start:batch_end]
Y = hf["Y" + dataSet][batch_start:batch_end]
yield (X,Y) #a tuple with two numpy arrays with batch_size samples
batch_start += batch_size
batch_end += batch_size
if not loop: break
\ No newline at end of file
#%% CNN
import os
os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'
import tensorflow as tf
import numpy as np
from tensorflow.keras.models import Sequential
......@@ -11,11 +13,10 @@ modelNN = Sequential()
modelNN.add(Conv1D(32, 7, activation='relu',input_shape=((72, 100))))
modelNN.add(Conv1D(32, 7, activation='relu'))
#modelNN.add(GlobalMaxPooling1D())
modelNN.add(GlobalMaxPooling1D())
modelNN.add(Flatten())
modelNN.add(Dense(512,activation='relu'))
modelNN.add(Dense(128,activation='relu'))
#modelNN.add(Dense(50,activation='relu',input_dim=X[0].size))
modelNN.add(Dense(10,activation='relu'))
modelNN.add(Dense(3,activation='softmax'))
modelNN.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=["sparse_categorical_accuracy"])
......@@ -23,19 +24,33 @@ modelNN.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=
#%%
from hdf5 import hdf5Generator
path = "G:\\ml\\"
num_rows = 340000
batchSize = 512
num_rows = 4.8E6
batchSize = 2048
steps = num_rows/batchSize
#early stop
earlystop = keras.callbacks.EarlyStopping(monitor='accuracy',patience=10,verbose=False,restore_best_weights=True)
earlystop = keras.callbacks.EarlyStopping(monitor='sparse_categorical_accuracy',patience=10,verbose=False,restore_best_weights=True)
cbList = [earlystop]
trainData = hdf5Generator(path + "w2vCNN.hdf5", batchSize, "Train")
valData = hdf5Generator(path + "w2vCNN.hdf5", batchSize, "Val")
hist = modelNN.fit(trainData, validation_data=valData, epochs=12, steps_per_epoch=steps, validation_steps=steps)
#hist = modelNN.fit(hdf5Generator("vectors.hdf5", batchSize),epochs=15, steps_per_epoch=steps)
#hist = modelNN.fit(hdf5Generator("vectors.hdf5", batchSize),epochs=15,batch_size=batchSize,callbacks=cbList)
#%%
cW = {0:4.18,1:9.53,2:1.52}
hist = modelNN.fit(trainData, validation_data=valData, epochs=100,class_weight=cW, steps_per_epoch=steps, validation_steps=steps,callbacks=cbList)
modelNN.save("D:\\ml\\CNN-Classfication")
#modelNN.fit(train,epochs=12,validation_data=val,batch_size=batchSize,steps_per_epoch= num_rows/batchSize,callbacks=cbList,validation_steps=num_rows/batchSize)
# %%eval
testData = hdf5Generator(path + "w2vCNN.hdf5", batchSize, "Test",loop=False)
modelNN.evaluate(testData)
#%%
tD = hdf5Generator(path + "w2vCNN.hdf5", batchSize, "Test",loop=False)
y_pred = np.argmax(modelNN.predict(tD),axis=-1)
#%%
y_test=[]
for (x,y) in hdf5Generator(path + "w2vCNN.hdf5", batchSize, "Test",loop=False):
y_test.append(y)
y_test = np.array(y_test).flatten()
#%% confusion matrix
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test,y_pred,normalize='true')
# %%
......@@ -8,6 +8,7 @@ import pandas as pd
import json
from tensorflow.python.keras.constraints import MaxNorm
from tensorflow.python.keras.layers.core import Dropout
model_path = "D:\\ml\\full_yelp_w2v_model"
#data_path ="C:\\Users\\sls21\\Documents\\Uni\\word2vec\\sample.json"
......@@ -28,15 +29,15 @@ def getSentenceVectorCNN(sentence):
i += 1
except:
pass
#if wordVecs == np.zeros((72,100)): #maybe dont alllow sentences with less than n wordvecotrs
# raise Exception('words not found in w2v model')
if np.all(wordVecs[5:]==0):
raise Exception('not enough words found in w2v model')
return wordVecs
# %% data
import numpy as np
try:
X = np.load("./Data/X_cnn.npy")
Y = np.load("./Data/Y_cnn.npy")
X = np.load("D:/ml/data/X_cnn.npy")
Y = np.load("D:/ml/data/Y_cnn.npy")
except:
X = []
Y = []
......@@ -61,8 +62,8 @@ except:
#Y.append(1 if y>2 else 0)
X = np.array(X)
Y = np.array(Y)
#np.save("./Data/X_cnn",X)
#np.save("./Data/Y_cnn",Y)
np.save("D:/ml/data/X_cnn.npy",X)
np.save("D:/ml/data/Y_cnn.npy",Y)
# %% CNN
import tensorflow as tf
import numpy as np
......@@ -87,35 +88,29 @@ import tensorflow as tf
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.layers import Conv1D,MaxPooling1D,GlobalMaxPooling1D
from tensorflow.keras.layers import Conv1D,MaxPooling1D,GlobalMaxPooling1D,Dropout
from tensorflow import keras
modelNN = Sequential()
modelNN.add(Conv1D(32, 7, activation='relu',input_shape=(X[0].shape)))
modelNN.add(Conv1D(32, 7, activation='relu'))
#modelNN.add(GlobalMaxPooling1D())
modelNN.add(GlobalMaxPooling1D())
modelNN.add(Flatten())
modelNN.add(Dense(512,activation='relu'))
modelNN.add(Dropout(0.5))
modelNN.add(Dense(128,activation='relu'))
#modelNN.add(Dense(50,activation='relu',input_dim=X[0].size))
modelNN.add(Dropout(0.25))
modelNN.add(Dense(10,activation='relu'))
modelNN.add(Dropout(0.1))
modelNN.add(Dense(3,activation='softmax'))
modelNN.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=["accuracy"])
# %% fit
#early stop
earlystop = keras.callbacks.EarlyStopping(monitor='val_accuracy',patience=10,verbose=False,restore_best_weights=True)
earlystop = keras.callbacks.EarlyStopping(monitor='val_accuracy',patience=5,verbose=False,restore_best_weights=True)
cbList = [earlystop]
hist = modelNN.fit(X,Y,epochs=1000,validation_split=0.2,batch_size=128,callbacks=cbList)
hist = modelNN.fit(X,Y,epochs=50,validation_split=0.2,batch_size=128,callbacks=cbList)
#%%
\ No newline at end of file
## Notes
# np.unique(Y,return_counts=True)
# (array([0, 1]), array([ 77051, 272891], dtype=int64))
# /Y.size
# -> array([0.2201822, 0.7798178])
# -> Unbalanced dataset
#current val_acc ~ 91.5 %
#%%
import os
#os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
from math import nan
from gensim.test.utils import datapath
os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'
from gensim import utils
from w2v_yelp_model import getWordVecModel
import pandas as pd
import json
model_path = "D:\\ml\\full_yelp_w2v_model"
......@@ -24,14 +21,14 @@ def getSentenceVectorCNN(sentence):
i += 1
except:
pass
#if wordVecs == np.zeros((72,100)): #maybe dont alllow sentences with less than n wordvecotrs
# raise Exception('words not found in w2v model')
if np.all(wordVecs[5:]==0):
raise Exception('not enough words found in w2v model')
return wordVecs
#%% Data Generator
import numpy as np
import json
def generate_arrays_from_file(path, batchsize):
def generate_arrays_from_file(path, batchsize,loop=True):
inputs = []
targets = []
batchcount = 0
......@@ -51,13 +48,14 @@ def generate_arrays_from_file(path, batchsize):
batchcount += 1
except:
continue
if batchcount > batchsize:
if batchcount >= batchsize:
X = np.array(inputs)
y = np.array(targets)
yield (X, y)
inputs = []
targets = []
batchcount = 0
if not loop: break
#%% CNN
import tensorflow as tf
......@@ -84,12 +82,25 @@ modelNN.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=
#early stop
earlystop = keras.callbacks.EarlyStopping(monitor='val_accuracy',patience=25,verbose=False,restore_best_weights=True)
cbList = [earlystop]
num_rows = 350000
batchSize = 512
#num_rows = 4.8E6
num_rows = 410000
batchSize = 2048
#hist = modelNN.fit(generate_arrays_from_file('./sample.json',128),epochs=1000,validation_split=0.2,batch_size=128,callbacks=cbList)
train = generate_arrays_from_file('D:\\ml\\data\\train.json',batchSize)
val = generate_arrays_from_file('D:\\ml\\data\\val.json',batchSize)
modelNN.fit(train,epochs=12,validation_data=val,batch_size=batchSize,steps_per_epoch= num_rows/batchSize,callbacks=cbList,validation_steps=num_rows/batchSize)
#%%
modelNN.fit(train,epochs=1,validation_data=val,steps_per_epoch= num_rows/batchSize,callbacks=cbList,validation_steps=num_rows/batchSize)
# %%
modelNN.evaluate(generate_arrays_from_file('D:\\ml\\data\\val.json',16000,False))
# %%
y_pred = np.argmax(modelNN.predict(generate_arrays_from_file('D:\\ml\\data\\val.json',16000,False)),axis=-1)
# %%
y_t = []
for a in generate_arrays_from_file('D:\\ml\\data\\val.json',batchSize,False):
y_t.append(a[1])
# %%
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment