本篇是神经网络体系搭建的第四篇,解决体系搭建的TensorFlow相关问题,详见神经网络体系搭建(序)
TensorFlow安装
建议用Anaconda。 - Mac & Linux
代码语言:javascript复制conda create -n tensorflow python=3.5
source activate tensorflow
conda install pandas matplotlib jupyter notebook scikit-learn
conda install -c conda-forge tensorflow
- Windows
conda create -n tensorflow python=3.5
activate tensorflow
conda install pandas matplotlib jupyter notebook scikit-learn
conda install -c conda-forge tensorflow
TensorFlow的套路
初识TensorFlow,最不舒服的一点是:变量不能好好声明定义,非得用特定api封装成tensor才能使用,而且必须到session里才能运行。但是熟悉了它的套路之后也就习惯了,可以帮助打破以前的思维定式。
Session
TesorFlow的API构建在computational graph概念上,是一种对数学运算过程可视化的方法。session是运行graph的环境,分配GPU/CPU。这是和以往程序不同的一点,它是在session中运行的,所以逻辑写在session里。
数据封装
在TensorFlow里,数据不以int、string等方式存储,而是以“tensor”的形式存在。也就是说,所有过去我们熟悉的基本类型,都得用它的api再包装一遍,变成tensor,才能在session里用。
常量
- 关键字:
tf.constant()
import tensorflow as tf
s = tf.constant('hello world!') # 0 维度的字符串 tensor
i = tf.constant(123) # 0 维度的int32 tensor
a = tf.constant([123,324,235432]) # 1 维度的int32 tensor
m = tf.constant([123,324,235432],[23,342,3]) # 2 维度的int32 tensor
非常量
- 很多时候一开始没有初值,需要运行时赋值,这时候就需要用**
tf.placeholder()
。用tf.placeholder()
赋值的变量需要在session中用**feed_dict设置值。 x = tf.placeholder(tf.string) y = tf.placeholder(tf.int32) z = tf.placeholder(tf.float32) with tf.Session() as sess: output = sess.run(x, feed_dict={x: 'Test String', y: 123, z: 45.67}) print(output) # 输出‘Test String’ - 还有一种是一开始有初值,后续需要不断更改的,比如权重矩阵w这一类,需要用
tf.Variable
,用tf.Variable
声明的变量必须在session用tf.global_variables_initializer()
初始化所有变量 n_features = 120 n_labels = 5 weights = tf.Variable(tf.truncated_normal((n_features, n_labels))) bias = tf.Variable(tf.zeros(n_labels)) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) print(sess.run(weights)) print(sess.run(bias )) 上述代码tf.truncated_normal()
表示取自一个正态分布的随机值,tf.zeros()
函数返回一个都是 0 的 tensor。
运算
实现神经网络算法避免不了加减乘除运算,这里罗列几个最基本的运算:
- 加
tf.add()
x = tf.add(5, 2) # 7 - 减
tf.subtract
x = tf.subtract(10, 4) # 6 - 乘
tf.multiply
x = multiply(2, 5) # 10 - 除
tf.divide
# 除需要做一下类型转换,转成同一类型才能相除,否则会报错 x = tf.divide(tf.cast(tf.constant(10), tf.float32), tf.cast(tf.constant(2), tf.float32)) # 5.0 - 矩阵乘法
tf.matmul
def linear(input, w, b): """ Return linear function in TensorFlow :param input: TensorFlow input :param w: TensorFlow weights :param b: TensorFlow biases :return: TensorFlow linear function """ # TODO: Linear Function (xW b) return tf.add(tf.matmul(input, w), b) - 自然对数
tf.log()
x = tf.log(100) # 4.60517
batch
batch在TensorFlow中经常出现。它指一次训练数据的一小部分,而不是一整个数据集,这可以减少内存占用。虽然从运算角度讲是低效的,但是总比在一些内存低的电脑上不能运行强。这是它产生的初衷。
可以看一个计算: 一个float32 占4个字节,则 train_features Shape: (55000, 784) Type: float32 占55000x784x4=172480000字节 train_labels Shape: (55000, 10) Type: float32 占55000x10x4=2200000字节 weights Shape: (784, 10) Type: float32 占784x10x4=31360字节 bias Shape: (10,) Type: float32 占10x4=40字节 输入、权重和偏置项总共的内存空间需求是 174MB,并不是太多。你可以在 CPU 和 GPU 上训练整个数据集。 但将来你要用到的数据集可能是以 G 来衡量,甚至更多。你可以买更多的内存,但是会很贵。
和随机梯度下降结合起来也很好用。因此每次训练对数据混洗,取一个batch,对每个batch用梯度下降求权重,因为batch是随机的,所以其实是在对每个batch做随机梯度下降。
batch的计算方法(用例取自优达学城)
例如有 1000 个数据点,想每个 batch 有 128 个数据。但是 1000 无法被 128 整除。你得到的结果是其中 7 个 batch 有 128 个数据点,1个 batch 有 104 个数据点。(7*128 1*104 = 1000)
batch 里面的数据点数量会不同的情况下,需要利用 TensorFlow 的 tf.placeholder()
函数来接收这些不同的 batch。
继续上述例子,如果每个样本有 n_input = 784 特征,n_classes = 10 个可能的标签,features 的维度应该是 [None, n_input],labels 的维度是 [None, n_classes]。
# Features and Labels
features = tf.placeholder(tf.float32, [None, n_input])
labels = tf.placeholder(tf.float32, [None, n_classes])
None 维度在这里是一个 batch size 的占位符。在运行时,TensorFlow 会接收任何大于 0 的 batch size。
batch的实现
代码语言:javascript复制import math
def batches(batch_size, features, labels):
"""
Create batches of features and labels
:param batch_size: The batch size
:param features: List of features
:param labels: List of labels
:return: Batches of (Features, Labels)
"""
assert len(features) == len(labels)
# TODO: Implement batching
output_batches = []
sample_size = len(features)
for start_i in range(0, sample_size, batch_size):
end_i = start_i batch_size
batch = [features[start_i:end_i], labels[start_i:end_i]]
output_batches.append(batch)
return output_batches
Epochs(代)
一个代是指整个数据集正向、反向训练一次。代在神经网络里是一个可调的超参数。
代码语言:javascript复制for epoch_i in range(epochs):
...
有了上面的基础知识,就可以用TensorFlow搭建模型了,当然,需要的比如softmax,交叉熵等等函数TensorFlow里都封装,具体用时查看API就行。
问题回答
至此,TensorFlow上手完毕。 - TensorFlow如何使用?套路是什么? 见上。简单讲除了所有数据封装在tensor中,运行在session中外没什么特别的。
以上内容来自822实验室神经网络知识分享 我们的822,我们的青春 欢迎所有热爱知识热爱生活的朋友和822思享实验室一起成长,吃喝玩乐,享受知识。