高效Tensor张量生成
高效Tensor張量生成
Efficient Tensor Creation
從C++中的Excel數(shù)據(jù)中創(chuàng)建Tensor張量的方法有很多種,在簡(jiǎn)單性和性能之間都有不同的折衷。本文討論了一些方法及其權(quán)衡。
提示
繼續(xù)閱讀之前請(qǐng)務(wù)必閱讀C++指南
將數(shù)據(jù)直接寫入Tensor張量
如果能做到這一點(diǎn)就更好了。
不要復(fù)制數(shù)據(jù)或包裝現(xiàn)有數(shù)據(jù),而是直接將數(shù)據(jù)寫入Tensor張量。
正向
對(duì)于進(jìn)程內(nèi)和進(jìn)程外的執(zhí)行,這將在沒(méi)有副本的情況下工作
沒(méi)有內(nèi)存對(duì)齊要求
不需要使用刪除程序
反向
可能需要對(duì)現(xiàn)有的應(yīng)用程序進(jìn)行大量的重構(gòu),才能使其正常工作
實(shí)例
可以將數(shù)據(jù)直接接收到Tensor張量的底層緩沖區(qū)中:
// Allocate a
tensor
auto tensor = allocator->allocate_tensor({6, 6});
// Get a pointer
to the underlying buffer
auto data = tensor->get_raw_data_ptr();
// Some function
that writes data directly into this buffer
recv_message_into_buffer(data);
或者可以手動(dòng)填寫Tensor張量:
// Allocate a
tensor
auto tensor = allocator->allocate_tensor({256, 256});
const auto &dims = tensor->get_dims();
// Get an
accessor
auto accessor = tensor->accessor<2>();
// Write data
directly into it
for (int i = 0; i < dims[0]; i++)
{
for (int j = 0; j < dims[1]; j++){accessor[i][j] = i * j;}
}
甚至可以將其與TBB并行:
// Allocate a
tensor
auto tensor = allocator->allocate_tensor({256, 256});
const auto &dims = tensor->get_dims();
// Get an
accessor
auto accessor = tensor->accessor<2>();
// Write data
into the tensor in parallel
tbb::parallel_for(
// Parallelize in blocks of 16 by 16tbb:blocked_range2d<size_t>(0, dims[0], 16, 0, dims[1], 16),// Run this lambda in parallel for each block in the range above[&](const blocked_range2d<size_t>& r) {for(size_t i = r.rows().begin(); i != r.rows().end(); i++){for(size_t j = r.cols().begin(); j != r.cols().end(); j++){accessor[i][j] = i * j;}}}
);
包裝現(xiàn)有內(nèi)存
如果已經(jīng)在某個(gè)緩沖區(qū)中保存了數(shù)據(jù),那么這個(gè)方法很好。
正向
在進(jìn)程內(nèi)執(zhí)行期間,這將在沒(méi)有副本的情況下工作
如果已經(jīng)有數(shù)據(jù)很容易做到
反向
需要了解什么是刪除者以及如何正確使用
為了有效地使用TF,數(shù)據(jù)需要64字節(jié)對(duì)齊
注意:這不是一個(gè)硬性要求,但是TF可以在引擎蓋下復(fù)制未對(duì)齊的數(shù)據(jù)
與#1相比,這會(huì)在進(jìn)程外執(zhí)行期間生成一個(gè)額外的副本
實(shí)例
從cv::Mat包裝數(shù)據(jù):
cv::Mat image = … // An image from somewhere
auto tensor = allocator->tensor_from_memory<uint8_t>(
// Dimensions{1, image.rows, image.cols, image.channels()},// Dataimage.data,// Deleter[image](void * unused) {// By capturing `image` in this deleter, we ensure// that the underlying data does not get deallocated// before we're done with the tensor.}
);
將數(shù)據(jù)復(fù)制到Tensor張量中
正向
很容易做到
無(wú)內(nèi)存對(duì)齊要求
不需要使用刪除程序
反向
在進(jìn)程內(nèi)執(zhí)行期間總是生成一個(gè)額外的副本
與#1相比,這會(huì)在進(jìn)程外執(zhí)行期間生成一個(gè)額外的副本(盡管此副本是由用戶顯式編寫的)
實(shí)例
從cv::Mat復(fù)制:
cv::Mat image = … // An image from somewhere
auto tensor = allocator->allocate_tensor<uint8_t>(
// Dimensions{1, image.rows, image.cols, image.channels()}
);
// Copy data
into the tensor
tensor->copy_from(image.data, tensor->get_num_elements());
該用哪一個(gè)?
一般來(lái)說(shuō),按業(yè)績(jī)衡量的方法順序如下:
直接將數(shù)據(jù)寫入Tensor張量
包裝現(xiàn)有內(nèi)存
將數(shù)據(jù)復(fù)制到Tensor張量中
也就是說(shuō),分析是朋友。
簡(jiǎn)單性和性能之間的折衷對(duì)于大Tensor張量和小Tensor張量也是不同的,因?yàn)楦北緦?duì)于小Tensor張量更便宜。
總結(jié)
以上是生活随笔為你收集整理的高效Tensor张量生成的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 图像复原的神经网络稀疏表示
- 下一篇: 机器视觉系统的几个问题解析