0964 456 787 [email protected]

Đối với bài toán multi-class classification, model được sử dụng nhiều nhất là các model đã chiến thắng trong các cuộc thi imageNet.

Đối với mỗi model ví dụ như VGG19, ResetNet, EfficientNet người dùng thường sử dụng Fine-tuning hoặc Transfer Learning để áp dụng vào bài toán của mình.

Tuy nhiên với mỗi loại bài toán classification thì các model sẽ cho accuracy khác nhau. Có 1 kỹ thuật gọi là Stacking Ensemble dùng để xếp chồng các model này lại thành 1 model.

Ở đây chúng ta sẽ sử dụng 1 ví dụ đơn giản để thể hiện kỹ thuật Stacking Ensemble.

Thư viện scikit-learn cung cấp function make_blobs() giúp tạo ra các dữ liệu phân lớn đơn giản để áp dụng cho bài toán này. Hàm sẽ thực hiện tạo ra 1100 mẫu vối các biến X, y.

  1. # generate 2d classification dataset
  2. X, y = make_blobs(n_samples=1000, centers=3, n_features=2, cluster_std=2, random_state=2)

Thể hiện dữ liệu trên đồ thị 2D như sau:

  1. # scatter plot of blobs dataset
  2. from sklearn.datasets.samples_generator import make_blobs
  3. from matplotlib import pyplot
  4. from pandas import DataFrame
  5. # generate 2d classification dataset
  6. X, y = make_blobs(n_samples=1100, centers=3, n_features=2, cluster_std=2, random_state=2)
  7. # scatter plot, dots colored by class value
  8. df = DataFrame(dict(x=X[:,0], y=X[:,1], label=y))
  9. colors = {0:'red', 1:'blue', 2:'green'}
  10. fig, ax = pyplot.subplots()
  11. grouped = df.groupby('label')
  12. for key, group in grouped:
  13.     group.plot(ax=ax, kind='scatter', x='x', y='y', label=key, color=colors[key])
  14. pyplot.show()

Kết quả chạy được như sau:

Ở đây ta tạo 1100 mẫu. Sẽ phân chia ra thành 1000 mẫu để train và 100 mẫu để test (validate). Ở đây input sẽ là X và output là y. Output ở đây sẽ chuyển sang dạng categorical sử dụng hàm y = to_categorical(y)

  1. # generate 2d classification dataset
  2. X, y = make_blobs(n_samples=1100, centers=3, n_features=2, cluster_std=2, random_state=2)
  3. # one hot encode output variable
  4. y = to_categorical(y)
  5. # split into train and test
  6. n_train = 100
  7. trainX, testX = X[:n_train, :], X[n_train:, :]
  8. trainy, testy = y[:n_train], y[n_train:]
  9. print(trainX.shape, testX.shape)

Tạo 1 model đơn giản

Định nghĩa model. Vì đây chỉ là 1 ví dụ đơn giản, nên không sử dụng các model kinh điển như VGG, ResNet, DenseNet, …

  1. # define model
  2. model = Sequential()
  3. model.add(Dense(25, input_dim=2, activation='relu'))
  4. model.add(Dense(3, activation='softmax'))
  5. model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

Fix dữ liệu train và model với epochs = 50

  1. # fit model
  2. history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=500, verbose=0)

Sau khi hoàn thành train xác định độ chính xác của tập train và test:

  1. # evaluate the model
  2. _, train_acc = model.evaluate(trainX, trainy, verbose=0)
  3. _, test_acc = model.evaluate(testX, testy, verbose=0)
  4. print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))

Show kết quả lên đồ thị:

  1. # learning curves of model accuracy
  2. pyplot.plot(history.history['acc'], label='train')
  3. pyplot.plot(history.history['val_acc'], label='test')
  4. pyplot.legend()
  5. pyplot.show()

Một đoạn chương trình hoàn chỉnh như sau:

  1. # develop an mlp for blobs dataset
  2. from sklearn.datasets.samples_generator import make_blobs
  3. from keras.utils import to_categorical
  4. from keras.models import Sequential
  5. from keras.layers import Dense
  6. from matplotlib import pyplot
  7. # generate 2d classification dataset
  8. X, y = make_blobs(n_samples=1100, centers=3, n_features=2, cluster_std=2, random_state=2)
  9. # one hot encode output variable
  10. y = to_categorical(y)
  11. # split into train and test
  12. n_train = 100
  13. trainX, testX = X[:n_train, :], X[n_train:, :]
  14. trainy, testy = y[:n_train], y[n_train:]
  15. print(trainX.shape, testX.shape)
  16. # define model
  17. model = Sequential()
  18. model.add(Dense(25, input_dim=2, activation='relu'))
  19. model.add(Dense(3, activation='softmax'))
  20. model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
  21. # fit model
  22. history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=500, verbose=0)
  23. # evaluate the model
  24. _, train_acc = model.evaluate(trainX, trainy, verbose=0)
  25. _, test_acc = model.evaluate(testX, testy, verbose=0)
  26. print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
  27. # learning curves of model accuracy
  28. pyplot.plot(history.history['acc'], label='train')
  29. pyplot.plot(history.history['val_acc'], label='test')
  30. pyplot.legend()
  31. pyplot.show()

Sau khi chạy cho kết quả như sau:

  1. (100, 2) (1000, 2)
  2. Train: 0.850, Test: 0.809

Đồ thi so sánh accuracy của tập train và test như sau:

Tạo nhiều model và lưu trọng số của các model

Trong thực tế khi xây dựng nhiều model, sẽ có nhiều cách như ví dụ sau:

  • Cùng 1 dạng model, fit những tập dữ liệu khác nhau (có thể sử dụng k-fold cross-validation – sẽ đề cập ở các post sau)
  • Cùng tập dữ liệu như nhau, fit vào các model khác nhau
  • Các model khác nhau, fit những tập dữ liệu khác nhau

Vì ở đây chỉ là 1 ví dụ đơn giản trong việc triển khai kỹ thuật stacking ensemble. Nên ở phần này chỉ đơn giản vẫn sử dụng chung tập trainX và trainy để fit vào cho 1 dạng model chung. Sau khi train hoàn thành 1 model sẽ lưu lại trọng số của model đó.

Bước đầu tiên ta tạo 1 hàm fit_model đề tạo 1 model mới đơn giản và fit dữ liệu vào.

  1. # fit model on dataset
  2. def fit_model(trainX, trainy):
  3. 	# define model
  4. 	model = Sequential()
  5. 	model.add(Dense(25, input_dim=2, activation='relu'))
  6. 	model.add(Dense(3, activation='softmax'))
  7. 	model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
  8. 	# fit model
  9. 	model.fit(trainX, trainy, epochs=500, verbose=0)
  10. 	return model

Tạo 1 đường dẫn chứa file lưu trọng số model

  1. # create directory for models
  2. makedirs('models')

Ở đây để đơn giản chúng ta sẽ tạo 5 model giống nhau và fit dữ liệu giống nhau

  1. # fit and save models
  2. n_members = 5
  3. for i in range(n_members):
  4. 	# fit model
  5. 	model = fit_model(trainX, trainy)
  6. 	# save model
  7. 	filename = 'models/model_' + str(i + 1) + '.h5'
  8. 	model.save(filename)
  9. 	print('>Saved %s' % filename)

Chương trình hoàn chỉnh như sau:

  1. # example of saving sub-models for later use in a stacking ensemble
  2. from sklearn.datasets.samples_generator import make_blobs
  3. from keras.utils import to_categorical
  4. from keras.models import Sequential
  5. from keras.layers import Dense
  6. from matplotlib import pyplot
  7. from os import makedirs
  8.  
  9. # fit model on dataset
  10. def fit_model(trainX, trainy):
  11. 	# define model
  12. 	model = Sequential()
  13. 	model.add(Dense(25, input_dim=2, activation='relu'))
  14. 	model.add(Dense(3, activation='softmax'))
  15. 	model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
  16. 	# fit model
  17. 	model.fit(trainX, trainy, epochs=500, verbose=0)
  18. 	return model
  19.  
  20. # generate 2d classification dataset
  21. X, y = make_blobs(n_samples=1100, centers=3, n_features=2, cluster_std=2, random_state=2)
  22. # one hot encode output variable
  23. y = to_categorical(y)
  24. # split into train and test
  25. n_train = 100
  26. trainX, testX = X[:n_train, :], X[n_train:, :]
  27. trainy, testy = y[:n_train], y[n_train:]
  28. print(trainX.shape, testX.shape)
  29. # create directory for models
  30. makedirs('models')
  31. # fit and save models
  32. n_members = 5
  33. for i in range(n_members):
  34. 	# fit model
  35. 	model = fit_model(trainX, trainy)
  36. 	# save model
  37. 	filename = 'models/model_' + str(i + 1) + '.h5'
  38. 	model.save(filename)
  39. 	print('>Saved %s' % filename)

Kết quả sau kho chạy sẽ tạo ra 5 file chứ weight của các model.

  1. (100, 2) (1000, 2)
  2. >Saved models/model_1.h5
  3. >Saved models/model_2.h5
  4. >Saved models/model_3.h5
  5. >Saved models/model_4.h5
  6. >Saved models/model_5.h5

(to be continue)