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

قم بتحميل DataFrame الباندا

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

ويقدم هذا البرنامج التعليمي أمثلة على كيفية تحميل الباندا DataFrames إلى TensorFlow.

سوف تستخدم صغير بيانات أمراض القلب التي توفرها UCI آلة التعلم مستودع. هناك عدة مئات من الصفوف في ملف CSV. يصف كل صف مريضًا ، ويصف كل عمود سمة. ستستخدم هذه المعلومات للتنبؤ بما إذا كان المريض يعاني من أمراض القلب ، وهي مهمة تصنيف ثنائية.

قراءة البيانات باستخدام الباندا

import pandas as pd
import tensorflow as tf

SHUFFLE_BUFFER = 500
BATCH_SIZE = 2

قم بتنزيل ملف CSV الذي يحتوي على مجموعة بيانات أمراض القلب:

csv_file = tf.keras.utils.get_file('heart.csv', 'https://storage.googleapis.com/download.tensorflow.org/data/heart.csv')
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/heart.csv
16384/13273 [=====================================] - 0s 0us/step
24576/13273 [=======================================================] - 0s 0us/step

اقرأ ملف CSV باستخدام الباندا:

df = pd.read_csv(csv_file)

هذا ما تبدو عليه البيانات:

df.head()
df.dtypes
age           int64
sex           int64
cp            int64
trestbps      int64
chol          int64
fbs           int64
restecg       int64
thalach       int64
exang         int64
oldpeak     float64
slope         int64
ca            int64
thal         object
target        int64
dtype: object

سوف بناء نماذج للتنبؤ التسمية الواردة في target العمود.

target = df.pop('target')

DataFrame كمصفوفة

إذا كانت البيانات لديه نوع بيانات موحدة، أو dtype ، انها ممكنا استخدام الباندا DataFrame في أي مكان يمكن استخدام مجموعة نمباي. يعمل هذا لأن pandas.DataFrame الطبقة تدعم __array__ البروتوكول، وTensorFlow في tf.convert_to_tensor وظيفة يقبل الأشياء التي تدعم بروتوكول.

خذ الميزات الرقمية من مجموعة البيانات (تخطي الميزات الفئوية في الوقت الحالي):

numeric_feature_names = ['age', 'thalach', 'trestbps',  'chol', 'oldpeak']
numeric_features = df[numeric_feature_names]
numeric_features.head()

وDataFrame يمكن تحويلها إلى مجموعة نمباي باستخدام DataFrame.values الملكية أو numpy.array(df) . لتحويله إلى موتر، واستخدام tf.convert_to_tensor :

tf.convert_to_tensor(numeric_features)
<tf.Tensor: shape=(303, 5), dtype=float64, numpy=
array([[ 63. , 150. , 145. , 233. ,   2.3],
       [ 67. , 108. , 160. , 286. ,   1.5],
       [ 67. , 129. , 120. , 229. ,   2.6],
       ...,
       [ 65. , 127. , 135. , 254. ,   2.8],
       [ 48. , 150. , 130. , 256. ,   0. ],
       [ 63. , 154. , 150. , 407. ,   4. ]])>

بشكل عام، إذا كان من الممكن تحويل كائن إلى موتر مع tf.convert_to_tensor أنها يمكن أن تنتقل إلى أي مكان يمكنك تمرير tf.Tensor .

مع Model.fit

A DataFrame، يفسر على أنه موتر واحد، ويمكن استخدامها مباشرة كحجة ل Model.fit الأسلوب.

يوجد أدناه مثال لتدريب نموذج على السمات الرقمية لمجموعة البيانات.

الخطوة الأولى هي تسوية نطاقات الإدخال. استخدام tf.keras.layers.Normalization طبقة لذلك.

لضبط الطبقة الوسطي والمعايير الانحراف قبل تشغيله ومن المؤكد أن استدعاء Normalization.adapt الأسلوب:

normalizer = tf.keras.layers.Normalization(axis=-1)
normalizer.adapt(numeric_features)

قم باستدعاء الطبقة الموجودة في الصفوف الثلاثة الأولى من DataFrame لتصور مثال على الإخراج من هذه الطبقة:

normalizer(numeric_features.iloc[:3])
<tf.Tensor: shape=(3, 5), dtype=float32, numpy=
array([[ 0.93383914,  0.03480718,  0.74578077, -0.26008663,  1.0680453 ],
       [ 1.3782105 , -1.7806165 ,  1.5923285 ,  0.7573877 ,  0.38022864],
       [ 1.3782105 , -0.87290466, -0.6651321 , -0.33687714,  1.3259765 ]],
      dtype=float32)>

استخدم طبقة التسوية كطبقة أولى لنموذج بسيط:

def get_basic_model():
  model = tf.keras.Sequential([
    normalizer,
    tf.keras.layers.Dense(10, activation='relu'),
    tf.keras.layers.Dense(10, activation='relu'),
    tf.keras.layers.Dense(1)
  ])

  model.compile(optimizer='adam',
                loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
                metrics=['accuracy'])
  return model

عند تمرير DataFrame باسم x حجة ل Model.fit ، ويعامل Keras وDataFrame لانها ستكون مجموعة نمباي:

model = get_basic_model()
model.fit(numeric_features, target, epochs=15, batch_size=BATCH_SIZE)
Epoch 1/15
152/152 [==============================] - 1s 2ms/step - loss: 0.6405 - accuracy: 0.7789
Epoch 2/15
152/152 [==============================] - 0s 2ms/step - loss: 0.5510 - accuracy: 0.7426
Epoch 3/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4935 - accuracy: 0.7459
Epoch 4/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4649 - accuracy: 0.7558
Epoch 5/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4492 - accuracy: 0.7624
Epoch 6/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4404 - accuracy: 0.7624
Epoch 7/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4350 - accuracy: 0.7789
Epoch 8/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4307 - accuracy: 0.7888
Epoch 9/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4291 - accuracy: 0.7756
Epoch 10/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4262 - accuracy: 0.7822
Epoch 11/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4242 - accuracy: 0.7855
Epoch 12/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4227 - accuracy: 0.7789
Epoch 13/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4229 - accuracy: 0.7987
Epoch 14/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4207 - accuracy: 0.7954
Epoch 15/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4212 - accuracy: 0.7822
<keras.callbacks.History at 0x7f52dc52b8d0>

مع tf.data

إذا كنت ترغب في تطبيق tf.data التحولات إلى DataFrame من موحد dtype ، و Dataset.from_tensor_slices وطريقة إنشاء مجموعة البيانات التي بالتكرار عبر الصفوف من DataFrame. كل صف هو في البداية متجه من القيم. لتدريب نموذج، تحتاج (inputs, labels) أزواج، حتى تمر (features, labels) و Dataset.from_tensor_slices سيعود أزواج الحاجة للشرائح:

numeric_dataset = tf.data.Dataset.from_tensor_slices((numeric_features, target))

for row in numeric_dataset.take(3):
  print(row)
(<tf.Tensor: shape=(5,), dtype=float64, numpy=array([ 63. , 150. , 145. , 233. ,   2.3])>, <tf.Tensor: shape=(), dtype=int64, numpy=0>)
(<tf.Tensor: shape=(5,), dtype=float64, numpy=array([ 67. , 108. , 160. , 286. ,   1.5])>, <tf.Tensor: shape=(), dtype=int64, numpy=1>)
(<tf.Tensor: shape=(5,), dtype=float64, numpy=array([ 67. , 129. , 120. , 229. ,   2.6])>, <tf.Tensor: shape=(), dtype=int64, numpy=0>)
numeric_batches = numeric_dataset.shuffle(1000).batch(BATCH_SIZE)

model = get_basic_model()
model.fit(numeric_batches, epochs=15)
Epoch 1/15
152/152 [==============================] - 1s 2ms/step - loss: 0.6827 - accuracy: 0.7393
Epoch 2/15
152/152 [==============================] - 0s 2ms/step - loss: 0.6239 - accuracy: 0.7327
Epoch 3/15
152/152 [==============================] - 0s 2ms/step - loss: 0.5740 - accuracy: 0.7327
Epoch 4/15
152/152 [==============================] - 0s 2ms/step - loss: 0.5316 - accuracy: 0.7360
Epoch 5/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4957 - accuracy: 0.7426
Epoch 6/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4726 - accuracy: 0.7591
Epoch 7/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4569 - accuracy: 0.7822
Epoch 8/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4482 - accuracy: 0.7723
Epoch 9/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4417 - accuracy: 0.7855
Epoch 10/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4379 - accuracy: 0.7855
Epoch 11/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4356 - accuracy: 0.7888
Epoch 12/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4326 - accuracy: 0.7888
Epoch 13/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4308 - accuracy: 0.7855
Epoch 14/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4288 - accuracy: 0.8020
Epoch 15/15
152/152 [==============================] - 0s 2ms/step - loss: 0.4267 - accuracy: 0.7888
<keras.callbacks.History at 0x7f52dc35db10>

A DataFrame بمثابة قاموس

عندما تبدأ في التعامل مع البيانات غير المتجانسة ، لم يعد من الممكن التعامل مع DataFrame كما لو كان مصفوفة واحدة. تتطلب التنسورات TensorFlow أن جميع العناصر لديها نفس dtype .

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

tf.data أنابيب المدخلات التعامل مع هذا بشكل جيد. كل tf.data التعامل مع عمليات القواميس والصفوف تلقائيا. لذلك، لجعل مجموعة بيانات من القاموس أمثلة من DataFrame، فقط ألقها إلى ديكت تشريح مع قبل Dataset.from_tensor_slices :

numeric_dict_ds = tf.data.Dataset.from_tensor_slices((dict(numeric_features), target))

فيما يلي الأمثلة الثلاثة الأولى من مجموعة البيانات هذه:

for row in numeric_dict_ds.take(3):
  print(row)
({'age': <tf.Tensor: shape=(), dtype=int64, numpy=63>, 'thalach': <tf.Tensor: shape=(), dtype=int64, numpy=150>, 'trestbps': <tf.Tensor: shape=(), dtype=int64, numpy=145>, 'chol': <tf.Tensor: shape=(), dtype=int64, numpy=233>, 'oldpeak': <tf.Tensor: shape=(), dtype=float64, numpy=2.3>}, <tf.Tensor: shape=(), dtype=int64, numpy=0>)
({'age': <tf.Tensor: shape=(), dtype=int64, numpy=67>, 'thalach': <tf.Tensor: shape=(), dtype=int64, numpy=108>, 'trestbps': <tf.Tensor: shape=(), dtype=int64, numpy=160>, 'chol': <tf.Tensor: shape=(), dtype=int64, numpy=286>, 'oldpeak': <tf.Tensor: shape=(), dtype=float64, numpy=1.5>}, <tf.Tensor: shape=(), dtype=int64, numpy=1>)
({'age': <tf.Tensor: shape=(), dtype=int64, numpy=67>, 'thalach': <tf.Tensor: shape=(), dtype=int64, numpy=129>, 'trestbps': <tf.Tensor: shape=(), dtype=int64, numpy=120>, 'chol': <tf.Tensor: shape=(), dtype=int64, numpy=229>, 'oldpeak': <tf.Tensor: shape=(), dtype=float64, numpy=2.6>}, <tf.Tensor: shape=(), dtype=int64, numpy=0>)

قواميس مع Keras

عادةً ما تتوقع نماذج وطبقات Keras وجود موتر إدخال فردي ، ولكن يمكن لهذه الفئات قبول وإرجاع الهياكل المتداخلة للقواميس ، و tuples ، و tensors. وتعرف هذه الهياكل باسم "أعشاش" (يرجى الرجوع إلى tf.nest وحدة لمزيد من التفاصيل).

هناك طريقتان مكافئتان لكتابة نموذج keras يقبل القاموس كمدخلات.

1. نمط الفئة الفرعية النموذجية

أن تكتب فئة فرعية من tf.keras.Model (أو tf.keras.Layer ). أنت تتعامل مباشرة مع المدخلات ، وتقوم بإنشاء المخرجات:

def stack_dict(inputs, fun=tf.stack):
    values = []
    for key in sorted(inputs.keys()):
      values.append(tf.cast(inputs[key], tf.float32))

    return fun(values, axis=-1)
class MyModel(tf.keras.Model):
  def __init__(self):
    # Create all the internal layers in init.
    super().__init__(self)

    self.normalizer = tf.keras.layers.Normalization(axis=-1)

    self.seq = tf.keras.Sequential([
      self.normalizer,
      tf.keras.layers.Dense(10, activation='relu'),
      tf.keras.layers.Dense(10, activation='relu'),
      tf.keras.layers.Dense(1)
    ])

  def adapt(self, inputs):
    # Stach the inputs and `adapt` the normalization layer.
    inputs = stack_dict(inputs)
    self.normalizer.adapt(inputs)

  def call(self, inputs):
    # Stack the inputs
    inputs = stack_dict(inputs)
    # Run them through all the layers.
    result = self.seq(inputs)

    return result

model = MyModel()

model.adapt(dict(numeric_features))

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'],
              run_eagerly=True)

يمكن لهذا النموذج أن يقبل إما قاموس الأعمدة أو مجموعة بيانات من عناصر القاموس للتدريب:

model.fit(dict(numeric_features), target, epochs=5, batch_size=BATCH_SIZE)
Epoch 1/5
152/152 [==============================] - 2s 16ms/step - loss: 0.5968 - accuracy: 0.7261
Epoch 2/5
152/152 [==============================] - 2s 15ms/step - loss: 0.5182 - accuracy: 0.7261
Epoch 3/5
152/152 [==============================] - 2s 15ms/step - loss: 0.4738 - accuracy: 0.7360
Epoch 4/5
152/152 [==============================] - 2s 15ms/step - loss: 0.4515 - accuracy: 0.7525
Epoch 5/5
152/152 [==============================] - 2s 15ms/step - loss: 0.4405 - accuracy: 0.7756
<keras.callbacks.History at 0x7f52dc165990>
numeric_dict_batches = numeric_dict_ds.shuffle(SHUFFLE_BUFFER).batch(BATCH_SIZE)
model.fit(numeric_dict_batches, epochs=5)
Epoch 1/5
152/152 [==============================] - 3s 17ms/step - loss: 0.4345 - accuracy: 0.7789
Epoch 2/5
152/152 [==============================] - 2s 15ms/step - loss: 0.4298 - accuracy: 0.7822
Epoch 3/5
152/152 [==============================] - 2s 15ms/step - loss: 0.4273 - accuracy: 0.7789
Epoch 4/5
152/152 [==============================] - 2s 15ms/step - loss: 0.4246 - accuracy: 0.7855
Epoch 5/5
152/152 [==============================] - 2s 15ms/step - loss: 0.4225 - accuracy: 0.7921
<keras.callbacks.History at 0x7f52dc0d4690>

فيما يلي تنبؤات الأمثلة الثلاثة الأولى:

model.predict(dict(numeric_features.iloc[:3]))
array([[[ 0.14884435]],

       [[ 0.37460226]],

       [[-0.08134247]]], dtype=float32)

2. أسلوب Keras الوظيفي

inputs = {}
for name, column in numeric_features.items():
  inputs[name] = tf.keras.Input(
      shape=(1,), name=name, dtype=tf.float32)

inputs
{'age': <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'age')>,
 'thalach': <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'thalach')>,
 'trestbps': <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'trestbps')>,
 'chol': <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'chol')>,
 'oldpeak': <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'oldpeak')>}
x = stack_dict(inputs, fun=tf.concat)

normalizer = tf.keras.layers.Normalization(axis=-1)
normalizer.adapt(stack_dict(dict(numeric_features)))

x = normalizer(x)
x = tf.keras.layers.Dense(10, activation='relu')(x)
x = tf.keras.layers.Dense(10, activation='relu')(x)
x = tf.keras.layers.Dense(1)(x)

model = tf.keras.Model(inputs, x)

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'],
              run_eagerly=True)
tf.keras.utils.plot_model(model, rankdir="LR", show_shapes=True)

بي إن جي

يمكنك تدريب النموذج الوظيفي بنفس طريقة تدريب الفئة الفرعية للنموذج:

model.fit(dict(numeric_features), target, epochs=5, batch_size=BATCH_SIZE)
Epoch 1/5
152/152 [==============================] - 2s 14ms/step - loss: 0.7151 - accuracy: 0.7030
Epoch 2/5
152/152 [==============================] - 2s 14ms/step - loss: 0.5883 - accuracy: 0.7360
Epoch 3/5
152/152 [==============================] - 2s 14ms/step - loss: 0.5205 - accuracy: 0.7360
Epoch 4/5
152/152 [==============================] - 2s 15ms/step - loss: 0.4838 - accuracy: 0.7492
Epoch 5/5
152/152 [==============================] - 2s 15ms/step - loss: 0.4622 - accuracy: 0.7492
<keras.callbacks.History at 0x7f52bc7b2690>
numeric_dict_batches = numeric_dict_ds.shuffle(SHUFFLE_BUFFER).batch(BATCH_SIZE)
model.fit(numeric_dict_batches, epochs=5)
Epoch 1/5
152/152 [==============================] - 2s 14ms/step - loss: 0.4487 - accuracy: 0.7723
Epoch 2/5
152/152 [==============================] - 2s 14ms/step - loss: 0.4392 - accuracy: 0.7789
Epoch 3/5
152/152 [==============================] - 2s 14ms/step - loss: 0.4339 - accuracy: 0.7789
Epoch 4/5
152/152 [==============================] - 2s 14ms/step - loss: 0.4303 - accuracy: 0.7789
Epoch 5/5
152/152 [==============================] - 2s 14ms/step - loss: 0.4269 - accuracy: 0.7855
<keras.callbacks.History at 0x7f52dc0d4910>

المثال الكامل

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

بناء رأس المعالجة المسبقة

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

من ناحية أخرى ، لا تحتاج الميزات الثنائية عمومًا إلى الترميز أو التسوية.

ابدأ بإنشاء قائمة بالميزات التي تقع في كل مجموعة:

binary_feature_names = ['sex', 'fbs', 'exang']
categorical_feature_names = ['cp', 'restecg', 'slope', 'thal', 'ca']

تتمثل الخطوة التالية في بناء نموذج معالجة مسبقة يطبق معالجة مسبقة مناسبة لكل مدخل على كل مدخل ويربط النتائج.

يستخدم هذا القسم API الوظيفي Keras لتنفيذ تجهيزها. عليك أن تبدأ من خلال خلق واحدة tf.keras.Input لكل عمود من dataframe:

inputs = {}
for name, column in df.items():
  if type(column[0]) == str:
    dtype = tf.string
  elif (name in categorical_feature_names or
        name in binary_feature_names):
    dtype = tf.int64
  else:
    dtype = tf.float32

  inputs[name] = tf.keras.Input(shape=(), name=name, dtype=dtype)
inputs
{'age': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'age')>,
 'sex': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'sex')>,
 'cp': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'cp')>,
 'trestbps': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'trestbps')>,
 'chol': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'chol')>,
 'fbs': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'fbs')>,
 'restecg': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'restecg')>,
 'thalach': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'thalach')>,
 'exang': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'exang')>,
 'oldpeak': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'oldpeak')>,
 'slope': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'slope')>,
 'ca': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'ca')>,
 'thal': <KerasTensor: shape=(None,) dtype=string (created by layer 'thal')>}

لكل إدخال ، ستقوم بتطبيق بعض التحويلات باستخدام طبقات Keras و TensorFlow ops. يبدأ كل ميزة كدفعة من سكالارس ( shape=(batch,) ). يجب أن يكون الإخراج لكل دفعة من tf.float32 ناقلات ( shape=(batch, n) ). ستجمع الخطوة الأخيرة كل هذه النواقل معًا.

المدخلات الثنائية

منذ المدخلات الثنائية لا تحتاج إلى أي تجهيزها، وأضيف محور ناقلات، ويلقي لهم float32 وإضافتها إلى قائمة المدخلات preprocessed:

preprocessed = []

for name in binary_feature_names:
  inp = inputs[name]
  inp = inp[:, tf.newaxis]
  float_value = tf.cast(inp, tf.float32)
  preprocessed.append(float_value)

preprocessed
[<KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'tf.cast_5')>,
 <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'tf.cast_6')>,
 <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'tf.cast_7')>]

المدخلات الرقمية

كما هو الحال في الجزء السابق سترغب في تشغيل هذه المدخلات الرقمية من خلال tf.keras.layers.Normalization طبقة قبل استخدامها. الفرق هو أنهم هذه المرة يتم إدخالهم كإملاء. رمز أدناه بجمع الميزات الرقمية من DataFrame، مداخن بعضهم البعض، ويمر هؤلاء إلى Normalization.adapt الأسلوب.

normalizer = tf.keras.layers.Normalization(axis=-1)
normalizer.adapt(stack_dict(dict(numeric_features)))

يقوم الكود أدناه بتكديس الميزات الرقمية وتشغيلها عبر طبقة التسوية.

numeric_inputs = {}
for name in numeric_feature_names:
  numeric_inputs[name]=inputs[name]

numeric_inputs = stack_dict(numeric_inputs)
numeric_normalized = normalizer(numeric_inputs)

preprocessed.append(numeric_normalized)

preprocessed
[<KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'tf.cast_5')>,
 <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'tf.cast_6')>,
 <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'tf.cast_7')>,
 <KerasTensor: shape=(None, 5) dtype=float32 (created by layer 'normalization_3')>]

الميزات الفئوية

لاستخدام الميزات الفئوية ، ستحتاج أولاً إلى ترميزها إما في متجهات ثنائية أو في حفلات الزفاف. وبما أن هذه الميزات يحتوي إلا على عدد قليل من الفئات، وتحويل المدخلات مباشرة إلى ناقلات الساخنة واحد باستخدام output_mode='one_hot' الخيار، بدعم byy كل من tf.keras.layers.StringLookup و tf.keras.layers.IntegerLookup طبقات.

فيما يلي مثال على كيفية عمل هذه الطبقات:

vocab = ['a','b','c']
lookup = tf.keras.layers.StringLookup(vocabulary=vocab, output_mode='one_hot')
lookup(['c','a','a','b','zzz'])
<tf.Tensor: shape=(5, 4), dtype=float32, numpy=
array([[0., 0., 0., 1.],
       [0., 1., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [1., 0., 0., 0.]], dtype=float32)>
vocab = [1,4,7,99]
lookup = tf.keras.layers.IntegerLookup(vocabulary=vocab, output_mode='one_hot')

lookup([-1,4,1])
<tf.Tensor: shape=(3, 5), dtype=float32, numpy=
array([[1., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 1., 0., 0., 0.]], dtype=float32)>

لتحديد المفردات لكل إدخال ، قم بإنشاء طبقة لتحويل تلك المفردات إلى متجه واحد ساخن:

for name in categorical_feature_names:
  vocab = sorted(set(df[name]))
  print(f'name: {name}')
  print(f'vocab: {vocab}\n')

  if type(vocab[0]) is str:
    lookup = tf.keras.layers.StringLookup(vocabulary=vocab, output_mode='one_hot')
  else:
    lookup = tf.keras.layers.IntegerLookup(vocabulary=vocab, output_mode='one_hot')

  x = inputs[name][:, tf.newaxis]
  x = lookup(x)
  preprocessed.append(x)
name: cp
vocab: [0, 1, 2, 3, 4]

name: restecg
vocab: [0, 1, 2]

name: slope
vocab: [1, 2, 3]

name: thal
vocab: ['1', '2', 'fixed', 'normal', 'reversible']

name: ca
vocab: [0, 1, 2, 3]

قم بتجميع رأس المعالجة المسبقة

عند هذه النقطة preprocessed هي مجرد قائمة بيثون من كل النتائج تجهيزها، كل نتيجة لها شكل (batch_size, depth) :

preprocessed
[<KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'tf.cast_5')>,
 <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'tf.cast_6')>,
 <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'tf.cast_7')>,
 <KerasTensor: shape=(None, 5) dtype=float32 (created by layer 'normalization_3')>,
 <KerasTensor: shape=(None, 6) dtype=float32 (created by layer 'integer_lookup_1')>,
 <KerasTensor: shape=(None, 4) dtype=float32 (created by layer 'integer_lookup_2')>,
 <KerasTensor: shape=(None, 4) dtype=float32 (created by layer 'integer_lookup_3')>,
 <KerasTensor: shape=(None, 6) dtype=float32 (created by layer 'string_lookup_1')>,
 <KerasTensor: shape=(None, 5) dtype=float32 (created by layer 'integer_lookup_4')>]

سلسلة كافة الميزات preprocessed على depth محور، بحيث يتم تحويل كل القاموس سبيل المثال في ناقلات واحد. يحتوي المتجه على ميزات فئوية وميزات رقمية وميزات فئوية واحدة ساخنة:

preprocesssed_result = tf.concat(preprocessed, axis=-1)
preprocesssed_result
<KerasTensor: shape=(None, 33) dtype=float32 (created by layer 'tf.concat_1')>

الآن قم بإنشاء نموذج من هذا الحساب حتى يمكن إعادة استخدامه:

preprocessor = tf.keras.Model(inputs, preprocesssed_result)
tf.keras.utils.plot_model(preprocessor, rankdir="LR", show_shapes=True)

بي إن جي

لاختبار المعالج، استخدم DataFrame.iloc استرجاع لشريحة المثال الأول من DataFrame. ثم قم بتحويله إلى قاموس وقم بتمرير القاموس إلى المعالج المسبق. والنتيجة هي متجه واحد يحتوي على السمات الثنائية ، والسمات الرقمية الطبيعية والميزات الفئوية الساخنة ، بالترتيب التالي:

preprocessor(dict(df.iloc[:1]))
<tf.Tensor: shape=(1, 33), dtype=float32, numpy=
array([[ 1.        ,  1.        ,  0.        ,  0.93383914, -0.26008663,
         1.0680453 ,  0.03480718,  0.74578077,  0.        ,  0.        ,

         1.        ,  0.        ,  0.        ,  0.        ,  0.        ,
         0.        ,  0.        ,  1.        ,  0.        ,  0.        ,
         0.        ,  1.        ,  0.        ,  0.        ,  0.        ,
         1.        ,  0.        ,  0.        ,  0.        ,  1.        ,
         0.        ,  0.        ,  0.        ]], dtype=float32)>

إنشاء وتدريب نموذج

الآن قم ببناء الجسم الرئيسي للنموذج. استخدام نفس التكوين كما في المثال السابق: زوجان من Dense طبقات والخطية تصحيح- Dense(1) طبقة الإخراج للتصنيف.

body = tf.keras.Sequential([
  tf.keras.layers.Dense(10, activation='relu'),
  tf.keras.layers.Dense(10, activation='relu'),
  tf.keras.layers.Dense(1)
])

الآن ضع القطعتين معًا باستخدام واجهة برمجة تطبيقات Keras الوظيفية.

inputs
{'age': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'age')>,
 'sex': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'sex')>,
 'cp': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'cp')>,
 'trestbps': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'trestbps')>,
 'chol': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'chol')>,
 'fbs': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'fbs')>,
 'restecg': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'restecg')>,
 'thalach': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'thalach')>,
 'exang': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'exang')>,
 'oldpeak': <KerasTensor: shape=(None,) dtype=float32 (created by layer 'oldpeak')>,
 'slope': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'slope')>,
 'ca': <KerasTensor: shape=(None,) dtype=int64 (created by layer 'ca')>,
 'thal': <KerasTensor: shape=(None,) dtype=string (created by layer 'thal')>}
x = preprocessor(inputs)
x
<KerasTensor: shape=(None, 33) dtype=float32 (created by layer 'model_1')>
result = body(x)
result
<KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'sequential_3')>
model = tf.keras.Model(inputs, result)

model.compile(optimizer='adam',
                loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
                metrics=['accuracy'])

يتوقع هذا النموذج قاموس المدخلات. إن أبسط طريقة لتمرير ذلك البيانات هو تحويل DataFrame إلى ديكت وتمرير ذلك ديكت كما x حجة ل Model.fit :

history = model.fit(dict(df), target, epochs=5, batch_size=BATCH_SIZE)
Epoch 1/5
152/152 [==============================] - 1s 4ms/step - loss: 0.5340 - accuracy: 0.7558
Epoch 2/5
152/152 [==============================] - 1s 4ms/step - loss: 0.4038 - accuracy: 0.7789
Epoch 3/5
152/152 [==============================] - 1s 4ms/step - loss: 0.3515 - accuracy: 0.8218
Epoch 4/5
152/152 [==============================] - 1s 4ms/step - loss: 0.3262 - accuracy: 0.8482
Epoch 5/5
152/152 [==============================] - 1s 4ms/step - loss: 0.3087 - accuracy: 0.8680

باستخدام tf.data يعمل أيضا:

ds = tf.data.Dataset.from_tensor_slices((
    dict(df),
    target
))

ds = ds.batch(BATCH_SIZE)
import pprint

for x, y in ds.take(1):
  pprint.pprint(x)
  print()
  print(y)
{'age': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([63, 67])>,
 'ca': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([0, 3])>,
 'chol': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([233, 286])>,
 'cp': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([1, 4])>,
 'exang': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([0, 1])>,
 'fbs': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([1, 0])>,
 'oldpeak': <tf.Tensor: shape=(2,), dtype=float64, numpy=array([2.3, 1.5])>,
 'restecg': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([2, 2])>,
 'sex': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([1, 1])>,
 'slope': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([3, 2])>,
 'thal': <tf.Tensor: shape=(2,), dtype=string, numpy=array([b'fixed', b'normal'], dtype=object)>,
 'thalach': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([150, 108])>,
 'trestbps': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([145, 160])>}

tf.Tensor([0 1], shape=(2,), dtype=int64)
history = model.fit(ds, epochs=5)
Epoch 1/5
152/152 [==============================] - 1s 4ms/step - loss: 0.2982 - accuracy: 0.8581
Epoch 2/5
152/152 [==============================] - 1s 5ms/step - loss: 0.2898 - accuracy: 0.8647
Epoch 3/5
152/152 [==============================] - 1s 5ms/step - loss: 0.2831 - accuracy: 0.8680
Epoch 4/5
152/152 [==============================] - 1s 5ms/step - loss: 0.2772 - accuracy: 0.8680
Epoch 5/5
152/152 [==============================] - 1s 4ms/step - loss: 0.2720 - accuracy: 0.8680