Python collections中的Counter

Counter是dict的子类,是一个简单的计数器

1
2
3
4
5
from collections import Counter
c = Counter()
for ch in 'programming':
c[ch] = c[ch] + 1
c # Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})

counter有多高效?
counter为什么这么高效?

速度测评

以下计数,发现并未对速度做优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from time import time
import tensorflow as tf
from collections import Counter


def _read_words(filename):
with tf.gfile.GFile(filename, "r") as f:
return f.read().decode("utf-8").replace("\n", "<eos>").split()


# 计数 + 排序
def _build_vocab(filename):
data = _read_words(filename)

start = time()
# 利用counter,计数+排序。counter并不快
counter = Counter(data)
count_pairs = sorted(counter.items(), key=lambda x: (-x[1], x[0]))

# 自己计数
# word_cnt = count(data)
# count_pairs = sorted(word_cnt.items(), key=lambda x: (-x[1], x[0]))

stop = time()
print("Stop: " + str(stop))
print(str(stop - start) + "秒")


words, _ = list(zip(*count_pairs))
word_to_id = dict(zip(words, range(len(words))))
return word_to_id


def count(data):
word_cnt = {}
for w in data:
if w in word_cnt:
word_cnt[w] += 1
else:
word_cnt[w] = 1
return word_cnt


word_to_id = _build_vocab("ptb_data/ptb.train.txt")
print(word_to_id["no"])

概念

  • 定义一个函数为虚函数,不代表函数为不被实现的函数。
  • 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。
  • 定义一个函数为纯虚函数,才代表函数没有被实现。
  • 定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。

C++多态(polymorphism)是通过虚函数来实现的。

#

虚函数只能借助于指针或者引用来达到多态的效果。

正则化 VS 标准化

regularization 与 normalization 区别?

  • “standardization 一般是指将数据正态化,使平均值1方差为0. ”

normalization和standardization是差不多的,都是把数据进行前处理,从而使数值都落入到统一的数值范围,从而在建模过程中,各个特征量没差别对待。normalization一般是把数据限定在需要的范围,比如一般都是【0,1】,从而消除了数据量纲对建模的影响。standardization 一般是指将数据正态化,使平均值0方差为1. 因此normalization和standardization 是针对数据而言的,消除一些数值差异带来的特种重要性偏见。经过归一化的数据,能加快训练速度,促进算法的收敛。

而regularization是在cost function里面加惩罚项,增加建模的模糊性,从而把捕捉到的趋势从局部细微趋势,调整到整体大概趋势。虽然一定程度上的放宽了建模要求,但是能有效防止over-fitting的问题(如图,来源于网上),增加模型准确性。因此,regularization是针对模型而言。

机器学习中的一个核心问题是设计不仅在训练数据上表现好,并且能在新输入上泛化好的算法。在机器学习中,许多策略显式地被设计来减少测试误差(可能会以增大训练误差为代价)。这些策略被统称为正则化。

正则化:对学习算法的修改——旨在减少泛化误差而不是训练误差

扩展阅读

softmax的困扰、改进

简介

数学上的softmax

在数学,尤其是概率论和相关领域中,Softmax函数,或称归一化指数函数,是逻辑函数的一种推广。它能将一个含任意实数的K维向量 ${\displaystyle \mathbf {z} }$“压缩”到另一个K维实向量 ${\displaystyle \sigma (\mathbf {z} )}$ 中,使得每一个元素的范围都在 ${\displaystyle (0,1)}$ 之间,并且所有元素的和为1。该函数的形式通常按下面的式子给出:

$${\displaystyle \sigma (\mathbf {z} ){j}={\frac {e^{z{j}}}{\sum {k=1}^{K}e^{z{k}}}}} \quad j = 1, …, K.$$

softmax的应用

Softmax函数实际上是有限项离散概率分布的梯度对数归一化。因此,Softmax函数在包括 多项逻辑回归,多项线性判别分析,朴素贝叶斯分类器和人工神经网络等的多种基于概率的多分类问题方法中都有着广泛应用。特别地,在多项逻辑回归和线性判别分析中,函数的输入是从K个不同的线性函数得到的结果,而样本向量 x 属于第 j 个分类的概率为:

$${\displaystyle P(y=j\mid \mathbf {x} )={\frac {e^{\mathbf {x} ^{\mathsf {T}}\mathbf {w} _{j}}}{\sum _{k=1}^{K}e^{\mathbf {x} ^{\mathsf {T}}\mathbf {w} _{k}}}}}$$

这可以被视作K个线性函数
${\displaystyle \mathbf {x} \mapsto \mathbf {x} ^{\mathsf {T}}\mathbf {w} _{1},\ldots ,\mathbf {x} \mapsto \mathbf {x} ^{\mathsf {T}}\mathbf {w} _{K}}$
Softmax函数的复合( \mathbf {x} ^{\mathsf {T}}\mathbf {w} \mathbf {x} \mathbf {w} )。

loss function

softmax loss是我们最熟悉的loss之一了,分类任务中使用它,分割任务中依然使用它。softmax loss实际上是由softmax和cross-entropy loss组合而成,两者放一起数值计算更加稳定。这里我们将其数学推导一起回顾一遍。

令z是softmax层的输入,f(z)是softmax的输出,则

softmax的瓶颈

softmax需要计算每个类别的score,并且归一化为概率p。
当类别特别多(比如大词表)的情况下,计算量超大。

  • 参数量=计算量=n*V
  • 复杂度O(n^2)

对于大词表V

softmax的瓶颈常见于语言模型的巨量词汇、

优化

汇总

对损失函数的近似方法

  • HSM: Hierarchical Softmax: 用两层的树((Goodman, 2001a; Mikolov
    et al., 2011c),或者更深层的结构()
  • NCE:
  • 重要性采样
  • class-based softmax:
  • adaptive softmax: 对class-based softmax的改进,针对GPU的加速

其他

  • Large-Margin Softmax Loss
  • weighted softmax loss
  • soft softmax loss
  • angular softmax loss
  • L2-constrained softmax loss
  • additive margin softmax loss

基于采样的近似方法

基于

其他

  1. 简单的trick

[batch_size, seq_length, hidden_size] * [hidden_size, vocab_size] 这样的操作,可以reshape成

[batch_size seq_length, hidden_size] [hidden_size, vocab_size] 的操作。即真个sequence一起算softmax。

但是有些decode中,上一时刻的output作为下一时刻的输入,就没办法这样算了。

对loss-function的优化/近似(Loss function approximation)

  • HSM: hierarchical softmax

树结构是一般基于frequency binning或者word similarities

hierarchical softmax是很多层二分类,在GPU上效率并不高。
假如,浅层的多分类,每层没必要是两个类。单层矩阵运算更容易用GPU加速
层数少了,在GPU上速度提升了,(当然如果是cpu,速度会更慢)

基于采样的优化/近似 (Sampling based approximation)

importance sampling

不同的采样策略:

  • unigram
  • bigram
  • power-raised distribution of the unigram

Self-normalized approaches

class based softmax

Classes for fast maximum entropy training. Joshua Goodman, 2001

We assign each word in the
vocabulary to a unique class. 比如,猫、狗属于动物类,周二、周三属于工作日。

FAQ

  • 类之间有没有word overlap?没有,这样能减小计算量。(HS的二叉树也)
  • 有没有大类小类?多层类?没有
  • class与word的对应关系是怎样得到的? 由用户自定义,自定义的方法有:
    • 按语义分类:猫、狗属于动物类,周二、周三属于工作日。
    • 按词频分类:首先词频排序,然后分块作为class

adaptive softmax

Facebook 人工智能研究(FAIR)设计出一种新式的 softmax 函数逼近,专用于 GPUs,帮助其在语言模型的基础上通过巨量词汇来有效训练神经网络。

这种方法叫做自适应 softmax(adaptive softmax),利用不平衡词分布形成簇(cluster),这种簇能明确地减少对计算复杂度的期望,从而规避对词汇量的线性依赖。这种方法通过利用流行架构的特殊性和矩阵-矩阵向量运算(matrix-matrix vector operations)进一步减少了训练和测试时的计算成本。这使得它特别适合于 GPU,而以往的方法,如分层 softmax,NCE 和重要性采样,都是为标准的 CPU 设计的。

有点类似HS和重要性采样吧?词频高的

FAQ

  • adaptive softmax为什么能加速?
  • 为什么要这样分cluster?

核心

NCE

negative sampling。这种只针对training吧?inference怎样sampling呢?

(CPU上会更低效)

FAQ

关于名称

  • softmax直接来看是一个归一化方法,loss的形式和是不是概率是不是softmax形式是没有必然联系的。当然它们现在的形式都是可以从entropy延伸出来,但是换一个新的loss,softmax也可以照用,或者不用softmax归一化,这个loss也一样可以继续用于优化。我觉得还是叫entropy loss比较好。
  • 全称是softmax cross entropy loss,但这个实在是太长了
  • 没什么全称的吧,好多地方都叫得不一样,就叫entropy loss最好了,既简洁又准确,这个loss就是entropy的形式
  • 这个损失函数的核心是softmax函数,用softmax得到概率才能用cross entropy,得到概率的方式也有很多,比如sigmoid后l1归一化。
  • caffe里除了softmax cross entropy,还有sigmoid cross entropy。

参考

为什么Python比C++慢很多?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# include <cstdio>



int n = 15 ;
int cnt ;



void Dfs ( int row, int shu, int pie, int na ) {
int ave = ((1 << n) - 1) & ~(shu | pie | na) ;
while ( ave ) {
int p = ave & -ave ;
ave ^= p ;
if ( row == n )
++ cnt ;
else
Dfs ( row + 1, shu | p, (pie | p) >> 1, (na | p) << 1 ) ;
}
}

int main ( ) {
Dfs ( 1, 0, 0, 0 ) ;
printf ( "%d\n", cnt ) ;
}

python collection

collections — High-performance container datatypes¶

collections是Python内建的一个集合模块,
在2.4版本开始被引入,该模块实现了专用容器数据类型替代python的通用内置容器:dict(字典),list(列表), set(集合)和tuple(元组)。

容器 中文名 简介 引入版本
namedtuple() 命名元组 使用工厂方法创建带有命名的字段的元组的子类 2.6
deque 双向队列 类似列表的容器,能够快速响应在任何一端进行pop 2.4
Counter 计数器 字典子类,为可以进行哈希的对象计数 2.7
OrderedDict 有序字典 字典子类,记录了字典的添加次序 2.7
defaultdict 字典 字典子类,调用一个工厂方法来提供缺失的值 2.5

除了具体的容器类,collections模块还提供了abstract_base_classes来测试一个类是否体用了一个特定的接口,例如,这是可哈希的还是一个映射。

在2.4版本中新加入,。

中文翻译:https://blog.csdn.net/Shiroh_ms08/article/details/52653385

扩展阅读

为什么需要bucket

bucket就是一种编码思想,bucket的存在是为了减小计算量,从而可以减少模型的训练时间。当然,使用dynamic_rnn或rnn这两个接口也可以减少运算时间。bucket是用在使用在cell(input,state)这种古老的方法上的。

  • 每一个bucket都是一个固定的computation graph;
  • 其次,每一个sequence的pad都不是很多,对于计算资源的浪费很小
  • 再次,这样的实现很简单,就是一个给长度聚类,对于framework的要求很低
  1. 对train set:要对sequence的长度聚类,确保如何分配bucket。
  2. 数据依旧要填充到最大长度
  3. 对每个bucket都要建立一个模型,但是模型都是共享变量的
  4. 对每个模型都要都要计算loss,保存到list中
  5. 训练的时候,最小化对应bucket的loss

源码

https://github.com/tensorflow/tensorflow/blob/27711108b5fce2e1692f9440631a183b3808fa01/tensorflow/contrib/legacy_seq2seq/python/ops/seq2seq.py#L1118

Update

最新版本的 tensorflow 不需要使用 bucketing了,直接用 dynamic rnn 就好,它会根据每个batch自动计算最好的输出,不过要更定每个
example的 sequence length。
当然,现在有人可以做到自动计算 sequence length 了,可参考 tensorlayer.layers
这个方法也用在google 最新开源的 image captioning 例子里了。

dynamic rnn是如何解决效率问题的?

有了dynamic rnn, buket也仍然有用,因为后续logits loss计算的时候batch length小仍然会减少计算量。“One reason is that seq2seq was created before dynamic rnn was available. The other is that, even with dynamic rnn, it still helps for speed if your batches are organized by bucket”

dynamic rnn并不会提升效率.

The parameter sequence_length is optional and is used to copy-through state and zero-out outputs when past a batch element’s sequence length. So it’s more for correctness than performance.

参考

Faster R‑CNN是首个利用CNN来完成proposals的预测的,之后的很多目标检测网络都是借助了
Faster R‑CNN的思想。而Faster R‑CNN系列的网络都可以分成2个部分:
1.Fully Convolutional subnetwork before RoI Layer
2.RoI‑wise subnetwork

Position‑sensitive RoI pooling

位置敏感RoI池化操作了(Position‑sensitive RoI pooling)