python遥感影像分类代码_【博客翻译】使用 Python Tensorflow 实现简单的神经网络卫星遥感影像分类...
Landsat 5 多光谱数据分类指导手册原作者:Pratyush Tripathy
翻译:荆雪涵
姐妹篇雪涵:【博客翻译】CNN 与中分辨率遥感影像分类zhuanlan.zhihu.com
深度学习在很多邻域使用,解决了许多复杂的问题,在空间分析领域也不例外。既然你已经点进来了,那估计你对遥感影像以及Landsat 5 TM数据有一定的了解。我们只需要了解一下机器学习的基础知识,便可以快速掌握这个教程的内容。如果你没有接触过机器学习,其实用一句话说就是,建立一系列特征值X与目标值Y的联系。我们通过提供带有标签的训练数据,从而习得X和Y之间的联系,最后我们可以使用训练好的模型预测那些还没有标签的数据。
基于卫星数据学术问题
卫星影像中的一些土地类别是比较难区分的,比如城市用地/裸地/矿区,这些地物的光谱值十分的相似,所以过去几十年,区分相似光谱的地物一直是一个难题。传统的监督分类法或者非监督分类法,虽然在分类领域十分常见,但是也带来一些问题,我们看一下下面的例子。
上图,如果我们用一条垂线来分割这张图片,我们将这条垂线从左往右移动,如果我们规定垂线右边都归为房子类,很显然这个分类方法是有问题的,因为房子和树木的分布并没有一个明确的边界。所以我们是无法用一条直线来进行分类的。但是这并不意味我们无法将上面这张图片正确分类。
在上面这张动图中,我们分别用蓝线,红线,绿线对树木和房子进行分类,我们规定线的右边为房子类别。如果用红线分类的话,绝大多的房子都被正确分类,只有一个房子没有被正确分类,并且还有一颗树木被错误的归为了房子类别。如果我们用蓝线的话,我们就可以正确分类所有的房子,但是会有三棵树被错误的分类。在使用蓝线分类的例子中,蓝线将所有的房子都正确分类,我们称之为高召回(Recall),但是在房子类别中,有三颗树木被错误分类,我们称为低精度(Precision)。类似的,如果我们用绿线分类,绿线的右边都是房子,我们就称为高精度(Precision)不过召回率就会低一些,因为有三个房子没有被识别到。很多时候,我们都要进行精度率和召回率之间的博弈。
上面树木和房子分类的例子,其实就是我们对遥感影像进行土地分类的一个类别。所以每一幅遥感影像的分类重点是要具体问题具体分析的。举个例子,如果你要保证所有的城市用地都被正确归类,那么你的最终结果中就会出现其他一些和城市用地光谱类似的地物,也就是说你需要一个高召回率的分类器。反过来看,如果你的最终结果不可以出现出城市用地外的其他地物,你就需要一个高精度的分类器。
本文使用的数据
我们将使用Landsat 5 TM数据的波段2-波段7,共计六个波段的数据,我们的目标是从遥感影像中区分出城市用地(Built-up)。2011年印度班加罗尔的Landsat 5 的多光谱数据以及城市用地二值图层,将被用作训练数据和测试数据。我们将使用2011年海得拉巴的数据来进行预测。
因为我们使用了标注数据,所以我们的方法称为监督机器学习。
我们将使用Google的Tensorflow框架,并使用Python语言构建一个神经网络。我们需要以下几个库。pytrsgis 用于读写GeoTIFF格式的数据
scikit-learn 用于数据预处理以及精度检测
numpy 用于基本数组操作
首先将影像放入一个文件夹里,使用如下代码读取GeoTIFF影像图片。
import os
from pyrsgis import raster
os.chdir("E:\\yourDirectoryName")
mxBangalore = 'l5_Bangalore2011_raw.tif'
builtupBangalore = 'l5_Bangalore2011_builtup.tif'
mxHyderabad = 'l5_Hyderabad2011_raw.tif'
# Read the rasters as array
ds1, featuresBangalore = raster.read(mxBangalore, bands='all')
ds2, labelBangalore = raster.read(builtupBangalore, bands=1)
ds3, featuresHyderabad = raster.read(mxHyderabad, bands='all')
代码中的raster模块可以同时读取GeoTIFF影像的地理坐标以及DN值,并且存放于numpy数组中。关于pyrsgis的详细介绍可以参考此页面。
使用如下代码可以将数组的尺寸打印出来。
print("Bangalore multispectral image shape: ", featuresBangalore.shape)
print("Bangalore binary built-up image shape: ", labelBangalore.shape)
print("Hyderabad multispectral image shape: ", featuresHyderabad.shape)
Bangalore multispectral image shape: 6, 2054, 2044
Bangalore binary built-up image shape: 2054, 2044
Hyderabad multispectral image shape: 6, 1318, 1056
从上面的输出结果可以看出班加罗尔的两幅数据的行列数是一致的,都是2054*2044。两幅遥感影像数据波段数也都为6。模型会根据所有波段的DN值来判断像元是否归为城市用地,所以遥感影像的波段数必须保持一致,波段顺序也必须一致。
下面我们要将我们的遥感影像数据转化为一个二维数组,这样才可以输入到机器学习的模型中去。数组的每一行分别代表六个波段的DN值。我们使用pyrsgis中的convert模块可以实现数转化。见下图。
from pyrsgis.convert import changeDimension
featuresBangalore = changeDimension(featuresBangalore)
labelBangalore = changeDimension (labelBangalore)
featuresHyderabad = changeDimension(featuresHyderabad)
nBands = featuresBangalore.shape[1]
labelBangalore = (labelBangalore == 1).astype(int)
print("Bangalore multispectral image shape: ", featuresBangalore.shape)
print("Bangalore binary built-up image shape: ", labelBangalore.shape)
print("Hyderabad multispectral image shape: ", featuresHyderabad.shape)
Bangalore multispectral image shape: 4198376, 6
Bangalore binary built-up image shape: 4198376
Hyderabad multispectral image shape: 1391808, 6
上面代码的第七行,我们提取了数值为1的像元,这样是为了避免数据中出现NoData的像元,NoData通常是极大或者极小的数值,会对训练过程造成影像。
我们会将数据分组,分别用于训练和验证。这样我们才可以说训练出来模型同样适用于预测新的数据。否则,模型就会过适(Overfitting)。
from sklearn.model_selection import train_test_split
xTrain, xTest, yTrain, yTest = train_test_split(featuresBangalore, labelBangalore, test_size=0.4, random_state=42)
print(xTrain.shape)
print(yTrain.shape)
print(xTest.shape)
print(yTest.shape)
(2519025, 6)
(2519025,)
(1679351, 6)
(1679351,)
上面代码中的test_size=0.4代表我们把数据分开,60%为训练数据,40%为验证数据。
许多机器学习模型都需要将数据进行归一化,也就是说我们将DN值的范围变化到0-1之间。
需要注意的是,归一化通常需要计算数据实际的最大最小值来确定数据的范围。不过这里为了简化过程我们使用0-255作为我们数据的范围。
我们还需要将寻来你数据数组从二维变化成三维,新数组的每一行将代表一个像元的信息。
```python
# Normalise the data
xTrain = xTrain / 255.0
xTest = xTest / 255.0
featuresHyderabad = featuresHyderabad / 255.0
# Reshape the data
xTrain = xTrain.reshape((xTrain.shape[0], 1, xTrain.shape[1]))
xTest = xTest.reshape((xTest.shape[0], 1, xTest.shape[1]))
featuresHyderabad = featuresHyderabad.reshape((featuresHyderabad.shape[0], 1, featuresHyderabad.shape[1]))
# Print the shape of reshaped data
print(xTrain.shape, xTest.shape, featuresHyderabad.shape)
(2519025, 1, 6) (1679351, 1, 6) (1391808, 1, 6)
上述准备工作完成后,我们可以使用Keras库建立模型。我们会使用一个顺序模型(Sequential Model),顾名思义就是将神经网络层依次按顺序连接。我们有一个输入数据层,节点数等于波段数。然后是一个节点为14的reLu激活函数层。最后是节点数为2的softmax激活函数层,因为我们最终的预测结果为两类:城市用地,非城市用地。激活函数的更多内容可以参考此处。
from tensorflow import keras
# Define the parameters of the model
model = keras.Sequential([
keras.layers.Flatten(input_shape=(1, nBands)),
keras.layers.Dense(14, activation='relu'),
keras.layers.Dense(2, activation='softmax')])
# Define the accuracy metrics and parameters
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
# Run the model
model.fit(xTrain, yTrain, epochs=2)
从代码中的第十行看出,我们的模型使用了adam优化器(其他的优化器可以参考这里),损失函数类型选择categorical-sparse-crossentropy(类别稀疏交叉熵),具体含义可以参考这里。最后我们使用准确度(accuracy)来衡量模型的表现。
最后我们使用训练数据,训练两个循环。模型的训练时间取决于数据量以及电脑性能。训练中可以看到如下消息。
训练完成后,我们将使用测试数据来验证模型的预测精度。代码如下,
from sklearn.metrics import confusion_matrix, precision_score, recall_score
# Predict for test data
yTestPredicted = model.predict(xTest)
yTestPredicted = yTestPredicted[:,1]
# Calculate and display the error metrics
yTestPredicted = (yTestPredicted>0.5).astype(int)
cMatrix = confusion_matrix(yTest, yTestPredicted)
pScore = precision_score(yTest, yTestPredicted)
rScore = recall_score(yTest, yTestPredicted)
print("Confusion matrix: for 14 nodes\n", cMatrix)
print("\nP-Score:%.3f, R-Score:%.3f" % (pScore, rScore))
softmax函数会计算每一类别的概率。之前代码的第六行我们只提取了城市用地类别。空间分析模型的优劣不像其他机器学习模型那么的好评判,我们通常要将位置信息也考虑进去,而不是简单的把误差叠加。因此,我们将使用混淆矩阵,召回率,精确率等一系列参数来评估模型表现。
从混淆矩阵中可以看出,有上千个城市用地像元被归类为非城市用地类别,但是这一部分的比例相对数据的总量来说是微不足道的。测试数据的精确度和召回率超过了0.8.
你可以尝试花时间将模型多训练几次,从而找到合适的隐藏层个数,合适的隐藏层节点个数合适的训练循环次数。你还可以使用NDBI或者NDVI数据作为输入训练数据。当我们训练好一个合适精度的模型后,我们可以使用这个模型来预测一张新的GeoTIFF遥感图。我们后续只需将模型稍作修改,还可以用于其他的应用。
predicted = model.predict(featuresHyderabad)
predicted = predicted[:,1]
#Export raster
prediction = np.reshape(predicted, (ds.RasterYSize, ds.RasterXSize))
outFile = 'Hyderabad_2011_BuiltupNN_predicted.tif'
raster.export(prediction, ds3, filename=outFile, dtype='float')
需要注意的是,预测后的结果是连续的概率值,并不是一张0或1的二值图。不过使用GIS软件,设置一个阈值,可以很快的将概率数值二值化。得到下面右图的结果。
模型的精度已经在上文评估过了,不过你可以对新数据的预测结果在进行一次评估。遥感影像分类除了之前提到的一些难点,季节,地域,光谱特征多样性也同样会对模型带来一些不确定的影像。
本文介绍了很简单的神经网络,较为复杂的卷积神经网同样被用来做遥感分类,你可以阅读本文的姊妹篇。
文中的代码数据可以打开此链接下载。
python遥感影像分类代码_【博客翻译】使用 Python Tensorflow 实现简单的神经网络卫星遥感影像分类...相关推荐
- python执行一段代码_我发现了个 Python 黑魔法,执行任意代码都会自动念上一段 『平安经』...
最近的"平安经"可谓是引起了不小的风波啊. 作为一个正儿八经的程序员,最害怕的就是自己的代码上线出现各种各样的 BUG. 为此明哥就研究了一下,如何在你执行任意 Python 代码 ...
- python迷宫小游戏代码_课内资源 - 基于python实现的迷宫游戏
一.项目概述与编译环境 本次大作业选题为题目2,即小兔子找胡萝卜的迷宫问题,最终完成开发的游戏名为Caveman and Treasure(穴居人寻宝),游戏整体界面如下: 该项目在windows下编 ...
- python调用第三方软件发信代码_【IT专家】python调用第三方邮件接口
本文由我司收集整编,推荐下载,如有疑问,请与我司联系 python 调用第三方邮件接口 2017/08/10 1 单线程发送 #!/usr/bin/env python# -*- coding: UT ...
- Python实现自动推本地github博客到远程仓库
Python实现自动推本地github博客到远程仓库 以前的简单版本 通过python中的os模块操作系统命令 详情可参考:Python实现一行代码推本地git到远程仓库 升级版本 本次加入了监听文件 ...
- python个人博客搭建说明书_技术分享|利用Python Django一步步搭建个人博客(二)...
原标题:技术分享|利用Python Django一步步搭建个人博客(二) Hello,欢迎来到我们的"利用Python Django一步步搭建个人博客"系列的第二部分.在第一部分中 ...
- 用python搭建个人博客过程_技术分享|利用Python Django一步步搭建个人博客(四)...
您好,欢迎来到本期"利用Python Django一步步搭建个人博客"系列的第四部分.在上一篇教程中,我们学习了如何编写URL并将其映射到页面.在我们继续之前,我们需要做的一件事是 ...
- 程序员的黑科技_用代码回复博客
本文讲述了如何使用代码模拟HTTP请求来实现数据爬取.点赞.评论回复等功能. 内容包括: 1.抓包软件WireShark的简单使用方法 2.Python库requests的基本使用 3.一个用代码回复 ...
- python 论坛爬虫代码_python博客文章爬虫实现代码
例子,python网页爬虫实例,实现博客文章抓取的python爬虫. 代码示例: #!/usr/bin/python #-*-coding:utf-8-*- # JCrawler # Author: ...
- python入门指南bl-Python Flask开源博客系统Bl
本博文在51CTO技术博客首发. 开源不易,Python良心之作,真心送给广大朋友,恳请给予支持,不胜感激! 大家可以从下面的地址中去体验Blog_mini的功能,我把副本部署在了腾讯云上供大家使用: ...
最新文章
- HDU ACM 1267 下沙的沙子有几粒?-gt;DP
- 剑指Offer 56 数组中数字出现的次数
- Java循环案例-求PI值
- [leetcode]160.相交链表
- 微软备战 RPA 市场,Power Platform,Ready GO!
- c# 读取记事本txt文档到DataTable中
- 山东省计算机考试无法报名,山东省2017年9月全国计算机等级考试报名事项公告...
- Vue使用nextTick的原因和作用
- poj 匈牙利二分匹配算法2239 Selecting Courses
- vba字典学习案例二
- 单细胞测序技术(single cell sequencing)
- 计算机广告设计毕业论文,广告设计毕业论文题目
- 轻量化网络(二)MobileNetV2: Inverted Residuals and Linear Bottlenecks
- 计算机图形学当前研究热点和发展方向,微软亚洲研究院网络图形组深入解释了图形学的现状、发展和未来...
- 智能井盖运用5G技术
- 什么是数字化和数字化转型?
- 名悦集团:汽车油耗突然飙升,或与这些驾驶习惯有关
- java开发工程师每天工作几小时,详细说明
- pandas数据分析读书笔记(三)
- 自己动手做sidebar