import pathlib
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
%matplotlib inline
data_dir='./DataSet/airplane_lake'
data_root=pathlib.Path(data_dir)
for item in data_root.iterdir():
print(item)
#上面这段是提取数据文件,pathlib.Path()方法创建一个路径对象。iterdir()方法遍历文件夹下面的子目录。
all_image_path=list(data_root.glob('*/*'))
all_image_path=[str(path) for path in all_image_path]
#glob(‘*/*’)方法获取所有子目录下的所有文件。另外需要用str()方法将所有路径对象转化成字符串。
import random
random.shuffle(all_image_path)
image_count=len(all_image_path)
label_name=sorted(item.name for item in data_root.glob('*/'))
label_to_index=dict((name,index) for index,name in enumerate(label_name))
all_image_label=[label_to_index[pathlib.Path(p).parent.name]for p in all_image_path]
#random.shuffle()方法对列表进行乱序。(乱序原因是因为原始数据列表中不同种类别图片是分开的,不这
#样训练)label_name变量获取图片的标签,数据按不同的类别放在不同文件夹下,将文件夹名称当作标签称。
#label_to_index变量将获取的标签名字打上标签,存在一个字典中,如airplane标签为0,lake标签为1。
#当然这是在多分类任务中比较有用。
#all_image_label变量获取所有图片对应的标签。pathlib.Path(p).parent.name 表示获取p路径的父目录#的名字,因为父目录的名字就是该图片的标签。
import IPython.display as display #随机选取3个图片并显示它们的标签
index_to_label=dict((v,k) for k,v in label_to_index.items() )
for n in range(3):
image_index=random.choice(range(len(all_image_path)))
display.display(display.Image(all_image_path[image_index]))
print(index_to_label[all_image_label[image_index]])
#random.choice()方法随机从范围中选取一个数
#定义一个函数。读取一张图片,返回归一化后的图片
def load_preprosess_image(path):
img_raw=tf.io.read_file(path)
img_tensor=tf.image.decode_jpeg(img_raw,channels=3)
img_tensor=tf.image.resize_with_crop_or_pad(img_tensor,256,256)
img_tensor=tf.cast(img_tensor,tf.float32)
img=img_tensor/255
return img
#tf.data 导入数据集
path_ds=tf.data.Dataset.from_tensor_slices(all_image_path)
image_dataset=path_ds.map(load_preprosess_image)
label_dataset=tf.data.Dataset.from_tensor_slices(all_image_label)
dataset=tf.data.Dataset.zip((image_dataset,label_dataset))
#map()方法将所有数据导入load_preprosess_image函数进行处理。参数为一个方法。
#dataset 划分数据集
test_count=int(image_count*0.2) #划分20%的数据进行测试
train_count=image_count-test_count #余下的80%作为训练数据
train_dataset=dataset.skip(test_count)
test_dataset=dataset.take(test_count)
BATCH_SIZE=32
train_dataset=train_dataset.repeat().shuffle(100).batch(BATCH_SIZE) #先shuffle再batch
test_datset=test_dataset.batch(BATCH_SIZE)
#skip()为跳过的意思,表示跳过前test_count个数据,剩下的数据都要。take()相反,表示取前#test_count个数据
#建立模型
model=tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(64,(3,3),input_shape=(256,256,3),activation='relu'))
model.add(tf.keras.layers.Conv2D(64,(3,3),activation='relu'))
model.add(tf.keras.layers.MaxPooling2D())
model.add(tf.keras.layers.Conv2D(128,(3,3),activation='relu'))
model.add(tf.keras.layers.Conv2D(128,(3,3),activation='relu'))
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(128,activation='relu'))
model.add(tf.keras.layers.Dense(1,activation='sigmoid'))
model.summary()
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['acc'])
steps_per_epoch=train_count//BATCH_SIZE
validation_steps=test_count//BATCH_SIZE
steps_per_epoch,validation_steps
history=model.fit(train_dataset,
epochs=30,
steps_per_epoch=steps_per_epoch,
validation_data=test_datset,
validation_steps=validation_steps)
plt.plot( history.epoch, history.history.get('acc'),label='acc')
plt.plot( history.epoch, history.history.get('val_acc'),label='val_acc')
plt.legend()
plt.plot( history.epoch, history.history.get('loss'),label='loss')
plt.plot( history.epoch, history.history.get('val_loss'),label='val_loss')
plt.legend()
数据集:
数据集名称
二级目录:
三级目录:
数据集地址:https://pan.baidu.com/s/1Blseqmkm-n8ONOt40lqTCw%C2%A0#list/path=%2F