{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "0823043e-8451-4dc8-968c-ca066003f4a7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Running on local URL: http://127.0.0.1:7958\n", "\n", "To create a public link, set `share=True` in `launch()`.\n" ] }, { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import gradio as gr\n", "import torch\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from test_functions.Ackley10D import *\n", "from test_functions.Ackley2D import *\n", "from test_functions.Ackley6D import *\n", "from test_functions.HeatExchanger import *\n", "from test_functions.CantileverBeam import *\n", "from test_functions.Car import *\n", "from test_functions.CompressionSpring import *\n", "from test_functions.GKXWC1 import *\n", "from test_functions.GKXWC2 import *\n", "from test_functions.HeatExchanger import *\n", "from test_functions.JLH1 import *\n", "from test_functions.JLH2 import *\n", "from test_functions.KeaneBump import *\n", "from test_functions.GKXWC1 import *\n", "from test_functions.GKXWC2 import *\n", "from test_functions.PressureVessel import *\n", "from test_functions.ReinforcedConcreteBeam import *\n", "from test_functions.SpeedReducer import *\n", "from test_functions.ThreeTruss import *\n", "from test_functions.WeldedBeam import *\n", "# Import other objective functions as needed\n", "import time\n", "\n", "from Rosen_PFN4BO import *\n", "from PIL import Image\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "def s(input_string):\n", " return input_string\n", "\n", "\n", "\n", "\n", "def optimize(objective_function, iteration_input, progress=gr.Progress()):\n", "\n", " print(objective_function)\n", "\n", " # Variable setup\n", " Current_BEST = torch.tensor( -1e10 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -1e10 )\n", "\n", " if objective_function==\"CantileverBeam.png\":\n", " Current_BEST = torch.tensor( -82500 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -82500 )\n", " elif objective_function==\"CompressionSpring.png\":\n", " Current_BEST = torch.tensor( -8 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -8 )\n", " elif objective_function==\"HeatExchanger.png\":\n", " Current_BEST = torch.tensor( -30000 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -30000 )\n", " elif objective_function==\"ThreeTruss.png\":\n", " Current_BEST = torch.tensor( -300 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -300 )\n", " elif objective_function==\"Reinforcement.png\":\n", " Current_BEST = torch.tensor( -440 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -440 )\n", " elif objective_function==\"PressureVessel.png\":\n", " Current_BEST = torch.tensor( -40000 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -40000 ) \n", " elif objective_function==\"SpeedReducer.png\":\n", " Current_BEST = torch.tensor( -3200 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -3200 ) \n", " elif objective_function==\"WeldedBeam.png\":\n", " Current_BEST = torch.tensor( -35 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -35 )\n", " elif objective_function==\"Car.png\":\n", " Current_BEST = torch.tensor( -35 ) # Some arbitrary very small number\n", " Prev_BEST = torch.tensor( -35 )\n", "\n", " # Initial random samples\n", " # print(objective_functions)\n", " trained_X = torch.rand(20, objective_functions[objective_function]['dim'])\n", "\n", " # Scale it to the domain of interest using the selected function\n", " # print(objective_function)\n", " X_Scaled = objective_functions[objective_function]['scaling'](trained_X)\n", "\n", " # Get the constraints and objective\n", " trained_gx, trained_Y = objective_functions[objective_function]['function'](X_Scaled)\n", "\n", " # Convergence list to store best values\n", " convergence = []\n", " time_conv = []\n", "\n", " START_TIME = time.time()\n", "\n", "\n", "# with gr.Progress(track_tqdm=True) as progress:\n", "\n", "\n", " # Optimization Loop\n", " for ii in progress.tqdm(range(iteration_input)): # Example with 100 iterations\n", "\n", " # (0) Get the updated data for this iteration\n", " X_scaled = objective_functions[objective_function]['scaling'](trained_X)\n", " trained_gx, trained_Y = objective_functions[objective_function]['function'](X_scaled)\n", "\n", " # (1) Randomly sample Xpen \n", " X_pen = torch.rand(1000,trained_X.shape[1])\n", "\n", " # (2) PFN inference phase with EI\n", " default_model = 'final_models/model_hebo_morebudget_9_unused_features_3.pt'\n", " \n", " ei, p_feas = Rosen_PFN_Parallel(default_model,\n", " trained_X, \n", " trained_Y, \n", " trained_gx,\n", " X_pen,\n", " 'power',\n", " 'ei'\n", " )\n", "\n", " # Calculating CEI\n", " CEI = ei\n", " for jj in range(p_feas.shape[1]):\n", " CEI = CEI*p_feas[:,jj]\n", "\n", " # (4) Get the next search value\n", " rec_idx = torch.argmax(CEI)\n", " best_candidate = X_pen[rec_idx,:].unsqueeze(0)\n", "\n", " # (5) Append the next search point\n", " trained_X = torch.cat([trained_X, best_candidate])\n", "\n", "\n", " ################################################################################\n", " # This is just for visualizing the best value. \n", " # This section can be remove for pure optimization purpose\n", " Current_X = objective_functions[objective_function]['scaling'](trained_X)\n", " Current_GX, Current_Y = objective_functions[objective_function]['function'](Current_X)\n", " if ((Current_GX<=0).all(dim=1)).any():\n", " Current_BEST = torch.max(Current_Y[(Current_GX<=0).all(dim=1)])\n", " else:\n", " Current_BEST = Prev_BEST\n", " ################################################################################\n", " \n", " # (ii) Convergence tracking (assuming the best Y is to be maximized)\n", " # if Current_BEST != -1e10:\n", " print(Current_BEST)\n", " print(convergence)\n", " convergence.append(Current_BEST.abs())\n", " time_conv.append(time.time() - START_TIME)\n", "\n", " # Timing\n", " END_TIME = time.time()\n", " TOTAL_TIME = END_TIME - START_TIME\n", " \n", " # Website visualization\n", " # (i) Radar chart for trained_X\n", " radar_chart = None\n", " # radar_chart = create_radar_chart(X_scaled)\n", " # (ii) Convergence tracking (assuming the best Y is to be maximized)\n", " convergence_plot = create_convergence_plot(objective_function, iteration_input, \n", " time_conv, \n", " convergence, TOTAL_TIME)\n", "\n", "\n", " return convergence_plot\n", " # return radar_chart, convergence_plot\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "def create_radar_chart(X_scaled):\n", " fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))\n", " labels = [f'x{i+1}' for i in range(X_scaled.shape[1])]\n", " values = X_scaled.mean(dim=0).numpy()\n", " \n", " num_vars = len(labels)\n", " angles = np.linspace(0, 2 * np.pi, num_vars, endpoint=False).tolist()\n", " values = np.concatenate((values, [values[0]]))\n", " angles += angles[:1]\n", "\n", " ax.fill(angles, values, color='green', alpha=0.25)\n", " ax.plot(angles, values, color='green', linewidth=2)\n", " ax.set_yticklabels([])\n", " ax.set_xticks(angles[:-1])\n", " # ax.set_xticklabels(labels)\n", " ax.set_xticklabels([f'{label}\\n({value:.2f})' for label, value in zip(labels, values[:-1])]) # Show values\n", " ax.set_title(\"Selected Design\", size=15, color='black', y=1.1)\n", " \n", " plt.close(fig)\n", " return fig\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "def create_convergence_plot(objective_function, iteration_input, time_conv, convergence, TOTAL_TIME):\n", " fig, ax = plt.subplots()\n", " \n", " # Realtime optimization data\n", " ax.plot(time_conv, convergence, '^-', label='PFN-CBO (Realtime)' )\n", "\n", " # Stored GP data\n", " if objective_function==\"CantileverBeam.png\":\n", " GP_TIME = torch.load('CantileverBeam_CEI_Avg_Time.pt')\n", " GP_OBJ = torch.load('CantileverBeam_CEI_Avg_Obj.pt')\n", " \n", " elif objective_function==\"CompressionSpring.png\":\n", " GP_TIME = torch.load('CompressionSpring_CEI_Avg_Time.pt')\n", " GP_OBJ = torch.load('CompressionSpring_CEI_Avg_Obj.pt')\n", "\n", " elif objective_function==\"HeatExchanger.png\":\n", " GP_TIME = torch.load('HeatExchanger_CEI_Avg_Time.pt')\n", " GP_OBJ = torch.load('HeatExchanger_CEI_Avg_Obj.pt')\n", " \n", " elif objective_function==\"ThreeTruss.png\":\n", " GP_TIME = torch.load('ThreeTruss_CEI_Avg_Time.pt')\n", " GP_OBJ = torch.load('ThreeTruss_CEI_Avg_Obj.pt')\n", " \n", " elif objective_function==\"Reinforcement.png\":\n", " GP_TIME = torch.load('ReinforcedConcreteBeam_CEI_Avg_Time.pt')\n", " GP_OBJ = torch.load('ReinforcedConcreteBeam_CEI_Avg_Obj.pt')\n", " \n", " elif objective_function==\"PressureVessel.png\":\n", " GP_TIME = torch.load('PressureVessel_CEI_Avg_Time.pt')\n", " GP_OBJ = torch.load('PressureVessel_CEI_Avg_Obj.pt')\n", " \n", " elif objective_function==\"SpeedReducer.png\":\n", " GP_TIME = torch.load('SpeedReducer_CEI_Avg_Time.pt')\n", " GP_OBJ = torch.load('SpeedReducer_CEI_Avg_Obj.pt')\n", " \n", " elif objective_function==\"WeldedBeam.png\":\n", " GP_TIME = torch.load('WeldedBeam_CEI_Avg_Time.pt')\n", " GP_OBJ = torch.load('WeldedBeam_CEI_Avg_Obj.pt') \n", "\n", " elif objective_function==\"Car.png\":\n", " GP_TIME = torch.load('Car_CEI_Avg_Time.pt')\n", " GP_OBJ = torch.load('Car_CEI_Avg_Obj.pt') \n", " \n", " # Plot GP data \n", " ax.plot(GP_TIME[:iteration_input], GP_OBJ[:iteration_input], '^-', label='GP-CBO (Data)' )\n", "\n", " \n", " ax.set_xlabel('Time (seconds)')\n", " ax.set_ylabel('Objective Value')\n", " ax.set_title('Convergence Plot for {t} iterations'.format(t=iteration_input))\n", " # ax.legend()\n", "\n", " if objective_function==\"CantileverBeam.png\":\n", " ax.axhline(y=50000, color='red', linestyle='--', label='Optimal Value')\n", "\n", " elif objective_function==\"CompressionSpring.png\":\n", " ax.axhline(y=0, color='red', linestyle='--', label='Optimal Value')\n", "\n", " elif objective_function==\"HeatExchanger.png\":\n", " ax.axhline(y=4700, color='red', linestyle='--', label='Optimal Value')\n", " \n", " elif objective_function==\"ThreeTruss.png\":\n", " ax.axhline(y=262, color='red', linestyle='--', label='Optimal Value')\n", " \n", " elif objective_function==\"Reinforcement.png\":\n", " ax.axhline(y=355, color='red', linestyle='--', label='Optimal Value')\n", " \n", " elif objective_function==\"PressureVessel.png\":\n", " ax.axhline(y=5000, color='red', linestyle='--', label='Optimal Value')\n", " \n", " elif objective_function==\"SpeedReducer.png\":\n", " ax.axhline(y=2650, color='red', linestyle='--', label='Optimal Value')\n", " \n", " elif objective_function==\"WeldedBeam.png\":\n", " ax.axhline(y=6, color='red', linestyle='--', label='Optimal Value') \n", "\n", " elif objective_function==\"Car.png\":\n", " ax.axhline(y=25, color='red', linestyle='--', label='Optimal Value') \n", "\n", " \n", " ax.legend(loc='best')\n", " # ax.legend(loc='lower left')\n", " \n", "\n", " # Add text to the top right corner of the plot\n", " if len(convergence) == 0:\n", " ax.text(0.5, 0.5, 'No Feasible Design Found', transform=ax.transAxes, fontsize=12,\n", " verticalalignment='top', horizontalalignment='right')\n", " \n", " \n", " plt.close(fig)\n", " return fig\n", "\n", "\n", "\n", "\n", "\n", "\n", "# Define available objective functions\n", "objective_functions = {\n", " # \"ThreeTruss.png\": {\"image\": \"ThreeTruss.png\", \n", " # \"function\": ThreeTruss, \n", " # \"scaling\": ThreeTruss_Scaling, \n", " # \"dim\": 2},\n", " \"CompressionSpring.png\": {\"image\": \"CompressionSpring.png\", \n", " \"function\": CompressionSpring, \n", " \"scaling\": CompressionSpring_Scaling, \n", " \"dim\": 3},\n", " \"Reinforcement.png\": {\"image\": \"Reinforcement.png\", \"function\": ReinforcedConcreteBeam, \"scaling\": ReinforcedConcreteBeam_Scaling, \"dim\": 3},\n", " \"PressureVessel.png\": {\"image\": \"PressureVessel.png\", \"function\": PressureVessel, \"scaling\": PressureVessel_Scaling, \"dim\": 4},\n", " \"SpeedReducer.png\": {\"image\": \"SpeedReducer.png\", \"function\": SpeedReducer, \"scaling\": SpeedReducer_Scaling, \"dim\": 7},\n", " \"WeldedBeam.png\": {\"image\": \"WeldedBeam.png\", \"function\": WeldedBeam, \"scaling\": WeldedBeam_Scaling, \"dim\": 4},\n", " \"HeatExchanger.png\": {\"image\": \"HeatExchanger.png\", \"function\": HeatExchanger, \"scaling\": HeatExchanger_Scaling, \"dim\": 8},\n", " \"CantileverBeam.png\": {\"image\": \"CantileverBeam.png\", \"function\": CantileverBeam, \"scaling\": CantileverBeam_Scaling, \"dim\": 10},\n", " \"Car.png\": {\"image\": \"Car.png\", \"function\": Car, \"scaling\": Car_Scaling, \"dim\": 11},\n", "}\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "# Extract just the image paths for the gallery\n", "image_paths = [key for key in objective_functions]\n", "\n", "\n", "def submit_action(objective_function_choices, iteration_input):\n", " # print(iteration_input)\n", " # print(len(objective_function_choices))\n", " # print(objective_functions[objective_function_choices]['function'])\n", " if len(objective_function_choices)>0:\n", " selected_function = objective_functions[objective_function_choices]['function']\n", " return optimize(objective_function_choices, iteration_input)\n", " return None\n", "\n", "# Function to clear the output\n", "def clear_output():\n", " # print(gallery.selected_index)\n", " \n", " return gr.update(value=[], selected=None), None, 15, gr.Markdown(\"\"), 'Test_formulation_default.png'\n", "\n", "def reset_gallery():\n", " return gr.update(value=image_paths)\n", "\n", "\n", "with gr.Blocks() as demo:\n", " # Centered Title and Description using gr.HTML\n", " gr.HTML(\n", " \"\"\"\n", "
\n", "

Pre-trained Transformer for Constrained Bayesian Optimization

\n", "

Paper: \n", " Fast and Accurate Bayesian Optimization with Pre-trained Transformers for Constrained Engineering Problems \n", "

\n", "\n", "

This is a demo for Bayesian Optimization using PFN (Prior-Data Fitted Networks). \n", " Select your objective function by clicking on one of the check boxes below, then enter the iteration number to run the optimization process. \n", " The results will be visualized in the radar chart and convergence plot.

\n", " \n", " \n", " \n", "\n", "
\n", " \"\"\"\n", " )\n", "\n", " \n", " with gr.Row():\n", " \n", " \n", " with gr.Column(variant='compact'):\n", " # gr.Markdown(\"# Inputs: \")\n", " \n", " with gr.Row():\n", " gr.Markdown(\"## Select a problem (objective): \")\n", " img_key = gr.Markdown(value=\"\", visible=False)\n", " \n", " gallery = gr.Gallery(value=image_paths, label=\"Objective Functions\", \n", " # height = 450, \n", " object_fit='contain',\n", " columns=3, rows=3, elem_id=\"gallery\")\n", " \n", " gr.Markdown(\"## Enter iteration Number: \")\n", " iteration_input = gr.Slider(label=\"Iterations:\", minimum=15, maximum=50, step=1, value=15)\n", " \n", "\n", " # Row for the Clear and Submit buttons\n", " with gr.Row():\n", " clear_button = gr.Button(\"Clear\")\n", " submit_button = gr.Button(\"Submit\", variant=\"primary\")\n", "\n", " with gr.Column():\n", " # gr.Markdown(\"# Outputs: \")\n", " gr.Markdown(\"## Problem Formulation: \")\n", " formulation = gr.Image(value='Formulation_default.png', height=150)\n", " gr.Markdown(\"## Results: \")\n", " gr.Markdown(\"The graph will plot the best observed data v.s. the time for the algorithm to run up until the iteration. The PFN-CBO shows the result of the realtime optimization running in the backend while the GP-CBO shows the stored data from our previous experiments since running GP-CBO will take longer time.\")\n", " convergence_plot = gr.Plot(label=\"Convergence Plot\")\n", "\n", "\n", "\n", " def handle_select(evt: gr.SelectData):\n", " selected_image = evt.value\n", " key = evt.value['image']['orig_name']\n", " formulation = 'Test_formulation.png'\n", " print('here')\n", " print(key)\n", "\n", " return key, formulation\n", " \n", " gallery.select(fn=handle_select, inputs=None, outputs=[img_key, formulation])\n", "\n", "\n", " \n", " submit_button.click(\n", " submit_action,\n", " inputs=[img_key, iteration_input],\n", " # outputs= [radar_plot, convergence_plot],\n", " outputs= convergence_plot,\n", " \n", " # progress=True # Enable progress tracking\n", " \n", " )\n", "\n", " clear_button.click(\n", " clear_output,\n", " inputs=None,\n", " outputs=[gallery, convergence_plot, iteration_input, img_key, formulation]\n", " ).then(\n", " # Step 2: Reset the gallery to the original list\n", " reset_gallery,\n", " inputs=None,\n", " outputs=gallery\n", " )\n", "\n", " \n", "\n", "demo.launch()\n" ] }, { "cell_type": "code", "execution_count": null, "id": "776c7ab2-96a1-4e22-9b4b-daf69960e3c4", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "9d2c7c58-43b1-4e5b-9135-17683dac1788", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "5d33a24c-818c-4023-bbbd-495f992a9d1a", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "764d0258-ec88-41d5-b5b5-e0bcb39ff313", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "d2c35245-543c-4b82-8d12-04f3dda1468b", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "e3663adc-3e95-418b-bf50-0a372615cdd6", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "30886262-bd87-4760-a585-7872e071663f", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.14" } }, "nbformat": 4, "nbformat_minor": 5 }