zoukankan      html  css  js  c++  java
  • Eager Execution

      Tensorflow的Eager Execution是一种命令编程环境,操作会返回具体的值。

      要启动Eager Execution,请将tf.enable_eager_execution()添加到程序或控制台回话的开头。

      启用Eager Execution会改变TensorFlow操作的行为方式,现在他们会立即评估并将值返回给Python。tf.Tensor对象会引用具体值,而不是指向计算图中的节点的符号句柄。由于不需要构建稍后在会话中运行的计算图,因此使用print()或调试程序很容易检查结果。评估、输出和检查张量值不会中断计算梯度的流程。

      tf.Tensor与numpy ndarray可以互相转换。

    动态控制流:

      在执行模型时,主机语言的所有功能都可用。

    构建模型

      将TensorFlow与Eager与Eager Execution结合使用时,可以编写自己的层或使用在tf.keras.layers程序包中提供的层。

      虽然可以使用任何Python对象表示层,但TensorFlow提供了便利的基类tf.karas.layers.Layer。可以通过他实现自己的层:

    class MysimpleLayer(tf.keras.layers.Layer):
        def __init__(self,output_units):
            super(MysimpleLayer,self).__init__()
            self.output_units=output_units
        def build(self,input_shape):
            #权重形状
            self.kernel=self.add_variable("kernel",[input_shape[-1],self.output_units])
        def call(self,input):
            #输出
            return tf.matmul(input,self.kernel)

      最好使用tf.keras.layers.Dense层(而不是上面的MysimpleLayer),它具有其功能的超集(它可以添加偏差)。

      将层组合成模型时,可以使用tf.keras.Sequential表示层线性堆叠的模型。他非常适合基本模型:

    model=tf.keras.Sequential([tf.keras.layer.Dense(10,input_shape=(784,)),
    tf.keras.layers.Dense(10)])#必须指明第一层的形状

      或者,通过继承tf.keras.Model将模型整理为类。这是一个本身也是层的层容器,允许tf.keras.Model对象包含其他tf.keras.Model对象。

    class MniSTModel(tf.keras.Model):
        def __init__(self):
            super(MniSTModel,self).__init__()
            self.dese1=tf.keras.layers.Dense(units=10)
            self.dense2=tf.keras.layers.Dense(units=10)
        def call(self,input):
            result=self.dense1(input)
            result=self.dense2(result)
            result=self.dense2(result)#复用dense2权重
            return result
    
    model=MniSTModel()

    计算梯度

      自动微分对于实现机器学习算法(例如神经网络的反向传播)来说很有用。在Eager Execution期间,使用tf.GradientTape跟踪操作以便稍后计算梯度。

      tf.GradientTape是一种选择性功能,可在不跟踪时提供最佳性能。由于在每次调用期间都可能发生不同的操作,因此所有的前向传播都会记录到“磁带"中。要计算梯度,反向播放磁带,然后放弃。特定的tf.gradientTape只能计算一个梯度;随后的调用会抛出运行时错误。

    w=tf.Variable([[1.0]])
    with tf.GradientTape() as tape:
        loss=w*w
    
    grad=tape.gradient(loss,w)
    print(grad)#=>tf.Tensor([[2.]],shape=(1,1),dtype=float32)

    训练模型

      以下实例将创建一个多层模型,该模型会对标准MNIST手写数组进行分类。它演示了在Eager Execution环境中构建可训练图的优化器和层API。

    #下载mnist数据集
    (mnist_images,mnist_labels),_=tf.keras.datasets.mnist.load_data()
    
    dataset=tf.data.Dataset.from_tensor_silices((tf.cast(mnist_images[...,tf.newaxis]/255,tf.float32),tf.cast(mnist_labels,tf.int64)))
    dataset=dataset.shuffle(1000).batch(32)
    
    #构建模型
    mnist_model=tf.keras.Sequential([tf.keras.layers.Conv2D(16,[3,3],activation='relu'),
        tf.keras.layers.Conv2D(16,[3,3],activation='relu'),
        tf.keras.layers.GlobalAveragePooling2D(),
        tf.keras.layers.Dense(10)
    ])

      即使没有训练,也可以在Eager Execution中调用模型并检查输出:

    for images,labels in dataset.take(1):
        print('logits:",mnist_model(images[0:1]).numpy())

       虽然keras模型具有内置训练循环(使用fit方法),但有时需要更多自定义设置。 下面是一个用eager实现的训练循环示例:

    optimizer=tf.train.AdamOptimizer()
    loss_history=[]
    
    for (batch,(images,labels)) in enumerate(dataset.take(400)):
        if batch %80==0:
            print()
        print('.',end=' ')
        with tf.GradientTape() as tape:
            logits=mnist_model(images,training=True)
            loss_value=tf.losses.sparse_sorftmax_cross_entropy(labels,logits)
    loss_history.append(loss_value.numpy())
    grads=tape.gradient(loss_value,mnist_model.variables)
    optimizer.apply_gradients(zip(grads,mnist_model.variables),global_step=tf.train.get_or_create_global_step())
    
    import matplotlib.pyplot as plt
    plt.plot(loss_history)
    plt.xlabel('Batch #')
    plt.ylabel('loss [entropy]')
    Text(0,0.5,'loss [entropy]')

    变量和优化器

      tf.Variable对象会储存在训练期间访问的可变tf.Tensor值,以更加轻松地实现自动微分。模型的参数可作为变量封装在类中。

      通过将tf.Variable与tf.GradientTape结合使用可以更好的封装模型参数。例如,上面的自动微分示例可以重写为:

    class Model(tf.keras.Model):
        def __init__(self):
            super(Model,self).__init__()
            self.W=tf.Variable(5.,name='weight')
            self.B=tf.Variable(10.,name='bias')
        def call(self,inputs):
            return inputs*self.W+self.B
    
    #创建小型数据集
    NUM_EXAMPLES=2000
    training_inputs=tf.random_normal([NUM_EXAMPLES])
    noise=tf.random_normal([NUM_EXAMPLES])
    training_outputs=training_inputs*3+2+noise
    
    #损失函数
    def loss(model,inputs,targets):
        error=model(inputs)-targets
        return tf.reduce_mean(tf.square(error))
    
    def grad(model,inputs,targets):
        with tf.GradientTape() as tape:
            loss_value=loss(model,inputs,targets)
        return tape.gradient(loss_value,[model.W,model.B])
    
    #1.建立model实例  2.计算损失函数对W、B的微分  3.更新参数
    model=Model()
    optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.01)
    
    print('Initial loss:{:.3f}'.format(loss(model,training_inputs,training_outputs)))
    
    #训练xunhuan
    for i in range(300):
        grads=grad(model,training_inputs,training_outputs)
        optimizer.apply_gradients(zip(grads,[model.W,model.B]),global_step=tf.train.get_or_create_global_step())
        if i%20==0:
            print('Loss at step {:03d}:{:.3f}'.format(i,loss(model,training_inputs,training_outputs)))
    print('Final loss:{:.3f}'.format(loss(model,training_inputs,training_outputs)))
    print('W={},B={}'.format(model.W.numpy(),model.B.numpy()))

      

  • 相关阅读:
    求能粘贴Word 内容(含图片)的在线编辑器
    html5分割上传实现超大文件无插件网页上传代码
    html5分割上传实现超大文件无插件网页上传源代码
    html5分割上传实现超大文件无插件网页上传源码
    html5分割上传实现超大文件无插件网页上传插件
    html5分割上传实现超大文件无插件网页上传控件
    html5分割上传实现超大文件无插件网页上传组件
    (推荐)手机频率与信号测试软件Cellular-Z使用方法
    虚拟化产品对比-思维导图
    图解VMware内存机制
  • 原文地址:https://www.cnblogs.com/biwangwang/p/11355581.html
Copyright © 2011-2022 走看看