Tensorflow基本概念
- 使用图(Graphs)来表示计算任务
- 在会话(Session)中执行图
- 使用Tensor表示数据
- 通过变量(Variable)维护状态
- 使用feed和fetch可以为任意的操作赋值或取值
Tensor flow是一个编程系统,使用图(graphs)表示计算任务,图(graphs)中的节点称之为op(operation),一个op获得0个或多个Tensor,执行计算,产生0个或多个Tensor。Tensor是一个n维的数组或列表,图必须在会话(Session)里被启动。
注 op生成的全部是Tensor。
Tensor flow基础程序
1、创建图,并启动图
# 创建常量Tensor
m1 = tf.constant([[3,3]])
m2 = tf.constant([[2],[3]])
#创建一个矩阵乘法op(operation),把m1和m2传入
product = tf.matmul(m1,m2)
#这个时候打印product,只能看到product的属性,不能计算它的值,因为图只能在会话在被启动。
# 上面的部分为一个完整的图(graphs)
# 定义会话有两种方式
sess = tf.Session()
result = sess.run(product)
print(result)
sess.close()
# **************
with tf.Session() as sess:
result = sess.run(product)
print(result)
2、变量
# 创建变量,并初始化
w = tf.Variable(<initial-value>, name=<optional-name>)
# 所有变量初始化
init = tf.global_variables_initializer()
with tf.Session() as sess:
#执行变量初始化
sess.run(init)
print(sess.run(state))
# 变量初始化完成后,才能运行其余的图
3、Fetch和Feed
#Fetch:可以在session中同时计算多个op
#定义三个常量
input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
#定义一个加法op
add = tf.add(input2,input3)
#定义一个乘法op
mul = tf.multiply(input1,add)
with tf.Session() as sess:
#同时执行乘法op和加法op
result = sess.run([mul,add])
print(result)
[21.0, 7.0]
#Feed:先定义占位符,等需要的时候再传入数据
#创建占位符
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
#定义乘法op
output = tf.multiply(input1,input2)
with tf.Session() as sess:
#feed的数据以字典的形式传入
print(sess.run(output,feed_dict={input1:[8.],input2:[2.]}))
[16.]
关于fetch与feed,是Tensorflow中会话下运行图的方式。
4、Tensorflow线性回归
#使用numpy生成100个随机点
#样本点
x_data = np.random.rand(100)
y_data = x_data*0.1 + 0.2
#构造一个线性模型
d = tf.Variable(3.0)
k = tf.Variable(0.8)
y = k*x_data + d
#二次代价函数
loss = tf.losses.mean_squared_error(y_data,y)
#定义一个梯度下降法来进行训练的优化器
# 0.3代表学习率
optimizer = tf.train.GradientDescentOptimizer(0.3)
#最小化代价函数
train = optimizer.minimize(loss)
#初始化变量
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for step in range(201):
sess.run(train)
if step%20 ==0:
print(step,sess.run([k,d]))
此算法和LMS算法类似,根据期望结果,修正线性系数,使其无限逼近实际系数。
5、Tensorflow非线性回归
#使用numpy生成200个随机点
x_data = np.linspace(-0.5,0.5,200)[:,np.newaxis]
noise = np.random.normal(0,0.02,x_data.shape)
y_data = np.square(x_data) + noise
plt.scatter(x_data,y_data)
plt.show()
利用feed方式在会话中计算图
#定义两个placeholder
x = tf.placeholder(tf.float32,[None,1]) # 数据的输入值
y = tf.placeholder(tf.float32,[None,1]) # 标签的输入值
#定义神经网络结构:1-20-1 # 20个神经元 1个输出
#定义神经网络中间层
Weights_L1 = tf.Variable(tf.random_normal([1,20])) # 随机输入 变为 tensorflow的变量
biases_L1 = tf.Variable(tf.zeros([20])) # 偏置值
Wx_plus_b_L1 = tf.matmul(x,Weights_L1) + biases_L1 # 神经网络的计算:输入x乘上加权值再加上偏置
L1 = tf.nn.tanh(Wx_plus_b_L1) # 隐藏层的输出
#定义神经网络输出层
Weights_L2 = tf.Variable(tf.random_normal([20,1]))
biases_L2 = tf.Variable(tf.zeros([1]))
Wx_plus_b_L2 = tf.matmul(L1,Weights_L2) + biases_L2
prediction = tf.nn.tanh(Wx_plus_b_L2)
#二次代价函数
loss = tf.losses.mean_squared_error(y,prediction)
#使用梯度下降法训练, 梯度下降法最小化代价函数
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
with tf.Session() as sess:
#变量初始化
sess.run(tf.global_variables_initializer()) # run 获得
for _ in range(5000):
sess.run(train_step,feed_dict={x:x_data,y:y_data})
#获得预测值
prediction_value = sess.run(prediction,feed_dict={x:x_data})
#画图
plt.figure()
plt.scatter(x_data,y_data)
plt.plot(x_data,prediction_value,'r-',lw=5)
plt.show()
MINIST数据集分类简单版本
#载入数据集
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
#每个批次的大小
batch_size = 64
#计算一共有多少个批次 // 表示整数除法
n_batch = mnist.train.num_examples // batch_size
#定义两个placeholder
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])
#创建一个简单的神经网络
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
prediction = tf.nn.softmax(tf.matmul(x,W)+b)
#二次代价函数
loss = tf.losses.mean_squared_error(y,prediction)
#使用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
# 方法 训练 优点 缺点
# 标准梯度下降法 所有的数据 权值的更新比较准确 训练速度比较慢
# 随机梯度下降法 一个数据 训练速度比较快 权值更新方向可能是错的
# 批量随机梯度下降法 批次 权值更新方向比较准确,训练速度比较快
#初始化变量
init = tf.global_variables_initializer()
#结果存放在一个布尔型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))#argmax返回一维张量中最大的值所在的位置
#求准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
with tf.Session() as sess:
sess.run(init)
#epoch:所有数据训练一次,就是一个epoch周期, 21个周期,循环21次,每个周期循环1700多次
for epoch in range(21):
#batch:一般为32,64个数据
for batch in range(n_batch):
batch_xs,batch_ys = mnist.train.next_batch(batch_size) # 每个批次的数据和标签都是不同的
sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
print("Iter " + str(epoch) + ",Testing Accuracy " + str(acc))
相比于上节中Tensorflow非线性回归中用的两层神经网络:中间层和输出层。此例子为仅仅只用了一层神经网络。
上节非线性回归采用的是tf.nn.tanh回归作为输出层函数,此例子采用tf.nn.softmax回归作为输出层函数,具体不同,自行百度!
tf.nn.tanh:双曲正切曲线
tf.nn.softmax回归:将logistic的预测二分类的概率的问题推广到了n分类的概率的问题。
怎么变换三种梯度下降方法,还没研究明白!!
训练函数分析
tf.train.GradientDescentOptimizer使用随机梯度下降算法,使参数沿着 梯度的反方向,即总损失减小的方向移动,实现更新参数
tf.train.MomentumOptimizer在更新参数时,利用了超参数,参数更新公式是
d
i
=
β
d
i
−
1
+
g
(
θ
i
−
1
)
d_i = \beta d_{i-1} + g(\theta_{i-1})
di=βdi−1+g(θi−1)
θ
i
=
θ
i
−
1
−
α
d
i
\theta_i = \theta_{i-1} - \alpha d_i
θi=θi−1−αdi
其中,?为学习率,超参数为?,?为参数,
g
(
θ
i
−
1
)
g(\theta_{i-1})
g(θi−1)为损失函数的梯度。
tf.train.AdamOptimizer利用自适应学习率的优化算法,Adam 算法和随 机梯度下降算法不同。随机梯度下降算法保持单一的学习率更新所有的参数,学 习率在训练过程中并不会改变。而 Adam 算法通过计算梯度的一阶矩估计和二 阶矩估计而为不同的参数设计独立的自适应性学习率。
学习率:决定每次参数更新的幅度。
优化器中都需要一个叫做学习率的参数,使用时,如果学习率选择过大会出现震 荡不收敛的情况,如果学习率选择过小,会出现收敛速度慢的情况。我们可以选 个比较小的值填入,比如 0.01、0.001