基于卷积神经网络和迁移学习实现场景图片分类任务 | 您所在的位置:网站首页 › 网络图片 › 基于卷积神经网络和迁移学习实现场景图片分类任务 |
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 实验室设备网 版权所有 |