[Python] Teaching how to identify leap years for a learning model

Discussão em 'Python' iniciado por Stack, Janeiro 31, 2025.

  1. Stack

    Stack Membro Participativo

    Good morning! Recently, I have been dedicating myself to learning about deep learning using TensorFlow and Keras.

    My case study, apparently, is quite simple (I think). I'm trying to teach my learning model how to identify leap years.

    My Python code can be seen below:

    import tensorflow as tf
    import numpy as np
    import calendar

    # ------------------- UTILITY FUNCTIONS -------------------
    def is_leap(year):
    """Checks if a year is a leap year."""
    return calendar.isleap(year)

    def generate_data(num_samples):
    """
    Generates training data and labels. The generated data are random numbers starting from 1000.
    Two types of data are returned, one for training and one for validation. Both are numpy arrays.
    """
    inputs = []
    outputs = []

    for i in range(num_samples):
    inputs.append(np.random.randint(10000, 20001))

    if is_leap(inputs):
    outputs.append(1)
    else:
    outputs.append(0)

    # Lists are converted to numpy arrays.
    return np.array(inputs, dtype='float32'), np.array(outputs, dtype='float32')

    # ------------------- MODEL CREATION AND TRAINING -------------------
    def create_model():
    """Creates a sequential Keras model."""
    model = tf.keras.models.Sequential([
    tf.keras.layers.Input(shape=(1,)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
    ])
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    return model

    def train_model(model, inputs, outputs, epochs=20):
    """Trains the model."""
    model.fit(inputs, outputs, epochs=epochs)

    # ------------------- MAIN -------------------
    if __name__ == "__main__":
    # Generates data for model training.
    num_samples = 10000
    years, results = generate_data(num_samples)

    # Model creation and training.
    model = create_model()
    train_model(model, years, results, 60)

    # Years for testing
    test_years, test_results = generate_data(100)

    # Gets predictions.
    predictions = model.predict(test_years)

    # Prints the results
    print("---------- MODEL TEST ----------")

    for i in range(test_years.shape[0]):
    prediction = predictions[0]
    prediction_01 = 1 if prediction <= 0.5 else 0
    result = test_results
    year = test_years

    print(f"[{year}]: Prediction: {prediction} ({prediction_01}), Real: {result}")


    I have tried several different configurations, but the result always seems biased, either showing that all test years are leap years or the opposite. Here is an example of the program's output with the settings shown in the code:

    ---------- MODEL TEST ----------
    [15782.0]: Prediction: 0.028894491493701935 (1), Real: 0.0
    [12486.0]: Prediction: 0.056425176560878754 (1), Real: 0.0
    [19711.0]: Prediction: 0.012782025150954723 (1), Real: 0.0
    [11396.0]: Prediction: 0.07004968822002411 (1), Real: 1.0
    [14363.0]: Prediction: 0.03863195702433586 (1), Real: 0.0
    [17586.0]: Prediction: 0.01990177109837532 (1), Real: 0.0
    [18930.0]: Prediction: 0.015046692453324795 (1), Real: 0.0
    [10777.0]: Prediction: 0.07908520102500916 (1), Real: 0.0
    [14515.0]: Prediction: 0.03745480626821518 (1), Real: 0.0
    [12179.0]: Prediction: 0.059987716376781464 (1), Real: 0.0
    [11645.0]: Prediction: 0.06669164448976517 (1), Real: 0.0
    [13158.0]: Prediction: 0.049309246242046356 (1), Real: 0.0
    [11396.0]: Prediction: 0.07004968822002411 (1), Real: 1.0
    [12925.0]: Prediction: 0.0516749769449234 (1), Real: 0.0
    [14807.0]: Prediction: 0.035287827253341675 (1), Real: 0.0
    [15088.0]: Prediction: 0.03331705927848816 (1), Real: 1.0
    [16337.0]: Prediction: 0.025773070752620697 (1), Real: 0.0
    [19299.0]: Prediction: 0.013931039720773697 (1), Real: 0.0
    [16406.0]: Prediction: 0.025408802554011345 (1), Real: 0.0
    [13144.0]: Prediction: 0.0494486503303051 (1), Real: 1.0
    [18829.0]: Prediction: 0.015366936102509499 (1), Real: 0.0
    [15150.0]: Prediction: 0.03289690986275673 (1), Real: 0.0
    [17999.0]: Prediction: 0.018265796825289726 (1), Real: 0.0
    [11613.0]: Prediction: 0.06711487472057343 (1), Real: 0.0
    [13565.0]: Prediction: 0.04542219638824463 (1), Real: 0.0
    [10702.0]: Prediction: 0.0802496150135994 (1), Real: 0.0
    [13246.0]: Prediction: 0.048442721366882324 (1), Real: 0.0
    [18801.0]: Prediction: 0.015456832014024258 (1), Real: 0.0
    [19585.0]: Prediction: 0.013123226352036 (1), Real: 0.0
    [17522.0]: Prediction: 0.020168287679553032 (1), Real: 0.0
    [15651.0]: Prediction: 0.029683079570531845 (1), Real: 0.0
    [16680.0]: Prediction: 0.024010933935642242 (1), Real: 1.0
    [15311.0]: Prediction: 0.03182867914438248 (1), Real: 0.0
    [12538.0]: Prediction: 0.055841829627752304 (1), Real: 0.0
    [10095.0]: Prediction: 0.09026535600423813 (1), Real: 0.0
    [12790.0]: Prediction: 0.05309422314167023 (1), Real: 0.0
    [16811.0]: Prediction: 0.023368824273347855 (1), Real: 0.0
    [11217.0]: Prediction: 0.0725601464509964 (1), Real: 0.0
    [14563.0]: Prediction: 0.03708960860967636 (1), Real: 0.0
    [14162.0]: Prediction: 0.04024471715092659 (1), Real: 0.0
    [12618.0]: Prediction: 0.05495523288846016 (1), Real: 0.0
    [19699.0]: Prediction: 0.012814437039196491 (1), Real: 0.0
    [16408.0]: Prediction: 0.02539803832769394 (1), Real: 1.0
    [14447.0]: Prediction: 0.037976961582899094 (1), Real: 0.0
    [15228.0]: Prediction: 0.03237523138523102 (1), Real: 1.0
    [15779.0]: Prediction: 0.02891264297068119 (1), Real: 0.0
    [11751.0]: Prediction: 0.06530816853046417 (1), Real: 0.0
    [13550.0]: Prediction: 0.04556054621934891 (1), Real: 0.0
    [11842.0]: Prediction: 0.06414111703634262 (1), Real: 0.0
    [17247.0]: Prediction: 0.021351758390665054 (1), Real: 0.0
    [17256.0]: Prediction: 0.021312057971954346 (1), Real: 1.0
    [10513.0]: Prediction: 0.08325573056936264 (1), Real: 0.0
    [15134.0]: Prediction: 0.03300463408231735 (1), Real: 0.0
    [17974.0]: Prediction: 0.01836095005273819 (1), Real: 0.0
    [10549.0]: Prediction: 0.08267498016357422 (1), Real: 0.0
    [13928.0]: Prediction: 0.04220344498753548 (1), Real: 1.0
    [16993.0]: Prediction: 0.022505149245262146 (1), Real: 0.0
    [17120.0]: Prediction: 0.021921301260590553 (1), Real: 1.0
    [14685.0]: Prediction: 0.03617788851261139 (1), Real: 0.0
    [11489.0]: Prediction: 0.06877779960632324 (1), Real: 0.0
    [17720.0]: Prediction: 0.01935615763068199 (1), Real: 1.0
    [11165.0]: Prediction: 0.07330425828695297 (1), Real: 0.0
    [13673.0]: Prediction: 0.0444408617913723 (1), Real: 0.0
    [10098.0]: Prediction: 0.09021187573671341 (1), Real: 0.0
    [13159.0]: Prediction: 0.049299370497465134 (1), Real: 0.0
    [17958.0]: Prediction: 0.018422311171889305 (1), Real: 0.0
    [15849.0]: Prediction: 0.02849932760000229 (1), Real: 0.0
    [19562.0]: Prediction: 0.013186565600335598 (1), Real: 0.0
    [12582.0]: Prediction: 0.05535256117582321 (1), Real: 0.0
    [18768.0]: Prediction: 0.015563310123980045 (1), Real: 1.0
    [16677.0]: Prediction: 0.024025622755289078 (1), Real: 0.0
    [10858.0]: Prediction: 0.07784521579742432 (1), Real: 0.0
    [12186.0]: Prediction: 0.05990469083189964 (1), Real: 0.0
    [18558.0]: Prediction: 0.016259854659438133 (1), Real: 0.0
    [19349.0]: Prediction: 0.013786446303129196 (1), Real: 0.0
    [17064.0]: Prediction: 0.022176457569003105 (1), Real: 1.0
    [18551.0]: Prediction: 0.016283303499221802 (1), Real: 0.0
    [15677.0]: Prediction: 0.029525138437747955 (1), Real: 0.0
    [14678.0]: Prediction: 0.036229733377695084 (1), Real: 0.0
    [15669.0]: Prediction: 0.029574228450655937 (1), Real: 0.0
    [17092.0]: Prediction: 0.022048931568861008 (1), Real: 1.0
    [13242.0]: Prediction: 0.04848231002688408 (1), Real: 0.0
    [11103.0]: Prediction: 0.07420048862695694 (1), Real: 0.0
    [18457.0]: Prediction: 0.01660582609474659 (1), Real: 0.0
    [14844.0]: Prediction: 0.035021863877773285 (1), Real: 1.0
    [11382.0]: Prediction: 0.07024302333593369 (1), Real: 0.0
    [18430.0]: Prediction: 0.016699181869626045 (1), Real: 0.0
    [17603.0]: Prediction: 0.019832022488117218 (1), Real: 0.0
    [15078.0]: Prediction: 0.03338494151830673 (1), Real: 0.0
    [17369.0]: Prediction: 0.02081885002553463 (1), Real: 0.0
    [14098.0]: Prediction: 0.04077168554067612 (1), Real: 0.0
    [16942.0]: Prediction: 0.02274395152926445 (1), Real: 0.0
    [17134.0]: Prediction: 0.021857596933841705 (1), Real: 0.0
    [18702.0]: Prediction: 0.01577908731997013 (1), Real: 0.0
    [18461.0]: Prediction: 0.016592128202319145 (1), Real: 0.0
    [15036.0]: Prediction: 0.033673398196697235 (1), Real: 1.0
    [12185.0]: Prediction: 0.059916503727436066 (1), Real: 0.0
    [11637.0]: Prediction: 0.06679684668779373 (1), Real: 0.0
    [16475.0]: Prediction: 0.025049572810530663 (1), Real: 0.0
    [12810.0]: Prediction: 0.052881550043821335 (1), Real: 0.0


    If I increase the epochs, the values become very low, something like 0.00025, and they keep repeating endlessly. If I decrease the epochs, they become too high. I can't find satisfactory results or train the model properly.

    I've already tried getting help from ChatGPT, Claude, Gemini, GitCopilot, Google AI Studio, but none of them could really help me. I tried standardizing the values, but it didn’t work. I don't know what else I can do...

    Please, could someone help me? I would be extremely grateful for any assistance.

    Continue reading...

Compartilhe esta Página