c++配置深度学习libtorch GPU环境
·
配置条件:win11, GPU 12.6,cuda 12.6.3, cudnn 8.9.7, vs 2022, libtorch 2.9.0, Release模式
注意:cuda、 cudnn、libtorch、vs这几个一定要匹配,否则可能会报错。他们很矫情~~
cmakelists.txt设置如下
cmake_minimum_required(VERSION 3.28)
project(libtorchtest)
# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置构建目录为输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
# LibTorch 配置
set(CMAKE_PREFIX_PATH "G:/software/libtorch290_cu126Release")
find_package(Torch REQUIRED)
if(NOT Torch_FOUND)
message(FATAL_ERROR "LibTorch not found")
endif()
message(STATUS "Torch include directories: ${TORCH_INCLUDE_DIRS}")
message(STATUS "Torch libraries: ${TORCH_LIBRARIES}")
# 包含头文件目录
include_directories(${TORCH_INCLUDE_DIRS})
# 一次性复制所有必需的 DLL 文件
add_custom_target(copy_dlls ALL
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"G:/software/libtorch290_cu126Release/lib/torch_cpu.dll"
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"G:/software/libtorch290_cu126Release/lib/torch_cuda.dll"
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"G:/software/libtorch290_cu126Release/lib/c10.dll"
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"G:/software/libtorch290_cu126Release/lib/c10_cuda.dll"
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"G:/software/libtorch290_cu126Release/lib/libiomp5md.dll"
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMENT "Copying DLL files to build directory"
)
#[[ 第一种写法
函数:添加 Torch 可执行文件
function(add_torch_executable target_name source_file)
add_executable(${target_name} ${source_file})
target_link_libraries(${target_name} ${TORCH_LIBRARIES})
add_dependencies(${target_name} copy_dlls)
# 设置目标属性,确保包含目录正确
target_include_directories(${target_name} PRIVATE ${TORCH_INCLUDE_DIRS})
# Windows 特定设置
if(WIN32)
target_compile_definitions(${target_name} PRIVATE _USE_MATH_DEFINES)
target_link_options(${target_name} PRIVATE "/INCLUDE:?warp_size@cuda@at@@YAHXZ")
endif()
endfunction()
# 添加所有可执行文件
#add_torch_executable(SVM ../SVM.cpp)
#add_torch_executable(LinearRegression ../LinearRegression.cpp)
#add_torch_executable(LSTMM ../LSTMM.cpp)
#add_torch_executable(test ../test.cpp)
#]]
# 以下是第二种写法
add_executable(test ../test.cpp)
if(MSVC)
# 禁用 C4267 警告
add_compile_options(/wd4267)
# 或者针对特定目标
target_compile_options(test PRIVATE /wd4267)
endif()
target_link_libraries(test ${TORCH_LIBRARIES})
add_dependencies(test copy_dlls)
# 设置目标属性,确保包含目录正确
target_include_directories(test PRIVATE ${TORCH_INCLUDE_DIRS})
#[[ Windows 特定设置
if(WIN32)
target_compile_definitions(test PRIVATE _USE_MATH_DEFINES)
target_link_options(test PRIVATE "/INCLUDE:?warp_size@cuda@at@@YAHXZ")
endif() #]]
add_executable(LSTMM ../LSTMM.cpp)
target_link_libraries(LSTMM ${TORCH_LIBRARIES})
add_dependencies(LSTMM copy_dlls)
# 设置目标属性,确保包含目录正确
target_include_directories(LSTMM PRIVATE ${TORCH_INCLUDE_DIRS})
测试代码(循环神经网络LSTM)
#include <torch/torch.h>
#include <iostream>
#include <vector>
// 定义 LSTM 模型
struct LSTMNet : torch::nn::Module {
LSTMNet(int input_size, int hidden_size, int num_layers, int output_size) {
// 使用成员函数设置LSTM选项
auto lstm_options = torch::nn::LSTMOptions(input_size, hidden_size)
.num_layers(num_layers)
.batch_first(true);
// 注册模块
lstm = register_module("lstm", torch::nn::LSTM(lstm_options));
fc = register_module("fc", torch::nn::Linear(hidden_size, output_size));
}
torch::Tensor forward(torch::Tensor x) {
// 获取LSTM参数
int64_t num_layers = lstm->options.num_layers();
int64_t hidden_size = lstm->options.hidden_size();
// 初始化隐藏状态
auto h0 = torch::zeros({num_layers, x.size(0), hidden_size}).to(x.device());
auto c0 = torch::zeros({num_layers, x.size(0), hidden_size}).to(x.device());
// LSTM 前向传播
auto lstm_out = lstm->forward(x, std::make_tuple(h0, c0));
auto out = std::get<0>(lstm_out);
// 只取最后一个时间步的输出
auto out_last = out.index({torch::indexing::Slice(), -1});
// 全连接层
return fc->forward(out_last);
}
torch::nn::LSTM lstm{nullptr};
torch::nn::Linear fc{nullptr};
};
int main() {
// 1. 设置设备 (优先使用GPU)
torch::Device device = torch::cuda::is_available() ?
torch::Device(torch::kCUDA) :
torch::Device(torch::kCPU);
std::cout << "Using device: " << device << std::endl;
// 2. 超参数设置
const int sequence_length = 10; // 序列长度
const int input_size = 1; // 输入特征维度
const int hidden_size = 64; // LSTM隐藏层大小
const int num_layers = 2; // LSTM层数
const int output_size = 1; // 输出维度
const int batch_size = 32; // 批大小
const int num_epochs = 100; // 训练轮数
const float learning_rate = 0.01;
// 3. 创建模型并移至GPU
auto model = std::make_shared<LSTMNet>(input_size, hidden_size, num_layers, output_size);
model->to(device);
// 4. 创建优化器和损失函数
torch::optim::Adam optimizer(model->parameters(), torch::optim::AdamOptions(learning_rate));
auto criterion = torch::nn::MSELoss();
// 5. 生成模拟数据 (正弦波序列)
std::vector<float> data;
for (int i = 0; i < 1000; ++i) {
data.push_back(std::sin(i * 0.1));
}
// 6. 创建数据集
auto dataset = torch::from_blob(data.data(), {static_cast<int64_t>(data.size())})
.to(torch::kFloat32)
.view({-1, 1});
// 7. 训练循环
std::cout << "Start training..." << std::endl;
for (int epoch = 0; epoch < num_epochs; ++epoch) {
float epoch_loss = 0;
int batch_count = 0;
// 迭代批次
for (int i = 0; i < data.size() - sequence_length - batch_size; i += batch_size) {
// 准备输入和目标张量
std::vector<torch::Tensor> inputs, targets;
for (int j = 0; j < batch_size; ++j) {
int start_idx = i + j;
auto input_seq = dataset.index({torch::indexing::Slice(start_idx, start_idx + sequence_length)});
auto target_val = dataset.index({start_idx + sequence_length});
inputs.push_back(input_seq);
targets.push_back(target_val);
}
// 创建批次张量 [batch_size, seq_len, input_size]
auto batch_input = torch::stack(inputs).view({batch_size, sequence_length, input_size});
auto batch_target = torch::stack(targets).view({batch_size, output_size});
// 移至设备
batch_input = batch_input.to(device);
batch_target = batch_target.to(device);
// 前向传播
auto output = model->forward(batch_input);
// 计算损失
auto loss = criterion(output, batch_target);
epoch_loss += loss.item<float>();
batch_count++;
// 反向传播和优化
optimizer.zero_grad();
loss.backward();
optimizer.step();
}
// 打印训练进度
if ((epoch + 1) % 10 == 0) {
std::cout << "Epoch [" << (epoch + 1) << "/" << num_epochs
<< "], Loss: " << (epoch_loss / batch_count) << std::endl;
}
}
// 8. 模型测试
std::cout << "\nTesting model..." << std::endl;
model->eval(); // 设置为评估模式
// 使用最后一段序列进行预测
auto test_input = dataset.index({
torch::indexing::Slice(dataset.size(0) - sequence_length, torch::indexing::None)
}).view({1, sequence_length, input_size}).to(device);
auto prediction = model->forward(test_input);
// 打印实际值和预测值
float actual_value = dataset[dataset.size(0) - 1].item<float>();
float predicted_value = prediction.item<float>();
std::cout << "Actual next value: " << actual_value << std::endl;
std::cout << "Predicted next value: " << predicted_value << std::endl;
std::cout << "Absolute error: " << std::abs(actual_value - predicted_value) << std::endl;
return 0;
}
运行结果
Using device: cuda
Start training...
Epoch [10/100], Loss: 2.66655e-06
Epoch [20/100], Loss: 0.000258789
Epoch [30/100], Loss: 0.000613829
Epoch [40/100], Loss: 4.297e-06
Epoch [50/100], Loss: 0.00117912
Epoch [60/100], Loss: 1.13044e-07
Epoch [70/100], Loss: 0.00135332
Epoch [80/100], Loss: 2.26288e-05
Epoch [90/100], Loss: 1.03347e-07
Epoch [100/100], Loss: 2.108e-06
Testing model...
Actual next value: -0.589924
Predicted next value: -0.503256
Absolute error: 0.0866677
Process finished with exit code 0
更多推荐
所有评论(0)