【Gin框架入门到精通系列06】Gin中的中间件机制

GIN框架介绍以及使用 李文周的博客 阅读详情
AI摘要

本文是Gin框架入门到精通系列的第六篇,介绍了Gin框架中的中间件机制。涵盖中间件概念、原理、类型,Gin内置中间件,自定义中间件开发,代码实践及实用技巧,如性能优化、测试方法和常见使用场景,还给出进阶学习资源。

📚 原创系列: “Gin框架入门到精通系列”

🔄 转载说明: 本文最初发布于"Gopher部落"微信公众号,经原作者授权转载。

🔗 关注原创: 欢迎扫描文末二维码,关注"Gopher部落"微信公众号获取第一手Gin框架技术文章。

📑 Gin框架学习系列导航

本文是【Gin框架入门到精通系列】的第6篇,点击下方链接查看更多文章

👉 数据交互篇
  1. Gin连接数据库
  2. Gin中的中间件机制👈 当前位置
  3. Gin中的参数验证
  4. Gin中的Cookie和Session管理
  5. Gin中的文件上传与处理

🔍 查看完整系列文章

📖 文章导读

在本文中,您将学习到:

  • 中间件的基本概念和在HTTP请求处理中的核心作用
  • Gin框架内置中间件的功能与用法详解
  • 自定义中间件的开发流程和最佳实践
  • 复杂场景下的中间件组织与协作
  • 提升应用安全性和性能的中间件应用技巧
  • 中间件的测试策略与常见问题解决方案

中间件是Gin框架的强大特性之一,掌握它可以让您的代码更加模块化、可维护,并能优雅地处理横切关注点(cross-cutting concerns)。

[外链图片转存中…(img-MMSLpLxL-1742921718352)]

一、导言部分

1.1 本节知识点概述

本文是Gin框架入门到精通系列的第六篇文章,主要介绍Gin框架中的中间件机制。通过本文的学习,你将了解到:

  • 中间件的基本概念和工作原理
  • Gin框架内置的常用中间件
  • 如何创建和使用自定义中间件
  • 中间件在实际项目中的应用场景

中间件是Gin框架的核心特性之一,掌握中间件机制对于构建功能强大、可维护的Web应用至关重要。

1.2 学习目标说明

完成本节学习后,你将能够:

  • 理解HTTP请求处理的生命周期和中间件的执行流程
  • 熟练使用Gin内置的中间件解决常见问题
  • 根据业务需求开发自定义中间件
  • 组织和管理复杂应用中的多个中间件
  • 利用中间件实现日志记录、权限控制、错误处理等功能

1.3 预备知识要求

学习本教程需要以下预备知识:

  • 基本的Go语言知识
  • HTTP协议基础
  • 已完成前五篇教程的学习

二、理论讲解

2.1 中间件的概念与原理

2.1.1 什么是中间件

在Web应用开发中,中间件(Middleware)是位于应用程序与服务器之间的软件组件,能够拦截HTTP请求和响应,并执行特定的逻辑处理。

🔍 中间件解析:可以将中间件想象成一条管道上的过滤器,每个HTTP请求都必须通过这些过滤器才能到达目标处理函数,同样,响应也会通过这些过滤器返回给客户端。

中间件的主要作用包括:

功能类型 说明 实例
预处理请求 在请求到达业务逻辑前进行验证、转换或过滤 身份验证、请求日志记录、输入验证
后处理响应 在响应返回客户端前进行修改或增强 响应压缩、添加安全头、格式转换
横切关注点 处理与业务逻辑无关但必要的功能 性能监控、错误处理、跨域资源共享

在Gin框架中,中间件是一个接收上下文对象*gin.Context的函数,其基本结构为:

func MyMiddleware() gin.HandlerFunc {
   
   
    return func(c *gin.Context) {
   
   
        // 中间件逻辑
    }
}
2.1.2 中间件的工作原理

Gin的中间件工作原理基于责任链模式(Chain of Responsibility Pattern)。这种设计模式允许多个处理器依次处理同一个请求,每个处理器专注于自己的职责领域。

[外链图片转存中…(img-uZFpKkJn-1742921718352)]

在Gin中,每个中间件可以执行以下操作:

  1. 前置操作:在请求处理前执行某些逻辑
  2. 流程控制:通过调用c.Next()将控制权传递给下一个中间件
  3. 后置操作:在下游中间件执行完毕后继续执行操作
  4. 中断处理:通过调用c.Abort()终止后续中间件的执行

以下是中间件执行流程的示意图:

┌─────────────────────────────────────────────────────────────────────┐
│                            HTTP请求                                  │
└───────────────────────────────┬─────────────────────────────────────┘
                                │
┌───────────────────────────────▼─────────────────────────────────────┐
│ 中间件1前置逻辑(如:请求日志记录开始)                              │
└───────────────────────────────┬─────────────────────────────────────┘
                                │
                                │  c.Next()调用
                                │
┌───────────────────────────────▼─────────────────────────────────────┐
│ 中间件2前置逻辑(如:身份验证)                                      │
└───────────────────────────────┬─────────────────────────────────────┘
                                │
                                │  c.Next()调用
                                │
┌───────────────────────────────▼─────────────────────────────────────┐
│ 最终处理函数(如:获取用户列表)                                     │
└───────────────────────────────┬─────────────────────────────────────┘
                                │
                                │  处理函数返回
                                │
┌───────────────────────────────▼─────────────────────────────────────┐
│ 中间件2后置逻辑(如:记录操作日志)                                  │
└───────────────────────────────┬─────────────────────────────────────┘
                                │
                                │  返回到中间件1
                                │
┌───────────────────────────────▼─────────────────────────────────────┐
│ 中间件1后置逻辑(如:计算响应时间)                                  │
└───────────────────────────────┬─────────────────────────────────────┘
                                │
┌───────────────────────────────▼─────────────────────────────────────┐
│                          HTTP响应                                    │
└─────────────────────────────────────────────────────────────────────┘

⚠️ 注意:如果中间件调用了c.Abort(),则后续的中间件不会执行,但当前中间件的剩余代码仍会继续执行。

2.1.3 Gin中间件的类型

在Gin框架中,中间件可以分为以下几种类型:

1. 全局中间件

应用于所有路由,在任何路由处理之前执行。

// 全局中间件:应用于所有路由
router.Use(Logger())
2. 路由组中间件

只应用于特定路由组内的路由。

// 路由组中间件:只应用于authorized组
authorized := router.Group("/")
authorized.Use(AuthRequired())
3. 单个路由中间件

仅应用于单个特定路由。

// 单个路由中间件:只应用于此路由
router.GET("/benchmark", MyBenchLogger(), benchEndpoint)

🌟 最佳实践:按照特殊性原则组织中间件,将通用功能(如日志、错误处理)设为全局中间件,将特定功能(如认证、权限)设为路由组或单个路由中间件。

2.2 Gin内置中间件介绍

Gin框架提供了多种内置中间件,用于解决常见的Web开发需求。这些中间件经过了性能优化,可以直接在项目中使用。

2.2.1 Logger中间件

Logger中间件用于记录HTTP请求的详细信息,如请求方法、路径、状态码、响应时间等。

// 创建一个默认的路由器(包含Logger和Recovery中间件)
r := gin.Default()

// 或者手动添加Logger中间件
r := gin.New()
r.Use(gin.Logger())

Logger中间件输出的日志格式例如:

[GIN] 2023/07/15 - 11:48:16 | 200 |   1.234567ms |      ::1 | GET      "/ping"

日志包含以下信息:

  • 时间戳
  • 状态码
  • 延迟时间
  • 客户端IP
  • 请求方法
  • 请求路径

📝 提示:在生产环境中,你可能需要自定义日志格式或将日志写入文件,这时可以编写自定义的日志中间件。

2.2.2 Recovery中间件

Recovery中间件用于捕获处理过程中的panic异常,防止服务器崩溃,并返回500状态码。

r := gin.New()
r.Use(gin.Recovery())

工作原理:

  1. 使用defer和recover()捕获可能发生的panic
  2. 记录错误堆栈信息
  3. 返回500错误响应
  4. 允许服务继续运行,不会因单个请求处理异常而崩溃

⚠️ 重要提示:在所有生产环境的Gin应用中,Recovery中间件都是必不可少的,它能确保服务的稳定性和可靠性。

2.2.3 BasicAuth中间件

BasicAuth中间件提供了HTTP基本认证功能,用于保护敏感路由。

// 设置授权用户
authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
   
   
    "admin": "password123",
    "user":  "secret",
}))

// 受保护的路由
authorized.GET("/secrets", func(c *gin.Context) {
   
   
    // 获取用户名
    user := c.MustGet(gin.AuthUserKey).(string)
    c.JSON(200, gin.H{
   
   
        "user":    user,
        "message": "You have access to the secrets",
    })
})

BasicAuth工作流程:

  1. 检查请求头中的Authorization字段
  2. 如果不存在或格式不正确,返回401 Unauthorized响应,并带有WWW-Authenticate头
  3. 如果存在且有效,设置用户信息到上下文并继续处理
  4. 在处理函数中可以通过c.MustGet(gin.AuthUserKey)获取用户名

🔒 安全提示:BasicAuth的凭证在传输过程中只是Base64编码,未加密,因此应始终与HTTPS一起使用。

2.2.4 CORS中间件

跨域资源共享(CORS)中间件允许来自不同域的前端应用访问API。

// 使用默认配置
r.Use(cors.Default())

对于更精细的控制,可以使用第三方包github.com/gin-contrib/cors:

r.Use(cors.New(cors.Config{
   
   
    AllowOrigins:     []string{
   
   "https://example.com"},
    AllowMethods:     []string{
   
   "GET", "POST", "PUT", "DELETE"},
    AllowHeaders:     []string{
   
   "Origin", "Content-Type"},
    ExposeHeaders:    []string{
   
   "Content-Length"},
    AllowCredentials: true,
    AllowOriginFunc: func(origin string) bool {
   
   
        return origin == "https://github.com"
    },
    MaxAge: 12 * time.Hour,
}))

CORS配置选项说明:

  • AllowOrigins:允许的源域名
  • AllowMethods:允许的HTTP方法
  • AllowHeaders:允许的请求头
  • ExposeHeaders:向客户端暴露的响应头
  • AllowCredentials:是否允许携带凭证
  • AllowOriginFunc:动态判断源是否允许
  • MaxAge:预检请求结果的缓存时间

🌐 前后端分离提示:在前后端分离的架构中,CORS中间件几乎是必需的,它允许前端应用(通常运行在不同的域或端口)安全地调用后端API。

2.3 自定义中间件开发

2.3.1 中间件的基本结构

Gin中间件本质上是一个返回gin.HandlerFunc的函数,其基本结构如下:

func MiddlewareName() gin.HandlerFunc {
   
   
    // 初始化中间件所需的资源或配置
    
    // 返回实际的中间件处理函数
    return func(c *gin.Context) {
   
   
        // 前置处理逻辑:在请求到达路由处理函数前执行
        
        // 调用下一个中间件
        c.Next()
        
        // 后置处理逻辑:在所有中间件和处理函数执行完后执行
    }
}

这种结构有两个主要优势:

  1. 闭包特性:可以在外层函数中接收配置参数,初始化资源
  2. 两阶段处理:可以轻松实现请求前和响应后的不同逻辑
2.3.2 中间件执行流程控制

在中间件内部,有两个关键函数控制执行流程:

  • c.Next():暂停当前中间件的执行,执行后续中间件,然后再回来执行当前中间件的剩余代码
  • c.Abort():阻止调用链上的后续中间件执行,但不会中断当前中间件的后续代码

执行流程控制示例:

func MyMiddleware() gin.HandlerFunc {
   
   
    return func(c *gin.Context) {
   
   
        // 前置逻辑
        fmt.Println("⬇️ 进入中间件")
        
        // 条件性终止
        if unauthorized(c) {
   
   
            // 设置错误响应
            c.AbortWithStatusJSON(403, gin.H{
   
   "error": "Forbidden"})
            // 注意:即使Abort,下面的代码仍会执行
            fmt.Println("❌ 请求被拒绝")
            return // 使用return阻止执行后续代码
        }
        
        // 继续调用链
        c.Next()
        
        // 后置逻辑,只有未被Abort时才会执行
        fmt.Println("⬆️ 离开中间件")
    }
}

⚠️ 常见错误:调用c.Abort()后,当前中间件的后续代码仍会执行,如果需要完全退出中间件,还需要使用return语句。

中间件流程控制的典型模式:

func MyMiddleware() gin.HandlerFunc {
   
   
    return func(c *gin.Context) {
   
   
        // 模式1:执行所有中间件链
        // ...前置逻辑...
        c.Next()
        // ...后置逻辑...
        
        // 模式2:有条件地终止
        if !someCondition {
   
   
            c.AbortWithStatus(400)
            return
        }
        c.Next()
        
        // 模式3:仅执行前置逻辑,不使用Next()
        // ...处理逻辑...
        // (不调用c.Next(),后续中间件自动执行)
    }
}
2.3.3 中间件之间的数据传递

中间件可以通过Gin上下文在整个请求生命周期内传递数据:

// 第一个中间件设置数据
func Middleware1() gin.HandlerFunc {
   
   
    return func(c *gin.Context) {
   
   
        // 使用Set存储数据
        c.Set("requestID", uuid.New().String())
        c.Set("startTime", time.Now())
        
        c.Next()
        
        // 可以在这里访问和修改数据
    }
}

// 第二个中间件或处理器读取数据
func Middleware2() gin.HandlerFunc {
   
   
    return func(c *gin.Context) {
   
   
        // 使用Get获取数据
        requestID, exists := c.Get("requestID")
        if exists {
   
   
            fmt.Printf("处理请求: %v\n", requestID)
        }
        
        // 使用MustGet获取数据(如果不存在会panic)
        startTime := c.MustGet("startTime").(time.Time)
        
        c.Next()
        
        // 计算处理时间
        duration := time.Since(startTime)
        fmt.Printf("请求处理时间: %v\n", duration)
    }
}

💡 类型安全提示:c.Get()返回的是interface{}类型,需要进行类型断言才能安全使用。如果确定键一定存在,可以使用c.MustGet(),但要注意它会在键不存在时引发panic。

数据传递的最佳实践:

  1. 使用有意义的键名,考虑添加前缀避免冲突
  2. 使用自定义类型增强类型安全
  3. 在错误处理中间件中设置错误信息
  4. 避免在中间件间传递过多复杂数据

三、代码实践

3.1 常用自定义中间件实现

本节将展示几个实用的自定义中间件实现,这些中间件可以直接应用到你的Gin项目中。

3.1.1 日志中间件

下面是一个完整的自定义日志中间件,它记录请求的关键信息和处理时间:

// middleware/logger.go

package middleware

import (
    "log"
    "time"
    
    "github.com/gin-gonic/gin"
)

// Logger 返回一个记录请求详情的日志中间件
func Logger() gin.HandlerFunc {
   
   
    return func(c *gin.Context) {
   
   
        // 开始时间
        startTime := time.Now()
        
        // 设置变量记录请求处理状态
        c.Set("status", 200)
        
        // 请求路径
        path := c.Request.URL.Path
        
        // 请求方法
        method := c.Request.Method
        
        // 处理请求 - 调用下一个中间件或处理函数
        c.Next()
        
        // 结束时间
        endTime := time.Now()
        
        // 执行时间
        latency := endTime.Sub(startTime)
        
        // 获取状态码
        statusCode := c.Writer.Status()
        
        // 请求IP
        clientIP := c.ClientIP()
        
        // 获取错误信息(如果有)
        errorMessage := ""
        if len(c.Errors) > 0 {
   
   
            errorMessage = c.Errors.String()
        }
        
        // 日志格式
        log.Printf("[GIN] %s | %3d | %13v | %15s | %-7s | %s | %s",
            endTime.Format("2006/01/02 - 15:04:05"), // 时间
            statusCode,                              // 状态码
            latency,                                 // 耗时
            clientIP,                                // 客户端IP
            method,                                  // 请求方法
            path,                                    // 请求路径
            errorMessage,                            // 错误信息
        )
        
        // 示例:特定条件下记录更详细的信息
        if statusCode >= 500 {
   
   
            // 记录请求头和响应体等详细信息
            log.Printf("[ERROR] 服务器错误: %v", c.Errors.String())
        }
    }
}

使用方式:

import "myapp/middleware"

func main() {
   
   
    r := gin.New() // 创建不带默认中间件的路由
    
    // 使用自定义日志中间件
    r.Use(middleware.Logger())
    
    // 其他路由设置...
    r.Run(":8080")
}

🛠 定制化提示:在实际应用中,你可能需要:

  • 将日志输出到文件而非控制台
  • 为不同环境设置不同的日志级别
  • 使用结构化日志格式(如JSON)
  • 添加请求ID用于分布式跟踪
3.1.2 认证中间件

JWT(JSON Web Token)认证是现代Web应用中常用的认证方式。以下是一个完整的JWT认证中间件实现:

// middleware/auth.go

package middleware

import (
    "errors"
    "net/http"
    "strings"
    "time"
    
    "github.com/gin-gonic/gin"
    "github.com/golang-jwt/jwt/v4"
)

// JWTConfig JWT配置
type JWTConfig struct {
   
   
    SecretKey     string        // JWT密钥
    Realm         string        // 认证领域
    TokenLookup   string        // Token查找位置
    TokenHeadName string        // Token头部名称
    Timeout       time.Duration // Token超时时间
}

// DefaultJWTConfig 默认JWT配置
var DefaultJWTConfig = JWTConfig{
   
   
    SecretKey:     "secret_key",
    Realm:         "gin jwt",
    TokenLookup:   "header:Authorization",
    TokenHeadName: "Bearer",
    Timeout:       time.Hour * 24,
}

// JWTClaims JWT声明
type JWTClaims struct {
   
   
    UserID uint   
golang——Gin框架及路由介绍 gin框架中采用的路由库是基于httprouter做的支持Restful风格的API,意思是"表面层状态转化",是一个互联网应用程序的API设计理念:URL定位资源。可以创建路由组,为了管理相同的URL。import ("net/http"//将应用切换到“发布模式”以提升性能//创建路由//默认使用了两个中间件Logger(),Recovery()})})//路由组1})})//路由组2})})//监听端口,默认绑定端口8080。 阅读详情

相关推荐

Gin框架使用Zap接收日志

Gin框架使Zap编写Logger中间件和Recover中间件替换默认Logger()和Recover()中间件。

寻找09之夏的博客 2961

【Gin框架入门到精通系列】全系列导航手册

本文是Gin框架入门到精通系列的导航手册,系统梳理了从入门到精通的25篇学习资源。包含基础入门、中间件、高级功能、测试部署和架构实战等全方位内容,为您提供清晰的Gin框架学习路径。

GopherTribe的博客 3396

go语言Gin框架常见面试题

在这个示例中,我们使用c.FormFile方法获取名为"file"的文件,并使用c.SaveUploadedFile方法将其保存到磁盘。要在Gin框架中解析JSON请求体,我们可以使用JSON方法。这个方法接受一个结构体指针作为参数,并将请求体解析为JSON格式,并将其映射到指定的结构体字段中。在这个示例中,我们使用c.ShouldBindJSON方法将请求体解析为JSON格式,并将其映射到User结构体的字段中。低内存占用:在处理大量请求时,Gin使用的内存很少,因此它可以在较小的服务器上运行。

jzpfbpx的博客 853

制造业与工业知识图谱应用

在全球数字化转型背景下,制造业面临创新周期缩短、质量管控精细化等挑战。知识图谱技术通过结构化表示工业知识,为智能制造提供关键技术支撑。工业知识图谱具有专业性强、多源异构数据融合、实时性要求高等特点,其构建流程涵盖本体设计、知识抽取与整合等环节。研究显示,知识图谱与大模型结合可提升工业场景的智能化水平,在设备故障诊断、供应链优化等领域具有显著应用价值。该技术有望成为制造业数字化转型的核心驱动力。

分享一些感兴趣的技术方面 1442

Win11下WSL2安装Ubuntu22.04避坑指南:从镜像源到C++环境配置

本文提供了一份详细的Win11下WSL2安装Ubuntu22.04的实战避坑指南。内容涵盖从WSL2核心安装、自定义安装路径,到更换国内镜像源以解决更新缓慢问题,并一站式配置完整的C++开发环境(包括GCC、CMake、vcpkg等),最后分享提升开发体验的进阶技巧,助你在Windows上打造高效的Linux开发工作站。

weixin_29260291的博客 562

Transformer凭什么取代RNN?深入拆解自注意力机制与梯度消失问题的终极对决

本文深入探讨了Transformer如何通过自注意力机制解决RNN的梯度消失问题,成为自然语言处理领域的新标准。通过对比RNN和Transformer的架构差异,揭示了自注意力机制在并行计算、长期依赖处理等方面的技术优势,并提供了实际任务中的性能对比数据。

f6g7h8i9j的博客 190

STM32版CCD线性摄像头寻线寻迹小车_stm32接ccd

目前大多数的小车寻线寻迹都是用红外对管寻线,这是比较简单也比较成熟的技术方案,且成本也低。本文将介绍使用CCD线性摄像头寻线寻迹。TSL1401 线性传感器由一个 1x128 的光电二极管阵列、相关的电荷放大电路以及一个内部像素数据保功能组成。内部像素数据保功能可以为所有像素点提供同时积分的开始和停止时间。该阵列由 128 个像素组成,每个像素的感光面积为 3,524.3 平方微米。像素之间的间隔为 8μm。内部控制逻辑简化了操作,该模块需要串行输入(SI)信号和时钟信号(CLK)。

2401_87557129的博客 3229

微信小程序云开发 - 实现商家转账到零钱(微信企业付款到零钱) V3功能流程及完整实例代码,过微信云开发的云函数实现企业付款到零钱(提供详细示例源码纯云函数实现,证书、密钥、签名等各种常见问题解决方案

企业付款到零钱(微信小程序提现功能,提现到零钱)微信小程序-云函数实现微信企业付款到零钱功能,实现微信商户号中的企业付款到零钱的功能,微信小程序+云开发+商家转账至零钱+微信小程序用户提现,使用云开发环境的云函数实现微信小程序的支付功能,微信小程序实现微信企业付款到零钱功能的流程,V3 V2基于微信云开发的商家转账至零钱,小程序云函数企业付款到零钱功能实现,云开发实现微信商户支付企业付款到零钱功能,不用服务器纯云函数实现,详细示例代码demo教程,API证书错误,转账不到账怎么办,密钥生成有误,转账失败,有

🏆 前端领域优质创作者 1万+

越野换了逐飞的ips200pro的屏幕后代码烧录中报错: “Cannot initialize device connection” 和 “Flashing failed” ...如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1150

YOLOv11改进 | 引入SFSConv空间频率选择卷积(含SFSC3k2二次创新),空间频率特征协同作用,检测性能全面提升

本文提出在YOLOv11中引入SFSConv空间频率选择卷积模块,通过显式分离和动态融合空间域与频率域特征,解决传统卷积对多尺度目标检测的局限性。SFSConv包含空间频率分离、动态权重融合和协同特征重建三个核心机制,并进一步创新提出SFSC3k2结构,通过双路频率分支增强特征协同作用。该改进显著提升了YOLOv11在遥感、医学等多尺度复杂场景下的检测性能,实验显示在微小目标检测任务中mAP提升5%-10%。代码实现展示了SFSConv模块的核心逻辑及其在PyTorch中的高效实现。

走向CTO的路上... 767

【DRAM存储器六十七】DDR5介绍--训练相关之write leveling

详述DDR5 write leveling细节

highman110的博客 287

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

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

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

上一篇: 【Gin框架入门到精通系列05】Gin连接数据库
下一篇: 【Gin框架入门到精通系列07】Gin中的参数验证
Gopher部落
博客等级 码龄2年 784粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gopher部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值