tensorflow--基础知识

目录

  • 1 基本概念
  • 2 批标准化BN
  • 3 优化方法

1 基本概念

  • 图(Graph):图描述了计算的过程,TensorFlow使用图来表示计 算任务。
  • 张量(Tensor):TensorFlow使用tensor表示数据。每个Tensor是 一个类型化的多维数组。
  • 操作(op):图中的节点被称为op(opearation的缩写),一个op 获得0个或多个Tensor,执行计算,产生0个或多个Tensor。
  • 会话(Session):图必须在称之为“会话”的上下文中执行。会话 将图的op分发到诸如CPU或GPU之类的设备上执行。
  • 变量(Variable):运行过程中可以被改变,用于维护状态。

1.1 图

把操作任务描述成有向无环图,按着计算顺序定义图中的节点。

matrix1 = tf.constant([[3.,3.]])
# 定义一个1*2矩阵
matrix2 = tf.constant([[2.],[2.]])
# 定义一个2*1的矩阵
product = tf.matmul(matrix1, matrix2)
# 用矩阵乘法将两个矩阵相乘

1.2 会话与设备

启动图的第一步是创建一个Session对象,会话提供在图中执行操作的一些方法。通过会话可以把定义在图中的操作执行出来:

# 创建一个会话:
with tf.Session() as sess:
    # 指定在第二个CPU上执行。/gpu可以指定在GPU上执行
    with tf.device('/cpu:1'):
        result = sess.run([product])
        print(result)

# [array([[ 12.]], dtype=float32)]

1.3 变量

变量是一种特殊的数据,它在图中有固定的位置,不像普通张量那样可以流动。创建一个变量张量,使用tf.Variable()构造函数,这个构造函数需要一个初始值,初始值的形状和类型决定了这个变量的形状和类型。
Tensorflow还提供了填充机制,可以在构建图时使用tf.placeholder()临时替代任意操作的张量,在调用Session对象的run()方法去执行图时,使用填充数据作为调用的参数,调用结束后,填充数据就消失了。

output = tf.Variable(0)
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.multiply(input1, input2)

with tf.Session() as sess:
    feed_dict={input1:[7.], input2:[8.]}
    result = sess.run([output],feed_dict=feed_dict)
    print(result)

# [array([ 56.], dtype=float32)]

1.4例子

tensorflow运行分为4步:

  • 加载数据定义超参数
  • 构建网络
  • 训练模型
  • 评估模型、进行预测

同个一个例子来学习方程:

y=x20.5

生成和加载数据

import tensorflow as tf
import numpy as np

# 在[-1,1]之间创建300个数据,并将形状从(3,)->(300,1)
x_data = np.linspace(-1,1,300)[:, np.newaxis]
# 加入一些噪声,与x_data的维度一致
noise = np.random.normal(0, 0.05, x_data.shape)
# y = x^2 - 0.5 + 噪声
y_data = np.square(x_data) - 0.5 + noise

# 定义占位符,用于输入神经网络的变量
xs = tf.placeholder(tf.float32, [None, 1])
ys = tf.placeholder(tf.float32, [None, 1])

构建网络模型

# 定义构建网络的函数
def add_layer(inputs, in_size, out_size, activation_function=None):
    # 构建权重,是一个in_size*out_size的矩阵,正态随机初始化
    weights = tf.Variable(tf.random_normal([in_size, out_size]))
    # 构建偏置,1*out_size的矩阵
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)
    # 矩阵相乘
    Wx_plus_b = tf.matmul(inputs, weights) + biases
    # 激活函数
    if activation_function is None:
        outputs = Wx_plus_b
    else:
        outputs = activation_function(Wx_plus_b)
    return outputs

# 构建隐藏层1,假设有20个单元,用relu激活函数
h1 = add_layer(xs, 1, 20, activation_function=tf.nn.relu)
# 输出层,将隐藏层的数据放到输出层中,与label y作比较
prediction = add_layer(h1, 20, 1, activation_function=None)


# 定义损失函数
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), reduction_indices = [1]))
# 用梯度下降法,以0.1为学习率
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

训练模型

#初始化所有变量
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

for i in range(1000):
    sess.run(train_step, feed_dict={xs : x_data, ys : y_data})
    if i%100 == 0:
        print(sess.run(loss, feed_dict={xs : x_data, ys : y_data}))
# 可以看到损失值一直减少
"""
6.78231
0.00632235
0.00436786
0.00395835
0.00373421
0.00363523
0.00357616
0.00354066
0.00351801
0.00349816
"""

2 批标准化(batch normalization BN)

深度神经网络随着网络深度加深,会有梯度弥散问题,导致训练起来会变得困难,当训练样本和目标样本分布不一致的时候无法很好的泛化,BN就是在每一层都对训练样本做一个矫正。

2.1 方法

在激活函数之前做一个非线性映射,对 y=Wx+b 做规范化,是结果的各个维度均值为0,方差为1,稳定的分布有利于网络训练。

2.2 优点:

  • 加大探索步长,加快收敛速度
  • 更容易跳出局部最小值
  • 破坏原来的数据分布,一定程度上缓解过拟合

2.3 示例

import tensorflow as tf

W = tf.constant([[-2.,12.,6.],[3.,2.,8.]],)
print(W.shape)
mean,var = tf.nn.moments(W, axes = [0])

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    resultMean = sess.run(mean)
    print(resultMean)
    resultVar = sess.run(var)
    print(resultVar)

size = 3
scale = tf.Variable(tf.ones([size]))
shift = tf.Variable(tf.zeros([size]))
epsilon = 0.001
W = tf.nn.batch_normalization(W, mean, var, shift, scale, epsilon)
#W = (W - mean) / tf.sqrt(var + 0.001)
#W = W * scale + shift

with tf.Session() as sess:
    #必须要加这句不然执行多次sess会报错
    sess.run(tf.global_variables_initializer())
    resultW = sess.run(W)
    print(resultW)
#观察初始W第二列 12>2 返回BN的W值第二列第二行是负的,其余两列相反

"""
[[-0.99992001  0.99997997 -0.99950027]
 [ 0.99991995 -0.99997997  0.99950027]]
 """

3优化方法

3.1 BGD (batch gradient descent)

提取训练集中所有内容 xi ,以及相关的输出 yi ,计算梯度和误差并更新参数

  • 优缺点:
    • 不需要减少学习率,但是训练时间长

3.1 SGD (stochastic gradient descent)

拆分成一个个小的批次。随机抽取放进模型计算并更新参数

  • 优点:
    • 收敛速度快。
  • 缺点:
    • 不同的批次有会有不同梯度,应该用不同的学习率,但是调整比较困难
    • 容易收敛到局部最优或者鞍点

3.2 Momentum

模拟物理中动量的概念,在更新时在一定程度上保留之前的方向,直观上讲就是,要是当前时刻的梯度与历史时刻梯度方向相似,这种趋势在当前时刻则会加强;要是不同,则当前时刻的梯度方向减弱。能抑制震荡,加快收敛。

3.3 Adagrad

能自适应的调整学习率,如果梯度比较大学习率衰减得快一些,梯度比较小学习率衰减得慢一些。

  • 优点
    • 收敛速度比较好,性能比较稳定
  • 缺点:
    • 容易过早的减小学习率使得训练提前结束,特别是在网络结果比较深的情况下。

3.4 RMSprop

RMSProp通过引入一个衰减系数,让r每回合都衰减一定比例,类似于Momentum中的做法。

  • 优点:
    • 相比于AdaGrad,这种方法很好的解决了深度学习中过早结束的问题 ,适合处理非平稳目标,对于RNN效果很好

3.5 Adam

Adam(Adaptive Moment Estimation)本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。

猜你喜欢

转载自blog.csdn.net/xiayto/article/details/79581748