最近想将之前用普通机器学习做的一个项目,用三层的全连接神经网络跑一遍,在做label时候,需要将(0,1)这两种label转为one-hot编码,因此探究了一下tf.one_hot的用法。
tf.one_hot(indices, depth, on_value=None, off_value=None, axis=None, dtype=None, name=None)
indices: 是一个矩阵,可以是一维的矩阵(居多),也可以是多维的
depth:要输出的one-hot编码的tensor的列的维度,比如说输入的是(1800,)的一维矩阵,depth是3,其会输出[1800,3]的shape的tensor
on_value:默认是1,可以自己指定,就是将one-hot编码的那个‘1’换成了你所指定的数字
off_value:默认是0,可以自己指定,就是将one-hot编码的那个‘0’换成了你所指定的数字
axis:默认是-1,一般我们就默认好了,符合直觉,具体用法:
If
indices
is a vector of lengthfeatures(看作是样本个数,就是上面的1800)
, the output shape will be:
features x depth if axis == -1
depth x features if axis == 0
Ifindices
is a matrix (batch) with shape[batch, features](有不同组的样本)
, the output shape will be:
batch x features x depth if axis == -1
batch x depth x features if axis == 1
depth x batch x features if axis == 0
dtype:默认是tf.float32
官方提供的例子:
indices = [0, 1, 2]
depth = 3
tf.one_hot(indices, depth) # output: [3 x 3]
# [[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]]
indices = [0, 2, -1, 1]
depth = 3
tf.one_hot(indices, depth,
on_value=5.0, off_value=0.0,
axis=-1) # output: [4 x 3]
# [[5.0, 0.0, 0.0], # one_hot(0)
# [0.0, 0.0, 5.0], # one_hot(2)
# [0.0, 0.0, 0.0], # one_hot(-1)
# [0.0, 5.0, 0.0]] # one_hot(1)
indices = [[0, 2], [1, -1]]
depth = 3
tf.one_hot(indices, depth,
on_value=1.0, off_value=0.0,
axis=-1) # output: [2 x 2 x 3]
# [[[1.0, 0.0, 0.0], # one_hot(0)
# [0.0, 0.0, 1.0]], # one_hot(2)
# [[0.0, 1.0, 0.0], # one_hot(1)
# [0.0, 0.0, 0.0]]] # one_hot(-1)
自己试验一下发现,这个one-hot编码是从0开始的编码,即使你的label里面没有0,比如说是从(1,2)的label,那它也只会从0开始编码,这个需要特别注意到:
>>> indices = [1,2,1,1,2]
>>> depth = 2
>>> tf.one_hot(indices, depth)
输出:这里没有将2编码出来,因为深度(depth)不够,只能编码到1
[[ 0. 1.]
[ 0. 0.]
[ 0. 1.]
[ 0. 1.]
[ 0. 0.]]
>>>depth = 3
>>>tf.one_hot(indices, depth)
输出:这里将2编码出来了,因为深度(depth)够了
[[ 0. 1. 0.]
[ 0. 0. 1.]
[ 0. 1. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
之前在学习优达的h深度学习网课时其实也碰到过one-hot编码,它当时对mnist数据集的label进行one-hot编码时,只利用numpy一句话即可。
>>>train_label = np.array([0,1,2,3,4,5,6,7,8,9,2,3,0])
>>>train_label_one_hot = (np.arange(10) == train_label[:,None]).astype(np.float32)
>>>train_label_one_hot
array([[ 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.],
[ 0., 0., 0., 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., 0., 0., 0., 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., 0., 0., 0., 1.],
[ 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)
np,arange(10)创建一个shape为(10,)的array([0,1,2,3,4,5,6,7,8,9]),与train_label[:,None]创建的shape为(13,1)的array进行广播比较,得到shape为(13,10) 的True,False填值矩阵,再转换格式即可。