好了, 咱们今天终于进入了现阶段机器学习领域内最流行的一个框架啦 --TensorFlow. 对的, 这款由谷歌开发的机器学习框架非常的简单易用并且得到了几乎所有主流的认可, 谷歌为了推广它的这个框架甚至单独开辟了免费学习这个框架的视频教程, 可惜这些教程都是基于 TensorFlow1.0 版本的, 一直没有更新. 现在都是 TensorFlow2.0 版本了, 其中的开发的 API 的变化非常非常大, 很多都是不兼容的, 非常坑, 如果大家还是觉得要跳坑, 我不拦着哈. 它的应用的官方视频教程的地址是 , 虽然这个视频的覆盖面比较广, 但是它也有几个最大的缺点: 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 就是处理数据的, 如果咱们连数据的结构形式都不懂, 实在是说不过去嘛.
来源: https://www.cnblogs.com/tangxiaobo199181/p/12238432.html