当前位置: 首页 > 科技观察

使用TensorFlow构建LSTM模型的详细教程

时间:2023-03-13 23:33:40 科技观察

目标本文的目标是解释可用于构建基本LSTM模型的简单代码。我不会讨论和分析结果。这只是为了让您开始编码。设置环境我将在本文中使用python来编写LSTM。环境搭建如下:推荐大家下载pycharmIDE,通过IDE将Tensorflow等所有库下载到你的项目中。您可以按照以下步骤设置您的环境。下载PyCharmIDE创建项目将Tensorflow、NumPy、SciPy、scikit-learn和Pandas下载到您的项目中。在项目中创建一个新的python文件如果您想手动创建环境,下面列出了python和Tensorflow的兼容版本以及您需要遵循本文的所有其他库。注意:不要使用与提到的不同版本的python,因为它可能与给定的Tensorflow版本不兼容。下载scikit-learn时,先下载NumPy和SciPy包。Python:3.6.5Tensorflow:1.9.0scikit-learn:0.19.1Pip:10.0.1NumPy:1.14.3Pandas:0.23.0SciPy:1.1.0我们到底下载了什么?Tensorflow:这是一个机器学习框架。Pandas:这是一个有助于分析并使数据准备变得容易的库。scikit-learn:这是一个机器学习库,具有各种机器学习算法,还实现了必要的辅助函数。NumPy:这是一个可以对多维数组和矩阵执行高级数学函数的库。SciPy:这是一个用于科学和技术计算的库。Pip:这是一个Python的包管理系统,可以安装和管理用Python编写的软件包。数据?对于本文,我们将使用在kaggle上发布的信用卡欺诈数据集。我们将使用此数据集来训练我们的LSTM模型,以对交易是欺诈性交易还是正常交易进行分类。您可以在此处获取数据集表单的csv文件(https://www.kaggle.com/mlg-ulb/creditcardfraud/version/2)。下载后,将其放入您的项目中以便于访问。如果您可以在开始使用数据之前浏览数据并阅读并理解每一列数据代表什么,这将很有帮助。注意:如果你在像“随机森林分类器”这样的机器学习算法上测试这个数据集,它会给出更好的分数,但我们可以使用这个数据集作为构建LSTM模型的起点。此外,您应该记住,该数据集具有非常高的类别不平衡。Python代码首先,让我们导入所需的Python库。importtensorflowastfiimportpandasasspdimportnumpyasnpfromtensorflow.contribiimportrnnfromsklearn.model_selectionimporttrain_test_splitfromsklearn.metricsimportf1_score,accuracy_score,recall_score,precision_score现在,我们必须将所有数据加载到我们的程序中。我们可以使用Pandasdata=pd.read_csv('creditcard.csv',skiprows=[0],header=None)上面的Python代码将从csv文件加载所有数据,省略标题行,因此加载数据现在看起来像这样:前5行数据接下来,我们将加载的数据拆分为标签和特征。features=data.iloc[:,1:30]labels=data.iloc[:,-1]如果浏览信用卡数据,您会注意到有31列。代码的第1行将数据从第1列(第0列)加载到第30列作为“特征”。正如kaggle中提到的,最后一列是指定交易是否存在欺诈行的那一列。因此,在第二行代码中,我们将最后一列中的数据作为标签加载。注意:我们将第0列排除在外,因为它仅提供有关交易顺序的信息,对我们的培训没有任何实际价值。我们可以根据数据出现的顺序保留数据的顺序。我们现在有了标签和特征,我们需要将它们分成训练集和测试集。我们可以使用scikit-learn的“traintestsplitfunction”。X_train,X_test,y_train,y_test=train_test_split(features,labels,test_size=0.2,shuffle=False,random_state=42)该函数自动将特征和标签拆分为测试集和训练集。“X_train”和“X_test”是特征的训练集和测试集,“y_test”和“y_train”是标签的训练集和测试集。参数“test_size”指定测试集应占整个数据集的20%。“shuffle”参数指定在将数据拆分为测试和训练集之前是否应该对其进行混洗。这里我们将其设置为false以保留交易发生的顺序。我们使用“random_state”参数,以便每次运行此函数时都能获得相同的输出。我们现在要指定我们的超参数epochs=8n_classes=1n_units=200n_features=29batch_size=35epochs:epochs对应于我们将通过模型运行数据集的迭代次数。n_classes:这对应于我们为该分类所做的类数。在我们的例子中,我们有一个二元分类,如果是正常交易,我们分配0,如果是欺诈交易,则分配1。在最基本的层面上,如果我们采用一列,我们可以很容易地用0和1表示欺诈交易和正常交易。因此,我们可以将类数设置为1。n_units:这对应于LSTM隐藏状态(c和h)的大小。n_features:顾名思义,这代表数据集中的特征数量。batch_size:这是指您将输入模型的每批数据的大小。每批将有一个反向传播。接下来,我们将为将提供给机器学习模型的批处理数据定义占位符。xplaceholder=tf.placeholder('float',[None,n_features])yplaceholder=tf.placeholder('float')'xplaceholder'占位符包含一批特征数据,'yplaceholder'包含相应批次的标签数据。'xplaceholder'的形状已指定为(,n_features)因为'None'值允许长度灵活地达到插入的占位符的长度,但馈送矩阵应具有与相同数量的特征在代码中指定。由于没有为“yplaceholder”明确指定形状,因此它将是一个向量,但其长度将取决于输入占位符的内容。在我们的例子中,y将是一个长度为batch_size的向量。我们已经完成了大部分准备工作,所以我们现在将设计、训练和测试我们的LSTM模型:tf.Variable(tf.random_normal([n_classes]))}x=tf.split(xplaceholder,n_features,1)print(x)lstm_cell=rnn.BasicLSTMCell(n_units)outputs,states=rnn.static_rnn(lstm_cell,x,dtype=tf.float32)output=tf.matmul(outputs[-1],layer['weights'])+layer['bias']returnoutput让我们看懂代码。我将首先解释“recurrent_neural_network_model()”函数中的代码在做什么,逐行解释Python代码如下:在这一行中,我们手动定义权重和偏差的形状。我们分别为TensorFlow变量'weight'和'bias'分配shape[rnn_size,n_classes]和[n_classes]的随机值。现在我们将数据作为序列分配给“x”。为此,我们将特征批次沿其垂直维度(维度:1)分成29个切片,这是一个二维张量。每个切片都是序列的一个元素,作为LSTM层的输入。(序列中一个元素的形状为:(,1))然后我们创建LSTM层。此函数实例化所有门的变量。'outputs'变量包含LSTM层在每个时间步的所有输出,'state'包含两个隐藏状态(h和c)的最后一个状态的值。这里我们只是使用'outputs[-1]'来获取LSTM层的最后一个输出并将其与之前定义的权重矩阵相乘并为其添加偏置值。结果值是正向传递的logit值。最后,我们将logit值返回给调用函数“train_neural_network()”。deftrain_neural_network():#1logit=recurrent_neural_network_model()logit=tf.reshape(logit,[-1])#3cost=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logit,labels=yplaceholder))optimizer=tf.train.AdamOptimizer().minimize(cost)withtf.Session()assess:#6tf.global_variables_initializer().run()tf.local_variables_initializer().run()#7forepochinrange(epochs):epoch_loss=0#8i=0foriinrange(int(len(X_train)/batch_size)):#10#11start=iend=i+batch_size#13batch_x=np.array(X_train[start:end])batch_y=np.array(y_train[start:end])#15_,c=sess.run([optimizer,cost],feed_dict={xplaceholder:batch_x,yplaceholder:batch_y})epoch_loss+=ci+=batch_size#18print('Epoch',epoch,'completedoutof',epochs,'loss:',epoch_loss)pred=tf.round(tf.nn.sigmoid(logit)).eval({xplaceholder:np.array(X_test),yplaceholder:np.array(y_test)})#20f1=f1_score(np.array(y_test),pred,average='macro')accuracy=accuracy_score(np.array(y_test),pred)recall=recall_score(y_true=np.array(y_test),y_pred=pred)precision=precision_score(y_true=np.array(y_test),y_pred=pred)#24print("F1Score:",f1)print("AccuracyScore:",accuracy)print("Recall:",recall)print("Precision:",precision)train_neural_network()现在让我们了解'train_neural_network()'函数中的代码是做什么的,逐行解释Python代码如下:1.这里我们将接收到的logit值赋给变量logit值是激活的倒数。2.然后我们将矩阵重塑为向量,因为在将其输入损失函数时,标签和对数的形状应该相等。3.我们在这里定义损失函数。使用“sigmoid_cross_entropy_with_logits”函数是因为我们在做二元分类。如果这是一个多类分类,我们应该使用像“softmax_cross_entropy_with_logits”这样的损失函数。4.我们使用“AdamOptimizer()”优化器,因为它具有相当好的性能。到目前为止,我们讨论的所有代码都不在Tensorflow会话中。从这里开始,所有讨论的代码都将在TensorFlow会话中。在调用“train_neural_network()”启动程序后,Tensorflow会话的起点将是执行开始的地方。我们正在初始化迄今为止声明的所有全局变量。6.然后我们正在初始化项目中的所有局部变量。7.这里我们定义一个循环,直到满足我们定义的迭代次数(epoch)。8.在每个纪元开始时将纪元损失重置为0。9.定义变量以在将数据拆分为批次时跟踪开始和结束计算10.这里我们再次定义一个循环,直到批次达到计算阈值。11.和12.我们使用“开始”和“结束”变量来跟踪每次迭代中数据的拆分位置。13.和14.在每次迭代中,一批特征和标签将分别分配给“batch_x”和“batch_y”变量。15.在这一行中,我们通过将“batch_x”和“batch_y”变量中的值提供给前面提到的占位符,告诉Tensorflow运行必要的子图来计算优化器和成本。结果,优化器的值和成本被计算并分别分配给“throw-away”和“c”变量。16.当前批次的损失将添加到“epoch_loss”变量中。17.这一行有助于遍历每批数据(特征和标签)。18.打印那个时期的总损失到目前为止,我们已经讨论了模型的训练方面。训练将一直持续到epoch的数量达到阈值。接下来的几行代码用于测试模型。注意:理想情况下,我们会将数据集分为3组,即训练、验证和测试。我们将保留测试集并使用验证集来查看模型的性能并更改超参数以获得更好的性能。当我们认为模型已经足够改进时,我们只拿测试集看看模型做得如何。对于本文,我们只使用了两个训练集和测试集以保持简单。19.这是我们将测试数据集提供给模型并告诉Tensorflow运行计算logits所需的子图的地方。然后我们通过sigmoid激活传递logit值以获得预测。四舍五入值以从预测值中删除小数位。20.这里我们计算F1分数。F1Score是Precision和Recall的加权平均值。您可以从此处阅读更多相关信息。21.然后我们计算准确度分数。22.本次召回正在统计中。召回率是正确预测的阳性观察结果与所有阳性观察结果的比率。23.我们也在计算精度。精度是正确预测的阳性观察值与预测的阳性观察值总数的比率。24.至27.打印出所有计算出的分数。所以,我们终于完成了代码。我希望本文能帮助您了解使用Tensorflow构建基本LSTM的过程。请注意,此模型是一个非常基础的版本,是构建和改进的良好起点。