1. 前言
數(shù)據(jù)的讀取很大程度上決定了代碼運行的快慢。
先從python端的data io開始。在MXNet的python文件夾中,io.py定義了io需要的函數(shù),其中_init_to_moduel會在我們import該包的時候運行,它的函數(shù)體如下:
def _init_io_module():
"""List and add all the data iterators to current module."""
plist = ctypes.POINTER(ctypes.c_void_p)()
size = ctypes.c_uint()
check_call(_LIB.MXListDataIters(ctypes.byref(size), ctypes.byref(plist))) # 查看一共注冊了多少個迭代器
module_obj = sys.modules[__name__]
for i in range(size.value):
hdl = ctypes.c_void_p(plist[i])
dataiter = _make_io_iterator(hdl)
setattr(module_obj, dataiter.__name__, dataiter) # 將迭代器注冊到包名下
該函數(shù)會將注冊的迭代器都在io的名字空間下注冊。注冊之前,會使用MXDataIter進行包裝,也就是說當我們在調(diào)用例如ImageRecordIter的方法的時候,其實調(diào)用的是MXDataIter的方法。
在初始化的時候,會調(diào)用Init方法,在調(diào)用next的時候,會調(diào)用對應的Next方法,在調(diào)用reset的時候會調(diào)用BeforeFirst。
2. data.h
定義了迭代器的接口。
-
DataIter:定義了數(shù)據(jù)迭代器的接口-
BeforeFirst開始迭代之前的準備,reset調(diào)用。 -
Next返回下一個數(shù)據(jù) -
Value返回當前數(shù)據(jù)
-
class Row
3. io.h
MXnet中的迭代器
IIterator:DataInst:單個數(shù)據(jù)的結構體表示DataBatch:NDArray的DataBatch表示,由Iterator返回
4. augmenter
MXNet中定義了數(shù)據(jù)增強的迭代器,在源碼中主要定義了兩個增強的方法,一個是image_aug_default.cc,一個image_det_aug_default。
4.1 image_aug_default.cc
-
struct DefaultImageAugmentParam : public dmlc::Parameter<DefaultImageAugmentParam>:定義了augmentation需要的參數(shù),Parameter是dmlc中定義的一個基礎結構體,用于定義參數(shù)。在文件parameter.h中定義了該結構體,需要了解的是DMLC_REGISTER_PARAMETER, DMLC_DECLARE_PARAMETER, DMLC_DECLARE_FIELD的作用-
DMLC_DECLARE_PARAMETER:給定parameter的名稱,用于定義這個parameter,該宏會創(chuàng)建一個靜態(tài)函數(shù):static ::dmlc::parameter::ParamManager *__MANAGER__();,這個__MANAGER__函數(shù)會返回一個類型為ParamManager的變量。接著,宏會定義另一個函數(shù):__DECLARE__,函數(shù)體在后面的括號中。 -
DMLC_DECLARE_FIELD:用于創(chuàng)建參數(shù)的一個域,也就是一個具體的參數(shù)。調(diào)用方法:this->DECLARE(manager, #FieldName, FieldName),這個方法的定義如下:
-
template<typename DType>
inline parameter::FieldEntry<DType>& DECLARE(
parameter::ParamManagerSingleton<PType> *manager,
const std::string &key, DType &ref) { // NOLINT(*)
parameter::FieldEntry<DType> *e =
new parameter::FieldEntry<DType>();
e->Init(key, this->head(), ref);
manager->manager.AddEntry(key, e);
return *e;
}
-
DMLC_REGISTER_PARAMETER:用于注冊這個參數(shù),它會定義__MANAGER__函數(shù)
(//TODO)
- 類
DefaultImageAugmenter定義了數(shù)據(jù)增強的方法,它繼承自ImageAugmenter
5. iter_image_recordio.cc
5.1 Init
初始化函數(shù)會首先初始化未定義的參數(shù),然后使用參數(shù)初始化parser_。接著會初始化iter_,它的定義:dmlc::ThreadIter<std::vector<InstVector<DType>> > iter_;
6. inst_vector.h
TensorVector:由一組Tensor組成的vector,支持不同shape
InstVector:由一組(label, example)組成的列表
7. threaditer.h
定義了類:ThreadedIter,在該類的內(nèi)部定義了內(nèi)部類:Producer。
-
Init: