基于卷积神经网络和迁移学习实现场景图片分类任务 您所在的位置:网站首页 网络图片 基于卷积神经网络和迁移学习实现场景图片分类任务

基于卷积神经网络和迁移学习实现场景图片分类任务

2022-11-05 00:56| 来源: 网络整理| 查看: 265

import  osimport pathlibos.environ['CUDA_VISIBLE_DEVICES'] = "1"os.environ['TF_CPP_MIN_LOG_LEVEL']='2'import  tensorflow as tfimport randomimport numpy as npimport sysimport globdata_root = pathlib.Path(r'C:\Users\86177\.keras\datasets\training')print(data_root)for item in data_root.iterdir():    print(item)

#Get the names of 15 folderslabel_names = sorted(item.name for item in data_root.glob('*/') if item.is_dir())print(label_names)

#Mark the name of the folder with a serial number (0-14)label_to_index = dict((name, index) for index, name in enumerate(label_names))

#Configure the picture mapping corresponding to the serial numberindex_to_label = dict((v,k) for k, v in label_to_index.items())all_image_paths = list(data_root.glob('*/*'))all_image_paths = [str(path) for path in all_image_paths]random.shuffle(all_image_paths)image_count = len(all_image_paths)print(image_count)

#Get the tags of all picturesall_image_labels = [label_to_index[pathlib.Path(path).parent.name]for path in all_image_paths]print("First 10 labels indices: ", all_image_labels[:10])

#Define loading and preprocessing functions, decode pictures and unify picture sizesdef preprocess_image(image):    image = tf.image.decode_jpeg(image, channels=3)    image = tf.image.resize(image, [192, 192])    image /= 255.0  # normalize to [0,1] range  return image    return imagedef load_and_preprocess_image(path):    image = tf.io.read_file(path)    return preprocess_image(image)

# Divide the training set into training set and test set according to the ratio of 8:2i = int(len(all_image_paths)*0.8)

train_path = all_image_paths[:i]train_label = all_image_labels[:i]test_path = all_image_paths[i:]test_label = all_image_labels[i:]

#"From_tensor_slices" method uses tensor slice elements to build a dataset of image pathspath_trainds = tf.data.Dataset.from_tensor_slices(train_path)#Similarly, reconstruct the label data set and use tf.cast to convert to int64 data typelabel_trainds = tf.data.Dataset.from_tensor_slices(tf.cast(train_label, tf.int64))#Acquire the picture according to the path, and get the picture data set after loading and preprocessingimage_trainds = path_trainds.map(load_and_preprocess_image )print(image_trainds)#Pack the picture and its corresponding label to form a training settrain_ds = tf.data.Dataset.zip((image_trainds, label_trainds))print(train_ds)print(len(train_ds))

#The test set is processed the same as the training setpath_testds = tf.data.Dataset.from_tensor_slices(test_path)label_testds = tf.data.Dataset.from_tensor_slices(tf.cast(test_label, tf.int64))image_testds = path_testds.map(load_and_preprocess_image )print(image_testds)test_ds = tf.data.Dataset.zip((image_testds, label_testds))print(test_ds)print(len(test_ds))

# Define a function to convert the training data into a data type that tensorflow can handledef preprocess(x, y):    # [0~1]    x = tf.cast(x, dtype=tf.float32)    y = tf.cast(y, dtype=tf.int32)    return x,y#Set batchsize to break up the training set to prevent overfitting in the training processBATCHSIZE = 32train_db = train_ds.repeat().shuffle(400).map(preprocess).batch(BATCHSIZE)test_db = test_ds.shuffle(400).map(preprocess).batch(BATCHSIZE)

#Because the training set data is too small, the function is defined in the training phase to perform real-time augmentation of the data to prevent overfittingdef augment_data(image, label):    print("扩展数据调用!")    # Randomly flip the picture horizontally    image = tf.image.random_flip_left_right(image)    # Randomly set the contrast of the picture    image = tf.image.random_contrast(image, lower=0.0, upper=1.0)    # # Randomly flip the picture vertically    image = tf.image.random_flip_up_down(image)    # # Randomly set the brightness of the picture    image = tf.image.random_brightness(image, max_delta=0.5)    # # Randomly set the chroma of the picture    image = tf.image.random_hue(image, max_delta=0.3)    # # Randomly set the saturation of the picture    image = tf.image.random_saturation(image, lower=0.3, upper=0.5)    return image,label

train_db = train_db.map(augment_data)

# #Self-created convolutional neural network model structure# model = tf.keras.Sequential([##     tf.keras.layers.Conv2D(64, (3, 3), input_shape=(192, 192, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.MaxPooling2D(),#     tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.MaxPooling2D(),#     tf.keras.layers.Conv2D(256, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.Conv2D(256, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.MaxPooling2D(),#     tf.keras.layers.Conv2D(512, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.Conv2D(512, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.MaxPooling2D(),#     tf.keras.layers.Conv2D(512, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.Conv2D(512, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.Conv2D(512, (3, 3), activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.GlobalAveragePooling2D(),#     # tf.keras.layers.Flatten(),#     tf.keras.layers.Dense(1024, activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.Dense(512, activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.Dense(128, activation='relu'),#     tf.keras.layers.BatchNormalization(),#     tf.keras.layers.Dense(15)# ])

# Migrate the MobileNetV2 model without loading the top layerbase_model = tf.keras.applications.mobilenet_v2.MobileNetV2(include_top=False, weights='imagenet',                                                            input_shape=(192, 192, 3))inputs = tf.keras.layers.Input(shape=(192, 192, 3))

#Define the function to change the value range of the data set, because MobileNetV2 accepts the input data value range is [-1,1], and our previous pre-function maps the quantized value of the picture to [0,1]def change_range(image,label):    return 2*image-1,labelkeras_ds = train_db.map(change_range)keras_vds = test_db.map(change_range)

#Define model structuremodel = tf.keras.Sequential([    base_model,    tf.keras.layers.GlobalAveragePooling2D(),    tf.keras.layers.Dense(15)

])#Assemble model, set optimizer, loss function and performance evaluation indexmodel.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0001),  #optimizer=tf.keras.optimizers.SGD(lr=0.005, momentum=0.9),  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),  metrics=['accuracy'])model.summary()

#Run modelmodel.fit(keras_ds,epochs=20,steps_per_epoch=37,validation_data=keras_vds,validation_steps=9)# Evaluate modelloss, accuracy = model.evaluate(keras_vds)print('\ntest loss', loss)print('accuracy', accuracy)

#Define loading test set data functiondef load_and_preprocess_image2(path):    image = tf.io.read_file(path)    image = tf.image.decode_jpeg(image, channels=3)    image = tf.image.resize(image, [192, 192])    image = tf.cast(image, tf.float32)    image = image / 255.0    return image

f = open('out7.txt', 'a+')for i in range(0, 2988):  # the final image is 2987.jpg.    test_img = glob.glob("./data/testing/%s" % i + ".jpg")    if (i != 1314 and i != 2938 and i != 2962):        BATCHSIZE2 = 1        path_trainds = tf.data.Dataset.from_tensor_slices(test_img)        image_trainds = path_trainds.map(load_and_preprocess_image2)

        test_tensor = image_trainds.batch(BATCHSIZE2)        # Predict the test set data        pred = model.predict(test_tensor)        A = index_to_label.get(np.argmax(pred))

       # Write the prediction results into a txt file        name = str(i) + '.jpg'        print(name, A.lower(), file=f)

f.close()



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有