#python #tensorflow #machine-learning #model #gurobi
#python #тензорный поток #машинное обучение #Модель #gurobi
Вопрос:
В модели gurobi мне нужно использовать переменную (добавленную через addVar) в качестве входных данных для модели тензорного потока (я использовал простую модель, обученную следовать функции: y = 2x 1), которая затем используется в ограничении.
Модель tensorflow уже обучена и загружена, мне просто нужно использовать метод predict .
Проблема оптимизации заключается в следующем: получить наилучшие входные данные для модели tensorflow, чтобы прогноз вывода был наиболее близок к заданной ссылке.
Например, если я хочу, чтобы прогноз был равен 11, входные данные модели должны быть очень близки к 5 (2*5 1 = 11). Способ, которым я это реализовал, заключается в использовании целевой функции абсолютной ошибки между эталонным значением и прогнозируемым, путем линеализации функции abs(), чтобы иметь возможность использовать ее в Gurobi.
Модель gurobi верна, проблема заключается в использовании переменной gurobi в качестве входных данных для модели tf, потому что, пока проблема оптимизации не решена, она не имеет определенного значения (присвоение ей начального значения не сработает).
Это код для моей модели:
import gurobipy as gp
# Load tensorflow model
model = tf.keras.models.load_model('./models/test_model.h5')
mdl = gp.Model()
ref = 11 # desired output value
w = mdl.addVar(lb=-10, name='input')
a = ref # just for naming purposes
b = mdl.addVar(lb=-10,name = "b")
x = mdl.addVar(name='error') # variable needed to linealize abs() function
mdl.update()
# objective function is abs(ref - model.predict([w])[0][0])
mdl.setObjective(x, gp.GRB.MINIMIZE)
mdl.addConstr(w <= 10)
mdl.addConstr(w >= -10)
# mdl.addConstr(b == 2*w 1) # if I use this line instead of the next one, everything works but I am not using the tensorflow model
mdl.addConstr(b == model.predict([w])[0][0]) # does not work
# 3 constraints needed for the abs() linealization
mdl.addConstr(x >= 0)
mdl.addConstr(a - b <= x)
mdl.addConstr(b - a <= x)
mdl.update()
# Solve and show solution
mdl.optimize()
for v in mdl.getVars():
print('%s %g' % (v.varName, v.x))
print('2w 1 =', 2*w.X 1)
И данная ошибка:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~AppDataLocalTemp/ipykernel_6484/1577208091.py in <module>
16
17 # mdl.addConstr(b == 2*w 1) # if I use this line instead of the next one, everything works but I am not using the tensorflow model
---> 18 mdl.addConstr(b == model.predict([w])[0][0]) # does not work
19
20 # 3 constraints needed for the abs() linealization
~AppDataLocalPackagesPythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0LocalCachelocal-packagesPython38site-packageskerasenginetraining.py in predict(self, x, batch_size, verbose, steps, callbacks, max_queue_size, workers, use_multiprocessing)
1718 '. Consider setting it to AutoShardPolicy.DATA.')
1719
-> 1720 data_handler = data_adapter.get_data_handler(
1721 x=x,
1722 batch_size=batch_size,
~AppDataLocalPackagesPythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0LocalCachelocal-packagesPython38site-packageskerasenginedata_adapter.py in get_data_handler(*args, **kwargs)
1381 if getattr(kwargs["model"], "_cluster_coordinator", None):
1382 return _ClusterCoordinatorDataHandler(*args, **kwargs)
-> 1383 return DataHandler(*args, **kwargs)
1384
1385
~AppDataLocalPackagesPythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0LocalCachelocal-packagesPython38site-packageskerasenginedata_adapter.py in __init__(self, x, y, sample_weight, batch_size, steps_per_epoch, initial_epoch, epochs, shuffle, class_weight, max_queue_size, workers, use_multiprocessing, model, steps_per_execution, distribute)
1135 self._steps_per_execution_value = steps_per_execution.numpy().item()
1136
-> 1137 adapter_cls = select_data_adapter(x, y)
1138 self._adapter = adapter_cls(
1139 x,
~AppDataLocalPackagesPythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0LocalCachelocal-packagesPython38site-packageskerasenginedata_adapter.py in select_data_adapter(x, y)
974 if not adapter_cls:
975 # TODO(scottzhu): This should be a less implementation-specific error.
--> 976 raise ValueError(
977 "Failed to find data adapter that can handle "
978 "input: {}, {}".format(
ValueError: Failed to find data adapter that can handle input: (<class 'list'> containing values of types {"<class 'gurobipy.Var'>"}), <class 'NoneType'>
Однако, если я использую строку над b == model.predict([w])[0][0]
ограничением, все работает нормально, и найденное решение действительно равно 5:
Gurobi Optimizer version 9.5.0 build v9.5.0rc5 (win64)
Thread count: 2 physical cores, 4 logical processors, using up to 4 threads
Optimize a model with 6 rows, 3 columns and 9 nonzeros
Model fingerprint: 0xc4fcfa7a
Coefficient statistics:
Matrix range [1e 00, 2e 00]
Objective range [1e 00, 1e 00]
Bounds range [1e 01, 1e 01]
RHS range [1e 00, 1e 01]
Presolve removed 4 rows and 1 columns
Presolve time: 0.01s
Presolved: 2 rows, 2 columns, 4 nonzeros
Iteration Objective Primal Inf. Dual Inf. Time
0 0.0000000e 00 1.050000e 01 0.000000e 00 0s
1 0.0000000e 00 0.000000e 00 0.000000e 00 0s
Solved in 1 iterations and 0.04 seconds (0.00 work units)
Optimal objective 0.000000000e 00
input 5
b 11
error 0
2w 1 = 11.0
Ответ №1:
Вы просто не можете передать переменную Gurobi в модель TensorFlow. Это совершенно разные программные пакеты, которые не совместимы таким образом. Вы должны изучить, как использовать обратные вызовы Gurobi, чтобы увидеть, как вы можете вызывать разные коды из запущенной оптимизации. Пожалуйста, обратите внимание, что вы не можете изменять проблему по своему усмотрению во время выполнения обратного вызова. Вы также можете просто попробовать итеративный подход: оптимизировать, чтобы получить первую оценку, которую затем можно подключить к Tensorflow, а затем оптимизировать с использованием новой информации.
Я не уверен, какова цель вашего подхода, поэтому мои предложения могут быть неприменимы к вашей идее.
РЕДАКТИРОВАТЬ: возможно, вы сможете использовать этот инструмент для своего приложения: ReLU_ANN_MILP