类脑科学实验(四)——LSTM的实现
目录
- 实验背景
- 实验目的
- 实验内容
- 实验原理
- 实验要求
- 实验步骤
- 微信公众号
- 实验代码
实验背景
LSTM(Long Short-Term Memory)是长短期记忆网络,是一种时间递归神经网络,适合于处理和预测时间序列中间隔和延迟相对较长的重要事件。
LSTM区别于RNN的地方,主要就在于它在算法中加入了一个判断信息有用与否的“处理器”,这个处理器作用的结构被称为cell。
一个cell当中被放置了三扇门,分别叫做输入门、遗忘门和输出门。
一个信息进入LSTM的网络当中,可以根据规则来判断是否有用。只有符合算法认证的信息才会留下,不符的信息则通过遗忘门被遗忘。
说起来无非就是一进二出的工作原理,却可以在反复运算下解决神经网络中长期存在的大问题。
目前已经证明,LSTM是解决长序依赖问题的有效技术,并且这种技术的普适性非常高,导致带来的可能性变化非常多。
各研究者根据LSTM纷纷提出了自己的变量版本,这就让LSTM可以处理千变万化的垂直问题。
实验目的
- 加深对Hebb学习模型的理解,能够使用Hebb学习模型解决简单问题
实验内容
- 根据LSTM模型的相关知识,使用Python语言实现一个简单LSTM模型。
实验原理
LSTM是一类可以处理长期依赖问题的特殊的RNN,LSTM主要用来处理长期依赖问题,与传统RNN相比,长时间的信息记忆能力是与生俱来的。所有的RNN链式结构中都有不断重复的模块,用来随时间传递信息。传统的RNN使用十分简单的结构,如下图所示。
LSTM链式结构中重复模块的结构更加复杂,有四个互相交互的层 (如下图所示)。
与传统RNN相比,除了拥有隐藏状态外,LSTM还增加了一个细胞状态,记录随时间传递的信息。在传递过程中,通过当前输入、上一时刻隐藏层状态、上一时刻细胞状态以及门结构来增加或删除细胞状态中的信息。门结构用来控制增加或删除信息的程度,一般由sigmoid函数和向量点乘来实现。
LSTM共包含3个门结构,来控制细胞状态和隐藏状态,下边分别进行介绍。
遗忘门。遗忘门决定上一时刻细胞状态中的多少信息可以传递到当前时刻中。
输入门。输入门用来控制当前输入新生成的信息中有多少信息可以加入到细胞状态中。Ct层用来产生当前时刻新的信息,it层用来控制有多少新信息可以传递给细胞状态。
更新细胞状态。基于遗忘门和输入门的输出,来更新细胞状态。更新后的细胞状态有两部分构成:一,来自上一时刻旧的细胞状态信息;二,当前输入新生成的信息。
输出门,基于更新的细胞状态,输出隐藏状态。
实验要求
- 随机产生0-127之间的两个八位的二进制整数,作为一组输入数据,将这两个数的和作为一个标签,这三个数据组成一组训练数据,训练数据的组数应尽可能多。
- 创建LSTM网络。
- 实现两个八位的二进制整数的加法运算,网络能够输出正确的加法运算结果。
实验步骤
- 定义非线性函数与其导数
- 声明一个查找表
这个表是一个实数与对应二进制表示的映射,帮助我们将实数转化为其二进制表示。
- 设置隐含层与输入、输出层的连接
- 随机生成二进制数字并得到结果,组成数据集
- 计算误差
- 更新权重
- 输出结果
本文参考了以下两篇博客,特此感谢
人人都能用Python写出LSTM-RNN的代码![你的神经网络学习最佳起步]
Anyone Can Learn To Code an LSTM-RNN in Python (Part 1: RNN)
微信公众号
同时也欢迎各位关注我的微信公众号 南木的下午茶
实验代码
import copy, numpy as np
np.random.seed(0)# compute sigmoid nonlinearity
def sigmoid(x):output = 1/(1+np.exp(-x))return output# convert output of sigmoid function to its derivative
def sigmoid_output_to_derivative(output):return output*(1-output)# training dataset generation
int2binary = {}
binary_dim = 8largest_number = pow(2,binary_dim)
binary = np.unpackbits(np.array([range(largest_number)],dtype=np.uint8).T,axis=1)
for i in range(largest_number):int2binary[i] = binary[i]# input variables
alpha = 0.1
input_dim = 2
hidden_dim = 16
output_dim = 1# initialize neural network weights
synapse_0 = 2*np.random.random((input_dim,hidden_dim)) - 1
synapse_1 = 2*np.random.random((hidden_dim,output_dim)) - 1
synapse_h = 2*np.random.random((hidden_dim,hidden_dim)) - 1synapse_0_update = np.zeros_like(synapse_0)
synapse_1_update = np.zeros_like(synapse_1)
synapse_h_update = np.zeros_like(synapse_h)# training logic
for j in range(1000):# generate a simple addition problem (a + b = c)a_int = np.random.randint(largest_number/2) # int versiona = int2binary[a_int] # binary encodingb_int = np.random.randint(largest_number/2) # int versionb = int2binary[b_int] # binary encoding# true answerc_int = a_int + b_intc = int2binary[c_int]# where we'll store our best guess (binary encoded)d = np.zeros_like(c) #初始化一个空的二进制数组,用来存储神经网络的预测值overallError = 0layer_2_deltas = list()layer_1_values = list()layer_1_values.append(np.zeros(hidden_dim))# moving along the positions in the binary encodingfor position in range(binary_dim):# generate input and outputX = np.array([[a[binary_dim - position - 1],b[binary_dim - position - 1]]])y = np.array([[c[binary_dim - position - 1]]]).T# hidden layer (input ~+ prev_hidden)layer_1 = sigmoid(np.dot(X,synapse_0) + np.dot(layer_1_values[-1],synapse_h))# output layer (new binary representation)layer_2 = sigmoid(np.dot(layer_1,synapse_1))# did we miss?... if so, by how much?layer_2_error = y - layer_2layer_2_deltas.append((layer_2_error)*sigmoid_output_to_derivative(layer_2))overallError += np.abs(layer_2_error[0])# decode estimate so we can print it outd[binary_dim - position - 1] = np.round(layer_2[0][0])# store hidden layer so we can use it in the next timesteplayer_1_values.append(copy.deepcopy(layer_1))future_layer_1_delta = np.zeros(hidden_dim)for position in range(binary_dim):X = np.array([[a[position],b[position]]])layer_1 = layer_1_values[-position-1]prev_layer_1 = layer_1_values[-position-2]# error at output layerlayer_2_delta = layer_2_deltas[-position-1]# error at hidden layerlayer_1_delta = (future_layer_1_delta.dot(synapse_h.T) + layer_2_delta.dot(synapse_1.T)) * sigmoid_output_to_derivative(layer_1)# let's update all our weights so we can try againsynapse_1_update += np.atleast_2d(layer_1).T.dot(layer_2_delta)synapse_h_update += np.atleast_2d(prev_layer_1).T.dot(layer_1_delta)synapse_0_update += X.T.dot(layer_1_delta)future_layer_1_delta = layer_1_deltasynapse_0 += synapse_0_update * alphasynapse_1 += synapse_1_update * alphasynapse_h += synapse_h_update * alpha synapse_0_update *= 0synapse_1_update *= 0synapse_h_update *= 0# print out progressif(j % 100 == 1):#print ("Error:" + str(overallError))#print ("Pred(预测值):" + str(d)) out = 0for index,x in enumerate(reversed(d)):out += x*pow(2,index)print("a=")print(a)print("b=")print(b)print ("a+b=")print(c)print("\na = "+str(a_int)+", b = "+str(b_int))print ("a + b = "+str(a_int) + " + " + str(b_int) + " = " + str(c_int))print ("------------")
类脑科学实验(四)——LSTM的实现相关推荐
- 类脑科学实验(三)——Hebb学习
目录 实验背景 实验目的 实验内容 实验原理 实验要求 实验步骤 实验代码 实验背景 由赫布提出的Hebb学习规则是一个无监督学习规则,这种学习的结果是使网络能够提取训练集的统计特性,从而把输入信息按 ...
- 实验四 类和对象;类的继承和派生;多态性; 接口;构造器应用
实验四 类和对象:类的继承和派生:多态性: 接口:构造器应用 一.实验目的 1. 掌握类与对象的关系: 2. 掌握类的定义: 3. 掌握对象的声明及使用: 4. 掌握构造方法的概念及调用时机: 5. ...
- MOOS-ivp 实验四 MOOS编程入门(2)MOOS类讲解
MOOS-ivp 实验四 MOOS编程入门(2)MOOSapp类讲解 文章目录 MOOS-ivp 实验四 MOOS编程入门(2)MOOSapp类讲解 前言 一.MOOSapp父类的结构和方法 1.使用 ...
- 实验四:继承性和派生类 建一个楼房Building为基类,建立住宅类House继承Building,存储房号和面积,建立办公室类Office继承Building,存储办公室名称和电话
/* * 实验四:继承性和派生类 * 内容提要:建立一个楼房基类Building为基类,用于存储地址和楼号 * 建立住宅类House继承Building, 用来存储房号和面积, * 另外建立办公室类O ...
- C++ 实验四 NO. 3 书店的前台收银销售类, 请完成该类定义,实验并且要满足: 1)向购物车中添加书籍;2):查看购物车;3):结算
//************************************************************************************************** ...
- JAVA类与对象tank_实验四 类与对象
实验四类与对象 1.实验目的 1.使用类来封装对象的属性和行为: 2.掌握对象的组合以及参数传递: 3.掌握类变量与实例变量,以及类方法与实例方法的区别 2.实验内容 1.参考实验指导书中P17-25 ...
- 实验四 类和对象; 类的继承和派生;多态性; 接口;构造器应用
一.实验目的 1 . 掌握类与对象的关系: 2 . 掌握类的定义: 3 . 掌握对象的声明及使用: 4 . 掌握构造方法的概念及调用时机: 5 . 掌握构造方法的重载: 6 . 掌握匿名对象的使用. ...
- python实训总结报告书_20172304 实验四python综合实践报告
20172304 实验四python综合实践报告 姓名:段志轩 学号:20172304 指导教师:王志强 课程:Python程序设计 实验时间:2020年5月13日至2020年6月14日 实验分析 本 ...
- 《程序设计与数据结构》实验四报告
学号 2017-2018-2 <程序设计与数据结构>实验四报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 康皓越 学号:20172326 实验教师:王志强 实验日 ...
最新文章
- Linux进程及进程管理命令
- 有关IList 、List 使用Contains的问题
- 北大百年讲堂创新大会小游记
- 纪中B组模拟赛总结(2020.2.22)
- java连加密的mysql_Java 实现加密数据库连接
- JUC阻塞队列BlockingQueue讲解
- linux之同时监控多个日志文件变化
- Tapestry5中的DI
- Centos6.x 64位 安装JDK
- bat脚本保存dir结果_DOS批处理脚本及应用举例
- CentOS 关闭蜂鸣器声音
- 【图像分割】基于matlab GUI二值化+灰白质医学影像分割【含Matlab源码 184期】
- ubuntu文件夹加密_安装Ubuntu后如何加密您的主文件夹
- java xtend_Eclipse Xtend对Java说:我帮你瘦身
- 中华好诗词大学季第二季(五)
- 文字05 自定义字体
- 提高员工执行力,提高项目执行力,提升企业执行力
- 1734: 炮兵阵地
- mysql权限系统的工作原理_MySQL
- RDMA技术详解——原理和三种实现方式
热门文章
- 【干货】微信公众号运营必备工具(完整版)
- linux的shell命令行参数,shell脚本命令行参数简介
- 抖音团购券码核销PHP
- python:输入圆半径计算圆周长、圆面积、圆球表面积(高教社,《Python编程基础及应用》习题3-10)
- 瑞萨G2UL开发板-U盘读写速度测试
- M1芯片import numpy 报错问题
- Nginx正向代理和反向代理详解及其配置
- 计算机上n,在n上的另一台计算机上启动进程
- 微信小程序单个和循环倒计时
- Matplotlib绘图显示缺少中文字体-RuntimeWarning: Glyph 8722 missing from current font.