机器学习-Tensorflow之Tensor和Dataset学习
HappyPuppy 人气:0好了,咱们今天终于进入了现阶段机器学习领域内最流行的一个框架啦——TensorFlow。对的,这款由谷歌开发的机器学习框架非常的简单易用并且得到了几乎所有主流的认可,谷歌为了推广它的这个框架甚至单独开辟了免费学习这个框架的视频教程,可惜这些教程都是基于TensorFlow1.0版本的,一直没有更新。现在都是TensorFlow2.0版本了,其中的开发的API的变化非常非常大,很多都是不兼容的,非常坑,如果大家还是觉得要跳坑,我不拦着哈。它的应用的官方视频教程的地址是https:/https://img.qb5200.com/download-x/developers.google.com/machine-learning/crash-course/ml-intro ,虽然这个视频的覆盖面比较广,但是它也有几个最大的缺点:1,就像上面指出来的,它的教程是基于1.0版本的,如果你把它放到最新的TensorFlow中去运行,你会发现一大堆的错误;2,它的视频的内容深度很浅很浅,基本就是随便讲几个API;所以综上所述,大家可以参考参考它的视频,但是一定不要钻牛角尖,否则你会发现很痛苦的。好了,那么咱们就来进入到咱们今天的主题,那就是TensorFlow中的Tensor和dataset对象。正所谓基础不牢,地动山摇,而tensor和dataset就是TensorFlow中的基础中的基础。大家都知道TensorFlow的主要任务就是处理数据的,而TensorFlow中的数据基本格式就是tensor和dataset,所以咱们肯定得要重视起来。这节内容呢,咱们先讲一讲TensorFlow操作对象的数据格式,以及TensorFlow中基本的数据对象。
- Tensor
Tensor其实翻译过来就是张量的意思,这里我不解释什么是张量,咱们就把它看成一个对象object,然后这个object里面有存储数据和其他一些属性,例如shape,dtype等等。为了更加形象的展示一下在TensorFlow中tensor到底长什么样子,咱们来看一个小例子如下
<tf.Tensor: id=835, shape=(2,), dtype=int32, numpy=array([4, 6])>
从上面咱们可以看出,Tensor对象有一个id属性;一个shape属性,它是个tuple;一个dtype属性;咱们的核心也是重点是在他的numpy属性,这里也可以看出它是一个ndarray类型的数据。它的形式就是这么的简单,虽然简单,但是大家一定要理解它的意思以及本质,不要跟其他的数据类型搞混了,例如numpy中的array,Python中的list, 他们虽然长得很像,很多情况下也相互兼容,但是他们实质上是属于不同的数据类型。那么既然咱们已经知道了tensor长什么样子,也知道tensor中的内容含义,那么咱们如何创建一个tensor呢?其实任何一种Python或者numpy中的data,只要是通过TensorFlow中的运算符来计算过,那么就自动转成并且返回tensor类型了,对的,你没有听错,TensorFlow中也有他自己的加减乘除等运算的api,咱们看看下面几个简单的例子
tf.add(1,2) tf.add([1,2],[3,4]) tf.square(5) tensor = tf.constant([1,2,3,4,5])
上面的返回结果分别是
<tf.Tensor: id=859, shape=(), dtype=int32, numpy=3> <tf.Tensor: id=862, shape=(2,), dtype=int32, numpy=array([4, 6])> <tf.Tensor: id=864, shape=(), dtype=int32, numpy=25> <tf.Tensor: id=865, shape=(5,), dtype=int32, numpy=array([1, 2, 3, 4, 5])>
根据前面对于tensor结构的分析,结合上面的例子,咱们就能更加深入的理解tensor这个数据对象了;那么这里问题又来了,如果咱们有Python的数据或者numpy的数据,我们如何能将他们转化成tensor,甚至于他们能够相互转化呢???这是一个经常遇到的需求,咱们当然有办法啦,看下面的代码
"2. converting between Tensor and numpy array" ndarray = np.ones([3,3]) #2.1 from numpy array to tensor (through tensorflow operations) tensor = tf.multiply(ndarray,1) #2.2 from tensor to numpy array (through explicitly numpy()) tensor_to_numpy = tensor.numpy()
哈哈,是不是超级简单,从numpy转成tensor,只需要TensorFlow乘以1就OK啦,相反地,从tensor转成numpy只需要调用tensor的函数numpy()就行了。是不是so easy. TensorFlow都为咱们想好了。
补充:这里稍微补充一个小知识点,那就是GPU和CPU。在TensorFlow的应用中,或者说机器学习领域,一般都是大数据的处理,一般情况下,GPU对于数据的处理量和处理速度都大于CPU(因为CPU里面有很多非常复杂的逻辑单元和中断系统等等),所以咱们一般都会将Tensor或者Dataset存储在GPU中进行运算。那么问题来了,咱们怎么获取我们机器的这些硬件信息呢?咱们如何把tensor存储到制定的硬件里面去呢??
print(tf.config.experimental.list_physical_devices())#show the available devices
上面的代码可以打印出咱们机器里面可用的CPU和GPU, 结果如下
[PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU'), PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
可以看出咱们的机器有一个CPU和一个GPU,分别是CPU:0和GPU:0; 有了这个之后,咱们就可以让咱们的数据存储并且运算在指定的硬件上面,咱们可以用下面的方式来指定
#force execuion on CPU
with tf.device("CPU:0"): x = tf.random.uniform([1000,1000]) #assert x.device.endswith("CPU:0") time_matmul(x) #force execution on GPU print("On GPU") with tf.device("GPU:0"): x=tf.random.uniform([1000,1000]) #assert x.device.endswith("GPU:0") time_matmul(x)
从上面咱们可以看出,咱们可以用with这个关键字来指定咱们的tensor存储在哪里。上面代码的第一部分是指定到CPU,第二部分是指定到GPU。
- Dataset
Dataset顾名思义就是数据集的意思,虽然他的定义比较抽象,但是其实大家可以把它想象成一个装Tensor的容器,一个dataset可能只来自于一个tensor,也可以是多个Tensor。但是这里的一个小细节需要注意,那就是当一个dataset来自于多个Tensor的时候,那么这些tensors的第一个dimension必须要是相同的,否则会产生incompatible errors错误哦。大家需要主要澳。那么咱们先来看看如何创建一个Dataset呢??
tensor1 = tf.multiply([1,2,3,4,5],1) dataset1 = tf.data.Dataset.from_tensor_slices(tensor1)
咱们从上面可以看出来,第一句代码是创建一个tensor对象,第二句就是创建dataset的过程,咱们最常用的创建dataset的API就是from_tensor_slicers这个方法,它后面的参数可以是一个tensor也可以是多个tensors. 那么上面是一个最简单的dataset,接下来咱们看一个堪忧2个tensor的dataset:
c1 = tf.random.uniform([4]) c2= tf.random.uniform([4,10]) dataset2 = tf.data.Dataset.from_tensor_slices(( c1,c2 ))
咱们可以看出来,上面的代码也是先创建2个tensor,分别是C1, C2。同样的咱们通过from_tensor_slices这个方法创建dataset对象,但是咱们可以看出它里面的参数是一个tuple,这个tuple里面的元素就是2个tensors。注意:这里2个tensor的第一维(first dimension)是一样的,记住这个必须一样,否则必报错哈。既然咱们已经创建了dataset,那么咱们如何获取里面的值呢???在以前的TensorFlow版本都是通过创建iterator的方式来获取dataset里面的element,那么在最新的版本中,这个方法已经被deprecate了,取而代之的是用for-in是方式遍历了,如下所示,咱们去这个dataset2的第一条数据来演示
for element in dataset2: print(element) break
咱们看看dataset2的第一条数据长成啥样哈?
(<tf.Tensor: id=67, shape=(), dtype=float32, numpy=0.8284787>, <tf.Tensor: id=68, shape=(10,), dtype=float32, numpy= array([0.46768987, 0.4085338 , 0.06623507, 0.16808486, 0.7843472 , 0.6430875 , 0.94050014, 0.79995286, 0.35672653, 0.97420156], dtype=float32)>)
仔细分析一下,它是一个tuple,这个tuple里面装有两个tensor对象。咱们这下应该全明白了tensor和dataset是啥了以及他们之间的关系了吧。
- 总结
那么咱们现在来总结一下哈,本节主要介绍了TensorFlow中基本的数据格式,分别是tensor和dataset。上面分别讲述了tensor和dataset的结构,创建过程,内容获取等方面的知识到。虽然TensorFlow是兼容咱们的numpy数据类型,但是有些情况下还是会有一些问题,所以咱们在后面学习TensorFlow应用的过程中尽量还是将数据转化成tensor,即使tensor也是基于numpy的。这节的重点是看懂tensor对象的内部参数的意思,以及dataset的结构。这是整个TensorFlow的根基,毕竟TensorFlow就是处理数据的,如果咱们连数据的结构形式都不懂,实在是说不过去嘛。
加载全部内容