Подготовка нового набора данных по обучающей модели с предварительным обучением - PullRequest
0 голосов
/ 05 февраля 2020

Код:

from keras.preprocessing import image as image_util 
from keras.applications.imagenet_utils import preprocess_input
from keras.applications.imagenet_utils import decode_predictions
from keras.applications import ResNet50
import numpy as np 
import argparse
import cv2
import time 

ap = argparse.ArgumentParser()
ap.add_argument("-i","--image",required= True,help ="path of the image")
args = vars(ap.parse_args())

# orig = cv2.imread(args["image"]) #Opencv function to load a image
start_time = time.time()
image = image_util.load_img(args["image"],target_size=(224,224))
image = image_util.img_to_array(image)

#print("!!!!!.....!!!!")
print(image.shape)


image = np.expand_dims(image,axis=0) #(224,224,3) --> (1,224,224,3)
#print("!!!!!.....!!!!")
print(image.shape)
image = preprocess_input(image)

#Loading the model 
model = ResNet50(weights="imagenet")
pred = model.predict(image)
#print("111!!!!!.....!!!!")
#print(pred)
p = decode_predictions(pred)
#print("222!!!!!.....!!!!")
#print(p)

for (i,(imagenetID,label,prob)) in enumerate(p[0]):
    print("{}. {}: {:.2f}%".format(i+1, label, prob*100))

ans = p[0][0]
ans = ans[1]
print("THE PREDICTED IMAGE IS: "+ans)

orig = cv2.imread(args["image"]) #Opencv function to load a image
(imagenetID,label,prob) = p[0][0]
cv2.putText(orig, "{},{:.2f}%".format(label,prob*100),(10,30),cv2.FONT_HERSHEY_COMPLEX,0.5,(0,0,0),1)
cv2.imshow("classification",orig)
cv2.waitKey(0)
print("--- %s seconds ---" % (time.time() - start_time))  

Этот код работает на весах imag enet и имеет предварительно обученную модель, которая может классифицировать различные изображения. Мне нужно обучить новый объект, т.е. мой собственный набор данных. (скажем, например, яблоко). Что мне делать, чтобы обновить веса, добавив мой новый набор данных?

1 Ответ

1 голос
/ 05 февраля 2020

Общий подход состоит в том, чтобы брать только нижние слои предварительно обученного CNN (например, Re sNet) и добавлять новые слои поверх существующего CNN.

После того, как у вас есть модель, вам, вероятно, следует заблокировать предварительно подготовленные слои в начале тренировки, чтобы не разрушать уже обученные веса, а затем после нескольких циклов, когда уклон стабилизируется, вы можете разблокировать их. слоев и продолжить обучение.

Самый простой способ отбросить верхние слои предварительно обученной сети - установить для аргумента include_top значение False.

base_model = ResNet50(include_top=False, weights="imagenet") 

Затем вы можете начать добавлять свои слои как обычно, т.е. (n_classes относится к числу классов, которые вы хотите классифицировать)

my_hidden1 = keras.layers.Dense(128, activation="relu")(base_model)
# rest of the custom layers
...
output = keras.layers.Dense(n_classes, activation="softmax")(previous_layer)
model = keras.Model(inputs=base_model.input, outputs=output)

Чтобы заблокировать предварительно подготовленные слои в начале

for layer in base_model.layers:
    layer.trainable = False

Тогда вы можете compile и fit ваша новая модель на несколько эпох (даже с большей скоростью обучения), т.е.

optimizer = keras.optimizers.SGD(lr=0.2, momentum=0.9, decay=0.01)
model.compile(optimizer=optimizer, ...)
model.fit(...)

После того, как начальное обучение завершено, вы можете разблокировать базовые слои и продолжить обучение (обычно вы хотите уменьшить скорость обучения на этом этапе).

for layer in base_model.layers:
    layer.trainable = True

optimizer = keras.optimizers.SGD(lr=0.01, momentum=0.9, decay=0.001)
model.compile(...)
model.fit(...)

Обратите внимание, что вам придется запускать compile каждый раз, когда вы блокируете или разблокируете эти слои. * 1 026 *

...