万丈高山,从平地走起
Intro
这篇博文用于记录一些keras的函数用法和示例,以及部分函数的实现原理。
方便自己查阅。
因为原始keras的backend没法直接输出结果,所以这里我直接用的tf2.0,如果直接在keras中使用,去掉tensorflow就行啦。
to_categorical
将 list 中的标签转换成维度为num_classes
的one_hot
矩阵,用法:to_categorical(x, num_classes)
# from keras.utils.np_utils import to_categorical
from tensorflow.keras.utils import to_categoricalx = [0,1,2]
num_classes = 10
print(to_categorical(x, num_classes=num_classes))
"""
Using TensorFlow backend.
[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]]
"""
repeat
重复数组的数值,用法:repeat(x, n)
,假设原来x
的维度为(batch, feat_dim)
,那么其输出的shape为(batch, n, feat_dim)
。
import tensorflow.keras.backend as K
x = K.ones((2,4))
y = K.repeat(x, 3)
y.shape
"""
TensorShape([2, 3, 4])
"""
dropout
Dropout 操作,用法:dropout(x, level, noise_shape=None, seed=None)
。
import tensorflow.keras.backend as K
x = K.ones((2,3))
x_drop = K.dropout(x, 0.5)
print(x.numpy())
print(x_drop.numpy())
"""
[[1. 1. 1.]
[1. 1. 1.]] #x
[[0. 0. 2.]
[0. 2. 2.]] #x_drop
"""
假设输入为 x x x,丢包的比例为 r r r,那么不丢的那部分数据其量化系数为 1 1 − r \frac{1}{1-r} 1−r1,丢掉的那些数据直接置零。
我先大白话说一下这个操作的一个流程,首先生成一个跟输入的形状一样的随机矩阵,然后在这个矩阵中,它的元素如果大于等于丢包比例
r
r
r ,那么就把这个元素置1,如果低于
r
r
r,就直接 mask
掉,这样我们就可以知道要留下哪些位置的数据,去掉哪些数据了,为了保证变换前后的输入的和大致一样,我们给这些留下的数据乘以一个 scale
,就是
1
1
−
r
\frac{1}{1-r}
1−r1 。
直接看源码吧:
noise_shape = _get_noise_shape(x, noise_shape)
当 noise_shap
为 None
的时候,代码中的 noise_shape
就是输入的 shape,
random_tensor = random_ops.random_uniform(noise_shape, seed=seed, dtype=x.dtype)
接下来就是生成一个 shape 为 noise_shape
的随机矩阵,这个随机矩阵服从标准正态分布。
keep_prob=1-rate
这个用来算那个量化系数。
keep_mask = random_tensor >= rate
得到 mask
,其条件就是比丢包率 rate
高的元素都置1了。
ret = x * scale * math_ops.cast(keep_mask, x.dtype)
然后对原始输入进行转换,就是乘以量化系数 scale
,再乘以 mask
矩阵。
基于以上,当我们设定了rate之后,然后多运行几遍,会发现元素的值不是0,就是原来位置的元素乘以 1 1 − r \frac{1}{1-r} 1−r1 ,但是每次运行,值为0的元素的个数是不一定的,所以丢掉地数据个数并不是确定的,这也是个分布,根据源码的分析,我们当然就知道是因为啥了,毕竟……用于产生mask矩阵的那个矩阵是随机生成的呀。
in_train_phase
在训练的时候采用的一些操作在测试的时候是不需要的,比如说dropout
,用这个函数来确定在什么阶段选择什么操作。用法:in_train_phase(x, alt, training=None)
,注意x
和alt
的shape应当是一样的。以dropout距离如下:
import tensorflow.keras.backend as K
x = np.ones(shape=[2,3,4])
batch, timestep, inputdim = x.shape
dropout = 0.5
ones = K.ones_like(K.reshape(x, [:, 0, :], [-1, inputdim]))
dropout_matrix = K.dropout(ones, dropout)
expanded_dropout_matrix = K.repeat(dropout_matrix, timestep)
x_drop = K.in_train_phase(x*expanded_dropout_matrix, x, training=True)
print(x, x_drop)
"""
[[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]]
tf.Tensor(
[[[0. 0. 2. 0.]
[0. 0. 2. 0.]
[0. 0. 2. 0.]]
[[0. 2. 2. 2.]
[0. 2. 2. 2.]
[0. 2. 2. 2.]]], shape=(2, 3, 4), dtype=float64)
"""