簡體   English   中英

CNN 能比預訓練的 CNN 做得更好嗎?

[英]Can CNN do better than pretrained CNN?

據我所知。 預訓練的 CNN 可以比 CNN 做得更好。 我有一個包含 855 張圖像的數據集。 我應用了 CNN 並獲得了 94% 的准確率。然后我應用了經過微調的預訓練 model(VGG16、ResNet50、Inception_V3、MobileNet),但我仍然獲得了最高的 60%,其中兩個在分類方面做得非常糟糕。 CNN 真的可以比預訓練的 model 做得更好還是我的實現是錯誤的。 我已經將我的圖像轉換為 100 x 100 尺寸,並按照keras 應用程序的方式進行操作。 那到底是什么問題??

朴素的 CNN 方法:

def cnn_model():
    size = (100,100,1)
    num_cnn_layers =2
    NUM_FILTERS = 32
    KERNEL = (3, 3)
    MAX_NEURONS = 120

    model = Sequential()

    for i in range(1, num_cnn_layers+1):
        if i == 1:
            model.add(Conv2D(NUM_FILTERS*i, KERNEL, input_shape=size, 
            activation='relu', padding='same'))
        else:
            model.add(Conv2D(NUM_FILTERS*i, KERNEL, activation='relu', 
            padding='same'))

    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Flatten())
    model.add(Dense(int(MAX_NEURONS), activation='relu'))
    model.add(Dropout(0.25))
    model.add(Dense(int(MAX_NEURONS/2), activation='relu'))
    model.add(Dropout(0.4))
    model.add(Dense(3, activation='softmax'))

    model.compile(loss='categorical_crossentropy', optimizer='adam', 
    metrics=['accuracy'])
    return model

VGG16 方法:

def vgg():
`  `vgg_model = keras.applications.vgg16.VGG16(weights='imagenet',include_top=False,input_shape = (100,100,3))
    model = Sequential()
    for layer in vgg_model.layers:
        model.add(layer)

    # Freeze the layers 
    for layer in model.layers:
        layer.trainable = False

    model.add(keras.layers.Flatten())
    model.add(keras.layers.Dense(3, activation='softmax'))

    model.compile(optimizer=keras.optimizers.Adam(lr=1e-5),
              loss='categorical_crossentropy',
              metrics=['accuracy'])
    return model 

在這兩種情況下,您所說的 CNN 都在談論同一件事,這是一種神經網絡 model。 只是預訓練的 model 已經在其他一些數據上進行了訓練,而不是您正在處理並嘗試分類的數據集。

這里通常使用的稱為遷移學習。 與其凍結所有層,不如嘗試將最后幾層保持打開狀態,以便使用您自己的數據重新訓練它們,以便預訓練的 model 可以編輯其權重和偏差以滿足您的需求。 您嘗試分類的數據集可能與預訓練模型無關。

這是我自己工作的一個例子,還有一些額外的代碼,但你可以用你自己的代碼讓它工作,邏輯保持不變

#You extract the layer which you want to manipulate, usually the last few.
last_layer = pre_trained_model.get_layer(name_of_layer)

# Flatten the output layer to 1 dimension
x = layers.Flatten()(last_output)
# Add a fully connected layer with 1,024 hidden units and ReLU activation
x = layers.Dense(1024,activation='relu')(x)
# Add a dropout rate of 0.2
x = layers.Dropout(0.2)(x)                  
# Add a final sigmoid layer for classification
x = layers.Dense(1,activation='sigmoid')(x)           

#Here we combine your newly added layers and the pre-trained model.
model = Model( pre_trained_model.input, x) 

model.compile(optimizer = RMSprop(lr=0.0001), 
              loss = 'binary_crossentropy', 
              metrics = ['accuracy'])

除了@Ilknur Mustafa 提到的內容之外,由於您的數據集可能與用於預訓練的圖像不同,您可以嘗試重新訓練預訓練的 model 的最后幾層,而不是添加一個全新的層。 下面的示例代碼除了 output 層之外沒有添加任何額外的可訓練層。 通過這種方式,您可以通過在現有權重上重新訓練最后幾層來受益,而不是從頭開始訓練。 如果您沒有要訓練的大型數據集,這可能會有所幫助。

# load model without classifier layers 
vgg = VGG16(include_top=False, input_shape=(100, 100, 3), weights='imagenet', pooling='avg')
# make only last 2 conv layers trainable 
for layer in vgg.layers[:-4]:
    layer.trainable = False
# add output layer  
out_layer = Dense(3, activation='softmax')(vgg.layers[-1].output)
model_pre_vgg = Model(vgg.input, out_layer)
# compile model 
opt = SGD(lr=1e-5) 
model_pre_vgg.compile(optimizer=opt, loss=keras.losses.categorical_crossentropy, metrics=['accuracy'])
#You extract the layer which you want to manipulate, usually the last few.
last_layer = pre_trained_model.get_layer(name_of_layer)

# Flatten the output layer to 1 dimension
x = layers.Flatten()(last_output)
# Add a fully connected layer with 1,024 hidden units and ReLU activation
x = layers.Dense(1024,activation='relu')(x)
# Add a dropout rate of 0.2
x = layers.Dropout(0.2)(x)                  
# Add a final sigmoid layer for classification
x = layers.Dense(1,activation='sigmoid')(x)           

#Here we combine your newly added layers and the pre-trained model.
model = Model( pre_trained_model.input, x) 

model.compile(optimizer = RMSprop(lr=0.0001), 
              loss = 'binary_crossentropy', 
              metrics = ['accuracy'])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM