TensorFlow記錄(一)

記錄學習TensorFlow過程中遇到知識點

1.函數 tf.contrib.keras.preprocessing.sequence.pad_sequences()

用於填充數組(列表),返回一個數組類型。函數參數:

def pad_sequences(sequences: {__iter__, __len__},
                  maxlen: Any = None,
                  dtype: str = 'int32',
                  padding: str = 'pre',
                  truncating: str = 'pre',
                  value: float = 0.) -> ndarray

傳入的sequence是一個序列,maxlen是填充的最大長度,padding有兩種參數pre , post,分別指定在序列之前或者最後進行填充。truncating指定當最大長度少於輸入序列長度時候從前面截斷還是從後面截斷。最後的value指定填充所用的數字。例如:

data = [[1,2,3.4],[3,4.7,5,6]]

print(type(data))
pad_data = kr.preprocessing.sequence.pad_sequences(data, maxlen=3, dtype=np.float32, truncating='pre')
print(type(pad_data))
print(pad_data)

輸出:

<class 'list'>
<class 'numpy.ndarray'>
[[1.  2.  3.4]
 [4.7 5.  6. ]]

2.函數 tf.contrib.keras.utils.to_categorical()

函數將數字轉化爲對應的 one-hot 編碼,函數參數:

def to_categorical(y: Any,
                   num_classes: Any = None,
                   dtype: str = 'float32') -> ndarray

num_class 指定編碼的長度,例如:

labels = list(range(4))
labels = kr.utils.to_categorical(labels, num_classes=len(labels))

print(labels)

輸出:

[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]

3.tf.flags.DEFINE_XXX()

例如:

import tensorflow as tf

FLAGS = tf.flags.FLAGS
tf.flags.DEFINE_integer('test_int', 100, 'introduce')

print(FLAGS.test_int)

使用這個函數可以定義命令行參數,尤其是對於數據集地址,等需要改變的參數,可以直接在運行文件時候外部進行改變,而非修改源代碼,使用方法例如:
在這裏插入圖片描述

4.tf.contrib 快速處理文本數據

使用函數tf.contrib.learn.preprocessing.VocabularyProcessor(length)可以快速創建詞彙表,函數調用格式:

tf.contrib.learn.preprocessing.VocabularyProcessor (max_document_length, min_frequency=0, vocabulary=None, tokenizer_fn=None)

其中max_document_length是文檔的最大長度,處理過程中文檔長度大於這個數值會捨去,小於則會補0,min_frequency是詞頻,只有超過這個數值的詞語纔會收錄到詞彙表中,第三個暫且記下(沒搞懂有什麼用。。),最後一個則是分詞函數
例如:

import tensorflow as tf
from tensorflow.contrib import learn
import numpy as np

# 文本數據
data = ["It is a nice day", "Today is rainy", "a b c d e f g"]
# 得到最長的文本長度
max_doc_len = max(len(x.split(" ")) for x in data)
# 將數據集中每一條數據處理爲最大長度,使用0補齊
vocab_processor = learn.preprocessing.VocabularyProcessor(max_doc_len)

x = np.array(list(vocab_processor.fit_transform(data)))
print(x)

打印的結果:

[[ 1  2  3  4  5  0  0]
 [ 6  2  7  0  0  0  0]
 [ 3  8  9 10 11 12 13]]

可以看到已經將每個出現的單詞進行了編號,並進行了補齊。

5.文本數據隨機打亂方法

這並不是tensorflow的方法,直接使用numpy就可以很方便地完成,例如:

# 先使用 random 常生於
data = np.array([x for x in "abcde"])
print(data)
# data 也就是[ a, b, c, d, e]
# 使用 全排列函數 產生一個序列
shuffle_indices = np.random.permutation(len(data))

print(shuffle_indices)
# 注意這樣寫的條件事 data 必須是 ndarray 類型,如果不是,可以使用 np.array()函數轉化
data = data[shuffle_indices]

print(data)

輸出:

['a' 'b' 'c' 'd' 'e']
[1 2 3 0 4]
['b' 'c' 'd' 'a' 'e']

6. tf.concat() 函數-拼接數組

很多地方都會使用 tf.concat()函數來進行拼接函數的結果,比如經過一些並行計算的卷積處理之後,一般都會使用這個函數將不同卷積層的結果拼接在一起再進行後續操作,之前不太理解這個函數拼接的方式,試驗了幾次之後算是理解了這個函數的操作,在這裏記錄一下。

首先,這個函數的定義如下:

def concat(values: {__len__},
           axis: Any,
           name: str = "concat")

主要是兩個參數:

  • values 一般會以列表或者數組的形式傳入這個參數,表示將這個列表中的所有元素都進行拼接
  • axis 指定的是進行拼接的維度

舉個例子來說:

a = np.random.randint(1, 10, (2, 3, 4))
b = np.random.randint(1, 10, (2, 3, 5))

concat_op = tf.concat([a, b], axis=2)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    res = sess.run(concat_op)
    print(res.shape)

輸出的結果是:

(2, 3, 9)

可以看到,是在第三個維度(axis=2)上進行拼接,簡單來說,這個函數就是相應的維度上進行簡單相加即可。這裏進行拼接的數組有一個非常明顯的特徵,就是這些數組只能在指定的要進行拼接的維度上不一樣,否則是不能完成拼接的。

7.tf.contrib.layers.l2_regularizer()

這是TF提供的正則化函數,如果要使用 l1 正則,那麼換成 l1 即可,使用例子如下:

weights = tf.constant([[1., -2.], [-3., 4.]])
l1_op = tf.contrib.layers.l1_regularizer(.5)(weights)
l2_op = tf.contrib.layers.l2_regularizer(.5)(weights)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(l1_op))
    print(sess.run(l2_op))

輸出:

5.0
7.5

這裏 L1 正則沒有什麼問題,每一個元素的絕對值和乘以 lambda(0.5)就是5.0 .但是注意這裏計算 L2 的時候,注意在實現上會將總損失值除以2然後在乘以 lambda ,也就是:

(1 * 1 + -2 * -2 + -3 * -3 + 4 * 4)  / 2 * 0.5 = 7.5 

另外,要注意到執行上面的代碼會報出 WARNING, 提示 tf.contrib mudule will not be include in TensorFlow 2.0.從提示的信息來看,應該會歸併到一個叫 tensorflow_addons 的mudule中吧。

8.tf.nn.embedding_lookup()函數

簡單來說,這個函數的功能就是,傳入一個a數組和一個索引數組,然後按照索引數組從a數組中取出相應的列組成一個新的數組返回。
這個函數的定義:

def embedding_lookup(params: Any,
                     ids: Any,
                     partition_strategy: str = "mod",
                     name: Any = None,
                     validate_indices: bool = True,
                     max_norm: Any = None) -> Union[{dtype}, Tensor, {values}, IndexedSlices, object]

主要的參數也就是 params 和 ids ,其中 params 是完整數組, ids 表示索引數組。這個函數一般用在word2vec等相關的任務中,例如傳入的訓練數據是一個 batch_size 的索引數組,現在要根據這個索引從完整的詞彙embeddings表中拿出這些訓練詞向量,就可以使用這個函數。例如:

import numpy as np
import tensorflow as tf

a = tf.random_uniform(shape=[5,2])
b = tf.constant([3,4])

get_op = tf.nn.embedding_lookup(a, b)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    ta, tb, tc = sess.run([a, b, get_op])
    print(ta)
    print(tb)
    print(tc)

具體來說,比如我們對句子進行分類,往往傳入的batch數據尺寸爲 [batch_size, sentence_length],這個數組就是 idx 索引數組,其中 sentence_length 就是某個句子的長度(有多少單詞),然後會按照這個單詞的序號去 完整的詞向量表中找到這個單詞的詞向量,這樣操作的結果就是 [batch_size, sentence_length, embedding_dims]。
另外,注意上面的:

    ta, tb, tc = sess.run([a, b, get_op])

a是計算過程中隨機生成的,如果想要查看這個結果,就要在一次 run 中進行獲取。

9.tf.nn.softmax_cross_entropy_with_logits_v2(logits=pred, labels=Y)

這裏要說明:

tf.nn.softmax_cross_entropy_with_logits_v2()

注意這個函數的兩個參數,其中:
logits表示模型輸出的值 也就是預測值, labels表示正確標籤

logits 的輸入格式是 [batch_size, n_class], labels的輸入格式同上,但是要注意每一橫行都要是類別的 one-hot 形式。
注意區分下面這個:

tf.nn.sparse_softmax_cross_entropy_with_logits()

傳入的模型前向傳播計算結果是(1, num_classes)的形式,但是labels傳入的值應該是一個索引值,也就是一個類別單值,可以使用 tf.argmax(x, axis=1) 從 one-hot 編碼向量中獲得。

但是注意這兩個函數都含有 softmax 的計算過程,因此不需要進行 softmax 進行歸一化。

10.關於 one-hot 數據的生成

兩種方式,一種使用 Numpy,利用單位矩陣的特點生成,例如:

n_class = 5

# 生成單條 one-hot數據
# 藉助 eye 函數可以生成單位矩陣
# 後面傳入數組的話, 可以表示取出第幾行 根據單位矩陣的特點
# 這裏生成的是 第一個值爲 1 的 one-hot
res1 = np.eye(n_class)[0]
print(res1)
print('-'*30)

# 生成多條 one-hot 形式數據
index = [1,2,3]
res2 = np.eye(n_class)[index]
print(res2)

或者直接在 TF 中生成:
這個函數是tensorflow中提供的將數字標籤轉化爲 one-hot 形式的方法:

def one_hot(indices: Any,
            depth: Any,
            on_value: Any = None,
            off_value: Any = None,
            axis: Any = None,
            dtype: Any = None,
            name: Any = None) -> Any

主要要提供的參數有 indecies 這是原始的數字標籤, on_value 表示如果是正類,用什麼數字表示,一般默認是1.0, off_value顯然就是相反的如果是負類 ,該用什麼數字進行表示

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章