<jupyter_start><jupyter_text>Introduction to binary classification using Keras and Tensorflow  1. Create a DataFrame of the images filenames and class labelsWe will use this `DataFrame` to create the training, validation, and testing image generators.<jupyter_code>filepaths = glob.glob("../data/raw/dogs-vs-cats-redux-kernel-edition/train/*.jpg")
data = {"filename": [], "class": []}
for filepath in filepaths:
    filename = filepath.split('/')[-1]
    data["filename"].append(filename)
    if filename.startswith("dog"):
        data["class"].append(1)
    else:
        data["class"].append(0)

df = pd.DataFrame.from_dict(data)
df.info()
df.head()
df.tail()<jupyter_output><empty_output><jupyter_text>2. Split the training data into training and validation setsDividing the full training data set into training and validation data sets will help us make sure that we are not overfitting out models. Once we have identified a good model architecture we will re-train using the full data set prior to making predictions.<jupyter_code>_prng = np.random.RandomState(42)
training_df, validation_df = model_selection.train_test_split(df,
                                                              test_size=0.1,
                                                              random_state=_prng,
                                                              shuffle=True)

# flow_from_dataframe expects a particular index!
training_df.reset_index(drop=True, inplace=True)
validation_df.reset_index(drop=True, inplace=True)
training_df.info()
training_df.head()
NUMBER_TRAINING_SAMPLES, _ = training_df.shape
validation_df.info()
validation_df.head()
NUMBER_VALIDATION_SAMPLES, _ = validation_df.shape<jupyter_output><empty_output><jupyter_text>3. Training and Validation PreprocessingTo start we need to rescale the images so that the images are represented as arrays of floating point numbers between 0 and 1 instead of arrays of integers between 0 and 255. We also need to resize the images so that all images have the same width and height as measured by pixels.  We will discuss more advanced preprocessing in a later section on data augmentation.<jupyter_code>TARGET_SIZE = (160, 160)
INPUT_SHAPE = TARGET_SIZE + (3,)
BATCH_SIZE = 20

_generator_kwargs = {"rescale": 1 / 255}

_training_flow_kwargs = {"dataframe": training_df,
                         "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/train/",
                         "target_size": TARGET_SIZE,
                         "class_mode": "binary",
                         "batch_size": BATCH_SIZE,
                         "seed": 42}

training_data_flow = (keras.preprocessing
                           .image
                           .ImageDataGenerator(**_generator_kwargs)
                           .flow_from_dataframe(**_training_flow_kwargs))
                     
_validation_flow_kwargs = {"dataframe": validation_df,
                           "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/train/",
                           "target_size": TARGET_SIZE,
                           "class_mode": "binary",
                           "batch_size": BATCH_SIZE,
                           "seed": 24}

validation_data_flow = (keras.preprocessing
                             .image
                             .ImageDataGenerator(**_generator_kwargs)
                             .flow_from_dataframe(**_validation_flow_kwargs))<jupyter_output>Found 22500 images belonging to 2 classes.
Found 2500 images belonging to 2 classes.<jupyter_text>4. Define a benchmark CNN modelIn this section we roll our own CNN model to provide a benchmark submission.<jupyter_code>model_fn = keras.models.Sequential([
    keras.layers.Conv2D(filters=32, kernel_size=(3,3), input_shape=INPUT_SHAPE),
    keras.layers.BatchNormalization(),
    keras.layers.ReLU(),
    keras.layers.MaxPool2D(pool_size=(2,2)),
    keras.layers.Conv2D(filters=64, kernel_size=(3,3)),
    keras.layers.BatchNormalization(),
    keras.layers.ReLU(),
    keras.layers.MaxPool2D(pool_size=(2,2)),
    keras.layers.Conv2D(filters=128, kernel_size=(3,3)),
    keras.layers.BatchNormalization(),
    keras.layers.ReLU(),
    keras.layers.MaxPool2D(pool_size=(2,2)),
    keras.layers.Flatten(),
    keras.layers.Dense(512),
    keras.layers.BatchNormalization(),
    keras.layers.ReLU(),
    keras.layers.Dense(1, activation="sigmoid")
])

optimzer = keras.optimizers.RMSprop(lr=1e-3)

loss_fn = keras.losses.BinaryCrossentropy()

_metrics = [
    keras.metrics.BinaryAccuracy(),
    keras.metrics.Recall()
]

model_fn.compile(optimzer, loss_fn, metrics=_metrics)
model_fn.summary()<jupyter_output>_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 126, 126, 16)      448       
_________________________________________________________________
batch_normalization_v1 (Batc (None, 126, 126, 16)      64        
_________________________________________________________________
re_lu (ReLU)                 (None, 126, 126, 16)      0         
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 63, 63, 16)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 61, 61, 32)        4640      
_________________________________________________________________
batch_normalization_v1_1 (Ba (None, 61, 61, 32)        128       
_________________________________________________________________
re_lu_1 (R[...]<jupyter_text>4.1 Define the training loop<jupyter_code>_callbacks = [
    keras.callbacks.ReduceLROnPlateau(monitor='val_binary_accuracy', patience=2, verbose=1, factor=0.5, min_lr=0.00001),
    keras.callbacks.EarlyStopping(patience=10)
]

training_metrics = model_fn.fit_generator(training_data_flow,
                                          epochs=5,
                                          steps_per_epoch=NUMBER_TRAINING_SAMPLES // BATCH_SIZE,
                                          callbacks=_callbacks,
                                          validation_data=validation_data_flow,
                                          validation_steps=NUMBER_VALIDATION_SAMPLES // BATCH_SIZE,
                                          verbose=1)<jupyter_output>WARNING:tensorflow:From /home/pughdr/.conda/envs/tensorflow-gpu-tutorials/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
Epoch 1/5
167/167 [==============================] - 35s 209ms/step - loss: 0.5006 - binary_accuracy: 0.7624 - recall: 0.6248
1500/1500 [==============================] - 377s 252ms/step - loss: 0.5662 - binary_accuracy: 0.7164 - recall: 0.7013 - val_loss: 0.5006 - val_binary_accuracy: 0.7624 - val_recall: 0.6248
Epoch 2/5
167/167 [==============================] - 19s 111ms/step - loss: 0.4168 - binary_accuracy: 0.8132 - recall: 0.8469
1500/1500 [==============================] - 198s 132ms/step - loss: 0.4392 - binary_accuracy: 0.8004 - recall: 0.7917 - val_loss: 0.4168 - val_binary_accuracy: 0.8132 - val_recall: 0.8469
Epoch 3/5
167/167 [==============================] - 17s 102ms/step - loss: 0.[...]<jupyter_text>4.2 Exploring training history<jupyter_code>history_df = (pd.DataFrame
                .from_dict(training_metrics.history))
history_df.head()
_ = (history_df.loc[:, ["loss", "val_loss"]]
               .plot())<jupyter_output><empty_output><jupyter_text>5. Image Augmentation to reduce over-fittingImage augmentation is a simple but powerful tool to help you avoid over-fitting your raw data. Check out the Keras preprocessing module documantion for the details.Data augmentation is _NOT_ done on disk but rather in memory!<jupyter_code>TARGET_SIZE = (160, 160)
INPUT_SHAPE = TARGET_SIZE + (3,)
BATCH_SIZE = 20

model_fn = keras.models.Sequential([
    keras.layers.Conv2D(filters=32, kernel_size=(3,3), input_shape=INPUT_SHAPE),
    keras.layers.BatchNormalization(),
    keras.layers.ReLU(),
    keras.layers.MaxPool2D(pool_size=(2,2)),
    keras.layers.Conv2D(filters=64, kernel_size=(3,3)),
    keras.layers.BatchNormalization(),
    keras.layers.ReLU(),
    keras.layers.MaxPool2D(pool_size=(2,2)),
    keras.layers.Conv2D(filters=128, kernel_size=(3,3)),
    keras.layers.BatchNormalization(),
    keras.layers.ReLU(),
    keras.layers.MaxPool2D(pool_size=(2,2)),
    keras.layers.Flatten(),
    keras.layers.Dense(512),
    keras.layers.BatchNormalization(),
    keras.layers.ReLU(),
    keras.layers.Dense(1, activation="sigmoid")
])

optimzer = keras.optimizers.RMSprop()

loss_fn = keras.losses.BinaryCrossentropy()

_metrics = [
    keras.metrics.BinaryAccuracy(),
    keras.metrics.Recall()
]

model_fn.compile(optimzer, loss_fn, metrics=_metrics)
_training_generator_kwargs = {"rotation_range": 40,
                              "rescale": 1 / 255,
                              "shear_range": 0.2,
                              "zoom_range": 0.2,
                              "horizontal_flip": True,
                              "width_shift_range": 0.2,
                              "height_shift_range": 0.2,
                              "fill_mode": "nearest"}

_training_flow_kwargs = {"dataframe": training_df,
                         "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/train/",
                         "target_size": TARGET_SIZE,
                         "class_mode": "binary",
                         "batch_size": BATCH_SIZE,
                         "seed": 42}

training_data_flow = (keras.preprocessing
                           .image
                           .ImageDataGenerator(**_training_generator_kwargs)
                           .flow_from_dataframe(**_training_flow_kwargs))
                    
_validation_generator_kwargs = {"rescale": 1 / 255}

_validation_flow_kwargs = {"dataframe": validation_df,
                           "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/train/",
                           "target_size": TARGET_SIZE,
                           "class_mode": "binary",
                           "batch_size": BATCH_SIZE,
                           "seed": 24}

validation_data_flow = (keras.preprocessing
                             .image
                             .ImageDataGenerator(**_validation_generator_kwargs)
                             .flow_from_dataframe(**_validation_flow_kwargs))
_callbacks = [
    keras.callbacks.ReduceLROnPlateau(monitor='val_binary_accuracy', patience=2, verbose=1, factor=0.5, min_lr=0.00001),
    keras.callbacks.EarlyStopping(patience=10)
]

training_metrics = model_fn.fit_generator(training_data_flow,
                                          epochs=100,
                                          steps_per_epoch=NUMBER_TRAINING_SAMPLES // BATCH_SIZE,
                                          callbacks=_callbacks,
                                          validation_data=validation_data_flow,
                                          validation_steps=NUMBER_VALIDATION_SAMPLES // BATCH_SIZE,
                                          verbose=1)
history_df = (pd.DataFrame
                .from_dict(training_metrics.history))<jupyter_output><empty_output><jupyter_text>Over-fitting problem as been solved by data augmentation!<jupyter_code>_ = (history_df.loc[:, ["loss", "val_loss"]]
               .plot())<jupyter_output><empty_output><jupyter_text>6. Improving the model using transfer learning<jupyter_code>keras.applications.MobileNetV2?
feature_extractor = (keras.applications
                          .MobileNetV2(input_shape=INPUT_SHAPE, include_top=False, weights="imagenet"))

feature_extractor.trainable = False

model_fn = keras.models.Sequential([
    feature_extractor,
    keras.layers.GlobalAveragePooling2D(),
    keras.layers.Dense(1, activation="sigmoid")
])

optimzer = keras.optimizers.RMSprop(lr=1e-3)

loss_fn = keras.losses.BinaryCrossentropy()

_metrics = [
    keras.metrics.BinaryAccuracy(),
    keras.metrics.Recall()
]

model_fn.compile(optimzer, loss_fn, metrics=_metrics)
model_fn.summary()
_training_generator_kwargs = {"rotation_range": 40,
                              "rescale": 1 / 255,
                              "shear_range": 0.2,
                              "zoom_range": 0.2,
                              "horizontal_flip": True,
                              "width_shift_range": 0.2,
                              "height_shift_range": 0.2,
                              "fill_mode": "nearest"}

_training_flow_kwargs = {"dataframe": training_df,
                         "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/train/",
                         "target_size": TARGET_SIZE,
                         "class_mode": "binary",
                         "batch_size": BATCH_SIZE,
                         "seed": 42}

training_data_flow = (keras.preprocessing
                           .image
                           .ImageDataGenerator(**_training_generator_kwargs)
                           .flow_from_dataframe(**_training_flow_kwargs))
                    
_validation_generator_kwargs = {"rescale": 1 / 255}

_validation_flow_kwargs = {"dataframe": validation_df,
                           "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/train/",
                           "target_size": TARGET_SIZE,
                           "class_mode": "binary",
                           "batch_size": BATCH_SIZE,
                           "seed": 24}

validation_data_flow = (keras.preprocessing
                             .image
                             .ImageDataGenerator(**_validation_generator_kwargs)
                             .flow_from_dataframe(**_validation_flow_kwargs))
_callbacks = [
    keras.callbacks.ReduceLROnPlateau(monitor='val_binary_accuracy', patience=2, verbose=1, factor=0.5, min_lr=0.00001),
    keras.callbacks.EarlyStopping(patience=10)
]

training_metrics = model_fn.fit_generator(training_data_flow,
                                          epochs=100,
                                          steps_per_epoch=NUMBER_TRAINING_SAMPLES // BATCH_SIZE,
                                          callbacks=_callbacks,
                                          validation_data=validation_data_flow,
                                          validation_steps=NUMBER_VALIDATION_SAMPLES // BATCH_SIZE,
                                          verbose=1)
history_df = (pd.DataFrame
                .from_dict(training_metrics.history))
_ = (history_df.loc[:, ["binary_accuracy", "val_binary_accuracy"]]
               .plot())
_ = (history_df.loc[:, ["loss", "val_loss"]]
               .plot())<jupyter_output><empty_output><jupyter_text>6.1 Fine-tuning a model by retraining last few layers<jupyter_code>feature_extractor = (keras.applications
                          .MobileNetV2(input_shape=INPUT_SHAPE, include_top=False, weights="imagenet"))

start_fine_tuning_at = 100
for layer in feature_extractor.layers[:start_fine_tuning_at]:
    layer.trainable = False

model_fn = keras.models.Sequential([
    feature_extractor,
    keras.layers.GlobalAveragePooling2D(),
    keras.layers.Dense(1, activation="sigmoid")
])

optimzer = keras.optimizers.RMSprop(lr=1e-3)

loss_fn = keras.losses.BinaryCrossentropy()

_metrics = [
    keras.metrics.BinaryAccuracy(),
    keras.metrics.Recall()
]

model_fn.compile(optimzer, loss_fn, metrics=_metrics)
_training_generator_kwargs = {"rotation_range": 40,
                              "rescale": 1 / 255,
                              "shear_range": 0.2,
                              "zoom_range": 0.2,
                              "horizontal_flip": True,
                              "width_shift_range": 0.2,
                              "height_shift_range": 0.2,
                              "fill_mode": "nearest"}

_training_flow_kwargs = {"dataframe": training_df,
                         "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/train/",
                         "target_size": TARGET_SIZE,
                         "class_mode": "binary",
                         "batch_size": BATCH_SIZE,
                         "seed": 42}

training_data_flow = (keras.preprocessing
                           .image
                           .ImageDataGenerator(**_training_generator_kwargs)
                           .flow_from_dataframe(**_training_flow_kwargs))
                    
_validation_generator_kwargs = {"rescale": 1 / 255}

_validation_flow_kwargs = {"dataframe": validation_df,
                           "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/train/",
                           "target_size": TARGET_SIZE,
                           "class_mode": "binary",
                           "batch_size": BATCH_SIZE,
                           "seed": 24}

validation_data_flow = (keras.preprocessing
                             .image
                             .ImageDataGenerator(**_validation_generator_kwargs)
                             .flow_from_dataframe(**_validation_flow_kwargs))
_callbacks = [
    keras.callbacks.ReduceLROnPlateau(monitor='val_binary_accuracy', patience=2, verbose=1, factor=0.5, min_lr=0.00001),
    keras.callbacks.EarlyStopping(patience=10)
]

training_metrics = model_fn.fit_generator(training_data_flow,
                                          epochs=100,
                                          steps_per_epoch=NUMBER_TRAINING_SAMPLES // BATCH_SIZE,
                                          callbacks=_callbacks,
                                          validation_data=validation_data_flow,
                                          validation_steps=NUMBER_VALIDATION_SAMPLES // BATCH_SIZE,
                                          verbose=1)
history_df = (pd.DataFrame
                .from_dict(training_metrics.history))

_ = (history_df.loc[:, ["binary_accuracy", "val_binary_accuracy"]]
               .plot())
_ = (history_df.loc[:, ["loss", "val_loss"]]
               .plot())<jupyter_output><empty_output><jupyter_text>7. Retrain the model using all available training data<jupyter_code># define the model
TARGET_SIZE = (160, 160)
INPUT_SHAPE = TARGET_SIZE + (3,)
BATCH_SIZE = 20

feature_extractor = (keras.applications
                          .MobileNetV2(input_shape=INPUT_SHAPE, include_top=False, weights="imagenet"))

start_fine_tuning_at = 100
for layer in feature_extractor.layers[:start_fine_tuning_at]:
    layer.trainable = False

model_fn = keras.models.Sequential([
    feature_extractor,
    keras.layers.GlobalAveragePooling2D(),
    keras.layers.Dense(1, activation="sigmoid")
])

optimzer = keras.optimizers.RMSprop(lr=1e-3)

loss_fn = keras.losses.BinaryCrossentropy()

_metrics = [
    keras.metrics.BinaryAccuracy(),
]

model_fn.compile(optimzer, loss_fn, metrics=_metrics)

# define the data flow for training images
_training_generator_kwargs = {"rotation_range": 40,
                              "rescale": 1 / 255,
                              "shear_range": 0.2,
                              "zoom_range": 0.2,
                              "horizontal_flip": True,
                              "width_shift_range": 0.2,
                              "height_shift_range": 0.2,
                              "fill_mode": "nearest"}

_training_flow_kwargs = {"dataframe": df,
                         "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/train/",
                         "target_size": TARGET_SIZE,
                         "class_mode": "binary",
                         "batch_size": BATCH_SIZE,
                         "seed": 42}

training_data_flow = (keras.preprocessing
                           .image
                           .ImageDataGenerator(**_training_generator_kwargs)
                           .flow_from_dataframe(**_training_flow_kwargs))


# define the training loop
_callbacks = [
    keras.callbacks.ReduceLROnPlateau(monitor='binary_accuracy', patience=2, verbose=1, factor=0.5, min_lr=0.00001),
    keras.callbacks.EarlyStopping(monitor="loss", patience=10)
]

training_metrics = model_fn.fit_generator(training_data_flow,
                                          epochs=100,
                                          steps_per_epoch=25000 // BATCH_SIZE,
                                          callbacks=_callbacks,
                                          verbose=1)<jupyter_output>Found 25000 images belonging to 2 classes.
Epoch 1/100
1250/1250 [==============================] - 314s 251ms/step - loss: 0.2040 - binary_accuracy: 0.9243
Epoch 2/100
1250/1250 [==============================] - 297s 237ms/step - loss: 0.1345 - binary_accuracy: 0.9500
Epoch 3/100
1250/1250 [==============================] - 302s 242ms/step - loss: 0.1104 - binary_accuracy: 0.9603
Epoch 4/100
1250/1250 [==============================] - 299s 239ms/step - loss: 0.1019 - binary_accuracy: 0.9629
Epoch 5/100
1250/1250 [==============================] - 304s 243ms/step - loss: 0.0902 - binary_accuracy: 0.9668
Epoch 6/100
1250/1250 [==============================] - 299s 239ms/step - loss: 0.0874 - binary_accuracy: 0.9693
Epoch 7/100
1250/1250 [==============================] - 297s 238ms/step - loss: 0.0813 - binary_accuracy: 0.9710
Epoch 8/100
1250/1250 [==============================] - 289s 231ms/step - loss: 0.0794 - binary_accuracy: 0.9717
Epoch 9/100
1250/1250 [======================[...]<jupyter_text>8. Submit predictions to Kaggle!<jupyter_code>filepaths = glob.glob("../data/raw/dogs-vs-cats-redux-kernel-edition/test/*.jpg")
data = {"filename": []}
for filepath in filepaths:
    filename = filepath.split('/')[-1]
    data["filename"].append(filename)

testing_df = (pd.DataFrame
                .from_dict(data)
                .reset_index(drop=True))

NUMBER_TESTING_SAMPLES, _ = testing_df.shape<jupyter_output><empty_output><jupyter_text>8.1 Create the testing image generator<jupyter_code>_testing_generator_kwargs = {"rescale": 1 / 255}

_testing_flow_kwargs = {"dataframe": testing_df,
                        "directory": "../data/raw/dogs-vs-cats-redux-kernel-edition/test/",
                        "target_size": TARGET_SIZE,
                        "y_col": None,
                        "class_mode": None,
                        "batch_size": BATCH_SIZE,
                        "shuffle": False}

testing_data_flow = (keras.preprocessing
                          .image
                          .ImageDataGenerator(**_testing_generator_kwargs)
                          .flow_from_dataframe(**_testing_flow_kwargs))<jupyter_output>Found 12500 images.<jupyter_text>8.2 Make predictions<jupyter_code>if NUMBER_TESTING_SAMPLES % BATCH_SIZE == 0:
    NUMBER_PREDICTION_STEPS = (NUMBER_TESTING_SAMPLES // BATCH_SIZE)
else:
    NUMBER_PREDICTION_STEPS = (NUMBER_TESTING_SAMPLES // BATCH_SIZE) + 1

predictions = model_fn.predict_generator(testing_data_flow,
                                         steps=NUMBER_PREDICTION_STEPS,
                                         verbose=1)
fig, axes = plt.subplots(3, 3, sharex=True, sharey=True, figsize=(10, 10))

idx = 0
for i in range(3):
    for j in range(3):
        filename = testing_df.loc[idx, "filename"]
        probability = predictions[idx, 0]
        category = "dog" if probability >= 0.5 else "cat"
        _filepath = f"../data/raw/dogs-vs-cats-redux-kernel-edition/test/{filename}"
        img = (keras.preprocessing
                    .image
                    .load_img(_filepath, target_size=TARGET_SIZE))
        axes[i, j].imshow(img)
        axes[i, j].set_title(f"{filename} is a {category}")
        idx += 1

fig.tight_layout()<jupyter_output><empty_output><jupyter_text>8.3 Create the submission file<jupyter_code>import os
import time

if not os.path.isdir("../data/kaggle-submissions/dogs-vs-cats-redux-kernel-edition/"):
    os.makedirs("../data/kaggle-submissions/dogs-vs-cats-redux-kernel-edition/")

timestamp = time.strftime("%Y%m%d-%H%M%S")
(pd.DataFrame({"id": range(1, NUMBER_TESTING_SAMPLES + 1), "label": predictions.ravel()})
   .to_csv(f"../data/kaggle-submissions/dogs-vs-cats-redux-kernel-edition/submission-{timestamp}.csv", index=False))
!head $(ls ../data/kaggle-submissions/dogs-vs-cats-redux-kernel-edition/submission-*.csv | tail -n 1)
!tail $(ls ../data/kaggle-submissions/dogs-vs-cats-redux-kernel-edition/submission-*.csv | tail -n 1)
%%bash
export KAGGLE_USERNAME="YOUR_USERNAME"
export KAGGLE_KEY="YOUR_API_KEY"
kaggle competitions submit dogs-vs-cats-redux-kernels-edition \
  -f $(ls ../data/kaggle-submissions/dogs-vs-cats-redux-kernel-edition/submission-*.csv | tail -n 1) \
  -m "Fine-tuned transfer learning using MobileNetV2 with imagenet weights."<jupyter_output>Successfully submitted to Dogs vs. Cats Redux: Kernels Edition
{'fraction_non_alphanumeric': 0.12362648339793024, 'fraction_numerical': 0.03328405322251968, 'mean_word_length': 2.246594889090673, 'pattern_counts': {'":': 103, '<': 55, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 66, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '576704', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 7905, 'n_tokens_neox': 7202, 'n_words': 1248, 'path': 'dogs-vs-cats-redux-kernel-edition/notebooks/intro-to-binary-classification-using-keras.ipynb', 'repo_name': 'kaust-vislab/tensorflow-tutorials', 'size': '25027'}