This commit is contained in:
Clemens Marschner 2016-04-13 14:30:06 +02:00
Родитель d96f491dad
Коммит ca4afe5c67
14 изменённых файлов: 50 добавлений и 183 удалений

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

@ -586,7 +586,6 @@ CNTK_SRC =\
$(SOURCEDIR)/CNTK/BrainScript/BrainScriptEvaluator.cpp \
$(SOURCEDIR)/CNTK/BrainScript/BrainScriptParser.cpp \
$(SOURCEDIR)/CNTK/BrainScript/BrainScriptTest.cpp \
$(SOURCEDIR)/CNTK/BrainScript/ExperimentalNetworkBuilder.cpp \
$(SOURCEDIR)/Common/BestGpu.cpp \
$(SOURCEDIR)/Common/MPIWrapper.cpp \

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

@ -73,7 +73,7 @@ void NDLNodeEvaluatorImpl<ElemType>::Evaluate(NDLNode<ElemType>* node, const wst
size_t i = 0;
auto tensorShape = ProcessTensorShapeParameters(node, params, i, /*isImage=*/false, cnNodeType);
wstring dynamicAxis = node->GetOptionalParameter("dynamic", "");
wstring dynamicAxis = node->GetOptionalParameter("dynamicAxis", "");
// first look for this node already existing in the network
// BUGBUG: How does this set the dimensions then?
if (m_net->NodeNameExists(name))
@ -98,7 +98,7 @@ void NDLNodeEvaluatorImpl<ElemType>::Evaluate(NDLNode<ElemType>* node, const wst
size_t imageHeight = ((NDLNode<ElemType>*) params[1])->GetScalar();
size_t imageChannels = ((NDLNode<ElemType>*) params[2])->GetScalar();
ImageLayoutKind imageLayoutKind = ImageLayoutKindFrom(node->GetOptionalParameter("imageLayout", "HWC"));
wstring dynamicAxis = node->GetOptionalParameter("dynamic", "");
wstring dynamicAxis = node->GetOptionalParameter("dynamicAxis", "");
if (isSparse)
nodePtr = builder.CreateSparseInputNode(name, ImageDimensions::AsTensorShape(imageWidth, imageHeight, imageChannels, imageLayoutKind), dynamicAxis);

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

@ -34,11 +34,11 @@ Parameter = LearnableParameter // deprecated
# TODO: make Parameter take tensor dims?
ParameterTensor(dims, learningRateMultiplier = 1.0, init = 'uniform'/*|fixedValue|gaussian|fromFile*/, initValueScale = 1, value = 0, initFromFilePath = '', initFromLiteral = '', initOnCPUOnly=true, randomSeed=-1, tag='') = new ComputationNode [ operation = 'LearnableParameter' ; shape = new TensorShape [ /*dims*/ ] /*plus the function args*/ ]
ConstantFromString(literal, tag='') = ParameterTensor((0)/*dim, will be inferred*/, init = 'fromLiteral', initFromLiteral = literal, learningRateMultiplier = 0.0)
DynamicAxis(Name='', tag='') = new ComputationNode [ operation = 'DynamicAxis' ; name = Name ]
Input(dims, dynamicAxis='', tag='feature') = new ComputationNode [ operation = 'InputValue' ; shape = new TensorShape [ /*dims*/ ] ; dynamicAxes = dynamicAxis ; isImage = false /*plus the function args*/ ]
SparseInput(dims, dynamicAxis='', tag='feature') = new ComputationNode [ operation = 'SparseInputValue' ; shape = new TensorShape [ /*dims*/ ] ; dynamicAxes = dynamicAxis ; isImage = false /*plus the function args*/ ]
ImageInput(imageWidth, imageHeight, imageChannels, imageLayout='CHW', dynamicAxis='', tag='feature') = new ComputationNode [ operation = 'InputValue' ; dynamicAxes = dynamicAxis ; isImage = true /*plus the function args*/ ]
SparseImageInput(imageWidth, imageHeight, imageChannels, imageLayout='CHW', dynamicAxis='', tag='feature') = new ComputationNode [ operation = 'SparseInputValue' ; dynamicAxes = dynamicAxis ; isImage = true /*plus the function args*/ ]
DynamicAxis(name='', tag='') = new ComputationNode [ operation = 'DynamicAxis' ; /*plus the function args*/ ]
Input(dims, dynamicAxis='', tag='feature') = new ComputationNode [ operation = 'InputValue' ; shape = new TensorShape [ /*dims*/ ] ; isImage = false /*plus the function args*/ ]
SparseInput(dims, dynamicAxis='', tag='feature') = new ComputationNode [ operation = 'SparseInputValue' ; shape = new TensorShape [ /*dims*/ ] ; isImage = false /*plus the function args*/ ]
ImageInput(imageWidth, imageHeight, imageChannels, imageLayout='CHW', dynamicAxis='', tag='feature') = new ComputationNode [ operation = 'InputValue' ; isImage = true /*plus the function args*/ ]
SparseImageInput(imageWidth, imageHeight, imageChannels, imageLayout='CHW', dynamicAxis='', tag='feature') = new ComputationNode [ operation = 'SparseInputValue' ; isImage = true /*plus the function args*/ ]
EnvironmentInput(propertyName, tag='') = new ComputationNode [ operation = 'EnvironmentInput' /*plus the function args*/ ]
ConstantTensor(val, dims, tag='') = ParameterTensor(dims, learningRateMultiplier = 0, init = 'fixedValue', value = val)
Constant(val, rows = 1, cols = 1, tag='') = Parameter(rows, cols, learningRateMultiplier = 0, init = 'fixedValue', value = val)

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

@ -1,134 +0,0 @@
#if 0 // this entire file can be removed once CNTK.core.bs works
// ExperimentalNetworkBuilder.cpp -- interface to new version of NDL (and config) parser --fseide
#define _CRT_NONSTDC_NO_DEPRECATE // make VS accept POSIX functions without _
#define _CRT_SECURE_NO_WARNINGS // "secure" CRT not available on all platforms --add this at the top of all CPP files that give "function or variable may be unsafe" warnings
#include <string>
using namespace std;
// TODO: move to actual text files to be included
wstring standardFunctions =
L"Print(value, format='') = new PrintAction [ what = value /*; how = format*/ ] \n"
L"Debug(value, say = '', enabled = true) = new Debug [ /*macro arg values*/ ] \n"
L"Format(value, format) = new StringFunction [ what = 'Format' ; arg = value ; how = format ] \n"
L"Replace(s, from, to) = new StringFunction [ what = 'Replace' ; arg = s ; replacewhat = from ; withwhat = to ] \n"
L"Substr(s, begin, num) = new StringFunction [ what = 'Substr' ; arg = s ; pos = begin ; chars = num ] \n"
L"Chr(c) = new StringFunction [ what = 'Chr' ; arg = c ] \n"
L"Floor(x) = new NumericFunction [ what = 'Floor' ; arg = x ] \n"
L"Length(x) = new NumericFunction [ what = 'Length' ; arg = x ] \n"
L"Ceil(x) = -Floor(-x) \n"
L"Round(x) = Floor(x+0.5) \n"
L"Sign(x) = if x > 0 then 1 else if x < 0 then -1 else 0 \n"
L"Min(a,b) = if a < b then a else b \n"
L"Max(a,b) = if a > b then a else b \n"
L"Fac(n) = if n > 1 then Fac(n-1) * n else 1 \n";
wstring commonMacros =
L"BFF(in, rows, cols) = [ B = Parameter(rows, 1, init = 'fixedValue', value = 0) ; W = Parameter(rows, cols) ; z = W*in+B ] \n"
L"SBFF(in, rows, cols) = [ Eh = Sigmoid(BFF(in, rows, cols).z) ] \n "
L"MeanVarNorm(feat) = PerDimMeanVarNormalization(feat, Mean(feat), InvStdDev(feat)) \n"
L"LogPrior(labels) = Log(Mean(labels)) \n";
wstring computationNodes = // TODO: use actual TypeName() here? would first need to make it a wide string; we should also extract those two methods into the base macro
L"LearnableParameter(rows, cols, learningRateMultiplier = 1.0, init = 'uniform'/*|fixedValue|gaussian|fromFile*/, initValueScale = 1, value = 0, initFromFilePath = '', initOnCPUOnly=true, randomSeed=-1, tag='') = new ComputationNode [ operation = 'LearnableParameter' ; shape = new TensorShape [ dims = (rows : cols) ] /*plus the function args*/ ]\n"
L"Parameter = LearnableParameter // deprecated \n"
L"ParameterTensor(dims, learningRateMultiplier = 1.0, init = 'uniform'/*|fixedValue|gaussian|fromFile*/, initValueScale = 1, value = 0, initFromFilePath = '', initOnCPUOnly=true, randomSeed=-1, tag='') = new ComputationNode [ operation = 'LearnableParameter' ; shape = new TensorShape [ /*dims*/ ] /*plus the function args*/ ]\n"
// TODO: ImageParameter?
// ^^ already works; vv untested
L"Input(dims, tag='feature') = new ComputationNode [ operation = 'InputValue' ; shape = new TensorShape [ /*dims*/ ] ; isImage = false /*plus the function args*/ ]\n" // note: naming a little inconsistent // TODO: re-test after flag change
L"SparseInput(dims, tag='feature') = new ComputationNode [ operation = 'SparseInputValue' ; shape = new TensorShape [ /*dims*/ ] ; isImage = false /*plus the function args*/ ]\n"
L"ImageInput(imageWidth, imageHeight, imageChannels, imageLayout='CHW', tag='feature') = new ComputationNode [ operation = 'InputValue' ; isImage = true /*plus the function args*/ ]\n"
L"SparseImageInput(imageWidth, imageHeight, imageChannels, imageLayout='CHW', tag='feature') = new ComputationNode [ operation = 'SparseInputValue' ; isImage = true /*plus the function args*/ ]\n"
L"Constant(val, rows = 1, cols = 1, tag='') = Parameter(rows, cols, learningRateMultiplier = 0, init = 'fixedValue', value = val) \n"
L"PastValue(dims, input, timeStep = 1, defaultHiddenActivation = 0.1, tag='') = new ComputationNode [ operation = 'PastValue' ; inputs = input ; shape = new TensorShape [ /*dims*/ ] /*plus the function args*/ ]\n"
L"FutureValue(dims, input, timeStep = 1, defaultHiddenActivation = 0.1, tag='') = new ComputationNode [ operation = 'FutureValue' ; inputs = input ; shape = new TensorShape [ /*dims*/ ] /*plus the function args*/ ]\n"
// TODO: ^^ DelayedValues no longer need to know their dimension. That is inferred in Validation.
L"Shift(input, fromOffset, boundaryValue, boundaryMode=-1/*context*/, dim=-1, tag='') = new ComputationNode [ operation = 'Shift' ; inputs = (input : boundaryValue) /*plus the function args*/ ]\n"
L"RowSlice(startIndex, numRows, input, tag='') = new ComputationNode [ operation = 'RowSlice' ; inputs = input /*plus the function args*/ ]\n"
L"RowRepeat(input, numRepeats, tag='') = new ComputationNode [ operation = 'RowRepeat' ; inputs = input /*plus the function args*/ ]\n"
L"RowStack(inputs, tag='') = new ComputationNode [ operation = 'RowStack' /*plus the function args*/ ]\n"
L"Reshape(input, numRows, imageWidth = 0, imageHeight = 0, imageChannels = 0, tag='') = new ComputationNode [ operation = 'LegacyReshape' ; inputs = input /*plus the function args*/ ]\n"
L"NewReshape(input, dims, beginDim=0, endDim=0, tag='') = new ComputationNode [ operation = 'Reshape' ; inputs = input ; shape = new TensorShape [ /*dims*/ ] /*plus the function args*/ ]\n"
L"ReshapeDimension(x, dim, tensorShape) = NewReshape(x, tensorShape, beginDim=dim, endDim=dim + 1) \n"
L"FlattenDimensions(x, dim, num) = NewReshape(x, 0, beginDim=dim, endDim=dim + num) \n"
L"SplitDimension(x, dim, N) = ReshapeDimension(x, dim, 0:N) \n"
L"TransposeDimensions(input, dim1, dim2, tag='') = new ComputationNode [ operation = 'TransposeDimensions' ; inputs = input /*plus the function args*/ ]\n"
L"Transpose(x) = TransposeDimensions(x, 1, 2)\n"
L"Times(A, B, outputRank=1, tag='') = new ComputationNode [ operation = 'Times' ; inputs = ( A : B ) /*plus the function args*/ ]\n"
// TODO: Logistic should be generated with with BinaryStandardNode macro below.
L"Logistic(label, probability, tag='') = new ComputationNode [ operation = 'Logistic' ; inputs = (label : probability) /*plus the function args*/ ]\n"
L"WeightedLogistic(label, probability, instanceWeight, tag='') = new ComputationNode [ operation = 'Logistic' ; inputs = (label : probability : instanceWeight) /*plus the function args*/ ]\n"
L"ReconcileDynamicAxis(dataInput, layoutInput, tag='') = new ComputationNode [ operation = 'ReconcileDynamicAxis' ; inputs = (dataInput : layoutInput) /*plus the function args*/ ]\n"
L"Convolution(weightNode, inputValueNode, kernelWidth, kernelHeight, outputChannels, horizontalSubsample, verticalSubsample, zeroPadding = false, maxTempMemSizeInSamples = 0, imageLayout='CHW', tag='') = new ComputationNode [ operation = 'Convolution' ; inputs = (weightNode : inputValueNode) /*plus the function args*/ ]\n"
L"MaxPooling(input, windowWidth, windowHeight, horizontalSubsample, verticalSubsample, imageLayout='CHW', tag='') = new ComputationNode [ operation = 'MaxPooling' ; inputs = input /*plus the function args*/ ]\n"
L"AveragePooling(input, windowWidth, windowHeight, horizontalSubsample, verticalSubsample, imageLayout='CHW', tag='') = new ComputationNode [ operation = 'AveragePooling' ; inputs = input /*plus the function args*/ ]\n"
// TODO: define DelayedValue, with negative delay for future; cannot do this yet, need to be able to say something like delay = -(^.delay)
// aliases
L"ColumnwiseCrossProduct = KhatriRaoProduct // deprecated \n" // TODO: should it be deprecated? It is described as easier to understand in the CNTKBook.
L"ClassificationError = ErrorPrediction \n"
L"Delay = PastValue \n" // TODO: should it allow negative offsets and an if test here?
L"BatchNormalization(input, scale, bias, runMean, runInvStdDev, eval, spatial, normalizationTimeConstant = 0, epsilon = 0.00001, useCntkEngine = true, imageLayout='CHW', tag='') = new ComputationNode [ operation = 'BatchNormalization' ; inputs = (input : scale : bias : runMean : runInvStdDev) /*plus the function args*/ ]\n"
// standard nodes. We use macros to define these strings.
#define UnaryStandardNode(Op, a) L## #Op L"(" L## #a L", tag='') = new ComputationNode [ operation = '" L## #Op L"' ; inputs = " L## #a L" /*plus the function args*/ ]\n"
#define BinaryStandardNode(Op, a, b) L## #Op L"(" L## #a L", " L## #b L", tag='') = new ComputationNode [ operation = '" L## #Op L"' ; inputs = (" L## #a L" : " L## #b L") /*plus the function args*/ ]\n"
#define TernaryStandardNode(Op, a, b, c) L## #Op L"(" L## #a L", " L## #b L", " L## #c L", tag='') = new ComputationNode [ operation = '" L## #Op L"' ; inputs = (" L## #a L" : " L## #b L" : " L## #c L") /*plus the function args*/ ]\n"
#define QuaternaryStandardNode(Op, a, b, c, d) L## #Op L"(" L## #a L", " L## #b L", " L## #c L", " L## #d L", tag='') = new ComputationNode [ operation = '" L## #Op L"' ; inputs = (" L## #a L" : " L## #b L" : " L## #c L" : " L## #d L") /*plus the function args*/ ]\n"
#ifdef COMING_SOON
TernaryStandardNode(CRF, labelVectorSequence, positionDependenScoreVectorSequence, transitionScores) // TODO: better names
#endif
UnaryStandardNode(Abs, x)
QuaternaryStandardNode(ClassBasedCrossEntropyWithSoftmax, labelClassDescriptorVectorSequence, mainInputInfo, mainWeight, classLogProbsBeforeSoftmax)
// BUGBUG: the commented-out ones are not mentioned in the CNTK book, nor are their parameters documented in the source code
BinaryStandardNode(ColumnElementTimes, aVectorSequence, anotherVectorSequence)
BinaryStandardNode(CosDistance, aVectorSequence, anotherVectorSequence)
QuaternaryStandardNode(CosDistanceWithNegativeSamples, aVectorSequence, anotherVectorSequence, numShifts, numNegSamples)
//BinaryStandardNode(CosDistanceWithNegativeSamplesNode)
UnaryStandardNode(Cosine, x)
BinaryStandardNode(CrossEntropy, refProbVectorSequence, outProbVectorSequence)
BinaryStandardNode(CrossEntropyWithSoftmax, labelVectorSequence, outProbVectorSequence)
BinaryStandardNode(DiagTimes, diagonalMatrixAsColumnVector, matrix)
UnaryStandardNode(Dropout, activationVectorSequence)
//BinaryStandardNode(DummyCriterionNode)
BinaryStandardNode(ElementTimes, aMatrix, anotherMatrix)
BinaryStandardNode(ErrorPrediction, labelVectorSequence, outVectorSequence) // CNTKBook: ClassificationError?
UnaryStandardNode(Exp, x)
QuaternaryStandardNode(GMMLogLikelihood, unnormalizedPriorVector, meansAsRows, logStdDevAsRows, dataVectorSequence)
UnaryStandardNode(InvStdDev, dataVectorSequence)
BinaryStandardNode(KhatriRaoProduct, leftMatrix, rightMatrix)
//BinaryStandardNode(LSTMNode)
UnaryStandardNode(Log, x)
UnaryStandardNode(LogSoftmax, z)
//BinaryStandardNode(LookupTableNode)
UnaryStandardNode(MatrixL1Reg, matrix)
UnaryStandardNode(MatrixL2Reg, matrix)
// BUGBUG: CNTKBook also mentions L1Norm and L2Norm
UnaryStandardNode(Mean, dataVectorSequence)
BinaryStandardNode(Minus, leftMatrix, rightMatrix)
UnaryStandardNode(Negate, input)
TernaryStandardNode(PerDimMeanVarDeNormalization, dataVectorSequence, meanVector, invStdDevVector) // TODO: correct?
TernaryStandardNode(PerDimMeanVarNormalization, dataVectorSequence, meanVector, invStdDevVector)
BinaryStandardNode(Plus, leftMatrix, rightMatrix)
UnaryStandardNode(RectifiedLinear, z)
//BinaryStandardNode(RowElementTimesNode)
BinaryStandardNode(Scale, scalarScalingFactor, matrix)
#ifdef COMING_SOON
//BinaryStandardNode(SequenceDecoderNode)
#endif
UnaryStandardNode(Sigmoid, z)
UnaryStandardNode(Softmax, z)
UnaryStandardNode(Hardmax, z)
BinaryStandardNode(SquareError, aMatrix, anotherMatrix)
UnaryStandardNode(SumColumnElements, z)
UnaryStandardNode(SumElements, matrix)
UnaryStandardNode(Tanh, z)
UnaryStandardNode(TimeReverse, vectorSequence)
BinaryStandardNode(TransposeTimes, leftMatrix, rightMatrix)
// those nodes are deprecated, we won't implement them in BS:
//BinaryStandardNode(NoiseContrastiveEstimationNode)
//BinaryStandardNode(ParallelNode)
//BinaryStandardNode(StrideTimesNode)
;
#endif

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

@ -203,7 +203,6 @@
<ClCompile Include="BrainScript\BrainScriptEvaluator.cpp" />
<ClCompile Include="BrainScript\BrainScriptParser.cpp" />
<ClCompile Include="BrainScript\BrainScriptTest.cpp" />
<ClCompile Include="BrainScript\ExperimentalNetworkBuilder.cpp" />
<ClCompile Include="CNTK.cpp" />
<ClCompile Include="ModelEditLanguage.cpp" />
<ClCompile Include="stdafx.cpp" />
@ -226,4 +225,4 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
</Project>

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

@ -44,9 +44,6 @@
<ClCompile Include="BrainScript\BrainScriptTest.cpp">
<Filter>BrainScript</Filter>
</ClCompile>
<ClCompile Include="BrainScript\ExperimentalNetworkBuilder.cpp">
<Filter>BrainScript</Filter>
</ClCompile>
<ClCompile Include="..\Common\ExceptionWithCallStack.cpp">
<Filter>Common</Filter>
</ClCompile>

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

@ -120,6 +120,8 @@ struct MBLayout
// copy the content of another MBLayoutPtr over
// Use this instead of actual assignment to make it super-obvious that this is not copying the pointer but actual content. The pointer is kept fixed.
// Use "keepName" if the "identity" of the target is to be preserved, e.g.
// while copying from reader space to network space.
void CopyFrom(const MBLayoutPtr& other, bool keepName=false)
{
m_numTimeSteps = other->m_numTimeSteps;
@ -521,7 +523,7 @@ private:
size_t m_numFramesDeclared;
size_t m_numGapFrames;
// Lookup tables for determining whether any sequence at time t is a identical layouts, do noboundary or gap.
// Lookup tables for determining whether any sequence at time t is a boundary or gap.
// An optional time delay can be given, then the test is whether going from t to (t + time delay) crosses a boundary.
// The purpose is for knowing when to reset state of a recurrent node.
//

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

@ -76,7 +76,7 @@ static shared_ptr<ComputationNode<ElemType>> CreateStandardNode(const std::wstri
else if (nodeType == OperationNameOf(PerDimMeanVarDeNormalizationNode)) return New<PerDimMeanVarDeNormalizationNode<ElemType>>(forward<_Types>(_Args)...);
else if (nodeType == OperationNameOf(PassNode)) return New<PassNode<ElemType>>(forward<_Types>(_Args)...);
else if (nodeType == OperationNameOf(PlusNode)) return New<PlusNode<ElemType>>(forward<_Types>(_Args)...);
else if (nodeType == OperationNameOf(ReconcileDynamicAxisNode)) return New<ReconcileDynamicAxisNode<ElemType>>(forward<_Types>(_Args)...);
else if (nodeType == OperationNameOf(ReconcileDynamicAxisNode)) return New<ReconcileDynamicAxisNode<ElemType>>(forward<_Types>(_Args)...);
else if (nodeType == OperationNameOf(ReciprocalNode)) return New<ReciprocalNode<ElemType>>(forward<_Types>(_Args)...);
else if (nodeType == OperationNameOf(RectifiedLinearNode)) return New<RectifiedLinearNode<ElemType>>(forward<_Types>(_Args)...);
else if (nodeType == OperationNameOf(ReshapeNode)) return New<ReshapeNode<ElemType>>(forward<_Types>(_Args)...);

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

@ -525,13 +525,19 @@ void ComputationNetwork::ResetMBLayouts()
for (const auto& node : GetAllNodesForRoot(nullptr))
node->LinkToMBLayout(nullptr);
// DynamicAxis nodes are (apart from the network-wide MBLayout) the only holders of MBLayouts. Initialize them.
// DynamicAxis nodes are (apart from the network-wide MBLayout) the main holders of MBLayouts. Initialize them.
// The only other instances are nodes that change the MBLayout, like WhereNode.
for (auto node : GetNodesWithType(L"DynamicAxis"))
node->LinkToMBLayout(make_shared<MBLayout>(1, 0, node->GetName()));
// This is now initialized inside of the Input nodes, with the proper connections.
for (auto node : InputNodes(nullptr))
node->AttachDynamicAxis([&](std::wstring name) { return GetNodeFromName(name); }, /* default */ m_pMBLayoutOfNetwork);
{
auto n = dynamic_pointer_cast<IDynamic>(node);
if (!n)
LogicError("Expected %ls to implement IDynamic, but it doesn't.", node->NodeDescription().c_str());
n->AttachDynamicAxis([&](std::wstring name) { return GetNodeFromName(name); }, /* default */ m_pMBLayoutOfNetwork);
}
}
// -----------------------------------------------------------------------

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

@ -332,28 +332,25 @@ TensorShape ComputationNodeBase::GetOneSampleTensorSliceFor(size_t rank, const F
prototype += "NULL";
continue;
}
const char* mbSizeMark = child->m_pMBLayout ? " x " : "";
#if 0
if (child->m_sampleLayout.GetRank() == 3 && (child->m_sampleLayout[1] != 1 || child->m_sampleLayout[0] != 1)) // looks like an image: use WHC notation
prototype += msra::strfun::strprintf("%ls[%s%s {W=%lu, H=%lu, C=%lu}]", child->NodeName().c_str(), string(child->m_sampleLayout).c_str(), mbSizeMark,
child->m_sampleLayout[1], child->m_sampleLayout[2], child->m_sampleLayout[0]);
// BUGBUG: This ^^ will print based on the old legacy layout, and we have no way of knowing here whether that is correct.
else
#endif
prototype += msra::strfun::strprintf("[%s%s%ls]", string(child->m_sampleLayout).c_str(), mbSizeMark,
child->HasMBLayout() ? child->GetMBLayout()->GetAxisName().c_str() : L"");
prototype += child->ShapeDescription().c_str();
}
prototype += extraArgs;
//prototype += ")";
}
prototype += msra::strfun::strprintf(" -> [%s%s%ls]", string(GetSampleLayout()).c_str(), HasMBLayout() ? " x " : "",
HasMBLayout() ? GetMBLayout()->GetAxisName().c_str() : L"");
prototype += msra::strfun::strprintf(" -> %s", ShapeDescription().c_str());
return prototype;
}
const std::string ComputationNodeBase::ShapeDescription() const
{
return msra::strfun::strprintf("[%s%s%ls]",
string(m_sampleLayout).c_str(),
HasMBLayout() ? " x " : "",
HasMBLayout() ? GetMBLayout()->GetAxisName().c_str() : L"");
}
template <class ElemType>
/*virtual*/ void ComputationNode<ElemType>::DumpNodeInfo(const bool /*printValues*/, const bool printMetadata, File& fstream) const
{

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

@ -473,12 +473,6 @@ public:
VerifyDims(node->GetSampleLayout(), node->HasMBLayout());
}
virtual void AttachDynamicAxis(std::function<ComputationNodeBasePtr(const std::wstring)> nodeLookup, MBLayoutPtr defaultLayout)
{
// Applies only to input nodes.
NOT_IMPLEMENTED;
}
// MBLayout (minibatch structure)
void LinkToMBLayout(MBLayoutPtr pMBLayout)
{
@ -551,7 +545,7 @@ public:
return GetInputsFromConfig(configp, L"inputs");
}
static vector<ComputationNodeBasePtr> GetInputsFromConfig(const ScriptableObjects::IConfigRecordPtr configp, const std::wstring property)
static vector<ComputationNodeBasePtr> GetInputsFromConfig(const ScriptableObjects::IConfigRecordPtr configp, const std::wstring& property)
{
vector<ComputationNodeBasePtr> inputs;
const auto* inputsArg = configp->Find(property);
@ -810,6 +804,9 @@ public:
return std::wstring(L"Node '") + NodeName().c_str() + L"' (" + OperationName().c_str() + L" operation)";
};
// Helper that returns [a x b x c], including dynamic axes.
const std::string ShapeDescription() const;
protected:
// -----------------------------------------------------------------------
@ -844,7 +841,8 @@ protected:
typedef ComputationNodeBase::ComputationNodeBasePtr ComputationNodeBasePtr;
// =======================================================================
// NumInputs -- little helper interface to allow derived Node classes to specify how many inputs they expect
// NumInputs -- little helper interface to allow derived Node classes to
// specify how many inputs they expect
// =======================================================================
struct INumInputs { virtual size_t GetExpectedNumInputs() const = 0; };
@ -857,6 +855,14 @@ struct NumInputs : public INumInputs // e.g. derive from NumInputs<2>
}
};
// =======================================================================
//
// =======================================================================
struct IDynamic
{
virtual void AttachDynamicAxis(std::function<ComputationNodeBasePtr(const std::wstring)> nodeLookup, MBLayoutPtr defaultLayout) = 0;
};
// =======================================================================
// ComputationNode -- abstract base class for computation nodes, deriving
// from CompuationNodeBase, parameterized by float vs. double
@ -1921,7 +1927,6 @@ protected:
public: \
using Base::AttachInputs; \
using Base::AttachInputsFromConfig; \
using Base::AttachDynamicAxis; \
using Base::CreateGradientMatrixIfNull; \
using Base::NodeName; \
using Base::RequiresPreCompute; \

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

@ -129,7 +129,7 @@ public:
m_displayName = name;
}
DynamicAxisNode(const ScriptableObjects::IConfigRecordPtr configp)
: DynamicAxisNode(configp->Get(L"deviceId"), (const std::wstring&)configp->Get(L"name"))
: DynamicAxisNode(configp->Get(L"deviceId"), (const std::wstring&)configp->Get(L"axisName"))
{
}
@ -168,7 +168,7 @@ template class DynamicAxisNode<double>;
// -----------------------------------------------------------------------
template <class ElemType>
class InputValueBase : public ComputationNode<ElemType>, public NumInputs<0>
class InputValueBase : public ComputationNode<ElemType>, public NumInputs<0>, public IDynamic
{
typedef ComputationNode<ElemType> Base;
UsingComputationNodeMembers;
@ -205,11 +205,11 @@ protected:
{
AttachInputsFromConfig(configp, this->GetExpectedNumInputs());
wstring axisName = L"";
if (configp->Exists(L"dynamicAxes"))
if (configp->Exists(L"dynamicAxis"))
{
if (configp->Find(L"dynamicAxes")->Is<ComputationNodeBase>())
if (configp->Find(L"dynamicAxis")->Is<ComputationNodeBase>())
{
ComputationNodeBasePtr axis = configp->Get(L"dynamicAxes");
ComputationNodeBasePtr axis = configp->Get(L"dynamicAxis");
axisName = axis->GetName();
}
// Else: Use default axis.
@ -245,7 +245,7 @@ protected:
// more dependencies on the order in which things are evaluated, though.
if (!node->Is<DynamicAxisNode<ElemType>>())
RuntimeError("%ls: dynamicAxis argument must be of type DynamicAxis(), but got %ls.",
NodeDescription().c_str(), node->NodeDescription().c_str());
NodeDescription().c_str(), node->NodeDescription().c_str());
m_dynamicAxisNode = node->As<DynamicAxisNode<ElemType>>();
if (!m_dynamicAxisNode->HasMBLayout())
LogicError("%ls: Expected %ls to have MBLayout, but it doesn't.", NodeDescription().c_str(), node->NodeDescription().c_str());

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

@ -122,7 +122,6 @@
<ClCompile Include="..\..\..\Source\CNTK\BrainScript\BrainScriptEvaluator.cpp" />
<ClCompile Include="..\..\..\Source\CNTK\BrainScript\BrainScriptParser.cpp" />
<ClCompile Include="..\..\..\Source\CNTK\BrainScript\BrainScriptTest.cpp" />
<ClCompile Include="..\..\..\Source\CNTK\BrainScript\ExperimentalNetworkBuilder.cpp" />
<ClCompile Include="..\..\..\Source\Common\Config.cpp" />
<ClCompile Include="..\..\..\Source\Common\DataReader.cpp" />
<ClCompile Include="..\..\..\Source\Common\DataWriter.cpp" />

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

@ -34,9 +34,6 @@
<ClCompile Include="..\..\..\Source\CNTK\BrainScript\BrainScriptTest.cpp">
<Filter>From BrainScript</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\CNTK\BrainScript\ExperimentalNetworkBuilder.cpp">
<Filter>From BrainScript</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="Config">