深度学习框架TensorFlow的学习与应用

视频地址: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里被启动。

【个人感想】

用编译原理的知识解释一下上面的图

表达式→表达式 操作 表达式 | 变量 | 常量 | 占位符

在会话中可以运行的是表达式。

很明显因为有表达式→常量,所以常量也是表达式。

编译原理中的“句子”、“短语”等等概念都可以应用到这来。

代码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函数 softmax(x)_i=\frac{exp(x_i)}{\sum_jexp(x_j)}

代码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节 交叉熵

二次代价函数:C=\frac{1}{2n}\sum_x\left \| {\rm y}(x)-a^L(x) \right \|^2,即对于每个样本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递归神经网络

以前的模型不能处理相邻两帧数据的联系
递归神经网络RNN会把上一个时间的信息作为一个输入​​​​
LSTM

代码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))
发布了80 篇原创文章 · 获赞 22 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u010099177/article/details/93775741