एक प्रशिक्षित केरस मॉडल लोड करें और प्रशिक्षण जारी रखें


95

मैं सोच रहा था कि क्या यह संभव है कि एक आंशिक रूप से प्रशिक्षित केरस मॉडल को बचाया जाए और फिर से मॉडल को लोड करने के बाद प्रशिक्षण जारी रखा जाए।

इसका कारण यह है कि मेरे पास भविष्य में अधिक प्रशिक्षण डेटा होगा और मैं पूरे मॉडल को फिर से प्राप्त नहीं करना चाहता।

मैं जिन कार्यों का उपयोग कर रहा हूं वे हैं:

#Partly train model
model.fit(first_training, first_classes, batch_size=32, nb_epoch=20)

#Save partly trained model
model.save('partly_trained.h5')

#Load partly trained model
from keras.models import load_model
model = load_model('partly_trained.h5')

#Continue training
model.fit(second_training, second_classes, batch_size=32, nb_epoch=20)

संपादित 1: पूरी तरह से काम कर रहे उदाहरण को जोड़ा

10 युगों के बाद पहले डेटासेट के साथ अंतिम युग का नुकसान 0.0748 और सटीकता 0.9863 होगी।

मॉडल को सहेजने, हटाने और पुनः लोड करने के बाद, दूसरे डेटासेट पर प्रशिक्षित मॉडल की हानि और सटीकता क्रमशः 0.1711 और 0.950% होगी।

क्या यह नए प्रशिक्षण डेटा या पूरी तरह से पुन: प्रशिक्षित मॉडल के कारण है?

"""
Model by: http://machinelearningmastery.com/
"""
# load (downloaded if needed) the MNIST dataset
import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from keras.models import load_model
numpy.random.seed(7)

def baseline_model():
    model = Sequential()
    model.add(Dense(num_pixels, input_dim=num_pixels, init='normal', activation='relu'))
    model.add(Dense(num_classes, init='normal', activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

if __name__ == '__main__':
    # load data
    (X_train, y_train), (X_test, y_test) = mnist.load_data()

    # flatten 28*28 images to a 784 vector for each image
    num_pixels = X_train.shape[1] * X_train.shape[2]
    X_train = X_train.reshape(X_train.shape[0], num_pixels).astype('float32')
    X_test = X_test.reshape(X_test.shape[0], num_pixels).astype('float32')
    # normalize inputs from 0-255 to 0-1
    X_train = X_train / 255
    X_test = X_test / 255
    # one hot encode outputs
    y_train = np_utils.to_categorical(y_train)
    y_test = np_utils.to_categorical(y_test)
    num_classes = y_test.shape[1]

    # build the model
    model = baseline_model()

    #Partly train model
    dataset1_x = X_train[:3000]
    dataset1_y = y_train[:3000]
    model.fit(dataset1_x, dataset1_y, nb_epoch=10, batch_size=200, verbose=2)

    # Final evaluation of the model
    scores = model.evaluate(X_test, y_test, verbose=0)
    print("Baseline Error: %.2f%%" % (100-scores[1]*100))

    #Save partly trained model
    model.save('partly_trained.h5')
    del model

    #Reload model
    model = load_model('partly_trained.h5')

    #Continue training
    dataset2_x = X_train[3000:]
    dataset2_y = y_train[3000:]
    model.fit(dataset2_x, dataset2_y, nb_epoch=10, batch_size=200, verbose=2)
    scores = model.evaluate(X_test, y_test, verbose=0)
    print("Baseline Error: %.2f%%" % (100-scores[1]*100))

3
क्या आपने इसका परीक्षण किया है? मैं काम नहीं करने के लिए कोई कारण नहीं देखता।
माज़

अब मैं जो देख रहा हूं वह यह है कि मॉडल को लोड करने के बाद मेरी सटीकता लगभग 10 प्रतिशत हो जाती है (केवल पहले युग में)। यदि पुनः लोड हो रहा है तो यह निश्चित रूप से नए प्रशिक्षण डेटा के कारण होता है। लेकिन मैं सिर्फ यह सुनिश्चित करना चाहता हूं कि वास्तव में ऐसा हो।
विल्मर वान ओमेरेन

6
क्या आप अपने मॉडल को सीधे model.save के साथ सहेज रहे हैं या आप एक मॉडल चेकपॉइंट ( keras.io/callbacks/#example-model-checkpoint ) का उपयोग कर रहे हैं ? यदि आप model.save का उपयोग कर रहे हैं, तो क्या ऐसा मौका होगा कि आप सबसे अच्छे (सबसे कम त्रुटि) के बजाय नवीनतम मॉडल (यानी अंतिम काल) को बचा रहे हैं? क्या आप वास्तविक कोड प्रदान कर सकते हैं?
माज़

मैं अपने नवीनतम मॉडल को सहेज रहा हूं, सबसे अच्छा नहीं (जब तक यह बात मुझे नहीं पता कि यह संभव था)। मैं कुछ कोड तैयार करूँगा
विल्मर वान ओमेरेन

3
तो क्या आप उसे पुनः लोड नहीं कर सकते और उसी ट्रेन डेटा पर प्रशिक्षण जारी रख सकते हैं? यह आपको आश्वस्त करना चाहिए कि यदि परिणाम तुलनीय होगा तो पुनः लोड करना ठीक है।
मार्सिन मोजेको

जवाबों:


36

वास्तव में - model.saveआपके मामले में प्रशिक्षण को फिर से शुरू करने के लिए आवश्यक सभी जानकारी को बचाता है। केवल एक चीज जो मॉडल को फिर से लोड करने से खराब हो सकती है वह है आपका आशावादी राज्य। यह जांचने के लिए - saveमॉडल को पुन: लोड करने और उसे प्रशिक्षण डेटा पर प्रशिक्षित करने का प्रयास करें।


1
@ मार्सीन: करैस का उपयोग करते समय save(), क्या यह मॉडल का सबसे अच्छा परिणाम (सबसे कम नुकसान) या मॉडल का अंतिम परिणाम (अंतिम अपडेट) बचाता है? धन्यवाद
सिंह लाई

4
आखिरी अपडेट। मॉडल चेकपॉइंट कॉलबैक सर्वश्रेष्ठ को बचाने के लिए है।
होली

2
@ क्या आप इस keras.io/callbacks/#modelcheckpoint का उल्लेख कर रहे हैं ? यह डिफ़ॉल्ट रूप से लगता है, यह अंतिम अपडेट बचाता है (सबसे अच्छा नहीं); यदि save_best_only=Trueस्पष्ट रूप से सेट किया गया हो तो सबसे अच्छा केवल एक ही बचा है।
flow2k

7

समस्या यह हो सकती है कि आप अपने ऑप्टिमाइज़र के लिए एक अलग ऑप्टिमाइज़र - या अलग-अलग तर्क का उपयोग करें। मैं सिर्फ एक कस्टम pretrained मॉडल के साथ एक ही मुद्दा था, का उपयोग कर

reduce_lr = ReduceLROnPlateau(monitor='loss', factor=lr_reduction_factor,
                              patience=patience, min_lr=min_lr, verbose=1)

प्रीट्रेनड मॉडल के लिए, जिससे मूल सीखने की दर 0.0003 से शुरू होती है और पूर्व-प्रशिक्षण के दौरान इसे घटाकर min_learning दर कर दिया जाता है, जो 0.000003 है

मैंने अभी उस लाइन को स्क्रिप्ट पर कॉपी किया है जो पूर्व-प्रशिक्षित मॉडल का उपयोग करता है और वास्तव में खराब सटीकता प्राप्त करता है। जब तक मैंने देखा कि प्रिटेंडेड मॉडल की अंतिम सीखने की दर न्यूनतम सीखने की दर थी, अर्थात 0.000003। और अगर मैं उस सीखने की दर के साथ शुरू करता हूं, तो मैं ठीक उसी तरह की सटीकता प्राप्त करता हूं जैसा कि प्रीट्रेन मॉडल के आउटपुट के रूप में शुरू होता है - जो समझ में आता है, जैसा कि सीखने की दर के साथ शुरू करना, जो कि प्रीट्रेन में उपयोग किए गए अंतिम सीखने की दर से 100 गुना बड़ा है। मॉडल जीडी के एक बड़े ओवरशूट के परिणामस्वरूप होगा और इसलिए भारी कमी में सुधार होगा।


5

उपर्युक्त अधिकांश उत्तर महत्वपूर्ण बिंदुओं को कवर करते हैं। यदि आप हाल के टेंसोरफ़्लो ( TF2.1या ऊपर) का उपयोग कर रहे हैं , तो निम्न उदाहरण आपकी सहायता करेगा। कोड का मॉडल भाग Tensorflow वेबसाइट से है।

import tensorflow as tf
from tensorflow import keras
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

def create_model():
  model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(512, activation=tf.nn.relu),  
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax)
    ])

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

# Create a basic model instance
model=create_model()
model.fit(x_train, y_train, epochs = 10, validation_data = (x_test,y_test),verbose=1)

कृपया मॉडल को * .tf प्रारूप में सहेजें। मेरे अनुभव से, यदि आपके पास कोई custom_loss परिभाषित है, तो * .h5 प्रारूप ऑप्टिमाइज़र की स्थिति को नहीं बचाएगा और इसलिए यदि आप उस मॉडल को फिर से अपनाना नहीं चाहते हैं जहाँ से हमने छोड़ा था।

# saving the model in tensorflow format
model.save('./MyModel_tf',save_format='tf')


# loading the saved model
loaded_model = tf.keras.models.load_model('./MyModel_tf')

# retraining the model
loaded_model.fit(x_train, y_train, epochs = 10, validation_data = (x_test,y_test),verbose=1)

यह दृष्टिकोण उस प्रशिक्षण को पुनः आरंभ करेगा जहां हमने मॉडल को सहेजने से पहले छोड़ा था। दूसरों के द्वारा उल्लेख किया है, अगर आप या सबसे अच्छा मॉडल के वजन को सहेजना चाहते आप मॉडल के वजन हर युग आप keras कॉलबैक समारोह (ModelCheckpoint) जैसे विकल्पों के साथ उपयोग करने की आवश्यकता सहेजना चाहते save_weights_only=True, save_freq='epoch'और save_best_only

अधिक जानकारी के लिए, कृपया यहां और दूसरा उदाहरण यहां देखें


1
अच्छा, यह बहुत आशाजनक लग रहा है - जानकारी के लिए धन्यवाद। इस उदाहरण में, यह मुझे ऐसा लगता है जैसे आप मॉडल को उसी डेटा पर पुनः प्रयोग कर रहे हैं जो प्रशिक्षण के लिए उपयोग किया गया था। यदि ऐसा है, तो मुझे लगता है कि सही दृष्टिकोण प्रशिक्षण डेटा के एक नए सबसेट को लोड करने के लिए होगा (इस प्रक्रिया के लिए पेश की जा रही नई जानकारी को प्रतिबिंबित करने के लिए)?
बिबज़्ज़ज़

1
@bibzzzz आपसे सहमत है। बहुत अच्छी टिप्पणी। मैं प्रदर्शन में सुधार करने के लिए उसी डेटा पर फिर से प्रदर्शित करना चाहता था। जिस्ट स्पष्ट रूप से प्रदर्शन में सुधार दिखाता है जहां मॉडल को बचाने से पहले इसे रोक दिया गया था। मैं अलग-अलग डेटा पर फिर से विचार करने के लिए आपके साथ पूरी तरह से सहमत हूं और बाद में इसका प्रयास करूंगा। धन्यवाद!
विष्णुवर्धन जनपति

उत्कृष्ट - आपने इसे बहुत अच्छी तरह से प्रदर्शित किया है, धन्यवाद।
बिबज़्ज़ज़

2

ध्यान दें कि केरस कभी-कभी लोड किए गए मॉडल के साथ समस्या होती है, जैसे कि यहां । यह उन मामलों की व्याख्या कर सकता है जिनमें आप एक ही प्रशिक्षित सटीकता से शुरू नहीं करते हैं।


1

उपरोक्त सभी मदद करता है, आपको एलआर के रूप में उसी सीखने की दर () से फिर से शुरू करना होगा जब मॉडल और वजन बचाए गए थे। इसे सीधे ऑप्टिमाइज़र पर सेट करें।

ध्यान दें कि वहां से सुधार की गारंटी नहीं है, क्योंकि मॉडल स्थानीय न्यूनतम तक पहुंच सकता है, जो वैश्विक हो सकता है। किसी अन्य स्थानीय न्यूनतम की खोज करने के लिए एक मॉडल को फिर से शुरू करने का कोई मतलब नहीं है, जब तक कि आप एक नियंत्रित फैशन में सीखने की दर बढ़ाने का इरादा नहीं करते हैं और मॉडल को संभवतः कम से कम बेहतर रूप से दूर नहीं करते हैं।


ऐसा क्यों है? क्या मैं पहले की तुलना में एक छोटे LR का उपयोग नहीं कर सकता हूँ?
lte__

वास्तव में, यदि आप अधिक डेटा प्राप्त करते हैं तो निरंतर प्रशिक्षण MAY आपको एक बेहतर मॉडल में ले जाता है। इसलिए एक अन्य स्थानीय न्यूनतम खोज करने के लिए एक मॉडल को फिर से शुरू करने का एक बिंदु है।
कोरी लेविंसन

0

आप कॉन्सेप्ट ड्रिफ्ट को भी मार सकते हैं, देखिए कि क्या आप एक मॉडल को रिटेन कर सकते हैं जब नई टिप्पणियां उपलब्ध हैं । वहाँ भी भयावह भूल की अवधारणा है जिस पर अकादमिक पत्रों का एक समूह चर्चा करता है। यहाँ भयावह भूल की MNIST अनुभवजन्य जांच के साथ एक है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.