Please modify the training function in my code to be used in two different ways: the first is by setting a fixed loss function value and making the training function run an infinite number of epochs until it gets close enough to the value set earlier, or the second way which is just setting a number of epochs to train and adding a condition so that if a specific key is pressed the training should stop and the model should be saved as is, code: import tkinter as tk
from tkinter import filedialog
from keras.models import Sequential
from keras.layers import Embedding, LSTM, Dense
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.utils import to_categorical
import numpy as np
import os
import pickle

# Data loader and preprocessor function
def preprocess_data(file_paths, sequence_length=5):
tokenizer = Tokenizer()

# Load and concatenate content from all selected dataset files
all_text = “”
for file_path in file_paths:
with open(file_path, ‘r’, encoding=‘utf-8’) as file:
text = file.read()
all_text += text + “\n” # Ensure separation between files’ content

sentences = all_text.split(‘\n’)

tokenizer.fit_on_texts(sentences)
sequences = tokenizer.texts_to_sequences(sentences)

big_sequence = [token for seq in sequences for token in seq]
input_sequences, output_words = [], []
for i in range(0, len(big_sequence) - sequence_length):
input_sequences.append(big_sequence[i:i + sequence_length])
output_words.append(big_sequence[i + sequence_length])

input_sequences = pad_sequences(input_sequences, maxlen=sequence_length)

vocab_size = len(tokenizer.word_index) + 1

output_words = np.array(output_words)
output_words = to_categorical(output_words, num_classes=vocab_size)

return input_sequences, output_words, vocab_size, tokenizer


# Function to train and save the model
def train_model():
num_layers = int(entry_layers.get())
layer_size = int(entry_size.get())
model_name = entry_name.get()
epochs = int(entry_epochs.get())
data_paths = root.filenames # Changed to accept multiple filenames

# Preprocess the data
input_sequences, output_words, vocab_size, tokenizer = preprocess_data(data_paths)

tokenizer_path = os.path.join(‘tokenizers’, f’{model_name}_tokenizer.pickle’)
if not os.path.exists(‘tokenizers’):
os.makedirs(‘tokenizers’)
with open(tokenizer_path, ‘wb’) as handle:
pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)
print(f"Tokenizer saved at {tokenizer_path}“)

model = Sequential()
model.add(Embedding(input_dim=vocab_size, output_dim=layer_size, input_length=input_sequences.shape[1]))
for _ in range(num_layers - 1):
model.add(LSTM(units=layer_size, return_sequences=True))
model.add(LSTM(units=layer_size))
model.add(Dense(vocab_size, activation=‘softmax’))

model.compile(optimizer=‘adam’, loss=‘categorical_crossentropy’, metrics=[‘accuracy’])
model.fit(input_sequences, output_words, epochs=epochs)

if not os.path.exists(‘models’):
os.makedirs(‘models’)
model.save(os.path.join(‘models’, f’{model_name}.h5’))
print(f"Model {model_name} trained and saved successfully!”)

# UI Setup
root = tk.Tk()
root.title(“Chatbot Language Model Trainer”)

# Number of layers
lbl_layers = tk.Label(root, text=“Number of layers:”)
lbl_layers.pack()
entry_layers = tk.Entry(root)
entry_layers.pack()

# Layer size
lbl_size = tk.Label(root, text=“Size of each layer:”)
lbl_size.pack()
entry_size = tk.Entry(root)
entry_size.pack()

# Model name
lbl_name = tk.Label(root, text=“Model name:”)
lbl_name.pack()
entry_name = tk.Entry(root)
entry_name.pack()

# Number of epochs
lbl_epochs = tk.Label(root, text=“Number of epochs:”)
lbl_epochs.pack()
entry_epochs = tk.Entry(root)
entry_epochs.pack()

# Data file path
lbl_data_path = tk.Label(root, text=“Data file path:”)
lbl_data_path.pack()
entry_data_path = tk.Entry(root)
entry_data_path.pack()

# Function to select multiple files
def select_files():
file_paths = filedialog.askopenfilenames() # Changed to open multiple files
root.filenames = file_paths # Store the list of file paths on the root object
entry_data_path.delete(0, tk.END)
entry_data_path.insert(0, "; ".join(file_paths)) # Display all file paths in the entry

btn_browse = tk.Button(root, text=“Browse…”, command=select_files) # Changed to select_files
btn_browse.pack()

# Train button
btn_train = tk.Button(root, text=“Train Model”, command=train_model)
btn_train.pack()

# Start the tkinter loop
root.mainloop()