Tải một mô hình Keras được đào tạo và tiếp tục đào tạo


98

Tôi đã tự hỏi liệu có thể lưu mô hình Keras đã được đào tạo một phần và tiếp tục đào tạo sau khi tải lại mô hình hay không.

Lý do cho điều này là tôi sẽ có nhiều dữ liệu đào tạo hơn trong tương lai và tôi không muốn đào tạo lại toàn bộ mô hình một lần nữa.

Các chức năng mà tôi đang sử dụng là:

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

Chỉnh sửa 1: đã thêm ví dụ hoạt động đầy đủ

Với tập dữ liệu đầu tiên sau 10 kỷ, mất mát của kỷ cuối sẽ là 0,0748 và độ chính xác 0,9863.

Sau khi lưu, xóa và tải lại mô hình, độ mất mát và độ chính xác của mô hình được đào tạo trên tập dữ liệu thứ hai sẽ tương ứng là 0,1711 và 0,9504.

Điều này gây ra bởi dữ liệu đào tạo mới hay do một mô hình được đào tạo lại hoàn toàn?

"""
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
Bạn đã thử nghiệm nó chưa? Tôi thấy không có lý do gì để điều đó không hoạt động.
maz

Những gì tôi thấy bây giờ là độ chính xác của tôi giảm xuống khoảng 10 phần trăm sau khi tải mô hình (chỉ trong kỷ nguyên đầu tiên). Nếu quá trình tải lại hoạt động, điều này tất nhiên là do dữ liệu đào tạo mới gây ra. Nhưng tôi chỉ muốn đảm bảo rằng điều này thực sự là như vậy.
Wilmar van Ommeren

7
Bạn đang lưu mô hình của mình trực tiếp với model.save hay bạn đang sử dụng điểm kiểm tra mô hình ( keras.io/callbacks/#example-model-checkpoints )? Nếu bạn đang sử dụng model.save, liệu bạn có thể đang lưu mô hình mới nhất (tức là kỷ nguyên trước) thay vì mô hình tốt nhất (lỗi thấp nhất) không? Bạn có thể cung cấp mã thực tế?
maz

Tôi đang lưu mô hình mới nhất của mình, không phải là mô hình tốt nhất (cho đến thời điểm này tôi không biết điều đó là có thể). Tôi sẽ chuẩn bị một số mã
Wilmar van Ommeren

3
Vì vậy, bạn không thể tải lại và tiếp tục đào tạo trên cùng một dữ liệu tàu? Điều này sẽ đảm bảo với bạn rằng việc tải lại là ok nếu kết quả có thể so sánh được.
Marcin Możejko

Câu trả lời:


36

Trên thực tế - model.savelưu tất cả thông tin cần thiết để bắt đầu lại đào tạo trong trường hợp của bạn. Điều duy nhất có thể bị hỏng khi tải lại mô hình là trạng thái trình tối ưu hóa của bạn. Để kiểm tra điều đó - hãy thử savetải lại mô hình và đào tạo nó trên dữ liệu đào tạo.


1
@Marcin: khi sử dụng keras save(), nó lưu kết quả tốt nhất (tổn thất thấp nhất) của mô hình hay kết quả cuối cùng (cập nhật cuối cùng) của mô hình? cảm ơn
Lion Lai

5
cập nhật cuối cùng. Gọi lại điểm kiểm tra mô hình là để lưu điểm tốt nhất.
Holi

2
@Khaj Bạn có đang đề cập đến keras.io/callbacks/#modelcheckpoint này không? Có vẻ như theo mặc định, nó lưu bản cập nhật cuối cùng (không phải bản tốt nhất); tốt nhất chỉ được lưu nếu save_best_only=Trueđược đặt rõ ràng.
flow2k

7

Vấn đề có thể là bạn sử dụng một trình tối ưu hóa khác - hoặc các đối số khác nhau cho trình tối ưu hóa của bạn. Tôi vừa gặp vấn đề tương tự với một mô hình tùy chỉnh trước, sử dụng

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

đối với mô hình đào tạo trước, theo đó tốc độ học ban đầu bắt đầu ở 0,0003 và trong quá trình đào tạo trước, nó được giảm xuống tỷ lệ min_learning, là 0,000003

Tôi vừa sao chép dòng đó sang tập lệnh sử dụng mô hình được đào tạo trước và có độ chính xác thực sự kém. Cho đến khi tôi nhận thấy rằng tốc độ học tập cuối cùng của mô hình đào tạo trước là tốc độ học tập tối thiểu, tức là 0,000003. Và nếu tôi bắt đầu với tốc độ học tập đó, tôi sẽ nhận được chính xác cùng độ chính xác để bắt đầu với kết quả đầu ra của mô hình được đào tạo trước - điều này có ý nghĩa, khi bắt đầu với tốc độ học tập lớn hơn 100 lần so với tốc độ học tập cuối cùng được sử dụng trong mô hình sẽ dẫn đến một lượng lớn GD quá mức và do đó độ chính xác giảm đi rất nhiều.


5

Hầu hết các câu trả lời trên đều bao hàm những điểm quan trọng. Nếu bạn đang sử dụng Tensorflow gần đây ( TF2.1hoặc cao hơn), thì ví dụ sau sẽ giúp bạn. Phần mô hình của mã là từ trang web 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)

Vui lòng lưu mô hình ở định dạng * .tf. Theo kinh nghiệm của tôi, nếu bạn đã xác định bất kỳ custom_loss nào, thì định dạng * .h5 sẽ không lưu trạng thái trình tối ưu hóa và do đó sẽ không phục vụ mục đích của bạn nếu bạn muốn đào tạo lại mô hình từ nơi chúng tôi đã rời đi.

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

Cách tiếp cận này sẽ bắt đầu lại quá trình đào tạo tại nơi chúng tôi đã rời khỏi trước khi lưu mô hình. Như đã đề cập bởi những người khác, nếu bạn muốn tiết kiệm trọng lượng của mô hình tốt nhất hoặc bạn muốn tiết kiệm trọng lượng của mô hình mọi thời đại bạn cần phải sử dụng keras callbacks function (ModelCheckpoint) với các tùy chọn như save_weights_only=True, save_freq='epoch', và save_best_only.

Để biết thêm chi tiết, vui lòng kiểm tra tại đây và một ví dụ khác ở đây .


1
tốt, điều này trông rất hứa hẹn - cảm ơn vì thông tin. trong ví dụ này, đối với tôi dường như bạn đang đào tạo lại mô hình trên cùng một dữ liệu đã được sử dụng để đào tạo. nếu vậy, tôi có nghĩ rằng cách tiếp cận đúng sẽ là tải một tập hợp con dữ liệu đào tạo mới để đào tạo lại (nhằm phản ánh thông tin mới đang được đưa vào quy trình)?
bibzzzz

1
@bibzzzz Đồng ý với bạn. Nhận xét rất tốt. Tôi muốn chứng minh việc đào tạo lại trên cùng một dữ liệu để cải thiện hiệu suất. Ý chính cho thấy rõ sự cải thiện về hiệu suất khi nó bị dừng trước khi lưu mô hình. Tôi hoàn toàn đồng ý với bạn để đào tạo lại trên các dữ liệu khác nhau và sẽ thử nó sau. Cảm ơn!
Vishnuvardhan Janapati

xuất sắc - bạn đã thể hiện điều này rất tốt, cảm ơn bạn.
bibzzzz

2

Lưu ý rằng Keras đôi khi gặp sự cố với các mô hình đã tải, như ở đây . Điều này có thể giải thích các trường hợp mà bạn không bắt đầu từ cùng một độ chính xác được đào tạo.


1

Tất cả những điều trên đều hữu ích, bạn phải tiếp tục từ cùng một tỷ lệ học tập () như LR khi mô hình và trọng số được lưu. Đặt nó trực tiếp trên trình tối ưu hóa.

Lưu ý rằng cải tiến từ đó không được đảm bảo, vì mô hình có thể đã đạt mức tối thiểu cục bộ, có thể là toàn cầu. Không có lý do gì để tiếp tục một mô hình để tìm kiếm một mức tối thiểu cục bộ khác, trừ khi bạn có ý định tăng tỷ lệ học tập theo cách có kiểm soát và đưa mô hình vào mức tối thiểu có thể tốt hơn không xa.


Tại sao vậy? Tôi không thể sử dụng LR nhỏ hơn trước đây?
lte__

Trên thực tế, việc tiếp tục đào tạo CÓ THỂ đưa bạn đến một mô hình tốt hơn nếu bạn nhận được nhiều dữ liệu hơn. Vì vậy, có một điểm để tiếp tục một mô hình để tìm kiếm một địa phương tối thiểu khác.
Corey Levinson

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.