## 步骤
### 开启 InteractiveSession
import tensorflow as tf
sess = tf.InteractiveSession()
tensorflow依靠c++后端来计算。连接着后端的部分称为session。tensorflow的一般用法是,首先创建一幅graph,然后用session启动它。
#### 用于计算的Graph
为了在python能实施高效的数值计算,tensorflow会使用NumPy等库,将复杂的计算放在python外部进行,例如矩阵乘法。但是在每次切换回python的时候,还是有大量的开销。这种开销在GPUs和分布式的运行方式下,成本非常高,大量的计算资源消耗在了数据转换上面。
tensorflow对此进行了优化,阻止了单步的复杂运算,改为创建了一幅graph用来描述运算过程,并且完全在python外运行。
因此,python代码的角色就变为构建外部运算graph,并且决定graph的哪一部分应该运行。
## 构建 Softmax Regression Model
这里我们构建一个具有单个线性层的简单softmax回归模型。
### Placeholders
x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
当运行graph时,x用于存储我们的输入。输入图像x构成一个2维浮点张量。
'[None, 784]'的784是一幅简单的扁平MNIST的维度;`None`代表处理的批次的大小,可以是任意大小。
输出的`y_`构成了2维张量,其中每一行是10维向量,表示0~9的数字类别。
当然,placeholder的shape参数是可选的,当shape形状不匹配时,能够帮助tensorflow捕获异常。
### 变量Variables
为模型定义权重'w'和偏置'b',tensorflow将它们定义为`Variable`类型。
`Variable`存储在computation graph中,可以使用和改变。
```python
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
```
我们使用`tf.Variable`为每个参数传递初始值,这里我们用全0初始化'w'和'b'。
维度采用784x10,这是因为有784个输入特征,和10个输出;‘b'是10维也是因为10个类别。
```python
sess.run(tf.initialize_all_variables())
```
也可以通过一步初始化所有的`Variable`
### softmax预测 和 损失函数
我们可以仅仅用一行就完成回归模型的构造:
将输入图片'x'和权重矩阵'W'相乘,再加上偏置'b',之后计算softmax的概率。
```python
y = tf.nn.softmax(tf.matmul(x,W) + b)
```
损失函数使用target和prediction之间的交叉熵。
```python
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
```
其中,`tf.reduce_sum`对所有类别求和,`tf.reduce_mean`对和取平均。
## Train the Model
在定义模型和损失函数之后,就直接是训练了。tensorflow能够自动微分用以计算每个变量的损失函数的梯度。
作为例子,这里我们使用最速梯度下降,步长为0.5,逐步下降交叉熵。
```python
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
```
tensorflow在这样代码里真正做的,是往graph里添加新的操作。这些操作包括:计算梯度,计算参数的更新步长,并且更新参数。
返回值`train_step`,在运行时,会对参数运行梯度下降算法。训练过程只需重复地运行`train_step`就能完成。
```python
for i in range(1000):
batch = mnist.train.next_batch(50)
train_step.run(feed_dict={x: batch[0], y_: batch[1]})
```
每次训练迭代,载入50个训练样本。然后运行`train_step`操作,使用`feed_dict`更新训练样本,代替`x` and `y_`张量。
`feed_dict`能够用来更新graph中任意的张量。
### Evaluate the Model
首先找出那些预测正确的标签。tf.argmax 能给出某个tensor对象在某一维上的其数据最大值所在的索引值。由于标签向量是由0,1组成,因此最大值1所在的索引位置就是类别标签,比如tf.argmax(y,1)返回的是模型对于任一输入x预测到的标签值,而 tf.argmax(y_,1) 代表正确的标签,我们可以用 tf.equal 来检测我们的预测是否真实标签匹配(索引位置一样表示匹配)。
```python
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
```
上面这行代码会给我们一组布尔值。
为了确定正确预测项的比例,我们可以把布尔值转换成浮点数,然后取平均值。例如,[True, False, True, True] 会变成 [1,0,1,1] ,取平均值后得到 0.75.
```python
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
```
最后,我们计算所学习到的模型在测试数据集上面的正确率。这个最终结果值应该大约是91%。
```python
print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
```