tensorflow2.0学习-1

原文https://github.com/lyhue1991/eat_tensorflow2_in_30_days

1、数据准备

有三种数据形式:结构化数据、图像和文本

结构化数据:一般使用panda

图像数据:在tensorflow中常用方案有两种,第一种是使用tf.keras中的ImageDataGenerator工具构建图片数据生成器。

                  第二种是使用tf.data.Dataset搭配tf.image中的一些图片处理方法构建数据管道。

第一种方法更为简单,其使用范例可以参考以下文章。

https://zhuanlan.zhihu.com/p/67466552

第二种方法是TensorFlow的原生方法,更加灵活,使用得当的话也可以获得更好的性能。

# cifar2数据集为cifar10数据集的子集,只包括前两种类别airplane和automobile。
import tensorflow as tf 
from tensorflow.keras import datasets,layers,models
BATCH_SIZE = 100

def load_image(img_path,size = (32,32)):
    label = tf.constant(1,tf.int8) if tf.strings.regex_full_match(img_path,".*/automobile/.*") \
            else tf.constant(0,tf.int8)
    img = tf.io.read_file(img_path)
    img = tf.image.decode_jpeg(img) #注意此处为jpeg格式
    img = tf.image.resize(img,size)/255.0
    return(img,label)
#使用并行化预处理num_parallel_calls 和预存数据prefetch来提升性能
ds_train = tf.data.Dataset.list_files("./data/cifar2/train/*/*.jpg") \
           .map(load_image, num_parallel_calls=tf.data.experimental.AUTOTUNE) \
           .shuffle(buffer_size = 1000).batch(BATCH_SIZE) \
           .prefetch(tf.data.experimental.AUTOTUNE)  

ds_test = tf.data.Dataset.list_files("./data/cifar2/test/*/*.jpg") \
           .map(load_image, num_parallel_calls=tf.data.experimental.AUTOTUNE) \
           .batch(BATCH_SIZE) \
           .prefetch(tf.data.experimental.AUTOTUNE)  
%matplotlib inline
%config InlineBackend.figure_format = 'svg'

#查看部分样本
from matplotlib import pyplot as plt 

plt.figure(figsize=(8,8)) 
for i,(img,label) in enumerate(ds_train.unbatch().take(9)):
    ax=plt.subplot(3,3,i+1)
    ax.imshow(img.numpy())
    ax.set_title("label = %d"%label)
    ax.set_xticks([])
    ax.set_yticks([]) 
plt.show()

for x,y in ds_train.take(1):
    print(x.shape,y.shape)

文本数据:在tensorflow中常用方案有两种:

第一种是利用tf.keras.preprocessing中的Tokenizer词典构建工具和tf.keras.utils.Sequence构建文本数据生成器管道。

较为复杂,其使用范例可以参考以下文章。https://zhuanlan.zhihu.com/p/67697840

第二种是使用tf.data.Dataset搭配tf.keras.preprocessing中的Tokenizer词典构建工具构建文本数据管道。

import numpy as np 
import pandas as pd 
from matplotlib import pyplot as plt
import tensorflow as tf
from tensorflow.keras import models,layers,preprocessing,optimizers,losses,metrics
from tqdm import tqdm

train_data_path = "./data/imdb/train.csv"
test_data_path =  "./data/imdb/test.csv"

train_token_path = "./data/imdb/train_token.csv"
test_token_path = "./data/imdb/test_token.csv"

MAX_WORDS = 10000  # 仅考虑最高频的10000个词
MAX_LEN = 200  # 每个样本保留200个词的长度
BATCH_SIZE = 20 
# 统计文本行数
def linecount(file):
    count = 0
    with open(file,'r',encoding = 'utf-8') as f:
        while True:
            buffer = f.read(1024 * 1024)
            if not buffer:
                break
            count += buffer.count('\n')
    return count

train_samples = linecount(train_data_path)
test_samples = linecount(test_data_path)
# 制作词典
def text_generator():
    with open(train_data_path,'r',encoding = 'utf-8') as f,\
    tqdm(total = train_samples) as pbar:      
        while True:
            text = (f.readline().rstrip().split('\t')[-1])
            if not text:
                break
            words = text.split(" ")
            if len(words) > MAX_LEN:
                words = words[0:MAX_LEN]
            pbar.update(1)
            yield words
            
tokenizer = preprocessing.text.Tokenizer(num_words=MAX_WORDS)            
texts = text_generator()
tokenizer.fit_on_texts(texts)
# 单词编码
def tokenize_texts(infile,outfile,samples):
    with open(infile,encoding="utf-8") as fin, \
    open(outfile,"w",encoding="utf-8") as fout, tqdm(total = samples) as pbar:
        while True:
            data = fin.readline().rstrip()
            if not data:
                break
            label,text = data.split("\t")
            words = text.split(" ")
            wordids = preprocessing.sequence.pad_sequences(tokenizer.texts_to_sequences([words]),MAX_LEN)
            print(label+"\t"+" ".join(str(x) for x in wordids[0]),file=fout)
            pbar.update(1)
            
tokenize_texts(test_data_path,test_token_path,test_samples)
tokenize_texts(train_data_path,train_token_path,train_samples)
# 构建管道
def parse_line(line):
    t = tf.strings.split(line,"\t")
    label = tf.reshape(tf.cast(tf.strings.to_number(t[0]),tf.int32),(-1,))
    features = tf.cast(tf.strings.to_number(tf.strings.split(t[1]," ")),tf.int32)
    return (features,label)

ds_train=  tf.data.TextLineDataset(filenames = [train_token_path]) \
   .map(parse_line,num_parallel_calls = tf.data.experimental.AUTOTUNE) \
   .shuffle(buffer_size = 1000).batch(BATCH_SIZE) \
   .prefetch(tf.data.experimental.AUTOTUNE)

ds_test=  tf.data.TextLineDataset(filenames = [test_token_path]) \
   .map(parse_line,num_parallel_calls = tf.data.experimental.AUTOTUNE) \
   .shuffle(buffer_size = 1000).batch(BATCH_SIZE) \
   .prefetch(tf.data.experimental.AUTOTUNE)

2、基础

建模流程:尽管TensorFlow设计上足够灵活,可以用于进行各种复杂的数值计算。

但通常人们使用TensorFlow来实现机器学习模型,尤其常用于实现神经网络模型。

从原理上说可以使用张量构建计算图来定义神经网络,并通过自动微分机制训练模型。

但为简洁起见,一般推荐使用TensorFlow的高层次keras接口来实现神经网络网模型。

使用TensorFlow实现神经网络模型的一般流程包括:

1,准备数据

2,定义模型

3,训练模型

4,评估模型

5,使用模型

6,保存模型。

对新手来说,其中最困难的部分实际上是准备数据过程。

我们在实践中通常会遇到的数据类型包括结构化数据,图片数据,文本数据。

核心概念:TensorFlow™ 是一个采用 数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。它灵活的架构让你可以在多种平台上展开计算,例如台式计算机中的一个或多个CPU(或GPU),服务器,移动设备等等。TensorFlow 最初由Google大脑小组(隶属于Google机器智能研究机构)的研究员和工程师们开发出来,用于机器学习和深度神经网络方面的研究,但这个系统的通用性使其也可广泛用于其他计算领域

TensorFlow的主要优点:

  • 灵活性:支持底层数值计算,C++自定义操作符

  • 可移植性:从服务器到PC到手机,从CPU到GPU到TPU

  • 分布式计算:分布式并行计算,可指定操作符对应计算设备

俗话说,万丈高楼平地起,TensorFlow这座大厦也有它的地基。

Tensorflow底层最核心的概念是张量,计算图以及自动微分。

层次结构:TensorFlow中5个不同的层次结构:即硬件层,内核层,低阶API,中阶API,高阶API。并以线性回归为例,直观对比展示在不同层级实现模型的特点。

TensorFlow的层次结构从低到高可以分成如下五层。

最底层为硬件层,TensorFlow支持CPU、GPU或TPU加入计算资源池。

第二层为C++实现的内核,kernel可以跨平台分布运行。

第三层为Python实现的操作符,提供了封装C++内核的低级API指令,主要包括各种张量操作算子、计算图、自动微分. 如tf.Variable,tf.constant,tf.function,tf.GradientTape,tf.nn.softmax... 如果把模型比作一个房子,那么第三层API就是【模型之砖】。

第四层为Python实现的模型组件,对低级API进行了函数封装,主要包括各种模型层,损失函数,优化器,数据管道,特征列等等。 如tf.keras.layers,tf.keras.losses,tf.keras.metrics,tf.keras.optimizers,tf.data.DataSet,tf.feature_column... 如果把模型比作一个房子,那么第四层API就是【模型之墙】。

第五层为Python实现的模型成品,一般为按照OOP方式封装的高级API,主要为tf.keras.models提供的模型的类接口。 如果把模型比作一个房子,那么第五层API就是模型本身,即【模型之屋】。

tensorflow2.0学习-1_第1张图片

 

低阶API:TensorFlow的低阶API主要包括张量操作,计算图和自动微分。如果把模型比作一个房子,那么低阶API就是【模型之砖】。

在低阶API层次上,可以把TensorFlow当做一个增强版的numpy来使用。

TensorFlow提供的方法比numpy更全面,运算速度更快,如果需要的话,还可以使用GPU进行加速。

前面几章我们对低阶API已经有了一个整体的认识,本章我们将重点详细介绍张量操作和Autograph计算图。

张量的操作主要包括张量的结构操作和张量的数学运算。

张量结构操作诸如:张量创建,索引切片,维度变换,合并分割。

张量数学运算主要有:标量运算,向量运算,矩阵运算。另外我们会介绍张量运算的广播机制。

Autograph计算图我们将介绍使用Autograph的规范建议,Autograph的机制原理,Autograph和tf.Module.

3、使用流程

使用Keras接口有以下3种方式构建模型:使用Sequential按层顺序构建模型,使用函数式API构建任意结构模型,继承Model基类构建自定义模型。

此处选择使用最简单的Sequential,按层顺序模型。

tf.keras.backend.clear_session()
model = models.Sequential()
model.add(layers.Dense(20,activation = 'relu',input_shape=(15,)))
model.add(layers.Dense(10,activation = 'relu' ))
model.add(layers.Dense(1,activation = 'sigmoid' ))
model.summary()

训练模型通常有3种方法,内置fit方法,内置train_on_batch方法,以及自定义训练循环。此处我们选择最常用也最简单的内置fit方法。

# 二分类问题选择二元交叉熵损失函数
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['AUC'])

history = model.fit(x_train,y_train, batch_size= 64, epochs= 30, validation_split=0.2) #分割一部分训练数据用于验证

评估模型

model.evaluate(x = x_test,y = y_test)

使用模型

model.predict(x_test[0:10])

保存模型:可以使用Keras方式保存模型,也可以使用TensorFlow原生方式保存。前者仅仅适合使用Python环境恢复模型,后者则可以跨平台进行模型部署。推荐使用后一种方式进行保存。

Keras方式保存
# 保存模型结构及权重
model.save('./data/keras_model.h5')  
del model  #删除现有模型
# identical to the previous one
model = models.load_model('./data/keras_model.h5')
model.evaluate(x_test,y_test)
# 保存模型结构
json_str = model.to_json()
# 恢复模型结构
model_json = models.model_from_json(json_str)
#保存模型权重
model.save_weights('./data/keras_model_weight.h5')
# 恢复模型结构
model_json = models.model_from_json(json_str)
model_json.compile(
        optimizer='adam',
        loss='binary_crossentropy',
        metrics=['AUC']
    )
# 加载权重
model_json.load_weights('./data/keras_model_weight.h5')
model_json.evaluate(x_test,y_test)
TensorFlow原生方式保存
# 保存权重,该方式仅仅保存权重张量
model.save_weights('./data/tf_model_weights.ckpt',save_format = "tf")
# 保存模型结构与模型参数到文件,该方式保存的模型具有跨平台性便于部署
model.save('./data/tf_model_savedmodel', save_format="tf")
print('export saved model.')
model_loaded = tf.keras.models.load_model('./data/tf_model_savedmodel')
model_loaded.evaluate(x_test,y_test)

 

你可能感兴趣的:(tensorflow)