def evaluate( black_model: 'The path to the model to play black', white_model: 'The path to the model to play white', output_dir: 'Where to write the evaluation results'='data/evaluate/sgf', readouts: 'How many readouts to make per move.'=400, games: 'the number of games to play'=16, verbose: 'How verbose the players should be (see selfplay)' = 1): black_model = os.path.abspath(black_model) white_model = os.path.abspath(white_model) with timer("Loading weights"): black_net = dual_net.DualNetwork(black_model) white_net = dual_net.DualNetwork(white_model) with timer("%d games" % games): players = evaluation.play_match( black_net, white_net, games, readouts, verbose) for idx, p in enumerate(players): fname = "{:s}-vs-{:s}-{:d}".format(black_net.name, white_net.name, idx) with open(os.path.join(output_dir, fname + '.sgf'), 'w') as f: f.write(sgf_wrapper.make_sgf(p[0].position.recent, p[0].make_result_string( p[0].position), black_name=os.path.basename( black_model), white_name=os.path.basename(white_model)))
def test_inference(self): with tempfile.TemporaryDirectory() as model_dir: model_path = os.path.join(model_dir, 'blah') n = dual_net.DualNetworkTrainer(model_path, **fast_hparams) n.bootstrap() n1 = dual_net.DualNetwork(model_path, **fast_hparams) n1.run(go.Position()) # In the past we've had issues initializing two separate NNs # in the same process... just double check that two DualNetwork # instances can live side by side. n2 = dual_net.DualNetwork(model_path, **fast_hparams) n2.run(go.Position())
def evaluate( black_model: 'The path to the model to play black', white_model: 'The path to the model to play white', output_dir: 'Where to write the evaluation results' = 'sgf/evaluate', games: 'the number of games to play' = 16, verbose: 'How verbose the players should be (see selfplay)' = 1): utils.ensure_dir_exists(output_dir) with utils.logged_timer("Loading weights"): black_net = dual_net.DualNetwork(black_model) white_net = dual_net.DualNetwork(white_model) with utils.logged_timer("Playing game"): evaluation.play_match(black_net, white_net, games, output_dir, verbose)
def test_inference(self): with tempfile.TemporaryDirectory() as working_dir, \ tempfile.TemporaryDirectory() as export_dir: dual_net.bootstrap(working_dir, **fast_hparams) exported_model = os.path.join(export_dir, 'bootstrap-model') dual_net.export_model(working_dir, exported_model) n1 = dual_net.DualNetwork(exported_model, **fast_hparams) n1.run(go.Position()) # In the past we've had issues initializing two separate NNs # in the same process... just double check that two DualNetwork # instances can live side by side. n2 = dual_net.DualNetwork(exported_model, **fast_hparams) n2.run(go.Position())
def make_gtp_instance(load_file, cgos_mode=False, kgs_mode=False, minigui_mode=False): """Takes a path to model files and set up a GTP engine instance.""" # Here so we dont try load EdgeTPU python library unless we need to #if load_file.endswith(".tflite"): #from dual_net_edge_tpu import DualNetworkEdgeTpu #n = DualNetworkEdgeTpu(load_file) #else: #from dual_net import DualNetwork #n = DualNetwork(load_file) n = dual_net.DualNetwork(load_file) if cgos_mode: player = CGOSPlayer(network=n, seconds_per_move=5, timed_match=True, two_player_mode=True) else: player = MCTSPlayer(network=n, two_player_mode=True) name = "Minigo-" + os.path.basename(load_file) version = "0.2" engine = gtp_engine.Engine() engine.add_cmd_handler( gtp_engine.EngineCmdHandler(engine, name, version)) if kgs_mode: engine.add_cmd_handler(KgsCmdHandler(player)) engine.add_cmd_handler(RegressionsCmdHandler(player)) engine.add_cmd_handler(GoGuiCmdHandler(player)) if minigui_mode: engine.add_cmd_handler(MiniguiBasicCmdHandler(player, courtesy_pass=kgs_mode)) else: engine.add_cmd_handler(BasicCmdHandler(player, courtesy_pass=kgs_mode)) return engine
def freeze_graph(load_file): """ Loads a network and serializes just the inference parts for use by e.g. the C++ binary """ n = dual_net.DualNetwork(load_file) out_graph = tf.graph_util.convert_variables_to_constants( n.sess, n.sess.graph.as_graph_def(), ["policy_output", "value_output"]) with gfile.GFile(os.path.join(load_file + '.pb'), 'wb') as f: f.write(out_graph.SerializeToString())
def selfplay( load_file: "The path to the network model files", output_dir: "Where to write the games" = "data/selfplay", holdout_dir: "Where to write the games" = "data/holdout", output_sgf: "Where to write the sgfs" = "sgf/", readouts: 'How many simulations to run per move' = 100, verbose: '>=2 will print debug info, >=3 will print boards' = 1, resign_threshold: 'absolute value of threshold to resign at' = 0.95, holdout_pct: 'how many games to hold out for evaluation' = 0.05): _ensure_dir_exists(output_sgf) _ensure_dir_exists(output_dir) with timer("Loading weights from %s ... " % load_file): network = dual_net.DualNetwork(load_file) network.name = os.path.basename(load_file) with timer("Playing game"): player = selfplay_mcts.play(network, readouts, resign_threshold, verbose) output_name = '{}-{}'.format(int(time.time()), socket.gethostname()) game_data = player.extract_data() with gfile.GFile(os.path.join(output_sgf, '{}.sgf'.format(output_name)), 'w') as f: f.write(player.to_sgf()) tf_examples = preprocessing.make_dataset_from_selfplay(game_data) # Hold out 5% of games for evaluation. if random.random() < holdout_pct: fname = os.path.join(holdout_dir, "{}.tfrecord.zz".format(output_name)) else: fname = os.path.join(output_dir, "{}.tfrecord.zz".format(output_name)) preprocessing.write_tf_examples(fname, tf_examples)
def load_player(model_path): print("Loading weights from %s ... " % model_path) with timer("Loading weights from %s ... " % model_path): network = dual_net.DualNetwork(model_path) network.name = os.path.basename(model_path) player = MCTSPlayer(network, verbosity=2) return player
def __init__(self, color, buffer=None): self.color = color # 己方棋子颜色(先后手信息),1:黑,-1:白 self.board_selfNow = np.zeros((9, 9), int) # 己方当前棋面 self.board_opp_known = np.zeros((9, 9), int) # 已知的对手棋盘信息(不包含历史信息) self.board_sims = [] # 模拟出的完全信息棋盘 self.tryAction = [] self.illegalBoard = np.zeros((9, 9), int) self.num_oppStones = 0 # 对手棋子总数 if color == -1: self.num_oppStones = 1 self.scoreNet = dual_net.DualNetwork(modelDir) # 计算落子得分的网络 self.board_flat_idx = np.array([idx for idx in range(81)]) # 空间位置概率 self.basePb = np.array([ 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2, 2, 1, 2, 1, 2, 3, 3, 3, 3, 3, 2, 1, 2, 2, 3, 4, 4, 4, 3, 2, 2, 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 2, 3, 4, 4, 4, 3, 2, 2, 1, 2, 3, 3, 3, 3, 3, 2, 1, 2, 1, 2, 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1 ], dtype=float) self.basePb = self.basePb self.basePb = np.reshape(self.basePb, (9, 9)) # 复盘时用 if buffer is not None: with closing(shelve.open(buffer, 'r')) as shelf: self.color = shelf['color'] self.board_selfNow = shelf['board_selfNow'] self.board_opp_known = shelf['board_opp_known'] self.num_oppStones = shelf['num_oppStones']
def evaluate( black_model: 'The path to the model to play black', white_model: 'The path to the model to play white', output_dir: 'Where to write the evaluation results' = 'sgf/evaluate', readouts: 'How many readouts to make per move.' = 400, games: 'the number of games to play' = 16, verbose: 'How verbose the players should be (see selfplay)' = 1): _ensure_dir_exists(output_dir) with timer("Loading weights"): black_net = dual_net.DualNetwork(black_model) white_net = dual_net.DualNetwork(white_model) with timer("%d games" % games): evaluation.play_match(black_net, white_net, games, readouts, output_dir, verbose)
def dual_net_list(model): dual = dual_net.DualNetwork(model) print("Dual Net will calculate L2 cost over these variables") with dual.sess.graph.as_default(): var_names = [v.name for v in tf.trainable_variables()] _ = reduce_and_print_vars(var_names) print()
def initialize_game(sgf_file, load_file, move=1): with open(sgf_file) as f: sgf_contents = f.read() iterator = sgf_wrapper.replay_sgf(sgf_contents) for i in range(move): position_w_context = next(iterator) player = strategies.MCTSPlayerMixin(dual_net.DualNetwork(load_file)) player.initialize_game(position_w_context.position) return player
def do_predict(filename, model_path, tries_per_move, attempt): network = dual_net.DualNetwork(model_path, inference=False) move_ratings = predict_move(filename, network, tries_per_move) ratings = sum(move_ratings) tries = len(move_ratings) with open('{}.{}.result'.format(filename, attempt), 'w') as f: f.write(str(tries)) f.write('\n') f.write(str(ratings)) f.write('\n')
def report_for_puzzles(model_path, sgf_files, rounds, tries_per_move=1): results = {} tries = 0 sum_ratings = 0 network = dual_net.DualNetwork(model_path) for attempt in range(rounds): for filename in sgf_files: if filename not in results: results[filename] = [] move_ratings = predict_move(filename, network, tries_per_move=tries_per_move) tries += len(move_ratings) sum_ratings += sum(move_ratings) results[filename].append(sum(move_ratings) / len(move_ratings)) report_model_results({model_path: results}) return results, sum_ratings * 1.0 / tries
def evaluate( black_model: 'The path to the model to play black', white_model: 'The path to the model to play white', output_dir: 'Where to write the evaluation results'='sgf/evaluate', readouts: 'How many readouts to make per move.'=200, games: 'the number of games to play'=20, verbose: 'How verbose the players should be (see selfplay)' = 1): qmeas.start_time('evaluate') _ensure_dir_exists(output_dir) with timer("Loading weights"): black_net = dual_net.DualNetwork(black_model) white_net = dual_net.DualNetwork(white_model) winners = [] with timer("%d games" % games): winners = evaluation.play_match( black_net, white_net, games, readouts, output_dir, verbose) qmeas.stop_time('evaluate') white_count = 0 for win in winners: if 'W' in win or 'w' in win: white_count += 1 return white_count * 1.0 / games
def report_for_puzzles(model_path, sgf_files, rounds): results = {} tries = 0 correct = 0 network = dual_net.DualNetwork(model_path) for attempt in range(rounds): for filename in sgf_files: if filename not in results: results[filename] = [] move, target, is_right = predict_move(filename, network) tries += 1 if is_right: correct += 1 results[filename].append((move, target, is_right)) report_model_results({model_path: results}) return results, correct * 1.0 / tries
def run_game(load_file, selfplay_dir=None, holdout_dir=None, sgf_dir=None, holdout_pct=0.05): '''Takes a played game and record results and game data.''' if sgf_dir is not None: minimal_sgf_dir = os.path.join(sgf_dir, 'clean') full_sgf_dir = os.path.join(sgf_dir, 'full') utils.ensure_dir_exists(minimal_sgf_dir) utils.ensure_dir_exists(full_sgf_dir) if selfplay_dir is not None: utils.ensure_dir_exists(selfplay_dir) utils.ensure_dir_exists(holdout_dir) with utils.logged_timer("Loading weights from %s ... " % load_file): network = dual_net.DualNetwork(load_file) with utils.logged_timer("Playing game"): player = play(network) output_name = '{}-{}'.format(int(time.time()), socket.gethostname()) game_data = player.extract_data() if sgf_dir is not None: with gfile.GFile( os.path.join(minimal_sgf_dir, '{}.sgf'.format(output_name)), 'w') as f: f.write(player.to_sgf(use_comments=False)) with gfile.GFile( os.path.join(full_sgf_dir, '{}.sgf'.format(output_name)), 'w') as f: f.write(player.to_sgf()) tf_examples = preprocessing.make_dataset_from_selfplay(game_data) if selfplay_dir is not None: # Hold out 5% of games for validation. if random.random() < holdout_pct: fname = os.path.join(holdout_dir, "{}.tfrecord.zz".format(output_name)) else: fname = os.path.join(selfplay_dir, "{}.tfrecord.zz".format(output_name)) preprocessing.write_tf_examples(fname, tf_examples)
def main(argv): network = dual_net.DualNetwork('minigo-models/models/000737-fury') # add path to model board = np.zeros([N, N], dtype=np.int8) pos_w_con = list(replay_sgf_file('go_puzzles/10458/10494.sgf')) # Loading a puzzle from go_puzzles folder board += pos_w_con[0].position.board # Setting up the board # Let's add new pieces from another puzzle pos_w_con = list(replay_sgf_file('go_puzzles/14511/14515.sgf')) board += pos_w_con[0].position.board # Load the board position pos = Position(board = board) print(pos) # Generate saliency maps, see results folder play_network(network, board)
def analyze_symmetries(sgf_file, load_file): with open(sgf_file) as f: sgf_contents = f.read() iterator = sgf_wrapper.replay_sgf(sgf_contents) net = dual_net.DualNetwork(load_file) for i, pwc in enumerate(iterator): if i < 200: continue feats = features.extract_features(pwc.position) variants = [ symmetries.apply_symmetry_feat(s, feats) for s in symmetries.SYMMETRIES ] values = net.sess.run( net.inference_output['value_output'], feed_dict={net.inference_input['pos_tensor']: variants}) mean = np.mean(values) stdev = np.std(values) all_vals = sorted(zip(values, symmetries.SYMMETRIES)) print("{:3d} {:.3f} +/- {:.3f} min {:.3f} {} max {:.3f} {}".format( i, mean, stdev, *all_vals[0], *all_vals[-1]))
def selfplay(load_file: "The path to the network model files", output_dir: "Where to write the games" = "data/selfplay", holdout_dir: "Where to write the games" = "data/holdout", output_sgf: "Where to write the sgfs" = "sgf/", verbose: '>=2 will print debug info, >=3 will print boards' = 1, holdout_pct: 'how many games to hold out for validation' = 0.05): clean_sgf = os.path.join(output_sgf, 'clean') full_sgf = os.path.join(output_sgf, 'full') utils.ensure_dir_exists(clean_sgf) utils.ensure_dir_exists(full_sgf) utils.ensure_dir_exists(output_dir) utils.ensure_dir_exists(holdout_dir) with utils.logged_timer("Loading weights from %s ... " % load_file): network = dual_net.DualNetwork(load_file) with utils.logged_timer("Playing game"): player = selfplay_mcts.play(network, verbose) output_name = '{}-{}'.format(int(time.time()), socket.gethostname()) game_data = player.extract_data() with gfile.GFile(os.path.join(clean_sgf, '{}.sgf'.format(output_name)), 'w') as f: f.write(player.to_sgf(use_comments=False)) with gfile.GFile(os.path.join(full_sgf, '{}.sgf'.format(output_name)), 'w') as f: f.write(player.to_sgf()) tf_examples = preprocessing.make_dataset_from_selfplay(game_data) # Hold out 5% of games for evaluation. if random.random() < holdout_pct: fname = os.path.join(holdout_dir, "{}.tfrecord.zz".format(output_name)) else: fname = os.path.join(output_dir, "{}.tfrecord.zz".format(output_name)) preprocessing.write_tf_examples(fname, tf_examples)
def play_match_one(black_model, white_model, i, readouts, sgf_dir, verbosity): """Plays matches between two neural nets. black_net: Instance of minigo.DualNetwork, a wrapper around a tensorflow convolutional network. white_net: Instance of the minigo.DualNetwork. games: number of games to play. We play all the games at the same time. sgf_dir: directory to write the sgf results. readouts: number of readouts to perform for each step in each game. return true if black wins """ with timer("Loading weights"): black_net = dual_net.DualNetwork(black_model, selfplay=True, inference=True) white_net = dual_net.DualNetwork(white_model, selfplay=True, inference=True) # For n games, we create lists of n black and n white players black = MCTSPlayer(black_net, verbosity=verbosity, two_player_mode=True, num_parallel=SIMULTANEOUS_LEAVES) white = MCTSPlayer(white_net, verbosity=verbosity, two_player_mode=True, num_parallel=SIMULTANEOUS_LEAVES) black_name = os.path.basename(black_net.save_file) white_name = os.path.basename(white_net.save_file) black_win = False num_move = 0 # The move number of the current game black.initialize_game() white.initialize_game() while True: start = time.time() active = white if num_move % 2 else black inactive = black if num_move % 2 else white current_readouts = active.root.N while active.root.N < current_readouts + readouts: active.tree_search() # print some stats on the search if verbosity >= 3: print(active.root.position) # First, check the roots for hopeless games. if active.should_resign(): # Force resign active.set_result(-1 * active.root.position.to_play, was_resign=True) inactive.set_result(active.root.position.to_play, was_resign=True) if active.is_done(): fname = "{:d}-{:s}-vs-{:s}-{:d}.sgf".format( int(time.time()), white_name, black_name, i) if active.result_string is None: # This is an exceptionally rare corner case where we don't get a winner. # Our temporary solution is to just drop this game. break if (active.result_string[0] == 'W'): black_win = False else: black_win = True if num_move > 0: with open(os.path.join(sgf_dir, fname), 'w') as _file: sgfstr = sgf_wrapper.make_sgf(active.position.recent, active.result_string, black_name=black_name, white_name=white_name) _file.write(sgfstr) print("Finished game", i, active.result_string) break move = active.pick_move() # print('DBUG Picked move: ', move, active, num_move) active.play_move(move) inactive.play_move(move) dur = time.time() - start num_move += 1 if (verbosity > 1) or (verbosity == 1 and num_move % 10 == 9): timeper = (dur / readouts) * 100.0 print(active.root.position) print("%d: %d readouts, %.3f s/100. (%.2f sec)" % (num_move, readouts, timeper, dur)) return black_win
if flags.json_file and os.path.isfile(flags.json_file): print('') print('Loading data from', flags.json_file) with open(flags.json_file, 'r') as json_file: data = json.load(json_file) else: data = { 'percentiles': [], 'median': [], 'percentile90': [], 'worst': [], 'avg_stddev': [] } dual_network = dual_net.DualNetwork(flags.load_file) # Find all .sgf files within flags.sgf_folder. for subdir, dirs, files in os.walk(flags.sgf_folder): for file in files: if file.endswith('.sgf'): sgf_file_path = os.path.join(subdir, file) try: percentiles, worst, avg_stddev = analyze_symmetries( sgf_file_path, dual_network) data['percentiles'].append(percentiles) data['median'].append(percentiles[50]) data['percentile90'].append(percentiles[90]) data['worst'].append(worst) data['avg_stddev'].append(avg_stddev)
def main(argv): network = dual_net.DualNetwork( 'minigo-models/models/000737-fury') # add path to model board = np.zeros([N, N], dtype=np.int8) # pos_w_con = list(replay_sgf_file('go_puzzles/14511/14511.sgf')) # pos_w_con = list(replay_sgf_file('go_puzzles/10/10.sgf')) # board += pos_w_con[0].position.board # pos_w_con = list(replay_sgf_file('go_puzzles/9225/9225.sgf')) # board += pos_w_con[0].position.board # pos_w_con = list(replay_sgf_file('go_puzzles/14571/14587.sgf')) # board += pos_w_con[0].position.board # pos_w_con = list(replay_sgf_file('go_puzzles/14054/14064.sgf')) # board += pos_w_con[0].position.board # pos_w_con = list(replay_sgf_file('go_puzzles/10458/7592.sgf')) # board += pos_w_con[0].position.board # pos_w_con = list(replay_sgf_file('go_puzzles/10458/10458.sgf')) # board += pos_w_con[0].position.board # pos_w_con = list(replay_sgf_file('go_puzzles/10458/10495.sgf')) # board += pos_w_con[0].position.board pos_w_con = list(replay_sgf_file('go_puzzles/10458/10494.sgf')) board += pos_w_con[0].position.board # pos_w_con = list(replay_sgf_file('go_puzzles/10458/7593.sgf')) # board += pos_w_con[0].position.board pos_w_con = list(replay_sgf_file('go_puzzles/14511/14515.sgf')) board += pos_w_con[0].position.board # pos_w_con = list(replay_sgf_file('go_puzzles/10458/7589.sgf')) # board += pos_w_con[0].position.board # for i in pos_w_con: # print(i.position) # board[5, 7] = -1 # board[6][7] = -1 # board[8][4:6] = -1 # board[3][8] = -1 # board[5][3] = -1 # board[[11,12,13],:] = 0 pos = Position(board=board) # board = board + pos_w_con[0].position.board # print(pos) # board[0][3] = -1 # board[0][4] = 1 # board[1][1] = -1 # board[1][3] = -1 # board[1][4] = 1 # board[2][0] = -1 # board[2, 2] = -1 # board[2,3:5] = 1 # board[3, 0:2] = -1 # board[3, [2, 4]] = 1 # board[4, 0] = -1 # board[4, [1, 3]] = 1 # board[5, :3] = 1 # snap back # board = np.zeros([19, 19], dtype=np.int8) # board[0, 2] = 1 # board[0, [5,6]] = -1 # board[1][[1,5]] = 1 # board[1][[2,3,4,6]] = -1 # board[2][[0, 2,3,4,5]] = 1 # board[[2,3], 6] = -1 # Noise # board[2,-2] = 1 # # board[4, 11] = -1 # board[5, 15] = 1 # board[8, 15] = -1 # board[10, -1] = 1 # # board[12, 10] = -1 # # board[12, 13] = 1 # board[17, 16] = -1 # board[abs(board)==1] *= -1 # to invert the board colors pos = Position(board=board) print(pos) # simulate(network, board, steps=10) play_network(network, board)
def selfplay_laod_model(model_name): load_file = os.path.join(MODELS_DIR, model_name) network = dual_net.DualNetwork(load_file) return network
def play_match(black_model, white_model, games, sgf_dir): """Plays matches between two neural nets. Args: black_model: Path to the model for black player white_model: Path to the model for white player """ with utils.logged_timer("Loading weights"): black_net = dual_net.DualNetwork(black_model) white_net = dual_net.DualNetwork(white_model) readouts = FLAGS.num_readouts black = MCTSPlayer(black_net, two_player_mode=True) white = MCTSPlayer(white_net, two_player_mode=True) black_name = os.path.basename(black_net.save_file) white_name = os.path.basename(white_net.save_file) for i in range(games): num_move = 0 # The move number of the current game for player in [black, white]: player.initialize_game() first_node = player.root.select_leaf() prob, val = player.network.run(first_node.position) first_node.incorporate_results(prob, val, first_node) while True: start = time.time() active = white if num_move % 2 else black inactive = black if num_move % 2 else white current_readouts = active.root.N while active.root.N < current_readouts + readouts: active.tree_search() # print some stats on the search if FLAGS.verbose >= 3: print(active.root.position) # First, check the roots for hopeless games. if active.should_resign(): # Force resign active.set_result(-1 * active.root.position.to_play, was_resign=True) inactive.set_result( active.root.position.to_play, was_resign=True) if active.is_done(): fname = "{:d}-{:s}-vs-{:s}-{:d}.sgf".format(int(time.time()), white_name, black_name, i) with gfile.GFile(os.path.join(sgf_dir, fname), 'w') as _file: sgfstr = sgf_wrapper.make_sgf(active.position.recent, active.result_string, black_name=black_name, white_name=white_name) _file.write(sgfstr) print("Finished game", i, active.result_string) break move = active.pick_move() active.play_move(move) inactive.play_move(move) dur = time.time() - start num_move += 1 if (FLAGS.verbose > 1) or (FLAGS.verbose == 1 and num_move % 10 == 9): timeper = (dur / readouts) * 100.0 print(active.root.position) print("%d: %d readouts, %.3f s/100. (%.2f sec)" % (num_move, readouts, timeper, dur))
def selfplay( load_file: "The path to the network model files", output_dir: "Where to write the games"="data/selfplay", holdout_dir: "Where to write the games"="data/holdout", output_sgf: "Where to write the sgfs"="sgf/", readouts: 'How many simulations to run per move'=100, verbose: '>=2 will print debug info, >=3 will print boards' = 1, resign_threshold: 'absolute value of threshold to resign at' = 0.95 holdout_pct: 'how many games to hold out for evaluation' = 0.05): _ensure_dir_exists(output_sgf) _ensure_dir_exists(output_dir) with timer("Loading weights from %s ... " % load_file): network = dual_net.DualNetwork(load_file) network.name = os.path.basename(load_file) with timer("Playing game"): player = selfplay_mcts.play( network, readouts, resign_threshold, verbose) output_name = '{}-{}'.format(int(time.time()), socket.gethostname()) game_data = player.extract_data() with gfile.GFile(os.path.join(output_sgf, '{}.sgf'.format(output_name)), 'w') as f: f.write(player.to_sgf()) tf_examples = preprocessing.make_dataset_from_selfplay(game_data) # Hold out 5% of games for evaluation. if random.random() < holdout_pct: