Tensorflow学习笔记 (用 tf.data 加载图片)
原代碼來自tensorflow
Tensorflow學習筆記 (用 tf.data 加載圖片)
本教程提供一個如何使用 tf.data 加載圖片的簡單例子。
導入模塊,配置
import tensorflow as tftf.data用于數據集的構建與預處理
AUTOTUNE = tf.data.experimental.AUTOTUNE下載并檢查數據集
從origin網址中下載文件,命名為’flower_photos’,untar=True表示對文件進行解壓。
通過pathlib.Path(data_root_orig)獲得文件的路徑(雖然data_root_orig 也表示下載的文件路徑,但pathlib.Path可以支持不同的操作系統)
查看data_root路徑下的文件
data_root路徑下有5個子文件夾和1txt文件。
for item in data_root.iterdir():print(item)data_root.路徑下有6個子文件,data_root.glob(’/’)表示讀取子文件夾中的所有圖片。
import random all_image_paths = list(data_root.glob('*/*')) all_image_paths列表中的部分內容如下所示
[WindowsPath(‘C:/Users/HUAWEI/.keras/datasets/flower_photos/daisy/100080576_f52e8ee070_n.jpg’),
WindowsPath(‘C:/Users/HUAWEI/.keras/datasets/flower_photos/daisy/10140303196_b88d3d6cec.jpg’),
去掉WindowsPath,只留下圖片的路徑
all_image_paths = [str(path) for path in all_image_paths] all_image_paths
打亂圖片路徑順序
查看一共有多少圖片
檢查圖片
打開data_root路徑下的"LICENSE.txt"文件,編碼為’utf-8’,讀取文件第4行以后的內容。
將列表中的每一項以’ CC-BY’作為分隔符分開。
將attributions變成字典
attributions = dict(attributions) attributionscaption_image是一個查看圖片拍攝者的函數。將圖片在計算機中的路徑作為參數輸入,用pathlib.Path將路徑變成本機系統適用的路徑。image_path相當于data_root的一個子集,pathlib.Path(image_path).relative_to(data_root)相當于將image_path減去data_root。示例如下
import IPython.display as displaydef caption_image(image_path):image_rel = pathlib.Path(image_path).relative_to(data_root)return "Image (CC BY 2.0) " + ' - '.join(attributions[str(image_rel)].split(' - ')[:-1])隨機選取3張圖片,瀏覽圖片并打印其拍攝者
for n in range(3):image_path = random.choice(all_image_paths)display.display(display.Image(image_path))print(caption_image(image_path))print()確定可用的標簽
查看data_root路徑下的所有文件(5個文件夾,1個txt文件),如果文件是文件夾時,將文件的文件名選出并排序。
label_names = sorted(item.name for item in data_root.glob('*/') if item.is_dir()) label_names通過枚舉的方法,為每個標簽分配索引。
label_to_index = dict((name, index) for index, name in enumerate(label_names)) label_to_index設置所有圖片的標簽。通過for path in all_image_paths得到所有圖片的路徑,形如’/home/kbuilder/.keras/datasets/flower_photos/tulips/8673416166_620fc18e2f_n.jpg’,pathlib.Path(path).parent.name可以得到圖片上一級文件夾的名稱,如tulips。
通過鍵值對匹配給所有圖片貼上標簽。
加載并格式化圖片
加載并格式化圖片,使圖片適用于模型訓練。
通過tf.io.read_file()和圖片路徑讀取原始數據,返回給image,將原始數據image解碼為圖像tensor.
該函數用于原始數據的解碼,image是原始數據。tf.image.decode_jpeg用于對圖片的解碼,channels=3表示輸出RGB圖像,最后返回uint8類型的Tensor。
對圖像大小進行調整,[192, 192]表示新圖像的大小。
對圖像進行歸一化處理。
查看調整后的圖像
不顯示網格線
設置橫坐標
設置標題,并將首字母大寫
構建一個 tf.data.Dataset
構建 tf.data.Dataset 最簡單的方法就是使用 from_tensor_slices 方法。
將字符串數組切片,得到一個字符串數據集:
現在創建一個新的數據集,通過在路徑數據集上映射 preprocess_image 來動態加載和格式化圖片,返回一個迭代器。即通過load_and_preprocess_image將path_ds映射至image_ds,動態加載和格式化圖片。
image_ds = path_ds.map(load_and_preprocess_image, num_parallel_calls=AUTOTUNE)瀏覽圖片
import matplotlib.pyplot as pltplt.figure(figsize=(8,8)) for n, image in enumerate(image_ds.take(4)):plt.subplot(2,2,n+1)plt.imshow(image)plt.grid(False)plt.xticks([])plt.yticks([])plt.xlabel(caption_image(all_image_paths[n]))plt.show()使用同樣的 from_tensor_slices 方法你可以創建一個標簽數據集
label_ds = tf.data.Dataset.from_tensor_slices(tf.cast(all_image_labels, tf.int64))由于這些數據集順序相同,你可以將他們打包在一起得到一個(圖片, 標簽)對數據集:
image_label_ds = tf.data.Dataset.zip((image_ds, label_ds))ds = tf.data.Dataset.from_tensor_slices((all_image_paths, all_image_labels))元組被解壓縮到映射函數的位置參數中
def load_and_preprocess_from_path_label(path, label):return load_and_preprocess_image(path), labelimage_label_ds = ds.map(load_and_preprocess_from_path_label) image_label_ds訓練時,數據應充分打亂,分割為batch,永遠穿越重復,盡可能提供batch
BATCH_SIZE = 32設置一個和數據集大小一致的 shuffle buffer size(隨機緩沖區大小)以保證數據被充分打亂。
ds = image_label_ds.shuffle(buffer_size=image_count) ds = ds.repeat() ds = ds.batch(BATCH_SIZE)當模型在訓練的時候,prefetch 使數據集在后臺取得 batch。
ds = ds.prefetch(buffer_size=AUTOTUNE) ds ds = image_label_ds.apply(tf.data.experimental.shuffle_and_repeat(buffer_size=image_count)) ds = ds.batch(BATCH_SIZE) ds = ds.prefetch(buffer_size=AUTOTUNE) ds傳遞數據至模型
mobile_net = tf.keras.applications.MobileNetV2(input_shape=(192, 192, 3), include_top=False) mobile_net.trainable=False該模型期望它的輸出被標準化至 [-1,1] 范圍內,在你將輸出傳遞給 MobilNet 模型之前,你需要將其范圍從 [0,1] 轉化為 [-1,1]:
def change_range(image,label):return 2*image-1, labelkeras_ds = ds.map(change_range)構建一個包裝了 MobileNet 的模型并在 tf.keras.layers.Dense 輸出層之前使用 tf.keras.layers.GlobalAveragePooling2D 來平均那些空間向量:
model = tf.keras.Sequential([mobile_net,tf.keras.layers.GlobalAveragePooling2D(),tf.keras.layers.Dense(len(label_names), activation = 'softmax')]) logit_batch = model(image_batch).numpy()print("min logit:", logit_batch.min()) print("max logit:", logit_batch.max()) print()print("Shape:", logit_batch.shape)編譯模型
model.compile(optimizer=tf.keras.optimizers.Adam(),loss='sparse_categorical_crossentropy',metrics=["accuracy"])查看Dense層可訓練的變量個數
len(model.trainable_variables)model.summary()注意,出于演示目的每一個 epoch 中你將只運行 3 step,但一般來說在傳遞給 model.fit() 之前你會指定 step 的真實數量
steps_per_epoch=tf.math.ceil(len(all_image_paths)/BATCH_SIZE).numpy() steps_per_epochmodel.fit(ds, epochs=1, steps_per_epoch=3)總結
以上是生活随笔為你收集整理的Tensorflow学习笔记 (用 tf.data 加载图片)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux kvm安装win7,ubun
- 下一篇: linux ubuntu bionic,