最近看了吳恩達老師的深度學習課程,又看了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: embeddings_constraint=None: input_length=None: mask_zero:布爾值,確定是否將輸入中的‘0’看作是應該被忽略的‘填充’ 輸入 (samples,sequence_length)的2D張量 |
嵌入層將正整數(下標)轉換為具有固定大小的向量,如[[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作用相同,但適用於稀疏情況
參考文獻