一、理解variance 与 bias

varivance:反映准确率   bias:反映模型的拟合能力

  • 高方差(variance)—— 过拟合 —— 训练集上表现好,验证集上表现差
  • 高偏差(bias)—— 欠拟合 —— 训练集上表现就比较差

解决方法:对于high bias,增加模型复杂度,训练一个更大的网络;对于high variance,增加训练数据;采用正则化的方法

二、NCHW与NHWC数据格式

(1) 基本概念

深度学习框架中,数据一般是4D,用NCHW或NHWC表达,其中:

  • N - Batch
  • C - Channel
  • H - Height
  • W - Width

(2)逻辑表达

假定N = 2,C = 16,H = 5,W = 4,那么这个4D数据,看起来是这样的:

我们比较直接的理解方式是3D,上图中从三个方向上理解,C方向/H方向/W方向。再加N方向上,就是4D。上图中红色标准的数值是这个数据里每个元素的数值。

(3)逻辑表达

无论逻辑表达上是几维的数据,在计算机中存储时都是按照1D来存储的。NCHW和NHWC格式数据的存储形式如下图所示:

  • NCHW是先取W方向数据;然后H方向;再C方向;最后N方向。
  • NHWC是先取C方向数据;然后W方向;再H方向;最后N方向。

(4)不同框架支持

目前的主流ML框架对NCHW和NHWC数据格式做了支持,有些框架可以支持两种且用户未做设置时有一个缺省值:

  • TensorFlow:缺省NHWC,GPU也支持NCHW
  • Caffe:NCHW
  • PyTorch:NCHW

三、小数化整数

  • math.round() —— 四舍五入,注意正负数的不同
  • math.ceil() —— 向上取整,即小数部分直接舍去,并向正数部分进1
  • math.floor() —— “向下取整” ,即小数部分直接舍去

四、lambda函数

(1)lambda函数语法

表现形式如下:lambda [arg1,[arg2,.....argn]]:expression

  • 其中,lambda 是 Python 预留的关键字,[arg…]expression 由用户自定义。

(2)lambda函数特性

  • 匿名,即无名称
  • 有输入输出:输入是传入到参数列表的值,输出是根据表达式expression计算得到的值
  • 有自己的命名空间,不能访问自己参数列表之外或全局命名空间里的参数

(3)用法示例 常见的lambda函数示例

1lambda x, y: x*y	# 函数输入是x和y,输出是它们的积x*y
2lambda:None		# 函数没有输入参数,输出是None
3lambda *args: sum(args)     # 输入是任意个数参数,输出是它们的和
4lambda **kwargs: 1	# 输入是任意键值对参数,输出是1
  • 将lambda函数赋值给一个变量,由该变量间接调用: add = lambda x, y: x+y,相当于将变量add指向具有加法功能的函数,执行add(1, 2),其输出结果就为 3。
  • 将lambda函数赋值给其他函数,从而将其他函数用该lambda函数替换
1#将标准库time中的函数sleep的功能屏蔽(Mock):
2time.sleep=lambda x: None
3# 这样,在后续代码中调用time库的sleep函数将不会执行原有的功能。
4# 例如:
5time.sleep(3)	# 程序不会休眠 3 秒钟,因为lambda输出为None,所以结果是什么都不做
  • 将lambda函数作为参数传递给其他函数,与高阶函数一起使用

五、Python回调函数

(1)回调机制callback

程序运行时,一般情况下,应用程序会时常通过API调用一些库函数。但是有些库函数却要求应用先传给它一个函数,以便在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。

(2)回调的优势

提供了非常大的灵活性。在回调中,利用某种方式,把回调函数像参数一样传入中间函数,通过登记不同的回调函数,来决定、改变中间函数的行为。示例如下:

 1#回调函数1:生成一个2k形式的偶数
 2def double(x):
 3    return x * 2   
 4#回调函数2:生成一个4k形式的偶数
 5def quadruple(x):
 6    return x * 4
 7 
 8from even import *
 9#中间函数:接受一个生成偶数的函数作为参数,返回一个奇数
10def getOddNumber(k, getEvenNumber):
11    return 1 + getEvenNumber(k)
12    
13#起始函数,这里是程序的主函数
14def main():    
15    k = 1
16    i = getOddNumber(k, double)#当需要生成一个2k+1形式的奇数时
17    print(i)    
18    i = getOddNumber(k, quadruple)#当需要一个4k+1形式的奇数时
19    print(i)
20    i = getOddNumber(k, lambda x: x * 8)#当需要一个8k+1形式的奇数时
21    print(i)
22if __name__ == "__main__":
23    main()

六、Python中的yield用法

如果不太好理解yield,可以先把yield当作return的同胞兄弟来看,他们都在函数中使用,并履行着返回某种结果的职责。

这两者的区别是:

  • 有return的函数直接返回所有结果,程序终止不再运行,并销毁局部变量;
  • yield的函数则返回一个可迭代的 generator(生成器)对象,可以使用for循环或者调用next()方法遍历生成器对象来提取结果。