Giúp bảo vệ Great Barrier Reef với TensorFlow trên Kaggle Tham Challenge

Phân loại dữ liệu có cấu trúc với các cột tính năng

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải xuống sổ ghi chép

Hướng dẫn này trình bày cách phân loại dữ liệu có cấu trúc (ví dụ: dữ liệu dạng bảng trong CSV). Chúng tôi sẽ sử dụng Keras để xác định mô hình, và tf.feature_column như một cầu nối để ánh xạ từ cột trong một CSV để tính năng dùng để huấn luyện mô hình. Hướng dẫn này chứa mã hoàn chỉnh để:

  • Tải một tập tin CSV bằng Pandas .
  • Xây dựng một đường ống đầu vào cho hàng loạt và shuffle hàng sử dụng tf.data .
  • Ánh xạ từ các cột trong CSV đến các đối tượng địa lý được sử dụng để đào tạo mô hình bằng cách sử dụng các cột đối tượng địa lý.
  • Xây dựng, đào tạo và đánh giá một mô hình bằng Keras.

Tập dữ liệu

Chúng tôi sẽ sử dụng một phiên bản đơn giản của PetFinder bộ dữ liệu . Có vài nghìn hàng trong CSV. Mỗi hàng mô tả một con vật cưng và mỗi cột mô tả một thuộc tính. Chúng tôi sẽ sử dụng thông tin này để dự đoán tốc độ vật nuôi sẽ được nhận nuôi.

Sau đây là mô tả của tập dữ liệu này. Lưu ý rằng có cả cột số và cột phân loại. Có một cột văn bản miễn phí mà chúng tôi sẽ không sử dụng trong hướng dẫn này.

Cột Sự miêu tả Loại tính năng Loại dữ liệu
Kiểu Loại động vật (Chó, Mèo) Phân loại dây
Tuổi Tuổi của vật nuôi Số số nguyên
Giống1 Giống vật nuôi chính Phân loại dây
Màu1 Màu 1 của thú cưng Phân loại dây
Màu 2 Màu 2 của thú cưng Phân loại dây
MaturitySize Kích thước khi trưởng thành Phân loại dây
FurLength Chiều dài lông Phân loại dây
Đã tiêm phòng Thú cưng đã được tiêm phòng Phân loại dây
Tiệt trùng Thú cưng đã được triệt sản Phân loại dây
Sức khỏe Tình trạng sức khỏe Phân loại dây
Phí Phí nhận con nuôi Số số nguyên
Sự miêu tả Hồ sơ viết lên cho con vật cưng này Chữ dây
PhotoAmt Tổng số ảnh đã tải lên cho con vật cưng này Số số nguyên
AdoptionSpeed Tốc độ chấp nhận Phân loại số nguyên

Nhập TensorFlow và các thư viện khác

pip install sklearn
import numpy as np
import pandas as pd

import tensorflow as tf

from tensorflow import feature_column
from tensorflow.keras import layers
from sklearn.model_selection import train_test_split

Sử dụng Pandas để tạo khung dữ liệu

Gấu trúc là một thư viện với nhiều tiện ích hữu ích cho tải và làm việc với các dữ liệu có cấu trúc Python. Chúng tôi sẽ sử dụng Pandas để tải xuống tập dữ liệu từ một URL và tải nó vào khung dữ liệu.

import pathlib

dataset_url = 'http://storage.googleapis.com/download.tensorflow.org/data/petfinder-mini.zip'
csv_file = 'datasets/petfinder-mini/petfinder-mini.csv'

tf.keras.utils.get_file('petfinder_mini.zip', dataset_url,
                        extract=True, cache_dir='.')
dataframe = pd.read_csv(csv_file)
Downloading data from http://storage.googleapis.com/download.tensorflow.org/data/petfinder-mini.zip
1671168/1668792 [==============================] - 0s 0us/step
1679360/1668792 [==============================] - 0s 0us/step
dataframe.head()

Tạo biến mục tiêu

Nhiệm vụ trong tập dữ liệu ban đầu là dự đoán tốc độ vật nuôi sẽ được nhận nuôi (ví dụ: trong tuần đầu tiên, tháng đầu tiên, ba tháng đầu tiên, v.v.). Hãy đơn giản hóa điều này cho hướng dẫn của chúng tôi. Ở đây, chúng tôi sẽ chuyển điều này thành một bài toán phân loại nhị phân và chỉ đơn giản là dự đoán liệu vật nuôi có được nhận nuôi hay không.

Sau khi sửa đổi cột nhãn, 0 sẽ cho biết vật nuôi không được nhận nuôi và 1 sẽ cho biết nó đã được nhận.

# In the original dataset "4" indicates the pet was not adopted.
dataframe['target'] = np.where(dataframe['AdoptionSpeed']==4, 0, 1)

# Drop un-used columns.
dataframe = dataframe.drop(columns=['AdoptionSpeed', 'Description'])

Chia khung dữ liệu thành đào tạo, xác thực và kiểm tra

Tập dữ liệu chúng tôi đã tải xuống là một tệp CSV duy nhất. Chúng tôi sẽ chia điều này thành các tập huấn luyện, xác nhận và thử nghiệm.

train, test = train_test_split(dataframe, test_size=0.2)
train, val = train_test_split(train, test_size=0.2)
print(len(train), 'train examples')
print(len(val), 'validation examples')
print(len(test), 'test examples')
7383 train examples
1846 validation examples
2308 test examples

Tạo đường dẫn đầu vào bằng tf.data

Tiếp theo, chúng tôi sẽ quấn dataframes với tf.data . Điều này sẽ cho phép chúng tôi sử dụng các cột tính năng làm cầu nối để ánh xạ từ các cột trong khung dữ liệu Pandas đến các tính năng được sử dụng để đào tạo mô hình. Nếu chúng tôi đang làm việc với một tệp CSV rất lớn (lớn đến mức nó không vừa với bộ nhớ), chúng tôi sẽ sử dụng tf.data để đọc trực tiếp từ đĩa. Điều đó không được đề cập trong hướng dẫn này.

# A utility method to create a tf.data dataset from a Pandas Dataframe
def df_to_dataset(dataframe, shuffle=True, batch_size=32):
  dataframe = dataframe.copy()
  labels = dataframe.pop('target')
  ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
  if shuffle:
    ds = ds.shuffle(buffer_size=len(dataframe))
  ds = ds.batch(batch_size)
  return ds
batch_size = 5 # A small batch sized is used for demonstration purposes
train_ds = df_to_dataset(train, batch_size=batch_size)
val_ds = df_to_dataset(val, shuffle=False, batch_size=batch_size)
test_ds = df_to_dataset(test, shuffle=False, batch_size=batch_size)
2021-08-12 05:35:14.232343: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-12 05:35:14.240910: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-12 05:35:14.241897: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-12 05:35:14.244078: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-08-12 05:35:14.244713: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-12 05:35:14.245783: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-12 05:35:14.246715: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-12 05:35:14.858272: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-12 05:35:14.859347: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-12 05:35:14.860347: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-12 05:35:14.861291: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1510] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 14648 MB memory:  -> device: 0, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:05.0, compute capability: 7.0

Hiểu đường dẫn đầu vào

Bây giờ chúng ta đã tạo xong đường dẫn đầu vào, hãy gọi nó để xem định dạng dữ liệu mà nó trả về. Chúng tôi đã sử dụng kích thước lô nhỏ để giữ cho đầu ra có thể đọc được.

for feature_batch, label_batch in train_ds.take(1):
  print('Every feature:', list(feature_batch.keys()))
  print('A batch of ages:', feature_batch['Age'])
  print('A batch of targets:', label_batch )
Every feature: ['Type', 'Age', 'Breed1', 'Gender', 'Color1', 'Color2', 'MaturitySize', 'FurLength', 'Vaccinated', 'Sterilized', 'Health', 'Fee', 'PhotoAmt']
A batch of ages: tf.Tensor([3 1 7 3 2], shape=(5,), dtype=int64)
A batch of targets: tf.Tensor([0 0 0 1 1], shape=(5,), dtype=int64)

Chúng ta có thể thấy rằng tập dữ liệu trả về một từ điển tên cột (từ khung dữ liệu) ánh xạ tới các giá trị cột từ các hàng trong khung dữ liệu.

Thể hiện một số loại cột tính năng

TensorFlow cung cấp nhiều loại cột tính năng. Trong phần này, chúng tôi sẽ tạo một số loại cột tính năng và trình bày cách chúng chuyển đổi một cột từ khung dữ liệu.

# We will use this batch to demonstrate several types of feature columns
example_batch = next(iter(train_ds))[0]
# A utility method to create a feature column
# and to transform a batch of data
def demo(feature_column):
  feature_layer = layers.DenseFeatures(feature_column)
  print(feature_layer(example_batch).numpy())

Cột số

Đầu ra của một cột tính năng trở thành đầu vào cho mô hình (sử dụng hàm demo được định nghĩa ở trên, chúng ta sẽ có thể thấy chính xác cách mỗi cột từ khung dữ liệu được chuyển đổi). Một cột số là loại đơn giản nhất của cột. Nó được sử dụng để đại diện cho các tính năng có giá trị thực. Khi sử dụng cột này, mô hình của bạn sẽ nhận được giá trị cột từ khung dữ liệu không thay đổi.

photo_count = feature_column.numeric_column('PhotoAmt')
demo(photo_count)
[[1.]
 [1.]
 [6.]
 [2.]
 [1.]]

Trong tập dữ liệu PetFinder, hầu hết các cột từ khung dữ liệu đều được phân loại.

Các cột được bán đấu giá

Thông thường, bạn không muốn đưa một số trực tiếp vào mô hình mà thay vào đó, hãy chia giá trị của nó thành các danh mục khác nhau dựa trên phạm vi số. Xem xét dữ liệu thô đại diện cho tuổi của một người. Thay vì đại diện cho tuổi như một cột số, chúng ta có thể chia thành nhiều tuổi xô sử dụng một cột bucketized . Lưu ý các giá trị duy nhất bên dưới mô tả độ tuổi mà mỗi hàng phù hợp.

age = feature_column.numeric_column('Age')
age_buckets = feature_column.bucketized_column(age, boundaries=[1, 3, 5])
demo(age_buckets)
[[0. 0. 0. 1.]
 [0. 1. 0. 0.]
 [0. 0. 0. 1.]
 [0. 0. 0. 1.]
 [0. 0. 0. 1.]]

Cột phân loại

Trong tập dữ liệu này, Kiểu được biểu diễn dưới dạng một chuỗi (ví dụ: 'Chó' hoặc 'Mèo'). Chúng tôi không thể cấp chuỗi trực tiếp cho một mô hình. Thay vào đó, trước tiên chúng ta phải ánh xạ chúng thành các giá trị số. Các cột từ vựng phân loại cung cấp một cách để biểu diễn các chuỗi dưới dạng một vectơ duy nhất (giống như bạn đã thấy ở trên với các nhóm tuổi). Các từ vựng có thể được thông qua như là một danh sách sử dụng categorical_column_with_vocabulary_list , hoặc nạp từ một tập tin sử dụng categorical_column_with_vocabulary_file .

animal_type = feature_column.categorical_column_with_vocabulary_list(
      'Type', ['Cat', 'Dog'])

animal_type_one_hot = feature_column.indicator_column(animal_type)
demo(animal_type_one_hot)
[[0. 1.]
 [1. 0.]
 [1. 0.]
 [1. 0.]
 [0. 1.]]

Nhúng cột

Giả sử thay vì chỉ có một vài chuỗi khả thi, chúng ta có hàng nghìn (hoặc nhiều hơn) giá trị cho mỗi danh mục. Vì một số lý do, khi số lượng danh mục ngày càng lớn, việc đào tạo mạng nơ-ron bằng cách sử dụng mã hóa một nóng trở nên không khả thi. Chúng ta có thể sử dụng một cột nhúng để khắc phục hạn chế này. Thay vì đại diện cho dữ liệu như một nóng vector của nhiều khía cạnh, một cột nhúng đại diện cho dữ liệu như một vector thấp chiều, dày đặc, trong đó mỗi tế bào có thể chứa bất kỳ số, không chỉ là 0 hoặc 1. Kích thước của nhúng ( 8, trong ví dụ bên dưới) là một tham số phải được điều chỉnh.

# Notice the input to the embedding column is the categorical column
# we previously created
breed1 = feature_column.categorical_column_with_vocabulary_list(
      'Breed1', dataframe.Breed1.unique())
breed1_embedding = feature_column.embedding_column(breed1, dimension=8)
demo(breed1_embedding)
[[-0.29149556  0.14527628 -0.14971544 -0.03371305 -0.18008554 -0.1355874
   0.07782566 -0.25116035]
 [ 0.17409092 -0.5352956   0.17639622  0.14120959  0.06684854 -0.1125162
  -0.29759833  0.13288419]
 [-0.54347     0.12352454  0.2705486   0.38947123  0.03339173 -0.00610726
  -0.07117687 -0.01907084]
 [ 0.42062348  0.62146646 -0.16005716  0.08512937  0.19332875  0.24204789
  -0.03377973  0.47258624]
 [ 0.06813324  0.28805184  0.02640903 -0.05147618  0.6982352  -0.06342584
  -0.1650086  -0.06650425]]

Các cột tính năng băm

Một cách khác để đại diện cho một cột phân loại với một số lượng lớn các giá trị là sử dụng một categorical_column_with_hash_bucket . Cột Tính năng này sẽ tính toán một giá trị hash của đầu vào, sau đó chọn một trong những hash_bucket_size xô để mã hóa một chuỗi. Khi sử dụng cột này, bạn không cần phải cung cấp từ vựng và bạn có thể chọn đặt số lượng băm nhỏ hơn đáng kể so với số danh mục thực tế để tiết kiệm dung lượng.

breed1_hashed = feature_column.categorical_column_with_hash_bucket(
      'Breed1', hash_bucket_size=10)
demo(feature_column.indicator_column(breed1_hashed))
[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]

Các cột tính năng bị chéo

Kết hợp tính năng này vào một tính năng duy nhất, tốt hơn được gọi là thánh giá tính năng , cho phép một mô hình để học hỏi trọng lượng riêng biệt cho mỗi sự kết hợp của tính năng. Ở đây, chúng tôi sẽ tạo ra một tính năng mới đó là sự kết hợp giữa Tuổi và Loại. Lưu ý rằng crossed_column không xây dựng bảng đầy đủ của tất cả các kết hợp có thể (mà có thể là rất lớn). Thay vào đó, nó được hỗ trợ bởi một hashed_column , vì vậy bạn có thể chọn cách lớn bàn là.

crossed_feature = feature_column.crossed_column([age_buckets, animal_type], hash_bucket_size=10)
demo(feature_column.indicator_column(crossed_feature))
[[0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]]

Chọn cột để sử dụng

Chúng tôi đã thấy cách sử dụng một số loại cột tính năng. Bây giờ chúng ta sẽ sử dụng chúng để đào tạo một người mẫu. Mục tiêu của hướng dẫn này là hiển thị cho bạn mã hoàn chỉnh (ví dụ: cơ học) cần thiết để làm việc với các cột tính năng. Chúng tôi đã chọn một vài cột để đào tạo mô hình của chúng tôi bên dưới một cách tùy ý.

feature_columns = []

# numeric cols
for header in ['PhotoAmt', 'Fee', 'Age']:
  feature_columns.append(feature_column.numeric_column(header))
# bucketized cols
age = feature_column.numeric_column('Age')
age_buckets = feature_column.bucketized_column(age, boundaries=[1, 2, 3, 4, 5])
feature_columns.append(age_buckets)
# indicator_columns
indicator_column_names = ['Type', 'Color1', 'Color2', 'Gender', 'MaturitySize',
                          'FurLength', 'Vaccinated', 'Sterilized', 'Health']
for col_name in indicator_column_names:
  categorical_column = feature_column.categorical_column_with_vocabulary_list(
      col_name, dataframe[col_name].unique())
  indicator_column = feature_column.indicator_column(categorical_column)
  feature_columns.append(indicator_column)
# embedding columns
breed1 = feature_column.categorical_column_with_vocabulary_list(
      'Breed1', dataframe.Breed1.unique())
breed1_embedding = feature_column.embedding_column(breed1, dimension=8)
feature_columns.append(breed1_embedding)
# crossed columns
age_type_feature = feature_column.crossed_column([age_buckets, animal_type], hash_bucket_size=100)
feature_columns.append(feature_column.indicator_column(age_type_feature))

Tạo một lớp tính năng

Bây giờ chúng ta đã xác định các cột tính năng của chúng tôi, chúng tôi sẽ sử dụng một DenseFeatures lớp để nhập chúng vào mô hình Keras của chúng tôi.

feature_layer = tf.keras.layers.DenseFeatures(feature_columns)

Trước đó, chúng tôi đã sử dụng kích thước lô nhỏ để chứng minh các cột tính năng hoạt động như thế nào. Chúng tôi tạo một đường dẫn đầu vào mới với quy mô lô lớn hơn.

batch_size = 32
train_ds = df_to_dataset(train, batch_size=batch_size)
val_ds = df_to_dataset(val, shuffle=False, batch_size=batch_size)
test_ds = df_to_dataset(test, shuffle=False, batch_size=batch_size)

Tạo, biên dịch và đào tạo mô hình

model = tf.keras.Sequential([
  feature_layer,
  layers.Dense(128, activation='relu'),
  layers.Dense(128, activation='relu'),
  layers.Dropout(.1),
  layers.Dense(1)
])

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

model.fit(train_ds,
          validation_data=val_ds,
          epochs=10)
Epoch 1/10
WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'Type': <tf.Tensor 'ExpandDims_11:0' shape=(None, 1) dtype=string>, 'Age': <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>, 'Breed1': <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=string>, 'Gender': <tf.Tensor 'ExpandDims_6:0' shape=(None, 1) dtype=string>, 'Color1': <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=string>, 'Color2': <tf.Tensor 'ExpandDims_3:0' shape=(None, 1) dtype=string>, 'MaturitySize': <tf.Tensor 'ExpandDims_8:0' shape=(None, 1) dtype=string>, 'FurLength': <tf.Tensor 'ExpandDims_5:0' shape=(None, 1) dtype=string>, 'Vaccinated': <tf.Tensor 'ExpandDims_12:0' shape=(None, 1) dtype=string>, 'Sterilized': <tf.Tensor 'ExpandDims_10:0' shape=(None, 1) dtype=string>, 'Health': <tf.Tensor 'ExpandDims_7:0' shape=(None, 1) dtype=string>, 'Fee': <tf.Tensor 'ExpandDims_4:0' shape=(None, 1) dtype=int64>, 'PhotoAmt': <tf.Tensor 'ExpandDims_9:0' shape=(None, 1) dtype=int64>}
Consider rewriting this model with the Functional API.
WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'Type': <tf.Tensor 'ExpandDims_11:0' shape=(None, 1) dtype=string>, 'Age': <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>, 'Breed1': <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=string>, 'Gender': <tf.Tensor 'ExpandDims_6:0' shape=(None, 1) dtype=string>, 'Color1': <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=string>, 'Color2': <tf.Tensor 'ExpandDims_3:0' shape=(None, 1) dtype=string>, 'MaturitySize': <tf.Tensor 'ExpandDims_8:0' shape=(None, 1) dtype=string>, 'FurLength': <tf.Tensor 'ExpandDims_5:0' shape=(None, 1) dtype=string>, 'Vaccinated': <tf.Tensor 'ExpandDims_12:0' shape=(None, 1) dtype=string>, 'Sterilized': <tf.Tensor 'ExpandDims_10:0' shape=(None, 1) dtype=string>, 'Health': <tf.Tensor 'ExpandDims_7:0' shape=(None, 1) dtype=string>, 'Fee': <tf.Tensor 'ExpandDims_4:0' shape=(None, 1) dtype=int64>, 'PhotoAmt': <tf.Tensor 'ExpandDims_9:0' shape=(None, 1) dtype=int64>}
Consider rewriting this model with the Functional API.
2021-08-12 05:35:16.625423: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:185] None of the MLIR Optimization Passes are enabled (registered 2)
225/231 [============================>.] - ETA: 0s - loss: 0.6541 - accuracy: 0.6914WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'dict'> input: {'Type': <tf.Tensor 'ExpandDims_11:0' shape=(None, 1) dtype=string>, 'Age': <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>, 'Breed1': <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=string>, 'Gender': <tf.Tensor 'ExpandDims_6:0' shape=(None, 1) dtype=string>, 'Color1': <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=string>, 'Color2': <tf.Tensor 'ExpandDims_3:0' shape=(None, 1) dtype=string>, 'MaturitySize': <tf.Tensor 'ExpandDims_8:0' shape=(None, 1) dtype=string>, 'FurLength': <tf.Tensor 'ExpandDims_5:0' shape=(None, 1) dtype=string>, 'Vaccinated': <tf.Tensor 'ExpandDims_12:0' shape=(None, 1) dtype=string>, 'Sterilized': <tf.Tensor 'ExpandDims_10:0' shape=(None, 1) dtype=string>, 'Health': <tf.Tensor 'ExpandDims_7:0' shape=(None, 1) dtype=string>, 'Fee': <tf.Tensor 'ExpandDims_4:0' shape=(None, 1) dtype=int64>, 'PhotoAmt': <tf.Tensor 'ExpandDims_9:0' shape=(None, 1) dtype=int64>}
Consider rewriting this model with the Functional API.
231/231 [==============================] - 4s 11ms/step - loss: 0.6513 - accuracy: 0.6929 - val_loss: 0.5530 - val_accuracy: 0.7172
Epoch 2/10
231/231 [==============================] - 2s 9ms/step - loss: 0.5726 - accuracy: 0.7142 - val_loss: 0.5061 - val_accuracy: 0.7481
Epoch 3/10
231/231 [==============================] - 2s 10ms/step - loss: 0.5145 - accuracy: 0.7249 - val_loss: 0.5066 - val_accuracy: 0.7557
Epoch 4/10
231/231 [==============================] - 2s 10ms/step - loss: 0.5018 - accuracy: 0.7345 - val_loss: 0.4926 - val_accuracy: 0.7405
Epoch 5/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4950 - accuracy: 0.7332 - val_loss: 0.4997 - val_accuracy: 0.7600
Epoch 6/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4852 - accuracy: 0.7425 - val_loss: 0.4907 - val_accuracy: 0.7443
Epoch 7/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4791 - accuracy: 0.7436 - val_loss: 0.4965 - val_accuracy: 0.7411
Epoch 8/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4779 - accuracy: 0.7471 - val_loss: 0.4956 - val_accuracy: 0.7356
Epoch 9/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4700 - accuracy: 0.7479 - val_loss: 0.4910 - val_accuracy: 0.7394
Epoch 10/10
231/231 [==============================] - 2s 9ms/step - loss: 0.4621 - accuracy: 0.7528 - val_loss: 0.5080 - val_accuracy: 0.7248
<keras.callbacks.History at 0x7f4a784c4d90>
loss, accuracy = model.evaluate(test_ds)
print("Accuracy", accuracy)
73/73 [==============================] - 0s 6ms/step - loss: 0.5444 - accuracy: 0.6919
Accuracy 0.6919410824775696

Bước tiếp theo

Cách tốt nhất để tìm hiểu thêm về phân loại dữ liệu có cấu trúc là tự mình thử. Chúng tôi khuyên bạn nên tìm một tập dữ liệu khác để làm việc và đào tạo một mô hình để phân loại nó bằng cách sử dụng mã tương tự như trên. Để cải thiện độ chính xác, hãy suy nghĩ cẩn thận về những tính năng nào cần đưa vào mô hình của bạn và cách chúng được thể hiện.