python 动态加载模块、类、函数

背景

在Java中我们可以通过反射来根据类名创建类实例,那么在Python我们怎么实现类似功能呢?

  • importlib (或者低版本中的import)
    -

简介

方式一

1
2
3
4
if data=='a':
import loader_a as loader
else:
import load_b as loader

方式二

1
2
3
4
5
6
7
8
import importlib

def class_for_name(module_name, class_name):
# load the module, will raise ImportError if module cannot be loaded
m = importlib.import_module(module_name)
# get the class, will raise AttributeError if class cannot be found
c = getattr(m, class_name)
return c

更优雅的方式

动态加载模块:
方式1:系统函数import()
方式2:imp, importlib 模块
方式3:exec 函数

动态加载类和函数
首先,使用加载模块,使用内置函数提供的反射方法getattr(),依次按照层级获取模块->类\全局方法->类对象\类方法。

##

Java的方式

参考

https://blog.csdn.net/shijichao2/article/details/51165576

python的重写(Override)与重载(Overload)

overload: 函数重载
override: 重写,也就是覆盖

函数重载

重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。

1
2
3
4
5
6
7
8
def f(a ,b):
return a+ b

def f(a,b,c):
return a+b+c

print(f(2,4))
print(f(2,3,4))

会报错

为什么 Python 不支持函数重载?

函数重写

重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。

函数重载主要是为了解决两个问题。
1。可变参数类型。
2。可变参数个数。
数。

tensorflow的softmax实现

第一个参数logits:就是神经网络最后一层的输出,如果有batch的话,它的大小就是[batchsize,num_classes],num_classes就是分类的数量。单样本的话,大小就是num_classes
第二个参数labels:实际的标签,它的shape同上

第一步是先对网络最后一层的输出做一个softmax,
这一步通常是求取输出属于某一类的概率,对于单样本而言,
输出就是一个num_classes大小的向量([Y1,Y2,Y3…]其中Y1,Y2,Y3…分别代表了是属于该类的概率),
多样本的话就是输出[batchsize,num_classes]大小的矩阵
softmax的公式是:

第二步是softmax的输出向量[Y1,Y2,Y3…]和样本的实际标签做一个交叉熵cross_entropy,公式如下:

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
# -*- coding: utf-8 -*-
# https://blog.csdn.net/m0_37041325/article/details/77040060
import tensorflow as tf

# our NN's output (尚未经过softmax)
logits = tf.constant([[0.9, 2.1, 3.0], [0.9, 2.1, 3.0], [0.9, 2.1, 3.0]])
# true label
# 注意这里标签必须是浮点数,不然在后面计算tf.multiply时就会因为类型不匹配tf_log的float32数据类型而出错
y_ = tf.constant([[0, 0, 1.0], [0, 0, 1.0], [0, 0, 1.0]])


# 方式一:自己算cross entropy
y = tf.nn.softmax(logits)
tf_log = tf.log(y)
pixel_wise_mult = tf.multiply(y_, tf_log)
cross_entropy = -tf.reduce_sum(pixel_wise_mult)


# 方式二:用组合版 softmax_cross_entropy (TF进行了内部优化)
cross_entropy2_step1 = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=logits)
cross_entropy2_step2 = tf.reduce_sum(cross_entropy2_step1) # dont forget tf.reduce_sum()!!
with tf.Session() as sess:
y_value, tf_log_value, pixel_wise_mult_value, cross_entropy_value = sess.run(
[y, tf_log, pixel_wise_mult, cross_entropy])
cross_entropy2_step1_value, cross_entropy2_step2_value = sess.run([cross_entropy2_step1, cross_entropy2_step2])
print("==== 方式一 ====\n")
print("step1:softmax result=\n%s\n" % (y_value))
print("step2:tf_log_result result=\n%s\n" % (tf_log_value))
print("step3:pixel_mult=\n%s\n" % (pixel_wise_mult_value))
print("step4:cross_entropy result=\n%s\n" % (cross_entropy_value))

print("==== 方式二 ====\n")
print("Function(softmax_cross_entropy_with_logits) result=\n%s\n" % (cross_entropy2_step1_value))
print("Function(tf.reduce_sum) result=\n%s\n" % (cross_entropy2_step2_value))

海交通大学的Zeping Yu 和Gongshen Liu,在论文“Sliced Recurrent Neural Networks”中,提出了全新架构“切片循环神经网络”(SRNN)。SRNN可以通过将序列分割成多个子序列来实现并行化。SRNN能通过多个层获得高级信息,而不需要额外的参数。

https://github.com/zepingyu0512/srnn

SRNN和标准RNN之间的区别在于SRNN将输入序列切分为许多最小子序列,并利用每个子序列上的循环单元。通过这种方式,子序列可以很容易地并行化。
�式,子序列可以很容易地并行化。

Quasi-RNN的核心是在 k-gram CNN(文本卷积)的基础上使用 adaptive gating。
在讨论k-gram卷积的时候,通常不会使用k=1既 window size 1作为运行参数。这点在包括Q-RNN本身的许多论文中都有体现 [1,2,3,4,5]。

SRU中的矩阵变换虽然可以看做 k=1的情况,但这跟声称“所有前馈神经网络(fast forward network)都是 k=1 卷积” 或者 “VGG net 和 GoogLeNet 是 AlexNet 改成3*3卷积然后加深度”没有本质差别。
3卷积然后加深度”没有本质差别。

fastText

简介

从另一个角度来说,fastText可以看作是用window_size=1的卷积 + average pooling的CNN [3]对句子进行建模。

核心 - 创新点

1 在word2vec的基础上, 把Ngrams也当做词训练word2vec模型, 最终每个词的vector将由这个词的Ngrams得出. 这个改进能提升模型对morphology的效果, 即”字面上”相似的词语distance也会小一些.

疑问

ngram的vector跟word vector什么关系?加和?

trick

hierarchical softmax类别数较多时,通过构建一个霍夫曼编码树来加速softmax layer的计算,和之前word2vec中的trick相同N-gram features只用unigram的话会丢掉word order信息,所以通过加入N-gram features进行补充用hashing来减少N-gram的存储

缺陷

The movie is not very good , but i still like it .
The movie is very good , but i still do not like it .
I do not like it , but the movie is still very good .
其中第1、3句整体极性是positive,但第2句整体极性就是negative。如果只是通过简单的取平均来作为sentence representation进行分类的话,可能就会很难学出词序对句子语义的影响。

总结

对简单的任务来说,用简单的网络结构进行处理基本就够了,
但是对比较复杂的任务,还是依然需要更复杂的网络结构来学习sentence representation的。

在合适的任务上应当使用合适的方法,像文本分类这样的任务,如果是长文本,即使用BOW也能做很不错的效果。

用了deep的结构之后,效果没有提升的原因是很多的,比如

  1. 数据量不够,过拟合严重
  2. 数据标记质量有限,本身的标记中就有一定的噪音。

疑问

fastText训练embedding,跟word2vec的区别是什么? 会考虑subword
所有subword都会考虑吗,那样会词典特别大哎?
整体的向量和局部向量的关系?近似是之和,还是=和?

参考

  • FastText.zip: Compressing text classification models
  • Bag of Tricks for Efficient Text Classification
  • Enriching Word Vectors with Subword Information
  • DAN: Deep Unordered Composition Rivals Syntactic Methods for Text Classification
    • DAN这种东西。。居然在SST数据下和最高的差距还不是很大呐。
    • 简化的dan,加上word2vec中使用的hierarchical softmax, 再加ngrams特征,就是一篇文章
  • Natural Language Processing (Almost) from Scratch
  • 如何评价Word2Vec作者提出的fastText算法? | 知乎