From c400773b402f572fffab0e7a0697fd97b2a90549 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 27 Mar 2020 17:45:24 -0400 Subject: [PATCH 1/6] added LoadedNets to simplify loading new networks --- badgyal/__init__.py | 5 ++--- badgyal/abstractnet.py | 35 +++++++++++++++++++++++++++++++---- badgyal/bgnet.py | 26 -------------------------- badgyal/mgnet.py | 27 --------------------------- badgyal/named_nets.py | 4 ++++ 5 files changed, 37 insertions(+), 60 deletions(-) delete mode 100644 badgyal/bgnet.py delete mode 100644 badgyal/mgnet.py create mode 100644 badgyal/named_nets.py diff --git a/badgyal/__init__.py b/badgyal/__init__.py index cc0d66e..cbe0584 100644 --- a/badgyal/__init__.py +++ b/badgyal/__init__.py @@ -1,4 +1,3 @@ -from badgyal.abstractnet import AbstractNet -from badgyal.bgnet import BGNet -from badgyal.mgnet import MGNet +from badgyal.abstractnet import AbstractNet, LoadedNet +from badgyal.named_nets import BGNet, MGNet from badgyal.board2planes import board2planes, bulk_board2planes diff --git a/badgyal/abstractnet.py b/badgyal/abstractnet.py index b658bd6..7a70429 100644 --- a/badgyal/abstractnet.py +++ b/badgyal/abstractnet.py @@ -6,6 +6,7 @@ from badgyal.board2planes import board2planes, policy2moves, bulk_board2planes import pylru import sys +import os @@ -15,7 +16,6 @@ class AbstractNet: - def __init__(self, cuda=True): self.net = self.load_net() self.cuda = cuda @@ -26,11 +26,11 @@ def __init__(self, cuda=True): self.prefetch = {} def process_boards(self, boards): - input = bulk_board2planes(boards) + boards = bulk_board2planes(boards) if self.cuda: - input = input.cuda() + boards = boards.cuda() with torch.no_grad(): - policies, values = self.net(input) + policies, values = self.net(boards) return policies, values def cache_boards(self, boards, softmax_temp=1.61): @@ -86,3 +86,30 @@ def eval(self, board, softmax_temp=1.61): # return the values return policy, value + +class LoadedNet(AbstractNet): + def __init__(self, path, channels=128, blocks=10, se=4, policy_channels=None, classical=True, cuda=True): + self.path = path + self.channels = channels + self.blocks = blocks + self.se = se + if policy_channels == None: + self.policy_channels = channels + else: + self.policy_channels = policy_channels + self.classical = classical + super().__init__(cuda=cuda) + + def load_net(self): + cwd = os.path.abspath(os.path.dirname(__file__)) + full_path = os.path.join(cwd, self.path) + net = model.Net(self.channels, + self.blocks, + self.policy_channels, + self.se, + classical=self.classical) + if self.classical: + net.import_proto_classical(full_path) + else: + net.import_proto(full_path) + return net diff --git a/badgyal/bgnet.py b/badgyal/bgnet.py deleted file mode 100644 index 658c02d..0000000 --- a/badgyal/bgnet.py +++ /dev/null @@ -1,26 +0,0 @@ -import torch -import badgyal.model as model -import badgyal.net as proto_net -import badgyal.proto.net_pb2 as pb -import chess -from badgyal.board2planes import board2planes, policy2moves, bulk_board2planes -import pylru -import sys -import os.path -from badgyal import AbstractNet - -CHANNELS=128 -BLOCKS=10 -SE=4 - -class BGNet(AbstractNet): - - def __init__(self, cuda=True): - super().__init__(cuda=cuda) - - def load_net(self): - my_path = os.path.abspath(os.path.dirname(__file__)) - file = os.path.join(my_path, "badgyal-8.pb.gz") - net = model.Net(CHANNELS, BLOCKS, CHANNELS, SE, classical=True) - net.import_proto_classical(file) - return net diff --git a/badgyal/mgnet.py b/badgyal/mgnet.py deleted file mode 100644 index a24bfe6..0000000 --- a/badgyal/mgnet.py +++ /dev/null @@ -1,27 +0,0 @@ -import torch -import badgyal.model as model -import badgyal.net as proto_net -import badgyal.proto.net_pb2 as pb -import chess -from badgyal.board2planes import board2planes, policy2moves, bulk_board2planes -import pylru -import sys -import os.path -from badgyal import AbstractNet - -CHANNELS=32 -BLOCKS=4 -SE=2 - - -class MGNet(AbstractNet): - - def __init__(self, cuda=True): - super().__init__(cuda=cuda) - - def load_net(self): - my_path = os.path.abspath(os.path.dirname(__file__)) - file = os.path.join(my_path, "meangirl-8.pb.gz") - net = model.Net(CHANNELS, BLOCKS, CHANNELS, SE, classical=True) - net.import_proto_classical(file) - return net diff --git a/badgyal/named_nets.py b/badgyal/named_nets.py new file mode 100644 index 0000000..347dbe0 --- /dev/null +++ b/badgyal/named_nets.py @@ -0,0 +1,4 @@ +from badgyal.abstractnet import LoadedNet + +BGNet = LoadedNet("badgyal-8.pb.gz", 128, 10, 4, cuda=True) +MGNet = LoadedNet("meangirl-8.pb.gz", 32, 4, 2, cuda=True) From da1bdf40aaa206d5b858c56af16bddfb931ffcb7 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 27 Mar 2020 17:45:24 -0400 Subject: [PATCH 2/6] added LoadedNets to simplify loading new networks --- badgyal/__init__.py | 5 ++--- badgyal/abstractnet.py | 35 +++++++++++++++++++++++++++++++---- badgyal/bgnet.py | 26 -------------------------- badgyal/mgnet.py | 27 --------------------------- badgyal/named_nets.py | 4 ++++ 5 files changed, 37 insertions(+), 60 deletions(-) delete mode 100644 badgyal/bgnet.py delete mode 100644 badgyal/mgnet.py create mode 100644 badgyal/named_nets.py diff --git a/badgyal/__init__.py b/badgyal/__init__.py index cc0d66e..cbe0584 100644 --- a/badgyal/__init__.py +++ b/badgyal/__init__.py @@ -1,4 +1,3 @@ -from badgyal.abstractnet import AbstractNet -from badgyal.bgnet import BGNet -from badgyal.mgnet import MGNet +from badgyal.abstractnet import AbstractNet, LoadedNet +from badgyal.named_nets import BGNet, MGNet from badgyal.board2planes import board2planes, bulk_board2planes diff --git a/badgyal/abstractnet.py b/badgyal/abstractnet.py index b658bd6..7a70429 100644 --- a/badgyal/abstractnet.py +++ b/badgyal/abstractnet.py @@ -6,6 +6,7 @@ from badgyal.board2planes import board2planes, policy2moves, bulk_board2planes import pylru import sys +import os @@ -15,7 +16,6 @@ class AbstractNet: - def __init__(self, cuda=True): self.net = self.load_net() self.cuda = cuda @@ -26,11 +26,11 @@ def __init__(self, cuda=True): self.prefetch = {} def process_boards(self, boards): - input = bulk_board2planes(boards) + boards = bulk_board2planes(boards) if self.cuda: - input = input.cuda() + boards = boards.cuda() with torch.no_grad(): - policies, values = self.net(input) + policies, values = self.net(boards) return policies, values def cache_boards(self, boards, softmax_temp=1.61): @@ -86,3 +86,30 @@ def eval(self, board, softmax_temp=1.61): # return the values return policy, value + +class LoadedNet(AbstractNet): + def __init__(self, path, channels=128, blocks=10, se=4, policy_channels=None, classical=True, cuda=True): + self.path = path + self.channels = channels + self.blocks = blocks + self.se = se + if policy_channels == None: + self.policy_channels = channels + else: + self.policy_channels = policy_channels + self.classical = classical + super().__init__(cuda=cuda) + + def load_net(self): + cwd = os.path.abspath(os.path.dirname(__file__)) + full_path = os.path.join(cwd, self.path) + net = model.Net(self.channels, + self.blocks, + self.policy_channels, + self.se, + classical=self.classical) + if self.classical: + net.import_proto_classical(full_path) + else: + net.import_proto(full_path) + return net diff --git a/badgyal/bgnet.py b/badgyal/bgnet.py deleted file mode 100644 index 658c02d..0000000 --- a/badgyal/bgnet.py +++ /dev/null @@ -1,26 +0,0 @@ -import torch -import badgyal.model as model -import badgyal.net as proto_net -import badgyal.proto.net_pb2 as pb -import chess -from badgyal.board2planes import board2planes, policy2moves, bulk_board2planes -import pylru -import sys -import os.path -from badgyal import AbstractNet - -CHANNELS=128 -BLOCKS=10 -SE=4 - -class BGNet(AbstractNet): - - def __init__(self, cuda=True): - super().__init__(cuda=cuda) - - def load_net(self): - my_path = os.path.abspath(os.path.dirname(__file__)) - file = os.path.join(my_path, "badgyal-8.pb.gz") - net = model.Net(CHANNELS, BLOCKS, CHANNELS, SE, classical=True) - net.import_proto_classical(file) - return net diff --git a/badgyal/mgnet.py b/badgyal/mgnet.py deleted file mode 100644 index a24bfe6..0000000 --- a/badgyal/mgnet.py +++ /dev/null @@ -1,27 +0,0 @@ -import torch -import badgyal.model as model -import badgyal.net as proto_net -import badgyal.proto.net_pb2 as pb -import chess -from badgyal.board2planes import board2planes, policy2moves, bulk_board2planes -import pylru -import sys -import os.path -from badgyal import AbstractNet - -CHANNELS=32 -BLOCKS=4 -SE=2 - - -class MGNet(AbstractNet): - - def __init__(self, cuda=True): - super().__init__(cuda=cuda) - - def load_net(self): - my_path = os.path.abspath(os.path.dirname(__file__)) - file = os.path.join(my_path, "meangirl-8.pb.gz") - net = model.Net(CHANNELS, BLOCKS, CHANNELS, SE, classical=True) - net.import_proto_classical(file) - return net diff --git a/badgyal/named_nets.py b/badgyal/named_nets.py new file mode 100644 index 0000000..347dbe0 --- /dev/null +++ b/badgyal/named_nets.py @@ -0,0 +1,4 @@ +from badgyal.abstractnet import LoadedNet + +BGNet = LoadedNet("badgyal-8.pb.gz", 128, 10, 4, cuda=True) +MGNet = LoadedNet("meangirl-8.pb.gz", 32, 4, 2, cuda=True) From 52e3eb9c59ede5930f004b8139a683c9a6699a7d Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 17 Apr 2020 20:40:12 -0400 Subject: [PATCH 3/6] fixed some of t59 and t70 loading --- badgyal/__init__.py | 2 +- badgyal/abstractnet.py | 14 ++++++++++++++ badgyal/named_nets.py | 3 +++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/badgyal/__init__.py b/badgyal/__init__.py index 671bf54..8ca3091 100644 --- a/badgyal/__init__.py +++ b/badgyal/__init__.py @@ -1,4 +1,4 @@ from badgyal.abstractnet import AbstractNet, LoadedNet -from badgyal.named_nets import BGNet, MGNet +from badgyal.named_nets import * from badgyal.policy_index import policy_index from badgyal.board2planes import board2planes, bulk_board2planes diff --git a/badgyal/abstractnet.py b/badgyal/abstractnet.py index dd8b6a2..5c5dd62 100644 --- a/badgyal/abstractnet.py +++ b/badgyal/abstractnet.py @@ -145,3 +145,17 @@ def load_net(self): else: net.import_proto(full_path) return net + +class MultiNet(AbstractNet): + def __init__(self, nets): + self.nets = nets + + def eval(self, board, softmax_temp=1.61): + for net in self.nets: + policy, value = net.eval(board, softmax_temp) + print(policy) + + + def bulk_eval(self, boards, softmax_temp=1.61): + for net in self.nets: + policies, values = net.eval(boards, softmax_temp) diff --git a/badgyal/named_nets.py b/badgyal/named_nets.py index 782ddde..df4d3b3 100644 --- a/badgyal/named_nets.py +++ b/badgyal/named_nets.py @@ -1,4 +1,7 @@ from badgyal.abstractnet import LoadedNet + +T59 = lambda cuda: LoadedNet("../../nets/591226.pb.gz", 128, 10, 4, classical=False, cuda=cuda) +T70 = lambda cuda: LoadedNet("../../nets/701494.pb.gz", 128, 10, 4, classical=False, cuda=cuda) BGNet = lambda cuda: LoadedNet("badgyal-8.pb.gz", 128, 10, 4, cuda=cuda) MGNet = lambda cuda: LoadedNet("meangirl-8.pb.gz", 32, 4, 2, cuda=cuda) From 2f48677c2b75bea1aa85fc748185f1db044e3aea Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 17 Apr 2020 21:56:28 -0400 Subject: [PATCH 4/6] multinet fixes --- badgyal/abstractnet.py | 27 +++++++++++++++++++++++---- badgyal/named_nets.py | 8 ++++---- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/badgyal/abstractnet.py b/badgyal/abstractnet.py index 5c5dd62..c61ad95 100644 --- a/badgyal/abstractnet.py +++ b/badgyal/abstractnet.py @@ -7,16 +7,17 @@ import pylru import sys import os - +import numpy as np +from collections import defaultdict CACHE=100000 MAX_BATCH = 8 MIN_POLICY=0.2 +WDL = np.array([-1., 0., 1.]) class AbstractNet: - def __init__(self, cuda=True): self.net = self.load_net() self.cuda = cuda @@ -59,6 +60,8 @@ def cache_eval(self, board): return None, None def value_to_scalar(self, value): + if not self.classical: + return np.dot(WDL, value) return value.item() def eval(self, board, softmax_temp=1.61): @@ -150,12 +153,28 @@ class MultiNet(AbstractNet): def __init__(self, nets): self.nets = nets + def __call__(self, cuda=True): + self.nets = [net(cuda=cuda) for net in self.nets] + return self + def eval(self, board, softmax_temp=1.61): + num_nets = len(self.nets) + policy_avg = defaultdict(float) + value_tot = 0 for net in self.nets: policy, value = net.eval(board, softmax_temp) - print(policy) + value_tot += value + for move, p in policy.items(): + policy_avg[move] += p + for move in policy_avg.keys(): + policy_avg[move] /= num_nets + return policy_avg, value_tot/num_nets def bulk_eval(self, boards, softmax_temp=1.61): + num_nets = len(self.nets) + policy_avg = defaultdict(float) + value_tot = 0 for net in self.nets: - policies, values = net.eval(boards, softmax_temp) + policies, values = net.bulk_eval(boards, softmax_temp) + print(policies, values) diff --git a/badgyal/named_nets.py b/badgyal/named_nets.py index df4d3b3..5e829e0 100644 --- a/badgyal/named_nets.py +++ b/badgyal/named_nets.py @@ -1,7 +1,7 @@ -from badgyal.abstractnet import LoadedNet +from badgyal.abstractnet import LoadedNet, MultiNet - -T59 = lambda cuda: LoadedNet("../../nets/591226.pb.gz", 128, 10, 4, classical=False, cuda=cuda) -T70 = lambda cuda: LoadedNet("../../nets/701494.pb.gz", 128, 10, 4, classical=False, cuda=cuda) BGNet = lambda cuda: LoadedNet("badgyal-8.pb.gz", 128, 10, 4, cuda=cuda) MGNet = lambda cuda: LoadedNet("meangirl-8.pb.gz", 32, 4, 2, cuda=cuda) +T59 = lambda cuda: LoadedNet("../../nets/591226.pb.gz", 128, 10, 4, classical=False, cuda=cuda) +T70 = lambda cuda: LoadedNet("../../nets/701494.pb.gz", 128, 10, 4, classical=False, cuda=cuda) +M1 = lambda cuda: MultiNet([BGNet]) From c8c8271a3c6203d8aaf6e3b0dd85a5eaf38d7c71 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 17 Apr 2020 22:10:52 -0400 Subject: [PATCH 5/6] wdl net support --- badgyal/abstractnet.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/badgyal/abstractnet.py b/badgyal/abstractnet.py index c61ad95..6d81cfb 100644 --- a/badgyal/abstractnet.py +++ b/badgyal/abstractnet.py @@ -7,14 +7,12 @@ import pylru import sys import os -import numpy as np from collections import defaultdict CACHE=100000 MAX_BATCH = 8 MIN_POLICY=0.2 -WDL = np.array([-1., 0., 1.]) class AbstractNet: @@ -60,8 +58,6 @@ def cache_eval(self, board): return None, None def value_to_scalar(self, value): - if not self.classical: - return np.dot(WDL, value) return value.item() def eval(self, board, softmax_temp=1.61): @@ -148,6 +144,20 @@ def load_net(self): else: net.import_proto(full_path) return net + + + def value_to_scalar(self, value): + if not self.classical: + wdl0 = value[0].item() + wdl1 = value[1].item() + wdl2 = value[2].item() + min_val = min(wdl0, wdl1, wdl2) + w_val = math.exp(wdl0 - min_val) + d_val = math.exp(wdl1 - min_val) + l_val = math.exp(wdl2 - min_val) + p = (w_val * 1.0 + d_val * 0.5 ) / (w_val + d_val + l_val) + return 2.0*p-1.0; + return value.item() class MultiNet(AbstractNet): def __init__(self, nets): From 3393d7a3351b089eff06767fd2eda542c27de0d5 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 17 Apr 2020 23:47:28 -0400 Subject: [PATCH 6/6] remove multinet; --- badgyal/abstractnet.py | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/badgyal/abstractnet.py b/badgyal/abstractnet.py index a55c38e..3b9b57b 100644 --- a/badgyal/abstractnet.py +++ b/badgyal/abstractnet.py @@ -175,33 +175,3 @@ def value_to_scalar(self, value): p = (w_val * 1.0 + d_val * 0.5 ) / (w_val + d_val + l_val) return 2.0*p-1.0; return value.item() - -class MultiNet(AbstractNet): - def __init__(self, nets): - self.nets = nets - - def __call__(self, cuda=True): - self.nets = [net(cuda=cuda) for net in self.nets] - return self - - def eval(self, board, softmax_temp=1.61): - num_nets = len(self.nets) - policy_avg = defaultdict(float) - value_tot = 0 - for net in self.nets: - policy, value = net.eval(board, softmax_temp) - value_tot += value - for move, p in policy.items(): - policy_avg[move] += p - for move in policy_avg.keys(): - policy_avg[move] /= num_nets - return policy_avg, value_tot/num_nets - - - def bulk_eval(self, boards, softmax_temp=1.61): - num_nets = len(self.nets) - policy_avg = defaultdict(float) - value_tot = 0 - for net in self.nets: - policies, values = net.bulk_eval(boards, softmax_temp) - print(policies, values)