У меня есть следующий скрипт, можешь добавить комментарии и пояснить что он делает

# -*- coding: utf-8 -*-

import tensorflow as tf
from tensorflow.keras.optimizers import Adamax

from tensorflow.keras.preprocessing.image import ImageDataGenerator
import numpy as np
import pandas as pd

import os

from tensorflow.keras.models import load_model


def load_data_frame(sdir):
    filepaths = []
    labels = []
    flist = os.listdir(sdir)
    for f in flist:
        fpath = os.path.join(sdir, f)

        filepaths.append(fpath.replace('\\', '/'))
        labels.append("UNK")

    Fseries = pd.Series(filepaths, name='image')
    Lseries = pd.Series(labels, name='dx')
    return pd.concat([Fseries, Lseries], axis=1)


def scalar(img):
    return img


gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
    try:
        for gpu in gpus:
            tf.config.experimental.set_memory_growth(gpu, True)
        logical_gpus = tf.config.list_logical_devices('GPU')
        print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
    except RuntimeError as e:
        print(e)

height = 224
width = 224
channels = 3
img_shape = (height, width, channels)
img_size = (height, width)

print()
print("Загрузка списка меток для проверки...")

# Загружаем список всех файлов с метками
df = pd.read_csv(r".\25k_df.csv")

# Загружаем изображения для последующей классификации
predict_dir = './predict'

# Переставляем метки по алфавиту
labels = ['AK', 'BCC', 'BKL', 'DF', 'MEL', 'NV', 'SCC', 'VASC']

df_predict = load_data_frame(predict_dir)

tvgen = ImageDataGenerator(preprocessing_function=scalar)

predict_gen = tvgen.flow_from_dataframe(df_predict,
                                        directory=None,
                                        x_col="image",
                                        y_col="dx",
                                        target_size=img_size,
                                        class_mode='categorical',
                                        color_mode='rgb',
                                        shuffle=False,
                                        batch_size=50)

print()
print("Загрузка моделей")
# Загружаем 3 заранее обученных модели из .h5 файлов
model_1 = load_model("./Models/model-88.70.h5")
model_2 = load_model("./Models/model-88.80.h5")
model_3 = load_model("./Models/model-89.20.h5")

model_1.compile(Adamax(lr=.001), loss='categorical_crossentropy', metrics=['accuracy'])
model_2.compile(Adamax(lr=.001), loss='categorical_crossentropy', metrics=['accuracy'])
model_3.compile(Adamax(lr=.001), loss='categorical_crossentropy', metrics=['accuracy'])

"""
# Вывод меток
# Метки распределяются по алфавиту
valid_gen.class_indices
Out[6]: {'AK': 0, 'BCC': 1, 'BKL': 2, 'DF': 3, 'MEL': 4, 'NV': 5, 'SCC': 6, 'VASC': 7}
"""
print()
print("Прогнозирование")
# В списки выгружается значение вероятности для каждого класса классифицируемых объектов
predictions1 = model_1.predict_generator(predict_gen)
predictions2 = model_2.predict_generator(predict_gen)
predictions3 = model_3.predict_generator(predict_gen)

# Удаляем полные пути и оставляем только имена файлов
df_predict['image'] = df_predict['image'].apply(os.path.basename)
# Формируем список изображений
images = df_predict['image'].to_list()

pr1 = [labels[np.argmax(x)] for x in predictions1]

pr2 = [labels[np.argmax(x)] for x in predictions2]

pr3 = [labels[np.argmax(x)] for x in predictions3]

# Список с правильным метками
DXs = []

for x in images:
    if len(df[df['image'] == x]['dx']) != 0:
        DXs.append(df[df['image'] == x]['dx'].iloc[0])
    else:
        DXs.append('UNK')

# Реализуем ансамбль
pr_sum = []
max_sum = 0
max_idx = 0
for x, y, z in zip(predictions1, predictions2, predictions3):
    for i in range(8):
        if max_sum < x[i] + y[i] + z[i]:
            max_sum = x[i] + y[i] + z[i]
            max_idx = i

    pr_sum.append(max_idx)
    max_sum = 0

result = [labels[x] for x in pr_sum]

predict_table = pd.DataFrame({'Изображение': images, 'Model 1': pr1, 'Model 2': pr2, 'Model 3': pr3,
                              'Ансамбль': result, 'Правильная метка': DXs})