垃圾分类子项目2 - 加入舵机控制

Linux Swap 子系统:架构、内存管理与虚拟化 Swap Linux Swap机制通过将不活跃内存页移至磁盘或压缩内存,扩展系统有效内存容量,缓解内存压力。传统架构中,逻辑Swap槽与物理存储绑定,导致资源浪费,尤其在使用Zswap等压缩技术时。为此,Vswap与Xswap提出虚拟化方案:前者以XArray实现灵活映射,支持多后端迁移;后者采用稀疏映射,简化管理但容量固定。二者在架构设计、资源记账与动态扩展上各有权衡,反映了内核开发中对性能、可维护性与灵活性的深层考量。 阅读详情

观前提醒: 本文建立子在上一篇的基础上实现,加入了舵机开盖功能

上一篇: 垃圾分类子项目-识别垃圾类型-优快云博客



固定摄像头设备号:

为什么要设置

我们在拔插摄像团队的时候经常遇到摄像头设备号变动的情况,这就导致我们之前设置好的开机自启脚本失效

具体参考大佬的这篇博文: 【linux】linux下摄像头设置固定的设备名-udev-优快云博客

以下是我自己的设备号标注,不必观看

^第一步查看外设的设备号,主设备号:辅助设备号。使用命令:lsusb

Bus 002 Device 003: ID 1e45:8022 Suyin HD Camera

1e45:8022

1e45:8022

查看usb设备的信息
^^^^使用如下命令:udevadm info -a -p /sys/class/video4linux/video0

3.3 编辑规则
^^^^进入/etc/udev/rules.d/文件夹下,新建video.rules文件,文件内容如下:

KERNEL=="video*" , ATTRS{idVendor}== "32e4", ATTRS{idProduct}=="9422", ATTR{index}=="0",MODE:="0777", SYMLINK+="came0"
KERNEL=="video*" , ATTRS{idVendor}== "32e4", ATTRS{idProduct}=="9422", ATTR{index}=="1",MODE:="0777", SYMLINK+="came1

摄像头的USB 接口:

2-1:1.0

KERNELS=="2-1:1.0"


========================================================

主程序代码:

编译命令:


gcc -o test *c *h -I /usr/include/python3.10/ -l python3.10 -l wiringPi

运行:

-E --  保留当前用户的 环境变量
sudo -E ./test 

部分问题解决:

pinMode: You have not called one of the wiringPiSetup   functions, so I'm aborting your program before it crashes anyway.
翻译:  pinMode:您还没有调用wiringPiSetup函数之一,因此我将在您的程序崩溃之前中止它。

解决方式: 在main 函数前面初始化部分加入:  wiringPiSetup();

问题2: 另一个舵机不动
原因: buffer[2] 的复位位置,放下了子线程后面 -- 父子线程是并行的,父线程调用的给buffer[2] 复位,子线程就处理不到buffer[2] 的实际值了
解决方法: 换个位置 -- 放到创建子线程前 -- > 这段代码是父线程单独先执行的 具体可以放到 拍照前面

cpu优化:
问题3:CPU  占用率过高
原因:vscode 远程连接编辑  产生打的node 服务  -- 导致CPU 占有率比较高
解决方法: vscode 上编译完,之后关闭vscode ,在mobaxtrem 里面打开

屏蔽 代码新思路: 

#if0 // 条件一直是不成立,一直不执行 -- 屏蔽
//需要屏蔽的代码
#endif


 

====================================


case1: 实现基本的图像识别控制 舵机 -- 垃圾桶开盖雏形


 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // access()
#include <error.h>  // remove()
#include <wiringPi.h> 
#include <softPwm.h>

#include "uartTool.h"
#include "garbage.h"
#include "pwm.h"

static int detect_process(const char *process_name) // 判断进程是否在运行
{
    int n = -1;
    FILE *strm;
    char buf[128] = {0};
    sprintf(buf, "ps -ax | grep %s|grep -v grep", process_name); // 组合进程名字,为完整命令
    if ((strm = popen(buf, "r")) != NULL)                        // 通过 popen 的 方式去执行
    {
        if (fgets(buf, sizeof(buf), strm) != NULL) // 执行完后 判断是否能拿到正确的进程号,空格分开,第一个字符串就是进程号
        {
            n = atoi(buf); // 拿到就放回 进程号,不然  返回 -1
        }
    }
    else
    {
        return -1; // 执行失败
    }
    pclose(strm);
    return n;
}


int main(int argc, char **argv)
{
    int serial_fd = -1;
    int len = 0;
    int ret = -1;
    char *category = NULL;
    unsigned char buffer[6] = {0xAA, 0x55, 0x00, 0x00, 0x55, 0xAA}; // 初始化 buffer[2] --  关联垃圾类型
    wiringPiSetup();
    garbage_init();                                                 // 先初始化 阿里云接口
    ret = detect_process("mjpg_streamer");                          // 用于判断mjpg_streamer服务是否已经启动
    if (-1 == ret)
    {
        puts("detect process failed");
        goto END;
    }

    serial_fd = myserialOpen(SERIAL_DEV, BAUD); // 初始化串口,打开串口设备(语言模块)

    if (serial_fd == -1)
    { // 初始化串口失败
        goto END;
    }

    while (1) // 等待语言输入
    {
        len = serialGetstring(serial_fd, buffer); // 通过串口获得语言输入

        printf("lend=%d, buf[2]=0x%x\n", len, buffer[2]);
        if (len > 0 && buffer[2] == 0x46) // 判断是否 需要启动识别
        {
            buffer[2] = 0x00; // 判断完后 恢复,方便下次判断
            system(WGET_CMD); // 拍照

            if (access(GARBAGE_FILE, F_OK) == 0) // 判断 文件存在
            {
                category = garbage_category(category); // 通过通过阿里云接口图像识别 获取垃圾类型

                if (strstr(category, "干垃圾"))
                {
                    buffer[2] = 0x41;
                }
                else if (strstr(category, "湿垃圾"))
                {
                    buffer[2] = 0x42;
                }
                else if (strstr(category, "可回收垃圾"))
                {
                    buffer[2] = 0x43;
                }
                else if (strstr(category, "有害垃圾"))
                {
                    buffer[2] = 0x44;
                }
                else
                {
                    buffer[2] = 0x45;
                }
            }
            else
            { // 没有获取到图片
                buffer[2] = 0x45;
                //}
            }
          printf("buffer[2] = 0x%x\n",buffer[2]);  
          serialSendstring(serial_fd, buffer, 6); // 将识别到的数据发送到串口,回传给语音模块
          
          if(buffer[2] == 0x43){
          pwm_write(PWM_GARBAGE1);
          delay (5000); //开盖5s
          pwm_stop(PWM_GARBAGE1); //停止写入波形
          }
          
          else if(buffer[2] == 0x45){
          printf("start\n");
          pwm_write(PWM_GARBAGE2);
          delay (5000); //开盖5s
          pwm_stop(PWM_GARBAGE2); //停止写入波形
          }
          
          
          buffer[2] = 0x00;                       // 发送完后,一堆有效数据位清零,方便下一次调用
          remove(GARBAGE_FILE);                   // 清理缓存 删除刚刚拍摄的图片,避免对下一次拍摄造成干扰

        }
    }
    close(serial_fd); // 关闭串口文件描述符  fd
    END:
        garbage_final();
        return 0;
    }

============================================

常用出错判断; -- 方便定位出错位置

     if(-1 == serial_fd)
     {
       printf("%s | %s | %s:open serial failed\n",__FILE__,__func__,__LINE__);//三个宏的含义: 文件名 - main.c,函数名 - pget_voice ,行号 -  138
       pthread_exit(0); //串口打开失败 -->退出
     }

格式化操作:

alt + shift + 左键  拉下来 就能删掉n列 -- 实现 n 列的缩进 

优化: 不用join 来等待线程退出
 pthread_detach(pthread_self()); // pthread_self -- 拿到自己的线程id --> 与父进程分离,不然开盖等待时间太长影响下一次识别
   
main 函数里的变量和全局变量尽量不要重复,不然肯呢个造成调用错误  

-------------------------


====================================================


case2 - 使用线程优化代码: 


思路: 


在main 里面创建两个线程: 语音线程  和  阿里云交互线程                                                         语音线程 - 负责判断是否有语言命令输入

 阿里云交互线程:  下面有两个线程:舵机控制线程  和  语言播报线程
    这样就有三个线程同时执行了:

      主线程: 处理接收到的信号,进行拍照 和 图像识别,判断垃圾类型

      舵机控制线程:根据 主线程得到的垃圾类型,使用对应舵机(打开对应垃圾桶)
      语音播报线程: 根据主线程得到垃圾类型,播报对应语言

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // access()
#include <error.h>  // remove()
#include <wiringPi.h>
#include <softPwm.h>
#include <pthread.h>

#include "uartTool.h"
#include "garbage.h"
#include "pwm.h"

static int detect_process(const char *process_name) // 判断进程是否在运行
{
    int n = -1;
    FILE *strm;
    char buf[128] = {0};
    sprintf(buf, "ps -ax | grep %s|grep -v grep", process_name); // 组合进程名字,为完整命令
    if ((strm = popen(buf, "r")) != NULL)                        // 通过 popen 的 方式去执行
    {
        if (fgets(buf, sizeof(buf), strm) != NULL) // 执行完后 判断是否能拿到正确的进程号,空格分开,第一个字符串就是进程号
        {
            n = atoi(buf); // 拿到就放回 进程号,不然  返回 -1
        }
    }
    else
    {
        return -1; // 执行失败
    }
    pclose(strm);
    return n;
}



int serial_fd = -1;    // 线程调用 -- 定义为全局
pthread_cond_t cond;   // 设置条件变量
pthread_mutex_t mutex; //  设置线程锁

void *pget_voice(void *arg) // 语言播放线程函数
{
    int len = 0;
    unsigned char buffer[6] = {0xAA, 0x55, 0x00, 0x00, 0x55, 0xAA}; // 初始化 buffer[2] --  关联垃圾类型
    if (-1 == serial_fd)
    {
        printf("%s | %s | %d:open serial failed\n", __FILE__, __func__, __LINE__); // 三个宏的含义: 文件名 - main.c,函数名 - pget_voice ,行号 -  138
        pthread_exit(0);                                                           // 串口打开失败 -->退出
    }

    while (1)
    {
        len = serialGetstring(serial_fd, buffer); // 通过串口获得语言输入
        if (len > 0 && buffer[2] == 0x46)         // 判断是否 接到识别指令
        {
            pthread_mutex_lock(&mutex);   //  先上锁,保证后面执行这块不会被打断
            buffer[2] = 0x00;             // 判断完后的复位
            pthread_cond_signal(&cond);   // 发送信号,告诉阿里云线程开始识别了
            pthread_mutex_unlock(&mutex); // 解锁,与上锁包含的代码块执行的时候不会被打断
        }
    }

    pthread_exit(0);
}

void *popen_trash_can(void *arg) // 开盖
{ 
    pthread_detach(pthread_self());
    unsigned char *buffer = (unsigned char *)arg;
 
      if(buffer[2] == 0x43){
      pwm_write(PWM_GARBAGE1);
      delay (2000); //开盖5s
      pwm_stop(PWM_GARBAGE1); //停止写入波形
      }
      else if(buffer[2] != 0x45){
      pwm_write(PWM_GARBAGE2);
      delay (2000); //开盖5s
      pwm_stop(PWM_GARBAGE2); //停止写入波形
      }
     pthread_exit(0); 
}

void *psend_voice(void *arg) // 发送语言播报
{
     pthread_detach(pthread_self()); // pthread_self -- 拿到自己的线程id --> 与父进程分离,不然开盖等待时间太长影响下一次识别

    unsigned char *buffer = (unsigned char *)arg;
     if (-1 == serial_fd) //判断串口是否打开
    {
        printf("%s | %s | %d:open serial failed\n", __FILE__, __func__, __LINE__); // 三个宏的含义: 文件名 - main.c,函数名 - pget_voice ,行号 -  138
        pthread_exit(0);                                                           // 串口打开失败 -->退出
    }
   
    printf("buffer[2] = 0x%x\n",buffer[2]);  
    if(NULL!=buffer) //有数据
        serialSendstring(serial_fd, buffer, 6); // 将识别到的数据发送到串口,回传给语音模块,语言模块收到数据后进行相应输出 -- 实现语言播报
          


     pthread_exit(0); 
}

void *pcategory(void *arg) // 阿里云 -- 垃圾类型识别线程函数
{

    unsigned char buffer[6] = {0xAA, 0x55, 0x00, 0x00, 0x55, 0xAA}; // 初始化 buffer[2] --  关联垃圾类型
    char *category = NULL;
    pthread_t send_voice_tid,trash_tid;
    
    while (1)
    {
        pthread_mutex_lock(&mutex);       // 拿锁
        pthread_cond_wait(&cond, &mutex); // 等待 接受到信号 -- 才能开始识别
        pthread_mutex_unlock(&mutex);
         // 开始识别  
         buffer[2] = 0x00;  // 拍照前复位         
        system(WGET_CMD); // 拍照
 
        if (access(GARBAGE_FILE, F_OK) == 0) // 判断 文件存在
        {
            category = garbage_category(category); // 通过通过阿里云接口图像识别 获取垃圾类型

            if (strstr(category, "干垃圾"))
            {
                buffer[2] = 0x41;
            }
            else if (strstr(category, "湿垃圾"))
            {
                buffer[2] = 0x42;
            }
            else if (strstr(category, "可回收垃圾"))
            {
                buffer[2] = 0x43;
            }
            else if (strstr(category, "有害垃圾"))
            {
                buffer[2] = 0x44;
            }
            else
            {
                buffer[2] = 0x45;
            }
        }
        else
        { // 没有获取到图片
            buffer[2] = 0x45;
            //}
        }
            
    // 创建打开垃圾桶线程  
    pthread_create(&trash_tid, NULL, popen_trash_can, (void*)buffer);

    // 创建语音播报线程
    pthread_create(&send_voice_tid, NULL,  psend_voice, (void*)buffer);

         // buffer[2] = 0x00;                       // 发送完后,一堆有效数据位清零,方便下一次调用
          remove(GARBAGE_FILE);                   // 清理缓存 删除刚刚拍摄的图片,避免对下一次拍摄造成干扰
    }
    pthread_exit(0);
}

int main(int argc, char **argv)
{

    int len = 0;
    int ret = -1;
    char *category = NULL;
    pthread_t get_voice_tid, category_tid; // 创建线程id

    unsigned char buffer[6] = {0xAA, 0x55, 0x00, 0x00, 0x55, 0xAA}; // 初始化 buffer[2] --  关联垃圾类型
    wiringPiSetup(); // 初始化wiringPi库
    garbage_init();  // 初始化 阿里云接口
    ret = detect_process("mjpg_streamer"); // 用于判断mjpg_streamer服务是否已经启动
    if (-1 == ret)
    {
        puts("detect process failed");
        goto END;
    }

    serial_fd = myserialOpen(SERIAL_DEV, BAUD); // 初始化串口,打开串口设备(语言模块)

    if (serial_fd == -1)
    { // 初始化串口失败
        goto END;
    }
    // 创建语言线程  -- 注意第一个参数类型是指针变量 pthread_t *
    pthread_create(&get_voice_tid, NULL, pcategory, NULL);

    // 创建阿里云交互线程
    pthread_create(&category_tid, NULL, pget_voice, NULL);

    // 第二个参数表示接收到的返回值 -- 没有就NULL
    pthread_join(get_voice_tid, NULL); // 等待线程退出
    pthread_join(category_tid, NULL);

    pthread_mutex_destroy(&mutex); // 释放锁
    pthread_cond_destroy(&cond);  // 释放条件变量
    close(serial_fd); // 关闭串口文件描述符  fd
END:
    garbage_final();

    return 0;
}

HFSS求解器背后的数学原理:从麦克斯韦方程到S参数计算 本文深入解析了Ansys HFSS求解器的数学原理,从麦克斯韦方程出发,详细介绍了模式驱动求解(Driven Solution)和本征模求解(Eigenmode)等核心算法。通过有限元方法和模式匹配技术,HFSS将电磁场问题转化为矩阵方程求解,实现S参数计算和场分布分析,为工程师提供精确的电磁仿真工具。 阅读详情

相关推荐

数据库系统概论课后习题答案(第五版 王珊、萨师煊)

第1章 绪论 1 .试述数据、数据库、数据库系统、数据库管理系统的概念。 答: ( l )数据( Data ) :描述事物的符号记录称为数据。数据的种类有数字、文字、图形、图像、声音、正文等。数据与其语义是不可分的。解析在现代计算机系统中数据的概念是广义的。早期的计算机系统主要用于科学计算,处理的数据是整数、实数、浮点数等传统数学中的数据。现代计算机能存储和处理的对象十分广泛,表

早知晓的博客 11万+

基于stm32单片机舵机控制人体感应智能垃圾桶Proteus仿真和程序源码全套资料

本设计使用C语言编程设计,程序代码采用keil5编写,程序有中文注释,新手容易看懂,仿真采用Proteus软件进行仿真。2、可以通过按键模拟人体红外感应,当有人接近垃圾桶的时候,舵机自动打开垃圾桶,人离开后,舵机自动关闭垃圾桶;1、采用stm32单片机+LCD1602+舵机+按键+LED组成,制作一个人体感应智能垃圾桶设计;3、该智能垃圾桶支持手动按键打开和关闭,按下打开按键,垃圾桶打开,再次按下关闭按键,垃圾桶关闭;5、LCD1602显示当前垃圾桶是处于打开或者是关闭状态;

C51_STM32的博客 838

3D点云目标检测Complex-YOLO(训练篇)(一)———KITTI数据集预处理与制作

KITTI dataset Download dataset KITTI 3D Object Detection Evaluation 2017 link 下载四个部分,共41.4GB 解压后为四部分内容(相机校准矩阵calib、RGB图像image_2、标签label_2、点云数据velodyne) 对应的testing和training数据。其中,training数据为7481张(图片和点云对应的场景),testing数据 7518张(无label_2数据)。 Data Preprocess

“知识最大的敌人不是无知,而是错觉” 7151

智能垃圾分类垃圾桶(K210+stm32mp157)

k210垃圾分类+语音控制+stm32mp157图像采集 UDP传输

weixin_53776127的博客 1万+

Zabbix华为交换机光衰告警

zabbix使用自动发现监控huawei网络设备光衰

qq_31651649的博客 4529

SPSS&Mplus—共同方法偏差(Common Method Bias)控制与检验

共同方法偏差(Common Method Bias)的控制方法:程序控制(Procedural)和统计控制(Statistical)。

m0_54401011的博客 1万+

垃圾分类子项目三 - 添加oled显示

我们要使用oled,就需要添加 i2c 功能需要在这个文件中添加这行,使用 i2c 协议。

mx_jun的博客 290

UVM对象实例化及覆盖的几种方法

UVM对象实例化的方法有多种,以下以object为例: 1)第一种:直接利用new函数进行实例化 trans t1; t1 = new("t1");//利用new函数进行实例化 2)第二种:uvm_component_registry中提供的方法type_id::create,此种方法也是最常使用的方法 trans t2; t2 = trans::type_id::create("t2",this); 3)第三种:uvm_factory中提供的方法creat_object_by_type trans t

沧月九流的博客 3377

理解 Linux 动态库加载:LD_LIBRARY_PATH

flyfish

二分掌柜的 347

未来智能家居解决方案:AI应用架构师的前沿探索

当你加班到深夜回家时,门锁自动识别你的脚步声解锁,玄关灯渐亮成你最爱的暖光,空调早已调到25℃(你夏天的习惯温度),音箱播放着最近循环的爵士乐,茶几上的智能水壶烧好了温水——这不是科幻电影,而是未来智能家居的日常。如何让“冰冷的设备”变成“懂你的伙伴”。我们将深入探讨五大前沿技术(边缘AI、多模态融合、联邦学习、数字孪生、个性化推荐)的底层原理,用“家里的小管家”“邻居互相学习”等生活化比喻简化复杂概念,结合代码示例与架构图还原实现流程,并通过智能卧室、智能厨房等真实案例展示落地路径。

AI天才研究院 1410

在 ABAP 世界把 SAML 2.0 玩明白:跨域 SSO 的通信模式、配置路径与落地实践

摘要 SAML 2.0是ABAP平台实现标准化SSO的推荐方案,提供Front-Channel(浏览器传递SAML报文)和Back-Channel(使用工件绑定通过SOAP兑换断言)两种通信方式。前者包括HTTP Redirect和POST绑定,后者通过Artifact绑定提升安全性。配置重点包括:激活ICF服务、使用SAML2事务码建立信任、设置用户标识映射、选择绑定方式(POST易调试、Artifact更安全)及配置安全策略(签名/加密)。典型流程包括SP-initiated和IdP-initiated

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 293

Linux-iostat命令详解

Linux命令学习记录

m0xin的博客 121

keil工程After Build/Rebuild添加带参.exe实现全流程(2):带参调用.exe的几种方法

keil工程After Build/Rebuild添加带参.exe实现全流程(2):带参调用.exe的几种方法。

kevin1499的博客 1617

USB 技术系列 11 · USB Linux 驱动框架

本文系统解析Linux USB驱动框架,涵盖USB Core、HCD(xhci-hcd/dwc3)、类驱动(CDC/HID/Mass Storage)分层架构,详解usb_device_id匹配、probe/disconnect生命周期及Device Tree配置。结合RISC-V N300实战,揭示Host/Device双模式驱动开发核心逻辑,助力嵌入式BSP开发者掌握USB子系统全栈能力。

peter_pan_study的博客 254

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

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

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

Linux 服务器性能排查手册(2026):CPU、内存、磁盘IO、网络四大瓶颈定位

iptables 四表五链模型、firewalld zone 信任级别、云安全组与主机防火墙的关系与优先级,避坑改了防火墙把自己挡在服务器外面的翻车事故。

2502_91473995的博客 321

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Linux rm 误删文件恢复实操教程

Linux使用rm删除文件时,并不会直接抹除磁盘上的数据,只是移除文件索引,让系统不再识别这块空间。只要没有写入新数据,原有扇区内容就会保留。新文件写入才有可能覆盖这些区域,一旦覆盖就很难找回。恢复的本质就是扫描磁盘,找到这些还存在、但索引丢失的数据条目,再把它们导出保存到其他分区。越早停止写入,恢复成功的概率越高。

海天数据恢复-winhex数据恢复教程 233

深度学习工具包 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")

Windows/Linux下强实时运动控制内核(二):基于Qt的Delta机械手的开发应用

强实时运动控制内核MotionRT750下Qt开发Delta机械手的完整开发流程。

weixin_57350300的博客 241

Linux epoll 一篇讲透:从 select/poll 到红黑树、LT/ET,再到完整 TCP 服务器

一万个客户端已经连上服务器,眼下只有十个客户端发来了数据。服务器怎样把时间花在这十个连接上?理解这个问题,就抓住了 epoll 的主线。接下来,我们沿着“为什么需要它 → 接口怎么用 → 内核如何实现 → LT/ET 怎么写 → 完整服务器怎么运行”的顺序,把知识连起来。**阅读基础:**了解socketbindlistenaccept的基本用途即可。本文示例面向 Linux,服务器使用 C++17,实验脚本使用 Python 3。

2601_94861874的博客 194

Linux 网络基础详解:IP、子网、路由与 ip、ss 命令实战

建库建表、增删改查、连接查询(内连左连右连)、聚合函数、权限控制 GRANT/REVOKE,每条命令配可运行示例,零基础也能跟着敲会 SQL 基础。

2502_91473995的博客 617

Linux、Shell、MySQL 测试卷逐题细讲(下篇:MySQL)

本文为Linux、Shell、MySQL测试卷下半段MySQL部分逐题讲解,包含填空、选择与SQL分析三类题型。填空题覆盖COUNT、HAVING、DISTINCT、事务、约束、索引等核心语法;选择题辨析存储过程、索引类型、ACID、存储引擎、用户管理等考点。SQL大题围绕员工、部门、职位、地点四张关联表,考察多表连接、分组聚合、自连接、相关子查询、NULL处理等高频写法,标注LEFT JOIN统计计数、NULL判断、子查询别名等易错坑点,同时梳理试卷OCR识别带来的干扰问题,重点提示SQL实操中的常见失误

dongziwen1的博客 184

深入浅出聊聊 Linux 的 PageCache 与系统极致性能

本文深入浅出解析了 Linux PageCache 的核心机制,揭示其如何通过“延迟写、预读读”提升系统性能。以监控告警为切入点,阐明 free -h 中 buff/cache 并非真正占用,真正可用内存由 available 决定。结合 Kafka、Elasticsearch、MySQL 等实战场景,说明中间件如何依赖 PageCache 实现极致性能。强调不可手动清理缓存,并建议合理调优脏页参数,避免卡顿。最终指出:内存满≠危机,而是系统高效运行的体现。

小小默:进无止境 483

Linux 下 OpenCode 接入自定义大模型 API 教程:以 DeepSeek-V4.1-Flash-1017 为例

本文介绍在Linux下通过Python脚本配置OpenCode接入自定义大模型API(以DeepSeek-V4.1-Flash-1017为例),实现永久化、非侵入式配置。通过修改~/.config/opencode/opencode.json文件,添加OpenAI兼容服务商BLSC,注册模型并设置APIKey。支持命令行测试、默认模型设定及安全权限控制,操作简单且不影响原有配置。适用于各类支持OpenAI接口的自定义模型服务,提升开发灵活性与安全性。

qq_15060477的博客 128

【Linux 命令实战(06):Linux 文件权限管理,掌握 chmod、chown、chgrp】

chmod:修改文件和目录权限。chown:修改文件所有者,也可以修改所属用户组。chgrp:修改文件所属用户组。r:读取。w:写入。x:执行,对于目录则表示进入和访问能力。ugo:分别代表所有者、所属组和其他用户。我认为,权限管理最重要的不是记住755644这些数字,而是先弄清楚谁需要访问文件、需要执行什么操作,再给出恰当的权限。尤其是在测试服务器和生产服务器上,不要为了图方便直接使用chmod 777。权限开放得越大,并不代表问题解决得越好。

一些微不足道的见解、希望能帮助各位 335

【Linux 命令实战(02):文件与目录操作,掌握 pwd、ls、cd 三个核心命令】

命令作用cd /进入根目录cd ~进入当前用户家目录cd返回当前用户家目录cd …返回上一级目录cd …/…返回上两级目录cd -返回上一次所在目录进入指定目录命令核心用途常用参数pwd查看当前目录-L、-Pls查看文件和目录cd切换目录…、~、-Linux 文件系统的基本结构。绝对路径与相对路径的区别。Tab 自动补全。Shell 通配符。使用&&组合命令。这篇文章主要解决的是如何在 Linux 文件系统中快速定位目录。

一些微不足道的见解、希望能帮助各位 201

Linux篇(五)

本文系统梳理了Linux常用终端快捷键、软件包管理(yum/apt)、服务管理(systemctl)、软链接(ln)、时间与IP配置、域名解析、固定IP设置及网络命令(ping/wget/curl),涵盖日常运维核心操作,助力高效管理Linux环境。

wykyzdq的博客 202

【Linux】进程间通信的基础概念及基于匿名管道的进程池

前面我们介绍了进程的创建、退出和等待,接下来看看进程之间怎样传递数据。这篇从匿名管道入手,再用管道把父子进程联系起来,写一个简单的进程池小demo。而且我把发行版从CentOS切换成Ubuntu了,主要是CentOS已经不维护了,可惜了。。。

qeen87的博客 324
上一篇: 垃圾分类子项目-识别垃圾类型
下一篇: 垃圾分类子项目三 - 添加oled显示
mx_jun
博客等级 码龄5年 1605粉丝 148原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值