在Keras模型中one-hot編碼,Embedding層,使用預訓練的詞向量/處理圖片


最近看了吳恩達老師的深度學習課程,又看了python深度學習這本書,對深度學習有了大概的了解,但是在實戰的時候,

還是會有一些細枝末節沒有完全弄懂,這篇文章就用來總結一下用keras實現深度學習算法的時候一些我自己很容易搞錯的點。

 一、與序列文本有關

1.僅對序列文本進行one-hot編碼

比如:使用路透社數據集(包含許多短新聞及其對應的主題,包括46個不同的主題,每個主題有至少10個樣本)

from keras.datasets import reuters
(train_data,train_labels),(test_data,test_labels) = reuters.load_data(new_words=10000)

加載數據集時,參數new_words=10000表示將數據限定為前10000個最常出現的單詞

 

有8982個訓練樣本和2246個測試樣本

 

每個樣本都是一個整數列表(表示單詞的索引)

 
word_index=reuters.get_word_index()
reverse_word_index=dict([(value,key) for (key,value) in word_index.items()])
decoded_newswire = ' '.join([reverse_word_index.get(i-3,'?') for i in train_data[0]])

將索引解碼為新聞文本

這里舉個例子將訓練集的第一條樣本取出來,將它解碼為文本

import numpy as np
def vectorize_sequences(sequences,dimension=10000):
    results = np.zeros((len(sequences),dimension))
    for i, sequence in enumerate(sequences):
        results[i,sequence] = 1
    return results

x_train = vectorize_sequences(train_data) 
x_test = vectorize_sequences(test_data)

編碼數據

把每個樣本sequence編碼為長度為10000的向量

#方法一:自定義one-hot
def to_one_hot(labels,dimension=46):
    results = np.zeros((len(labels),dimension))
    for i,label in enumerte(labels):
        results[i,label] = i.
    return results

one_hot_train_labels = to_one_hot(train_labels)
  

#方法二:keras內置方法
from keras.utils.np_utils import to_categorical

one_hot_train_labels = to_categorical(train_labels)

標簽向量化有兩種方法:

第一種是自定義的one-hot編碼,將標簽列表轉換為整數張量

第二種是keras內置的方法

 

 

2.keras的Embedding層【Embedding層只能作為模型的第一層

keras.layers.embeddings.Embedding(
input_dim, 
output_dim,
embeddings_initializer='uniform', 
embeddings_regularizer=None, 
activity_regularizer=None, 
embeddings_constraint=None, 
mask_zero=False, 
input_length=None
)
input_dim:字典長度,即輸入數據最大下標+1  
output_dim:代表全連接嵌入的維度 
embeddings_initializer='uniform':
嵌入矩陣的初始化方法,為預定義初始化方法名的字符串,或用於初始化權重的初始化器
embeddings_regularizer=None:
嵌入矩陣的正則項,為Regularizer對象
embeddings_constraint=None:
嵌入矩陣的約束項,為Constraints對象
input_length=None:
當輸入序列的長度固定時,該值為其長度。如果要在該層后接Flatten層,
然后接Dense層,則必須指定該參數,否則Dense層的輸出維度無法自動推斷。
mask_zero:布爾值,確定是否將輸入中的‘0’看作是應該被忽略的‘填充’
(padding)值,該參數在使用遞歸層處理變長輸入時有用。設置為True的話,
模型中后續的層必須都支持masking,否則會拋出異常。如果該值為True,
則下標0在字典中不可用,input_dim應設置為|vocabulary| + 2。

  輸入 (samples,sequence_length)的2D張量 
  輸出   (samples, sequence_length, output_dim)的3D張量

 

嵌入層將正整數(下標)轉換為具有固定大小的向量,如[[4],[20]]->[[0.25,0.1],[0.6,-0.2]]

[[4],[20]]表示一句話由兩個單詞組成,第一個單詞在詞向量的位置為4,第二個單詞位置為20

而位置為4的單詞,對應的二維詞向量就是[0.25,0.1];類似,位置為20的單詞的詞向量為[0.6,-0.2]

下面簡單描述一下:

上圖的流程是把文章的單詞使用詞向量來表示。
(1)提取文章所有的單詞,把其按其出現的次數降序(這里只取前50000個),比如單詞‘network’出現的次數最多,編號ID為0,依次類推…

(2)每個編號ID都可以使用50000維的二進制(one-hot)表示

(3)最后,我們會生產一個矩陣M,行大小為詞的個數50000,列大小為詞向量的維度(通常取128或300),比如矩陣的第一行就是編號ID=0,即network對應的詞向量。

那這個矩陣M怎么獲得呢?在Skip-Gram 模型中,我們會隨機初始化它,然后使用神經網絡來訓練這個權重矩陣

 

3.在Keras模型中使用預訓練的詞向量

這個例子展示了兩個樣本通過embedding層,兩個樣本都經過了`max_len=5`的填充處理,

最終的維度就變成了`(2, max_len, 5)`,這是因為使用了50維的詞嵌入。

 

首先拿到一段文本,要想通過該文本完成分類或其他的任務,就必須要把這個文本轉成詞向量的形式。

先對訓練集進行按行切分(或者,已經有一個所有句子的列表了),然后找到單詞數最大的那行作為max_len,這個待會要輸入模型中的

對於沒達到max_len的句子,可以通過把句子給擴充為max_len長度

import keras.preprocessing.sequence import pad_sequences
pad_sequences(sequences,maxlen=max_len)

然后得到每行單詞對應的詞向量,現在所有行的維度應該是(行數,單詞數最多的那行對應的單詞個數,每個單詞詞向量的維度) 

模型的輸入是(一批多少序列batch,輸入長度input_length)

word index單詞索引不超過999,詞向量的個數上限值1000
輸出是(None,10,64) None表示batch的維度(個數),64是每個單詞的詞向量的維度
model = Sequential()
model.add(Embedding(1000, 64, input_length=10))
input_array = np.random.randint(1000, size=(32, 10))#32句話,每句話10個單詞

model.compile('rmsprop', 'mse')
output_array = model.predict(input_array)
assert output_array.shape == (32, 10, 64) #32句話,每句話10個單詞,每個單詞有64維的詞向量

4. 當多個循環層堆疊時,前面所有循環層中間層都需要返回完整的輸出序列,最后一層僅返回最終輸出  

 

 

 二與圖片數據有關

 1.處理一張輸入圖像,改成模型規定輸入格式才能輸入模型中

from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input,decode_predictions
import numpy as np

img_path = '圖片的路徑'
img = image.load_img(img_path,target_size=(224,224)) #224 224是模型要求輸入大小

x = image.img_to_array(image)#將圖片轉換為(224,224,3)的float32格式的numpy數組

x = np.expand_dims(x,axis=0)#添加一個維度,將數組轉換為(1,224,224,3)形狀的批量,
#因為keras模型是以batch作為輸入的,所以一張圖片就相當於batch=1

x = preprocess_input(x)#對批量進行預處理(按通道進行顏色標准化)

preds = model.predict(x)

2.輸入圖像的張量,顯示圖片

注意:這里圖像的張量,取值可能不是[0,255]區間內的整數,需要對這個張量進行后處理,將其轉換為可顯示的圖像

def deprocess_image(x):
    x -= x.mean() #對張量做標准化,使其均值為0,標准差為0.1
    x /= (x.std() + 1e-5)
    x *= 0.1

    x += 0.5
    x = np.clip(x,0,1) #將x裁切(clip)到[0,1]區間
    
    x *= 255
    x = np.clip(x,0,255).astype('uint8') #將x轉換為RGB數組
    return x

#執行下面這句話就能看到圖片了
#例:image的大小為(150,150,3)
plt.imshow(deprocess_image(image))

3.我們拿到的訓練數據一般不是同一個大小的,需要將圖像全部調整成指定大小的

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale = 1./255) #將所有圖像乘以1/255縮放
test_datagen = ImageDataGenerator(rescale = 1./255)

train_generator = train_datagen.flow_from_directory(
            train_dir,
            target_size=(150,150),#將所有圖像的大小調整為(255,255)
            batch_size = 20,
            class_mode = 'binary, #這里目標是二分類,所以用二進制標簽
)       

 

三、常見的誤差與精確性指標

誤差

  • mean_squared_error / mse  均方誤差,常用的目標函數,公式為((y_pred-y_true)**2).mean()
  • mean_absolute_error / mae 絕對值均差,公式為(|y_pred-y_true|).mean()
  • mean_absolute_percentage_error / mape公式為:(|(y_true - y_pred) / clip((|y_true|),epsilon, infinite)|).mean(axis=-1) * 100,和mae的區別就是,累加的是(預測值與實際值的差)除以(剔除不介於epsilon和infinite之間的實際值),然后求均值。
  • mean_squared_logarithmic_error / msle公式為: (log(clip(y_pred, epsilon, infinite)+1)- log(clip(y_true, epsilon,infinite)+1.))^2.mean(axis=-1),這個就是加入了log對數,剔除不介於epsilon和infinite之間的預測值與實際值之后,然后取對數,作差,平方,累加求均值。
  • squared_hinge 公式為:(max(1-y_true*y_pred,0))^2.mean(axis=-1),取1減去預測值與實際值乘積的結果與0比相對大的值的平方的累加均值。
  • hinge 公式為:(max(1-y_true*y_pred,0)).mean(axis=-1),取1減去預測值與實際值乘積的結果與0比相對大的值的的累加均值。
  • binary_crossentropy: 常說的邏輯回歸, 就是常用的交叉熵函數
  • categorical_crossentropy: 多分類的邏輯, 交叉熵函數的一種變形吧,沒看太明白

精確性

  • binary_accuracy: 對二分類問題,計算在所有預測值上的平均正確率
  • categorical_accuracy:對多分類問題,計算再所有預測值上的平均正確率
  • sparse_categorical_accuracy:與categorical_accuracy相同,在對稀疏的目標值預測時有用
  • top_k_categorical_accracy: 計算top-k正確率,當預測值的前k個值中存在目標類別即認為預測正確
  • sparse_top_k_categorical_accuracy:與top_k_categorical_accracy作用相同,但適用於稀疏情況


參考文獻 

一文詳解 Word2vec 之 Skip-Gram 模型(結構篇) 

深度學習中Embedding層有什么用?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM