يوم مجتمع ML هو 9 نوفمبر! الانضمام إلينا للحصول على التحديثات من TensorFlow، JAX، وأكثر معرفة المزيد

تصنيف النص الأساسي

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

يوضح هذا البرنامج التعليمي تصنيف النص بدءًا من ملفات النص العادي المخزنة على القرص. ستقوم بتدريب مصنف ثنائي لإجراء تحليل المشاعر على مجموعة بيانات IMDB. في نهاية دفتر الملاحظات ، هناك تمرين يمكنك تجربته ، حيث ستقوم بتدريب مصنف متعدد الفئات للتنبؤ بالعلامة الخاصة بسؤال البرمجة على Stack Overflow.

import matplotlib.pyplot as plt
import os
import re
import shutil
import string
import tensorflow as tf

from tensorflow.keras import layers
from tensorflow.keras import losses
from tensorflow.keras import preprocessing
print(tf.__version__)
2.6.0

تحليل المشاعر

هذا الكمبيوتر الدفتري القطارات نموذج تحليل المشاعر إلى ويستعرض الفيلم تصنيف بأنها إيجابية أو سلبية، استنادا إلى نص المراجعة. وهذا مثال من ثنائي -أو من الدرجة يومين تصنيف، وهو نوع مهم وقابلة للتطبيق على نطاق واسع من آلة مشكلة التعلم.

عليك استخدام واسع الفيلم الاستعراضي الإدراجات الذي يحتوي على النص من 50000 يستعرض الفيلم من قاعدة بيانات الأفلام على الإنترنت . يتم تقسيم هذه إلى 25000 مراجعة للتدريب و 25000 مراجعة للاختبار. ومتوازنة تدريب واختبار مجموعات، وهذا يعني أنها تحتوي على عدد متساو من الاستعراضات إيجابية وسلبية.

قم بتنزيل واستكشاف مجموعة بيانات IMDB

لنقم بتنزيل مجموعة البيانات واستخراجها ، ثم نستكشف بنية الدليل.

url = "https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz"

dataset = tf.keras.utils.get_file("aclImdb_v1", url,
                                    untar=True, cache_dir='.',
                                    cache_subdir='')

dataset_dir = os.path.join(os.path.dirname(dataset), 'aclImdb')
Downloading data from https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
84131840/84125825 [==============================] - 6s 0us/step
84140032/84125825 [==============================] - 6s 0us/step
os.listdir(dataset_dir)
['imdbEr.txt', 'README', 'train', 'test', 'imdb.vocab']
train_dir = os.path.join(dataset_dir, 'train')
os.listdir(train_dir)
['urls_neg.txt',
 'pos',
 'unsup',
 'unsupBow.feat',
 'labeledBow.feat',
 'urls_unsup.txt',
 'urls_pos.txt',
 'neg']

و aclImdb/train/pos و aclImdb/train/neg الدلائل تحتوي على العديد من الملفات النصية، كل منها هو استعراض فيلم واحد. دعونا نلقي نظرة على واحد منهم.

sample_file = os.path.join(train_dir, 'pos/1181_9.txt')
with open(sample_file) as f:
  print(f.read())
Rachel Griffiths writes and directs this award winning short film. A heartwarming story about coping with grief and cherishing the memory of those we've loved and lost. Although, only 15 minutes long, Griffiths manages to capture so much emotion and truth onto film in the short space of time. Bud Tingwell gives a touching performance as Will, a widower struggling to cope with his wife's death. Will is confronted by the harsh reality of loneliness and helplessness as he proceeds to take care of Ruth's pet cow, Tulip. The film displays the grief and responsibility one feels for those they have loved and lost. Good cinematography, great direction, and superbly acted. It will bring tears to all those who have lost a loved one, and survived.

قم بتحميل مجموعة البيانات

بعد ذلك ، ستقوم بتحميل البيانات من القرص وإعدادها بتنسيق مناسب للتدريب. للقيام بذلك، وسوف تستخدم مفيدة text_dataset_from_directory المرافق العامة، التي تتوقع بنية دليل على النحو التالي.

main_directory/
...class_a/
......a_text_1.txt
......a_text_2.txt
...class_b/
......b_text_1.txt
......b_text_2.txt

لإعداد بيانات للتصنيف ثنائي، وسوف تحتاج مجلدين على القرص، الموافق class_a و class_b . وسوف تكون هذه الإيجابية والسلبية ويستعرض الفيلم، والتي يمكن العثور عليها في aclImdb/train/pos و aclImdb/train/neg . نظرًا لأن مجموعة بيانات IMDB تحتوي على مجلدات إضافية ، فسوف تقوم بإزالتها قبل استخدام هذه الأداة المساعدة.

remove_dir = os.path.join(train_dir, 'unsup')
shutil.rmtree(remove_dir)

بعد ذلك، سوف تستخدم text_dataset_from_directory أداة لإنشاء وصفت tf.data.Dataset . tf.data هو مجموعة قوية من الأدوات اللازمة للعمل مع البيانات.

عند تشغيل تجربة تعلم الآلة، بل هو أفضل الممارسات لتقسيم مجموعة البيانات الخاصة بك إلى ثلاثة انشقاقات: القطار ، التحقق من صحة ، و الاختبار .

تم بالفعل تقسيم مجموعة بيانات IMDB إلى تدريب واختبار ، لكنها تفتقر إلى مجموعة التحقق من الصحة. دعونا خلق مجموعة المصادقة باستخدام 80:20 انقسام بيانات التدريب باستخدام validation_split حجة أدناه.

batch_size = 32
seed = 42

raw_train_ds = tf.keras.preprocessing.text_dataset_from_directory(
    'aclImdb/train', 
    batch_size=batch_size, 
    validation_split=0.2, 
    subset='training', 
    seed=seed)
Found 25000 files belonging to 2 classes.
Using 20000 files for training.

كما ترى أعلاه ، يوجد 25000 مثال في مجلد التدريب ، ستستخدم 80٪ (أو 20000) منها للتدريب. كما سترون في لحظة، يمكنك تدريب نموذج عن طريق تمرير بيانات مباشرة إلى model.fit . إذا كنت جديدا على tf.data ، يمكنك أيضا أعاد على مجموعة البيانات وطباعة بعض الأمثلة على النحو التالي.

for text_batch, label_batch in raw_train_ds.take(1):
  for i in range(3):
    print("Review", text_batch.numpy()[i])
    print("Label", label_batch.numpy()[i])
Review b'"Pandemonium" is a horror movie spoof that comes off more stupid than funny. Believe me when I tell you, I love comedies. Especially comedy spoofs. "Airplane", "The Naked Gun" trilogy, "Blazing Saddles", "High Anxiety", and "Spaceballs" are some of my favorite comedies that spoof a particular genre. "Pandemonium" is not up there with those films. Most of the scenes in this movie had me sitting there in stunned silence because the movie wasn\'t all that funny. There are a few laughs in the film, but when you watch a comedy, you expect to laugh a lot more than a few times and that\'s all this film has going for it. Geez, "Scream" had more laughs than this film and that was more of a horror film. How bizarre is that?<br /><br />*1/2 (out of four)'
Label 0
Review b"David Mamet is a very interesting and a very un-equal director. His first movie 'House of Games' was the one I liked best, and it set a series of films with characters whose perspective of life changes as they get into complicated situations, and so does the perspective of the viewer.<br /><br />So is 'Homicide' which from the title tries to set the mind of the viewer to the usual crime drama. The principal characters are two cops, one Jewish and one Irish who deal with a racially charged area. The murder of an old Jewish shop owner who proves to be an ancient veteran of the Israeli Independence war triggers the Jewish identity in the mind and heart of the Jewish detective.<br /><br />This is were the flaws of the film are the more obvious. The process of awakening is theatrical and hard to believe, the group of Jewish militants is operatic, and the way the detective eventually walks to the final violent confrontation is pathetic. The end of the film itself is Mamet-like smart, but disappoints from a human emotional perspective.<br /><br />Joe Mantegna and William Macy give strong performances, but the flaws of the story are too evident to be easily compensated."
Label 0
Review b'Great documentary about the lives of NY firefighters during the worst terrorist attack of all time.. That reason alone is why this should be a must see collectors item.. What shocked me was not only the attacks, but the"High Fat Diet" and physical appearance of some of these firefighters. I think a lot of Doctors would agree with me that,in the physical shape they were in, some of these firefighters would NOT of made it to the 79th floor carrying over 60 lbs of gear. Having said that i now have a greater respect for firefighters and i realize becoming a firefighter is a life altering job. The French have a history of making great documentary\'s and that is what this is, a Great Documentary.....'
Label 1

لاحظ الاستعراضات تحتوي على النص الخام (مع علامات الترقيم وعلامات HTML في بعض الأحيان مثل <br/> ). سوف تظهر كيفية التعامل مع هذه في القسم التالي.

التسميات هي 0 أو 1. لمعرفة أي من هذه تتوافق مع ويستعرض الفيلم الإيجابية والسلبية، يمكنك التحقق من class_names الملكية على مجموعة البيانات.

print("Label 0 corresponds to", raw_train_ds.class_names[0])
print("Label 1 corresponds to", raw_train_ds.class_names[1])
Label 0 corresponds to neg
Label 1 corresponds to pos

بعد ذلك ، ستقوم بإنشاء مجموعة بيانات تحقق من الصحة والاختبار. ستستخدم المراجعات الـ 5000 المتبقية من مجموعة التدريب للتحقق من صحتها.

raw_val_ds = tf.keras.preprocessing.text_dataset_from_directory(
    'aclImdb/train', 
    batch_size=batch_size, 
    validation_split=0.2, 
    subset='validation', 
    seed=seed)
Found 25000 files belonging to 2 classes.
Using 5000 files for validation.
raw_test_ds = tf.keras.preprocessing.text_dataset_from_directory(
    'aclImdb/test', 
    batch_size=batch_size)
Found 25000 files belonging to 2 classes.

جهز مجموعة البيانات للتدريب

بعد ذلك، سوف توحيد، tokenize، وvectorize البيانات باستخدام مفيدة preprocessing.TextVectorization طبقة.

يشير التوحيد القياسي إلى المعالجة المسبقة للنص ، عادةً لإزالة علامات الترقيم أو عناصر HTML لتبسيط مجموعة البيانات. يشير الترميز إلى تقسيم السلاسل إلى رموز (على سبيل المثال ، تقسيم جملة إلى كلمات فردية ، عن طريق تقسيمها على مسافة بيضاء). تشير Vectorization إلى تحويل الرموز المميزة إلى أرقام بحيث يمكن تغذيتها في شبكة عصبية. يمكن إنجاز كل هذه المهام باستخدام هذه الطبقة.

كما رأيتم أعلاه، الاستعراضات تحتوي HTML علامات مختلفة مثل <br /> . لن يتم إزالة هذه العلامات من قبل standardizer الافتراضية في TextVectorization طبقة (الذي يحول النص إلى أحرف صغيرة وشرائح علامات الترقيم بشكل افتراضي، ولكن لا تجريد HTML). ستكتب وظيفة توحيد مخصصة لإزالة HTML.

def custom_standardization(input_data):
  lowercase = tf.strings.lower(input_data)
  stripped_html = tf.strings.regex_replace(lowercase, '<br />', ' ')
  return tf.strings.regex_replace(stripped_html,
                                  '[%s]' % re.escape(string.punctuation),
                                  '')

بعد ذلك، سوف تقوم بإنشاء TextVectorization طبقة. ستستخدم هذه الطبقة لتوحيد بياناتنا وترميزها وتوحيدها. تعيين output_mode ل int لخلق مؤشرات عدد صحيح فريد لكل رمز.

لاحظ أنك تستخدم وظيفة التقسيم الافتراضية ، ووظيفة التقييس المخصصة التي حددتها أعلاه. عليك أيضا تحديد بعض الثوابت لنموذج، مثل الحد الأقصى صريحة sequence_length ، والذي يؤدي إلى طبقة سادة أو اقتطاع تسلسل بالضبط sequence_length القيم.

max_features = 10000
sequence_length = 250

vectorize_layer = layers.TextVectorization(
    standardize=custom_standardization,
    max_tokens=max_features,
    output_mode='int',
    output_sequence_length=sequence_length)

بعد ذلك، سوف الدعوة adapt لتناسب حالة طبقة تجهيزها لمجموعة البيانات. سيؤدي هذا إلى قيام النموذج ببناء فهرس من السلاسل إلى أعداد صحيحة.

# Make a text-only dataset (without labels), then call adapt
train_text = raw_train_ds.map(lambda x, y: x)
vectorize_layer.adapt(train_text)

لنقم بإنشاء دالة لمعرفة نتيجة استخدام هذه الطبقة في المعالجة المسبقة لبعض البيانات.

def vectorize_text(text, label):
  text = tf.expand_dims(text, -1)
  return vectorize_layer(text), label
# retrieve a batch (of 32 reviews and labels) from the dataset
text_batch, label_batch = next(iter(raw_train_ds))
first_review, first_label = text_batch[0], label_batch[0]
print("Review", first_review)
print("Label", raw_train_ds.class_names[first_label])
print("Vectorized review", vectorize_text(first_review, first_label))
Review tf.Tensor(b'Great movie - especially the music - Etta James - "At Last". This speaks volumes when you have finally found that special someone.', shape=(), dtype=string)
Label neg
Vectorized review (<tf.Tensor: shape=(1, 250), dtype=int64, numpy=
array([[  86,   17,  260,    2,  222,    1,  571,   31,  229,   11, 2418,
           1,   51,   22,   25,  404,  251,   12,  306,  282,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
           0,    0,    0,    0,    0,    0,    0,    0]])>, <tf.Tensor: shape=(), dtype=int32, numpy=0>)

كما ترى أعلاه ، تم استبدال كل رمز بعدد صحيح. يمكنك البحث عن رمزية (سلسلة) أن كل عدد صحيح يتوافق مع بالدعوة .get_vocabulary() على طبقة.

print("1287 ---> ",vectorize_layer.get_vocabulary()[1287])
print(" 313 ---> ",vectorize_layer.get_vocabulary()[313])
print('Vocabulary size: {}'.format(len(vectorize_layer.get_vocabulary())))
1287 --->  silent
 313 --->  night
Vocabulary size: 10000

أنت جاهز تقريبًا لتدريب نموذجك. كخطوة نهائية للمعالجة المسبقة ، ستقوم بتطبيق طبقة TextVectorization التي قمت بإنشائها مسبقًا على مجموعة بيانات القطار والتحقق من الصحة والاختبار.

train_ds = raw_train_ds.map(vectorize_text)
val_ds = raw_val_ds.map(vectorize_text)
test_ds = raw_test_ds.map(vectorize_text)

تكوين مجموعة البيانات للأداء

هاتان طريقتان مهمتان يجب عليك استخدامهما عند تحميل البيانات للتأكد من أن الإدخال / الإخراج لا يصبح محظورًا.

.cache() يحتفظ البيانات في الذاكرة بعد محملة تشغيله القرص. سيضمن ذلك عدم تحول مجموعة البيانات إلى عنق زجاجة أثناء تدريب نموذجك. إذا كانت مجموعة البيانات الخاصة بك كبيرة جدًا بحيث لا يمكن وضعها في الذاكرة ، فيمكنك أيضًا استخدام هذه الطريقة لإنشاء ذاكرة تخزين مؤقت على القرص ذات أداء فعال ، وهي أكثر كفاءة في القراءة من العديد من الملفات الصغيرة.

.prefetch() تداخل البيانات وتجهيزها وتنفيذ نموذج في حين أن التدريب.

يمكنك معرفة المزيد حول كلتا الطريقتين، وكذلك كيفية بيانات ذاكرة التخزين المؤقت على القرص في دليل بيانات الأداء .

AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
test_ds = test_ds.cache().prefetch(buffer_size=AUTOTUNE)

قم بإنشاء النموذج

حان الوقت لإنشاء شبكتك العصبية:

embedding_dim = 16
model = tf.keras.Sequential([
  layers.Embedding(max_features + 1, embedding_dim),
  layers.Dropout(0.2),
  layers.GlobalAveragePooling1D(),
  layers.Dropout(0.2),
  layers.Dense(1)])

model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, None, 16)          160016    
_________________________________________________________________
dropout (Dropout)            (None, None, 16)          0         
_________________________________________________________________
global_average_pooling1d (Gl (None, 16)                0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 16)                0         
_________________________________________________________________
dense (Dense)                (None, 1)                 17        
=================================================================
Total params: 160,033
Trainable params: 160,033
Non-trainable params: 0
_________________________________________________________________

يتم تكديس الطبقات بالتسلسل لبناء المصنف:

  1. الطبقة الأولى هي Embedding طبقة. تأخذ هذه الطبقة المراجعات المشفرة بعدد صحيح وتبحث عن متجه تضمين لكل فهرس كلمة. يتم تعلم هذه النواقل باعتبارها نموذج القطارات. تضيف المتجهات بعدًا إلى صفيف الإخراج. الأبعاد الناتجة: (batch, sequence, embedding) . لمعرفة المزيد عن التضمينات، راجع كلمة تضمين البرنامج التعليمي .
  2. المقبل، GlobalAveragePooling1D طبقة بإرجاع متجه الانتاج ذات طول ثابت على سبيل المثال كل من المتوسط على مدى البعد التسلسل. هذا يسمح للنموذج بالتعامل مع المدخلات ذات الطول المتغير ، بأبسط طريقة ممكنة.
  3. يتم إيصاله هذا متجه الانتاج ذات طول ثابت من خلال مرتبطة ارتباطا كاملا ( Dense طبقة) مع 16 وحدة المخفية.
  4. الطبقة الأخيرة متصلة بكثافة مع عقدة خرج واحدة.

وظيفة الخسارة والمحسن

يحتاج النموذج إلى وظيفة خسارة ومحسن للتدريب. منذ هذه مشكلة تصنيف الثنائية ونموذج مخرجات احتمال (طبقة وحدة واحدة مع تفعيل السيني)، عليك استخدام losses.BinaryCrossentropy فقدان الوظيفة.

الآن ، قم بتكوين النموذج لاستخدام مُحسِّن ووظيفة خسارة:

model.compile(loss=losses.BinaryCrossentropy(from_logits=True),
              optimizer='adam',
              metrics=tf.metrics.BinaryAccuracy(threshold=0.0))

تدريب النموذج

سوف تقوم بتدريب هذا النموذج من قبل تمرير dataset الكائن إلى الأسلوب مناسبا.

epochs = 10
history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=epochs)
Epoch 1/10
625/625 [==============================] - 3s 4ms/step - loss: 0.6633 - binary_accuracy: 0.6982 - val_loss: 0.6142 - val_binary_accuracy: 0.7726
Epoch 2/10
625/625 [==============================] - 2s 3ms/step - loss: 0.5479 - binary_accuracy: 0.8020 - val_loss: 0.4978 - val_binary_accuracy: 0.8230
Epoch 3/10
625/625 [==============================] - 2s 3ms/step - loss: 0.4440 - binary_accuracy: 0.8457 - val_loss: 0.4198 - val_binary_accuracy: 0.8464
Epoch 4/10
625/625 [==============================] - 2s 3ms/step - loss: 0.3775 - binary_accuracy: 0.8668 - val_loss: 0.3733 - val_binary_accuracy: 0.8608
Epoch 5/10
625/625 [==============================] - 2s 3ms/step - loss: 0.3343 - binary_accuracy: 0.8795 - val_loss: 0.3445 - val_binary_accuracy: 0.8680
Epoch 6/10
625/625 [==============================] - 2s 3ms/step - loss: 0.3037 - binary_accuracy: 0.8890 - val_loss: 0.3256 - val_binary_accuracy: 0.8718
Epoch 7/10
625/625 [==============================] - 2s 3ms/step - loss: 0.2805 - binary_accuracy: 0.8988 - val_loss: 0.3123 - val_binary_accuracy: 0.8740
Epoch 8/10
625/625 [==============================] - 2s 3ms/step - loss: 0.2616 - binary_accuracy: 0.9062 - val_loss: 0.3030 - val_binary_accuracy: 0.8760
Epoch 9/10
625/625 [==============================] - 2s 3ms/step - loss: 0.2457 - binary_accuracy: 0.9103 - val_loss: 0.2961 - val_binary_accuracy: 0.8778
Epoch 10/10
625/625 [==============================] - 2s 3ms/step - loss: 0.2318 - binary_accuracy: 0.9166 - val_loss: 0.2915 - val_binary_accuracy: 0.8784

قم بتقييم النموذج

دعونا نرى كيف يعمل النموذج. سيتم إرجاع قيمتين. الخسارة (رقم يمثل خطأنا ، والقيم الأقل أفضل) والدقة.

loss, accuracy = model.evaluate(test_ds)

print("Loss: ", loss)
print("Accuracy: ", accuracy)
782/782 [==============================] - 1s 2ms/step - loss: 0.3101 - binary_accuracy: 0.8736
Loss:  0.3100942075252533
Accuracy:  0.8736400008201599

هذا النهج الساذج إلى حد ما يحقق دقة تبلغ حوالي 86٪.

أنشئ مخططًا للدقة والخسارة بمرور الوقت

model.fit() ترجع History الكائن الذي يحتوي على القاموس مع كل ما حدث أثناء التدريب:

history_dict = history.history
history_dict.keys()
dict_keys(['loss', 'binary_accuracy', 'val_loss', 'val_binary_accuracy'])

هناك أربعة إدخالات: واحد لكل مقياس يتم مراقبته أثناء التدريب والتحقق من الصحة. يمكنك استخدام هذه لتخطيط فقدان التدريب والتحقق من الصحة للمقارنة ، بالإضافة إلى دقة التدريب والتحقق من الصحة:

acc = history_dict['binary_accuracy']
val_acc = history_dict['val_binary_accuracy']
loss = history_dict['loss']
val_loss = history_dict['val_loss']

epochs = range(1, len(acc) + 1)

# "bo" is for "blue dot"
plt.plot(epochs, loss, 'bo', label='Training loss')
# b is for "solid blue line"
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()

plt.show()

بي إن جي

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')

plt.show()

بي إن جي

في هذه المؤامرة ، تمثل النقاط خسارة التدريب ودقته ، والخطوط الصلبة هي خسارة التحقق من الصحة والدقة.

لاحظ فقدان التدريب تتناقص مع كل عصر والتدريب وزيادة دقة مع كل عصر. هذا متوقع عند استخدام تحسين النسب المتدرج - يجب أن يقلل الكمية المرغوبة في كل تكرار.

هذا ليس هو الحال بالنسبة لفقدان التحقق من الصحة والدقة - يبدو أنهم وصلوا إلى الذروة قبل دقة التدريب. هذا مثال على التخصيص الزائد: يعمل النموذج بشكل أفضل على بيانات التدريب مقارنةً بالبيانات التي لم يسبق لها مثيل من قبل. بعد هذه النقطة، ونموذج الإفراط في المثلى ويتعلم التمثيل محددة لبيانات التدريب التي لا نعمم على بيانات الاختبار.

بالنسبة لهذه الحالة بالذات ، يمكنك منع فرط التجهيز ببساطة عن طريق إيقاف التدريب عندما لا تزداد دقة التحقق من الصحة. واحد طريقة للقيام بذلك هو استخدام tf.keras.callbacks.EarlyStopping رد.

تصدير النموذج

في رمز أعلاه، قمت بتطبيق TextVectorization طبقة إلى مجموعة البيانات قبل تغذية النص إلى النموذج. إذا كنت تريد أن تجعل النموذج الخاص بك قادر على معالجة السلاسل الخام (على سبيل المثال، لتبسيط نشر ذلك)، يمكنك تضمين TextVectorization طبقة داخل النموذج الخاص بك. للقيام بذلك ، يمكنك إنشاء نموذج جديد باستخدام الأوزان التي قمت بتدريبها للتو.

export_model = tf.keras.Sequential([
  vectorize_layer,
  model,
  layers.Activation('sigmoid')
])

export_model.compile(
    loss=losses.BinaryCrossentropy(from_logits=False), optimizer="adam", metrics=['accuracy']
)

# Test it with `raw_test_ds`, which yields raw strings
loss, accuracy = export_model.evaluate(raw_test_ds)
print(accuracy)
782/782 [==============================] - 3s 3ms/step - loss: 0.3101 - accuracy: 0.8736
0.8736400008201599

الاستدلال على البيانات الجديدة

للحصول على توقعات للحصول على أمثلة جديدة، يمكنك ببساطة الاتصال model.predict() .

examples = [
  "The movie was great!",
  "The movie was okay.",
  "The movie was terrible..."
]

export_model.predict(examples)
array([[0.61295563],
       [0.43563995],
       [0.3546928 ]], dtype=float32)

بما في ذلك منطق النص تجهيزها داخل النموذج الخاص بك يتيح لك تصدير نموذج للإنتاج أن يبسط نشر، ويقلل من احتمالات قطار / اختبار الانحراف .

هناك اختلاف في الأداء يجب مراعاته عند اختيار مكان تطبيق طبقة TextVectorization. يتيح لك استخدامه خارج النموذج الخاص بك القيام بمعالجة غير متزامنة لوحدة المعالجة المركزية وتخزين بياناتك مؤقتًا عند التدريب على وحدة معالجة الرسومات. لذلك ، إذا كنت تقوم بتدريب النموذج الخاص بك على وحدة معالجة الرسومات ، فربما ترغب في استخدام هذا الخيار للحصول على أفضل أداء أثناء تطوير النموذج الخاص بك ، ثم قم بالتبديل إلى تضمين طبقة TextVectorization داخل النموذج الخاص بك عندما تكون جاهزًا للاستعداد للنشر .

زيارة هذا البرنامج التعليمي لمعرفة المزيد حول حفظ النماذج.

تمرين: تصنيف متعدد الفئات لأسئلة Stack Overflow

أظهر هذا البرنامج التعليمي كيفية تدريب مصنف ثنائي من البداية على مجموعة بيانات IMDB. باعتبارها ممارسة، يمكنك تعديل هذا الكمبيوتر الدفتري لتدريب المصنف متعدد الطبقات للتنبؤ علامة سؤال البرمجة على تجاوز المكدس .

A مجموعة البيانات وأعد لتتمكن من استخدامها التي تحتوي على مجموعة من عدة آلاف من مسائل البرمجة (على سبيل المثال، "كيف يمكن فرز القاموس من حيث القيمة في بيثون؟") نشرت على تجاوز المكدس. يتم تصنيف كل منها بعلامة واحدة بالضبط (إما Python أو CSharp أو JavaScript أو Java). مهمتك هي أن تأخذ سؤالاً كمدخلات ، وتوقع العلامة المناسبة ، في هذه الحالة ، Python.

مجموعة البيانات التي ستعمل مع يحتوي على عدة آلاف من الأسئلة المستخرج من أكبر جمهور تجاوز المكدس بيانات في الاستعلام الشامل ، والذي يحتوي على أكثر من 17 مليون وظيفة.

بعد تنزيل مجموعة البيانات ، ستجد أنها تحتوي على بنية دليل مشابهة لمجموعة بيانات IMDB التي عملت معها سابقًا:

train/
...python/
......0.txt
......1.txt
...javascript/
......0.txt
......1.txt
...csharp/
......0.txt
......1.txt
...java/
......0.txt
......1.txt

لإكمال هذا التمرين ، يجب عليك تعديل دفتر الملاحظات هذا للعمل مع مجموعة بيانات Stack Overflow عن طريق إجراء التعديلات التالية:

  1. في الجزء العلوي من الكمبيوتر المحمول، قم بتحديث التعليمات البرمجية التي التنزيلات مجموعة البيانات IMDB مع رمز لتحميل بيانات تجاوز المكدس التي تم prepreared. نظرًا لأن مجموعة بيانات Stack Overflow لها بنية دليل مماثلة ، فلن تحتاج إلى إجراء العديد من التعديلات.

  2. تعديل طبقة الأخيرة من النموذج الخاص بك لقراءة Dense(4) ، كما أن هناك الآن أربع فئات الانتاج.

  3. عند ترجمة هذا النموذج، تغيير الخسارة إلى tf.keras.losses.SparseCategoricalCrossentropy . هذه هي وظيفة فقدان الصحيحة لاستخدام لمشكلة تصنيف متعدد الطبقات، عندما التسميات لكل فئة هي الأعداد الصحيحة (في هذه الحالة، يمكن أن تكون 0، أو 3). وبالإضافة إلى ذلك، تغيير المقاييس ل metrics=['accuracy'] ، لأن هذه مشكلة تصنيف متعدد الطبقات ( tf.metrics.BinaryAccuracy يستخدم فقط للمصنفات الثنائية).

  4. عندما يخططون دقة مع مرور الوقت، وتغير binary_accuracy و val_binary_accuracy إلى accuracy و val_accuracy ، على التوالي.

  5. بمجرد اكتمال هذه التغييرات ، ستتمكن من تدريب مصنف متعدد الفئات.

تعلم المزيد

قدم هذا البرنامج التعليمي تصنيف النص من البداية. لمعرفة المزيد حول سير العمل تصنيف النص بشكل عام، وتحقق من دليل تصنيف النص من جوجل للمطورين.

# MIT License
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.