数据集为飞机与河流的图像,分别存在两个文件夹中
文件夹名称相当于图像的标签
首先需要从文件夹中读入图像:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import pathlib
import random
data_root = pathlib.Path('F:\\深度学习课程资料\\tensorflow\\数据集\\2_class')
##建立根目录的pathlib对象
all_image_path = [str(path) for path in data_root.glob('*/*')]
##获得根目录下所有得文件,并将其转换成字符串列表
random.shuffle(all_image_path)
##打乱列表顺序
label_name = sorted([item.name for item in data_root.glob('*/')])
##将根目录下文件夹的名字作为标签
label_to_index = dict((item,index) for index,item in enumerate(label_name))
##获得标签名作为key,编号作为value的字典
index_to_label = dict((v,k) for k,v in label_to_index.items())
##获得编号作为key,标签名作为value的字典
all_image_label = [label_to_index[pathlib.Path(pic).parent.name] for pic in all_image_path]
##获得所有图像的对应得标签编号,
##pathlib.Path(pic).parent.name是得到图像的上一级目录的名称,
##若pathlib.Path(pic).parent则是得到上一级目录的绝对路径
现在随机从中选取三张显示出来:
import IPython.display as display
for n in range(3):
image_index = random.choice(range(len(all_image_path)))
##随机挑选图像索引
display.display(display.Image(all_image_path[image_index]))
##display模块输入路径来显示图像
print(index_to_label[all_image_label[image_index]])
##打印图像标签
显示结果如下:
接下来是对于图像路经来读取图像:
def load_image(img_path):##img_path:图像路径
img_raw = tf.io.read_file(img_path)##获得图像的二进制格式
img_tensor = tf.image.decode_jpeg(img_raw,channels=3)
##对二进制格式的jpeg图片进行解码获得图像的灰度矩阵
img_tensor = tf.image.resize(img_tensor ,(256,256))
##将图片裁剪成规定的大小,使得函数能获得图片的shape
img_tensor = tf.cast(img_tensor,tf.float32)##将其转变为float型,方便归一化
img = img_tensor/255
return img
完整的分类代码:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import pathlib
import random
##设置GPU的调用策略为动态调用
gpus = tf.config.experimental.list_physical_devices(device_type='GPU')
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu,True)
##数据预处理部分
path_root = pathlib.Path('F:\\深度学习课程资料\\tensorflow\\数据集\\2_class')
all_img_path = path_root.glob('*/*')
all_img_path = [str(path) for path in all_img_path]##获得所有图片路径
random.shuffle(all_img_path)##打乱图片路径,为了最后划分训练,测试集时随机性大
label_name = sorted([item.name for item in path_root.glob('*/')])##获得标签
##标签为key,编号为value
label_to_index = dict((item,index) for index,item in enumerate(label_name))
##编号为key,标签为value
index_to_label = dict((key,value) for value,key in label_to_index.items())
##根据打乱的图片路径,获得每个图片的标签
all_img_label = [label_to_index[pathlib.Path(pic).parent.name] for pic in all_img_path]
##转变成dataset型
path_ds = tf.data.Dataset.from_tensor_slices(all_img_path)
label_ds = tf.data.Dataset.from_tensor_slices(all_img_label)
##根据路径读取图片
def load_img(img_path):
img_raw = tf.io.read_file(img_path)
img_tensor = tf.image.decode_jpeg(img_raw,channels=3)
img_tensor = tf.image.resize(img_tensor,[256,256])
img_tensor = tf.cast(img_tensor,tf.float32)
img = img_tensor/255
return img
##将dataset里每个路径转换成图片
img_ds = path_ds.map(load_img)
##将图片与标签合成
all_image_ds = tf.data.Dataset.zip((img_ds,label_ds))
##获得和设置每个集合数量
count = len(all_img_path)
train_count = int(0.8*count)
test_count = count-train_count
##切分训练集和测试集
train_ds = all_image_ds.take(train_count)
test_ds = all_image_ds.skip(train_count)
BATCH_SIZE = 32
##设置每个epoch里需要迭代几次才能将所有BATCH训练完
steps_per_epoch = train_count//BATCH_SIZE
validation_steps = test_count//BATCH_SIZE
##打乱每个BATCH的图片顺序
train_ds = train_ds.shuffle(count).repeat().batch(BATCH_SIZE)
test_ds = test_ds.batch(BATCH_SIZE)
##建立网络
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(64,(3,3),input_shape=(256,256,3),padding='same',activation='relu'))
model.add(tf.keras.layers.Conv2D(64,(3,3),padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPooling2D())
model.add(tf.keras.layers.Conv2D(128,(3,3),padding='same',activation='relu'))
model.add(tf.keras.layers.Conv2D(128,(3,3),padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPooling2D())
model.add(tf.keras.layers.Conv2D(256,(3,3),padding='same',activation='relu'))
model.add(tf.keras.layers.Conv2D(256,(3,3),padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPooling2D())
model.add(tf.keras.layers.Conv2D(512,(3,3),padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPooling2D())
model.add(tf.keras.layers.Conv2D(512,(3,3),padding='same',activation='relu'))
model.add(tf.keras.layers.MaxPooling2D())
model.add(tf.keras.layers.Conv2D(1024,(3,3),padding='same',activation='relu'))
model.add(tf.keras.layers.GlobalAveragePooling2D())##将整张特征图做平均,将多张二维压成一维
model.add(tf.keras.layers.Dense(1024,activation='relu'))
model.add(tf.keras.layers.Dense(512,activation='relu'))
##model.add(tf.keras.layers.Dense(64,activation='relu'))
model.add(tf.keras.layers.Dense(1,activation='sigmoid'))
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['acc'])
history = model.fit(train_ds,
epochs=30,
steps_per_epoch=steps_per_epoch,
validation_data=test_ds,
validation_steps=validation_steps)