浏览代码

run black on ml-agents (#2125)

Run black after Barracuda 0.2 merge
/develop-generalizationTraining-TrainerController
Ervin T 6 年前
当前提交
a3d03fb4
共有 2 个文件被更改,包括 729 次插入606 次删除
  1. 398
      ml-agents/mlagents/trainers/barracuda.py
  2. 937
      ml-agents/mlagents/trainers/tensorflow_to_barracuda.py

398
ml-agents/mlagents/trainers/barracuda.py


from collections import defaultdict
import numpy as np
import json
import struct # convert from Python values and C structs
import struct # convert from Python values and C structs
import re
import argparse
import os.path

self.globals = []
self.memories = []
def __init__(self, **entries): self.__dict__.update(entries)
def __init__(self, **entries):
self.__dict__.update(entries)
parser.add_argument('source_file', help=help)
parser.add_argument('target_file', help='output Barracuda binary file')
parser.add_argument('-trim', '--trim-unused-by-output')
parser.add_argument('--print-layers', action='store_true')
parser.add_argument('--print-source-json', action='store_true')
parser.add_argument('-json', '--print-barracuda-json', action='store_true')
parser.add_argument('--print-layer-links', action='store_true')
parser.add_argument('--print-patterns', action='store_true')
parser.add_argument('--print-tensors', action='store_true')
parser.add_argument('--print-supported-ops', action='store_true')
parser.add_argument('--verbose', action='store_true')
parser.add_argument("source_file", help=help)
parser.add_argument("target_file", help="output Barracuda binary file")
parser.add_argument("-trim", "--trim-unused-by-output")
parser.add_argument("--print-layers", action="store_true")
parser.add_argument("--print-source-json", action="store_true")
parser.add_argument("-json", "--print-barracuda-json", action="store_true")
parser.add_argument("--print-layer-links", action="store_true")
parser.add_argument("--print-patterns", action="store_true")
parser.add_argument("--print-tensors", action="store_true")
parser.add_argument("--print-supported-ops", action="store_true")
parser.add_argument("--verbose", action="store_true")
args.compress_f16 = False # TEMP: disabled, until properly implemented parser.add_argument('-f16', '--compress-f16', action='store_true')
output_extension = '.bc' if not args.compress_f16 else '.f16.bc'
args.compress_f16 = (
False
) # TEMP: disabled, until properly implemented parser.add_argument('-f16', '--compress-f16', action='store_true')
output_extension = ".bc" if not args.compress_f16 else ".f16.bc"
print('File', args.source_file, 'does not exist.')
print("File", args.source_file, "does not exist.")
return os.path.splitext(os.path.basename(filename))[0] + newExtenstion;
return os.path.splitext(os.path.basename(filename))[0] + newExtenstion
args.target_file = os.path.join(args.target_file, replaceFilenameExtension(args.source_file, output_extension))
args.target_file = os.path.join(
args.target_file,
replaceFilenameExtension(args.source_file, output_extension),
)
# Fuse training time BatchNorm tensors into Scale & Bias
def fuse_batchnorm_weights(gamma, beta, mean, var, epsilon):

bias = beta - gamma * mean / np.sqrt(var + epsilon)
return [scale, bias]
if hasattr(model, 'layers'):
if hasattr(model, "layers"):
model = model.layers
inputs_and_memories = set(list(inputs) + list(memories[1::3]))

ready.add(l.name)
return missing
# Class to represent a graph
# Class to represent a graph
class Graph:
def __init__(self,vertices):
self.graph = defaultdict(list) #dictionary containing adjacency List
self.V = vertices #No. of vertices
# function to add an edge to graph
def addEdge(self,u,v):
self.graph[u].append(v)
# A recursive function used by topologicalSort
def topologicalSortUtil(self,v,visited,stack):
# Mark the current node as visited.
class Graph:
def __init__(self, vertices):
self.graph = defaultdict(list) # dictionary containing adjacency List
self.V = vertices # No. of vertices
# function to add an edge to graph
def addEdge(self, u, v):
self.graph[u].append(v)
# A recursive function used by topologicalSort
def topologicalSortUtil(self, v, visited, stack):
# Mark the current node as visited.
# Recur for all the vertices adjacent to this vertex
for i in self.graph[v]:
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)
# Push current vertex to stack which stores result
stack.insert(0,v)
# Recur for all the vertices adjacent to this vertex
for i in self.graph[v]:
if visited[i] == False:
self.topologicalSortUtil(i, visited, stack)
# Push current vertex to stack which stores result
stack.insert(0, v)
# The function to do Topological Sort. It uses recursive
# topologicalSortUtil()
def topologicalSort(self):
# Mark all the vertices as not visited
visited = [False] * self.V
stack = []
# Call the recursive helper function to store Topological
# Sort starting from all vertices one by one
for i in range(self.V):
if visited[i] == False:
self.topologicalSortUtil(i, visited, stack)
# The function to do Topological Sort. It uses recursive
# topologicalSortUtil()
def topologicalSort(self):
# Mark all the vertices as not visited
visited = [False]*self.V
stack =[]
# Call the recursive helper function to store Topological
# Sort starting from all vertices one by one
for i in range(self.V):
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)
#print(stack)
# print(stack)
if (len(find_missing_inputs(model, inputs_and_memories)) == 0):
if len(find_missing_inputs(model, inputs_and_memories)) == 0:
return model
g = Graph(len(model))

for l in model:
layers[l.name] = id;
layers[l.name] = id
id += 1
for layer in model:

print("SORTED:", sorted_layer_indices)
new_model = [model[idx] for idx in sorted_layer_indices]
assert(len(find_missing_inputs(new_model, inputs_and_memories)) == 0)
assert len(find_missing_inputs(new_model, inputs_and_memories)) == 0
if hasattr(model, 'layers'):
if hasattr(model, "layers"):
def flatten(items,enter=lambda x:isinstance(x, list)):
def flatten(items, enter=lambda x: isinstance(x, list)):
# http://stackoverflow.com/a/40857703
# https://github.com/ctmakro/canton/blob/master/canton/misc.py
"""Yield items from any nested iterable; see REF."""

yield x
def trim_model(model, outputs):
layers = {l.name:l for l in model}
layers = {l.name: l for l in model}
connected = {o for o in outputs}
while len(outputs) > 0:
outputs = set(flatten([layers[o].inputs for o in outputs if o in layers]))

connected.add(o)
trimmed = [l.name for l in model if l.name not in connected]
return str(arr)[1:-1] # array to string without brackets
return str(arr)[1:-1] # array to string without brackets
print("TRIMMED:", array_without_brackets(trimmed))
return [l for l in model if l.name in connected]

print("Trimming model given outputs to preserve:", preserve_outputs)
model = trim_model(model, preserve_outputs)
else:
print("WARNING: Trim couldn't find any layers to match:", criteria_regexp_string)
print(
"WARNING: Trim couldn't find any layers to match:", criteria_regexp_string
)
if model[i].type == model[i+1].type and model[i].type == 255: # Load
model[i].tensors += model[i+1].tensors
del model[i+1]
if model[i].type == model[i + 1].type and model[i].type == 255: # Load
model[i].tensors += model[i + 1].tensors
del model[i + 1]
compress_classes = {
'Dense'
}
compress_classes = {"Dense"}
if (l.class_name in compress_classes):
print("Compressing %s layer '%s' weights to float16" % (l.class_name, l.name))
if l.class_name in compress_classes:
print(
"Compressing %s layer '%s' weights to float16" % (l.class_name, l.name)
)
if isinstance(o, np.ndarray): # skip binary data packed inside ndarray
if isinstance(o, np.ndarray): # skip binary data packed inside ndarray
if getattr(o, '__dict__', None):
if getattr(o, "__dict__", None):
s = json.dumps(model.layers, cls=StructEncoder, separators=(', ',':'))
s = json.dumps(model.layers, cls=StructEncoder, separators=(", ", ":"))
s = s.replace(']}, {', ']},\n{')
s = s.replace(':[{', ':[\n\t{')
s = s.replace('}, {', '},\n\t{')
s = s.replace("]}, {", "]},\n{")
s = s.replace(":[{", ":[\n\t{")
s = s.replace("}, {", "},\n\t{")
return str(arr)[1:-1] # array to string without brackets
return str(arr)[1:-1] # array to string without brackets
if print_layer_links:
for l in model.layers:

if model.globals:
if isinstance(model.globals, dict):
model.globals = {x.name:x.shape for x in model.globals}
model.globals = {x.name: x.shape for x in model.globals}
ins = {i:model.inputs[i] for i in l.inputs if i in model.inputs}
ins = {i: model.inputs[i] for i in l.inputs if i in model.inputs}
else:
ins = [i for i in l.inputs if i in model.inputs]
if ins:

print("OUT:", array_without_brackets(model.outputs))
if (print_tensors):
if print_tensors:
def __init__(self, scope=''):
def __init__(self, scope=""):
if attr == '_':
if attr == "_":
return self.layers[-1].name if len(self.layer) > 0 else self.scope
raise AttributeError(attr)

i = 1
while name in self.names_taken:
name = self.layers[-1].op + '_' + str(i)
name = self.layers[-1].op + "_" + str(i)
self.layers[-1].name = self.scope + ('/' if self.scope else '') + name
self.layers[-1].name = self.scope + ("/" if self.scope else "") + name
def concat(self, a, b, axis=-1, out=''):
self.layers += [Struct(name=out, op='Concat', axis=axis, input=[a, b])]
def concat(self, a, b, axis=-1, out=""):
self.layers += [Struct(name=out, op="Concat", axis=axis, input=[a, b])]
def mad(self, x, kernel, bias, out=''):
self.layers += [Struct(name=out, op='Dense', input=[x, kernel, bias])]
def mad(self, x, kernel, bias, out=""):
self.layers += [Struct(name=out, op="Dense", input=[x, kernel, bias])]
def mul(self, a, b, out=''):
self.layers += [Struct(name=out, op='Mul', input=[a, b])]
def mul(self, a, b, out=""):
self.layers += [Struct(name=out, op="Mul", input=[a, b])]
def add(self, a, b, out=''):
self.layers += [Struct(name=out, op='Add', input=[a, b])]
def add(self, a, b, out=""):
self.layers += [Struct(name=out, op="Add", input=[a, b])]
def sub(self, a, b, out=''):
self.layers += [Struct(name=out, op='Sub', input=[a, b])]
def sub(self, a, b, out=""):
self.layers += [Struct(name=out, op="Sub", input=[a, b])]
def sigmoid(self, x, out=''):
self.layers += [Struct(name=out, op='Sigmoid', input=[x])]
def sigmoid(self, x, out=""):
self.layers += [Struct(name=out, op="Sigmoid", input=[x])]
def tanh(self, x, out=''):
self.layers += [Struct(name=out, op='Tanh', input=[x])]
def tanh(self, x, out=""):
self.layers += [Struct(name=out, op="Tanh", input=[x])]
def reduce(self, op, x, axis=-1, out=''):
self.layers += [Struct(name=out, op='Reduce'+op, axis=axis, input=[x])]
def reduce(self, op, x, axis=-1, out=""):
self.layers += [Struct(name=out, op="Reduce" + op, axis=axis, input=[x])]
def pool(self, op, x, out=''):
self.layers += [Struct(name=out, op=op+'Pool', input=[x])]
def pool(self, op, x, out=""):
self.layers += [Struct(name=out, op=op + "Pool", input=[x])]
def strided_slice(self, x, begin, end, strides, rank, out=''):
self.layers += [Struct(name=out, op='StridedSlice', rank=rank, starts=begin, ends=end, slice_strides=strides, input=[x])]
def strided_slice(self, x, begin, end, strides, rank, out=""):
self.layers += [
Struct(
name=out,
op="StridedSlice",
rank=rank,
starts=begin,
ends=end,
slice_strides=strides,
input=[x],
)
]
''' combines mean operation out of several simpler ops
'''
""" combines mean operation out of several simpler ops
"""
if np.array_equal(axis, [1,2]):
nn.pool('GlobalAvg', input, out=name)
elif np.array_equal(axis, [1,2,3]):
nn.reduce('Mean', # over channels
nn.pool('GlobalAvg', input), # over height & width
out=name)
elif np.array_equal(axis, [3]) or np.array_equal(axis, [-1]) or np.array_equal(axis, 3) or np.array_equal(axis, -1):
nn.reduce('Mean', input, out=name)
if np.array_equal(axis, [1, 2]):
nn.pool("GlobalAvg", input, out=name)
elif np.array_equal(axis, [1, 2, 3]):
nn.reduce(
"Mean", # over channels
nn.pool("GlobalAvg", input), # over height & width
out=name,
)
elif (
np.array_equal(axis, [3])
or np.array_equal(axis, [-1])
or np.array_equal(axis, 3)
or np.array_equal(axis, -1)
):
nn.reduce("Mean", input, out=name)
def rnn(name, input, state, kernel, bias, new_state, number_of_gates = 2):
''' - Ht = f(Xt*Wi + Ht_1*Ri + Wbi + Rbi)
'''
def rnn(name, input, state, kernel, bias, new_state, number_of_gates=2):
""" - Ht = f(Xt*Wi + Ht_1*Ri + Wbi + Rbi)
"""
nn.tanh(
nn.mad(kernel=kernel, bias=bias,
x=nn.concat(input, state)),
out=new_state);
nn.tanh(nn.mad(kernel=kernel, bias=bias, x=nn.concat(input, state)), out=new_state)
def gru(name, input, state, kernel_r, kernel_u, kernel_c, bias_r, bias_u, bias_c, new_state, number_of_gates = 2):
''' - zt = f(Xt*Wz + Ht_1*Rz + Wbz + Rbz)
def gru(
name,
input,
state,
kernel_r,
kernel_u,
kernel_c,
bias_r,
bias_u,
bias_c,
new_state,
number_of_gates=2,
):
""" - zt = f(Xt*Wz + Ht_1*Rz + Wbz + Rbz)
'''
"""
nn = Build(name)
inputs = nn.concat(input, state)

c = nn.tanh(nn.mad(kernel=kernel_c, bias=bias_c,
x=nn.concat(input, r_state)))
c = nn.tanh(nn.mad(kernel=kernel_c, bias=bias_c, x=nn.concat(input, r_state)))
# new_h = u' * state + (1 - u') * c'
# = u' * state + c' - u' * c'

# - u' * c'
nn.sub(nn._, nn.mul(u, c),
out=new_state)
nn.sub(nn._, nn.mul(u, c), out=new_state)
return nn.layers;
return nn.layers
def lstm(name, input, state_c, state_h, kernel_i, kernel_j, kernel_f, kernel_o, bias_i, bias_j, bias_f, bias_o, new_state_c, new_state_h):
''' Full:
def lstm(
name,
input,
state_c,
state_h,
kernel_i,
kernel_j,
kernel_f,
kernel_o,
bias_i,
bias_j,
bias_f,
bias_o,
new_state_c,
new_state_h,
):
""" Full:
- it = f(Xt*Wi + Ht_1*Ri + Pi . Ct_1 + Wbi + Rbi)
- ft = f(Xt*Wf + Ht_1*Rf + Pf . Ct_1 + Wbf + Rbf)
- ct = g(Xt*Wc + Ht_1*Rc + Wbc + Rbc)

'''
"""
''' No peephole:
""" No peephole:
- it = f(Xt*Wi + Ht_1*Ri + Wbi + Rbi)
- ft = f(Xt*Wf + Ht_1*Rf + Wbf + Rbf)
- ct = g(Xt*Wc + Ht_1*Rc + Wbc + Rbc)

'''
"""
j = nn.tanh(nn.mad(inputs, kernel_j, bias_j))
j = nn.tanh(nn.mad(inputs, kernel_j, bias_j))
nn.add(
nn.mul(state_c, f), nn.mul(i, j),
out=new_state_c)
nn.add(nn.mul(state_c, f), nn.mul(i, j), out=new_state_c)
# new_h =
nn.mul(o, nn.tanh(new_state_c),
out=new_state_h)
# new_h =
nn.mul(o, nn.tanh(new_state_c), out=new_state_h)
self.f = open(filename, 'wb+')
self.f = open(filename, "wb+")
def __enter__(self):
return self

def write_str(self, s):
self.write_int32(len(s))
self.f.write(s.encode('ascii'))
self.f.write(s.encode("ascii"))
self.f.write(struct.pack('<f', d))
self.f.write(struct.pack("<f", d))
self.f.write(struct.pack('<i', d))
self.f.write(struct.pack("<i", d))
self.f.write(struct.pack('<q', d))
self.f.write(struct.pack("<q", d))
def write_shape(self, s):
self.write_int32(len(s))

def close(self):
self.f.close()
#VERSION = 0xBA22AC0DA000 + BARRACUDA_VERSION
# VERSION = 0xBA22AC0DA000 + BARRACUDA_VERSION
w.write_int64(BARRACUDA_VERSION)
# inputs

w.write_str_array(model.outputs)
# memories
w.write_int32(len(model.memories)//3)
for mem_shape, mem_in, mem_out in zip(model.memories[0::3], model.memories[1::3], model.memories[2::3]):
w.write_int32(len(model.memories) // 3)
for mem_shape, mem_in, mem_out in zip(
model.memories[0::3], model.memories[1::3], model.memories[2::3]
):
w.write_shape(mem_shape)
w.write_str(mem_in)
w.write_str(mem_out)

w.write_int32(len(model.layers))
for l in model.layers:
assert(not l.name in l.inputs)
assert not l.name in l.inputs
w.write_int32(0) #dummy
w.write_int32(0) #dummy
w.write_int32(0) # dummy
w.write_int32(0) # dummy
w.write_shape(l.pads)
w.write_shape(l.strides)
w.write_shape(l.pool_size)

w.write_int32(0) #dummy
w.write_int32(0) # dummy
assert(len(x.shape) == 4)
assert(x.data.nbytes % 4 == 0)
length = x.data.nbytes >> 2 # length is measured in float32s (at least for now)
assert len(x.shape) == 4
assert x.data.nbytes % 4 == 0
length = (
x.data.nbytes >> 2
) # length is measured in float32s (at least for now)
w.write_str(x.name)
w.write_shape(x.shape)

def print_known_operations(known_classes, known_activations):
print('OPS supported by the converter:')
print("OPS supported by the converter:")
print('ACTIVATIONS supported by the converter:')
print("ACTIVATIONS supported by the converter:")
print(key)
print(key)

937
ml-agents/mlagents/trainers/tensorflow_to_barracuda.py
文件差异内容过多而无法显示
查看文件

正在加载...
取消
保存