swh:1:snp:f50ab94432af916b5fb8b4ad831e8dddded77084
Tip revision: ea5a77ebd44c2efef7abe96aabd46024fb52e140 authored by Eldar Akchurin on 08 June 2017, 13:39:36 UTC
Exposing user deserializer in Python
Exposing user deserializer in Python
Tip revision: ea5a77e
chunkevalsource.h
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
//
#pragma once
//#include <objbase.h>
#include "basetypes.h" // for attempt()
#include "htkfeatio.h" // for reading HTK features
#include "minibatchsourcehelpers.h"
#ifndef __unix__
#include "ssematrix.h"
#endif
#ifdef LEAKDETECT
#include <vld.h> // for memory leak detection
#endif
namespace msra { namespace dbn {
class chunkevalsource // : public numamodelmanager
{
const size_t chunksize; // actual block size to perform computation on
// data FIFO
msra::dbn::matrix feat;
std::vector<std::vector<float>> frames; // [t] all feature frames concatenated into a big block
std::vector<char> boundaryflags; // [t] -1 for first and +1 last frame, 0 else (for augmentneighbors())
std::vector<size_t> numframes; // [k] number of frames for all appended files
std::vector<std::wstring> outpaths; // [k] and their pathnames
std::vector<unsigned int> sampperiods; // [k] and sample periods (they should really all be the same...)
size_t vdim; // input dimension
size_t udim; // output dimension
bool minibatchready;
void operator=(const chunkevalsource &);
private:
void clear() // empty the FIFO
{
frames.clear();
boundaryflags.clear();
numframes.clear();
outpaths.clear();
sampperiods.clear();
minibatchready = false;
}
void saveandflush(msra::dbn::matrix &pred)
{
const size_t framesinblock = frames.size();
// write out all files
size_t firstframe = 0;
foreach_index (k, numframes)
{
const std::wstring &outfile = outpaths[k];
unsigned int sampperiod = sampperiods[k];
size_t n = numframes[k];
msra::files::make_intermediate_dirs(outfile);
fprintf(stderr, "saveandflush: writing %zu frames to %S\n", n, outfile.c_str());
msra::dbn::matrixstripe thispred(pred, firstframe, n);
// some sanity check for the data we've written
const size_t nansinf = thispred.countnaninf();
if (nansinf > 0)
fprintf(stderr, "chunkeval: %d NaNs or INF detected in '%S' (%d frames)\n", (int) nansinf, outfile.c_str(), (int) thispred.cols());
// save it
msra::util::attempt(5, [&]()
{
msra::asr::htkfeatwriter::write(outfile, "USER", sampperiod, thispred);
});
firstframe += n;
}
assert(firstframe == framesinblock);
framesinblock;
// and we are done --forget the FIFO content & get ready for next chunk
clear();
}
public:
chunkevalsource(size_t numinput, size_t numoutput, size_t chunksize)
: vdim(numinput), udim(numoutput), chunksize(chunksize)
{
frames.reserve(chunksize * 2);
feat.resize(vdim, chunksize); // initialize to size chunksize
}
// append data to chunk
template <class MATRIX>
void addfile(const MATRIX &feat, const string &featkind, unsigned int sampperiod, const std::wstring &outpath)
{
// append to frames; also expand neighbor frames
if (feat.cols() < 2)
throw std::runtime_error("evaltofile: utterances < 2 frames not supported");
foreach_column (t, feat)
{
std::vector<float> v(&feat(0, t), &feat(0, t) + feat.rows());
frames.push_back(v);
boundaryflags.push_back((t == 0) ? -1 : (t == feat.cols() - 1) ? +1 : 0);
}
numframes.push_back(feat.cols());
outpaths.push_back(outpath);
sampperiods.push_back(sampperiod);
}
void createevalminibatch()
{
const size_t framesinblock = frames.size();
feat.resize(vdim, framesinblock); // input features for whole utt (col vectors)
// augment the features
msra::dbn::augmentneighbors(frames, boundaryflags, 0, framesinblock, feat);
minibatchready = true;
}
void writetofiles(msra::dbn::matrix &pred)
{
saveandflush(pred);
}
msra::dbn::matrix chunkofframes()
{
assert(minibatchready);
return feat;
}
bool isminibatchready()
{
return minibatchready;
}
size_t currentchunksize()
{
return frames.size();
}
void flushinput()
{
createevalminibatch();
}
void reset()
{
clear();
}
};
class chunkevalsourcemulti // : public numamodelmanager
{
const size_t chunksize; // actual block size to perform computation on
// data FIFO
std::vector<msra::dbn::matrix> feat;
std::vector<std::vector<std::vector<float>>> framesmulti; // [t] all feature frames concatenated into a big block
std::vector<char> boundaryflags; // [t] -1 for first and +1 last frame, 0 else (for augmentneighbors())
std::vector<size_t> numframes; // [k] number of frames for all appended files
std::vector<std::vector<std::wstring>> outpaths; // [k] and their pathnames
std::vector<std::vector<unsigned int>> sampperiods; // [k] and sample periods (they should really all be the same...)
std::vector<size_t> vdims; // input dimension
std::vector<size_t> udims; // output dimension
bool minibatchready;
void operator=(const chunkevalsourcemulti &);
private:
void clear() // empty the FIFO
{
foreach_index (i, vdims)
{
framesmulti[i].clear();
outpaths[i].clear();
sampperiods[i].clear();
}
boundaryflags.clear();
numframes.clear();
minibatchready = false;
}
void saveandflush(msra::dbn::matrix &pred, size_t index)
{
const size_t framesinblock = framesmulti[index].size();
// write out all files
size_t firstframe = 0;
foreach_index (k, numframes)
{
const std::wstring &outfile = outpaths[index][k];
unsigned int sampperiod = sampperiods[index][k];
size_t n = numframes[k];
msra::files::make_intermediate_dirs(outfile);
fprintf(stderr, "saveandflush: writing %zu frames to %S\n", n, outfile.c_str());
msra::dbn::matrixstripe thispred(pred, firstframe, n);
// some sanity check for the data we've written
const size_t nansinf = thispred.countnaninf();
if (nansinf > 0)
fprintf(stderr, "chunkeval: %d NaNs or INF detected in '%S' (%d frames)\n", (int) nansinf, outfile.c_str(), (int) thispred.cols());
// save it
msra::util::attempt(5, [&]()
{
msra::asr::htkfeatwriter::write(outfile, "USER", sampperiod, thispred);
});
firstframe += n;
}
assert(firstframe == framesinblock);
framesinblock;
// and we are done --forget the FIFO content & get ready for next chunk
}
public:
chunkevalsourcemulti(std::vector<size_t> vdims, std::vector<size_t> udims, size_t chunksize)
: vdims(vdims), udims(udims), chunksize(chunksize)
{
foreach_index (i, vdims)
{
msra::dbn::matrix thisfeat;
std::vector<std::vector<float>> frames; // [t] all feature frames concatenated into a big block
frames.reserve(chunksize * 2);
framesmulti.push_back(frames);
// framesmulti[i].reserve (chunksize * 2);
thisfeat.resize(vdims[i], chunksize);
feat.push_back(thisfeat);
outpaths.push_back(std::vector<std::wstring>());
sampperiods.push_back(std::vector<unsigned int>());
// feat[i].resize(vdims[i],chunksize); // initialize to size chunksize
}
}
// append data to chunk
template <class MATRIX>
void addfile(const MATRIX &feat, const string &featkind, unsigned int sampperiod, const std::wstring &outpath, size_t index)
{
// append to frames; also expand neighbor frames
if (feat.cols() < 2)
throw std::runtime_error("evaltofile: utterances < 2 frames not supported");
foreach_column (t, feat)
{
std::vector<float> v(&feat(0, t), &feat(0, t) + feat.rows());
framesmulti[index].push_back(v);
if (index == 0)
boundaryflags.push_back((t == 0) ? -1 : (t == feat.cols() - 1) ? +1 : 0);
}
if (index == 0)
numframes.push_back(feat.cols());
outpaths[index].push_back(outpath);
sampperiods[index].push_back(sampperiod);
}
void createevalminibatch()
{
foreach_index (i, framesmulti)
{
const size_t framesinblock = framesmulti[i].size();
feat[i].resize(vdims[i], framesinblock); // input features for whole utt (col vectors)
// augment the features
msra::dbn::augmentneighbors(framesmulti[i], boundaryflags, 0, framesinblock, feat[i]);
}
minibatchready = true;
}
void writetofiles(msra::dbn::matrix &pred, size_t index)
{
saveandflush(pred, index);
}
msra::dbn::matrix chunkofframes(size_t index)
{
assert(minibatchready);
assert(index <= feat.size());
return feat[index];
}
bool isminibatchready()
{
return minibatchready;
}
size_t currentchunksize()
{
return framesmulti[0].size();
}
void flushinput()
{
createevalminibatch();
}
void reset()
{
clear();
}
};
class FileEvalSource // : public numamodelmanager
{
const size_t chunksize; // actual block size to perform computation on
// data FIFO
std::vector<msra::dbn::matrix> feat;
std::vector<std::vector<std::vector<float>>> framesMulti; // [t] all feature frames concatenated into a big block
std::vector<char> boundaryFlags; // [t] -1 for first and +1 last frame, 0 else (for augmentneighbors())
std::vector<size_t> numFrames; // [k] number of frames for all appended files
std::vector<std::vector<unsigned int>> sampPeriods; // [k] and sample periods (they should really all be the same...)
std::vector<size_t> vdims; // input dimension
std::vector<size_t> leftcontext;
std::vector<size_t> rightcontext;
bool minibatchReady;
size_t minibatchSize;
size_t frameIndex;
void operator=(const FileEvalSource &);
private:
void Clear() // empty the FIFO
{
foreach_index (i, vdims)
{
framesMulti[i].clear();
sampPeriods[i].clear();
}
boundaryFlags.clear();
numFrames.clear();
minibatchReady = false;
frameIndex = 0;
}
public:
FileEvalSource(std::vector<size_t> vdims, std::vector<size_t> leftcontext, std::vector<size_t> rightcontext, size_t chunksize)
: vdims(vdims), leftcontext(leftcontext), rightcontext(rightcontext), chunksize(chunksize)
{
foreach_index (i, vdims)
{
msra::dbn::matrix thisfeat;
std::vector<std::vector<float>> frames; // [t] all feature frames concatenated into a big block
frames.reserve(chunksize * 2);
framesMulti.push_back(frames);
// framesmulti[i].reserve (chunksize * 2);
thisfeat.resize(vdims[i], chunksize);
feat.push_back(thisfeat);
sampPeriods.push_back(std::vector<unsigned int>());
// feat[i].resize(vdims[i],chunksize); // initialize to size chunksize
}
}
// append data to chunk
template <class MATRIX>
void AddFile(const MATRIX &feat, const string & /*featkind*/, unsigned int sampPeriod, size_t index)
{
// append to frames; also expand neighbor frames
if (feat.cols() < 2)
throw std::runtime_error("evaltofile: utterances < 2 frames not supported");
foreach_column (t, feat)
{
std::vector<float> v(&feat(0, t), &feat(0, t) + feat.rows());
framesMulti[index].push_back(v);
if (index == 0)
boundaryFlags.push_back((t == 0) ? -1 : (t == feat.cols() - 1) ? +1 : 0);
}
if (index == 0)
numFrames.push_back(feat.cols());
sampPeriods[index].push_back(sampPeriod);
}
void CreateEvalMinibatch()
{
foreach_index (i, framesMulti)
{
const size_t framesInBlock = framesMulti[i].size();
feat[i].resize(vdims[i], framesInBlock); // input features for whole utt (col vectors)
// augment the features
size_t leftextent, rightextent;
// page in the needed range of frames
if (leftcontext[i] == 0 && rightcontext[i] == 0)
{
leftextent = rightextent = augmentationextent(framesMulti[i][0].size(), vdims[i]);
}
else
{
leftextent = leftcontext[i];
rightextent = rightcontext[i];
}
// msra::dbn::augmentneighbors(framesMulti[i], boundaryFlags, 0, leftcontext[i], rightcontext[i],)
msra::dbn::augmentneighbors(framesMulti[i], boundaryFlags, leftextent, rightextent, 0, framesInBlock, feat[i]);
}
minibatchReady = true;
}
void SetMinibatchSize(size_t mbSize)
{
minibatchSize = mbSize;
}
msra::dbn::matrix ChunkOfFrames(size_t index)
{
assert(minibatchReady);
assert(index <= feat.size());
return feat[index];
}
bool IsMinibatchReady()
{
return minibatchReady;
}
size_t CurrentFileSize()
{
return framesMulti[0].size();
}
void FlushInput()
{
CreateEvalMinibatch();
}
void Reset()
{
Clear();
}
};
};
};