mkdir mooc # 新建一個mooc文件夾 cd mooc mkdir 1.helloworld # 新建一個helloworld文件夾 cd 1.helloworld touch helloworld.py
# -*- coding: UTF-8 -*- # 引入 TensorFlow 庫 import tensorflow as tf # 建立一個 Constant(常量)Operation(操做) hw = tf.constant("Hello World! I love TensorFlow!") # 我愛 TensorFlow # 啓動一個 TensorFlow 的 Session(會話) sess = tf.Session() # 運行 Graph(計算圖) print(sess.run(hw)) # 關閉 Session(會話) sess.close()
TensorFlow的編程模式java
命令式編程:python
容易理解,命令語句基本沒優化: C,java, C++, Pythonc++
符號式編程:git
涉及較多的嵌入和優化,運行速度有同比提高github
計算流圖。c和d是能夠共用內存的。有必定優化。算法
TensorFlow的計算流圖,符號式編程的範式。有節點有邊,邊是計算結果在節點中流動。數據庫
Tensor 在 計算流圖中流動(flow)編程
這張圖簡化一下,取其中一部分。api
邊就是Tensor(張量)在流動數組
節點就是一個operation操做,數學計算或後面的激勵函數等的操做。
節點的輸入與輸出都是Tensor張量。
邊和節點共同構成了Graph 也就是數據流圖。
數據流圖會被放進session會話中進行運行。會話能夠在不一樣的設備上去運行,好比cpu和GPU。
數據流圖:
Tensor (張量) 邊裏流動的數據
Operation(操做)
Tensor 會做爲operation的輸入,operation輸出的依然是Tensor
數據模型 - Tensor(張量)
張量是TensorFlow中最重要的結構。
計算模型 - Graph(圖)
運行模型 - Session(會話)
計算流圖,也是TensorFlow的基本架構,代表了圖正在運行的狀態。
黑色的線不斷流動, 其中流動的就是Tensor,一個一個的節點就是它的操做
燒杯中進行的化學反應就是操做,其中流動的就是張量。
火狐打開一個瀏覽器就是打開了一個會話。
使用x,y,z三行構建了一個圖,構建了一個實驗儀器。
TensorFlow使用了客戶端和服務端的經典架構。
客戶端是咱們編寫的程序,程序請求服務端(C++)的運行時。
建立一個會話,使用會話中的run方法。
靜態的圖。數據流圖
如何讓某一部分動起來?
須要點燃酒精燈。
要讓這一部分運行起來。就得run
定義算法的計算圖(Graph)的結構 靜態
使用會話(Session) 執行計算
TensorFlow和numpy有必定聯繫
有不少相似的概念和api
介紹Tensor時,有不少api名稱很類似
numpy官網,科學計算。n階數組對象。
numpy速度是很是快的,比原生快不少。
由於numpy的許多函數是用c語言來實現的。還使用了一些優化,甚至比你本身用c實現快不少。
scipy 是一個開源軟件。Matplotlib。pandas。jupyter notebook
numpy的操做對象是一個多維的數組。相似Tensor
ndarray ndim shape size dtype(同一類型元素)
import numpy as np vector = np.array([1,2,3]) vector.shape vector.size vector.ndim type(vector)# 建立二維數組(矩陣)matrix = np.array([[1, 2],[3, 4]]) matrix.shape matrix.size matrix.ndim type(matrix)
對於矩陣進行轉置
one = np.arange(12)# 0 - 11one.reshape((3,4)) two = one.reshape((3,4)) two.shape two.size two.ndim
不斷流動的東西就是張量。節點就是operation計算
TensorFlow裏的數據都是Tensor,因此它能夠說是一個張量的流圖
維度是0的話,是一個標量(Scalar)
vector & Matrix
numpy中的基礎要素就是array,和Tensor 差很少的一種表述。
import numpy as np zeros = np.zeros((3,4)) zeros ones = np.ones((5,6)) ones# 對角矩陣: 必須是一個方陣.對角線是1,其餘都是0的方陣ident = np.eye(4)
一個張量裏面的元素類型都是同樣的。
由於一個tensor 只能包含一種數據類型。dtype
TensorFlow.datatype list
https://www.tensorflow.org/api_docs/python/tf/DType
TensorFlow數據類型有不少。
其餘屬性:
https://www.tensorflow.org/api_docs/python/tf/Tensor
能夠經過搜索Tensor 查看到它的其餘屬性。
A Tensor是一個輸出的符號句柄 Operation。它不包含該操做輸出的值,而是提供了在TensorFlow中計算這些值的方法tf.Session。
device,在哪一個設備上被計算出來的。
Graph 這個Tensor 所屬的一個圖
name 是咱們能夠給張量起的名字
op 是產生這個Tensor 的一個操做
Constant
Variable
Placeholder
SparseTensor
值不能改變的一種Tensor
但取這個Tensor值有可能仍是會變
定義在tf.constant類
tf.constant( value, dtype=None, shape=None, name='Const', verify_shape=False)
數值:標量,向量,矩陣
verify_shape 驗證形狀
官網例子:
# Constant 1-D Tensor populated with value list.tensor = tf.constant([1, 2, 3, 4, 5, 6, 7]) => [1 2 3 4 5 6 7]
# Constant 2-D tensor populated with scalar value -1.tensor = tf.constant(-1.0, shape=[2, 3]) => [[-1. -1. -1.]
咱們的代碼
const = tf.constant(3) const # 輸出const:0 shape=() dtype=int32
run以後才能獲得具體的數。與普通的變量常量是不同的。
值能夠改變的一種tensor
定義在tf.Variable. 注意這個v是大寫的,和constant是不同的。
屬性: initial_value
__init__( initial_value=None, trainable=True, collections=None, validate_shape=True, caching_device=None, name=None, variable_def=None, dtype=None, expected_shape=None, import_scope=None, constraint=None)
定義一個變量的張量。
var = tf.Variable(3)var# 不會輸出真實值,只會輸出數據類型等特徵量
咱們能夠在建立變量的時候指定好它的數據類型
var1 = tf.Variable(4, dtype=tf.int64) var1# 默認系統給的變量名會自動遞增
先佔住一個固定的位置,等着你以後往裏面添加值的一種Tensor
例子: 圖書館佔座
tf.placeholder
https://www.tensorflow.org/api_docs/python/tf/placeholder
tf.placeholder( dtype, shape=None, name=None)
屬性少。沒有值。形狀。賦值的機制用到了python中字典的機制
x = tf.placeholder(tf.float32, shape=(1024, 1024)) y = tf.matmul(x, x)with tf.Session() as sess: print(sess.run(y)) # ERROR: will fail because x was not fed. rand_array = np.random.rand(1024, 1024) print(sess.run(y, feed_dict={x: rand_array})) # Will succeed.
feed_dict 真正運行時才經過feed_dict關鍵字以字典形式向裏面傳值。
一種"稀疏"的Tensor,相似線性代數裏面的稀疏矩陣的概念
tf.SparseTensor
在矩陣中,若數值爲0的元素數目遠遠多於非0元素的數目,而且非0元素分佈沒有規律時,則稱該矩陣爲稀疏矩陣;與之相反,若非0元素數目佔大多數時,則稱該矩陣爲稠密矩陣。 定義非零元素的總數比上矩陣全部元素的總數爲矩陣的稠密度。
定義稀疏矩陣,只須要定義非0的數,其餘爲0的數會自動的填充。
SparseTensor(indices=[[0, 0], [1, 2]], values=[1, 2], dense_shape=[3, 4])
指定座標,對應座標的值,以及它的形狀。
[[1, 0, 0, 0] [0, 0, 2, 0] [0, 0, 0, 0]]
Tensor("MUL:0", shape=(),dtype=float32)
類型 : tf.Variable
名字: MUL
0表示索引
你是operation產生的第幾個張量
shape 就是形狀 dtype 數據類型
定義一個有名字的Variable
named_var = tf.Variable([5,6], name="named_var") named_var
自動生成的會以數據類型爲名字。
Graph(圖)的形象比喻
每一個節點能夠想象成一個儀器,在對咱們的實驗品進行操做。
儀器中被操做,以及在各個儀器中流動的是tensor
定義算法的計算圖(Graph)結構
把實驗的器材等組裝好
使用會話(Session)執行圖的一部分(計算)
開始點燃酒精燈等操做
Graph tf.Graph
https://www.tensorflow.org/api_docs/python/tf/Graph
若是你沒有顯式的去建立圖,它其實已經幫你註冊了一個默認的圖。
默認Graph老是已註冊,並可經過調用訪問 tf.get_default_graph。
沒有輸出值是由於咱們尚未用會話運行這一部分。
建立sess對象
咱們能夠看一下Session這個類
https://www.tensorflow.org/api_docs/python/tf/Session
一個Session對象封裝了Operation 執行對象的環境,並對Tensor對象進行評估。例如:
OPeration是圖上的節點,輸入張量,產生張量。
run( fetches, feed_dict=None, options=None, run_metadata=None)
run返回的結果就是一個張量。
>>> tf.get_default_graph() <tensorflow.python.framework.ops.Graph object at 0x000001EC0C5EE160>
>>> if c.graph is tf.get_default_graph():... print("The Graph of c is the default graph") ... The Graph of c is the default graph
能夠看到c所屬的圖確實是默認圖。
# -*- coding: UTF-8 -*- # 引入 TensorFlow import tensorflow as tf # 建立兩個常量 Tensor const1 = tf.constant([[2, 2]]) const2 = tf.constant([[4], [4]]) # 張量相乘(multiply 是 相乘 的意思) multiply = tf.matmul(const1, const2) # 嘗試用 print 輸出 multiply 的值 print("sess.run() 以前,嘗試輸出 multiply 的值: {}".format(multiply)) # 建立了 Session(會話)對象 sess = tf.Session() # 用 Session 的 run 方法來實際運行 multiply 這個 # 矩陣乘法操做,並把操做執行的結果賦值給 result result = sess.run(multiply) # 用 print 打印矩陣乘法的結果 print("sess.run() 以後,輸出 multiply 的值: {}".format(result)) if const1.graph is tf.get_default_graph(): print("const1 所在的圖(Graph)是當前上下文默認的圖") # 關閉已用完的 Session(會話) sess.close() # 第二種方法來建立和關閉 Session # 用了 Python 的上下文管理器(with ... as ... :) with tf.Session() as sess: result2 = sess.run(multiply) print("multiply 的結果是 {} ".format(result2))
用顯示的close和with上下文管理器兩種方式實現
展現構建的計算圖和節點等信息在瀏覽器裏。
輸入手寫4等相關4的圖片。輸出這是4
輸入狗狗圖片,輸出多是狗狗
輸入歷史的股票曲線,預測出將來這一年的市值
打開黑盒,照亮。方便調參等操做。
節點和操做。
上層節點能夠打開,看到下層節點。
以後可能會加入debug功能,目前還只是一種展現。
# 第一個參數爲指定的保存路徑,第二個參數爲要保存的圖tf.summary.FileWriter("日誌保存路徑", sess.graph)
https://www.tensorflow.org/api_docs/python/tf/summary?hl=zh-cn
注意咱們這裏的summary是小寫的summary。
張量摘要用於導出關於模型的信息。
官網的develop 中的get Started 裏面有關於TensorBoard的信息。
開源的github源代碼。
tensorboard --logdir=日誌所在路徑
Tensorflow安裝以後,會默認安裝有TensorBoard
上一節的代碼中自行添加一行
# 第一個參數爲指定的保存路徑,第二個參數爲要保存的圖 tf.summary.FileWriter("./", sess.graph)
用於導出關於模型的精簡信息的方法
可使用TensorBoard等工具訪問這些信息
打開瀏覽器會有一系列菜單。
6006端口打開。
菜單分別是標量,圖片,音頻,圖。
能夠點擊節點,若是有加號打開節點裏面內容。節點含義會列在右邊。
distributions 訓練的一些分佈。histograms 直方圖。
對於數字進行分類。
能夠分類進行顏色加顏色。
咱們剛纔點擊過的雙擊圖形,節點裏面又有子節點。
很像一些編程語言(如 c++) 的namespace, 包含嵌套的關係
卷積神經網絡下的誤差,adam方法(一種優化方法)
通常的操做不會改變輸入的Tensor,若是是一條黃線,表示操做節點能夠改變輸入的Tensor
# -*- coding: UTF-8 -*- # 引入tensorflow import tensorflow as tf # 構造圖(Graph)的結構 # 用一個線性方程的例子 y = W * x + b W = tf.Variable(2.0, dtype=tf.float32, name="Weight") # 權重 b = tf.Variable(1.0, dtype=tf.float32, name="Bias") # 誤差 x = tf.placeholder(dtype=tf.float32, name="Input") # 輸入 with tf.name_scope("Output"): # 輸出的命名空間 y = W * x + b # 輸出 # const = tf.constant(2.0) # 不須要初始化 # 定義保存日誌的路徑 path = "./log" # 建立用於初始化全部變量(Variable)的操做 # 若是定義了變量,但沒有初始化的操做,會報錯 init = tf.global_variables_initializer() # 建立 Session(會話) with tf.Session() as sess: sess.run(init) # 初始化變量 writer = tf.summary.FileWriter(path, sess.graph) result = sess.run(y, {x: 3.0}) # 爲 x 賦值 3 print("y = W * x + b,值爲 {}".format(result)) # 打印 y = W * x + b 的值,就是 7
使用tensorBoard
tensorboard --logdir=./log
6006相似於GOOGle的goog
不像以前的例子有不少菜單,只打開了一個graph菜單。
以後的圖有可能很複雜,查看損失函數,優化計算流圖。
生活中所見的遊樂園。
展現了基本的神經網絡結構
JavaScript編寫的網頁應用
經過瀏覽器就能夠訓練簡單的神經網絡
訓練過程可視化,高度定製化
https://playground.tensorflow.org/
不用擔憂運行復雜的神經網絡而搞垮。
數據集 - 特徵 - 隱藏層(深度: 不少層) - 輸出
測試的損失。訓練的損失。越接近0越好。
epoch是完整的運行過程。
黃色越黃越接近-1
點亮輸入。選擇激勵函數。問題類型分類仍是迴歸。
遊樂場對神經網絡有更形象的認識。
一個極其強大的python繪圖庫:
官網有不少例子。
scipy下的一個組件。
不多的代碼便可繪製2d 3d 靜態動態等各類圖形
通常經常使用的是它的子包: pyplot 提供相似matlab的繪圖框架
sudo pip install matplotlib
代碼:
# -*- coding: UTF-8 -*-# 引入 Matplotlib 的分模塊 pyplotimport matplotlib.pyplot as plt# 引入 numpyimport numpy as np# 建立數據# Linespace建立必定範圍內的圖線。-2到2之間等分100個點x = np.linspace(-2, 2, 100)#y = 3 * x + 4y1 = 3 * x + 4y2 = x ** 3# 建立圖像#plt.plot(x, y)plt.plot(x, y1) plt.plot(x, y2)# 顯示圖像plt.show()
藍色的爲y1.從-2到2的一條直線。
代碼示例2:
# -*- coding: UTF-8 -*-import matplotlib.pyplot as pltimport numpy as np# 建立數據x = np.linspace(-4, 4, 50) y1 = 3 * x + 2y2 = x ** 2# 第一張圖# 指定圖的大小plt.figure(num=1, figsize=(7, 6))# 第一張圖兩個線plt.plot(x, y1) plt.plot(x, y2, color="red", linewidth=3.0, linestyle="--")# 第二張圖plt.figure(num=2) plt.plot(x, y2, color="green")# 顯示全部圖像plt.show()
代碼示例3:
子圖的繪製
import numpy as npimport matplotlib.pyplot as pltfrom matplotlib.ticker import NullFormatter # useful for `logit` scale# Fixing random state for reproducibility# 爲了重現結果,設置隨機種子np.random.seed(19680801)# make up some data in the interval ]0, 1[y = np.random.normal(loc=0.5, scale=0.4, size=1000) y = y[(y > 0) & (y < 1)] y.sort() x = np.arange(len(y))# plot with various axes scalesplt.figure(1)# linear# 兩行兩列子圖中第一個plt.subplot(221) plt.plot(x, y) plt.yscale('linear') plt.title('linear') plt.grid(True)# logplt.subplot(222) plt.plot(x, y) plt.yscale('log') plt.title('log') plt.grid(True)# symmetric logplt.subplot(223) plt.plot(x, y - y.mean()) plt.yscale('symlog', linthreshy=0.01) plt.title('symlog') plt.grid(True)# logitplt.subplot(224) plt.plot(x, y) plt.yscale('logit') plt.title('logit') plt.grid(True)# Format the minor tick labels of the y-axis into empty strings with# `NullFormatter`, to avoid cumbering the axis with too many labels.plt.gca().yaxis.set_minor_formatter(NullFormatter())# Adjust the subplot layout, because the logit one may take more space# than usual, due to y-tick labels like "1 - 10^{-3}"plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25, wspace=0.35) plt.show()
繪製一個像碗同樣的圖像。
from mpl_toolkits.mplot3d.axes3d import Axes3Dimport matplotlib.pyplot as pltimport numpy as np fig, ax1 = plt.subplots(figsize=(8, 5), subplot_kw={'projection': '3d'}) alpha = 0.8r = np.linspace(-alpha,alpha,100) X,Y= np.meshgrid(r,r) l = 1./(1+np.exp(-(X**2+Y**2))) ax1.plot_wireframe(X,Y,l) ax1.plot_surface(X,Y,l, cmap=plt.get_cmap("rainbow")) ax1.set_title("Bowl shape") plt.show()
製做靜態圖像,製做動態圖像。
示例5:
import numpy as npfrom matplotlib import cmimport matplotlib.pyplot as pltimport mpl_toolkits.mplot3d.axes3d as p3import matplotlib.animation as animationdef cost_function(x): return x[0]**2 + x[1]**2def gradient_cost_function(x): return np.array([2*x[0], 2*x[1]]) nb_steps = 20x0 = np.array([0.8, 0.8]) learning_rate = 0.1def gen_line(): x = x0.copy() data = np.empty((3, nb_steps+1)) data[:, 0] = np.concatenate((x, [cost_function(x)])) for t in range(1, nb_steps+1): grad = gradient_cost_function(x) x -= learning_rate * grad data[:, t] = np.concatenate((x, [cost_function(x)])) return datadef update_line(num, data, line): # NOTE: there is no .set_data() for 3 dim data... line.set_data(data[:2, :num]) line.set_3d_properties(data[2, :num]) return line# Attaching 3D axis to the figurefig = plt.figure() ax = p3.Axes3D(fig)# Plot cost surfaceX = np.arange(-0.5, 1, 0.1) Y = np.arange(-1, 1, 0.1) X, Y = np.meshgrid(X, Y) Z = cost_function((X, Y)) surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)# Optimizedata = gen_line()# Creating line objects# NOTE: Can't pass empty arrays into 3d version of plot()line = ax.plot(data[0, 0:1], data[0, 0:1], data[0, 0:1], 'rx-', linewidth=2)[0]# Setting the axes propertiesax.view_init(30, -160) ax.set_xlim3d([-1.0, 1.0]) ax.set_xlabel('X') ax.set_ylim3d([-1.0, 1.0]) ax.set_ylabel('Y') ax.set_zlim3d([0.0, 2.0]) ax.set_zlabel('Z')# Creating the Animation objectline_ani = animation.FuncAnimation(fig, update_line, nb_steps+1, fargs=(data, line), \ interval=200, blit=False)# line_ani.save('gradient_descent.gif', dpi=80, writer='imagemagick')plt.show()
演示了梯度降低的示例
代碼下載地址:
https://github.com/martin-gorner/tensorflow-mnist-tutorial
注意錯誤:
ImportError: No module named 'tensorflowvisu'
是由於這個tensorflowvisu.py的文件得位於同一級目錄。
能夠看到精度在不斷上升。損失在不斷下降。能夠看到他訓練了哪些數字。
weights,權重。Biases,誤差。 測試的手寫數字
這個例子是用TensorFlow結合Matplotlib來繪製一個實時的動圖。
線性迴歸通常用於預測,好比: 股票漲跌
梯度降低是機器學習中最核心的優化算法
複習一下Operation(操做)
基本的操做:
逐元素的數學操做
矩陣操做
狀態型操做
神經網絡操做
保存,還原操做
模型訓練操做
tf.nn.relutf.add
這些均可以在官網直接搜索查看到。
查看在線文檔,搜索,或目錄查看。
help(要查看的對象)
梯度降低優化器
構建一個基於梯度降低的優化器。
# -*- coding: UTF-8 -*-''' 用梯度降低的優化方法來快速解決線性迴歸問題 '''import numpy as npimport matplotlib.pyplot as pltimport tensorflow as tf# 構建數據:100個隨機點points_num = 100# 以後要往vectors中填充100個點的值vectors = []# 用 Numpy 的正態隨機分佈函數生成 100 個點# 這些點的(x, y)座標值: 對應線性方程 y = 0.1 * x + 0.2# 權重 (Weight) 爲 0.1,誤差 (Bias)爲 0.2try: # 運行100次 for i in xrange(points_num): # 橫座標值,隨機正態分佈函數。區間0-0.66 x1 = np.random.normal(0.0, 0.66) # 在真實值上加一些誤差 y1 = 0.1 * x1 + 0.2 + np.random.normal(0.0, 0.04) # 將點list加入vectors列表中 vectors.append([x1, y1])except: for i in range(points_num): x1 = np.random.normal(0.0, 0.66) y1 = 0.1 * x1 + 0.2 + np.random.normal(0.0, 0.04) vectors.append([x1, y1]) x_data = [v[0] for v in vectors] # 列表生成式取出真實的點的 x 座標y_data = [v[1] for v in vectors] # 真實的點的 y 座標# 圖像 1 :展現 100 個隨機數據點plt.plot(x_data, y_data, 'ro', label="Original data") # 紅色圓圈圈型的點plt.title("Linear Regression using Gradient Descent")# 展現labelplt.legend() plt.show()
咱們要找到一條線性迴歸的直線,以後給它x值就能夠預測y值。也就是尋找一條直線它的w最接近0.1,b最接近於0.2最好。
# 構建線性迴歸模型# 初始化參數,傳入shape,最小值,最大值W = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) # 初始化 Weight# 誤差。初始化爲0b = tf.Variable(tf.zeros([1])) # 初始化 Bias# 這裏的y是y帽子,也就是模型預測出來的值y = W * x_data + b # 模型計算出來的 y# 定義 loss function (損失函數) 或 cost function (代價函數)# 計算殘差平方和。用(y帽子-真實的y)的平方累加的和。N就是總的點數,100.# 對 Tensor 的全部維度計算 ((y - y_data) ^ 2) 之和 / N# reduce_mean就是最後面的/N操做。square平方: y - y_dataloss = tf.reduce_mean(tf.square(y - y_data))# 用梯度降低的優化器來優化咱們的 loss functioin# 讓它更快的找到最終最擬合的w和b: 梯度降低的優化器。學習率,梯度降低的快慢。optimizer = tf.train.GradientDescentOptimizer(0.5) # 設置學習率爲 0.5(步長),通常都是小於1的數。# 太大的學習率可能錯過局部最小值的那個點。# 讓它(損失函數)儘量的損失最小train = optimizer.minimize(loss)# 建立會話sess = tf.Session()# 初始化數據流圖中的全部變量init = tf.global_variables_initializer() sess.run(init)try: # 訓練 20 步 for step in range(20): # 優化每一步 sess.run(train) # 打印出每一步的損失,權重和誤差.必須run才能獲得實際的值。 print(("Step=%d, Loss=%f, [Weight=%f Bias=%f]") % (step, sess.run(loss), sess.run(W), sess.run(b)))except: # 訓練 20 步 for step in xrange(20): # 優化每一步 sess.run(train) # 打印出每一步的損失,權重和誤差 print("Step=%d, Loss=%f, [Weight=%f Bias=%f]") \ % (step, sess.run(loss), sess.run(W), sess.run(b)) # 圖像 2 :繪製全部的點而且繪製出最佳擬合的直線plt.plot(x_data, y_data, 'bo', label="Original data") # 藍色圓圈的點plt.title("Linear Regression using Gradient Descent")# 橫座標是x_data.縱座標爲此時的wb肯定的yplt.plot(x_data, sess.run(W) * x_data + sess.run(b), label="Fitted line") # 擬合的線plt.legend() plt.xlabel('x') plt.ylabel('y') plt.show()# 關閉會話sess.close()
進階版模仿:
作出擬合過程的動態圖像。
主要做用: 加入非線性
tf.nn 點擊nn
https://www.tensorflow.org/api_guides/python/nn#Activation_Functions
能夠看到供咱們使用的激活函數。
wiki中不一樣激活函數的圖像,變種。
https://en.wikipedia.org/wiki/Activation_function
1 / float(1 + np.exp(-x))
# -*- coding: UTF-8 -*-import numpy as npimport matplotlib.pyplot as pltimport tensorflow as tf# 建立輸入數據x = np.linspace(-7, 7, 180) # (-7, 7) 之間等間隔的 180 個點# 激活函數的原始手工實現def sigmoid(inputs): # y = 1 / (1 + exp(-x)) np.exp至關於e的多少次方 y = [1 / float(1 + np.exp(-x)) for x in inputs] return ydef relu(inputs): # f(x) = max(0,x) x大於0時,函數值y就是x。x<0時函數值y就是0. # x若是大於0,則真值爲1;y=x;而x若不知足>0真值爲0;y=0 y = [x * (x > 0) for x in inputs] return ydef tanh(inputs): # e的x次方-e的負x次方作分母。e的x次方+e的負x次方作分母 y = [(np.exp(x) - np.exp(-x)) / float(np.exp(x) - np.exp(-x)) for x in inputs] return ydef softplus(inputs): # y = log(1+e的x平方) y = [np.log(1 + np.exp(x)) for x in inputs] return y# 通過 TensorFlow 的激活函數處理的各個 Y 值y_sigmoid = tf.nn.sigmoid(x) y_relu = tf.nn.relu(x) y_tanh = tf.nn.tanh(x) y_softplus = tf.nn.softplus(x)# 建立會話sess = tf.Session()# 運行run,獲得四個返回值y_sigmoid, y_relu, y_tanh, y_softplus = sess.run([y_sigmoid, y_relu, y_tanh, y_softplus])# 建立各個激活函數的圖像plt.figure(1, figsize=(8, 6)) plt.subplot(221) plt.plot(x, y_sigmoid, c='red', label='Sigmoid')# y軸取值的區間plt.ylim((-0.2, 1.2))# 顯示label,放在最適合的位置plt.legend(loc='best') plt.subplot(222) plt.plot(x, y_relu, c='red', label='Relu') plt.ylim((-1, 6)) plt.legend(loc='best') plt.subplot(223) plt.plot(x, y_tanh, c='red', label='Tanh') plt.ylim((-1.3, 1.3)) plt.legend(loc='best') plt.subplot(224) plt.plot(x, y_softplus, c='red', label='Softplus') plt.ylim((-1, 6)) plt.legend(loc='best')# 顯示圖像plt.show()# 關閉會話sess.close()
用到的數據集: MNIST(手寫數字的數據庫)
TensorFlow中封裝了這個數據集。
咱們要構建的cnn的結構大體如上圖所示
輸入時
28*28*1
的一張圖片。黑白圖片因此高度爲1,若是是彩色的,高度爲3.紅綠藍。
第一層卷積,有32個過濾器。會變成一個28*28*32
的矩陣
通過池化層的Pool(2*2
)會變成14*14*32
的網絡結構
第二層卷積,有64個過濾器。會變成14*14*64
的結構
在通過一個Pool 亞採樣層,就會變成一個7*7*64
以後再進行扁平的序化。就變成1*1*1024
最後通過一個全鏈接網絡去輸出。輸出1*1*10
下載數據並聲明變量
# -*- coding: UTF-8 -*-import numpy as npimport tensorflow as tf# 下載並載入 MNIST 手寫數字庫(55000 * 28 * 28)55000 張訓練圖像from tensorflow.examples.tutorials.mnist import input_data# 這個名字是自定義的,會保存在當前目錄下。若是已經下載的有了,下次就不會download了。mnist = input_data.read_data_sets('mnist_data', one_hot=True)# one_hot 獨熱碼的編碼 (encoding) 形式# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 的十位數字# 第一位上被激活,惟一的表示這一個數字。# 0 : 1000000000# 1 : 0100000000# 2 : 0010000000# 3 : 0001000000# 4 : 0000100000# 5 : 0000010000# 6 : 0000001000# 7 : 0000000100# 8 : 0000000010# 9 : 0000000001# onehot設置True會表示成onehot的編碼。不然會表示自己。# None 表示張量 (Tensor) 的第一個維度能夠是任何長度 除以255input_x = tf.placeholder(tf.float32, [None, 28 * 28]) / 255. # 輸入output_y = tf.placeholder(tf.int32, [None, 10]) # 輸出:10個數字的標籤input_x_images = tf.reshape(input_x, [-1, 28, 28, 1]) # 改變形狀以後的輸入
咱們想去構建的是一個相似於上圖的結構的卷積神經網絡。
輸入是一張28,28,1的灰度圖,1表示它只有一個顏色。
圖片通過層層的卷積與池化以後會有一個輸出。會變成一個1,1,10的輸出
咱們想要經過圖片數據+標籤 經過cnn 預測出0-9十種結果。
咱們的CNN識別mnist的輸入端是這樣的。
28,28像素的一個圖片。784
而mnist中的圖片張數是55000張圖片。
輸出是如上圖,對應了55000維度,對於每個預測的值它有一個onehot的編碼
只有一位取1,其餘位所有爲0.
表示識別出來的數字分別爲4,9,5,8
padding決定補零模式。same表示輸入與輸出的維數一致。
# 從 Test(測試)數據集裏選取 3000 個手寫數字的圖片和對應標籤test_x = mnist.test.images[:3000] # 圖片test_y = mnist.test.labels[:3000] # 標籤# 構建咱們的卷積神經網絡:# 第 1 層卷積(二維的卷積) tf.nn 和 tf.layers 中的cov2d有類似有不一樣。# 讓圖像通過卷積層,維度變爲28*28*32。用一個5,5的過濾器(採集器)。# 從左上角到右下角一點一點採集。每一個過濾器掃一遍,輸出增長一層。# 掃了32遍,深度就會從1變爲32# 第二個卷積層,掃了64遍,變成了64# tf.layers.conv2d二維的卷積函數(https://www.tensorflow.org/api_docs/python/tf/layers/conv2d?hl=zh-cn)conv1 = tf.layers.conv2d( inputs=input_x_images, # 形狀 [28, 28, 1],這裏仍是一個placeholder,後面會填充值 filters=32, # 32 個過濾器,輸出的深度(depth)是32 kernel_size=[5, 5], # 過濾器(卷積核心)在二維的大小是(5 * 5) strides=1, # 卷積步幅,步長是1 padding='same', # same 表示輸出的大小不變,所以須要在外圍補零 2 圈 activation=tf.nn.relu # 激活函數是 Relu) # 形狀 [28, 28, 32]
池化(亞採樣)
# 第 1 層池化(亞採樣)比原來的那些數據,輸出沒有輸入那麼多、# 只採一部分數據。pool1 = tf.layers.max_pooling2d( inputs=conv1, # 形狀 [28, 28, 32] pool_size=[2, 2], # 過濾器在二維的大小是(2 * 2) strides=2 # 步長是 2) # 通過亞採樣以後,形狀 [14, 14, 32]
pooling有幾種方案。平均,max。平面區域中選最大的值。
輸入必須是一個張量,要有四個維度
https://www.tensorflow.org/api_docs/python/tf/layers/max_pooling2d?hl=zh-cn
步長爲2,隔一步採一個樣。
亞採樣層的過濾器只有一個,因此沒有改變深度。改變了二維大小
通過卷積層,深度會不斷加深。提取到的特徵會不斷增多。
# 第 2 層卷積conv2 = tf.layers.conv2d( inputs=pool1, # 輸入形狀 [14, 14, 32] filters=64, # 64 個過濾器,輸出的深度(depth)是64 kernel_size=[5, 5], # 過濾器在二維的大小是(5 * 5) strides=1, # 步長是1 padding='same', # same 表示輸出的大小不變,所以須要在外圍補零 2 圈 activation=tf.nn.relu # 激活函數是 Relu) # 輸出形狀 [14, 14, 64]
第二層池化的過濾器是綠色方塊。
# 第 2 層池化(亞採樣)pool2 = tf.layers.max_pooling2d( inputs=conv2, # 形狀 [14, 14, 64] pool_size=[2, 2], # 過濾器在二維的大小是(2 * 2) strides=2 # 步長是 2) # 輸出形狀 [7, 7, 64]
知道原理以後,構建神經網絡就跟作三明治漢堡包似的,來層面包來片肉。
將輸出的7,7,64 壓成1,1,1024
# 平坦化(flat)flat = tf.reshape(pool2, [-1, 7 * 7 * 64]) # 形狀 會變成[7 * 7 * 64, ]
輸入時pool2。-1表示: 根據以後肯定的參數推斷-1這個位置的參數大小。
扁平化。將三維形狀,扁平化。
# 1024 個神經元的全鏈接層dense = tf.layers.dense(inputs=flat, units=1024, activation=tf.nn.relu)
有多少個神經元組成的全鏈接層。全鏈接層也有一個激活函數的參數,若是沒有加激活函數,會是一個線性的,加了激活函數會變成一個非線性的。這裏咱們擁有一個有1024神經元的全鏈接層
丟棄50% rate(丟棄的率)是0.5
# Dropout : 丟棄 50%, rate=0.5dropout = tf.layers.dropout(inputs=dense, rate=0.5)
# 10 個神經元的全鏈接層,這裏不用激活函數來作非線性化了logits = tf.layers.dense(inputs=dropout, units=10) # 輸出。形狀[1, 1, 10]
# 計算偏差 (計算 Cross entropy (交叉熵),再用 Softmax 計算百分比機率)loss = tf.losses.softmax_cross_entropy(onehot_labels=output_y, logits=logits)
https://www.tensorflow.org/api_docs/python/tf/losses/softmax_cross_entropy
交叉熵的損失。
onehot_labels 就是咱們真實的標籤值,output_y,暫時是一個placeholder,以後會賦值(訓練集裏對應的真實標籤)。
logits 傳入咱們的預估,logits(y帽子)
# Adam 優化器來最小化偏差,學習率 0.001使之最小化。使loss最小train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
# 精度。計算 預測值 和 實際標籤 的匹配程度# 返回(accuracy, update_op), 會建立兩個局部變量accuracy = tf.metrics.accuracy( labels=tf.argmax(output_y, axis=1), predictions=tf.argmax(logits, axis=1),)[1]
https://www.tensorflow.org/api_docs/python/tf/metrics/accuracy
Calculates how often predictions matches labels
計算預測值與真實值之間的差距,匹配度
argmax函數會返回張量軸上最大值的下標。
accuracy函數會返回兩個值,咱們取其中一個值。
accuracy:Tensor表明準確度,total除以的值count。 update_op:一種適當增長total和count變量而且其值匹配的操做accuracy。
# 建立會話sess = tf.Session()
# 初始化變量:全局和局部init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer()) sess.run(init)
初始化全局和局部變量。group是一個組的概念。
https://www.tensorflow.org/api_docs/python/tf/group
建立一個將多個操做分組的操做。
# 訓練神經網絡for i in range(20000): # 從訓練集中進行選取。batch,一包。 batch = mnist.train.next_batch(50) # 從 Train(訓練)數據集裏取"下一個"50 個樣本 # run以後,loss的返回值給到train_loss train_op的值給到train_op_ # 給實際的input_x和input_y賦值。batch有兩列,0是圖片,1是真實標籤。 train_loss, train_op_ = sess.run([loss, train_op], {input_x: batch[0], output_y: batch[1]}) if i % 100 == 0: # 這裏測試的精度是在測試集上的精度。 test_accuracy = sess.run(accuracy, {input_x: test_x, output_y: test_y}) # 步數,訓練的損失,測試的精度 print(("Step=%d, Train loss=%.4f, [Test accuracy=%.2f]") \ % (i, train_loss, test_accuracy))
# 測試:打印 20 個預測值 和 真實值 的對# 輸入測試集的20項,輸出預測的y(onehot)test_output = sess.run(logits, {input_x: test_x[:20]})# 取到它預測的y是哪一個真實數字inferenced_y = np.argmax(test_output, 1) print(inferenced_y, 'Inferenced numbers') # 推測的數字# 取出測試集中的真實標籤值print(np.argmax(test_y[:20], 1), 'Real numbers') # 真實的數字
連接:https://www.imooc.com/article/45760