This is my code and it contains some print functions for debugging: import os
import cv2
import numpy as np
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import Input, Conv2D, MaxPooling2D, Flatten, LSTM, Dense, Embedding, Concatenate
from keras import Model
from keras.utils import to_categorical
from keras.layers import RepeatVector, TimeDistributed


# Constants for the image and sequence properties
IMAGE_HEIGHT = 256
IMAGE_WIDTH = 256
NUM_CHANNELS = 3
NUM_HTML_TOKENS = 10000  # Assuming 10,000 possible tokens in the HTML vocabulary
MAX_SEQUENCE_LENGTH = 500  # This should be set to the maximum sequence length after exploring your dataset
EPOCHS = 10

def resize_image_with_padding(img, target_width, target_height):
    old_width, old_height = img.shape[1], img.shape[0]
    aspect_ratio = old_width / old_height

    # Determine new width and height, preserving aspect ratio
    if old_width > old_height:
        new_width = target_width
        new_height = int(target_width / aspect_ratio)
    else:
        new_height = target_height
        new_width = int(target_height * aspect_ratio)

    # Resize the image
    img_resized = cv2.resize(img, (new_width, new_height))

    # Padding calculations
    delta_w = target_width - new_width
    delta_h = target_height - new_height
    top, bottom = delta_h // 2, delta_h - (delta_h // 2)
    left, right = delta_w // 2, delta_w - (delta_w // 2)

    # Add padding to the resized image
    color = [0, 0, 0]  # Padding color (black)
    img_padded = cv2.copyMakeBorder(img_resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)

    return img_padded


# Load and preprocess your images and HTML
# Function to load images and corresponding HTML
def load_and_preprocess_data(screenshots_dir, html_dir, image_height, image_width):
    images = []
    all_html_sources = []

    # Debugging print: Check the content of your html directory
    print("Content of html_dir:", os.listdir(html_dir))

    screenshots = os.listdir(screenshots_dir)

    # Debugging print: Check the content of your screenshot directory
    print("Content of screenshots_dir:", screenshots)



    for filename in sorted(os.listdir(screenshots_dir)):
        if filename.endswith(".png"):
            # Load and preprocess each image
            img_path = os.path.join(screenshots_dir, filename)
            img = cv2.imread(img_path)
            img = resize_image_with_padding(img, image_width, image_height)
            img = img / 255.0  # Normalize pixel values to [0, 1]
            images.append(img)
            
            # Find corresponding HTML file with the same base name
            base_name = os.path.splitext(filename)[0]
            html_filename = base_name + ".html"
            html_path = os.path.join(html_dir, html_filename)
            if os.path.isfile(html_path):
                with open(html_path, "r", encoding="utf-8") as file:
                    html_content = file.read()
                    all_html_sources.append(html_content)

    html_path = os.path.join(html_dir, html_filename)
    print(f"Trying to open {html_path}")
    
    return np.array(images), all_html_sources

# Paths to your data directories
screenshots_dir = "C:/Users/Dell-PC/Desktop/Projets/Img-2-Code/screenshots"
html_dir = "C:/Users/Dell-PC/Desktop/Projets/Img-2-Code/html"
images, all_html_sources = load_and_preprocess_data(screenshots_dir, html_dir, IMAGE_HEIGHT, IMAGE_WIDTH)

print("Number of HTML files read: ", len(all_html_sources))
if len(all_html_sources) > 0:
    print("First few characters of the first HTML source: ", all_html_sources[0][:100])
else:
    print("No HTML sources were read. Check the HTML directory and filenames.")


# Tokenize the HTML content
tokenizer = Tokenizer(num_words=NUM_HTML_TOKENS)
tokenizer.fit_on_texts(all_html_sources)

# Convert text to a sequence of integers
sequences = tokenizer.texts_to_sequences(all_html_sources)

print("Length of text sequences: ", len(sequences))
if len(sequences) > 0:
    print("First tokenized sequence shape: ", np.array(sequences[0]).shape)
else:
    print("No sequences were generated. Check all_html_sources.")


# Check if the sequences have been created properly
print("Number of sequences:", len(sequences))
if len(sequences) > 0:
    print("First sequence:", sequences[0])
else:
    print("Sequences have not been created properly.")

# Pad the sequences so they all have the same length
html_sequences = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH, padding="post")

# Now check the shape of html_sequences
print("Shape of html_sequences after padding:", html_sequences.shape)


# Convert html_sequences to one-hot-encoded for use with categorical crossentropy
html_sequences_one_hot = to_categorical(html_sequences, num_classes=NUM_HTML_TOKENS)

# Step 1: Create the CNN model to extract features from the image
input_image = Input(shape=(IMAGE_HEIGHT, IMAGE_WIDTH, NUM_CHANNELS))
cnn = Conv2D(filters=32, kernel_size=(3,3), activation="relu")(input_image)
cnn = MaxPooling2D(pool_size=(2,2))(cnn)
cnn = Conv2D(filters=64, kernel_size=(3,3), activation="relu")(cnn)
cnn = MaxPooling2D(pool_size=(2,2))(cnn)
cnn = Flatten()(cnn)
cnn = Dense(units=512)(cnn)  # Ensure the CNN output size matches the LSTM input
cnn_out_repeated = RepeatVector(MAX_SEQUENCE_LENGTH)(cnn)


# Step 2: Create an embedding layer for the HTML input sequence
decoder_input_sequence = Input(shape=(MAX_SEQUENCE_LENGTH,))
embedding_layer = Embedding(NUM_HTML_TOKENS, 256)(decoder_input_sequence)
lstm = LSTM(units=512, return_sequences=True)(embedding_layer)

# Instead of the Concatenate layer, combine CNN and LSTM outputs with a TimeDistributed layer
# We can stack the CNN’s output on top of the LSTM by using a concatenate layer with axis=-1
combined_outputs = Concatenate(axis=-1)([cnn_out_repeated, lstm])
# Step 3: Apply a TimeDistributed Dense layer to generate a probability over the vocabulary for each time step
decoder_output = TimeDistributed(Dense(NUM_HTML_TOKENS, activation="softmax"))(combined_outputs)
model = Model([input_image, decoder_input_sequence], decoder_output)

# Compile the model with a loss and an optimizer
#model.compile(optimizer="adam", loss="sparse_categorical_crossentropy")

# Shift html_sequences to the right by one place for the decoder input
decoder_input_sequences = np.pad(html_sequences[:, :-1], ((0, 0), (1, 0)), "constant", constant_values=(0, 0))

# Verify dimensions after padding operation
if decoder_input_sequences.size == 0:
    print("The padding operation has somehow emptied the array.")
else:
    print("decoder_input_sequences.shape after padding:", decoder_input_sequences.shape)

# Check if the padding operation reduces the size to zero
if decoder_input_sequences.size == 0:
    print("The padding operation has somehow emptied the array.")
else:
    print(decoder_input_sequences.shape)

print(images.shape)  # should print (num_samples, IMAGE_HEIGHT, IMAGE_WIDTH, NUM_CHANNELS)
print(decoder_input_sequences.shape)  # should print (num_samples, MAX_SEQUENCE_LENGTH)
print(html_sequences_one_hot.shape)  # should print (num_samples, MAX_SEQUENCE_LENGTH, NUM_HTML_TOKENS)

# For using with sparse_categorical_crossentropy
targets = html_sequences[:, 1:]  # targets are shifted by 1 position
targets = np.expand_dims(targets, -1)  # add an extra dimension

print("decoder_input_sequences.shape:", decoder_input_sequences.shape)
print("targets.shape:", targets.shape)


# Train the model accordingly
#model.fit([images, decoder_input_sequences], targets, epochs=EPOCHS)
#  model.fit(
#    [images, decoder_input_sequences],
#   targets,
#   epochs=EPOCHS
#   )


# Save or evaluate your model
#model.save("Image_to_html.keras")   and this is the output it gives me: Content of html_dir: ['html_1.html', 'html_10.html', 'html_11.html', 'html_12.html', 'html_13.html', 'html_14.html', 'html_15.html', 'html_2.html', 'html_3.html', 'html_4.html', 'html_5.html', 'html_6.html', 'html_7.html', 'html_8.html', 'html_9.html']
Content of screenshots_dir: ['screen_1.png', 'screen_10.png', 'screen_11.png', 'screen_12.png', 'screen_13.png', 'screen_14.png', 'screen_15.png', 'screen_2.png', 'screen_3.png', 'screen_4.png', 'screen_5.png', 'screen_6.png', 'screen_7.png', 'screen_8.png', 'screen_9.png']
Trying to open C:/Users/Dell-PC/Desktop/Projets/Img-2-Code/html\screen_9.html
Number of HTML files read:  0
No HTML sources were read. Check the HTML directory and filenames.
Length of text sequences:  0
No sequences were generated. Check all_html_sources.
Number of sequences: 0
Sequences have not been created properly.
Shape of html_sequences after padding: (0, 500)
2023-12-09 13:29:56.086754: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: SSE SSE2 SSE3 SSE4.1 SSE4.2 AVX AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
The padding operation has somehow emptied the array.
The padding operation has somehow emptied the array.
(15, 256, 256, 3)
(0, 500)
(0, 500, 10000)
decoder_input_sequences.shape: (0, 500)
targets.shape: (0, 499, 1)