補(bǔ)充
一、關(guān)于vector的轉(zhuǎn)置
numpy轉(zhuǎn)置一維行變量array時(shí):
print(features)
> array([ 0.49671415, -0.1382643 , 0.64768854])
print(features.T)
> array([ 0.49671415, -0.1382643 , 0.64768854])
print(features[:, None])
> array([[ 0.49671415],
[-0.1382643 ],
[ 0.64768854]])
numpy轉(zhuǎn)置二維array時(shí):
np.array(features, ndmin=2)
> array([[ 0.49671415, -0.1382643 , 0.64768854]])
np.array(features, ndmin=2).T
> array([[ 0.49671415],
[-0.1382643 ],
[ 0.64768854]])
二、keras
序列模型
from keras.models import Sequential
#Create the Sequential model
model = Sequential()
keras.models.Sequential 類(lèi)是神經(jīng)網(wǎng)絡(luò)模型的封裝容器。它會(huì)提供常見(jiàn)的函數(shù),例如 fit()
、evaluate()
和 compile()
。我們將介紹這些函數(shù)(在碰到這些函數(shù)的時(shí)候)。我們開(kāi)始研究模型的層吧。
層
Keras 層就像神經(jīng)網(wǎng)絡(luò)層。有全連接層、最大池化層和激活層。你可以使用模型的 add() 函數(shù)添加層。例如,簡(jiǎn)單的模型可以如下所示:
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Flatten
#創(chuàng)建序列模型
model = Sequential()
#第一層 - 添加有128個(gè)節(jié)點(diǎn)的全連接層以及32個(gè)節(jié)點(diǎn)的輸入層
model.add(Dense(128, input_dim=32))
或者:
model.add(Flatten(input_shape=X_train.shape[1:]))
Flatten層用來(lái)將輸入“壓平”,即把多維的輸入一維化,常用在從卷積層到全連接層的過(guò)渡。Flatten不影響batch的大小
#第二層 - 添加 softmax 激活層
model.add(Activation('softmax'))
#第三層 - 添加dropout層
model.add(Dropout(0.2))
#第三層 - 添加全連接層
model.add(Dense(10))
#第四層 - 添加 Sigmoid 激活層
model.add(Activation('sigmoid'))
上面兩個(gè)可以結(jié)合到一起
model.add(Dense(10, activation='sigmoid'))
Keras 將根據(jù)第一層自動(dòng)推斷后續(xù)所有層的形狀。這意味著,你只需為第一層設(shè)置輸入維度。
上面的第一層 model.add(Dense(input_dim=32)) 將維度設(shè)為 32(表示數(shù)據(jù)來(lái)自 32 維空間)。第二層級(jí)獲取第一層級(jí)的輸出,并將輸出維度設(shè)為 128 個(gè)節(jié)點(diǎn)。這種將輸出傳遞給下一層級(jí)的鏈繼續(xù)下去,直到最后一個(gè)層級(jí)(即模型的輸出)。可以看出輸出維度是 10。
構(gòu)建好模型后,我們就可以用以下命令對(duì)其進(jìn)行編譯。我們將損失函數(shù)指定為我們一直處理的 categorical_crossentropy。我們還可以指定優(yōu)化程序,稍后我們將了解這一概念,暫時(shí)將使用 adam。最后,我們可以指定評(píng)估模型用到的指標(biāo)。我們將使用準(zhǔn)確率。
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics = ['accuracy'])
我們可以使用以下命令來(lái)查看模型架構(gòu):
model.summary()
然后使用以下命令對(duì)其進(jìn)行擬合,指定 epoch 次數(shù)和我們希望在屏幕上顯示的信息詳細(xì)程度。
然后使用fit命令訓(xùn)練模型并通過(guò) epoch 參數(shù)來(lái)指定訓(xùn)練輪數(shù)(周期),每 epoch 完成對(duì)整數(shù)據(jù)集的一次遍歷。 verbose 參數(shù)可以指定顯示訓(xùn)練過(guò)程信息類(lèi)型,這里定義為 0 表示不顯示信息。
model.fit(X, y, nb_epoch=1000, verbose=0)
注意:在 Keras 1 中,nb_epoch 會(huì)設(shè)置 epoch 次數(shù),但是在 Keras 2 中,變成了 epochs。
最后,我們可以使用以下命令來(lái)評(píng)估模型:
model.evaluate()
callback回調(diào)
callback回調(diào)下有很多,比如上面所說(shuō)的early stop,還有最常用的checkpoint,我們通過(guò)checkpoint來(lái)記錄我們的訓(xùn)練過(guò)程,或者是最好的權(quán)重
from keras.callbacks import ModelCheckpoint
# train the model
checkpointer = ModelCheckpoint(filepath='mnist.model.best.hdf5',
verbose=1, save_best_only=True)
hist = model.fit(X_train, y_train, batch_size=128, epochs=10,
validation_split=0.2, callbacks=[checkpointer],
verbose=1, shuffle=True)
ModelCheckpoint checkpoint的內(nèi)容以及存儲(chǔ)地址,
filepath checkpoint 保存路徑
ModelCheckpoint - verbose 日志顯示,0為不在標(biāo)準(zhǔn)輸出流輸出日志信息,1為輸出進(jìn)度條記錄
save_best_only 是否只存最好的權(quán)重
validation_split 驗(yàn)證集百分比
callbacks 回調(diào)有哪些
shuffle 打亂數(shù)據(jù)集
fit - verbose 日志顯示,0為不在標(biāo)準(zhǔn)輸出流輸出日志信息,1為輸出進(jìn)度條記錄,2為每個(gè)epoch輸出一行記錄
當(dāng)然checkpoint有保存,那么自然有提取
model.load_weights()
參數(shù)內(nèi)加路徑即可。
Keras 中的卷積層
要在 Keras 中創(chuàng)建卷積層,你首先必須導(dǎo)入必要的模塊:
from keras.layers import Conv2D
然后,你可以通過(guò)使用以下格式創(chuàng)建卷積層:
Conv2D(filters, kernel_size, strides, padding, activation='relu', input_shape)
參數(shù)
必須傳遞以下參數(shù):
-
filters
- 過(guò)濾器數(shù)量。 -
kernel_size
- 指定(方形)卷積窗口的高和寬的數(shù)字。
你可能還需要調(diào)整其他可選參數(shù):
-
strides
- 卷積 stride。如果不指定任何值,則strides
設(shè)為1
。 -
padding
- 選項(xiàng)包括'valid'
和'same'
。如果不指定任何值,則padding
設(shè)為'valid'
。same是用零填充邊緣來(lái)滿(mǎn)足strides的移動(dòng),而valid是說(shuō)卷積框不超出input范圍。 -
activation
- 通常為'relu'
。如果未指定任何值,則不應(yīng)用任何激活函數(shù)。強(qiáng)烈建議你向網(wǎng)絡(luò)中的每個(gè)卷積層添加一個(gè) ReLU 激活函數(shù)。
注意:可以將 kernel_size
和 strides
表示為數(shù)字或元組。
在模型中將卷積層當(dāng)做第一層級(jí)(出現(xiàn)在輸入層之后)時(shí),必須提供另一個(gè) input_shape
參數(shù):
-
input_shape
- 指定輸入的高度、寬度和深度(按此順序)的元組。
注意:如果卷積層不是網(wǎng)絡(luò)的第一個(gè)層級(jí),請(qǐng)勿包含 input_shape
參數(shù)。
你還可以設(shè)置很多其他元組參數(shù),以便更改卷積層的行為。要詳細(xì)了解這些參數(shù),建議參閱官方文檔。
- 示例 1*
假設(shè)我要構(gòu)建一個(gè) CNN,輸入層接受的是 200 x 200 像素(對(duì)應(yīng)于高 200、寬 200、深 1 的三維數(shù)組)的灰度圖片。然后,假設(shè)我希望下一層級(jí)是卷積層,具有 16 個(gè)過(guò)濾器,每個(gè)寬和高分別為 2。在進(jìn)行卷積操作時(shí),我希望過(guò)濾器每次跳轉(zhuǎn) 2 個(gè)像素。并且,我不希望過(guò)濾器超出圖片界限之外;也就是說(shuō),我不想用 0 填充圖片。要構(gòu)建該卷積層,我將使用下面的代碼:
Conv2D(filters=16, kernel_size=2, strides=2, activation='relu', input_shape=(200, 200, 1))
示例 2
假設(shè)我希望 CNN 的下一層級(jí)是卷積層,并將示例 1 中構(gòu)建的層級(jí)作為輸入。假設(shè)新層級(jí)是 32 個(gè)過(guò)濾器,每個(gè)的寬和高都是 3。在進(jìn)行卷積操作時(shí),我希望過(guò)濾器每次移動(dòng) 1 個(gè)像素。我希望卷積層查看上一層級(jí)的所有區(qū)域,因此不介意過(guò)濾器在進(jìn)行卷積操作時(shí)是否超過(guò)上一層級(jí)的邊緣。然后,要構(gòu)建此層級(jí),我將使用以下代碼:
Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')
示例 3
如果在線(xiàn)查看代碼,經(jīng)常會(huì)在 Keras 中見(jiàn)到以下格式的卷積層:
Conv2D(64, (2,2), activation='relu')
在這種情況下,有 64 個(gè)過(guò)濾器,每個(gè)的大小是 2x2,層級(jí)具有 ReLU 激活函數(shù)。層級(jí)中的其他參數(shù)使用默認(rèn)值,因此卷積的 stride 為 1,填充設(shè)為 'valid'。
維度
和神經(jīng)網(wǎng)絡(luò)一樣,我們按以下步驟在 Keras 中創(chuàng)建 CNN:首先創(chuàng)建一個(gè)序列模型。
使用 .add() 方法向該網(wǎng)絡(luò)中添加層級(jí)。
from keras.models import Sequential
from keras.layers import Conv2D
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=2, strides=2, padding='valid',
activation='relu', input_shape=(200, 200, 1)))
model.summary()
我們不會(huì)訓(xùn)練該 CNN;相反,我們將使用該可執(zhí)行文件根據(jù)所提供的參數(shù)研究卷積層的維度如何變化。
注意卷積層的形狀是如何變化的。對(duì)應(yīng)的是輸出內(nèi)容中的 Output Shape 下的值。在上圖中,None 對(duì)應(yīng)的是批次大小,卷積層的高度為 100,寬度為 100,深度為 16。
公式:卷積層中的參數(shù)數(shù)量
卷積層中的參數(shù)數(shù)量取決于 filters、kernel_size 和 input_shape 的值。我們定義幾個(gè)變量:
- K - 卷積層中的過(guò)濾器數(shù)量
- F - 卷積過(guò)濾器的高度和寬度
- D_in - 上一層級(jí)的深度
注意:K = filters,F(xiàn) = kernel_size。類(lèi)似地,D_in 是 input_shape 元組中的最后一個(gè)值。
因?yàn)槊總€(gè)過(guò)濾器有 FFD_in 個(gè)權(quán)重,卷積層由 K 個(gè)過(guò)濾器組成,因此卷積層中的權(quán)重總數(shù)是 KFFD_in。因?yàn)槊總€(gè)過(guò)濾器有 1 個(gè)偏差項(xiàng),卷積層有 K 個(gè)偏差。因此,卷積層中的參數(shù)數(shù)量是 KFFD_in + K。
公式:卷積層的形狀
卷積層的形狀取決于 kernel_size、input_shape、padding 和 stride 的值。我們定義幾個(gè)變量:
- K - 卷積層中的過(guò)濾器數(shù)量
- F - 卷積過(guò)濾器的高度和寬度
- H_in - 上一層級(jí)的高度
- W_in - 上一層級(jí)的寬度
注意:K = filters、F = kernel_size,以及S = stride。類(lèi)似地,H_in 和 W_in 分別是 input_shape 元組的第一個(gè)和第二個(gè)值。
卷積層的深度始終為過(guò)濾器數(shù)量 K。
如果 padding = 'same',那么卷積層的空間維度如下:
- height = ceil(float(H_in) / float(S))
- width = ceil(float(W_in) / float(S))
如果 padding = 'valid',那么卷積層的空間維度如下:
height = ceil(float(H_in - F + 1) / float(S))
width = ceil(float(W_in - F + 1) / float(S))
Keras 中的最大池化層
要在 Keras 中創(chuàng)建最大池化層,你必須首先導(dǎo)入必要的模塊:
from keras.layers import MaxPooling2D
然后使用以下格式創(chuàng)建卷積層:
MaxPooling2D(pool_size, strides, padding)
參數(shù)
你必須包含以下參數(shù):
- pool_size - 指定池化窗口高度和寬度的數(shù)字。
你可能還需要調(diào)整其他可選參數(shù):
- strides - 垂直和水平 stride。如果不指定任何值,則 strides 默認(rèn)為 pool_size。
- padding - 選項(xiàng)包括 'valid' 和 'same'。如果不指定任何值,則 padding 設(shè)為 'valid'。
注意:可以將 pool_size 和 strides 表示為數(shù)字或元組。
示例
假設(shè)我要構(gòu)建一個(gè) CNN,并且我想通過(guò)在卷積層后面添加最大池化層,降低卷積層的維度。假設(shè)卷積層的大小是 (100, 100, 15),我希望最大池化層的大小為 (50, 50, 15)。要實(shí)現(xiàn)這一點(diǎn),我可以在最大池化層中使用 2x2 窗口,stride 設(shè)為 2,代碼如下:
MaxPooling2D(pool_size=2, strides=2)
如果你想將 stride 設(shè)為 1,但是窗口大小依然保留為 2x2,則使用以下代碼:
MaxPooling2D(pool_size=2, strides=1)
檢查最大池化層的維度
from keras.models import Sequential
from keras.layers import MaxPooling2D
model = Sequential()
model.add(MaxPooling2D(pool_size=2, strides=2, input_shape=(100, 100, 15)))
model.summary()
運(yùn)行可看到:
用keras構(gòu)建CN模型
和神經(jīng)網(wǎng)絡(luò)一樣,我們通過(guò)首先創(chuàng)建一個(gè)序列
模型來(lái)創(chuàng)建一個(gè) CNN。
from keras.models import Sequential
導(dǎo)入幾個(gè)層,包括熟悉的神經(jīng)網(wǎng)絡(luò)層,以及在這節(jié)課學(xué)習(xí)的新的層。
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
和神經(jīng)網(wǎng)絡(luò)一樣,通過(guò)使用 .add()
方法向網(wǎng)絡(luò)中添加層級(jí):
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=2, padding='same', activation='relu', input_shape=(32, 32, 3)))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=32, kernel_size=2, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=64, kernel_size=2, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Flatten())
model.add(Dense(500, activation='relu'))
model.add(Dense(10, activation='softmax'))
該網(wǎng)絡(luò)以三個(gè)卷積層(后面跟著最大池化層)序列開(kāi)始。前 6 個(gè)層級(jí)旨在將圖片像素?cái)?shù)組輸入轉(zhuǎn)換為所有空間信息都丟失、僅保留圖片內(nèi)容信息的數(shù)組 。然后在 CNN 的第七個(gè)層級(jí)將該數(shù)組扁平化為向量。后面跟著兩個(gè)密集層,旨在進(jìn)一步說(shuō)明圖片中的內(nèi)容。最后一層針對(duì)數(shù)據(jù)集中的每個(gè)對(duì)象類(lèi)別都有一個(gè)條目,并具有一個(gè) softmax 激活函數(shù),使其返回概率。
注意:在該視頻中,你可能注意到卷積層表示為 Convolution2D
,而不是 Conv2D
。對(duì)于 Keras 2.0 來(lái)說(shuō),二者都可以,但是最好使用 Conv2D
。
注意事項(xiàng)
- 始終向 CNN 中的
Conv2D
層添加 ReLU 激活函數(shù)。但是網(wǎng)絡(luò)的最后層級(jí)除外,密集
層也應(yīng)該具有 ReLU 激活函數(shù)。 - 在構(gòu)建分類(lèi)網(wǎng)絡(luò)時(shí),網(wǎng)絡(luò)中的最后層級(jí)應(yīng)該是具有 softmax 激活函數(shù)的
密集
層。最后層級(jí)的節(jié)點(diǎn)數(shù)量應(yīng)該等于數(shù)據(jù)集中的類(lèi)別總數(shù)。
圖像增強(qiáng)
具體使用方法如下,首先需要?jiǎng)?chuàng)建圖像增強(qiáng)生成器ImageDataGenerator,隨機(jī)旋轉(zhuǎn)圖片,移動(dòng)圖片,翻轉(zhuǎn)圖片,最后要fit我們的訓(xùn)練圖片。
from keras.preprocessing.image import ImageDataGenerator
# create and configure augmented image generator
datagen_train = ImageDataGenerator(
width_shift_range=0.1, # randomly shift images horizontally (10% of total width)
height_shift_range=0.1, # randomly shift images vertically (10% of total height)
horizontal_flip=True) # randomly flip images horizontally
# fit augmented image generator on data
datagen_train.fit(x_train)
使用圖像增強(qiáng)后,模型的訓(xùn)練也需要進(jìn)行變動(dòng),
1、fit變?yōu)閒it_generator,只要通過(guò)ImageDataGenerator類(lèi)來(lái)生成增強(qiáng)圖像,就一定需要將fit改為fit_generator
2、datagen_train.flow,這個(gè)flow是使數(shù)據(jù)生成器創(chuàng)建一批批增強(qiáng)圖像,參數(shù)中要有訓(xùn)練數(shù)據(jù),訓(xùn)練數(shù)據(jù)的label,和設(shè)定一批圖像的數(shù)量
3、steps_per_epoch,表示每個(gè)epoch的步長(zhǎng),通常會(huì)設(shè)定為數(shù)據(jù)集中的樣本數(shù)量除以批次大小,對(duì)應(yīng)代碼的話(huà), x_train.shape[0] 對(duì)應(yīng)的是訓(xùn)練數(shù)據(jù)集 x_train 中的獨(dú)特樣本數(shù)量。通過(guò)將 steps_per_epoch 設(shè)為此值,我們確保模型在每個(gè) epoch 中看到 x_train.shape[0] 個(gè)增強(qiáng)圖片。
from keras.callbacks import ModelCheckpoint
batch_size = 32
epochs = 100
# train the model
checkpointer = ModelCheckpoint(filepath='aug_model.weights.best.hdf5', verbose=1,
save_best_only=True)
model.fit_generator(datagen_train.flow(x_train, y_train, batch_size=batch_size),
steps_per_epoch=x_train.shape[0] // batch_size,
epochs=epochs, verbose=2, callbacks=[checkpointer],
validation_data=(x_valid, y_valid),
validation_steps=x_valid.shape[0] // batch_size)
三、突破性的CNN架構(gòu)
-
AlexNet
alexnet.png -
VGG
VGG.png -
ResNet
ResNet.png