TensorFlow学习笔记(11)常见文件类型及加载

        神经网络的训练常常需要大量的数据,导入数据是神经网络能够开始训练的第一步。对于不同的文件类型,有不同的加载方式。本篇笔记主要记录了常见的几种文件的加载,附上代码注释以及自己暂时未能想通的的一些疑问,希望等再次回头看的时候会茅塞顿开。

1、加载numpy类型数据(.npz)

numpy数据以.npz的形式存储,在模型训练的过程中,最重要的一步就是要把数据集导入到神经网络。在TensorFlow中,必须使用不同的函数去加载不同的数据类型,.npz文件用的是numpy库的np.load()

import tensorflow as tf
import numpy as np

DATA_URL='https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz'
path=tf.keras.utils.get_file('mnist.npz',DATA_URL)
# 从URL获取指定文件并获得其路径

with np.load(path) as data:
    train_examples=data['x_train']
    train_labels=data['y_train']
    test_examples=data['x_test']
    test_labels=data['y_test']
    pass
# with 上下文管理器 打开后关闭
# np,load加载.npz类型文件,打开后以data命名

train_dataset=tf.data.Dataset.from_tensor_slices((train_examples,train_labels))
test_dataset=tf.data.Dataset.from_tensor_slices((test_examples,test_labels))
# 数据加载完成后,利用from_tensor_slice()函数将特征和标签一一对应

BATCH_SIZE=64
SHUFFLE_BUFFER_SIZE=100
train_dataset=train_dataset.shuffle(SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE)
test_dataset=test_dataset.batch(BATCH_SIZE)
# 将训练数据集以每组100个打乱,然后分为64个一个batch

model=tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28,28)),
    # 限制输入层的结构
    tf.keras.layers.Dense(128,activation='relu'),
    tf.keras.layers.Dense(10)
    # 输出的可能结果
])

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

model.fit(train_dataset,epochs=10)
model.summary()

model.evaluate(test_dataset)

2、加载.CSV 文件

import functools
import pandas as pd
import numpy as np
import tensorflow as tf

TRAIN_DATA_URL = "https://storage.googleapis.com/tf-datasets/titanic/train.csv"
TEST_DATA_URL = "https://storage.googleapis.com/tf-datasets/titanic/eval.csv"
# 获取文件的路径地址

train_file_path = tf.keras.utils.get_file("train.csv", TRAIN_DATA_URL)
test_file_path = tf.keras.utils.get_file("eval.csv", TEST_DATA_URL)
# 根据文件地址下载文件并保存为对应的文件名

# 让 numpy 数据更易读。
np.set_printoptions(precision=3, suppress=True)
# precission 表示数字精度   suppress  表示小数不需要用科学计数法输出
df=pd.read_csv(train_file_path)

# 显示所有行(参数设置为None代表显示所有行,也可以自行设置数字)
pd.set_option('display.max_columns', None)
# 显示所有列
pd.set_option('display.max_rows', None)
# 设置数据的显示长度,默认为50
pd.set_option('max_colwidth', 200)
# 禁止自动换行(设置为Flase不自动换行,True反之)
pd.set_option('expand_frame_repr', False)
# 打印csv文件的前几行,查看数据是否正确(默认为十行)
print(df.head(3))
# print(pathlib.Path(train_file_path))

# CSV 文件的每列都会有一个列名。dataset 的构造函数会自动识别这些列名。如果文件的第一行不包含列名
# 那么需要将列名通过字符串列表传给 make_csv_dataset 函数的 column_names 参数
# CSV_COLUMN_NAMES = ["survived", "sex", "age", "n_siblings_spouses", "parch", "fare", "class", "deck", "embark_town",
#                     "alone"]
# dataset = tf.data.experimental.make_cvs_dataset(...,column_names=CSV_COLUMN_NAMES,...)
# 如果我们要有选择地加载csv文件中地某些列作为训练地属性,
# 可以使用make_cvs_dataset函数中地select_columns参数进行指定
# dataset = tf.data.experimental.make_csv_dataset(
#   select_columns = "要选择的列名称")
# 如果cvs文件列中包含我们预测地类别属性,需要使用make_cvs_dataset函数中地label_name进行指定,代码同上

LABEL_COLUMN = "survived"
LABELS = [0, 1]
# 设置参数,标签表示状态

def get_dataset(file_path, **kwargs):
    dataset = tf.data.experimental.make_csv_dataset(train_file_path,
                                                    # 读取的文件路径
                                                    batch_size=5,
                                                    # 一次读取的大小
                                                    label_name=LABEL_COLUMN,
                                                    # 选择与标签名字对应的列
                                                    na_value="?",
                                                    # 表示缺失值用?表示
                                                    num_epochs=1,
                                                    # 指定此数据集重复次数的 int。如果没有,则永远循环遍历数据集
                                                    ignore_errors=True,
                                                    **kwargs)
    return dataset
#定义了一个函数加载CSV中的数据,每次读取5个,只重复一次

train_dataset = get_dataset(train_file_path)
# 利用get_dataset函数获取数据
test_dataset = get_dataset(test_file_path)


def show_batch(dataset):
  for batch, label in dataset.take(1):
    for key, value in batch.items():
      print("{:20s}: {}".format(key,value.numpy()))

show=show_batch(train_dataset)
print(show)
# 打印一个batch的内容

CATEGORIES = {
    'sex': ['male', 'female'],
    'class' : ['First', 'Second', 'Third'],
    'deck' : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
    'embark_town' : ['Cherbourg', 'Southhampton', 'Queenstown'],
    'alone' : ['y', 'n']
}
# 类别信息
categorical_columns = []
for feature, vocab in CATEGORIES.items():
    cat_col = tf.feature_column.categorical_column_with_vocabulary_list(
        key=feature, vocabulary_list=vocab)
    categorical_columns.append(tf.feature_column.indicator_column(cat_col))

print(categorical_columns)

def process_continuous_data(mean, data):
  # 标准化数据
  data = tf.cast(data, tf.float32) * 1/(2*mean)
  # 强制转换数据
  return tf.reshape(data, [-1, 1])


MEANS = {
    'age': 29.631308,
    'n_siblings_spouses': 0.545455,
    'parch': 0.379585,
    'fare': 34.385399
}

numerical_columns = []

for feature in MEANS.keys():
    num_col = tf.feature_column.numeric_column(feature,
                                               normalizer_fn=functools.partial(process_continuous_data, MEANS[feature]))
    numerical_columns.append(num_col)

print(numerical_columns)

preprocessing_layer = tf.keras.layers.DenseFeatures(categorical_columns+numerical_columns)
# 预处理层,基于给定 feature_columns 生成密集 Tensor 的层。两个列相加生成一个新对象,后一个列直接附在前一个列的后边
model = tf.keras.Sequential([
    preprocessing_layer,
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid'),
])
# 输出神经元只有一个,0或者1
model.compile(
    loss='binary_crossentropy',
    # 二分类交叉熵函数
    optimizer='adam',
    # 优化器
    metrics=['accuracy'])
    # 评价标准

train_data = train_dataset.shuffle(500)
# 将训练数据打乱
test_data = test_dataset

model.fit(train_data, epochs=20)
# 输入训练集,训练神经网络,循环20次

test_loss, test_accuracy = model.evaluate(test_data)
# evaluate函数,输入数据和标签,输出损失值和选定的指标,并直接赋给test_loss, test_accuracy
# 返回了多少个值,是不固定的,如果在complie的时候没有指定metrics的话,默认只有loss一个返回值。

print('\n\nTest Loss {}, Test Accuracy {}'.format(test_loss, test_accuracy))

predictions = model.predict(test_data)
# predict函数是输入测试数据,输出测试结果
# 显示部分结果
for prediction, survived in zip(predictions[:10], list(test_data)[0][1][:10]):
    print("Predicted survival: {:.2%}".format(prediction[0]),
          " | Actual outcome: ",
          ("SURVIVED" if bool(survived) else "DIED"))

3、加载数据帧数据(.csv)

        Dataframe(数据帧),是一个二位的数组格式,以CSV文件的形式存储。本部分引入的代码案例是根据不同人的各种身体条件判断是否患有心脏病的。在导入的CSV数据中,一共有13个不同的特征,而在搭建神经网络时输入层只有10个神经元,对于此部分难以理解。提出两个想法:①数据的13个特征并没有全部使用,而是某一步的代码有某些功能而自己并没有理解;②自己并没有搞清楚输入层的网络结构。针对想法(2),针对Sequential搭建的网络结构,第一个数据表达的就是神经元个数。那么只有针对想法①展开,在注释过所有的代码后,暂时没有发现具体哪一步对特征数据进行了筛选。希望能在后续的学习中理解此部分内容,也欢迎读者指正。

import pandas as pd
import tensorflow as tf

pd.set_option('display.max_columns', None)   # 显示完整的列
pd.set_option('display.max_rows', None)  # 显示完整的行
pd.set_option('display.expand_frame_repr', False)  # 设置不折叠数据
pd.set_option('display.max_colwidth', 100)

csv_file=tf.keras.utils.get_file('heart.csv','https://storage.googleapis.com/download.tensorflow.org/data/heart.csv')

df=pd.read_csv(csv_file)

df['thal']=pd.Categorical(df['thal'])
# 将thal列(数据帧(dataframe)中的object)转换为离散数值
df['thal']=df.thal.cat.codes
# cat.codes 分类的编码,用数字表示分类数据

print(df.head(5))

target=df.pop('target')
dataset=tf.data.Dataset.from_tensor_slices((df.values,target.values))
# 切片,使特征和标签数据一一对应
for feat,targ in dataset.take(5):
    print('Features: {}, Target: {}'.format(feat, targ))
# 打印前五行,查看数据
print(tf.constant(df['thal']))
# constant 创建一个常量张量,查看thal的内容
train_dataset=dataset.shuffle(len(df)).batch(1)
# len函数表示获取df数据的长度,然后shuffle一次性打乱所有的数据,再将数据分为一个数据一个batch
def create_model():
    model=tf.keras.Sequential([
        tf.keras.layers.Dense(10,activation='relu'),
        tf.keras.layers.Dense(10,activation='relu'),
        tf.keras.layers.Dense(1,activation='sigmoid')
    ])
    model.compile(
        optimizer='adam',
        loss='binary_crossentropy',
        # 二进制交叉熵损失函数
        metrics=['accuracy']
        # 评价标准
    )
    return model

model=create_model()
history=model.fit(train_dataset,epochs=5)
model.summary()

4、TFRecord和tf.Example

        为了高效的读取数据,常用的方法是对数据进行序列化并将其存储在一组可线性读取的文件中。这非常适合通过网络进行流式传输的数据。

TFRecord 格式是一种用于存储二进制记录序列的简单格式。

协议缓冲区是一个跨平台、跨语言的库,用于高效地序列化结构化数据。

协议消息由  文件定义,这通常是了解消息类型最简单的方法。.proto

tf.Example消息(或 protobuf)是一种灵活的消息类型,表示 映射。它专为 TensorFlow 而设计,并被用于 TFX 等高级 API。{"string": value}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值