tensorflow1.x学习

329 阅读5分钟

分类问题的经典损失函数 分类问题设置n个输出结点(n为分类类别的个数),对于每个样例,网络可以得到一个n维数组作为输出结果。可以用交叉熵(cross entropy)判断输出向量和期望向量的差距。

交叉熵刻画了两个概率分布之间的距离。给定两个概率分布p和q,则通过q来表示p的交叉熵为: H(p,q)=i=1np(xi)logq(xi)H(p,q)=-\sum_{i=1}^{n}p(x_i)logq(x_i)

通过Softmax回归可以将神经网络的输出向量变成一个概率分布(Softmax的输出也是一个向量,但其满足概率分布的所有要求),从而可以应用交叉熵计算预测类别的概率分布和真实类别的概率分布之间的距离。 H(p,q)刻画的是用概率分布q表示概率分布p的困难程度,所以当交叉熵作为神经网络的损失函数时,p代表真实分类,q代表神经网络输出的预测值。所以交叉熵的值越小,网络效果越好。

因为交叉熵一般会与softmax回归一起使用,所以TensorFlow对这两个功能进行了统一封装,提供了tf.nn.softmax_cross_entropy_with_logits函数。

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(
    labels=y_, logits=y)
# y_代表真实分类结果,y代表网络输出结果
# y_和y两者维度均为m x n,其中m为一个batch中样本的数量,n为分类的类别数量

tf.get_variable()函数

tf.get_variable(
    name, shape=None, dtype=None, initializer=None, regularizer=None,
    trainable=None, collections=None, caching_device=None, partitioner=None,
    validate_shape=True, use_resource=None, custom_getter=None, constraint=None,
    synchronization=tf.VariableSynchronization.AUTO,
    aggregation=tf.compat.v1.VariableAggregation.NONE
)

name是生成变量的名字 shape是生成变量的维度 dtype是生成变量的类型 initializer初始化 trainable 如:

F = tf.get_variable('F', shape=[self.batch_size, self.K],
                    initializer=tf.orthogonal_initializer(gain=1.0, seed=None, dtype=tf.float32),
                    trainable=False)

v = tf.matmul(v1, v2)函数实现矩阵乘法;

v = v1 * v2是矩阵对应元素相乘;

tf.clip_by_value(v, 2, 4)函数将张量中的数值限制在一个范围内,大于4的换成4,小于2的换成2;

tf.reduce_mean(input_tensor, axis=None, keep_dims=False, name=None, reduction_indices=None) 函数用于计算张量沿着指定的轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor的平均值。axis指定轴,如不指定则求整个张量的均值。keep_dims指是否降维度,设置为True,则输出的结果保持输入tensor的形状,默认设置为False,输出结果会降低维度;

x = tf.placeholder(tf.float32, shape=(l, 2), name=”input")为避免计算图在迭代中为过多的常量创建节点,TensorFlow提供placeholder函数用于输入数据。placeholder 当于定义了一个位置,这个位置中的数据在程序运行时再指定。这样在程序 中就不需要生成大量常量来提供输入数据,而只需要将数据通过 placeholder 传入TensorFlow计算图。在placeholder定义时,这个位置上的数据类型是需要指定的。和其他张量一样,placeholder的类型也不能改变。placeholder 中数据的维度信息可以根据提供的数据推导得出,所以不用一定给出。如:

input = tf.placeholder(tf.float32, [None, self.num_steps], name='inputs')
noise = tf.placeholder(tf.float32, [None, self.num_steps], name='noise')
F_new_value = tf.placeholder(tf.float32, [None, self.K], name='F_new_value')
real_fake_label = tf.placeholder(tf.float32, [None, 2], name='real_fake_label')

sess.run()函数使用feed_dict参数为计算图中的所有的placeholder指定值,feed_dict是一个字典,如

loss_val, abstract, _ = sess.run(
    [loss_tensors['loss'], real_hidden_abstract, train_op],
    feed_dict={input_tensors['inputs']: np.concatenate((input, fake_input), axis=0),
                input_tensors['noise']: noise,
                input_tensors['real_fake_label']: train_real_fake_labels})

tensorflow1.x程序一般分为两个阶段。在第一个阶段需要定义计算图中所有的张量和计算,第二个阶段执行计算。 tensorflow1.x在计算之前需要先建立会话(Session),在会话中计算结果。

# 创建一个会话
sess = tf.Session() 
# 使用这个创建好的会话来得到关心的运算的结果
sess.run() 
# 关闭会话使得本次运行中使用到的资源可以被释放
sess.close()

上面这种方法容易导致资源泄漏,因为在程序异常退出的时候,关闭会话的函数可能不会被执行导致资源泄漏。所以一般使用Python的上下文管理器来使用会话。

在Python的上下文管理器机制中,只要将所有的计算都放在with内部即可,当上下文管理器退出的时候会自动释放所有的资源。

# 创建一个会话,并通过Python中的上下文管理器来管理这个会话 
with tf.Session() as sess: 
# 使用创建好的会话来计算关心的结果
    sess.run() 

tf.Session(target='', graph=None, config=None)函数创建会话,三个参数均不是必须。 target参数为要连接到的执行引擎,默认使用进程内引擎。graph参数为要启动的计算图。config参数是ConfigProto协议的缓冲区,为该会话的配置选项。

gpu_config = tf.ConfigProto()
# 第一种方法
sess = tf.Session(config=gpu_config)
sess.run()
sess.close()
# 第二种方法,使用上下文管理器
with tf.Session(config=gpu_config) as sess:
    sess.run()

通过ConfigProto函数配置需要生成的会话,通过ConfigProto可以配置类似并行的线程数,GPU分配策略,运算超时时间等参数。 allow_soft_placement为布尔型参数,设置为True时,GPU上的运算可以放到CPU上进行,该参数默认值为False。 log_device_placement也为布尔型,设置为True时,日志将会记录每个节点被安排在哪个设备上以方便调试。在生产环境中,该参数设为False可以减少日志量。

config = tf.ConfigProto(allow_soft_placement=True, log_device_placement=True) 
sessl = tf.InteractiveSession(config=config)
sess2 = tf.Session(config=config)
tf.compat.v1.nn.rnn_cell.GRUCell(
    num_units, activation=None, reuse=None, kernel_initializer=None,
    bias_initializer=None, name=None, dtype=None, **kwargs
)
# num_units为隐藏层神经元个数,是必须指定的参数
# activation激活函数,默认为tanh
# 主要使用的参数就是上面的两个

tf共享变量

tf.get_variable(<name>, <shape>, <initializer>) 创建或返回给定名称的变量`
tf.variable_scope(<scope_name>) 管理传给get_variable()的变量名称的作用域`

[来自](tensorflow变量作用域(variable scope) - 善良的大猪猪 - 博客园 (cnblogs.com))