技术标签: tensorflow LSTM 长短时记忆网络 机器学习 神经网络学习小记录 人工智能
又出去和女朋友快乐的玩耍了,但是不要忘了学习噢。
在过去的时间里我们学习了RNN循环神经网络,其结构示意图是这样的:
其存在的最大问题是,当w1、w2、w3这些值小于0时,如果一句话够长,那么其在神经网络进行反向传播与前向传播时,存在梯度消失的问题。
0.925=0.07,如果一句话有20到30个字,那么第一个字的隐含层输出传递到最后,将会变为原来的0.07倍,相比于最后一个字的影响,大大降低。
其具体情况是这样的:
长短时记忆网络就是为了解决梯度消失的问题出现的。
原始RNN的隐藏层只有一个状态h,从头传递到尾,它对于短期的输入非常敏感。
如果我们再增加一个状态c,让它来保存长期的状态,问题就可以解决了。
对于RNN和LSTM而言,其两个step单元的对比如下。
我们把LSTM的结构按照时间维度展开:
我们可以看出,在n时刻,LSTM的输入有三个:
1、当前时刻网络的输入值;
2、上一时刻LSTM的输出值;
3、上一时刻的单元状态。
LSTM的输出有两个:
1、当前时刻LSTM输出值;
2、当前时刻的单元状态。
LSTM用两个门来控制单元状态cn的内容:
1、遗忘门(forget gate),它决定了上一时刻的单元状态cn-1有多少保留到当前时刻;
2、输入门(input gate),它决定了当前时刻网络的输入c’n有多少保存到单元状态。
LSTM用一个门来控制当前输出值hn的内容:
输出门(output gate),它决定了当前时刻单元状态cn有多少输出。
tf.contrib.rnn.BasicLSTMCell(
num_units,
forget_bias=1.0,
state_is_tuple=True,
activation=None,
reuse=None,
name=None,
dtype=None
)
在使用时,可以定义为:
lstm_cell = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)
在定义完成后,可以进行状态初始化:
self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
tf.nn.dynamic_rnn(
cell,
inputs,
sequence_length=None,
initial_state=None,
dtype=None,
parallel_iterations=None,
swap_memory=False,
time_major=False,
scope=None
)
在LSTM的最后,需要用该函数得出结果。
self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(
lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
返回的是一个元组 (outputs, state):
outputs:LSTM的最后一层的输出,是一个tensor。如果为time_major== False,则它的shape为[batch_size,max_time,cell.output_size]。如果为time_major== True,则它的shape为[max_time,batch_size,cell.output_size]。
states:states是一个tensor。state是最终的状态,也就是序列中最后一个cell输出的状态。一般情况下states的形状为 [batch_size, cell.output_size],但当输入的cell为BasicLSTMCell时,states的形状为[2,batch_size, cell.output_size ],其中2也对应着LSTM中的cell state和hidden state。
整个LSTM的定义过程为:
def add_input_layer(self,):
#X最开始的形状为(256 batch,28 steps,28 inputs)
#转化为(256 batch*28 steps,128 hidden)
l_in_x = tf.reshape(self.xs, [-1, self.input_size], name='to_2D')
#获取Ws和Bs
Ws_in = self._weight_variable([self.input_size, self.cell_size])
bs_in = self._bias_variable([self.cell_size])
#转化为(256 batch*28 steps,256 hidden)
with tf.name_scope('Wx_plus_b'):
l_in_y = tf.matmul(l_in_x, Ws_in) + bs_in
# (batch * n_steps, cell_size) ==> (batch, n_steps, cell_size)
# (256*28,256)->(256,28,256)
self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='to_3D')
def add_cell(self):
#神经元个数
lstm_cell = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)
#每一次传入的batch的大小
with tf.name_scope('initial_state'):
self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
#不是主列
self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(
lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
def add_output_layer(self):
#设置Ws,Bs
Ws_out = self._weight_variable([self.cell_size, self.output_size])
bs_out = self._bias_variable([self.output_size])
# shape = (batch,output_size)
# (256,10)
with tf.name_scope('Wx_plus_b'):
self.pred = tf.matmul(self.cell_final_state[-1], Ws_out) + bs_out
该例子为手写体识别例子,将手写体的28行分别作为每一个step的输入,输入维度均为28列。
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
mnist = input_data.read_data_sets("MNIST_data",one_hot = "true")
BATCH_SIZE = 256 # 每一个batch的数据数量
TIME_STEPS = 28 # 图像共28行,分为28个step进行传输
INPUT_SIZE = 28 # 图像共28列
OUTPUT_SIZE = 10 # 共10个输出
CELL_SIZE = 256 # RNN 的 hidden unit size,隐含层神经元的个数
LR = 1e-3 # learning rate,学习率
def get_batch(): #获取训练的batch
batch_xs,batch_ys = mnist.train.next_batch(BATCH_SIZE)
batch_xs = batch_xs.reshape([BATCH_SIZE,TIME_STEPS,INPUT_SIZE])
return [batch_xs,batch_ys]
class LSTMRNN(object): #构建LSTM的类
def __init__(self, n_steps, input_size, output_size, cell_size, batch_size):
self.n_steps = n_steps
self.input_size = input_size
self.output_size = output_size
self.cell_size = cell_size
self.batch_size = batch_size
#输入输出
with tf.name_scope('inputs'):
self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs')
self.ys = tf.placeholder(tf.float32, [None, output_size], name='ys')
#直接加层
with tf.variable_scope('in_hidden'):
self.add_input_layer()
#增加LSTM的cell
with tf.variable_scope('LSTM_cell'):
self.add_cell()
#直接加层
with tf.variable_scope('out_hidden'):
self.add_output_layer()
#计算损失值
with tf.name_scope('cost'):
self.compute_cost()
#训练
with tf.name_scope('train'):
self.train_op = tf.train.AdamOptimizer(LR).minimize(self.cost)
#正确率计算
self.correct_pre = tf.equal(tf.argmax(self.ys,1),tf.argmax(self.pred,1))
self.accuracy = tf.reduce_mean(tf.cast(self.correct_pre,tf.float32))
def add_input_layer(self,):
#X最开始的形状为(256 batch,28 steps,28 inputs)
#转化为(256 batch*28 steps,128 hidden)
l_in_x = tf.reshape(self.xs, [-1, self.input_size], name='to_2D')
#获取Ws和Bs
Ws_in = self._weight_variable([self.input_size, self.cell_size])
bs_in = self._bias_variable([self.cell_size])
#转化为(256 batch*28 steps,256 hidden)
with tf.name_scope('Wx_plus_b'):
l_in_y = tf.matmul(l_in_x, Ws_in) + bs_in
# (batch * n_steps, cell_size) ==> (batch, n_steps, cell_size)
# (256*28,256)->(256,28,256)
self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='to_3D')
def add_cell(self):
#神经元个数
lstm_cell = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)
#每一次传入的batch的大小
with tf.name_scope('initial_state'):
self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
#不是主列
self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(
lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
def add_output_layer(self):
#设置Ws,Bs
Ws_out = self._weight_variable([self.cell_size, self.output_size])
bs_out = self._bias_variable([self.output_size])
# shape = (batch,output_size)
# (256,10)
with tf.name_scope('Wx_plus_b'):
self.pred = tf.matmul(self.cell_final_state[-1], Ws_out) + bs_out
def compute_cost(self):
self.cost = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(logits = self.pred,labels = self.ys)
)
def _weight_variable(self, shape, name='weights'):
initializer = np.random.normal(0.0,1.0 ,size=shape)
return tf.Variable(initializer, name=name,dtype = tf.float32)
def _bias_variable(self, shape, name='biases'):
initializer = np.ones(shape=shape)*0.1
return tf.Variable(initializer, name=name,dtype = tf.float32)
if __name__ == '__main__':
#搭建 LSTMRNN 模型
model = LSTMRNN(TIME_STEPS, INPUT_SIZE, OUTPUT_SIZE, CELL_SIZE, BATCH_SIZE)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
#训练10000次
for i in range(10000):
xs, ys = get_batch() #提取 batch data
if i == 0:
#初始化data
feed_dict = {
model.xs: xs,
model.ys: ys,
}
else:
feed_dict = {
model.xs: xs,
model.ys: ys,
model.cell_init_state: state #保持 state 的连续性
}
#训练
_, cost, state, pred = sess.run(
[model.train_op, model.cost, model.cell_final_state, model.pred],
feed_dict=feed_dict)
#打印精确度结果
if i % 20 == 0:
print(sess.run(model.accuracy,feed_dict = {
model.xs: xs,
model.ys: ys,
model.cell_init_state: state #保持 state 的连续性
}))
希望得到朋友们的喜欢。
有不懂的朋友可以评论询问噢。
Android Studio 插件之 Android ButterKnife ZeleznyButterKnife程序员都是懒惰的,不会偷懒的程序员都不是好的程序员。大部分Android开发应该都知道 @JakeWharton 大神的 ButterKnife 注解库,使用这个库我们可以不用写很多无聊的 findViewById() 和 setOnClickListener() 等代码。 Butte
转自:http://blog.sina.com.cn/s/blog_685febef01011bvv.html无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用在编程时经常遇到“无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用”这样的错误,最近看了一些这方面的书籍,现将解决方案大概叙述一下:连
第十六章:无尽加班何时休——状态模式 状态模式 : 优点:缺点: 所使用的项目是:工作状态 功能: 界面: 设计思路:收获: 附:1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理。最直接的解决方案是将这些所有可能发生的情况全都考虑到。然后使用if... ellse语句来做状态判断来...
公司一直是前后端分离的,最近集团开始推进中后台可视化开发组件(基于React封装),跟师兄聊起来也听说最近对后台开发人员的前端能力也是越来越重视了。所以作为一名后端,了解下前端的框架对自己也是大有好处的! 首先,博主由于在小公司做过,有一定的前端基础,但是学习React框架的时候还是遇到了一些阻力。因为前端框架的一些思想是和后端完全不同的,特别是React这个面向组件的动...
使用extract_first()设置默认值当我们使用scrapy爬虫时,经常用xpath提取信息。但是,当xpath提取不到内容时会返回None值,None值在后续的处理过程中很不友好,所以我们可以使用extract_first()设置默认值。>>> test = response.css(".lllaaa a").extract_first("默认值")>>...
文章目录学习目标:1、什么是软考2、软考的好处3、系统规划和管理师考试相关(1)考试形式:笔试(2)考试科目:三科,每科75分。每科45分才能通过(3)如何成为优秀的系统规划与管理师(4)学习技巧(5)关键知识要点收获学习安排进度执行情况:学习目标:90天通过2021年上半年的系统规划与管理师考试之之软高之系统规划和管理师考试相关1、什么是软考 计算机技术与软件专业技术资格(水平)考试是在人力资源和社会保障部、工业和信息化部领导下 的国家级考试,https://www.ruankao.org
以通俗易懂的方式解释了BatchNorm和LayerNorm的原理,并指出它们的区别
使用 Nginx Upload Module 上传文件安装编译环境:yum -y install gcc gcc-c++kernel-devel创建目录:mkdir /tmp/nginx进入目录:cd /tmp/nginxwget http://www.zlib.net/zlib-1.2.11.tar.gzwget http://nginx.org/download/nginx-1.10.2.ta...
相信大家在使用nextjs的时候,难免遇到一些坑。其实可能大部分原因在于 nextjs 做了很多封装,我们可能不能第一时间搞清楚包括它相关的所有配置,比如其中的webpack配置。我前面也写过 SSR 实现的文章和简单的轮子《实现ssr服务端渲染》,也知道 SSR 要实现为 nextjs 这样的三方框架,还是会需要经历很复杂编码的。总归有时候遇到问题,在网上也查不到一个正确的解决方案。比如,我...
Docker容器技术(3)—— ELK集群搭建与Mysql日志采集基于Docker搭建ELK,并采集Mysql日志获取Docker镜像创建ELK专用Docker网络Elasticsearch创建es数据目录启动ElasticsearchLogstash创建存放logstash使用的配置文件目录编写logstash.conf启动logstash容器Kibana启动kibana容器配置索引查看日志基于Docker搭建ELK,并采集Mysql日志 系统版本:Centos7.8 2003 Mysql版本:
1. Vue.js简介Vue.js是一个构建数据驱动的web界面的框架Vue.js的目标是实现响应的数据绑定和组合的视觉组件.Vue.js的核心是一个响应的数据绑定系统.2.data 用于定义属性,实例中有三个属性分别为:site、url、alexa。methods 用于定义的函数,可以通过 return 来返回函数值。{{ }} 用于输出对象属性和函数返回值。<!DOCTYPE h...
高中数学一对一补习高考对本部分内容主要从以下两个方面考查:1.主要是求直线的方程;两条直线平行与垂直的判定;两条直线的交点和距离问题等,一般以选择题、填空题的形式考查。2.对于圆的考查,主要是结合直线的方程用几何法或待定系数法确定圆的标准方程;直线与圆、圆与圆的位置关系等问题,其中含参数问题为命题热点,一般以选择题、填空题的形式考查,难度不大。高中数学一对一补习建议授课方式:精析精研,...