This commit is contained in:
Willi Richert 2016-03-29 17:39:07 +02:00
Родитель 554f6f81fc
Коммит 3cf7665c83
14 изменённых файлов: 634 добавлений и 330 удалений

Просмотреть файл

@ -15,13 +15,13 @@ _FLOATX = 'float32'
CNTK_TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), "templates")
CNTK_TRAIN_TEMPLATE_PATH = os.path.join(
CNTK_TEMPLATE_DIR, "cntk_train_template.cntk")
CNTK_TEMPLATE_DIR, "cntk_train_template.cntk")
CNTK_TEST_TEMPLATE_PATH = os.path.join(
CNTK_TEMPLATE_DIR, "cntk_test_template.cntk")
CNTK_TEMPLATE_DIR, "cntk_test_template.cntk")
CNTK_PREDICT_TEMPLATE_PATH = os.path.join(
CNTK_TEMPLATE_DIR, "cntk_predict_template.cntk")
CNTK_TEMPLATE_DIR, "cntk_predict_template.cntk")
CNTK_EVAL_TEMPLATE_PATH = os.path.join(
CNTK_TEMPLATE_DIR, "cntk_eval_template.cntk")
CNTK_TEMPLATE_DIR, "cntk_eval_template.cntk")
CNTK_TRAIN_CONFIG_FILENAME = "train.cntk"
CNTK_TEST_CONFIG_FILENAME = "test.cntk"
CNTK_PREDICT_CONFIG_FILENAME = "predict.cntk"
@ -52,6 +52,7 @@ def get_new_context():
class AbstractContext(object, metaclass=ABCMeta):
'''
This is the abstract CNTK context. It provides an API to run CNTK actions.
'''
@ -85,7 +86,7 @@ class AbstractContext(object, metaclass=ABCMeta):
else:
os.mkdir(self.directory)
self.name = name
self.name = name
self.device_id = device_id
self.clean_up = clean_up
self.input_nodes = set()
@ -110,19 +111,19 @@ class AbstractContext(object, metaclass=ABCMeta):
:param reader: the reader to use for reading the data
:param override_existing: if the folder exists already override it
'''
model_dir = os.path.join(self.directory, 'Models')
if os.path.exists(model_dir) and os.listdir(model_dir) == []:
if override_existing:
print ("Overriding the existing models")
if override_existing:
print("Overriding the existing models")
sh.rmtree(model_dir)
else:
raise Exception("Directory '%s' already exists, set the flag override_existing to true if you want to override it"
%self.directory)
% self.directory)
tmpl = open(CNTK_TRAIN_TEMPLATE_PATH, "r").read()
model_filename = os.path.join(model_dir, self.name)
description, has_inputs, readers = self.root_node.to_config()
description, has_inputs, readers = self.root_node.to_config()
if reader:
readers.append(reader)
@ -138,17 +139,17 @@ class AbstractContext(object, metaclass=ABCMeta):
def _generate_test_config(self, reader):
'''
Generates the configuration file for the test action.
'''
'''
tmpl = open(CNTK_TEST_TEMPLATE_PATH, "r").read()
model_filename = os.path.join(self.directory, 'Models', self.name)
# if no reader is passed generate the reader from the network
if reader:
reader_config = reader.generate_config()
else:
description, has_inputs, readers = self.root_node.to_config()
reader_config = '\n'.join(r.generate_config() for r in readers)
else:
description, has_inputs, readers = self.root_node.to_config()
reader_config = '\n'.join(r.generate_config() for r in readers)
tmpl_dict = {
'DevideId': self.device_id,
'ModelPath': model_filename,
@ -163,14 +164,15 @@ class AbstractContext(object, metaclass=ABCMeta):
'''
tmpl = open(CNTK_PREDICT_TEMPLATE_PATH, "r").read()
model_filename = os.path.join(self.directory, 'Models', self.name)
output_filename_base = os.path.join(self.directory, 'Outputs', self.name)
output_filename_base = os.path.join(
self.directory, 'Outputs', self.name)
# if no reader is passed generate the reader from the network
if reader:
reader_config = reader.generate_config()
else:
description, has_inputs, readers = self.root_node.to_config()
reader_config = '\n'.join(r.generate_config() for r in readers)
else:
description, has_inputs, readers = self.root_node.to_config()
reader_config = '\n'.join(r.generate_config() for r in readers)
tmpl_dict = {
'DevideId': self.device_id,
@ -179,13 +181,13 @@ class AbstractContext(object, metaclass=ABCMeta):
'Reader': reader_config,
}
return tmpl % tmpl_dict
def _generate_eval_config(self, root_node, reader):
'''
Generates the configuration file for write action.
:param root_node: the node to evaluate.
:param reader: the reader used to load the data, None if the network does not have input
'''
'''
model_description, has_input, readers = root_node.to_config()
if reader:
readers.append(reader)
@ -199,14 +201,14 @@ class AbstractContext(object, metaclass=ABCMeta):
reader = NumPyReader(data, fn)
from .ops.cntk1 import Input
dummy_input_node = Input(2, var_name='dummy_node')
reader.add_input(dummy_input_node, 0, 2)
reader.add_input(dummy_input_node, 0, 2)
model_description += "dummy_node = Input(2, tag='output')"
readers.append(reader)
tmpl = open(CNTK_EVAL_TEMPLATE_PATH, "r").read()
output_filename = os.path.join(self.directory, CNTK_OUTPUT_FILENAME)
tmpl_dict = {
'DevideId': self.device_id,
'DevideId': self.device_id,
'OutputFile': output_filename,
'ModelDescription': model_description,
'Reader': '\n'.join(r.generate_config() for r in readers),
@ -214,7 +216,7 @@ class AbstractContext(object, metaclass=ABCMeta):
return tmpl % tmpl_dict
@abstractmethod
def train(self, optimizer, reader=None, override_existing = True):
def train(self, optimizer, reader=None, override_existing=True):
'''
Abstract method for the action train.
:param reader: the reader to use for this action. Alternatively, you
@ -289,7 +291,7 @@ class Context(AbstractContext):
return output.decode("utf-8")
def train(self, optimizer, reader=None, override_existing = True):
def train(self, optimizer, reader=None, override_existing=True):
'''
Run the train action locally.
:param optimizer: the SGD optimizer to use for training
@ -297,7 +299,8 @@ class Context(AbstractContext):
can attach a reader directly to the input node.
:param override_existing: if the folder exists already override it
'''
config_content = self._generate_train_config(optimizer, reader, override_existing)
config_content = self._generate_train_config(
optimizer, reader, override_existing)
return self._call_cntk(CNTK_TRAIN_CONFIG_FILENAME, config_content)
def test(self, reader=None):
@ -324,7 +327,8 @@ class Context(AbstractContext):
Regular expression to parse the shape information of the nodes out of
CNTK's output
'''
VAR_SHAPE_REGEX = re.compile('^Validating --> (?P<var_name>[^ ]+) = [^>]*> \[(?P<shape>[^]]+)')
VAR_SHAPE_REGEX = re.compile(
'^Validating --> (?P<var_name>[^ ]+) = [^>]*> \[(?P<shape>[^]]+)')
SHAPE_STRIDE_REGEX = re.compile('\{.*?\}')
@staticmethod
@ -349,7 +353,7 @@ class Context(AbstractContext):
var_shape[var_name] = tuple(shape_list)
return var_shape
def _eval(self, node, reader):
# FIXME manually setting the tag to output might have side-effects
node.tag = 'output'
@ -357,7 +361,8 @@ class Context(AbstractContext):
output = self._call_cntk(CNTK_EVAL_CONFIG_FILENAME, config_content)
shapes = Context._parse_shapes_from_output(output)
out_name = os.path.join(self.directory, CNTK_OUTPUT_FILENAME + '.' + node.var_name)
out_name = os.path.join(
self.directory, CNTK_OUTPUT_FILENAME + '.' + node.var_name)
data = np.loadtxt(out_name)
return data, shapes
@ -374,7 +379,8 @@ class Context(AbstractContext):
Returns the output generated by `node`
'''
if not isinstance(node, ComputationNode):
raise ValueError('node is not of type ComputationNode, but %s'%type(node))
raise ValueError(
'node is not of type ComputationNode, but %s' % type(node))
data, shapes = self._eval(node, reader)
@ -382,7 +388,7 @@ class Context(AbstractContext):
expected_shape = shapes[node.var_name]
receieved_all = data.size == expected_size
if not receieved_all:
if not receieved_all:
# For some reason the CNTK write action has issues with multi-row
# output. So we have to CNTK reshape it to one row and do it again,
# but then NumPy reshape using node's expected shape.
@ -390,15 +396,16 @@ class Context(AbstractContext):
reshaped = NewReshape(node, expected_size)
data, _ = self._eval(reshaped, reader)
if not (len(expected_shape)==2 and expected_shape[1] == 1):
if not (len(expected_shape) == 2 and expected_shape[1] == 1):
# CNTK outputs e.g. [2 x 1] although it is just a vector.
# TODO find better way to distinguis between
# TODO find better way to distinguis between
data = data.reshape(expected_shape)
return data
class ClusterContext(AbstractContext):
'''
This is a sub-class of AbstractContext, use it to submit your workloads to the cluster.
'''

Просмотреть файл

@ -8,7 +8,7 @@ from cntk import *
if (__name__ == "__main__"):
X = constant(np.asarray([[2,3], [4,5]]))
X = constant(np.asarray([[2, 3], [4, 5]]))
out = 2.5 * X + 100
with Context('demo', clean_up=False) as ctx:

Просмотреть файл

@ -7,10 +7,11 @@ from cntk import *
if (__name__ == "__main__"):
X = Input(2)
X.attach_uci_fast_reader("Train-3Classes.txt", 0)
y = Input(3)
y.attach_uci_fast_reader("Train-3Classes.txt", 2, True, 1, "SimpleMapping-3Classes.txt")
y.attach_uci_fast_reader(
"Train-3Classes.txt", 2, True, 1, "SimpleMapping-3Classes.txt")
W = LearnableParameter(3, 2)
b = LearnableParameter(3, 1)
@ -26,4 +27,4 @@ if (__name__ == "__main__"):
ctx.train(my_sgd, None)
#result = ctx.eval(out)
#print(result.argmax(axis=1))
# print(result.argmax(axis=1))

Просмотреть файл

@ -4,10 +4,11 @@ import os
import struct
import numpy as np
def loadData(src, cimg):
print ('Downloading ' + src)
print('Downloading ' + src)
gzfname, h = urllib.request.urlretrieve(src, './delete.me')
print ('Done.')
print('Done.')
try:
with gzip.open(gzfname) as gz:
n = struct.unpack('I', gz.read(4))
@ -17,21 +18,24 @@ def loadData(src, cimg):
# Read number of entries.
n = struct.unpack('>I', gz.read(4))[0]
if n != cimg:
raise Exception('Invalid file: expected {0} entries.'.format(cimg))
raise Exception(
'Invalid file: expected {0} entries.'.format(cimg))
crow = struct.unpack('>I', gz.read(4))[0]
ccol = struct.unpack('>I', gz.read(4))[0]
if crow != 28 or ccol != 28:
raise Exception('Invalid file: expected 28 rows/cols per image.')
raise Exception(
'Invalid file: expected 28 rows/cols per image.')
# Read data.
res = np.fromstring(gz.read(cimg * crow * ccol), dtype = np.uint8)
res = np.fromstring(gz.read(cimg * crow * ccol), dtype=np.uint8)
finally:
os.remove(gzfname)
return res.reshape((cimg, crow * ccol))
def loadLabels(src, cimg):
print ('Downloading ' + src)
print('Downloading ' + src)
gzfname, h = urllib.request.urlretrieve(src, './delete.me')
print ('Done.')
print('Done.')
try:
with gzip.open(gzfname) as gz:
n = struct.unpack('I', gz.read(4))
@ -41,26 +45,31 @@ def loadLabels(src, cimg):
# Read number of entries.
n = struct.unpack('>I', gz.read(4))
if n[0] != cimg:
raise Exception('Invalid file: expected {0} rows.'.format(cimg))
raise Exception(
'Invalid file: expected {0} rows.'.format(cimg))
# Read labels.
res = np.fromstring(gz.read(cimg), dtype = np.uint8)
res = np.fromstring(gz.read(cimg), dtype=np.uint8)
finally:
os.remove(gzfname)
return res.reshape((cimg, 1))
if __name__ == "__main__":
trnData = loadData('http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz', 60000)
trnLbl = loadLabels('http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz', 60000)
trnData = loadData(
'http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz', 60000)
trnLbl = loadLabels(
'http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz', 60000)
trn = np.hstack((trnLbl, trnData))
if not os.path.exists('./Data'):
os.mkdir('./Data')
print ('Writing train text file...')
np.savetxt(r'./Data/Train-28x28.txt', trn, fmt = '%u', delimiter='\t')
print ('Done.')
testData = loadData('http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz', 10000)
testLbl = loadLabels('http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz', 10000)
print('Writing train text file...')
np.savetxt(r'./Data/Train-28x28.txt', trn, fmt='%u', delimiter='\t')
print('Done.')
testData = loadData(
'http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz', 10000)
testLbl = loadLabels(
'http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz', 10000)
test = np.hstack((testLbl, testData))
print ('Writing test text file...')
np.savetxt(r'./Data/Test-28x28.txt', test, fmt = '%u', delimiter='\t')
print ('Done.')
print('Writing test text file...')
np.savetxt(r'./Data/Test-28x28.txt', test, fmt='%u', delimiter='\t')
print('Done.')

Просмотреть файл

@ -8,55 +8,59 @@ from cntk import *
# MNIST Example, one hidden layer neural network
# =====================================================================================
def dnn_sigmoid_layer(in_dim, out_dim, x, param_scale):
W = LearnableParameter(out_dim, in_dim, initValueScale=param_scale)
b = LearnableParameter(out_dim, 1, initValueScale=param_scale)
W = LearnableParameter(out_dim, in_dim, initValueScale=param_scale)
b = LearnableParameter(out_dim, 1, initValueScale=param_scale)
t = Times(W, x)
z = Plus(t, b)
return Sigmoid(z)
def dnn_layer(in_dim, out_dim, x, param_scale):
W = LearnableParameter(out_dim, in_dim, initValueScale=param_scale)
b = LearnableParameter(out_dim, 1, initValueScale=param_scale)
t = Times(W, x)
return Plus(t, b)
if (__name__ == "__main__"):
# Network definition
feat_dim=784
label_dim=10
hidden_dim=200
training_filename=os.path.join("Data", "Train-28x28.txt")
test_filename=os.path.join("Data", "Test-28x28.txt")
# Network definition
feat_dim = 784
label_dim = 10
hidden_dim = 200
training_filename = os.path.join("Data", "Train-28x28.txt")
test_filename = os.path.join("Data", "Test-28x28.txt")
features = Input(feat_dim, var_name='features')
features.attach_uci_fast_reader(training_filename, 1)
feat_scale = Constant(0.00390625)
feats_scaled = Scale(feat_scale, features)
labels = Input(label_dim, tag='label', var_name='labels')
labels.attach_uci_fast_reader(training_filename, 0, True, 1, os.path.join("Data", "labelsmap.txt"))
h1 = dnn_sigmoid_layer(feat_dim, hidden_dim, feats_scaled, 1)
labels.attach_uci_fast_reader(
training_filename, 0, True, 1, os.path.join("Data", "labelsmap.txt"))
h1 = dnn_sigmoid_layer(feat_dim, hidden_dim, feats_scaled, 1)
out = dnn_layer(hidden_dim, label_dim, h1, 1)
out.tag = 'output'
ec = CrossEntropyWithSoftmax(labels, out)
ec.tag = 'criterion'
# Build the optimizer (settings are scaled down)
my_sgd = SGD(epoch_size = 600, minibatch_size = 32, learning_ratesPerMB = 0.1, max_epochs = 5, momentum_per_mb = 0)
# Create a context or re-use if already there
with Context('mnist_one_layer', root_node= ec, clean_up=False) as ctx:
# CNTK actions
#ctx.train(my_sgd)
features.attach_uci_fast_reader(test_filename, 1)
labels.attach_uci_fast_reader(test_filename, 0, True, 1, os.path.join("Data", "labelsmap.txt"))
ctx.predict()
ctx.test()
ctx.predict()
ec = CrossEntropyWithSoftmax(labels, out)
ec.tag = 'criterion'
# Build the optimizer (settings are scaled down)
my_sgd = SGD(epoch_size=600, minibatch_size=32,
learning_ratesPerMB=0.1, max_epochs=5, momentum_per_mb=0)
# Create a context or re-use if already there
with Context('mnist_one_layer', root_node=ec, clean_up=False) as ctx:
# CNTK actions
# ctx.train(my_sgd)
features.attach_uci_fast_reader(test_filename, 1)
labels.attach_uci_fast_reader(
test_filename, 0, True, 1, os.path.join("Data", "labelsmap.txt"))
ctx.predict()
ctx.test()
ctx.predict()

Просмотреть файл

@ -2,13 +2,16 @@ from abc import ABCMeta, abstractmethod
import numpy as np
import scipy.sparse as sparse
def _tuple_to_cntk_shape(shape):
return ':'.join(str(v) for v in shape)
# Indent model description by how many spaces
MODEL_INDENTATION = 8
class ComputationNode(object):
'''
Base class for all nodes and operators. Provides a NumPy-like interface
with operators that are converted to CNTK operators.
@ -16,22 +19,24 @@ class ComputationNode(object):
def __init__(self, name, params=None, var_name=None, reader=None):
if not isinstance(name, str):
raise ValueError("Parameter 'name' has to be a string and not '%s'"%type(name))
raise ValueError(
"Parameter 'name' has to be a string and not '%s'" % type(name))
if var_name is not None and not isinstance(var_name, str):
raise ValueError("Parameter 'var_name' has to be a string and not '%s'"%type(var_name))
raise ValueError(
"Parameter 'var_name' has to be a string and not '%s'" % type(var_name))
self.name = name
self.params = params
self.var_name = var_name
self.var_name = var_name
self.consumers = []
for p in self.params:
if hasattr(p, 'consumers'):
p.consumers.append(self)
self.reader = None
def _is_input(self):
return isinstance(self, InputComputationNodeBase)
return isinstance(self, InputComputationNodeBase)
def __add__(self, other):
if not isinstance(other, ComputationNode):
@ -132,7 +137,7 @@ class ComputationNode(object):
return param
def _to_config_recursively(self, desc, unrolled_nodes, inputs,
readers, node_counter=0):
readers, node_counter=0):
param_variable_names = []
if self.params:
for p_name in self.params:
@ -146,7 +151,7 @@ class ComputationNode(object):
# Special treatment for special operator.
# Used like RowStack(v0:v1:v2)
inputs_param = p_value
else:
else:
inputs_param = [p_value]
input_nodes_vars = []
@ -161,7 +166,8 @@ class ComputationNode(object):
unrolled_nodes[pv] = child_var
input_nodes_vars.append(child_var)
param_variable_names.append(_tuple_to_cntk_shape(input_nodes_vars))
param_variable_names.append(
_tuple_to_cntk_shape(input_nodes_vars))
else:
param_variable_names.append(
self._param_to_brainscript(p_name, p_value))
@ -180,7 +186,8 @@ class ComputationNode(object):
params = self._get_cntk_param_string(param_variable_names)
line = ' '*MODEL_INDENTATION + "%s = %s(%s)" % (self.var_name, self.name, params)
line = ' ' * MODEL_INDENTATION + \
"%s = %s(%s)" % (self.var_name, self.name, params)
desc.append(line)
return self.var_name, node_counter, desc
@ -190,28 +197,28 @@ class ComputationNode(object):
Helper method to generate the CNTK configuration for this node.
'''
unrolled_nodes = {}
inputs=set()
readers=set()
inputs = set()
readers = set()
var_name, node_counter, desc = self._to_config_recursively(
desc=[],
unrolled_nodes=unrolled_nodes,
desc=[],
unrolled_nodes=unrolled_nodes,
inputs=inputs,
readers=readers)
return var_name, node_counter, desc, len(inputs)>0, readers
return var_name, node_counter, desc, len(inputs) > 0, readers
def _dedupe_readers(self, readers):
import copy
readers_map = {}
for r in readers:
filename = r['FileName']
if filename in readers_map:
readers_map = {}
for r in readers:
filename = r['FileName']
if filename in readers_map:
readers_map[filename].inputs_def.extend(r.inputs_def)
else:
readers_map[filename] = copy.deepcopy(r)
return [r for r in readers_map.values()]
def to_config(self):
'''
Generate CNTK configuration for this node including the configuration
@ -221,52 +228,57 @@ class ComputationNode(object):
return "\n".join(desc), has_inputs, self._dedupe_readers(readers)
class InputComputationNodeBase(ComputationNode, metaclass=ABCMeta):
'''
Base class for all non-image input nodes nodes and operators. Provides methods to attach
a reader to an input node
'''
def attach_text_format_reader(self, filename, input_alias=None, format='dense'):
'''
attach a TextFormatReader to the node
'''
self.reader = CNTKTextFormatReader(filename)
self.reader.add_input(self, input_alias, self.dims, format)
def attach_uci_fast_reader(self,
filename,
input_start,
islabel = False,
num_label_cols=None,
def attach_uci_fast_reader(self,
filename,
input_start,
islabel=False,
num_label_cols=None,
label_mapping_file=None,
custom_delimiter=None):
custom_delimiter=None):
'''
attach a UCIFastReader to the node
'''
self.reader = UCIFastReader(filename, custom_delimiter)
self.reader = UCIFastReader(filename, custom_delimiter)
if islabel:
self.reader.add_input(self, input_start, num_label_cols, self.dims, label_mapping_file)
self.reader.add_input(
self, input_start, num_label_cols, self.dims, label_mapping_file)
else:
self.reader.add_input(self, input_start, self.dims)
class ImageInputComputationNodeBase(ComputationNode, metaclass=ABCMeta):
'''
Base class for all image input nodes nodes and operators. Provides methods to attach
a reader to an input node
'''
def attach_image_reader(self, filename, **kw):
'''
attach a TextFormatReader to the node
'''
raise NotImplementedError
# importing after defining ComputationNode to work around circular imports
from cntk.ops.cntk1 import *
from cntk.ops import cntk1 as cntk1_ops # to have a separate namespace when we want to override below
# to have a separate namespace when we want to override below
from cntk.ops import cntk1 as cntk1_ops
from .reader import UCIFastReader, CNTKTextFormatReader
# redefine some operators to work with NumPy and sequences as input
@ -275,10 +287,12 @@ from .reader import UCIFastReader, CNTKTextFormatReader
def _dense_seq_to_str(seq):
return ' '.join(seq.astype(np.str))
def _sparse_seq_to_str(seq):
#return ' '.join('%s:%s'%(k,seq[k]) for k in sorted(seq.items()))
# return ' '.join('%s:%s'%(k,seq[k]) for k in sorted(seq.items()))
raise NotImplementedError
def _seq_to_text_format(sequences, alias):
'''
`sequences` is a NumPy array
@ -292,14 +306,16 @@ def _seq_to_text_format(sequences, alias):
elif sparse.issparse(first_elem):
seq_to_str = _sparse_seq_to_str
else:
raise ValueError('sequence elements have to be of type numpy.ndarray (dense) or dictionary (sparse), you gave "%s"'%str(first_elem))
raise ValueError(
'sequence elements have to be of type numpy.ndarray (dense) or dictionary (sparse), you gave "%s"' % str(first_elem))
lines = []
for idx, seq in enumerate(sequences):
lines.append('%i|%s %s'%(idx, alias, seq_to_str(seq)))
lines.append('%i|%s %s' % (idx, alias, seq_to_str(seq)))
return '\n'.join(lines)
def _get_constant_node(value, **kw):
'''
This function creates a node that represents `value` as a constant tensor
@ -316,14 +332,15 @@ def _get_constant_node(value, **kw):
# of the overall context without having to always pass it
# explicitly?
from cntk.context import get_context
from cntk.context import get_context
import tempfile
# We have to use NamedTemporaryFile and close it, because when using the
# obvious first choice, mkstemp(), would later fail in cntk.exe because the
# file would still be locked.
# TODO make it same filename as alias
tf = tempfile.NamedTemporaryFile(prefix='_param_', suffix='.txt', dir=get_context().directory, delete = False)
tf = tempfile.NamedTemporaryFile(
prefix='_param_', suffix='.txt', dir=get_context().directory, delete=False)
tf.close()
if isinstance(value, list):
@ -331,7 +348,7 @@ def _get_constant_node(value, **kw):
if len(value.shape) == 1:
# 1D list: interpret as one scalar per sample
value = value[:,np.newaxis]
value = value[:, np.newaxis]
if sparse.issparse(value):
raise ValueError('only dense data is supported')
@ -348,31 +365,33 @@ def _get_constant_node(value, **kw):
from cntk.reader import CNTKTextFormatReader
param_node = cntk1_ops.LearnableParameter(
size,
1,
learningRateMultiplier=0.0,
init='fromFile',
initFromFilePath=tf.name,
**kw)
size,
1,
learningRateMultiplier=0.0,
init='fromFile',
initFromFilePath=tf.name,
**kw)
reshape_node = cntk1_ops.NewReshape(param_node,
dims=value.shape,
var_name=var_name)
dims=value.shape,
var_name=var_name)
return reshape_node
def _get_input_node(value, **kw):
# FIXME We need to better manage the context. How can we get hold
# of the overall context without having to always pass it
# explicitly?
from cntk.context import get_context
from cntk.context import get_context
import tempfile
# We have to use NamedTemporaryFile and close it, because the obvious first
# choice, mkstemp(), would later fail in cntk.exe because the file would still be locked.
tf = tempfile.NamedTemporaryFile(prefix='_input_', suffix='.txt',
dir=get_context().directory, delete = False)
# choice, mkstemp(), would later fail in cntk.exe because the file would
# still be locked.
tf = tempfile.NamedTemporaryFile(prefix='_input_', suffix='.txt',
dir=get_context().directory, delete=False)
tf.close()
if isinstance(value, list):
@ -380,14 +399,14 @@ def _get_input_node(value, **kw):
if len(value.shape) == 1:
# 1D list: interpret as one scalar per sample
value = value[:,np.newaxis]
value = value[:, np.newaxis]
if 'alias' in kw:
alias = kw['alias']
del kw['alias'] # don't confuse with constructor's parameters
del kw['alias'] # don't confuse with constructor's parameters
else:
# TODO make sure we don't have clashes
alias = '_I_%i'%np.random.randint(1000)
alias = '_I_%i' % np.random.randint(1000)
with open(tf.name, 'w') as f:
f.write(_seq_to_text_format(value, alias))
@ -403,13 +422,15 @@ def _get_input_node(value, **kw):
return input_node
def is_sequence(data):
'''
Checks whether the data is a CNTK sequence, which is expressed in Python as
a list of varying sized NumPy objects.
'''
is_list = isinstance(data, list)
return is_list and len(data)>0 and isinstance(data[0], np.ndarray)
return is_list and len(data) > 0 and isinstance(data[0], np.ndarray)
def is_tensor(data):
'''
@ -421,7 +442,7 @@ def is_tensor(data):
if not isinstance(data, list):
return False
while len(data)>0:
while len(data) > 0:
# All but the innermost dimension's values have to be lists
try:
data[0][0]
@ -436,6 +457,7 @@ def is_tensor(data):
return True
def input(value, **kw):
'''
Defining Input as a factory override that creates either a Constant()
@ -446,7 +468,7 @@ def input(value, **kw):
In case the `value` is a list of NumPy arrays, a CNTK Input() operator is
returned, interpreting every element as a sequence of tensors.
In case the `value` is a NumPy array or list of lists, a CNTK Input()
operator is returned, interpreting it as a dense tensor.
@ -455,7 +477,8 @@ def input(value, **kw):
if is_sequence(value) or is_tensor(value):
return _get_input_node(value, **kw)
else:
raise ValueError('value type is not supported: %s'%type(value))
raise ValueError('value type is not supported: %s' % type(value))
def constant(value, **kw):
'''
@ -467,7 +490,7 @@ def constant(value, **kw):
In case the `value` is a list of NumPy arrays, a CNTK Input() operator is
returned, interpreting every element as a sequence of tensors.
In case the `value` is a NumPy array or list of lists, a CNTK Input()
operator is returned, interpreting it as a dense tensor.
@ -479,5 +502,4 @@ def constant(value, **kw):
if is_tensor(value):
return _get_constant_node(value, **kw)
else:
raise ValueError('value type is not supported: %s'%type(value))
raise ValueError('value type is not supported: %s' % type(value))

Просмотреть файл

@ -2,97 +2,134 @@
from cntk.graph import ComputationNode, InputComputationNodeBase, ImageInputComputationNodeBase
class Print(ComputationNode):
def __init__(self, value, format='', name='Print', var_name=None):
super(Print, self).__init__(params=['value', 'format'], name=name, var_name=var_name)
super(Print, self).__init__(
params=['value', 'format'], name=name, var_name=var_name)
self.value = value
self.format = format
self.params_with_defaults = ['format']
class Debug(ComputationNode):
def __init__(self, value, say='', enabled=True, name='Debug', var_name=None):
super(Debug, self).__init__(params=['value', 'say', 'enabled'], name=name, var_name=var_name)
super(Debug, self).__init__(
params=['value', 'say', 'enabled'], name=name, var_name=var_name)
self.value = value
self.say = say
self.enabled = enabled
self.params_with_defaults = ['say', 'enabled']
class Format(ComputationNode):
def __init__(self, value, format, name='Format', var_name=None):
super(Format, self).__init__(params=['value', 'format'], name=name, var_name=var_name)
super(Format, self).__init__(
params=['value', 'format'], name=name, var_name=var_name)
self.value = value
self.format = format
self.params_with_defaults = []
class Replace(ComputationNode):
def __init__(self, s, from_, to, name='Replace', var_name=None):
super(Replace, self).__init__(params=['s', 'from_', 'to'], name=name, var_name=var_name)
super(Replace, self).__init__(
params=['s', 'from_', 'to'], name=name, var_name=var_name)
self.s = s
self.from_ = from_
self.to = to
self.params_with_defaults = []
class Substr(ComputationNode):
def __init__(self, s, begin, num, name='Substr', var_name=None):
super(Substr, self).__init__(params=['s', 'begin', 'num'], name=name, var_name=var_name)
super(Substr, self).__init__(
params=['s', 'begin', 'num'], name=name, var_name=var_name)
self.s = s
self.begin = begin
self.num = num
self.params_with_defaults = []
class Chr(ComputationNode):
def __init__(self, c, name='Chr', var_name=None):
super(Chr, self).__init__(params=['c'], name=name, var_name=var_name)
self.c = c
self.params_with_defaults = []
class Length(ComputationNode):
def __init__(self, x, name='Length', var_name=None):
super(Length, self).__init__(params=['x'], name=name, var_name=var_name)
super(Length, self).__init__(
params=['x'], name=name, var_name=var_name)
self.x = x
self.params_with_defaults = []
class Ceil(ComputationNode):
def __init__(self, x, name='Ceil', var_name=None):
super(Ceil, self).__init__(params=['x'], name=name, var_name=var_name)
self.x = x
self.params_with_defaults = []
class Round(ComputationNode):
def __init__(self, x, name='Round', var_name=None):
super(Round, self).__init__(params=['x'], name=name, var_name=var_name)
self.x = x
self.params_with_defaults = []
class Sign(ComputationNode):
def __init__(self, x, name='Sign', var_name=None):
super(Sign, self).__init__(params=['x'], name=name, var_name=var_name)
self.x = x
self.params_with_defaults = []
class Min(ComputationNode):
def __init__(self, a, b, name='Min', var_name=None):
super(Min, self).__init__(params=['a', 'b'], name=name, var_name=var_name)
super(Min, self).__init__(
params=['a', 'b'], name=name, var_name=var_name)
self.a = a
self.b = b
self.params_with_defaults = []
class Max(ComputationNode):
def __init__(self, a, b, name='Max', var_name=None):
super(Max, self).__init__(params=['a', 'b'], name=name, var_name=var_name)
super(Max, self).__init__(
params=['a', 'b'], name=name, var_name=var_name)
self.a = a
self.b = b
self.params_with_defaults = []
class Fac(ComputationNode):
def __init__(self, n, name='Fac', var_name=None):
super(Fac, self).__init__(params=['n'], name=name, var_name=var_name)
self.n = n
self.params_with_defaults = []
class LearnableParameter(ComputationNode):
def __init__(self, rows, cols, learningRateMultiplier=1.0, init='uniform', initValueScale=1, value=0, initFromFilePath='', initOnCPUOnly=True, randomSeed=-1, name='LearnableParameter', var_name=None):
super(LearnableParameter, self).__init__(params=['rows', 'cols', 'learningRateMultiplier', 'init', 'initValueScale', 'value', 'initFromFilePath', 'initOnCPUOnly', 'randomSeed'], name=name, var_name=var_name)
super(LearnableParameter, self).__init__(params=[
'rows', 'cols', 'learningRateMultiplier', 'init', 'initValueScale', 'value', 'initFromFilePath', 'initOnCPUOnly', 'randomSeed'], name=name, var_name=var_name)
self.rows = rows
self.cols = cols
self.learningRateMultiplier = learningRateMultiplier
@ -102,11 +139,15 @@ class LearnableParameter(ComputationNode):
self.initFromFilePath = initFromFilePath
self.initOnCPUOnly = initOnCPUOnly
self.randomSeed = randomSeed
self.params_with_defaults = ['learningRateMultiplier', 'init', 'initValueScale', 'value', 'initFromFilePath', 'initOnCPUOnly', 'randomSeed']
self.params_with_defaults = [
'learningRateMultiplier', 'init', 'initValueScale', 'value', 'initFromFilePath', 'initOnCPUOnly', 'randomSeed']
class ParameterTensor(ComputationNode):
def __init__(self, dims, learningRateMultiplier=1.0, init='uniform', initValueScale=1, value=0, initFromFilePath='', initOnCPUOnly=True, randomSeed=-1, name='ParameterTensor', var_name=None):
super(ParameterTensor, self).__init__(params=['dims', 'learningRateMultiplier', 'init', 'initValueScale', 'value', 'initFromFilePath', 'initOnCPUOnly', 'randomSeed'], name=name, var_name=var_name)
super(ParameterTensor, self).__init__(params=[
'dims', 'learningRateMultiplier', 'init', 'initValueScale', 'value', 'initFromFilePath', 'initOnCPUOnly', 'randomSeed'], name=name, var_name=var_name)
self.dims = dims
self.learningRateMultiplier = learningRateMultiplier
self.init = init
@ -115,25 +156,35 @@ class ParameterTensor(ComputationNode):
self.initFromFilePath = initFromFilePath
self.initOnCPUOnly = initOnCPUOnly
self.randomSeed = randomSeed
self.params_with_defaults = ['learningRateMultiplier', 'init', 'initValueScale', 'value', 'initFromFilePath', 'initOnCPUOnly', 'randomSeed']
self.params_with_defaults = [
'learningRateMultiplier', 'init', 'initValueScale', 'value', 'initFromFilePath', 'initOnCPUOnly', 'randomSeed']
class Input(InputComputationNodeBase):
def __init__(self, dims, tag='feature', name='Input', var_name=None):
super(Input, self).__init__(params=['dims', 'tag'], name=name, var_name=var_name)
super(Input, self).__init__(
params=['dims', 'tag'], name=name, var_name=var_name)
self.dims = dims
self.tag = tag
self.params_with_defaults = ['tag']
class SparseInput(InputComputationNodeBase):
def __init__(self, dims, tag='feature', name='SparseInput', var_name=None):
super(SparseInput, self).__init__(params=['dims', 'tag'], name=name, var_name=var_name)
super(SparseInput, self).__init__(
params=['dims', 'tag'], name=name, var_name=var_name)
self.dims = dims
self.tag = tag
self.params_with_defaults = ['tag']
class ImageInput(ImageInputComputationNodeBase):
def __init__(self, imageWidth, imageHeight, imageChannels, imageLayout='CHW', tag='feature', name='ImageInput', var_name=None):
super(ImageInput, self).__init__(params=['imageWidth', 'imageHeight', 'imageChannels', 'imageLayout', 'tag'], name=name, var_name=var_name)
super(ImageInput, self).__init__(params=[
'imageWidth', 'imageHeight', 'imageChannels', 'imageLayout', 'tag'], name=name, var_name=var_name)
self.imageWidth = imageWidth
self.imageHeight = imageHeight
self.imageChannels = imageChannels
@ -141,9 +192,12 @@ class ImageInput(ImageInputComputationNodeBase):
self.tag = tag
self.params_with_defaults = ['imageLayout', 'tag']
class SparseImageInput(ImageInputComputationNodeBase):
def __init__(self, imageWidth, imageHeight, imageChannels, imageLayout='CHW', tag='feature', name='SparseImageInput', var_name=None):
super(SparseImageInput, self).__init__(params=['imageWidth', 'imageHeight', 'imageChannels', 'imageLayout', 'tag'], name=name, var_name=var_name)
super(SparseImageInput, self).__init__(params=[
'imageWidth', 'imageHeight', 'imageChannels', 'imageLayout', 'tag'], name=name, var_name=var_name)
self.imageWidth = imageWidth
self.imageHeight = imageHeight
self.imageChannels = imageChannels
@ -151,33 +205,45 @@ class SparseImageInput(ImageInputComputationNodeBase):
self.tag = tag
self.params_with_defaults = ['imageLayout', 'tag']
class EnvironmentInput(ComputationNode):
def __init__(self, propertyName, name='EnvironmentInput', var_name=None):
super(EnvironmentInput, self).__init__(params=['propertyName'], name=name, var_name=var_name)
super(EnvironmentInput, self).__init__(
params=['propertyName'], name=name, var_name=var_name)
self.propertyName = propertyName
self.params_with_defaults = []
class PastValue(ComputationNode):
def __init__(self, dims, input, timeStep=1, defaultHiddenActivation=0.1, name='PastValue', var_name=None):
super(PastValue, self).__init__(params=['dims', 'input', 'timeStep', 'defaultHiddenActivation'], name=name, var_name=var_name)
super(PastValue, self).__init__(params=[
'dims', 'input', 'timeStep', 'defaultHiddenActivation'], name=name, var_name=var_name)
self.dims = dims
self.input = input
self.timeStep = timeStep
self.defaultHiddenActivation = defaultHiddenActivation
self.params_with_defaults = ['timeStep', 'defaultHiddenActivation']
class FutureValue(ComputationNode):
def __init__(self, dims, input, timeStep=1, defaultHiddenActivation=0.1, name='FutureValue', var_name=None):
super(FutureValue, self).__init__(params=['dims', 'input', 'timeStep', 'defaultHiddenActivation'], name=name, var_name=var_name)
super(FutureValue, self).__init__(params=[
'dims', 'input', 'timeStep', 'defaultHiddenActivation'], name=name, var_name=var_name)
self.dims = dims
self.input = input
self.timeStep = timeStep
self.defaultHiddenActivation = defaultHiddenActivation
self.params_with_defaults = ['timeStep', 'defaultHiddenActivation']
class Shift(ComputationNode):
def __init__(self, input, fromOffset, boundaryValue, boundaryMode=-1, dim=-1, name='Shift', var_name=None):
super(Shift, self).__init__(params=['input', 'fromOffset', 'boundaryValue', 'boundaryMode', 'dim'], name=name, var_name=var_name)
super(Shift, self).__init__(params=[
'input', 'fromOffset', 'boundaryValue', 'boundaryMode', 'dim'], name=name, var_name=var_name)
self.input = input
self.fromOffset = fromOffset
self.boundaryValue = boundaryValue
@ -185,87 +251,121 @@ class Shift(ComputationNode):
self.dim = dim
self.params_with_defaults = ['boundaryMode', 'dim']
class RowSlice(ComputationNode):
def __init__(self, startIndex, numRows, input, name='RowSlice', var_name=None):
super(RowSlice, self).__init__(params=['startIndex', 'numRows', 'input'], name=name, var_name=var_name)
super(RowSlice, self).__init__(
params=['startIndex', 'numRows', 'input'], name=name, var_name=var_name)
self.startIndex = startIndex
self.numRows = numRows
self.input = input
self.params_with_defaults = []
class RowRepeat(ComputationNode):
def __init__(self, input, numRepeats, name='RowRepeat', var_name=None):
super(RowRepeat, self).__init__(params=['input', 'numRepeats'], name=name, var_name=var_name)
super(RowRepeat, self).__init__(
params=['input', 'numRepeats'], name=name, var_name=var_name)
self.input = input
self.numRepeats = numRepeats
self.params_with_defaults = []
class RowStack(ComputationNode):
def __init__(self, inputs, name='RowStack', var_name=None):
super(RowStack, self).__init__(params=['inputs'], name=name, var_name=var_name)
super(RowStack, self).__init__(
params=['inputs'], name=name, var_name=var_name)
self.inputs = inputs
self.params_with_defaults = []
class Reshape(ComputationNode):
def __init__(self, input, numRows, imageWidth=0, imageHeight=0, imageChannels=0, name='Reshape', var_name=None):
super(Reshape, self).__init__(params=['input', 'numRows', 'imageWidth', 'imageHeight', 'imageChannels'], name=name, var_name=var_name)
super(Reshape, self).__init__(params=[
'input', 'numRows', 'imageWidth', 'imageHeight', 'imageChannels'], name=name, var_name=var_name)
self.input = input
self.numRows = numRows
self.imageWidth = imageWidth
self.imageHeight = imageHeight
self.imageChannels = imageChannels
self.params_with_defaults = ['imageWidth', 'imageHeight', 'imageChannels']
self.params_with_defaults = [
'imageWidth', 'imageHeight', 'imageChannels']
class NewReshape(ComputationNode):
def __init__(self, input, dims, beginDim=0, endDim=0, name='NewReshape', var_name=None):
super(NewReshape, self).__init__(params=['input', 'dims', 'beginDim', 'endDim'], name=name, var_name=var_name)
super(NewReshape, self).__init__(
params=['input', 'dims', 'beginDim', 'endDim'], name=name, var_name=var_name)
self.input = input
self.dims = dims
self.beginDim = beginDim
self.endDim = endDim
self.params_with_defaults = ['beginDim', 'endDim']
class TransposeDimensions(ComputationNode):
def __init__(self, input, dim1, dim2, name='TransposeDimensions', var_name=None):
super(TransposeDimensions, self).__init__(params=['input', 'dim1', 'dim2'], name=name, var_name=var_name)
super(TransposeDimensions, self).__init__(
params=['input', 'dim1', 'dim2'], name=name, var_name=var_name)
self.input = input
self.dim1 = dim1
self.dim2 = dim2
self.params_with_defaults = []
class Times(ComputationNode):
def __init__(self, A, B, outputRank=1, name='Times', var_name=None):
super(Times, self).__init__(params=['A', 'B', 'outputRank'], name=name, var_name=var_name)
super(Times, self).__init__(
params=['A', 'B', 'outputRank'], name=name, var_name=var_name)
self.A = A
self.B = B
self.outputRank = outputRank
self.params_with_defaults = ['outputRank']
class Logistic(ComputationNode):
def __init__(self, label, probability, name='Logistic', var_name=None):
super(Logistic, self).__init__(params=['label', 'probability'], name=name, var_name=var_name)
super(Logistic, self).__init__(
params=['label', 'probability'], name=name, var_name=var_name)
self.label = label
self.probability = probability
self.params_with_defaults = []
class WeightedLogistic(ComputationNode):
def __init__(self, label, probability, instanceWeight, name='WeightedLogistic', var_name=None):
super(WeightedLogistic, self).__init__(params=['label', 'probability', 'instanceWeight'], name=name, var_name=var_name)
super(WeightedLogistic, self).__init__(
params=['label', 'probability', 'instanceWeight'], name=name, var_name=var_name)
self.label = label
self.probability = probability
self.instanceWeight = instanceWeight
self.params_with_defaults = []
class ReconcileMBLayout(ComputationNode):
def __init__(self, dataInput, layoutInput, name='ReconcileMBLayout', var_name=None):
super(ReconcileMBLayout, self).__init__(params=['dataInput', 'layoutInput'], name=name, var_name=var_name)
super(ReconcileMBLayout, self).__init__(
params=['dataInput', 'layoutInput'], name=name, var_name=var_name)
self.dataInput = dataInput
self.layoutInput = layoutInput
self.params_with_defaults = []
class Convolution(ComputationNode):
def __init__(self, weightNode, inputValueNode, kernelWidth, kernelHeight, outputChannels, horizontalSubsample, verticalSubsample, zeroPadding=False, maxTempMemSizeInSamples=0, imageLayout='CHW', name='Convolution', var_name=None):
super(Convolution, self).__init__(params=['weightNode', 'inputValueNode', 'kernelWidth', 'kernelHeight', 'outputChannels', 'horizontalSubsample', 'verticalSubsample', 'zeroPadding', 'maxTempMemSizeInSamples', 'imageLayout'], name=name, var_name=var_name)
super(Convolution, self).__init__(params=['weightNode', 'inputValueNode', 'kernelWidth', 'kernelHeight', 'outputChannels',
'horizontalSubsample', 'verticalSubsample', 'zeroPadding', 'maxTempMemSizeInSamples', 'imageLayout'], name=name, var_name=var_name)
self.weightNode = weightNode
self.inputValueNode = inputValueNode
self.kernelWidth = kernelWidth
@ -276,11 +376,15 @@ class Convolution(ComputationNode):
self.zeroPadding = zeroPadding
self.maxTempMemSizeInSamples = maxTempMemSizeInSamples
self.imageLayout = imageLayout
self.params_with_defaults = ['zeroPadding', 'maxTempMemSizeInSamples', 'imageLayout']
self.params_with_defaults = [
'zeroPadding', 'maxTempMemSizeInSamples', 'imageLayout']
class MaxPooling(ComputationNode):
def __init__(self, input, windowWidth, windowHeight, horizontalSubsample, verticalSubsample, imageLayout='CHW', name='MaxPooling', var_name=None):
super(MaxPooling, self).__init__(params=['input', 'windowWidth', 'windowHeight', 'horizontalSubsample', 'verticalSubsample', 'imageLayout'], name=name, var_name=var_name)
super(MaxPooling, self).__init__(params=[
'input', 'windowWidth', 'windowHeight', 'horizontalSubsample', 'verticalSubsample', 'imageLayout'], name=name, var_name=var_name)
self.input = input
self.windowWidth = windowWidth
self.windowHeight = windowHeight
@ -289,9 +393,12 @@ class MaxPooling(ComputationNode):
self.imageLayout = imageLayout
self.params_with_defaults = ['imageLayout']
class AveragePooling(ComputationNode):
def __init__(self, input, windowWidth, windowHeight, horizontalSubsample, verticalSubsample, imageLayout='CHW', name='AveragePooling', var_name=None):
super(AveragePooling, self).__init__(params=['input', 'windowWidth', 'windowHeight', 'horizontalSubsample', 'verticalSubsample', 'imageLayout'], name=name, var_name=var_name)
super(AveragePooling, self).__init__(params=[
'input', 'windowWidth', 'windowHeight', 'horizontalSubsample', 'verticalSubsample', 'imageLayout'], name=name, var_name=var_name)
self.input = input
self.windowWidth = windowWidth
self.windowHeight = windowHeight
@ -300,9 +407,12 @@ class AveragePooling(ComputationNode):
self.imageLayout = imageLayout
self.params_with_defaults = ['imageLayout']
class BatchNormalization(ComputationNode):
def __init__(self, input, scale, bias, runMean, runInvStdDev, eval, spatial, normalizationTimeConstant=0, epsilon=1e-05, useCntkEngine=True, imageLayout='CHW', name='BatchNormalization', var_name=None):
super(BatchNormalization, self).__init__(params=['input', 'scale', 'bias', 'runMean', 'runInvStdDev', 'eval', 'spatial', 'normalizationTimeConstant', 'epsilon', 'useCntkEngine', 'imageLayout'], name=name, var_name=var_name)
super(BatchNormalization, self).__init__(params=['input', 'scale', 'bias', 'runMean', 'runInvStdDev', 'eval',
'spatial', 'normalizationTimeConstant', 'epsilon', 'useCntkEngine', 'imageLayout'], name=name, var_name=var_name)
self.input = input
self.scale = scale
self.bias = bias
@ -314,287 +424,409 @@ class BatchNormalization(ComputationNode):
self.epsilon = epsilon
self.useCntkEngine = useCntkEngine
self.imageLayout = imageLayout
self.params_with_defaults = ['normalizationTimeConstant', 'epsilon', 'useCntkEngine', 'imageLayout']
self.params_with_defaults = [
'normalizationTimeConstant', 'epsilon', 'useCntkEngine', 'imageLayout']
class Abs(ComputationNode):
def __init__(self, x, name='Abs', var_name=None):
super(Abs, self).__init__(params=['x'], name=name, var_name=var_name)
self.x = x
self.params_with_defaults = []
class ClassBasedCrossEntropyWithSoftmax(ComputationNode):
def __init__(self, labelClassDescriptorVectorSequence, mainInputInfo, mainWeight, classLogProbsBeforeSoftmax, name='ClassBasedCrossEntropyWithSoftmax', var_name=None):
super(ClassBasedCrossEntropyWithSoftmax, self).__init__(params=['labelClassDescriptorVectorSequence', 'mainInputInfo', 'mainWeight', 'classLogProbsBeforeSoftmax'], name=name, var_name=var_name)
super(ClassBasedCrossEntropyWithSoftmax, self).__init__(params=[
'labelClassDescriptorVectorSequence', 'mainInputInfo', 'mainWeight', 'classLogProbsBeforeSoftmax'], name=name, var_name=var_name)
self.labelClassDescriptorVectorSequence = labelClassDescriptorVectorSequence
self.mainInputInfo = mainInputInfo
self.mainWeight = mainWeight
self.classLogProbsBeforeSoftmax = classLogProbsBeforeSoftmax
self.params_with_defaults = []
class ColumnElementTimes(ComputationNode):
def __init__(self, aVectorSequence, anotherVectorSequence, name='ColumnElementTimes', var_name=None):
super(ColumnElementTimes, self).__init__(params=['aVectorSequence', 'anotherVectorSequence'], name=name, var_name=var_name)
super(ColumnElementTimes, self).__init__(
params=['aVectorSequence', 'anotherVectorSequence'], name=name, var_name=var_name)
self.aVectorSequence = aVectorSequence
self.anotherVectorSequence = anotherVectorSequence
self.params_with_defaults = []
class CosDistance(ComputationNode):
def __init__(self, aVectorSequence, anotherVectorSequence, name='CosDistance', var_name=None):
super(CosDistance, self).__init__(params=['aVectorSequence', 'anotherVectorSequence'], name=name, var_name=var_name)
super(CosDistance, self).__init__(
params=['aVectorSequence', 'anotherVectorSequence'], name=name, var_name=var_name)
self.aVectorSequence = aVectorSequence
self.anotherVectorSequence = anotherVectorSequence
self.params_with_defaults = []
class CosDistanceWithNegativeSamples(ComputationNode):
def __init__(self, aVectorSequence, anotherVectorSequence, numShifts, numNegSamples, name='CosDistanceWithNegativeSamples', var_name=None):
super(CosDistanceWithNegativeSamples, self).__init__(params=['aVectorSequence', 'anotherVectorSequence', 'numShifts', 'numNegSamples'], name=name, var_name=var_name)
super(CosDistanceWithNegativeSamples, self).__init__(params=[
'aVectorSequence', 'anotherVectorSequence', 'numShifts', 'numNegSamples'], name=name, var_name=var_name)
self.aVectorSequence = aVectorSequence
self.anotherVectorSequence = anotherVectorSequence
self.numShifts = numShifts
self.numNegSamples = numNegSamples
self.params_with_defaults = []
class Cosine(ComputationNode):
def __init__(self, x, name='Cosine', var_name=None):
super(Cosine, self).__init__(params=['x'], name=name, var_name=var_name)
super(Cosine, self).__init__(
params=['x'], name=name, var_name=var_name)
self.x = x
self.params_with_defaults = []
class CrossEntropy(ComputationNode):
def __init__(self, refProbVectorSequence, outProbVectorSequence, name='CrossEntropy', var_name=None):
super(CrossEntropy, self).__init__(params=['refProbVectorSequence', 'outProbVectorSequence'], name=name, var_name=var_name)
super(CrossEntropy, self).__init__(params=[
'refProbVectorSequence', 'outProbVectorSequence'], name=name, var_name=var_name)
self.refProbVectorSequence = refProbVectorSequence
self.outProbVectorSequence = outProbVectorSequence
self.params_with_defaults = []
class CrossEntropyWithSoftmax(ComputationNode):
def __init__(self, labelVectorSequence, outProbVectorSequence, name='CrossEntropyWithSoftmax', var_name=None):
super(CrossEntropyWithSoftmax, self).__init__(params=['labelVectorSequence', 'outProbVectorSequence'], name=name, var_name=var_name)
super(CrossEntropyWithSoftmax, self).__init__(params=[
'labelVectorSequence', 'outProbVectorSequence'], name=name, var_name=var_name)
self.labelVectorSequence = labelVectorSequence
self.outProbVectorSequence = outProbVectorSequence
self.params_with_defaults = []
class DiagTimes(ComputationNode):
def __init__(self, diagonalMatrixAsColumnVector, matrix, name='DiagTimes', var_name=None):
super(DiagTimes, self).__init__(params=['diagonalMatrixAsColumnVector', 'matrix'], name=name, var_name=var_name)
super(DiagTimes, self).__init__(
params=['diagonalMatrixAsColumnVector', 'matrix'], name=name, var_name=var_name)
self.diagonalMatrixAsColumnVector = diagonalMatrixAsColumnVector
self.matrix = matrix
self.params_with_defaults = []
class Dropout(ComputationNode):
def __init__(self, activationVectorSequence, name='Dropout', var_name=None):
super(Dropout, self).__init__(params=['activationVectorSequence'], name=name, var_name=var_name)
super(Dropout, self).__init__(
params=['activationVectorSequence'], name=name, var_name=var_name)
self.activationVectorSequence = activationVectorSequence
self.params_with_defaults = []
class ElementTimes(ComputationNode):
def __init__(self, aMatrix, anotherMatrix, name='ElementTimes', var_name=None):
super(ElementTimes, self).__init__(params=['aMatrix', 'anotherMatrix'], name=name, var_name=var_name)
super(ElementTimes, self).__init__(
params=['aMatrix', 'anotherMatrix'], name=name, var_name=var_name)
self.aMatrix = aMatrix
self.anotherMatrix = anotherMatrix
self.params_with_defaults = []
class ErrorPrediction(ComputationNode):
def __init__(self, labelVectorSequence, outVectorSequence, name='ErrorPrediction', var_name=None):
super(ErrorPrediction, self).__init__(params=['labelVectorSequence', 'outVectorSequence'], name=name, var_name=var_name)
super(ErrorPrediction, self).__init__(
params=['labelVectorSequence', 'outVectorSequence'], name=name, var_name=var_name)
self.labelVectorSequence = labelVectorSequence
self.outVectorSequence = outVectorSequence
self.params_with_defaults = []
class Exp(ComputationNode):
def __init__(self, x, name='Exp', var_name=None):
super(Exp, self).__init__(params=['x'], name=name, var_name=var_name)
self.x = x
self.params_with_defaults = []
class GatherPacked(ComputationNode):
def __init__(self, indexSequence, sourceData, name='GatherPacked', var_name=None):
super(GatherPacked, self).__init__(params=['indexSequence', 'sourceData'], name=name, var_name=var_name)
super(GatherPacked, self).__init__(
params=['indexSequence', 'sourceData'], name=name, var_name=var_name)
self.indexSequence = indexSequence
self.sourceData = sourceData
self.params_with_defaults = []
class GMMLogLikelihood(ComputationNode):
def __init__(self, unnormalizedPriorVector, meansAsRows, logStdDevAsRows, dataVectorSequence, name='GMMLogLikelihood', var_name=None):
super(GMMLogLikelihood, self).__init__(params=['unnormalizedPriorVector', 'meansAsRows', 'logStdDevAsRows', 'dataVectorSequence'], name=name, var_name=var_name)
super(GMMLogLikelihood, self).__init__(params=[
'unnormalizedPriorVector', 'meansAsRows', 'logStdDevAsRows', 'dataVectorSequence'], name=name, var_name=var_name)
self.unnormalizedPriorVector = unnormalizedPriorVector
self.meansAsRows = meansAsRows
self.logStdDevAsRows = logStdDevAsRows
self.dataVectorSequence = dataVectorSequence
self.params_with_defaults = []
class InvStdDev(ComputationNode):
def __init__(self, dataVectorSequence, name='InvStdDev', var_name=None):
super(InvStdDev, self).__init__(params=['dataVectorSequence'], name=name, var_name=var_name)
super(InvStdDev, self).__init__(
params=['dataVectorSequence'], name=name, var_name=var_name)
self.dataVectorSequence = dataVectorSequence
self.params_with_defaults = []
class KhatriRaoProduct(ComputationNode):
def __init__(self, leftMatrix, rightMatrix, name='KhatriRaoProduct', var_name=None):
super(KhatriRaoProduct, self).__init__(params=['leftMatrix', 'rightMatrix'], name=name, var_name=var_name)
super(KhatriRaoProduct, self).__init__(
params=['leftMatrix', 'rightMatrix'], name=name, var_name=var_name)
self.leftMatrix = leftMatrix
self.rightMatrix = rightMatrix
self.params_with_defaults = []
class Log(ComputationNode):
def __init__(self, x, name='Log', var_name=None):
super(Log, self).__init__(params=['x'], name=name, var_name=var_name)
self.x = x
self.params_with_defaults = []
class LogSoftmax(ComputationNode):
def __init__(self, z, name='LogSoftmax', var_name=None):
super(LogSoftmax, self).__init__(params=['z'], name=name, var_name=var_name)
super(LogSoftmax, self).__init__(
params=['z'], name=name, var_name=var_name)
self.z = z
self.params_with_defaults = []
class MatrixL1Reg(ComputationNode):
def __init__(self, matrix, name='MatrixL1Reg', var_name=None):
super(MatrixL1Reg, self).__init__(params=['matrix'], name=name, var_name=var_name)
super(MatrixL1Reg, self).__init__(
params=['matrix'], name=name, var_name=var_name)
self.matrix = matrix
self.params_with_defaults = []
class MatrixL2Reg(ComputationNode):
def __init__(self, matrix, name='MatrixL2Reg', var_name=None):
super(MatrixL2Reg, self).__init__(params=['matrix'], name=name, var_name=var_name)
super(MatrixL2Reg, self).__init__(
params=['matrix'], name=name, var_name=var_name)
self.matrix = matrix
self.params_with_defaults = []
class Mean(ComputationNode):
def __init__(self, dataVectorSequence, name='Mean', var_name=None):
super(Mean, self).__init__(params=['dataVectorSequence'], name=name, var_name=var_name)
super(Mean, self).__init__(
params=['dataVectorSequence'], name=name, var_name=var_name)
self.dataVectorSequence = dataVectorSequence
self.params_with_defaults = []
class Minus(ComputationNode):
def __init__(self, leftMatrix, rightMatrix, name='Minus', var_name=None):
super(Minus, self).__init__(params=['leftMatrix', 'rightMatrix'], name=name, var_name=var_name)
super(Minus, self).__init__(
params=['leftMatrix', 'rightMatrix'], name=name, var_name=var_name)
self.leftMatrix = leftMatrix
self.rightMatrix = rightMatrix
self.params_with_defaults = []
class Negate(ComputationNode):
def __init__(self, input, name='Negate', var_name=None):
super(Negate, self).__init__(params=['input'], name=name, var_name=var_name)
super(Negate, self).__init__(
params=['input'], name=name, var_name=var_name)
self.input = input
self.params_with_defaults = []
class PackedIndex(ComputationNode):
def __init__(self, targetObject, indexSequence, name='PackedIndex', var_name=None):
super(PackedIndex, self).__init__(params=['targetObject', 'indexSequence'], name=name, var_name=var_name)
super(PackedIndex, self).__init__(
params=['targetObject', 'indexSequence'], name=name, var_name=var_name)
self.targetObject = targetObject
self.indexSequence = indexSequence
self.params_with_defaults = []
class PerDimMeanVarDeNormalization(ComputationNode):
def __init__(self, dataVectorSequence, meanVector, invStdDevVector, name='PerDimMeanVarDeNormalization', var_name=None):
super(PerDimMeanVarDeNormalization, self).__init__(params=['dataVectorSequence', 'meanVector', 'invStdDevVector'], name=name, var_name=var_name)
super(PerDimMeanVarDeNormalization, self).__init__(params=[
'dataVectorSequence', 'meanVector', 'invStdDevVector'], name=name, var_name=var_name)
self.dataVectorSequence = dataVectorSequence
self.meanVector = meanVector
self.invStdDevVector = invStdDevVector
self.params_with_defaults = []
class PerDimMeanVarNormalization(ComputationNode):
def __init__(self, dataVectorSequence, meanVector, invStdDevVector, name='PerDimMeanVarNormalization', var_name=None):
super(PerDimMeanVarNormalization, self).__init__(params=['dataVectorSequence', 'meanVector', 'invStdDevVector'], name=name, var_name=var_name)
super(PerDimMeanVarNormalization, self).__init__(params=[
'dataVectorSequence', 'meanVector', 'invStdDevVector'], name=name, var_name=var_name)
self.dataVectorSequence = dataVectorSequence
self.meanVector = meanVector
self.invStdDevVector = invStdDevVector
self.params_with_defaults = []
class Plus(ComputationNode):
def __init__(self, leftMatrix, rightMatrix, name='Plus', var_name=None):
super(Plus, self).__init__(params=['leftMatrix', 'rightMatrix'], name=name, var_name=var_name)
super(Plus, self).__init__(
params=['leftMatrix', 'rightMatrix'], name=name, var_name=var_name)
self.leftMatrix = leftMatrix
self.rightMatrix = rightMatrix
self.params_with_defaults = []
class RectifiedLinear(ComputationNode):
def __init__(self, z, name='RectifiedLinear', var_name=None):
super(RectifiedLinear, self).__init__(params=['z'], name=name, var_name=var_name)
super(RectifiedLinear, self).__init__(
params=['z'], name=name, var_name=var_name)
self.z = z
self.params_with_defaults = []
class Scale(ComputationNode):
def __init__(self, scalarScalingFactor, matrix, name='Scale', var_name=None):
super(Scale, self).__init__(params=['scalarScalingFactor', 'matrix'], name=name, var_name=var_name)
super(Scale, self).__init__(
params=['scalarScalingFactor', 'matrix'], name=name, var_name=var_name)
self.scalarScalingFactor = scalarScalingFactor
self.matrix = matrix
self.params_with_defaults = []
class ScatterPacked(ComputationNode):
def __init__(self, cond, indexSequence, sourceData, name='ScatterPacked', var_name=None):
super(ScatterPacked, self).__init__(params=['cond', 'indexSequence', 'sourceData'], name=name, var_name=var_name)
super(ScatterPacked, self).__init__(
params=['cond', 'indexSequence', 'sourceData'], name=name, var_name=var_name)
self.cond = cond
self.indexSequence = indexSequence
self.sourceData = sourceData
self.params_with_defaults = []
class Sigmoid(ComputationNode):
def __init__(self, z, name='Sigmoid', var_name=None):
super(Sigmoid, self).__init__(params=['z'], name=name, var_name=var_name)
super(Sigmoid, self).__init__(
params=['z'], name=name, var_name=var_name)
self.z = z
self.params_with_defaults = []
class Softmax(ComputationNode):
def __init__(self, z, name='Softmax', var_name=None):
super(Softmax, self).__init__(params=['z'], name=name, var_name=var_name)
super(Softmax, self).__init__(
params=['z'], name=name, var_name=var_name)
self.z = z
self.params_with_defaults = []
class Hardmax(ComputationNode):
def __init__(self, z, name='Hardmax', var_name=None):
super(Hardmax, self).__init__(params=['z'], name=name, var_name=var_name)
super(Hardmax, self).__init__(
params=['z'], name=name, var_name=var_name)
self.z = z
self.params_with_defaults = []
class Sqrt(ComputationNode):
def __init__(self, z, name='Sqrt', var_name=None):
super(Sqrt, self).__init__(params=['z'], name=name, var_name=var_name)
self.z = z
self.params_with_defaults = []
class SquareError(ComputationNode):
def __init__(self, aMatrix, anotherMatrix, name='SquareError', var_name=None):
super(SquareError, self).__init__(params=['aMatrix', 'anotherMatrix'], name=name, var_name=var_name)
super(SquareError, self).__init__(
params=['aMatrix', 'anotherMatrix'], name=name, var_name=var_name)
self.aMatrix = aMatrix
self.anotherMatrix = anotherMatrix
self.params_with_defaults = []
class SumColumnElements(ComputationNode):
def __init__(self, z, name='SumColumnElements', var_name=None):
super(SumColumnElements, self).__init__(params=['z'], name=name, var_name=var_name)
super(SumColumnElements, self).__init__(
params=['z'], name=name, var_name=var_name)
self.z = z
self.params_with_defaults = []
class SumElements(ComputationNode):
def __init__(self, matrix, name='SumElements', var_name=None):
super(SumElements, self).__init__(params=['matrix'], name=name, var_name=var_name)
super(SumElements, self).__init__(
params=['matrix'], name=name, var_name=var_name)
self.matrix = matrix
self.params_with_defaults = []
class Tanh(ComputationNode):
def __init__(self, z, name='Tanh', var_name=None):
super(Tanh, self).__init__(params=['z'], name=name, var_name=var_name)
self.z = z
self.params_with_defaults = []
class TimeReverse(ComputationNode):
def __init__(self, vectorSequence, name='TimeReverse', var_name=None):
super(TimeReverse, self).__init__(params=['vectorSequence'], name=name, var_name=var_name)
super(TimeReverse, self).__init__(
params=['vectorSequence'], name=name, var_name=var_name)
self.vectorSequence = vectorSequence
self.params_with_defaults = []
class TransposeTimes(ComputationNode):
def __init__(self, leftMatrix, rightMatrix, name='TransposeTimes', var_name=None):
super(TransposeTimes, self).__init__(params=['leftMatrix', 'rightMatrix'], name=name, var_name=var_name)
super(TransposeTimes, self).__init__(
params=['leftMatrix', 'rightMatrix'], name=name, var_name=var_name)
self.leftMatrix = leftMatrix
self.rightMatrix = rightMatrix
self.params_with_defaults = []
class Where(ComputationNode):
def __init__(self, cond, name='Where', var_name=None):
super(Where, self).__init__(params=['cond'], name=name, var_name=var_name)
super(Where, self).__init__(
params=['cond'], name=name, var_name=var_name)
self.cond = cond
self.params_with_defaults = []
@ -602,33 +834,47 @@ Parameter = LearnableParameter
ColumnwiseCrossProduct = KhatriRaoProduct
ClassificationError = ErrorPrediction
Delay = PastValue
class Constant(Parameter):
def __init__(self, value, rows=1, cols=1, name='Constant', var_name=None):
super(Constant, self).__init__(rows, cols, learningRateMultiplier=0, init='fixedValue', value=value, name=name, var_name=var_name)
self.params=['value', 'rows', 'cols']
super(Constant, self).__init__(rows, cols, learningRateMultiplier=0,
init='fixedValue', value=value, name=name, var_name=var_name)
self.params = ['value', 'rows', 'cols']
self.params_with_defaults = ['rows', 'cols']
class ReshapeDimension(NewReshape):
def __init__(self, x, dim, tensorShape, name='ReshapeDimension', var_name=None):
super(ReshapeDimension, self).__init__(x, tensorShape, beginDim=dim, endDim=dim + 1, name=name, var_name=var_name)
self.params=['x', 'dim', 'tensorShape']
super(ReshapeDimension, self).__init__(
x, tensorShape, beginDim=dim, endDim=dim + 1, name=name, var_name=var_name)
self.params = ['x', 'dim', 'tensorShape']
self.params_with_defaults = []
class FlattenDimensions(NewReshape):
def __init__(self, x, dim, num, name='FlattenDimensions', var_name=None):
super(FlattenDimensions, self).__init__(x, 0, beginDim=dim, endDim=dim + num, name=name, var_name=var_name)
self.params=['x', 'dim', 'num']
super(FlattenDimensions, self).__init__(
x, 0, beginDim=dim, endDim=dim + num, name=name, var_name=var_name)
self.params = ['x', 'dim', 'num']
self.params_with_defaults = []
class SplitDimension(ReshapeDimension):
def __init__(self, x, dim, N, name='SplitDimension', var_name=None):
super(SplitDimension, self).__init__(x, dim, '<not yet supported>', name=name, var_name=var_name)
self.params=['x', 'dim', 'N']
super(SplitDimension, self).__init__(
x, dim, '<not yet supported>', name=name, var_name=var_name)
self.params = ['x', 'dim', 'N']
self.params_with_defaults = []
class Transpose(TransposeDimensions):
def __init__(self, x, name='Transpose', var_name=None):
super(Transpose, self).__init__(x, 1, 2, name=name, var_name=var_name)
self.params=['x']
self.params = ['x']
self.params_with_defaults = []

Просмотреть файл

@ -2,10 +2,10 @@ class SGD(dict):
"""This is the Stochastic Gradien Descent optimizer used to train the networks
"""
def __init__(self, epoch_size = 0, minibatch_size = 1, learning_ratesPerMB = "0.1", \
learning_rates_per_sample = None, momentum_per_mb = "0.9", \
momentum_per_sample = None, max_epochs = 5, dropout_rate = None):
def __init__(self, epoch_size=0, minibatch_size=1, learning_ratesPerMB="0.1",
learning_rates_per_sample=None, momentum_per_mb="0.9",
momentum_per_sample=None, max_epochs=5, dropout_rate=None):
""" SGD constructor
:param epoch_size: the number of samples to use in each epoch. An intermediate
@ -53,7 +53,7 @@ class SGD(dict):
"""
config = []
for k,v in self.items():
for k, v in self.items():
if (v is not None):
config.append('{0} = {1}\r\n'.format(k,v))
config.append('{0} = {1}\r\n'.format(k, v))
return ''.join(config)

Просмотреть файл

@ -22,6 +22,7 @@ class AbstractReader(dict, metaclass=ABCMeta):
def __ne__(self, x): return x is not self
class UCIFastReader(AbstractReader):
"""This is the reader class the maps to UCIFastReader of CNTK
@ -36,7 +37,7 @@ class UCIFastReader(AbstractReader):
self["FileName"] = filename
self["CustomDelimiter"] = custom_delimiter
self.inputs_def = []
def add_input(self, name_or_node, input_start, input_dim, num_of_classes=None, label_mapping_file=None):
"""Add an input to the reader
:param name_or_node: either name of the input in the network definition or the node itself
@ -47,10 +48,11 @@ class UCIFastReader(AbstractReader):
the mapping file path, it can be simply with all the possible classes, one per line
"""
if not name_or_node or input_start is None or input_dim is None:
raise ValueError("one of the parameters of add_input is None")
self.inputs_def.append((name_or_node, input_start, input_dim, num_of_classes, label_mapping_file))
raise ValueError("one of the parameters of add_input is None")
self.inputs_def.append(
(name_or_node, input_start, input_dim, num_of_classes, label_mapping_file))
def generate_config(self):
"""Generate the reader configuration block
"""
@ -66,14 +68,14 @@ class UCIFastReader(AbstractReader):
template += '''\
customDelimiter = %(CustomDelimiter)s
'''
if self.inputs_def is not None:
for (name_or_node, start, dim, num_of_classes, map_file) in self.inputs_def:
for (name_or_node, start, dim, num_of_classes, map_file) in self.inputs_def:
if (isinstance(name_or_node, ComputationNode)):
name = name_or_node.var_name
else:
name = name_or_node
template += '''\
{0} = [
start = {1}
@ -83,22 +85,23 @@ class UCIFastReader(AbstractReader):
if num_of_classes:
template += '''\
labelDim= {0}
'''.format(num_of_classes)
'''.format(num_of_classes)
if map_file:
template += '''\
labelMappingFile= "{0}"
'''.format(map_file)
'''.format(map_file)
template += '''\
]
'''
template += '''\
]
'''
return template % self
class CNTKTextFormatReader(AbstractReader):
"""This is the reader class the maps to CNTKTextFormatReader of CNTK
@ -120,12 +123,12 @@ class CNTKTextFormatReader(AbstractReader):
format: dense or sparse
"""
if not name_or_node or input_dim is None or format is None:
raise ValueError("one of the parameters of add_input is None")
raise ValueError("one of the parameters of add_input is None")
input_alias = input_alias or name_or_node
self.inputs_def.append((name_or_node, input_alias, input_dim, format))
def generate_config(self):
"""Generate the reader configuration block
"""
@ -138,10 +141,10 @@ class CNTKTextFormatReader(AbstractReader):
template += '''
input = [
'''
for (name_or_node, input_alias, dim, format) in self.inputs_def:
for (name_or_node, input_alias, dim, format) in self.inputs_def:
if (isinstance(name_or_node, ComputationNode)):
name = name_or_node.var_name
name = name_or_node.var_name
else:
name = name_or_node
@ -149,23 +152,23 @@ class CNTKTextFormatReader(AbstractReader):
a = name
else:
a = input_alias
template += '''
{0}=[
alias = "{1}"
dim = {2}
format = "{3}"
]'''.format(name, a, dim, format)
template += '''
]
]
'''
return template % self
def NumPyReader(data, filename):
#TODO: get rid of this
# TODO: get rid of this
"""
This is a factory that wraps Python arrays with a UCIFastReader.
"""
@ -182,4 +185,3 @@ def NumPyReader(data, filename):
np.savetxt(filename, data, delimiter=' ', newline='\r\n', fmt=format_str)
return UCIFastReader(filename)

Просмотреть файл

@ -1,7 +1,8 @@
from ..context import *
def test_parse_shapes():
output = '''\
output = '''\
FormNestedNetwork: WARNING: Was called twice for v3 Plus operation
Validating network. 5 nodes to process in pass 1.
@ -24,13 +25,12 @@ Validating network, final pass.
Post-processing network complete.
'''
expected = {
'dummy_node':(2,),
'v0':(4,1),
'v1':(2,2),
'v2':(1,1),
'v3':(2,2)
}
assert Context._parse_shapes_from_output(output) == expected
expected = {
'dummy_node': (2,),
'v0': (4, 1),
'v1': (2, 2),
'v2': (1, 1),
'v3': (2, 2)
}
assert Context._parse_shapes_from_output(output) == expected

Просмотреть файл

@ -51,50 +51,56 @@ def test_overload_exception():
with pytest.raises(ValueError):
C(range(0, 10))[0:3:2]
def _to_list(desc):
return [line.strip() for line in desc.split('\n')]
@pytest.mark.parametrize("root_node, expected", [
(C(2, var_name='c0'), ["c0 = Constant(2, rows=1, cols=1)"]),
# Input should behave as Constant in case of scalars
(I([1,2], var_name='i1'), ["i1 = Input(2:1, tag='feature')"]),
(I([1, 2], var_name='i1'), ["i1 = Input(2:1, tag='feature')"]),
(Plus(C(0), C(1)),
["v0 = Constant(0, rows=1, cols=1)", "v1 = Constant(1, rows=1, cols=1)", "v2 = Plus(v0, v1)"]),
])
def test_description(root_node, expected):
description, has_inputs, readers = root_node.to_config()
description, has_inputs, readers = root_node.to_config()
assert _to_list(description) == expected
def test_graph_with_same_node_twice():
v0 = C(1)
root_node = Plus(v0, v0)
expected = ['v0 = Constant(1, rows=1, cols=1)', 'v1 = Plus(v0, v0)']
description, has_inputs, readers = root_node.to_config()
description, has_inputs, readers = root_node.to_config()
assert _to_list(description) == expected
assert readers == []
@pytest.mark.parametrize("alias, data, expected", [
('', [A([1,0]), A([0,0,1,0])], ValueError), # no alias given
('A', [object()], ValueError),
])
('', [A([1, 0]), A([0, 0, 1, 0])], ValueError), # no alias given
('A', [object()], ValueError),
])
def test_sequence_conversion_exceptions(alias, data, expected):
with pytest.raises(expected):
_seq_to_text_format(data, alias=alias)
def test_constant_var_name():
var_name = 'NODE'
node = C([A([])], var_name=var_name)
assert node.var_name == var_name
@pytest.mark.parametrize("alias, data, expected", [
('W', [A([])], """\
0|W \
"""),
('W', [A([1,0]), A([0,0,1,0])], """\
('W', [A([1, 0]), A([0, 0, 1, 0])], """\
0|W 1 0
1|W 0 0 1 0\
"""),
])
])
def test_sequence_conversion_dense(alias, data, expected):
assert _seq_to_text_format(data, alias=alias) == expected
@ -103,43 +109,44 @@ if False:
('W', [A({})], """\
0|W \
"""),
('W', [{3:1, 50:1, 2:0}, {1:-5}], """\
('W', [{3: 1, 50: 1, 2: 0}, {1: -5}], """\
0|W 2:0 3:1 50:1
1|W 1:-5\
"""),
])
])
def test_sequence_conversion_sparse(alias, data, expected):
# We use the dictionary in data to create a SciPy sparse dictionary of
# keys, which we then feed to the converter.
dok_data = []
for data_elem in data:
d = scipy.sparse.dok_matrix((100,1))
for k,v in data_elem.items():
d = scipy.sparse.dok_matrix((100, 1))
for k, v in data_elem.items():
d[k] = v
dok_data.append(d)
assert _seq_to_text_format(dok_data, alias=alias) == expected
@pytest.mark.parametrize("data, expected", [
([], True),
([1], True),
([[1,2]], True),
([[1, 2]], True),
([[]], True),
([[A([1,2])]], False),
([A([1,2])], False),
([A([1,2]), A([])], False),
])
([[A([1, 2])]], False),
([A([1, 2])], False),
([A([1, 2]), A([])], False),
])
def test_is_tensor(data, expected):
assert is_tensor(data) == expected
@pytest.mark.parametrize("data, expected", [
([], False),
([1], False),
([[1,2]], False),
([[1, 2]], False),
([[]], False),
([[A([1,2])]], False),
([A([1,2])], True),
([A([1,2]), A([])], True),
])
([[A([1, 2])]], False),
([A([1, 2])], True),
([A([1, 2]), A([])], True),
])
def test_is_sequence(data, expected):
assert is_sequence(data) == expected

Просмотреть файл

@ -10,15 +10,18 @@ from ..reader import *
C = constant
I = input
def _test(root_node, expected, clean_up=True):
with get_new_context() as ctx:
ctx.clean_up = clean_up
assert not ctx.input_nodes
result = ctx.eval(root_node)
expected = np.asarray(expected)
assert result.shape == expected.shape or result.shape == (1,1) and expected.shape==()
assert result.shape == expected.shape or result.shape == (
1, 1) and expected.shape == ()
assert np.all(result == expected)
@pytest.mark.parametrize('root_node, expected', [
# __add__ / __radd__
(C(0) + C(1), 1),
@ -41,11 +44,13 @@ def _test(root_node, expected, clean_up=True):
# normal ops
(C(np.ones((2,3))*3), [[3,3,3], [3,3,3]]),
(C(np.ones((2,3))*3)+np.vstack([np.ones(3), np.ones(3)+1]), [[4,4,4], [5,5,5]]),
(C(np.ones((2,3))*3)*np.vstack([np.ones(3), np.ones(3)+1]), [[3,3,3], [6,6,6]]),
(C(np.ones((2, 3)) * 3), [[3, 3, 3], [3, 3, 3]]),
(C(np.ones((2, 3)) * 3) + \
np.vstack([np.ones(3), np.ones(3) + 1]), [[4, 4, 4], [5, 5, 5]]),
(C(np.ones((2, 3)) * 3) * \
np.vstack([np.ones(3), np.ones(3) + 1]), [[3, 3, 3], [6, 6, 6]]),
# special treatment of inputs in RowStack
# special treatment of inputs in RowStack
# (RowStack((C(1), C(2))), [[1],[2]]), # TODO figure out the real semantic
# of RowStack
@ -57,7 +62,7 @@ def _test(root_node, expected, clean_up=True):
# to ComputationNode
(abs(C(-3)), 3),
(abs(C(3)), 3),
(abs(C([[-1,2],[50,-0]])), [[1,2],[50,0]]),
(abs(C([[-1, 2], [50, -0]])), [[1, 2], [50, 0]]),
# more complex stuff
#(Plus(C(5), 3), 8),
@ -65,20 +70,21 @@ def _test(root_node, expected, clean_up=True):
def test_overload_eval(root_node, expected):
_test(root_node, expected)
@pytest.mark.parametrize('root_node, expected', [
# __add__ / __radd__
(C(np.asarray([1,2]))+0, [1,2]),
(C(np.asarray([1,2]))+.1, [1.1,2.1]),
(.1+C(np.asarray([1,2])), [1.1,2.1]),
(C(np.asarray([1,2]))*0, [0,0]),
(C(np.asarray([1,2]))*.1, [0.1,0.2]),
(.1*C(np.asarray([1,2])), [0.1,0.2]),
(C(np.asarray([[1,2],[3,4]]))+.1, [[1.1,2.1],[3.1,4.1]]),
(C(np.asarray([[1,2],[3,4]]))*2, [[2,4],[6,8]]),
(2*C(np.asarray([[1,2],[3,4]])), [[2,4],[6,8]]),
(2*C(np.asarray([[1,2],[3,4]]))+100, [[102,104],[106,108]]),
(C(np.asarray([[1,2],[3,4]]))*C(np.asarray([[1,2],[3,4]])), [[1,4],[9,16]]),
(C(np.asarray([1, 2])) + 0, [1, 2]),
(C(np.asarray([1, 2])) + .1, [1.1, 2.1]),
(.1 + C(np.asarray([1, 2])), [1.1, 2.1]),
(C(np.asarray([1, 2])) * 0, [0, 0]),
(C(np.asarray([1, 2])) * .1, [0.1, 0.2]),
(.1 * C(np.asarray([1, 2])), [0.1, 0.2]),
(C(np.asarray([[1, 2], [3, 4]])) + .1, [[1.1, 2.1], [3.1, 4.1]]),
(C(np.asarray([[1, 2], [3, 4]])) * 2, [[2, 4], [6, 8]]),
(2 * C(np.asarray([[1, 2], [3, 4]])), [[2, 4], [6, 8]]),
(2 * C(np.asarray([[1, 2], [3, 4]])) + 100, [[102, 104], [106, 108]]),
(C(np.asarray([[1, 2], [3, 4]]))
* C(np.asarray([[1, 2], [3, 4]])), [[1, 4], [9, 16]]),
])
def test_ops_on_numpy(root_node, expected, tmpdir):
_test(root_node, expected, clean_up=False)

Просмотреть файл

@ -8,18 +8,18 @@ from .. import cntk1_ops
allclose = np.testing.assert_allclose
def test_NumPyReader(tmpdir):
data = [[1, 2], [3, 4]]
fn = str(tmpdir / 'test.txt')
reader = NumPyReader(data, fn)
input_node = cntk1_ops.Input(2, var_name='testInput')
reader.add_input(input_node, 0,2)
reader.add_input(input_node, 0, 2)
out = input_node + 2
with get_new_context() as ctx:
result = ctx.eval(out, reader)
assert np.all(result == np.asarray(data)+2)
assert np.all(result == np.asarray(data) + 2)
# TODO test other readers

Просмотреть файл

@ -14,7 +14,7 @@ from cntk.utils import CNTK_EXECUTABLE_PATH
# BrainSCript's node definitions are created when a build is triggered so we
# should be able to find the file in the path of the cntk exeutable.
CNTKCORE_DEFS = os.path.join(
os.path.dirname(CNTK_EXECUTABLE_PATH), 'CNTK.core.bs')
os.path.dirname(CNTK_EXECUTABLE_PATH), 'CNTK.core.bs')
REGEX_STANDARD = re.compile(r'(?P<operator>\w+)\((?P<operands>.*?)\) = .*')
REGEX_COMPNODE = re.compile(
@ -78,14 +78,14 @@ class %(name)s(%(parentclass)s):
def __init__(self, comp_match):
self.name = comp_match.group('operator')
if self.name in INPUT_NODES:
self.parentclass = 'InputComputationNodeBase'
self.parentclass = 'InputComputationNodeBase'
elif self.name in IMAGE_INPUT_NODES:
self.parentclass = 'ImageInputComputationNodeBase'
self.parentclass = 'ImageInputComputationNodeBase'
else:
self.parentclass = 'ComputationNode'
self.raw_operands = comp_match.group('operands')
self.operands = []