本文內容以下:python
1. keras中,shape如何定義?git
2. 關於model.compile 的參數傳遞,傳遞字符串呢?仍是傳遞對象?github
3. 如何獲取模型中的每一個layer信息?如input_shape,output_shape,layer的參數配置等api
4. 如何將預訓練好的詞向量加載到Embedding layer中?數組
5. 如何獲取單個layer的weight?瀏覽器
6. keras如何與tensorboard結合?網絡
7. keras 如何作fine-tuning?dom
8. keras使用過程當中,如何構造data與label?(將其構造爲numpy數組便可)ide
9. 若是data過大,不適合一次性加載到內存中,該如何處理?(文本訓練通常用不到,畢竟txt文件,1M就是100萬char,已經很大了。一本小說幾百萬字,也就幾M,十幾M)函數
10 . keras中Sequential 模型 與函數式API的區別是什麼?
11. GRU與LSTM的參數如何理解?
【一】keras中的shape定義
keras中,Sequential 模型中的第一層須要指定shape,不然keras沒法自動計算後面的layer的shape而運行報錯。
1. 經過參數 input_shape 指定shape,該參數的shape信息不包含batch_size信息,batch_size默認爲None
例如:指定shape爲2D,則 input_shape = (100,)或者 input_shape = (None,)
指定shape爲3D,則 input_shape = (100,20) 或者 input_shape = (None,20)
input_shape 能夠是元組,也能夠是列表。仍是統一用元組吧。
2. 經過參數 batch_input_shape指定shape,該參數的shape信息包含batch_size,且第一個維度就是batch_size大小。
例如:指定shape爲2D,則 batch_input_shape = (None,100,)或者 batch_input_shape = (None,None)
指定shape爲3D,則 batch_input_shape = (None,100,20) 或者 batch_input_shape = (None,None,20)
代碼示例以下:
# -*- coding:utf-8 -*- import keras from keras.layers import Dense model = keras.Sequential() # shape通常使用元組定義,列表也行,仍是統一使用元組表示吧 # 必須是input_shape=(2,)不能是input_shape=(2) # 輸入是2D,shape = (None,2) model.add(Dense(units=3,input_shape=(2,))) # shape = (None, 2, 3) #model.add(Dense(units=3,input_shape=(2,2))) #model.add(Dense(units=3,input_shape=[2,2])) # shape=(2,3) #model.add(Dense(units=3,batch_input_shape=(2,3))) model.summary()
3. 那是否是第一層的layer都須要經過input_shape或者batch_input_shape參數來指定shape信息呢?
答案是否認的,只要能推算出shape便可具體能夠參見:https://keras.io/zh/getting-started/sequential-model-guide/
這裏對常見的第一層layer作個舉例。
3.1 第一層爲Embedding
狀況一:不知道輸入數據的長度,只知道詞典的大小與embedding_size。
model = keras.Sequential() # input_dim就是詞典大小,out_dim就是embedding_size model.add(Embedding(input_dim=10000,output_dim=100)) model.summary() 結果爲: Layer (type) Output Shape Param # ================================================================= embedding_1 (Embedding) (None, None, 100) 1000000 =================================================================
狀況二:知道數據數據的長度,好比:輸入定長的句子
model = keras.Sequential() # input_length就是數據數據的長度 model.add(Embedding(input_dim=10000,output_dim=100,input_length=200)) model.summary() 結果爲: _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding_1 (Embedding) (None, 200, 100) 1000000 =================================================================
embedding layer做爲第一層時,就默認了,輸入數據必須是2D,通過embedding layer後,輸出必定爲3D。
【二】model.compile 的參數傳遞
1. 參數之優化器,均在 keras.optimizers 模塊下面定義
model.compile(optimizer='Adam') model.compile(optimizer=keras.optimizers.Adam(lr=0.01))
2. 參數之損失 loss,均在 keras.losses下定義
該loss可使用keras.losses模塊下面定義的loss,也可使用tf.loss模塊下面定義的loss,能夠參考:https://keras.io/zh/losses/
model.compile(optimizer=keras.optimizers.Adam(),loss=tf.losses.sigmoid_cross_entropy) model.compile(optimizer='Adam',loss=keras.losses.binary_crossentropy)
3. 參數之 metrics
在訓練和測試期間的模型評估標準。一般你會使用 metrics = ['accuracy']。
metrics能夠支持中評估方法:分別是:'accuracy', 'acc', 'crossentropy', 'ce'
這個從源碼能夠看出,雖然傳遞的是字符串,可是最終仍是使用 keras.metrics.模塊中的評估方法,並且從字符串到方法的映射,還和loss函數有關係。
從源碼來看,傳遞'acc'和‘accuracy’是同樣的,傳遞'ce‘和'crossentropy‘是同樣的。一個是簡寫,一個是全稱罷了。
其餘參數暫時不探討了,能夠參考源碼或者keras官方文檔(https://keras.io/zh/models/sequential/)
【三】如何獲取模型中的每一個layer信息?
# -*- coding:utf-8 -*- import keras import tensorflow as tf from keras.layers import Dense from keras.layers import Embedding model = keras.Sequential() model.add(Embedding(input_dim=10000,output_dim=100,input_length=200,name="emb")) model.summary() # 經過layer的名字獲取layer emb_layer = model.get_layer(name="emb") # 獲取layer的shape信息 print(emb_layer.input_shape) print(emb_layer.output_shape) # 獲取layer的參數配置信息 print(emb_layer.get_config()) 結果以下: (None, 200) (None, 200, 100) {'name': 'emb', 'trainable': True, 'batch_input_shape': (None, 200), 'dtype': 'float32', 'input_dim': 10000, 'output_dim': 100, 'embeddings_initializer': {'class_name': 'RandomUniform', 'config': {'minval': -0.05, 'maxval': 0.05, 'seed': None}}, 'embeddings_regularizer': None, 'activity_regularizer': None, 'embeddings_constraint': None, 'mask_zero': False, 'input_length': 200}
【四】如何將預訓練好的詞向量加載到Embedding layer中?
這裏以斯坦福大學經過glove訓練好的word embedding爲例(https://nlp.stanford.edu/projects/glove/)
# 初始化詞典 embedding_matrix = np.zeros(shape=(V,m)) word_index = {} embedding_index = {} # 選擇m=50的預訓練數據,將預訓練的詞與vector提取到embedding_index中存儲起來 with open("glove.6B.50d.txt") as f: for line in f: values = line.split() word = values[0] coefs = np.asarray(values[1:],dtype=np.float32) embedding_index[word] = coefs ''' x_train,t_train = imdb_load("train") token = text.Tokenizer(num_words=max_features) token.fit_on_texts(x_train) ''' # 獲取當前語料(imdb)的詞 word_index = token.word_index not_find = 0 for word,i in word_index.items(): if i < V: # 查預訓練的詞表 embedding_vec = embedding_index.get(word) if embedding_vec is not None: embedding_matrix[i] = embedding_vec else: not_find += 1 # 將權值設置到embedding layer中 model.layers[0].set_weigth([embedding_matrix]) # frozen embedding layer,也能夠不凍結。不凍結的話就能夠fine-tuning該層 model.layers[0].trainable = False
【五】 如何獲取單個layer的weight?
# 經過layer的名字獲取layer emb_layer = model.get_layer(name="emb") weigth = emb_layer.get_weights() print(weigth) 返回的是np數組 結果以下: [array([[-0.04013518, 0.04399543, 0.03000858, ..., -0.0194814 , -0.04092554, -0.02486232], [-0.00160228, -0.04412872, 0.03846688, ..., 0.02017101, -0.02005241, 0.01420185], [ 0.04151604, 0.04445838, 0.03028882, ..., 0.04380548, 0.04354296, -0.02567321], ..., [ 0.02195187, -0.01256204, 0.01097646, ..., -0.04138255, -0.01372109, 0.02588195], [-0.00363313, 0.01956742, -0.00567082, ..., -0.03723276, 0.02284933, -0.04223878], [-0.0346414 , 0.01633375, 0.03251269, ..., 0.04532002, -0.02762125, -0.03938962]], dtype=float32)]
【六】keras如何與tensorboard結合?
使用方式比較簡單,給fit函數傳遞一個keras.callbacks.TensorBoard 做爲callback對象便可
tensorboard = keras.callbacks.TensorBoard(log_dir="./logs/") train_history = model.fit(x=x_train, y=y_train, batch_size=128, epochs=1, validation_data=(x_test,y_test), callbacks=[tensorboard])
啓動tensorboard(tensorboard --logdir=./logs/)以後,而後在瀏覽器輸入:http://localhost:6006 ,便可看到各類信息
參考官方文檔(https://keras.io/zh/callbacks/),該回調接口,有不少參數。
其中關於embedding的可視化,參考官方案例:(https://github.com/keras-team/keras/blob/master/examples/tensorboard_embeddings_mnist.py)
【七】keras 如何作fine-tuning?
1. fine-tuning 通常是指,將模型的部分層保留,部分層刪除或者修改,進而造成一個新的模型。好比在CV的分類網絡中,一本將基於ImageNet訓練出來的resnet等網絡的最後一層修改,而後將預訓練的模型參數導入新的模型中。那麼要實現fine-tuning,在keras中如何實現呢?
思路仍是一致:先保存原有模型參數,構造新模型,最後將原有模型中與新模型layer一致的參數,用過layer-name導入到新的模型中。
1)定義原始模型,並保存模型參數。
# -*- coding:utf-8 -*- import keras from keras.layers import Dense model = keras.Sequential() model.add(Dense(units=5,batch_input_shape=(2,5),name="fc1")) model.add(Dense(units=3,name="fc2")) model.summary() # 保存模型 model.save_weights('./models/fc.h5')
2)定義新模型,加載原始模型的權值參數
# -*- coding:utf-8 -*- import keras from keras.layers import Dense # 定義模型,模型的前2層和原始模型一致 model = keras.Sequential() model.add(Dense(units=5,batch_input_shape=(2,5),name="fc1")) model.add(Dense(units=3,name="fc2")) # 第三層是新模型新增的層 model.add(Dense(units=1,name="fc3")) # 加載原始模型的參數到新模型中,經過設置by_name=True來實現,即經過layer名字查找對應的參數,其底層機制,與tf和caffe應該是一致的 model.load_weights(filepath='./models/fc.h5',by_name=True) model.summary()
注意地點,進行參數加載時,layer的配置信息必須徹底一致,好比shape
【十】 keras中Sequential 模型 與函數式API的區別是什麼?
1. 首先看看官網對函數式API的定義:
2. 函數式API的使用方法這裏便再也不講述了,可參考:https://keras.io/zh/getting-started/functional-api-guide/
3. 函數式API的返回值是什麼?
----- 這個是官網描述,咱們來看看代碼
from keras.layers import Input x = Input(shape=(5,)) print(type(x)) 結果以下: <class 'tensorflow.python.framework.ops.Tensor'>
能夠看出,網絡層的實例返回的確是張量。
使用函數式API,能夠向TensorFlow同樣編寫代碼,並且比TensorFlow簡單不少。
x = Input(shape=(5,),name="x") fc1 = Dense(units=5)(x) fc1 = keras.activations.relu(x=fc1) print(fc1) # 結果以下 Tensor("Relu:0", shape=(?, 5), dtype=float32)
keras.layer將所需定義的W、b等variable自動定義了。
有些layer可能返回多個輸出值,當咱們僅須要其中的幾個返回值而丟棄其餘的返回值值時,函數式API給以知足這種需求(好比GRU/LSTM)
【十一】GRU與LSTM的參數如何理解?
1. GRU參數
2. 這個return相關的兩個參數。
先看看例子:
from keras.layers import Input from keras.layers import GRU from keras.layers import LSTM x = Input(shape=(None, 20)) y = GRU(units=10) print(y(x)) Tensor("gru_1/TensorArrayReadV3:0", shape=(?, 10), dtype=float32) y = GRU(units=10,return_state=True) print(y(x)) [<tf.Tensor 'gru_2/TensorArrayReadV3:0' shape=(?, 10) dtype=float32>, <tf.Tensor 'gru_2/while/Exit_2:0' shape=(?, 10) dtype=float32>] y = GRU(units=10,return_state=True,return_sequences=True) print(y(x)) [<tf.Tensor 'gru_3/transpose_1:0' shape=(?, ?, 10) dtype=float32>, <tf.Tensor 'gru_3/while/Exit_2:0' shape=(?, 10) dtype=float32>] y = LSTM(units=10) print(y(x)) Tensor("lstm_1/TensorArrayReadV3:0", shape=(?, 10), dtype=float32) y = LSTM(units=10,return_state=True) print(y(x)) [<tf.Tensor 'lstm_2/TensorArrayReadV3:0' shape=(?, 10) dtype=float32>, <tf.Tensor 'lstm_2/while/Exit_2:0' shape=(?, 10) dtype=float32>, <tf.Tensor 'lstm_2/while/Exit_3:0' shape=(?, 10) dtype=float32>] y = LSTM(units=10,return_state=True,return_sequences=True) print(y(x)) [<tf.Tensor 'lstm_3/transpose_1:0' shape=(?, ?, 10) dtype=float32>, <tf.Tensor 'lstm_3/while/Exit_2:0' shape=(?, 10) dtype=float32>, <tf.Tensor 'lstm_3/while/Exit_3:0' shape=(?, 10) dtype=float32>]
return_state: 布爾值。若是爲false,LSTM僅返回Ht,GRU僅返回Ht。若是是true,LSTM返回C0/C1...Ct和H0,H1,H2,,,,Ht每個時間步計算出的中間狀態值
return_sequences: 布爾值。是返回輸出序列中的最後一個輸出,仍是所有序列 ------>也就是返回值list中的第一個值,list[0]。即LSTM或者GRU,是否返回全部的輸出值,即y】h0,h1,h2,......,ht。若是返回,則增長一個shape維度。
x = Input(shape=(50, 20)) y = GRU(units=10) print(y(x)) y = GRU(units=10,return_sequences=True) print(y(x)) Tensor("gru_1/TensorArrayReadV3:0", shape=(?, 10), dtype=float32) Tensor("gru_2/transpose_1:0", shape=(?, ?, 10), dtype=float32)
關於這return的配置使用,keras給出了一個官方案例,在實現seq2seq時提到了。(https://github.com/keras-team/keras/blob/master/examples/lstm_seq2seq.py)
總結:LSTM的stats 返回值是2組,GRU的stats返回值是1組。所以,LSTM的返回值是1個或者三個,GRU是1個或者2個。