视频地址:https://www.bilibili.com/video/av20542427
TensorFlow网站(Google官方版):http://www.tensorfly.cn/tfdoc/tutorials/overview.html
第2节 TensorFlow的基础使用
TensorFlow是一个编程系统,使用图graphs来表示计算任务,图中的节点称之为operation,一个op获得≥0个Tensor。
Tensor看作是一个n维的数组或列表,图必须在会话Session里被启动。
【个人感想】
用编译原理的知识解释一下上面的图
表达式→表达式 操作 表达式 | 变量 | 常量 | 占位符
在会话中可以运行的是表达式。
很明显因为有表达式→常量,所以常量也是表达式。
编译原理中的“句子”、“短语”等等概念都可以应用到这来。
扫描二维码关注公众号,回复: 9902212 查看本文章
代码2-1 如何创建会话并执行会话中的内容
import tensorflow as tf
# 创建一个常量op
m1 = tf.constant([[3, 3]])
# 创建一个2行1列的常量op
m2 = tf.constant([[2], [3]])
# 矩阵相乘
product = tf.matmul(m1, m2)
print(product)
#OUT# Tensor("MatMul:0", shape=(1, 1), dtype=int32)
# 定义一个会话 还需要一个图, product逻辑自动形成一个图
sess = tf.Session()
result = sess.run(product)
print(result)
sess.close()
#OUT# [[15]]
# 自动关闭Session: with语句
with tf.Session() as sess:
pass
代码2-2 变量的使用
import tensorflow as tf
x = tf.Variable([1, 2]) # 参数是initial value
a = tf.constant([3, 3])
# 增加一个减法操作
sub = tf.subtract(x, a)
# 和一个加法操作
add = tf.add(x, sub)
# 初始化所有变量的过程
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init) # 在同一个会话中, 是连续的
print(sess.run(sub))
print(sess.run(add))
# 创建变量初值为0
state = tf.Variable(0, name='counter')
new_value = tf.add(state, 1)
update = tf.assign(state, new_value) # 赋值, 左←右
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print(sess.run(state))
for i in range(5):
sess.run(update)
print(sess.run(state))
代码2-3 TensorFlow中的Fetch和Feed
import tensorflow as tf
# Fetch 在会话中同时执行多个操作, 得到运行结果
input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
add = tf.add(input2, input3)
mul = tf.multiply(input1, add)
with tf.Session() as sess:
result = sess.run([mul, add]) # FETCH
print(result)
#OUT# [21.0, 7.0]
# Feed
# 创建占位符, 待填充 feed
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.multiply(input1, input2)
with tf.Session() as sess:
# 运行的时候再把值传入
print(sess.run(output, feed_dict={input1:[7.], input2:[2.]}))
#OUT# [14.]
代码2-4 TensorFlow简单案例
import numpy as np
import tensorflow as tf
# 使用numpy生成100个随机点
x_data = np.random.rand(100)
y_data = x_data * 0.1 + 0.2 # 真实值
# 构造一个线性模型
b = tf.Variable(0.)
k = tf.Variable(0.)
y = k * x_data + b # 预测值. 直接乘号, 运算符重载.
# 二次代价函数
loss = tf.reduce_mean(tf.square(y_data - y))
# 定义梯度下降法优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.2)
# 定义最小化代价函数
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, b]))
#OUT#
# 0 [0.05602787, 0.10101426]
# 20 [0.10537198, 0.19700642]
# 40 [0.10338055, 0.1981162]
# 60 [0.10212733, 0.19881456]
# 80 [0.10133871, 0.199254]
# 100 [0.10084243, 0.19953056]
# 120 [0.10053015, 0.19970457]
# 140 [0.100333616, 0.1998141]
# 160 [0.10020994, 0.19988301]
# 180 [0.10013211, 0.19992639]
# 200 [0.10008313, 0.19995368]
【个人感想】
optimizer.minimize() 返回的东西可以看成是表达式,也就是对变量的操作。
第3节 使用TensorFlow进行回归和分类
代码3-1 回归
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
# 使用numpy生成200个随机点
x_data = np.linspace(-0.5, 0.5, 200)[:, np.newaxis] # 产生均匀分布的200个点. 中括号里面是转置.
y_data = np.square(x_data) + np.random.normal(0, 0.02, x_data.shape) # y=x*x+正态分布的噪音
# 定义两个placeholder
x = tf.placeholder(tf.float32, [None, 1]) # 任意行, 1列, 根据样本定义的
y = tf.placeholder(tf.float32, [None, 1]) # 任意行, 1列, 根据样本定义的
# 定义神经网络的中间层
Weights_L1 = tf.Variable(tf.random_normal([1, 10]))
biases_L1 = tf.Variable(tf.zeros([1, 10]))
Wx_plus_b_L1 = tf.matmul(x, Weights_L1) + biases_L1
L1 = tf.nn.tanh(Wx_plus_b_L1)
# 定义神经网络的输出层
Weights_L2 = tf.Variable(tf.random_normal([10, 1])) # 中间是10个神经元, 所以10对1的矩阵
biases_L2 = tf.Variable(tf.zeros([1, 1]))
Wx_plus_b_L2 = tf.matmul(L1, Weights_L2) + biases_L2
prediction = tf.nn.tanh(Wx_plus_b_L2) # 激活函数
# 二次代价函数
loss = tf.reduce_mean(tf.square(y - prediction))
# 使用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for _ in range(2000):
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-')
plt.show()
运行结果:
【个人感想】
线性层是经常写的东西,其中的维度要注意,与神经网络1层的节点个数有关系。
从语法树的层面讲,上面的程序的结构如下:
从神经网络的层面讲,上面的数据流图的结构如下:
3-2 手写数字识别
输入数据60000个样本*几百像素, label=60000个样本*10(one-hot向量)
softmax函数
代码3-3 手写数字识别(基础版)
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 载入数据集
mnist = input_data.read_data_sets("MNIST_data", one_hot=True) # 该语句会自动下载(我是手动下载的) onehot把标签转换为01的格式.
# 定义每个批次的大小 (每次放一批进行训练)
batch_size = 100
m_batch = mnist.train.num_examples // batch_size
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.reduce_mean(tf.square(y - prediction)) # 二次代价函数
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
init = tf.global_variables_initializer()
# 求准确率
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1)), tf.float32))
with tf.Session() as sess:
sess.run(init)
for epoch in range(21):
for batch in range(m_batch): # 一共多少批
batch_xs, batch_ys = mnist.train.next_batch(batch_size) # 一批多少个样本
sess.run(train_step, feed_dict={x: batch_xs, y: batch_ys})
r1, r2 = sess.run([loss, accuracy], feed_dict={x: mnist.test.images, y: mnist.test.labels})
print("loss函数的结果与准确率" % [r1, r2])
第4节 交叉熵
二次代价函数:,即对于每个样本x,y是实际值,a是预测值。
二次代价函数在某些情况下不合理(有一个类似sigmoid的图像,在两侧是x调整很大但是y调整很小),所以提出了交叉熵代价函数。
交叉熵能实现:误差大的时候调整得快,误差小的时候调整得慢。
代码4-1 交叉熵作为代价函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction))
Dropout 随机选择部分神经元工作
代码4-2 DropOut
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 载入数据集
mnist = input_data.read_data_sets("MNIST_data", one_hot=True) # 该语句会自动下载(我是手动下载的) onehot把标签转换为01的格式.
# 定义每个批次的大小 (每次放一批进行训练)
batch_size = 100
m_batch = mnist.train.num_examples // batch_size
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)
# 创建一个4层的神经网络
W1 = tf.Variable(tf.zeros([784, 100]))
b1 = tf.Variable(tf.zeros([100]))
L1 = tf.nn.tanh(tf.matmul(x, W1) + b1)
L1_drop = tf.nn.dropout(L1, keep_prob)
W2 = tf.Variable(tf.zeros([100, 100]))
b2 = tf.Variable(tf.zeros([100]))
L2 = tf.nn.tanh(tf.matmul(L1_drop, W2) + b2)
L2_drop = tf.nn.dropout(L2, keep_prob)
W3 = tf.Variable(tf.zeros([100, 100]))
b3 = tf.Variable(tf.zeros([100]))
L3 = tf.nn.tanh(tf.matmul(L2_drop, W3) + b3)
L3_drop = tf.nn.dropout(L3, keep_prob)
W4 = tf.Variable(tf.zeros([100, 10]))
b4 = tf.Variable(tf.zeros([10]))
L4 = tf.nn.softmax(tf.matmul(L3_drop, W4) + b4)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=L4))
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
init = tf.global_variables_initializer()
# 求准确率
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y, 1), tf.argmax(L4, 1)), tf.float32))
with tf.Session() as sess:
sess.run(init)
for epoch in range(21):
for batch in range(m_batch): # 一共多少批
batch_xs, batch_ys = mnist.train.next_batch(batch_size) # 一批多少个样本
r = sess.run([train_step, loss], feed_dict={x: batch_xs, y: batch_ys, keep_prob:0.9})
print(r[1])
# print(sess.run([loss], feed_dict={x: batch_xs, y: batch_ys, keep_prob:0.5}))
accu1 = sess.run(accuracy, feed_dict={x:mnist.train.images, y:mnist.train.labels,keep_prob:1.0})
accu2 = sess.run(accuracy, feed_dict={x:mnist.test.images, y:mnist.test.labels, keep_prob:1.0})
print("%s准确率 %s" %(epoch, [accu1, accu2]))
优化器
标准梯度下降法:计算所有样本的汇总误差,然后根据总误差来更新权值。
随机梯度下降法 SGD:随机抽取一个样本来计算误差,然后更新权值
批量梯度下降法:一种折中的方案,从总样本中选一批最好的。
视频4-3, 20分40秒有个动画,动画中,SGD走得最慢,Adadelta走得最快。
新的优化器是比较快的,但是梯度下降法可能最后的准确率高。吴恩达推荐Adam。
代码4-3
train_step = tf.train.AdamOptimizer(1e-2).minimize(loss)
第5节 使用TensorBoard进行结构可视化
Google官方中文教程:http://www.tensorfly.cn/tfdoc/how_tos/summaries_and_tensorboard.html
5-2 使用TensorBoard查看网络结构
5-3 查看网络运行数据
使用TensorBoard观察运行数据,可以判断网络的数据是否正确。
第6节 卷积神经网络
6-1 基本知识
传统神经网络的问题:权值太多,计算量太大,需要大量样本训练
数据量的大小最好是未知数(权值)的5~30倍。
CNN通过共享感受野和权值共享减少了神经网络需要训练的个数。
卷积层:一个矩阵跟图像的每个像素相乘,池化层:选择一个图像中某一块的最大值、平均值等等。
代码6-2 卷积神经网络分类
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
batch_size = 100
m_batch = mnist.train.num_examples // batch_size
# 初始化权重
def weight_variable(shape):
return tf.Variable(tf.truncated_normal(shape, stddev=0.1)) # 生成新的正态分布
# 初始化偏置
def bias_variable(shape):
return tf.Variable(tf.constant(0.1, shape=shape))
# 卷积层
def conv2d(x, w):
return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') # 步长: 批次个数, 宽, 高, 通道数量
# 池化层
def max_pool_2x2(x):
# 注释 KSIZE = [1, x, y, 1]
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
# 定义两个placeholder
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
# 改变x的格式转为4D的向量
x_image = tf.reshape(x, [-1, 28, 28, 1]) # -1代表批次的大小
# 第一层的权值和偏置值
w_conv1 = weight_variable([5, 5, 1, 32]) # 卷积采样窗口5*5, 输入通道是1, 输出通道
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
# 第二层的权值、偏置值、卷积层、池化层
w_conv2 = weight_variable([5, 5, 32, 64]) # 64个卷积核从32个平面抽取特征
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
# 28*28的图片第一次卷积后还是28*28, 第一次池化后是14*14
# 第二次卷积后是14*14, 第二次池化后是7*7
# 最终得到64张7*7的平面
# 初始化第一个全连接层的权重
w_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
# 把池化层2输出为扁平化1层
flat_fc1 = tf.reshape(h_pool2, [-1, 7 * 7 * 64]) # -1可以用来对形状进行推断, 在这里-1是一批样本的个数
h_fc1 = tf.nn.relu(tf.matmul(flat_fc1, w_fc1) + b_fc1)
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
# 初始化第二个全连接层
w_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])
h_fc2 = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2) + b_fc2)
# 交叉熵代价函数
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=h_fc2))
# 使用AdamOptimizer进行优化
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
# 结果存在布尔列表中
correct_prediction = tf.equal(tf.argmax(h_fc2, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(21):
for batch in range(m_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
sess.run(train_step, feed_dict={x:batch_xs, y:batch_ys, keep_prob:0.7})
acc = sess.run(accuracy, feed_dict={x:mnist.test.images, y:mnist.test.labels, keep_prob:1.0})
print("Iter %s Testing Accuracy=%s" % (epoch, acc))
第7节 LSTM
RNN递归神经网络
代码7-2
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MINST_data', one_hot=True)
# 输入图片是28*28
n_inputs = 28
max_time = 28
lstm_size = 100
n_classes = 10
batch_size = 50
n_batch = mnist.train.num_examples
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
weights = tf.Variable(tf.truncated_normal([lstm_size, n_classes], stddev=0.1))
biases = tf.Variable(tf.constant(0.1, shape=[n_classes]))
# 定义RNN网络
def RNN(X, weights, blases):
inputs = tf.reshape(X, [-1, max_time, n_inputs])
# 定义LSTM基本CELL
lstm_cell = tf.contrib.run.core_run_cell.BasicLSTMCell(lstm_size)
# final_state[0]是cell_state, final_state[1]是hidden_state
outputs, final_state = tf.nn.dynamic_rnn(lstm_cell, inputs, dtype=tf.float32)
results = tf.nn.softmax(tf.matmul(final_state[1], weights) * biases)
return results
prediction = RNN(x, weights, biases)
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=y))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1)), tf.float32))
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for epoch in range(6):
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 %s, accuracy %s" % (epoch, acc))