• tensorflow学习019——Eager模式与自定义训练


    变量与自动微分

    点击查看代码
    import tensorflow as tf
    
    v = tf.Variable(1.0) #创建变量
    v.assign(5) #改变变量的值为5
    v.assign_add(2) #对变量进行+操作
    v.read_value() #读取变量的值
    
    w = tf.Variable([[1.0]])
    with tf.GradientTape() as t: #可以跟踪变量的变化
        loss = w * w
    grad = t.gradient(loss, w) #求解loss对w的微分
    print(grad)
    	
    #对常量的微分
    w = tf.constant(2.0)
    with tf.GradientTape() as t:
        t.watch(w)
        loss = w * w
    loss_dw = t.gradient(loss, w)
    print(loss_dw)
    
    需要注意的是计算的数据需要是float类型才可以

    with tf.GradientTape(persistent=True) as t:

    加上上面这行代码中的参数persistent,则后面可以多次调用t.gradient(),不加的话,则调用一次就释放了,后面不能再调用

    自定义训练

    点击查看代码
    import tensorflow as tf
    
    (train_image, train_labels), (test_image, test_labels)= tf.keras.datasets.mnist.load_data()
    train_image = tf.expand_dims(train_image,-1)  # 原先形状为(60000,28,28),现在变为(60000,28,28,1) 扩展维度,也就是通道维度
    # 如果使用参数1,那么形状就变为了(60000,1,28,28)
    test_image = tf.expand_dims(test_image,-1)
    test_image = test_image / 255
    train_image = train_image / 255  # 进行归一化
    train_image = tf.cast(train_image, tf.float32)  # 将数据类型转换为float,因为只有float才能进行自动微分
    test_image = tf.cast(test_image, tf.float32)
    train_labels = tf.cast(train_labels,tf.int64)
    test_labels = tf.cast(test_labels, tf.int64)
    dataset = tf.data.Dataset.from_tensor_slices((train_image,train_labels))  # 将图片和标签进行对应组合,这个函数是将第一维进行拆分
    # 也就是可以拆分为60000个单独的数据
    dataset = dataset.shuffle(1000).batch(32)  # 对数据进行混洗以及绑定32个为一组
    test_dataset = tf.data.Dataset.from_tensor_slices((test_image,test_labels))
    test_dataset = test_dataset.batch(32)
    
    # 自定义训练,不需要编译模型,是自己写
    
    model = tf.keras.Sequential([
        tf.keras.layers.Conv2D(16, [3,3], activation='relu', input_shape=(None,None,1)),  # None表示只要是灰度图都可以,没有规定大小
        tf.keras.layers.Conv2D(32, [3,3], activation='relu'),
        tf.keras.layers.GlobalMaxPool2D(),
        tf.keras.layers.Dense(10)  # 这里没有进行激活函数,那么就需要再后面的loss函数中进行一些操作
    ])
    optimizer=tf.keras.optimizers.Adam()  # 优化器
    loss_func = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)  # 前面没有加入激活函数,这里需要将该参数设为True
    
    def loss(model, x, y):  # 计算损失的函数
        y_ = model(x)
        return loss_func(y,y_)
    
    
    # 训练网络的一步  也就是单批次的训练过程
    # def train_step(model, images, labels):  # 计算损失函数和model变量(可训练参数)之间的梯度
    #     with tf.GradientTape() as t:  # 追踪了损失函数
    #         loss_step = loss(model,images,labels)  # 每一步的损失值
    #     grads = t.gradient(loss_step, model.trainable_variables)  # 获得交叉熵损失对网络可训练参数之间的梯度
    #     optimizer.apply_gradients(zip(grads,model.trainable_variables))  # 优化器用获得梯度来改变可训练参数
    #
    # def train(epochs):
    #     for epoch in range(epochs):
    #         print('Epoch{} is starting'.format(epoch + 1))
    #         for (batch, (images, labels)) in enumerate(dataset):
    #             train_step(model,images,labels)
    #             print(epoch," ",batch)
    
    
    train_loss = tf.keras.metrics.Mean('train_loss')
    train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('train_accuracy')
    test_loss = tf.keras.metrics.Mean('test_loss')
    test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy('test_accuracy')
    
    
    def train_step(model,images,labels):
        with tf.GradientTape() as t:
            pred = model(images)
            loss_step = loss_func(labels,pred)
        grads = t.gradient(loss_step,model.trainable_variables)
        optimizer.apply_gradients(zip(grads,model.trainable_variables))
        train_loss(loss_step)
        train_accuracy(labels,pred)
    
    def test_step(model, images, labels):
        pred = model(images)
        loss_step = loss_func(labels,pred)
        test_loss(loss_step)
        test_accuracy(labels,pred)
    
    
    def train(epoches):
        for epoch in range(epoches):
            for (batch,(images,labels)) in enumerate(dataset):
                train_step(model,images,labels)
            print('Epoch {}/{} loss is {},accuracy is {}'.format(epoch+1,epoches,train_loss.result(),train_accuracy.result()))
    
            for (batch,(images,labels)) in enumerate(test_dataset):
                test_step(model,images,labels)
            print('Epoch {}/{} test_loss is {},test_accuracy is {}'.format(epoch+1,epoches,test_loss.result(),test_accuracy.result()))
    
            train_loss.reset_states()
            train_accuracy.reset_states()
            test_loss.reset_states()
            test_accuracy.reset_states()
    
    train(10)
    

    tf.keras.metrics汇总计算模块

    点击查看代码
    # m = tf.keras.metrics.Mean('acc')  # 创建计算均值的对象  acc表示一个名称
    # m(10)  # 也可以使用m([10,20,30,40])这样的形式
    # m(20)
    # print(m.result().numpy())  # 会返回15,是10和20的均值
    # m.reset_states()  # 重置对象,也就是将里面的数值都重置,没有了10和20
    
    # a = tf.keras.metrics.SparseCategoricalAccuracy('acc')  # 初始化一个计算正确率的对象
    # print(a(labels,model(features)))  labels是正确的结果,model是一个模型,可以使用其对features进行预测,由于预测的结果是10个
    # 概率值,而SparseCategoricalAccuracy会自动选出其中最大的进行计算
    
  • 相关阅读:
    线性方程组迭代法
    统计学习方法——朴素贝叶斯法、先验概率、后验概率
    信息熵、相对熵(KL散度)、交叉熵、条件熵
    六级听力词组积累
    样本均值和样本方差的无偏性证明、样本方差的方差
    Python 矩阵相关
    Python 绘图
    win10、VSCode、python3数据科学库
    Python杂记
    Gradient descend 梯度下降法和归一化、python中的实现(未完善)
  • 原文地址:https://www.cnblogs.com/sunjianzhao/p/15961118.html
Copyright © 2020-2023  润新知