我正在阅读《深度学习与围棋》这本书,虽然我还没有读得很深入,但我已经编写了基础部分(规则、辅助类)和一个Qt GUI界面。所有这些都运行良好,于是我决定编写极小极大算法的示例程序,看看能否战胜它;-) 但它太慢了:在9×9的初始棋盘上,下一招需要几分钟的时间。默认深度为3步,我认为第一步的计算将需要(9×9)x(9×9-1)x(9×9-2)约50万个位置。好吧,这是Python,不是C,但我认为这应该可以在最多一分钟内计算出来。
我删除了一个对copy.deepcopy()的调用,这似乎消耗了很多时间。但它仍然太慢了。
这里是一些内容:计算线程:
class BotPlay(QThread): """ 计算机器人下一步的线程 """ def __init__(self, bot, bots, game): """ 构造函数,用于计算下一步 :param bot: 需要下棋的机器人 :param bots: 两个机器人的集合 :param game: 当前游戏状态(在下棋前) """ QThread.__init__(self) self.bot = bot self.bots = bots self.game = game played = pyqtSignal(Move, dict, GameState) def __del__(self): self.wait() def run(self): self.msleep(300) bot_move = self.bot.select_move(self.game) self.played.emit(bot_move, self.bots, self.game)
选择移动方法及其类:
class DepthPrunedMinimaxAgent(Agent): @bot_thinking(associated_name="minimax prof. -> LONG") def select_move(self, game_state: GameState): PonderedMove = namedtuple('PonderedMove', 'move outcome') best_move_so_far = None for possible_move in game_state.legal_moves(): next_state = game_state.apply_move(possible_move) our_best_outcome = -1 * self.best_result(next_state, capture_diff) if best_move_so_far is None or our_best_outcome > best_move_so_far.outcome: best_move_so_far = PonderedMove(possible_move, our_best_outcome) return best_move_so_far.move def best_result(self, game_state: GameState, eval_fn, max_depth: int = 2): if game_state.is_over(): if game_state.next_player == game_state.winner(): return sys.maxsize else: return -sys.maxsize if max_depth == 0: return eval_fn(game_state) best_so_far = -sys.maxsize for candidate_move in game_state.legal_moves(): next_state = game_state.apply_move(candidate_move) opponent_best_result = self.best_result(next_state, eval_fn, max_depth - 1) our_result = -opponent_best_result if our_result > best_so_far: best_so_far = our_result return best_so_far
我几乎可以肯定问题不是来自GUI,因为书中给出的程序的初始版本,完全是控制台模式的,和我的程序一样慢。
我的请求是什么?嗯,为了确保这种慢速行为不是正常的,并且可能找到问题出在哪里。极小极大算法来自书中,所以它是正确的。
谢谢你
回答:
机器学习通常使用Python进行,因为:
-
- 它简单且安全
-
- 它灵活
-
- 所有繁重的工作都由专门的模块完成,如tensorflow和keras
在你的情况下,第三点不成立。所有这些嵌套调用、参数传递、复制和棋盘评估都在Python中进行。这会比在编译型语言中花费多10到100倍的时间[需要引用]。
流行的机器学习项目似乎都使用Python,但实际的Python代码只是用于处理和输入数据,控制对tensorflow的调用,以及显示结果。这就是他们能做到这一点的原因。
所以,是的,你的故事中没有什么不寻常。你有查看过Leela-zero吗?它更加复杂/涉及,但开源且做得非常好,而且它可能已经打败了你。