← 返回文章列表

PyTorch实现CNN分类与RNN序列预测

CNN的参数计算 CNN图像分类 RNN循环神经网络 专门处理序列数据的神经网络 词嵌入层作用 词嵌入层的作用就是将文本转换为向量 …

CNN的参数计算

CNN图像分类

import torch
import torch.nn as nn
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor
import torch.optim as optim
from torch.utils.data import DataLoader
import time
import matplotlib.pyplot as plt
from torchsummary import  summary

BATCH_SIZE = 8
#1.准备数据集
def create_dataset():

    train_dataset = CIFAR10('./data',train=True,transform=ToTensor(),download=True)
    test_dataset = CIFAR10('./data',train=False,transform=ToTensor(),download=True)

    return train_dataset,test_dataset
#2。搭建神经网络
class ImgModel(nn.Module):

    def __init__(self):
        super().__init__()

        self.conv1 = nn.Conv2d(3,6,3,1,0)
        self.pool1 = nn.MaxPool2d(2,2,0)
        self.conv2 = nn.Conv2d(6,6,3,1,0)
        self.pool2 = nn.MaxPool2d(2,2,0)

        self.linear1 = nn.Linear(216,120)
        self.linear2 = nn.Linear(120,84)
        self.output = nn.Linear(84,10)

    def forward(self,x):
        #第一层:卷积层(加权求和)-》激励层(激活函数)+池化层
        x = self.pool1(torch.relu(self.conv1(x)))
        #第二层
        x = self.pool2(torch.relu(self.conv2(x)))
        #全连接层:细节——>全连接层只能处理2维数据
        x = x.reshape(x.size(0),-1)

        x =torch.relu(self.linear1(x))

        x =torch.relu(self.linear2(x))

        #输出层
        return self.output(x) #不用softmax,因为后续的损失函数用CrossEntropyLoss
def train(train_dataset):
    dataloader = DataLoader(train_dataset,batch_size=BATCH_SIZE,shuffle=True)
    model = ImgModel()
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(),lr=0.001)
    epochs = 10
    for epoch in range(epochs):
        total_loss,total_samples,total_correct,start = 0.0,0,0,time.time()
        for x,y in dataloader:
            model.train()
            y_pred = model(x)
            loss=criterion(y_pred,y)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            total_correct+=(torch.argmax(y_pred,dim=-1)==y).sum()
            total_loss+=loss.item()*len(y)
            total_samples +=  len(y)
        print(f'epoch:{epoch+1},loss:{total_loss/total_samples:.4f},accuracy:{total_correct/total_samples:.2f},time:{time.time()-start:.2f}s')
    torch.save(model.state_dict(),'./model/img_model.pth')
def evaluate():
    dataloader = DataLoader(test_dataset,batch_size=BATCH_SIZE,shuffle=False)

    model = ImgModel()

    model.load_state_dict(torch.load('./model/img_model.pth'))

    total_correct,total_samples = 0,0

    for x,y in dataloader:
        model.eval()

        y_pred = model(x)

        #搭建网络时,没有用softmax函数,用argmax函数

        y_pred = torch.argmax(y_pred,dim=-1)
        total_correct+=(y_pred == y).sum()

        total_samples+=len(y)

    print(f'accuracy:{total_correct/total_samples:.2f}')

if __name__ == '__main__':
    #1.获取数据集
    train_dataset,test_dataset = create_dataset()
    #2.搭建神经网络
    model = ImgModel()
    #查看模型参数
    # summary(model,(3,32,32),batch_size=BATCH_SIZE)
    #训练
    train(train_dataset)
    evaluate()

RNN循环神经网络

专门处理序列数据的神经网络

词嵌入层作用

词嵌入层的作用就是将文本转换为向量。

词嵌入层在 RNN 中的作用有输入表示降低维度捕捉语义相似性

词嵌入层首先会根据输入的词的数量构建一个词向量矩阵,例如: 我们有 100 个词,每个词希望转换成 128 维度的向量,那么构建的矩阵形状即为: 100*128,输入的每个词都对应了一个该矩阵中的一个向量

词嵌入层工作流程

初始化词向量:词嵌入层的初始词向量通常会使用随机初始化或者通过加载预训练的词向量(如Word2Vec或GloVe)进行初始化。

输入索引:每个单词在词汇表中都有一个唯一的索引。输入文本(例如一个句子)会先被分词,然后每个单词会被转换为相应的索引。

查找词向量:词嵌入层将这些单词索引映射为对应的词向量。这些词向量是一个低维稠密向量,表示该词的语义。

输入到RNN:这些词向量作为RNN的输入,RNN处理它们并根据上下文生成一个序列的输出。

RNN计算过程

实际上只有一个神经元

计算当前时刻的输出:网络的输出yt是当前时刻的隐藏状态经过一个线性变换得到的。

上述公式中:

1.yt 是当前时刻的输出(通常是一个向量,表示当前时刻的预测值,RNN层的预测值)

2.ht 是当前时刻的隐藏状态

3.Why 是从隐藏状态到输出的权重矩阵

4.by 是输出层的偏置项

词汇表映射:

输出yt是一个向量,该向量经过全连接层后输出得到最终预测结果Ypred,Ypred中每个元素代表当前时刻生成词汇表中某个词的得分(或概率,通过激活函数如softmax)。**词汇表有多少个词,**Ypred就有多少个元素值,最大元素值对应的词就是当前时刻预测生成的词。

神经元工作机制总结:

接收输入:每个RNN神经元接收来自输入数据xt和前一时刻的隐藏状态ht-1。

更新隐藏状态:神经元通过一个加权和(由权重矩阵和偏置项组成)更新当前时刻的隐藏状态ht,该隐藏状态包含了来自过去的记忆以及当前输入的信息。

输出计算:基于当前隐藏状态ht,神经元生成当前时刻的输出yt,该输出可以用于任务的最终预测。

公式:本次的隐藏状态 = tanh(上次的隐藏状态加权求和+本次的输入加权求和)

​ 本次的输出 = 本次的隐藏状态加权求和,有词汇表中所有词的概率,选概率最大的那个词作为最终预测结果

API介绍

RNN = torch.nn.RNN(input_size,hidden_size,num_layer*)

参数意义是:

1.input_size:输入数据的维度,一般设为词向量的维度;

2.hidden_size:隐藏层h的维度,也是当前层神经元的输出维度;

3.num_layers: 隐藏层h的层数,默认为1.

将RNN实例化就可以将数据送入进行处理

PyTorch RNN层的使用

l 输入数据和输出结果

将RNN实例化就可以将数据送入其中进行处理,处理的方式如下所示:

output, hn = RNN(x, h0)

n输入数据:输入主要包括词嵌入的x 、初始的隐藏层h0

px的表示形式为[seq_len, batch, input_size],即[句子的长度,batch的大小,词向量的维度]

ph0的表示形式为[num_layers, batch, hidden_size],即[隐藏层的层数,batch的大,隐藏层h的维数]

n输出结果:主要包括输出结果output,最后一层的hn

poutput的表示形式与输入x类似,为[seq_len, batch, hidden_size],即[句子的长度,batch的大小,输出向量的维度]

phn的表示形式与输入h0一样,为[num_layers, batch, hidden_size],即[隐藏层的层数,batch的大,隐藏层h的维度]