完整代码数据与注释:PyTorch、多层感知机(MLP)实现细胞聚类

简介

细胞聚类是生物信息学和医学研究中的关键问题之一。通过对细胞数据进行聚类,我们可以识别潜在的生物学群体,并更好地理解细胞之间的关系。本项目旨在通过构建一个基于PyTorch的MLP模型,实现对细胞数据的自动聚类。
数据
共计148301条数据,特征如下。

Index(['cell_id', 'x', 'y', 'DAPI-01', 'CD20', 'CXCR5', 'IL21', 'PAX5',
       'PMTOR', 'LAG3', 'KI67', 'BCA1', 'FOXP3', 'STAT3', 'TBET', 'CD4',
       'IRF4', 'CD45RO', 'CD3E', 'VIMENTIN', 'CD38', 'PD1', 'PAN CYTO', 'CD21',
       'ICOS', 'MAC2/GAL3', 'CD8', 'PDL1', 'S100B', 'GZMB', 'TCF1', 'IRF7',
       'IFNG', 'CD19', 'STAT1', 'TOX', 'CD11C', 'CD45', 'HLA DR', 'CD39',
       'CXCR3', 'IL21R', 'Cluster', 'Cell Cluster'],
      dtype='object')

结果展示

[图片]

[图片]

[图片]

项目逻辑

  1. 数据预处理:
  • 读取和加载细胞数据集
  • 删除不必要的列,提取特征和目标变量
  • 对目标变量进行编码,以便于神经网络处理
  • 划分数据集为训练集和测试集
  1. MLP模型构建:
  • 使用PyTorch构建一个多层感知机(MLP)
  • 设计合适的网络结构,包括输入层、隐藏层和输出层
  • 初始化模型参数,设置损失函数和优化器
  1. 模型训练与评估:
  • 训练MLP模型并记录损失值
  • 绘制训练损失曲线,以便于直观了解模型的学习过程
  • 通过在测试集上进行预测,评估模型的性能
  • 绘制混淆矩阵,详细了解模型的分类效果
  1. 新数据预测:
  • 读取新的细胞数据集
  • 对新数据进行与训练数据相似的预处理步骤
  • 加载已保存的MLP模型参数
  • 使用模型进行新数据的聚类预测
  • 解码预测结果,可视化细胞分类信息

数据预处理


# 读取并加载数据集
data = pd.read_csv('data.csv')

# 删除不需要的列
data = data.drop(['cell_id', 'x', 'y', 'Cell Cluster'], axis=1)

# 提取特征和目标变量
X = data.drop('Cluster', axis=1)
y = data['Cluster']

# 对目标变量进行编码
label_encoder = LabelEncoder()
y = label_encoder.fit_transform(y)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=42)

# 将数据转换为PyTorch张量
X_train_tensor = torch.tensor(X_train.values, dtype=torch.float32)
X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train, dtype=torch.long)
y_test_tensor = torch.tensor(y_test, dtype=torch.long)

# 打印数据预处理后的信息
print("数据预处理完成,部分数据信息如下:")
print("X_train_tensor shape:", X_train_tensor.shape)
print("y_train_tensor shape:", y_train_tensor.shape)
print("X_test_tensor shape:", X_test_tensor.shape)
print("y_test_tensor shape:", y_test_tensor.shape)

上述代码首先使用pandas库读取CSV文件,然后删除不需要的列。接着,提取特征(X)和目标变量(y)。对目标变量进行了编码,使用LabelEncoder将类别标签转换为数字。之后,使用train_test_split将数据集划分为训练集和测试集。最后,将数据转换为PyTorch张量,以便后续在PyTorch中进行处理。

构建多层感知机(MLP)模型

下面是构建多层感知机(MLP)模型的代码,包括定义模型结构、初始化参数、以及定义损失函数和优化器:


# 定义MLP模型的结构
class MLP(nn.Module):
    def __init__(self, input_size):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(input_size, 64)
        self.fc2 = nn.Linear(64, 32)
        self.fc3 = nn.Linear(32, len(label_encoder.classes_))

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# 初始化模型
input_size = X_train.shape[1]
model = MLP(input_size=input_size)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

# 打印模型结构
print("MLP模型结构:")
print(model)

在这段代码中,首先定义了一个简单的MLP模型结构,包括三个全连接层(nn.Linear)。在forward方法中定义了每个层之间的流动方式,使用ReLU作为激活函数。
接着,通过MLP(input_size=input_size)初始化了一个MLP模型,其中input_size是输入特征的维度,即X_train的列数。
然后,定义了损失函数为交叉熵损失(nn.CrossEntropyLoss()),并选择了Adam优化器(optim.Adam)来更新模型参数,学习率设置为0.01。
最后,通过print(model)打印了MLP模型的结构,以便检查模型的配置是否正确。

训练模型

下面是训练模型、记录损失值和绘制训练损失曲线的代码:

# 用于记录每个epoch的损失值
losses = []

# 训练模型
num_epochs = 100for epoch in range(num_epochs):# 梯度归零
    optimizer.zero_grad()
    # 前向传播
    outputs = model(X_train_tensor)
    # 计算损失
    loss = criterion(outputs, y_train_tensor)
    # 反向传播
    loss.backward()
    # 更新参数
    optimizer.step()
# 记录损失值
    losses.append(loss.item())
# 打印每个epoch的损失值print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')

# 绘制损失曲线
plt.plot(losses, label='Training Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss Over Epochs')
plt.legend()
plt.show()

在这段代码中,首先定义了一个空列表losses,用于存储每个epoch的损失值。然后,进入训练循环,循环num_epochs次。
在每个epoch内,模型的梯度被归零(optimizer.zero_grad()),然后进行前向传播,计算损失,反向传播,最后通过优化器更新模型参数。
每个epoch的损失值被记录到losses列表中。在每个epoch结束后,通过print语句打印当前epoch的损失值。
最后,使用matplotlib绘制了训练损失曲线,以便可视化损失值的变化趋势。

保存和加载模型

下面是保存和加载模型的代码:

# 保存模型参数
torch.save(model.state_dict(), 'mlp_model.pth')

# 加载模型
loaded_model = MLP(input_size=X_train.shape[1])
loaded_model.load_state_dict(torch.load('mlp_model.pth'))
loaded_model.eval()

# 可选:打印加载的模型结构print("Loaded Model Structure:")
print(loaded_model)

在这段代码中,首先使用torch.save保存了训练好的模型参数。model.state_dict()返回一个包含模型所有参数的字典,将其保存为名为mlp_model.pth的文件。
然后,使用MLP(input_size=X_train.shape[1])创建了一个新的MLP模型(loaded_model),并使用load_state_dict方法加载保存的模型参数。
最后,通过loaded_model.eval()将模型设置为评估模式。在PyTorch中,加载模型参数后需要将模型设置为eval模式,以确保在推理时不会影响到Batch Normalization和Dropout等层的行为。

模型评估

下面是模型评估的代码,包括在测试集上进行预测、计算模型准确率以及绘制混淆矩阵:


# 在测试集上进行预测with torch.no_grad():
    outputs = loaded_model(X_test_tensor)
    _, predicted = torch.max(outputs, 1)

# 计算模型准确率
accuracy = accuracy_score(predicted.numpy(), y_test)
print(f'模型在测试集上的准确率: {accuracy}')

# 计算混淆矩阵
cm = confusion_matrix(y_test, predicted)

# 可视化混淆矩阵
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=label_encoder.classes_, yticklabels=label_encoder.classes_)
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()

在这段代码中,首先使用加载的模型在测试集上进行预测。通过torch.no_grad()上下文管理器,确保在预测过程中不计算梯度,因为在评估阶段不再需要反向传播。
然后,使用accuracy_score计算模型的准确率,将模型在测试集上的预测结果与实际标签进行比较。
最后,使用confusion_matrix计算混淆矩阵,该矩阵提供了模型在每个类别上的分类性能。通过seaborn和matplotlib库绘制混淆矩阵,以便更详细地了解模型的分类效果。

新数据预测

# 读取新数据集
testData = pd.read_csv('testData.csv')

# Drop不需要的列,与训练数据预处理方式相同
new_data = testData.drop(['cell_id', 'x', 'y', 'Cell Cluster', 'Cluster'], axis=1)

# Load保存的模型
loaded_model = MLP(input_size=new_data.shape[1])
loaded_model.load_state_dict(torch.load('mlp_model.pth'))
loaded_model.eval()

# 将新数据转换为PyTorch张量
new_data_tensor = torch.tensor(new_data.values, dtype=torch.float32)

# 使用模型进行新数据的预测
with torch.no_grad():
    new_outputs = loaded_model(new_data_tensor)
    _, new_predicted = torch.max(new_outputs, 1)

# Decode预测的标签
decoded_predictions = label_encoder.inverse_transform(new_predicted.numpy())

# 打印或使用预测结果
print("Predictions on new data:")
print(decoded_predictions)

在这段代码中,首先通过pd.read_csv读取了新的数据集。然后,与训练数据相同的方式,通过drop删除不需要的列,进行必要的预处理。
接着,通过创建一个新的MLP模型,并加载已保存的模型参数,将模型设置为评估模式。
将新数据转换为PyTorch张量,使用加载的模型进行预测。通过torch.no_grad()确保在预测过程中不计算梯度。
最后,使用label_encoder.inverse_transform将预测的标签反向转换,以获取可读的标签。打印或使用这些预测结果,具体取决于你的需求。

项目链接

GitHub:https://github.com/Olivia-account/Cell-Clustering-with-PyTorch-MLP

后记

如果觉得有帮助的话,求 关注、收藏、点赞、星星 哦!

  • 25
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

人工智能技术小白修炼手册

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

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

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

打赏作者

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

抵扣说明:

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

余额充值