Keras: Memilih Fungsi Loss
Deep learning neural network di-train dengan menggunakan algoritma stochastic gradient descent optimization.
Sebagai bagian dari optimisasi algoritma, kesalahan kondisi model harus diperkirakan berulang kali. Ini membutuhkan pilihan fungsi kesalahan, secara konvensional disebut fungsi loss, yang dapat digunakan untuk memperkirakan loss model sehingga weight dapat diperbarui untuk mengurangi loss pada evaluasi selanjutnya.
Neural network model mempelajari pemetaan dari input ke output dari contoh dan pilihan fungsi loss harus sesuai dengan framing masalah pemodelan prediktif spesifik, seperti klasifikasi atau regresi. Lebih lanjut, konfigurasi lapisan keluaran juga harus sesuai untuk fungsi loss yang dipilih.
Dalam tutorial ini, kita akan mempelajari cara memilih fungsi loss untuk deep learning neural network untuk masalah pemodelan prediktif yang diberikan.
Sesudah menyelesaikan tutorial ini, anda akan mengetahui:
- Bagaimana mengkonfigurasi model untuk mean squared error dan varian-nya untuk regression problems.
- Bagaimana mengkonfigurasi model untuk cross-entropy dan fungsi hinge loss untuk binary classification.
- Bagaimana mengkonfigurasi model untuk cross-entropy dan fungsi KL divergence loss untuk multi-class classification.
Tutorial Overview
Tutorial ini di bagi dalam tiga bagian, yaitu:
Regression Loss Functions Mean Squared Error Loss Mean Squared Logarithmic Error Loss Mean Absolute Error Loss Binary Classification Loss Functions Binary Cross-Entropy Hinge Loss Squared Hinge Loss Multi-Class Classification Loss Functions Multi-Class Cross-Entropy Loss Sparse Multiclass Cross-Entropy Loss Kullback Leibler Divergence Loss
Kita akan fokus pada bagaimana memilih dan mengimplementasikan berbagai fungsi loss. Untuk teori lebih lanjut tentang fungsi loss, bisa lihat tulisan:
Regression Loss Function
Masalah pemodelan prediktif regresi melibatkan memprediksi kuantitas yang bernilai nyata. Pada bagian ini, kita akan menyelidiki fungsi loss yang sesuai untuk masalah pemodelan prediksi regresi.
Sebagai konteks untuk investigasi ini, kami akan menggunakan generator masalah regresi standar yang disediakan oleh perpustakaan scikit-learn di fungsi make_regress(). Fungsi ini akan menghasilkan contoh-contoh dari masalah regresi sederhana dengan sejumlah variabel input, noise statistik, dan properti lainnya.
Kita akan menggunakan fungsi ini untuk mendefinisikan masalah yang memiliki 20 fitur input; 10 fitur bermakna dan 10 tidak relevan. Sebanyak 1.000 contoh akan dihasilkan secara acak. Generator angka pseudorandom akan diperbaiki untuk memastikan bahwa kami mendapatkan 1.000 contoh yang sama setiap kali kode dijalankan.
# generate regression dataset X, y = make_regression(n_samples=1000, n_features=20, noise=0.1, random_state=1)
Neural network umumnya berkinerja lebih baik ketika variabel input dan output bernilai real yang di skalakan (scaled) pada kisaran yang masuk akal. Untuk masalah ini, masing-masing variabel input dan variabel target memiliki distribusi Gaussian; oleh karena itu, standarisasi data dalam hal ini dibutuhkan.
Kita dapat mencapai ini menggunakan kelas transformator StandardScaler juga dari library scikit-learn. Pada masalah yang sebenarnya, kita akan menyiapkan scaler pada set data training dan menerapkannya pada set train dan test, tetapi untuk menyederhanakan, kita akan menskalakan semua data bersama sebelum dipecah menjadi set train dan test.
# standardize dataset X = StandardScaler().fit_transform(X) y = StandardScaler().fit_transform(y.reshape(len(y),1))[:,0]
Setelah di skalakan, data dibagi rata menjadi set train dan test.
# split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :]
Model Multilayer Perceptron (MLP) yang kecil akan didefinisikan untuk mengatasi masalah ini dan memberikan dasar untuk mengeksplorasi berbagai fungsi kerugian.
Model akan mengharapkan 20 fitur sebagai input sebagaimana didefinisikan oleh masalah. Model akan memiliki satu lapisan tersembunyi dengan 25 node dan akan menggunakan fungsi rectified linear activation (ReLU). Lapisan output akan memiliki 1 simpul, mengingat satu nilai riil yang akan diprediksi, dan akan menggunakan fungsi aktivasi linier.
# define model model = Sequential() model.add(Dense(25, input_dim=20, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(1, activation='linear'))
Model ini akan cocok dengan stochastic gradient descent dengan learning rate 0,01 dan momentum 0,9, keduanya nilai default yang cukup baik.
Training akan dilakukan sebanyak 100 epoch dan set test akan dievaluasi pada akhir setiap epoch sehingga kita dapat merencanakan kurva learning di akhir run.
opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='...', optimizer=opt) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=100, verbose=0)
Sekarang kita memiliki dasar masalah dan model, kita dapat mengevaluasi tiga fungsi loss umum yang sesuai untuk masalah pemodelan prediksi regresi.
Meskipun MLP digunakan dalam contoh-contoh ini, fungsi loss yang sama dapat digunakan ketika melatih model CNN dan RNN untuk regresi.
Mean Squared Error Loss
Mean Squared Error, atau MSE, loss adalah default loss yang digunakan untuk masalah regresi.
Secara matematis, ini adalah fungsi loss yang disukai di bawah inference framework of maximum likelihood jika distribusi variabel target adalah Gaussian. Ini adalah fungsi loss yang harus dievaluasi terlebih dahulu dan hanya diubah jika anda memiliki alasan yang bagus.
Mean squared error dihitung sebagai rata-rata perbedaan kuadrat antara nilai yang diprediksi dan yang sebenarnya. Hasilnya selalu positif terlepas dari tanda nilai yang diprediksi dan aktual dan nilai sempurna adalah 0,0. Kuadrat berarti bahwa kesalahan yang lebih besar menghasilkan lebih banyak kesalahan daripada kesalahan yang lebih kecil, yang berarti bahwa model akan dihukum karena membuat kesalahan yang lebih besar.
Fungsi mean squared error loss dapat digunakan dalam Keras dengan menuliskan ‘mse‘ atau ‘mean_squared_error‘ sebagai fungsi loss saat menyusun model.
model.compile(loss='mean_squared_error')
Disarankan bahwa layer output memiliki satu simpul untuk variabel target dan fungsi aktivasi linier digunakan.
model.add(Dense(1, activation='linear'))
Contoh lengkap menunjukkan MLP pada masalah regresi yang dijelaskan tercantum di bawah ini.
# mlp for regression with mse loss function from sklearn.datasets import make_regression from sklearn.preprocessing import StandardScaler from keras.models import Sequential from keras.layers import Dense from keras.optimizers import SGD from matplotlib import pyplot # generate regression dataset X, y = make_regression(n_samples=1000, n_features=20, noise=0.1, random_state=1) # standardize dataset X = StandardScaler().fit_transform(X) y = StandardScaler().fit_transform(y.reshape(len(y),1))[:,0] # split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # define model model = Sequential() model.add(Dense(25, input_dim=20, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(1, activation='linear')) opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='mean_squared_error', optimizer=opt) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=100, verbose=0) # evaluate the model train_mse = model.evaluate(trainX, trainy, verbose=0) test_mse = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_mse, test_mse)) # plot loss during training pyplot.title('Loss / Mean Squared Error') pyplot.plot(history.history['loss'], label='train') pyplot.plot(history.history['val_loss'], label='test') pyplot.legend() pyplot.show()
Menjalankan contoh pertama mem-print kesalahan kuadrat rata-rata model pada train dan test dataset.
Mengingat sifat stokastik dari algoritma training, Basil spesifik dapat bervariasi. Coba jalankan contoh beberapa kali.
Dalam kasus ini, kita dapat melihat bahwa model berusaha mencapai nol kesalahan, setidaknya sampai tiga tempat desimal.
Train: 0.000, Test: 0.001
Plot garis juga dibuat menunjukkan mean squared error loss selama periode pelatihan untuk set train (biru) dan test (oranye).
Kita dapat melihat bahwa model terkonvergensi dengan cukup cepat dan baik kinerja train dan test tetap setara. Perilaku kinerja dan konvergensi model menunjukkan bahwa mean squared error cocok untuk neural network yang mempelajari masalah ini.
Mean Squared Logarithmic Error Loss
Mungkin ada masalah regresi di mana nilai target memiliki penyebaran nilai dan ketika memprediksi nilai besar, kita mungkin tidak ingin menghukum model sebanyak kesalahan kuadrat rata-rata.
Sebagai gantinya, kita pertama-tama dapat menghitung nilai log dari masing-masing nilai yang diprediksi, lalu menghitung rata-rata kesalahan kuadrat. Ini disebut Mean Squared Logarithmic Error loss, atau disingkat MSLE.
Ini memiliki efek membuat santai efek punishing saat ada perbedaan besar dalam nilai prediksi yang besar.
Sebagai ukuran loss, mungkin lebih tepat ketika model memprediksi unscaled quantities secara langsung. Namun demikian, kita dapat menunjukkan fungsi loss ini menggunakan masalah regresi sederhana.
Model ini dapat diperbarui untuk menggunakan fungsi loss ‘mean_squared_logarithmic_error‘ dan mempertahankan konfigurasi yang sama untuk layer output. Kita juga akan melacak mean squared error sebagai metrik saat memasang model sehingga kita dapat menggunakannya sebagai ukuran kinerja dan plot kurva pembelajaran.
model.compile(loss='mean_squared_logarithmic_error', optimizer=opt, metrics=['mse'])
Contoh lengkap menggunakan fungsi loss MSLE tercantum di bawah ini.
# mlp for regression with msle loss function from sklearn.datasets import make_regression from sklearn.preprocessing import StandardScaler from keras.models import Sequential from keras.layers import Dense from keras.optimizers import SGD from matplotlib import pyplot # generate regression dataset X, y = make_regression(n_samples=1000, n_features=20, noise=0.1, random_state=1) # standardize dataset X = StandardScaler().fit_transform(X) y = StandardScaler().fit_transform(y.reshape(len(y),1))[:,0] # split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # define model model = Sequential() model.add(Dense(25, input_dim=20, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(1, activation='linear')) opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='mean_squared_logarithmic_error', optimizer=opt, metrics=['mse']) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=100, verbose=0) # evaluate the model _, train_mse = model.evaluate(trainX, trainy, verbose=0) _, test_mse = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_mse, test_mse)) # plot loss during training pyplot.subplot(211) pyplot.title('Loss') pyplot.plot(history.history['loss'], label='train') pyplot.plot(history.history['val_loss'], label='test') pyplot.legend() # plot mse during training pyplot.subplot(212) pyplot.title('Mean Squared Error') pyplot.plot(history.history['mean_squared_error'], label='train') pyplot.plot(history.history['val_mean_squared_error'], label='test') pyplot.legend() pyplot.show()
Menjalankan contoh pertama mem-print mean squared error untuk model pada datset train dan test.
Mengingat sifat stokastik dari algoritma training, hasil spesifik anda dapat bervariasi. Coba jalankan contoh tersebut beberapa kali.
Dalam hal ini, kita dapat melihat bahwa model tersebut menghasilkan MSE yang sedikit lebih buruk pada datset training dan testing. Ini mungkin tidak cocok untuk masalah ini karena distribusi variabel target adalah standar Gaussian.
Train: 0.165, Test: 0.184
Plot garis juga dibuat menunjukkan mean squared logarithmic error losst selama periode training untuk set train (biru) dan test (oranye) (atas), dan plot yang sama untuk mean squared error (bawah).
Kita dapat melihat bahwa algoritma MSLE konvergen lebih dari a100 epoch; tampaknya MSE mungkin menunjukkan tanda-tanda overfitting dari masalah yang ada, jatuh secara cepat cepat dan mulai naik pada epoch 20 dan seterusnya.
Mean Absolute Error Loss
Pada beberapa masalah regresi, distribusi variabel target mungkin sebagian besar Gaussian, tetapi mungkin memiliki outlier, mis. nilai besar atau kecil jauh dari nilai rata-rata.
The Mean Absolute Error loss, atau MAE, adalah fungsi loss yang sesuai dalam kasus ini karena itu lebih kuat untuk outlier. Ini dihitung sebagai rata-rata perbedaan absolut antara nilai aktual dan prediksi.
Model dapat diperbarui untuk menggunakan fungsi loss ‘mean_absolute_error‘ dan mempertahankan konfigurasi yang sama untuk layer output.
model.compile(loss='mean_absolute_error', optimizer=opt, metrics=['mse'])
Contoh lengkap menggunakan mean absolute error sebagai fungsi loss pada masalah test regresi terlampir di bawah ini.
# mlp for regression with mae loss function from sklearn.datasets import make_regression from sklearn.preprocessing import StandardScaler from keras.models import Sequential from keras.layers import Dense from keras.optimizers import SGD from matplotlib import pyplot # generate regression dataset X, y = make_regression(n_samples=1000, n_features=20, noise=0.1, random_state=1) # standardize dataset X = StandardScaler().fit_transform(X) y = StandardScaler().fit_transform(y.reshape(len(y),1))[:,0] # split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # define model model = Sequential() model.add(Dense(25, input_dim=20, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(1, activation='linear')) opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='mean_absolute_error', optimizer=opt, metrics=['mse']) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=100, verbose=0) # evaluate the model _, train_mse = model.evaluate(trainX, trainy, verbose=0) _, test_mse = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_mse, test_mse)) # plot loss during training pyplot.subplot(211) pyplot.title('Loss') pyplot.plot(history.history['loss'], label='train') pyplot.plot(history.history['val_loss'], label='test') pyplot.legend() # plot mse during training pyplot.subplot(212) pyplot.title('Mean Squared Error') pyplot.plot(history.history['mean_squared_error'], label='train') pyplot.plot(history.history['val_mean_squared_error'], label='test') pyplot.legend() pyplot.show()
Menjalankan contoh pertama mem-print mean squared error untuk model dataset train dan test.
Mengingat sifat stokastik dari algoritma training, hasil spesifik anda dapat bervariasi. Coba jalankan contoh beberapa kali.
Dalam kasus ini, kita dapat melihat bahwa model learn masalah, mencapai kesalahan mendekati nol, setidaknya ke tiga tempat desimal.
Train: 0.002, Test: 0.002
Plot garis juga dibuat yang menunjukkan mean absolute error loss selama periode pelatihan untuk set train (biru) dan test (oranye) (atas), dan plot serupa untuk mean squared error (bawah).
Dalam hal ini, kita dapat melihat bahwa MAE memang konvergen akan tetapi pencapaiannya bergelombang, meskipun dinamika MSE tidak tampak sangat terpengaruh. Kita tahu bahwa variabel target adalah Gaussian standar tanpa outlier besar, sehingga MAE tidak cocok untuk kasus ini.
Mungkin lebih tepat untuk masalah ini jika kita tidak menskalakan variabel target terlebih dahulu.
Binary Classification Loss Function
Klasifikasi biner adalah masalah-masalah pemodelan prediktif di mana contoh diberikan satu dari dua label.
Masalahnya sering di lihat sebagai memprediksi nilai 0 atau 1 untuk kelas pertama atau kedua dan sering diimplementasikan sebagai memprediksi probabilitas milik nilai kelas 1.
Pada bagian ini, kami akan menyelidiki fungsi kerugian yang sesuai untuk masalah pemodelan prediktif klasifikasi biner.
Kami akan menghasilkan contoh dari masalah test lingkaran di scikit-belajar sebagai basis untuk penelitian ini. Masalah lingkaran melibatkan sampel yang diambil dari dua lingkaran konsentris pada bidang dua dimensi, di mana titik pada lingkaran luar milik kelas 0 dan titik untuk lingkaran dalam milik kelas 1. Noise statistik ditambahkan ke sampel untuk menambah ambiguitas dan membuat masalahnya lebih sulit untuk dipelajari.
Kami akan men-generate 1.000 contoh dan menambahkan 10% noise statistik. Generator nomor pseudorandom akan di-seed dengan nilai yang sama untuk memastikan bahwa kami selalu mendapatkan 1.000 contoh yang sama.
# generate circles X, y = make_circles(n_samples=1000, noise=0.1, random_state=1)
Kita dapat membuat scatter plot dataset untuk mendapatkan gambaran tentang masalah yang kita modelkan. Contoh lengkapnya tercantum di bawah ini.
# scatter plot of the circles dataset with points colored by class from sklearn.datasets import make_circles from numpy import where from matplotlib import pyplot # generate circles X, y = make_circles(n_samples=1000, noise=0.1, random_state=1) # select indices of points with each class label for i in range(2): samples_ix = where(y == i) pyplot.scatter(X[samples_ix, 0], X[samples_ix, 1], label=str(i)) pyplot.legend() pyplot.show()
Menjalankan contoh menciptakan scatter plot contoh, di mana variabel input menentukan lokasi titik dan nilai kelas mendefinisikan warna, dengan kelas 0 biru dan oranye kelas 1.
Poin sudah diskalakan dengan cukup sekitar 0, hampir di [-1,1]. Kita tidak akan mengubah skala mereka dalam hal ini.
Dataset akan di split sama untuk train dan test set.
# split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:]
Model MLP sederhana dapat didefinisikan untuk mengatasi masalah ini yang mengharapkan dua input untuk dua fitur dalam dataset, lapisan tersembunyi dengan 50 node, fungsi aktivasi linear yang diperbaiki dan lapisan output yang perlu dikonfigurasi untuk pilihan fungsi loss.
# define model model = Sequential() model.add(Dense(50, input_dim=2, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(1, activation='...'))
Model ini akan cocok menggunakan stochastic gradient descent dengan tingkat pembelajaran default yang masuk akal 0,01 dan momentum 0,9.
opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='...', optimizer=opt, metrics=['accuracy'])
Kami akan mencocokkan model untuk 200 training epoch dan mengevaluasi kinerja model terhadap loss dan akurasi pada akhir setiap epoch sehingga kami dapat mem-plot kurva pembelajaran.
# fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=200, verbose=0)
Sekarang kita memiliki dasar masalah dan model, kita dapat melihat mengevaluasi tiga fungsi loss umum yang sesuai untuk masalah pemodelan prediktif klasifikasi biner.
Meskipun MLP digunakan dalam contoh-contoh ini, fungsi loss yang sama dapat digunakan ketika melatih model CNN dan RNN untuk klasifikasi biner.
Binary Cross-Entropy Loss
Cross-entropy adalah fungsi loss default yang digunakan untuk masalah klasifikasi biner.
Ini dimaksudkan untuk digunakan dengan klasifikasi biner di mana nilai target berada di set {0, 1}.
Secara matematis, ini adalah fungsi loss yang lebih disukai di bawah inference framework of maximum likelihood. Ini adalah fungsi loss yang harus dievaluasi terlebih dahulu dan hanya diubah jika anda memiliki alasan yang bagus.
Cross-entropy akan menghitung skor yang merangkum perbedaan rata-rata antara distribusi probabilitas aktual dan prediksi untuk kelas prediksi 1. Skor tersebut diminimalkan dan nilai cross-entropy yang baik adalah 0.
Cross-entropy dapat ditentukan sebagai fungsi loss di Keras dengan menetapkan ‘binary_crossentropy‘ saat menyusun model.
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
Fungsi ini mensyaratkan bahwa lapisan output dikonfigurasikan dengan satu simpul dan aktivasi ‘sigmoid in untuk memprediksi probabilitas untuk kelas 1.
model.add(Dense(1, activation='sigmoid'))
Contoh lengkap dari MLP dengan kehilangan lintas-entropi untuk masalah klasifikasi biner dua lingkaran tercantum di bawah ini.
# mlp for the circles problem with cross entropy loss from sklearn.datasets import make_circles from keras.models import Sequential from keras.layers import Dense from keras.optimizers import SGD from matplotlib import pyplot # generate 2d classification dataset X, y = make_circles(n_samples=1000, noise=0.1, random_state=1) # split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # define model model = Sequential() model.add(Dense(50, input_dim=2, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(1, activation='sigmoid')) opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy']) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=200, verbose=0) # evaluate the model _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_acc, test_acc)) # plot loss during training pyplot.subplot(211) pyplot.title('Loss') pyplot.plot(history.history['loss'], label='train') pyplot.plot(history.history['val_loss'], label='test') pyplot.legend() # plot accuracy during training pyplot.subplot(212) pyplot.title('Accuracy') pyplot.plot(history.history['acc'], label='train') pyplot.plot(history.history['val_acc'], label='test') pyplot.legend() pyplot.show()
Menjalankan contoh untuk mem-print akurasi klasifikasi untuk model pada dataset train dan test.
Mengingat sifat stokastik dari algoritma training, hasil spesifik anda dapat bervariasi. Coba jalankan contoh beberapa kali.
Dalam hal ini, kita dapat melihat bahwa model bisa learn masalah dengan cukup baik, mencapai akurasi sekitar 83% pada dataset train dan sekitar 85% pada dataset test. Skor cukup dekat, menunjukkan bahwa model yang di peroleh mungkin tidak over atau underfit.
Train: 0.836, Test: 0.852
Gambar juga dibuat menunjukkan dua plot garis, bagian atas dengan cross-entropy loss over epochs untuk dataset train (biru) dan test (oranye), dan plot bawah menunjukkan classification accuracy over epochs.
Plot menunjukkan bahwa proses trainig konvergsi dengan baik. Plot untuk loss baik, mengingat sifat kesalahan yang kontinyu antara distribusi probabilitas, sedangkan plot garis untuk akurasi menunjukkan adanya tonjolan, memberikan contoh dataset train dan test pada akhirnya hanya dapat diprediksi sebagai benar atau salah, memberikan umpan balik yang kurang terperinci pada kinerja.
Hinge Loss
Alternatif untuk cross-entropy untuk masalah klasifikasi biner adalah fungsi hinge loss, terutama dikembangkan untuk digunakan dengan model Support Vector Machine (SVM).
Ini dimaksudkan untuk digunakan dengan klasifikasi biner di mana nilai target berada di set {-1, 1}.
Fungsi kehilangan engsel mendorong contoh untuk memiliki tanda yang benar, menetapkan lebih banyak kesalahan ketika ada perbedaan dalam tanda antara nilai kelas aktual dan prediksi.
Laporan kinerja dengan hinge loss beragam, kadang-kadang menghasilkan kinerja yang lebih baik daripada cross-entropy pada masalah klasifikasi biner.
Pertama, variabel target harus dimodifikasi untuk memiliki nilai dalam set {-1, 1}.
# change y from {0,1} to {-1,1} y[where(y == 0)] = -1
Fungsi hinge loss dapat diset ‘hinge‘ dalam fungsi compile.
model.compile(loss='hinge', optimizer=opt, metrics=['accuracy'])
Akhirnya, lapisan output dari jaringan harus dikonfigurasi untuk memiliki satu simpul dengan fungsi aktivasi hyperbolic tangent yang mampu menghasilkan nilai tunggal dalam kisaran [-1, 1].
model.add(Dense(1, activation='tanh'))
Contoh lengkap MLP dengan fungsi hinge loss untuk two circles binary classification problem tercantum di bawah ini.
# mlp for the circles problem with hinge loss from sklearn.datasets import make_circles from keras.models import Sequential from keras.layers import Dense from keras.optimizers import SGD from matplotlib import pyplot from numpy import where # generate 2d classification dataset X, y = make_circles(n_samples=1000, noise=0.1, random_state=1) # change y from {0,1} to {-1,1} y[where(y == 0)] = -1 # split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # define model model = Sequential() model.add(Dense(50, input_dim=2, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(1, activation='tanh')) opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='hinge', optimizer=opt, metrics=['accuracy']) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=200, verbose=0) # evaluate the model _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_acc, test_acc)) # plot loss during training pyplot.subplot(211) pyplot.title('Loss') pyplot.plot(history.history['loss'], label='train') pyplot.plot(history.history['val_loss'], label='test') pyplot.legend() # plot accuracy during training pyplot.subplot(212) pyplot.title('Accuracy') pyplot.plot(history.history['acc'], label='train') pyplot.plot(history.history['val_acc'], label='test') pyplot.legend() pyplot.show()
Menjalankan contoh pertama-tama mem-print classification accuracy untuk model pada dataset train dan test.
Mengingat sifat stokastik dari algoritma training, hasil spesifik anda dapat bervariasi. Coba jalankan contoh beberapa kali.
Dalam hal ini, kita dapat melihat kinerja yang sedikit lebih buruk daripada menggunakan cross-entropy, dengan konfigurasi model yang dipilih dengan akurasi kurang dari 80% pada dataset train dan test.
Train: 0.792, Test: 0.740
A figure is also created showing two line plots, the top with the hinge loss over epochs for the train (blue) and test (orange) dataset, and the bottom plot showing classification accuracy over epochs.
Plot hinge loss menunjukkan bahwa model telah konvergen dan memiliki loss yang wajar pada kedua dataset. Alur akurasi klasifikasi juga menunjukkan tanda-tanda konvergensi, meskipun pada tingkat kinerja yang lebih rendah daripada yang diinginkan pada masalah ini.
Squared Hinge Loss
Fungsi hinge loss memiliki banyak pengembangan, seringkali menjadi subjek investigasi dengan model SVM.
Pengembangan yang populer disebut squared hinge loss yang hanya menghitung kuadrat dari score hinge loss. Ini memiliki efek menghaluskan permukaan fungsi kesalahan dan membuatnya lebih mudah untuk dikerjakan secara numerik.
Jika menggunakan hinge loss memang menghasilkan kinerja yang lebih baik pada masalah klasifikasi biner yang diberikan, kemungkinan bahwa squared hinge loss mungkin sesuai.
Seperti halnya menggunakan fungsi hinge loss, variabel target harus dimodifikasi untuk memiliki nilai dalam set {-1, 1}.
# change y from {0,1} to {-1,1} y[where(y == 0)] = -1
Squared hinge loss dapat ditentukan sebagai ‘squared_hinge‘ dalam fungsi compile() saat mendefinisikan model.
model.compile(loss='squared_hinge', optimizer=opt, metrics=['accuracy'])
Dan akhirnya, lapisan output harus menggunakan node tunggal dengan fungsi aktivasi tangen hiperbolik yang mampu menghasilkan nilai kontinu dalam kisaran [-1, 1].
model.add(Dense(1, activation='tanh'))
Contoh lengkap dari MLP dengan fungsi squared hinge loss pada masalah klasifikasi biner dua lingkaran tercantum di bawah ini.
# mlp for the circles problem with squared hinge loss from sklearn.datasets import make_circles from keras.models import Sequential from keras.layers import Dense from keras.optimizers import SGD from matplotlib import pyplot from numpy import where # generate 2d classification dataset X, y = make_circles(n_samples=1000, noise=0.1, random_state=1) # change y from {0,1} to {-1,1} y[where(y == 0)] = -1 # split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # define model model = Sequential() model.add(Dense(50, input_dim=2, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(1, activation='tanh')) opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='squared_hinge', optimizer=opt, metrics=['accuracy']) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=200, verbose=0) # evaluate the model _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_acc, test_acc)) # plot loss during training pyplot.subplot(211) pyplot.title('Loss') pyplot.plot(history.history['loss'], label='train') pyplot.plot(history.history['val_loss'], label='test') pyplot.legend() # plot accuracy during training pyplot.subplot(212) pyplot.title('Accuracy') pyplot.plot(history.history['acc'], label='train') pyplot.plot(history.history['val_acc'], label='test') pyplot.legend() pyplot.show()
Menjalankan contoh pertama-tama memprint keakuratan klasifikasi untuk model pada dataset train dan test.
Mengingat sifat stokastik dari algoritma pelatihan, hasil spesifik anda dapat bervariasi. Coba jalankan contoh beberapa kali.
Dalam kasus ini, kita dapat melihat bahwa untuk masalah ini dan konfigurasi model yang dipilih, hinge squared loss mungkin tidak sesuai, sehingga akurasi klasifikasi kurang dari 70% pada dataset train dan test.
Train: 0.682, Test: 0.646
Gambar juga dibuat menunjukkan dua plot garis, bagian atas dengan squared hinge loss over epochs untuk dataset train (biru) dan test (oranye), dan plot bawah menunjukkan classification accuracy over epochs.
Plot loss menunjukkan bahwa memang, model konvergensi, tetapi bentuk permukaan error tidak semulus fungsi loss lainnya di mana perubahan kecil pada nilai weight menyebabkan perubahan besar loss.
Multi-Class Classification Loss Functions
Multi-Class classification adalah masalah-masalah pemodelan prediktif di mana contoh diberikan satu dari lebih dari dua kelas.
Masalahnya sering di frame untuk memprediksi nilai integer, di mana setiap kelas diberi nilai integer unik dari 0 hingga (num_classes - 1). Masalahnya sering diimplementasikan sebagai memprediksi probabilitas dari contoh milik masing-masing kelas yang dikenal.
Pada bagian ini, kita akan melihat fungsi loss yang sesuai untuk multi-class classification predictive modeling problems.
Kita akan menggunakan masalah blobs sebagai dasar untuk penelitian. Fungsi make_blobs() yang disediakan oleh scikit-learn menyediakan cara untuk men-generate contoh yang diberikan sejumlah kelas dan fitur input tertentu. Kita akan menggunakan fungsi ini untuk menghasilkan 1.000 contoh untuk masalah klasifikasi 3-kelas dengan 2 variabel input. Generator nomor pseudorandom akan di-seed secara konsisten sehingga 1.000 contoh yang sama dihasilkan setiap kali kode dijalankan.
# generate dataset X, y = make_blobs(n_samples=1000, centers=3, n_features=2, cluster_std=2, random_state=2)
Dua variabel input dapat diambil sebagai koordinat x dan y untuk titik pada bidang dua dimensi.
Contoh di bawah ini membuat sebaran plot dari seluruh titik pewarnaan dataset oleh keanggotaan kelas mereka.
# scatter plot of blobs dataset from sklearn.datasets.samples_generator import make_blobs from numpy import where from matplotlib import pyplot # generate dataset X, y = make_blobs(n_samples=1000, centers=3, n_features=2, cluster_std=2, random_state=2) # select indices of points with each class label for i in range(3): samples_ix = where(y == i) pyplot.scatter(X[samples_ix, 0], X[samples_ix, 1]) pyplot.show()
Menjalankan contoh membuat scatter plot yang menunjukkan 1.000 contoh dalam dataset dengan contoh milik kelas 0, 1, dan 2 warna biru, oranye, dan hijau.
Fitur input Gaussian dan dapat mengambil manfaat dari standardisasi; namun demikian, kita akan menjaga nilai-nilai tetap dalam contoh ini untuk mempersingkat.
Dataset akan dibagi secara merata antara dataset training dan testing.
# split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:]
Model MLP kecil akan digunakan sebagai dasar untuk mengeksplorasi fungsi loss.
Model mengharapkan dua variabel input, memiliki 50 node di hidden layer dan fungsi rectified linear activation, dan lapisan output yang harus di optimasi berdasarkan pemilihan fungsi loss.
# define model model = Sequential() model.add(Dense(50, input_dim=2, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(..., activation='...'))
Model ini cocok menggunakan stochastic gradient descent dengan tingkat pembelajaran default yang masuk akal 0,01 dan momentum 0,9.
# compile model opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='...', optimizer=opt, metrics=['accuracy'])
Model ini akan di-fit untuk 100 epoch pada dataset training dan dataset testing akan digunakan sebagai dataset validasi, memungkinkan kita untuk mengevaluasi baik loss dan akurasi klasifikasi dari dataset train dan test di akhir setiap epoch pelatihan dan menggambar kurva learning .
# fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=100, verbose=0)
Sekarang kita memiliki dasar masalah dan model, kita dapat melihat mengevaluasi tiga fungsi loss umum yang sesuai untuk multi-class classification predictive modeling problem.
Meskipun MLP digunakan dalam contoh-contoh ini, fungsi loss yang sama dapat digunakan ketika melatih model CNN dan RNN untuk multi-class classification.
Multi-Class Cross-Entropy Loss
Cross-entropy adalah fungsi loss default untuk digunakan untuk masalah klasifikasi multi-kelas.
Dalam hal ini, ini dimaksudkan untuk digunakan dengan klasifikasi multi-kelas di mana nilai target berada di set {0, 1, 3, ..., n}, di mana setiap kelas diberi nilai integer unik.
Secara matematis, ini adalah fungsi loss yang lebih disukai di bawah inference framework of maximum likelihood. Ini adalah fungsi loss yang harus dievaluasi terlebih dahulu dan hanya diubah jika anda memiliki alasan yang kuat.
Cross-entropy akan menghitung skor yang merangkum perbedaan rata-rata antara distribusi probabilitas aktual dan prediksi untuk semua kelas dalam masalah yang diamati. Skor diminimalkan dan nilai cross-entropy yang sempurna adalah 0.
Cross-entropy dapat dispesifikasikan sebagai fungsi loss di Keras dengan menentukan 'categorical_crossentropy ‘saat menyusun model.
Fungsi ini mensyaratkan bahwa lapisan output dikonfigurasikan dengan n node (satu untuk setiap kelas), dalam hal ini tiga node, dan aktivasi ‘softmax‘ untuk memprediksi probabilitas untuk setiap kelas.
model.add(Dense(3, activation='softmax'))
Pada akhirnya, ini berarti bahwa variabel target harus berupa one hot encoded.
Ini untuk memastikan bahwa setiap contoh memiliki probabilitas yang diharapkan dari 1,0 untuk nilai kelas aktual dan probabilitas yang diharapkan dari 0,0 untuk semua nilai kelas lainnya. Ini dapat dicapai dengan menggunakan fungsi to_categorical() Keras.
# one hot encode output variable y = to_categorical(y)
Contoh lengkap dari MLP dengan cross-entropy loss untuk masalah klasifikasi multi-kelas tercantum di bawah ini.
# mlp for the blobs multi-class classification problem with cross-entropy loss from sklearn.datasets.samples_generator import make_blobs from keras.layers import Dense from keras.models import Sequential from keras.optimizers import SGD from keras.utils import to_categorical from matplotlib import pyplot # generate 2d classification dataset X, y = make_blobs(n_samples=1000, centers=3, n_features=2, cluster_std=2, random_state=2) # one hot encode output variable y = to_categorical(y) # split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # define model model = Sequential() model.add(Dense(50, input_dim=2, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(3, activation='softmax')) # compile model opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy']) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=100, verbose=0) # evaluate the model _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_acc, test_acc)) # plot loss during training pyplot.subplot(211) pyplot.title('Loss') pyplot.plot(history.history['loss'], label='train') pyplot.plot(history.history['val_loss'], label='test') pyplot.legend() # plot accuracy during training pyplot.subplot(212) pyplot.title('Accuracy') pyplot.plot(history.history['acc'], label='train') pyplot.plot(history.history['val_acc'], label='test') pyplot.legend()
Menjalankan contoh pertama-tama mem-print keakuratan klasifikasi untuk model pada dataset train dan test.
Mengingat sifat stokastik dari algoritma training, hasil spesifik anda dapat bervariasi. Coba jalankan contoh beberapa kali.
Dalam hal ini, kita dapat melihat model bekerja dengan baik, mencapai akurasi klasifikasi sekitar 84% pada dataset training dan sekitar 82% pada dataset testing.
Train: 0.840, Test: 0.822
Gambar juga dibuat menunjukkan dua plot garis, bagian atas dengan cross-entropy loss over epochs untuk dataset train (biru) dan test (oranye), dan plot bawah menunjukkan akurasi classification accuracy over epochs..
Dalam kasus ini, plot menunjukkan model yang tampaknya telah terkonvergensi. Plot garis untuk cross-entropy dan akurasi keduanya menunjukkan perilaku konvergensi yang baik, meskipun agak bergelombang. Model dapat dikonfigurasikan dengan baik tanpa ada tanda-tanda over atau under fitting. Tingkat pembelajaran atau ukuran batch dapat disesuaikan untuk meratakan kelancaran konvergensi dalam kasus ini.
Sparse Multiclass Cross-Entropy Loss
Kemungkinan penyebab frustrasi ketika menggunakan cross-entropy dengan masalah klasifikasi dengan sejumlah besar label adalah one hot encoding process.
Misalnya, memprediksi kata dalam vocabulary dapat memiliki puluhan atau ratusan ribu kategori, satu untuk setiap label. Ini dapat berarti bahwa elemen target dari setiap contoh pelatihan mungkin memerlukan one hot encoded vector yang dikodekan dengan puluhan atau ratusan ribu nilai nol, yang membutuhkan memori yang besar.
Sparse cross-entropy dilakukan dengan melakukan perhitungan kesalahan cross-entropy yang sama, tanpa mengharuskan variabel target menjadi one hot encoded sebelum training.
Sparse cross-entropy dapat digunakan dalam keras untuk multi-class classification dengan menggunakan ‘sparse_categorical_crossentropy‘ saat memanggil fungsi compile().
model.compile(loss='sparse_categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
Fungsi ini mensyaratkan bahwa lapisan output dikonfigurasikan dengan n node (satu untuk setiap kelas), dalam hal ini tiga node, dan aktivasi ‘softmax‘ untuk memprediksi probabilitas untuk setiap kelas.
model.add(Dense(3, activation='softmax'))
Tidak diperlukan one hot encoding dari variabel target, manfaat dari fungsi loss ini.
Contoh lengkap pelatihan MLP dengan sparse cross-entropy pada blobs multi-class classification problem tercantum di bawah ini.
# mlp for the blobs multi-class classification problem with sparse cross-entropy loss from sklearn.datasets.samples_generator import make_blobs from keras.layers import Dense from keras.models import Sequential from keras.optimizers import SGD from matplotlib import pyplot # generate 2d classification dataset X, y = make_blobs(n_samples=1000, centers=3, n_features=2, cluster_std=2, random_state=2) # split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # define model model = Sequential() model.add(Dense(50, input_dim=2, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(3, activation='softmax')) # compile model opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='sparse_categorical_crossentropy', optimizer=opt, metrics=['accuracy']) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=100, verbose=0) # evaluate the model _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_acc, test_acc)) # plot loss during training pyplot.subplot(211) pyplot.title('Loss') pyplot.plot(history.history['loss'], label='train') pyplot.plot(history.history['val_loss'], label='test') pyplot.legend() # plot accuracy during training pyplot.subplot(212) pyplot.title('Accuracy') pyplot.plot(history.history['acc'], label='train') pyplot.plot(history.history['val_acc'], label='test') pyplot.legend() pyplot.show()
Menjalankan contoh pertama-tama mem-print keakuratan klasifikasi untuk model pada dataset training dan testing.
Mengingat sifat stokastik dari algoritma training, hasil spesifik anda dapat bervariasi. Coba jalankan contoh beberapa kali.
Dalam hal ini, kita dapat melihat model mencapai kinerja yang baik pada masalah tersebut. Bahkan, jika anda mengulangi percobaan berkali-kali, kinerja rata-rata sparse dan non-sparse cross-entropy sebanding harus sebanding.
Train: 0.832, Test: 0.818
Gambar juga dibuat menunjukkan dua plot garis, bagian atas dengan sparse cross-entropy loss over epochs untuk dataset train (biru) dan testing (oranye), dan plot bawah menunjukkan classification accuracy over epochs.
Dalam hal ini, plot menunjukkan konvergensi yang baik dari model atas pelatihan sehubungan dengan loss dan akurasi klasifikasi.
Kullback Leibler Divergence Loss
Singkatnya Kullback Leibler Divergence, atau KL Divergence, adalah ukuran bagaimana satu distribusi probabilitas berbeda dari distribusi baseline.
KL divergence loss dengan nilai 0 menunjukkan distribusi identik. Dalam praktiknya, perilaku KL Divergence sangat mirip dengan cross-entropy. Ini menghitung berapa banyak informasi yang hilang (dalam bentuk bit) jika distribusi probabilitas yang diprediksi digunakan untuk memperkirakan distribusi probabilitas target yang diinginkan.
Dengan demikian, fungsi KL divergence loss lebih umum digunakan ketika menggunakan model yang belajar untuk memperkirakan fungsi yang lebih kompleks daripada hanya klasifikasi multi-kelas, seperti dalam kasus autoencoder yang digunakan untuk mempelajari representasi fitur padat di bawah model yang harus merekonstruksi input asli. Dalam hal ini, KL divergence loss akan lebih disukai. Namun demikian, ini dapat digunakan untuk klasifikasi multi-kelas, dalam hal ini secara fungsional setara dengan multi-class cross-entropy.
KL divergence loss dapat digunakan dalam Keras dengan men-set ‘kullback_leibler_divergence‘ dalam fungsi compile().
model.compile(loss='kullback_leibler_divergence', optimizer=opt, metrics=['accuracy'])
Seperti cross-entropy, lapisan output dikonfigurasikan dengan n node (satu untuk setiap kelas), dalam hal ini tiga node, dan aktivasi ‘softmax‘ untuk memprediksi probabilitas untuk setiap kelas.
Sama, seperti dengan categorical cross-entropy, kita harus one hot encode variabel target untuk memiliki probabilitas yang diharapkan dari 1,0 untuk nilai kelas dan 0,0 untuk semua nilai kelas lainnya.
# one hot encode output variable y = to_categorical(y)
Contoh lengkap pelatihan MLP dengan KL divergence loss untuk blobs multi-class classification problem tercantum di bawah ini.
# mlp for the blobs multi-class classification problem with kl divergence loss from sklearn.datasets.samples_generator import make_blobs from keras.layers import Dense from keras.models import Sequential from keras.optimizers import SGD from keras.utils import to_categorical from matplotlib import pyplot # generate 2d classification dataset X, y = make_blobs(n_samples=1000, centers=3, n_features=2, cluster_std=2, random_state=2) # one hot encode output variable y = to_categorical(y) # split into train and test n_train = 500 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # define model model = Sequential() model.add(Dense(50, input_dim=2, activation='relu', kernel_initializer='he_uniform')) model.add(Dense(3, activation='softmax')) # compile model opt = SGD(lr=0.01, momentum=0.9) model.compile(loss='kullback_leibler_divergence', optimizer=opt, metrics=['accuracy']) # fit model history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=100, verbose=0) # evaluate the model _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_acc, test_acc)) # plot loss during training pyplot.subplot(211) pyplot.title('Loss') pyplot.plot(history.history['loss'], label='train') pyplot.plot(history.history['val_loss'], label='test') pyplot.legend() # plot accuracy during training pyplot.subplot(212) pyplot.title('Accuracy') pyplot.plot(history.history['acc'], label='train') pyplot.plot(history.history['val_acc'], label='test') pyplot.legend() pyplot.show()
Menjalankan contoh pertama-tama mem-print keakuratan klasifikasi untuk model pada dataset training dan testing.
Mengingat sifat stokastik dari algoritma training, hasil spesifik anda dapat bervariasi. Coba jalankan contoh beberapa kali.
Dalam hal ini, kita melihat kinerja yang mirip dengan hasil yang terlihat dengan cross-entropy loss, dalam hal ini akurasi sekitar 82% pada dataset training dan testing.
Train: 0.822, Test: 0.822
Gambar juga dibuat menunjukkan dua plot garis, bagian atas KL divergence loss over epochs untuk dataset train (biru) dan test (oranye), dan plot bawah menunjukkan classification accuracy over epochs.
Dalam kasus ini, plot menunjukkan perilaku konvergensi yang baik untuk loss dan akurasi klasifikasi. Sangat mungkin bahwa evaluasi cross-entropy akan menghasilkan perilaku yang hampir identik mengingat kesamaan dalam ukuran.