C++常用多线程模式

NVIDIA驱动装好了,Gazebo为啥还是卡?手把手教你用optirun搞定GPU加速 本文详细解析了NVIDIA驱动安装后Gazebo仍卡顿的原因,并提供三步精准诊断与GPU加速实战方案。通过optirun快速启用GPU加速,解决OpenGL与显示服务器的配置问题,显著提升仿真性能。适用于ROS、PX4等开发环境,帮助用户充分利用显卡性能。 阅读详情

1. Fork - Join模式

  • 原理:将一个大任务分解为多个子任务,这些子任务在不同的线程中并行执行,当所有子任务完成后,再将它们的结果合并得到最终结果。
  • 优点:充分利用多核处理器的并行能力,提高计算效率;任务分解和结果合并的过程清晰,便于理解和实现分治算法等。
  • 缺点:需要考虑子任务的划分合理性以及线程间的同步问题,以确保结果的正确性。
  • 适用场景:适用于能有效分解为多个独立子任务的计算密集型任务,如大规模数据处理、科学计算中的矩阵运算等。
#include <iostream>
#include <vector>
#include <thread>
#include <numeric>

// 计算数组某区间的和
void sum_subarray(const std::vector<int>& arr, int start, int end, int& result) {
    result = std::accumulate(arr.begin() + start, arr.begin() + end, 0);
}

int main() {
    std::vector<int> arr(1000);
    std::iota(arr.begin(), arr.end(), 1);

    int mid = arr.size() / 2;
    int left_sum = 0, right_sum = 0;

    // Fork: 创建两个线程分别计算左右子数组的和
    std::thread left_thread(sum_subarray, std::ref(arr), 0, mid, std::ref(left_sum));
    std::thread right_thread(sum_subarray, std::ref(arr), mid, arr.size(), std::ref(right_sum));

    // Join: 等待两个线程完成
    left_thread.join();
    right_thread.join();

    int total_sum = left_sum + right_sum;
    std::cout << "Total sum: " << total_sum << std::endl;

    return 0;
}

2. Producer - Consumer模式

  • 原理:生产者线程负责生产数据并将其放入缓冲区,消费者线程从缓冲区取出数据进行处理。通过缓冲区实现生产者和消费者的解耦,使它们可以以不同的速度运行。
  • 优点:提高了程序的并发度和整体性能,生产者和消费者可以独立优化和扩展,代码可读性和维护性较好。
  • 缺点:需要合理设计缓冲区大小和同步机制,避免缓冲区溢出或不足,同时要处理好生产者和消费者之间的同步与互斥问题。
  • 适用场景:广泛应用于各种数据处理场景,如文件读取与处理、网络数据的接收与解析、消息队列系统等。
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>

std::queue<int> task_queue;
std::mutex mtx;
std::condition_variable cv;
bool is_running = true;

// 生产者函数
void producer() {
    for (int i = 0; i < 10; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        {
            std::unique_lock<std::mutex> lock(mtx);
            task_queue.push(i);
            std::cout << "Produced: " << i << std::endl;
        }
        cv.notify_one();
    }
    {
        std::unique_lock<std::mutex> lock(mtx);
        is_running = false;
    }
    cv.notify_all();
}

// 消费者函数
void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return!task_queue.empty() ||!is_running; });
        if (task_queue.empty() &&!is_running) {
            break;
        }
        int task = task_queue.front();
        task_queue.pop();
        std::cout << "Consumed: " << task << std::endl;
    }
}

int main() {
    std::thread producer_thread(producer);
    std::thread consumer_thread(consumer);

    producer_thread.join();
    consumer_thread.join();

    return 0;
}

3. Readers - Writers模式

  • 原理:允许多个读者线程同时访问共享资源,但当有写者线程访问时,所有读者和其他写者都需等待。写者线程具有更高的优先级,以确保数据的一致性。
  • 优点:能有效提高对共享资源的访问效率,在有大量读操作和少量写操作的情况下,能充分利用多核处理器的并行性。
  • 缺点:实现较为复杂,需要精细地控制读写线程的同步与互斥,以避免数据不一致和死锁等问题。
  • 适用场景:常用于数据库系统、文件系统等需要频繁读写共享数据的场景,其中读操作远远多于写操作。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex rw_mutex;
std::condition_variable rw_cv;
int readers = 0;
bool writer_active = false;

// 读者函数
void reader(int id) {
    {
        std::unique_lock<std::mutex> lock(rw_mutex);
        rw_cv.wait(lock, [] { return!writer_active; });
        ++readers;
    }

    std::cout << "Reader " << id << " is reading." << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    {
        std::unique_lock<std::mutex> lock(rw_mutex);
        --readers;
        if (readers == 0) {
            rw_cv.notify_one();
        }
    }
}

// 写者函数
void writer(int id) {
    {
        std::unique_lock<std::mutex> lock(rw_mutex);
        rw_cv.wait(lock, [] { return!writer_active && readers == 0; });
        writer_active = true;
    }

    std::cout << "Writer " << id << " is writing." << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    {
        std::unique_lock<std::mutex> lock(rw_mutex);
        writer_active = false;
        rw_cv.notify_all();
    }
}

int main() {
    std::thread r1(reader, 1);
    std::thread r2(reader, 2);
    std::thread w1(writer, 1);
    std::thread r3(reader, 3);

    r1.join();
    r2.join();
    w1.join();
    r3.join();

    return 0;
}

4. Work Thread模式

  • 原理:有一个任务队列,多个工作线程从队列中获取任务并执行。任务队列可以是优先级队列或普通队列,工作线程根据一定的规则从队列中取出任务进行处理。
  • 优点:实现相对简单,易于扩展工作线程的数量来应对不同的负载需求,能有效利用线程资源,避免线程的频繁创建和销毁。
  • 缺点:任务队列的管理和线程的调度需要一定的开销,可能会出现任务饥饿现象,即某些低优先级任务长时间得不到执行。
  • 适用场景:适用于处理大量异步任务的场景,如网络服务器中的请求处理、分布式系统中的任务调度等。
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <vector>

std::queue<std::function<void()>> work_queue;
std::mutex queue_mutex;
std::condition_variable queue_cv;
bool is_working = true;

// 工作线程函数
void worker() {
    while (true) {
        std::function<void()> task;
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            queue_cv.wait(lock, [] { return!work_queue.empty() ||!is_working; });
            if (work_queue.empty() &&!is_working) {
                break;
            }
            task = std::move(work_queue.front());
            work_queue.pop();
        }
        task();
    }
}

int main() {
    std::vector<std::thread> workers;
    for (int i = 0; i < 3; ++i) {
        workers.emplace_back(worker);
    }

    // 添加任务到队列
    {
        std::unique_lock<std::mutex> lock(queue_mutex);
        for (int i = 0; i < 5; ++i) {
            work_queue.emplace([i] {
                std::cout << "Task " << i << " is being executed." << std::endl;
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            });
        }
    }
    queue_cv.notify_all();

    // 等待所有任务完成
    {
        std::unique_lock<std::mutex> lock(queue_mutex);
        is_working = false;
    }
    queue_cv.notify_all();

    for (auto& t : workers) {
        t.join();
    }

    return 0;
}

5. Actor模式

  • 原理:将整个处理过程分为多个阶段,每个阶段由一个或多个Actor(参与者)负责。数据在这些Actor之间像流水线一样依次传递,每个Actor处理完数据后将其传递给下一个Actor,直到最终处理完成。
  • 优点:提高了系统的吞吐量和响应性,各个阶段可以并行执行,而且易于维护和扩展,每个Actor可以独立开发和测试。
  • 缺点:需要精心设计流水线的各个阶段和数据传递方式,以确保数据的正确流转和系统的稳定性。
  • 适用场景:适用于处理流程较为复杂且可以明确划分为多个阶段的任务,如视频编码解码、图像处理流水线、网络数据包的处理等。
#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>

// 第一个阶段 Actor
class FirstActor {
public:
    std::queue<int> input_queue;
    std::mutex mtx;
    std::condition_variable cv;
    bool is_finished = false;

    void run() {
        for (int i = 0; i < 5; ++i) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
            {
                std::unique_lock<std::mutex> lock(mtx);
                input_queue.push(i);
            }
            cv.notify_one();
        }
        {
            std::unique_lock<std::mutex> lock(mtx);
            is_finished = true;
        }
        cv.notify_all();
    }
};

// 第二个阶段 Actor
class SecondActor {
public:
    FirstActor& first_actor;
    std::queue<int> output_queue;
    std::mutex mtx;
    std::condition_variable cv;
    bool is_finished = false;

    SecondActor(FirstActor& fa) : first_actor(fa) {}

    void run() {
        while (true) {
            int data;
            {
                std::unique_lock<std::mutex> lock(first_actor.mtx);
                first_actor.cv.wait(lock, [this] { return!first_actor.input_queue.empty() || first_actor.is_finished; });
                if (first_actor.input_queue.empty() && first_actor.is_finished) {
                    break;
                }
                data = first_actor.input_queue.front();
                first_actor.input_queue.pop();
            }
            data *= 2;
            {
                std::unique_lock<std::mutex> lock(mtx);
                output_queue.push(data);
            }
            cv.notify_one();
        }
        {
            std::unique_lock<std::mutex> lock(mtx);
            is_finished = true;
        }
        cv.notify_all();
    }
};

// 第三个阶段 Actor
class ThirdActor {
public:
    SecondActor& second_actor;

    ThirdActor(SecondActor& sa) : second_actor(sa) {}

    void run() {
        while (true) {
            int data;
            {
                std::unique_lock<std::mutex> lock(second_actor.mtx);
                second_actor.cv.wait(lock, [this] { return!second_actor.output_queue.empty() || second_actor.is_finished; });
                if (second_actor.output_queue.empty() && second_actor.is_finished) {
                    break;
                }
                data = second_actor.output_queue.front();
                second_actor.output_queue.pop();
            }
            std::cout << "Final result: " << data << std::endl;
        }
    }
};

int main() {
    FirstActor first_actor;
    SecondActor second_actor(first_actor);
    ThirdActor third_actor(second_actor);

    std::thread t1(&FirstActor::run, &first_actor);
    std::thread t2(&SecondActor::run, &second_actor);
    std::thread t3(&ThirdActor::run, &third_actor);

    t1.join();
    t2.join();
    t3.join();

    return 0;
}

6、 Pipeline模式概述

Pipeline(流水线)模式是一种将一个复杂任务分解为多个独立子任务,并让这些子任务像流水线一样依次执行的设计模式。每个子任务负责处理一部分工作,处理完后将结果传递给下一个子任务,最终完成整个复杂任务。这种模式可以提高系统的并发性能和可维护性,因为每个子任务可以独立开发、测试和优化,而且不同的子任务可以并行执行。

应用场景

  • 数据处理流程:例如在图像或视频处理中,一个完整的处理流程可能包括图像读取、降噪、增强、裁剪等多个步骤,每个步骤可以作为一个独立的子任务在流水线上执行。
  • 网络请求处理:在网络服务器中,一个请求可能需要经过接收、解析、验证、业务逻辑处理、响应生成等多个阶段,使用流水线模式可以高效地处理大量请求。

C++实现示例

以下是一个简单的C++示例,模拟一个简单的数据处理流水线,包含三个子任务:数据生成、数据处理和数据输出。

#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>

// 第一个阶段:数据生成
class DataGenerator {
public:
    std::queue<int> outputQueue;
    std::mutex mtx;
    std::condition_variable cv;
    bool isFinished = false;

    void run() {
        for (int i = 0; i < 10; ++i) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
            {
                std::unique_lock<std::mutex> lock(mtx);
                outputQueue.push(i);
            }
            cv.notify_one();
        }
        {
            std::unique_lock<std::mutex> lock(mtx);
            isFinished = true;
        }
        cv.notify_all();
    }
};

// 第二个阶段:数据处理
class DataProcessor {
public:
    DataGenerator& generator;
    std::queue<int> outputQueue;
    std::mutex mtx;
    std::condition_variable cv;
    bool isFinished = false;

    DataProcessor(DataGenerator& gen) : generator(gen) {}

    void run() {
        while (true) {
            int data;
            {
                std::unique_lock<std::mutex> lock(generator.mtx);
                generator.cv.wait(lock, [this] { return!generator.outputQueue.empty() || generator.isFinished; });
                if (generator.outputQueue.empty() && generator.isFinished) {
                    break;
                }
                data = generator.outputQueue.front();
                generator.outputQueue.pop();
            }
            // 简单的数据处理,这里将数据加倍
            data *= 2;
            {
                std::unique_lock<std::mutex> lock(mtx);
                outputQueue.push(data);
            }
            cv.notify_one();
        }
        {
            std::unique_lock<std::mutex> lock(mtx);
            isFinished = true;
        }
        cv.notify_all();
    }
};

// 第三个阶段:数据输出
class DataOutputter {
public:
    DataProcessor& processor;

    DataOutputter(DataProcessor& proc) : processor(proc) {}

    void run() {
        while (true) {
            int data;
            {
                std::unique_lock<std::mutex> lock(processor.mtx);
                processor.cv.wait(lock, [this] { return!processor.outputQueue.empty() || processor.isFinished; });
                if (processor.outputQueue.empty() && processor.isFinished) {
                    break;
                }
                data = processor.outputQueue.front();
                processor.outputQueue.pop();
            }
            std::cout << "Processed data: " << data << std::endl;
        }
    }
};

int main() {
    DataGenerator generator;
    DataProcessor processor(generator);
    DataOutputter outputter(processor);

    std::thread generatorThread(&DataGenerator::run, &generator);
    std::thread processorThread(&DataProcessor::run, &processor);
    std::thread outputterThread(&DataOutputter::run, &outputter);

    generatorThread.join();
    processorThread.join();
    outputterThread.join();

    return 0;
}

代码解释

  1. DataGenerator类:负责生成数据,将生成的数据放入输出队列outputQueue,并通过条件变量cv通知下一个阶段有新数据可用。
  2. DataProcessor类:从DataGenerator的输出队列中获取数据,对数据进行处理(这里简单地将数据加倍),然后将处理后的数据放入自己的输出队列,并通知下一个阶段。
  3. DataOutputter类:从DataProcessor的输出队列中获取数据,并将其输出到控制台。
  4. main函数:创建三个线程分别运行三个阶段的任务,并等待所有线程执行完毕。

通过这种方式,数据在三个阶段之间依次传递,形成了一个简单的流水线。每个阶段可以独立运行,提高了系统的并发性能。

LangGraph实战:用Plan-and-Execute模式5步搭建智能问答机器人(附Tavily搜索集成) 本文详细介绍了如何利用LangGraph的Plan-and-Execute模式,通过规划、执行、动态调整三个核心阶段,构建一个能够处理复杂多步骤问题的智能问答机器人。文章提供了从环境配置、状态管理到核心节点(规划、执行、重新规划)实现的完整实战指南,并集成了Tavily搜索工具,展示了如何将智能任务规划应用于实际信息查询场景。 阅读详情

相关推荐

HMC5883L磁力计在STM32F4上的I2C驱动与数据校准实战

本文详细介绍了HMC5883L磁力计在STM32F4平台上的I2C驱动开发与数据校准实战。通过解析寄存器配置、数据读取处理和椭圆拟合校准算法,帮助开发者实现精准的地磁测量,特别适用于无人机导航和机器人系统中的航向确定与陀螺仪漂移修正。

2y3u4i5o6p的博客 1038

多线程的十二种设计模式

1、Immutable Object模式(不可变对象) 通过将对象变为只读的形式来保证线程安全,是比较好的无锁实现。 无非就是将所有可以变的变量的setter全部对访问者关闭,并且防止有可修改引用泄露出去。 2、Guarded Suspension模式(保护性暂挂) 有时候一些线程在执行的时候需要满足一些条件,倘若没有满足的话便无法执行下去,这个时候我们通过暂挂(跑一跑空循环之类的)来让线程暂时挂起,等待条件满足的时候再继续执行。 在后面的Promise模式中,比如在多线程中写得很多的Future就经常会用

长舒的博客 3443

解决Docker拉取镜像报错:Get https://registry-1.docker.io/v2/: 报错

解决Docker拉取镜像报错: Get “https://registry-1.docker.io/v2/”: net/http: request canceled while waiting for connection问题描述Get "https://registry-1.docker.io/v2/"是docker官方的镜像源,下载很慢的,一般会自己指定国内映射的加速镜像源。

qq_33650333的博客 4174

多线程设计模式-全面详解(学习总结---从入门到深化)

先模拟一个非线程安全的安检口类,旅客(线程)分别手持登机牌和身份证接受工作人 员的检查,示例代码如下所示。 问题分析 首字母相同却未通过检查 为何出现首字母不相同的情况 线程安全 何时适合使用 single thread execution 模式呢?答案如下。 具体代码实现逻辑图如下: 具体代码逻辑实现思路:不可变对象一定是线程安全的。 关于线程不安全的代码示例如下: 运行结果如下: 我们先自己来解决一下这个问题,线程不安全,我给它

1487

别再乱调NvM_WriteBlock了!手把手教你搞懂Autosar NVM状态机与读写时序

本文深入解析Autosar NVM状态机与读写时序,帮助开发者避免常见错误。通过详细的状态机解读、最佳实践代码示例和异常处理策略,提升嵌入式系统中数据存储的可靠性。特别针对NvM_WriteBlock的调用逻辑和状态机机制进行实战讲解,解决工程师在实际开发中遇到的异步写入问题。

weixin_33701617的博客 346

GB28181协议实战:5分钟搞定海康摄像头SIP注册失败问题(附Wireshark抓包分析)

本文详细解析了海康摄像头在GB28181协议下SIP注册失败的7个关键原因及解决方案,包括网络可达性、鉴权参数、NAT穿越等核心问题。通过Wireshark抓包分析,提供快速定位方法,帮助工程师高效解决SIP注册失败问题,提升实时图像联调效率。

weixin_29212867的博客 559

多线程十二种设计模式详解

文章目录前言多线程程序的评价标准Single Threaded Execution 模式Single Threaded Execution 模式简介Single Threaded Execution 模式中的登场角色在什么情况下使用 Single Threaded Execution 呢 ?生存性与死锁可复用性和继承反常临界区的大小和性能Immutable Object(不可变对象) 模式Immutable Object模式简介示例代码Immutable 模式中的登场角色在什么场景下使用Immutable模

qq_42605751的博客 2786

模型预测控制 (MPC, Model Predictive Control) 算法详解及案例分析

模型预测控制是一种基于模型的控制策略,通过在线求解一个有限时域的优化问题,预测系统的未来行为,并根据预测结果调整控制输入,以实现系统的稳定性和性能优化。

闲人编程的博客 2941

多线程的模式

Master-Worker模式是常用的并行计算模式,它的核心思想是系统由两类进程协作工作:Master进程和Worker进程。在生产者-消费者模式中:通常有两类线程,即若干个生产者的线程和若干个消费者的线程。生产者线程负责提交用户请求,消费者线程负责具体处理生产者提交的任务,在生产者和消费者之间通过共享内存缓存区进行通信。在子线程请求并处理数据的过程中,主线程可以继续做别的事情,即异步加载数据。Future模式非常适合在处理耗时很长的业务逻辑时进行使用,可以有效减少系统的响应时间,提高系统的吞吐量。

qq_41273137的博客 374

最新Python爬虫实战(入门爬虫篇)——案例3:爬取二次元cos图片批量下载到本地(附上完整爬虫代码)

本次案例通过Python爬虫技术实现了二次元图片的批量下载。代码采用模块化设计,函数实现cookies的自动解析,简化了配置流程,涵盖“请求列表页→提取详情页URL→请求详情页→提取图片链接→保存图片”的完整流程,与豆瓣案例的核心逻辑和格式完全对齐。学习重点包括:抓包工具定位多层级数据源、正则表达式匹配复杂链接、模拟请求头绕过反爬机制、文件名安全处理及自动化文件管理。需要注意控制请求频率并遵守网站使用规范,适用于入门爬虫实践,帮助学习者掌握多层级页面爬取的核心逻辑。

努力让自己发光,对的人才能迎着光而来 14万+

【AI应用实战-WorkBuddy】WorkBuddy 能帮你做什么(一)

文章摘要: WorkBuddy是一款AI工作助手,专为提升效率而设计,适用于经常处理文档、代码、数据分析等重复性任务的职场人士。它能通过自然语言交互快速完成五大核心场景任务: 周报撰写:输入工作要点,10分钟生成专业周报; 代码调试:解析报错信息,3分钟提供解决方案; Excel分析:自动计算数据趋势并生成图表和结论; 自动化脚本:将重复流程转为脚本,节省98%时间; 文档生成:根据代码自动补充README、API文档和注释。 效果对比:传统手动操作耗时1-3小时的任务,WorkBuddy可将时间缩短至10

353

多线程处理的几种模式—Proactor和Reactor

Proactor和Reactor都是并发编程中的设计模式。他们都是用于派发/分离IO操作事件的。所谓的IO事件也就是诸如read/write的IO操作。"派发/分离"就是将单独的IO事件通知到上层模块。两个模式不同的地方在于,Proactor用于异步IO,而Reactor用于同步IO。     Two patterns that involve event demultiplexors ar...

xiaomin1991222的专栏 433

通过Netlink检测网线插拔

Android/Linux通过netlink编程检测网线插拔。

阿xin*的嵌入式AI 1037

C++11实现简易定时器

定时器timer是多线程编程中经常设计到的工具类 定时器的原理其实很简单: 创建一个新线程 在那个线程里等待 等待指定时长后后做任务 这里用C++11实现了一个简单易用的定时器,包含两种模式: 周期性定时任务执行 单次延时任务执行 timer.hpp #ifndef _TIMER_H_ #define _TIMER_H_ #include <functional> #incl...

踏莎行的博客 9471

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C++单例模式(Singleton)

单例模式(Singleton)是一种设计模式,用来确保一个类在整个程序运行期间只会生成一个实例,并提供一个全局的访问点。这个模式通常用于管理共享资源,例如配置管理、日志记录器或线程池。

m0_72877724的博客 483

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

单件模式(Singleton Pattern)之C++实现

单件模式确保一个类只有一个实例,并提供一个全局访问点。 #include #include using namespace std; class Singleton { public: static Singleton* GetInstance(); void print(); void write(string strTmp); private: Singleton(); sta

张小帅的专栏 988

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C++单例模式精解

因为非静态对象没有唯一性,所以我们要人为加一个判断语句来看是否第一次调用getInstance函数,所以在类中声明一个静态成员(因为我们想用它在静态成员函数中做判断)来接收通过静态成员函数getInstance创建堆上的对象,返回Point*类型的指针,如果该静态成员_pInstance为空就可以创建对象;多个指针指向同一块空间,是比较危险的,如果我像上面代码那样将代码进行回收了,我在用其他指向原来那块空间的指针来访问就会出问题,所以为了避免问题,就使用下面的单例模式的规范。

m0_74696257的博客 955

C++ 线程

C++11 提供了强大的多线程支持,涵盖了线程的创建、同步、共享数据管理等,极大简化了多线程编程的复杂性。

qq_50373827的博客 737

C++编程:多线程文件写入

在 C++ 中实现多线程文件写入有多种方法,各有优缺点。

倔强老吕的博客 915

设计模式(一)创建型模式之单例模板

理论 单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。 为何使用? 在应用系统开发中,我们常常有以下需求: 在多个线程之间,比如初始化一次socket资源;比如servlet环境,共享同一个资源或者操作同一个对象 在整个程序空间使用全局变量,共享资源 大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。 ...

Ascend 191

设计模式之 singleton

<br />常见设计模式的解析和实现(C++)之五-Singleton模式 作用:保证一个类仅有一个实例,并提供一个访问它的全局访问点。<br /><br />UML结构图:<br /><br /><br />解析:<br />Singleton模式其实是对全局静态变量的一个取代策略,上面提到的Singleton模式的两个作用在C++中是通过如下的机制实现的:1)仅有一个实例,提供一个类的静态成员变量,大家知道类的静态成员变量对于一个类的所有对象而言是惟一的 2)提供一个访问它的全局访问点,也就是提

Not_Plain的专栏 599

C++23 std::fstreams基础回顾

是C++标准库中的一个类,用于处理文件的输入输出操作。它继承自和,可以同时进行文件的读写操作,因此被称为“文件流”(File Stream)。通过,开发者可以方便地对文件进行读取、写入和修改等操作,是C++中处理文件的常用工具。在历史上,C++的I/O流库曾经有一个noreplace打开模式,它对应于POSIXopen的O_EXCL标志。但由于可移植性的原因,这个模式没有被包含在C++ 98标准中,因为它在ISO C 90中并不存在。然而,随着时间的推移,ISO C为fopen。

码事漫谈 1214

设计模式 C++单例模式

什么是设计模式(Design Pattern) 设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结 设计模式功能 为了代码可重用性、让代码更容易被他人理解、保证代码可靠性 单例模式 单例模式作用:主要解决一个全局使用的类频繁的创建和销毁的问题。单例模式下可以确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 单例模式的三要素:1、某个类只能有一个实例 2、它必须自行创建这个实例 3、必须自行向整个系统提供这个实例 单例模式使用场景:比如在某个服务器程序中,该服务器

WhiteShirtI的博客 652

ros之cpp快速搭建

ros之cpp快速搭建 单线程callback模式 #include <ros/ros.h> #include <sensor_msgs/PointCloud2.h> #include <pcl/point_cloud.h> #include <pcl/point_types.h> #include <pcl_conversions/pcl_...

weixin_30363817的博客 336

C++ 重点(智能指针,多线程,GDB调试等)

c++重点知识梳理

weixin_41645749的博客 1736

c++技能

c++必须掌握的技能 c++语法 设计模式 socket编程 TCP/IP 多线程编程 一门脚本语言(Lua, Python, Perl等); 数据库 CMAKE/MAKEFILE 一些常用的系统库中头文件的函数功能的测试 工业级代码形成过程 http://qiusuoge.com/11674.html ...

叶落随风 215
上一篇: C++内存分配方式
下一篇: C++无锁队列
越甲八千
博客等级 码龄11年 2959粉丝 553原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值