TensorFlow学习笔记(8)加载与预处理

        在TensorFlow官网的加载和预处理Notebook页面进行学习时,发现配置环境的版本太低,代码没有办法完全实现。期间也尝试了重装,改环境,改源码,总有一部分难以解决。属实才疏学浅,便在代码部分借鉴了CSDN博主(永恒的星河)的代码。在此基础上完成了代码运行,并做出了注释。

import tensorflow as tf
import pathlib
import random
import matplotlib.pyplot as plt
from PIL import Image
# pillow 图像处理模块
import numpy as np

# 数据集下载
DATA_URL = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
# 文件的URL地址
path = tf.keras.utils.get_file(fname='flower_photos', origin=DATA_URL, untar=True)
# get_file:创建文件,fname:文件名,origin:来源 untar:解压
data_root = pathlib.Path(path)
# 利用pathlib中的path使path文件形成一个路径

# 获取每个类别下的图片路径
all_image_paths = list(data_root.glob('*/*'))
# glob获取data_root文件夹下所有文件夹下的所有内容  list 形成列表
all_image_paths = [str(path) for path in all_image_paths]
# 对all_image_paths中的文件,使其形成字符形式
random.shuffle(all_image_paths)
# 打乱all_image_paths中的内容
image_count = len(all_image_paths)

# 获取图像描述
attributions = (data_root / "LICENSE.txt").open(encoding="utf-8").readlines()[4:]
# 以utf-8的格式打开data_root下的LICENSE.txt文件,按行读取
attributions = [line.split('CC-BY') for line in attributions]
# 拆分
attributions = dict(attributions)
print(attributions)

def caption_image(image_path):
    image_rel = pathlib.Path(image_path).relative_to(data_root)
    image_rel = str(image_rel).replace("\\", "/")
    image_rel = image_rel + " "
    return "Image (CC BY 2.0) " + " - ".join(attributions[image_rel].split(" - ")[:-1])

# 随机显示四张图片
plt.figure(figsize=(10,10))
for n in range(1,5):
    image_path = random.choice(all_image_paths)
    img_data = np.asarray(Image.open(image_path))
    # display.display(display.Image(image_path))
    plt.subplot(2,2,n)
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])
    plt.xlabel(caption_image(image_path))
    plt.imshow(img_data)
plt.show()

# 获取具体类别,将其数值化处理
label_names = sorted(item.name for item in data_root.glob("*/") if item.is_dir())
# 对于所有data_root下的文件夹进行排序
label_to_index = dict((name, index) for index, name in enumerate(label_names))
# 将一个可遍历对象组合为一个索引序列,同时列出数据和数据下标
print(label_to_index)
# 打印类别和索引对应字典
all_image_labels = [label_to_index[pathlib.Path(impath).parent.name] for impath in all_image_paths]
print("First 10 labels indices: ", all_image_labels[:10])
# 打印前十个标签索引

# 解析图像数据,将其归一化
def process_image(image):
    image = tf.image.decode_jpeg(image, channels=3)
    # 定义图片的通道数
    image = tf.image.resize(image, (192, 192))
    # 定义图片大小
    image /= 255.0
    # 归一化
    return image


def load_and_process_image(path):
    image = tf.io.read_file(path)
    return process_image(image)

# 将图片转化为datasets处理,方便模型训练和数据处理
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_process_image(path), label
image_label_ds = ds.map(load_and_preprocess_from_path_label)
# map 对指定的序列做映射
print(image_label_ds)

# 使用 tf.data.Dataset.cache 在 epoch 之间轻松缓存计算结果。
# 这是非常高效的,特别是当内存能容纳全部数据时。
# 在被预处理之后(解码和调整大小),图片在此被缓存:
BATCH_SIZE=12
ds = image_label_ds.cache()
# 设置一个和数据集大小一致的 shuffle buffer size(随机缓冲区大小)以保证数据被充分打乱
ds = ds.apply(
    tf.data.experimental.shuffle_and_repeat(buffer_size=image_count))
ds = ds.batch(BATCH_SIZE)
# 当模型在训练的时候,`prefetch` 使数据集在后台取得 batch。
ds = ds.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)

# 模型迁移、模型构建及训练
mobile_net = tf.keras.applications.MobileNetV2(input_shape=(192, 192, 3), include_top=False)
mobile_net.trainable = False
help(tf.keras.applications.mobilenet_v2.preprocess_input)

def change_range(image, label):
    return 2 * image - 1, label

keras_ds = ds.map(change_range)

image_batch, label_batch = next(iter(keras_ds))
feature_map_batch = mobile_net(image_batch)
print(feature_map_batch.shape)

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"])

steps_per_epoch = int(tf.math.ceil(len(all_image_paths) / BATCH_SIZE).numpy())
model.fit(ds, epochs=10, steps_per_epoch=steps_per_epoch)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值