win11系统下配置c++机器学习库mlpack
·
配置条件: win11,clion c++,msvc 工具链, mlpack
mlpack下载地址 https://www.mlpack.org/
mlpack的依赖库 
ensmallen下载地址 https://ensmallen.org/
cereal下载地址 https://github.com/USCiLab/cereal/releases/tag/v1.3.2
Armadillo 见我之前写的文章https://blog.csdn.net/hyl20012/article/details/147638951?spm=1001.2014.3001.5502
cmakelists.txt设置如下
cmake_minimum_required(VERSION 4.0)
project(mlpacktest)
set(CMAKE_CXX_STANDARD 20)
# 设置各依赖库的路径
set(MLPACK_ROOT "H:/software/mlpack462/Sources")
set(ARMADILLO_ROOT "H:/software/armadillo14_4_2")
set(ENSMALLEN_ROOT "H:/software/ensmallen3100")
set(CEREAL_ROOT "H:/software/cereal132")
# 包含所有头文件路径
include_directories(
${MLPACK_ROOT}/include
${ARMADILLO_ROOT}/include
${ENSMALLEN_ROOT}/include
${CEREAL_ROOT}/include
)
# 链接库文件路径
link_directories(
${MLPACK_ROOT}/lib
${ARMADILLO_ROOT}/examples/lib_win64
)
# 查找所有mlpack库文件
file(GLOB MLPACK_LIBRARIES
"${MLPACK_ROOT}/lib/mlpack_*.lib"
"${MLPACK_ROOT}/lib/mipack_*.lib"
)
# 添加可执行文件
add_executable(test main.cpp)
# MSVC编译器特定设置
if(MSVC)
target_compile_options(test PRIVATE
/EHsc
/wd4005 # 宏重定义
/wd4804 # 不安全布尔操作
/wd4819 # 字符编码问题
)
endif()
# 链接所有找到的mlpack库
target_link_libraries(test
${MLPACK_LIBRARIES}
libopenblas.dll
)
# MSVC编译器特定设置
if(MSVC)
target_compile_options(test PRIVATE /EHsc)
endif()
# 复制所有必要的DLL文件 - 从MLPACK_ROOT目录复制
set(REQUIRED_DLLS
"libopenblas.dll"
"libgcc_s_seh-1.dll"
"libgfortran-3.dll"
)
foreach(DLL ${REQUIRED_DLLS})
add_custom_command(TARGET test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${MLPACK_ROOT}/${DLL}"
$<TARGET_FILE_DIR:test>
COMMENT "Copying ${DLL} to output directory"
)
endforeach()
测试代码1:基础测试 - 验证头文件和基础功能
//基础测试 - 验证头文件和基础功能
#include <iostream>
#include <mlpack/core.hpp>
#include <armadillo>
using namespace std;
using namespace arma;
using namespace mlpack;
int main()
{
cout << "=== MLPACK 基础配置测试 ===" << endl;
// 测试 1: 版本信息
cout << "1. 版本信息测试:" << endl;
cout << "MLPACK 版本: " << MLPACK_VERSION_MAJOR << "."
<< MLPACK_VERSION_MINOR << "." << MLPACK_VERSION_PATCH << endl;
// 测试 2: Armadillo 矩阵操作
cout << "\n2. Armadillo 矩阵测试:" << endl;
mat A = randu<mat>(3, 3);
mat B = randu<mat>(3, 3);
mat C = A * B;
cout << "矩阵 A:\n" << A << endl;
cout << "矩阵 B:\n" << B << endl;
cout << "矩阵 C = A * B:\n" << C << endl;
// 测试 3: 简单的 mlpack 功能
cout << "\n3. MLPACK 核心功能测试:" << endl;
vec v = randu<vec>(5);
cout << "随机向量: " << v.t() << endl;
cout << "向量均值: " << mean(v) << endl;
cout << "\n? 基础配置测试通过!" << endl;
return 0;
}
运行结果
=== MLPACK 基础配置测试 ===
1. 版本信息测试:
MLPACK 版本: 4.6.2
2. Armadillo 矩阵测试:
矩阵 A:
0.7868 0.9467 0.2513
0.2505 0.0193 0.0227
0.7107 0.4049 0.5206
矩阵 B:
0.3447 0.1400 0.8571
0.2742 0.5439 0.4998
0.5610 0.5219 0.4194
矩阵 C = A * B:
0.6718 0.7562 1.2529
0.1044 0.0574 0.2338
0.6481 0.5915 1.0298
3. MLPACK 核心功能测试:
随机向量: 0.7443 0.2492 0.2393 0.3201 0.9105
向量均值: 0.492658
? 基础配置测试通过!
Process finished with exit code 0
测试代码2:中级测试 - 包含数据加载和简单算法
// 中级测试 - 包含数据加载和简单算法
#include <iostream>
#include <mlpack/core.hpp>
#include <mlpack/core/data/load.hpp>
#include <mlpack/core/data/save.hpp>
#include <armadillo>
using namespace std;
using namespace arma;
using namespace mlpack;
using namespace mlpack::data;
int main()
{
cout << "=== MLPACK 中级功能测试 ===" << endl;
// 创建一些测试数据
mat data = randu<mat>(5, 10); // 5个特征,10个样本
rowvec labels = randu<rowvec>(10); // 10个标签
cout << "1. 数据创建测试:" << endl;
cout << "数据矩阵大小: " << size(data) << endl;
cout << "标签向量大小: " << size(labels) << endl;
// 测试数据保存和加载(如果需要文件操作)
cout << "\n2. 数据操作测试:" << endl;
try {
// 保存数据到临时文件
Save("test_data.csv", data, true);
cout << "数据保存成功" << endl;
// 加载数据
mat loadedData;
Load("test_data.csv", loadedData, true);
cout << "数据加载成功,大小: " << size(loadedData) << endl;
// 验证数据一致性
if (approx_equal(data, loadedData, "absdiff", 1e-5)) {
cout << "数据一致性验证通过" << endl;
} else {
cout << "警告: 加载的数据与原始数据有差异" << endl;
}
} catch (const exception& e) {
cout << "文件操作测试跳过: " << e.what() << endl;
}
// 测试 3: 基础统计
cout << "\n3. 统计功能测试:" << endl;
cout << "数据均值: " << mean(mean(data)) << endl;
cout << "数据标准差: " << stddev(vectorise(data)) << endl;
cout << "\n? 中级功能测试通过!" << endl;
return 0;
}
运行结果
=== MLPACK 中级功能测试 ===
1. 数据创建测试:
数据矩阵大小: 5x10
标签向量大小: 1x10
2. 数据操作测试:
数据保存成功
数据加载成功,大小: 5x10
数据一致性验证通过
3. 统计功能测试:
数据均值: 0.458978
数据标准差: 0.286455
? 中级功能测试通过!
Process finished with exit code 0
测试代码3:协同过滤测试代码
//3 协同过滤测试代码
#include <iostream>
#include <mlpack/core.hpp>
#include <mlpack/methods/cf/cf.hpp>
#include <armadillo>
using namespace std;
using namespace arma;
using namespace mlpack;
// 移除 using namespace mlpack::cf; 因为可能不存在
int main()
{
cout << "=== MLPACK 协同过滤测试 ===" << endl;
// 创建模拟评分数据
// 格式: [用户ID, 物品ID, 评分]
mat ratings(3, 20); // 3行: 用户,物品,评分; 20列: 20个评分
// 填充模拟数据
for (size_t i = 0; i < 20; ++i) {
ratings(0, i) = floor(i / 5) + 1; // 用户ID: 1,1,1,1,1,2,2,2,2,2,...
ratings(1, i) = (i % 5) + 1; // 物品ID: 1,2,3,4,5,1,2,3,4,5,...
ratings(2, i) = rand() % 5 + 1; // 评分: 1-5的随机数
}
cout << "1. 模拟评分数据创建成功" << endl;
cout << "数据大小: " << size(ratings) << endl;
cout << "前5个评分:\n" << ratings.submat(0, 0, 2, 4) << endl;
// 分割训练集和测试集
mat trainRatings, testRatings;
data::Split(ratings, trainRatings, testRatings, 0.2); // 20% 作为测试集
cout << "\n2. 数据分割完成" << endl;
cout << "训练集大小: " << size(trainRatings) << endl;
cout << "测试集大小: " << size(testRatings) << endl;
try {
// 创建协同过滤模型 - 不使用命名空间限定
cout << "\n3. 训练协同过滤模型..." << endl;
CFType<RegSVDPolicy> cfModel(
trainRatings,
RegSVDPolicy(),
3, // 相似用户数
2 // 分解秩
);
cout << "模型训练成功" << endl;
// 准备测试组合
Mat<size_t> combinations(2, testRatings.n_cols);
for (size_t i = 0; i < testRatings.n_cols; ++i) {
combinations(0, i) = size_t(testRatings(0, i)); // 用户
combinations(1, i) = size_t(testRatings(1, i)); // 物品
}
// 预测评分
vec predictions;
cfModel.Predict(combinations, predictions);
cout << "\n4. 预测完成" << endl;
cout << "预测值示例: " << predictions.subvec(0, min((size_t)3, predictions.n_elem-1)).t() << endl;
cout << "实际值示例: " << testRatings.row(2).subvec(0, min((size_t)3, testRatings.n_cols-1)) << endl;
// 计算RMSE
if (testRatings.n_cols > 0) {
double rmse = norm(predictions - testRatings.row(2).t(), 2) /
sqrt((double)testRatings.n_cols);
cout << "RMSE: " << rmse << endl;
}
// 获取推荐
cout << "\n5. 生成推荐..." << endl;
Col<size_t> users = {1}; // 为用户1生成推荐
Mat<size_t> recommendations;
cfModel.GetRecommendations(3, recommendations, users); // 推荐3个物品
cout << "为用户1推荐的物品ID: ";
for (size_t i = 0; i < recommendations.n_elem; ++i) {
cout << recommendations[i] << " ";
}
cout << endl;
} catch (const exception& e) {
cout << "? 协同过滤测试失败: " << e.what() << endl;
return -1;
}
cout << "\n? 协同过滤测试通过!" << endl;
return 0;
}
运行结果
=== MLPACK 协同过滤测试 ===
1. 模拟评分数据创建成功
数据大小: 3x20
前5个评分:
1.0000 1.0000 1.0000 1.0000 1.0000
1.0000 2.0000 3.0000 4.0000 5.0000
2.0000 3.0000 5.0000 1.0000 5.0000
2. 数据分割完成
训练集大小: 3x16
测试集大小: 3x4
3. 训练协同过滤模型...
模型训练成功
4. 预测完成
预测值示例: 2.6290 3.1484 0.8088 4.2313
实际值示例: 3.0000 2.0000 2.0000 1.0000
RMSE: 1.82458
5. 生成推荐...
为用户1推荐的物品ID: 4 1 0
? 协同过滤测试通过!
Process finished with exit code 0
测试代码4:SVM 支持向量机测试代码
//SVM 支持向量机测试代码
#include <mlpack/core.hpp>
#include <mlpack/methods/linear_svm/linear_svm.hpp>
#include <iostream>
using namespace mlpack;
using namespace arma;
using namespace std;
int main()
{
cout << "=== MLPack Linear SVM 简单测试 ===" << endl;
// 设置随机种子
arma::arma_rng::set_seed(12345);
// 1. 创建简单的二分类数据
cout << "\n1. 生成测试数据..." << endl;
// 特征数=2, 样本数=100
mat data(2, 100);
Row<size_t> labels(100);
// 类别0: 中心在(1,1)
for (size_t i = 0; i < 50; ++i)
{
data(0, i) = 1.0 + 0.3 * randn();
data(1, i) = 1.0 + 0.3 * randn();
labels(i) = 0;
}
// 类别1: 中心在(4,4)
for (size_t i = 50; i < 100; ++i)
{
data(0, i) = 4.0 + 0.3 * randn();
data(1, i) = 4.0 + 0.3 * randn();
labels(i) = 1;
}
cout << "数据维度: " << data.n_rows << " x " << data.n_cols << endl;
cout << "标签数量: " << labels.n_elem << endl;
// 2. 分割训练集和测试集
cout << "\n2. 分割数据集..." << endl;
mat trainData, testData;
Row<size_t> trainLabels, testLabels;
data::Split(data, labels, trainData, testData, trainLabels, testLabels, 0.2);
cout << "训练集: " << trainData.n_cols << " 个样本" << endl;
cout << "测试集: " << testData.n_cols << " 个样本" << endl;
// 3. 训练线性SVM模型
cout << "\n3. 训练线性SVM模型..." << endl;
double lambda = 0.0001; // 正则化参数
size_t numClasses = 2; // 类别数
// 创建并训练SVM
LinearSVM<> svm(trainData, trainLabels, numClasses, lambda);
cout << "模型训练完成!" << endl;
// 4. 在测试集上预测
cout << "\n4. 测试模型性能..." << endl;
Row<size_t> predictions;
svm.Classify(testData, predictions);
// 5. 计算准确率
size_t correct = 0;
for (size_t i = 0; i < testLabels.n_elem; ++i)
{
if (predictions(i) == testLabels(i))
correct++;
}
double accuracy = (double)correct / testLabels.n_elem * 100.0;
cout << "测试准确率: " << accuracy << "% (" << correct << "/" << testLabels.n_elem << ")" << endl;
// 6. 显示模型参数信息
cout << "\n5. 模型参数信息..." << endl;
cout << "权重矩阵维度: " << svm.Parameters().n_rows << " x " << svm.Parameters().n_cols << endl;
// 7. 保存模型(可选)
// data::Save("linear_svm_model.xml", "linear_svm", svm, false);
// cout << "模型已保存到 linear_svm_model.xml" << endl;
cout << "\n=== 测试完成 ===" << endl;
return 0;
}
运行结果
=== MLPack Linear SVM 简单测试 ===
1. 生成测试数据...
数据维度: 2 x 100
标签数量: 100
2. 分割数据集...
训练集: 80 个样本
测试集: 20 个样本
3. 训练线性SVM模型...
模型训练完成!
4. 测试模型性能...
测试准确率: 45% (9/20)
5. 模型参数信息...
权重矩阵维度: 2 x 2
=== 测试完成 ===
Process finished with exit code 0
测试代码:MLPACK 模块可用性测试。为了全面了解您的 mlpack 版本中哪些模块可用,请运行这个综合测试:
//MLPACK 模块可用性测试
//为了全面了解您的 mlpack 版本中哪些模块可用,请运行这个综合测试:
#include <iostream>
#include <mlpack/core.hpp>
#include <armadillo>
using namespace std;
// 测试函数声明
bool testCore();
bool testDataIO();
bool testCF();
bool testKMeans();
bool testLinearRegression();
int main()
{
cout << "=== MLPACK 模块可用性综合测试 ===" << endl;
cout << "MLPACK 版本: " << MLPACK_VERSION_MAJOR << "."
<< MLPACK_VERSION_MINOR << "." << MLPACK_VERSION_PATCH << endl;
cout << "\n1. 测试核心功能..." << endl;
if (testCore()) {
cout << "? 核心功能测试通过" << endl;
} else {
cout << "? 核心功能测试失败" << endl;
}
cout << "\n2. 测试数据IO功能..." << endl;
if (testDataIO()) {
cout << "? 数据IO功能测试通过" << endl;
} else {
cout << "? 数据IO功能测试失败" << endl;
}
cout << "\n3. 测试K-means功能..." << endl;
if (testKMeans()) {
cout << "? K-means功能测试通过" << endl;
} else {
cout << "? K-means功能测试失败" << endl;
}
cout << "\n=== 测试完成 ===" << endl;
return 0;
}
bool testCore()
{
try {
arma::mat A = arma::randu<arma::mat>(2, 2);
arma::mat B = arma::randu<arma::mat>(2, 2);
arma::mat C = A * B;
return true;
} catch (...) {
return false;
}
}
bool testDataIO()
{
try {
arma::mat data = arma::randu<arma::mat>(3, 5);
// 测试数据分割功能
arma::mat train, test;
mlpack::data::Split(data, train, test, 0.3);
return true;
} catch (...) {
return false;
}
}
bool testKMeans()
{
try {
#ifdef MLPACK_METHODS_KMEANS_KMEANS_HPP
arma::mat data = arma::randu<arma::mat>(2, 10);
arma::mat centroids;
arma::Row<size_t> assignments;
// 尝试不同的命名空间组合
mlpack::kmeans::KMeans<> kmeans;
kmeans.Cluster(data, 2, assignments, centroids);
return true;
#else
return false;
#endif
} catch (const std::exception& e) {
cout << "K-means错误: " << e.what() << endl;
return false;
} catch (...) {
return false;
}
}
运行结果
=== MLPACK 模块可用性综合测试 ===
MLPACK 版本: 4.6.2
1. 测试核心功能...
? 核心功能测试通过
2. 测试数据IO功能...
? 数据IO功能测试通过
3. 测试K-means功能...
? K-means功能测试失败
=== 测试完成 ===
Process finished with exit code 0
更多推荐
所有评论(0)