<jupyter_start><jupyter_text><jupyter_code>#creating a basic binary text classification system using IMDB Dataset.
# it classifies a movie review either as positive or negative
import matplotlib.pyplot as plt
import os
import re
import shutil
import string
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras import losses
from tensorflow.keras import preprocessing
from tensorflow.keras.layers.experimental.preprocessing import TextVectorization
#download the dataset

url = "https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz"

dataset = tf.keras.utils.get_file("aclImdb_v1.tar.gz", url,
                                    untar=True, cache_dir='.',
                                    cache_subdir='')

dataset_dir = os.path.join(os.path.dirname(dataset), 'aclImdb')
print(dataset_dir)
print(os.listdir(dataset_dir))
train_dir = os.path.join(dataset_dir, 'train')
os.listdir(train_dir)
sample_file = os.path.join(train_dir, 'pos/1181_9.txt')
with open(sample_file) as f:
  print(f.read())
#removing unnecessary files
remove_dir = os.path.join(train_dir, 'unsup')
shutil.rmtree(remove_dir)
batch_size = 32
seed = 42

raw_train_ds = tf.keras.preprocessing.text_dataset_from_directory(
    'aclImdb/train',
    batch_size = batch_size,
    validation_split = 0.2,
    subset = 'training',
    seed = seed
)
type(raw_train_ds)
for text_batch, label_batch in raw_train_ds.take(1):
  for i in range(3):
    print("Review", text_batch.numpy()[i])
    print("Label", label_batch.numpy()[i])
print("Label 0 corresponds to", raw_train_ds.class_names[0])
print("Label 1 corresponds to", raw_train_ds.class_names[1])
#let us create a validation set. here we set the subset to 'Validation'
raw_val_ds = tf.keras.preprocessing.text_dataset_from_directory(
    'aclImdb/train',
    batch_size = batch_size,
    validation_split = 0.2,
    subset = 'validation',
    seed = seed
)
#let us create a test dataset
raw_test_ds = tf.keras.preprocessing.text_dataset_from_directory(
    'aclImdb/train',
    batch_size = batch_size
)
#standardization, ex : remove punctuation or html elements.
#tokenization, splitting string into token like splitting the sentence into words
#vectorization, it is the process of converting token into number

def custom_standardization(input_data):
  lowercase = tf.strings.lower(input_data) #make all text lowercase
  stripped_html = tf.strings.regex_replace(lowercase, '<br />',' ') # strip out the html tags using regex replace
  return tf.strings.regex_replace(stripped_html, '[%s]' % re.escape(string.punctuation), '') #replace space charachters with space
max_features = 10000
sequence_length = 250

vectorize_layer = TextVectorization(
    standardize = custom_standardization,
    max_tokens = max_features,
    output_mode = 'int',
    output_sequence_length = sequence_length
)
iter(raw_train_ds).next()
# let us remove the label that is present in the batch dataset
train_text = raw_train_ds.map(lambda x,y : x)
vectorize_layer.adapt(train_text) #this takes in the word dataset and vectorizes it according to the vectorization configutation that we had set up earlier
#creating a method to vectorize a text 
#input text  and label for that particular text

def vectorize_text(text, label):
  text = tf.expand_dims(text,-1)
  return vectorize_layer(text), label

text_batch, label_batch = next(iter(raw_train_ds))
first_review, first_label = text_batch[0], label_batch[0]
print("Review", first_review)
print("Label", raw_train_ds.class_names[first_label])
print("Vectorized review", vectorize_text(first_review, first_label))
# we can use the formatted vectors and find it's corresponding word using get_vocabulary method
print("1285 ---> ",vectorize_layer.get_vocabulary()[1285])
print(" 673 ---> ",vectorize_layer.get_vocabulary()[673])
print('Vocabulary size: {}'.format(len(vectorize_layer.get_vocabulary())))
train_ds = raw_train_ds.map(vectorize_text)
val_ds = raw_val_ds.map(vectorize_text)
test_ds = raw_test_ds.map(vectorize_text)
#creating a cache inorder to make sure data processing does not become a bottle neck while running a model
AUTOTUNE = tf.data.experimental.AUTOTUNE 

train_ds = train_ds.cache().prefetch(buffer_size = AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size = AUTOTUNE)
test_ds = test_ds.cache().prefetch(buffer_size = AUTOTUNE)
embedding_dim = 16

model = tf.keras.Sequential([
  layers.Embedding(max_features + 1, embedding_dim),
  layers.Dropout(0.2),
  layers.GlobalAveragePooling1D(),
  layers.Dropout(0.2),
  layers.Dense(1)])

model.summary()
embedding_dim = 16

model = tf.keras.Sequential([
  layers.Embedding(max_features + 1, embedding_dim),
  layers.Dropout(0.2),
  layers.GlobalAveragePooling1D(),
  layers.Dropout(0.2),
  layers.Dense(1)])

model.summary()
model.compile(loss=losses.BinaryCrossentropy(from_logits=True), optimizer='adam', metrics=tf.metrics.BinaryAccuracy(threshold=0.0))

epochs = 10
history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=epochs)
loss, accuracy = model.evaluate(test_ds)

print("Loss: ", loss)
print("Accuracy: ", accuracy)
# creating an accuracy plot for training and validation process
history_dict = history.history
history_dict.keys()
train_acc = history_dict['binary_accuracy']
validation_acc = history_dict['val_binary_accuracy']

epochs = range(1, len(train_acc)+1)

plt.plot(epochs,train_acc, 'bo', label = 'Training Accuracy')
plt.plot(epochs, validation_acc, 'b', label = 'Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()

plt.show()

train_loss = history_dict['loss']
validation_loss = history_dict['val_loss']

epochs = range(1, len(train_acc)+1)

plt.plot(epochs,train_loss, 'bo', label = 'Training Loss')
plt.plot(epochs, validation_loss, 'b', label = 'Validation Loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()

plt.show()
export_model = tf.keras.Sequential([
  vectorize_layer,
  model,
  layers.Activation('sigmoid')
])

export_model.compile(
    loss=losses.BinaryCrossentropy(from_logits=False), optimizer="adam", metrics=['accuracy']
)

# Test it with `raw_test_ds`, which yields raw strings
loss, accuracy = export_model.evaluate(raw_test_ds)
print(accuracy)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11434906556857777, 'fraction_numerical': 0.011403230915426037, 'mean_word_length': 5.626442812172088, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 8, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '537999', 'license': 'MIT', 'n_tokens_mistral': 2158, 'n_tokens_neox': 2085, 'n_words': 491, 'path': 'BinaryTextClassification.ipynb', 'repo_name': 'raiadi96/Pytorch', 'size': '6314'}