我没有根据[官方文件]使用回调函数保存模型:https://radimrehurek.com/gensim/models/callbacks.html
AttributeError:无法腌制本地对象'train_model..shf'
from random import shuffle
from gensim.models.callbacks import CallbackAny2Vec
from gensim.test.utils import get_tmpfile
class shf(CallbackAny2Vec):
def __init__(self, x, path_prefix):
self.epoch = 0
self.x = x
self.path_prefix = path_prefix
def on_epoch_begin(self, model):
shuffle(self.x)
def on_epoch_end(self, model):
print("epoch:%s"%self.epoch)
if self.epoch % 10 == 0:
output_path = get_tmpfile('{}_epoch{}.model'.format(self.path_prefix, self.epoch))
model.save(output_path)
self.epoch += 1
model_dm = gensim.models.Doc2Vec(min_count=1, window=10, size=size, sample=1e-3, negative=5, workers=3)
model_dm.build_vocab(x_train + x_test)
fun = shf(x_train, "\models")
model_dm.train(x_train, total_examples=model_dm.corpus_count, epochs=100, callbacks=[fun])
答案 0 :(得分:0)
您应该在问题中包含逐字记录的完整错误堆栈,以帮助答覆者确切地了解触发错误的步骤/代码行。
但是,使用回调保存模型也会带来许多问题,尤其是当您仅在本地定义一个类(与S
类一起使用)时,该类在重新加载模型时可能不可用。 an open gensim
issue中对问题和解决方法进行了一些讨论,并且库可能会选择将来完全禁用回调保存功能(例如,仅在回调持续时间内指定回调并且有效)一次致电fileprivate
)。
同时,您遇到的错误可能是Python 3.x中的新问题–在保存而不是加载时发现了问题。而且,如果您在另一个模块中定义了回调类,可以在保存之前通过名称导入(这样也可以在重新加载之前通过名称导入),那么它可能会解决您的问题。
关于您的设置的其他注意事项:
在每个训练纪元之前洗牌通常是过大的杀伤力,其收益微不足道,特别是对于较大的数据集或较大的纪元计数。 (如果您的原始数据源中包含相似类别或词汇的示例,那么单个初始混编可能还是有帮助的。)
如果您完成shf
的文档数量大于后来调用train()
的文档数量,那么build_vocab()
将不是正确的数字train()
中的。 (这是从model_dm.corpus_count
缓存的总数,而不是训练示例的数量。)因此,学习率管理和记录的进度指示器将略有下降。同样,将初始化模型以了解仅会出现在非培训文档中的单词。与这些单词相关联的模型的某些部分将保持未经训练的状态-因为在total_examples
中没有提供其用法示例,这可能会导致比完全忽略它们更糟糕的模型结果。
如果您用build_vocab()
调用train()
,则在创建模型时也可能会提供train()
,以便模型将值记为该值默认循环数(例如,如果以后调用epochs=100
)。