Bináris osztályozás

Feladat:

Ha két osztály elemeit kell megkülönböztetni, akkor bináris osztályozásnak, vagy logisztikus regressziónak is hívják a feladatot. A kimenet 0 és 1 közötti szám, amely minél közelebb van a két véglethez, annál biztosabb a modell a döntésben. Ha a kimenet 0.5-höz nagyon közel van, akkor a modell valószínűleg rosszul működik.

CNN: Konvolúció, Max pooling

A konvolúciós neurális hálók nevükből adódóan konvolúciós rétegeket tartalmaznak, adott méretű és számú kernelt rétegenként. Megadható a stride paraméter, azaz a konvolúció során használt lépésköz is. Általában a konvolúciós rétegeket max pooling rétegek követik. Egy 2x2 max pooling réteg felére csökkenti a kimenetet, közben mindenhol a megtekintett 4 elem legnagyobbikát válaszja. Kisebb adattal könnyebb dolgozni.

Batch size

Legtöbbször nem lehetséges a teljes tanuló adathalmazt egyben betáplálni az algoritmusnak, ennek oka a nagy mérete és a tanításhoz használt eszköz memóriakorlátja. A megoldás az, hogy kis méretű csoportokra kell felosztani az adatot, ez a batch. A batch size paraméter a minták száma egy csoportban.

Epoch

Maga a tanítás egy iteratív folyamat. Egy epoch alatt az iterációk száma megegyezik azzal, hogy hány batch adja ki a teljes adathalmazt. Minden epoch alatt a teljes adathalmaz keresztül áramlik a hálón, így hangolva a súlyokat, konvolúciós kerneleket. Ideálisan minden epoch alatt nő a pontosság, majd egy idő után alig.

Segédlet

Keras telepítése: https://keras.io/getting_started

TensorFlow telepítése: https://www.tensorflow.org/install

MNIST képek: Letöltés

Forráskód: Modell tanítása

        
from keras import utils, layers, Sequential

# Load and preprocess images
data_dir = "path-to-resources/mnist-binary/train"
train_data, val_data = utils.image_dataset_from_directory(
    data_dir,
    labels = "inferred",
    label_mode = "binary",
    batch_size = 128, # Default would be 32
    image_size = (28, 28),
    color_mode = "grayscale",
    subset = "both",
    validation_split = 0.2,  # 20% of data used for validation
    seed = 123  # Optional random seed for shuffling and transformations
)

# Normalize the images
train_data = train_data.map(lambda image, label: (image / 255.0, label))
val_data = val_data.map(lambda image, label: (image / 255.0, label))

# Build the CNN model
model = Sequential([
        layers.Input(shape = (28, 28, 1)),
        layers.Conv2D(32, kernel_size = (3, 3), activation = "relu"),
        layers.MaxPooling2D(pool_size = (2, 2)),
        layers.Conv2D(64, kernel_size = (3, 3), activation = "relu"),
        layers.MaxPooling2D(pool_size = (2, 2)),
        layers.Flatten(),
        layers.Dropout(0.5),
        layers.Dense(1, activation="sigmoid"),
])
model.compile(loss = "binary_crossentropy", optimizer = "adam", metrics = ["accuracy"])
model.summary()

# Train the model for 10 epochs
model.fit(train_data, epochs = 10, validation_data = val_data)

# Evaluate the trained model
score = model.evaluate(val_data, verbose=0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])

# Save the model in a '.keras' file
model.save('mnist_binary_classifier.keras')        
      

Forráskód: Modell tesztelése

        
import os
from keras import models
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

# Load the saved model
model = models.load_model('mnist_binary_classifier.keras')

test_folder = 'path-to-resources/mnist-binary/test'

# Define classes
class_1 = 7 # Would also work as "Seven"
class_2 = 8 # Would also work as "Eight"

# Function to load and preprocess an image
def preprocess_image(img_path):
    img = Image.open(img_path).convert("L")
    img = img.resize((28, 28))
    img_data = np.array(img, dtype=np.uint8)
    img_data = img_data / 255.0  # Normalize pixel values
    img_data = np.expand_dims(img_data, axis=0)  # Add a new axis at the 0th position (batch)
    return img, img_data

# Get a list of all image files in the folder
test_image_paths = [os.path.join(test_folder, fname) for fname in os.listdir(test_folder) if fname.endswith(('.jpg'))]

# Loop through each image, preprocess, predict, and display the result
plt.figure(figsize=(10, 5))
for i, img_path in enumerate(test_image_paths[:10]): 
    test_image, test_image_prep = preprocess_image(img_path)
    prediction = model.predict(test_image_prep)[0][0]
    predicted_class = class_2 if prediction > 0.5 else class_1
    confidence = prediction if prediction > 0.5 else 1 - prediction
    plt.subplot(2, 5, i + 1)
    plt.imshow(test_image, cmap="gray")
    plt.axis('off')
    plt.title(f"Predicted: {predicted_class}\n{confidence:.8f}")
plt.show()