接着上一篇 DNN情感分析模型

两个函数,一个是数据转换函数,一个是输入函数

# 数据输入管道
# 首先是数据转换函数
# 重点理解和思考着函数
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 。(请注意,这些嵌入是临时学习的结果。在任何指定的训练迭代中,都是当前查询的权重

猜你喜欢

转载自blog.csdn.net/hpulfc/article/details/80283296
今日推荐