[英]CNN architecture: classifying “good” and “bad” images
我正在研究實現CNN以便將圖像分類為“好”或“壞”的可能性,但是我目前的體系結構沒有運氣。
表示“不良”圖像的特征:
實現神經網絡基於這些特征對圖像進行分類是否可行,還是最好讓傳統算法簡單地查看整個圖像的亮度/對比度變化並以這種方式分類?
我曾嘗試使用VGGNet架構來訓練CNN,但無論歷元數或步驟數如何,我似乎總是有偏見且不可靠。
例子:
我當前模型的架構非常簡單(因為我是整個機器學習領域的新手),但似乎可以與其他分類問題配合使用,並且我對其進行了一些修改,以更好地解決此二進制分類問題:
# CONV => RELU => POOL layer set
# define convolutional layers, use "ReLU" activation function
# and reduce the spatial size (width and height) with pool layers
model.add(Conv2D(32, (3, 3), padding="same", input_shape=input_shape)) # 32 3x3 filters (height, width, depth)
model.add(Activation("relu"))
model.add(BatchNormalization(axis=channel_dimension))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25)) # helps prevent overfitting (25% of neurons disconnected randomly)
# (CONV => RELU) * 2 => POOL layer set (increasing number of layers as you go deeper into CNN)
model.add(Conv2D(64, (3, 3), padding="same", input_shape=input_shape)) # 64 3x3 filters
model.add(Activation("relu"))
model.add(BatchNormalization(axis=channel_dimension))
model.add(Conv2D(64, (3, 3), padding="same", input_shape=input_shape)) # 64 3x3 filters
model.add(Activation("relu"))
model.add(BatchNormalization(axis=channel_dimension))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25)) # helps prevent overfitting (25% of neurons disconnected randomly)
# (CONV => RELU) * 3 => POOL layer set (input volume size becoming smaller and smaller)
model.add(Conv2D(128, (3, 3), padding="same", input_shape=input_shape)) # 128 3x3 filters
model.add(Activation("relu"))
model.add(BatchNormalization(axis=channel_dimension))
model.add(Conv2D(128, (3, 3), padding="same", input_shape=input_shape)) # 128 3x3 filters
model.add(Activation("relu"))
model.add(BatchNormalization(axis=channel_dimension))
model.add(Conv2D(128, (3, 3), padding="same", input_shape=input_shape)) # 128 3x3 filters
model.add(Activation("relu"))
model.add(BatchNormalization(axis=channel_dimension))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25)) # helps prevent overfitting (25% of neurons disconnected randomly)
# only set of FC => RELU layers
model.add(Flatten())
model.add(Dense(512))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.5))
# sigmoid classifier (output layer)
model.add(Dense(classes))
model.add(Activation("sigmoid"))
該模型是否存在明顯的遺漏或錯誤,還是我不能使用深度學習(使用我當前的GPU,GTX 970)來解決此問題?
感謝您的時間和經驗,
喬希
編輯:這是我用於編譯/訓練模型的代碼:
# initialise the model and optimiser
print("[INFO] Training network...")
opt = SGD(lr=initial_lr, decay=initial_lr / epochs)
model.compile(loss="sparse_categorical_crossentropy", optimizer=opt, metrics=["accuracy"])
# set up checkpoints
model_name = "output/50_epochs_{epoch:02d}_{val_acc:.2f}.model"
checkpoint = ModelCheckpoint(model_name, monitor='val_acc', verbose=1,
save_best_only=True, mode='max')
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2,
patience=5, min_lr=0.001)
tensorboard = TensorBoard(log_dir="logs/{}".format(time()))
callbacks_list = [checkpoint, reduce_lr, tensorboard]
# train the network
H = model.fit_generator(training_set, steps_per_epoch=500, epochs=50, validation_data=test_set, validation_steps=150, callbacks=callbacks_list)
獨立於任何其他建議(包括已經提供的答案),並假設classes=2
(您沒有弄清楚-我們在這里要求提供MCVE的原因),您似乎在最后一層犯了一個基本錯誤,即:
# sigmoid classifier (output layer)
model.add(Dense(classes))
model.add(Activation("sigmoid"))
僅當您的最后一層由單個節點組成時,才適用S型激活。 如果我懷疑classes=2
,也是基於您在評論中令人費解的陳述,
使用三個不同的圖像,我的結果是0.987不好,0.999很好
和
我以前給過你模型的預測
您應該使用softmax激活,即
model.add(Dense(classes))
model.add(Activation("softmax"))
或者,您可以使用sigmoid,但最后一層應包含一個節點,即
model.add(Dense(1))
model.add(Activation("sigmoid"))
后者通常在二進制分類設置中是首選,但是結果在原理上應該相同。
更新 (更新問題后):
sparse_categorical_crossentropy
在這里也不是正確的損失。
總之,請嘗試以下更改:
model.compile(loss="binary_crossentropy", optimizer=Adam(), metrics=["accuracy"])
# final layer:
model.add(Dense(1))
model.add(Activation("sigmoid"))
使用Adam優化器(需要導入)。 另外, 默認情況下不應使用dropout-請參見此線程 ; 從沒有它開始,僅在必要時添加(即,如果您看到過度擬合的跡象)。
我建議您去轉學而不是訓練整個網絡。 使用在像ImageNet這樣的龐大數據集上訓練的權重
您可以使用Keras輕松地做到這一點,您只需要導入權重如xception的模型並刪除代表1000個類別的imagenet數據集的最后一層到2個節點密集層,因為您只有2個類別,並且將基礎層和trainable=True
設置為trainable=False
trainable=True
對於自定義添加的層trainable=True
,例如具有節點= 2的密集層。
您可以像往常一樣訓練模型。
演示代碼-
from keras.applications import *
from keras.models import Model
base_model = Xception(input_shape=(img_width, img_height, 3), weights='imagenet', include_top=False
x = base_model.output
x = GlobalAveragePooling2D()(x)
predictions = Dense(2, activation='softmax')(x)
model = Model(base_model.input, predictions)
# freezing the base layer weights
for layer in base_model.layers:
layer.trainable = False
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.