【问题标题】:How to set PYTHONHASHSEED environment variable in PyCharm for testing Word2Vec model?如何在 PyCharm 中设置 PYTHONHASHSEED 环境变量以测试 Word2Vec 模型?
【发布时间】:2020-03-29 11:16:53
【问题描述】:

我需要编写一个完全可重现的 Word2Vec 测试,并且需要将 PYTHONHASHSEED 设置为固定值。这是我目前的设置-yp

# conftest.py
@pytest.fixture(autouse=True)
def env_setup(monkeypatch):
    monkeypatch.setenv("PYTHONHASHSEED", "123")

# test_w2v.py

def test_w2v():
    assert os.getenv("PYTHONHASHSEED") == "123"
    expected_words_embeddings = np.array(...)
    w2v = Word2Vec(my_tokenized_sentences, workers=1, seed=42, hashfxn=hash)
    words_embeddings = np.array([w2v.wv.get_vector(word) for word in sentence for sentence in my_tokenized_sentences)])
    np.testing.assert_array_equal(expected_words_embeddings, words_embeddings)

这是奇怪的事情。

如果我通过PYTHONHASHSEED=123 python3 -m pytest test_w2v.py 从终端运行测试,则测试通过,没有任何问题。但是,如果我从 PyCharm 运行测试(使用 pytest,从编辑配置 -> 模板 -> Python 测试 -> pytest 设置),那么它会失败。最有趣的是,它不会在assert os.getenv("PYTHONHASHSEED") == "123" 失败,但它会在np.testing.assert_array_equal(expected_words_embeddings, words_embeddings) 失败

为什么会出现这种情况,有没有办法解决这个问题?

【问题讨论】:

  • 根据this question中的答案可能是PyCharm中设置的env var太晚了。一种解决方法是在 PyCharm 启动脚本中设置变量。

标签: python unit-testing testing pytest word2vec


【解决方案1】:

不能在 Python 代码中设置PYTHONHASHSEED;它需要在 Python 解释器启动之前设置,因为这是解释器唯一一次咨询它。您可以在启动 PyCharm 之前全局设置它,或者可能有一个 PyCharm 选项来为您从 PyCharm 触发的任何执行环境设置环境变量。 (例如:How to set environment variables in PyCharm?

但更一般地说,您通常不应该尝试让您的 gensim Word2Vec 测试这种确定性。

如果您要测试的任何东西 对精确参数敏感 - 因为只有精确播种和(慢得多)单线程训练才能在您选择的容差范围内,或者得到您复制的精确答案从较早的运行 - 那么你并没有真正验证算法在它通常受到的真正随机性下的贡献。在gensim FAQ 中查看更多讨论。

【讨论】:

  • 修复随机性有充分的理由。如果要重构复杂的数据科学代码(例如,用于生产工程),可以很方便地确定代码更改对功能没有影响。在调试间歇性生产故障时,也便于重现或排除随机性。
  • 当然,在某些情况下。但是我看到的大多数人在 StackOverflow、Gensim Github 问题或 Gensim 讨论列表上的 Word2Vec 上要求这样做的人都试图避免考虑这种随机算法的固有可变性(尤其是在很多-更高吞吐量的多线程版本),并保持不那么健壮的编码/测试实践,这些实践应该更能容忍结果中的“抖动”。
  • 您的观点是有效的 - 对于研究阶段。但是一旦你开始生产,像这样的技术对于支持非常有用。在代码中,您很少需要 PYTHONHASHSEED,因为您可以使用 random.seed()、numpy.random.seed 和 tensorflow..random.set_seed,具体取决于您使用的库。您仍然可以获得某些对象的差异,例如,如果它们获取当前时间。
  • 在生产中,大多数将使用多线程,因为吞吐量很重要,这会由于其他线程调度抖动而破坏可重复性。
猜你喜欢
  • 2017-07-31
  • 1970-01-01
  • 2013-12-22
  • 2021-08-10
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多