(前言:我只是一个接触深度学习小半个月的小白,由于理解这个原理想了很久很久,所以想发篇文来记录一下,仅此而已,当然也希望有和我一样困惑的小伙伴看到后会有启发,我的知识还不全面,如有说错的地方欢迎大佬前辈们指正。以下的理解是我根据自己的小实验得出来的结果,因为《python深度学习》教程里有一些函数之类的我没有了解过。换言之如果也是同样的小白也能够看得懂我是什么意思)
from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
1.首先第一步是导入数据集
import numpy as np
def vectorize_sequences(sequences, dimension=10000):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
results[i, sequence] = 1. # 索引results矩阵中的位置,赋值为1,全部都是从第0行0列开始的
return results
x_train = vectorize_sequences(train_data)
2.第二步则是定义张量化函数,然后调用该函数
3.开始分析:
导入到 train_data 内的数据是一个嵌套了25000个列表的列表,即为25000条评论组成的列表,每条评论也是一个列表,列表的内容是该条评论中的单词在word_index内对应的索引,即一个个0-9999的整数
train_data
[ [1, 2, 85, ... 98, 63]
[3, 95, 54, ... 6 ,891]
. . . .
. . . .
. . . .
[62, 5, 9, ... 45, 7] ]
//train_data这个列表内含有25000个列表,每个列表内所含元素数目并非相等,因为每条评论中的单词数不一定相同,我这里对齐是因为觉得好看一点
(我只是举一个能表现它内容形状的例子方便理解,里面的数据并非真实如此,关于该数据集的详细介绍可以转到IMDB数据集的解释_西檬饭-CSDN博客_imdb数据集 中查看)
def vectorizer_sequences 函数内定义了两个形参,dimension已经直接赋值为10000了,对应了我们每条评论最多10000个单词,另一个sequences我们后面为其赋予了train_data这个参数,
接着我们又定义了一个形状为(25000,10000)的零矩阵,len(sequences)即为len(train_data)=25000,
接下来是一个for循环,这里使用了enumerate方法,即遍历train_data中的每一个元素,
for i,sequence in enumerate(sequences)中的 i,sequence 指的是,sequences(即train_data)中的 第 i 个列表, 而刚才我们说过enumerate方法的作用是遍历其中的每一个元素,
意思是第 i 条评论有多少个元素,这个for循环就会执行多少次
x = [[3, 5, 8, 9],
[2, 1, 9],
[9, 5, 14, 8, 4],
[2, 8, 9]]
print(x)
y = np.zeros((4, 15))
print(y)
print("\n'")
for i, n in enumerate(x):
y[i, n] = 1.
print(y)
print("\n")
为了方便理解,我做了一个微缩版的张量化函数,其得到的结果如下
[[3, 5, 8, 9], [2, 1, 9], [9, 5, 14, 8, 4], [2, 8, 9]]
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
[[0. 0. 0. 1. 0. 1. 0. 0. 1. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
[[0. 0. 0. 1. 0. 1. 0. 0. 1. 1. 0. 0. 0. 0. 0.]
[0. 1. 1. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
[[0. 0. 0. 1. 0. 1. 0. 0. 1. 1. 0. 0. 0. 0. 0.]
[0. 1. 1. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 1. 0. 0. 1. 1. 0. 0. 0. 0. 1.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
[[0. 0. 0. 1. 0. 1. 0. 0. 1. 1. 0. 0. 0. 0. 0.]
[0. 1. 1. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 1. 0. 0. 1. 1. 0. 0. 0. 0. 1.]
[0. 0. 1. 0. 0. 0. 0. 0. 1. 1. 0. 0. 0. 0. 0.]]
在这个小实验的结果我们可以看到依次输出的是x这个列表,类比于我们的train_data列表
然后是y这个(4,15)的0矩阵,类比于我们的results那个(25000,10000)的0矩阵,
然后是i=0的第一次for循环的输出,我们可以看到在第一行(其实是索引为0的那一行)的第4,6,9,10位元素发生了改变,即第一行的索引为3,5,8,9的元素都由0.变为了1.,这个结果就是for循环在enumerate遍历x的第一个列表(即索引为0的列表)中的各个元素分别执行了为(0,3),(0,5),(0,8),(0,9)的赋值为1.的操作
然后我们可以看到后续依次为后续三行的相似操作
4.总结:
这个张量化的原理就是显示每一条评论中所包含的所有单词在word_index字典中的位次,比如说张量化后的第一条评论中的前三个元素都为0.,而第四和第五个元素值为1.,意思就是这条评论中包含of 和to 这两个单词,但是不包含the,and,a这三个单词