赞
踩
Python版本:Python 3.8.16
TensorFlow版本:2.6.0
书中选用的数据集为卫星图像数据集,在这里也采用同样的数据集
下载地址为:https://wwn.lanzout.com/i6KkX0t8ulfe
解压后的如图所示:


| 类别名 | 含义 | 示例图像 |
|---|---|---|
| glacier | 冰川 | ![]() |
| rock | 岩石 | ![]() |
| urban | 城市区域 | ![]() |
| water | 水域 | ![]() |
| wetland | 农田 | ![]() |
| wood | 森林 | ![]() |
在TensorFlow 2.x中,制作TFRecord主要涉及以下步骤:
import tensorflow as tf import os image_labels = {"glacier": 0, "rock": 1, "urban": 2, "water": 3 , "wetland": 4, "wood": 5 } def _bytes_feature(value): return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value])) def _int64_feature(value): return tf.train.Feature(int64_list=tf.train.Int64List(value=[value])) def image_example(image_string, label): image_shape = tf.image.decode_jpeg(image_string).shape feature = { 'height': _int64_feature(image_shape[0]), 'width': _int64_feature(image_shape[1]), 'depth': _int64_feature(image_shape[2]), 'label': _int64_feature(label), 'image_raw': _bytes_feature(image_string), } return tf.train.Example(features=tf.train.Features(feature=feature)) def creat_tfrecord(path,path_data): with tf.io.TFRecordWriter(path_data) as writer: for label in os.listdir(path): if label not in image_labels: continue label_path = os.path.join(path, label) for image_name in os.listdir(label_path): image_path = os.path.join(label_path, image_name) tf_example = image_example(open(image_path, 'rb').read(), image_labels[label]) writer.write(tf_example.SerializeToString()) train_folder = "data_prepare/pic/train" validation_folder = "data_prepare/pic/validation" train_output_file = "./train.tfrecord" validation_output_file = "./validation.tfrecord" creat_tfrecord(train_folder,train_output_file) creat_tfrecord(validation_folder,validation_output_file)
import tensorflow as tf raw_image_dataset = tf.data.TFRecordDataset('train.tfrecord') image_feature_description = { 'height': tf.io.FixedLenFeature([], tf.int64), 'width': tf.io.FixedLenFeature([], tf.int64), 'depth': tf.io.FixedLenFeature([], tf.int64), 'label': tf.io.FixedLenFeature([], tf.int64), 'image_raw': tf.io.FixedLenFeature([], tf.string), } def _parse_image_function(example_proto): return tf.io.parse_single_example(example_proto, image_feature_description) parsed_image_dataset = raw_image_dataset.map(_parse_image_function) for raw_record in parsed_image_dataset.take(1): print(repr(raw_record))
import tensorflow as tf from tensorflow.keras import layers, models, optimizers from tensorflow.keras.applications.inception_v3 import InceptionV3 from tensorflow.keras.preprocessing.image import ImageDataGenerator NUM_CLASSES = 6 IMG_SIZE = (299, 299) BATCH_SIZE = 32 LEARNING_RATE = 0.001 EPOCHS = 20 TRAIN_TFRECORD = "./train.tfrecord" VALID_TFRECORD = "./validation.tfrecord" def parse_tfrecord(serialized_example): feature_description = { 'height': tf.io.FixedLenFeature([], tf.int64), 'width': tf.io.FixedLenFeature([], tf.int64), 'depth': tf.io.FixedLenFeature([], tf.int64), 'label': tf.io.FixedLenFeature([], tf.int64), 'image_raw': tf.io.FixedLenFeature([], tf.string), } example = tf.io.parse_single_example(serialized_example, feature_description) image = tf.image.decode_jpeg(example['image_raw'], channels=3) image = tf.image.resize(image, IMG_SIZE) image = tf.cast(image, tf.float32) / 255.0 label = tf.one_hot(example['label'], NUM_CLASSES) return image, label def create_dataset(file_path): dataset = tf.data.TFRecordDataset(file_path) dataset = dataset.map(parse_tfrecord, num_parallel_calls=tf.data.AUTOTUNE) dataset = dataset.shuffle(1000) dataset = dataset.batch(BATCH_SIZE) dataset = dataset.prefetch(tf.data.AUTOTUNE) return dataset train_dataset = create_dataset(TRAIN_TFRECORD) valid_dataset = create_dataset(VALID_TFRECORD) base_model = InceptionV3(weights='imagenet', include_top=False, input_shape=(*IMG_SIZE, 3)) x = layers.GlobalAveragePooling2D()(base_model.output) x = layers.Dense(1024, activation='relu')(x) x = layers.Dropout(0.5)(x) x = layers.Dense(NUM_CLASSES, activation='softmax')(x) model = models.Model(inputs=base_model.input, outputs=x) for layer in base_model.layers: layer.trainable = False model.compile(optimizer=optimizers.Adam(LEARNING_RATE), loss='categorical_crossentropy', metrics=['accuracy']) history = model.fit(train_dataset, epochs=EPOCHS, validation_data=valid_dataset) loss, accuracy = model.evaluate(valid_dataset) print("Validation accuracy:", accuracy) model.save("13.h5")
我使用20个epoch来训练,每个epoch包含150个batch。训练过程中,损失函数的值从1.0670下降到了0.3733,准确率从0.7135上升到了0.8617。同时也可以看到,验证集的损失值从1.0338下降到了0.6949,准确率从0.6058上升到了0.7692。模型的训练过程看起来还不错,但我觉得不是很好。
import tensorflow as tf import numpy as np from PIL import Image NUM_CLASSES = 6 IMG_SIZE = (299, 299) model = tf.keras.models.load_model('13.h5') def preprocess_image(image_path): img = Image.open(image_path) img = img.resize(IMG_SIZE) img = np.array(img) / 255.0 img = np.expand_dims(img, axis=0) return img image_path = 'data_prepare/pic/validation/wood/73987_98782_18.jpg' preprocessed_image = preprocess_image(image_path) prediction = model.predict(preprocessed_image) predicted_class = np.argmax(prediction) print("Predicted class:", predicted_class)
可以看出正确的预测出了图片的类别
本次的数据集我是从网上下载下来的数据集与书本上的一致,不知道是我的下载地址有误,还是数据集本身是这样的,我觉得数据集有些图片的标签是不是标错了例如:
在数据集中这张图片的标签为wetland,但这明显根本不是wetland,而是urban。还有一部分的图片也有这样的情况,不知道是什么原因。所以我认为模型训练的效果不理想可能跟这个有关,当然,这只是我自己的看法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。