2017-07-28 69 views
3

在上下文中,我對機器學習的世界比較陌生,我正在嘗試一個項目,其目標是在NBA比賽中對比賽進行分類。我的輸入是來自NBA比賽中每場比賽的40幀的序列,我的標籤對於給定的比賽來說是11種全面的分類。Keras VGG16是否需要預修重量?

該計劃是採取每個幀的序列,並將每幀傳遞到CNN提取一組功能。然後,來自給定視頻的每個特徵序列將被傳遞到RNN。

我目前在我的大部分實施中使用Keras,並且我選擇爲我的CNN使用VGG16模型。這裏是下面的一些相關代碼:

video = keras.Input(shape = (None, 255, 255, 3), name = 'video') 
cnn = keras.applications.VGG16(include_top=False, weights = None, input_shape= 
(255,255,3), pooling = 'avg', classes=11) 
cnn.trainable = True 

我的問題是 - 將它仍然是有益的,我初始化VGG16 ConvNet的權重「imagenet」如果我的目標是NBA比賽的視頻片段進行分類?如果是這樣,爲什麼?如果沒有,我如何訓練VGG16 ConvNet以獲取我自己的權重集,然後如何將它們插入到此函數中?在使用VGG16模型時,我有幸找到任何教程,其中有人包含他們自己的一組權重。

我很抱歉,如果我的問題看起來很天真,但我真的很感謝任何幫助,在清除這一點。

+0

考慮訪問[數據科學SE(https://datascience.stackexchange.com)或[交叉驗證(https://stats.stackexchange.com)爲關於機器學習的問題。 –

回答

5

您是否應該針對您的特定任務重新培養VGG16? 絕對不是!重新訓練這樣一個巨大的網絡是困難的,並且需要很多直覺和知識來訓練深度網絡。讓我們來分析一下爲什麼你可以使用的權重,對ImageNet預先訓練,您的任務:

  • ImageNet是一個巨大的數據集,包含數以百萬計的圖像。 VGG16本身在強大的GPU上已經過3-4天左右的訓練。在CPU上(假設您沒有像NVIDIA GeForce Titan X那樣強大的GPU)需要數週時間。

  • ImageNet包含來自真實世界場景的圖像。 NBA比賽也可以被視爲真實世界的場景。因此,ImageNet功能的預先訓練很可能也可用於NBA比賽。

實際上,您不需要使用預先訓練好的VGG16的所有卷積層。讓我們來看看​​,看看他們檢測(從this article拍攝;圖像過大,所以我把剛纔的鏈接緊湊):

  • 第一和第二卷積塊着眼於低電平的功能,如拐角,邊緣等
  • 第三和第四卷積塊看起來在表面特徵,曲線,圓等
  • 第五層着眼於高級別功能

所以,您可以決定哪種功能會受益負責您的具體任務。你需要第五檔的高級功能嗎?或者你可能想使用第三塊的中級功能?也許你想在VGG的最底層疊加另一個神經網絡?有關更多說明,請參閱我編寫的以下教程;它曾經是SO文檔。使用VGG和Keras

在這個例子中,三個簡單的和全面的子實例


遷移學習和微調都:從可用的預先訓練模型

  • 加載權重,包括與Keras圖書館
  • 疊加另一個網絡在VGG的任何層頂上培訓
  • 插入其他層的中間層
  • 提示和一般原則進行的大拇指進行微調和轉讓與VGG學習

預加載訓練的權重

ImageNet模型,包括VGG-16VGG-19,可在Keras。在此例中,將使用VGG-16。欲瞭解更多信息,請訪問Keras Applications documentation

from keras import applications 

# This will load the whole VGG16 network, including the top Dense layers. 
# Note: by specifying the shape of top layers, input tensor shape is forced 
# to be (224, 224, 3), therefore you can use it only on 224x224 images. 
vgg_model = applications.VGG16(weights='imagenet', include_top=True) 

# If you are only interested in convolution filters. Note that by not 
# specifying the shape of top layers, the input tensor shape is (None, None, 3), 
# so you can use them for any size of images. 
vgg_model = applications.VGG16(weights='imagenet', include_top=False) 

# If you want to specify input tensor 
from keras.layers import Input 
input_tensor = Input(shape=(160, 160, 3)) 
vgg_model = applications.VGG16(weights='imagenet', 
           include_top=False, 
           input_tensor=input_tensor) 

# To see the models' architecture and layer names, run the following 
vgg_model.summary() 

創建與VGG

採取底層的新網絡假定爲與大小(160, 160, 3)圖像某些特定的任務,要使用VGG的預訓練的底層,向上以名稱block2_pool分層。

vgg_model = applications.VGG16(weights='imagenet', 
           include_top=False, 
           input_shape=(160, 160, 3)) 

# Creating dictionary that maps layer names to the layers 
layer_dict = dict([(layer.name, layer) for layer in vgg_model.layers]) 

# Getting output tensor of the last VGG layer that we want to include 
x = layer_dict['block2_pool'].output 

# Stacking a new simple convolutional network on top of it  
x = Conv2D(filters=64, kernel_size=(3, 3), activation='relu')(x) 
x = MaxPooling2D(pool_size=(2, 2))(x) 
x = Flatten()(x) 
x = Dense(256, activation='relu')(x) 
x = Dropout(0.5)(x) 
x = Dense(10, activation='softmax')(x) 

# Creating new model. Please note that this is NOT a Sequential() model. 
from keras.models import Model 
custom_model = Model(input=vgg_model.input, output=x) 

# Make sure that the pre-trained bottom layers are not trainable 
for layer in custom_model.layers[:7]: 
    layer.trainable = False 

# Do not forget to compile it 
custom_model.compile(loss='categorical_crossentropy', 
        optimizer='rmsprop', 
        metrics=['accuracy']) 

移除多個層和在中間插入

一個新的假定需要由具有單個卷積層替換block1_conv1block2_conv2,在這樣一種方式,以加快VGG16預先訓練的重量被保存。 這個想法是將整個網絡拆分成不同的層,然後將其組裝回來。下面是代碼專門針對你的任務:

vgg_model = applications.VGG16(include_top=True, weights='imagenet') 

# Disassemble layers 
layers = [l for l in vgg_model.layers] 

# Defining new convolutional layer. 
# Important: the number of filters should be the same! 
# Note: the receiptive field of two 3x3 convolutions is 5x5. 
new_conv = Conv2D(filters=64, 
        kernel_size=(5, 5), 
        name='new_conv', 
        padding='same')(layers[0].output) 

# Now stack everything back 
# Note: If you are going to fine tune the model, do not forget to 
#  mark other layers as un-trainable 
x = new_conv 
for i in range(3, len(layers)): 
    layers[i].trainable = False 
    x = layers[i](x) 

# Final touch 
result_model = Model(input=layer[0].input, output=x)