tensorflow常用函数接口汇总以及用tensorflow实现自编码机模型

最近学习tensorflow,这里做一个小总结,先说一下我的运行环境,win10+Anaconda3.5,导入tensorflow。

首先提供一个trick,对于一些初次见到的API接口,有时候直接百度搜索出来的答案七七八八的不好看懂,中文官方手册也不是很方便,提供一个比较简单的方法:
(1)打开命令提示符;
(2)输入python;
(3)如下输入

import tensorflow as tf
help(tf.contrib.layers.batch_norm)

注:help()括号里面放你需要查询的函数

—————————————————————————————————————小白记

Tensorflow是一套深度学习开源软件库。从实现上来说,它的计算核心是基于高性能C/C++实现的,外部封装使用了简单的Python语言。
这里简单介绍汇总了一些tensorflow的常用接口,方便以后查询。

1 使用placeholder声明输入占位符

tf.placeholder ()函数

placeholder(
    dtype,
    shape=None,
    name=None
)

比如:

X = tf.placeholder("float", [None, n_input])

或

x = tf.placeholder(tf.float32, shape=(1024, 1024))

后面的shape参数中第一个为行数,第二个为列数,若显示为None,表示同时放入任意条记录

2 声明参数变量

tf.variable ()函数

W = tf.Variable(tf.random_normal([6, 2]), name = 'weights')
b = tf.Variable(tf.zeros([2]), name = 'bias')

或

weights = {
    'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
    'decoder_h1': tf.Variable(tf.random_normal([n_hidden_1, n_input])),
}
biases = {
    'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
    'decoder_b1': tf.Variable(tf.random_normal([n_input])),
}

可以定义变量的类型,形状,名称,有点类似前面的tf.placeholder ()

3 构造前向传播计算图

tf.nn.softmax()函数

softmax(logits, axis=None, name=None, dim=None)

比如:

y_pred = tf.nn.softmax(tf.matmul(input, W) + bias)

其中,logits指的是一个非空的张量,它的数据类型只能为以下几种:half,float32,float64。

另外,softmax函数指的是一个归一化的指数函数。若输入数据是c维度的向量z,那么softmax函数的数据也是一个C维度的向量y,里面的值是0或者1。softmax函数的定义式如下:
无

下面对这一块内容做一个解释。所谓前向传播就是网络正向计算,由输入计算出标签的过程。在这行语句中,tf.matmul()是矩阵乘法算子,tf.nn.softmax()是softmax函数。另外,对于偏置向量bias,可以直接用加号“+”完成矩阵相加操作,这与Numpy等库用法类似。Tensorflow中的Tensor对象和Variable对象都对常用四则运算符号进行过重载,运用很灵活。

4 声明代价函数

tf.reduce_sum()函数

reduce_sum ( 
    input_tensor , 
    axis = None , 
    keep_dims = False , 
    name = None , 
    reduction_indices = None

参数:
input_tensor:要减少的张量。应该有数字类型。
axis:要减小的尺寸。如果为None(默认),则缩小所有尺寸。必须在范围[-rank(input_tensor), rank(input_tensor))内。
keep_dims:如果为true,则保留长度为1的缩小尺寸。
name:操作的名称(可选)。
reduction_indices:axis的废弃的名称。

函数中的input_tensor是按照axis中已经给定的维度来计算的;除非keep_dims是true,否则张量的秩将在axis的每个条目中减少1;如果keep_dims为true,则减小的维度将保留为长度1。
如果axis没有条目,则缩小所有维度,并返回具有单个元素的张量。

比如:

x = tf.constant([[1, 1, 1], [1, 1, 1]])
tf.reduce_sum(x)  # 6
tf.reduce_sum(x, 0)  # [2, 2, 2]
tf.reduce_sum(x, 1)  # [3, 3]
tf.reduce_sum(x, 1, keep_dims=True)  # [[3], [3]]
tf.reduce_sum(x, [0, 1])  # 6

tf.reduce_mean()函数

reduce_mean(
    input_tensor,
    axis=None,
    keep_dims=False,
    name=None,
    reduction_indices=None
)

参数:
input_tensor:要减少的张量。应该有数字类型。
axis:要减小的尺寸。如果为None(默认),则减少所有维度。必须在[-rank(input_tensor), rank(input_tensor))范围内。
keep_dims:如果为true,则保留长度为1的缩小尺寸。
name:操作的名称(可选)。
reduction_indices:axis的不支持使用的名称。
返回:
该函数返回减少的张量。
numpy兼容性
相当于np.mean

比如:

x = tf.constant([[1., 1.], [2., 2.]])
tf.reduce_mean(x)  # 1.5
tf.reduce_mean(x, 0)  # [1.5, 1.5]
tf.reduce_mean(x, 1)  # [1.,  2.]

这两个函数基本类似

这里给出一个计算代价函数的例子,首先给出它的计算公式:

无

# 使用交叉熵作为代价函数
cross_entropy = -th.reduce_sum(y * tf.log(y_pred + 1e-10), reduction_indices = 1)

# 批量样本的代价值为所有样本交叉熵的平均值
cost = tf.reduce_mean(cross_entropy)

5 加入优化算法

tf.train.RMSPropOptimizer()函数

Tensorflow内置了多种经典的优化算法,如随机梯度下降法(SGD),动量算法(Momentum),Adagrad算法,ADAM算法,RMSProp算法。另外还有在线学习算法FTRL。优化器内部会自动构建梯度计算和反向传播部分的计算图。

一般对于优化算法,最关键的参数是学习率,对于学习率的设定是一门技术。而且,不同的优化算法在不同的问题上可能会有不同的收敛速度,在解决问题时可以做多种尝试。

这里给出一个例子:

# 使用随机梯度下降算法优化器来最小化代价,系统自动构建反向传播部分的计算图
optimizer = tf.train.RMSPropOptimizer(learning_rate).minimize(cost)

6 构建模型的训练过程

sess.run()函数

Session启动后就正式进入了训练过程。首先要做的就是使用初始化所有变量,方法是:

# 初始化所有变量,必须最先执行
tf.global_variables_initializer()

Session.run(fetches, feed_dict=None, options=None, run_metadata=None),其中有两个关键的参数,fetches指定需要被计算的节点,可以用数组同时指定多个节点。计算所需要的数据则由feed_dict代入。feed_dict需要传入一个字典,字典的key是输入占位符placeholder,value为真实的输入数据(另外,有一点要声明,参数fetches指定的东西,必须是前面指定过的,不能是之后出现的)。

Session.run()执行完计算之后,会返回计算节点的结果。若节点为算子(算子是一个函数空间到函数空间上的映射O:X→X),则没有返回值,若节点是tensor,则返回当前值。最常见的是优化算子和代价函数tensor的组合,前者不需要返回值,后者计算得到的代价值将会返回,比如(需要注意的是tensorflow并没有计算整个图,只是计算了与想要fetch 的值相关的部分):

—,loss = sess.run(fetches = [train_op, cost], feed_dict=feed)

7 存储和加载模型参数

save()函数
用于存储模型:

# save(sess, path)
save_model = "model_aed_previous/model_aed_previous"
saver = tf.train.Saver()
saver.save(sess, save_model_path)

restore()函数
用于提取模型

# restore(sess, path)
save_model = "model_aed_previous/model_aed_previous"
saver = tf.train.Saver()
saver.restore(sess, save_model_path)

这两个函数不作解释,会用就好。
在上面的程序示例中,由Saver.save()触发的存储操作会生成4个文件。第一个是名为“model.ckpt”的文件,这个文件是真实存储变量及其取值的文件。第二个是名为“model.cpkt.meta”的描述文件,在这个文件存储的是MetaGraphDef结构的对象经过二进制序列化后的内容。MetaGraphDef结构由Proyocol buffer定义,其中包含了整个计算图的描述,各个变量定义的声明,输入管道的形式,以及其它的信息。meta文件可以在没有计算图声明代码的情况下载入模型,而若在应用时还有原始的python程序代码,程序就可以重新构建计算图的基本信息,则加载时只需要“model.ckpt”一个文件即可。第三个文件是以“model.ckpt.index”为名称的文件,存储了变量在checkpoint文件中的位置索引。最后一个是名为“checkpoint”的文件,这个文件中存储了最新存档的文件路劲

8 tensorflow实现三层自编码机

前面给出的都是分块的,如果需要对整个流程有了解还是得看整块代码,这里给出一个tensorflow实现三层自编码机模型的例子。

# 这里就涉及到学习参数的问题了,学习率,迭代次数,小批次
learning_rate = 0.01
training_epochs = 10
batch_size = 256
display_step = 1

# 隐藏层的结点数,输入层的结点数
n_hidden_1 = 50
n_input = train_x.shape[1]

# tuple使用()表示不可变序列,list使用[]表示可变序列,shape参数的[None, n_input]表示行数不固定,列数为属性数
X = tf.placeholder("float", [None, n_input])
# 定义了权重矩阵和偏置参数(先设为随机数)
weights = {
    'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
    'decoder_h1': tf.Variable(tf.random_normal([n_hidden_1, n_input])),
}
biases = {
    'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
    'decoder_b1': tf.Variable(tf.random_normal([n_input])),
}

# 定义了编码和解码函数,tf.matmul(x,y)表示将矩阵a乘以b,tf.add(a, b)表示a和b相加,tf.nn.sigmoid()则是单纯的激活函数了,每个神经元输出的是一个单值
def encoder(x):
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']), biases['encoder_b1']))
    return layer_1
def decoder(x):
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']), biases['decoder_b1']))
    return layer_1
# 这里则是完全描绘出了一个具体的自编码机模型,这里的tf.reduce_mean()定义了损失函数,用的是方差,cost是损失函数,optimizer定义了优化器
# 对于函数tf.reduce_mean(),这里给出它的解释tf.reduce_mean(x)表示求一个矩阵的总体平均值,tf.reduce_mean(x, 0)表示求一个矩阵的列平均值,得到一个行向量
# tf.reduce_mean(x, 1)表示求一个矩阵的行平均值,得到一个列向量
encoder_op = encoder(X)
decoder_op = decoder(encoder_op)
y_pred = decoder_op
y_true = X
batch_mse = tf.reduce_mean(tf.pow(y_true - y_pred, 2), 1)
cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2))
optimizer = tf.train.RMSPropOptimizer(learning_rate).minimize(cost)

# save_model = "model_aed_previous/model_aed_previous"
# # save_model = "model_aed_next/model_aed_next"
# saver = tf.train.Saver()
# init = tf.global_variables_initializer()
# with tf.Session() as sess:
#     now = datetime.now()
#     sess.run(init)
#     total_batch = int(train_x.shape[0] / batch_size)
#     for epoch in range(training_epochs):
#         for i in range(total_batch):
#             batch_idx = np.random.choice(train_x.shape[0], batch_size)
#             batch_xs = train_x[batch_idx]
#             _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs})
#         if epoch % display_step == 0:
#             train_batch_mse = sess.run(batch_mse, feed_dict={X: train_x})
#             print("Epoch:", '%04d' % (epoch + 1),
#                   "cost=", "{:.9f}".format(c),
#                   "Train auc=", "{:.6f}".format(auc(train_y, train_batch_mse)),
#                   "Time elapsed=", "{}".format(datetime.now() - now))
#     print("Optimization Finished!")
#     save_path = saver.save(sess, save_model)
#     print("Model saved in file: %s" % save_path)

# save_model = "model_aed_previous/model_aed_previous"

# 这里要使用模型开始预测了
# tf.train.Saver()用于先创建一个saver对象
# tf.global_variables_initializer添加用于初始化变量的节点
# sess.run()的作用是计算整个张量图,feed_dict的作用是给使用placeholder创建出来的tensor赋值,给出了损失函数
# 这里也计算了预测准确度(这里算的究竟是什么的准确率)
# restore()函数是模型恢复函数,参数为restore(sess, save_path),save()函数用于保存模型,参数为save(sess, save_model)
save_model = "model_aed_next/model_aed_next"
saver = tf.train.Saver()
init = tf.global_variables_initializer()
with tf.Session() as sess:
    saver.restore(sess, save_model)
    test_batch_mse = sess.run(batch_mse, feed_dict={X: test_x})
# 这里算的不是正确率,算的是ROC?
    print("Test auc score: {:.6f}".format(auc(test_y, test_batch_mse)))

# save_model = "model_aed_previous/model_aed_previous"
# 这里给出了预测集和训练集两者的样本大小,却没有计算其准确率
save_model = "model_aed_next/model_aed_next"
saver = tf.train.Saver()
init = tf.global_variables_initializer()
with tf.Session() as sess:
    saver.restore(sess, save_model)
    test_encoding = sess.run(encoder_op, feed_dict={X: test_x})
    train_encoding = sess.run(encoder_op, feed_dict={X: train_x})
    print("Dim for test_encoding and train_encoding are:", test_encoding.shape, train_encoding.shape)

这里面同时有训练和测试的代码,时间问题,这里不过多叙述,应该还好理解,欢迎大家共同学习交流~~~

猜你喜欢

转载自blog.csdn.net/qq_26591517/article/details/80119095