zoukankan      html  css  js  c++  java
  • 吴裕雄--天生自然TensorFlow2教程:前向传播(张量)- 实战

    手写数字识别流程
    MNIST手写数字集7000*10张图片
    60k张图片训练,10k张图片测试
    每张图片是28*28,如果是彩色图片是28*28*3
    0-255表示图片的灰度值,0表示纯白,255表示纯黑
    打平28*28的矩阵,得到28*28=784的向量
    对于b张图片得到[b,784];然后对于b张图片可以给定编码
    把上述的普通编码给定成独热编码,但是独热编码都是概率值,并且概率值相加为1,类似于softmax回归
    套用线性回归公式
    X[b,784] W[784,10] b[10] 得到 [b,10]
    高维图片实现非常复杂,一个线性模型无法完成,因此可以添加非线性因子
    f(X@W+b),使用激活函数让其非线性化,引出relu函数
    1 =relu(X@W1+b1)
    H2 = relu(h1@W2+b2)
    Out = relu(h2@W3+b3)
    第一步,把[1,784]变成[1,512]变成[1,256]变成[1,10]
    得到[1,10]后将结果进行独热编码
    使用欧氏距离或者使用mse进行误差度量
    [1,784]通过三层网络输出一个[1,10]
    # [b,784] ==> [b,256] ==> [b,128] ==> [b,10]
    # [dim_in,dim_out],[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]))
    # learning rate
    lr = 1e-3
    for epoch in range(10):  # iterate db for 10
        # tranin every train_db
        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])
            with tf.GradientTape() as tape:  # only data types of tf.variable are logged
                # x: [b,28*28]
                # h1 = x@w1 + b1
                # [b,784]@[784,256]+[256] ==> [b,256] + [256] ==> [b,256] + [b,256]
                h1 = x @ w1 + tf.broadcast_to(b1, [x.shape[0], 256])
                h1 = tf.nn.relu(h1)
                # [b,256] ==> [b,128]
                # h2 = x@w2 + b2  # b2 can broadcast automatic
                h2 = h1 @ w2 + b2
                h2 = tf.nn.relu(h2)
                # [b,128] ==> [b,10]
                out = h2 @ w3 + b3
                # compute loss
                # out: [b,10]
                # 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)
            # compute gradients
            grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])
            # w1 = w1 - lr * w1_grad
            # w1 = w1 - lr * grads[0]  # not in situ update
            # in situ update
            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(f'epoch:{epoch}, step: {step}, loss:{float(loss)}')
  • 相关阅读:
    Google
    LeetCode 664. 奇怪的打印机
    LeetCode 79. 单词搜索
    LeetCode 224. 基本计算器
    Windows 端口映射
    LeetCode 354. 俄罗斯套娃信封问题
    LeetCode 300. 最长递增子序列
    LeetCode 338. 比特位计数
    LeetCode 395. 至少有K个重复的最长子串
    LeetCode 424. 替换后的最长重复字符
  • 原文地址:https://www.cnblogs.com/tszr/p/12124447.html
Copyright © 2011-2022 走看看