使用 TensorFlow 加載 Numpy 數(shù)據(jù)
在科學(xué)計(jì)算之中,Numpy 是一種必不可少的工具,因此我們在機(jī)器學(xué)習(xí)的過程之中難免會遇到使用 Numpy 數(shù)據(jù)的情況,所以我們有必要學(xué)習(xí)如何在 TensorFlow 之中學(xué)習(xí)如何使用 Numpy 數(shù)據(jù)。
1. 什么是 Numpy
Numpy 是 Python 的一個(gè)擴(kuò)展庫。支持高階維度數(shù)組的復(fù)雜運(yùn)算以及矩陣的運(yùn)算。因此在進(jìn)行科學(xué)計(jì)算的時(shí)候使用 Numpy 進(jìn)行數(shù)據(jù)處理便會特別的方便。
在具體的使用過程之中,我們一般會遇到兩種情況:
- 在內(nèi)存中定義了 Numpy 數(shù)組,需要提供給 TesnorFlow 使用;
- 我們需要加載 Numpy 存放的文件的數(shù)據(jù),也就是需要從“.npz”文件之中讀取數(shù)據(jù)。
因此這節(jié)課之中我們就從兩個(gè)方面來說明如何使用 Numpy 數(shù)據(jù)。
2. 在內(nèi)存中使用 Numpy 數(shù)據(jù)
如果我們在內(nèi)存中定義了 Numpy 數(shù)據(jù),那么我們便可以通過 tf.convert_to_tensor() 函數(shù)來將 Numpy 數(shù)據(jù)轉(zhuǎn)化為 Tensor,從而提供給 TensorFlow 使用。比如以下示例:
import tensorflow as tf
import Numpy as np
x_np = np.zeros((5, 3))
x_tensor = tf.convert_to_tensor(x_np)
print(type(x_np), type(x_tensor))
print(x_tensor)
我們可以得到結(jié)果如下,說明該函數(shù)已經(jīng)成功的將 Numpy 數(shù)組轉(zhuǎn)化為了 Tensor 對象:
<class 'Numpy.ndarray'> <class 'tensorflow.python.framework.ops.EagerTensor'>
tf.Tensor(
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]], shape=(5, 3), dtype=float64)
那如果我們需要將 Tensor 轉(zhuǎn)化為 Numpy 呢?我們只需要使用 Tensor 對象中的 Numpy 函數(shù)即可將其轉(zhuǎn)化為 Numpy 。
比如我們接上面的例子:
......
print(type(x_np_new))
print(x_np_new)
我們可以得到輸出:
<class 'Numpy.ndarray'>
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
由此我們可以發(fā)現(xiàn),通過 Tensor 對象的 Numpy 方法可以將 Tensor 對象轉(zhuǎn)化為 Numpy 數(shù)組。
3. 從“.npz”文件之中讀取數(shù)據(jù)
當(dāng)我們要從 .npz 文件之中讀取并使用數(shù)據(jù)的時(shí)候,我們大概要經(jīng)過三個(gè)步驟:
- 打開 .npz 文件,并且其格式加載數(shù)據(jù),要注意,不同的 .npz 文件中的格式都是由人為定義的,因此只有了解了文件中的組織格式,才能加載數(shù)據(jù);
- 將加載的 .npz 數(shù)據(jù)轉(zhuǎn)化為 tf.data.Dataset ;
- 進(jìn)一步處理并使用該數(shù)據(jù)集合。
下面我們以一個(gè)簡單的手寫數(shù)字識別數(shù)據(jù)集(mnist)為例,來演示如何進(jìn)行數(shù)據(jù)的加載與使用。
3.1 打開文件并加載數(shù)據(jù)
這里用到的npz文件大家可以從谷歌倉庫中下載,大家可以通過該鏈接下載。
然后我們需要首先得到下載文件的本地地址,在這里我假設(shè)地址是’/root/.keras/datasets/mnist.npz’。
該數(shù)據(jù)集是由一個(gè)字典組成,這個(gè)字典由四個(gè)元素組成,他們的key分別是:
- x_train: 訓(xùn)練數(shù)據(jù)的圖片數(shù)據(jù);
- y_train: 訓(xùn)練數(shù)據(jù)的標(biāo)簽;
- x_test: 測試數(shù)據(jù)的圖片數(shù)據(jù);
- y_test: 測試數(shù)據(jù)的標(biāo)簽。
了解了數(shù)據(jù)的結(jié)構(gòu)后,我們便可以通過以下操作進(jìn)行數(shù)據(jù)的加載:
import Numpy as np
import tensorflow as tf
path = '/root/.keras/datasets/mnist.npz'
with np.load(path) as np_data:
train_exa = np_data['x_train']
train_labels = np_data['y_train']
test_exa = np_data['x_test']
test_labels = np_data['y_test']
這樣我們便完成了數(shù)據(jù)的加載。
3.2 構(gòu)建tf.data.Dataset數(shù)據(jù)集
和之前一樣,我們主要是通過 tf.data.Dataset.from_tensor_slices() 函數(shù)來構(gòu)建數(shù)據(jù)集。比如我們可以通過以下代碼實(shí)現(xiàn):
train_dataset = tf.data.Dataset.from_tensor_slices((train_exa, train_labels))
test_dataset = tf.data.Dataset.from_tensor_slices((test_exa, test_labels))
print(train_dataset, test_dataset)
我們可以得到如下輸出:
<TensorSliceDataset shapes: ((28, 28), ()), types: (tf.uint8, tf.uint8)>
<TensorSliceDataset shapes: ((28, 28), ()), types: (tf.uint8, tf.uint8)>
由此,我們便通過 Numpy 數(shù)組正式構(gòu)建了 tf.data.Dataset 數(shù)據(jù)集合。
3.3 進(jìn)一步的處理與使用
當(dāng)我們僅僅創(chuàng)建了數(shù)據(jù)集是遠(yuǎn)遠(yuǎn)不夠的,我們還要進(jìn)行進(jìn)一步的處理,比如分批、打亂等基本操作。
train_dataset = train_dataset.shuffle(128).batch(64)
test_dataset = test_dataset.batch(64)
print(train_dataset, test_dataset)
我們可以得到如下輸出:
<BatchDataset shapes: ((None, 28, 28), (None,)), types: (tf.uint8, tf.uint8)>
<BatchDataset shapes: ((None, 28, 28), (None,)), types: (tf.uint8, tf.uint8)>
在這里,我們對數(shù)據(jù)集合進(jìn)行了亂序處理,然后將其按照 64 的大小進(jìn)行批次的劃分。
在接下來我們便可以使用該數(shù)據(jù)集,在這里我們可以使用一個(gè)簡單的分類模型進(jìn)行示例:
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy'])
model.fit(train_dataset, epochs=20)
model.evaluate(test_dataset)
我們可以通過輸出發(fā)現(xiàn),該模型對數(shù)據(jù)進(jìn)行了良好的分類:
Epoch 1/20
469/469 [==============================] - 1s 3ms/step - loss: 6.4886 - accuracy: 0.8282
Epoch 2/20
469/469 [==============================] - 1s 3ms/step - loss: 1.0750 - accuracy: 0.8630
......
Epoch 20/20
469/469 [==============================] - 1s 3ms/step - loss: 0.1222 - accuracy: 0.9657
157/157 [==============================] - 0s 1ms/step - loss: 0.2871 - accuracy: 0.9456
[0.2871202528476715, 0.9455999732017517]
4. 小結(jié)
在這節(jié)課之中,我們學(xué)習(xí)了什么是 Numpy 數(shù)據(jù),同時(shí)一方面了解了 Numpy 數(shù)組與 Tensor 如何在內(nèi)存中互相轉(zhuǎn)化,另一方面我們也了解了如何從".npz"文件之中讀取數(shù)據(jù)并進(jìn)一步使用。