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])}")