记录自己入门tensorflow框架,搭建模型过程中踩到的坑,方便以后查看学习。
以下代码绝大部分来源于<Hands-on Machine learning with Scikit-lean, keras & tensorflow>
代码经过部分修改后应该是可以直接运行的
环境:tensorflow 2.x, python 3.8.x
#使用tensorflow进行数据集加载和预处理
import tensorflow as tf
from tensorflow import data
import pandas as pd
import os
from tensorflow import keras
# 函数定义纯粹为了区分不同的数据处理方法,没有实际意义
def data_API():
# 创建数据集的两种方法
X = tf.range(10)
dataset = data.Dataset.from_tensor_slices(X)
for item in dataset:
print(item)
dataset = data.Dataset.range(10)
print("--------------------------------------")
for item in dataset:
print(item)
# 链式转换
# 这里需要注意,repeat()后面可以不用接batch() 可以单独使用,但是其中一定要赋值,不然就会疯狂抓取数据,死循环一样
# 传入参数的含义:参阅api介绍或可以直接百度
dataset = dataset.repeat(3).batch(9)
for item in dataset:
print(item)
# 使用 map()方法来变换元素
print("------map------")
dataset = data.Dataset.range(10)
dataset = dataset.map(lambda x : x**2) # map方法出入的函数必须可以转为tf.function(), 也就是转换完以后,return出来的得是tensor
# dataset = dataset.repeat(1).batch(len(dataset))
for item in dataset:
print(item)
# filter过滤数据集
print("-----filter---过滤掉元素-----")
dataset = dataset.filter(lambda x : x < 100)
for item in dataset:
print(item)
# take()查看一些元素, 其实每次都是抓取数据集中前 N条数据, N是传入的参数, 比如下面, N=10
print("----take---部分元素-----")
dataset = data.Dataset.range(100)
for item in dataset.take(10):
print(item)
# 乱序数据,使数据集能够尽可能实现相互独立,分布均匀
def out_of_order_data():
dataset = data.Dataset.range(20).repeat(3)
dataset = dataset.shuffle(buffer_size=5, seed=42).batch(7)
for item in dataset:
print(item)
**#在这里学习的时候遇到了一个坑**
def preprocess_data(line):
# 此处 line是tensor类型,要转换为str类型才能进行字符串操作,
# 下面的defs中对应的是line中的数据类型, 比如:传入的line中的数据类型构成是这样的 '1, test, 100 20 30, 1.023'
# tf是可以直接让你按照“,”分割一次性把这些数据提取出来,并转换到tensor中储存起来的,注意:100 20 30是用空格分割的,因此只能把它当成字符串来看待。所以defs应该这样写 defs = [tf.constant(0, dtype=tf.int32), tf.constant("", dtype=tf.string),tf.constant("", dtype=tf.string), tf.constant(0., dtype=tf.float32) ], defs的维度对应“,”分割后的数据维度, 数据类型只要是对应的就可以 int16和int32都行
defs = [tf.constant(0, dtype=tf.int32)] * 2 + [tf.constant("", dtype=tf.string)]
fields = tf.io.decode_csv(line, record_defaults=defs) # tf.io.decode_csv将 CSV每一列映射到解析为tensor中的数值类型,拆分以“,”连接的CSV数据 # defs中定义了要将每一维转换的数据类型,可以每一维都不同
y, max_len, x = tf.stack(fields[0]), tf.stack(fields[1]), tf.stack(fields[2])
return x, y
def csv_reader_dataset(filepath, repeat=1, n_readers=5, n_read_threads = None, shuffle_buffer_size=10000,
n_parse_threads=5, batch_size = 32):
# filepath是使用列表存储的路径集合,可以是相对路径或绝对路径
dataset = data.Dataset.list_files(filepath)
dataset = dataset.interleave(lambda filepath: data.TextLineDataset(filepath).skip(1),
cycle_length=n_readers, num_parallel_calls=n_parse_threads)
# interleave函数是将filepath对应的文件中的数据交叉提取出来,文件是“.csv”类型。
dataset = dataset.map(preprocess_data, num_parallel_calls=n_parse_threads)
dataset = dataset.shuffle(shuffle_buffer_size).repeat(repeat)
return dataset.batch(batch_size).prefetch(1)
def train_df_process():
n_readers = 5
train_data = pd.read_csv("./chapter_13/train_df.csv", sep=",")
batch_size = train_data.shape[0] // n_readers
train_filepath = []
for i in range(n_readers):
filepath = "./chapter_13/my_train_0" + str(i) + ".csv"
train_filepath.append(filepath)
batch_data = train_data.loc[batch_size*i:(batch_size*(i+1)), ('label', 'text_len', 'words')]
batch_data.to_csv(filepath, index=False)
filepath_dataset = tf.data.Dataset.list_files(train_filepath, seed=42) # 返回一个乱序的文件路径数据集
dataset = filepath_dataset.interleave(lambda filepath: tf.data.TextLineDataset(filepath).skip(1),
cycle_length=n_readers)
train_set = csv_reader_dataset(train_filepath)
# for item in train_set.take(10):
# print(item)
from sklearn.datasets import fetch_openml
if __name__ == "__main__":
# data_API()
# out_of_order_data()
# preprocess_data()
# mnist = fetch_openml('mnist_784', version=1)
# X, y = mnist["data"], mnist["target"]
# print(type(mnist), type(X), type(y))
train_df_process()