基于pytorch使用实现cnn如何使用pytorch构建cnn卷积神经网络(代码片段)

_刘文凯_ _刘文凯_     2022-12-04     270

关键词:

基于pytorch使用实现CNN 如何使用pytorch构建CNN卷积神经网络

本文是一个基于pytorch使用CNN在生物信息学上进行位点预测的例子
基于pytorch实现CNN,基于CNN进行位点预测,将CNN代码进行封装,可以非常简单的使用代码,基于最简单的特征提取方法。


目录结构:

如下图所示:


数据:

百度网盘地址(数据很小):
链接:https://pan.baidu.com/s/1uvYs7EBJiK3U89v7vMX9yw
提取码:nii4


代码:

以下代码直接复制可以运行

import torch  # 需要的各种包
import torch.nn as nn
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import StratifiedKFold
from torch.autograd import Variable
import torch.utils.data as Data

import torch.utils.data as data
import torchvision  # 数据库模块
import pandas as pd
import numpy as np
torch.manual_seed(1)  # reproducible 将随机数生成器的种子设置为固定值,这样,当调用时torch.rand(x),结果将可重现
from sklearn.preprocessing import LabelEncoder,OneHotEncoder

class CNN(nn.Module):
    def __init__(self, seq_len):
        super(CNN, self).__init__() # 固定写法

        self.conv1 = nn.Sequential( #  假设输入为(1,21)
            nn.Conv1d(in_channels=1,  # input height 必须手动提供 输入张量的channels数
                      out_channels=16,  # n_filter 必须手动提供 输出张量的channels数
                      kernel_size=3,  # filter size 必须手动提供 卷积核的大小
                      stride=1,  # filter step 卷积核在图像窗口上每次平移的间隔,即所谓的步长
                      padding=1  # 填补为2
                      ),  # output shape (16,21)
            nn.ReLU(),  # 分段线性函数,把所有的负值都变为0,而正值不变,即单侧抑制
            nn.MaxPool1d(kernel_size=3, stride=1, padding=1), # 2采样,28/2=14,output shape (16,14,14) maxpooling有局部不变性而且可以提取显著特征的同时降低模型的参数,从而降低模型的过拟合
            nn.Dropout(p=0.2)
        )

        self.conv2 = nn.Sequential(nn.Conv1d(16, 32, 3, 1, 1),
                                   nn.ReLU(),  # 分段线性函数,把所有的负值都变为0,而正值不变,即单侧抑制
                                   nn.MaxPool1d(kernel_size=3, stride=1, padding=1),
                                   # 2采样,28/2=14,output shape (16,14,14) maxpooling有局部不变性而且可以提取显著特征的同时降低模型的参数,从而降低模型的过拟合
                                   nn.Dropout(p=0.2)
                                   )  # 输出为 max_len/

        self.out = nn.Linear(seq_len*32, 2)  # 全连接层,输出为2个one_hot编码

    def forward(self, x):
        x = self.conv1(x)  # 卷一次
        x = self.conv2(x)  # 卷两次
        x = x.view(x.size(0), -1)  # 展平, 将前面多维度的tensor展平成一维 x.size(0)指batchsize的值
        output = self.out(x)  # fc out全连接层 分类器
        return output

class Use_torch_CNN():
    def __init__(self, epoch, batch_size, lr):
        self.epoch = epoch
        self.batch_size =batch_size
        self.lr = lr

    def to_torch(self, X_train, y_train):  # 转化为torch数据
        BATCH_SIZE = self.batch_size
        X_train = torch.FloatTensor(X_train)
        y_train = torch.FloatTensor(y_train)

        train_loader = Data.DataLoader(Data.TensorDataset(X_train, y_train), BATCH_SIZE,
                                       shuffle=False)  # 自动划分Batch_size

        return train_loader

    def train(self, X_train, y_train):
        seq_len = X_train.shape[-1]
        train_loader = self.to_torch(X_train, y_train)

        ####### 以下为数据训练 ##########

        self.cnn = CNN(seq_len=seq_len)  # 创建网络
        print(self.cnn)  # 查看网络结构
        optimizer = torch.optim.Adam(self.cnn.parameters(), lr=self.lr)  # optimizer 优化器
        loss_func = nn.CrossEntropyLoss()  # 损失函数 交叉熵

        for epoch in range(self.epoch):
            for step, (x, y) in enumerate(train_loader):
                batch_x = Variable(x)
                batch_x = torch.unsqueeze(batch_x, dim=1)
                batch_y = Variable(y)

                optimizer.zero_grad()  # 梯度归零 必须项
                output = self.cnn(batch_x)  # 输入训练数据
                loss = loss_func(output, batch_y)  # 计算误差 # 实际输出, 期望输出
                loss.backward()  # 误差反向传递 只需要调用.backward()即可
                optimizer.step()
            print(f"epoch:epoch  loss:loss")


    def predict_proba(self, X_valid):
        val_data_x = torch.FloatTensor(X_valid)
        val_data_x = torch.unsqueeze(val_data_x, dim=1)
        test_output = self.cnn(val_data_x)
        y_scores = test_output.detach().numpy()

        return y_scores

    def predict(self, X_valid):
        y_scores = self.predict_proba(X_valid)
        return np.argmax(y_scores, axis=1)





def ex_feature(data_pos, data_neg):  ## 提取特征
    def split_word(data_init, k=1):  ## 分词处理 一般为1分词
        data = data_init.tolist()
        split_dict = '[PAD]': 0, '[CLS]': 1, '[SEP]': 2, '[MASK]': 3, 'B': 4,
                      'Q': 5, 'I': 6, 'D': 7, 'M': 8, 'V': 9, 'G': 10, 'K': 11,
                      'Y': 12, 'P': 13, 'H': 14, 'Z': 15, 'W': 16, 'U': 17, 'A': 18,
                      'N': 19, 'F': 20, 'R': 21, 'S': 22, 'C': 23, 'E': 24, 'L': 25,
                      'T': 26, 'X': 27, 'O': 28

        def str_sum(s, i):
            d = ''
            for j in range(k):
                d += s[i + j]
            return d

        for i, seq in enumerate(data):
            data[i] = seq[0]

        token_list = list()
        max_len = 0  ## 最大长度
        for seq in data:
            seq_id = [split_dict[str_sum(seq, i)] for i in range(len(seq) - k + 1) if i % k == 0]  # 字符转为数字
            token_list.append(seq_id)
            if len(seq_id) > max_len:
                max_len = len(seq_id)  ## 获取最大长度

        return token_list, max_len

    def add_CLS_SEP(token_list, max_len):  # 增加标志 以及 补零
        split_dict = '[PAD]': 0, '[CLS]': 1, '[SEP]': 2, '[MASK]': 3, 'B': 4,
                      'Q': 5, 'I': 6, 'D': 7, 'M': 8, 'V': 9, 'G': 10, 'K': 11,
                      'Y': 12, 'P': 13, 'H': 14, 'Z': 15, 'W': 16, 'U': 17, 'A': 18,
                      'N': 19, 'F': 20, 'R': 21, 'S': 22, 'C': 23, 'E': 24, 'L': 25,
                      'T': 26, 'X': 27, 'O': 28

        data = []
        for i in range(len(token_list)):  # 由于长度不一致,不建议用numpy操作
            token_list[i] = [split_dict['[CLS]']] + token_list[i] + [split_dict['[SEP]']]
            n_pad = max_len - len(token_list[i])
            token_list[i].extend([0] * n_pad)  # 补零对齐
            data.append(token_list[i])

        return data

    data_pos, max_len_pos = split_word(data_pos)
    data_neg, max_len_neg = split_word(data_neg)

    max_len = np.max([max_len_pos, max_len_neg])

    data_pos = add_CLS_SEP(data_pos, max_len)
    data_neg = add_CLS_SEP(data_neg, max_len)

    return data_pos, data_neg


def generate_train_test(Px, Nx):  # 分出X Y
    Px = np.array(Px)
    Nx = np.array(Nx)

    Py = np.ones((Px.shape[0], 1))
    Ny = np.zeros((Nx.shape[0], 1))

    P_train = np.concatenate((Px, Py), axis=1)  # 按列合并
    N_train = np.concatenate((Nx, Ny), axis=1)  # 按列合并

    data_train = np.concatenate((P_train, N_train), axis=0)  # 按行合并

    np.random.seed(42)
    np.random.shuffle(data_train)  # 混淆数据

    X = data_train[:,:-1] # 除-1列外的所有列
    Y = (data_train[:,-1]).reshape(-1,1)

    return X, Y


def get_kfold_data(X, Y, k=5):
    X = np.array(X)
    Y = np.array(Y)
    kfold = StratifiedKFold(n_splits=k, shuffle=True, random_state=520)
    data_kfold_list = []
    for train_idx, val_idx in kfold.split(X,y):
        data_kfold_list.append('train':'X':X[train_idx],'Y':Y[train_idx],
                                'val':'X':X[val_idx],'Y':Y[val_idx])
    return data_kfold_list

    ### 迭代器形式 省内存 ###
    # for train_idx, val_idx in kfold.split(X,y):
    #     data_kfold_list = 'train':'X':X[train_idx],'Y':y[train_idx],
    #                             'val':'X':X[val_idx],'Y':y[val_idx]
    #     yield data_kfold_list
    # return

def get_one_data(X, Y, k=5):
    X = np.array(X)
    Y = np.array(Y)
    One_Hot = OneHotEncoder().fit(Y)
    Y_one_hot = One_Hot.transform(Y).toarray()

    kfold = StratifiedKFold(n_splits=k, shuffle=True, random_state=520)
    for train_idx, val_idx in kfold.split(X,Y):
        return X[train_idx], Y_one_hot[train_idx], X[val_idx], Y_one_hot[val_idx]


if __name__ == '__main__':

    EPOCH = 10  # 训练迭代次数
    BATCH_SIZE = 32  # 分块送入训练器
    LR = 0.001  # 学习率 learning rate

    ######## 以下为数据加载 #######
    data_pos = np.array(pd.read_csv('./data/gly_pos.fa', header=None))
    data_neg = np.array(pd.read_csv('./data/gly_neg.fa', header=None))

    data_pos, data_neg = ex_feature(data_pos, data_neg)  # 提取特征

    train_x, train_y = generate_train_test(data_pos, data_neg)
    X_train, y_train, X_valid, y_valid = get_one_data(train_x, train_y)

    cnn = Use_torch_CNN(epoch=EPOCH, batch_size=BATCH_SIZE, lr=LR) # 构建模型

    cnn.train(X_train, y_train)  # 训练模型

    y_scores = cnn.predict_proba(X_valid)  # 预测

    auc = roc_auc_score(y_valid[:,1], y_scores[:,1])  # y_true, y_score

    print(f'auc:auc')



结果:

如下图所示,结果并不好,原因很简单,因为这个模型“提取特征”部分没做好:


改进思路

1、增加特征提取方式
2、利用自编码器提取特征

如何将基于自定义图像的数据集加载到 Pytorch 中以与 CNN 一起使用?

】如何将基于自定义图像的数据集加载到Pytorch中以与CNN一起使用?【英文标题】:HowdoIloadcustomimagebaseddatasetsintoPytorchforusewithaCNN?【发布时间】:2019-01-0517:15:46【问题描述】:我已经在互联网上搜索了几个小时,以找到解决我问... 查看详情

ai常用框架和工具丨13.pytorch实现基于cnn的手写数字识别

代码实例,PyTorch实现基于CNN的手写数字识别,希望对您有所帮助。文章目录环境说明一、模型训练1.1导入相关依赖1.2选择使用的硬件1.3超参数配置1.4准备训练集和测试集1.5模型创建1.6模型评估指标1.7模型训练1.8模型测试1.9模型... 查看详情

ai常用框架和工具丨13.pytorch实现基于cnn的手写数字识别

代码实例,PyTorch实现基于CNN的手写数字识别,希望对您有所帮助。文章目录环境说明一、模型训练1.1导入相关依赖1.2选择使用的硬件1.3超参数配置1.4准备训练集和测试集1.5模型创建1.6模型评估指标1.7模型训练1.8模型测试1.9模型... 查看详情

ai常用框架和工具丨13.pytorch实现基于cnn的手写数字识别

代码实例,PyTorch实现基于CNN的手写数字识别,希望对您有所帮助。文章目录环境说明一、模型训练1.1导入相关依赖1.2选择使用的硬件1.3超参数配置1.4准备训练集和测试集1.5模型创建1.6模型评估指标1.7模型训练1.8模型测试1.9模型... 查看详情

使用 pytorch-lightning 实现 Network in Network CNN 模型

】使用pytorch-lightning实现NetworkinNetworkCNN模型【英文标题】:ImplementaNetworkinNetworkCNNmodelusingpytorch-lightning【发布时间】:2021-08-2721:32:06【问题描述】:我正在尝试实现NiN模型。基本上试图从d2l复制代码这是我的代码。importpandasaspdimp... 查看详情

如何在简单的pytorch模型中重构cnn层的输出张量以供线性层使用

】如何在简单的pytorch模型中重构cnn层的输出张量以供线性层使用【英文标题】:Howtorestructuretheoutputtensorofacnnlayerforusebyalinearlayerinasimplepytorchmodel【发布时间】:2021-01-2313:53:07【问题描述】:给定一个带有维度的pytorch输入数据集... 查看详情

pytorch实战笔记——cnn实现情感分析(代码片段)

本文展示的是使用Pytorch构建一个TextCNN来实现情感分析。本文的架构是第一章详细介绍TextCNN(不带公式版),第二章是核心代码部分。目录1.TextCNN2.TextCNN实现情感分析参考1.TextCNN相较于LSTM而言,我个人其实是没看... 查看详情

使用pytorch实现手写数字识别(代码片段)

使用Pytor##标题ch实现手写数字识别思路和流程分析准备数据,这些需要准备DataLoader构建模型,这里可以使用torch构造一个深层的神经网络模型的训练模型的保存,保存模型,后续持续使用模型的评估,使用测... 查看详情

pytorch基于cnn的手写数字识别(在mnist数据集上训练)(代码片段)

最终成果http://pytorch-cnn-mnist.herokuapp.com/GITHUBhttps://github.com/XavierJiezou/pytorch-cnn-mnist本文以最经典的mnist数据集为例,讲述了使用pytorch做机器学习的一整套流程,文中所提到的所有代码都可以到github中查看。项目场景简单的... 查看详情

3.使用pytorch深度学习库训练第一个卷积神经网络cnn(代码片段)

这篇博客将介绍如何使用PyTorch深度学习库训练第一个卷积神经网络(CNN)。训练CNN使用KMNIST数据集(MNISTdigits数据集的替代品,内置在PyTorch中)识别手写平假名字符(handwrittenHiraganacharacters)。在图像... 查看详情

基于facenet+retinaface+pytorch实现卷积神经网络(cnn)人脸识别

文件大小:4.38G开发环境:Python3.7.10、OpenCV4.1.2.30、PyCharm2020点击下载:点击下载简要概述:卷积神经网络的人脸识别,人脸检测用的是Retinaface,识别用到的是facenet。两组都是训练好的模型,在modeldata... 查看详情

图像分类convit从入门到实战——使用convit实现植物幼苗的分类(pytorch)(代码片段)

摘要来自Facebook的研究者提出了一种名为ConViT的新计算机视觉模型,它结合了两种广泛使用的AI架构——卷积神经网络(CNN)和Transformer,该模型取长补短,克服了CNN和Transformer本身的一些局限性。同时,借助这两种架... 查看详情

pytorch实现tpu版本cnn模型(代码片段)

...时间的问题,我们使用TPU运行时环境来加速训练。为此,PyTorch一直在通过提供最先进的硬件加速器 查看详情

使用 PyTorch 进行两流 CNN 并行推理

】使用PyTorch进行两流CNN并行推理【英文标题】:Two-StreamCNNparallelinferencingwithPyTorch【发布时间】:2021-09-1113:36:59【问题描述】:目前我正在完成我的最后一年项目,该项目涉及开发一个多流CNN来执行动作识别。但是,最终输出依... 查看详情

5.使用pytorch预先训练的模型执行目标检测(代码片段)

5.使用PyTorch预先训练的网络执行目标检测这篇博客将介绍如何使用PyTorch预训练的网络执行目标检测,这些网络是开创性的、最先进的图像分类网络,包括使用ResNet的更快R-CNN、使用MobileNet的更快R-CNN和RetinaNet。具有ResNet50... 查看详情

使用 pytorch 训练和测试 CNN。有和没有 model.eval()

】使用pytorch训练和测试CNN。有和没有model.eval()【英文标题】:TrainingandtestingCNNwithpytorch.Withandwithoutmodel.eval()【发布时间】:2019-09-2017:53:38【问题描述】:我有两个问题:-我正在尝试训练一个用一些预先训练的权重初始化的卷积... 查看详情

pytorch实现卷积神经网络cnn

Pytorch是torch的Python版本,对TensorFlow造成很大的冲击,TensorFlow无疑是最流行的,但是Pytorch号称在诸多性能上要优于TensorFlow,比如在RNN的训练上,所以Pytorch也吸引了很多人的关注。之前有一篇关于TensorFlow实现的CNN可以用来做对比... 查看详情

基于pytorch的cnnlstm神经网络模型调参小结

(Demo)这是最近两个月来的一个小总结,实现的demo已经上传github,里面包含了CNN、LSTM、BiLSTM、GRU以及CNN与LSTM、BiLSTM的结合还有多层多通道CNN、LSTM、BiLSTM等多个神经网络模型的的实现。这篇文章总结一下最近一段时间遇到的问... 查看详情