【C++】和【预训练模型】实现【机器学习】【图像分类】的终极指南

目录

💗1. 准备工作和环境配置💕

💖安装OpenCV💕

💖安装Dlib💕

下载并编译TensorFlow C++ API💕

💗2. 下载和配置预训练模型💕

💖2.1 下载预训练的ResNet-50模型💕

💖2.2 配置TensorFlow C++ API💕

💖2.3 加载和使用模型💕

💗3.编写代码进行图像分类💕

💖CMakeLists.txt💕

💖main.cpp💕

💗4. 代码分析和推导💕

💖初始化TensorFlow会话💕

💖读取和导入模型💕

💖读取输入图像💕

💖创建输入Tensor💕

💖运行会话并处理输出💕

💗5. 进阶优化与性能提升💕

💖多线程处理💕

💖GPU加速💕

💖模型优化💕

💗6. 问题与解决方案💕

💖问题1:内存不足💕

💖问题2:推理速度慢💕

💖问题3:模型兼容性问题💕

 


 

在现代机器学习和人工智能应用中,图像分类是一个非常常见且重要的任务。通过使用预训练模型,我们可以显著减少训练时间并提高准确性。C++作为一种高效的编程语言,特别适用于需要高性能计算的任务。226b4e959a0c4b4ca7e72460c6008eb7.png

💗1. 准备工作和环境配置💕

首先,我们需要配置开发环境。这里我们将使用以下工具和库:

  • C++ 编译器 (如GCC)
  • CMake 构建系统
  • OpenCV 库
  • Dlib 库
  • 下载并编译C++版本的TensorFlow

💖安装OpenCV💕

在Linux系统上,可以通过以下命令安装OpenCV:

sudo apt-get update
sudo apt-get install libopencv-dev

💖安装Dlib💕

Dlib是一个现代C++工具包,包含了机器学习算法和工具。可以通过以下命令安装:

git clone https://github.com/davisking/dlib.git
cd dlib
mkdir build
cd build
cmake ..
cmake --build .
sudo make install

下载并编译TensorFlow C++ API💕

下载TensorFlow的C++库并编译,可以参考TensorFlow官方文档进行详细的步骤。确保下载的版本与您当前的环境兼容。

💗2. 下载和配置预训练模型💕

使用ResNet-50模型,这是一个用于图像分类的深度卷积神经网络。在TensorFlow中,可以轻松地获取预训练的ResNet-50模型。以下是下载和配置ResNet-50模型的详细步骤:

💖2.1 下载预训练的ResNet-50模型💕

首先,我们需要下载预训练的ResNet-50模型。TensorFlow提供了很多预训练模型,您可以从TensorFlow的模型库中获取ResNet-50。

1.访问TensorFlow模型库: 打开浏览器,访问TensorFlow模型库的GitHub页面:TensorFlow Model Garden

2.选择预训练模型: 在模型库中找到ResNet-50模型。通常在tensorflow/models/official/vision/image_classification目录下可以找到相关的预训练模型。

3.下载模型文件: 下载模型文件,模型文件通常是一个.pb文件(TensorFlow模型的protobuf格式)。如果直接下载预训练模型文件不方便,可以使用TensorFlow的tf.keras.applications模块直接加载ResNet-50,并保存为.pb文件。

使用Python脚本下载并保存ResNet-50模型:

import tensorflow as tfmodel = tf.keras.applications.ResNet50(weights='imagenet')
model.save('resnet50_saved_model', save_format='tf')
  • 运行此脚本将会在当前目录生成一个名为resnet50_saved_model的文件夹,其中包含了模型的.pb文件。

💖2.2 配置TensorFlow C++ API💕

在下载模型文件后,我们需要配置TensorFlow的C++ API来加载和使用该模型。以下是配置步骤:

1.安装TensorFlow C++库: 从TensorFlow的官方网站下载适用于您的平台的TensorFlow C++库。如果没有现成的二进制包,可以从源代码编译TensorFlow C++库。

git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow
./configure
bazel build //tensorflow:libtensorflow_cc.so

编译完成后,库文件位于bazel-bin/tensorflow目录下。

2.设置环境变量: 将TensorFlow C++库的包含路径和库文件路径添加到环境变量中。

export TF_CPP_INCLUDE_DIR=/path/to/tensorflow/include
export TF_CPP_LIB_DIR=/path/to/tensorflow/lib

3.配置CMakeLists.txt: 更新项目的CMakeLists.txt文件,包含TensorFlow C++库的路径。

cmake_minimum_required(VERSION 3.10)
project(ImageClassification)set(CMAKE_CXX_STANDARD 14)find_package(OpenCV REQUIRED)
find_package(Dlib REQUIRED)include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${Dlib_INCLUDE_DIRS})
include_directories(${TF_CPP_INCLUDE_DIR})
link_directories(${TF_CPP_LIB_DIR})add_executable(ImageClassification main.cpp)
target_link_libraries(ImageClassification ${OpenCV_LIBS} dlib::dlib tensorflow_cc)

💖2.3 加载和使用模型💕

在完成上述配置后,可以在C++代码中加载和使用ResNet-50模型。下面是示例代码,演示如何加载和使用该模型进行图像分类:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <dlib/dnn.h>
#include <tensorflow/core/public/session.h>
#include <tensorflow/core/protobuf/meta_graph.pb.h>using namespace std;
using namespace cv;
using namespace tensorflow;// 定义图像分类函数
void classifyImage(const std::string& model_path, const std::string& image_path) {// 初始化TensorFlow会话Session* session;Status status = NewSession(SessionOptions(), &session);if (!status.ok()) {std::cerr << "Error creating TensorFlow session: " << status.ToString() << std::endl;return;}// 读取模型GraphDef graph_def;status = ReadBinaryProto(Env::Default(), model_path, &graph_def);if (!status.ok()) {std::cerr << "Error reading graph definition from " << model_path << ": " << status.ToString() << std::endl;return;}// 将模型导入会话status = session->Create(graph_def);if (!status.ok()) {std::cerr << "Error creating graph: " << status.ToString() << std::endl;return;}// 读取输入图像Mat img = imread(image_path);if (img.empty()) {std::cerr << "Error reading image: " << image_path << std::endl;return;}// 预处理图像Mat img_resized;resize(img, img_resized, Size(224, 224));img_resized.convertTo(img_resized, CV_32FC3);img_resized = img_resized / 255.0;// 创建输入TensorTensor input_tensor(DT_FLOAT, TensorShape({1, 224, 224, 3}));auto input_tensor_mapped = input_tensor.tensor<float, 4>();// 将图像数据复制到输入Tensorfor (int y = 0; y < 224; ++y) {for (int x = 0; x < 224; ++x) {for (int c = 0; c < 3; ++c) {input_tensor_mapped(0, y, x, c) = img_resized.at<Vec3f>(y, x)[c];}}}// 运行会话std::vector<Tensor> outputs;status = session->Run({{"input_tensor", input_tensor}}, {"output_tensor"}, {}, &outputs);if (!status.ok()) {std::cerr << "Error during inference: " << status.ToString() << std::endl;return;}// 处理输出auto output_tensor = outputs[0].tensor<float, 2>();int best_label = std::distance(output_tensor(0).data(), std::max_element(output_tensor(0).data(), output_tensor(0).data() + output_tensor.dim_size(1)));std::cout << "Predicted label: " << best_label << std::endl;// 清理session->Close();delete session;
}int main(int argc, char** argv) {if (argc != 3) {std::cerr << "Usage: " << argv[0] << " <model_path> <image_path>" << std::endl;return 1;}const std::string model_path = argv[1];const std::string image_path = argv[2];classifyImage(model_path, image_path);return 0;
}

💗3.编写代码进行图像分类💕

使用预训练的ResNet-50模型进行图像分类。

💖CMakeLists.txt💕

cmake_minimum_required(VERSION 3.10)
project(ImageClassification)set(CMAKE_CXX_STANDARD 14)find_package(OpenCV REQUIRED)
find_package(Dlib REQUIRED)include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${Dlib_INCLUDE_DIRS})
include_directories(/path/to/tensorflow/include)
link_directories(/path/to/tensorflow/lib)add_executable(ImageClassification main.cpp)
target_link_libraries(ImageClassification ${OpenCV_LIBS} dlib::dlib tensorflow)

💖main.cpp💕

#include <iostream>
#include <opencv2/opencv.hpp>
#include <dlib/dnn.h>
#include <tensorflow/core/public/session.h>
#include <tensorflow/core/protobuf/meta_graph.pb.h>using namespace std;
using namespace cv;
using namespace tensorflow;// 定义图像分类函数
void classifyImage(const std::string& model_path, const std::string& image_path) {// 初始化TensorFlow会话Session* session;Status status = NewSession(SessionOptions(), &session);if (!status.ok()) {std::cerr << "Error creating TensorFlow session: " << status.ToString() << std::endl;return;}// 读取模型GraphDef graph_def;status = ReadBinaryProto(Env::Default(), model_path, &graph_def);if (!status.ok()) {std::cerr << "Error reading graph definition from " << model_path << ": " << status.ToString() << std::endl;return;}// 将模型导入会话status = session->Create(graph_def);if (!status.ok()) {std::cerr << "Error creating graph: " << status.ToString() << std::endl;return;}// 读取输入图像Mat img = imread(image_path);if (img.empty()) {std::cerr << "Error reading image: " << image_path << std::endl;return;}// 预处理图像Mat img_resized;resize(img, img_resized, Size(224, 224));img_resized.convertTo(img_resized, CV_32FC3);img_resized = img_resized / 255.0;// 创建输入TensorTensor input_tensor(DT_FLOAT, TensorShape({1, 224, 224, 3}));auto input_tensor_mapped = input_tensor.tensor<float, 4>();// 将图像数据复制到输入Tensorfor (int y = 0; y < 224; ++y) {for (int x = 0; x < 224; ++x) {for (int c = 0; c < 3; ++c) {input_tensor_mapped(0, y, x, c) = img_resized.at<Vec3f>(y, x)[c];}}}// 运行会话std::vector<Tensor> outputs;status = session->Run({{"input_tensor", input_tensor}}, {"output_tensor"}, {}, &outputs);if (!status.ok()) {std::cerr << "Error during inference: " << status.ToString() << std::endl;return;}// 处理输出auto output_tensor = outputs[0].tensor<float, 2>();int best_label = std::distance(output_tensor(0).data(), std::max_element(output_tensor(0).data(), output_tensor(0).data() + output_tensor.dim_size(1)));std::cout << "Predicted label: " << best_label << std::endl;// 清理session->Close();delete session;
}int main(int argc, char** argv) {if (argc != 3) {std::cerr << "Usage: " << argv[0] << " <model_path> <image_path>" << std::endl;return 1;}const std::string model_path = argv[1];const std::string image_path = argv[2];classifyImage(model_path, image_path);return 0;
}

💗4. 代码分析和推导💕

💖初始化TensorFlow会话💕

首先,我们初始化一个TensorFlow会话。这个会话将用于执行图中的操作。

Session* session;
Status status = NewSession(SessionOptions(), &session);
if (!status.ok()) {std::cerr << "Error creating TensorFlow session: " << status.ToString() << std::endl;return;
}

💖读取和导入模型💕

使用ReadBinaryProto函数读取二进制格式的模型文件,并将其导入会话。

GraphDef graph_def;
status = ReadBinaryProto(Env::Default(), model_path, &graph_def);
if (!status.ok()) {std::cerr << "Error reading graph definition from " << model_path << ": " << status.ToString() << std::endl;return;
}status = session->Create(graph_def);
if (!status.ok()) {std::cerr << "Error creating graph: " << status.ToString() << std::endl;return;
}

💖读取输入图像💕

我们使用OpenCV读取图像,并将其大小调整为224x224,这是ResNet-50模型所需的输入尺寸。

Mat img = imread(image_path);
if (img.empty()) {std::cerr << "Error reading image: " << image_path << std::endl;return;
}Mat img_resized;
resize(img, img_resized, Size(224, 224));
img_resized.convertTo(img_resized, CV_32FC3);
img_resized = img_resized / 255.0;

💖创建输入Tensor💕

接下来,创建一个TensorFlow的Tensor,并将图像数据复制到该Tensor中。

Tensor input_tensor(DT_FLOAT, TensorShape({1, 224, 224, 3}));
auto input_tensor_mapped = input_tensor.tensor<float, 4>();for (int y = 0; y < 224; ++y) {for (int x = 0; x < 224; ++x) {for (int c = 0; c < 3; ++c) {input_tensor_mapped(0, y, x, c) = img_resized.at<Vec3f>(y, x)[c];}}
}

💖运行会话并处理输出💕

使用会话运行模型,并获取输出结果。

std::vector<Tensor> outputs;
status = session->Run({{"input_tensor", input_tensor}}, {"output_tensor"}, {}, &outputs);
if (!status.ok()) {std::cerr << "Error during inference: " << status.ToString() << std::endl;return;
}auto output_tensor = outputs[0].tensor<float, 2>();
int best_label = std::distance(output_tensor(0).data(), std::max_element(output_tensor(0).data(), output_tensor(0).data() + output_tensor.dim_size(1)));std::cout << "Predicted label: " << best_label << std::endl;

💗5. 进阶优化与性能提升💕

在这部分中,我们将探讨如何进一步优化代码以提高性能和效率。这些技巧和方法包括多线程处理、GPU加速、模型优化等。

💖多线程处理💕

在处理大量图像时,利用多线程可以显著提高处理速度。C++中的std::thread库使得多线程编程更加方便。多线程处理:

#include <thread>
#include <vector>// 定义一个处理图像的函数
void processImage(const std::string& model_path, const std::string& image_path) {classifyImage(model_path, image_path);
}int main(int argc, char** argv) {if (argc < 3) {std::cerr << "Usage: " << argv[0] << " <model_path> <image_paths...>" << std::endl;return 1;}const std::string model_path = argv[1];std::vector<std::string> image_paths;for (int i = 2; i < argc; ++i) {image_paths.push_back(argv[i]);}std::vector<std::thread> threads;for (const auto& image_path : image_paths) {threads.emplace_back(processImage, model_path, image_path);}for (auto& t : threads) {if (t.joinable()) {t.join();}}return 0;
}

通过这种方式,我们可以同时处理多个图像,从而提高整体处理效率。

💖GPU加速💕

GPU在处理大规模并行计算任务时具有显著优势。TensorFlow的C++ API支持GPU加速,只需在创建会话时指定GPU设备即可:

SessionOptions options;
options.config.mutable_gpu_options()->set_allow_growth(true);
Session* session;
Status status = NewSession(options, &session);
if (!status.ok()) {std::cerr << "Error creating TensorFlow session: " << status.ToString() << std::endl;return;
}

在配置好CUDA和cuDNN后,TensorFlow会自动利用GPU进行计算,从而显著提高计算速度。

💖模型优化💕

模型优化是提升推理速度和减少内存占用的重要手段。常用的方法包括模型量化和裁剪。可以使用TensorFlow的模型优化工具进行这些优化。

使用TensorFlow的模型优化API进行量化:

import tensorflow as tf
from tensorflow_model_optimization.quantization.keras import vitis_quantizemodel = tf.keras.models.load_model('model.h5')
quantized_model = vitis_quantize.quantize_model(model)
quantized_model.save('quantized_model.h5')

将量化后的模型加载到C++项目中,可以显著减少模型的计算量,从而提高推理速度。

💗6. 问题与解决方案💕

在实际应用中,可能会遇到各种问题。以下是一些常见问题及其解决方案,具体分析每种问题的可能原因和详细的解决步骤。

💖问题1:内存不足💕

解决方案:

1.减少批处理大小: 批处理大小(batch size)是指一次性送入模型进行处理的数据样本数。如果批处理大小过大,可能会导致内存溢出。可以通过减小批处理大小来减少内存使用。例如,将批处理大小从32减小到16甚至更小。

// 将批处理大小设置为1
Tensor input_tensor(DT_FLOAT, TensorShape({1, 224, 224, 3}));

2.使用模型量化技术: 模型量化通过将浮点数转换为低精度整数来减少模型大小和内存占用。TensorFlow提供了量化工具,可以在训练后对模型进行量化。

import tensorflow as tf
from tensorflow_model_optimization.quantization.keras import vitis_quantizemodel = tf.keras.models.load_model('model.h5')
quantized_model = vitis_quantize.quantize_model(model)
quantized_model.save('quantized_model.h5')

3.更高效的数据预处理方法: 使用OpenCV或其他图像处理库进行高效的数据预处理,尽量减少在内存中的图像副本。在读取图像后立即进行缩放和归一化处理。

Mat img = imread(image_path);
resize(img, img_resized, Size(224, 224));
img_resized.convertTo(img_resized, CV_32FC3);
img_resized = img_resized / 255.0;

💖问题2:推理速度慢💕

解决方案:

1.使用GPU加速: GPU在处理大规模并行计算任务时具有显著优势。在TensorFlow中可以通过指定GPU设备来加速推理。

SessionOptions options;
options.config.mutable_gpu_options()->set_allow_growth(true);
Session* session;
Status status = NewSession(options, &session);
if (!status.ok()) {std::cerr << "Error creating TensorFlow session: " << status.ToString() << std::endl;return;
}

2.利用多线程并行处理: 使用C++的多线程库(如std::thread)来并行处理多个图像,充分利用多核CPU的计算能力。

#include <thread>
#include <vector>void processImage(const std::string& model_path, const std::string& image_path) {classifyImage(model_path, image_path);
}int main(int argc, char** argv) {if (argc < 3) {std::cerr << "Usage: " << argv[0] << " <model_path> <image_paths...>" << std::endl;return 1;}const std::string model_path = argv[1];std::vector<std::string> image_paths;for (int i = 2; i < argc; ++i) {image_paths.push_back(argv[i]);}std::vector<std::thread> threads;for (const auto& image_path : image_paths) {threads.emplace_back(processImage, model_path, image_path);}for (auto& t : threads) {if (t.joinable()) {t.join();}}return 0;
}

3.优化模型结构: 优化模型结构,例如减少模型层数、使用更小的卷积核等,可以提高推理速度。具体方法包括剪枝、合并卷积层等。

4.使用模型量化和裁剪技术: 量化可以显著减少模型大小和计算量,从而提高推理速度。模型裁剪(pruning)通过去除不重要的权重来优化模型。

import tensorflow_model_optimization as tfmotprune_low_magnitude = tfmot.sparsity.keras.prune_low_magnitude
pruning_params = {'pruning_schedule': tfmot.sparsity.keras.PolynomialDecay(initial_sparsity=0.30,final_sparsity=0.70,begin_step=2000,end_step=10000)
}model_for_pruning = prune_low_magnitude(model, **pruning_params)
model_for_pruning.compile(optimizer='adam',loss=tf.keras.losses.categorical_crossentropy,metrics=['accuracy'])model_for_pruning.fit(train_data, train_labels, epochs=2, validation_split=0.1)

💖问题3:模型兼容性问题💕

解决方案:

  1. 确保模型文件和库版本匹配: 在不同平台上使用模型时,确保模型文件与库版本匹配非常重要。例如,TensorFlow模型的版本和TensorFlow库的版本必须一致。

  2. 重新训练和导出模型: 如果遇到兼容性问题,尝试在目标平台上重新训练并导出模型。这样可以确保模型和运行环境的完全兼容。

    import tensorflow as tf# 重新训练模型
    model = tf.keras.models.Sequential([tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)),tf.keras.layers.MaxPooling2D((2, 2)),tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),tf.keras.layers.MaxPooling2D((2, 2)),tf.keras.layers.Flatten(),tf.keras.layers.Dense(64, activation='relu'),tf.keras.layers.Dense(10, activation='softmax')
    ])model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    model.fit(train_images, train_labels, epochs=10)# 导出模型
    model.save('retrained_model.h5')
    

    3.使用中间格式进行转换: 使用ONNX(开放神经网络交换)格式,可以在不同的深度学习框架之间转换模型。可以使用tf2onnx将TensorFlow模型转换为ONNX格式,然后在目标平台上加载ONNX模型。

    import tf2onnx
    import tensorflow as tfmodel = tf.keras.models.load_model('model.h5')
    spec = (tf.TensorSpec((None, 224, 224, 3), tf.float32, name="input"),)
    output_path = "model.onnx"model_proto, _ = tf2onnx.convert.from_keras(model, input_signature=spec, opset=13)
    with open(output_path, "wb") as f:f.write(model_proto.SerializeToString())
    

    然后在C++中使用ONNX Runtime加载和推理ONNX模型:

    #include <onnxruntime/core/providers/cpu/cpu_provider_factory.h>
    #include <onnxruntime/core/providers/tensorrt/tensorrt_provider_factory.h>
    #include <onnxruntime/core/session/onnxruntime_cxx_api.h>int main() {Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "ONNXModel");Ort::SessionOptions session_options;session_options.AppendExecutionProvider_TensorRT();session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);Ort::Session session(env, "model.onnx", session_options);// 输入、输出和推理代码略...return 0;
    }
    

     

    2abe820ccf5e4af399c6049449f1dd1e.png

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/350022.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文入门vim

先来波快问快答。 第一个问题&#xff0c;vim是什么&#xff1f; vim就是一文本编辑器。 第二个问题&#xff0c;我们为什么要使用vim&#xff1f; 好像在终端中可选择使用的文本编辑器也不多&#xff08;其他有&#xff0c;但是相对而言vim用的比较广泛&#xff09; 第三…

automa学习:写一个取某东图书数据的片断

周五了&#xff0c;实在没事情了。正好上午有个朋友问automa的事&#xff0c;心想再写一个练习一下&#xff0c;毕竟&#xff0c;熟能生巧。 目标某东图书&#xff1a; 分析及介绍如下。 1.新建标签页 1.悬停元素。要注意 县 停 .cate_menu_item:nth-child(14) > .cate_…

SQL进阶day10————多表查询

目录 1嵌套子查询 1.1月均完成试卷数不小于3的用户爱作答的类别 1.2月均完成试卷数不小于3的用户爱作答的类别 ​编辑1.3 作答试卷得分大于过80的人的用户等级分布 2合并查询 2.1每个题目和每份试卷被作答的人数和次数 2.2分别满足两个活动的人 3连接查询 3.1满足条件…

【docker】如何解决artalk的跨域访问问题

今天折腾halo的时候&#xff0c;发现artalk出现跨域访问报错&#xff0c;内容如下。 Access to fetch at https://artk.musnow.top/api/stat from origin https://halo.musnow.top has been blocked by CORS policy: The Access-Control-Allow-Origin header contains multipl…

【字符函数】

接下来介绍部分字符函数测试 2. 字符转换函数 1.字符分类函数 1.1iscntrl 注&#xff1a;任何控制字符 检查是否有控制字符 符合为真 int main() {int i 0;char str[] "first line \n second line \n";//判断是否遇到控制字符while (!iscntrl(str[i])){p…

AI办公自动化:kimi批量搜索提取PDF文档中特定文本内容

工作任务&#xff1a;PDF文档中有资料来源这一行&#xff0c;比如&#xff1a; 资料来源&#xff1a;moomoo tech、The Information、Bloomberg、Reuters&#xff0c;浙商证券研究所 数据来源&#xff1a;CSDN、浙商证券研究所 数据来源&#xff1a;CSDN、arXiv、浙商证券研…

效率翻倍!ComfyUI 必装的工作流+模型管理插件 Workspace Manager

一、Workspace Manager 安装方式 插件 Github 网址&#xff1a; https://github.com/11cafe/comfyui-workspace-manager 如果你没有安装 Workspace Manager 插件&#xff0c;可以通过以下 2 种方式安装&#xff1a; ① 通过 ComfyUI Manager 安装&#xff08;推荐&#xff0…

这世上又多了一只爬虫(spiderflow)

让我们一起默念&#xff1a; 爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫爬虫 接着大声喊出来&#xff1a; 一&#xff01;只&#xff01;爬&#xff01;虫&#xff01;呀&#xff01;爬&#xff01;呀&#xff01;爬&#xf…

【机器学习】因TensorFlow所适配的numpy版本不适配,用anaconda降低numpy的版本

目录 0 TensorFlow最高支持的numpy版本 1 激活你的环境&#xff08;如果你正在使用特定的环境&#xff09; 2 查找可用的NumPy版本 3 安装特定版本的NumPy 4. 验证安装 5.&#xff08;可选&#xff09;如果你更改了base环境 0 TensorFlow最高支持的numpy版本 要使用 …

[C#]使用C#部署yolov10的目标检测tensorrt模型

【测试通过环境】 win10 x64vs2019 cuda11.7cudnn8.8.0 TensorRT-8.6.1.6 opencvsharp4.9.0 .NET Framework4.7.2 NVIDIA GeForce RTX 2070 Super cuda和tensorrt版本和上述环境版本不一样的需要重新编译TensorRtExtern.dll&#xff0c;TensorRtExtern源码地址&#xff1a;T…

Rust 实战丨并发构建倒排索引

引言 继上篇 Rust 实战丨倒排索引&#xff0c;本篇我们将参考《Rust 程序设计&#xff08;第二版&#xff09;》中并发编程篇章来实现高并发构建倒排索引。 本篇主要分为以下几个部分&#xff1a; 功能展示&#xff1a;展示我们最终实现的 2 个工具的效果&#xff08;构建索…

MySQL之高级特性(四)

高级特性 查询缓存 什么情况下查询缓存能发挥作用 并不是什么情况下查询缓存都会提高系统性能的。缓存和失效都会带来额外的消耗&#xff0c;所以只有当缓存带来的资源节约大于本身的资源消耗时才会给系统带来性能提升。这跟具体的服务器压力模型有关。理论上&#xff0c;可…

Stable Diffusion本地化部署详细攻略

一、硬件要求 内存&#xff1a;至少16GB 硬盘&#xff1a;至少60GB以上的磁盘空间&#xff0c;推荐SSD固态硬盘 显卡&#xff1a;推荐NVIDIA显卡 显存&#xff1a;至少4GB Stabl Diffusion因为是在本地部署&#xff0c;对显卡的要求比较高&#xff0c;如果经济能力可以的话…

【尚庭公寓SpringBoot + Vue 项目实战】图片上传(十)

【尚庭公寓SpringBoot Vue 项目实战】图片上传&#xff08;十&#xff09; 文章目录 【尚庭公寓SpringBoot Vue 项目实战】图片上传&#xff08;十&#xff09;1、图片上传流程2、图片上传接口查看3、代码开发3.1、配置Minio Client3.2、开发上传图片接口 4、异常处理 1、图片…

open-amv开发环境搭建

open-amv是基于rv1103主控芯片的视觉开发板子 1.板子使用 板子使用type c作为调试口&#xff0c;同时供电&#xff0c;请在电脑上下载adb&#xff0c;当板子通过tpye c与电脑连接后&#xff0c;执行命令adb shell就会进入到板子的linux系统命令行。 2.编译环境 2.1 搭建doc…

碳化硅陶瓷膜良好的性能

碳化硅陶瓷膜是一种高性能的陶瓷材料&#xff0c;以其独特的物理和化学特性&#xff0c;在众多领域展现出了广泛的应用前景。以下是对碳化硅陶瓷膜的详细介绍&#xff1a; 一、基本特性 高强度与高温稳定性&#xff1a;碳化硅陶瓷膜是一种非晶态陶瓷材料&#xff0c;具有极高的…

力扣 面试题17.04.消失的数字

数组nums包含从0到n的所有整数&#xff0c;但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗&#xff1f; 示例 1&#xff1a; 输入&#xff1a;[3,0,1] 输出&#xff1a;2 示例 2&#xff1a; 输入&#xff1a;[9,6,4,2,3,5,7,0,1] 输出&#x…

机器学习笔记 - 用于3D点云数据分类的Point Net的训练

一、数据集 ShapeNet 是一项持续不断的努力,旨在建立一个注释丰富的大型 3D 形状数据集。我们为世界各地的研究人员提供这些数据,以支持计算机图形学、计算机视觉、机器人技术和其他相关学科的研究。ShapeNet 是普林斯顿大学、斯坦福大学和 TTIC 研究人员的合作成果。 Shape…

AXI 1G/2.5G Ethernet Subsystem IP核使用过程中参数配置全解

AXI 1G/2.5G Ethernet Subsystem 是一个为FPGA设计的以太网子系统&#xff0c;它支持1Gbps和2.5Gbps的数据传输速率&#xff0c;使得FPGA能够直接进行高速以太网通信。这个子系统通常包含以太网MAC控制器、GMII&#xff08;千兆媒体独立接口&#xff09;或RGMII&#xff08;简化…

【LLM之RAG】Adaptive-RAG论文阅读笔记

研究背景 文章介绍了大型语言模型&#xff08;LLMs&#xff09;在处理各种复杂查询时的挑战&#xff0c;特别是在不同复杂性的查询处理上可能导致不必要的计算开销或处理不足的问题。为了解决这一问题&#xff0c;文章提出了一种自适应的查询处理框架&#xff0c;动态选择最合…