interface接口--GO面向对象编程思想

Golang interface 接口详解 前言 之前写过,golang 是通过 结构体(struct)-方法(method)-接口(interface) 的组合使用来实现面向对象的思想。在之前的文章 Golang 复合类型 和 Golang method 方法详解 已经详细介绍过 struct 和 method,本文将介绍 golang 面向对象的另一个重要组成部分:接口(interface)。 接口概念 接口是一种抽象的类型,描述了一系列方法的集合,作用是对一系列具有联系的方法做出抽象和概括,类似于其他语言中类的成员变量。不同的是,golang 阅读详情

一、interface接口

interface 是GO语言的基础特性之一。可以理解为一种类型的规范或者约定。它跟java,C# 不太一样,不需要显示说明实现了某个接口,它没有继承或子类或“implements”关键字,只是通过约定的形式,隐式的实现interface 中的方法即可。因此,Golang 中的 interface 让编码更灵活、易扩展。

如何理解go 语言中的interface ? 只需记住以下三点即可:

  1. interface 是方法声明的集合
  2. 任何类型的对象实现了在interface 接口中声明的全部方法,则表明该类型实现了该接口。
  3. interface 可以作为一种数据类型,实现了该接口的任何对象都可以给对应的接口类型变量赋值。

注意:

a. interface 可以被任意对象实现,一个类型/对象也可以实现多个 interface

b. 方法不能重载,如 eat(), eat(s string) 不能同时存在

package main

import "fmt"

type Phone interface {
    call()
}

type NokiaPhone struct {
}

func (nokiaPhone NokiaPhone) call() {
    fmt.Println("I am Nokia, I can call you!")
}

type ApplePhone struct {
}

func (iPhone ApplePhone) call() {
    fmt.Println("I am Apple Phone, I can call you!")
}

func main() {
    var phone Phone
    phone = new(NokiaPhone)
    phone.call()

    phone = new(ApplePhone)
    phone.call()
}

        上述中体现了interface接口的语法,在main函数中,也体现了多态的特性。
同样一个phone的抽象接口,分别指向不同的实体对象,调用的call()方法,打印的效果不同,那么就是体现出了多态的特性。

二、面向对象中的开闭原则

开闭原则定义:
开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
简单的说就是在修改需求的时候,应该尽量通过扩展来实现变化,而不是通过修改已有代码来实现变化。

2.1 平铺式的模块设计


那么作为interface数据类型,他存在的意义在哪呢? 实际上是为了满足一些面向对象的编程思想。我们知道,软件设计的最高目标就是高内聚,低耦合。那么其中有一个设计原则叫开闭原则。什么是开闭原则呢,接下来我们看一个例子:

package main

import "fmt"

//我们要写一个类,Banker银行业务员
type Banker struct {
}

//存款业务
func (this *Banker) Save() {
	fmt.Println( "进行了 存款业务...")
}

//转账业务
func (this *Banker) Transfer() {
	fmt.Println( "进行了 转账业务...")
}

//支付业务
func (this *Banker) Pay() {
	fmt.Println( "进行了 支付业务...")
}

func main() {
	banker := &Banker{}

	banker.Save()
	banker.Transfer()
	banker.Pay()
}


代码很简单,就是一个银行业务员,他可能拥有很多的业务,比如Save()存款、Transfer()转账、Pay()支付等。那么如果这个业务员模块只有这几个方法还好,但是随着我们的程序写的越来越复杂,银行业务员可能就要增加方法,会导致业务员模块越来越臃肿。

这样的设计会导致,当我们去给Banker添加新的业务的时候,会直接修改原有的Banker代码,那么Banker模块的功能会越来越多,出现问题的几率也就越来越大,假如此时Banker已经有99个业务了,现在我们要添加第100个业务,可能由于一次的不小心,导致之前99个业务也一起崩溃,因为所有的业务都在一个Banker类里,他们的耦合度太高,Banker的职责也不够单一,代码的维护成本随着业务的复杂正比成倍增大。

2.2 开闭原则设计

那么,如果我们拥有接口, interface这个东西,那么我们就可以抽象一层出来,制作一个抽象的Banker模块,然后提供一个抽象的方法。 分别根据这个抽象模块,去实现支付Banker(实现支付方法),转账Banker(实现转账方法)
如下:

那么依然可以搞定程序的需求。 然后,当我们想要给Banker添加额外功能的时候,之前我们是直接修改Banker的内容,现在我们可以单独定义一个股票Banker(实现股票方法),到这个系统中。 而且股票Banker的实现成功或者失败都不会影响之前的稳定系统,他很单一,而且独立。

所以以上,当我们给一个系统添加一个功能的时候,不是通过修改代码,而是通过增添代码来完成,那么就是开闭原则的核心思想了。所以要想满足上面的要求,是一定需要interface来提供一层抽象的接口的。

golang代码实现

package main

import "fmt"

//抽象的银行业务员
type AbstractBanker interface{
	DoBusi()	//抽象的处理业务接口
}

//存款的业务员
type SaveBanker struct {
	//AbstractBanker
}

func (sb *SaveBanker) DoBusi() {
	fmt.Println("进行了存款")
}

//转账的业务员
type TransferBanker struct {
	//AbstractBanker
}

func (tb *TransferBanker) DoBusi() {
	fmt.Println("进行了转账")
}

//支付的业务员
type PayBanker struct {
	//AbstractBanker
}

func (pb *PayBanker) DoBusi() {
	fmt.Println("进行了支付")
}


func main() {
	//进行存款
	sb := &SaveBanker{}
	sb.DoBusi()

	//进行转账
	tb := &TransferBanker{}
	tb.DoBusi()
	
	//进行支付
	pb := &PayBanker{}
	pb.DoBusi()

}

当然我们也可以根据AbstractBanker设计一个小框架

//实现架构层(基于抽象层进行业务封装-针对interface接口进行封装)
func BankerBusiness(banker AbstractBanker) {
	//通过接口来向下调用,(多态现象)
	banker.DoBusi()
}

那么main中可以如下实现业务调用:

func main() {
	//进行存款
	BankerBusiness(&SaveBanker{})

	//进行存款
	BankerBusiness(&TransferBanker{})

	//进行存款
	BankerBusiness(&PayBanker{})
}

三、接口的意义

好了,现在interface已经基本了解,那么接口的意义最终在哪里呢,想必现在你已经有了一个初步的认知,实际上接口的最大的意义就是实现多态的思想,就是我们可以根据interface类型来设计API接口,那么这种API接口的适应能力不仅能适应当下所实现的全部模块,也适应未来实现的模块来进行调用。 调用未来可能就是接口的最大意义所在吧,这也是为什么架构师那么值钱,因为良好的架构师是可以针对interface设计一套框架,在未来许多年却依然适用。

四、面向对象的依赖倒转原则

4.1 依赖倒转原则 (面向接口编程)


基本概念:

  • 高层模块不应该依赖低层模块,二者都应该依赖其抽象
  • 抽象不应该依赖细节(具体实现),细节(具体实现)应该依赖抽象

依赖倒转(倒置)的中心思想是面向接口编程

依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。

以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。抽象指的是接口或抽象类,细节就是具体的实现类

使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成

依赖倒转要做的事:

低层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好

变量的声明类型尽量是抽象类或接口, 这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序扩展和优化

继承时遵循里氏替换原则

4.2 耦合度极高的模块关系设计

package main

import "fmt"

// === > 奔驰汽车 <===
type Benz struct {

}

func (this *Benz) Run() {
	fmt.Println("Benz is running...")
}

// === > 宝马汽车  <===
type BMW struct {

}

func (this *BMW) Run() {
	fmt.Println("BMW is running ...")
}


//===> 司机张三  <===
type Zhang3 struct {
	//...
}

func (zhang3 *Zhang3) DriveBenZ(benz *Benz) {
	fmt.Println("zhang3 Drive Benz")
	benz.Run()
}

func (zhang3 *Zhang3) DriveBMW(bmw *BMW) {
	fmt.Println("zhang3 drive BMW")
	bmw.Run()
}

//===> 司机李四 <===
type Li4 struct {
	//...
}

func (li4 *Li4) DriveBenZ(benz *Benz) {
	fmt.Println("li4 Drive Benz")
	benz.Run()
}

func (li4 *Li4) DriveBMW(bmw *BMW) {
	fmt.Println("li4 drive BMW")
	bmw.Run()
}

func main() {
	//业务1 张3开奔驰
	benz := &Benz{}
	zhang3 := &Zhang3{}
	zhang3.DriveBenZ(benz)

	//业务2 李四开宝马
	bmw := &BMW{}
	li4 := &Li4{}
	li4.DriveBMW(bmw)
}

我们来看上面的代码和图中每个模块之间的依赖关系,实际上并没有用到任何的interface接口层的代码,显然最后我们的两个业务 张三开奔驰, 李四开宝马,程序中也都实现了。但是这种设计的问题就在于,小规模没什么问题,但是一旦程序需要扩展,比如我现在要增加一个丰田汽车 或者 司机王五, 那么模块和模块的依赖关系将成指数级递增,想蜘蛛网一样越来越难维护和捋顺。

4.3 面向抽象层依赖倒转

如上图所示,如果我们在设计一个系统的时候,将模块分为3个层次,抽象层、实现层、业务逻辑层。那么,我们首先将抽象层的模块和接口定义出来,这里就需要了interface接口的设计,然后我们依照抽象层,依次实现每个实现层的模块,在我们写实现层代码的时候,实际上我们只需要参考对应的抽象层实现就好了,实现每个模块,也和其他的实现的模块没有关系,这样也符合了上面介绍的开闭原则。这样实现起来每个模块只依赖对象的接口,而和其他模块没关系,依赖关系单一。系统容易扩展和维护。

我们在指定业务逻辑也是一样,只需要参考抽象层的接口来业务就好了,抽象层暴露出来的接口就是我们业务层可以使用的方法,然后可以通过多态的线下,接口指针指向哪个实现模块,调用了就是具体的实现方法,这样我们业务逻辑层也是依赖抽象成编程。

我们就将这种的设计原则叫做依赖倒转原则。

来一起看一下修改的代码:

package main

package main

import "fmt"

// ===== >   抽象层  < ========
type Car interface {
	Run()
}

type Driver interface {
	Drive(car Car)
}

// ===== >   实现层  < ========
type BenZ struct {
	//...
}

func (benz * BenZ) Run() {
	fmt.Println("Benz is running...")
}

type Bmw struct {
	//...
}

func (bmw * Bmw) Run() {
	fmt.Println("Bmw is running...")
}

type Zhang_3 struct {
	//...
}

func (zhang3 *Zhang_3) Drive(car Car) {
	fmt.Println("Zhang3 drive car")
	car.Run()
}

type Li_4 struct {
	//...
}

func (li4 *Li_4) Drive(car Car) {
	fmt.Println("li4 drive car")
	car.Run()
}


// ===== >   业务逻辑层  < ========
func main() {
	//张3 开 宝马
	var bmw Car
	bmw = &Bmw{}

	var zhang3 Driver
	zhang3 = &Zhang_3{}

	zhang3.Drive(bmw)

	//李4 开 奔驰
	var benz Car
	benz = &BenZ{}

	var li4 Driver
	li4 = &Li_4{}

	li4.Drive(benz)
}

4.3 依赖倒转小练习

	 
模拟组装2台电脑
--- 抽象层 ---
	有显卡Card  方法display
	有内存Memory 方法storage
    有处理器CPU   方法calculate
--- 实现层层 ---
	有 Intel因特尔公司 、产品有(显卡、内存、CPU)
	有 Kingston 公司, 产品有(内存3)
	有 NVIDIA 公司, 产品有(显卡)
--- 逻辑层 ---
	1. 组装一台Intel系列的电脑,并运行
        2. 组装一台 Intel CPU  Kingston内存 NVIDIA显卡的电脑,并运行
/*
	模拟组装2台电脑
    --- 抽象层 ---
	有显卡Card  方法display
	有内存Memory 方法storage
    有处理器CPU   方法calculate

    --- 实现层层 ---
	有 Intel因特尔公司 、产品有(显卡、内存、CPU)
	有 Kingston 公司, 产品有(内存3)
	有 NVIDIA 公司, 产品有(显卡)

	--- 逻辑层 ---
	1. 组装一台Intel系列的电脑,并运行
    2. 组装一台 Intel CPU  Kingston内存 NVIDIA显卡的电脑,并运行
*/
package main

import "fmt"

//------  抽象层 -----
type Card interface{
	Display()
}

type Memory interface {
	Storage()
}

type CPU interface {
	Calculate()
}

type Computer struct {
	cpu CPU
	mem Memory
	card Card
}

func NewComputer(cpu CPU, mem Memory, card Card) *Computer{
	return &Computer{
		cpu:cpu,
		mem:mem,
		card:card,
	}
}

func (this *Computer) DoWork() {
	this.cpu.Calculate()
	this.mem.Storage()
	this.card.Display()
}

//------  实现层 -----
//intel
type IntelCPU struct {
	CPU	
}

func (this *IntelCPU) Calculate() {
	fmt.Println("Intel CPU 开始计算了...")
}

type IntelMemory struct {
	Memory
}

func (this *IntelMemory) Storage() {
	fmt.Println("Intel Memory 开始存储了...")
}

type IntelCard struct {
	Card
}

func (this *IntelCard) Display() {
	fmt.Println("Intel Card 开始显示了...")
}

//kingston
type KingstonMemory struct {
	Memory
}

func (this *KingstonMemory) Storage() {
	fmt.Println("Kingston memory storage...")
}

//nvidia
type NvidiaCard struct {
	Card
}

func (this *NvidiaCard) Display() {
	fmt.Println("Nvidia card display...")
}



//------  业务逻辑层 -----
func main() {
	//intel系列的电脑
	com1 := NewComputer(&IntelCPU{}, &IntelMemory{}, &IntelCard{})
	com1.DoWork()

	//杂牌子
	com2 := NewComputer(&IntelCPU{}, &KingstonMemory{}, &NvidiaCard{})
	com2.DoWork()
}

参考

依赖倒转原则 (面向接口编程)_诗水人间的博客-优快云博客_倒转原则.如何使用接口和抽象类连接

面向对象设计的六大原则_iris丶的博客-优快云博客_面向对象六大设计原则

Golang笔记——Interface类型 接口定义了类型应该具备的行为(即方法)。Go 的接口与其他语言(如 Java 或 C++)中的接口有一些不同之处,特别是Go 的接口不需要显式声明实现,即只要类型实现了接口的方法,就自动实现了该接口。Method1() // 方法签名Method2() // 方法签名类型断言:用于在运行时提取接口的具体类型值,如果类型不匹配,可以使用ok变量避免运行时错误。类型开关:允许你对接口值的动态类型进行多分支判断,可以在多个可能的类型之间选择。反射:通过reflect包可以。 阅读详情

相关推荐

golang技术随笔(一)深入理解interface

Go语言的主要设计者之一罗布·派克( Rob Pike)曾经说过,如果只能选择一个Go语言的特 性移植到其他语言中,他会选择接口。可见接口在golang中的地位,及其对gloang这门语言所带来的活力。      golang中的interface是什么 接口相当于是一份契约,它规定了一个对象所能提供的一组操作。要理解golang中接口的概念我们最好还是先来看看别的现代语言是如何实现

justaipanda的专栏 3万+

零基础学 Go 语言(40):Go 中四种类型转换方法

首发自微信公众号《Go编程时光》,如无授权请勿转载 查看本系列教程目录,请点击 零基础小白入门 Go语言 系列教程 Go 语言是静态语言,在编写代码时,就对类型有严格的要求,一旦类型不匹配,就有可能编译失败。 因此在写代码时,就要经常用到类型的转换,这些知识点,对于一个新手来说,可以说是一个不小的门槛,经常要通常搜索引擎来寻找答案。 今天我总结了四种日常开发中最经常遇到的类型转换方法,吃透后就可以自由的进行类型转换。 第一种:显式类型转换 使用对应的类型函数进行转换,还是以上面的例子来帮助理解,使用 i.

王炳明 1878

【GoLang笔记】浅析Go语言Interface类型的语法行为及用法

Go不是一种典型的OO语言,它在语法上不支持类和继承的概念。 没有继承是否就无法拥有多态行为了呢?答案是否定的,Go语言引入了一种新类型—Interface,它在效果上实现了类似于C++的“多态”概念,虽然与C++的多态在语法上并非完全对等,但至少在最终实现的效果上,它有多态的影子。 那么,Go的Interface类型到底是什么呢?怎么使用呢?这正是本篇笔记试图说明的问题。 1. Metho

slvher的专栏 1万+

Golang interface 接口详细原理和使用技巧

Golang interface 接口详细原理和使用技巧 审核中

后端系统和架构 4770

原形网络(Prototypical Networks)基于PyTorch的实现

我在Jay2coomzz的基础上修改了数据处理方式和evaluation_model()方法,作为初学者若有不当之处恳请大家批评指正,原文链接如下: https://blog.youkuaiyun.com/weixin_38471579/article/details/102631018 数据集和源码链接将放到评论区 文章目录1 数据集一个简单的数据集介绍数据集处理2 搭建网络CNNProtonets 1 数据集 一个简单的数据集介绍 Omniglot数据集一共包含1623 类手写体,每一类中包含20 个样本。其中.

weixin_43872532的博客 6636

QT快速配置MSVC2017编译环境(3分钟极简指南)

本文提供了一份3分钟极简指南,帮助开发者快速配置QT的MSVC2017编译环境。通过断网安装、精准勾选组件和配置QT Creator编译器路径等步骤,大幅提升QT开发效率。MSVC2017作为Windows平台高性能C++编译器,特别适合处理大型QT项目,编译速度优势明显。

weixin_30399821的博客 504

GoLang之接口interface

接口interface学习

weixin_52690231的博客 1万+

手把手教你用TP4056和PMOS管搭建锂电池自动切换电路(含元器件选型指南)

本文详细介绍了如何使用TP4056和PMOS管搭建锂电池自动切换电路,包括核心架构设计、元器件选型指南和PCB布局优化。通过智能充电算法和电源路径切换模块,实现外部供电与锂电池的无缝切换,提升便携式设备的电源管理效率。

julia4scientist的博客 890

Go接口类型转换

在 Go语言中,接口类型是一种特殊的类型,它定义了一组方法,但是并不提供具体实现。接口类型可以被任何实现了这组方法的类型实现,这使得我们可以写出非常灵活的代码,以适应各种不同的数据类型。上面的代码定义了一个名为 Animal的接口类型,它包含一个名为 Speak的方法。任何实现了 Speak方法的类型都可以实现 Animal接口类型。上面的代码定义了两个类型:Dog和Cat,它们都实现了 Animal接口类型中的 Speak方法。

GeeCode的博客 1261

(01)ORB-SLAM2源码无死角解析-(38) EPnP 算法原理详解→理论基础二:分情况求得beta初始解

讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解的(01)ORB-SLAM2源码无死角解析链接如下(本文内容来自计算机视觉life ORB-SLAM2 课程课件): (01)ORB-SLAM2源码无死角解析-(00)目录_最新无死角讲解:https://blog.youkuaiyun.com/weixin_43013761/article/details/123092196 文末正下方中心提供了本人联系方式,点击本人照片即可显示WX→官方认证{\color{blue}{文末正下方中心}

江南才尽江南山,年少无知年少狂! 1024

8、内存交织技术详解

本文详细解析了内存交织技术的基本原理、工作机制及实现方式,探讨了其在提升内存访问速度和系统性能中的关键作用。文章还分析了内存交织的优缺点、实际应用场景以及与其他优化技术的结合应用,并提出了未来发展的可能方向,为理解与运用该技术提供了全面参考。

g9h0i1的博客 549

GO语言中封装,继承,和多态

方式是否

成长中de大神 2038

笔试题-2023-加特兰-数字IC设计【纯净题目版】

笔试题-2023-加特兰-数字IC设计【纯净题目版】

w0shishabi的博客 2248

Golang 使用面向对象思想编程

之前对Golang的面向对象理解的不是很深刻。在实际项目中,有遇到这样的情况,才真正理解了面向对象编程带来的好处。 项目是这样的:需要写一个串口服务程序,用来收发数据。 我先选了一个比较简陋的库,可能后续会换。因此需要写一些通用的代码,这样后续换库的时候,可以不用对服务程序进行任何代码修改。 设计了一个接口SerialOperation,包含了一些串口操作的基本方法,我的串口服务程序要用到的方法。因此只要实现了这些方法的串口库,就可以不用任何代码修改,就能直接进行使用。 serialAT.go packag

duapple的博客 900

8、音频运行时系统的架构设计

本文深入探讨了音频运行时系统的分层设计及其优势,包括逻辑层和物理层的功能划分。通过分层设计,开发者可以更轻松地管理和优化音频资源,确保其在不同平台上的高效运行。文章还介绍了平台适配与优化、错误处理与调试以及未来发展方向等内容,为开发者提供了宝贵的参考和指导。

juice的博客 462

Android系统开发面试指南:系统Launcher岗位解析

本文针对上海礼聪Android系统开发岗位(侧重系统Launcher、充电/电池/USB底层开发)提供面试指南。内容涵盖应用开发(启动流程优化)、系统底层(充电状态机、USBOTG)、编程能力(线程安全LRU实现)、问题排查(ANR分析)及沟通协作等核心考点。通过5类典型问题及技术深度解析,帮助候选人系统准备,重点考察Framework源码理解、系统调试能力和工程思维。建议结合PowerManagerService等模块源码和systrace工具进行实践准备,同时注重技术表达与协作能力的展现。

郑伟强dev的专栏 935

go--面向对象

本文介绍了Go语言面向对象编程的基本概念和实现方式。主要内容包括: 结构体使用:通过Student结构体示例展示了创建和初始化结构体的多种方法,包括直接创建、指针方式和地址引用。 封装实现:通过首字母大小写控制访问权限,使用Get/Set方法操作私有字段,确保数据安全性。 组合复用(类似继承):通过结构体嵌入实现代码复用,如Student结构体嵌入Person,可直接访问Person的字段和方法。 方法特性:说明了方法与函数的区别,方法需要绑定指定类型并通过变量调用,支持值接收者和指针接收者。 Go通过结构

dufuvjbj的博客 273

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【Golang】Go语言编程思想(一):接口

对 Golang 的接口 interface 进行学习和记录。

YGGP的博客 1072

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

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

【Golang】interface接口设计原则

interface接口 interface 是GO语言的基础特性之一。可以理解为一种类型的规范或者约定。它跟java,C# 不太一样,不需要显示说明实现了某个接口,它没有继承或子类或“implements”关键字,只是通过约定的形式,隐式的实现interface 中的方法即可。因此,Golang 中的 interface 让编码更灵活、易扩展。 如何理解go 语言中的interface ?只需记住以下三点即可。 interface是方法声明的集合 任何类型的对象实现了在interface接口中声明的全部方

内脏裂了 2万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

golang接口-interface

接口(interface)是 Go 语言中的一种类型,用于定义行为的集合,它通过描述类型必须实现的方法,规定了类型的行为契约。它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

lmryBC49的博客 1609

Golang 之 interface接口全面理解

什么是 interface 在面向对象编程中,可以这么说:“接口定义了对象的行为”, 那么具体的实现行为就取决于对象了。 在Go中,接口是一组方法签名(声明的是一组方法的集合)。当一个类型为接口中的所有方法提供定义时,它被称为实现该接口。它与oop非常相似。接口指定类型应具有的方法,类型决定如何实现这些方法。 让我们来看看这个例子: Animal 类型是一个接口,我们将定义一个 Animal 作为任何可以说话的东西。这是 Go 类型系统的核心概念:我们根据类型可以执行的操作而不是其所能容纳的数据类型

Webben 951

go - interface 接口

Interface 1. 概述   Interface 是一组抽象方法(未具体实现的方法/仅包含方法名参数返回值的方法)的集合,有点像但又不同于其他编程语言中的 interface 。   如果实现了 interface 中的所有方法,即该类/对象就实现了该接口 2. interface 类型   格式: type interfaceName interface { //方

农夫仔 1万+

【Go系列】 Struct与interface

structAge intimport ("fmt""math"c.Scale(2)在上面的例子中,Area方法是一个值接收者方法,它返回圆的面积。Scale方法是一个指针接收者方法,它修改圆的半径。interfaceGo语言的设计哲学与传统的面向对象语言不同,它不提供传统的继承机制,而是使用组合(embedding)和接口来实现代码复用和多态。

u013379032的博客 1411
上一篇: k8s部署fabric 2.4
下一篇: 深入 Go 语言 defer 实现原理
cbmljs
博客等级 码龄10年 329粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值