两个函数,一个是数据转换函数,一个是输入函数
# 数据输入管道 # 首先是数据转换函数 # 重点理解和思考着函数 def _parse_function(record): """Extracts features and labels. Args: record: File path to a TFRecord file Returns: A `tuple` `(labels, features)`: features: A dict of tensors representing the features labels: A tensor with the corresponding labels. """ features = { "terms": tf.VarLenFeature(dtype=tf.string), # terms are strings of varying lengths "labels": tf.FixedLenFeature(shape=[1], dtype=tf.float32) # labels are 0 or 1 } # print ("features", features) # 使用转换函数 parsed_features = tf.parse_single_example(record, features) # print("parsed_features", parsed_features) terms = parsed_features['terms'].values labels = parsed_features['labels'] # print ("terms", terms) # print ("labels", labels) return {'terms':terms}, labels
输入函数:
# 用于为训练输入数据的输入函数 # 这里只需要输入文件名,也即训练数据的路径 # 并且由于输入的特征数据并不是长度相同,所以需要使用Dataset.padded_batch, 进行填充以此进行分桶 # Create an input_fn that parses the tf.Examples from the given files, # and split them into features and targets. def _input_fn(input_filenames, num_epochs=None, shuffle=True): # Same code as above; create a dataset and map features and labels ds = tf.data.TFRecordDataset(input_filenames) ds = ds.map(_parse_function) if shuffle: ds = ds.shuffle(10000) # Our feature data is variable-length, so we pad and batch # each field of the dataset structure to whatever size is necessary ds = ds.padded_batch(25, ds.output_shapes) # 对数据进行填充,以此进行批量处理 ds = ds.repeat(num_epochs) # Return the next batch of data features, labels = ds.make_one_shot_iterator().get_next() return features, labels
一些总结:
嵌套的作用:
简单点就是降维,对于一个推荐系统或是翻译系统,单词表的大小决定了构造出来的稀疏向量的形,如果不进行嵌套,将会产生很多个特征列,
这些特征列数量变多而产生的计算,将会超过硬件的计算能力。并且对于所构造出来的向量(以独热编码方是生成)大多是属于稀疏向量,里面很多0值,
所以为了简化向量,可以仅仅是保留有用的信息,然后表示成一些简单内容嵌入到神经网络中去,(这些简单的内容可以进行少量的计算,达到与之前原来相同的效果)通过反向传播逐步的确立出出嵌套矩阵!这样就能保存上下文的语义关系了!
!!!
假设稀疏数据包含 "great"、"beautiful" 和 "excellent" 这几个值。由于在此处使用的词汇表大小为 V=54 ,因此第一层中的每个单元(神经元)的权重将为 54。我们用 s 表示稀疏输入中的项数。对于此示例稀疏数据, s=3 。对于具有 V 个可能值的输入层,带有 d 个单元的隐藏层需要运行一次“矢量 - 矩阵”乘法运算: (1×V)∗(V×d) 。此运算会产生 O(V∗d) 的计算成本。请注意,此成本与隐藏层中的权重数成正比,而与 s 无关。如果输入使用 indicator_column 进行了独热编码(长度为 V 的布尔型矢量,存在用 1 表示,其余则为 0),这表示很多零进行了相乘和相加运算。
当我们通过使用大小为 d 的 embedding_column 获得完全相同的结果时,我们将仅查询与示例输入中存在的 3 个特征 "great"、"beautiful" 和 "excellent" 相对应的嵌入并将这三个嵌入相加: (1×d)+(1×d)+(1×d) 。由于不存在的特征的权重在“矢量-矩阵”乘法中与 0 相乘,因此对结果没有任何影响;而存在的特征的权重在“矢量-矩阵”乘法中与 1 相乘。因此,将通过嵌入查询获得的权重相加会获得与“矢量-矩阵”乘法相同的结果。
当使用嵌入时,计算嵌入查询是一个 O(s∗d) 计算;从计算方面而言,它比稀疏数据中的 indicator_column 的 O(V∗d) 更具成本效益,因为 s 远远小于 V 。(请注意,这些嵌入是临时学习的结果。在任何指定的训练迭代中,都是当前查询的权重