| import streamlit as st |
| from tensorflow import keras |
| import os |
| import matplotlib.pyplot as plt |
| from io import BytesIO |
| from NNVisualiser import NNVisualiser |
| import glob |
| import inspect |
| from tensorflow.keras.models import save_model |
| import tempfile |
| import re |
| import zipfile |
| import io |
|
|
| |
| def create_zip_of_png_files(): |
| |
| cwd = os.getcwd() |
| png_files = [f for f in os.listdir(cwd) if f.endswith('.png')] |
|
|
| |
| zip_buffer = io.BytesIO() |
|
|
| with zipfile.ZipFile(zip_buffer, 'w') as zip_file: |
| for png_file in png_files: |
| zip_file.write(os.path.join(cwd, png_file), arcname=png_file) |
|
|
| zip_buffer.seek(0) |
| return zip_buffer |
|
|
| def generate_title_from_method_name(method_name): |
| |
| if method_name.startswith("plot"): |
| method_name = method_name[4:] |
| |
| |
| words = re.findall(r'[A-Z][a-z]*', method_name) |
| |
| |
| title = "Plotting " + " ".join(words[:]) + " Plot " |
| |
| return title |
|
|
| def downloadKerasModel(): |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".keras") as tmp_file: |
| save_model(model, tmp_file.name) |
| tmp_file.seek(0) |
| model_data = tmp_file.read() |
| return model_data |
|
|
| |
| |
| def generate_folder_hierarchy(root_folder, max_depth=7): |
| folder_dict = {} |
|
|
| |
| for dirpath, dirnames, filenames in os.walk(root_folder): |
| |
| rel_path = os.path.relpath(dirpath, root_folder) |
| depth = rel_path.count(os.sep) + 1 |
|
|
| |
| if depth > max_depth: |
| continue |
|
|
| |
| dirnames[:] = [d for d in dirnames if not d.startswith('.') and d != '1'] |
|
|
| sub_dict = folder_dict |
| |
| for part in rel_path.split(os.sep): |
| if part == '.' or part.startswith('.'): |
| continue |
| if part not in sub_dict: |
| sub_dict[part] = {} |
| sub_dict = sub_dict[part] |
|
|
| return folder_dict |
|
|
| @st.cache_data |
| def getPlotMethods(): |
| return [name for name, func in inspect.getmembers(NNVisualiser, inspect.isfunction) if name.startswith('plot')] |
|
|
| |
| root_folder = os.getcwd(); |
| folder_hierarchy = generate_folder_hierarchy(root_folder) |
|
|
| |
| st.title("Repository : Simple ANN Models with UAT Architecture") |
| st.write(f"A Collection of ANN Models with a 1-xReLU-1 Architecture for Basic 1D Functions on Bounded Intervals") |
| |
|
|
| |
|
|
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| |
| |
|
|
|
|
| |
|
|
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| |
| |
|
|
| repo = st.sidebar.selectbox("Select Model Repository",list(folder_hierarchy.keys())) |
| initialisation = st.sidebar.selectbox("Select Initialisation", list(folder_hierarchy[repo].keys())) |
| sampleSize = st.sidebar.selectbox("Select Sample Size", list(folder_hierarchy[repo][initialisation].keys())) |
| batchSize = st.sidebar.selectbox("Select Batch Size", list(folder_hierarchy[repo][initialisation][sampleSize].keys())) |
| epochs = st.sidebar.selectbox("Select Epochs Count", list(folder_hierarchy[repo][initialisation][sampleSize][batchSize].keys())) |
| functions = st.sidebar.selectbox("Select Function", list(folder_hierarchy[repo][initialisation][sampleSize][batchSize][epochs].keys())) |
| neurons = st.sidebar.selectbox("Select Neurons Count", list(folder_hierarchy[repo][initialisation][sampleSize][batchSize][epochs][functions].keys())) |
|
|
| |
| st.write(f"You selected: {repo} : {initialisation} : {sampleSize} : {batchSize} : {epochs} : {functions} : {neurons}") |
|
|
| modelPath = os.path.join(os.getcwd(), repo, initialisation, sampleSize, batchSize, epochs, functions, neurons); |
| model = keras.models.load_model(modelPath); |
|
|
| visualiser = NNVisualiser(model); |
| visualiser.setSavePlots(True); |
|
|
| |
| def get_layer_info(model): |
| layer_info = [] |
| for layer in model.layers: |
| layer_info.append({ |
| 'index': len(layer_info), |
| 'type': layer.__class__.__name__, |
| 'units': getattr(layer, 'units', None), |
| }) |
| return layer_info |
|
|
| layer_info = get_layer_info(model) |
|
|
| |
| layer_indices = [layer['index'] for layer in layer_info] |
| neuron_counts = [layer['units'] for layer in layer_info] |
|
|
| |
| |
|
|
| |
| |
|
|
| |
| |
| |
|
|
| |
| plotMethods = getPlotMethods() |
| selectedPlotMethod = st.sidebar.selectbox("Select Plot", plotMethods) |
|
|
| |
| image_files = glob.glob("*.png") |
| for file in image_files: |
| try: |
| os.remove(file) |
| except Exception as e: |
| st.write("Error in removing previous plots") |
|
|
| st.session_state.title_text = generate_title_from_method_name(selectedPlotMethod) |
| st.title(st.session_state.title_text) |
|
|
| |
| visualiser.setSavePlots(True); |
| method = getattr(visualiser, selectedPlotMethod, None) |
|
|
| if method is not None: |
| if 'Neuron' in selectedPlotMethod: |
| selected_layer_index = st.sidebar.selectbox("Select Layer Index", layer_indices) |
| |
| selected_layer_units = neuron_counts[selected_layer_index] |
| |
| neuron_indices = list(range(selected_layer_units)) |
| selected_neuron_index = st.sidebar.selectbox("Select Neuron Index", neuron_indices) |
| params = (selected_layer_index, selected_neuron_index) |
| method(*params) |
| elif 'Layer' in selectedPlotMethod: |
| selected_layer_index = st.sidebar.selectbox("Select Layer Index", layer_indices) |
| params = (selected_layer_index,) |
| method(*params) |
| else: |
| method() |
|
|
| st.session_state.kerasModelToDownload = downloadKerasModel() |
| st.session_state.plotsToDownload = create_zip_of_png_files() |
|
|
| @st.fragment() |
| def downloads(): |
| st.download_button( |
| label="Download Model", |
| data = downloadKerasModel(), |
| file_name="model.keras", |
| mime="application/octet-stream" |
| ); |
| |
| st.download_button( |
| label="Download Plots", |
| data=create_zip_of_png_files(), |
| file_name="images.zip", |
| mime="application/zip" |
| ); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| with st.sidebar: |
| downloads() |
|
|
| |
|
|
| image_files = glob.glob("*.png") |
|
|
| |
| st.image(image_files) |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
|
|