用TensorFlow作好一個機器學習項目,須要具有多種代碼能力:python
工程開發能力:怎麼讀取數據、怎麼設計與運行Computation Graph、怎麼保存與恢復變量、怎麼保存統計結果、怎麼共享變量、怎麼分佈式部署git
數據操做能力:怎麼將原始數據一步步轉化爲模型須要的數據,中間可能涉及到Tensor轉換、字符串處理、JSON處理等json
模型理論知識:線性迴歸,邏輯迴歸,softmax regression,支持向量機,決策樹,隨機森林,GBDT,CNN,RNNsegmentfault
數值計算理論知識:交叉熵數值計算的潛在問題(爲何要用tf.nn.softmax_cross_entropy_with_logits
),梯度降低法,海森矩陣與特徵向量,牛頓法,Adam梯度法。數組
本系列文章已對TensorFlow的工程開發和與模型理論知識的結合作了較多的總結。本文的目的是聚焦於數據操做能力,講述TensorFlow中比較重要的一些API,幫助你們實現各自的業務邏輯。app
TensorFlow提供兩種類型的拼接:機器學習
tf.concat(values, axis, name='concat')
:按照指定的已經存在的軸進行拼接分佈式
tf.stack(values, axis=0, name='stack')
:按照指定的新建的軸進行拼接函數
t1 = [[1, 2, 3], [4, 5, 6]] t2 = [[7, 8, 9], [10, 11, 12]] tf.concat([t1, t2], 0) ==> [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] tf.concat([t1, t2], 1) ==> [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]] tf.stack([t1, t2], 0) ==> [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]] tf.stack([t1, t2], 1) ==> [[[1, 2, 3], [7, 8, 9]], [[4, 5, 6], [10, 11, 12]]] tf.stack([t1, t2], 2) ==> [[[1, 7], [2, 8], [3, 9]], [[4, 10], [5, 11], [6, 12]]]
上面的結果讀起來不太直觀,咱們從shape角度看一下就很容易明白了:學習
t1 = [[1, 2, 3], [4, 5, 6]] t2 = [[7, 8, 9], [10, 11, 12]] tf.concat([t1, t2], 0) # [2,3] + [2,3] ==> [4, 3] tf.concat([t1, t2], 1) # [2,3] + [2,3] ==> [2, 6] tf.stack([t1, t2], 0) # [2,3] + [2,3] ==> [2*,2,3] tf.stack([t1, t2], 1) # [2,3] + [2,3] ==> [2,2*,3] tf.stack([t1, t2], 2) # [2,3] + [2,3] ==> [2,3,2*]
tf.slice(input_, begin, size, name=None)
:按照指定的下標範圍抽取連續區域的子集
tf.gather(params, indices, validate_indices=None, name=None)
:按照指定的下標集合從axis=0
中抽取子集,適合抽取不連續區域的子集
input = [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]], [[5, 5, 5], [6, 6, 6]]] tf.slice(input, [1, 0, 0], [1, 1, 3]) ==> [[[3, 3, 3]]] tf.slice(input, [1, 0, 0], [1, 2, 3]) ==> [[[3, 3, 3], [4, 4, 4]]] tf.slice(input, [1, 0, 0], [2, 1, 3]) ==> [[[3, 3, 3]], [[5, 5, 5]]] tf.gather(input, [0, 2]) ==> [[[1, 1, 1], [2, 2, 2]], [[5, 5, 5], [6, 6, 6]]]
假設咱們要從input中抽取[[[3, 3, 3]]]
,這個輸出在inputaxis=0
的下標是1,axis=1
的下標是0,axis=2
的下標是0-2,因此begin=[1,0,0]
,size=[1,1,3]
。
假設咱們要從input中抽取[[[3, 3, 3], [4, 4, 4]]]
,這個輸出在inputaxis=0
的下標是1,axis=1
的下標是0-1,axis=2
的下標是0-2,因此begin=[1,0,0]
,size=[1,2,3]
。
假設咱們要從input中抽取[[[3, 3, 3], [5, 5, 5]]]
,這個輸出在inputaxis=0
的下標是1-2,axis=1
的下標是0,axis=2
的下標是0-2,因此begin=[1,0,0]
,size=[2,1,3]
。
假設咱們要從input中抽取[[[1, 1, 1], [2, 2, 2]],[[5, 5, 5], [6, 6, 6]]]
,這個輸出在input的axis=0
的下標是[0, 2]
,不連續,能夠用tf.gather
抽取。
tf.string_to_number(string_tensor, out_type=None, name=None)
: 將字符串轉化爲tf.float32
(默認)和tf.int32
tf.to_double(x, name='ToDouble')
:轉化爲tf.float64
tf.to_float(x, name='ToFloat')
:轉化爲tf.float32
tf.to_int32(x, name='ToInt32')
:轉化爲tf.int32
tf.to_int64(x, name='ToInt64')
:轉化爲tf.int64
tf.cast(x, dtype, name=None)
:轉化爲dtype
指定的類型
tf.reshape(tensor, shape, name=None)
:轉化爲新shape
,如有一個維度設置爲-1,會自動推導
TensorFlow使用三個dense tensor來表達一個sparse tensor:indices
、values
、dense_shape
。
假如咱們有一個dense tensor:
[[1, 0, 0, 0] [0, 0, 2, 0] [0, 0, 0, 0]]
那麼用SparseTensor表達這個數據對應的三個dense tensor以下:
indices
:[[0, 0], [1, 2]]
values
:[1, 2]
dense_shape
:[3, 4]
能夠經過如下兩種方法,將sparse tensor轉化爲dense tensor:
tf.sparse_to_dense(sparse_indices, output_shape, sparse_values, default_value=0, validate_indices=True, name=None)
tf.sparse_tensor_to_dense(sp_input, default_value=0, validate_indices=True, name=None)
tf.string_split(source, delimiter=' ')
source
是一維數組,用於將一組字符串按照delimiter
拆分爲多個元素,返回值爲一個SparseTensor
。
假若有兩個字符串,source[0]
是「hello world」,source[1]
是「a b c」,那麼輸出結果以下:
st.indices
: [0, 0; 0, 1; 1, 0; 1, 1; 1, 2]
st.values
: ['hello', 'world', 'a', 'b', 'c']
st.dense_shape
:[2, 3]
tf.string_join(inputs, separator=None, name=None)
,用起來比較簡單:
tf.string_join(["hello", "world"], separator=" ") ==> "hello world"
經過tf.py_func(func, inp, Tout, stateful=True, name=None)
能夠將任意的python函數func
轉變爲TensorFlow op。
func
接收的輸入必須是numpy array,能夠接受多個輸入參數;輸出也是numpy array,也能夠有多個輸出。inp傳入輸入值,Tout指定輸出的基本數據類型。
先看一個解析json的例子,輸入是一個json array,輸出是一個特徵矩陣。
import tensorflow as tf import numpy as np import json json_str_1 = ''' {"name": "shuiping.chen", "score": 95, "department": "industrial engineering", "rank": 2 } ''' json_str_2 = ''' {"name": "zhuibing.dan", "score": 87, "department": "production engineering", "rank": 4 } ''' input_array = np.array([json_str_1, json_str_2]) def parse_json(json_str_array): fea_dict_array = [ json.loads(item) for item in json_str_array ] ret_feature = [] for fea_dict in fea_dict_array: feature = [fea_dict["score"], fea_dict["rank"]] ret_feature.append(feature) return np.array(ret_feature, dtype=np.float32) parse_json_op = tf.py_func(parse_json, [input_array], tf.float32) sess = tf.Session() print sess.run(parse_json_op)
再看一個多輸入多輸出的例子,輸入兩個numpy array,輸出三個array,分別是和、差、乘積。
array1 = np.array([[1, 2], [3, 4]], dtype=np.float32) array2 = np.array([[5, 6], [7, 8]], dtype=np.float32) def add_minus_dot(array1, array2): return array1 + array2, array1 - array2, np.dot(array1, array2) add_minus_dot_op = tf.py_func(add_minus_dot, [array1, array2], [tf.float32, tf.float32, tf.float32]) print sess.run(add_minus_dot_op)