一.TensorFlow基础介绍

(一)TensorFlow中的基础概念介绍

1.什么是TensorFlow:Google开源的基于数据流图的科学计算库,适合用于机器学习,深度学习等人工智能领域,tensorflow的源码:

https://github.com/tensorflow

https://gitub.com/tensorflow/models

Tensor:张量(数据)

Flow:计算流(数据流向)

TensorFlow架构:(1)前端:编程模型,构造计算图,Python,C++,Java (2)后端:运行计算图,C++

2.为什么选择TensorFlow:高度的灵活性/真正的可移植性/将科研和产品联系在一起/自动求微分/多语言支持/性能最优化/社区内容丰富

3.Graph:图描述了计算的过程,可以通过tensorboard图形化流程结构,下面是一个图形化的结果:包括了相应的数据和运算,箭头表示数据的流向,这里的计算图就是我们所谓的网络。

对于这样的一个计算图,包括以下操作:

(1)声明(单个图/多个图)

单个图代码:

import tensorflow as tf

g=tf.Graph()#声明一个Graph

g=tf.get_default_graph()#获取当前默认的graph

x=tf.constant(0)

g=x.graph#通过变量也可以获取当前的graph

多个图代码:

g1 = tf.Graph()

with g1.as_default():

x1 = tf.constant(1.0, name="x1")#利用with 来声明当前的变量所对应的Graph

g2 = tf.Gragh()

with g2.as_default():

x2 = tf.contant(2.0,name="x2")

with tf.Session(graph=g2) as sess1:#我们在定义Session时,也可以将Graph指代相应的图,这时session则作用在当前graph下

x1_list = tf.import_graph_def(g1.as_graph_def(),return_elements =["x1:0",name='')

print(sess1.run(x1_list[0]+x2))

(2)保存为pb文件(我们网络训练好之后,我们会进行保存)

g1 = tf.Graph()

tf.train.write_graph(g1.as_graph_def(),'.','graph.pb',False)#这时我们就可以对当前的网络的参数和结构进行保存

(3)从pb中恢复Graph

with gfile.FastGFile("graph.pb",'rb')as f:

graph_def = tf.GraphDef()

graph_def.ParseFromString(f.read())

tf.import_graph_def(graph_def, name='')

sess = tf.Session()

c1_tensor = sess.graph.get_tensor_by_name("c1:0")#节点的获取

c1 = sess.run(c1_tensor)#计算当前节点的值

(4)Tensorboard可视化

import tensorflow as tf

a=tf.contant(1,name='input_a')

b=tf.contant(2,name='input_b')#所有的变量都是tensor

c=tf.multiply(a,b,name='maltiply_c')

d=tf.add(a,b,name='add_d)

e=tf.add(d,c,name='add_e')

sess=tf.Session()

sess.run(e)#获取e节点所对应的值

writer=tf.summary.FileWriter('graph',sess.graph)#将graph添加到日志模块中

4.Session:图必须在称之为“会话"的上下文中执行,会话将图的操作分发到诸如CPU或GPU之类的设备上执行。完成了前端和后端的沟通,包括的操作:

(1)创建关闭

sess =tf.Session()

sess=tf.InteractiveSession()

with tf.Session()as Sess:

...(完成数据的注入,计算图在后端的执行)

sess.close

(2)注入机制(具体完成计算图运算的过程)

sess.run(...)#在run中指定需要指定计算的节点

sess.run(tf.global_variable_initializer())#获取当前计算图中全部的变量,然后run完成变量的初始化

a=tf.placeholder(dtype=tf.float32)

b=tf.placeholder(dtype=tf.float32)#a,b两个占位符

add =a+b

add_val=sess.run(add,feed_dict={a:1,b:2})#对a,b进行赋值,run对add进行计算

(3)指定设备

a = tf.placeholder(dtype=tf.float32)

b = tf.placeholder(dtype=tf.float32)

add = a+b#定义一个计算图

with tf.Session() as sess:

with tf.device("/cpu:0):

print(sess.run(add,feed_dict={a:1,b:2}))

(4)资源分配(控制GPU资源使用率)

config =tf.ConfigProto()

config.gpu_option.allow_growth =True

sesstion = tf.Session(config=config,...)#按需分配,可以知道当前网络的一个batchsize所占用的资源是多少,就可以清楚的设置batchsize的上限。

5.Tensor:在TensorFlow中,所有在节点之间传递的数据都为Tensor对象,N维数组,图像:(batch*height*width*channel)

定义方式:tf.constant(value,dtype,shape,name.verify_shape)#常量;tf.Variable(shape,dtype,name)#变量;tf.placeholder(dtype,shape,name)#占位符;tf.SparseTensor()#稀疏的张量

6.Operation:TensorFlow Graph中计算节点,输入输出均为Tensor,调用Session.run(tensor)或者tensor.eval()方可获取该Tensor的值

7.Feed:通过feed为计算图注入值,占位符的值

8.Fech:使用Fech获取计算结果。

tf.Session.run(fetches,feed_dict=None)#feches可以是一个tensor,也可以是list

(二)TensorFlow中的核心API

1.基本运算

.tf.expand_dims(inputs,dim,name=None)#维度的扩展

.tf.split(splt_dim,num_split,value,name='split')#维度的切分

.tf.concat(concat_dim,values,name='concat')#数据的拼接

.tf.cast()#数据类型的转化

.tf.reshape()#对数据形状的变化

.tf.equal()#判断是不是相等

.tf.matmul(a,b)#乘法

.tf.argmax()#最大值所对应的索引值

.tf.squeeze()#去掉向量中维度为1的相应的坐标轴

(1)tf.nn库:

.tf.nn.conv2d(卷积层)

.tf.nn.max_pool

.tf.nn.avg_pool(池化层)

.tf.nn.relu(激活层)

.tf.nn.dropout

.tf.nn.I2_normalize(归一化层)

.tf.nn.batch_normalization

.tf.nn.I2_loss

tf.nn.softmax_cross_entropy_with_logits(交叉熵)

(2)tf.train库:

.tf.train.Saver.save(模型的存储)

.tf.train.Saver.restore(模型的恢复)

.tf.train.GradientDescentOptimizer(0.01).minimize(loss)(模型的优化)

.tf.train.exponential_decay(1e-2.global_steps=sample_size/batch,decay_rate=0.98,staircase=True)(模型的学习率)

(3)TensorFlow中的数据操作

.TensorFlow提供了TFRecord的格式来统一存储数据,TFRecord将图像数据和标签放在一起的二进制文件,能更好的利用内存,实现快速的复制,移动,读取,存储

.数据读取:tf.train.string_input_producer,tf.train.slice_input_producer

.数据解析:tf.TFRecordReader,tf.parse_single_example

.数据写入:tf.python_io.TFRecordWriter

.数据写入相关的API方法:

.write=tf.python_io.TFRecordWriter()

.example=tf.train.Example()#会存储具体的数据,可以定义一个feature

.writer.close()

writer.writer(example.SerializeToString())#将数据序列化后写入TFRecord文件中

实战:

下面以cifar10为例,介绍如何使用tensorflow对图像进行数据读取和数据打包

编程环境:Ubuntu18.04,pycharm,tf1.13.1,cuda10.0,cudnn7.4.1(花了好几天安装了双系统,配好环境,呕心沥血呀)

在pycharm中创建工程:tf-rend-write

1.下载数据集:

方法一:可以到cifar10官网下载CIFAR-10 python version,另外官网上也提供了如何解析当前打包后的数据程序:

def unpickle(file):import picklewith open(file, 'rb') as fo:dict = pickle.load(fo, encoding='bytes')return dict

方法二:用程序直接在项目里下载(在工程下新建文件data装数据集)

import urllib.request as ur
import os
import sys
import tarfile
def download_and_uncompress_tarball(tarball_url, dataset_dir):"""Downloads the `tarball_url` and uncompresses it locally.Args:tarball_url: The URL of a tarball file.dataset_dir: The directory where the temporary files are stored."""filename = tarball_url.split('/')[-1]filepath = os.path.join(dataset_dir, filename)def _progress(count, block_size, total_size):sys.stdout.write('\r>> Downloading %s %.1f%%' % (filename, float(count * block_size) / float(total_size) * 100.0))sys.stdout.flush()filepath, _ = ur.urlretrieve(tarball_url, filepath, _progress)#直接将远程数据下载到本地。print()statinfo = os.stat(filepath)print('Successfully downloaded', filename, statinfo.st_size, 'bytes.')tarfile.open(filepath, 'r:gz').extractall(dataset_dir)#指定解压路径和解压方式为解压gzip
DATA_URL = 'http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz'#数据下载的URL
DATA_DIR = 'data'#存储的文件夹路径
download_and_uncompress_tarball(DATA_URL, DATA_DIR)

解析:

(1)urlretrieve的使用

直接将远程数据下载到本地。

urllib.urlretrieve(url, filename, reporthook, data)

参数说明:

url:外部或者本地url(这里是DATA_URL)

filename:指定了保存到本地的路径(如果未指定该参数,urllib会生成一个临时文件来保存数据)(这里是DATA_DIR)

reporthook:是一个回调函数,当连接上服务器、以及相应的数据块传输完毕的时候会触发该回调。我们可以利用这个回调函数来显示当前的下载进度(这里是_progress)

data:指post到服务器的数据。该方法返回一个包含两个元素的元组(filename, headers),filename表示保存到本地的路径,header表示服务器的响应头。

(2)os.stat() 方法

用于在给定的路径上执行一个系统 stat 的调用。

os.stat(path)

path -- 指定路径

返回值

stat 结构:

  • st_mode: inode 保护模式
  • st_ino: inode 节点号。
  • st_dev: inode 驻留的设备。
  • st_nlink: inode 的链接数。
  • st_uid: 所有者的用户ID。
  • st_gid: 所有者的组ID。
  • st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
  • st_atime: 上次访问的时间。
  • st_mtime: 最后一次修改的时间。
  • st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。

下载好的数据集如图:

我们发现数据集是以二进制文件格式存储的,接下来我们会对二进制文件进行解析成具体图片,并存到image文件夹下的train和test文件夹里。以data_batch开头的为我们训练集,test_batch为我们测试集。

2.下面我们来解析二进制文件,首先将我们cifar10的10个分类存放在classfication这个变量中,在将官网的解析文件的脚本拷贝过来。

classification = ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']def unpickle(file):import picklewith open(file, 'rb') as fo:dict = pickle.load(fo, encoding='bytes')return dict

我们可以发现这里的数据是以字典的形式进行存储的,字典的键值分别是data和label

先定义二进制文件的路径:

folders = '/home/jincheng/PycharmProjects/tf-read-write/data_manager/data/cifar-10-batches-py'

使用glob来获取当前文件夹下所有的训练样本所对应的文件:

trfiles = glob.glob(folders + "/data_batch*")

接下来对每个文件调用解析函数,获取到解析数据是一个字典,分别定义两个空list来读取字典的数据和标签。我们将标签打印出来看看。

data  = []
labels = []
for file in trfiles:dt = unpickle(file)data += list(dt[b"data"])labels += list(dt[b"labels"])
print(labels)

结果:(label值对应着classfication的下标)

接下来我们对数据进行解析,将图片进行存储,在cifar10中,图片的大小为32*32,我们将data转为4个纬度的数据,-1表达了当前有多少张图片,具体-1的值会根据data原始的维度来除以一张图片的大小:

imgs = np.reshape(data, [-1, 3, 32, 32])
#采用opencv对图像进行读取和存储,对所有图片进行遍历,img.shape第0个位置是当前数据的数量。由于cv对图片的存储纬度由所不同,先将
#[-1,3,32,32]转化为[-1,32,32,3],在将RGB转化为BGR
for i in range(imgs.shape[0]):im_data = imgs[i, ...]im_data = np.transpose(im_data, [1, 2, 0])#[-1,32,32,3]im_data = cv2.cvtColor(im_data, cv2.COLOR_RGB2BGR)#接下来定义数据存放的位置,图片的下一级目录为图片的类别f = "{}/{}".format("/home/jincheng/PycharmProjects/tf-read-write/data_manager/data/image/train", classification[labels[i]])#如果文件夹不存在,则新建if not os.path.exists(f):os.mkdir(f)#向相应类别的文件夹写入当前的图片cv2.imwrite("{}/{}.jpg".format(f, str(i)), im_data)

运行得到以下结果:

同理也可以得到测试集的数据

下面我们进行数据打包,打包成TFRecord二进制文件格式的数据,并且将这些数据用于后续的模型训练

import glob
idx = 0#idx用来指向我们当前已经遍历到了第几个类别
im_data = []
im_labels = []
for path in classification:#对10个类别进行遍历path = "/home/jincheng/PycharmProjects/tf-read-write/data_manager/data/image/train/" + path#将train路径拼接上类别成为类别文件夹的路径im_list = glob.glob(path + "/*")#利用glob获取类别文件夹下面的图片,返回的是图片路径listim_label = [idx for i in  range(im_list.__len__())]#定义一个和图片list长度相同的标签list,实际是当前类别遍历的ID号idx += 1#每次遍历完一个类别,将idx+1im_data += im_listim_labels += im_label#这样我们就得到了训练集所有的图片数据和标签

接下来我们对这些获取得到的数据进行存储

tfrecord_file = "data/train.tfrecord"#定义用来存tfrecord文件的路径
writer = tf.python_io.TFRecordWriter(tfrecord_file)#定义tfrecord写入的实例,参数为文件的路径
index = [i for i in range(im_data.__len__())]
np.random.shuffle(index)#用来在打包数据的时候就打乱顺序
for i in range(im_data.__len__()):#遍历当前数据文件im_d = im_data[index[i]]im_l = im_labels[index[i]]data = cv2.imread(im_d)#现在图片的数据是图片的路径,所以通过opencv对图片的数据进行读取#data = tf.gfile.FastGFile(im_d, "rb").read()#和opencv一样可以读取数据,并且度出是bytes型了,并且解码方式和opencv不同ex = tf.train.Example(#将数据写入tfrecord需要定义一个example通过feature对数据进行存储features = tf.train.Features(feature = {#通过字典存放数据"image":tf.train.Feature(bytes_list=tf.train.BytesList(#采用bytes进行存储value=[data.tobytes()])),"label": tf.train.Feature(int64_list=tf.train.Int64List(#laibel用intvalue=[im_l])),}))#通过example对一组图片的数据和标签进行封装writer.write(ex.SerializeToString())#我们将example序列化后写入tfrecord中
writer.close()#写入数据后,我们将writee关闭

运行结果:

3.数据读取

方法一:采用tf.train.slice_input_producer:

import tensorflow as tf
#定义两个list分别表达了图片的路径和label
images = ['image1.jpg', 'image2.jpg', 'image3.jpg', 'image4.jpg']
labels = [1, 2, 3, 4]
[images, labels] = tf.train.slice_input_producer([images, labels],num_epochs=None,shuffle=True)
#对输入的图片list按照相应的规则生成相应的张量,输出两个张量,num_pochs表示将所有样本循环训练的次数
with tf.Session() as sess:#通过session来执行当前从文件队列中获取tensor的流程sess.run(tf.local_variables_initializer())#对局部变量进行初始化tf.train.start_queue_runners(sess=sess)#构造文件队列填充的线程for i in range(10):print(sess.run([images, labels]))#从文件队列中获取数据

结果:

方法二:tf.train.string_input_producer从文件中读取数据

3个文件分别为(文件名和label):

import tensorflow as tf
filename = ['data/A.csv', 'data/B.csv', 'data/C.csv']
file_queue = tf.train.string_input_producer(filename,shuffle=True,num_epochs=2)#参数为文件路径的list,输出是文件队列
reader = tf.WholeFileReader()#定义文件的读取器
key, value = reader.read(file_queue)#获取到文件的数据
with tf.Session() as sess:sess.run(tf.local_variables_initializer())tf.train.start_queue_runners(sess=sess)for i in range(6):print(sess.run([key, value]))

结果:

方法三:对TFRecord打包过的数据进行解析

import tensorflow as tf
filelist = ['data/train.tfrecord']#定义一个list,就是想要读取的tfrecord文件的路径
file_queue = tf.train.string_input_producer(filelist,num_epochs=None,shuffle=True)
#对于文件类的读取同样采用tf.train.string_input_producer,输出文件队列
reader = tf.TFRecordReader()#定义读取器
_, ex = reader.read(file_queue)#读取文件
feature = {'image':tf.FixedLenFeature([], tf.string),#将bytes解码为string'label':tf.FixedLenFeature([], tf.int64)
}#对序列化之后的数据进行解码
batchsize = 2
batch  = tf.train.shuffle_batch([ex], batchsize, capacity=batchsize*10,min_after_dequeue=batchsize*5)
#通过shuffle_batch构造一个batchsize的数据
example = tf.parse_example(batch, features=feature)#对这个batch进行解码
image = example['image']
label = example['label']
image = tf.decode_raw(image, tf.uint8)#将string解码为uint8
image = tf.reshape(image, [-1, 32, 32, 3])
with tf.Session() as sess:sess.run(tf.local_variables_initializer())tf.train.start_queue_runners(sess=sess)for i in range(1):image_bth, _ = sess.run([image,label])import cv2cv2.imshow("image", image_bth[0,...])#对第一张图片进行可视化cv2.waitKey(0)#等待

结果:

(三)TensorFlow中的高层接口(slim)

.slim layers

.slim.arg_scope(list_ops_or_scope,**kwargs)#第一个是操作列表,第二个是这些操作共同用的参数

.在使用slim.batch_norm()函数时,我们需要定义以下两个参数

1.normalizer_fn=slim.batch_norm

2.normalizer_params=batch_norm_params:'is_training'(训练时设置为true),‘updates_collections':tf.GraphKeys.UPDATE OPS对batch_norm层进行标识

batch_norm层参数需另外更新,方法有两种:

.slim.data

有很多对数据的操作方法,在slim.__init__中有如下几种:

.slim evaluation

其中包含用于使用metric_ops.py模块中的指标编写模型评估脚本的帮助函数:

1.evaluation_loop(多次评估)

2.evaluation_once(一次评估)

.slim learning

学习率:(开始大,结尾小)

优化器:

.slim losses

.slim nets(已经定义好的网络结构)

.slim variables

.slim metrics

1.value_op是一个幂等操作,返回度量的当前值

2.update_op是执行上述聚合步骤以及返回度量值的操作

(四)TensorFlow实现数据增强

数据增强是防止模型过拟合的手段

1.tf.image库进行数据增强(颜色扰动,裁剪/Pad,噪声/模糊,翻转/旋转,Draw Boxes,标准化)

2.其他数据增强的方法:

扩大样本,增加图像的扰动性以及模型的鲁棒性

3.TensorFlow常见数据增强方法:

(五)Tensorboard调试技巧

1.Tensorboard可以进行网络可视化/训练中间结果可视化

pip3 install tensorboard

tensorboard --logdir logs

在浏览器中输入localhost:6060

配合tf.summary的使用:

记录可视化的值,将这些值添加到log中,比如sess.graph,bias,loss,image然后通过sess.run将合并后的中间结果存放到log中,我们在存放的时候是按照step(一个计数器,从0开始),最后tensorboard会将我们存好的log按照step进行绘制。

一些结果图:

下一期:TensorFlow挑战Cifar-10图像分类任务

计算机视觉之人脸学习(五)相关推荐

  1. 【转】 计算机视觉、图像处理学习资料汇总

    计算机视觉.图像处理学习资料汇总 分类: 数字图像处理2012-07-19 09:24 2629人阅读 评论(1) 收藏 举报 图像处理processingimage微软compressionreso ...

  2. 笔记:计算机视觉与深度学习-北邮-鲁鹏-2020年录屏-第一讲

    笔记:计算机视觉与深度学习-北邮-鲁鹏-2020年录屏 写在开头(重复的) 1.课程来源:B站视频. 2.笔记目的:个人学习+增强记忆+方便回顾 3.时间:2021年4月8日 4.同类笔记链接:(钩子 ...

  3. 中科院陈智能:计算机视觉经典——深度学习与目标检测

    不到现场,照样看最干货的学术报告! 嗨,大家好.这里是学术报告专栏,读芯术小编不定期挑选并亲自跑会,为大家奉献科技领域最优秀的学术报告,为同学们记录报告干货,并想方设法搞到一手的PPT和现场视频--足 ...

  4. 如何使用计算机视觉进行人脸识别和测试?

    人脸识别和检测是计算机视觉领域中的一个重要研究方向.以下是一个简单的流程,用于使用计算机视觉进行人脸识别和. 如何使用计算机视觉进行人脸识别和测试? 收集和准备数据集:从网络.摄像头或其他来源收集包含 ...

  5. 面向计算机视觉的深度学习:1~5

    原文:Deep Learning for Computer Vision 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自[ApacheCN 深度学习 译文集],采用译后编辑(MTPE)流程 ...

  6. 全球30篇最热门的计算机视觉和深度学习论文

    全球30篇最热门的计算机视觉和深度学习论文 2016-06-23分类:机器学习评论(0) 大数据交流QQ群,汇聚2万大数据爱好者.加入,开启你的数据江湖!! 这是一份被国外专家引用最多的计算机视觉和深 ...

  7. 计算机视觉算法——Transformer学习笔记

    算机视觉算法--Transformer学习笔记 计算机视觉算法--Transformer学习笔记 1. Vision Transformer 1.1 网络结构 1.2 关键知识点 1.2.1 Self ...

  8. PyTorch框架学习五——图像预处理transforms(一)

    PyTorch框架学习五--图像预处理transforms(一) 一.transforms运行机制 二.transforms的具体方法 1.裁剪 (1)随机裁剪:transforms.RandomCr ...

  9. 基于二哈实现多人人脸学习和识别

    一.实验目的及要求 [一]实现人脸识别. [二]实现云数据库应用. 二.实验原理与内容 基于二哈实现多人人脸学习和识别. 基于TinywebDB实现云数据库应. 基于EasyIoT实现mqtt数据上传 ...

最新文章

  1. js /jquery停止事件冒泡和阻止浏览器默认事件
  2. Java线程安全Lock、ReentrantLock、ReentrantReadWriteLock
  3. 2021HDU多校9 - 7073 Integers Have Friends 2.0(随机数)
  4. java自定义注解实现前后台参数校验
  5. mysql 表丢失_Mysql数据库备份 部分数据表丢失 Mysql table doesn't exist 解决
  6. java blockqueue_[Java基础] Java多线程-工具篇-BlockingQueue
  7. C++ 二叉搜索树的实现
  8. Word批量转PDF 无水印
  9. 微信小程序前端推送消息通知 -- 需要获取用户订阅权限
  10. 虚拟机centos7无法正常启动
  11. 内存测试(ubuntu)
  12. 揭秘金庸笔下的假面江湖
  13. sequence和sequencer — UVM
  14. uniapp之地址定位选择,根据字母排序
  15. aws php环境,AWS/CENTOS搭建LAMP环境
  16. css overflow属性及使用方法(场景)
  17. 企业为什么要大力推进OA办公?
  18. 浅谈下二级域名做网站优化的利与弊!
  19. 汇丰银行面试--软件测试面试题
  20. 有交互项的多元线性回归

热门文章

  1. 中国互联网用户自主意识的觉醒
  2. mg动画制作方法详解,你想要的都在这里了 | 万彩动画大师
  3. Java进阶学习-9 细胞自动机
  4. cs231n Assignment 1# two layer net详细答案及总结
  5. InstallShield安装包卸载-完美卸载
  6. typora---beta版本
  7. 有没有一键生成漫画风格人物漫画插件
  8. 用python实现汉字叠加
  9. 【论文笔记】Efficient and Realtime Distracted Driver Detection With MobileVGG Network
  10. 王一恒《跨部门沟通与协作》讲座学习笔记(图文)