Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/guoguo/linuxBuildFix' into yu/me…
Browse files Browse the repository at this point in the history
…mshare
  • Loading branch information
yzhang87 committed Oct 8, 2015
2 parents 2796743 + aa80293 commit acca557
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 230 deletions.
14 changes: 8 additions & 6 deletions Common/Include/DataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,10 @@ class DATAREADER_API IDataReader

void SetDoRandomize(bool b){ mDoRandomize = b; }

// Gets a copy of the minibatch for the forward computation. This can be
// useful if some of the computation has to happen in the reader.
// TODO: No, there should be no computation in the reader.
// Workaround for the two-forward-pass sequence and ctc training, which
// allows processing more utterances at the same time. Only used in
// Kaldi2Reader.
// TODO: move this out of the reader.
virtual bool GetMinibatchCopy(
std::vector<std::vector<std::pair<wstring, size_t>>>& /*uttInfo*/,
std::map<std::wstring, Matrix<ElemType>*>& /*matrices*/,
Expand All @@ -111,9 +112,10 @@ class DATAREADER_API IDataReader
return false;
}

// Sets the neural network output to the reader. This can be useful if some
// of the computation has to happen in the reader.
// TODO: No, there should be no computation in the reader.
// Workaround for the two-forward-pass sequence and ctc training, which
// allows processing more utterances at the same time. Only used in
// Kaldi2Reader.
// TODO: move this out of the reader.
virtual bool SetNetOutput(
const std::vector<std::vector<std::pair<wstring, size_t>>>& /*uttInfo*/,
const Matrix<ElemType>& /*outputs*/,
Expand Down
95 changes: 27 additions & 68 deletions DataReader/Kaldi2Reader/HTKMLFReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1105,16 +1105,14 @@ namespace Microsoft { namespace MSR { namespace CNTK {

// We initialize the sentence boundary information before we process
// the utterances.
m_sentenceBegin.Resize(m_numberOfuttsPerMinibatch, m_currentMBSize);
m_minibatchPackingFlags.resize(m_currentMBSize);
m_pMBLayout->Init(m_numberOfuttsPerMinibatch, m_currentMBSize, !m_framemode);
for (size_t i = 0; i < m_numberOfuttsPerMinibatch; i++)
{
for (size_t j = 0; j < m_currentMBSize; j++)
{
m_sentenceBegin.SetValue(i, j, (ElemType) SEQUENCE_MIDDLE);
m_pMBLayout->SetWithoutOr(i, j, MinibatchPackingFlags::None);
}
}
std::fill(m_minibatchPackingFlags.begin(), m_minibatchPackingFlags.end(), MinibatchPackingFlags::None);

// Iterates over utterances. m_numberOfuttsPerMinibatch = 1 is a
// special case.
Expand All @@ -1133,8 +1131,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
// Sets the utterance boundary.
if (startFrame == 0)
{
m_sentenceBegin.SetValue(i, 0, (ElemType)SEQUENCE_START);
m_minibatchPackingFlags[0] |= MinibatchPackingFlags::SequenceStart;
m_pMBLayout->Set(i, 0, MinibatchPackingFlags::SequenceStart);
}

endFrame = startFrame + m_currentMBSize;
Expand All @@ -1161,13 +1158,11 @@ namespace Microsoft { namespace MSR { namespace CNTK {
{
if (startFrame == 0)
{
m_sentenceBegin.SetValue(i, 0, (ElemType)SEQUENCE_START);
m_minibatchPackingFlags[0] |= MinibatchPackingFlags::SequenceStart;
m_pMBLayout->Set(i, 0, MinibatchPackingFlags::SequenceStart);
}

// We have to set the utterance end.
m_sentenceBegin.SetValue(i, m_sentenceBegin.GetNumCols() - 1, (ElemType)SEQUENCE_END);
m_minibatchPackingFlags[m_sentenceBegin.GetNumCols() - 1] |= MinibatchPackingFlags::SequenceEnd;
m_pMBLayout->Set(i, m_pMBLayout->GetNumTimeSteps() - 1, MinibatchPackingFlags::SequenceEnd);
}

// Now puts the utterance into the minibatch, and loads the
Expand Down Expand Up @@ -1198,8 +1193,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
{
for (size_t k = 0; k < m_currentMBSize; k++)
{
m_sentenceBegin.SetValue(i, k, (ElemType) NO_INPUT);
m_minibatchPackingFlags[k] |= MinibatchPackingFlags::NoInput;
m_pMBLayout->Set(i, k, MinibatchPackingFlags::NoInput);

// Populates <NO_INPUT> with real features, the
// following implementation is not efficient...
Expand All @@ -1224,14 +1218,12 @@ namespace Microsoft { namespace MSR { namespace CNTK {
{
if (startFrame == 0)
{
m_sentenceBegin.SetValue(i, 0, (ElemType)SEQUENCE_START);
m_minibatchPackingFlags[0] |= MinibatchPackingFlags::SequenceStart;
m_pMBLayout->Set(i, 0, MinibatchPackingFlags::SequenceStart);
}

// We have to set the utterance end.
assert(m_toProcess[i] - startFrame - 1 < m_sentenceBegin.GetNumCols());
m_sentenceBegin.SetValue(i, m_toProcess[i] - startFrame - 1, (ElemType)SEQUENCE_END);
m_minibatchPackingFlags[m_toProcess[i] - startFrame - 1] |= MinibatchPackingFlags::SequenceEnd;
assert(m_toProcess[i] - startFrame - 1 < m_pMBLayout->GetNumTimeSteps());
m_pMBLayout->Set(i, m_toProcess[i] - startFrame - 1, MinibatchPackingFlags::SequenceEnd);
}
endFrame = m_toProcess[i];
size_t currentMBFilled = endFrame - startFrame;
Expand All @@ -1249,11 +1241,9 @@ namespace Microsoft { namespace MSR { namespace CNTK {
while (reNewSucc && (currentMBFilled + m_toProcess[i] <= m_currentMBSize))
{
// Sets the utterance boundary.
assert(currentMBFilled + m_toProcess[i] <= m_sentenceBegin.GetNumCols());
m_sentenceBegin.SetValue(i, currentMBFilled, (ElemType)SEQUENCE_START);
m_minibatchPackingFlags[currentMBFilled] |= MinibatchPackingFlags::SequenceStart;
m_sentenceBegin.SetValue(i, currentMBFilled + m_toProcess[i] - 1, (ElemType)SEQUENCE_END);
m_minibatchPackingFlags[currentMBFilled + m_toProcess[i] - 1] |= MinibatchPackingFlags::SequenceEnd;
assert(currentMBFilled + m_toProcess[i] <= m_pMBLayout->GetNumTimeSteps());
m_pMBLayout->Set(i, currentMBFilled, MinibatchPackingFlags::SequenceStart);
m_pMBLayout->Set(i, currentMBFilled + m_toProcess[i] - 1, MinibatchPackingFlags::SequenceEnd);
populateSucc = PopulateUtteranceInMinibatch(matrices, i, 0, m_toProcess[i], m_currentMBSize, currentMBFilled);
if (m_doMinibatchBuffering && populateSucc)
{
Expand All @@ -1279,16 +1269,14 @@ namespace Microsoft { namespace MSR { namespace CNTK {
m_processedFrame[i] += m_currentMBSize - currentMBFilled;
if (currentMBFilled < m_currentMBSize)
{
m_sentenceBegin.SetValue(i, currentMBFilled, (ElemType)SEQUENCE_START);
m_minibatchPackingFlags[currentMBFilled] |= MinibatchPackingFlags::SequenceStart;
m_pMBLayout->Set(i, currentMBFilled, MinibatchPackingFlags::SequenceStart);
}
}
else
{
for (size_t k = currentMBFilled; k < m_currentMBSize; k++)
{
m_sentenceBegin.SetValue(i, k, (ElemType) NO_INPUT);
m_minibatchPackingFlags[k] |= MinibatchPackingFlags::NoInput;
m_pMBLayout->Set(i, k, MinibatchPackingFlags::NoInput);

// Populates <NO_INPUT> with real features, the
// following implementation is not efficient...
Expand Down Expand Up @@ -1353,15 +1341,8 @@ namespace Microsoft { namespace MSR { namespace CNTK {
(startIndex + currentMBSize <= originalMBSize) ?
currentMBSize : (originalMBSize - startIndex);

// Sets sentence boundary for the current minibatch.
currentMinibatch.sentenceBegin.SetValue(
m_sentenceBegin.ColumnSlice(startIndex, numFrames));

// Sets packing flag for the current minibatch.
currentMinibatch.minibatchPackingFlag.resize(numFrames);
currentMinibatch.minibatchPackingFlag.assign(
m_minibatchPackingFlags.begin() + startIndex,
m_minibatchPackingFlags.begin() + startIndex + numFrames);
// Sets MBLayout.
currentMinibatch.pMBLayout->CopyFromRange(m_pMBLayout, startIndex, numFrames);

// Sets the minibatch size for the current minibatch.
currentMinibatch.currentMBSize = numFrames;
Expand Down Expand Up @@ -1424,8 +1405,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
assert(m_minibatchBuffer.size() > index);

// Restores the variables related to the minibatch.
m_sentenceBegin.SetValue(m_minibatchBuffer[index].sentenceBegin);
m_minibatchPackingFlags = m_minibatchBuffer[index].minibatchPackingFlag;
m_pMBLayout->CopyFrom(m_minibatchBuffer[index].pMBLayout);
m_currentMBSize = m_minibatchBuffer[index].currentMBSize;
m_minibatchUttInfo = m_minibatchBuffer[index].minibatchUttInfo;

Expand Down Expand Up @@ -1470,9 +1450,9 @@ namespace Microsoft { namespace MSR { namespace CNTK {
}
else
{
m_uttDerivBuffer->GetDerivative(
m_minibatchUttInfo, m_sentenceBegin,
m_minibatchPackingFlags, matrices[iter->first]);
m_uttDerivBuffer->GetDerivative(m_minibatchUttInfo,
m_pMBLayout,
matrices[iter->first]);
}
}
else if (m_nameToTypeMap[iter->first] == InputOutputTypes::readerObj)
Expand Down Expand Up @@ -1661,15 +1641,9 @@ namespace Microsoft { namespace MSR { namespace CNTK {
const msra::dbn::matrix feat = m_fileEvalSource->ChunkOfFrames(id);
if (first)
{
m_sentenceBegin.Resize((size_t)1, (size_t)feat.cols());
m_minibatchPackingFlags.resize(feat.cols());
m_sentenceBegin.SetValue((ElemType) SEQUENCE_MIDDLE);
m_sentenceBegin.SetValue(0, 0, (ElemType) SEQUENCE_START);
m_sentenceBegin.SetValue(0, (size_t)feat.cols()-1, (ElemType) SEQUENCE_END);

std::fill(m_minibatchPackingFlags.begin(), m_minibatchPackingFlags.end(), MinibatchPackingFlags::None);
m_minibatchPackingFlags[0] = MinibatchPackingFlags::SequenceStart;
m_minibatchPackingFlags[(size_t)feat.cols()-1] = MinibatchPackingFlags::SequenceEnd;
m_pMBLayout->Init(1, feat.cols(), true);
m_pMBLayout->Set(0, 0, MinibatchPackingFlags::SequenceStart);
m_pMBLayout->SetWithoutOr(0, feat.cols() - 1, MinibatchPackingFlags::SequenceEnd);
first = false;
}

Expand Down Expand Up @@ -1944,8 +1918,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
bool HTKMLFReader<ElemType>::GetMinibatchCopy(
std::vector<std::vector<std::pair<wstring, size_t>>>& uttInfo,
std::map<std::wstring, Matrix<ElemType>*>& matrices,
Matrix<ElemType>& sentenceBegin,
std::vector<MinibatchPackingFlags>& minibatchPackingFlag)
MBLayoutPtr pMBLayout)
{
// We need to get a "copy" of the minibatch to do the forward
// computation for sequence training.
Expand All @@ -1957,8 +1930,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
m_getMinibatchCopy = true;
if (GetMinibatchToTrainOrTest(matrices))
{
sentenceBegin.SetValue(m_sentenceBegin);
minibatchPackingFlag = m_minibatchPackingFlags;
pMBLayout->CopyFrom(m_pMBLayout);
uttInfo = m_minibatchUttInfo;
m_getMinibatchCopy = false;
return true;
Expand All @@ -1974,8 +1946,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
bool HTKMLFReader<ElemType>::SetNetOutput(
const std::vector<std::vector<std::pair<wstring, size_t>>>& uttInfo,
const Matrix<ElemType>& outputs,
const Matrix<ElemType>& sentenceBegin,
const std::vector<MinibatchPackingFlags>& minibatchPackingFlag)
const MBLayoutPtr pMBLayout)
{
// Set the likelihoods for the utterance with which we can comput the
// derivatives. Note that the minibatch may only contain partial output
Expand All @@ -1984,9 +1955,7 @@ namespace Microsoft { namespace MSR { namespace CNTK {
if (m_doMinibatchBuffering)
{
assert(m_framemode == false);
return m_uttDerivBuffer->SetLikelihood(uttInfo, outputs,
sentenceBegin,
minibatchPackingFlag);
return m_uttDerivBuffer->SetLikelihood(uttInfo, outputs, pMBLayout);
}
return false;
}
Expand Down Expand Up @@ -2114,16 +2083,6 @@ namespace Microsoft { namespace MSR { namespace CNTK {
}
}

template<class ElemType>
void HTKMLFReader<ElemType>::SetSentenceSegBatch(Matrix<ElemType> &sentenceBegin, vector<MinibatchPackingFlags>& minibatchPackingFlag)
{
if (!m_framemode)
{
sentenceBegin.SetValue(m_sentenceBegin);
minibatchPackingFlag = m_minibatchPackingFlags;
}
}

// For Kaldi2Reader, we now make the following assumptions
// 1. feature sections will always have a sub-field "scpFile"
// 2. label sections will always have a sub-field "mlfFile"
Expand Down
38 changes: 8 additions & 30 deletions DataReader/Kaldi2Reader/HTKMLFReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ class HTKMLFReader : public IDataReader<ElemType>
{
std::vector<std::vector<ElemType>> features;
std::vector<std::vector<ElemType>> labels;
Matrix<ElemType> sentenceBegin;
vector<MinibatchPackingFlags> minibatchPackingFlag;
MBLayoutPtr pMBLayout;
std::vector<std::vector<std::pair<wstring, size_t>>> minibatchUttInfo;
size_t currentMBSize;
MinibatchBufferUnit() : pMBLayout(make_shared<MBLayout>()), currentMBSize(0) {}
};
bool m_doMinibatchBuffering;
bool m_getMinibatchCopy;
Expand Down Expand Up @@ -151,35 +151,14 @@ class HTKMLFReader : public IDataReader<ElemType>


public:
MBLayoutPtr m_pMBLayout;

/// a matrix of n_stream x n_length
/// n_stream is the number of streams
/// n_length is the maximum lenght of each stream
/// for example, two sentences used in parallel in one minibatch would be
/// [2 x 5] if the max length of one of the sentences is 5
/// the elements of the matrix is 0, 1, or -1, defined as SEQUENCE_START, SEQUENCE_MIDDLE, NO_INPUT in cbasetype.h
/// 0 1 1 0 1
/// 1 0 1 0 0
/// for two parallel data streams. The first has two sentences, with 0 indicating begining of a sentence
/// the second data stream has two sentences, with 0 indicating begining of sentences
/// you may use 1 even if a sentence begins at that position, in this case, the trainer will carry over hidden states to the following
/// frame.
Matrix<ElemType> m_sentenceBegin;

/// a matrix of 1 x n_length
/// 1 denotes the case that there exists sentnece begin or no_labels case in this frame
/// 0 denotes such case is not in this frame


vector<MinibatchPackingFlags> m_minibatchPackingFlags;

/// by default it is false
/// if true, reader will set to SEQUENCE_MIDDLE for time positions that are orignally correspond to SEQUENCE_START
/// set to true so that a current minibatch can uses state activities from the previous minibatch.
/// default will have truncated BPTT, which only does BPTT inside a minibatch

bool mIgnoreSentenceBeginTag;
HTKMLFReader() : m_sentenceBegin(CPUDEVICE) {
HTKMLFReader() : m_pMBLayout(make_shared<MBLayout>()){
}

virtual void Init(const ConfigParameters& config);
Expand All @@ -195,19 +174,18 @@ class HTKMLFReader : public IDataReader<ElemType>
virtual bool GetMinibatchCopy(
std::vector<std::vector<std::pair<wstring, size_t>>>& uttInfo,
std::map<std::wstring, Matrix<ElemType>*>& matrices,
Matrix<ElemType>& sentenceBegin,
vector<MinibatchPackingFlags>& sentenceExistsBeginOrNoLabels);
MBLayoutPtr pMBLayout);
virtual bool SetNetOutput(
const std::vector<std::vector<std::pair<wstring, size_t>>>& uttInfo,
const Matrix<ElemType>& outputs,
const Matrix<ElemType>& sentenceBegin,
const vector<MinibatchPackingFlags>& sentenceExistsBeginOrNoLabels);
const MBLayoutPtr pMBLayout);

virtual bool DataEnd(EndDataType endDataType);
void SetSentenceEndInBatch(vector<size_t> &/*sentenceEnd*/);
void SetSentenceEnd(int /*actualMbSize*/){};

void SetSentenceSegBatch(Matrix<ElemType> &sentenceBegin, vector<MinibatchPackingFlags>& sentenceExistsBeginOrNoLabels);
void CopyMBLayoutTo(MBLayoutPtr pMBLayout) { pMBLayout->CopyFrom(m_pMBLayout); }
bool RequireSentenceSeg() const override { return !m_framemode; };
};

}}}
Loading

0 comments on commit acca557

Please sign in to comment.