代码之家  ›  专栏  ›  技术社区  ›  Sai Krishnadas

在迁移学习预训练模型上训练新数据集

  •  0
  • Sai Krishnadas  · 技术社区  · 6 年前

    代码:

    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))  
    

    此代码适用于图像净重,并具有一个可以对各种图像进行分类的预训练模型。 我需要训练一个新对象,即我自己的数据集。(比如说苹果)。 我该怎么做才能更新添加新数据集的权重?

    0 回复  |  直到 6 年前
        1
  •  1
  •   Matus Dubrava    6 年前

    一般的方法是只采用预训练CNN的较低层(如ResNet),并在现有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(...)
    

    请注意,您必须运行 编译 每次锁定或解锁这些层时。

    推荐文章