当前位置:   article > 正文

【TensorFlow基础】加载和预处理数据_tensorflow 数据预处理

tensorflow 数据预处理

目录

1.图像

1.1 配置环境

1.2 加载数据集

1.3 数据预处理

1.4 训练模型

2.CSV

2.1 配置环境

2.2 加载数据

2.3 数据预处理

2.4 构建模型

2.5 训练、评估和预测

3.Numpy

3.1 配置环境

3.2 加载数据

3.3 数据预处理

4.pandas.DataFrame

4.1 配置环境

4.2 加载数据

4.3 数据预处理

4.4 创建并训练模型

5.TFRecord和tf.Example

6.文本

6.1 配置环境

6.2 加载数据

6.3 数据预处理

6.4 构建模型

6.5 训练模型


1.图像

1.1 配置环境

  1. import tensorflow as tf
  2. AUTOTUNE = tf.data.experimental.AUTOTUNE

1.2 加载数据集

使用tf.data加载图片

  1. # 下载数据集
  2. import pathlib
  3. data_root_orig = tf.keras.utils.get_file(origin='https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
  4. fname='flower_photos', untar=True)
  5. data_root = pathlib.Path(data_root_orig)
  6. print(data_root)
  7. '''
  8. Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz
  9. 228813984/228813984 [==============================] - 3s 0us/step
  10. /home/kbuilder/.keras/datasets/flower_photos
  11. '''
  12. # 查看数据集
  13. for item in data_root.iterdir():
  14. print(item)
  15. '''
  16. /home/kbuilder/.keras/datasets/flower_photos/daisy
  17. /home/kbuilder/.keras/datasets/flower_photos/dandelion
  18. /home/kbuilder/.keras/datasets/flower_photos/sunflowers
  19. /home/kbuilder/.keras/datasets/flower_photos/roses
  20. /home/kbuilder/.keras/datasets/flower_photos/LICENSE.txt
  21. /home/kbuilder/.keras/datasets/flower_photos/tulips
  22. '''

1.3 数据预处理

  1. # 1. 打乱数据集
  2. import random
  3. all_image_paths = list(data_root.glob('*/*'))
  4. all_image_paths = [str(path) for path in all_image_paths]
  5. random.shuffle(all_image_paths)
  6. image_count = len(all_image_paths)
  7. image_count
  8. # 3670
  9. # 检查图片
  10. import os
  11. attributions = (data_root/"LICENSE.txt").open(encoding='utf-8').readlines()[4:]
  12. attributions = [line.split(' CC-BY') for line in attributions]
  13. attributions = dict(attributions)
  14. import IPython.display as display
  15. def caption_image(image_path):
  16. image_rel = pathlib.Path(image_path).relative_to(data_root)
  17. return "Image (CC BY 2.0) " + ' - '.join(attributions[str(image_rel)].split(' - ')[:-1])
  18. for n in range(3):
  19. image_path = random.choice(all_image_paths)
  20. display.display(display.Image(image_path))
  21. print(caption_image(image_path))
  22. print()
  23. # 2. 确定每张图片的标签
  24. # 2.1 列出可用的标签
  25. label_names = sorted(item.name for item in data_root.glob('*/') if item.is_dir())
  26. label_names
  27. # ['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']
  28. # 2.2 为每个标签分配索引
  29. label_to_index = dict((name, index) for index, name in enumerate(label_names))
  30. label_to_index
  31. # {'daisy': 0, 'dandelion': 1, 'roses': 2, 'sunflowers': 3, 'tulips': 4}
  32. # 2.3 创建一个列表包含每个文件的标签索引
  33. all_image_labels = [label_to_index[pathlib.Path(path).parent.name]
  34. for path in all_image_paths]
  35. print("First 10 labels indices: ", all_image_labels[:10])
  36. # First 10 labels indices: [4, 2, 4, 1, 1, 2, 4, 4, 3, 2]
  37. # 3. 加载和格式化图片
  38. # 3.1 取第一张图片
  39. img_path = all_image_paths[0]
  40. img_path
  41. # '/home/kbuilder/.keras/datasets/flower_photos/tulips/14099204939_60e6ffa4c3_n.jpg'
  42. # 查看原始数据
  43. img_raw = tf.io.read_file(img_path)
  44. print(repr(img_raw)[:100]+"...")
  45. # <tf.Tensor: shape=(), dtype=string, numpy=b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00...
  46. # 3.2 将原始数据转换为图像tensor
  47. img_tensor = tf.image.decode_image(img_raw)
  48. print(img_tensor.shape)
  49. print(img_tensor.dtype)
  50. '''
  51. (212, 320, 3)
  52. <dtype: 'uint8'>
  53. '''
  54. # 3.3 根据模型调整图像tensor大小
  55. img_final = tf.image.resize(img_tensor, [192, 192])
  56. img_final = img_final/255.0
  57. print(img_final.shape)
  58. print(img_final.numpy().min())
  59. print(img_final.numpy().max())
  60. '''
  61. (192, 192, 3)
  62. 0.0
  63. 1.0
  64. '''
  65. # 3.4 将以上操作封装在一个函数中
  66. def preprocess_image(image):
  67. image = tf.image.decode_jpeg(image, channels=3)
  68. image = tf.image.resize(image, [192, 192])
  69. image /= 255.0 # normalize to [0,1] range
  70. return image
  71. def load_and_preprocess_image(path):
  72. image = tf.io.read_file(path)
  73. return preprocess_image(image)
  74. # 应用封装好的函数
  75. import matplotlib.pyplot as plt
  76. image_path = all_image_paths[0]
  77. label = all_image_labels[0]
  78. plt.imshow(load_and_preprocess_image(img_path))
  79. plt.grid(False)
  80. plt.xlabel(caption_image(img_path))
  81. plt.title(label_names[label].title())
  82. print()

构建一个tf.data.Dataset

使用from_tensor_slices方法可以简单地构建一个tf.data.Dataset

  1. # 1. 构建字符串数据集path_ds
  2. # 将字符串数组切片得到一个字符串数据集path_ds
  3. path_ds = tf.data.Dataset.from_tensor_slices(all_image_paths)
  4. print(path_ds)
  5. # <TensorSliceDataset element_spec=TensorSpec(shape=(), dtype=tf.string, name=None)>
  6. # 2. 加载并格式化图片,构建图片数据集image_ds
  7. # 创建一个新的图像数据集image_ds,通过在路径数据集上映射 preprocess_image 来动态加载和格式化图片
  8. image_ds = path_ds.map(load_and_preprocess_image, num_parallel_calls=AUTOTUNE)
  9. import matplotlib.pyplot as plt
  10. plt.figure(figsize=(8,8))
  11. for n, image in enumerate(image_ds.take(4)):
  12. plt.subplot(2,2,n+1)
  13. plt.imshow(image)
  14. plt.grid(False)
  15. plt.xticks([])
  16. plt.yticks([])
  17. plt.xlabel(caption_image(all_image_paths[n]))
  18. plt.show()
  19. # 3. 创建标签数据集label_ds
  20. label_ds = tf.data.Dataset.from_tensor_slices(tf.cast(all_image_labels, tf.int64))
  21. for label in label_ds.take(10):
  22. print(label_names[label.numpy()])
  23. # 4. 构建(图片,标签)对数据集image_label_ds
  24. image_label_ds = tf.data.Dataset.zip((image_ds, label_ds))
  25. print(image_label_ds)
  26. # <ZipDataset element_spec=(TensorSpec(shape=(192, 192, 3), dtype=tf.float32, name=None), TensorSpec(shape=(), dtype=tf.int64, name=None))>

1.4 训练模型

准备训练数据:

  • 训练数据应被充分打乱;
  • 训练数据应被分割为batch;
  1. # 1. 准备训练数据
  2. BATCH_SIZE = 32
  3. # 设置一个和数据集大小一致的 shuffle buffer size(随机缓冲区大小)以保证数据被充分打乱
  4. # 当模型在训练的时候,`prefetch` 使数据集在后台取得 batch,使用额外的内存减少延迟时间。
  5. ds = image_label_ds.shuffle(buffer_size=image_count) # ds每次输出是不确定的
  6. ds = ds.repeat() # ds每次repeat产生不同的结果
  7. ds = ds.batch(BATCH_SIZE) # 将ds分成batch
  8. ds = ds.prefetch(buffer_size=AUTOTUNE) # 将ds的batch存储好
  9. ds
  10. # <PrefetchDataset element_spec=(TensorSpec(shape=(None, 192, 192, 3), dtype=tf.float32, name=None), TensorSpec(shape=(None,), dtype=tf.int32, name=None))>

1. 顺序很重要:

  • 在 .repeat 之后 .shuffle,会在 epoch 之间打乱数据(当有些数据出现两次的时候,其他数据还没有出现过);
  • 在 .batch 之后 .shuffle,会打乱 batch 的顺序,但是不会在 batch 之间打乱数据;

2. 在完全打乱中使用较大的缓冲区大小提供更好的随机化但使用更多的内存。
3. 在从随机缓冲区中拉取任何元素前,要先填满它。所以当 Dataset(数据集)启动的时候一个大的 buffer_size(缓冲区大小)可能会引起延迟。
4. 在随机缓冲区完全为空之前,被打乱的数据集不会报告数据集的结尾。Dataset(数据集)由 .repeat 重新启动,导致需要再次等待随机缓冲区被填满。

构建并训练模型:

  1. # 2. 构建模型
  2. # 2.1 使用 MobileNet v2 模型副本进行训练
  3. mobile_net = tf.keras.applications.MobileNetV2(input_shape=(192, 192, 3), include_top=False)
  4. # 设置 MobileNet v2 权重不可训练
  5. mobile_net.trainable=False
  6. # 将模型输出标准化至 [-1,1] 范围内
  7. def change_range(image,label):
  8. return 2*image-1, label
  9. keras_ds = ds.map(change_range)
  10. # MobileNet v2 为每张图片的特征返回一个6*6的空间网格
  11. # 数据集可能需要几秒来启动,因为要填满其随机缓冲区,传递一个batch的图片
  12. image_batch, label_batch = next(iter(keras_ds))
  13. feature_map_batch = mobile_net(image_batch)
  14. print(feature_map_batch.shape)
  15. # (32, 6, 6, 1280)
  16. # 每个batch有32条样本,每个样本返回个6*6的空间网格
  17. # 2.2 构建模型
  18. model = tf.keras.Sequential([
  19. mobile_net,
  20. tf.keras.layers.GlobalAveragePooling2D(), # 平均空间向量
  21. tf.keras.layers.Dense(len(label_names), activation = 'softmax')])
  22. logit_batch = model(image_batch).numpy()
  23. print("min logit:", logit_batch.min())
  24. print("max logit:", logit_batch.max())
  25. print()
  26. print("Shape:", logit_batch.shape)
  27. '''
  28. min logit: 0.014231807
  29. max logit: 0.7678226
  30. Shape: (32, 5)
  31. '''
  32. model.compile(optimizer=tf.keras.optimizers.Adam(),
  33. loss='sparse_categorical_crossentropy',
  34. metrics=["accuracy"])
  35. # 2.3 查看模型结构
  36. # 此时可训练的变量为dense层中的weight和bias
  37. model.summary()
  38. '''
  39. Model: "sequential"
  40. _________________________________________________________________
  41. Layer (type) Output Shape Param #
  42. =================================================================
  43. mobilenetv2_1.00_192 (Funct (None, 6, 6, 1280) 2257984
  44. ional)
  45. global_average_pooling2d (G (None, 1280) 0
  46. lobalAveragePooling2D)
  47. dense (Dense) (None, 5) 6405
  48. =================================================================
  49. Total params: 2,264,389
  50. Trainable params: 6,405
  51. Non-trainable params: 2,257,984
  52. _________________________________________________________________
  53. '''
  54. # 2.4 训练模型
  55. # 出于演示目的每一个 epoch 只运行 3 step,在传递给 model.fit() 之前指定 step 的数量
  56. steps_per_epoch=tf.math.ceil(len(all_image_paths)/BATCH_SIZE).numpy()
  57. steps_per_epoch
  58. # 115.0
  59. model.fit(ds, epochs=1, steps_per_epoch=3)

2.CSV

使用泰坦尼克号乘客的数据,模型会根据乘客的年龄、性别、票务舱和是否独自旅行等特征来预测乘客生还的可能性。

2.1 配置环境

  1. import functools
  2. import numpy as np
  3. import tensorflow as tf
  4. import tensorflow_datasets as tfds
  5. TRAIN_DATA_URL = "https://storage.googleapis.com/tf-datasets/titanic/train.csv"
  6. TEST_DATA_URL = "https://storage.googleapis.com/tf-datasets/titanic/eval.csv"
  7. train_file_path = tf.keras.utils.get_file("train.csv", TRAIN_DATA_URL)
  8. test_file_path = tf.keras.utils.get_file("eval.csv", TEST_DATA_URL)
  9. # 让 numpy 数据更易读
  10. np.set_printoptions(precision=3, suppress=True)

2.2 加载数据

查看csv文件了解文件格式:

  1. head {train_file_path}
  2. '''
  3. survived,sex,age,n_siblings_spouses,parch,fare,class,deck,embark_town,alone
  4. 0,male,22.0,1,0,7.25,Third,unknown,Southampton,n
  5. 1,female,38.0,1,0,71.2833,First,C,Cherbourg,n
  6. 1,female,26.0,0,0,7.925,Third,unknown,Southampton,y
  7. 1,female,35.0,1,0,53.1,First,C,Southampton,n
  8. 0,male,28.0,0,0,8.4583,Third,unknown,Queenstown,y
  9. 0,male,2.0,3,1,21.075,Third,unknown,Southampton,n
  10. 1,female,27.0,0,2,11.1333,Third,unknown,Southampton,n
  11. 1,female,14.0,1,0,30.0708,Second,unknown,Cherbourg,n
  12. 1,female,4.0,1,1,16.7,Third,G,Southampton,n
  13. '''

CSV 文件的每列都会有一个列名,dataset 的构造函数会自动识别这些列名。如果文件的第一行不包含列名,那么需要将列名通过字符串列表传给 make_csv_dataset 函数的 column_names 参数。

  1. CSV_COLUMNS = ['survived', 'sex', 'age', 'n_siblings_spouses', 'parch', 'fare', 'class', 'deck', 'embark_town', 'alone']
  2. dataset = tf.data.experimental.make_csv_dataset(
  3. ...,
  4. column_names=CSV_COLUMNS,
  5. ...)

这个示例使用了所有的列。如果你需要忽略数据集中的某些列,创建一个包含你需要使用的列的列表,然后传给构造器的(可选)参数 select_columns。

  1. dataset = tf.data.experimental.make_csv_dataset(
  2. ...,
  3. select_columns = columns_to_use,
  4. ...)

指定标签所在的列:

  1. LABEL_COLUMN = 'survived'
  2. LABELS = [0, 1]

读取CSV数据并创建dataset:

  1. def get_dataset(file_path):
  2. dataset = tf.data.experimental.make_csv_dataset(
  3. file_path,
  4. batch_size=12, # 为了示例更容易展示,手动设置较小的值
  5. label_name=LABEL_COLUMN,
  6. na_value="?",
  7. num_epochs=1,
  8. ignore_errors=True)
  9. return dataset
  10. raw_train_data = get_dataset(train_file_path)
  11. raw_test_data = get_dataset(test_file_path)

dataset 中的每个条目都是一个批次,用一个元组(多个样本,多个标签)表示。样本中的数据组织形式是以列为主的张量(而不是以行为主的张量),每条数据中包含的元素个数就是批次大小(这个示例中是 12)。

  1. examples, labels = next(iter(raw_train_data)) # 第一个批次
  2. print("EXAMPLES: \n", examples, "\n")
  3. print("LABELS: \n", labels)
  4. '''
  5. EXAMPLES:
  6. OrderedDict([('sex', <tf.Tensor: shape=(12,), dtype=string, numpy=
  7. array([b'female', b'female', b'male', b'male', b'female', b'male',
  8. b'female', b'male', b'female', b'male', b'female', b'male'],
  9. dtype=object)>), ('age', <tf.Tensor: shape=(12,), dtype=float32, numpy=
  10. array([28., 41., 28., 24., 63., 28., 28., 65., 34., 9., 27., 30.],
  11. dtype=float32)>), ...])
  12. LABELS:
  13. tf.Tensor([1 0 0 0 1 0 0 0 1 0 1 0], shape=(12,), dtype=int32)
  14. '''

2.3 数据预处理

离散数据:对于有些分类的特征(即有些列只能在有限的集合中取值),使用 tf.feature_column API 创建一个 tf.feature_column.indicator_column 集合,每个tf.feature_column.indicator_column 对应一个分类的列。

  1. CATEGORIES = {
  2. 'sex': ['male', 'female'],
  3. 'class' : ['First', 'Second', 'Third'],
  4. 'deck' : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
  5. 'embark_town' : ['Cherbourg', 'Southhampton', 'Queenstown'],
  6. 'alone' : ['y', 'n']
  7. }
  8. categorical_columns = []
  9. for feature, vocab in CATEGORIES.items():
  10. cat_col = tf.feature_column.categorical_column_with_vocabulary_list(
  11. key=feature, vocabulary_list=vocab)
  12. categorical_columns.append(tf.feature_column.indicator_column(cat_col))
  13. # 查看刚才创建的内容
  14. categorical_columns
  15. '''
  16. [IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='sex', vocabulary_list=('male', 'female'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),
  17. IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='class', vocabulary_list=('First', 'Second', 'Third'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),
  18. IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='deck', vocabulary_list=('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),
  19. IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='embark_town', vocabulary_list=('Cherbourg', 'Southhampton', 'Queenstown'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),
  20. IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='alone', vocabulary_list=('y', 'n'), dtype=tf.string, default_value=-1, num_oov_buckets=0))]
  21. '''

 连续数据:需要对离散数据进行标准化

  1. def process_continuous_data(mean, data):
  2. # 标准化数据
  3. data = tf.cast(data, tf.float32) * 1/(2*mean)
  4. return tf.reshape(data, [-1, 1])
  5. MEANS = {
  6. 'age' : 29.631308,
  7. 'n_siblings_spouses' : 0.545455,
  8. 'parch' : 0.379585,
  9. 'fare' : 34.385399
  10. }
  11. numerical_columns = []
  12. for feature in MEANS.keys():
  13. num_col = tf.feature_column.numeric_column(feature, normalizer_fn=functools.partial(process_continuous_data, MEANS[feature]))
  14. numerical_columns.append(num_col)
  15. # 查看创建的内容
  16. numerical_columns
  17. '''
  18. [NumericColumn(key='age', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=functools.partial(<function process_continuous_data at 0x7f74fc4f8c10>, 29.631308)),
  19. NumericColumn(key='n_siblings_spouses', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=functools.partial(<function process_continuous_data at 0x7f74fc4f8c10>, 0.545455)),
  20. NumericColumn(key='parch', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=functools.partial(<function process_continuous_data at 0x7f74fc4f8c10>, 0.379585)),
  21. NumericColumn(key='fare', shape=(1,), default_value=None, dtype=tf.float32, normalizer_fn=functools.partial(<function process_continuous_data at 0x7f74fc4f8c10>, 34.385399))]
  22. '''

将离散数据和连续数据的集合合并在一起,并传递给tf.keras.layers.DenseFeatures创建一个进行预处理的输入层。

preprocessing_layer = tf.keras.layers.DenseFeatures(categorical_columns+numerical_columns)

2.4 构建模型

  1. model = tf.keras.Sequential([
  2. preprocessing_layer, # 预处理层
  3. tf.keras.layers.Dense(128, activation='relu'), # 全连接层
  4. tf.keras.layers.Dense(128, activation='relu'), # 全连接层
  5. tf.keras.layers.Dense(1, activation='sigmoid'), # 输出层
  6. ])
  7. model.compile(
  8. loss='binary_crossentropy',
  9. optimizer='adam',
  10. metrics=['accuracy'])

2.5 训练、评估和预测

  1. # 1. 训练模型
  2. train_data = raw_train_data.shuffle(500)
  3. test_data = raw_test_data
  4. model.fit(train_data, epochs=20)
  5. # 2. 评估模型
  6. test_loss, test_accuracy = model.evaluate(test_data)
  7. print('\n\nTest Loss {}, Test Accuracy {}'.format(test_loss, test_accuracy))
  8. # Test Loss 0.4481576979160309, Test Accuracy 0.8030303120613098
  9. # 3. 进行预测
  10. predictions = model.predict(test_data)
  11. # 显示前十个batch结果
  12. for prediction, survived in zip(predictions[:10], list(test_data)[0][1][:10]):
  13. print("Predicted survival: {:.2%}".format(prediction[0]),
  14. " | Actual outcome: ",
  15. ("SURVIVED" if bool(survived) else "DIED"))
  16. '''
  17. 22/22 [==============================] - 0s 4ms/step
  18. Predicted survival: 90.08% | Actual outcome: SURVIVED
  19. Predicted survival: 0.97% | Actual outcome: SURVIVED
  20. Predicted survival: 0.98% | Actual outcome: DIED
  21. Predicted survival: 10.06% | Actual outcome: SURVIVED
  22. Predicted survival: 62.49% | Actual outcome: DIED
  23. Predicted survival: 62.38% | Actual outcome: SURVIVED
  24. Predicted survival: 11.18% | Actual outcome: SURVIVED
  25. Predicted survival: 60.31% | Actual outcome: SURVIVED
  26. Predicted survival: 9.72% | Actual outcome: DIED
  27. Predicted survival: 21.93% | Actual outcome: DIED
  28. '''

3.Numpy

3.1 配置环境

  1. import numpy as np
  2. import tensorflow as tf

3.2 加载数据

  1. # 从.npz文件中加载数据
  2. DATA_URL = 'https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz'
  3. path = tf.keras.utils.get_file('mnist.npz', DATA_URL)
  4. with np.load(path) as data:
  5. train_examples = data['x_train']
  6. train_labels = data['y_train']
  7. test_examples = data['x_test']
  8. test_labels = data['y_test']
  9. # 创建数据集
  10. train_dataset = tf.data.Dataset.from_tensor_slices((train_examples, train_labels))
  11. test_dataset = tf.data.Dataset.from_tensor_slices((test_examples, test_labels))

3.3 数据预处理

  1. # shuffle and batch
  2. BATCH_SIZE = 64
  3. SHUFFLE_BUFFER_SIZE = 100
  4. train_dataset = train_dataset.shuffle(SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE)
  5. test_dataset = test_dataset.batch(BATCH_SIZE)
  6. # 构建并训练模型
  7. model = tf.keras.Sequential([
  8. tf.keras.layers.Flatten(input_shape=(28, 28)),
  9. tf.keras.layers.Dense(128, activation='relu'),
  10. tf.keras.layers.Dense(10)
  11. ])
  12. model.compile(optimizer=tf.keras.optimizers.RMSprop(),
  13. loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
  14. metrics=['sparse_categorical_accuracy'])
  15. model.fit(train_dataset, epochs=10)

4.pandas.DataFrame

使用由克利夫兰诊所心脏病基金会(Cleveland Clinic Foundation for Heart Disease)提供的小型数据集,此数据集中有几百行CSV。每行表示一个患者,每列表示一个属性(describe)。我们将使用这些信息来预测患者是否患有心脏病,这是一个二分类问题。

4.1 配置环境

  1. !pip install tensorflow-gpu==2.0.0-rc1
  2. import pandas as pd
  3. import tensorflow as tf

4.2 加载数据

  1. # 下载数据集CSV文件
  2. csv_file = tf.keras.utils.get_file('heart.csv', 'https://storage.googleapis.com/applied-dl/heart.csv')
  3. # 使用pandas读取CSV文件
  4. df = pd.read_csv(csv_file)
  5. # 使用df.head()查看数据集,df.dtypes查看每列特征的数据格式

4.3 数据预处理

  1. # 将分类的特征转换成离散数值
  2. df['thal'] = pd.Categorical(df['thal'])
  3. df['thal'] = df.thal.cat.codes
  4. # 使用tf.data.Dataset.from_tensor_slices读取数据
  5. target = df.pop('target') # label列
  6. dataset = tf.data.Dataset.from_tensor_slices((df.values, target.values))
  7. # shuffle and batch
  8. train_dataset = dataset.shuffle(len(df)).batch(1)

4.4 创建并训练模型

  1. def get_compiled_model():
  2. model = tf.keras.Sequential([
  3. tf.keras.layers.Dense(10, activation='relu'),
  4. tf.keras.layers.Dense(10, activation='relu'),
  5. tf.keras.layers.Dense(1, activation='sigmoid')
  6. ])
  7. model.compile(optimizer='adam',
  8. loss='binary_crossentropy',
  9. metrics=['accuracy'])
  10. return model
  11. model = get_compiled_model()
  12. model.fit(train_dataset, epochs=15)

5.TFRecord和tf.Example

先跳过


6.文本

使用tf.data.TextLineDataset加载文本文件,通常被用来以文本文件构建数据集(原文件中的一行为一个样本) 。使用相同作品(荷马的伊利亚特)三个不同版本的英文翻译,然后训练一个模型来通过单行文本确定译者。

6.1 配置环境

  1. import tensorflow as tf
  2. import tensorflow_datasets as tfds
  3. import os

6.2 加载数据

  1. DIRECTORY_URL = 'https://storage.googleapis.com/download.tensorflow.org/data/illiad/'
  2. FILE_NAMES = ['cowper.txt', 'derby.txt', 'butler.txt']
  3. for name in FILE_NAMES:
  4. text_dir = tf.keras.utils.get_file(name, origin=DIRECTORY_URL+name)
  5. parent_dir = os.path.dirname(text_dir)
  6. parent_dir
  7. # '/home/kbuilder/.keras/datasets'

6.3 数据预处理

每个样本都需要单独标记,使用 tf.data.Dataset.map为每个样本设定标签。这将迭代数据集中的每一个样本并且返回( example, label )对。

  1. def labeler(example, index):
  2. return example, tf.cast(index, tf.int64)
  3. labeled_data_sets = []
  4. for i, file_name in enumerate(FILE_NAMES):
  5. lines_dataset = tf.data.TextLineDataset(os.path.join(parent_dir, file_name))
  6. labeled_dataset = lines_dataset.map(lambda ex: labeler(ex, i))
  7. labeled_data_sets.append(labeled_dataset)

构建数据集:

  1. BUFFER_SIZE = 50000
  2. BATCH_SIZE = 64
  3. TAKE_SIZE = 5000
  4. all_labeled_data = labeled_data_sets[0]
  5. for labeled_dataset in labeled_data_sets[1:]:
  6. all_labeled_data = all_labeled_data.concatenate(labeled_dataset)
  7. all_labeled_data = all_labeled_data.shuffle(
  8. BUFFER_SIZE, reshuffle_each_iteration=False)
  9. # 使用 tf.data.Dataset.take 与 print 来查看 (example, label) 对的外观
  10. # numpy 属性显示每个 Tensor 的值
  11. for ex in all_labeled_data.take(5):
  12. print(ex)
  13. '''
  14. (<tf.Tensor: shape=(), dtype=string, numpy=b'To Ida; in his presence once arrived,'>, <tf.Tensor: shape=(), dtype=int64, numpy=0>)
  15. (<tf.Tensor: shape=(), dtype=string, numpy=b"Such now appears th' o'er-ruling sov'reign will">, <tf.Tensor: shape=(), dtype=int64, numpy=1>)
  16. (<tf.Tensor: shape=(), dtype=string, numpy=b'Them so prepared the King of men beheld'>, <tf.Tensor: shape=(), dtype=int64, numpy=0>)
  17. (<tf.Tensor: shape=(), dtype=string, numpy=b'mourn you, but the eddies of Scamander shall bear you into the broad'>, <tf.Tensor: shape=(), dtype=int64, numpy=2>)
  18. (<tf.Tensor: shape=(), dtype=string, numpy=b'there was no life left in him.'>, <tf.Tensor: shape=(), dtype=int64, numpy=2>)
  19. '''

将文本编码成数字:

  1. # 1. 建立词汇表
  2. # 1.1 迭代每个样本的 numpy 值
  3. # 1.2 使用 tfds.features.text.Tokenizer 来将其分割成 token
  4. tokenizer = tfds.features.text.Tokenizer()
  5. # 1.3 将 token 放入一个python集合中消除重复项
  6. vocabulary_set = set()
  7. for text_tensor, _ in all_labeled_data:
  8. some_tokens = tokenizer.tokenize(text_tensor.numpy())
  9. vocabulary_set.update(some_tokens)
  10. # 1.4 获取该词汇表的大小
  11. vocab_size = len(vocabulary_set)
  12. vocab_size
  13. # 17178
  14. # 2. 样本编码
  15. # 向编码器的encode方法传入一行文本后返回一个整数列表
  16. # 2.1 构建编码器
  17. encoder = tfds.features.text.TokenTextEncoder(vocabulary_set)
  18. # 2.2 运行编码器
  19. # 将编码器打包到 tf.py_function 并且传参至数据集的 map 方法在数据集上运行编码器
  20. # tf.py_function 将计算图表示为 python 函数
  21. # tf.py_function(func,inp,Tout,name=None),func是一个python函数,接受inp作为参数返回一个Tout类型的输出
  22. def encode(text_tensor, label):
  23. encoded_text = encoder.encode(text_tensor.numpy())
  24. return encoded_text, label
  25. def encode_map_fn(text, label):
  26. encoded_text, label = tf.py_function(encode,
  27. inp=[text, label],
  28. Tout=(tf.int64, tf.int64))
  29. encoded_text.set_shape([None])
  30. label.set_shape([])
  31. return encoded_text, label
  32. all_encoded_data = all_labeled_data.map(encode_map_fn)

将数据集分割成测试集和训练集并分batch:

使用 tf.data.Dataset.taketf.data.Dataset.skip 来建立一个小一些的测试数据集和稍大一些的训练数据集。在数据集被传入模型之前,数据集需要被分批。每个分支中的样本大小与格式需要一致,但是数据集中样本并不全是相同大小的(每行文本字数并不相同)。因此,使用 tf.data.Dataset.padded_batch(而不是 batch )将样本填充到相同的大小。

  1. train_data = all_encoded_data.skip(TAKE_SIZE).shuffle(BUFFER_SIZE)
  2. train_data = train_data.padded_batch(BATCH_SIZE)
  3. test_data = all_encoded_data.take(TAKE_SIZE)
  4. test_data = test_data.padded_batch(BATCH_SIZE)
  5. # 查看测试集
  6. sample_text, sample_labels = next(iter(test_data))
  7. sample_text[0], sample_labels[0]
  8. '''
  9. (<tf.Tensor: shape=(16,), dtype=int64, numpy=
  10. array([15746, 11433, 8394, 9006, 379, 3463, 17072, 0, 0,
  11. 0, 0, 0, 0, 0, 0, 0])>,
  12. <tf.Tensor: shape=(), dtype=int64, numpy=0>)
  13. '''
  14. # 现在,test_data 和 train_data 不是(example, label)对的集合,而是批次的集合
  15. # 每个批次都是一对(多样本, 多标签),表示为数组
  16. # 由于引入了一个新的 token 来编码,因此词汇表大小增加了一个
  17. vocab_size += 1

6.4 构建模型

  1. model = tf.keras.Sequential()
  2. # Embedding层将整数表示转换为密集矢量嵌入
  3. model.add(tf.keras.layers.Embedding(vocab_size, 64))
  4. # LSTM 层允许模型利用上下文中理解单词含义
  5. model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)))
  6. # 一个或多个紧密连接的层
  7. # 编辑 `for` 行的列表去检测层的大小
  8. for units in [64, 64]:
  9. model.add(tf.keras.layers.Dense(units, activation='relu'))
  10. # 输出层,第一个参数是标签个数。
  11. model.add(tf.keras.layers.Dense(3, activation='softmax'))
  12. # 编译模型
  13. model.compile(optimizer='adam',
  14. loss='sparse_categorical_crossentropy',
  15. metrics=['accuracy'])

6.5 训练模型

  1. model.fit(train_data, epochs=3, validation_data=test_data)
  2. eval_loss, eval_acc = model.evaluate(test_data)
  3. print('\nEval loss: {}, Eval accuracy: {}'.format(eval_loss, eval_acc))
  4. '''
  5. 79/79 [==============================] - 1s 18ms/step - loss: 0.3794 - accuracy: 0.8246
  6. Eval loss: 0.3794495761394501, Eval accuracy: 0.8245999813079834
  7. '''
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号