TensorFlow 2019

numpy  pandas  sklearn

算法

神经网络的Math

动手实现网络结构

应用

TensorFlow框架

图像案例

Machine Learning VS Deep Learning

1 特征提取方面 自动

2 数量集  量大/参数大

* 机器学习 : 朴素贝叶斯  决策树

  深度学习 : 统称神经网络

3 应用

图识别/自然语言处理/语言识别

4 架构

Caffe TensorFlow Pytorch(Facebook)

架构/框架对比        

TensorFlow 2019_第1张图片

Followers

TensorFlow:

语言多 : C++封装  Python封装 可Go/Swift

分布式训练 : GPU TPU(Google)

TensorBoard可视化 : Web

跨平台应用 : HTTP的TF服务 / TF Lite / tf .js

2  Tensorflow架构(一)

加法

a_t = tf.constant(10)

b_t = tf.constant(20)

c_t = tf.add(a_t ,b_t)

减法

* print 不支持,需要开启会话

with tf.session() as sess :

sum_t = sess.run(c_t)

print(“sum:/t”, sum_t)

3 Tensorflow架构(二)

Tensorflow  : 构架图阶段 , 执行图阶段

图 : 指令之间依赖关系

会话 : 本地/远程多设备

张量 : tensor                节点(operate) : 图的操作

数据流图:

**

 2 图和TensorBroad

图包含tf.Operation计算单元   tf.Tensor 数据流动

#获取默认图片

g = tf.get_default_graph()

print(g)

print(a.graph)

print(b.graph)

#会话默认图

print(sess.graph)

通过tf.Graph()创建图

new_g = tf.graph()

with new_g.as_default() :

new_a = tf.constant(30)

new_b = tf.constant(40)

new_c = tf.add(new_a ,new_b)

*很少,但是可以一个程序多个图(Model)

TensorBroad

图略

1 数据序列化 - events文件

tf.summary.FileWriter(./temp/tests , graph = sess.graph)

events.out.tfevents.{timestamp}{hostname}

2 启动 TensorBroad

 tensorboard --logdir = “./temp/tests”

代码

graph = sess.graph

OP

TensorFlow 2019_第2张图片

神经网络组件

softmax sigmod relu convolution max_pool

存储 恢复

 save restore

队列及同步运算

Enqueue Dequeue MutexAcquire MutexRelease

*打印类型

Tensor(“Const_1:0” , shape=() ,dtype =float32)

Tensor(“Add:0” , shape=() ,dtype =float32)

2.3 会话

tf.session()

tf.InteractiveSession()  : 交互上下文,用于shell

初始化

__int__(target=”” , graph = None ,config = None)

#通用开启

with tf.session() as sess :

...

return None

target         网址,训练器

config        控制会话

# 代码

tf.session(config = tf.ConfigProtol , allow_soft_placement = True , log_device_placement = True)

会话运行

 run(fetches , feed_dict = None , option = None , run_metadata = None)

*定义占位符(不知何值)

a = tf.placeholder(tf.float32)

b = tf.placeholder(tf.float32)

sum_ab = tf.add(a ,b)

sess.run(sum_ab ,feed_dict = {a:30 ,b:40})

会话在Shell中  InteractiveSession :

$ iPython

tf.InteractiveSession() 交互式

a.eval()  #在shell中直接run

张量Tensor

type shape(几阶)

类型图

TensorFlow 2019_第3张图片

TensorFlow 2019_第4张图片

创建张量指令

tf.zeros()

tf.one()

tf.contant()

TensorFlow 2019_第5张图片

random_n = tf.random_normal( [3,4] ,mean = 0.0 , stddev = 1.0)

平均值 标准差 (正态分布)

张量的转换

类型转换

tf.string_to_number()

tf.cast()

TensorFlow 2019_第6张图片

 形状改变

cast_one = tf.cast(one , tf.int32)

动态/静态

动态:

tf.reshape

元素数匹配即可

静态:

tf.set_shape

2D -> 2D

1D -> 1D

*形状可选/定义

a_p = tf.placeholder(dtype = tf.float32 , shape = [None ,None])

//联想四元数,角动量(slam)

变量OP

variable 可存磁盘 (权重、偏置)

tf.variable()

init = tf.global_variable_inltialier()

sess.run(init)

6 线性回归案例

y = wx + b    Wi

案例 y = 0.8x + 0.7

运算

矩阵运算        tf.matmul(x ,w)

平方                tf.square(error)

均值                tf.redoce_mean(error)

梯度下降优化

tf.train.GradientDescentOptimizer(learning_rate)

梯度下降优化

learning_rate 学习率,一般为0~1之间的较小值

method :

minimize(loss)

return : 梯度下降op

#特征值x,目标值y_true

X = tf.random_normal(shape=(100,1) ,mean=2 ,stddev=2)

y_true = tf.matmul(X ,[[0.8]]) + 0.7

#建立线性模型

weights = tf.Variable(initial_value = tf.rnadom_normal(shape=(1,1)))

bias = tf.Variable(initial_value=tf.random_normal(shape=(1,1)))

#确认损失函数(预测值与真实值之间的误差) - 均方差

error = tf.reduce_mean(tf.squera(y_predict - y_true))

#梯度下降优化损失 : 需要学习率(超参数)

#W2 = W1 - 学习率*方向

#b2 = b1 - 学习率*方向

optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.01).minimize(error)

#初始化变量

init = tf.global_variables_initializer()

with tf.Session() as sess :

sess.run(init)

print(“随机初始化权重%f,偏置为%f” % (weights.eval() , bias.eval()))

#训练

for i in range(100):

sess.run(optimizer)

print(“第%d步的误差为%f ,权重为%f ,偏置为%f” % (i ,error.eval() ,weights.eval()))

return None

/

def linearregression() :

#1准备数据集

#x [100 ,1] 0.8 + 0.7 = [100,1]

X = tf.random_normal([100,1] ,mean=0.0 ,stddev=1.0)

#0.8是个二维

y_true = tf.matmul(X ,[[0.8]] ) +[[0.7]]

#2建立线性回归模型

#W  [1,1] , b 1

weights = tf.Variable(inital_value = = tf.random_normal( [1,1] ) )  //w初始化

bias = tf.Variable(inital_value = = tf.random_normal( [1,1] ) )  //b必须使用变量OP被训练

y_predict = tf.matmul(X ,weights) + bias

#3确立损失函数,均方误差((y-y_predict)^2) / m

loss = tf.reduce_mean(tf.square(y_predict - y_true))

#4梯度下降优化:需要学习率(超参数)

optimizer = tf.train.GradientDescentOptimzer(learning_rate = 0.01).minimize(loss)

init_op = tf.gobal_variables_initalizer()

with tf.Session() as sess:

sess.run(init_op)

print(sess.run(optimizer))  // (1)优化不明显

for i in range(100):

print(sess.run(optimizer))  //(2)优化步长,梯度下降

print(“loss:” ,sess.run(loss))

print(“loss:” ,sess.run(“loss: weight: bias:” % [loss ,weigth ,bias] ))

return None

if __name__ == ‘__main__’ :

linearregression()

TensorFlow 2019_第7张图片

变量Variable设置trainable观察

属性 trainable

指定参数被训练

*迁移学习,部分参数(权重、偏置)不被训练

TensorBoard

添加命名空间

// Session命名空间

with tf.variable_scope(“original_data”) :

with tf.variable_scope(“linear_model”) :

//

Variable ( ,name = “rognal_date_since”)

Variable ( ,name = “w”)

// 添加本地文件

file_writer = tf.summary.FileWritter(“./temp/summary” ,)

$ tensorboard --logdir = “./temp/summary”

添加变量

零维度  tf.summary.scalar(“error” ,error)

高维度  tf.summary.histogram(“bias” ,bias)  weight

merge = tf.summary.merge_all()

for i in range(100) : //训练100此,每次损失值都要记录

summary = sess.run(merge)

file_writer = tf.summary(summary ,i)

模型的保存与加载(简单方式)

tf.train.Saver(var_list = None ,max_to_keep = 5)  //每隔5次

* 保存原则 : 什么值重要? 权重、偏置。

saver.save(sess ,”/tmp/ckpt/test/myregression.ckpt”)

saver.restore(sess ,”/tmp/ckpt/test/myregression.ckpt”)

ckpt格式 检查点文件格式

*eval()函数

1 字符串string转化成有效表达式

2 定义图、计算图时,类似run

3 有输出的Operation

命令行参数的使用

tf.app.flag 有个FLAG标志,它在程序中使用。

tf.app.flags.DEFINE_interger(“max_step” ,10 ,“训练步长”)

FLAG = tf.app.flags

for i in range(FLAG.max_step) :

print(“train loss:%f ,weight:%f ,bias:%f”% (loss.eval() ,weight.eval()  ,bias.eval()))

逻辑回归复习(神经网络基础)

Logistic回归

主要的二分分类的算法。

Sigmoid函数

TensorFlow 2019_第8张图片

TensorFlow 2019_第9张图片

逻辑回归 sigmoid     线性回归 均方误差

概率小于1,log是负值 : -log(P)  -log(0.4)

代价函数Cost Function : 所有损失值的平均

导数向量化编程介绍

TensorFlow 2019_第10张图片

梯度gradient

参数 w b 的更新

α是学习速率,即每次更新的w的步伐长度

导数

J雅可比公式 b b - a c < 0

逻辑回归训练实现前向和后向

向量化编程 : m个样本,每个样本都可以处理梯度

TensorFlow 2019_第11张图片

向量化 : 提高计算速度,比如Numpy

improt numpy as np

import time

a = np.random.rand(100000)

np常用:

np.ones   np.zeros 全1 全0 矩阵

np.exp  指数运算

np.log 对数计算

np.abs  绝对值计算

实现逻辑回归 - 案例

1 使用数据:制作二分类数据集

from sklearn.datasets import load_iris ,make_classification

from sklearn.model_selection import train_test_split

import numpy as np

X,Y = make_classification(n_samples = 500 ,n_features = 5 , n_classes = 2)

x_train ,x_test ,y_train ,y_test = train_test_split(X ,Y ,test_size=0.3)

2 步骤设计

def basic_sigmoid(x) :

s = 1 / (1 + np.exp(-x))

return s

def propagate(w ,b ,X ,Y):  //前向传播

m = X.shape[1]  //维数

A = basic_sigmoid(np.dot(w.T ,X) + b)

#计算损失

cost = -1 / m * np.sum(Y * np.log(A) + (1 - Y) * np.log(1 - A))  // sigmoid函数的导数公式

dz = A - Y

dw = 1 / m * np.dot(X ,dz.T)

db = 1 / m * np.sum(dz)

cost = np.squeeze(cost)

grad = {“dw”:dw ,””db”:db}

return grads ,cost

def optimize(w ,b ,X ,Y  ,num_iterations ,learning_rate):

costs = []

for i in range(num_iterations) :

# 梯度更新计算函数

grads ,cost = propagate(w ,b ,X ,Y)

#取出两个部分参数的梯度

dw = grads[‘dw’]

db = grads[‘db’]

#按照梯度下降公式去计算

w = w - learning_rate *dw

b = b - learning_rate * db

if i % 100 == 0 :

costs.append(cost)

if i % 100 = 0

print(“损失结果 %i : %f”% (i ,cost))

print(b)

params = {“w”:w ,”b”:b}

grads = {“dw”:dw ,”db”:db}

return params ,grads ,costs

def predict(w ,b ,X):

m = X.shape[1]

y_prediction = np.zeros( (1,m) )

w = w.reshape(X.shape[0] ,1)

#计算结果

A = basic_sigmoid(np.dot(w.T ,X) + b)

for i in range(A.shape[1]) :

if A[0 ,i] <=0.5 :

y_prediction[0 ,i] = 0

else :

y_prediction[0 ,i] = 1

return y_prediction

def model(x_train ,x_test ,y_train ,y_test ,num_iterations = 2000 ,learning_rate=0.0001)

x_train = x_train.reshape(-1 ,x_train.shape[0])

x_test = x_test.reshape(-1 ,x_test.shape[0])

y_train = y_train.reshape(-1 ,y_train.shape[0])

y_test= y_test.reshape(-1 ,y_test.shape[0])

print(x_train.shape)

print(x_test.shape)

print(y_train.shape)

print(y_test.shape)

#初始化参数

w , b = initialize_with_zeros(x_train.shape[0])

#梯度下降

#params:更新后的网络参数

#grads:最后一次梯度

#costs:每次更新损失列表

optimize(w ,b ,x_train ,y_train ,num_iterations ,learning_rate)

return None

神经网络与tf.keras

图片:宽 高 通道

如果一个像素点,有RGB三个颜色来描述它,就是三通道。

Keras开源的Python的神经网络库。

*减少认知困难,提供一系列API

*因为Keras和底层深度学习语言(特别是Tensorflow)集成一起

*Keras被学界和工业界广泛使用

*GPU相关的训练

tf.Keras的API

applications module : Keras应用程序具有预训练权重的固定架构

callbacks module : 回调,再模型训练期间在某些点调用的实用程序

datasets module : 数据集

initializers module : 序列化/反序列化

layers module : API

losses module : 内置损失功能

metrics module : 内置模标

models module : 代码克隆、线程模型 API

optimizers module : 内置优化器

preprocessing module :  数据预处理工具(图片预处理)

regularizers module : 内置正则化器

utils module : 实用程序

图片预处理

tensorflow.python.keras.preprocessing.image

预下载图片读取库

pip install Pillow

image = load_image(path = “”,target_size)

imageArr = image_to_array(image)

print(imageArr.shape)

NHWC 和 NCHW

通道数在前面,通道数在后面

NHWC [batch ,height ,width ,channels]

NCHW [batch ,channels ,height ,width]

Tensorflow 默认[height ,width ,channel]

RGB的格式

TensorFlow 2019_第12张图片

tf.transpose( depth_major ,[1 ,2 ,0]).eval()  //横竖转换

*转换维度

tf.reshape( [1,2,3,4,5,6,7,8,9,10,11,12] ,[3 , 2 ,2]).eval() //成功

tf.reshape( [1,2,3,4,5,6,7,8,9,10,11,12] ,[2 ,2 3]).eval() //失败

reshape()不能对一维中按照RGB做channel_last变换,只能做channel_first变换。

NHWC和NCHW变换

1 首先reshape()

2 transpose(),维度位置变换

tf.keras数据集

CIFAR小图片分类数据集

50000张32x32的小图片

10000张32x32的测试图片

from keras.datasets import cifar100

(x_train ,y_train) ,(x_test ,y_test) = cifar100.load_data()

时装分类Minist数据集

(x_train ,y_train) ,(x_test ,y_test) = keras.datasets.fashion_mnist.load_data()

图像神经网络

神经网络Neural Network NN :

输入层 隐藏层 输出层

*没有隐藏层,直接链接的层数,叫做全连接层。

感知机 Perceptorn Learning Algorithm  PLA

具有链接的权重和偏置 W b

TensorFlow 2019_第13张图片

Playground 2016年谷歌发布的模拟神经网络

TensorFlow 2019_第14张图片

x12  x1*x2  sin(x2)各自出现非线性分类的过程

神经网络原理

多分类 : 避免n个双分类器,设置n个输出结点的全连接输出

Softmax回归

1 数值 -> 预测概率值

2 概率和为1(归一化)

交叉熵损失 :

衡量预测的概率分布,和真实的概率分布之间的关系

损失大 /损失小  ->  预测不准 / 预测更准

TensorFlow 2019_第15张图片

                训练中增大或减少每个参数,看如何减少相比于训练数据集的误差,以望能找到最有的权重、偏置参数组合。

TensorFlow 2019_第16张图片

上示负责数据,三层隐藏层的解决方案(增加深度)

tf.keras API介绍(一)

构建模型 :

tf.keras.Sequential()  //堆叠层数        

tf.keras.layers() :

from tensorflow.python.keras.layers import  Dense

from tensorflow.python.keras.layers import  DepthwiseConv2D

from tensorflow.python.keras.layers import  Dot

from tensorflow.python.keras.layers import  Dropout

from tensorflow.python.keras.layers import  ELU

from tensorflow.python.keras.layers import  Embedding

from tensorflow.python.keras.layers import  Flatten

from tensorflow.python.keras.layers import  GRU

from tensorflow.python.keras.layers import  LSTMCell

......

Flatten :

将输入进行形状改变展开

28x28 -> 784

Dense :

Dense(units ,activation=None ,**kwargs):

*untis :  神经元个数

*activations : 激活函数,参考:

tf.nn.relu

tf.nn,softmax

tf.nn.sigmoid

tf.nn.tanh

*kwargs : 输入上层输入的形状,input_shape = ()

//两个隐藏层的10分类器

model = keras.Sequential(

keras.layers.Flattern(input_shape = (28 ,28)),

keras.layers.Dense(128 ,activation = tf.nn.relu),

keras.layers.Dense(10 ,activation = tf.nn.softmax)

)

训练与评估

通过调用model的compile方法去配置该模型所需要的训练参数和评估方法

optimizer :

梯度下降的优化器(keras.optimizers)

from tensorflow.keras.optimizers import  Adadelta

from tensorflow.keras.optimizers import  Adagrad

from tensorflow.keras.optimizers import  Adam

from tensorflow.keras.optimizers import  Nadam

from tensorflow.keras.optimizers import  Optimizer

from tensorflow.keras.optimizers import  RMSprop

from tensorflow.keras.optimizers import  SGD

from tensorflow.keras.optimizers import  desrialize

from tensorflow.keras.optimizers import  get

from tensorflow.keras.optimizers import  serialize

from tensorflow.keras.optimizers import  AdamOptimizer()

losses :

真实值和预测值之间的差值

损失类型

from tensorflow.keras.losses import  KLD

from tensorflow.keras.losses import  KLD as kls

from tensorflow.keras.losses import  KLD as kullback_leibler_divergence

from tensorflow.keras.losses import  MAE

from tensorflow.keras.losses import  MAE as mae

from tensorflow.keras.losses import  MAE as mean_absolute_error

from tensorflow.keras.losses import  MAPE

from tensorflow.keras.losses import  MAPE as mape

from tensorflow.keras.losses import  MAPE as mean_ablsolute_precentage_error

from tensorflow.keras.losses import  MSE

from tensorflow.keras.losses import  MSLE

from tensorflow.keras.losses import  binary_crossntroy

from tensorflow.keras.losses import  categorical_crossentropy  //均方误差

from tensorflow.keras.losses import  cosine

from tensorflow.keras.losses import  desrialize

from tensorflow.keras.losses import  get

from tensorflow.keras.losses import  hinge

from tensorflow.keras.losses import  logcosh

from tensorflow.keras.losses import  pisson

metrics = None,[‘accuracy‘]  //指标

进行训练

model.fit(x = None ,y = None ,batch_size = None ,epochs = 1 ,callbacks = None)

x : 特征值

1 numpy array

2 tensor

3 tf.data / tuple

4 a generate

y : 目标值

batch_size = None :

批次大小

epochs = 1

训练迭代次数

tf.keras API介绍(二)

Model module :

Model(inputs = a ,output = b)

*input : 定义模型的输入,input类型

*output : 定义模型的输出

def call(self , inputs) : 接受来自上层的输入

from keras.models import Model

from keras.layers import Input ,Dense

data = Input(shape=(784 ,))

out = Dense(32)data

model_Sec  = Model(input = data ,output = out)

print(model_Sec)

model.compile(optimizer=tf.keras.optimizers.Adam(),loss = ‘sparse_categorical_crossentropy’,metrics=[‘accuracy’])

return None

Models 属性

Models.Layers

Models.Input

Models.Output

Model.Compile() :

优化器 算法 损失计算

损失计算 :

sparse_categorical_crossentropy 对于目标值是整型的进行交叉熵损失计算

categorical_crossentropy 对于两个output tensor and a target tensor (one-hot code)进行交叉熵损失

Model.fit(x=None ,y=None ,batch_size=None ,epoch=1 ,call backs=None)

x:特征值

y:目标值

epochs=1 : 训练迭代次数

callback=None : 添加回调列表(用于tensorboard显示等)

model.evalute(test_image ,test_labels):

评估

或者预测model.predict(test)

其他方法:

model.save_weight()

model.load_weight()

使用多层神经网络进行时装分类

TensorFlow 2019_第17张图片

class SingleNN(object) :

model = keras.Sequential(

keras.layers.Flattern(input_shape=(28,28)),

keras.layers.Dense(128 ,activation=tf.nn.relu),

keras.layers.Dense(10 ,activation=tf.nn.softmax)

)

// 双层:128个单元,全连接10个类别输出

//编译定义优化过程,这里选择我们SGD优化器

keras.optimizers.SGD(lr=0.01)

//lose:tf.keras.losses.spare_categorical_crossentropy

//metrics:accuracy

def compile(self):

SingleNN.model.compile(optimizer=keras.optimizer.SGD(lr=0.01) ,loss=tf.keras.losses.spare_categorical_crossentropy ,metrics=[‘accuracy’])

return None

//训练

//设置batch_size=32或者128查看效果(值如何设置,优化部分会进行详解)

def fit(self):

SingleNN.model.fit(self.train ,self.train_label ,epochs=5 ,batch_size=32)

return None

//评估

def evaluate(self):

test_loss ,test_acc = SingleNN.model.evaluate(self.test ,self.test_label)

print(test_loss ,test_acc)

return None

def__init__(self):

(self.train_,self.train_label),(self.test ,self.test_label) = keras.datasets.fashion_mnist.load_data()

效果修改和对比

效果不好 :换优化器等

效果不好的根本原因: 对图片特征进行归一化

(0 ~ 255) -> (0~1)

#进行数据归一化

self.train = self.train / 255.0

self.test= self.test/ 255.0

模型的保存和加载

保存到h5文件,避免多个文件夹

SingleNN.model.load_weights(“./ckpt/SingleNN.h5”)

model check point

fit 的 Callbacks = “”详解

keras.callbacks.ModelCheckpoint(filepath ,mointor=’val_loss’,save_best_only=False ,save_weights_only=False ,mode=’auto’,period=1)

每隔多少次保存一次模型

提前中止 : 准确率或者阈值,然后中止

modelcheck = keras.callbacks.ModelCheckpoint(

filepath = ‘./ckpt/singlenn_{epoch:02d}-{val_acc:.2f}.h5’,

montor=’val_acc’,

save_best_only = True.

save_weights_only = True,

period = 1,

mode = ‘auto’

)

SingleNN.model.fit(self.x_train ,self.y_train ,epochs=1, batch_size=128 ,callbacks=[modelcheck])

Tensorboard效果

keras.callbacks.TensorBoard( log_dir=’./logs’,histogram_freq=0 ,batch_size=32 ,write_graph = True,write_grads=False,write_images=False ,embeddings_freq=0 ,embeddings_layer_names=None ,embeddings_metadata=None ,embeddings_data=None ,update_freq=’epoch’)

write_graph = True : 是否显示图结构

write_images = False :是否显示图片

write_grads = True :是否显示梯度hitogram_freq 必须大于零

tensorboard=keras.callbacks.TensorBoard(log_dir=’./graph’,histogram_freq=1 ,write_graph=True ,write_images=True)

SingleNN.model.fit(self.train ,self.train_label ,epochs=5 ,callbacks=[tensorboard])

深层神经网络

随着模型的层数(深度)增加,处理复杂问题的能力,可能越好

什么是深层网络

TensorFlow 2019_第18张图片

前向传播和反向传播

例如四层

单个样本的反向传播

TensorFlow 2019_第19张图片

多个样本的反向传播

TensorFlow 2019_第20张图片

参数和超参数

网络有限相关的两个概念

参数(权重、偏置) :模型运行过程中学习到的

超参数(人为设置) : 需要控制的一些参数信息(学习率、迭代次数、隐藏层层数、每层神经元个数、激活函数选择 等等)

优化过程遇到的问题

梯度消失局部最优

如何解决上述问题?

1 初始化参数策略 (relu函数无问题)

2 Mini梯度下降算法

batch一起epoch

TensorFlow 2019_第21张图片

3 梯度下降算法的优化

TensorFlow 2019_第22张图片

SGD 随机梯度下降

BGD 批梯度下降

Mini-Batch 小批量梯度下降

*选择方法是个数量的经验值

马鞍面

加权平均值优化

TensorFlow 2019_第23张图片

绿线显示的数据更光滑

RMSProp算法 : 求导增加一个动量,减少摆动。更平滑。

Adam算法 :(Adaptive Moment Estimation 自适应矩估计

TensorFlow 2019_第24张图片

亚当

目前在机器学习中,处理梯度最好的算法

tf.train.AdamOptimizer(learning_rate = 0.001 ,beta1 = 0.9 , beta2 = 0.999 ,epsilon = 1e-08 ,name = ‘adam’)

学习率α : 尝试一系列的值,寻找比较合适的

β1 : 作者常用却省值0.9

β2 : 建议0.999

ε : 建议1e-8

4 学习率衰减

如果设置一个固定的学习率,在最小点附件不容易收敛

所以随着时间逐渐减小学习率α的大小,有助于算法收敛

指数衰减 α = 0.95^(epoch_num) * α0

*其他非算法的优化的方式

标准化输入  平均值0 标准差1 的 平均正态分布

卷积神经网络的简介

Convolution Neural Network

线性模型解决问题的能力是有限的

TensorFlow 2019_第25张图片

使用非线性的激活函数

TensorFlow 2019_第26张图片

Leaky Relu 带泄露的Relu

为什么需要非线性的激活函数?

如果直接logistic回归,那么无论多少神经网络层,输出都是输入的线性组合。与没有隐藏层相当,相当于最原始的感知器。

感受野概念

如果不使用卷积处理图片?  特征数量太大(几个神经元,几千万个权重参数)。

基于是觉得卷积神经网络:

TensorFlow 2019_第27张图片

边缘检测 :

过滤器Filter

卷积网络CNN的三个组成

由一个或多个卷积层(Convolutions)池化层(Subsmpling) ,以及全连接层(Full connection)组成。

卷积曾主要目的是:提取图片特征

size : 卷积核/Filter的大小 3*3 5*5

padding : 填充

stride : 步长,通常1

为什么填充增加0值?  不对运算造成影响。

填充多少?         Vailed/Same输出大小和输入大小的比较。

池化层 Pooling

池化层作用 :

1 收集/减少图片的特征数量,避免全连接层参数过多。

2 提高FeatureMap的鲁棒性,防止过拟合(训练好但是测试差)

Max Pooling / Avg Pooling

全连接层

先对FeatureMap 扁平化

再接一个或多个全连接层,以进行模型学习

TensorFlow 2019_第28张图片

CIFAR100类识别

构建CNN常用API

Conv2D

MaxPool2D

keras.layers.Conv2D(32,kernel_size=5 ,strides=1 ,padding=’same’ ,data_format=’channels_last’,activation=tf.nn.relu),keras.layers.MaxPool2D(pool_size=2 ,strides=2 ,padding=’same’))

步骤实现,缩减版的LeNet v5

class CNNMnist(object) :

def __init__(self) :

(self.train ,self.train_label) ,(self.test ,self.test_label) = \ keras.datasets.cifar100.load_data()

self.train = self.train.reshape(-1 ,32 ,32 ,3) / 255.0

self.test = self.test.reshape(-1 ,32 ,32 ,3) / 255.0

设计模型LeNet:

两层卷积层 + 两个神经网络层

第一层

卷积: 32个filter 大小5*5 strides=1 padding=“SAME”

激活: Relu函数

池化: 大小2X2 strides=2

第二层

卷积: 64个filter 大小5*5 strides=1 padding=“SAME”

激活: Relu

池化:大小2X2 strides=2

model = keras.Sequential([

keras.layers.Conv2D(32 ,kerenl_size=5,strides=1,padding=”same”,data_format=’channel_last’,activation=tf.nn.relu),

keras.layers.MaxPool2D(pool_size=2 ,strides=2 ,padding=’same’),

keras.layers.Conv2D(64 ,kernel_size=5 ,strides=1 ,padding=’same’,data_format=’channels_last’ ,activation=tf.nn.relu),

keras.layers.MaxPool2D(pool_size=2 ,strides=2 ,padding=’same’),

keras.layers.Flatten(),

keras.layers.Dense(1024 ,activation =tf.nn.relu),

keras.layers.Dense(100 ,activation=tf.nn.softmax),

])

编译/执行。评估。

def compile(self):

CNNMnist.model.compile(

optimizer=keras.optimizers.Adam() ,

loss=tf.keras.losses.sparse_categorical_crossentropy,

metrics=[‘accuracy’]

)

return None

def fit(self):

CNNMnist.model.fit(self.train ,self.train_label ,epochs=1 ,batch_size=32)

return None

def ecaluate(self):

test_loss,test_acc=CNNMnist.model.evaluate(self.test ,self.test_label)

print(test_loss ,test_acc)

return None

卷积神经网络案例实现

#归一化

self.train = self.train /255.0

self.test = self.test /255.0

其余的代码同上节

正则化(Regularization)介绍 - 偏差方差

梯度下降的优化:限制权重;期望为0的正态分布;

梯度下降的优化,主要是数学方面。正则化的数学意义不大,主要是工程方面的意义。

数据集的划分

三个数据集:训练集(train set)、验证集(development set)、测试集(test set)

6:3:1 的比例(或者其他比例),进行交叉验证,选出最好的模型。

偏差-方差分解(bias-variance decomposition) 是解释学习算法泛化能力的一种重要工具

泛化误差: 数据集的偏差、方差、噪声。泛化性能是学习算法的能力、数据的充分性、以及学习任务的难度决定

偏差:度量学习算法的期望预测与真实值的偏离程度,刻画学习算法的拟合能力

方差:度量同样大小的训练集的变动所导致的性能变化,刻画数据扰动所造成的影响 

噪声:表达当前任务上任何学习算法所能达到的期望泛化误差的下界,刻画学习问题本身的难度

那么偏差、方差和数据集划分到底有什么关系?

1 训练集的错误率较小,验证集/测试集的错误率较大,说明模型存在较大方差,可能出现过拟合

2 训练集和测试集误差都很大,且两者接近,说明模型存在较大方差,可能出现欠拟合

3 反之,训练集和测试集错误率很小,且两者接近,说明模型效果比较好

*算法优化和正则化的区别?

算法优化是针对问题选模型、层数、激活函数;

正则化是处理过拟合中训练集/测试集(实际问题)的能力不一致;

正则化的方法:

1 L1和L2

2 DropOut

3 早停止

欧姆剃刀:简单模型比复杂模型的泛化能力好

TensorFlow 2019_第29张图片

正则化,即在成本函数中加入一个正则化项(惩罚项),惩罚模型的复杂度。防止网络过拟合。

逻辑回归L1和L2

L2又叫做权重衰减(减小的慢)

keras.regularizers.l1(0.01)

keras.regularizers.l2(0.01)

keras.regularizers.l1_l2(l1=0.01 ,l2=0.01)

TensorFlow 2019_第30张图片

DroupOut正则化

Drouput-regularition Model (随机丢弃)

TensorFlow 2019_第31张图片

keep_prob = 0.8

其他正则经验

早停止法(Early stop

*

数据增强

通过多种组合变换达成增加数据集大小

剪切 旋转/翻转 缩放 对比度变换  噪声扰动 颜色变换

翻转 tf.image.random_flip_left_right

旋转 tf.image.rotate

剪裁 tf.image.random_crop

TensorFlow 2019_第32张图片

数据增强在理论上,不会增加噪声。

经典分类网络结构

TensorFlow 2019_第33张图片

AlexNet

TensorFlow 2019_第34张图片

总参数数量:  60M = 6000万 , 5层卷积+3层全连接

使用非线性激活函数: Relu

防止过拟合的方法:Dropout

进化历史: AlexNet -- NIN -- (VGG / GoogLeNet) -- ResNet

VGG

2014年分类第二(第一是GoogleNet),定位任务第一

参数量大,140M = 1.4亿

模型分两种 16层,19层

TensorFlow 2019_第35张图片

为保持精确度,改进内存,引入Inception模块

TensorFlow 2019_第36张图片

MLP: 卷积1X1    NIN : 网络中的网络

参数/权重 数量的减少

1  看作对三个通道进行线性组合

2 通常卷积后加入非线性函数,这里加入激活函数,理解成一个简单MLP

实际中的Inception Modul:

TensorFlow 2019_第37张图片

卷积神经网络的学习可视化过程

TensorFlow 2019_第38张图片

TensorFlow 2019_第39张图片

TensorFlow 2019_第40张图片

TensorFlow 2019_第41张图片

TensorFlow 2019_第42张图片

TensorFlow 2019_第43张图片

使用Pre_trained模型进行VGG预测

tensorflow.keras.applications有很多现有模型。

TensorFlow 2019_第44张图片

from tensorflow.python.keras.applications.vgg16 import VGG16

from tensorflow.python.keras.applications.vgg16 import preprocess_input,decode_prediction

from tensorflow.python.keras.preprocessing.image import load_img, img_to_array

def predict():

model = VGG16()

print(model.summary())

image = load_img('' ,target_size = (224 ,224))

image = image_to_array(image)

print(image.shape)

#输入卷积中,需要四维结构

image = image.reshape((1 ,image.shape[0] ,image.shape[1] ,image.shape[2] ))

#VGG16进行归一化处理

image = preprocess_input(image)

y_predictions = model.predict(image)

print(y_predictions)

TensorFlow 2019_第45张图片

# 1000个类别里,“老虎”图片的维度是最大的

#VGG16解码工具

label = decode_predictions(y_predictions)

print("预测类别:%s ,概率是%s" % (label[0][0][1] ,label[0][0][2]))   //获取其中元组

if __name__ == '__main__':

predict()

以上内容,是使用VGG进行迁移学习。

神经网络调优与BN

知道常用的一些超参数

知道BN层的意义以及数学原理

算法层面:

学习率α (一般自学习)

β1 β2 :Adam优化算法的超参数,通常设置0.9 0.999 10-8

λ:正则化网络参数

网络层面:

hidden units : 各隐藏层神经元个数

layers: 神经网络层数

调参技巧:

TensorFlow 2019_第46张图片

合理参数设置:

学习率α: 0.001 0.01 0.1 跨度尽量大

算法参数β: 0.999 0.995 0.998 尽量接近1

试参数很步骤很麻烦,如何让整个过程简单?

批标准化 BN Batch Normaliztion):

2015年2月的arxiv论文

内部协变量偏移 internal covariate shift的现象,通过标准层化来解决。

使用批标准化的图像分类,效果优于人类。

TensorFlow 2019_第47张图片

深藏网络中,不止是初始的特征输入,而隐藏层也有输出,所以对深层网络层的每一层层级进行批标准化。

TensorFlow 2019_第48张图片

防止分母为0

原作者不希望方差1均值0,所以增加参数γ β

增加参数γ β(同W b一样),可以用各种梯度下降算法更新γ β的值,如同更新神经网络权重一样。为什么?

如果方差1均值0,那么得到较差的模型。

TensorFlow 2019_第49张图片

如果测试集中的数据,分布不一样,这个网路可能就不能准确区分。这种情况下需要重新训练

1   Batch Normalization的作用是减少 Internal Covation Shift带来的影响,让模型的鲁棒性更强。

2  Batch Normalization的作用,使得均值和方差保持固定(每层由γ β决定),不同层学习到不同的分布状态

3  因此厚层的学习更容易些,Batch Normalization 减少各层W和b之间的耦合性,让各层更加独立,实现自我训练学习的效果。

CNN(卷积神经网络) 的内容复习

激活函数的选择?

非线性的Relu比tanh好,避免梯度消失。

感受野/边缘检测 的概念

网络层的组成?

一个或多个卷积层、池化层以及全连接层等组成

卷积层(Convolutions)

池化层(Subsampling)

卷积层的目的是什么?

提取特征 filter

卷积核 padding stride

Valid填充/Same原图大小

多通道卷积

池化层的作用?

作用:减少图片的特征数量

最大池化/平均池化

stride  (类似卷积核)

部分代码

Conv2D

MaxPooling

正则化的作用?

作用:避免过拟合

训练好(迭代过多,层过深),效果差(测试机、线上效果差)

L2 Lp  

消除噪声

Droupout为什么有效?

当确定已发生过拟合现象时,

来保证损失函数是单调下降的。

其他的正则化方法/训练方法?

早停止

数据增强(旋转/裁剪等等)

经典的网络结构?

LeNet 

参数6万

AlexNet 

2012年,参数6M=6000万,5层卷积+3层全连接

VGG

1.4亿参数,输入224*224*3 ,1000个分类

GoogleNet

引入Inception结构,500万参数

什么是Inception结构?

卷积层代替全连接 / Conv2D 代替 Dense

参数量减少

案例: 迁移学习Pre_trained的VGG16模型,识别图片“老虎”

批标准化的作用?

手动超参数的网络调优。

解决 内部协变量 的现象。

减少各个层W和b之间的耦合性,让各层更加独立,实现自我训练学习的效果。

迁移学习(Transfer Learning

利用旧领域(数据、任务或模型)的相似性,将旧领域学习或训练好的模型,应用到新的领域中。

相反,机器学习系统很容易从海量数据中学习到一个鲁棒性很强的系统。

方法:

最常见的 fine tuning (微调)。

已训练好的模型,叫Pre-trained model

TensorFlow 2019_第50张图片

任务A海量数据已训练好的模型(1000类图片识别),新增任务B(250类图片识别)

1  可以在最后输出层(全连接层),在1000基础上,新增250个神经元

2  如果B数据量小,我们对A所有层进行freeze(通过Tensorflow的trainable=False参数实现),剩下层部分进行参数调整

3  如果B数据量大,我们对A中一半或者大部分的层进行freeze,剩下的部分layer进行新任务数据基础的微调。

迁移学习案例介绍

基于Keras中的VGG对五种图片类别的识别。

思路和步骤:

读取本地图片数据及类别

keras.preprocessing.image import ImageDataGenerator提供读取转换功能

模型的结构修改(添加自定义的分类层)

freeze掉原始VGG模型

编译以及训练和保存模型方式

输入数据进行预测

迁移学习--数据读取

train_generator = ImageDataGenerator()

生产图片的批次张量并且提供数据增强功能

rescale = 1.0/255 标准化

zca_whitening = False #zca白化的作用是针对图片进行PCA降维操作,减少图片冗余信息。

等等

TensorFlow 2019_第51张图片

import tensorflow as tf

from tensorflow.python import keras

from tensorflow.python.keras.preprocessing.image import ImageDataGenerator

class TransferModel(object):

def __init__(self):

self.train_generator = ImageDataGennerator(rescale = 1.0 / 255.0)

self.test_generator = ImageDataGennerator(rescale = 1.0 / 255.0)

self.train_dir  = "./data/train"

self.test_dir  = "./data/test"

self.image_size = (244 ,244)

self.batch_size = 32

def get_local_data(self):

train_gen = self.train_generator.flow_from_directory(

self.train_dir,

traget_size = (244 ,244),

class_model  = self.image_size,

batch_size = self.batch_size,

shuffle = True

)

test_gen = self.train_generator.flow_from_directory(

self.test_dir,

traget_size = (244 ,244),

class_model  = self.image_size,

batch_size = self.batch_size,

shuffle = True

)

return train_gen,test_gen

if __name__ == '__main__':

tm = TransferModel()

train_gen ,test_gen = tm.get_local_data()

print(train_gen)

print(test_gen)

for data in train_gen:

print(data)

模型定义

谷歌提供的NoTop模型:

VGG16不包含最后的三个全链接层。用来做fine tuning,专门开源模型。

keras_application/vgg16.py

TensorFlow 2019_第52张图片

self.base_ model = VGG16(weights = 'imagenet' ,include_top = Fasle)

weights='imagenet',意思是VGG在imagenet比赛中预训练的权重,使用resnet训练

模型修改

VGG模型的修改添加全连接层 GlobalAveragePooling2D

全局池化:

图像分类任务中,模型经过最后CNN层的尺寸为[batch_size ,img_width ,img_height ,channels],通常做法是街一个flaten layer,将尺寸改为[batch_size ,w h channels]再至少链接一个FC layer。这样做的问题:模型参数越多,容易过拟合

利用pooling layer来代替最后的FC layer

TensorFlow 2019_第53张图片

参数Dense 8 * 8 * 2048 * 1000
参数Conv2D  1 * 1 * 2048 * 1000

*如果正常训练,那么参数数量不可缺少、很重要

def  refine_vgg_model(self):

'''

微调VGG结构:

5blocks后面+全局平均池化(减少迁移学习的参数数量) + 两个全连接层

'''

#获取NoTop模型输出

x = self.base_model.outputs[0]

#在输出层后面增加我们结构

x = keras.layers.GlobalAveragePooling2D()(x)

x = keras.layers.Dense(1024 ,activation = rf.nn.relu)(x)

y_predict = keras.layers.Dense(5 ,activation=tf.nn.softmax)

transfer_model = keras.Model(input=self.base_model.inputs ,outputs = y_predict)

return transfer_model

freeze VGG模型

如果参数数量小,可以全部层freeze(trainable = False)

def freeze_vgg_model(self):

for layer in self.base_model.layers:

layer.trainable = False

#主代码

tm.freeze_vgg_model()

tm.compile(model)

tm.fit_generator(model ,train_gen ,test_gen)

#class tranfer类

trainfer_model = keras.models.Model(

input=self.base_model.inputs ,

outputs = y_predict

)

transfer_model.compile(

optimizer = keras.optimizers.Adam(),

loss = keras.losses.sparse_categotical_crossentropy,

metrics=['accuracy']

)

#class tranfer类的自定义fit方法

def fit_generator(self ,model ,train_gen ,test_gen)

keras.callbacks.ModelCheckpoint('./ckpt/transfer_{epoch:02d}-{val_acc:.2d}.h5',

mointor='val_acc',

save_weight_only = True,

save_best_only = True,

model = 'auto',

period = 1

 )

transfer_model.fit_generator(

train_gen ,

epochs = 3,

validation_data = test_gen,

callbacks=[model]

)

freeze模型训练 And 模型预测

from tensorflow.python.keras.preprocessing.image import ImageDataGenerator ,load_img ,img_to_array

#class transfer类

def predict(self ,model):

#加载模型 transfer_model

model.load_weights("./ckpt/transfer_02-0/93.h5")

#读取图片、处理

load_img(./data/test/dinosaurs/400.jpg ,target_size = (224 ,224))

image = img_to_array(image)

print(image.shape)

#四维(224 ,224 ,3)->  (1 ,224 ,224 ,3)

// image = tf.reshape(image ,[1 ,image.shape[0], image.shape[1], image.shape[2],] )

image = image.reshape(image ,[1 ,image.shape[0], image.shape[1], image.shape[2],] )

#处理图像内容,归一化处理等,进行预测

img = preprocess_input(img)

print(img.shape)

y_predict = model.predict(img)

index = np.argmax(y_predict ,axis = 1)

print(self.label_dict[str(index[0])])

#预测结果进行处理

image = preprocess_input(image)

predictions = model.predict(image)

print(predictions)

案例--商品物体检测

项目已部署上线,Web检测,百度机器人识别段。

TensorFlow 2019_第54张图片

Tensorflow server部署,SSD和YOLO

TensorFlow 2019_第55张图片

目标检测算法:

两步走:先区分推荐,再进行目标分类。

R-CNN FastR-CNN FasterR-CNN

端到端:采用一个网络一步到位

YOLO SSD

TensorFlow 2019_第56张图片

回顾图片分类的原理:

图片经过卷积、激活、池化相关层,最后加入全连接层。

TensorFlow 2019_第57张图片

常见CNN模型: AlexNet  VGG GoogleNet  ResNet

目标检测不仅仅是分类这么简单,还需要输出位置信息。

语义切割主要评估指标: IOU (Intersection over Union)

B-Box (bounding box): (x ,y ,w ,h)

TensorFlow 2019_第58张图片

TensorFlow 2019_第59张图片

Ground-truth bounding box : 图片真实标记的框 (人手画的)

Predicted bounding box:预测时标记的框

对于分类的概率,还是使用交叉熵损失

位置信息具体的数值,可使用MSE俊芳误差损失(L2损失)

R-CNN region proposal method 候选区域方法

为什么要循环检测?

TensorFlow 2019_第60张图片

因为检测数量不确定。解决办法overfeat模型。

Overfeat方法: K X M

缺点是暴力破解,计算量大

CVPR2014年提出的R-CNN。

R-CNN的原理

论文中的步骤:

1  默认找图片中2k个候选区域region proposal

2 基于ALexNet的227X227,通过CNN提取特征,2000X4096维矩阵

3  2000X4096维矩阵经过SVM分类器(假如20种分类,SVM是二分类,则有20个SVM SVM分类已经过时), 2000X20种类别矩阵,[2000 20]得分。

4  对2000X20矩阵做非极大抑制(NMS non-maximum suppression ,去除重复、不好的候选区域

5  修正B-box,对bbox做出回归微调

*候选区域(Region of Interset)

选择性搜索(SelectiveSearch),首先将每个像素分组,然后相近的像素进行合并。

TensorFlow 2019_第61张图片

候选框的长宽不固定,不能直接输入ALexNet CNN网络

TensorFlow 2019_第62张图片

修正候选区域

bbox regression,回归用于修正筛选后的候选区域,使之归于ground-truth。默认是线性关系,因为最后筛选出来的候选区域和ground-truth。

TensorFlow 2019_第63张图片

目标检测—评估指标

IoU交并比

TensorFlow 2019_第64张图片

平均精确率(mean average precision map)

精确率/召回率 *

TensorFlow 2019_第65张图片

R-CNN总结

在VOC2007数据集上平均map准确率达到66%

缺点:

1  训练阶段多: 微调网络+SVM训练+训练边框回归器

2  训练耗时:5000张图片,几百G的特征文件

3  处理速度慢: GPU VGG16需要47秒

图形形状变化: 需要crop/warp进行处理

R-CNN改进  SPPNet

改进哪里了?改进的详细细节?

R-CNN最慢的步骤在哪里?  进行卷积运算。

TensorFlow 2019_第66张图片

TensorFlow 2019_第67张图片

TensorFlow 2019_第68张图片

通过spatial pyramid pooling 将特征图转换成特定大小的特征向量。

CNN的改进 Fast R-CNN

提出Rol pooling,然后整合模型,把CNN Rolpooling 分类器SVM B-box一起训练。

Softmax替换SVM

多任务损失 Multi-task loss

1  对分类损失,是一个N+1的softmax输出

2  对回归损失,是一个4XN的输出的regression

所以使用平均绝对误差MAE 损失,即L1损失

fine-tuning 训练

微调时,调整CNN + Rol pooling + softmax

调整bbox regression回归中的参数

TensorFlow 2019_第69张图片

缺点

使用Selective Search 提取 Region Proposals ,没有真正的端到端,比较耗时

CNN改进  Faster R-CNN

TensorFlow 2019_第70张图片

Faster R-CNN 看成区域特征生成网路,加上Fast R-CNN。

区域特征生成网络 Region Proposal Networks RPN :

用于生成region proposals,称之为anchors

通过softmax判断anchors属于前景foreground还是背景background

bounding box regression 修正anchors获得精确的proposals

获取经验的2000个候选区

TensorFlow 2019_第71张图片

候选区域的训练:

正负anchors样本比例 1:3

TensorFlow 2019_第72张图片

RPN的原理

目的是得到候选区域

使用nxn的大小窗口去扫描特征图,得到K个候选窗口

TensorFlow 2019_第73张图片

Faster R-CNN 的训练:

1    RPN的训练,得到score分高的候选区域

2    Fast R-CNN的训练

Fast R-CNN classificaion : 得到正确的分类

Fast R-CNN regression (B-Box loss) : 得到更好的位置

开源Keras Faster RCNN 模型介绍

地址  GitHub - jinfagang/keras_frcnn: Keras Implementation of faster-rcnn

代码笔记

assert 断言 ,不成立条件中断执行

__feature__   使用python3的新特性

__iter__  迭代器,返回的是对象本身

**kw  关键词参数,用于词典

pip install opencv-python    #视频的OpenCv用途更大

代码架构:

TensorFlow 2019_第74张图片

工程里所有trainable = True

YOLOYou only look once

YOLOv4 结构 :

GoogleNet + 4个卷积 + 2个全连接层

惊不惊喜,意不意外?

例如:

TensorFlow 2019_第75张图片

1  每一个单元格,计算两个候选框

2  对9 X2 = 18 个候选框,进行概率计算、筛选

单元格 Grid Cell

YOLOv4 网络层输出大小: 7X7X30

TensorFlow 2019_第76张图片

每个Grid Cell 需要预测一个物体类别

每个Grid Cell 预测两个(默认)B-box位置,两个B-box置信度。

一个B-box: xmin ymin xmax ymax confidence

两个B-box 4 +1 + 4 + 1 有10个值

所以一个Grid Cell 需要输出 10 + 20(预测) = 30 个值

Grid Cell 的Score值

如没有object,score是0

如果有object,score是object和confidence的乘积

一个object的ground truth,两个B-box的IoU值比较,确定自己的物体。

TensorFlow 2019_第77张图片

不同于faster rcnn anchorsyolo的框坐标直接由网络输出,在 7X7X30 30里面。但是RPN网络对其优化得到一个更准的坐标和是否北京类别。

非最大抑制(NMS)

每个B-box的Class-Specific Confidence Score以后,设置阈值,滤掉概率低的bbox,对每个类别过滤IoU,得到最终检测结果

损失

三个部分 B-box损失 + confidence损失 + classfication 损失

与Faster R-CNN对比

Faster R-CNN利用RPN网络与真实值调整候选区域,然后再进行候选区域和卷积特征结果映射的特征向量,通过与真实值优化网络预测结果。

Yolo将这两步合成一步,直接网络输出预测结果进行优化。

YOLO是回归法的代表,特点是块,缺点是准确率(Grid Cell 中间)

YOLO对运动跟踪的效果更好

SSD Single Shot MultiBox Detector

2016年发表arxiv论文。结合yolo的回归思想和faster rcnn的anchors机制。

核心:不同尺度的特征图上采取卷积核预测一系列Default Bounding Boxes的类别、坐标偏移。

SSD以VGG-16为基础,使用VGG的前五个卷积,后面增加从Conv6开始的五个卷积结构,输入图片要求300*300

TensorFlow 2019_第78张图片

SSD会把中间不同尺度的特征图,再会进行BoundingBox的Detector & Classifier 预测

SSD会把中间不同尺度的feature map特征图都使用PriorBox层。

Detector & Classifier

PriorBox层由 Detector & Classifier 组成。

TensorFlow 2019_第79张图片

TensorFlow 2019_第80张图片

Detector & Classifier 的三个部分:

1  PriorBox层: 生成default boxes ,默认候选框

2  吸取YOLO邮电 Conv3X3 : 网络生成localization ,confidence,4个位置、预测概率、置信度

TensorFlow 2019_第81张图片

PriorBox 层 类似B-Box:

TensorFlow 2019_第82张图片

生成候选框后,prior_variance 做微调

TensorFlow 2019_第83张图片

SSD多个 Detector & Classifier的作用?

核心是在不同尺度的特征图上,进行Detector&Classifier容易使SSD观察到更小的物体

localization & confidence

两者主要是用来过滤、训练

TensorFlow 2019_第84张图片

训练与测试流程

输入-> 输出-> 结果与ground truth标记样本回归损失计算-> 反向传播,更新权值

样本标记

将prior box 与ground truth box 做匹配,标记正负样本。先不训练8735张图片,先进行置信度筛选,并且训练指定的正负样本。

default boxes按照正负样本控制positive :negative = 1 : 3

损失 losses

网络输出预测predict box 与ground truth回归变换之间的损失计算,置信度采用Softmax Loss(Faster R-CNN 是logstic loss),位置采用L1 losses。

TensorFlow 2019_第85张图片

TensorFlow 2019_第86张图片

测试test流程

输入 -> 输出  ->  nms  ->  输出

SSD兼顾速度和精度。

Keras SSD 代码结构

TensorFlow 2019_第87张图片

TensorFlow 2019_第88张图片

TensorFlow 2019_第89张图片

num_priors = 6 #配置好的关联框

案例: 利用SSD做图片的物体检测

输入数据,找几千个PriorBox,在非最大抑制NMS,输出结果

from nets.ssd_net import ssd300

from utils.ssd_utils import BBoxUtility

from tensorflow.python.keras.preprocesing.iamge import load_img ,img_to_array

from scipy.misc import imread

from  keras.applications.imagenet_utils import preprocess_input

import os

class SSDTest(object):

def __init__:

self.classes_name = ['car' ,'sofa' 等等]

self.classes_nums = len(self.classes_name) + 1

self.input_shape = (300 ,300 ,3)

def test(self):

#SSD300模型的输入以及加载参数

model=SSD300(self.input_shape ,num_classes=self.classes_nums)

#加载训练好的模型

model.load_weights("./ckpt/weights_SSD300.hdf5" ,by_name=True)

#读取多个本地路径测试图片,preprocess_input以及保存图片像素值

feature = []

images_data = []

for path in os.listdir("./images"):

img_path = os.path.join("./images" ,path)

image=load_img(img_path ,target_size=(self.input_shape[0] ,self.input_shape[0] ))

image = img_to_array(image)

feature.append(image)

images_data.append( imreadimread(img_path)) # 图片数据集

#预处理需要数组,不能是列表

#inputs = preprocess_input(feature)

#print(inputs)

inputs = preprocess_input(np.array(feature))

print(inputs)

#模型预测结果,处理7308PriorBox

pred= model.predict(inputs ,batch_size =1 ,verbvose=1)

print(pred.shape)

#形状是(2 ,7308 ,33)

# 2 张图片数量  ,7308个PriorBox ,33: 4+ 21+ 88(position confidence )

#进行非最大抑制算法处理NMS

bb = BBoxUtility(self.classes_nums)

res = bb.detection_out(pred)

print(res)

print(res[0].shape ,res[1].shape)

# (200 ,6)  (200,6)

#NMS后还有200个PriorBox ,6是label location xmin ymin xmax ymax

return res ,images_data

def teg_picture(self ,images_data ,outputs):

for i , img in enumerate(images_data):

pre_label = outputs[i][: , 0]

pre_conf = outputs[i][: , 1]

pre_xmin = outputs[i][: , 2]

pre_ymin = outputs[i][: , 3]

pre_xmax = outputs[i][: , 4]

pre_ymax = outputs[i][: , 5]

print("pre_label:{} ,pre_conf:() ,pre_xmin:{} ,pre_ymin:{} ,pre_xmax:{} ,pre_ymax:{}" .format(pre_label ,pre_conf ,pre_xmin ,pre_ymin ,pre_xmax ,pre_ymax))

#概率预测结果太多,置信度大于90%的图片我们看一下

top_indeicts = [i for  i ,conf in enumerate(pre_conf) if conf > 0.9]

top_label_indices = pre_label[top_indeicts].tolist()

top_xmin = pre_xmin[top_indices]

top_ymin = pre_ymin[top_indices]

top_xmax = pre_xmax[top_indices]

top_ymax = pre_ymax[top_indices]

print("after filter  top_label:{} ,top_conf:() ,top_xmin:{} ,top_ymin:{} ,top_xmax:{} ,top_ymax:{}" .format(top_label ,top_conf ,top_xmin ,top_ymin ,top_xmax ,top_ymax))

#matplot画图显示

#定义21种颜色,显示图片

#currentAxis增加图片中文本显示和标记

colors = plt.m.hsv(np.linspace(0,1,21)).tolist()

plt.imshow(img / 255.)

currentAxis = plt.gca()

for i in range(top_conf.shape[0]):

xmin = int(round(top_xmin[i] * img.shape[1]))

ymin = int(round(top_ymin[i] * img.shape[0]))

xmax = int(round(top_xmax[i] * img.shape[1]))

ymax = int(round(top_ymax[i] * img.shape[0]))

#获取图片的预测概率,名称,定义显示颜色

score = top_conf[i]

label = int(top_label_indices[i])

label_name = self.classes_name[label-1]

display_txt = '{:0.2f} ,{}'.format(score ,label_name)

coords = (xmin ,ymin),xmax - xmin + 1 ,ymax - ymin + 1

color = colors[label]

#显示方框

currentAxis.add_patch(plt.Rectangle(*coords ,fill= False ,edgecolor = color , 'alpha':0.5))

lt.show()

return None

if __name___ == '__main__':

ssd = SSDTest()

res = ssd.test()

ssd.tag_picture(images_data ,outputs)

常用目标检测检测数据集介绍

pascal Visual Object Classes

TensorFlow 2019_第90张图片

Classification Detection Segementation PersonLayout  由VOC2007 VOC2012提供

TensorFlow 2019_第91张图片

Open Images Dataset V4

谷歌提供

TensorFlow 2019_第92张图片

2018年发布190万张图片,针对600类别的1540万个边框盒

XML对应标记信息

TensorFlow 2019_第93张图片

数据集的目标标记

提供给训练的数据样本,图片和目标真实结果

特定的场景会缺少标记图片

LabelImg的图形图像注释工具。基于QT。注释以PASCAL格式保存。

TensorFlow 2019_第94张图片

Linux MacOS的教程

TensorFlow 2019_第95张图片

商品检测数据集的处理

XML的结构解析

from xml.etree import ElementTree as ET

tree = et.parse(filename) #获得树形结构

tree.getroot()  #获得树根

root.find() 与 findall()进行查询XML每个标签的内容

TensorFlow 2019_第96张图片

商品检测数据集的存储

TensorFlow 2019_第97张图片

复习(一)

YOLO的结构:

GoogleNet + 4个卷积 + 2个全连接

网络输出大小 7X7X30

单元格Grid Cell

一个B-box: xmin ymin xmax ymax confidence

损失

bbox损失 + confidence损失 + classification损失

优点

速度快,适合视频和跟踪

缺点

对单元格分割处不敏感,对小物体不敏感

SSD的结构:

基本结构同YOLO

Detector & Classifier 块:

组成PriorBox层,默认的候选框群

Conv3X3 组成localization,4个位置偏移

Conv3X3 组成confidence,21个类别置信度(需要区分前景背景)

数据集的制作和保存

复习(二)

训练时的fine tuning

TensorFlow 2019_第98张图片

案例 商品物体检测

上章节的分类图片迭代器

keras.preprocessing.image import ImageDataGeneratorm

本地图片,标注分割数据

from utils.detection_generate import Generator

1  初始化模型参数以及冻结部分结构

2  compile与fit_generator

from utils.ssd_losses import MultiboxLoss

指定模型冻结

freeze = [

'input_1' , 'conv1_1' ,'conv1_2','pool1',

'conv2_1',‘conv2_2’,‘pool2’,

'conv3_1', 'conv3_2' ,  'conv3_3' ,'pool3'

]

for L in self.model.layers :

if L.name in freeze:

L.trainable = False

SSD训练商品数据

略。

同以上,无新意。

问题解决与多GPU训练

TensorFlow 2019_第99张图片

GPU训练

英伟达

tf.keras  DistrubutionSttrategy

OpenCv介绍

TensorFlow 2019_第100张图片

TensorFlow 2019_第101张图片

视频捕捉

cv.VideoCapture()

CV颜色空间转换

HSV(色相 饱和度 明度)是一种将RGB彩色模型的点,在圆柱种表示的方法。

cv2.COLOR_BGR2GRAY

cv2.COLOR_BGR2HSV

cv2.COLOR_BGR2RBGB

CV画框画图

案例--视频检测介绍获取帧数据

太简单了。

CV采集视频,上文的SSD,NMS置信区间判断物体。

案例--视频检测介绍获取帧数据(2

文本框显示

TensorFlow 2019_第102张图片

显示FPS

总结:

1   图片的大小会变化

2   图片的信息shape ,随着处理,Tensor一直在变。

模型部署逻辑

  • 1    将训练好的模型,进行导出,tf.export工具
  • 2    使用TensorFlow serving 开启模型服务
  • 3    编写模型客户端程序,在web后台使用

TensorFlow 2019_第103张图片

模型格式pb

可以支持热更新

Serving服务安装开启和Serving

使用Docker部署

TensorFlow 2019_第104张图片

Client端代码

Serving Client 代码编写

TensorFlow 2019_第105张图片

这样做的目的,是服务端/客户端的分离,方便成员分工。

再次见到 Session

Web服务开启和Client对接

讲道理,这里不是核心知识,而且有点过时。

百度机器人接口对接

不完全开源

TensorFlow 2019_第106张图片

百度飞浆平台

收费

很多好的模型

TensorFlow 2019_第107张图片

人脸识别

模型基础都是BERT

TensorFlow 2019_第108张图片

人脸SDK

文字识别

识别笔画、语系

进行CNN识别

高精度的文字识别(生僻字)

调超参数

车牌识别

通用发票识别

语音识别

讯飞、搜狗、阿里

普通话、四川话、粤语

特征

傅里叶转换,正弦周期性

语音合成

物体检测课程总结

TensorFlow 2019_第109张图片

TensorFlow 2019_第110张图片

TensorFlow 2019_第111张图片

TensorFlow 2019_第112张图片

TensorFlow 2019_第113张图片

TensorFlow 2019_第114张图片

TensorFlow 2019_第115张图片

*

TensorFlow 2019_第116张图片

上述视频录制时间是2019年。技术2至5年一代,理论20至50年一代。

你可能感兴趣的:(tensorflow,人工智能,python)