[Python] MNIST multi digit prediction

Discussão em 'Python' iniciado por Stack, Agosto 1, 2025.

  1. Stack

    Stack Membro Participativo

    I tried to train a model on mnist dataset. It's working fine for single digit prediction and I got 96.92% accuracy on test data too but I have everything but it's not working for multidigit. even though I took an image with spacing in between and it was able to split and preprocess it properly. I have tried multiple threshold values, tried to increase and decrease hidden layers.

    the input image had 1234 but model is predicting 3356.enter image description here

    import numpy as np
    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.metrics import accuracy_score
    import matplotlib.pyplot as plt
    import tensorflow
    from tensorflow import keras
    from tensorflow.keras import Sequential
    from tensorflow.keras.layers import Dense
    from PIL import Image
    def apply_threshold(img, threshold=125):
    img = np.where(img > threshold, 1, 0).astype(np.uint8)
    return img

    def image_background(img):
    if img.mean() > 127:
    img = 255 - img
    return img

    def padding_and_resize(img):
    h, w = img.shape
    if h < w:
    new_img = np.zeros((int((w - h) / 2), w))
    new_img = np.append(new_img, img, axis=0)
    zeros = np.zeros(((w - h) - int((w - h) / 2), w))
    new_img = np.append(new_img, zeros, axis=0)
    img = new_img
    elif h > w:
    new_img = np.zeros((h, int((h - w) / 2)))
    new_img = np.append(new_img, img, axis=1)
    zeros = np.zeros((h, (h - w) - int((h - w) / 2)))
    new_img = np.append(new_img, zeros, axis=1)
    img = new_img

    img = Image.fromarray(img.astype(np.uint8))
    img = img.resize((28, 28))
    img = np.array(img)
    return img

    def reshaping_and_standardizing(img):
    return img.reshape(-1) / 255.0

    def split_digits(img):
    img_mean = img.mean()
    new_img = []

    for i in img:
    if np.sum(i) != 0:
    new_img.append(i)

    new_img = np.array(new_img)
    output_digits = []

    moving_on_digit = False
    start = 0
    end = 0
    for i in range(len(new_img[0])):
    if np.sum(new_img[:, i]) != 0 and (not moving_on_digit):
    moving_on_digit = True
    start = i
    elif np.sum(new_img[:, i]) == 0 and moving_on_digit:
    moving_on_digit = False
    end = i
    output_digits.append(new_img[:, start:end + 1])

    if moving_on_digit:
    output_digits.append(new_img[:, start:len(new_img[0])])

    return output_digits

    def img_processor(img, threshold=None):
    if threshold is None:
    threshold = img.mean()
    img = image_background(img)
    img = apply_threshold(img, threshold=threshold)
    img = padding_and_resize(img)
    img = reshaping_and_standardizing(img)
    return img

    (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

    x_train = pd.DataFrame(img_processor(img) for img in x_train)
    x_test = pd.DataFrame(img_processor(img) for img in x_test)

    y_train = pd.DataFrame(np.array([[0] * i + [1] + [0] * (9 - i)]).reshape(10) for i in y_train)

    model = Sequential()
    model.add(Dense(784, activation='relu', input_dim=784))
    model.add(Dense(128, activation='relu'))
    model.add(Dense(64, activation='relu'))
    model.add(Dense(10, activation='softmax'))

    model.summary()

    model.compile(loss='categorical_crossentropy', optimizer='Adam')
    model.fit(x_train, y_train, epochs=11)

    y_predict = model.predict(x_test)

    y_predict = np.argmax(y_predict, axis=1)

    str(round(accuracy_score(y_test, y_predict) * 100, 2)) + "%"

    # testing

    from PIL import Image

    # single digit testing
    img = Image.open('/content/drive/MyDrive/datasets/image_set/Screenshot 2025-07-30 052716.png')
    img = img.convert('L')
    img = img.resize((28, 28))
    img_array = np.array(img)
    img_array = img_array.reshape(1, 784)
    if img_array.mean() > 127:
    img_array = 255 - img_array
    img_array = img_array / 255.0
    y_predict = model.predict(img_array)
    np.argmax(y_predict, axis=1)

    img = Image.open('/content/Screenshot 2025-07-31 175136.png').convert('L')
    img = np.array(img)
    img = image_background(img)
    img = apply_threshold(img, threshold=img.mean())
    images = split_digits(img)
    digit = 0
    for img in images:
    img = padding_and_resize(img)
    plt.imshow(img, cmap='gray')
    plt.axis('off')
    plt.show()
    img = img.reshape(1, 784) / 255.0
    prediction = model.predict(img).argmax(axis=1)[0]
    digit *= 10
    digit += prediction
    print(digit)enter image description here

    Continue reading...

Compartilhe esta Página