基于RNN循环神经网络、LSTM、GRU和改进GRU空中目标意图识别实现(附源码+数据集+程序说明)

文章目录


前言

目标战术意图由一系列动作实现,因此目标状态呈现时序动态变化特征。针对目标意图识别问题的特点,本文是对基于循环神经网络进行意图识别的实现。现有的用于复杂环境下对目标意图识别方法主要有模板匹配、证据推理、贝叶斯网络和神经网络等。

数据集

类别:预警、反辐射、远距离支援干扰、轰炸
数据量够大,不用担心


基于RNN(循环神经网络)空中目标意图识别-kereas完整源码+数据集+评估指标曲线绘制+程序说明及注释

下载链接https://download.youkuaiyun.com/download/DeepLearning_/89939090

基于LSTM循环神经网络空中目标意图识别-kereas完整源码+数据集+评估指标曲线绘制+程序说明及注释

下载链接https://download.youkuaiyun.com/download/DeepLearning_/89939097

基于GRU循环神经网络空中目标意图识别-kereas完整源码+数据集+评估指标曲线绘制+程序说明及注释

下载链接https://download.youkuaiyun.com/download/DeepLearning_/89938743

基于改进GRU(添加注意力机制)循环神经网络空中目标意图识别-kereas完整源码+数据集+评估指标曲线绘制+程序说明及注释

下载链接https://download.youkuaiyun.com/download/DeepLearning_/89939093

提示:以下是本篇文章正文内容,下面案例可供参考

一、引入库

#!/usr/bin/env python
# coding: utf-8

import tensorflow as tf
import keras.backend as K
from keras.callbacks import ReduceLROnPlateau
from keras.layers import Multiply
from keras.layers.core import *
from keras.layers.recurrent import LSTM
from keras.layers.recurrent import GRU
from keras.layers.recurrent import SimpleRNN
from keras.layers import Bidirectional
from keras.models import *
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
import xml.etree.ElementTree as ET
import matplotlib.pyplot as plt
from collections import Counter
import pandas as pd
import numpy as np
import os
import time
import random
import math

二、程序主干

1.attention层的定义

代码如下(示例):

def attention_3d_block(inputs,SINGLE_ATTENTION_VECTOR):
    input_dim = int(inputs.shape[2])
    a = Permute((2, 1))(inputs)#(time_steps, input_dim)维度转置
    a = Reshape((input_dim, TIME_STEPS))(a) 
    a = Dense(TIME_STEPS, activation='softmax')(a)#计算每个特征的权重
    if SINGLE_ATTENTION_VECTOR:#是否共享注意力权重
        a = Lambda(lambda x: K.mean(x, axis=1), name='dim_reduction')(a)
        a = RepeatVector(input_dim)(a)
    a_probs = Permute((2, 1), name='attention_vec')(a)
    output_attention_mul = Multiply()([inputs, a_probs])
    return output_attention_mul

2.在GRU层后添加Attention层

代码如下(示例):

def modelAttentionAfterGRU():
    K.clear_session() #清除之前的模型
    inputs = Input(shape=(TIME_STEPS, INPUT_DIM,))
    GRU_out = GRU(units, return_sequences=True)(inputs)

    attention_mul = Flatten()(attention_mul)
    output = Dense(3, activation='softmax')(attention_mul)
    model = Model(input=[inputs], output=output)
    return model

3.在双向GRU层后添加Attention层

def modelAttentionBiLSTM():
    K.clear_session()
    inputs = Input(shape=(TIME_STEPS, INPUT_DIM,))
    units = 128
    attention_mul = Flatten()(attention_mul)
    inputs= Dense(3, activativa='softmax')(attention_mul)
    model = Model(input=[inputs], output=output)
    return model
def getData(data_length):
    x_data = []
    label = []
    specimen_size = 1500 #设定输入序列长度,只取前1500个数据点
    #特征值取值范围,用于归一化处理
    d_max = 8922;d_min = 0;d_gap = d_max-d_min
    c_max = 29;c_min = 0;c_gap = c_max-c_min
    p = getDocumentList('./SCENARIO_DATA')
    for pp in p:
        q = getDocumentList('./SCENARIO_DATA/%s'%(pp))
        for qq in q:
            tree = ET.parse('./SCENARIO_DATA/%s/%s'%(pp,qq))
            root = tree.getroot()#获取xml文档的根节点
            if (root[0].tag=='轰炸' or root[0].tag=='反辐射' or root[0].tag=='护航'):
                x_signal = [ [root[0][i].attrib[j] for j in ['x','y','z']] for i in range(len(root[0])) if root[0][i].tag=='数据' and i<specimen_size]
                if(len(x_signal)>1000):
                    x_signal=list(np.array(x_signal,dtype=float))
                    d0 = 0
                    x_feature = []
                    if(len(x_signal)<data_length):
                        data_length = len(x_signal)
                    for i in range(0,data_length-5,3):
                        d = 0
                        for j in range(i,i+5):
                            dx = math.pow(x_signal[j+1][0]-x_signal[j][0],2)
                            dy = math.pow(x_signal[j+1][1]-x_signal[j][1],2)
                            dz = math.pow(x_signal[j+1][2]-x_signal[j][2],2)
                            d += math.sqrt(dx+dy+dz)
                        a = (d/15-d0/15)/6
                        d0 = d #保留用于下一段加速度的计算
                        #使用窗口中的三个点构建三角形拟合二次曲线
                        len1 = math.sqrt( math.pow(x_signal[i+2][0]-x_signal[i][0],2)+math.pow(x_signal[i+2][1]-x_signal[i][1],2)+math.pow(x_signal[i+2][2]-x_signal[i][2],2) )
                        len2 = math.sqrt( math.pow(x_signal[i+2][0]-x_signal[i+4][0],2)+math.pow(x_signal[i+2][1]-x_signal[i+4][1],2)+math.pow(x_signal[i+2][2]-x_signal[i+4][2],2) )
                        len3 = math.sqrt( math.pow(x_signal[i+4][0]-x_signal[i+2][0],2)+math.pow(x_signal[i+4][1]-x_signal[i][1],2)+math.pow(x_signal[i+4][2]-x_signal[i][2],2) )
                        if( len1==0 or len2==0 or len3==0):
                            c = 0
                        else:
                            half = (len1+len2+len3)/2
                            if(half<len1 or half<len2 or half<len3):
                                c = 0
                            else:
                                h = 2*math.sqrt( half*(half-len1)*(half-len2)*(half-len3) )/len3
                                xh = math.sqrt(len1*len1-h*h)
                                poly = np.polyfit([0,xh,len3],[1,h,0],deg=2)
                                c = abs(poly[0])
                        x_feature.append([(d-d_min)/d_gap,(a-a_min)/a_gap,(c-c_min)/c_gap])#归一化处理
    
                    if len(x_feature)<500:
                        for j in range(500-len(x_feature)):
                            x_feature.append([0,0,0])

                    if root[0].tag=='轰炸':
                        label.append(0)
                        x_data.append(x_feature)
                    elif root[0].tag=='反辐射':
                        label.append(1)
                        x_data.append(x_feature)
                    elif root[0].tag=='护航':
                        label.append(2)
                        x_data.append(x_feature)

    x_data=np.array(x_data,dtype=float)
    #print(Counter(label))
    return x_data,label

INPUT_DIM = 3 #输入特征维度
TIME_STEPS = 500 #输入序列长度

if __name__ == '__main__':
    
    x_data,y_data = getData(1500)
    training_time = []
    weighted_error_rate = []
    reduce_lr =  tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss',factor=0.1,verbose=1,min_lr=0.0001,patience=10)#min_lr=0.0001
    for i_test in range(5):
        x_train,x_test, y_train,y_test= train_test_split(x_data, y_data, test_size=0.2, random_state=i_test, shuffle=True, stratify=y_data)
        start = time.time()
        #m = modelGRU() 
        m.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
        m.summary()
        historyGRU = m.fit([x_train], y_train, epochs=200, batch_size=32, validation_split=0.1,shuffle=True,callbacks=[reduce_lr])
        end = time.time()
        training_time.append(end-start)
        pred = m.predict(x_test)
        weighted_error_rate.append(weighted_error_rate_i)
    print("training_time: %0.3f s" % (np.mean(training_time)))  #均值和方差
    print("weighted_error_rate: %0.3f (± %0.3f)" % (np.mean(weighted_error_rate), np.var(weighted_error_rate))) #均值和方差

    #模型训练时的Loss可视化
    accGRU = historyGRU.history['accuracy']  # 训练集准确率
    lossGRU = historyGRU.history['loss']  # 训练集损失
    plt.plot(lossGRU, label='GRU')
    #plt.title('Training Loss')
    #使用中文图注
    plt.rcParams['font.sans-serif']=['SimHei']
    plt.rcParams['axes.unicode_minus']=False
    plt.xlabel('训练步数')
    plt.ylabel('损失')
    plt.legend()
    #plt.savefig('./训练损失.jpg')
    plt.show()

三、各个函数的意义如下

1、getData()函数负责读取xml文件,并处理成数据序列及对应的标签序列。参数data_length决定了所读取序列的长度。

2、getDocumentList()函数用于辅助getData()函数进行数据读取。

3、modelRNN()、modelLSTM()、modelGRU()都用于实现最基本的循环神经网络模型,只是所用神经元类型不同,分别为最基础的RNN、LSTM和GRU。

4、attention_3d_block()函数定义了Attention层,参数SINGLE_ATTENTION_VECTOR为True时共享注意力权重。注意力权重共享是说,我们的特征在一个时间结点上是多维的,即有可能是多个特征随时间变换一起发生了变换,那对应的注意力算出来也是多维的。此时,是多维特征共享一个注意力权重,还是每一维特征单独有一个注意力权重呢?当SINGLE_ATTENTION_VECTOR=True时,Lambda层将原本多维的注意力权重取平均,RepeatVector层再按特征维度复制粘贴,那么每一维特征的权重都是一样的了,也就是所说的共享一个注意力。

5、modelAttentionAfterGRU()用于实现在GRU层之后添加Attention层的模型。modelAttentionBiLSTM()用于实现在双向GRU层之后添加Attention层的模型。

6、全局变量INPUT_DIM表示输入特征的维度;TIME_STEPS = 500 表示输入到神经网络层序列的长度。

7、主函数中给出了一个示例:读取数据,划分训练集和测试集,多次训练神经网络模型进行交叉验证,计算加权错误率Weighted Error Rate和训练模型所用时间,最后将模型训练过程中的Loss(也可换成其他指标)变化可视化。

### 使用 BiLSTM 进行意图识别 在自然语言处理领域,BiLSTM(双向长短期记忆网络)是一种非常有效的工具,尤其适用于捕捉序列数据中的上下文信息。为了实现基于 BiLSTM意图识别系统,可以从以下几个方面着手: #### 数据预处理 首先,需要准备并清理训练数据集。这一步骤涉及去除无关字符、分词、标注标签等工作。对于意图识别来说,每条语句会被标记上对应的类别或动作。 ```python import pandas as pd from sklearn.model_selection import train_test_split # 假设有一个CSV文件作为输入源 data = pd.read_csv('intents_data.csv') sentences, labels = data['text'].tolist(), data['label'].tolist() # 划分为训练集测试集 X_train, X_test, y_train, y_test = train_test_split(sentences, labels, test_size=0.2) ``` #### 特征工程 接着是对文本进行向量化操作。常用的方法有词袋模型(Bag of Words),TF-IDF 或者更先进的 Word Embedding 技术如 GloVe BERT embeddings。这里推荐使用预训练好的嵌入层来初始化 LSTM 输入端的权重矩阵[^3]。 ```python from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences tokenizer = Tokenizer(num_words=10000, oov_token="<OOV>") tokenizer.fit_on_texts(X_train) sequences = tokenizer.texts_to_sequences(X_train) padded_sequences = pad_sequences(sequences, padding='post') vocab_size = len(tokenizer.word_index) + 1 embedding_dim = 16 max_length = max([len(x.split()) for x in sentences]) trunc_type='post' padding_type='post' word_index = tokenizer.word_index num_classes = len(set(labels)) ``` #### 构建 BiLSTM 模型结构 定义神经网络架构时,采用两层堆叠的方式构建 BiLSTM 层,并添加 Dense 输出层来进行分类预测。Dropout 可以帮助防止过拟合现象的发生。 ```python from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, Bidirectional, LSTM, Dropout, Dense model = Sequential([ Embedding(input_dim=vocab_size, output_dim=embedding_dim, input_length=max_length), Bidirectional(LSTM(units=64, return_sequences=True)), Dropout(rate=0.5), Bidirectional(LSTM(units=64)), Dropout(rate=0.5), Dense(64, activation='relu'), Dropout(rate=0.5), Dense(num_classes, activation='softmax')]) model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy']) print(model.summary()) ``` #### 训练与评估 最后,在划分好训练集之后就可以开始训练过程了。经过多次迭代优化参数直至收敛得到较好的泛化能力。完成后还可以进一步调整超参提高精度。 ```python history = model.fit(padded_sequences, np.array(y_train), epochs=10, validation_split=0.2) test_seq = tokenizer.texts_to_sequences(X_test) padded_test_seq = pad_sequences(test_seq, maxlen=max_length, truncating=trunc_type, padding=padding_type) loss, accuracy = model.evaluate(padded_test_seq, np.array(y_test)) print(f'Test Accuracy: {accuracy}') ```
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

onnx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值