|
032、改造为二值化神经网络的一般过程
改造为二值化的神经网络:
1、二值化的卷积层BinaryConv2D、全连接层BinaryDense、激活函数层binary_tanh、复写DropOut
2、实际数据的label由01的独热编码变为-1 +1形式(乘2减1即可)
3、分类问题:修改损失函数 带hinge的三个损失函数squared_hinge categorical_hinge hinge都还行 带crossentropy差得远
4、修改学习率的调整策略 需要回调
lr_decay = (lr_end / lr_start) ** (1. / epochs)
cb_lr_scheduler = LearningRateScheduler(lambda epoch: lr_start * lr_decay ** epoch)
- # -*- coding: utf-8 -*-
- import keras.backend as K
- import numpy as np
- import tensorflow as tf
- def round_through(x):
- '''
- 对 x 中的值取整, 同时使得求梯度的得到的值与原始值的梯度一样
- 小技巧, 创新思路:来自 [Sergey Ioffe](http://stackoverflow.com/a/36480182)
- '''
- rounded = K.round(x) # 四舍五入
- # 这是很重要的技巧 因为tf或keras 会自动求梯度 根据前向传播过程 在这里 不能这样
- return x + K.stop_gradient(rounded - x)
- def _hard_sigmoid(x):
- '''
- 当 x <= -1, y = 0;
- 当 -1 < x < 1, y = 0.5 * x + 0.5;
- 当 x > 1; y = 1;
- '''
- x = (0.5 * x) + 0.5
- return K.clip(x, 0, 1)
- def binary_tanh(x):
- '''
- 激活函数 就是二值化的过程
- 在前向传播(forward propagation)时, 输出如下:
- 当 x <= 0.0, y = -1
- 当 x > 0.0, y = 1
-
- 在后向传播(backward propagation)求梯度时, 求梯度的规则如下:
- 2 * _hard_sigmoid(x) - 1
- 当 x <= -1, y = -1;
- 当 -1 < x < 1, y = x;
- 当 x > 1; y = 1;
- 当|x| >= 1 时, 梯度为 0
- 当|x| < 1 时, 梯度为 1
- '''
- return 2 * round_through(_hard_sigmoid(x)) - 1
- def binarize(W, H=1):
- '''
- 二值化操作 W为kernel
- 将 [-H, H] 之间的值转换为 -H 或者 H
- '''
- Wb = H * binary_tanh(W / H)
- return Wb
- if __name__ == '__main__':
- kernel = np.random.normal(size=(3, 3))
- print('kernel:', kernel)
- with tf.Session() as sess:
- print(sess.run(binarize(kernel)))
- print(sess.run(binary_tanh(kernel)))
复制代码
东方老师AI官网:http://www.ai111.vip
有任何问题可联系东方老师微信:dfy_88888
【微信二维码图片】
|
|