TensorFlow2.0学习笔记(三)实战篇

文章目录

代码

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'  #清除多余信息 这句话放在import TensorFlow之前才有用
import tensorflow as tf
from tensorflow import keras #tensorflow.keras是TensorFlow一个深度集成的包
from tensorflow.keras import datasets #datasets是keras提供的一个可以直接管理一个数据集的一个工具
# 加载一个mnist的数据集,自动查看你有没有缓存一个mnist数据集,如果没有它就会自动从Google Colab上下载
# 遇到了TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败问题后,将翻墙软件设置为全局模式后就可以下载了
# x:[60000,28,28]
# y:[60000]
(x,y), _ =datasets.mnist.load_data()
# 拿到数据之后先把它转化为tensor
# 一般来说,我们把input的数据放在-11,或者01的一个范围,比较适合深度学习进行优化。于是,x的范围从0255变为01.
# y后面会做一个onehot
x = tf.convert_to_tensor(x, dtype=tf.float32)/255.
y = tf.convert_to_tensor(y, dtype=tf.int32)

print(x.shape, y.shape, x.dtype, y.dtype)
# 看一下x,y的最小最大值,结果如下
# tf.Tensor(0.0, shape=(), dtype=float32) tf.Tensor(255.0, shape=(), dtype=float32) x最小值为0,最大值为255
# tf.Tensor(0, shape=(), dtype=int32) tf.Tensor(9, shape=(), dtype=int32) y最小值为0,最大值为9
print(tf.reduce_min(x), tf.reduce_max(x))
print(tf.reduce_min(y), tf.reduce_max(y))
# 创建一个数据集,创建数据集的好处在于一次取一个batch,这里bacth取128,就是说一次取128个数值
train_db = tf.data.Dataset.from_tensor_slices((x, y)).batch(128)
# 创建迭代器,迭代器可以对train做iter
train_iter = iter(train_db)
sample = next(train_iter)
print('batch:', sample[0].shape, sample[1].shape)
# batch: (128, 28, 28) (128,)
# 创建权值,权值初始化为一个随机的被修剪过的正态分布,bias一般全部初始化为0
# 降维过程:[b,784] => [b,256] => [b,128] => [b,10] 中间过程的256128是自己定的,输出是根据你有多少类定的,输入是根据输入的x的大小定的
# w要满足矩阵运算的规则,w的shape为[dim_in,dim_out],b的shape为[dim_out]
w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
b1 = tf.Variable(tf.zeros([256]))
w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1))
b2 = tf.Variable(tf.zeros([128]))
w3 = tf.Variable(tf.random.truncated_normal([128, 10], stddev=0.1))
b3 = tf.Variable(tf.zeros([10]))
# 特殊表示法,1e-3表示10-3次方
lr = 1e-3
# 对整个数据集迭代10for epoch in  range(10):
    # 每进行一个batch叫做一个step,对每个batch迭代
    for step, (x, y) in enumerate(train_db):
        # x:[128, 28, 28]
        # y: [128]
        # 需要维度变换 [b,28,28] => [b,28*28]
        x = tf.reshape(x, [-1, 28*28])
        # 需要使用TensorFlow自动求导的一个过程,将需要求梯度(前项计算)的过程包在GradientTape
        # 自动跟踪类型为tf.Variable的变量
        with tf.GradientTape() as tape:
            # x:[b,28*28]
            # 前向传播:h1 = x@w1 + b1  [b,784]@[784,256] + [256] => [b,256] + [256],+号可以直接做broadcast
            h1 = x@w1 + b1
            # 非线性
            h1 = tf.nn.relu(h1)
            # [b,256] => [b,128]
            h2 = h1@w2 +b2
            h2 = tf.nn.relu(h2)
            # [b,128]
            # 最后一次一般不加激活函数层
            out = h2@w3 +b3
            # 计算误差
            # out:[b,10]
            # y: [b]
            # y: [b] =>[b,10]
            y_onehot = tf.one_hot(y,depth=10)
            # 均方差计算 mse = mean(sum(y-out)^2)
            # [b,10]
            loss = tf.square(y_onehot - out)
            # mean之后得到scalar
            loss = tf.reduce_mean(loss)
        #计算梯度
        grads = tape.gradient(loss,[w1,b1,w2,b2,w3,b3])
        # w1 = w1 -lr*w1_grad,相减之后w1的类型由tf.Variable变为tf.tensor
        '''
        w1 = w1 - lr * grads[0]
        b1 = b1 - lr * grads[1]
        w2 = w2 - lr * grads[2]
        b2 = b2 - lr * grads[3]
        w3 = w3 - lr * grads[4]
        b3 = b3 - lr * grads[5]
        这么写只能算一遍
        '''
        # 原地更新
        w1.assign_sub(lr * grads[0])
        b1.assign_sub(lr * grads[1])
        w2.assign_sub(lr * grads[2])
        b2.assign_sub(lr * grads[3])
        w3.assign_sub(lr * grads[4])
        b3.assign_sub(lr * grads[5])
        if step %100 == 0:
           print(epoch, step, 'loss:', float(loss))
        '''
        100 loss: nan
        200 loss: nan
        300 loss: nan
        400 loss: nan
        nan:not a number
        出现这句话说明梯度爆炸
        (只迭代一次)把w的方差设置为0.1后:
        100 loss: 0.20223207771778107
        200 loss: 0.18103241920471191
        300 loss: 0.14289739727973938
        400 loss: 0.1504320204257965
        迭代10次后:
        9 100 loss: 0.08612565696239471
        9 200 loss: 0.09116230905056
        9 300 loss: 0.08154936879873276
        9 400 loss: 0.09231320768594742
        '''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值