Open
Description
🐛 Bug
The penicillin test function gives better values than in the reference paper. In the original paper, the authors sample 10**6
configurations and obtain an optimum around -14.65
. Doing the same with the BoTorch implementation leads to values smaller than -20
.
To reproduce
** Code snippet to reproduce **
import numpy as np
import torch
from botorch.test_functions.multi_objective import Penicillin
from botorch.utils.transforms import unnormalize
p = Penicillin(noise_std=0, negate=True)
# Draw a lot of samples as in the original paper
input_orig = torch.tensor(np.random.random((1000000, 7))).double()
input = unnormalize(input_orig, bounds=torch.tensor(p._bounds).transpose(0, 1))
values = p.evaluate_true(input)[:, 0]
argmin = np.argmin(values.numpy())
print(values[argmin], input[argmin], input_orig[argmin])
# Check whether this value might be due to scalarization
print(p.evaluate_true(input[argmin]))
** Stack trace/error message **
tensor(-23.1735, dtype=torch.float64) tensor([8.6234e+01, 1.1553e+00, 3.0218e+02, 1.7137e+01, 3.2586e-02, 6.2063e+02,
5.3257e+00], dtype=torch.float64) tensor([0.4372, 0.0616, 0.9176, 0.9519, 0.0461, 0.6032, 0.2171],
dtype=torch.float64)
tensor([-23.1735, 29.2081, 496.0000], dtype=torch.float64)
Expected Behavior
A value around -14.65
System information
Please complete the following information:
- 0.7.0
- 1.9.0
- 1.13.1+cu117
- Ubuntu 20.04
Additional context
I tried to feed the found value into the original code from https://github.com/HarryQL/TuRBO-Penicillin but that fails with the best value found with the BoTorch Penicillin function:
import numpy as np
import torch
# X: biomass concentration
# g/L
# X_0 = 0.1
# S:substrate concentration
# g/L
# S_0 = 0.1
# CL:dissolved oxygen concentration
# P: penicillin concentration
# g/L
# P_0 = 0
# CO2:carbon dioxide concentration;
# H:hydrogen ion concentration for pH
# T: temperature.
C_L_star = 8.26
Y_xs = 0.45
Y_xo = 0.04
Y_ps = 0.90
Y_po = 0.20
K_1 = 10**(-10)
K_2 = 7 * 10**(-5)
m_X = 0.014
m_o = 0.467
alpha_1 = 0.143
alpha_2 = 4*10**(-7)
alpha_3 = 10**(-4)
mu_X = 0.092
K_X = 0.15
# K_ox = 2*10**(-2)
# K_op = 5*10**(-4)
mu_p = 0.005
K_p = 0.0002
K_I = 0.10
p = 3
K = 0.04
k_g = 7 * 10**(3)
E_g = 5100
k_d = 10**(33)
E_d = 50000
# rou_dot_C_p = 1/1500
# rou_c_dot_C_pc = 1/2000
rou_dot_C_p = 1000
rou_c_dot_C_pc = 1000
r_q1 = 60
r_q2 = 1.6783 * 10**(-4)
a = 1000
b = 0.60
alpha = 70
beta = 0.4
lambd = 2.5 * 10**(-4)
gamma = 10**(-5)
# kelvin
T_v = 273
T_o = 373
# CAL/(MOL K)
R = 1.9872
# total unit time: hrs
t = 2500
V_max = 180
V_limits = [60, 120]
X_limits = [0.05, 18]
CO2 = 0
T_limits = [293, 303]
S_limits = [0.05, 18]
F_limits = [0.01, 0.50]
s_f_limits = [500, 700]
H_limits = [5, 6.5]
limits = [V_limits, X_limits, T_limits, S_limits, F_limits, s_f_limits, H_limits]
def penicilin_exp_BO(X_input):
# V_limits, X_limits, T_limits, S_limits, F_limits, s_f_limits, H_limits
V, X, T, S, F, s_f, H_ = X_input[:, 0], X_input[:, 1], X_input[:, 2], X_input[:, 3], X_input[:, 4], X_input[:, 5], X_input[:, 6]
P = 0
CO2 = 0
t = 2500
l_P = []
l_V = []
l_X = []
l_T = []
l_S = []
l_F = []
l_s_f = []
l_H_ = []
l_CO2 = []
l_t = []
l_P.append(P)
l_V.append(V)
l_X.append(X)
l_T.append(T)
l_S.append(S)
l_F.append(F)
l_s_f.append(s_f)
l_H_.append(H_)
l_CO2.append(CO2)
l_t.append(0)
H = 10 ** (-H_)
for i in np.arange(t) + 1:
F_loss = V * lambd * (np.exp(5 * ((T - T_o) / (T_v - T_o))) - 1)
dV_dt = F - F_loss
mu = (mu_X / (1 + K_1 / H + H / K_2)) * (S / (K_X * X + S)) * (
(k_g * np.exp(-E_g / (R * T))) - (k_d * np.exp(-E_d / (R * T))))
dX_dt = mu * X - (X / V) * dV_dt
mu_pp = mu_p * (S / (K_p + S + S ** 2 / K_I))
dS_dt = - (mu / Y_xs) * X - (mu_pp / Y_ps) * X - m_X * X + F * s_f / V - (S / V) * dV_dt
dP_dt = (mu_pp * X) - K * P - (P / V) * dV_dt
dCO2_dt = alpha_1 * dX_dt + alpha_2 * X + alpha_3
# UPDATE
P = P + dP_dt
V = V + dV_dt
X = X + dX_dt
S = S + dS_dt
CO2 = CO2 + dCO2_dt
l_P.append(P)
l_V.append(V)
l_X.append(X)
l_T.append(T)
l_S.append(S)
l_F.append(F)
l_s_f.append(s_f)
l_H_.append(H_)
l_CO2.append(CO2)
l_t.append(i)
if V > V_max:
# print('Too large V')
break
if S < 0:
# print('Too small S')
break
if dP_dt < 10e-12:
# print('Converged P')
break
print(P)
return -P
query = [8.6234e+01, 1.1553e+00, 3.0218e+02, 1.7137e+01, 3.2586e-02, 6.2063e+02, 5.3257e+00]
print(query)
print(
penicilin_exp_BO(
torch.tensor(query).reshape((1, -1)).float()
)
)
which gives
[86.234, 1.1553, 302.18, 17.137, 0.032586, 620.63, 5.3257]
Traceback (most recent call last):
File "/home/feurerm/projects/2022_pfns_4_bo/local_harryql.py", line 177, in <module>
penicilin_exp_BO(
File "/home/feurerm/projects/2022_pfns_4_bo/local_harryql.py", line 130, in penicilin_exp_BO
(k_g * np.exp(-E_g / (R * T))) - (k_d * np.exp(-E_d / (R * T))))
RuntimeError: Overflow when unpacking long