一、理解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()方法遍历生成器对象来提取结果。