# Tensorflow 基础框架
# 处理结构
计算图纸
Tensorflow 首先要定义神经网络的结构,然后再把数据放入结构当中去运算和 training.
因为 TensorFlow 是采用数据流图(data flow graphs)来计算,所以首先我们得创建一个数据流流图,然后再将我们的数据(数据以张量 (tensor) 的形式存在)放在数据流图中计算。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor). 训练模型时 tensor 会不断的从数据流图中的一个节点 flow 到另一节点,这就是 TensorFlow 名字的由来.
# 例子 1
tensorflow version 1 代码如下
| import tensorflow as tf | |
| import numpy as np | |
| # create data | |
| x_data = np.random.rand(100).astype(np.float32) | |
| y_data = x_data*0.1 + 0.3 | |
| #搭建模型 | |
| Weights = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) | |
| biases = tf.Variable(tf.zeros([1])) | |
| y = Weights*x_data + biases | |
| #计算误差 | |
| loss = tf.reduce_mean(tf.square(y-y_data)) | |
| #传播误差 | |
| #反向传递误差的工作就教给 optimizer 了,我们使用的误差传递方法是梯度下降法: Gradient Descent 让后我们使用 optimizer 来进行参数的更新. | |
| optimizer = tf.train.GradientDescentOptimizer(0.5) | |
| train = optimizer.minimize(loss) | |
| #训练 | |
| #到目前为止,我们只是建立了神经网络的结构,还没有使用这个结构。在使用这个结构之前,我们必须先初始化所有之前定义的 Variable, 所以这一步是很重要的! | |
| # init = tf.initialize_all_variables () # tf 马上就要废弃这种写法 | |
| init = tf.global_variables_initializer() # 替换成这样就好 | |
| #接着,我们再创建会话 Session. 我们用 Session 来执行 init 初始化步骤。并且,用 Session 来 run 每一次 training 的数据。逐步提升神经网络的预测准确性. | |
| sess = tf.Session() | |
| sess.run(init) # Very important | |
| for step in range(201): | |
| sess.run(train) | |
| if step % 20 == 0: | |
| print(step, sess.run(Weights), sess.run(biases)) | 
tensorflow version 2 代码如下
| import tensorflow as tf | |
| import numpy as np | |
| #creat data | |
| x_data = np.random.rand(100).astype(np.float32) | |
| y_data = x_data*01.+0.3 | |
| ### creat tensorflow structure start ### | |
| Weights = tf.Variable(tf.random.uniform((1,),-1.0,1.0)) | |
| biases = tf.Variable(tf.zeros([1])) | |
| y = Weights*x_data+biases | |
| loss= lambda: tf.keras.losses.MSE(y_data,Weights * x_data +biases) | |
| optimizer = tf.keras.optimizers.SGD(learning_rate=0.5) | |
| ### creat tensorflow structure end ### | |
| for step in range(201): | |
| optimizer.minimize(loss, var_list=[Weights, biases]) | |
| if step %20==0: | |
|         #print(step,sess.run(Weights),sess.run(biases)) | |
| print("{} step, weights = {}, biases = {}".format(step, Weights.read_value(), biases.read_value())) # read_value 函数可用 numpy 替换 | 
# Session 会话控制
这一次我们会讲到 Tensorflow 中的 Session , Session 是 Tensorflow 为了控制,和输出文件的执行的语句。运行 session.run() 可以获得你要得知的运算结果,或者是你所要运算的部分.
首先,我们这次需要加载 Tensorflow ,然后建立两个 matrix , 输出两个 matrix 矩阵相乘的结果。
| import tensorflow as tf | |
| # create two matrixes | |
| matrix1 = tf.constant([[3,3]]) | |
| matrix2 = tf.constant([[2], | |
| [2]]) | |
| product = tf.matmul(matrix1,matrix2) | 
因为 product 不是直接计算的步骤,所以我们会要使用 Session 来激活 product 并得到计算结果。有两种形式使用会话控制 Session 。
| # method 1 | |
| sess = tf.Session() | |
| result = sess.run(product) | |
| print(result) | |
| sess.close() | |
| # [[12]] | |
| # method 2 | |
| with tf.Session() as sess: | |
| result2 = sess.run(product) | |
| print(result2) | |
| # [[12]] | 
tensorflow version 2 已经不需要用 session 控制了
| import tensorflow as tf | |
| matrix1=tf.constant([[3,3]]) | |
| matrix2=tf.constant([[2],[2]]) | |
| product=tf.matmul(matrix1,matrix2) | |
| tf.print(product) | 
# Variable 变量
在 Tensorflow 中,定义了某字符串是变量,它才是变量,这一点是与 Python 所不同的。
定义语法: state = tf.Variable()
| import tensorflow as tf | |
| state = tf.Variable(0, name='counter') | |
| # 定义常量 one | |
| one = tf.constant(1) | |
| # 定义加法步骤 (注:此步并没有直接计算) | |
| new_value = tf.add(state, one) | |
| # 将 State 更新成 new_value | |
| update = tf.assign(state, new_value) | 
如果你在 Tensorflow 中设定了变量,那么初始化变量是最重要的!!所以定义了变量以后,一定要定义 init = tf.initialize_all_variables() .
到这里变量还是没有被激活,需要再在 sess 里, sess.run(init) , 激活 init 这一步.
| # 如果定义 Variable, 就一定要 initialize | |
| init = tf.global_variables_initializer() # 替换成这样就好 | |
| # 使用 Session | |
| with tf.Session() as sess: | |
| sess.run(init) | |
| for _ in range(3): | |
| sess.run(update) | |
| print(sess.run(state)) | 
注意:直接 print(state) 不起作用!!
一定要把 sess 的指针指向 state 再进行 print 才能得到想要的结果!
附上 v2 代码
| import tensorflow as tf | |
| state=tf.Variable(0,name='counter') | |
| one=tf.constant(1) | |
| new_value=tf.add(state,one) | |
| for _ in range(3): | |
| 	#The variable value can be changed using one of the assign methods. | |
| state.assign_add(new_value) | |
| tf.print(state,new_value) | 
# Placeholder 传入值
placeholder 是 Tensorflow 中的占位符,暂时储存变量.
Tensorflow 如果想要从外部传入 data, 那就需要用到 tf.placeholder() , 然后以这种形式传输数据 sess.run(***, feed_dict={input: **}) .
示例:
| import tensorflow as tf | |
| #在 Tensorflow 中需要定义 placeholder 的 type ,一般为 float32 形式 | |
| input1 = tf.placeholder(tf.float32) | |
| input2 = tf.placeholder(tf.float32) | |
| # mul = multiply 是将 input1 和 input2 做乘法运算,并输出为 output  | |
| ouput = tf.multiply(input1, input2) | 
接下来,传值的工作交给了 sess.run() , 需要传入的值放在了 feed_dict={} 并一一对应每一个 input . placeholder 与 feed_dict={} 是绑定在一起出现的。
| with tf.Session() as sess: | |
| print(sess.run(ouput, feed_dict={input1: [7.], input2: [2.]})) | |
| # [ 14.] | 
v2 貌似已经换掉了 placeholder ,看到我再添加。
# Activation Function 激励函数
这里的 AF 就是指的激励函数。激励函数拿出自己最擅长的” 掰弯利器”, 套在了原函数上 用力一扭,原来的 Wx 结果就被扭弯了.
其实这个 AF, 掰弯利器,也不是什么触不可及的东西。它其实就是另外一个非线性函数。比如说 relu, sigmoid, tanh. 将这些掰弯利器嵌套在原有的结果之上,强行把原有的线性结果给扭曲了。使得输出结果 y 也有了非线性的特征。举个例子,比如我使用了 relu 这个掰弯利器,如果此时 Wx 的结果是 1, y 还将是 1, 不过 Wx 为 - 1 的时候,y 不再是 - 1, 而会是 0.
你甚至可以创造自己的激励函数来处理自己的问题,不过要确保的是这些激励函数必须是可以微分的,因为在 backpropagation 误差反向传递的时候,只有这些可微分的激励函数才能把误差传递回去.
想要恰当使用这些激励函数,还是有窍门的。比如当你的神经网络层只有两三层,不是很多的时候,对于隐藏层,使用任意的激励函数,随便掰弯是可以的,不会有特别大的影响。不过,当你使用特别多层的神经网络,在掰弯的时候,玩玩不得随意选择利器。因为这会涉及到梯度爆炸,梯度消失的问题。因为时间的关系,我们可能会在以后来具体谈谈这个问题.
最后我们说说,在具体的例子中,我们默认首选的激励函数是哪些。在少量层结构中,我们可以尝试很多种不同的激励函数。在卷积神经网络 Convolutional neural networks 的卷积层中,推荐的激励函数是 relu. 在循环神经网络中 recurrent neural networks, 推荐的是 tanh 或者是 relu (这个具体怎么选,我会在以后 循环神经网络的介绍中在详细讲解).
# 创建第一个神经网络
# 例子 3 添加层 def add_layer ()
# 计算机视觉介绍
# Anaconda 使用
| %config IPCompleter.greedy=True #按 tag 可以自动补全代码 | 
# 加载 Fashion MNIST 数据集
70000 张图片
10 个类别
28*28 像素
训练神经元网络
| import tensorflow as tf | |
| from tensorflow import keras | |
| import matplotlib.pyplot as plt | |
| #导入数据集 | |
| fasion_mnist = keras.datasets.fashion_mnist | |
| #划分数据集 | |
| (train_images,train_labels),(test_images,test_labels) = fasion_mnist.load_data() | |
| #看数据集大小 | |
| print(train_images.shape) | |
| #展示图片 | |
| plt.imshow(train_images[1]) | 

# 构建神经元网络模型


全连接的网络结构
| model = keras.Sequential() | |
| model.add(keras.layers.Flatten(input_shape=(28,28))) | |
| model.add(keras.layers.Dense(128,activation=tf.nn.relu)) | |
| model.add(keras.layers.Dense(10,activation=tf.nn.softmax)) | |
| model.summary() | |
| #以下为 console | |
| Model: "sequential_1" | |
| _________________________________________________________________ | |
| Layer (type) Output Shape Param # | |
| ================================================================= | |
| flatten_1 (Flatten) (None, 784) 个像素 0 | |
| _________________________________________________________________ | |
| dense (Dense) (None, 128) 100480 (784个像素+1权重)*128个神经元 | |
| _________________________________________________________________ | |
| dense_1 (Dense) (None, 10) 1290 (128个神经元+1权重)*10个类别 | |
| ================================================================= | |
| Total params: 101,770 | |
| Trainable params: 101,770 | |
| Non-trainable params: 0 | |
| _________________________________________________________________ | 
# 训练和评估模型
| #scaling or normalization 把灰度变成只有 1 和 0 | |
| train_imges_scaled=train_images/255 | |
| #metrics=['accuracy'] 是为了看到指标 accuracy 的变化, | |
| model.compile(optimizer=tf.optimizers.Adam(),loss=tf.losses.sparse_categorical_crossentropy,metrics=['accuracy']) | |
| #训练,epochs 重复次数 5 次 | |
| model.fit(train_imges_scaled,train_labels,epochs=5) | |
| #模型评估 | |
| test_images_scaled = test_images/255 | |
| model.evaluate(test_images_scaled,test_labels) | |
| import numpy as np | |
| print(np.argmax( model.predict([[test_images[0]/255]]))) | |
| print(test_labels[0]) | |
| plt.imshow(test_images[0]) | 
# 自动终止训练

| #重载一个 callback 方法 | |
| class myCallback(tf.keras.callbacks.Callback): | |
| def on_epoch_end(self,epoch,logs={}): | |
| if(logs.get('loss')<0.4): | |
| print("\n Loss is low so cancelling training!") | |
| self.model.stop_training = True | |
| callbacks= myCallback() | |
| mnist =tf.keras.datasets.fashion_mnist | |
| (training_images,training_labels),(test_images,test_labels) = mnist.load_data() | |
| training_images_scaled = training_images/255 | |
| test_images_scaled = test_images/255 | |
| model =tf.keras.models.Sequential([ | |
| tf.keras.layers.Flatten(), | |
| tf.keras.layers.Dense(512,activation = tf.nn.relu), | |
| tf.keras.layers.Dense(10,activation = tf.nn.softmax) | |
| ]) | |
| model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy']) | |
| model.fit(training_images_scaled,training_labels,epochs=5,callbacks=[callbacks]) | |
| ---console:--- | |
| Epoch 1/5 | |
| 1875/1875 [==============================] - 5s 3ms/step - loss: 0.4734 - accuracy: 0.8292 | |
| Epoch 2/5 | |
| 1867/1875 [============================>.] - ETA: 0s - loss: 0.3585 - accuracy: 0.8697 | |
|  Loss is low so cancelling training! | |
| 1875/1875 [==============================] - 5s 3ms/step - loss: 0.3583 - accuracy: 0.8697 | 

