7.1. Sınıflandırma için İnce Ayar
Reading time: 5 minutes
Nedir
İnce ayar, büyük miktarda veriden genel dil kalıplarını öğrenmiş bir önceden eğitilmiş modeli alıp bunu belirli bir görevi yerine getirecek şekilde veya alan spesifik dili anlamak için uyarlama sürecidir. Bu, modelin daha küçük, görev spesifik bir veri seti üzerinde eğitimine devam edilerek gerçekleştirilir; böylece model, yeni verinin inceliklerine daha iyi uyum sağlamak için parametrelerini ayarlarken, zaten edinmiş olduğu geniş bilgiyi kullanabilir. İnce ayar, modelin sıfırdan yeni bir model eğitmeye gerek kalmadan, özel uygulamalarda daha doğru ve ilgili sonuçlar vermesini sağlar.
tip
LLM'yi "anlayan" bir metin için önceden eğitmek oldukça pahalı olduğundan, genellikle açık kaynaklı önceden eğitilmiş modelleri belirli bir görevi yerine getirmesi için ince ayar yapmak daha kolay ve ucuzdur.
tip
Bu bölümün amacı, zaten önceden eğitilmiş bir modeli ince ayar yapmayı göstermektir; böylece LLM yeni metin üretmek yerine, verilen metnin her bir verilen kategoriye ait olma olasılıklarını seçecektir (örneğin, bir metnin spam olup olmadığını).
Veri setini hazırlama
Veri seti boyutu
Elbette, bir modeli ince ayar yapmak için LLM'nizi özelleştirmek için bazı yapılandırılmış verilere ihtiyacınız var. https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb adresinde önerilen örnekte, GPT2 bir e-postanın spam olup olmadığını tespit etmek için https://archive.ics.uci.edu/static/public/228/sms+spam+collection.zip verilerini kullanarak ince ayar yapılmıştır.
Bu veri seti, "spam" olanlardan çok daha fazla "spam olmayan" örnek içermektedir; bu nedenle kitap, "spam olmayan" örneklerden yalnızca "spam" olanlar kadarını kullanmayı önermektedir (bu nedenle, eğitim verisinden tüm ekstra örnekleri kaldırmak). Bu durumda, her birinden 747 örnek vardı.
Ardından, veri setinin %70'i eğitim için, %10'u doğrulama için ve %20'si test için kullanılır.
- Doğrulama seti, modelin hiperparametrelerini ince ayar yapmak ve model mimarisi hakkında kararlar almak için eğitim aşamasında kullanılır; bu, modelin görülmemiş veriler üzerindeki performansına geri bildirim sağlayarak aşırı uyum sağlamayı önlemeye yardımcı olur. Nihai değerlendirmeyi önyargılamadan yinelemeli iyileştirmelere olanak tanır.
- Bu, bu veri setinde yer alan verilerin doğrudan eğitim için kullanılmadığı, ancak en iyi hiperparametreleri ayarlamak için kullanıldığı anlamına gelir; bu nedenle bu set, modelin performansını test seti gibi değerlendirmek için kullanılamaz.
- Aksine, test seti, model tamamen eğitildikten ve tüm ayarlamalar tamamlandıktan sonra yalnızca kullanılır; bu, modelin yeni, görülmemiş verilere genelleme yeteneğini tarafsız bir şekilde değerlendirir. Test setindeki bu nihai değerlendirme, modelin gerçek dünya uygulamalarında nasıl performans göstermesi gerektiğine dair gerçekçi bir gösterge sunar.
Girdi uzunluğu
Eğitim örneği, aynı uzunlukta girdiler (bu durumda e-posta metni) beklediğinden, her girişi en büyük olanın boyutuna kadar genişletmek için <|endoftext|>
kimliklerini doldurma olarak eklemeye karar verildi.
Modeli başlatma
Açık kaynaklı önceden eğitilmiş ağırlıkları kullanarak modeli eğitmek için başlatın. Bunu daha önce yaptık ve https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb talimatlarını takip ederek bunu kolayca yapabilirsiniz.
Sınıflandırma başlığı
Bu özel örnekte (bir metnin spam olup olmadığını tahmin etme), GPT2'nin tam kelime dağarcığına göre ince ayar yapmaktan ziyade, yeni modelin e-postanın spam (1) olup olmadığını (0) söylemesini istiyoruz. Bu nedenle, yalnızca spam olup olmadığını gösteren olasılıkları veren son katmanı değiştireceğiz (yani 2 kelimelik bir kelime dağarcığı gibi).
# This code modified the final layer with a Linear one with 2 outs
num_classes = 2
model.out_head = torch.nn.Linear(
in_features=BASE_CONFIG["emb_dim"],
out_features=num_classes
)
Ayarları ince ayar yapmak
Hızlı bir şekilde ince ayar yapmak için tüm parametreleri ince ayar yapmak yerine sadece bazı son parametreleri ince ayar yapmak daha kolaydır. Bunun nedeni, alt katmanların genellikle temel dil yapıları ve uygulanabilir anlamları yakaladığı bilinmektedir. Bu nedenle, sadece son katmanları ince ayar yapmak genellikle yeterlidir ve daha hızlıdır.
# This code makes all the parameters of the model unrtainable
for param in model.parameters():
param.requires_grad = False
# Allow to fine tune the last layer in the transformer block
for param in model.trf_blocks[-1].parameters():
param.requires_grad = True
# Allow to fine tune the final layer norm
for param in model.final_norm.parameters():
param.requires_grad = True
Eğitim için kullanılacak girdiler
Önceki bölümlerde LLM, modelin dili daha iyi anlaması için, tahmin edilen her token'ın kaybını azaltarak eğitildi; bu, tahmin edilen token'ların neredeyse tamamının giriş cümlesinde olduğu (sadece sonunda gerçekten tahmin edilen 1 token vardı) anlamına geliyordu.
Bu durumda, modelin spam olup olmadığını tahmin edebilmesiyle ilgileniyoruz, bu nedenle yalnızca tahmin edilen son token ile ilgileniyoruz. Bu nedenle, önceki eğitim kayıp fonksiyonlarımızı yalnızca bu token'ı dikkate alacak şekilde değiştirmek gerekiyor.
Bu, https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/ch06.ipynb adresinde şu şekilde uygulanmıştır:
def calc_accuracy_loader(data_loader, model, device, num_batches=None):
model.eval()
correct_predictions, num_examples = 0, 0
if num_batches is None:
num_batches = len(data_loader)
else:
num_batches = min(num_batches, len(data_loader))
for i, (input_batch, target_batch) in enumerate(data_loader):
if i < num_batches:
input_batch, target_batch = input_batch.to(device), target_batch.to(device)
with torch.no_grad():
logits = model(input_batch)[:, -1, :] # Logits of last output token
predicted_labels = torch.argmax(logits, dim=-1)
num_examples += predicted_labels.shape[0]
correct_predictions += (predicted_labels == target_batch).sum().item()
else:
break
return correct_predictions / num_examples
def calc_loss_batch(input_batch, target_batch, model, device):
input_batch, target_batch = input_batch.to(device), target_batch.to(device)
logits = model(input_batch)[:, -1, :] # Logits of last output token
loss = torch.nn.functional.cross_entropy(logits, target_batch)
return loss
Her bir batch için yalnızca son tahmin edilen token'ın logits'leriyle ilgilendiğimizi unutmayın.
Tam GPT2 ince ayar sınıflandırma kodu
GPT2'yi bir spam sınıflandırıcısı olarak ince ayar yapmak için tüm kodu https://github.com/rasbt/LLMs-from-scratch/blob/main/ch06/01_main-chapter-code/load-finetuned-model.ipynb adresinde bulabilirsiniz.