003TensorFlow基础

核心内容

  • TensorFlow中的基本概念介绍
  • TensorFlow中的核心API
  • TensorFlow中的高层接口slim
  • TensorFlow的调试技巧
  • TensorFlow实现数据增强
  • TensorFlow挑战Cifar-10图像分类任务
TensorFlow

Google开源的基于数据流图的科学计算库,适用于机器学习、深度学习等人工智能领域

开源库:https://github.com/tensorflow
相关模型:https://github.com/tensorflow/models

Tensor+Flow=TensorFlow

张量+数据流=TensorFlow

数据是按一定方向流动的,需要一定的计算

Graph
  • 图描述了计算的过程,可以通过tensorflow图形化流程结构

    • graph是在前端进行的,可用tensorflow来进行可视化
    • 声明(单个/多个图)
    • 保存为pb文件
    • 从pb中恢复Graph
    • Tensorboard可视化
      在这里插入图片描述

input_a,input_b为数据的输入,add_e,maltiply_c为数据的加,乘运算,箭头表示数据的流向

计算图则为网络,网络的参数通过后续的学习得到

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import tensorflow as tf
a=tf.constant(1,name='input_a') #张量(常量)
b=tf.constant(2,name='input_b')#张量
c=tf.multiply(a,b,name='multiply_c')#乘运算
d=tf.add(a,b,name='add_d')#加运算
e=tf.add(d,c,name='add_e')
sess=tf.Session()#会话
sess.run(e)
writer=tf.summary.FileWriter('graph',sess.graph)
Session
  • 图必须在称之为“会话”的上下文中进行
  • 会话将图的op分发到诸如CPU或者GPU之类的设备上执行

session完成了前端和后端的沟通,起到了桥梁的作用
常见操作:

  • session的创建和关闭
  • session 的注入机制
  • 利用session指定不同的设备
  • 通过session完成资源分配
创建和关闭会话
import tensorflow as tf
sess=tf.Session()#使用最多,和使用with创建等价

sess=tf.InteractiveSession()#交互式Session,主要用在交互性要求较高的脚本中

with tf.Session() as Sess:
    ...
    
sess.close()#session关闭
注入机制

是Session具体完成计算图运算的过程,前端和后端的桥梁,注入数据

sess.run(...)#run 中指定需要计算的节点
sess.run(tf.global_variables_initializer())#tf.global_variables_initializer():获取当前计算图全部变量

a=tf.placeholder(dtype=tf.float32)#定义a和b,是占位符,实际取值是计算时再赋值即feed操作
b=tf.placeholder(dtype=tf.float32)
add=a+b
add_val=sess.run(add,feed_dict={a:1,b:2})#a赋值为1,b赋值为2,最终得到value为3=a+b
指定资源设备
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}))
资源分配-控制GPU资源使用率
config=tf.ConfigProto()
config.gpu_options.allow_growth=True#定义gpu参数
session=tf.Session(config=config,...)#利用config进行session的初始化
Tensor

在TensorFlow中,所有在节点之间传递的数据都为Tensor对象

将tensor表示为N维数组,图像:(batch * height * width * channel ):NHWC

Tensor 的定义:

tf.constant()#常量
tf.Variable()#变量
tf.placeholder()#占位符
tf.SparseTensor()#稀疏张量

具体定义:

#常量定义要给定具体的取值,value[1,2]以及当前常量的形状shape(1,2)
#数据类型dtype,可缺省,也可定义
#指定常量的name
#指定常量是否可以改变:verify_shape
cons=tf.constant(value=[1,2],dtype=tf.float32,shape=(1,2),name='testconst',verify_shape=False)

#占位
X=tf.placeholder(dtype=tf.float32,shape=[144,10],name='X')

X=tf.placeholder(dtype=float32,shape=[None,None],name='X')


#变量定义时不需要指定value,但需要shape,以及数据类型dtype和name
#变量即其值可以根据训练过程进行改变
W=tf.Variable(tf.zeros([3,10]),dtype=tf.float64,name='W')
Operation

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

Feed

通过feed为计算图注入值:
注入值通常就是占位符

a=tf.placeholder(tf.float32)
b=tf.placeholder(tf.float32)
c=tf.add(a,b)
with tf.Session() as sess:
    result=sess.run(c,feed_dict={a:3,b:4})#这里的c值就是Fecth
    print(result)
Fetch

使用Fetch获取计算结果

tf.Session.run(fetches,feed_dict=None)
#fetches可以是单独的参数,也可以是list

范例:

import tensorflow as tf
x=tf.placeholder(tf.float32,shape=(1,2))
w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2=tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))

a=tf.matmul(x,w1)#矩阵相乘
y=tf.matmul(a,w2)

with tf.Session() as sess:

	#变量运行前必须进行初始化操作
    init_op=tf.global_variables_initializer()
    sess.run(init_op)
    print(sess.run(y,feed_dict={x:[[0.7,0.5]]}))#对x赋值,计算y

结果:[[3.0904665]]

Tensorflow中核心API
基本运算
tf.expand_dims(input,dim,name=None)
tf.split(split_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的张量值

搭建网络时常用tf.nn库

tf.nn.conv2d:卷积层
tf.nn.max_pool:池化层
tf.nn.abg_pool:池化层
tf.nn.relu:激活层
tf.nn.dropout:
tf.nn.l2_normalize:归一化层
tf.nn.batch_nomalization:BN层
tf.nn.l2_loss:损失层
tf.nn.softmax_cross_entropy_with_logits:交叉熵损失层

tf.train库:定义了和优化相关的函数
在这里插入图片描述

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

相应的接口函数:

  • 数据读取:tf.train.string_input_producer
  • 数据解析:tf.TFRecordReader,tf.parse_single_example
  • 数据写入:tf.python_io.TFRecordWriter

数据写入相关API方法:

writer=tf.python_io.TFRecordWriter()

example=tf.train.Example()//在tf.train.Example()中存取具体的数据,可以定义一个feature,如图像的宽和高

example=tf.train.Example()//在tf.train.Example()中存取具体的数据,可以定义一个feature,如图像的宽和高

writer.close()

example=tf.train.Example(features=tf.train.Features(feature={
#定义标签和图片,相应的数据类型
    'label':tf.train.Feature(int64_list=tf.train.Feature(value=[index])),
    'img_raw':tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
}))
范例:读取cifar10数据

在cifar-10-batches-py中,已经是二进制文件,可以用python语言解析,也可以自行下载cifar数据进行解析后变成二进制文件。
官网数据下载:http://www.cs.toronto.edu/~kriz/cifar.html

其中data_batch为训练集,test_batch为测试集。

import urllib
import os
import sys
import tarfile
import glob
import pickle
import numpy as np
import cv2


classification=['airplane',
                'automobile',
                'bird',
                'cat',
                'deer',
                'dog',
                'frog',
                'horse',
                'ship',
                'truck']

#解析函数
def unpickle(file):
    import pickle
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='bytes')
    return dict

folders = '/Users/apple/Downloads/11人脸识别/projects/One/data/cifar-10-batches-py'

trfiles = glob.glob(folders + "/data_batch*")#获取所有文件,训练文件

data = []
labels = []

for file in trfiles:
    dict = unpickle(file) #解码之后的数据,以字典的格式
    data += list(dict[b"data"])
    labels += list(dict[b"labels"])


print(labels)

#图片解析,图片存储

imgs = np.reshape(data,[-1,3,32,32]) #将数据reshape为3 x 32 x 32 ,-1表示为当前有多少图片

for i in range(imgs.shape[0]):
    im_data = imgs[i,...]
    im_data = np.transpose(im_data,[1,2,0])
    im_data = cv2.cvtColor(im_data,cv2.COLOR_RGB2BGR)#数据,转换模式rgb,获取到适用opencv的数据

    f="{}/{}".format("data/image/train",classification[labels[i]])#拼接地址,并根据标签找到图片

    if not os.path.exists(f):#如果路径不存在
        os.mkdir(f)

    cv2.imwrite("{}/{}.jpg".format(f,str(i)),im_data)

结果:在项目train文件夹下多了十个文件夹,是cifar10数据集里的图片

TFRecord数据打包

使用tensorflow实现TFRecord图像数据打包,打包成二进制格式讲这些数据用于后续模型的训练

获得所有图片路径及其种类:

import glob

classification=['airplane',
                'automobile',
                'bird',
                'cat',
                'deer',
                'dog',
                'frog',
                'horse',
                'ship',
                'truck']

#按照图片类别进行打包
index = 0 #种类索引
im_data = [] #存储图片路径
im_lables = [] #存储图片种类标签

for path in classification: #遍历种类
    path = "/Users/apple/Downloads/11人脸识别/projects/face/data/image/train/" + path
    im_list = glob.glob(path + "/*") #获取图片list
    im_label = [index for i in range(im_list.__len__())] #获取图片的label,label就是classification对应的值,需要遍历索引号
    index +=1
    im_data += im_list #将每个种类下对应的图片路径存放在一起
    im_lables +=im_label

print(im_lables)
print(im_data)

封装图片数据:

#存储获取到的图片数据

tfrecord_file = "/Users/apple/Downloads/11人脸识别/projects/face/data/image/train.tfrecord"
writer = tf.python_io.TFRecordWriter(tfrecord_file)#传入文件路径

#要将获取到的文件资源写入tfrecord

#获取数据列表
for i in range(im_data.__len__()):
    im_d = im_data[i]#获取数据
    im_l = im_lables[i]#获取label
    #利用opencv函数对图像进行读取
    data = cv2.imread(im_d)#传入文件路径

    #将数据封装到example中
    ex = tf.train.Example(
        features = tf.train.Features(
            feature = {
                #图像数据采用byte格式存储
                "image":tf.train.Feature(
                    bytes_list=tf.train.BytesList(
                        value=[data.tobytes()])), #value:图片数据转成bytes
                "label":tf.train.Feature(
                    int64_list=tf.train.Int64List(
                        value=[im_l]))
            }
        )
    )

    writer.write(ex.SerializeToString())

writer.close()

在对图片数据进行打包时,要注意图片大小是否一致,cifar10中大小都为32x32x3,
图片大小不一致需对宽高进行定义:

 #定义图片大小
                "height": tf.train.Feature(
                    int64_list=tf.train.Int64List(
                        value=[data.shape[0]])),
                "width": tf.train.Feature(
                    int64_list=tf.train.Int64List(
                        value=[data.shape[1]]))                         

打包时可将数据打乱:

index = [i for i in range(im_data.__len__())]
np.random.shuffle(index)
#打包时可以将图片数据打乱
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_lables[index[i]]#获取label
    #利用opencv函数对图像进行读取
    data = cv2.imread(im_d)#传入文件路径

    #将数据封装到example中
    ex = tf.train.Example(
        features = tf.train.Features(
            feature = {
                #图像数据采用byte格式存储
                "image":tf.train.Feature(
                    bytes_list=tf.train.BytesList(
                        value=[data.tobytes()])), #value:图片数据转成bytes
                "label":tf.train.Feature(
                    int64_list=tf.train.Int64List(
                        value=[im_l]))
            }
        )
    )

    writer.write(ex.SerializeToString())

writer.close()

读取文件有两种方式:
opencv和tensorflow

data = cv2.imread(im_d)#传入文件路径
data = tf.gfile.FastGFile(im_d,"rb").read()#得到的文件更小,会进行编码,使用时要进行解码
利用tensorflow对图片数据进行读取
利用tf.train.slice_input_producer进行读取
#利用tensorflow对图片数据进行读取

import tensorflow as tf

images = ['image1.jpg','image2.jpg','image3.jpg','image4.jpg']
labels = [1,2,3,4]

#利用tf.train.slice_input_producer进行读取,传入参数为路径和标签

[images,labels] = tf.train.slice_input_producer([images,labels],num_epochs=None,shuffle=True)
#一个epoch表示将所有样本进行一轮循环,None 表示不规定多少个epoch,只要想从文件序列读取数据就有数据
#shuffle:对文件数据打乱


with tf.Session() as sess:
    sess.run(tf.local_variables_initializer())#初始化文件
    #文件队列填充的线程,启动后则填充
    tf.train.start_queue_runners(sess=sess)

    #从文件对列中获取数据
    #文件队列中只要八个数据,如果大于八则报错,epoch=2轮*4,如果想要更多数据则epoch=None
    for i in range(10):
        print(sess.run([images,labels]))

#结果:
"""[b'image1.jpg', 1]
[b'image3.jpg', 3]
[b'image2.jpg', 2]
[b'image4.jpg', 4]
[b'image1.jpg', 1]
[b'image4.jpg', 4]
[b'image3.jpg', 3]
[b'image2.jpg', 2]
[b'image3.jpg', 3]
[b'image1.jpg', 1]"""
利用tf.train.string_input_producer进行读取

import tensorflow as tf
#利用tf读取文件

filename = ['/Users/apple/Downloads/11人脸识别/projects/face/data/A.csv',
'/Users/apple/Downloads/11人脸识别/projects/face/data/B.csv',
'/Users/apple/Downloads/11人脸识别/projects/face/data/C.csv']

file_queue = tf.train.string_input_producer(filename,shuffle=True,num_epochs=2)#传入路径

reader = tf.WholeFileReader()#文件读取器

key, value = reader.read(file_queue) #获取键值对,key:图片名称,value图片内容

with tf.Session() as sess:
    sess.run(tf.local_variables_initializer())
    tf.train.start_queue_runners(sess=sess)#填充进程
    for i in range(6):#epoce=2,文件数为3
        print(sess.run([key,value]))


#结果:
"""[b'/Users/apple/Downloads/11\xe4\xba\xba\xe8\x84\xb8\xe8\xaf\x86\xe5\x88\xab/projects/face/data/A.csv', b'1.jpg,1\n2.jpg,2\n3.jpg,3\n']
[b'/Users/apple/Downloads/11\xe4\xba\xba\xe8\x84\xb8\xe8\xaf\x86\xe5\x88\xab/projects/face/data/C.csv', b'7.jpg,7\n8.jpg,8\n9.jpg,9\n']
[b'/Users/apple/Downloads/11\xe4\xba\xba\xe8\x84\xb8\xe8\xaf\x86\xe5\x88\xab/projects/face/data/B.csv', b'4.jpg,4\n5.jpg,5\n6.jpg,6\n']
[b'/Users/apple/Downloads/11\xe4\xba\xba\xe8\x84\xb8\xe8\xaf\x86\xe5\x88\xab/projects/face/data/B.csv', b'4.jpg,4\n5.jpg,5\n6.jpg,6\n']
[b'/Users/apple/Downloads/11\xe4\xba\xba\xe8\x84\xb8\xe8\xaf\x86\xe5\x88\xab/projects/face/data/C.csv', b'7.jpg,7\n8.jpg,8\n9.jpg,9\n']
[b'/Users/apple/Downloads/11\xe4\xba\xba\xe8\x84\xb8\xe8\xaf\x86\xe5\x88\xab/projects/face/data/A.csv', b'1.jpg,1\n2.jpg,2\n3.jpg,3\n']"""
利用TF对已经打包的数据进行解析

#对打包后的文件进行解析

import tensorflow as tf

filelist = ['/Users/apple/Downloads/11人脸识别/projects/face/data/image/train.tfrecord2']
file_queue = tf.train.string_input_producer(filelist, num_epochs=None,shuffle=True)

reader = tf.TFRecordReader()

_, ex = reader.read(file_queue)

#读取的数据是序列化后的数据

feature = {
    'image':tf.FixedLenFeature([],tf.string),
    'label':tf.FixedLenFeature([],tf.int64)
}
batchsize = 1
batch = tf.train.shuffle_batch([ex],batchsize,capacity=batchsize*10,min_after_dequeue=batchsize*5)

#解码
example = tf.parse_example(batch, features=feature)

image = example['image']
label = example['label']

image = tf.decode_raw(image,tf.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 cv2

        #可视化
        cv2.imshow("image", image_bth[0, ...])
        cv2.waitKey(0)
Tensorflow中的高层接口(待学)

搭建网络结构:TF-Slim, TFLearn, Keras, TensorLayer

Tensorflow实现数据增强(介绍)

使用tf.image库进行数据增强

  • 使用tf.image库进行数据增强
    • 颜色扰动(亮度、对比度、HSV、RGB等)
    • 裁剪/Pad
    • 噪声/模糊
    • 翻转/旋转(空间几何变换/放射变换)
    • Draw Boxes
    • 标准化
    • 其他数据增强方法
      • Mixup
      • Oversampling
      • 锐化/浮雕/灰度
      • 边界检测
      • 超像素
      • 255-V
        在这里插入图片描述

模型训练必须使用数据增强,充分利用大数据

TensorBoard使用

TensorBoard可以进行网络可视化/训练中间结果可视化

查看数据增强之后结果,数据分布,参数分布,各种图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值