tensorflow支持的数据类型:实数(tf.float32、tf.float64)、整数(tf.int8、tf.int16、tf.int32、tf.int64、tf.unit8)、布尔型(tf.bool)和复数(tf.complex64、tf.complex64)
卷积运算函数列举
# 以下两个卷积函数的区别:tf.layers.conv2d是对tf.nn.conv2d的一个封装,提供了更多的参数,使实现卷积更为简便,两个没有性能上面的明显区别
""" 卷积函数一 """
tf.layers.conv2d(inputs, # tensor的输入
filters, # 一个整数,卷积核的数量,也就是输出空间的维度
kernel_size, # 一个整数,或者包含了两个整数的元组/队列,表示卷积窗的高和宽。如果是一个整数,则宽高相等,一般为(3,3)或(5,5)
strides=(1, 1), # 一个整数,或者包含了两个整数的元组/队列,表示卷积的纵向和横向的步长。如果是一个整数,则横纵步长相等。另外, strides 不等于1 和 dilation_rate 不等于1 这两种情况不能同时存在。
padding='valid', # "valid" 或者 "same"(不区分大小写)。"valid" 表示不够卷积核大小的块就丢弃,"same"表示不够卷积核大小的块就补0
data_format='channels_last', # 若channels_last,则(batch, height, width, channels);若channels_first,则(batch, channels, height, width),表示输入维度的排序
dilation_rate=(1, 1), # 一个整数,或者包含了两个整数的元组/队列,表示使用扩张卷积时的扩张率。如果是一个整数,则所有方向的扩张率相等。另外, strides 不等于1 和 dilation_rate 不等于1 这两种情况不能同时存在
activation=None, # 激活函数,如果是None则为线性函数,激活函数有,常用的有tf.nn.relu,tf.sigmoid,tf.tanh
use_bias=True, # Boolean类型,表示是否使用偏差向量
kernel_initializer=None, # 卷积核的初始化,一般使用tf.truncated_normal_initializer(stddev=0.01)初始化
bias_initializer=init_ops.zeros_initializer(), # 偏差向量的初始化。如果是None,则使用默认的初始值
kernel_regularizer=None, # 卷积核的正则项
bias_regularizer=None, # 偏差向量的正则项
activity_regularizer=None, # 输出的正则函数
kernel_constraint=None, # 映射函数,当核被Optimizer更新后应用到核上。Optimizer 用来实现对权重矩阵的范数约束或者值约束。映射函数必须将未被影射的变量作为输入,且一定输出映射后的变量(有相同的大小)。做异步的分布式训练时,使用约束可能是不安全的。
bias_constraint=None, # 映射函数,当偏差向量被Optimizer更新后应用到偏差向量上
trainable=True, # 此变量是否被训练,如果为False,则进行卷积运算时不会更新此值
name=None, # 字符串,层的名字
reuse=None) # Boolean类型,表示是否可以重复使用具有相同名字的前一层的权重
""" 卷积函数二 """
tf.nn.conv2d(input, # 输入数据
filter, # 是一个四维的张量,其type必须和输入一样,[filter_height, filter_width, in_channels, out_channels]
strides, # 一个整数列表,表示卷积的纵向和横向的步长
padding, # "valid" 或者 "same"(不区分大小写)。"valid" 表示不够卷积核大小的块就丢弃,"same"表示不够卷积核大小的块就补0
use_cudnn_on_gpu=True, # bool型,是否在GPU上面运行
data_format="NHWC", # 表示输入维度的排序,除batch外,HWC分别代表height, width, channels排序
dilations=[1, 1, 1, 1], # data_format对应的四个维度的扩张因子,其中batch和channels必须值为1
name=None) # 字符串,层的名字
注意:tf.nn.conv2d在做完卷积操作,一般还需要使用,如下两个操作去优化
bias = tf.nn.bias_add(conv, biasse) # 加偏置
actived_conv = tf.nn.relu(bias) # 使用激活函数去线性化
池化函数列举
tf.layers.max_pooling2d(inputs, # 卷积的结果,必须要池化4层
pool_size, # 一个元组或者一个列表,表示池化窗口的长宽,一般为(2,2)
strides, # 可以是一个元组或者一个列表,表示池化时的步长,如果为一个单一数字,则表示在各个维度的步长一样
padding='valid', # 以下参数意义和卷积的参数意义一样
data_format='channels_last',
name=None)
# 实现了最大池化层的前向传播过程
tf.nn.max_pool(value, # 输入层的节点矩阵
ksize, # 表示过滤器的尺寸
strides, # 过滤器的步长
padding, # 以下参数意义和卷积的参数意义一样
data_format="NHWC",
name=None)
""" 一个完整的简易神经网络使用示例 """
import tensorflow as tf
# 随机数生成器
from numpy.random import RandomState
# 一个完整的神经网络解决二分类问题
# 定义训练数据batch 的大小
batch_size = 8
# 定义神经网络的参数,生成正太随机数
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
# 定义存放数据的地方
x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')
# 定义神经网络的前向传播的过程
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
# 定义损失函数-交叉熵,tf.log是对数函数,得到的值即为熵
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))
# 定义反向传播算法
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
# 通过随机数生成一个模拟数据集
rdm = RandomState(1) # 1为随机数的种子,只要随机种子seed相同,产生的随机数序列就相同
dataset_size = 128
# X = rdm.rand(dataset_size, 2) # 生成一个dataset_size行,2列的二维数组,值的大小在0-1的随机数
X = rdm.uniform(0, 1, (dataset_size, 2)) # 与rdm.rand此种用法等价,将数值限制在0-1
# 0和1表示法,其实是定义分类的规则,大部分神经网络分类都会采用0,1区分法,即伯努利分布
Y = [[int(x1+x2 < 1)] for (x1, x2) in X]
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 训练前的权重参数
print(sess.run(w1))
print(sess.run(w2))
# 设定训练的轮数
STEPS = 5000
for i in range(STEPS):
# 以batch_size行数据进行训练
start = (i*batch_size) % dataset_size
end = min(start+batch_size, dataset_size)
# 通过选取的样本训练神经网络并更新参数
sess.run(train_step, feed_dict={x: X[start:end], y_:Y[start:end]})
if i % 1000 == 0:
# 每隔一段时间计算在所有数据上的交叉熵并输出
total_cross_entropy = sess.run(cross_entropy, feed_dict={x: X, y_: Y})
print("After %d training step(s), cross entropy on all data is %g" % (i, total_cross_entropy))
# 训练完更新后的权重参数
print(sess.run(w1))
print(sess.run(w2))
函数 | 解释 |
---|---|
tf.Graph() | 生成新的计算图,如果TensorFlow没有指定graph,则会自动生成一个默认的计算图 |
tf.Graph().device('/gpu:0') | 指定计算运行的设备 |
tf.get_default_graph() | 获取当前的计算图 |
tf.constant(value, dtype=None, shape=None, name="Const", verify_shape=False) | 创建张量,在TensorFlow中所有的数据都通过张量的形式来表示;value可以为一维和多维,与shape结合使用;verify_shape=False时,张量的维数可以改变,否则相反;dtype不指定时,默认数据类型为tf.float32,name指定张量的名字 |
tf.add(x, y, name=None) | 计算两个张量和 |
tf.Session(target='', graph=None, config=None) | 生成会话,会话拥有并管理TensorFlow程序运行时的所有资源,当所有计算完成之后,需要关闭会话帮助系统回收资源,否则就可能出现资源泄漏的问题;使用方式和python中的with open很类似,with tf.Session() as sess,会话默认不会自动生成,需要指定 |
tf.Session().run() | 在会话中运行程序 |
tf.Session().close() | 关闭会话,释放本次会话中所用到的资源 |
tf.InteractiveSession() | 创建会话为当前默认的会话 |
tf.ConfigProto(allow_soft_placement=True, log_device_placement=True) | 创建会话时config指定的配置,可以配置类似并行的线程数、GPU分配策略、运算超时时间等参数;allow_soft_placement默认为false,在有GPU环境下,这个参数一般会设置为True,当为True时,以下条件满足其一则会在CPU上面运算:1.运算无法再GPU上执行。 2.没有GPU资源(比如运算计算被指定在第二个GPU上面运行,但是机器只有一个GPU) 3.运算输入包含对CPU计算结果的引用 ;log_device_placement默认为False,当为True时详细记录设备调试日志 |
tf.matmul(a,b) | 矩阵乘法,其中a,b都为行列匹配的矩阵 |
tf.Variable() | 1.创建变量,变量一旦创建好之后,变量的值可以改变,但是类型不可以改变,也就是dtype的值不能变;2.保存和更新神经网络的参数 |
tf.random_normal([2, 3], stddev=2) | 生成正太分布随机数,此处是生成一个2行3列的随机矩阵,stddev指定标准差的大小,矩阵中的元素均值为0,tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=dtypes.float32) |
tf.truncated_normal() | 正太分布,但如果随机出来的值偏离平均超过2个标准差,那么这个数将会被重新随机 |
tf.random_uniform() | 均匀分布 |
tf.random_gamma() | Gamma分布 |
tf.zeros(shape) | 产生全0的数组 |
tf.ones(shape) | 产生全1的数组 |
tf.fill(shape,number) | 产生一个全部为给定数字的数组 |
tf.global_variables_initializer().run() | 初始化全部局部和全局变量,在定义一个变量之后,在使用这边变量之前必须执行初始化操作,一般使用方式:init = tf.global_variables_initializer(),sess.run(init) |
tf.Variable().initial_value() | 获取一个变量的初始值,因为一个变量在计算中的值可能不断变化 |
sess.run(weight.initializer) | 初始化某个变量 |
tf.constant(shape) | 创建常量 |
tf.assign(count, counter,validate_shape=False) | 赋值函数,将counter的值赋值给count,其中两个变量的类型必须一致;如果两个变量维度不一样,则将validate_shape的值设为False,False则表示可以改变维度,在实践中比较少见 |
tf.all_variables() | 获取当前计算图的所有变量 |
tf.placeholder(tf.float32, shape=(1, 2), name="input") | 定义placeholder作为存放输入数据的地方,这里维度也不一定要定义,如果维度是确定的,给出维度可以降低出错的概率,调用:sess.run(y, feed_dict={x: [[0.7, 0.9]]}) |
sess.run(train_step, feed_dict={x: X[start:end], y_:Y[start:end]}) | 选取样本,并更新权重参数,一般结合placeholder使用 |
-tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0))) | 定义损失函数-交叉熵,理论上损失函数越小,模型的鲁棒性就越好,其中y为预测值,y_为真实值;tf.reduce_mean实质是求矩阵的平均值,矩阵中如果有一个元素为float,则计算结果为float,如果矩阵所有元素都为int型,则计算结果小数部分都会舍去;axis参数调整维度求平均值,0表示列平均,1表示行平均,默认None全部平均 |
tf.train.AdamOptimizer(0.001).minimize(cross_entropy) | 定义反向传播算法,选用Adam优化器 |
tf.clip_by_value(A, min, max) | 定义值域范围,输入一个张量A,把A中的每一个元素的值都压缩在min和max之间。小于min的让它等于min,大于max的元素的值等于max |
tf.log(x, name=None) | 取对数函数,底为10 |
v1*v2 | v1和v2都为张量,实现的是两个矩阵中各元素的乘积,而不是矩阵相乘,完全不同于tf.matmul,*使用来实现交叉熵的 |
tf.greater(v1,v2) | 比较张量中每个元素的大小,返回bool;当输入的张量的维度不一样时,TensorFlow会进行numpy广播处理 |
tf.select(bool,v1,v2) | 当bool的值为True时,选择张量v1中对应的元素,否则选择V2中对应的元素;注意select的判断和选择都是在元素级别,最后输出的是张量 |
tf.train.exponential_decay(learning_rate, global_step, decay_steps, decay_rate,staircase=False, name=None) | 指数衰减获取学习率,是一种极好的获取学习率的方式 |
tf.contrib.layers.l1_regularizer(w) | 解决过拟合问题,正则化函数L1,可以改变权重优化损失函数,返回的是一个函数,特点:不可导,更稀疏,构建模型更复杂 |
tf.contrib.layers.l2_regularizer(w) | 解决过拟合问题,正则化函数L2,可以改变权重优化损失函数,返回的是一个函数。特点:可导,简洁, |
tf.argmax(input, axis=None, name=None, dimension=None) | 若axis=0,则将列当做一维数组,获取其中值最大的索引;若若axis=1,则将行当做一维数组,获取其中值最大的索引,其中input为二维数组 |
tf.train.exponential_decay(learning_rate, global_step, decay_steps, decay_rate, staircase=False, name=None) | 通过指数衰减来获取学习率 |
tf.group(train_step, variables_averages_op) | 同时更新神经网络中参数和滑动平均值,确保这两步操作都执行完成 |
with tf.control_dependencies([train_step, variables_averages_op]): train_op = tf.no_op(name='train') | 同时更新神经网络中参数和滑动平均值,确保这两步操作都执行完成,与tf.group等价 |
saver=tf.train.Saver() | 保存训练好的模型,用来持久化数据,可以传入变量名的字典,重命名变量名,通过saver.save(sess,path)来保存,保存的文件后缀为ckpt,保存的路径下会自动生成四个文件 |
tf.train.import_meta_graph(path) | 从持久化的数据路径中加载数据 |
tf.nn.conv2d() | 底层做卷积运算,一般使用训练好的数据时使用 |
tf.layers.conv2d() |
上层做卷积运算,一般训练数据时使用,可传递的参数比较多,与tf.nn.conv2d运算效率上没有太大区别 |
tf.cast(x, dtype, name=None) | 将x的数据类型转化为dtype的数据类型 |