# 1.概念

graph：图，表示具体的计算任务
session：会话，图需要在会话中执行，一个会话可以包含很多图
tensor：张量，在此表示数据，类型是numpy::ndarray
variable：就是本意变量，图的重要组成部分
operation：简称op，是图中计算的节点，输入tensor计算后产生tensor
feed、fetch：意思是给图添加数据和获取图中的数据，因为训练过程中有些数据需要动态获得、临时给予数据

# 2. 例子

## 2.1 平面拟合

import tensorflow as tf
import numpy as np

# Create 100 phony x, y data points in NumPy, y = x * 0.1 + 0.3
x1_data = np.random.rand(100).astype(np.float32)
x2_data = np.random.rand(100).astype(np.float32)
y_data = x1_data * 10 + x2_data * 5 + 3 + tf.random_uniform([100], -0.1, 0.1)

# Try to find values for W and b that compute y_data = W * x_data + b
# (We know that W should be 0.1 and b 0.3, but TensorFlow will
# figure that out for us.)

# note: W b and y just statement/container  before initialization
W1 = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
W2 = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W1 * x1_data + W2*x2_data + b

# Minimize the mean squared errors.
loss = tf.reduce_mean(tf.square(y - y_data))
train = optimizer.minimize(loss)

# Before starting, initialize the variables.  We will 'run' this first.
init = tf.initialize_all_variables()

# Launch the graph.
sess = tf.Session()
sess.run(init)

# Fit the line.
for step in range(20001):
sess.run(train)
#if step % 20 == 0:
#print(step, sess.run(W), sess.run(b),sess.run(loss))

print(step, sess.run(W1), sess.run(W2), sess.run(b),sess.run(loss))
# Learns best fit is W: [0.1], b: [0.3]


## 2.2 矩阵相乘

import tensorflow as tf
import numpy as np

#when put here the "cpu" is same as "gpu" , because it has been deploied on gpu or cpu
#select the fastest device automatically
#matrix1 = np.random.rand(20000,1500).astype(np.float32)
#matrix2 = np.random.rand(1500,20000).astype(np.float32)
#product = tf.matmul(matrix1, matrix2)

with tf.Session() as sess3:
with tf.device("/gpu:0"):#gpu 11.6s and cpu 20.2s
matrix1 = np.random.rand(20000,1500).astype(np.float32)
matrix2 = np.random.rand(1500,20000).astype(np.float32)
product = tf.matmul(matrix1, matrix2)
result = sess3.run(product)

## 2.3 构建session的另一种方式

import tensorflow as tf
import numpy as np

#deploy a session
sess = tf.InteractiveSession()

#design the grape
matrix1 = np.random.rand(2000,1500).astype(np.float32)
matrix2 = np.random.rand(1500,2000).astype(np.float32)
product = tf.matmul(matrix1, matrix2)

#run the operation
print product.eval()

sess.close()

## 2.4一个计数器--说明构建阶段和运行阶段

TF把很多操作都规定成内部的函数，先显式地规定网络，然后才是运行

import tensorflow as tf

#design the graph
state = tf.Variable(0, name="counter")

one = tf.constant(1)
update = tf.assign(state, new_value)

#initialization
init_op = tf.initialize_all_variables()

#run
with tf.Session() as sess:
sess.run(init_op)
print sess.run(state)

for _ in range(3):
sess.run(update)
print sess.run(state)

## 2.5获取数据fetch（）

import tensorflow as tf

input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)

mul = tf.mul(input1, intermed)

with tf.Session() as sess:
result = sess.run([mul, intermed])
print result
result = sess.run([intermed])
print result

## 2.6填充数据feed（）

import tensorflow as tf
import numpy as np

input1 = tf.placeholder(tf.float32,shape=(5, 5))
input2 = tf.placeholder(tf.float32,shape=(5, 5))
output = tf.matmul(input1, input2)#matmul is different mul

with tf.Session() as sess:
rand_array = np.ones([5, 5])
print sess.run([output], feed_dict={input1: rand_array,input2: rand_array})