tensorflow基础版

一、tensorflow框架

图
会话
张量
变量

0.tensorflow的基本结构

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'


def tensorflow_demo():
    """
    TensorFlow的基本结构
    :return:
    """
    # 原生python加法运算
    a = 2
    b = 3
    c = a + b
    print("普通加法运算的结果:\n", c)

    # TensorFlow实现加法运算
    a_t = tf.constant(2)
    b_t = tf.constant(3)
    c_t = a_t + b_t
    print("TensorFlow加法运算的结果:\n", c_t)

    # 开启会话
    with tf.Session() as sess:
        c_t_value = sess.run(c_t)
        print("c_t_value:\n", c_t_value)

1.图

tensorflow的图主要是两个部分构成:
	构建图:
		定义数据(张量Tensor)和操作(节点Op)
	执行图:
		调用各方子渊,将定义和哦啊的数据和操作运行起来,配合会话使用
	查看默认图:
			tf.get_default_graph()
			a_t.graph
	自定义图:
		 	new_g = tf.Graph()
		  	with new_g.as_default():
		   	    a_new.graph
	TensorBoard-将图写入本地生成events文件:
        tf.summary.FileWriter("./tmp/summary", graph=sess.graph)
    数据:Tensor对象
    操作:Operation对象 - Op
        1 常见OP
            操作函数        &                           操作对象
            tf.constant(Tensor对象)           输入Tensor对象 -Const-输出 Tensor对象
            tf.add(Tensor对象1, Tensor对象2)   输入Tensor对象1, Tensor对象2 - Add对象 - 输出 Tensor对象3
        2 指令名称
            一张图 - 一个命名空间
    
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
def graph_demo():
    """
    图的演示
    :return:
    """
    # TensorFlow实现加法运算
    a_t = tf.constant(2, name="a_t")
    b_t = tf.constant(3, name="a_t")
    c_t = tf.add(a_t, b_t, name="c_t")
    print("a_t:\n", a_t)
    print("b_t:\n", b_t)
    print("c_t:\n", c_t)
    # print("c_t.eval():\n", c_t.eval())

    # 查看默认图
    # 方法1:调用方法
    default_g = tf.get_default_graph()
    print("default_g:\n", default_g)

    # 方法2:查看属性
    print("a_t的图属性:\n", a_t.graph)
    print("c_t的图属性:\n", c_t.graph)


    # 自定义图
    new_g = tf.Graph()
    # 在自己的图中定义数据和操作
    with new_g.as_default():
        a_new = tf.constant(20)
        b_new = tf.constant(30)
        c_new = a_new + b_new
        print("a_new:\n", a_new)
        print("b_new:\n", b_new)
        print("c_new:\n", c_new)
        print("a_new的图属性:\n", a_new.graph)
        print("c_new的图属性:\n", c_new.graph)

    # 开启会话
    with tf.Session() as sess:
        # c_t_value = sess.run(c_t)
        # 试图运行自定义图中的数据、操作
        # c_new_value = sess.run((c_new))
        # print("c_new_value:\n", c_new_value)
        print("c_t_value:\n", c_t.eval())
        print("sess的图属性:\n", sess.graph)
        # 1)将图写入本地生成events文件
        tf.summary.FileWriter("./tmp/summary", graph=sess.graph)

    # 开启new_g的会话
    with tf.Session(graph=new_g) as new_sess:
        c_new_value = new_sess.run((c_new))
        print("c_new_value:\n", c_new_value)
        print("new_sess的图属性:\n", new_sess.graph)


    return None

2.会话

  tf.Session:用于完整的程序当中
        tf.InteractiveSession:用于交互式上下文中的TensorFlow ,例如shell
        1)会话掌握资源,用完要回收 - 上下文管理器
        2)初始化会话对象时的参数
            graph=None
            target:如果将此参数留空(默认设置),
            会话将仅使用本地计算机中的设备。
            可以指定 grpc:// 网址,以便指定 TensorFlow 服务器的地址,
            这使得会话可以访问该服务器控制的计算机上的所有设备。
            config:此参数允许您指定一个 tf.ConfigProto
            以便控制会话的行为。例如,ConfigProto协议用于打印设备使用信息
        3)run(fetches,feed_dict=None)
        3 feed操作
            a = tf.placeholder(tf.float32, shape=)
            b = tf.placeholder(tf.float32, shape=)
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
def session_demo():
    """
    会话的演示
    :return:
    """

    # TensorFlow实现加法运算
    a_t = tf.constant(2, name="a_t")
    b_t = tf.constant(3, name="a_t")
    c_t = tf.add(a_t, b_t, name="c_t")
    print("a_t:\n", a_t)
    print("b_t:\n", b_t)
    print("c_t:\n", c_t)
    # print("c_t.eval():\n", c_t.eval())

    # 定义占位符
    a_ph = tf.placeholder(tf.float32)
    b_ph = tf.placeholder(tf.float32)
    c_ph = tf.add(a_ph, b_ph)
    print("a_ph:\n", a_ph)
    print("b_ph:\n", b_ph)
    print("c_ph:\n", c_ph)

    # 查看默认图
    # 方法1:调用方法
    default_g = tf.get_default_graph()
    print("default_g:\n", default_g)

    # 方法2:查看属性
    print("a_t的图属性:\n", a_t.graph)
    print("c_t的图属性:\n", c_t.graph)

    # 开启会话
    with tf.Session(config=tf.ConfigProto(allow_soft_placement=True,
                                        log_device_placement=True)) as sess:
        # 运行placeholder
        c_ph_value = sess.run(c_ph, feed_dict={a_ph: 3.9, b_ph: 4.8})
        print("c_ph_value:\n", c_ph_value)
        # c_t_value = sess.run(c_t)
        
        # 试图运行自定义图中的数据、操作
        # c_new_value = sess.run((c_new))
        # print("c_new_value:\n", c_new_value)
        
        # 同时查看a_t, b_t, c_t
        a, b, c = sess.run([a_t, b_t, c_t])
        print("abc:\n", a, b, c)
        print("c_t_value:\n", c_t.eval())
        print("sess的图属性:\n", sess.graph)
        
        # 1)将图写入本地生成events文件
        tf.summary.FileWriter("./tmp/summary", graph=sess.graph)

    return None

3.张量

张量Tensor
    print()
    ndarray
    1.张量(Tensor)
        张量 在计算机当中如何存储?
        标量 一个数字                 0阶张量
        向量 一维数组 [2, 3, 4]       1阶张量
        矩阵 二维数组 [[2, 3, 4],     2阶张量
                    [2, 3, 4]]
        ……
        张量 n维数组                  n阶张量
        1 张量的类型
        2 张量的阶
        创建张量的时候,如果不指定类型
        默认 tf.float32
            整型 tf.int32
            浮点型 tf.float32
    2 创建张量的指令
    3 张量的变换
        ndarray属性的修改
            类型的修改
                1)ndarray.astype(type)
                tf.cast(tensor, dtype)
                    不会改变原始的tensor
                    返回新的改变类型后的tensor
                2)ndarray.tostring()
            形状的修改
                1)ndarray.reshape(shape)
                    -1 自动计算形状
                2)ndarray.resize(shape)
                静态形状 - 初始创建张量时的形状
                1)如何改变静态形状
                    什么情况下才可以改变/更新静态形状?
                        只有在形状没有完全固定下来的情况下
                    tensor.set_shape(shape)
                2)如何改变动态形状
                    tf.reshape(tensor, shape)
                    不会改变原始的tensor
                    返回新的改变形状后的tensor
                    动态创建新张量时,张量的元素个数必须匹配
    4 张量的数学运算
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
def tensor_demo():
    """
    张量的演示
    :return:
    """
    tensor1 = tf.constant(4.0)
    tensor2 = tf.constant([1, 2, 3, 4])
    linear_squares = tf.constant([[4], [9], [16], [25]], dtype=tf.int32)

    print("tensor1:\n", tensor1)
    print("tensor2:\n", tensor2)
    print("linear_squares_before:\n", linear_squares)

    # 张量类型的修改
    l_cast = tf.cast(linear_squares, dtype=tf.float32)
    print("linear_squares_after:\n", linear_squares)
    print("l_cast:\n", l_cast)

    # 更新/改变静态形状
    # 定义占位符
    # 没有完全固定下来的静态形状
    a_p = tf.placeholder(dtype=tf.float32, shape=[None, None])
    b_p = tf.placeholder(dtype=tf.float32, shape=[None, 10])
    c_p = tf.placeholder(dtype=tf.float32, shape=[3, 2])
    print("a_p:\n", a_p)
    print("b_p:\n", b_p)
    print("c_p:\n", c_p)
    
    # 更新形状未确定的部分
    # a_p.set_shape([2, 3])
    # b_p.set_shape([2, 10])
    # c_p.set_shape([2, 3])
    
    # 动态形状修改
    a_p_reshape = tf.reshape(a_p, shape=[2, 3, 1])
    print("a_p:\n", a_p)
    # print("b_p:\n", b_p)
    print("a_p_reshape:\n", a_p_reshape)
    c_p_reshape = tf.reshape(c_p, shape=[2, 3])
    print("c_p:\n", c_p)
    print("c_p_reshape:\n", c_p_reshape)

4.变量

变量OP
    TensorFlow - 变量
    存储模型参数
    1 创建变量
        变量需要显式初始化,才能运行值
    2 使用tf.variable_scope()修改变量的命名空间
        使得结构更加清晰
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
def variable_demo():
    """
    变量的演示
    :return:
    """
    # 创建变量
    with tf.variable_scope("my_scope"):
        a = tf.Variable(initial_value=50)
        b = tf.Variable(initial_value=40)
    with tf.variable_scope("your_scope"):
        c = tf.add(a, b)
    print("a:\n", a)
    print("b:\n", b)
    print("c:\n", c)

    # 初始化变量
    init = tf.global_variables_initializer()

    # 开启会话
    with tf.Session() as sess:
        # 运行初始化
        sess.run(init)
        a_value, b_value, c_value = sess.run([a, b, c])
        print("a_value:\n", a_value)
        print("b_value:\n", b_value)
        print("c_value:\n", c_value)

5.高级API(keras)

参考地址: https://tensorflow.google.cn/guide/keras?hl=zh-cn

6.案例:线性回归

 案例:实现线性回归
    1 线性回归原理复习
        1)构建模型
            y = w1x1 + w2x2 + …… + wnxn + b
        2)构造损失函数
            均方误差
        3)优化损失
            梯度下降
    2 案例:实现线性回归的训练
        准备真实数据
            100样本
            x 特征值 形状 (100, 1)
            y_true 目标值 (100, 1)
            y_true = 0.8x + 0.7
        假定x 和 y 之间的关系 满足
            y = kx + b
            k ≈ 0.8 b ≈ 0.7
            流程分析:
            (100, 1) * (1, 1) = (100, 1)
            y_predict = x * weights(1, 1) + bias(1, 1)
            1)构建模型
            y_predict = tf.matmul(x, weights) + bias
            2)构造损失函数
            error = tf.reduce_mean(tf.square(y_predict - y_true))
            3)优化损失
            optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)
            5 学习率的设置、步数的设置与梯度爆炸
    3 增加其他功能
        1 增加变量显示
            1)创建事件文件
            2)收集变量
            3)合并变量
            4)每次迭代运行一次合并变量
            5)每次迭代将summary对象写入事件文件
        2 增加命名空间
        3 模型的保存与加载
            saver = tf.train.Saver(var_list=None,max_to_keep=5)
            1)实例化Saver
            2)保存
                saver.save(sess, path)
            3)加载
                saver.restore(sess, path)
        4 命令行参数使用
            1)tf.app.flags
            tf.app.flags.DEFINE_integer("max_step", 0, "训练模型的步数")
            tf.app.flags.DEFINE_string("model_dir", " ", "模型保存的路径+模型名字")
            2)FLAGS = tf.app.flags.FLAGS
            通过FLAGS.max_step调用命令行中传过来的参数
            3、通过tf.app.run()启动main(argv)函
def linear_regression():
    """
    自实现一个线性回归
    :return:
    """
    with tf.variable_scope("prepare_data"):
        # 1)准备数据
        X = tf.random_normal(shape=[100, 1], name="feature")
        y_true = tf.matmul(X, [[0.8]]) + 0.7

    with tf.variable_scope("create_model"):
        # 2)构造模型
        # 定义模型参数 用 变量
        weights = tf.Variable(initial_value=tf.random_normal(shape=[1, 1]), name="Weights")
        bias = tf.Variable(initial_value=tf.random_normal(shape=[1, 1]), name="Bias")
        y_predict = tf.matmul(X, weights) + bias

    with tf.variable_scope("loss_function"):
        # 3)构造损失函数
        error = tf.reduce_mean(tf.square(y_predict - y_true))

    with tf.variable_scope("optimizer"):
        # 4)优化损失
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)

    # 2_收集变量
    tf.summary.scalar("error", error)
    tf.summary.histogram("weights", weights)
    tf.summary.histogram("bias", bias)

    # 3_合并变量
    merged = tf.summary.merge_all()

    # 创建Saver对象
    saver = tf.train.Saver()

    # 显式地初始化变量
    init = tf.global_variables_initializer()

    # 开启会话
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init)

        # 1_创建事件文件
        file_writer = tf.summary.FileWriter("./tmp/linear", graph=sess.graph)

        # 查看初始化模型参数之后的值
        print("训练前模型参数为:权重%f,偏置%f,损失为%f" % (weights.eval(), bias.eval(), error.eval()))

        # 开始训练
        # for i in range(100):
        #     sess.run(optimizer)
        #     print("第%d次训练后模型参数为:权重%f,偏置%f,损失为%f" % (i+1, weights.eval(), bias.eval(), error.eval()))
        #
        #     # 运行合并变量操作
        #     summary = sess.run(merged)
        #     # 将每次迭代后的变量写入事件文件
        #     file_writer.add_summary(summary, i)
        #
        #     # 保存模型
        #     if i % 10 ==0:
        #         saver.save(sess, "./tmp/model/my_linear.ckpt")
        # 加载模型
        if os.path.exists("./tmp/model/checkpoint"):
            saver.restore(sess, "./tmp/model/my_linear.ckpt")

        print("训练后模型参数为:权重%f,偏置%f,损失为%f" % (weights.eval(), bias.eval(), error.eval()))


    return None
def linear_regression():
    """
    自实现一个线性回归
    :return:
    """
    with tf.variable_scope("prepare_data"):
        # 1)准备数据
        X = tf.random_normal(shape=[100, 1], name="feature")
        y_true = tf.matmul(X, [[0.8]]) + 0.7

    with tf.variable_scope("create_model"):
        # 2)构造模型
        # 定义模型参数 用 变量
        weights = tf.Variable(initial_value=tf.random_normal(shape=[1, 1]), name="Weights")
        bias = tf.Variable(initial_value=tf.random_normal(shape=[1, 1]), name="Bias")
        y_predict = tf.matmul(X, weights) + bias

    with tf.variable_scope("loss_function"):
        # 3)构造损失函数
        error = tf.reduce_mean(tf.square(y_predict - y_true))

    with tf.variable_scope("optimizer"):
        # 4)优化损失
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)

    # 2_收集变量
    tf.summary.scalar("error", error)
    tf.summary.histogram("weights", weights)
    tf.summary.histogram("bias", bias)

    # 3_合并变量
    merged = tf.summary.merge_all()

    # 创建Saver对象
    saver = tf.train.Saver()

    # 显式地初始化变量
    init = tf.global_variables_initializer()

    # 开启会话
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init)

        # 1_创建事件文件
        file_writer = tf.summary.FileWriter("./tmp/linear", graph=sess.graph)

        # 查看初始化模型参数之后的值
        print("训练前模型参数为:权重%f,偏置%f,损失为%f" % (weights.eval(), bias.eval(), error.eval()))

        # 开始训练
        # for i in range(100):
        #     sess.run(optimizer)
        #     print("第%d次训练后模型参数为:权重%f,偏置%f,损失为%f" % (i+1, weights.eval(), bias.eval(), error.eval()))
        #
        #     # 运行合并变量操作
        #     summary = sess.run(merged)
        #     # 将每次迭代后的变量写入事件文件
        #     file_writer.add_summary(summary, i)
        #
        #     # 保存模型
        #     if i % 10 ==0:
        #         saver.save(sess, "./tmp/model/my_linear.ckpt")
        # 加载模型
        if os.path.exists("./tmp/model/checkpoint"):
            saver.restore(sess, "./tmp/model/my_linear.ckpt")

        print("训练后模型参数为:权重%f,偏置%f,损失为%f" % (weights.eval(), bias.eval(), error.eval()))


    return None

# 1)定义命令行参数
tf.app.flags.DEFINE_integer("max_step", 100, "训练模型的步数")
tf.app.flags.DEFINE_string("model_dir", "Unknown", "模型保存的路径+模型名字")

# 2)简化变量名
FLAGS = tf.app.flags.FLAGS

def command_demo():
    """
    命令行参数演示
    :return:
    """
    print("max_step:\n", FLAGS.max_step)
    print("model_dir:\n", FLAGS.model_dir)

    return None

def main(argv):
    print("code start")
    return None

7.文件I/O操作

文件读取流程
    多线程 + 队列
    3.1.1 文件读取流程
        1)构造文件名队列
            file_queue = tf.train.string_input_producer(string_tensor,shuffle=True)
        2)读取与解码
            文本:
                读取:tf.TextLineReader()
                解码:tf.decode_csv()
            图片:
                读取:tf.WholeFileReader()
                解码:
                    tf.image.decode_jpeg(contents)
                    tf.image.decode_png(contents)
            二进制:
                读取:tf.FixedLengthRecordReader(record_bytes)
                解码:tf.decode_raw()
            TFRecords
                读取:tf.TFRecordReader()
            key, value = 读取器.read(file_queue)
            key:文件名
            value:一个样本
        3)批处理队列
            tf.train.batch(tensors, batch_size, num_threads = 1, capacity = 32, name=None)
        手动开启线程
            tf.train.QueueRunner()
            开启会话:
                tf.train.start_queue_runners(sess=None, coord=None)

案例1:读取狗图片

 图片数据
    1 图像基本知识
        文本  特征词 -> 二维数组
        字典  one-hot -> 二维数组
        图片  像素值
        1 图片三要素
            黑白图、灰度图
                一个通道
                    黑[0, 255]白
            彩色图
                三个通道
                    一个像素点 三个通道值构成
                    R [0, 255]
                    G [0, 255]
                    B [0, 255]
        2 TensorFlow中表示图片
            Tensor对象
                指令名称、形状、类型
                shape = [height, width, channel]
        3 图片特征值处理
            [samples, features]
            为什么要缩放图片到统一大小?
            1)每一个样本特征数量要一样多
            2)缩小图片的大小
            tf.image.resize_images(images, size)
        4 数据格式
            存储:uint8
            训练:float32
狗图片读取
        1)构造文件名队列
            file_queue = tf.train.string_input_producer(string_tensor,shuffle=True)
        2)读取与解码
            读取:
                reader = tf.WholeFileReader()
                key, value = reader.read(file_queue)
            解码:
                image_decoded = tf.image.decode_jpeg(value)
        3)批处理队列
            image_decoded = tf.train.batch([image_decoded], 100, num_threads = 2, capacity=100)
import tensorflow as tf
import os


def read_picture():
    """
    读取狗图片案例
    :return:
    """
    # 1、构造文件名队列
    # 构造文件名列表
    filename_list = os.listdir("./dog")
    # 给文件名加上路径
    file_list = [os.path.join("./dog/", i) for i in filename_list]
    # print("file_list:\n", file_list)
    # print("filename_list:\n", filename_list)
    file_queue = tf.train.string_input_producer(file_list)

    # 2、读取与解码
    # 读取
    reader = tf.WholeFileReader()
    key, value = reader.read(file_queue)
    print("key:\n", key)
    print("value:\n", value)

    # 解码
    image_decoded = tf.image.decode_jpeg(value)
    print("image_decoded:\n", image_decoded)

    # 将图片缩放到同一个大小
    image_resized = tf.image.resize_images(image_decoded, [200, 200])
    print("image_resized_before:\n", image_resized)
    # 更新静态形状
    image_resized.set_shape([200, 200, 3])
    print("image_resized_after:\n", image_resized)


    # 3、批处理队列
    image_batch = tf.train.batch([image_resized], batch_size=100, num_threads=2, capacity=100)
    print("image_batch:\n", image_batch)

    # 开启会话
    with tf.Session() as sess:
        # 开启线程
        # 构造线程协调器
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(sess=sess, coord=coord)

        # 运行
        filename, sample, image, n_image = sess.run([key, value, image_resized, image_batch])
        print("filename:\n", filename)
        print("sample:\n", sample)
        print("image:\n", image)
        print("n_image:\n", n_image)

        coord.request_stop()
        coord.join(threads)


    return None

if __name__ == "__main__":
    # 代码1:读取狗图片案例
    read_picture()

案例2:读取二进制图片

 TFRecords
    1 什么是TFRecords文件
    2 Example结构解析
        cifar10
            特征值 - image - 3072个字节
            目标值 - label - 1个字节
        example = tf.train.Example(features=tf.train.Features(feature={
        "image":tf.train.Feature(bytes_list=tf.train. BytesList(value=[image])
        "label":tf.train.Feature(int64_list=tf.train. Int64List(value=[label]))
        }))
        example.SerializeToString()
    3 案例:CIFAR10数据存入TFRecords文件
        流程分析
    4 读取TFRecords文件API
        1)构造文件名队列
        2)读取和解码
            读取
            解析example
            feature = tf.parse_single_example(value, features={
            "image":tf.FixedLenFeature([], tf.string),
            "label":tf.FixedLenFeature([], tf.int64)
            })
            image = feature["image"]
            label = feature["label"]
            解码
            tf.decode_raw()
import tensorflow as tf
import os


def read_picture():
    """
    读取狗图片案例
    :return:
    """
    # 1、构造文件名队列
    # 构造文件名列表
    filename_list = os.listdir("./dog")
    # 给文件名加上路径
    file_list = [os.path.join("./dog/", i) for i in filename_list]
    # print("file_list:\n", file_list)
    # print("filename_list:\n", filename_list)
    file_queue = tf.train.string_input_producer(file_list)

    # 2、读取与解码
    # 读取
    reader = tf.WholeFileReader()
    key, value = reader.read(file_queue)
    print("key:\n", key)
    print("value:\n", value)

    # 解码
    image_decoded = tf.image.decode_jpeg(value)
    print("image_decoded:\n", image_decoded)

    # 将图片缩放到同一个大小
    image_resized = tf.image.resize_images(image_decoded, [200, 200])
    print("image_resized_before:\n", image_resized)
    # 更新静态形状
    image_resized.set_shape([200, 200, 3])
    print("image_resized_after:\n", image_resized)


    # 3、批处理队列
    image_batch = tf.train.batch([image_resized], batch_size=100, num_threads=2, capacity=100)
    print("image_batch:\n", image_batch)

    # 开启会话
    with tf.Session() as sess:
        # 开启线程
        # 构造线程协调器
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(sess=sess, coord=coord)

        # 运行
        filename, sample, image, n_image = sess.run([key, value, image_resized, image_batch])
        print("filename:\n", filename)
        print("sample:\n", sample)
        print("image:\n", image)
        print("n_image:\n", n_image)

        coord.request_stop()
        coord.join(threads)


    return None

if __name__ == "__main__":
    # 代码1:读取狗图片案例
    read_picture()

案例3:全连接对手写数字进行识别

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data


def full_connection():
    """
    用全连接对手写数字进行识别
    :return:
    """
    # 1)准备数据
    mnist = input_data.read_data_sets("./mnist_data", one_hot=True)
    # 用占位符定义真实数据
    X = tf.placeholder(dtype=tf.float32, shape=[None, 784])
    y_true = tf.placeholder(dtype=tf.float32, shape=[None, 10])

    # 2)构造模型 - 全连接
    # [None, 784] * W[784, 10] + Bias = [None, 10]
    weights = tf.Variable(initial_value=tf.random_normal(shape=[784, 10], stddev=0.01))
    bias = tf.Variable(initial_value=tf.random_normal(shape=[10], stddev=0.1))
    y_predict = tf.matmul(X, weights) + bias

    # 3)构造损失函数
    loss_list = tf.nn.softmax_cross_entropy_with_logits(logits=y_predict, labels=y_true)
    loss = tf.reduce_mean(loss_list)

    # 4)优化损失
    # optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(loss)
    optimizer = tf.train.AdamOptimizer(learning_rate=0.01).minimize(loss)

    # 5)增加准确率计算
    bool_list = tf.equal(tf.argmax(y_true, axis=1), tf.argmax(y_predict, axis=1))
    accuracy = tf.reduce_mean(tf.cast(bool_list, tf.float32))

    # 初始化变量
    init = tf.global_variables_initializer()

    # 开启会话
    with tf.Session() as sess:

        # 初始化变量
        sess.run(init)

        # 开始训练
        for i in range(5000):
            # 获取真实值
            image, label = mnist.train.next_batch(500)

            _, loss_value, accuracy_value = sess.run([optimizer, loss, accuracy], feed_dict={X: image, y_true: label})

            print("第%d次的损失为%f,准确率为%f" % (i+1, loss_value, accuracy_value))


    return None

if __name__ == "__main__":
    full_connection()

二、神经网络

   神经网络
        输入层
            特征值和权重 线性加权
            y = w1x1 + w2x2 + …… + wnxn + b
            细胞核-激活函数
                sigmoid
                sign
        隐藏层
        输出层
    单个神经元 - 感知机
    感知机(PLA: Perceptron Learning Algorithm))
        x1, x2
        w1x1 + w2x2 + b = 常数
        w2x2 = -w1x1 - b + 常数
        x2 = kx1 + b
        x2 = kx1 + b
        x1 x2
        与问题
        0   0 0
        0   1 0
        1   0 0
        1   1 1
        异或问题
        0   0 0
        0   1 1
        1   0 1
        1   1 0
        单个神经元不能解决一些复杂问题
        1)多层神经元
        2)增加激活函数

案例:全连接对手写数字进行识别

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data


def full_connection():
    """
    用全连接对手写数字进行识别
    :return:
    """
    # 1)准备数据
    mnist = input_data.read_data_sets("./mnist_data", one_hot=True)
    # 用占位符定义真实数据
    X = tf.placeholder(dtype=tf.float32, shape=[None, 784])
    y_true = tf.placeholder(dtype=tf.float32, shape=[None, 10])

    # 2)构造模型 - 全连接
    # [None, 784] * W[784, 10] + Bias = [None, 10]
    weights = tf.Variable(initial_value=tf.random_normal(shape=[784, 10], stddev=0.01))
    bias = tf.Variable(initial_value=tf.random_normal(shape=[10], stddev=0.1))
    y_predict = tf.matmul(X, weights) + bias

    # 3)构造损失函数
    loss_list = tf.nn.softmax_cross_entropy_with_logits(logits=y_predict, labels=y_true)
    loss = tf.reduce_mean(loss_list)

    # 4)优化损失
    # optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(loss)
    optimizer = tf.train.AdamOptimizer(learning_rate=0.01).minimize(loss)

    # 5)增加准确率计算
    bool_list = tf.equal(tf.argmax(y_true, axis=1), tf.argmax(y_predict, axis=1))
    accuracy = tf.reduce_mean(tf.cast(bool_list, tf.float32))

    # 初始化变量
    init = tf.global_variables_initializer()

    # 开启会话
    with tf.Session() as sess:

        # 初始化变量
        sess.run(init)

        # 开始训练
        for i in range(5000):
            # 获取真实值
            image, label = mnist.train.next_batch(500)

            _, loss_value, accuracy_value = sess.run([optimizer, loss, accuracy], feed_dict={X: image, y_true: label})

            print("第%d次的损失为%f,准确率为%f" % (i+1, loss_value, accuracy_value))


    return None

if __name__ == "__main__":
    full_connection()

案例:读取文件

import pandas as pd
name = ["file_num", "chars"]

data = pd.read_csv("./GenPics/labels.csv", names=name, index_col="file_num")
labels = []
for label in data["chars"]:
    
    tmp = []
    
    for letter in label:
        
        tmp.append(ord(letter) - ord("A"))
        
    labels.append(tmp)
data["labels"] = labels    

案例:mnist手写数字数据在运行时候实时提供给给占位符

import tensorflow as tf
import os
from tensorflow.examples.tutorials.mnist import input_data
from tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3_base


# 1、利用数据,在训练的时候实时提供数据
# mnist手写数字数据在运行时候实时提供给给占位符

tf.app.flags.DEFINE_integer("is_train", 1, "指定是否是训练模型,还是拿数据去预测")
FLAGS = tf.app.flags.FLAGS


def create_weights(shape):
    return tf.Variable(initial_value=tf.random_normal(shape=shape, stddev=0.01))


def create_model(x):
    """
    构建卷积神经网络
    :param x:
    :return:
    """
    # 1)第一个卷积大层
    with tf.variable_scope("conv1"):

        # 卷积层
        # 将x[None, 784]形状进行修改
        input_x = tf.reshape(x, shape=[-1, 28, 28, 1])
        # 定义filter和偏置
        conv1_weights = create_weights(shape=[5, 5, 1, 32])
        conv1_bias = create_weights(shape=[32])
        conv1_x = tf.nn.conv2d(input=input_x, filter=conv1_weights, strides=[1, 1, 1, 1], padding="SAME") + conv1_bias

        # 激活层
        relu1_x = tf.nn.relu(conv1_x)

        # 池化层
        pool1_x = tf.nn.max_pool(value=relu1_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 2)第二个卷积大层
    with tf.variable_scope("conv2"):

        # 卷积层
        # 定义filter和偏置
        conv2_weights = create_weights(shape=[5, 5, 32, 64])
        conv2_bias = create_weights(shape=[64])
        conv2_x = tf.nn.conv2d(input=pool1_x, filter=conv2_weights, strides=[1, 1, 1, 1], padding="SAME") + conv2_bias

        # 激活层
        relu2_x = tf.nn.relu(conv2_x)

        # 池化层
        pool2_x = tf.nn.max_pool(value=relu2_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 3)全连接层
    with tf.variable_scope("full_connection"):
        # [None, 7, 7, 64]->[None, 7 * 7 * 64]
        # [None, 7 * 7 * 64] * [7 * 7 * 64, 10] = [None, 10]
        x_fc = tf.reshape(pool2_x, shape=[-1, 7 * 7 * 64])
        weights_fc = create_weights(shape=[7 * 7 * 64, 10])
        bias_fc = create_weights(shape=[10])
        y_predict = tf.matmul(x_fc, weights_fc) + bias_fc

    return y_predict


def full_connected_mnist():
    """
    单层全连接神经网络识别手写数字图片
    特征值:[None, 784]
    目标值:one_hot编码 [None, 10]
    :return:
    """
    mnist = input_data.read_data_sets("./mnist_data/", one_hot=True)
    # 1、准备数据
    # x [None, 784] y_true [None. 10]
    with tf.variable_scope("mnist_data"):
        x = tf.placeholder(tf.float32, [None, 784])
        y_true = tf.placeholder(tf.int32, [None, 10])

    y_predict = create_model(x)

    # 3、softmax回归以及交叉熵损失计算
    with tf.variable_scope("softmax_crossentropy"):
        # labels:真实值 [None, 10]  one_hot
        # logits:全脸层的输出[None,10]
        # 返回每个样本的损失组成的列表
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict))

    # 4、梯度下降损失优化
    with tf.variable_scope("optimizer"):
        # 学习率
        train_op = tf.train.AdamOptimizer(0.001).minimize(loss)

    # 5、得出每次训练的准确率(通过真实值和预测值进行位置比较,每个样本都比较)
    with tf.variable_scope("accuracy"):
        equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1))
        accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

    # (2)收集要显示的变量
    # 先收集损失和准确率
    tf.summary.scalar("losses", loss)
    tf.summary.scalar("acc", accuracy)

    # 初始化变量op
    init_op = tf.global_variables_initializer()

    # (3)合并所有变量op
    merged = tf.summary.merge_all()

    # 创建模型保存和加载
    saver = tf.train.Saver()

    # 开启会话去训练
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)

        # (1)创建一个events文件实例
        file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph)

        # 加载模型
        # if os.path.exists("./tmp/modelckpt/checkpoint"):
        #     saver.restore(sess, "./tmp/modelckpt/fc_nn_model")

        if FLAGS.is_train == 1:
            # 循环步数去训练
            for i in range(3000):
                # 获取数据,实时提供
                # 每步提供50个样本训练
                mnist_x, mnist_y = mnist.train.next_batch(50)
                # 运行训练op
                sess.run(train_op, feed_dict={x: mnist_x, y_true: mnist_y})
                print("训练第%d步的准确率为:%f, 损失为:%f " % (i+1,
                                     sess.run(accuracy, feed_dict={x: mnist_x, y_true: mnist_y}),
                                     sess.run(loss, feed_dict={x: mnist_x, y_true: mnist_y})
                                     )
                  )

                # 运行合变量op,写入事件文件当中
                summary = sess.run(merged, feed_dict={x: mnist_x, y_true: mnist_y})
                file_writer.add_summary(summary, i)
                # if i % 100 == 0:
                #     saver.save(sess, "./tmp/modelckpt/fc_nn_model")

        else:
            # 如果不是训练,我们就去进行预测测试集数据
            for i in range(100):
                # 每次拿一个样本预测
                mnist_x, mnist_y = mnist.test.next_batch(1)
                print("第%d个样本的真实值为:%d, 模型预测结果为:%d" % (
                                                      i+1,
                                                      tf.argmax(sess.run(y_true, feed_dict={x: mnist_x, y_true: mnist_y}), 1).eval(),
                                                      tf.argmax(sess.run(y_predict, feed_dict={x: mnist_x, y_true: mnist_y}), 1).eval()
                                                      )
                                                      )

    return None


if __name__ == "__main__":
    full_connected_mnist()

案例:验证码图片识别

import tensorflow as tf
import glob
import pandas as pd
import numpy as np


# 1)读取图片数据filename -> 标签值
def read_picture():
    """
    读取验证码图片
    :return:
    """
    # 1、构造文件名队列
    file_list = glob.glob("./GenPics/*.jpg")
    # print("file_list:\n", file_list)
    file_queue = tf.train.string_input_producer(file_list)

    # 2、读取与解码
    # 读取
    reader = tf.WholeFileReader()
    filename, image = reader.read(file_queue)

    # 解码
    image_decode = tf.image.decode_jpeg(image)

    # 更新图片形状
    image_decode.set_shape([20, 80, 3])
    # print("image_decode:\n", image_decode)
    # 修改图片类型
    image_cast = tf.cast(image_decode, tf.float32)

    # 3、构造批处理队列
    filename_batch, image_batch = tf.train.batch([filename, image_cast], batch_size=100, num_threads=2, capacity=100)

    return filename_batch, image_batch

# 2)解析csv文件,将标签值NZPP->[13, 25, 15, 15]
def parse_csv():

    # 解析CSV文件, 建立文件名和标签值对应表格

    csv_data = pd.read_csv("./GenPics/labels.csv", names=["file_num", "chars"], index_col="file_num")

    labels = []
    for label in csv_data["chars"]:
        tmp = []
        for letter in label:
            tmp.append(ord(letter) - ord("A"))
        labels.append(tmp)

    csv_data["labels"] = labels


    return csv_data


# 3)将filename和标签值联系起来
def filename2label(filenames, csv_data):
    """
    将filename和标签值联系起来
    :param filenames:
    :param csv_data:
    :return:
    """
    labels = []

    # 将b'文件名中的数字提取出来并索引相应的标签值

    for filename in filenames:
        digit_str = "".join(list(filter(str.isdigit, str(filename))))
        label = csv_data.loc[int(digit_str), "labels"]
        labels.append(label)

    # print("labels:\n", labels)

    return np.array(labels)


# 4)构建卷积神经网络->y_predict
def create_weights(shape):
    return tf.Variable(initial_value=tf.random_normal(shape=shape, stddev=0.01))


def create_model(x):
    """
    构建卷积神经网络
    :param x:[None, 20, 80, 3]
    :return:
    """
    # 1)第一个卷积大层
    with tf.variable_scope("conv1"):

        # 卷积层
        # 定义filter和偏置
        conv1_weights = create_weights(shape=[5, 5, 3, 32])
        conv1_bias = create_weights(shape=[32])
        conv1_x = tf.nn.conv2d(input=x, filter=conv1_weights, strides=[1, 1, 1, 1], padding="SAME") + conv1_bias

        # 激活层
        relu1_x = tf.nn.relu(conv1_x)

        # 池化层
        pool1_x = tf.nn.max_pool(value=relu1_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 2)第二个卷积大层
    with tf.variable_scope("conv2"):
        # [None, 20, 80, 3] --> [None, 10, 40, 32]
        # 卷积层
        # 定义filter和偏置
        conv2_weights = create_weights(shape=[5, 5, 32, 64])
        conv2_bias = create_weights(shape=[64])
        conv2_x = tf.nn.conv2d(input=pool1_x, filter=conv2_weights, strides=[1, 1, 1, 1], padding="SAME") + conv2_bias

        # 激活层
        relu2_x = tf.nn.relu(conv2_x)

        # 池化层
        pool2_x = tf.nn.max_pool(value=relu2_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")

    # 3)全连接层
    with tf.variable_scope("full_connection"):
        # [None, 10, 40, 32] -> [None, 5, 20, 64]
        # [None, 5, 20, 64] -> [None, 5 * 20 * 64]
        # [None, 5 * 20 * 64] * [5 * 20 * 64, 4 * 26] = [None, 4 * 26]
        x_fc = tf.reshape(pool2_x, shape=[-1, 5 * 20 * 64])
        weights_fc = create_weights(shape=[5 * 20 * 64, 4 * 26])
        bias_fc = create_weights(shape=[104])
        y_predict = tf.matmul(x_fc, weights_fc) + bias_fc

    return y_predict

# 5)构造损失函数
# 6)优化损失
# 7)计算准确率
# 8)开启会话、开启线程

if __name__ == "__main__":
    filename, image = read_picture()
    csv_data = parse_csv()

    # 1、准备数据
    x = tf.placeholder(tf.float32, shape=[None, 20, 80, 3])
    y_true = tf.placeholder(tf.float32, shape=[None, 4*26])

    # 2、构建模型
    y_predict = create_model(x)

    # 3、构造损失函数
    loss_list = tf.nn.sigmoid_cross_entropy_with_logits(labels=y_true, logits=y_predict)
    loss = tf.reduce_mean(loss_list)

    # 4、优化损失
    optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)

    # 5、计算准确率
    equal_list = tf.reduce_all(
    tf.equal(tf.argmax(tf.reshape(y_predict, shape=[-1, 4, 26]), axis=2),
             tf.argmax(tf.reshape(y_true, shape=[-1, 4, 26]), axis=2)), axis=1)
    accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

    # 初始化变量
    init = tf.global_variables_initializer()


    # 开启会话
    with tf.Session() as sess:

        # 初始化变量
        sess.run(init)

        # 开启线程
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(sess=sess, coord=coord)

        for i in range(1000):
            filename_value, image_value = sess.run([filename, image])
            # print("filename_value:\n", filename_value)
            # print("image_value:\n", image_value)

            labels = filename2label(filename_value, csv_data)
            # 将标签值转换成one-hot
            labels_value = tf.reshape(tf.one_hot(labels, depth=26), [-1, 4*26]).eval()

            _, error, accuracy_value = sess.run([optimizer, loss, accuracy], feed_dict={x: image_value, y_true: labels_value})

            print("第%d次训练后损失为%f,准确率为%f" % (i+1, error, accuracy_value))

        # 回收线程
        coord.request_stop()
        coord.join(threads)

案例:使用keras分类

import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

# 生成模拟数据集
# 假设我们有两个类别的数据,每个类别有50个样本
# 类别0的数据特征围绕点(2, 2)
# 类别1的数据特征围绕点(6, 6)
np.random.seed(0)  # 确保每次运行生成的数据都是一样的
num_samples_per_class = 50

# 生成类别0的数据
class_0_points = np.random.multivariate_normal(mean=[2, 2], cov=[[1, 0.5], [0.5, 1]], size=num_samples_per_class)
class_0_labels = np.zeros(shape=num_samples_per_class)

# 生成类别1的数据
class_1_points = np.random.multivariate_normal(mean=[6, 6], cov=[[1, 0.5], [0.5, 1]], size=num_samples_per_class)
class_1_labels = np.ones(shape=num_samples_per_class)

# 合并数据
points = np.vstack([class_0_points, class_1_points])
labels = np.hstack([class_0_labels, class_1_labels])

# 打乱数据
indices = np.arange(points.shape[0])
np.random.shuffle(indices)
points = points[indices]
labels = labels[indices]

# 定义模型
model = keras.Sequential([
    layers.Dense(units=5, activation='relu', input_shape=(2,)),
    layers.Dense(units=1, activation='sigmoid')
])

# 编译模型
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# 训练模型
model.fit(points, labels, epochs=50, batch_size=10)

# 评估模型
loss, accuracy = model.evaluate(points, labels)
print(f"模型评估结果 - 损失: {loss}, 准确率: {accuracy}")

# 使用模型进行预测
predictions = model.predict(points)
predictions = (predictions > 0.5)  # 将预测结果转换为0或1

# 打印前几个预测结果和真实标签
print("预测结果和真实标签:")
for i in range(10):
    print(f"预测: {int(predictions[i])}, 真实标签: {int(labels[i])}")

posted @ 2024-07-27 15:01  派森的猫  阅读(11)  评论(0编辑  收藏  举报