目录
1 Tensorflow入门
1.1 张量和图
TensorFlow是一种采用数据流图,用于数值计算的开源软件库。其中Tensor代表传递的数据是张量(即多维数组),Flow表示使用计算图进行运算。
例程:
# exp1
a = tf.constant(2, tf.int16)
b = tf.constant(4, tf.float32)
with tf.Session() as session:
tf.global_variables_initializer().run()
print(session.run(a))
print(session.run(b))
'''
output=2
4.0
'''
# exp2
a = tf.constant(2, tf.int16)
b = tf.constant(4, tf.float32)
graph = tf.Graph()
with graph.as_default():
a = tf.Variable(8, tf.float32)
b = tf.Variable(tf.zeros([2,2], tf.float32))
with tf.Session(graph=graph) as session:
tf.global_variables_initializer().run()
print(session.run(a))
print(session.run(b))
'''
output=8
[[ 0. 0.]
[ 0. 0.]]
'''
在TensorFlow中所有变量和运算都是存储在计算图中,在构建完模型所需的图,需要打开对话(Session)来运行计算图。
如以下代码,我们只定义了一张图,但并未运行它,因此不会输出结果
a=tf.constant([1,2],name="a")
b=tf.constant([2,4],name="b")
result = a+b
print(result)
需要创建一个运行结束后即关闭的会话来输出计算结果,有以下两种方法。
a=tf.constant([1,2])
b=tf.constant([2,4])
result = a+b
'''
sess=tf.Session()
print(sess.run(result))
sess.close
'''
with tf.Session() as sess:
print(sess.run(result))
1.2 常量、变量和占位符
TensorFlow中最基本的单位tensor,包括常量constant、变量variable、占位符placeholder。以下例程定义常量与变量
import numpy as np
a=tf.constant(2,tf.int16)
b=tf.constant(8.9,tf.float32)
d=tf.Variable(4,tf.int16)
g = tf.constant(np.zeros(shape=(2,2), dtype=np.float32))
# 等价于 g=tf.zeros([2,2],tf.float32)
h = tf.zeros([11], tf.int16)
i = tf.ones([2,2], tf.float32)
l = tf.Variable(tf.zeros([5,6,5], tf.float32))
# print(a,'\n',d,'\n',g,'\n',i,'\n',h,'\n',l)
with tf.Session() as sess:
print(sess.run(a),'\n',sess.run(g),'\n',sess.run(h))
'''
2
[[0. 0.]
[0. 0.]]
[0 0 0 0 0 0 0 0 0 0 0]
'''
常量在赋值后不可修改,占位符在执行方法时设置。在含有优化器的算法内,变量是动态计算的,未使用优化器时,变量仍作为普通变量。使用变量前,需要执行初始化方法,系统才会给变量赋值。
with tf.Session() as sess:
# 常量
node1 = tf.constant(3.0, tf.float32)
node2 = tf.constant(4.0)
print (node1, node2) # 只打印结点信息
# 占位符
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b # 与调用add方法类似
print (sess.run(adder_node, {a: 3, b: 4.5}))
print (sess.run(adder_node, {a: [1, 3], b: [2, 4]}))
# 变量
W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)
x = tf.placeholder(tf.float32)
# linear_model = node1 * x + node2
linear_model = W * x + b
sess.run(tf.global_variables_initializer()) #初始化模型参数
print ("linear_model: ", sess.run(linear_model, {x: [1, 2, 3, 4]}))
占位符在使用神经网络时很有帮助,以下展示了使用常量和占位符进行计算。
w1=tf.Variable(tf.random_normal([1,2],stddev=1,seed=1))
#因为需要重复输入x,而每建一个x就会生成一个结点,计算图的效率会低。所以使用占位符
x=tf.placeholder(tf.float32,shape=(1,2))
x1=tf.constant([[0.7,0.9]])
a=x+w1
b=x1+w1
sess=tf.Session()
sess.run(tf.global_variables_initializer())
#运行y时将占位符填上,feed_dict为字典,变量名不可变
y_1=sess.run(a,feed_dict={x:[[0.7,0.9]]})
y_2=sess.run(b)
print(y_1)
print(y_2)
sess.close
1.3 实例
构建三层全连接神经网络
# 定义变量w1,w2(权重)
w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2=tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
# 定义占位符x,y(样本集)
x=tf.placeholder(tf.float32,shape=(None,2)) # None可以根据batch大小确定维度,在shape的一个维度上使用None
y=tf.placeholder(tf.float32,shape=(None,1))
# 定义ReLU激活函数
a=tf.nn.relu(tf.matmul(x,w1)) #tf.nn.relu(features, name = None),这个函数的作用是计算激活函数relu,即max(features, 0)。即将矩阵中每个元素的负值置0。
yhat=tf.nn.relu(tf.matmul(a,w2)) # tf.matmul为矩阵相乘,yhat为预测的值
# 定义交叉熵损失函数和训练算法AdamOptimizer
cross_entropy=-tf.reduce_mean(y*tf.log(tf.clip_by_value(yhat,1e-10,1.0))) #tf.clip_by_value(A, min, max):输入一个张量A,把A中的每一个元素的值都压缩在min和max之间。小于min的让它等于min,大于max的元素的值等于max。
train_op=tf.train.AdamOptimizer(0.001).minimize(cross_entropy) # 学习率为0.001
# 随机生成512个样本,样本特征维数为2
data_size=512
X = np.random.RandomState(1).rand(data_size,2) # 样本范围为[0, 1)
# 生成标签,1为正样本,0为负样本
Y = [[int(x1+x2<1)] for (x1,x2) in X]
batch_size=10 # 每次训练读取样本个数
with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) # 初始化
print('初始化权重为:\n',sess.run(w1),'\n',sess.run(w2))
steps=10001
for i in range(steps):
#选定每一个批量读取的首尾位置,确保在1个epoch(全部样本训练一次为1个epoch)内采样训练
start = i*batch_size % data_size
end = min(start+batch_size,data_size)
sess.run(train_op,feed_dict={x:X[start:end],y:Y[start:end]}) # 开始训练
if i % 1000 == 0:
training_loss=sess.run(cross_entropy,feed_dict={x:X,y:Y})
print("在迭代%d次后,训练损失为%g"%(i,training_loss))
上面的代码定义了一个简单的三层全连接网络(输入层、隐藏层和输出层分别为 2、3 和 1 个神经元),隐藏层和输出层的激活函数使用的是 ReLU 函数。该模型训练的样本总数为 512,每次迭代读取的批量为 10。这个简单的全连接网络以交叉熵为损失函数,并使用Adam优化算法进行权重更新。
2 Tensorflow实现CNN(LeNet-5)
2.1 导入模块
import tensorflow as tf
import numpy as np
2.2 加载数据
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
数据集包括训练集数据(55000,784),训练集标签(55000,10),测试集数据(10000,784),测试集标签(10000,10)
2.3 构建神经网络
# 一,函数声明部分
def weight_variable(shape):
# 初始化权重;截断正态分布,标准差为0.1,默认最大为1,最小为-1,均值为0
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
# 初始化偏置值为0.1
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W):
# 卷积操作;x为做卷积的输入图像,W为相当于CNN中的卷积核,,strides是滑动的步长,padding方式为SAME:边缘外自动补0,遍历相乘;结果返回一个Tensor,这个输出,就是我们常说的feature map
# 详见https://blog.csdn.net/mao_xiao_feng/article/details/53444333
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x):
# 池化操作;x为池化层输入,ksize为池化窗口的大小
# 详见https://blog.csdn.net/mao_xiao_feng/article/details/53453926
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')
# 二,定义输入输出结构
# 声明一个占位符,None表示输入图片的数量不定,28*28图片分辨率
xs = tf.placeholder(tf.float32, [None, 28*28])
# 类别是0-9总共10个类别,对应输出分类结果
ys = tf.placeholder(tf.float32, [None, 10])
# x_image又把xs reshape成了28*28*1的形状,因为是灰色图片,所以通道是1.作为训练时的input,-1代表图片数量不定
x_image = tf.reshape(xs, [-1, 28, 28, 1])
# 三,搭建网络(核心步骤)
## 第一层卷积操作/池化操作 ##
# 定义32个5*5的通道为1的卷积核
W_conv1 = weight_variable([5, 5, 1, 32])
# 定义32个偏置值,每个卷积核对应一个偏置量
b_conv1 = bias_variable([32])
# 执行卷积操作并加上偏执量,激活函数为ReLU函数,得到卷积结果(32-5+1)28x28x32
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
# 执行池化操作,得到池化结果14x14x32
h_pool1 = max_pool_2x2(h_conv1)
## 第二层卷积/池化操作 ##
# 64个5*5的通道为32的卷积核
w_conv2 = weight_variable([5,5,32,64])
# 64个偏置值
b_conv2 = bias_variable([64])
# 卷积结果14x14x64,注意此时输入为上一层的输出结果h_pool1
h_conv2 = tf.nn.relu(conv2d(h_pool1,w_conv2)+b_conv2)
# 池化结果7x7x64
h_pool2 = max_pool_2x2(h_conv2)
## 第三层全连接操作 ##
W_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) # 将第二层卷积池化结果reshape成二维数据,只有一行7*7*64个数据,即[n_samples, 7, 7, 64] ->> [n_samples, 7*7*64]
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
## dropout操作,降低过拟合 ##
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
## 第四层输出操作 ##
# 二维张量,1*1024矩阵卷积,共10个卷积,对应我们开始的ys长度为10
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
# softmax输出,得到最终的分类结果1*1*10
y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
# 四,定义损失函数和优化算法
cross_entropy = -tf.reduce_sum(ys * tf.log(y_conv))
train_step = tf.train.GradientDescentOptimizer(0.0001).minimize(cross_entropy)
# 五,开始数据训练以及评测
with tf.Session() as sess:
# tf.argmax(vector, 1):返回的是vector中的最大值的索引号,如果vector是一个向量,那就返回一个值;
# tf.equal(A, B)是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,反正返回False,返回的值的矩阵维度和A是一样的
# tf.cast(x, dtype, name=None)将x转换成dtype类型
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(ys,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
sess.run(tf.global_variables_initializer())
for i in range(2000):
batch = mnist.train.next_batch(50)
sess.run(train_step,feed_dict={xs: batch[0], ys: batch[1], keep_prob: 0.5})
if i%100 == 0:
train_accuracy = accuracy.eval(feed_dict={xs:batch[0], ys: batch[1], keep_prob: 1.0})
print("step %d, training accuracy %g"%(i, train_accuracy))
print("test accuracy %g"%accuracy.eval(feed_dict={xs: mnist.test.images, ys: mnist.test.labels, keep_prob: 1.0}))
3 Tensorflow实现Capsule Network
见资料
4 Tensorflow实现RNN/LSTM/GRU
4.1 导入模块
import tensorflow as tf
import numpy as np
4.2 加载数据
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
4.3 设置超参数
train_rate=0.001 #学习速率
train_step=1000
batch_size=1280 #每批样本数
display_step=100 #控制输出频次
frame_size=28 #序列里面每一个分量的大小。因为每个分量都是一行像素,而一行像素有28个像素点。所以frame_size为28
sequence_length=28 #每个样本序列的长度。因为我们希望把一个28x28的图片当做一个序列输入到rnn进行训练,所以我们需要对图片进行序列化。一种最方便的方法就是我们认为行与行之间存在某些关系,于是把图片的每一行取出来当做序列的一个维度。所以这里sequence_size就是设置为28。
hidden_num=100 #隐层个数
n_classes=10 #类别数
4.4 神经网络模型
单层RNN/LSTM/GRU:只需在第12行中修改为BasicRNNCell/BasicLSTMCell/GRUCell即可,其余的都不变
多层RNN/LSTM/GRU:将第12行变成第13行(即tf.nn.rnn_cell.MultiRNNCell这行)
graph = tf.Graph()
with graph.as_default():
#定义输入,输出
x=tf.placeholder(dtype=tf.float32,shape=[None,sequence_length*frame_size],name="inputx")
y=tf.placeholder(dtype=tf.float32,shape=[None,n_classes],name="expected_y")
#定义权值
weights=tf.Variable(tf.truncated_normal(shape=[hidden_num,n_classes]))
bias=tf.Variable(tf.zeros(shape=[n_classes]))
# 定义RNN网络
def RNN(x,weights,bias):
'''返回[batch_size,n_classes]'''
x=tf.reshape(x,shape=[-1,sequence_length,frame_size])
# rnn_cell=tf.nn.rnn_cell.BasicRNNCell(hidden_num) # RNN/LSTM/GRU在此处选择BasicRNNCell/BasicLSTMCell/GRUCell。该网络中包含一个深度RNN网络,这个RNN包含hidden_num个隐层单元/RNN cell
rnn_cell = tf.nn.rnn_cell.MultiRNNCell([tf.nn.rnn_cell.GRUCell(hidden_num) for _ in range(3)]) # 构建多层RNN/LSTM/GRU网络,3表示3层(这里都是用MultiRNNCell,没有MultiGRUCell等)
output,states=tf.nn.dynamic_rnn(rnn_cell,x,dtype=tf.float32)
return tf.nn.softmax(tf.matmul(output[:,-1,:],weights)+bias,1)
# 计算预计输出
predy=RNN(x,weights,bias)
# 定义损失函数和优化算法
cost=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=predy,labels=y))
train=tf.train.AdamOptimizer(train_rate).minimize(cost)
# 计算accuracy
correct_pred=tf.equal(tf.argmax(predy,1),tf.argmax(y,1))
accuracy=tf.reduce_mean(tf.to_float(correct_pred))
## 开始训练
with tf.Session(graph=graph) as sess:
print('step','accuracy','loss')
sess.run(tf.initialize_all_variables())
step=1
testx,testy=mnist.test.next_batch(batch_size)
while step<train_step:
batch_x,batch_y=mnist.train.next_batch(batch_size)
# batch_x=tf.reshape(batch_x,shape=[batch_size,sequence_length,frame_size])
_loss,__=sess.run([cost,train],feed_dict={x:batch_x,y:batch_y})
if step % display_step ==0:
acc,loss=sess.run([accuracy,cost],feed_dict={x:testx,y:testy})
print(step,acc,loss)
step+=1
5 Tensorflow实现Bi-RNN/SLTM/GRU
1:#定义RNN网络 def RNN
2:weights定义的shape乘上2
具体见资料