8000 minigo/dual_net.py at v199 · jm16/minigo · GitHub
[go: up one dir, main page]

Skip to content
8000

Latest commit

 

History

History
347 lines (307 loc) · 14.1 KB

dual_net.py

File metadata and controls

347 lines (307 loc) · 14.1 KB
my_batchn = functools.partial(tf.layers.batch_normalization,
momentum=.997, epsilon=1e-5,
fused=True, center=True, scale=True,
training=train_mode)
my_conv2d = functools.partial(tf.layers.conv2d,
filters=hparams['k'], kernel_size=[3, 3], padding="same")
def my_res_layer(inputs, train_mode):
int_layer1 = my_batchn(my_conv2d(inputs))
initial_output = tf.nn.relu(int_layer1)
int_layer2 = my_batchn(my_conv2d(initial_output))
output = tf.nn.relu(inputs + int_layer2)
return output
initial_output = tf.nn.relu(my_batchn(
my_conv2d(input_tensors['pos_tensor'])))
# the shared stack
shared_output = initial_output
for i in range(hparams['num_shared_layers']):
shared_output = my_res_layer(shared_output, train_mode)
# policy head
policy_conv = tf.nn.relu(my_batchn(
my_conv2d(shared_output, filters=2, kernel_size=[1, 1]),
center=False, scale=False))
logits = tf.layers.dense(
tf.reshape(policy_conv, [batch_size, go.N * go.N * 2]),
go.N * go.N + 1)
policy_output = tf.nn.softmax(logits)
# value head
value_conv = tf.nn.relu(my_batchn(
my_conv2d(shared_output, filters=1, kernel_size=[1, 1]),
center=False, scale=False))
value_fc_hidden = tf.nn.relu(tf.layers.dense(
tf.reshape(value_conv, [batch_size, go.N * go.N]),
hparams['fc_width']))
value_output = value_output = tf.nn.tanh(
tf.reshape(tf.layers.dense(value_fc_hidden, 1), [batch_size]))
return {
'logits': logits,
'policy_output': policy_output,
'value_output': value_output,
}
def train_ops(input_tensors, output_tensors, **hparams):
global_step = tf.Variable(0, name="global_step", trainable=False)
policy_cost = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(
logits=output_tensors['logits'],
labels=input_tensors['pi_tensor']))
value_cost = tf.reduce_mean(tf.square(
output_tensors['value_output'] - input_tensors['value_tensor']))
l2_cost = 1e-4 * tf.add_n([tf.nn.l2_loss(v)
for v in tf.trainable_variables() if not 'bias' in v.name])
combined_cost = policy_cost + value_cost + l2_cost
learning_rate = tf.train.exponential_decay(1e-2, global_step, 10 ** 7, 0.1)
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
train_op = tf.train.MomentumOptimizer(
learning_rate, hparams['momentum']).minimize(
combined_cost, global_step=global_step)
return {
'policy_cost': policy_cost,
'value_cost': value_cost,
'l2_cost': l2_cost,
'combined_cost': combined_cost,
'global_step': global_step,
'train_op': train_op,
}
def logging_ops():
return tf.summary.merge([
tf.summary.histogram(weight_var.name, weight_var)
for weight_var in tf.trainable_variables()],
name="weight_summaries")
class StatisticsCollector(object):
"""Collect statistics on the runs and create graphs.
Accuracy and cost cannot be calculated with the full test dataset
in one pass, so they must be computed in batches. Unfortunately,
the built-in TF summary nodes cannot be told to aggregate multiple
executions. Therefore, we aggregate the accuracy/cost ourselves at
the python level, and then shove it through the accuracy/cost summary
nodes to generate the appropriate summary protobufs for writing.
"""
graph = tf.Graph()
with tf.device("/cpu:0"), graph.as_default():
policy_error = tf.placeholder(tf.float32, [])
value_error = tf.placeholder(tf.float32, [])
reg_error = tf.placeholder(tf.float32, [])
cost = tf.placeholder(tf.float32, [])
policy_summary = tf.summary.scalar("Policy error", policy_error)
value_summary = tf.summary.scalar("Value error", value_error)
reg_summary = tf.summary.scalar("Regularization error", reg_error)
cost_summary = tf.summary.scalar("Combined cost", cost)
accuracy_summaries = tf.summary.merge(
[policy_summary, value_summary, reg_summary, cost_summary],
name="accuracy_summaries")
session = tf.Session(graph=graph)
def __init__(self):
self.policy_costs = []
self.value_costs = []
self.regularization_costs = []
self.combined_costs = []
def report(self, policy_cost, value_cost, regularization_cost, combined_cost):
# TODO refactor this to take a dict, and do something like
# self.accums = defaultdict(list) and do self.accums[thing].append(value)
# so that it can handle an arbitrary number of values.
self.policy_costs.append(policy_cost)
self.value_costs.append(value_cost)
self.regularization_costs.append(regularization_cost)
self.combined_costs.append(combined_cost)
def collect(self):
avg_pol = sum(self.policy_costs) / len(self.policy_costs)
avg_val = sum(self.value_costs) / len(self.value_costs)
avg_reg = sum(self.regularization_costs) / len(self.regularization_costs)
avg_cost = sum(self.combined_costs) / len(self.combined_costs)
self.policy_costs = []
self.value_costs = []
self.regularization_costs = []
self.combined_costs = []
summary = self.session.run(self.accuracy_summaries,
feed_dict={self.policy_error:avg_pol,
self.value_error:avg_val,
self.reg_error:avg_reg,
self.cost: avg_cost})
return summary
0