Я хочу использовать свою модель keras на разных компьютерах с разными версиями Python.
Я не хочу использовать Pickle и numpy.savez, потому что это вызывает проблемы в разных средах.
Я начинаю с этого, и это работает нормально
import json
import numpy as np
from tensorflow import keras
def save_mod(model, name = "my_model"):
with open(name + '.json', 'w') as fp:
json.dump(model.to_json(), fp)
# save weights
model_weights = model.get_weights()
return model_weights
def load_mod(model_weights_, name = "my_model"):
# load config
with open(name + ".json", "r") as read_file:
json_string = json.load(read_file)
model_ = keras.models.model_from_json(json_string, custom_objects = {})
# load weights
model_.set_weights(model_weights_)
return model_
model = keras.models.load_model("segmentation.h5")
weights = save_mod(model)
loaded_model = load_mod(weights)
Затем я пытаюсь сохранить и загрузить веса
np.savetxt('weights.txt', weights, fmt='%s')
loaded_weights = np.fromfile('weights.txt')
print(len(weights))
print(len(loaded_weights))
>> 112
>> 31013
У меня есть 112 и 31013, метод не работает
with open('test.txt', 'wb') as f:
np.savetxt(f, np.column_stack(weights), fmt='%1.10f')
он говорит >> все входные массивы должны иметь одинаковое количество измерений, но массив с индексом 0 имеет 4 измерения, а массив с индексом 1 имеет 2 измерения.
наконец я сделал это
class EncodeNumpy(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.ndarray):
return obj.tolist()
return json.JSONEncoder.default(self, obj)
we = np.array(weights)
print(a.shape)
json_dump = json.dumps({'we': we}, cls=EncodeNumpy)
json_load = json.loads(json_dump)
a_restored = np.asarray(json_load["we"])
print(a_restored.shape)
model.set_weights(a_restored)
это дало мне массивы (112) и (112)
но model.set_weights(a_restored) возвращает
AttributeError: 'list' object has no attribute 'shape'
Последняя ошибка
AttributeError: 'list' object has no attribute 'shape'
вызвано тем, что numpy не может преобразовать внутренние списки в ndarrays из-за несоответствия размера.
См. пример: списки одинакового размера
np.array([[1, 2, 3], [1, 2, 3]])
# array([[1, 2, 3],
# [1, 2, 3]])
против списков, имеющих другой размер
np.array([[1, 2, 3], [1, 2]])
# array([list([1, 2, 3]), list([1, 2])], dtype=object)
Это не то, что вы хотите в любом случае. Правильный способ в этом случае — превратить каждый внутренний список в ndarray отдельно и поместить их в список вместо ndarray.
Например, вы можете сделать что-то вроде:
a_restored = [np.asarray(el) for el in json_load["we"]]
Теперь вы должны быть в состоянии загрузить гири.
json_load = json.loads(json_dump)
a_restored = [np.asarray(el) for el in json_load["we"]]
model.set_weights(a_restored)