new optional NDL/BS parameter 'imageLayout' to say according to which of the two layouts (cudnn or CNTL legacy) we should interpret a W, H, C specification. Currently implemented for InputImage;

InputValue no longer accepts a 'cols' parameter. Instead, it ignores it and uses 0 instead, since InputValues must always be minibatches
This commit is contained in:
Frank Seide 2015-12-30 11:35:40 -08:00
Родитель d0b5c8d3c4
Коммит c6d908eff8
6 изменённых файлов: 21 добавлений и 15 удалений

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

@ -40,8 +40,8 @@ using namespace std;
// ^^ already works; vv untested
L"Input(rows, cols, tag='feature') = new ComputationNode [ operation = 'InputValue' ; isImage = false /*plus the function args*/ ]\n" // note: naming a little inconsistent // TODO: re-test after flag change
L"SparseInput(rows, cols, tag='feature') = new ComputationNode [ operation = 'SparseInputValue' ; isImage = false /*plus the function args*/ ]\n"
L"ImageInput(imageWidth, imageHeight, imageChannels, numImages, tag='feature') = new ComputationNode [ operation = 'InputValue' ; isImage = true /*plus the function args*/ ]\n"
L"SparseImageInput(imageWidth, imageHeight, imageChannels, numImages, tag='feature') = new ComputationNode [ operation = 'SparseInputValue' ; isImage = true /*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, needGradient = false, init = 'fixedValue', value = val) \n"
L"PastValue(rows, cols, input, timeStep = 1, defaultHiddenActivation = 0.1, tag='') = new ComputationNode [ operation = 'PastValue' ; inputs = input /*plus the function args*/ ]\n"
L"FutureValue(rows, cols, input, timeStep = 1, defaultHiddenActivation = 0.1, tag='') = new ComputationNode [ operation = 'FutureValue' ; inputs = input /*plus the function args*/ ]\n"

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

@ -108,9 +108,10 @@ namespace Microsoft { namespace MSR { namespace CNTK {
size_t imageWidth = ((NDLNode<ElemType>*)params[0])->GetScalar();
size_t imageHeight = ((NDLNode<ElemType>*)params[1])->GetScalar();
size_t imageChannels = ((NDLNode<ElemType>*)params[2])->GetScalar();
size_t numImages = parameter.size() > 3 ? ((NDLNode<ElemType>*)params[3])->GetScalar() : 1;
size_t numImages = parameter.size() > 3 ? ((NDLNode<ElemType>*)params[3])->GetScalar() : 1; // BUGBUG: This comes through MBLayout, and should be forbidden.
ImageLayoutKind imageLayoutKind = ImageLayoutKindFrom(node->GetOptionalParameter("imageLayout", "HWC"));
nodePtr = builder.CreateInputNode(name, ImageLayoutWHC(imageWidth, imageHeight, imageChannels), numImages);
nodePtr = builder.CreateInputNode(name, ImageLayout(imageWidth, imageHeight, imageChannels, imageLayoutKind), numImages);
}
}
else if (cnNodeType == L"SparseImageInput")
@ -126,8 +127,9 @@ namespace Microsoft { namespace MSR { namespace CNTK {
size_t imageHeight = ((NDLNode<ElemType>*)params[1])->GetScalar();
size_t imageChannels = ((NDLNode<ElemType>*)params[2])->GetScalar();
size_t numImages = parameter.size() > 3 ? ((NDLNode<ElemType>*)params[3])->GetScalar() : 1;
ImageLayoutKind imageLayoutKind = ImageLayoutKindFrom(node->GetOptionalParameter("imageLayout", "HWC"));
nodePtr = builder.CreateSparseInputNode(name, ImageLayoutWHC(imageWidth, imageHeight, imageChannels), numImages);
nodePtr = builder.CreateSparseInputNode(name, ImageLayout(imageWidth, imageHeight, imageChannels, imageLayoutKind), numImages);
}
}
else if (OperationNameOf(LearnableParameter) == cnNodeType)
@ -323,7 +325,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
size_t img_channels = node->GetOptionalParameter("imageChannels", "0");
bool needGradient = node->GetOptionalParameter("needGradient", "false");
nodePtr = builder.Reshape(NULL, num_rows, ImageLayoutWHC(img_width, img_height, img_channels), name);
nodePtr = builder.Reshape(NULL, num_rows, ImageLayoutWHC(img_width, img_height, img_channels), name); // BUGBUG: use a tensor descriptor instead
nodePtr->SetParameterUpdateRequired(needGradient);
}
}

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

@ -452,8 +452,8 @@ namespace Microsoft { namespace MSR { namespace CNTK {
// Eventually this can go away once we switch completely to cudnn layout.
enum ImageLayoutKind
{
CHW, // cudnn
HWC // legacy
CHW, // cudnn; default for BrainScript
HWC // legacy; default for NDL
};
static inline ImageLayoutKind ImageLayoutKindFrom(const wstring & s)
{

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

@ -308,6 +308,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
// - PairNetworkNode
// - LSTMNode
// set our dimensions (rows, cols, sample layout)
// TODO: Separate SetDims() into version with and without MBLayout.
void SetDims(const TensorShape & sampleLayout, size_t cols)
{
m_sampleLayout = sampleLayout;

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

@ -54,6 +54,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
LearnableParameter(const ScriptableObjects::IConfigRecordPtr configp) :
LearnableParameter(configp->Get(L"deviceId"), L"<placeholder>", configp->Get(L"rows"), configp->Get(L"cols"))
{
// TODO: Change dimensions to take a generic tensor instead. That will be a (minor) breaking change that will require fix-ups when converting from NDL to BrainScript.
AttachInputs(configp, this->GetExpectedNumInputs());
// parameters[rows, [cols=1]] plus other optional parameters (needGradient=[true|false], init=[uniform|gaussian|fixedvalue], initValueScale=[1|float], value=[0|float])
// TODO: "needGradient" should be renamed to better match m_parameterUpdateRequired
@ -248,13 +249,14 @@ namespace Microsoft { namespace MSR { namespace CNTK {
InputValueBase(DEVICEID_TYPE deviceId, const wstring & name, size_t rows, size_t cols, bool isSparse) :
Base(deviceId, name)
{
Init(TensorShape(rows), cols, isSparse);
cols;// InputValues must be minibatches
Init(TensorShape(rows), 0, isSparse);
}
InputValueBase(DEVICEID_TYPE deviceId, const wstring & name, const TensorShape & imageLayout, size_t numImages, bool isSparse) :
Base(deviceId, name)
{
size_t cols = numImages;
Init(imageLayout, cols, isSparse);
numImages;//size_t cols = numImages;
Init(imageLayout, 0, isSparse);
}
InputValueBase(const ScriptableObjects::IConfigRecordPtr configp, bool isSparse) :
Base(configp->Get(L"deviceId"), L"<placeholder>")
@ -264,13 +266,12 @@ namespace Microsoft { namespace MSR { namespace CNTK {
if (!isImage)
{
size_t rows = configp->Get(L"rows");
size_t cols = configp->Get(L"cols");
Init(TensorShape(rows), cols, isSparse); // no tensor, just a vector
//size_t cols = configp->Get(L"cols"); // InputValues must be minibatches
Init(TensorShape(rows), 0, isSparse); // no tensor, just a vector
}
else
{
size_t cols = configp->Get(L"numImages"); // This is actually the MB size. --TODO: No need to specify it?
Init(ImageLayoutWHC(configp->Get(L"imageWidth"), configp->Get(L"imageHeight"), configp->Get(L"imageChannels")), cols, isSparse);
Init(ImageLayout(configp->Get(L"imageWidth"), configp->Get(L"imageHeight"), configp->Get(L"imageChannels"), ImageLayoutKindFrom(configp->Get(L"imageLayout"))), 0, isSparse);
}
}
public:

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

@ -172,6 +172,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
ReshapeNode(const ScriptableObjects::IConfigRecordPtr configp) :
ReshapeNode(configp->Get(L"deviceId"), L"<placeholder>", configp->Get(L"numRows"), ImageLayoutWHC(configp->Get(L"imageWidth"), configp->Get(L"imageHeight"), configp->Get(L"imageChannels")))
{
// BUGBUG: We should not operate on image layouts here, but on a proper tensor layout.
AttachInputs(configp, this->GetExpectedNumInputs());
}
@ -381,6 +382,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
// TODO: Say in one sentence what this logic does.
void InferTargetSampleLayout()
{
// BUGBUG: We should not operate on image layouts here, but on a proper tensor layout.
if (m_targetImageLayout.GetWidth() > 0)
{
if (m_targetImageLayout.GetHeight() > 0)