TensorFlow的小案例

1、利用TensorFlow写出BGD、SGD、MBGD的代码

(1)基于线性回归 TensorFlow BGD

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

if __name__ == '__main__':
    with tf.Graph().as_default():
        # 1. 创建执行图
            # a. 定义占位符, shape中的None表示不做限制的意思
        input_x = tf.placeholder(dtype=tf.float32, shape=[None, 1], name='x')
        input_y = tf.placeholder(dtype=tf.float32, shape=[None, 1], name='y')

        # b. 定义模型参数变量
        w = tf.Variable(initial_value=[[-5]], dtype=tf.float32)
        b = tf.Variable(initial_value=[3], dtype=tf.float32)

        # c. 计算预测值y
        y_ = tf.add(tf.matmul(input_x, w), b)

        # d. 基于预测值和实际值构建损失函数
        loss = tf.reduce_mean(tf.square(input_y - y_), name='loss')

        # e. 让损失函数最小的时候模型就是最优模型
            # 定义一个优化器
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
        # 对损失函数进行优化操作
        train_op = optimizer.minimize(loss=loss)

        # 2. 执行图运行
        with tf.Session() as sess:
            # 变量初始化 给定变量值
            sess.run(tf.global_variables_initializer())

            # 1. 随机数据产生、加载
            np.random.seed(28)
            N = 100
            x = np.linspace(0, 6, N) + np.random.normal(0, 2.0, N)
            y = 14 * x + 7 - np.random.normal(0, 5.0, N)
            x.shape = -1, 1
            y.shape = -1, 1
            print((np.shape(x), np.shape(y)))

====================================== BGD ===============================================
            # TODO: 下面为BGD的模型训练( epoch: 所有样本 一次迭代更新 )
            for epoch in range(200):
                # BGD迭代优化更新参数
                sess.run(fetches=[train_op],feed_dict={input_x:x,input_y:y})
                # 获取一个 epoch 更新后损失函数的大小
                loss_ = sess.run(loss,feed_dict={input_x:x,input_y:y})
                print('第{}个epoch后损失函数的大小为{}'.format(epoch+1,loss_))
==========================================================================================

            # 3. 使用训练好的模型对数据做一个预测
            predict = sess.run(y_, feed_dict={input_x: x})

            # 可视化画图
            plt.plot(x, y, 'ro')
            plt.plot(x, predict, 'g-')
            plt.show()

(2)基于线性回归 TensorFlow SGD

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

if __name__ == '__main__':
    with tf.Graph().as_default():
        # 1. 创建执行图
            # a. 定义占位符, shape中的None表示不做限制的意思
        input_x = tf.placeholder(dtype=tf.float32, shape=[None, 1], name='x')
        input_y = tf.placeholder(dtype=tf.float32, shape=[None, 1], name='y')

        # b. 定义模型参数变量
        w = tf.Variable(initial_value=[[-5]], dtype=tf.float32)
        b = tf.Variable(initial_value=[3], dtype=tf.float32)

        # c. 计算预测值y
        y_ = tf.add(tf.matmul(input_x, w), b)

        # d. 基于预测值和实际值构建损失函数
        loss = tf.reduce_mean(tf.square(input_y - y_), name='loss')

        # e. 让损失函数最小的时候模型就是最优模型
            # 定义一个优化器
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
        # 对损失函数进行优化操作
        train_op = optimizer.minimize(loss=loss)

        # 2. 执行图运行
        with tf.Session() as sess:
            # 变量初始化 给定变量值
            sess.run(tf.global_variables_initializer())

            # 1. 随机数据产生、加载
            np.random.seed(28)
            N = 100
            x = np.linspace(0, 6, N) + np.random.normal(0, 2.0, N)
            y = 14 * x + 7 - np.random.normal(0, 5.0, N)
            x.shape = -1, 1
            y.shape = -1, 1
            print((np.shape(x), np.shape(y)))

======================================= SGD ==============================================
            # TODO: 下面为SGD的模型训练( epoch: 所有样本 一次迭代更新 )
            for epoch in range(200):
                # SGD迭代优化更新参数
                random_index = np.random.permutation(N)   # # 产生[0,N)的序列,步长为1,并且将这个序列值进行打乱顺序的操作
                for idx in range(N):
                    # 用每一个样本进行更新模型参数,当所有样本更新之后 称为 一个epoch
                    sess.run(fetches=[train_op],feed_dict={input_x:[x[idx]],input_y:[y[idx]]})

                # 获取一个 epoch 更新后损失函数的大小
                loss_ = sess.run(loss,feed_dict={input_x:x,input_y:y})
                print('第{}个epoch后损失函数的大小为{}'.format(epoch+1,loss_))
==========================================================================================

            # 3. 使用训练好的模型对数据做一个预测
            predict = sess.run(y_, feed_dict={input_x: x})

            # 可视化画图
            plt.plot(x, y, 'ro')
            plt.plot(x, predict, 'g-')
            plt.show()

(3)基于线性回归 TensorFlow MBGD

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

if __name__ == '__main__':
    with tf.Graph().as_default():
        # 1. 创建执行图
            # a. 定义占位符, shape中的None表示不做限制的意思
        input_x = tf.placeholder(dtype=tf.float32, shape=[None, 1], name='x')
        input_y = tf.placeholder(dtype=tf.float32, shape=[None, 1], name='y')

        # b. 定义模型参数变量
        w = tf.Variable(initial_value=[[-15]], dtype=tf.float32)
        b = tf.Variable(initial_value=[10], dtype=tf.float32)

        # c. 计算预测值y
        y_ = tf.add(tf.matmul(input_x, w), b)

        # d. 基于预测值和实际值构建损失函数
        loss = tf.reduce_mean(tf.square(input_y - y_), name='loss')

        # e. 让损失函数最小的时候模型就是最优模型
            # 定义一个优化器
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
        # 对损失函数进行优化操作
        train_op = optimizer.minimize(loss=loss)

        # 2. 执行图运行
        with tf.Session() as sess:
            # 变量初始化 给定变量值
            sess.run(tf.global_variables_initializer())

            # 1. 随机数据产生、加载
            np.random.seed(28)
            N = 100
            x = np.linspace(0, 6, N) + np.random.normal(0, 2.0, N)
            y = 14 * x + 7 - np.random.normal(0, 5.0, N)
            x.shape = -1, 1
            y.shape = -1, 1
            print((np.shape(x), np.shape(y)))

======================================== MBGD ============================================
            # TODO: 下面为MBGD的模型训练( epoch: 所有样本 一次迭代更新,batch指的是epoch中一次使用多少样本更新参数 )

            batch_size = 10
            total_batch_num = N//batch_size
            for epoch in range(200):
                # SGD迭代优化更新参数
                random_index = np.random.permutation(N)   # # 产生[0,N)的序列,步长为1,并且将这个序列值进行打乱顺序的操作
                for idx in range(total_batch_num):
                    # 构建随机的 batch 索引
                    start = idx * batch_size
                    end = start + batch_size
                    index = random_index[start:end]
                    # 用每一个样本进行更新模型参数,当所有样本更新之后 称为 一个epoch
                    sess.run(fetches=[train_op],feed_dict={input_x:x[index],input_y:y[index]})

                # 获取一个 epoch 更新后损失函数的大小
                loss_ = sess.run(loss,feed_dict={input_x:x,input_y:y})
                print('第{}个epoch后损失函数的大小为{}'.format(epoch+1,loss_))
==========================================================================================

            # 3. 使用训练好的模型对数据做一个预测
            predict = sess.run(y_, feed_dict={input_x: x})

            # 可视化画图
            plt.plot(x, y, 'ro')
            plt.plot(x, predict, 'g-')
            plt.show()

2、利用TensorFlow softmax 手写数字识别(分类) 

(1)基于sklearn库的机器学习(logistic softmax)分类

import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
from sklearn.datasets import load_digits
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix

if __name__ == '__main__':
    # 1. 加载数据
    digits = load_digits()
    # print(digits)
    # print("key:{}".format(digits.keys()))
    # 总有1797张图像,10个类别,每个图像使用8*8=64个像素值进行图像的描述
    print("训练数据X的形状:{}".format(digits.data.shape))
    print("图像数据的形状:{}".format(digits.images.shape))
    print("目标属性的形状:{}".format(digits.target.shape))
    print("具体的目标属性:{}".format(digits.target_names))

    # # 可视化
    # idx = 136
    # print(digits.images[idx])
    # plt.imshow(digits.images[idx], cmap=plt.cm.gray_r)
    # plt.title(digits.target[idx])
    # plt.show()

    # 2. 数据的清洗

    # 3. 根据需求和原始模型从原始的特征属性中获取特征属性矩阵X和目标属性矩阵Y
    X = digits.data
    Y = digits.target

    # 4. 数据的分割(划分为训练数据和测试数据)
    n_samples = digits.images.shape[0]
    split_index = n_samples * 2 // 3
    x_train, x_test = X[:split_index], X[split_index:]
    y_train, y_test = Y[:split_index], Y[split_index:]
    print("训练数据格式:{}".format(x_train.shape))
    print("测试数据格式:{}".format(x_test.shape))

    # 5. 特征工程

    # 6. 模型对象的构建
    algo = LogisticRegression()

    # 7. 模型对象的训练
    algo.fit(x_train, y_train)

    # 8. 模型效果评估
    train_pred = algo.predict(x_train)
    test_pred = algo.predict(x_test)
    print('机器学习训练集真实值与预测值的维度为:',y_train.shape,train_pred.shape)
    print("训练数据上的准确率:{}".format(accuracy_score(y_train, train_pred)))
    print("测试数据上的准确率:{}".format(accuracy_score(y_test, test_pred)))
    print("训练数据上的混淆矩阵:\n{}".format(confusion_matrix(y_train, train_pred)))
    print("测试数据上的混淆矩阵:\n{}".format(confusion_matrix(y_test, test_pred)))
    print('获取每一个样本softmax每一个类别的概率:\n',algo.predict_proba(x_train))

(2)基于TensorFlow softmax 手写数字分类

1、注意:TensorFlow 分类问题与回归问题不同:
    回归问题:输入数据标签 Y 大多数只有 1列。
    分类问题:输入数据标签 Y 需要进行 哑编码(onehot),因此分类 深度学习 Y标签通常不是 1列。
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.datasets import load_digits
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import accuracy_score,confusion_matrix

if __name__ == '__main__':
    # 图构建
    with tf.Graph().as_default():
        # 模型构建
            # 定义输入数据占位符
                # 定义为 float32 比 float64 减少迭代次数 
        input_x = tf.placeholder(dtype=tf.float32, shape=(None, 64), name='x')             
        input_y = tf.placeholder(dtype=tf.float32, shape=(None, 10), name='y')
            # 构建网络参数
                # 截距正态可以减少迭代次数,方差一般为 0.001 - 0.05
        w_initial = tf.Variable(initial_value=tf.truncated_normal(shape=[64, 10],stddev=0.009),name='w')       
        b_initial = tf.Variable(initial_value=tf.zeros(shape=[10],dtype=tf.float32),name='b')  
                # 常数项通常置零
            # 计算预测值
        dec_value = tf.add(tf.matmul(input_x, w_initial), b_initial) 
                    # 计算得出softmax决策函数值,二维数组(样本数 * 类数)
        prob = tf.nn.softmax(dec_value)  # softmax根据决策函数值计算映射 0-1 的概率的二维数组 
        y_pre = tf.argmax(prob, axis=1)  # 计算一维数组预测值(eg: [0,1,3,4,5,6....])
                  # 寻找出二维数组prob 中axis=1维度最大值的索引(正好是预测值,它是一维结构(eg:[1、0、5、0、1 ...]))
        print(dec_value,input_y,y_pre)
        # 构建损失函数
            # 第一种:手写交叉熵损失函数:
        # loss = -tf.reduce_mean(tf.log(tf.reduce_sum(input_y * prob,axis=1)),name='loss')
            # 第二种:直接用 tensorflow 内置的softmax交叉熵损失函数:
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=input_y,
                                                         logits=dec_value),name='loss')
        '''
                参数:
                    labels=None,         ---- 是实际的标签对象,是一个二维的数组/Tensor,哑编码之后的
                    logits=None,         ---- 是预测的相当于决策函数值形成的二维的数组/Tensor
                    name=None):          ---- 操作命名
        '''
        # 构建优化器
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.006)
        train_op = optimizer.minimize(loss=loss)

        # 图运行
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            # 加载数据
            digits = load_digits()
            X = digits.data
            Y = digits.target.reshape((-1, 1))
            onehot = OneHotEncoder(sparse=False)
            onehot.fit(Y)

            n_samples = digits.images.shape[0]
            split_index = n_samples * 2 // 3
            x_train, x_test = X[:split_index], X[split_index:]
            y_train, y_test = Y[:split_index], Y[split_index:]
            y_train = onehot.transform(y_train)
            y_test = onehot.transform(y_test)
            print("训练数据格式:{}.{}".format(x_train.shape,y_train.shape))
            print("测试数据格式:{}.{}".format(x_test.shape,y_test.shape))
            print('================================================================== ')
            # 模型训练
                # TODO BGD
            # for epoch in range(800):
            #     # 模型训练优化
            #     sess.run(fetches=[train_op], feed_dict={
            #         input_x: x_train,  # 给定占位符的值
            #         input_y: y_train  # 给定占位符的值
            #     })
            #     loss_ = sess.run(fetches=[loss], feed_dict={
            #         input_x: x_train,  # 给定占位符的值
            #         input_y: y_train  # 给定占位符的值
            #     })
            #     print("第{}次训练后模型的损失函数值为:{}".format(epoch+1, loss_))
                # TODO MBGD
            N = x_train.shape[0]
            batch_size = 100
            total_batch_num = N // batch_size
            for epoch in range(800):
                # 模型训练优化
                random_index = np.random.permutation(N)
                for idx in range(total_batch_num):
                    # 构建随机batch索引
                    start = idx * batch_size
                    end = start + batch_size
                    random_batch = random_index[start:end]
                    # batch 训练
                    sess.run(fetches=[train_op], feed_dict={
                        input_x: x_train[random_batch],  # 给定占位符的值
                        input_y: y_train[random_batch]  # 给定占位符的值
                    })

                loss_ = sess.run(fetches=[loss], feed_dict={
                    input_x: x_train,  # 给定占位符的值
                    input_y: y_train  # 给定占位符的值
                })
                print("第{}次训练后模型的损失函数值为:{}".format(epoch+1, loss_))

            # 模型评估
            train_predict = sess.run(y_pre, feed_dict={input_x: x_train}).reshape((-1, 1))
            test_predict = sess.run(y_pre, feed_dict={input_x: x_test}).reshape((-1, 1))

            # 可视化画图
            y_train = onehot.inverse_transform(y_train)     # 将 onehot 类型的标签 转化为 0,1,2,3,4 ...
            y_test = onehot.inverse_transform(y_test)
            print("训练数据上的准确率:{}".format(accuracy_score(y_train, train_predict)))
            print("测试数据上的准确率:{}".format(accuracy_score(y_test, test_predict)))
            print("训练数据上的混淆矩阵:\n{}".format(confusion_matrix(y_train, train_predict)))
            print("测试数据上的混淆矩阵:\n{}".format(confusion_matrix(y_test, test_predict)))

            # 模型持久化


============================== 使用深度学习 accuracy_score 计算方式 ==========================

import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.datasets import load_digits
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import accuracy_score,confusion_matrix

if __name__ == '__main__':
    # 图构建
    with tf.Graph().as_default():
        # 模型构建
            # 定义输入数据占位符
        input_x = tf.placeholder(dtype=tf.float32, shape=(None, 64), name='x')   
                  # 定义为 float32 比 float64 减少迭代次数
        input_y = tf.placeholder(dtype=tf.float32, shape=(None, 10), name='y')
            # 构建网络参数
        w_initial = tf.Variable(initial_value=tf.truncated_normal(shape=[64, 10],stddev=0.009),name='w') 
                  # 截距正态可以减少迭代次数,方差一般为 0.001 - 0.05
        b_initial = tf.Variable(initial_value=tf.zeros(shape=[10],dtype=tf.float32),name='b')  
                  # 常数项通常置零
            # 计算预测值
        dec_value = tf.add(tf.matmul(input_x, w_initial), b_initial)
        prob = tf.nn.softmax(dec_value)
        y_pre = tf.argmax(prob, axis=1)
        print(dec_value,input_y,y_pre)
        # 构建损失函数
            # 第一种:手写交叉熵损失函数:
        # loss = -tf.reduce_mean(tf.log(tf.reduce_sum(input_y * prob,axis=1)),name='loss')
            # 第二种:直接用 tensorflow 内置的softmax交叉熵损失函数:
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=input_y,
                                                      logits=dec_value),name='loss')
        '''
                参数:
                    labels=None,         ---- 是实际的标签对象,是一个二维的数组/Tensor,哑编码之后的
                    logits=None,         ---- 是预测的相当于决策函数值形成的二维的数组/Tensor
                    name=None):          ---- 操作命名
        '''
        # 构建优化器
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.006)
        train_op = optimizer.minimize(loss=loss)

--------------------------------- 构建模型评估操作对象 ---------------------------------------
        # 构建模型评估的操作对象
            # 获取真实值(将 onehot 的标签 转化为 0,1,2,3,4,5 .....)
        y_true = tf.argmax(input_y,axis=1)
            # 计算准确率
            # 对实际值和预测值做比较,看一下是否相等, 然后将其转换为准确率
            # TODO: 要求y_pre和y_true的形状格式完全一致,两个都是一维结构
        acc_score = tf.reduce_mean(tf.cast(tf.equal(y_pre,y_true),dtype=tf.float32))

---------------------------------------------------------------------------------------------
        # 图运行
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            # 加载数据
            digits = load_digits()
            X = digits.data
            Y = digits.target
            X = digits.data
            Y = digits.target.reshape((-1, 1))
            onehot = OneHotEncoder(sparse=False)
            onehot.fit(Y)

            n_samples = digits.images.shape[0]
            split_index = n_samples * 2 // 3
            x_train, x_test = X[:split_index], X[split_index:]
            y_train, y_test = Y[:split_index], Y[split_index:]
            y_train = onehot.transform(y_train)
            y_test = onehot.transform(y_test)
            print("训练数据格式:{}.{}".format(x_train.shape,y_train.shape))
            print("测试数据格式:{}.{}".format(x_test.shape,y_test.shape))
            print('================================================================== ')
            # 模型训练
                # TODO BGD
            # for epoch in range(800):
            #     # 模型训练优化
            #     sess.run(fetches=[train_op], feed_dict={
            #         input_x: x_train,  # 给定占位符的值
            #         input_y: y_train  # 给定占位符的值
            #     })
            #     loss_ = sess.run(fetches=[loss], feed_dict={
            #         input_x: x_train,  # 给定占位符的值
            #         input_y: y_train  # 给定占位符的值
            #     })
            #     print("第{}次训练后模型的损失函数值为:{}".format(epoch+1, loss_))
                # TODO MBGD
            N = x_train.shape[0]
            batch_size = 100
            total_batch_num = N // batch_size
            for epoch in range(800):
                # 模型训练优化
                random_index = np.random.permutation(N)
                for idx in range(total_batch_num):
                    # 构建随机batch索引
                    start = idx * batch_size
                    end = start + batch_size
                    random_batch = random_index[start:end]
                    # batch 训练
                    sess.run(fetches=[train_op], feed_dict={
                        input_x: x_train[random_batch],  # 给定占位符的值
                        input_y: y_train[random_batch]  # 给定占位符的值
                    })

                loss_ = sess.run(fetches=[loss], feed_dict={
                    input_x: x_train,  # 给定占位符的值
                    input_y: y_train  # 给定占位符的值
                })
                print("第{}次训练后模型的损失函数值为:{}".format(epoch+1, loss_))

-------------------------------- 基于模型 评估tensor对象 评估模型 -----------------------------
            # 模型评估
            train_predict,acc_score_train = sess.run([y_pre,acc_score], feed_dict={input_x: x_train,input_y:y_train})
            test_predict,acc_score_test = sess.run([y_pre,acc_score], feed_dict={input_x: x_test,input_y:y_test})

            # 可视化画图
            y_train = onehot.inverse_transform(y_train)   # 将 onehot 类型的标签 转化为 0,1,2,3,4 ...
            y_test = onehot.inverse_transform(y_test)
            print("训练数据上的准确率:{}".format(acc_score_train))
            print("测试数据上的准确率:{}".format(acc_score_test))
            print("sklearn API 训练数据上的准确率:{}".format(accuracy_score(y_train, train_predict)))
            print("sklearn API 测试数据上的准确率:{}".format(accuracy_score(y_test, test_predict)))
            print("训练数据上的混淆矩阵:\n{}".format(confusion_matrix(y_train, train_predict)))
            print("测试数据上的混淆矩阵:\n{}".format(confusion_matrix(y_test, test_predict)))
---------------------------------------------------------------------------------------------
            # 模型持久化

 

 

 

你可能感兴趣的:(深度学习)