目录
上节:介绍了专用于计算机视觉的,卷积神经网络CNN模型。核心,就是对图像进行卷积操作,快速的提取图像的轮廓信息(特征)。
本节:将要介绍循环神经网络:关注数据里的前后的序列关系。
一、本章内容
1.1 六个部分
二、序列模型 Sequence Model
序列模型,Sequence Model。
2.1 生活中的实际案例:4个
案例1:自动撰写文章。
案例2:自动的寻找语句中的人名。
案例3:物体的位置预测。
案例4:股价预测
横坐标,是时间序列的形式
2.2 序列模型:有前后关系的数据
序列数据:指的是顺序的数据,指的有前后关系的数据。
- “不吃饭” vs “吃饭不”---------------- 每个汉字的先后顺序不同,结果不同
- 输入、输出,的不定长度
2.3 应用场景:4个
三、循环神经网络 RNN
Recurrent Neural Network, RNN
我以为是Recycle。。。
Neural
3.1 结构
左边:以前的传统MLP结构(神经网络):
X是x1、x2、x3...
y可以是一个多分类,也可以是一个回归预测
右边:是循环神经网络RNN的结构:
核心:将前面的序列数据,用在后面的结果预测中。
x1、x2、x3...是有前后关系的;
可以用x1来预测y1的结果。同时,x1还可以产生另外一个信息a1(a1包含了前面序列x1中的部分信息),把a1给到y2的预测中。即,y2的预测,是与前面的序列x1,有关系的。
test:
已更新typora版本到1.9.5:
3.2 数学模型
1.那么:x1是如何产生另外一个信息a1?
假设a0是0,W是一个初始的系数,可以是0,或一个随机数。
公式形式如下。具体的求解过程,类似于MLP多层感知器中的梯度下降法,找到损失函数最小的那个权重。
2.看一下模型是怎么搭建的:
确定输入:x1、x2、x3、x4...x10、x11
确定输出:0、0、0、0...1、0
问题:
此处,为什么要将文本转换为0和1呢?
答:计算机不理解文本,但是理解0、1.
就像之前学习的CNN卷积神经网络:
你给计算机一个图片,它是理解不了的;
你给整张图片对应的灰度数值,它是能够理解的。
3.
词汇数值化:
每一个英文词汇都对应一个数字,一一对应。(用Python中字典dict数据结构来存放)
为了更高效的计算,还需要将上述的数值,再次的转换为one-hot数组。形式是(-1,1),即n行1列。
也就是说,每一个词汇,最终会转换为一个n行1列形式的one-hot数组。
4.
将上述的n行1列形式的one-hot数组,与RNN模型,结合起来:
X的赋值:
y的赋值;
根据y的预测值,来得到损失函数,进而最小化;
上述,就是针对自然语言处理的、RNN模型的核心处理流程。
5.
另一种数值化的方式:(本实战二用的就是这种)
上面:词汇与数字一一对应;
下面:字母与数字一一对应。
不足:缺乏词汇之间的内部的关系,对模型的要求会更高。
3.3 课后题
C
RNN循环神经网络模型,是深度学习领域中的一个概念。此类模型需要用到海量数据,与它进行上下游的输入,起码得是数学领域中的数组或矩阵的形式。
四、不同类型的RNN模型
4.1 基础的RNN结构
1.
输入、输出的数量是多个,即多输入、多输出。同时,维度是一样的;
应用:语句中的特定信息(比如人名)的识别
2.
3.
多输入、单输出。应用:情感识别。
单输入、多输出。应用:文章生成。
4.
这里也是多输入、多输出,但是维度不同。应用:语言的翻译。
4.2 基础的RNN结构的缺陷
RNN结构的数据,都是序列模型,即数据是有先后关系的。
层层转递到靠后的序列数据,所有的信息的权重都是一样的。
每一层,在反推时,梯度越来越小,没法求解,没法找到损失函数的最小值。
我还是不太理解。
后部序列,有前部序列的信息。有就行呗,为啥还要权重?
4.3 长短期记忆网络 LSTM:增加记忆细胞,保留前部序列中的重要信息
1.
在上述RNN基础结构的基础上,增加一个记忆细胞Ci,用于记忆某些重要的数据信息。
原理:通过一些门:忘记门、更新门、输出门。
我认为:
就是这些门,通过权重的形式,对之前一律平等的数据信息,进行抓大放小。
2.
长短期记忆 LSTM,算是基础RNN结构的升级版。
4.4 双向循环神经网络 BRNN:还要考虑后部序列的重要信息
上面的长短期记忆 LSTM:只考虑了前部序列的信息。
如果还要考虑后部序列的信息呢?
4.5 深层循环神经网络 DRNN:单层的RNN,叠加在一起
将单层的RNN,叠加在一起,用于解决一些复杂的任务。
4.6 课后题
五、实战准备
5.1 实战(一):用基础的RNN,实现股价预测(重)
任务:
1.
左边:提取序列数据:
每一行都有8个数据;
然后,把上述的序列数据,作为输入给到RNN模型:
2.
右边:建立普通的RNN循环神经网络模型:
输出层:输出的y,是单个数值的预测,所以只有一个神经元。线性回归的激活函数;
回归预测,所以使用的损失函数是最小绝对值误差;------------------ 我的:平均的方差?
3.
RNN模型的输入数据的格式:input_shape
- samples,指的是样本的总数量。因为模型能自动计算,所以,后续实战二中的模型的入参中,就不需要画蛇添足的自己写上了。即,可以省略该参数。
- time_steps指的是步长,即滑动窗口的长度。比如,实战二中的time_steps为20。因为每次都是使用前20个字符,去预测第21个字符。
- features,就是后续实战中,的字典的长度。比如,实战二中的num_letters为23.
我的问题:
对于input_shape,我还是不太懂?中括号中,为什么是1、2呢?那0去哪里了?
答:samples,指的是样本的总数量。因为模型能自动计算,所以,后续实战二中的模型的入参中,就不需要画蛇添足的自己写上了。即,可以省略该参数。
5.2 实战(二):LSTM,自动生成文本
将文本转换成数值,再转换为n行1列的one-hot数组:
任务:
1.
文本加载;
字符字典建立;
2.
文本数据的批量预处理:
四个入参,两个结果:
六、实战(一):用基础的RNN,实现中国平安股价预测
6.1 任务
任务:
基于zgpa_train.csv数据集,建立RNN循环神经网络模型,预测中国平安的股价:
1.完成数据的预处理,将序列数据转化为可用于RNN输入的数据;
2.对新的测试数据zgpa_test.csv进行预测,并可视化结果;
3.存储预测结果,并观察局部的预测结果;
备注:模型结构:单层RNN,输出有5个神经元;每次使用前8个数据来预测第9个数据
6.2 task1:完成数据的预处理,将序列数据转化为可用于RNN输入的数据
只需要收盘价close;
因为是一个回归模型,为了使该模型更快的收敛,所以要对数据进行归一化处理;(也就是说,将数据的区间范围缩小到0~1)
define X and y:
不能像以前一样,直接从data中拿过来用;
这次,需要根据RNN循环神经网络的要求,从原来的序列数据中提取出来;
因为:0、1、2、3、4、5、6、7、8、9:一共10个样本,time_step = 8。最多是有三组样本。
因为最后一组样本,后面就没有需要再预测的数据了,因为末尾数字是9.
所以,就只使用两组样本。
对于len(data) - time_step
,就是10-8=2. 即range(2)
。
对于data[i : i+time_step]
:
- i 为0时,就是
data[0 : 8]
------------------------------ 顾左不顾右 - i 为1时,就是
data[1 : 9]
------------------------------ 顾左不顾右
feature的维度是1:
(723, 8, 1) 指的是有723个样本,每个样本中有8个数据点。1指的是每个数据点就是1个单独的数值。(也就是,最里面那层list中,元素数量只有1个)
即,样本数,序列的长度,每个数据的维度。
723怎么来的?
731 - 8 = 723
原始的数据总行数 - time_step = 样本数据的总行数
也就是说,extract_data() 方法中的for循环,是循环了723遍。
X的样本数,与y的样本数,是一致的;
因为输出层,只是输出一个数值,所以units=1。
因为是回归任务,所以可以尝试激活函数为线性:activation="linear"
问题:
有的时候,会发现损失函数,会停留在某个数值附近,不下降了。得到的效果不是很好。
即,模型求解时,到了一个局部的最小化的损失函数,现在死循环中。
解决:
重新执行建模过程、重新训练一次即可。
原因:
因为深度学习MLP模型求解时,一开始会有一个初始状态。这个初始状态给的不好,就会导致这样一个局部最优解。通过可视化看,效果就不是很好。
下面,也可以写成y_train = [i * max(price) for i in y]
形式,属于Python语法中的列表表达式。
可视化下:
橙色的预测数据,与蓝色的真实数据,吻合的挺好。
6.3 task2:对新的测试数据zgpa_test.csv进行预测,并可视化结果
再针对测试数据,基于训练好的模型进行下预测:
注意:
对于测试数据,归一化时,用的也是max(price)。
如果是max(test_price),就会原来模型的归一化的效果不一样了,不统一。
我明白了:
归一化,是要求所有的数据(训练数据或测试数据),得用同一套标准~
橙色的预测数据,与蓝色的真实数据,吻合的也挺好。
6.4 task3:存储预测结果,并观察局部的预测结果
1.存储结果:
先将python中的list转换为Numpy库中的数组array:
2.将数组array转换为Pandas库中的DataFrame数据结构;
columns=["real_price_test", "predict_price_test"]只是给字段起个名字;
已保存进了本地的csv文件中:
3.看一下本地文件:
通过task2中的可视化图,看起来效果不错。
但是,也要看下局部的放大观察:
因为上述的可视化图中,橙色的预测数据,总是滞后于蓝色的真实数据。
这种滞后性的缺点,就需要再观察局部的数据。
发现:
确实是慢了一拍。比如:现实生活中,你以为明天会涨,结果明天竟然跌了。
6.5 小结
七、实战(二):建立LSTM,来自动生成文本
7.1 任务
任务:
基于flare文本数据,建立LSTM模型,预测序列文字:
1.完成数据的预处理,将文字序列数据,转换为可用于LSTM输入的数据;
2.查看文本数据预处理后的数据结构,并进行数据分离的操作;
3.针对字符串输入("flare is a teacher in ai industry. He obtained his phd in Australia."), 预测其对应的后续字符。
备注:模型结构:单层LSTM,输出有20个神经元;每次使用前20个字符来预测第21个字符。
flare文本数据如下:
7.2 task1:完成数据的预处理,将文字序列数据,转换为可用于LSTM输入的数据
这次的数据加载跟以前不一样:
以前是read本地的csv文件,现在,只需要打开flare文件然后读取即可。
1.
换行符一般有两种:\n
、\r
移除换行符之后的总的data,长下面这样:一坨...
2.
为了建立字典做准备:字符去重;
建立最终的字典:char_to_int。其中:
- num_letters为23,该文本中一共出现了23种英文字母,就是说,后续建立的字典,总共有23页(就是字典的页数)(页码);
- enumerate(letters)指的是,将letters这个list中的索引位置与该位置上的元素,显示出来:
int_to_char就是形成的字典; - 这里的char_to_int,是一个字典dict:用字母作为索引(key),来找到对应它的数字(value);-------------- 下面橘黄色的建立字典dict的方式,是真简洁、高效、优雅。
步长:
3.
字符串的批量处理
- 方法1:可以把原始的充满字母和单词的文本,看作是一本人类的英文小说。因为我们要训练模型、预测,原始的人类英文小说的形式,肯定是机器学习和深度学习无法理解、无法直接使用的。所以,对其,要进行用“20的步长+1(结果)”的模式,一一的滑动的过一遍,转换一下数据的形式;
比如:
x y
flare is a teacher i ---------------- n
lare is a teacher in ----------------
are is a teacher in ---------------- a
re is a teacher in a ----------------
e is a teacher in a ---------------- i
is a teacher in ai ---------------- i
. .
. .
. .
x.append([a for a in data[i:i+slide]])的目的是:
在x这个列表中,以这样的形式存放:
[
['f', 'l', 'a', 'r', 'e', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 'a', 'c', 'h', 'e', 'r', ' ', 'i'], ['l', 'a', 'r', 'e', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 'a', 'c', 'h', 'e', 'r', ' ', 'i', 'n'], ['a', 'r', 'e', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 'a', 'c', 'h', 'e', 'r', ' ', 'i', 'n', ' '], ['r', 'e', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 'a', 'c', 'h', 'e', 'r', ' ', 'i', 'n', ' ', 'a'], ['e', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 'a', 'c', 'h', 'e', 'r', ' ', 'i', 'n', ' ', 'a', 'i'],
...
]
len(data) - slide 就是:56168 - 20 = 56148
(去除换行符后)原始的数据总行数 - slide = 样本数据的总行数
也就是说,extract_data() 方法中的for循环,是循环了56148遍。(7.3节,X、y的结构,可以验证)
- 方法2:就是基于以前组建好的字典,对上述的每个字符都转换为数字;
- 方法3:的中后部,没有看懂?1
注意:上述方法1中,有个错误。后面的bug2。
使用上述的批量处理文本数据的方法,提取出来:
4.
(0)为了更好的理解:
我后期改动了下代码,看一下某几个重要的中间变量 ,具体的长什么样子::
(1)
- 方法1:
(2)方法2:
(3)
下面代码意思是:将上面方法2的结果x_to_int,由二维list形式,转换为二维数组(即矩阵)的数学形式:
input_reshaped = np.array(x_to_int).reshape(len(x_to_int), slide)
(4)
下面代码意思是:新建一个(56148, 20,23)的三位list,用随机数进行填充:
new = np.random.randint(0, 10, size=[input_reshaped.shape[0], input_reshaped.shape[1], num_letters])
(5)
下面代码意思是:将二维数组(矩阵)input_reshaped,中的每个元素,都转换为one-hot的形式:(只有0、1)。然后,一一的覆盖上面的new中元素,焕然一新(而且还升维至了3维):
new[i, j, :] = to_categorical(input_reshaped[i, j], num_classes=num_letters)
本节遇到的几个bug:
bug1:
问题:
解决:
google了下,已搞定
bug2:
展示的是生成器对象,不是我想要的:
原因:
老师的代码:
网上其他人的验证:
解决及结果:
7.3 task2:查看文本数据预处理后的数据结构,并进行数据分离的操作
1.
看下X的结构:(56148, 20, 23)
- 指的是有56148个样本数;
- 每个样本是20个字符对应的one-hot数组;
- 这个字典有23页。
我的问题:上面X的类型是?
答:三维数组。
2.
看下y的长度:也是56148;y的类型,仍然是一个list,
进行数据分离;
将y_train这个变量,从list形式,转换为one-hot形式;
为了更好的理解:我查看了下几个中间变量的类型、结构
我发现:
相比于x,y要转换成one-hot的形式的时机,要比较晚。且是在数据分离split之后。
因为x早在方法3即data_preprocessing()中,及已经完成了one-hot的形式转换。
3.对于LSTM,activation="relu"。也可以不写,因为会有一个默认的激活函数。
因为不是一个输出,而是看下字典有多少页,即是多分类的,所以activation="softmax";
flare:
神经网络模型中,的参数,没有谁能确保它就是最好的。
都是做一些尝试之后,才得出,相对较好的参数。
因为是多分类的,所以损失函数loss="categorical_crossentropy"。
我的问题:
对于input_shape,我还是不太懂?中括号中,为什么是1、2呢?那0去哪里了?
答:samples,指的是样本的总数量。因为模型能自动计算,所以,本实战二中的模型的入参中,就不需要画蛇添足的自己写上了。即,可以省略该参数。(参考上面的章节:五、实战准备 / 5.1 实战(一))
注意:单词辨别:
下面的是metrics,------------ /e/挨,口腔中间----------------------- 意思是:指标
不是matrix。----------------------------- 字母表中的a的读音,口腔上边---- 意思是:矩阵
4.
训练模型;
做出预测;
下面预测,得到的是数字。如果想看到,文本的结果呢?那就基于字典,转换一下即可。
这就是,为什么在前面数据分离时,y_train没有进行one-hot 的转换。因为此时(即预测后),需要y_train的原始形式(即list的形式),与预测的结果(天然的是list的形式),进行对比。
5.
因为上面的accuracy: 0.7442是对应的最后一个batch样本的准确率。
下面的0.8566,是整体的样本的准确率。
7.4 task3:针对字符串输入("flare is a teacher in ai industry. He obtained his phd in Australia."), 预测其对应的后续字符
1.针对特定的字符串:
2.结果:
还是不太准:比如上面的红线处的两个单词,就是错误的。应该是phd、Australia。
这是因为:模型训练时,准确率是0.8442,不是100%
3.
那就可以回头,重复执行下fit训练的代码,在训练迭代5个epochs试试:
准确率,确实提升了:且是100%
预测结果,也确实全部预测正确:
4.
能否让预测结果,更直观的显示出来?
可以,每次以20个数据为输入,1个输出结果:
7.5 小结
这里的LSTM,与simpleRNN,没有体现出不一样。
以后,在自然语言处理时,发现文本多、需要前后关联,那么LSTM的效果就会比simpleRNN更加明显。
Comments | NOTHING