北京看白癜风上那个医院 https://disease.39.net/yldt/bjzkbdfyy/介绍了Caffe,这篇将介绍TensorFlow。
1什么是TensorFlow
TensorFlow是Googlebrain推出的开源机器学习库,与Caffe一样,主要用作深度学习相关的任务。与Caffe相比TensorFlow的安装简单很多,一条pip命令就可以解决,新手也不会误入各种坑。
TensorFlow=Tensor+Flow
Tensor就是张量,代表N维数组,与Caffe中的blob是类似的;Flow即流,代表基于数据流图的计算。神经网络的运算过程,就是数据从一层流动到下一层,在Caffe的每一个中间layer参数中,都有bottom和top,这就是一个分析和处理的过程。TensorFlow更直接强调了这个过程。
TensorFlow最大的特点是计算图,即先定义好图,然后进行运算,所以所有的TensorFlow代码,都包含两部分:
(1)创建计算图,表示计算的数据流。它做了什么呢?实际上就是定义好了一些操作,你可以将它看做是Caffe中的prototxt的定义过程。
(2)运行会话,执行图中的运算,可以看作是Caffe中的训练过程。只是TensorFlow的会话比Caffe灵活很多,由于是Python接口,取中间结果分析,Debug等方便很多。
2TensorFlow训练
咱们这是实战速成,没有这么多时间去把所有事情细节都说清楚,而是抓住主要脉络。有了TensorFlow这个工具后,我们接下来的任务就是开始训练模型。训练模型,包括数据准备、模型定义、结果保存与分析。
2.1数据准备
上一节我们说过Caffe中的数据准备,只需要准备一个list文件,其中每一行存储image、labelid就可以了,那是Caffe默认的分类网络的imagedata层的输入格式。如果想定义自己的输入格式,可以去新建自定义的DataLayer,而Caffe官方的datalayer和imagedatalayer都非常稳定,几乎没有变过,这是我更欣赏Caffe的一个原因。因为输入数据,简单即可。相比之下,TensorFlow中的数据输入接口就要复杂很多,更新也非常快,我知乎有一篇文章,说过从《从Caffe到TensorFlow1,IO操作》,有兴趣的读者可以了解一下。
这里我们不再说TensorFlow中有多少种数据IO方法,先确定好我们的数据格式,那就是跟Caffe一样,准备好一个list,它的格式一样是image、labelid,然后再看如何将数据读入TensorFlow进行训练。
我们定义一个类,叫imagedata,模仿Caffe中的使用方式。代码如下,源代码可移步Git。
importtensorflowastffromtensorflow.contrib.dataimportDatasetfromtensorflow.python.frameworkimportdtypesfromtensorflow.python.framework.opsimportconvert_to_tensorimportnumpyasnpclassImageData
efread_txt_file(self):self.img_paths=[]self.labels=[]forlineinopen(self.txt_file,r):items=line.split()self.img_paths.append(items[0])self.labels.append(int(items[1]))def__init__(self,txt_file,batch_size,num_classes,image_size,buffer_scale=):self.image_size=image_sizeself.batch_size=batch_sizeself.txt_file=txt_file##txtlistfile,storedas:imagenameidself.num_classes=num_classesbuffer_size=batch_size*buffer_scale#读取图片self.read_txt_file()self.dataset_size=len(self.labels)printnumoftraindatas=,self.dataset_size#转换成Tensorself.img_paths=convert_to_tensor(self.img_paths,dtype=dtypes.string)self.labels=convert_to_tensor(self.labels,dtype=dtypes.int32)#创建数据集data=Dataset.from_tensor_slices((self.img_paths,self.labels))printdatatype=,type(data)data=data.map(self.parse_function)data=data.repeat(0)data=data.shuffle(buffer_size=buffer_size)#设置selfdataBatchself.data=data.batch(batch_size)printself.datatype=,type(self.data)defaugment_dataset(self,image,size)
istorted_image=tf.image.random_brightness(image,max_delta=63)distorted_image=tf.image.random_contrast(distorted_image,lower=0.2,upper=1.8)#Subtractoffthemeananddividebythevarianceofthepixels.float_image=tf.image.per_image_standardization(distorted_image)returnfloat_imagedefparse_function(self,filename,label):label_=tf.one_hot(label,self.num_classes)img=tf.read_file(filename)img=tf.image.decode_jpeg(img,channels=3)img=tf.image.convert_image_dtype(img,dtype=tf.float32)img=tf.random_crop(img,[self.image_size[0],self.image_size[1],3])img=tf.image.random_flip_left_right(img)img=self.augment_dataset(img,self.image_size)returnimg,label_
下面来分析上面的代码,类是ImageData,它包含几个函数,__init__构造函数,read_txt_file数据读取函数,parse_function数据预处理函数,augment_dataset数据增强函数。
我们直接看构造函数吧,分为几个步骤:
(1)读取变量,文本list文件txt_file,批处理大小batch_size,类别数num_classes,要处理成的图片大小image_size,一个内存变量buffer_scale=。
(2)在获取完这些值之后,就到了read_txt_file函数。代码很简单,就是利用self.img_paths和self.labels存储输入txt中的文件列表和对应的label,这一点和Caffe很像了。
(3)然后,就是分别将img_paths和labels转换为Tensor,函数是convert_to_tensor,这是Tensor内部的数据结构。
(4)创建dataset,Dataset.from_tensor_slices,这一步,是为了将img和label合并到一个数据格式,此后我们将利用它的接口,来循环读取数据做训练。当然,创建好dataset之后,我们需要给它赋值才能真正的有数据。data.map就是数据的预处理,包括读取图片、转换格式、随机旋转等操作,可以在这里做。
data=data.repeat(0)是将数据复制0份,这可以满足我们训练0个epochs。data=data.shuffle(buffer_size=buffer_size)就是数据shuffle了,buffer_size就是在做shuffle操作时的控制变量,内存越大,就可以用越大的值。
(5)给selft.data赋值,我们每次训练的时候,是取一个batchsize的数据,所以self.data=data.batch(batch_size),就是从上面创建的dataset中,一次取一个batch的数据。
到此,数据接口就定义完毕了,接下来在训练代码中看如何使用迭代器进行数据读取就可以了。
关于更多TensorFlow的数据读取方法,请移步知乎专栏和