GenghisYoung233 / Gaofen-Batch

Gaofen Batch,基于GDAL和Electron的国产卫星影像预处理工具
GNU General Public License v3.0
55 stars 18 forks source link

时间序列影像分类 #2

Open rongtongxueya opened 1 year ago

rongtongxueya commented 1 year ago

我可能要冒昧的请教您,我看了您上一个代码关于高分影像农作物分类的代码,我想请教您这个时间序列的数据集是如何制作的呢?难道是一整年度的影像对应一个shp的分类样本数据吗?难道一整年中shp对应的块种类不会变吗?上个代码我debug之后是(1994,34,3),我想询问一下您这个1994和34对应的是?1994代表每个类别都是1994个样本吗,一共所有tif中的改类别的块数吗?34是时间序列34张tif吗?

GenghisYoung233 commented 1 year ago

一直没有看issue,不好意思。我针对这几个问题分别回答。

  1. 关于数据集的制作,核心函数是generate_training_data,调用rasterio.mask提取目标区域的影像值。
  2. 脚本假设给定的.shp文件在整个时间序列中是恒定的。换句话说,如果在一年的时间内某个地区的地物类型发生了变化,那么这个变化在当前的实现中是不会被捕获的。在我最初的实验,作物在一个生育周期内(不是一整年)所有数据被合成为时间序列影像,所以没有考虑作物种植结构改变的情况。
  3. 我猜不到(1994,34,3)是指的哪一步的结果。在生成的_train_dataset.csv表格文件里,高度H = 提取像元个数,宽度W = 时序影像数量 单景影像波段数,就是说,如果是34张3波段tif影像叠加后的时序影像,.shp文件覆盖了1994个像元,那么最后的csv的尺寸为(1994, 103)。其中csv的第一列为作物的class value。
rongtongxueya commented 1 year ago

不好意思,我又来了,我详细的阅读了您的代码之后,我一直困惑一个参数“sequencelength”,我看您回复我的这个“如果是 34 张 3 波段tif 影像截取后的相关影像,.shp 文件覆盖了 1994 个像元,那么最后的 csv 的尺寸为(1994, 103)。”这应该是整个周期内的所有影像在波段维度上进行了叠加,但是如果是叠加之后呢数据为啥会变成NTD,N是样本数量1994,D是102,那这个T应该是多少呢 def get_model(model, ndims, num_classes, sequencelength, device, hyperparameter): if model == "OmniScaleCNN": model = OmniScaleCNN(input_dim=ndims, num_classes=num_classes, sequencelength=sequencelength, hyperparameter).to(device) elif model == "LSTM": model = LSTM(input_dim=ndims, num_classes=num_classes, hyperparameter).to(device) elif model == "StarRNN": model = StarRNN(input_dim=ndims, num_classes=num_classes, bidirectional=False, use_batchnorm=False, use_layernorm=True, device=device, hyperparameter).to(device)

elif model == "InceptionTime":

#     model = InceptionTime(input_dim=ndims, num_classes=num_classes, device=device,
#                           **hyperparameter).to(device)
elif model == "MSResNet":
    model = MSResNet(input_dim=ndims, num_classes=num_classes, **hyperparameter).to(device)
elif model == "TransformerModel":
    model = TransformerModel(input_dim=ndims, num_classes=num_classes, activation="relu", **hyperparameter).to(device)
elif model == "TempCNN":
    model = TempCNN(input_dim=ndims, num_classes=num_classes, sequencelength=sequencelength, **hyperparameter).to(device)
else:
    raise ValueError("invalid model argument.")
#完成模型的初始化
return model
DoomfistOnly commented 1 year ago

训练模型涉及到两次维度转换,第一次是生成数据集、第二次是数据集的训练。在生成数据集时,因为csv表格只支持二维数据,所以将影像的数量(即时间序列的长度)与单个影像的波段数融合成一个维度。然后在数据集的训练中,又将这个维度拆分成影像的数量与单个影像的波段数。所以这里的sequencelength代表的是影像的数量。

rongtongxueya commented 1 year ago

非常感谢您愿意回答我。那其实我没明白,你看这个训练数据,那其实在波段维度进行了叠加之后,sequencelength直接设置成1也可以吧,直接不用转换成C*T了,这个T直接设置成1也可以吗还是那样会造成一些不好的结果(比如影响精度等)

GenghisYoung233 commented 1 year ago

哈哈,这就不是我能回答的了。这个库的核心是MarcCoruBreizhCrops库中的时间序列模型,我fork过来之后加入了部分数据处理的代码,来适配时间序列模型的输入输出格式,至于为什么要转换成C*T,应该跟模型的训练机制有关。