TensorFlow-神经网络初体验

深度学习day1

最常用的框架:TensorFlow和Pytorch  caffe和caffe2次之
PyTorch和Torch更适用于学术研究;TensorFlow、caffe、caffe2更适用于工业界的生产环境部署

caffe适用于处理静态图像;Torch和PyTorch更适用于动态图像;TensorFlow两种情况下都适用

TensorFlow和caffe2可在移动端使用

TensorFlow结构
1、TF数据流图
(1)构建图阶段--描述执行操作--定义数据(张量Tensor)和操作(节点Op)
(2)执行图阶段--执行操作
2、组件
(1)图
图与TensorBord

图包含了一组由tf.operation代表的计算单元对象和tf.Tensor代表的计算单元之间流动的数据
查看默认图的方法:直接访问tf.get_default_graph、查看属性graph()
创建图new_g = tf.Graph()
with new_g.as_default():
        定义数据和操作

TensorBord可视化

(1)数据序列化:tf.summary.FileWriter(path, graph ="" )
(2)启动tensorboard --logdir=path


(2)会话
tf.session 用于完整的程序中
tf.InteractiveSession 用于交互式上下文中的TensorFlow
初始化会话对象时的参数
graph = none
target
config 此参数允许指定一个tf.ConfigProto以便控制会话的行为。如ConfigProto协议用于打印设备使用信息

a = tf.palceholder(type,shape=)
a = tf.palceholder(type,shape=)
run(fetches, feed_dict = {a: value, b:value})

(3)张量(指令名称,形状shape,数据类型type)
    张量 n维数组
    标量 一个数字 shape()
    向量 一维数组 [2,3,4]  shape(3,)
    矩阵  二维数组[[1,2],[3,4],[4,5]] shape(3,1)
    张量的阶:0:纯量 只有大小,1:向量 大小和方向,2:矩阵 数据表 3:3阶张量 数据立体,n:n阶
创建张量:固定值张量 tf.zeros(shape,dtype,name)
        tf.ones(shape,dtype,name)
         tf.random_normal(shape,mean=0.0 均值,stddev=1.0 标准差,dtype=tf.float32)   默认为正态分布
张量变换:
类型变换:tf.cast(tensor,dtype)  不换改变原始tensor  而是返回新的tensor
形状改变:  静态形状(初始创建张量时的形状)
tensor.set_shape([ ])   只有在形状没有完全固定下来的情况下才可以改变  即shape=[None,None]  打印出来显示 ? 更新时需要满足原始的维度

动态形状( )
tf.reshape(tensor, type)   不会改变原始tensor 而是返回改变形状后的tensor  需要保持前后张量元素数量不变
张量的数学运算
算术 基础函数 矩阵 reduce 序列索引操作
(4)变量 - 存储模型参数
tf.Variable(initial_value = None,trainable = True, collections = N-, name=None)

 initial_value 初始值
trainable   是否被训练
collections  默认为[GraphKeys.GLOBAL_VARIABLES],
变量要显式初始化,才能运行值
显式初始化变量
init = tf.global_variable_initializer()
在开启的会话中运行初始化 sess.run(init)
使用tf.variable_scope()修改变量的命名空间  使得结构更加清晰
with tf.variable_scope("my_scope"):
       变量1
       变量2

实现线性回归的训练
 矩阵运算 tf.matmul(x,w)
平方 tf.square()
均值tf.reduce.mean()
梯度下降优化

在步数一定的情况下,学习率越高,效果越好
在学习率一定的情况下,步数越多,效果越好

增加变量显示--tensorboard
1、创建事件文件 
file_writer = tf.summary.FileWriter("./temp/linear", graph=sess.graph)  在会话中创建
2、收集变量
    tf.summary.scalar("error", error)  # 标量
    tf.summary.histogram("weigths", weights)  # 高维度变量
    tf.summary.histogram("bias", bias)  # 高维度变量
3、合并变量
    merge = tf.summary.merge_all()
4、执行合并变量操作
    summary = sess.run(merge)
5、每次迭代,将summary写入事件文件
    file_writer.add_summary(summary, i)

模型的保存与加载
saver = tf.train.Saver(var_list = None, max_to_keep = 5)
1、实例化saver
2、保存 指定会话,路径/模型名称.ckpt
saver.save(sess, path)
3、加载
saver.restore(sess, path)

定义命令行参数
tf.app.flags.DEFINE_integer("参数名", 参数值, "参数说明")

简化参数名
FLAGS = tf.app.flags.FLAGS
调用
参数名 = FLAGS.参数名


day2
数据IO操作
queuerunner(多线程+队列)
文件读取流程
1) 构造文件名队列
file_queue = tf.train.string_input_producer(string_tensor, shuffle=true)
string_tensor:含文件名+路径的1阶张量  列表即可
num_epochs:过几遍数据,默人无限过数据
return:文件队列
2) 读取与解码
读取:tf.TextLineReader
    读取文本文件,逗号分隔值(CSV)格式,默认按行读取
    返回读取器实例
解码:tf.decode_csv(value)
读取:tf.WholeFileReader
    读取图片文件
    返回读取器实例
解码:tf.image_decode_jpeg(value)
    将jpeg编码图解码为uint8张量
    返回uint8张量,3-D形状[height, width, channels]
解码:tf.image_decode_png(value)
    将png编码图解码为uint8张量
    返回uint8张量,3-D形状[height, width, channels]
读取:tf.FixedLengthRecordReader(record_bytes(一个样本字节数))
    读取每个记录是固定数量字节的二进制文件
解码:tf.decode_raw(): 解码二进制文件
解码阶段 默认所有的内容都解码为uint8类型,如果之后需要转换为指定类型,则可使用tf.cast()
record_bytes 整型 指定每次读取(一个样本)的字节数
    返回读取器实例
tf.TFRecordReader
    读取TFRecords文件
    返回读取器实例
返回Tensor元组
key, value = 读取器.read(file_queue)
key:文件名
value:一个样本的内容
此时仅仅完成了一个样本的读取,还需开启批量读取tf.train.batch


3) 批处理队列
tf.train.batch(tensors, batch_size, num_threads = 1, capacity = 32)  tensor对象的形状要全部相同
tf.image.resize_images(tensors, newshape[ heigth, width ])
读取指定大小(个数)的张量
tensors 可以是包含张量的列表,批处理的内容放到列表中
batch_size 从队列中读取批处理大小
num_threads:进入队列的线程数
capacity:整数,队列中元素的最大数量
返回tensors

tf.train.shuffle_batch

手动开启线程
tf.train.QueueRunner
开启会话:
    tf.train.start_queue_runners(sess=None, coord=)
    收集图中所有的队列线程 默认同时启动线程
     sess:所在的会话
    coord:线程协调器
    返回所有线程
tf.train.Coordinator()
线程协调员,对线程进行管理和协调
request_stop()   请求停止
should_stop() 询问是否结束
join(threads=None, stop_grace_period_secs=120)  回收线程
返回线程协调员实例

特征抽取
文本 - 数值(二维数组shape(样本数n_samples, 特征词m_features))
字典 - 数值(二维数组shape(样本数n_samples, 特征词m_features))
图片 - 数值(三维数组shape(长度height, 宽度width, 通道数channels))


神经网络
输入层、隐藏层、输出层
损失函数、优化损失函数

   soft回归--结果映射--多分类
    logits加上softmax映射
   损失函数
    交叉熵损失

全连接
    [None, 7, 7, 64] -> [None, 7*7*64]
    [None, 7*7*64] * [7*7*64, 10] = [None, 10]

每一个原始特征看做一个维度,特征数=维度^2/2

曲线拟合,使用非线性的激活函数,常见Sigmoid(s形曲线)也叫逻辑回归,简称logsig    
感知机激活函数用的是sign函数-1 x<=0  1 x>0


隐藏层用都是用Sigmoid作激活函数,而输出层用的是Purelin。这是因为Purelin可以保持之前任意范围的数值缩放,便于和样本值作比较,而Sigmoid的数值范围只能在0~1之间。

起初输入层的数值通过网络计算分别传播到隐藏层,再以相同的方式传播到输出层,最终的输出值和样本值作比较,计算出误差,这个过程叫前向传播(Forward Propagation)。

BP算法是一种计算偏导数的有效方法,它的基本原理是:利用前向传播最后输出的结果来计算误差的偏导数,再用这个偏导数和前面的隐藏层进行加权求和,
如此一层一层的向后传下去,直到输入层(不计算输入层),最后利用每个节点求出的偏导数来更新权重。

为了便于理解,后面我一律用“残差(error term)”这个词来表示误差的偏导数。
输出层→隐藏层:残差 = -(输出值-样本值) * 激活函数的导数
隐藏层→隐藏层:残差 = (右层每个节点的残差加权求和)* 激活函数的导数

如果输出层用Purelin作激活函数,Purelin的导数是1,输出层→隐藏层:残差 = -(输出值-样本值)

如果用Sigmoid(logsig)作激活函数,那么:Sigmoid导数 = Sigmoid*(1-Sigmoid)
输出层→隐藏层:残差 = -(Sigmoid输出值-样本值) * Sigmoid*(1-Sigmoid) = -(输出值-样本值)输出值(1-输出值) 
隐藏层→隐藏层:残差 = (右层每个节点的残差加权求和)* 当前节点的Sigmoid*(1-当前节点的Sigmoid)

残差全部计算好后,就可以更新权重了:
输入层:权重增加 = 当前节点的Sigmoid * 右层对应节点的残差 * 学习率
隐藏层:权重增加 = 输入值 * 右层对应节点的残差 * 学习率
偏移值的权重增加 = 右层对应节点的残差 * 学习率

卷积神经网络
与传统多层神经网络对比
输入层
隐藏层
    卷积层
    激活层
    池化层-下采样层
    全连接层
输出层

卷积神经网络原理
    结构
    卷积层:通过在原始图像上平移来提取特征
    激活层:增加非线性分割能力
    池化层:减少学习的参数,降低网络的复杂度(最大池化和平均池化)
    全连接层
    
卷积层

1、卷积核-filter-过滤器-模型参数
卷积神经网络中每层卷积层由若干卷积单元(卷积核)组成,每个卷积单元的参数都是通过反向传播算法最佳化得到的

卷积运算的目的是特征提取,第一层卷积层可能只能提取一些低级的特征如边缘、线条和角等级层,更多层的网络能从低级特征中迭代提取更复杂的特征
    个数:
    大小:1*1 3*3 5*5
    步长
    零填充的大小: 
    
输出大小计算公式
输入体积:H1*W1*D1
四个超参数:
    Filter数量K
    Filter大小F
    步长S
    零填充大小P
输出体积大小:H2*W2*D2
H2 = (H1 - F + 2P)/S + 1
W2 = (W1 - F + 2P)/S + 1
D2 = K

卷积网络API
每个过滤器会带若干权重和1个偏置
tf.conv2d(input, fliter, strides=, padding=, name=None)
input 给定的输入张量具有[batch, heigth, width, channel] 类型为float32,64
filter 指定过滤器的权重数量,[filter_height, filter_width, in_channels, out_channels]
    weights:变量initial_value = random_normal(shape=[F, F, 3/1, K])
strides strides = [1, stride, stride, 1]
    步长1 [1, 1, 1, 1]
padding :"SAME"
    "SAME" 越过边缘取样,取样的面积和输入图像的像素宽度一致 公式:ceil(H/S) 
            H为输入的图片的高或者宽度,S为步长
            无论过滤器的大小是多少,零填充的数量由api自动计算
    "VALID" 不越过边缘取样,取样的面积小于输入人的像素宽度。不填充

激活函数

sigmod缺点 1/(1+e^-x)
    计算量大
    梯度消失
    输入值得范围[-6,6]
Relu
    计算快
    解决了梯度消失
    图像没有负的像素值 
    
激活函数api
tf.nn.relu(features)
 features 卷积后加上偏置的结果
 
池化层-  特征提取 减少参数
    tf.nn.max_pool(value, ksize=, strides=, padding=, )
    value 上一步得到的4阶张量 [batch, height, width, channels]
    channel 并不是原始图片的通道数,而是卷积层filter个数
    ksize 池化窗口大小 [1, ksize, ksize, 1]
    strides 步长大小 [1, strides, strides, 1]
    padding "SAME" "VALID" 使用的填充算法的类型 默认使用SAME

卷积向下取整 池化向上取整

全连接层 - 分类器
    [None, 7, 7, 64] -> [None, 7*7*64]
    [None, 7*7*64] * [7*7*64, 10] = [None, 10]
    y_predict = tf.matmul(pools, weights) + bias
调参 提高准确率
1)学习率
2)随机初始化的权重。偏置的值
3)选择好的优化器
4)调整网络结构
    对于深度网络使用batch normalization(提高网络泛化能力,防止过拟合)或者droupout层
网络结构和优化

常见网络模型
    GooleNet 
    ResNet
    
图像目标检测
Yolo:GoogleNet+ bounding boxes
SSD:VGG + regionproposals
Faster-RCNN:VGG,ResNet


实战:验证码图片识别
1、数据集
    图片  nzpp 一个样本对应4个目标值 -> sigmod交叉熵
    一张手写图片 一个样本对应一个目标值 -> softmax交叉熵
     
     图片中字母分配不规则 采用图片切割不具备通用性 
     NZPP - > [13,25,15,15] -> [[0,0,0...1,0,0..],[0,0...1],[0,0...1,0..0],[0,0...1,0..0]]


        1)读取图片数据
            1、构建文件名队列
            file_names = glob.glob("path")
            file_queue = tf.train.string_input_producer(file_names)
        2)读取与解码
        reader = tf.WholeFileReader()
        filename,image = reader.read(file_queue)
           解码
             decoded = tf.image.decode_jepg(image)
           更新形状,将图片形状确定下来 方便批处理
             decoded.set_shape([20, 80, 3]) 
           修改图片类型
             iamge_cast = tf.cast(decoded, tf.float32)
        3)批处理
        filename_batch, image_batch = tf.train.batch([filename, iamge_cast], batch_size=100, num_threads=1, capacity=200)
            
            
            
            
            
            

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值