版权声明:本文为博主原创文章,未经博主允许不得转载。 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]]