独热(one-hot)编码的tensorflow实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22812319/article/details/83374125

一、独热编码

独热编码,又称一位有效码,用序列化的数字(只有0和1)表达特征。主要思路是使用N位数字对N种情况进行编码。

举个例子,对[0,1,2,3]分别进行编码。由于有4种情况,序列的长度为4,对应数字的位置1,其余置0。所以:

[1,0,0,0]

[0,1,0,0]

[0,0,1,0]

[0,0,0,1]

二、几个必要函数

掌握了独热编码的规律,我们先来看一段代码,了解几个必要的函数。

import tensorflow as tf

#创建一维向量a和b,shape均为(3, )

a = tf.constant([1,2,3])

b = tf.constant([4,5,6])

 

#a和b在一维上连接,c的shape为(6, )

c = tf.concat([a,b],0)

#由于a和b是一维向量,无法连接,会报错

#c1 = tf.concat([a,b],1)

 

#将a和b扩充为二维向量,二者的shape均为(3,1)

t1 = tf.expand_dims(a,1)

t2 = tf.expand_dims(b,1)

 

#分别在第二维和第一维上连接

concated = tf.concat([t1,t2],1)

concated1 = tf.concat([t1,t2],0)

 

#查看结果

with tf.Session() as sess:

  print(a,a.shape)

  print(b,b.shape)

  print(sess.run(t1),t1.shape)

  print(sess.run(t2),t2.shape)

  print(sess.run(c),c.shape)

  print(sess.run(concated),concated.shape)#(3,2)

  print(sess.run(concated1),concated1.shape)#(6,1)

 

tf.concat(values,dim,name='concat')

在某维上连接两个向量的函数。

Values - 需要连接的向量

Dim - 维数。0表示第一维,1表示第二维

由上面的例子可知,维度为(3,1)和(3,1)的两个向量,在第一维上连接,就是(6,1);在第二维连接,就是(3,2).

注意:有的版本可能是tf.concat(dim,values),具体可以自行实验。

 

tf.expand_dims(input, axis=None, name=None, dim=None)

扩充向量的维数。

由上面的例子可知,使用t1 = tf.expand_dims(a,1)将向量[1,2,3]扩充为[[1],[2],[3]],从原来的(3,)变为(3,1),便于在第二维上连接concat。

 

 三、独热编码实现

接下来看一段实际代码,了解独热编码究竟如何生成。

为了方便理解,假设现在我们要对5张手写数字进行分类,这些数字的标签labels的范围是0~9,形成(5, )的行向量,为[5,4,3,8,7]。

labels = [5,4,3,8,7]

NUM_CLASSES = 10

batch_size = tf.size(labels)

#labels表示图片的标签,5张图片有5个标签。Batch_size=5

labels = tf.expand_dims(labels, 1)

#扩充维数,将(5,)扩充为(5,1),里面的内容不变:[[5],[4],[3],[8],[7]]

indices = tf.expand_dims(tf.range(0, batch_size, 1), 1)

#扩充维数。由于batch_size=(5, ),循环之后生成5*1的矩阵:[[0],[1],[2],[3],[4]]

concated = tf.concat(1, [indices, labels])

#将indices和labels在第二维连接,形成5*2的矩阵:[[0,5],[1,4],[2,3],[3,8],[4,7]]

onehot_labels = tf.sparse_to_dense(
concated, tf.stack([batch_size, NUM_CLASSES]), 1.0, 0.0)

#转化为独热编码。

#tf.pack()将两个向量打包成一个。由于batch_size=5和NUM_CLASSES=10都是数,合并为行向量:[5,10]

#tf.sparse_to_dense()将稀疏矩阵转密集矩阵。stack()函数指定生成的矩阵的shape为5*10,concated指定更换值的坐标,1.0表示将concated指定坐标的值更换为1,0.0表示其余坐标值置0.

最终结果: 

def sparse_to_dense(sparse_indices,
                    output_shape,
                    sparse_values,
                    default_value=0,
                    validate_indices=True,
                    name=None):

几个参数的含义: 

sparse_indices: 元素的坐标[[0,0],[1,2]] 表示(0,0),和(1,2)处有值 

output_shape: 得到的密集矩阵的shape 

sparse_values: sparse_indices坐标表示的点的值,可以是0D或者1D张量。若0D,则所有稀疏值都一样。若是1D,则len(sparse_values)应该等于len(sparse_indices) 

default_values: 缺省点的默认值
tf.pack() ===> tf.stack(values, name = "pack")

Values表示输入的tensor,实现将两个tensor打包成一个。

        例子:

          a = tf.constant([1,2,3])   b=tf.constant([4,5,6])

          sess.run([a,b])

          输出:[array([1, 2, 3]), array([4, 5, 6])]

          sess.run(tf.stack([a,b],name='rank')) 

          输出:[[1,2,3],[4,5,6]]

 

猜你喜欢

转载自blog.csdn.net/qq_22812319/article/details/83374125