TensorFlow2.0笔记

安装TensorFlow的教程,很多自行搜索。我这里安装的是2.5.0版本

基础概念

1.张量

张量是TensorFlow的构图基本单元,是其最核心的组件,所有运算和优化都是基于张量完成的。

张量是一个多维数组,在TensorFlow 2.0中表现为tf.Tensor对象与NumPy ndarray对象类似,Tensor对象具有数据类型和形状。在TensorFlow2.0中,张量Tensor可以保持在GPU中,同时TensorFlow提供了操作库,操作张量Tensor

在2.0中 Tensor都有其自己的形状和类型,例如下面代码。

import tensorflow as tf
from  numpy import  int32


if __name__ == '__main__':
    # print(tf.add(1,2))
    # print(tf.square(3)+tf.square(4))
    x=tf.matmul([[3],[6]],[[2]])
    print(x)
    print(x.shape)
    print(x.dtype)

输出

tf.Tensor(
[[ 6]
 [12]], shape=(2, 1), dtype=int32)
(2, 1)
<dtype: 'int32'>

在TensorFlow 2.0中,NumPy数组和tf.Tensors之间最明显的区别是:①张量可以由GPU(或TPU)支持;②张量不可变;③TensorFlow tf.Tensors和NumPy ndarray之间的转换很容易。

2. GPU加速

GPU可以加速TensorFlow操作,当然没有注释的话,会自动选择CPU还是GPU。

在TensorFlow中,Placement是如何分配设备以执行何种操作,如果没有指定,会自动执行,也可以使用tf.device上下文管理器将TensorFlow操作显式分配到特定设备上。

3.数据集

数据集是数据的集合,这里使用tf.data.Dataset API构建管道,为模型提供数据。

  1. 创建源数据集

    在使用数据集之前,需要先创建一个源数据集,使用工厂函数(如Dataset.from_tensors,Dataset.from_tensor_slices)或从TextLineDataset和TFRecordDataset等文件中读取的对象来创建源数据集,

  2. 转换函数

    将map、batch和shuffle等转换函数应用于数据集记录

  3. 迭代

    迭代是处理数据集的常用方法,tf.data.Dataset对象支持迭代循环记录

4. 自定义层

TensorFlow 2.0推荐使用tf.keras来构建网络层。

构建一个简单的全连接网络,代码如下:

    layer = tf.keras.layers.Dense(100)
    layer = tf.keras.layers.Dense(100, input_shape=(None, 20))
    layer(tf.ones([6, 6]))
    print(layer.variables)

运行结果,包含权重和偏执信息。

[<tf.Variable 'dense_1/kernel:0' shape=(6, 100) dtype=float32, numpy=
array([[-0.00431676, -0.06364453,  0.18471815,  0.00917906,  0.06384067,
        -0.0105741 , -0.17715897,  0.09761019, -0.1670472 , -0.09340359,
         0.14406456, -0.12492266, -0.2299047 , -0.0464382 ,  0.0669059 ,
                .............
        -0.00495996, -0.04538904,  0.10822816,  0.1276768 ,  0.20116921,
        -0.20041212,  0.02798168, -0.06030737, -0.08965875, -0.07150203,
         0.0109331 , -0.21503884,  0.02873243, -0.00767355, -0.00091705,
         0.14365633,  0.15433769,  0.01709612,  0.11761661,  0.17389186]],
      dtype=float32)>, <tf.Variable 'dense_1/bias:0' shape=(100,) dtype=float32, numpy=
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
      dtype=float32)>]

Process finished with exit code 0

kersa可以分别获得权重和偏置,使用kernel和bias即可

自定义网络层,主要使用三个函数。init初始化函数、build函数、call函数,例如:

class Dense(tf.keras.layers.Layer):
    # 初始化函数
    def __init__(self,outputs):
        super(Dense,self).__init__()
        self.outputs=outputs
    #build函数
    def build(self, input_shape):
        self.kernel=self.add_weight('kernel',shape=[int(input_shape[-1]),self.outputs])
    #call函数
    def call(self, inputs):
        return tf.matmul(inputs,self.kernel)

TensorFlow使用的求导方法被称为自动微分,它既不是符号求导也不是数值求导,而是两者的结合。2.0利用tf.GradientTape API来实现自动求导功能,在tf.GradientTape()上下文中执行的操作都会被记录在“tape”中,然后TensorFlow 2.0使用反向自动微分来计算相关操作的梯度。

MLP

多层感知器(MLP)是一种前馈人工神经网络模型,可以将输入的多个数据集映射到单一的输出数据集上。一般地,单层神经网络并不能保证模型的准确率,这时需要使用多层感知其构成模型。

Keras

TensorFlow2.0最大的变化就是大量Keras作为默认的API。

1.基础

Keras是一个开源的人工神经网络库,可以作为TensorFlow、Thenao的高阶API,实现深度学习模型的设计、调试、应用、可视化等。

主要优点是方便用户使用、模块化和可组合、易于扩展,TensorFlow2.0常用的神经网络都在keras.layer中。

1.1构造数据

Keras构造数据的基础函数是tf.data,如下面的代码:

from __future__ import absolute_import,division,print_function
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers


# 构建模型函数
def get_model():
    inputs=keras.Input(shape=(784,),name='mnist_input')
    h1=layers.Dense(64,activation='relu')(inputs)
    h2=layers.Dense(64,activation='relu')(h1)
    outputs=layers.Dense(10,activation='softmax')(h2)
    model=keras.Model(inputs,outputs)
    model.compile(optimizer=keras.optimizers.RMSprop(),
                  loss=keras.losses.SparseCategoricalCrossentropy(),
                  metrics=[keras.metrics.SparseCategoricalAccuracy()])
    return model



if __name__ == '__main__':
    (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
    x_train=x_train.reshape(60000,784).astype('float32')/255
    x_test = x_test.reshape(10000,784).astype('float32') / 255
    x_val=x_train[-10000:]
    y_val=y_train[-10000:]
    x_train=x_train[:-10000]
    y_train = y_train[:-10000]

    model=get_model()
    train_dataset=tf.data.Dataset.from_tensor_slices((x_train,y_train))
    train_dataset=train_dataset.shuffle(buffer_size=1024).batch(64)

    val_dataset=tf.data.Dataset.from_tensor_slices((x_val,y_val))
    val_dataset=val_dataset.batch(64)
    model.fit(train_dataset,epochs=3,steps_per_epoch=100,
              validation_data=val_dataset,validation_steps=3)

结果:

 1.2样本权重和类权重

样本权重数组用于指定批处理中每个样本在计算损失率时应具有的权重值,通常用于处理不平衡的分类问题。当使用的权重是1和0时,该数组可以作为损失函数的掩码。

类权重更加具体,它将类索引映射到应该用于属于该类的样本的样本权重。区别代码:

from __future__ import absolute_import,division,print_function
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np

# 构建模型函数
def get_model():
    inputs=keras.Input(shape=(784,),name='mnist_input')
    h1=layers.Dense(64,activation='relu')(inputs)
    h2=layers.Dense(64,activation='relu')(h1)
    outputs=layers.Dense(10,activation='softmax')(h2)
    model=keras.Model(inputs,outputs)
    model.compile(optimizer=keras.optimizers.RMSprop(),
                  loss=keras.losses.SparseCategoricalCrossentropy(),
                  metrics=[keras.metrics.SparseCategoricalAccuracy()])
    return model



if __name__ == '__main__':
    (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
    x_train=x_train.reshape(60000,784).astype('float32')/255
    x_test = x_test.reshape(10000,784).astype('float32') / 255
    x_val=x_train[-10000:]
    y_val=y_train[-10000:]
    x_train=x_train[:-10000]
    y_train = y_train[:-10000]
    model=get_model()
    # # 类权重
    # class_weight={i:1.0 for i in range(10)}
    # class_weight[5]=2.0
    # print(class_weight)
    # model.fit(x_train,y_train,class_weight=class_weight,batch_size=64,epochs=4)
#   样本权重
    sample_weight=np.ones(shape=(len(y_train),))
    sample_weight[y_train==5]=2.0
    model.fit(x_train, y_train, sample_weight=sample_weight, batch_size=64, epochs=4)



1.3 回调

Keras中的回调是在训练期间(epoch开始时、batch结束时、epoch结束时等)不同点处调用的对象。可以自己按照实际情况自定义回调方法。

2 API

详细的Keras的知识,可以参考我的这篇文章。

2.1构建网络

有模型层的API可以构建网络,使用tf.keras.Model实例来调用并返回张量,完成训练,代码如下:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

  inputs=tf.keras.Input(shape=(784,),name='mnist_input')

  h1=layers.Dense(64,activation='relu')(inputs)
  h2=layers.Dense(64,activation='relu')(h1)
    
  outputs=layers.Dense(10,activation='softmax')(h2)

  model=keras.Model(inputs,outputs)


#初始化参数
  model.compile(optimizer=keras.optimizers.RMSprop(),
                loss=keras.losses.SparseCategoricalCrossentropy(),
                metrics=[keras.metrics.SparseCategoricalAccuracy()])

  sample_weight=np.ones(shape=(len(y_train),))
  sample_weight[y_train==5]=2.0
#训练4次
  model.fit(x_train, y_train, sample_weight=sample_weight, batch_size=64, epochs=4)

评估模型

test_scores=model.evaluate(x_test,y_test,verbose=0)

2.2 经典网络

使用API构建小型残差网络

#以TensorFlow为基础构建Keras
import ssl
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras import layers

if __name__ == '__main__':
    ssl._create_default_https_context = ssl._create_unverified_context
    # 实例化Keras 张量,并将其作为输入
    inputs = keras.Input(shape=(32, 32, 3),name = 'img') 
    # 定义网络层h1
    h1 = layers.Conv2D(32,3,activation = 'relu')(inputs)
    h1 = layers.Conv2D(64,3, activation = 'relu')(h1)
    block1_out = layers.MaxPooling2D(3)(h1)
    # 定义网络层h2
    h2 = layers.Conv2D(64,3,activation = 'relu', padding = 'same' )(block1_out)
    h2 = layers.Conv2D(64,3,activation = 'relu', padding = 'same')(h2)
    block2_out = layers.add([h2,block1_out])
    # 定义网络层h3
    h3 = layers.Conv2D(64,3,activation = 'relu', padding = 'same')(block2_out)
    h3 = layers.Conv2D(64,3,activation = 'relu', padding = 'same')(h3)
    block3_out = layers.add([h3,block2_out])
    # 定义网络层h4
    h4 = layers.Conv2D(64,3,activation = 'relu' )(block3_out)
    h4 = layers.GlobalMaxPool2D()(h4)
    h4 = layers.Dense(256,activation = 'relu')(h4)
    h4 = layers.Dropout(0.5)(h4)
    outputs = layers.Dense(10,activation = 'softmax' ) (h4)
    # 定义模型
    model = keras.Model(inputs,outputs) 
    # 输出模型详情
    model.summary()
    # 导入数据集并划分训练集和测试集
    (x_train,y_train),(x_test, y_test) = keras.datasets.cifar10.load_data()
    x_train = x_train.astype('float32') / 255
    x_test = y_train.astype('float32') / 255
    y_train = keras.utils.to_categorical(y_train,10)
    y_test = keras.utils.to_categorical(y_test,10) 
    # 初始化所有的权重参数
    model.compile(optimizer=keras.optimizers.RMSprop(1e-3),
                  loss='categorical_crossentropy', metrics=['acc'])
    # 制订训练计划并进行训练
    model.fit(x_train,y_train,batch_size = 64, epochs = 1,validation_split = 0.2)

2.3 构建简单的网络

使用API构建一个简单的网络,如下代码:

from __future__ import absolute_import,division,print_function
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras. layers as layers
#定义网络层,实际上就是设置网络权重和从输出到输入的计算过程
class MyLayer(layers.Layer):
    def __init__(self, input_dim=32,unit=32):
        super(MyLayer,self). __init__()
        w_init = tf.random_normal_initializer()
        self.weight = tf.Variable(initial_value=w_init(
            shape=(input_dim,unit),dtype=tf.float32),trainable=True)
        b_init = tf.zeros_initializer()
        self.bias = tf.Variable(initial_value=b_init(
            shape=(unit,),dtype=tf.float32),trainable=True)
    def call(self, inputs):
        return tf.matmul(inputs,self.weight) + self.bias

#创建一个将所有元素都设置为1的张量
if __name__ == '__main__':

    x= tf.ones ((3,5))
    my_layer = MyLayer(5,4)
    out = my_layer(x)
    print(out)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值