自然界的数据类型(用于神经网络处理)大致可分为两种,一种是未知相关的数据(如卷积神经网络中处理的二维图片),另一种叫做序列信号(也可以理解为时间轴上的数据)。
比如一段语音,就是一个序列信号,因为它的数据之间有一个时间的先后顺序;再比如聊天记录,它可能并不是一个时间序列,但是我们阅读的时候会有一个先后顺序。这种沿着一个时间序列不停的产生信号的数据我们就称之为序列(信号)。
在深度学习中就有一种网络使用了这种数据处理方式,它就是RNN(循环神经网络,结构如上图),RNN的应用之一就是自然语言处理。在自然语言处理中(拿文本翻译来说),我们总是需要一个单词一个单词的按先后顺序读入,从而产生和翻译结果中一一对应的关系。
现假设某一英文句子有十个单词,每个单词用长度为4的一维向量来表示,那么这个句子就可以用一个shape[10,4]的tensor来表达。
Sequence embedding的一种表示方法为[b,seq_len,feature_len],其中b代表句子个数,seq_len代表每句话中的单词个数,feature_len代表每个单词表示成数据的长度。
另一种表示方法为[seq_len,b,feature_len],这种表达方式可以理解为每次在第seq_len时刻(某单词出现的时刻,seq_len进行时间上的滑动处理)有b条信号曲线(波形曲线),每条曲线上对应一个feature_len向量
序列并不限于自然语言处理等直观的含序列关系的数据处理,它也可以用于图像处理,因为图像的像素与像素之间本身就存在一个上下文关系。
序列是从String类型到数据类型的转换,但是数值中存在大小关系,而String句子中往往不存在大小关系而是存在语义关系。那么如何实现一个这样的转换呢(不仅仅是逻辑上的转化还有语义上的转化)?
对于不同的需求,也有不同的处理方式。
比如,如果系统只需要处理一些特定的地点信号(从文本中提取地名),这样的任务就可以通过简单的onehot编码实现,即每一个地名对应一个label,但是这种方式的缺点也是显而易见的——浪费储存空间(onehot编码中大部分都是0,只有一个位置是1)、高维度(日常交流中人的词汇量上万甚至上十万),而优点就是可以保留语义相似度并且可训练,即语义相似的单词之间可以通过概率的方式展示出来,比如,“男性”一词,我们可以训练使得“男人”,“男生”与它进行高相似度匹配,通过onehot处理的结果就是以top概率展示出来。
对于Word embedding,最常见的有两种embadding方式,一种叫Word2Vec,顾名思义,就是将单词转化为向量,另一种叫GloVe(关于它可参考文章:https://blog.csdn.net/u014665013/article/details/79642083)
在tensorflow中提供了一个很简单的层来帮助我们学习语言文字的表示方法,使用过程如下:
import tensorflow as tf from tensorflow import keras x = tf.range(5) x = tf.random.shuffle(x) print(x) net = keras.layers.Embedding(10,4) print(net(x))
可以理解为我们要分析十个地名,每个地名使用长度为4的数据表示