libtorch知识总结

libtorch知识总结

  • 一, libtorch api
    • 1. 创建张量
    • 2. 属性
    • 3. 运算
    • 4. 形状变换
    • 5. 选择和切片
    • 6. 其它函数
  • 二,深度学习相关函数
  • 三,编译相关文件和命令
    • 1. g++命令
    • 2. Makefile
    • 3. CMakeLists.txt
      • 3.1 基本
      • 3.2 打包库
        • (1) CMakeLists.txt主文件
        • (2) sub CMakeLists.txt文件

一, libtorch api

1. 创建张量

torch::Tensor = torch::tensor({1,2,3}, torch::dtype(torch::kFLoat));
// arange
t1 = torch::arange(10);
t1 = torch::arange(1, 10);
t1 = torch::arange(1, 10, 2);
t1 = torch::arange(1, 10, 2, torch::kFloat);
// randn 正态随机分布张量
t1 = torch::randn({3, 3});
//rand 0-1均匀分布张昊
t1 = torch::rand({1, 3, 2, 3});
// randint
t1 = torch::randint(0, 2, {3, 3});
//ones 全一张量
t1 = torch::ones({2, 2});
t2 = torch::ones_like(t1, 1);
//zeros 全零张量
t1 = torch::zeros({2, 2});
t2 = torch::zeros_like(t1, 1);
//empty 空张量
t1 = torch::empty({2, 2});
t2 = torch::empty_like(t1, 1);
//full 全张量
t1 = torch::full({2, 2}, -1, torch::dtype(torch::kLong));
t2 = torch::full_like(t1, 1);
//fill_ 空张量填充
t1 = torch::empty({2, 2}).fill_(-2).to(torch::kCPU);
//clone 张量复制
t2 = t1.clone();
// where
d = torch::where(a > 0.5, b, c);

2. 属性

dtype() // 数据类型
device() // 设备
numel() // 数据总数
element_size() // 每个数据所占的内存大小
data_ptr() // 数据的首地址
ndimension() 
dim()
sizes() // 形状
size(0) // 某一维度的形状
numpy_T().sizes() // 整个形状转置
t() // 转置, 限二维张量

3. 运算

add() // 加
sub() // 减
mul() // 乘
div() // 除
true_divide() // 除
floor_divide() // 整除
matmul() // 矩阵乘法
mm() // 二维矩阵乘法

4. 形状变换

// reshape 改变形状
a = torch::arange(12, torch::kFloat).reshape({4, 3});
// cat 张量拼接
c = torch::cat({a, b}, 0);
// stack 张量堆叠
d = torch::stack({a, b}, 0);

//squeeze 压缩维度
//inline Tensor Tensor::squeeze() const//不加参数的,把所有为1的维度都压缩
//inline Tensor Tensor::squeeze(int64_t dim)const//加参数的,指定哪个维度压缩
//inline Tensor & Tensor::squeeze_() const //
//inline Tensor & Tensor::squeeze_(int64_t dim) const //
b = a.squeeze();
c = torch::squeeze(a, 0);
d = a.squeeze_(0);
//unsqueeze() 升维
// inline Tensor Tensor::unsqueeze(int64_t dim)
b = a.unsqueeze(0);
// static inline Tensor unsqueeze(const Tensor & self, int64_t dim) 
c = torch::unsqueeze(a, 2);
// transpose
// inline Tensor Tensor::transpose(int64_t dim0, int64_t dim1)
d = a.transpose(1, 0);
// permute
// inline Tensor Tensor::permute(IntArrayRef dims)
a = a.permute({2, 0, 1});
// flatten 展平tensor
// Tensor flatten(int64_t start_dim = 0, int64_t end_dim = -1) const;
// Tensor flatten(int64_t start_dim, int64_t end_dim, Dimname out_dim) const;
// Tensor flatten(Dimname start_dim, Dimname end_dim, Dimname out_dim) const;
// Tensor flatten(DimnameList dims, Dimname out_dim) const;
b = a.flatten();
c = a.flatten(1);
// expand_as // 扩展数据
f = e.expand_as(a);
// repeat // 重复数据
// inline Tensor Tensor::repeat(IntArrayRef repeats)
a = torch::tensor({1, 2, 3});
b = a.repeat({2, 2, 1});

5. 选择和切片

//select shallow copy
// inline Tensor Tensor::select(Dimname dim, int64_t index)
b = a.select(1, 2)
// static inline Tensor select(const Tensor & self, Dimname dim, int64_t index)
d = torch::select(a, 1, 2);
//index_select deep copy
// inline Tensor Tensor::index_select(int64_t dim, const Tensor & index)
//index inline Tensor Tensor::index(TensorList indices)
torch::Tensor idx = torch::tensor({1, 0}, torch::kLong);
b = a.index_select(1, idx);
//slice shallow copy
//slice inline Tensor Tensor::slice(int64_t dim, int64_t start, int64_t end, int64_t step)
b = a.slice(0, 0, 4, 2);
//narrow shallow copy 返回tensor的第dim维切片start: start+length的数
//inline Tensor Tensor::narrow(int64_t dim, int64_t start, int64_t length) const
c = a.narrow(0, 1, 2);
//inline Tensor Tensor::narrow_copy(int64_t dim, int64_t start, int64_t length) const
d = a.narrow_copy(1, 1, 3);
// masked_select 与 masked_fill
a = torch::rand({2, 3});
b = (a > 0.25);
c = a.masked_select(b);
d.masked_fill_(a > 0.5, -2);

6. 其它函数

// 排序
// Returns the indices that sort a tensor along a given dimension in ascending order by value.
a.argsort(dim, descending)
// nonzero
b = torch::nonzero(a);
// item 取标量数据
// toFloat toInt toDouble toLong 标量转换数据类型
c = a[0][0].item().toFloat();
// to() 设备
a.to(torch::kCPU)
a.to(torch::kCUDA, 1)
// toType() tensor转换数据类型
// from_blob // 外部内存创建一个tensor
inline at::Tensor from_blob(
    void* data,
    at::IntArrayRef sizes,
    const at::TensorOptions& options = at::TensorOptions())
torch::Tensor imgtensor = torch::from_blob(img.data, {img.rows, img.cols, 3}, torch::kByte);
// clamp 限制数据范围
b = a.clamp(3, 7);
// sort 排序
// static inline std::tuple sort(const Tensor & self, Dimname dim, bool descending)
// dim 0表示按行,1表示按列
// descending=false表示升序,true表示降序
// 返回的是元组,第一个表示排序后的值,第二个表示排序之后对应之前的索引。
std::tuple<torch::Tensor, torch::Tensor> sort_ret = torch::sort(scores, 0, 1);
torch::Tensor v = std::get<0>(sort_ret).to(scores.device());
torch::Tensor idx = std::get<1>(sort_ret).to(scores.device());

// max min
b = torch::max(a);
std::tuple<torch::Tensor, torch::Tensor> c = torch::max(a, 1);
auto max_val = std::get<0>(c);
auto index = std::get<1>(c);

//meshgrid 把tens变成方阵
//static inline std::vector meshgrid(TensorList tensors)
torch::Tensor scales = torch::tensor({1, 2});
torch::Tensor ratios = torch::tensor({3, 4});
std::vector<torch::Tensor> mesh = torch::meshgrid({scales, ratios});

二,深度学习相关函数

// 显卡设备
auto device = torch::device(torch::kCUDA);
auto device = torch::Device(torch::kCUDA,1);
// 统计显卡数量
int cudanum = torch::cuda::device_count();
torch::Device device = torch::cuda::is_available() ? torch::Device(torch::kCUDA,1) : torch::Device(torch::kCPU);
// 加载网络
int load_module(torch::jit::script::Module &module, const string &path, torch::Device device)
{
    try
    {
        module = torch::jit::load(path);
        module.to(device);
    }
    catch (c10::Error &e)
    {
        std::cerr << "error loading the model\n";
        return -1;
    }
    return 0;
}
// 加载图片
int load_image(cv::Mat &img, const string &path, int w, int type)
{
    img = cv::imread(path, type > 0 ? 1 : 0);
    int width, height;
    width = img.cols;
    height = img.rows;
    if (img.empty())
    {
        std::cerr << "error loading image";
        return -1;
    }
    resize(img, img, cv::Size(w, height * w / width));
    return 0;
}
// 前向计算(单输出)
int module_forward(torch::Tensor &y, const torch::Tensor &x, torch::jit::script::Module module)
{
    std::vector<torch::jit::IValue> inputs;
    inputs.emplace_back(x);
    try
    {
        y = module.forward(inputs).toTensor();
    }
    catch (c10::Error &e)
    {
        std::cerr << "error forwarding the model\n";
        return -1;
    }
    return 0;
}
// 前向计算(多输出)
int module_forward(std::vector<torch::Tensor> &vts_y, const torch::Tensor &x, torch::jit::script::Module module)
{
    torch::IValue iv_y;
    std::vector<torch::jit::IValue> inputs;
    inputs.emplace_back(x);
    try
    {
        iv_y = module.forward(inputs);
    }
    catch (c10::Error &e)
    {
        std::cerr << "error forwarding the model\n";
        return -1;
    }
    auto at_y = iv_y.toTuple()->elements();
    int n_ySize = at_y.size();
    for (int i = 0; i < n_ySize; i++)
    {
        vts_y.push_back(at_y[i].toTensor());
    }
    return 0;
}
// 前向计算(多输出,列表)
int module_forward(std::vector<torch::Tensor> &vts_y, const torch::Tensor &x, torch::jit::script::Module module)
{
    torch::IValue iv_y;
    std::vector<torch::jit::IValue> inputs;
    inputs.emplace_back(x);
    try
    {
        iv_y = module.forward(inputs);
    }
    catch (c10::Error &e)
    {
        std::cerr << "error forwarding the model\n";
        return -1;
    }
    auto at_y = iv_y.toTensorList();
    int n_ySize = at_y.size();
    for (int i = 0; i < n_ySize; i++)
    {
        vts_y.push_back((torch::Tensor) at_y[i]);
    }
    return 0;
}
// Mat数组转Tensor
void mat2tensor(torch::Tensor &img_tensor, const cv::Mat &img, torch::Device device)
{
    img_tensor = torch::from_blob(img.data, {1, img.rows, img.cols, img.channels()}, torch::kByte);
    img_tensor = img_tensor.toType(torch::kFloat);
    img_tensor = img_tensor.permute({0, 3, 1, 2});
    img_tensor = img_tensor.div_(255.0);
    img_tensor = img_tensor.sub_(0.5);
    img_tensor = img_tensor.div_(0.5);
    img_tensor = img_tensor.to(device);
}
// TensorMat转数组
void tensor2mat(cv::Mat &tensor_img, const torch::Tensor &img_tensor)
{
    tensor_img.create(cv::Size(img_tensor.size(-1), img_tensor.size(-2)), CV_8UC1);
    torch::Tensor img_tensor_ = img_tensor.to(torch::kU8);
    std::memcpy((void *)tensor_img.data, img_tensor_.data_ptr(), img_tensor.element_size() * img_tensor_.numel());
}
// 从tensor创建Mat数组方法二
cv::Mat img(img_tensor.size(1), img_tensor.size(2), CV_8UC1, img_tensor.data_ptr());

三,编译相关文件和命令

1. g++命令

g++ -o alibtorch main.cpp utils.cpp -I/home/wen/libtorch/include -I/home/wen/libtorch/include/torch/csrc/api/include -I/usr/local/include/opencv4 -L/home/wen/libtorch/lib -L/usr/local/lib -lc10 -ltorch_cpu -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs

2. Makefile

OBJS:=main.o utils.o demo.o
CXXFLAGS=-g -Wall -I/home/wen/libtorch/include -I/home/wen/libtorch/include/torch/csrc/api/include -I/usr/local/include/opencv4
LDFLAGS=-L/home/wen/libtorch/lib -L/usr/local/lib
LIBS=-lc10 -ltorch_cpu -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs 
main:$(OBJS)
	$(CXX) -o $@ $^ $(LDFLAGS) $(LIBS)
.PHONY:clean
clean:
	find ./ -name "*.o" -exec rm {} \; ; rm main

3. CMakeLists.txt

3.1 基本

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(torch)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_PREFIX_PATH ~/libtorch)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_INSTALL_PREFIX install)
find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
set(SRC_LIST main.cpp utils.cpp demo.cpp)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} ${TORCH_LIBRARIES} ${OpenCV_LIBS})
# set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
install(TARGETS ${PROJECT_NAME} 
	DESTINATION bin 
	PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
                    GROUP_READ GROUP_EXECUTE)
if (MSVC)
    file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll")
    add_custom_command(TARGET ${PROJECT_NAME} 
            POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different
            ${TORCH_DLLS}
	    $<TARGET_FILE_DIR:${PROJECT_NAME}>)
    file(GLOB OPENCV_DLLS "D:/lib/opencv/build/x64/vc15/bin/*.dll")
    add_custom_command(TARGET ${PROJECT_NAME}
            POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different
            ${OPENCV_DLLS}
	    $<TARGET_FILE_DIR:${PROJECT_NAME}>)
endif ()

3.2 打包库

(1) CMakeLists.txt主文件
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(atorch)
add_subdirectory(lib)
set(CMAKE_PREFIX_PATH ~/libtorch)
set(EXECUTABLE_OUTPUT_PATH ~/bin)
SET(CMAKE_INSTALL_PREFIX install)
find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
set(SRC_LIST main.cpp utils.cpp demo.cpp test.cpp)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} ${TORCH_LIBRARIES} ${OpenCV_LIBS})
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
install(TARGETS ${PROJECT_NAME}
	RUNTIME DESTINATION bin
	PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
                    GROUP_READ GROUP_EXECUTE)
install(TARGETS utils utils_static
	LIBRARY DESTINATION lib)
(2) sub CMakeLists.txt文件
set(LIBUTILS_SRC utils.cpp)
set(LIBRARY_OUTPUT_PATH ~/lib)
set(CMAKE_PREFIX_PATH ~/libtorch)
find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)
add_library(utils SHARED ${LIBUTILS_SRC})
add_library(utils_static STATIC ${LIBUTILS_SRC})
target_link_libraries(utils ${TORCH_LIBRARIES} ${OpenCV_LIBS})
target_link_libraries(utils_static ${TORCH_LIBRARIES} ${OpenCV_LIBS})
set_target_properties(utils_static PROPERTIES OUTPUT_NAME utils)

你可能感兴趣的:(libtorch,pytorch,c++)