OptKeras (Keras Optuna Wrapper) - use optkeras inside my own class, AttributeError: type object 'FrozenTrial' has no attribute '_field_types'
OptKeras (Keras Optuna Wrapper) - use optkeras inside my own class, AttributeError: type object 'FrozenTrial' has no attribute '_field_types'
我写了一个简单的 Keras 代码,其中我将 CNN 用于时尚 mnist 数据集。一切都很好。我实现了自己的 class 并且 class 化没问题。
但是,我想使用 Optuna,作为 OptKeras(Keras 的 Optuna 包装器),您可以在此处查看示例:https://medium.com/@Minyus86/optkeras-112bcc34ec73。
但是,我的代码有问题。当我尝试在我自己的 class 中使用 optKeras 时。这是代码:(普通 run
方法有效,但 optuna_run
给出错误:AttributeError: type object 'FrozenTrial' has no attribute '_field_types'
.
! pip install optkeras
# -*- coding: utf-8 -*-
#!/usr/bin/env python3
import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense, SimpleRNN
from keras.callbacks import ModelCheckpoint
from keras import backend as K
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import sklearn.metrics
import optuna
from optkeras.optkeras import OptKeras
import sys
import math
import numpy
import scipy.io as sio
import matplotlib.pyplot as plt
class OptunaTest():
def __init__(self):
self.fashion_mnist = keras.datasets.fashion_mnist
(self.train_images, self.train_labels), (self.test_images, self.test_labels) = self.fashion_mnist.load_data()
self.class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
self.train_images = self.train_images / 255.0
self.test_images = self.test_images / 255.0
self.model = None
self.study_name = 'FashionMnist' + '_Simple'
self.ok = OptKeras(study_name=self.study_name)
def run(self):
self.model = keras.Sequential()
self.model.add(keras.layers.Flatten(input_shape=(28, 28)))
self.model.add(keras.layers.Dense(128, activation='relu'))
self.model.add(keras.layers.Dense(10))
self.model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
self.model.fit(self.train_images, self.train_labels, epochs=5)
test_loss, test_acc = self.model.evaluate(self.test_images, self.test_labels, verbose=0)
predictions = self.model.predict(self.test_images)
INDEX = 10
print("\nPREDICTION: " + str(predictions[INDEX]))
print("\nMAX PREDICTION VAL: " + str(numpy.argmax(predictions[INDEX])))
print("\nLABEL: " + str(self.test_labels[INDEX]))
def optuna_run(self, trial):
K.clear_session()
self.model = keras.Sequential()
self.model.add(keras.layers.Flatten(input_shape=(28, 28)))
self.model.add(keras.layers.Dense(units = trial.suggest_categorical('units', [32, 64, 128]), activation = trial.suggest_categorical('activation', ['relu', 'linear'])))
self.model.add(keras.layers.Dense(units = trial.suggest_categorical('units', [32, 64, 128]), activation = trial.suggest_categorical('activation', ['relu', 'linear'])))
self.model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
self.model.fit(self.train_images, self.train_labels, epochs=5, callbacks = self.ok.callbacks(trial), verbose = self.ok.keras_verbose)
test_loss, test_acc = self.model.evaluate(self.test_images, self.test_labels, verbose=0)
predictions = self.model.predict(self.test_images)
print(ok.trial_best_value)
INDEX = 10
print("\nPREDICTION: " + str(predictions[INDEX]))
print("\nMAX PREDICTION VAL: " + str(numpy.argmax(predictions[INDEX])))
print("\nLABEL: " + str(self.test_labels[INDEX]))
if __name__ == "__main__":
ot = OptunaTest()
ot.run()
ot.ok.optimize(ot.optuna_run, timeout = 60)
也可以在这里找到代码:https://colab.research.google.com/drive/1uibWa80BdjatA5Kcw27eMUsS7SmwxaDk?usp=sharing。
完整的错误信息:
[W 2020-06-30 11:09:26,959] Setting status of trial#0 as TrialState.FAIL because of the following error: AttributeError("type object 'FrozenTrial' has no attribute '_field_types'",)
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 230, in synch_with_optuna
self.best_trial = self.study.best_trial
File "/usr/local/lib/python3.6/dist-packages/optuna/study.py", line 97, in best_trial
return copy.deepcopy(self._storage.get_best_trial(self._study_id))
File "/usr/local/lib/python3.6/dist-packages/optuna/storages/in_memory.py", line 293, in get_best_trial
raise ValueError("No trials are completed yet.")
ValueError: No trials are completed yet.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/optuna/study.py", line 734, in _run_trial
result = func(trial)
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 130, in fun_tf
return fun(trial)
File "<ipython-input-11-45495c9f2ae9>", line 65, in optima_run
self.model.fit(self.train_images, self.train_labels, epochs=10, callbacks = self.ok.callbacks(trial), verbose = self.ok.keras_verbose)
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 172, in callbacks
self.synch_with_optuna()
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 232, in synch_with_optuna
self.best_trial = get_trial_default()
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 367, in get_trial_default
num_fields = optuna.structs.FrozenTrial._field_types.__len__()
AttributeError: type object 'FrozenTrial' has no attribute '_field_types'
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py in synch_with_optuna(self)
229 try:
--> 230 self.best_trial = self.study.best_trial
231 except:
12 frames
ValueError: No trials are completed yet.
During handling of the above exception, another exception occurred:
AttributeError Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py in get_trial_default()
365
366 def get_trial_default():
--> 367 num_fields = optuna.structs.FrozenTrial._field_types.__len__()
368 assert num_fields in (10, 11, 12)
369 if num_fields == 12: # possible future version
AttributeError: type object 'FrozenTrial' has no attribute '_field_types'
问题的原因似乎是 optkeras(我得到的版本是 0.0.7)与 optuna 库不是最新的。通过进行以下更改,我能够使其与 optuna 1.5.0 一起使用:
首先,您需要像这样在 运行 您的代码之前对 get_default_trial
进行 monkey-patch:
import optkeras
optkeras.optkeras.get_trial_default = lambda: optuna.trial.FrozenTrial(
None, None, None, None, None, None, None, None, None, None, None)
这样做之后,我得到一个错误 Callback
说:
AttributeError: 'OptKeras' object has no attribute '_implements_train_batch_hooks'
要解决此问题,您必须手动编辑 optkeras.py,但不要太多 - 只需将 tensorflow.
添加到前两行导入中,即使它们:
import tensorflow.keras.backend as K
from tensorflow.keras.callbacks import Callback, CSVLogger, ModelCheckpoint
而不是:
import keras.backend as K
from keras.callbacks import Callback, CSVLogger, ModelCheckpoint
如果安装后无法更改代码,那可能有点问题 - 我可能只建议复制 optkeras 库的完整代码(它只是一个文件 optkeras.py)并使用 fixed在你的脚本或类似的东西中的那个版本。不幸的是,我没有看到猴子修补这个导入问题的好方法。也就是说,我认为即使从 python 即时更改它也相当容易(即在导入 optkeras 之前从 python 中更改 optkeras.py
行)或复制 optkeras.py(也来自 python 脚本)+ 即时替换字符串,然后从新位置导入。
完成后我只需要:
- 修正代码中的拼写错误(
print(ok.trial_best_value)
应该是 print(self.ok.trial_best_value)
)
- 将
validation_split=0.1
添加到 self.model.fit
调用(或者您可以使用其他东西进行调整 - 仅使用现有代码示例回调不会获得 val_loss
值,因为没有验证set 和 optkeras 默认使用 val_loss
- 请参阅 OptKeras
构造函数的 monitor
参数)。我的猜测是,您可能想要创建一个固定的验证集,或者监控训练损失 loss
而不是 val_loss
.
- 在
optuna_run
方法的末尾添加return test_loss
。
所有这些更改之后,一切似乎都正常。
我写了一个简单的 Keras 代码,其中我将 CNN 用于时尚 mnist 数据集。一切都很好。我实现了自己的 class 并且 class 化没问题。
但是,我想使用 Optuna,作为 OptKeras(Keras 的 Optuna 包装器),您可以在此处查看示例:https://medium.com/@Minyus86/optkeras-112bcc34ec73。
但是,我的代码有问题。当我尝试在我自己的 class 中使用 optKeras 时。这是代码:(普通 run
方法有效,但 optuna_run
给出错误:AttributeError: type object 'FrozenTrial' has no attribute '_field_types'
.
! pip install optkeras
# -*- coding: utf-8 -*-
#!/usr/bin/env python3
import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense, SimpleRNN
from keras.callbacks import ModelCheckpoint
from keras import backend as K
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import sklearn.metrics
import optuna
from optkeras.optkeras import OptKeras
import sys
import math
import numpy
import scipy.io as sio
import matplotlib.pyplot as plt
class OptunaTest():
def __init__(self):
self.fashion_mnist = keras.datasets.fashion_mnist
(self.train_images, self.train_labels), (self.test_images, self.test_labels) = self.fashion_mnist.load_data()
self.class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
self.train_images = self.train_images / 255.0
self.test_images = self.test_images / 255.0
self.model = None
self.study_name = 'FashionMnist' + '_Simple'
self.ok = OptKeras(study_name=self.study_name)
def run(self):
self.model = keras.Sequential()
self.model.add(keras.layers.Flatten(input_shape=(28, 28)))
self.model.add(keras.layers.Dense(128, activation='relu'))
self.model.add(keras.layers.Dense(10))
self.model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
self.model.fit(self.train_images, self.train_labels, epochs=5)
test_loss, test_acc = self.model.evaluate(self.test_images, self.test_labels, verbose=0)
predictions = self.model.predict(self.test_images)
INDEX = 10
print("\nPREDICTION: " + str(predictions[INDEX]))
print("\nMAX PREDICTION VAL: " + str(numpy.argmax(predictions[INDEX])))
print("\nLABEL: " + str(self.test_labels[INDEX]))
def optuna_run(self, trial):
K.clear_session()
self.model = keras.Sequential()
self.model.add(keras.layers.Flatten(input_shape=(28, 28)))
self.model.add(keras.layers.Dense(units = trial.suggest_categorical('units', [32, 64, 128]), activation = trial.suggest_categorical('activation', ['relu', 'linear'])))
self.model.add(keras.layers.Dense(units = trial.suggest_categorical('units', [32, 64, 128]), activation = trial.suggest_categorical('activation', ['relu', 'linear'])))
self.model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
self.model.fit(self.train_images, self.train_labels, epochs=5, callbacks = self.ok.callbacks(trial), verbose = self.ok.keras_verbose)
test_loss, test_acc = self.model.evaluate(self.test_images, self.test_labels, verbose=0)
predictions = self.model.predict(self.test_images)
print(ok.trial_best_value)
INDEX = 10
print("\nPREDICTION: " + str(predictions[INDEX]))
print("\nMAX PREDICTION VAL: " + str(numpy.argmax(predictions[INDEX])))
print("\nLABEL: " + str(self.test_labels[INDEX]))
if __name__ == "__main__":
ot = OptunaTest()
ot.run()
ot.ok.optimize(ot.optuna_run, timeout = 60)
也可以在这里找到代码:https://colab.research.google.com/drive/1uibWa80BdjatA5Kcw27eMUsS7SmwxaDk?usp=sharing。
完整的错误信息:
[W 2020-06-30 11:09:26,959] Setting status of trial#0 as TrialState.FAIL because of the following error: AttributeError("type object 'FrozenTrial' has no attribute '_field_types'",)
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 230, in synch_with_optuna
self.best_trial = self.study.best_trial
File "/usr/local/lib/python3.6/dist-packages/optuna/study.py", line 97, in best_trial
return copy.deepcopy(self._storage.get_best_trial(self._study_id))
File "/usr/local/lib/python3.6/dist-packages/optuna/storages/in_memory.py", line 293, in get_best_trial
raise ValueError("No trials are completed yet.")
ValueError: No trials are completed yet.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/optuna/study.py", line 734, in _run_trial
result = func(trial)
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 130, in fun_tf
return fun(trial)
File "<ipython-input-11-45495c9f2ae9>", line 65, in optima_run
self.model.fit(self.train_images, self.train_labels, epochs=10, callbacks = self.ok.callbacks(trial), verbose = self.ok.keras_verbose)
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 172, in callbacks
self.synch_with_optuna()
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 232, in synch_with_optuna
self.best_trial = get_trial_default()
File "/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py", line 367, in get_trial_default
num_fields = optuna.structs.FrozenTrial._field_types.__len__()
AttributeError: type object 'FrozenTrial' has no attribute '_field_types'
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py in synch_with_optuna(self)
229 try:
--> 230 self.best_trial = self.study.best_trial
231 except:
12 frames
ValueError: No trials are completed yet.
During handling of the above exception, another exception occurred:
AttributeError Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/optkeras/optkeras.py in get_trial_default()
365
366 def get_trial_default():
--> 367 num_fields = optuna.structs.FrozenTrial._field_types.__len__()
368 assert num_fields in (10, 11, 12)
369 if num_fields == 12: # possible future version
AttributeError: type object 'FrozenTrial' has no attribute '_field_types'
问题的原因似乎是 optkeras(我得到的版本是 0.0.7)与 optuna 库不是最新的。通过进行以下更改,我能够使其与 optuna 1.5.0 一起使用:
首先,您需要像这样在 运行 您的代码之前对 get_default_trial
进行 monkey-patch:
import optkeras
optkeras.optkeras.get_trial_default = lambda: optuna.trial.FrozenTrial(
None, None, None, None, None, None, None, None, None, None, None)
这样做之后,我得到一个错误 Callback
说:
AttributeError: 'OptKeras' object has no attribute '_implements_train_batch_hooks'
要解决此问题,您必须手动编辑 optkeras.py,但不要太多 - 只需将 tensorflow.
添加到前两行导入中,即使它们:
import tensorflow.keras.backend as K
from tensorflow.keras.callbacks import Callback, CSVLogger, ModelCheckpoint
而不是:
import keras.backend as K
from keras.callbacks import Callback, CSVLogger, ModelCheckpoint
如果安装后无法更改代码,那可能有点问题 - 我可能只建议复制 optkeras 库的完整代码(它只是一个文件 optkeras.py)并使用 fixed在你的脚本或类似的东西中的那个版本。不幸的是,我没有看到猴子修补这个导入问题的好方法。也就是说,我认为即使从 python 即时更改它也相当容易(即在导入 optkeras 之前从 python 中更改 optkeras.py
行)或复制 optkeras.py(也来自 python 脚本)+ 即时替换字符串,然后从新位置导入。
完成后我只需要:
- 修正代码中的拼写错误(
print(ok.trial_best_value)
应该是print(self.ok.trial_best_value)
) - 将
validation_split=0.1
添加到self.model.fit
调用(或者您可以使用其他东西进行调整 - 仅使用现有代码示例回调不会获得val_loss
值,因为没有验证set 和 optkeras 默认使用val_loss
- 请参阅OptKeras
构造函数的monitor
参数)。我的猜测是,您可能想要创建一个固定的验证集,或者监控训练损失loss
而不是val_loss
. - 在
optuna_run
方法的末尾添加return test_loss
。
所有这些更改之后,一切似乎都正常。