下面解释tf.one_hot函数
- tf.one_hot
tf.one_hot()函数是将input转化为one-hot类型数据输出,相当
将多个数值联合放在一起作为多个相同类型的向量,可用于表示各自的概率分布,通常用于分类任务中作为最后的FC层的输出,有时翻译成“独热”编码。
tensorflow的help中相关说明如下:
one_hot(indices, depth, on_value=None, off_value=None, axis=None, dtype=None, name=None)
Returns a one-hot tensor.
- indices表示输入的多个数值,通常是矩阵形式;depth表示输出的尺寸。
- 由于one-hot类型数据长度为depth位,其中只用一位数字表示原输入数据,这里的on_value就是这个数字,默认值为1,one-hot数据的其他位用off_value表示,默认值为0。
- tf.one_hot()函数规定输入的元素indices从0开始,最大的元素值不能超过(depth - 1),因此能够表示depth个单位的输入。若输入的元素值超出范围,输出的编码均为 [0, 0 … 0, 0]。
- indices = 0 对应的输出是[1, 0 … 0, 0], indices = 1 对应的输出是[0, 1 … 0, 0], 依次类推,最大可能值的输出是[0, 0 … 0, 1]。
4.5.2 向量
向量是一种非常常见的数据载体,如在全连接层和卷积神经网络层中,偏置张量𝒃就使用向量来表示。如图所示,每个全连接层的输出节点都添加了一个偏置值,把所有输出节点的偏置表示成向量形式:
考虑 2 个输出节点的网络层,我们创建长度为 2 的偏置向量𝒃,并累加在每个输出节点
z=wx,模拟获得激活函数的输入 z
z = tf.random.normal([4, 2])
b = tf.zeros([2]) # 模拟偏执向量
z = z + b # 累加偏执
print(“b:”,b)
print(“z:”,z)
注意:这里 shape 为[4,2]和 shape 为[2]的𝒃张量可以直接相加,这是为什么呢?
通过高层接口类 Dense()方式创建的网络层,张量 W 和𝒃存储在类的内部,由类自动创建并管理。可以通过全连接层的 bias 成员变量查看偏置变量𝒃
例如创建输入节点数为 4,输出节点数为 3 的线性层网络,那么它的偏置向量 b 的长度应为 3:
from tensorflow_core.python.layers import layers
fc = layers.Dense(3) # 创建一层wx+b,输出节点为3
通过build函数创建w,b张量,输入节点为4
fc.build(input_shape=(2, 4))
bias=fc.bias # 查看偏置
print(bias)
可以看到,类的偏置成员 bias 初始化为全 0,这也是偏置𝒃的默认初始化方案。
4.5.3 矩阵
矩阵也是非常常见的张量类型,比如全连接层的批量输入
,其中b表示输入样本的个数,即 batch size, d i n d_in din表示输入特征的长度。
比如特征长度为 4,一共包含 2 个样本的输入可以表示为矩阵:
x = tf.random.normal([2,4])
令全连接层的输出节点数为 3,则它的权值张量 W 的 shape 为[4,3]:
x = tf.random.normal([2, 4])
w = tf.ones([4, 3]) # 定义w张量
b = tf.zeros([3]) # 定义b张量
o = x @ w + b # x@w+b运算 @ 等价于tf.matmul表示矩阵相乘
print(o)
下面解释几行代码
- o = x @ w + b
@ 等价于tf.matmul表示矩阵相乘
其中 X,W 张量均是矩阵。x@w+b 网络层称为线性层,在 TensorFlow 中可以通过 Dense类直接实现,Dense 层也称为全连接层。
写到此处解释一下全连接层
最后的两列小圆球就是两个全连接层,在最后一层卷积结束后,进行了最后一次池化,输出了20个12_12的图像,然后通过了一个全连接层变成了1_100的向量。
我们通过 Dense 类创建输入 4 个节点,输出 3 个节点的网络层,可以通过全连接层的 kernel 成员名查看其权值矩阵 W:
import tensorflow as tf
from tensorflow_core.python import keras
from tensorflow.keras import layers
fc=layers.Dense(3) #定义全连接层的输出节点为3
fc.build(input_shape=(2,4)) #定义全连接层的输入节点为4
print(“fc.kernel:”,fc.kernel)
4.5.4 3 维张量
三维的张量一个典型应用是表示序列信号,它的格式是
-
b表示序列信号的数量
-
sequence len 表示序列信号在时间维度上的采样点数
-
feature len 表示每个点的特征长度。
如图 4.3 所示。为了能够方便字符串被神经网络处理,一般将单词通过嵌入层(Embedding Layer)编码为固定长度的向量,比如“a”编码为某个长度 3 的向量,那么 2 个等长(单词数为 5)的句子序列可以表示为 shape 为[2,5,3]的 3 维张量,其中 2 表示句子个数,5 表示单词数量,3 表示单词向量的长度
import tensorflow as tf
from tensorflow_core.python import keras
from tensorflow.keras import layers
(x_train, y_train), (x_test, y_test) = keras.datasets.imdb.load_data(num_words=10000) # 自动加载 IMDB 电影评价数据集
x_train = keras.preprocessing.sequence.pad_sequences(x_train, maxlen=80) # 将句子填充、截断为等长 80 个单词的句子
print(x_train.shape)
embedding = layers.Embedding(10000, 100) # 创建词向量 Embedding 层类
out = embedding(x_train) # 将数字编码的单词转换为词向量
print(out.shape)
可以看到,经过 Embedding 层编码后,句子张量的 shape 变为[25000,80,100],其中 100 表示每个单词编码为长度 100 的向量
对于特征长度为 1 的序列信号,比如商品价格在 60 天内即可表示商品的价格,因此 2 件商品的价格变化趋势可以使用 shape 为[2,60]的张量表示。为了方便统一格式,也将价格变化趋势表达为 shape 为 [2,60,1]的张量,其中的 1 表示特征长度为 1
4.5.5 4 维张量
4 维张量在卷积神经网络中应用的非常广泛,它用于保存特征图(Feature maps)数据,格式一般定义为 [ b , h , w , c ] [b,h,w,c] [b,h,w,c]
-
b表示输入的数量
-
h/w:特征图的宽高
-
c:特征图的通道数
import tensorflow as tf
from tensorflow_core.python import keras
from tensorflow.keras import layers
x = tf.random.normal([4, 32, 32, 3]) # 创建32*32的彩色图片,个数为4
layer = layers.Conv2D(16, kernel_size=3) # 创建卷积神经网络
out = layer(x) # 前向计算
print(out.shape) # 计算输出大小
print(layer.kernel.shape) # 卷积核张量也是 4 维张量,可以通过 kernel 成员变量访问
通过索引与切片操作可以提取张量的部分数据,使用频率非常高。
4.6.1 索引
import tensorflow as tf
from tensorflow_core.python import keras
from tensorflow.keras import layers
import numpy as np
x = tf.random.normal([4, 32, 32, 3])
print(“第一张图片的数据”, x[0])
print(“第一张图片的第二行数据:”, x[0][1])
print(“第一张图片的第二行第三列的像素:”, x[0][1][2])
print(“取第 3 张图片,第 2 行,第 1 列的像素,B 通道(第 2 个通道)颜色强度值:”, x[2][1][0][1])
当张量的维度数较高时,使用[𝑗][𝑘]…[𝑙]的方式书写不方便,可以采用[𝑗,𝑘,…,𝑙]的方式索引,它们是等价的。
print(“取第 2 张图片,第 10 行,第 3 列:”,x[1,9,2])
4.6.2 切片
通过start : end:step切片方式可以方便地提取一段数据
-
start 为开始读取位置的索引
-
end 为结束读取位置的索引(不包含 end 位)
-
step 为读取步长
以 shape 为[4,32,32,3]的图片张量为例:
print(“读