RNN原理

  • Recurrent Neural Network,循环神经网络

SimpleRNN

  • SimpleRNN其结构如下图所示:
    • 输入为一个向量序列\(\{x_0,x_1,x_2...x_n\}\)
    • 在时间步 \(t\),序列的元素 \(x_t\) 和上一时间步的输出 $h_{t-1} $一起,经过RNN单元处理,产生输出 \(h_t\); \[h_t=ϕ(Wx_t+Uh_{t−1})\] \[y_t=Vh_t\]
    • \(h_t\) 为隐藏层状态,携带了序列截止时间步 \(t\) 的信息;\(y_t\) 为时间步 \(t\) 的输出;\(h_t\) 继续作为下一时间步的输入
    • 整个序列被处理完,最终的输出 \(y_n\) 即为RNN的输出;根据情况,也可返回所有的输出序列 \(\{y_0,y_1,y_2...y_n\}\)
    • 序列的每个元素是经过同一个RNN处理,因此待学习的参数只有一组:\(W,U,V\)

接口 interface

接口定义

接口(interface)是调用方和实现方均需要遵守的一种约束,大家按照统一的方法命名、参数类型和数量来协调逻辑处理的过程。实际上,接口就是一组不需实现的方法声明,不能包含任何变量。到某个自定义类型要使用的时候,在根据具体情况把这些方法写出来(实现)。


反射简介

反射是指在程序运行期对程序本身进行访问和修改的能力。即可以在运行时动态获取变量的各种信息,比如变量的类型(type),类别(kind),如果是结构体变量,还可以获取到结构体本身的信息(字段与方法),通过反射,还可以修改变量的值,可以调用关联的方法。


方法与函数的混合使用

Go语言可以将类型的方法与普通函数作为一个概念,从而简化方法和函数混合作为回调类型时的复杂性。该特性与C#中的delegate类似,调用者无须关心谁来支持调用,系统会自动处理是否调用普通函数还是类型方法。


面向对象三大特性

封装

封装就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其它包只有通过被授权的操作(方法),才能对字段进行操作。


面向对象初识

模拟构造函数

Go和传统的面向对象语言如Java有着很大区别。结构体没有构造函数初始化功能,可以通过以下方式模拟:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import (
"fmt"
)

type Person struct {
Name string
Age int
}

func NewPersonByName(name string) *Person {
return &Person{
Name: name,
}
}

func NewPersonByAge(age int) *Person {
return &Person{
Age: age,
}
}

func main() {

p := NewPersonByName("zs")
fmt.Println(p) // {zs 0}

}

函数

函数声明

函数声明格式

1
2
3
4
func 函数名字 (参数列表) (返回值列表){
// 函数体
return 返回值列表
}

defer延迟执行

defer延迟执行修饰符

在函数中,程序员经常需要创建资源(比如:数据库连接、文件句柄、锁等) ,为了在函数执行完 毕后,及时的释放资源,Go设计者提供了defer(延时机制):

1
2
3
4
5
6
func main() {
//当执行到defer语句时,暂不执行,会将defer后的语句压入到独立的栈中,当函数执行完毕后,再从该栈按照先入后出的方式出栈执行
defer fmt.Println("defer1...")
defer fmt.Println("defer2...")
fmt.Println("main...")
}

package与import

在实际的开发中,我们往往需要在不同的文件中,去调用其它文件的定义的函数,比如 main.go 中,需要使用"fmt"包中的Println()函数:

1
2
package main
import "fmt"