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...