import torch
from torch import nn
import torch.utils.data as Data
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import accuracy_score, balanced_accuracy_score, confusion_matrix, roc_auc_score, f1_score
from imblearn.under_sampling import RandomUnderSampler
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
import json
import cross
seed = 42
INPUT_SIZE = 70
HIDDEN_LAYER_SIZE = 16
OUTPUT_SIZE = 1
NUM_LAYERS = 1
LR = 1e-3
EPOCHS = 50
BATCH_SIZE = 15
FOLD = 10
# 定义参数网格
param_grid = {
# 'hidden_size': [8, 16, 32, 64],
# 'num_layers': [1, 2],
# 'learning_rate': [0.001, 0.01],
# 'batch_size': [8, 16, 32, 64],
# 'epoch': [i for i in range(10, 100, 10)]
'hidden_size': [128], # 6,32,64,128
'num_layers': [1],
'learning_rate': [0.001], # 0.05,0.01,1e-3,1e-4
'batch_size': [32], # 8,16,32,64
'epoch': [500], # i for i in range(50, 300, 50)
'dropout_prob': [0.2]
}
file = f'result/LSTM-test/4-20-fold{FOLD}.csv'
# file = 'result/LSTM-test/4-7-fold10.csv'
best_val_accuracies = []
best_epochs = []
key = eval(input('0. 训练模型\t1. 保存的模型\n'))
class LSTM(nn.Module):
def __init__(self, input_size=70, hidden_layer_size=100, output_size=1, num_layers=1, dropout_prob=0.2):
'''
LSTM二分类任务
:param input_size: 输入数据的维度
:param hidden_layer_size: 隐层的数目
:param output_size: 输出的个数
'''
super(LSTM, self).__init__()
self.hidden_layer_size = hidden_layer_size
self.num_layers = num_layers
self.lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_layer_size, num_layers=num_layers)
self.dropout = nn.Dropout(dropout_prob)
self.linear = nn.Linear(hidden_layer_size, output_size)
self.sigmoid = nn.Sigmoid()
def forward(self, input_x):
'''
input_x.view(len(input_x), 1, -1) 将输入数据 input_x 变形为一个新的形状,其中:
第一维:保持原始大小,即 200(表示数据中的样本数)。
第二维:将维度扩展为 1,因为 LSTM 模型的输入通常需要包含一个批次(batch)的信息。
第三维:自动调整以适应新的形状,以满足输入到 LSTM 模型的要求。
这个改变后的形状适合输入到 LSTM 模型的输入层。在 LSTM 中,输入数据的形状通常是 (batch_size, seq_len, input_size),其中:
batch_size: 表示每个批次中包含的数据样本数量。
seq_len: 表示数据序列的长度。
input_size: 表示每个时间步所包含的特征数。
⭐⭐⭐我的理解:将输入数据转换成 一个batch的样本数,每个样本序列长度,剩下的为特征数,也就是(样本数, 1, -1)
'''
input_x = input_x.view(len(input_x), 1,
-1) # (batch, input_size),其中input_x.shape=(1,5),可以参照luojianmiaoshixiong的(input.size(0),input.size(1),-1)
'''
这行代码的作用是初始化 LSTM 的隐藏状态和细胞状态,使其变为 (1, 1, self.hidden_layer_size) 的形状,以便与输入数据相匹配。
在这里,我们用 torch.zeros 来创建全零的张量作为初始隐藏状态和细胞状态。其中,第一个 1 表示层数,第二个 1 表示批次大小,
而 self.hidden_layer_size 则表示每个隐藏状态的大小。
n_layers=1表示我们使用的是单层 LSTM
'''
'''
这个语句的作用是创建 LSTM 模型的初始隐藏状态和细胞状态。它包含两部分,分别对应隐藏状态(h)和细胞状态(c)。
'''
hidden_cell = (torch.zeros(self.num_layers, 1, self.hidden_layer_size),
torch.zeros(self.num_layers, 1,
self.hidden_layer_size)) # shape:(n_layers, batch_size, hidden_size)
'''
在 LSTM 模型中进行前向传播计算,并获取输出 lstm_out 以及最终的隐藏状态和细胞状态 h_n,h_c。
'''
lstm_out, (h_n, h_c) = self.lstm(input_x, hidden_cell)
linear_out = self.linear(lstm_out.view(len(input_x), -1)) # = self.linear(lstm_out[:,-1,:])
drop_out = self.dropout(linear_out)
predictions = self.sigmoid(drop_out)
return predictions
def means(list):
mean_res = []
for lt in list:
m = np.mean(lt)
mean_res.append(round(m, 4))
return mean_res
def std(list):
std_res = []
for lt in list:
s = np.std(lt)
std_res.append(round(s, 4))
return std_res
def main(epoch, hidden_size, num_layers, batch_size, lr, dropout_prob):
# 设定随机种子以保证结果的可复现性
torch.manual_seed(seed)
np.random.seed(seed)
train, label = cross.bold_train()
mymodel = 'LSTM' # 'SVM' vs 'DT'
index = 'BOLD-' + mymodel
sample = r'yes'
best_accuracy = 0.0
best_model = None
balanced_res = []
accuracy_res = []
sensitivity_res = []
specificity_res = []
auc_res = []
f1_res = []
all_tp = []
all_tn = []
all_fp = []
all_fn = []
skf = StratifiedKFold(n_splits=FOLD, shuffle=True, random_state=seed)
fold = 0
for train_index, test_index in skf.split(train, label):
print(f'#####fold {fold}')
X_train, X_test = train[train_index], train[test_index]
Y_train, Y_test = np.array(label)[train_index], np.array(label)[test_index]
_, predicted_labels, true_labels, model = train_eval(X_train, Y_train, X_test, Y_test, epoch, fold, hidden_size,
num_layers, batch_size, lr, dropout_prob)
accuracy, balanced, sensitivity, specificity, auc, f1, tp, tn, fp, fn = confusion_compute(predicted_labels,
true_labels)
accuracy_res.append(accuracy)
balanced_res.append(balanced)
sensitivity_res.append(sensitivity)
specificity_res.append(specificity)
auc_res.append(auc)
f1_res.append(f1)
all_tp.append(tp)
all_tn.append(tn)
all_fp.append(fp)
all_fn.append(fn)
print(f'Accuracy: {accuracy_res[fold]:.4f}')
print(f'Balanced Accuracy: {balanced_res[fold]:.4f}')
print(f'Sensitivity (TPR): {sensitivity_res[fold]:.4f}')
print(f'Specificity (TNR): {specificity_res[fold]:.4f}')
print(f'AUC: {auc_res[fold]:.4f}')
print(f'F1 Score: {f1_res[fold]:.4f}')
fold += 1
# 保存最佳模型和参数
if accuracy > best_accuracy:
best_accuracy = accuracy
best_model = model
# PATH = f'result/LSTM-test/state_dict_model_{epoch}.pth'
# if not os.path.exists(PATH):
# torch.save(best_model.state_dict(), PATH)
# print(f"Epoch: {epoch}, Best accuracy: {best_accuracy:.2f}")
all_list = [accuracy_res, balanced_res, sensitivity_res, specificity_res,
auc_res, f1_res, all_tp, all_tn, all_fp, all_fn]
mean_result = means(all_list)
std_result = std(all_list[:6])
mid = tuple(str(mean_result[i]) + "±" + str(std_result[i]) for i in range(6)) + tuple(mean_result[6:]) + tuple(
[sample, epoch, FOLD, hidden_size, num_layers, batch_size, lr, dropout_prob])
final_result = [mid]
if os.path.exists(file):
analyse_table = pd.DataFrame(final_result, index=[index])
analyse_table.to_csv(file, mode='a', header=False)
else:
analyse_table = pd.DataFrame(final_result, index=[index],
columns=['accuracy', 'balanced accuracy', 'sensitivity',
'specificity', 'auc', 'f1
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
这是使用pytorch实现LSTM模型的二分类实验过程,目前使用的是REST-meta-MDD数据集_torch-lstm.zip (6个子文件)
torch-lstm-master
get_WPE.py 12KB
cross.py 7KB
get_data.py 4KB
111torch-lstm.py 16KB
savemodel.py 12KB
torch-lstm.py 14KB
共 6 条
- 1
资源评论
普通网友
- 粉丝: 1127
- 资源: 5293
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功