目前所有的算法是基于1.12版本的tensorflow的实现,所以有必要学习一下1.x版本的tensorflow。
一、tensorflow 安装
基于tensorflow 1.4及以上
tensorflow的两个重要的依赖包:
- protocol buffer:谷歌开发的结构化数据处理工具,例如json,xml等。
- 主要的功能是把结构化的数据序列化进行网络传输或存储,然后把序列化的数据再反序列化为结构化数据。protocol buffer 需要定义数据的schema,利用schema来还原数据。使用 - protocol buffer序列化的数据比xml小3到10倍,反序列化时也快20到100倍。
- tensorflow系统中的数据基本上都使用protocol buffer来组织的,分布式的tensorflow的通信协议也gRPC也是以protocol buffer为基础的。
- bazel:谷歌开源的自动化构建工具,谷歌内部的绝大部分应用都是通过bazel构建的。功能类似于Maven等。
可以使用pip安装、docker安装及源码编译安装。
mac使用pip安装1.12.0版本的:pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.12.0-py3-none-any.whl

二、核心概念
- 计算模型
- 数据模型
- 运行模型
2.1 计算图
Tensorflow计算的过程有两个阶段:首先是定义计算,定义的计算是作为计算图上的一个节点。在Tensorflow程序中,会维护自动维护一个计算图,可以通过tf.get_default_graph函数来获取默认的计算图。除了使用默认的计算图,Tensorflow还支持tf.Graph()来创建新的计算图。在不同的计算图中的张量和计算是不可以共享的。
# coding:utf-8
import tensorflow as tf
# 不同的计算图中的计算与张量是相互隔离的
# 创建一个计算图
g1 = tf.Graph()
# 在计算图中定义一个张量v
with g1.as_default():
# 1.12版本把shape在initializer外边定义了
v = tf.get_variable("v", initializer=tf.zeros_initializer(), shape=[1])
# 创建一个新的计算图
g2 = tf.Graph()
with g2.as_default():
v1 = tf.get_variable("v", initializer=tf.ones_initializer(), shape=[1])
# 获取并输出g1中的张量v,结果是[0.]
with tf.Session(graph=g1) as sess:
tf.global_variables_initializer().run()
with tf.variable_scope("", reuse=True):
print(sess.run(tf.get_variable("v")))
# 获取并输出g2中的张量v,结果是[1.]
with tf.Session(graph=g2) as sess:
tf.global_variables_initializer().run()
with tf.variable_scope("", reuse=True):
print(sess.run(tf.get_variable("v")))
还可以指定计算图的设备,上一个计算两个常量的计算图:
with g.device("\gpu:0"):
result = a + b
计算图另一个作用是管理Tensorflow中的资源,把资源放到collection中,可以使用tf.add_to_collection函数来把资源放到collection,tf.get_collection函数来获取collection中所有的资源。放入到collection中的可以是常量、变量或队列等资源。
为了管理方便,Tensorflow也自动维护了一些常用的集合。
2.2 Tensor
Tensorflow中的张量Tensor是数据管理的模型,有零阶张量(也就是标量),一阶张量可以理解为一维数组,n阶张量可以理解为n维数组。Tensorflow中的张量并不会保存数据,只保存计算过程,是计算结果的引用。有三个属性:name,shape和dtype。
- name是node: src_output形式,node代表结点,src_output表示这个结点的第几个输出值。下面的例子result是来自add结点的第1个输出。
- shape是张量的维度,是一个一维数组,这个数组的长度是2.
- dtype是数据的type,浮点类型默认使用float32,整数默认是使用int32,使用默认类型容易出现类型不匹配的情况,所以一般会指定数据类型。

张量的使用:
- 是整个计算过程的引用,可以存储中间结果;
- 可以用来计算真实的数值;
2.3 会话Session
Session拥有并且管理Tensorflow运行过程中的所有的资源。可以显示的打开Session,并关闭Session。另一种方法是使用上下文管理器with来管理。
当一个会话声明后,可以使用指定session的方法来计算一个Tensor
sess = tf.Session()
result.eval(session=sess)
2.4 两层神经网络
一个两层的神经网络:
这个一个由输入层,隐藏层、输出层组成的典型的两层神经网络。使用向量的形式:
参数W的维度是。x的组织形式与Andrew ng的课中的组织形式是不同的,一行代表一个样本,一个样本有两个特征,所以x的维度是一行二列。
a = tf.matmul(x, W1)
y = tf.matmul(a, W2)
# 声明一个二行三列的变量,使用正态分布的对变量初始化
weight = tf.Variable(tf.random_normal([2,3], stddev=2))


两层神经网络的前向传播:
# coding=utf-8
import tensorflow as tf
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是一行两列的矩阵
x = tf.constant([[0.7, 0.9]])
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
with tf.Session() as sess:
# 对变量执行初始化
# sess.run(w1.initializer)
# sess.run(w2.initializer)
# 下面是对所有的变量进行初始化,而不是对每个变量单独执行
tf.global_variables_initializer().run()
print(sess.run(y))
可以通过tf.global_variables()来获取计算图上的所有变量,对持久化计算图的运行状态有帮助。
为什么要用placeholder?
训练一个神经网络需要进行很多轮的迭代,如果每次使用常量时,则会生成百万个的节点,占用很多的资源。而placeholder是占位的意思,先把计算图上位置占住,当用session计算的时候再把数据值传入。
# coding:utf-8
import warnings
warnings.filterwarnings('ignore')
import tensorflow as tf
import numpy as np
from numpy.random import RandomState
# 生成训练数据
datasize = 128
# 定义批大小
batch_size = 8
rdm = RandomState(1)
X = rdm.random([datasize, 2])
print(X.shape)
Y = np.array([[int(x1 + x2 > 1)] for (x1, x2) in X])
print(Y.shape)
# 定义placeholder
x = tf.placeholder(dtype=tf.float32, shape=(None, 2), name='x-input')
y_ = tf.placeholder(dtype=tf.float32, shape=(None, 1), name='y-input')
# 定义参数
w1 = tf.Variable(initial_value=tf.random_normal(shape=(2, 3), stddev=1, seed=1))
w2 = tf.Variable(initial_value=tf.random_normal(shape=(3, 1), stddev=1, seed=1))
# 定义模型
a = tf.matmul(x, w1)
y_pred = tf.sigmoid(tf.matmul(a, w2))
# 定义loss
cross_entropy = -tf.reduce_mean(
y_ * tf.log(tf.clip_by_value(y_pred, 1e-10, 1.0)) + (1 - y_) * tf.log(tf.clip_by_value(1 - y_pred, 1e-10, 1.0)))
# 向后传播
learning_rate = 0.001
train_step = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cross_entropy)
# 开始迭代
STEMPS = 5000
with tf.Session() as sess:
# 在迭代之前初始化所有的数据
tf.global_variables_initializer().run()
print('before loop w1:{}'.format(sess.run(w1)))
print('before loop w2:{}'.format(sess.run(w2)))
for i in range(STEMPS):
start = i * batch_size % datasize
# 当datasize无法整除batch_size时,end只能取到datasize的位置
end = min(start + batch_size, datasize)
sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
if i % 1000 == 0:
# 计算在全部训练数据上的cross entropy
print(f'After loop {i}, cross entropy loss is:{sess.run(cross_entropy, feed_dict={x: X, y_: Y})}')
print('after loop w1:{}'.format(sess.run(w1)))
print('after loop w2:{}'.format(sess.run(w2)))
三、深层神经网络
来源:CSDN
作者:林子要加油
链接:https://blog.csdn.net/real_ilin/article/details/104183152
