27 KiB
27 KiB
LSTM
import pandas as pd
import numpy as np
train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")
valid = pd.read_csv("valid.csv")
train.loc[train["review_score"]==-1, "review_score"]=0
test.loc[test["review_score"]==-1, "review_score"]=0
valid.loc[valid["review_score"]==-1, "review_score"]=0
Sprawdzanie długości najdłuższej recenzji (teoretycznie Steam zezwala na max 8000 znaków)
train["seq_length"] = train["review_text"].apply(lambda x : len(x.split()))
print(train["seq_length"].max())
1570
import tensorflow as tf
SEQ_PADDED_LENGTH = 1600
VOCABULARY_SIZE = 4000
vectorizer = tf.keras.layers.TextVectorization(output_sequence_length=SEQ_PADDED_LENGTH, max_tokens=VOCABULARY_SIZE)
vectorizer.adapt(train["review_text"])
len(vectorizer.get_vocabulary())
4000
train["vectorized"] = train["review_text"].apply(vectorizer)
test["vectorized"] = test["review_text"].apply(vectorizer)
valid["vectorized"] = valid["review_text"].apply(vectorizer)
from keras.optimizers import Adam
import keras.layers as layers
import keras
def create_model():
input_layer = layers.Input(shape=(SEQ_PADDED_LENGTH,))
embedding_layer = layers.Embedding(input_dim=VOCABULARY_SIZE+1, output_dim=16, input_length=SEQ_PADDED_LENGTH)(input_layer)
lstm_layer = layers.LSTM(64)(embedding_layer)
output_layer = layers.Dense(1,activation="sigmoid")(lstm_layer)
model = keras.Model(inputs=input_layer, outputs=output_layer)
model.compile(loss='binary_crossentropy', optimizer=Adam(learning_rate=1e-3), metrics=['accuracy'])
return model
model = create_model()
model.summary()
Model: "model_9" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_15 (InputLayer) [(None, 1600)] 0 embedding_14 (Embedding) (None, 1600, 16) 64016 lstm_15 (LSTM) (None, 64) 20736 dense_9 (Dense) (None, 1) 65 ================================================================= Total params: 84,817 Trainable params: 84,817 Non-trainable params: 0 _________________________________________________________________
train.iloc[120]["vectorized"].shape
TensorShape([1600])
train.iloc[120]["vectorized"].get_shape().as_list()
[1600]
train.iloc[120]["vectorized"]
<tf.Tensor: shape=(1600,), dtype=int64, numpy=array([423, 635, 423, ..., 0, 0, 0], dtype=int64)>
Część recenzji nie zawierała tekstu więc po usunięciu interpunkcji i znaków specjalnych były puste, teksty te trzeba usunąć z materiału treningowego
train["shapes"] = train["vectorized"].apply(lambda x : x.get_shape().as_list()[0])
train["shapes"].value_counts()
shapes 1600 43111 0 119 Name: count, dtype: int64
train.drop(train[train["vectorized"].map(lambda x : x.get_shape().as_list()[0])!=SEQ_PADDED_LENGTH].index, inplace=True)
train["shapes"].value_counts()
shapes 1600 43111 Name: count, dtype: int64
#valid.drop(valid[valid["vectorized"].map(lambda x : x.get_shape().as_list()[0])!=1600].index, inplace=True)
empty_valid = valid[valid["vectorized"].map(lambda x : x.get_shape().as_list()[0])==0]
empty_valid.head()
Unnamed: 0 | review_text | review_score | vectorized | |
---|---|---|---|---|
42 | 4552590 | !!! | 1 | () |
124 | 5286261 | . | 1 | () |
259 | 4934066 | ........ | 1 | () |
468 | 5584357 | . | 1 | () |
717 | 2172088 | =] | 1 | () |
"0" to maskowane pozycje, puste dane w zbiorze testowym można nimi uzupełnić
#test.loc[test["vectorized"].map(lambda x : x.get_shape().as_list()[0])!=SEQ_PADDED_LENGTH,"vectorized"] = tf.zeros((SEQ_PADDED_LENGTH,), dtype=tf.dtypes.int64)
#valid.loc[valid["vectorized"].map(lambda x : x.get_shape().as_list()[0])!=SEQ_PADDED_LENGTH,"vectorized"] = tf.zeros((SEQ_PADDED_LENGTH,), dtype=tf.dtypes.int64)
#empty_valid["vectorized"] = tf.zeros((len(empty_valid.index),1600), dtype=tf.dtypes.int64)
#empty_test["vectorized"] = tf.zeros((len(empty_test.index),1600), dtype=tf.dtypes.int64)
#empty_valid["vectorized"].iloc[0]
def vector_fix(x):
if x.get_shape().as_list()[0]==SEQ_PADDED_LENGTH:
return x
return tf.zeros((1600,), dtype=tf.dtypes.int64)
test["vectorized"] = test["vectorized"].apply(vector_fix)
valid["vectorized"] = valid["vectorized"].apply(vector_fix)
#train["vectorized"] = train["vectorized"].apply(lambda x : x.numpy())
#valid["vectorized"] = valid["vectorized"].apply(lambda x : x.numpy())
#test["vectorized"] = test["vectorized"].apply(lambda x : x.numpy())
train.iloc[0]["vectorized"]
<tf.Tensor: shape=(1600,), dtype=int64, numpy=array([ 96, 2, 824, ..., 0, 0, 0], dtype=int64)>
Trening nawet mniejszego modelu na pełnym zbiorze danych zajmował bardzo dużo czasu więc skróciłem zbiór treningowy
#train_y = np.stack(train["review_score"].values)
train_y = np.stack(train["review_score"].values)
valid_y = np.stack(valid["review_score"].values)
test_y = np.stack(test["review_score"].values)
###
#train_x = np.stack(train["vectorized"].values)
train_x = np.stack(train["vectorized"].values)
test_x = np.stack(test["vectorized"].values)
valid_x = np.stack(valid["vectorized"].values)
#callback = keras.callbacks.EarlyStopping(monitor='val_loss', mode='min', patience=3, restore_best_weights=True)
history = model.fit(train_x, train_y, validation_data=(valid_x, valid_y), epochs=3)
Epoch 1/3 1348/1348 [==============================] - 627s 465ms/step - loss: 0.6933 - accuracy: 0.4947 - val_loss: 0.6950 - val_accuracy: 0.1744 Epoch 2/3 918/1348 [===================>..........] - ETA: 3:00 - loss: 0.6932 - accuracy: 0.4982
[1;31m---------------------------------------------------------------------------[0m [1;31mKeyboardInterrupt[0m Traceback (most recent call last) Cell [1;32mIn [44], line 16[0m [0;32m 12[0m valid_x [38;5;241m=[39m np[38;5;241m.[39mstack(valid[[38;5;124m"[39m[38;5;124mvectorized[39m[38;5;124m"[39m][38;5;241m.[39mvalues) [0;32m 15[0m [38;5;66;03m#callback = keras.callbacks.EarlyStopping(monitor='val_loss', mode='min', patience=3, restore_best_weights=True)[39;00m [1;32m---> 16[0m history [38;5;241m=[39m [43mmodel[49m[38;5;241;43m.[39;49m[43mfit[49m[43m([49m[43mtrain_x[49m[43m,[49m[43m [49m[43mtrain_y[49m[43m,[49m[43m [49m[43mvalidation_data[49m[38;5;241;43m=[39;49m[43m([49m[43mvalid_x[49m[43m,[49m[43m [49m[43mvalid_y[49m[43m)[49m[43m,[49m[43m [49m[43mepochs[49m[38;5;241;43m=[39;49m[38;5;241;43m3[39;49m[43m)[49m File [1;32m~\miniconda3\lib\site-packages\keras\utils\traceback_utils.py:65[0m, in [0;36mfilter_traceback.<locals>.error_handler[1;34m(*args, **kwargs)[0m [0;32m 63[0m filtered_tb [38;5;241m=[39m [38;5;28;01mNone[39;00m [0;32m 64[0m [38;5;28;01mtry[39;00m: [1;32m---> 65[0m [38;5;28;01mreturn[39;00m fn([38;5;241m*[39margs, [38;5;241m*[39m[38;5;241m*[39mkwargs) [0;32m 66[0m [38;5;28;01mexcept[39;00m [38;5;167;01mException[39;00m [38;5;28;01mas[39;00m e: [0;32m 67[0m filtered_tb [38;5;241m=[39m _process_traceback_frames(e[38;5;241m.[39m__traceback__) File [1;32m~\miniconda3\lib\site-packages\keras\engine\training.py:1564[0m, in [0;36mModel.fit[1;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)[0m [0;32m 1556[0m [38;5;28;01mwith[39;00m tf[38;5;241m.[39mprofiler[38;5;241m.[39mexperimental[38;5;241m.[39mTrace( [0;32m 1557[0m [38;5;124m"[39m[38;5;124mtrain[39m[38;5;124m"[39m, [0;32m 1558[0m epoch_num[38;5;241m=[39mepoch, [1;32m (...)[0m [0;32m 1561[0m _r[38;5;241m=[39m[38;5;241m1[39m, [0;32m 1562[0m ): [0;32m 1563[0m callbacks[38;5;241m.[39mon_train_batch_begin(step) [1;32m-> 1564[0m tmp_logs [38;5;241m=[39m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mtrain_function[49m[43m([49m[43miterator[49m[43m)[49m [0;32m 1565[0m [38;5;28;01mif[39;00m data_handler[38;5;241m.[39mshould_sync: [0;32m 1566[0m context[38;5;241m.[39masync_wait() File [1;32m~\miniconda3\lib\site-packages\tensorflow\python\util\traceback_utils.py:150[0m, in [0;36mfilter_traceback.<locals>.error_handler[1;34m(*args, **kwargs)[0m [0;32m 148[0m filtered_tb [38;5;241m=[39m [38;5;28;01mNone[39;00m [0;32m 149[0m [38;5;28;01mtry[39;00m: [1;32m--> 150[0m [38;5;28;01mreturn[39;00m fn([38;5;241m*[39margs, [38;5;241m*[39m[38;5;241m*[39mkwargs) [0;32m 151[0m [38;5;28;01mexcept[39;00m [38;5;167;01mException[39;00m [38;5;28;01mas[39;00m e: [0;32m 152[0m filtered_tb [38;5;241m=[39m _process_traceback_frames(e[38;5;241m.[39m__traceback__) File [1;32m~\miniconda3\lib\site-packages\tensorflow\python\eager\def_function.py:915[0m, in [0;36mFunction.__call__[1;34m(self, *args, **kwds)[0m [0;32m 912[0m compiler [38;5;241m=[39m [38;5;124m"[39m[38;5;124mxla[39m[38;5;124m"[39m [38;5;28;01mif[39;00m [38;5;28mself[39m[38;5;241m.[39m_jit_compile [38;5;28;01melse[39;00m [38;5;124m"[39m[38;5;124mnonXla[39m[38;5;124m"[39m [0;32m 914[0m [38;5;28;01mwith[39;00m OptionalXlaContext([38;5;28mself[39m[38;5;241m.[39m_jit_compile): [1;32m--> 915[0m result [38;5;241m=[39m [38;5;28mself[39m[38;5;241m.[39m_call([38;5;241m*[39margs, [38;5;241m*[39m[38;5;241m*[39mkwds) [0;32m 917[0m new_tracing_count [38;5;241m=[39m [38;5;28mself[39m[38;5;241m.[39mexperimental_get_tracing_count() [0;32m 918[0m without_tracing [38;5;241m=[39m (tracing_count [38;5;241m==[39m new_tracing_count) File [1;32m~\miniconda3\lib\site-packages\tensorflow\python\eager\def_function.py:947[0m, in [0;36mFunction._call[1;34m(self, *args, **kwds)[0m [0;32m 944[0m [38;5;28mself[39m[38;5;241m.[39m_lock[38;5;241m.[39mrelease() [0;32m 945[0m [38;5;66;03m# In this case we have created variables on the first call, so we run the[39;00m [0;32m 946[0m [38;5;66;03m# defunned version which is guaranteed to never create variables.[39;00m [1;32m--> 947[0m [38;5;28;01mreturn[39;00m [38;5;28mself[39m[38;5;241m.[39m_stateless_fn([38;5;241m*[39margs, [38;5;241m*[39m[38;5;241m*[39mkwds) [38;5;66;03m# pylint: disable=not-callable[39;00m [0;32m 948[0m [38;5;28;01melif[39;00m [38;5;28mself[39m[38;5;241m.[39m_stateful_fn [38;5;129;01mis[39;00m [38;5;129;01mnot[39;00m [38;5;28;01mNone[39;00m: [0;32m 949[0m [38;5;66;03m# Release the lock early so that multiple threads can perform the call[39;00m [0;32m 950[0m [38;5;66;03m# in parallel.[39;00m [0;32m 951[0m [38;5;28mself[39m[38;5;241m.[39m_lock[38;5;241m.[39mrelease() File [1;32m~\miniconda3\lib\site-packages\tensorflow\python\eager\function.py:2496[0m, in [0;36mFunction.__call__[1;34m(self, *args, **kwargs)[0m [0;32m 2493[0m [38;5;28;01mwith[39;00m [38;5;28mself[39m[38;5;241m.[39m_lock: [0;32m 2494[0m (graph_function, [0;32m 2495[0m filtered_flat_args) [38;5;241m=[39m [38;5;28mself[39m[38;5;241m.[39m_maybe_define_function(args, kwargs) [1;32m-> 2496[0m [38;5;28;01mreturn[39;00m [43mgraph_function[49m[38;5;241;43m.[39;49m[43m_call_flat[49m[43m([49m [0;32m 2497[0m [43m [49m[43mfiltered_flat_args[49m[43m,[49m[43m [49m[43mcaptured_inputs[49m[38;5;241;43m=[39;49m[43mgraph_function[49m[38;5;241;43m.[39;49m[43mcaptured_inputs[49m[43m)[49m File [1;32m~\miniconda3\lib\site-packages\tensorflow\python\eager\function.py:1862[0m, in [0;36mConcreteFunction._call_flat[1;34m(self, args, captured_inputs, cancellation_manager)[0m [0;32m 1858[0m possible_gradient_type [38;5;241m=[39m gradients_util[38;5;241m.[39mPossibleTapeGradientTypes(args) [0;32m 1859[0m [38;5;28;01mif[39;00m (possible_gradient_type [38;5;241m==[39m gradients_util[38;5;241m.[39mPOSSIBLE_GRADIENT_TYPES_NONE [0;32m 1860[0m [38;5;129;01mand[39;00m executing_eagerly): [0;32m 1861[0m [38;5;66;03m# No tape is watching; skip to running the function.[39;00m [1;32m-> 1862[0m [38;5;28;01mreturn[39;00m [38;5;28mself[39m[38;5;241m.[39m_build_call_outputs([38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_inference_function[49m[38;5;241;43m.[39;49m[43mcall[49m[43m([49m [0;32m 1863[0m [43m [49m[43mctx[49m[43m,[49m[43m [49m[43margs[49m[43m,[49m[43m [49m[43mcancellation_manager[49m[38;5;241;43m=[39;49m[43mcancellation_manager[49m[43m)[49m) [0;32m 1864[0m forward_backward [38;5;241m=[39m [38;5;28mself[39m[38;5;241m.[39m_select_forward_and_backward_functions( [0;32m 1865[0m args, [0;32m 1866[0m possible_gradient_type, [0;32m 1867[0m executing_eagerly) [0;32m 1868[0m forward_function, args_with_tangents [38;5;241m=[39m forward_backward[38;5;241m.[39mforward() File [1;32m~\miniconda3\lib\site-packages\tensorflow\python\eager\function.py:499[0m, in [0;36m_EagerDefinedFunction.call[1;34m(self, ctx, args, cancellation_manager)[0m [0;32m 497[0m [38;5;28;01mwith[39;00m _InterpolateFunctionError([38;5;28mself[39m): [0;32m 498[0m [38;5;28;01mif[39;00m cancellation_manager [38;5;129;01mis[39;00m [38;5;28;01mNone[39;00m: [1;32m--> 499[0m outputs [38;5;241m=[39m [43mexecute[49m[38;5;241;43m.[39;49m[43mexecute[49m[43m([49m [0;32m 500[0m [43m [49m[38;5;28;43mstr[39;49m[43m([49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43msignature[49m[38;5;241;43m.[39;49m[43mname[49m[43m)[49m[43m,[49m [0;32m 501[0m [43m [49m[43mnum_outputs[49m[38;5;241;43m=[39;49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_num_outputs[49m[43m,[49m [0;32m 502[0m [43m [49m[43minputs[49m[38;5;241;43m=[39;49m[43margs[49m[43m,[49m [0;32m 503[0m [43m [49m[43mattrs[49m[38;5;241;43m=[39;49m[43mattrs[49m[43m,[49m [0;32m 504[0m [43m [49m[43mctx[49m[38;5;241;43m=[39;49m[43mctx[49m[43m)[49m [0;32m 505[0m [38;5;28;01melse[39;00m: [0;32m 506[0m outputs [38;5;241m=[39m execute[38;5;241m.[39mexecute_with_cancellation( [0;32m 507[0m [38;5;28mstr[39m([38;5;28mself[39m[38;5;241m.[39msignature[38;5;241m.[39mname), [0;32m 508[0m num_outputs[38;5;241m=[39m[38;5;28mself[39m[38;5;241m.[39m_num_outputs, [1;32m (...)[0m [0;32m 511[0m ctx[38;5;241m=[39mctx, [0;32m 512[0m cancellation_manager[38;5;241m=[39mcancellation_manager) File [1;32m~\miniconda3\lib\site-packages\tensorflow\python\eager\execute.py:54[0m, in [0;36mquick_execute[1;34m(op_name, num_outputs, inputs, attrs, ctx, name)[0m [0;32m 52[0m [38;5;28;01mtry[39;00m: [0;32m 53[0m ctx[38;5;241m.[39mensure_initialized() [1;32m---> 54[0m tensors [38;5;241m=[39m [43mpywrap_tfe[49m[38;5;241;43m.[39;49m[43mTFE_Py_Execute[49m[43m([49m[43mctx[49m[38;5;241;43m.[39;49m[43m_handle[49m[43m,[49m[43m [49m[43mdevice_name[49m[43m,[49m[43m [49m[43mop_name[49m[43m,[49m [0;32m 55[0m [43m [49m[43minputs[49m[43m,[49m[43m [49m[43mattrs[49m[43m,[49m[43m [49m[43mnum_outputs[49m[43m)[49m [0;32m 56[0m [38;5;28;01mexcept[39;00m core[38;5;241m.[39m_NotOkStatusException [38;5;28;01mas[39;00m e: [0;32m 57[0m [38;5;28;01mif[39;00m name [38;5;129;01mis[39;00m [38;5;129;01mnot[39;00m [38;5;28;01mNone[39;00m: [1;31mKeyboardInterrupt[0m: