首页 > 其他分享 >机器学习——景观识别

机器学习——景观识别

时间:2022-12-23 21:57:21浏览次数:76  
标签:plt 机器 img 景观 add import model 识别 size

一、选题背景:
景观识别是一种人工智能技术,旨在通过自然场景的图像或视频来识别和分类不同的景观类型。这种技术可以用于多种应用场景,如旅游、地理信息系统、环境监测等。
在旅游领域,景观识别技术可以帮助游客更好地了解当地的自然景观,为他们提供更加个性化的旅游体验。在地理信息系统领域,景观识别技术可以帮助收集和维护地理信息数据,例如道路、建筑物、植被等。在环境监测领域,景观识别技术可以帮助监测和分析自然环境的变化,例如森林覆盖率、植被生长情况等。
景观识别技术的研究对象主要是自然场景,包括城市、山区、河流、海滩、森林等。在研究过程中,需要考虑场景中的各种因素,如光照、气候、季节等,以及场景的多样性和复杂性。

二、机器学习设计方案:
网站中下载相关的数据集,对数据集进行整理,在python的环境中,给数据集中的文件打上标签,对数据进行预处理,利用keras,构建网络,训练模型,导入图片测试模型
本题采用的数据集来源于kaggle:https://www.kaggle.com/datasets/

三、机器学习的实现步骤:
1.目的:通过机器学习分别识别出海滩,冰川,森林,沙漠,山脉五个景观图片。
2.下载数据集:
image
3.导入需要的库

import numpy as np
import pandas as pd
import os
import tensorflow as tf
import matplotlib.pyplot as plt
from pathlib import Path
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Activation
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.applications.resnet import preprocess_input
from keras_preprocessing.image import ImageDataGenerator
from keras.models import load_model
from keras import optimizers
from keras.utils.np_utils import *

4.遍历数据集中的文件,将路径数据和标签数据生成DataFrame

dir = Path('E:/Landscape Classification')
# 用glob遍历在dir路径中所有jpg格式的文件,并将所有的文件名添加到filepaths列表中
filepaths = list(dir.glob(r'**/*.jpeg'))

# 将文件中的分好的小文件名(种类名)分离并添加到labels的列表中
labels = list(map(lambda l: os.path.split(os.path.split(l)[0])[1], filepaths))

# 将filepaths通过pandas转换为Series数据类型
filepaths = pd.Series(filepaths, name='FilePaths').astype(str)

# 将labels通过pandas转换为Series数据类型
labels = pd.Series(labels, name='Labels').astype(str)

# 将filepaths和Series两个Series的数据类型合成DataFrame数据类型
df = pd.merge(filepaths, labels, right_index=True, left_index=True)
df = df[df['Labels'].apply(lambda l: l[-2:] != 'GT')]
df = df.sample(frac=1).reset_index(drop=True)#查看形成的DataFrame的数据df
df

image

5.将原始数据按照一定的比例分成训练集、验证集和测试集。

X_train, X_test = train_test_split(df, test_size=0.3, stratify=df['Labels'])

print('Shape of Train Data: ', X_train.shape)
print('Shape of Test Data: ', X_test.shape)


X_train, X_val = train_test_split(X_train, test_size=0.4, stratify=X_train['Labels'])

print('Shape of Train Data: ', X_train.shape)
print('Shape of Val Data: ', X_val.shape)

# 查看各个标签的图片张数
X_train['Labels'].value_counts(ascending=True)

image

6.绘出图像和图像标签

#创建一个包含 5 行 5 列的图像的绘图窗口
fit, ax = plt.subplots(nrows=5, ncols=5, figsize=(13, 7))
for i, a in enumerate(ax.flat):#遍历子图
    a.imshow(plt.imread(df.FilePaths[i]))
    a.set_title(df.Labels[i])

plt.tight_layout()
plt.show()

image

image

7.创建一个图像生成器,用于生成训练、验证和测试数据。

# 批量的大小
BATCH_SIZE = 32
# 输入图片的大小
IMG_SIZE = (150, 150)

# 使用preprocessing_function参数指定了一个预处理函数,该函数用于将输入图像进行预处理,使其符合模型的输入格式。
img_data_gen = ImageDataGenerator(preprocessing_function=preprocess_input)
X_train = img_data_gen.flow_from_dataframe(dataframe=X_train,
                                          x_col='FilePaths',#参数指定了数据中包含图像路径的列名
                                          y_col='Labels',#参数指定了数据帧中包含图像标签的列名
                                          target_size=IMG_SIZE,#参数指定了图像的大小
                                          color_mode='rgb',#参数指定了图像的rgb颜色模式
                                          class_mode='categorical',#参数指定了图像的分类模式,多类别
                                          batch_size=BATCH_SIZE,#参数指定了生成器生成的每个批次的大小
                                          seed=42)#参数指定了随机数生成器的种子,用于生成随机打乱的数据。

X_val = img_data_gen.flow_from_dataframe(dataframe=X_val,
                                          x_col='FilePaths',
                                          y_col='Labels',
                                          target_size=IMG_SIZE,
                                          color_mode='rgb',
                                          class_mode='categorical',
                                          batch_size=BATCH_SIZE,
                                          seed=42)
X_test = img_data_gen.flow_from_dataframe(dataframe=X_test,
                                          x_col='FilePaths',
                                          y_col='Labels',
                                          target_size=IMG_SIZE,
                                          color_mode='rgb',
                                          class_mode='categorical',
                                          batch_size=BATCH_SIZE,
                                          seed=42)

image

8.绘出经过处理的图像和 图像标签索引,用于后面预测时对应创建字典的值

fit, ax = plt.subplots(nrows=2, ncols=3, figsize=(13,7))

for i, a in enumerate(ax.flat):
    img, label = X_train.next()
    a.imshow(img[0],)
    a.set_title(label[0])
plt.tight_layout()
plt.show()

image

9.创建卷积神经网络模型

#创建输入层,卷积层,池化层,全连接层,输出层
model = Sequential()

# 1层

#Output shape计算公式:(150-3+1=148
#param参数数量:32*3*3*3+32=896
model.add(Conv2D(
    filters=32, #卷积核个数32个
    kernel_size= (3,3) , 
    input_shape=(150,150,3) , 
))
model.add(Activation('relu'))
model.add(MaxPooling2D(
    pool_size=(2,2), # 输出图片尺寸:148/2=74*74
    strides=2,
))
#CNN 2层
model.add(Conv2D(
    filters=64,  #Output (50,50,64)
    kernel_size=(3,3),
))
model.add(Activation('relu'))
model.add(MaxPooling2D(  #Output(25,25,64)
    pool_size=(2,2),
    strides=2,
))

#CNN 3层
model.add(Conv2D(
    filters=128,  #Output (50,50,64)
    kernel_size=(3,3),
))
model.add(Activation('relu'))
model.add(MaxPooling2D(  #Output(25,25,64)
    pool_size=(2,2),
    strides=2,
))
#全连层1
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))

#全连层2
model.add(Dense(256))
model.add(Activation('relu'))

model.add(Dense(5))#添加5个节点的连接层
model.add(Activation('softmax'))#添加激活层,softmax将输入的一个向量转换为概率分布


#编译模型
model.compile(optimizer=optimizers.RMSprop(lr=1e-4),
               loss="categorical_crossentropy", 
               metrics=["accuracy"])
model.summary()

image

#训练模型
h1 = model.fit(X_train, validation_data=X_val,
               epochs=30, )
#保存模型
model.save('lwl41.h5')

image

10.绘制训练过程中模型的准确率和损失的变化曲线

accuracy = h1.history['accuracy']
loss = h1.history['loss']
val_loss = h1.history['val_loss']
val_accuracy = h1.history['val_accuracy']
plt.figure(figsize=(17, 7))
plt.subplot(2, 2, 1)
plt.plot(range(30), accuracy,'bo', label='Training Accuracy')
plt.plot(range(30), val_accuracy, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Accuracy : Training vs. Validation ')
plt.subplot(2, 2, 2)
plt.plot(range(30), loss,'bo' ,label='Training Loss')
plt.plot(range(30), val_loss, label='Validation Loss')
plt.title('Loss : Training vs. Validation ')
plt.legend(loc='upper right')
plt.show()

image
从图分析,这种情况可能是由于模型过度拟合训练数据而导致的,导致它在训练数据上表现良好,但是在验证数数上表现不佳。

11.通过ImageDataGenerator数据增强器,训练数据中进行随机变换的方式,帮助模型学习更多的特征,来降低过拟合

#修改预处理图像中ImageDataGenerator的参数,实现数据增强
img_data_gen = ImageDataGenerator(rescale=1./255,
                                  rotation_range=40, #将图像随机旋转40度
                                  width_shift_range=0.2, #在水平方向上平移比例为0.2
                                  height_shift_range=0.2, #在垂直方向上平移比例为0.2
                                  shear_range=0.2, #随机错切变换的角度为0.2
                                  zoom_range=0.2, #图片随机缩放的范围为0.2
                                  horizontal_flip=True, #随机将一半图像水平翻转
                                  fill_mode='nearest')

在重新进行训练和绘制损失曲线和精度曲线图
image
image
发现过拟合的情况已经有效的解决了。

12.导入图片进行预测

from PIL import Image
from keras.utils import image_utils
def con(file,outdir,w=150,h=150):
    img1=Image.open(file)
    img2=img1.resize((w,h),Image.BILINEAR)
    img2.save(os.path.join(outdir,os.path.basename(file)))
file='E:/Landscape Classification/Testing Data/Mountain/Mountain-Test (7).jpeg'
con(file,'E:/')
model=load_model('lwl41.h5')
img_path='E:/Landscape Classification/Testing Data/Mountain/Mountain-Test (7).jpeg'
img = image_utils.load_img(img_path,target_size=(150,150))
img = image_utils.img_to_array(img)
img = np.expand_dims(img, axis=0)
out = model.predict(img)
print(out)
dict={'0':'海滩','1':'冰川','2':'森林','3':'沙漠','4':'山脉'}
for i in range(5):
    if out[0][i]>0.5:
        print(dict[str(i)])
img=plt.imread('E:/Landscape Classification/Testing Data/Mountain/Mountain-Test (7).jpeg')
plt.imshow(img)

image

image

image

image
image

完整代码附上:

点击查看代码
#导入需要用到的库
import numpy as np
import pandas as pd
import os
import tensorflow as tf
import matplotlib.pyplot as plt
from pathlib import Path
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Activation
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.applications.resnet import preprocess_input
from keras_preprocessing.image import ImageDataGenerator
from keras.models import load_model
from keras import optimizers
from keras.utils.np_utils import *

dir = Path('E:/Landscape Classification')

# 用glob遍历在dir路径中所有jpg格式的文件,并将所有的文件名添加到filepaths列表中
filepaths = list(dir.glob(r'**/*.jpeg'))

# 将文件中的分好的小文件名(种类名)分离并添加到labels的列表中
labels = list(map(lambda l: os.path.split(os.path.split(l)[0])[1], filepaths))

# 将filepaths通过pandas转换为Series数据类型
filepaths = pd.Series(filepaths, name='FilePaths').astype(str)

# 将labels通过pandas转换为Series数据类型
labels = pd.Series(labels, name='Labels').astype(str)

# 将filepaths和Series两个Series的数据类型合成DataFrame数据类型
df = pd.merge(filepaths, labels, right_index=True, left_index=True)
df = df[df['Labels'].apply(lambda l: l[-2:] != 'GT')]
df = df.sample(frac=1).reset_index(drop=True)#查看形成的DataFrame的数据df
df


X_train, X_test = train_test_split(df, test_size=0.3, stratify=df['Labels'])

print('Shape of Train Data: ', X_train.shape)
print('Shape of Test Data: ', X_test.shape)


X_train, X_val = train_test_split(X_train, test_size=0.4,stratify=X_train['Labels'])

print('Shape of Train Data: ', X_train.shape)
print('Shape of Val Data: ', X_val.shape)

# 查看各个标签的图片张数
X_train['Labels'].value_counts(ascending=True)

fit, ax = plt.subplots(nrows=5, ncols=5, figsize=(13, 7))

for i, a in enumerate(ax.flat):
    a.imshow(plt.imread(df.FilePaths[i]))
    a.set_title(df.Labels[i])

plt.tight_layout()
plt.show()

# 批量的大小
BATCH_SIZE = 32
# 输入图片的大小
IMG_SIZE = (150, 150)

# 使用preprocessing_function参数指定了一个预处理函数,该函数用于将输入图像进行预处理,使其符合模型的输入格式。
img_data_gen = ImageDataGenerator(rescale=1./255,
                                  rotation_range=40, #将图像随机旋转40度
                                  width_shift_range=0.2, #在水平方向上平移比例为0.2
                                  height_shift_range=0.2, #在垂直方向上平移比例为0.2
                                  shear_range=0.2, #随机错切变换的角度为0.2
                                  zoom_range=0.2, #图片随机缩放的范围为0.2
                                  horizontal_flip=True, #随机将一半图像水平翻转
                                  fill_mode='nearest')
X_train = img_data_gen.flow_from_dataframe(dataframe=X_train,
                                          x_col='FilePaths',#参数指定了数据中包含图像路径的列名
                                          y_col='Labels',#参数指定了数据帧中包含图像标签的列名
                                          target_size=IMG_SIZE,#参数指定了图像的大小
                                          color_mode='rgb',#参数指定了图像的rgb颜色模式
                                          class_mode='categorical',#参数指定了图像的分类模式,多类别
                                          batch_size=BATCH_SIZE,#参数指定了生成器生成的每个批次的大小
                                          seed=42)#参数指定了随机数生成器的种子,用于生成随机打乱的数据。

X_val = img_data_gen.flow_from_dataframe(dataframe=X_val,
                                          x_col='FilePaths',
                                          y_col='Labels',
                                          target_size=IMG_SIZE,
                                          color_mode='rgb',
                                          class_mode='categorical',
                                          batch_size=BATCH_SIZE,
                                          seed=42)
X_test = img_data_gen.flow_from_dataframe(dataframe=X_test,
                                          x_col='FilePaths',
                                          y_col='Labels',
                                          target_size=IMG_SIZE,
                                          color_mode='rgb',
                                          class_mode='categorical',
                                          batch_size=BATCH_SIZE,
                                          seed=42)

#查看经过处理的图片以及它的binary标签
fit, ax = plt.subplots(nrows=2, ncols=3, figsize=(13,7))

for i, a in enumerate(ax.flat):
    img, label = X_train.next()
    a.imshow(img[0],)
    a.set_title(label[0])

plt.tight_layout()
plt.show()

#-- 创建卷积神经网络

#创建输入层,卷积层,池化层,全连接层,输出层
model = Sequential()

# 1层

#Output shape计算公式:(150-3+1=148
#param参数数量:32*3*3*3+32=896
model.add(Conv2D(
    filters=32, #卷积核个数32个
    kernel_size= (3,3) , 
    input_shape=(150,150,3) , 
))
model.add(Activation('relu'))
model.add(MaxPooling2D(
    pool_size=(2,2), # 输出图片尺寸:148/2=74*74
    strides=2,
))
#CNN 2层
model.add(Conv2D(
    filters=64,  #Output (50,50,64)
    kernel_size=(3,3),
))
model.add(Activation('relu'))
model.add(MaxPooling2D(  #Output(25,25,64)
    pool_size=(2,2),
    strides=2,
))

#CNN 3层
model.add(Conv2D(
    filters=128,  #Output (50,50,64)
    kernel_size=(3,3),
))
model.add(Activation('relu'))
model.add(MaxPooling2D(  #Output(25,25,64)
    pool_size=(2,2),
    strides=2,
))
#全连层1
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))

#全连层2
model.add(Dense(256))
model.add(Activation('relu'))

model.add(Dense(5))#添加5个节点的连接层
model.add(Activation('softmax'))#添加激活层,softmax将输入的一个向量转换为概率分布


#编译模型
model.compile(optimizer=optimizers.RMSprop(lr=1e-4),
               loss="categorical_crossentropy", 
               metrics=["accuracy"])
model.summary()

#训练模型
h1 = model.fit(X_train, validation_data=X_val,
               epochs=30, )
#保存模型
model.save('lwl41.h5')

#绘制损失和精度曲线图
accuracy = h1.history['accuracy']
loss = h1.history['loss']
val_loss = h1.history['val_loss']
val_accuracy = h1.history['val_accuracy']
plt.figure(figsize=(17, 7))
plt.subplot(2, 2, 1)
plt.plot(range(30), accuracy,'bo', label='Training Accuracy')
plt.plot(range(30), val_accuracy, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Accuracy : Training vs. Validation ')
plt.subplot(2, 2, 2)
plt.plot(range(30), loss,'bo' ,label='Training Loss')
plt.plot(range(30), val_loss, label='Validation Loss')
plt.title('Loss : Training vs. Validation ')
plt.legend(loc='upper right')
plt.show()

#预测
from PIL import Image
from keras.utils import image_utils
def con(file,outdir,w=150,h=150):
    img1=Image.open(file)
    img2=img1.resize((w,h),Image.BILINEAR)
    img2.save(os.path.join(outdir,os.path.basename(file)))
file='E:/Landscape Classification/Testing Data/Mountain/Mountain-Test (7).jpeg'
con(file,'E:/')
model=load_model('lwl41.h5')
img_path='E:/Landscape Classification/Testing Data/Mountain/Mountain-Test (7).jpeg'
img = image_utils.load_img(img_path,target_size=(150,150))
img = image_utils.img_to_array(img)
img = np.expand_dims(img, axis=0)
out = model.predict(img)
print(out)
dict={'0':'海滩','1':'冰川','2':'森林','3':'沙漠','4':'山脉'}
for i in range(5):
    if out[0][i]>0.5:
        print(dict[str(i)])
img=plt.imread('E:/Landscape Classification/Testing Data/Mountain/Mountain-Test (7).jpeg')
plt.imshow(img)

总结:
本次机器学习耗时较长时间,中途遇到很多问题,数据集的处理,模型的建立,训练模型过程中出现过拟合,数据增强的应用等等,通过本次课程设计,加深了我对机器学习多分类以及其标签学习的理解,了解了景观识别项目的整体流程,包括数据预处理、训练模型、测试模型等。掌握了数据增强的概念及其在训练模型中的应用方法。
改进建议是:
尽量使用更多的数据,以提高模型的准确性。
尝试使用更多的模型算法,以提高模型的性能。
尝试使用更多的图像预处理技术,来提升模型的性能。

标签:plt,机器,img,景观,add,import,model,识别,size
From: https://www.cnblogs.com/long-11/p/17001032.html

相关文章

  • 机器学习-----心律失常分类
    Python机器学习--------心率失常分类一、选题的背景介绍因为随着我国逐渐步入老龄化社会还有年轻人喜欢熬夜玩游戏,心血管疾病患者持续增加,使得心脏监护系统需求也在不断......
  • 【机器学习】李宏毅——Domain Adaptation(领域自适应)
    在前面介绍的模型中,一般我们都会假设训练资料和测试资料符合相同的分布,这样模型才能够有较好的效果。而如果训练资料和测试资料是来自于不同的分布,这样就会让模型在测试集......
  • Python | Opencv的人脸检测和人类识别
    ✅作者简介:热爱科研的算法开发者,Python、Matlab项目可交流、沟通、学习。......
  • 机器学习
                      ......
  • 机器学习——果蔬分类
    一、选题的背景为了实现对水果和蔬菜的分类识别,收集了香蕉、苹果、梨、葡萄、橙子、猕猴桃、西瓜、石榴、菠萝、芒果、黄瓜、胡萝卜、辣椒、洋葱、马铃薯、柠檬、番茄、萝......
  • 机器学习肝炎预测模型machine learning for hepatitis prediction model
    作者Toby,来自​​机器学习肝炎预测模型​​肝炎是由细菌、virus、寄生虫、酒精、药物、化学物质、自身免疫等多种致病因素引起的肝脏炎症的统称。儿童及成年人均可患病,virus......
  • 机器学习-企业破产预测
    企业破产预测选题背景企业破产是商品经济的必然产物.在社会主义商品经济条件下,企业破产也是一种客观存在的经济现象.新中国的第一部《企业破产法》已经诞生,它的实施必......
  • 【机器学习】李宏毅——Adversarial Attack(对抗攻击)
    研究这个方向的动机,是因为在将神经网络模型应用于实际场景时,它仅仅拥有较高的正确率是不够的,例如在异常检测中、垃圾邮件分类等等场景,那些负类样本也会想尽办法来“欺骗”......
  • 创建脚手架遇到代理问题和npm无法识别问题
    1.如果安装脚手架过程时,提示没有配置代理相关词语。那么你的node.js没有安装在C盘,导致权限不够高解决方法:找到node.js文件夹,右键属性,点击安全,点击高级(在然后就可以开始你......
  • 【python机器学习课程设计】狗的品种识别
    一、选题背景近年来,随着生活水平的提高,狗作为参加的宠物品种慢慢步入了中国千万家庭中。而狗的品种识别案例可以帮助我们了解狗品种的差异特征,并使用机器学习技术来分析这......