Step1 跟着课程学习,第一周的经验告诉我由于没有太多的机器学习思维,因此需要看一些简单的视频学习
PyTorch深度学习快速入门教程(绝对通俗易懂!)【小土堆】_哔哩哔哩_bilibili的第P16讲到了nn.Module的使用,很好地描述了上周的API线性回归的原理,这次终于听懂了定义函数以及继承父类
代码从 14行 开始运行。
首先,设定一个神经网络tudui,tudui按照Tudui()方法执行。
其中,Tudui()是nn.Module的子类,nn.Module就是一个pytorch的大类,创建Tudui类后(第5行),要定义第6,7行(规定:将子类先初始化,然后调用父类也进行初始化,还可以再这里加语法,本代码没加),第9行是定义前进forward(因为神经网络是这么传递的,而且还有backward),其中的input代表输入,可以用其他字母代替。第10行和第11行是该子类实现的功能:加1并输出。
接着回到第15行,设定一个一维输入x张量1.0
然后16行定义输出为output
第17行打印输出
Step2 常见的优化算法
1.梯度下降BGD:全局样本最优
2.随机梯度下降SGD:随机抽取样本进行梯度更新
3.小批量梯度下降MBGD:找一部分数据进行梯度更新
4.动量法:对梯度平滑处理,防止振幅过大
5.AdaGrad:自适应学习率
6.RMSProp:动量法的优化,对学习率进行加权
7.Adam:4和6的结合,自适应学习率+梯度振幅不会过大
Step3 数据加载
一.数据集类
1.torch.utils.data.Dataset
2.完成__getitem__:获取索引位置的一条数据
3.完成__len__:获取数据的总个数
代码如下:
import torch
from torch.utils.data import Dataset
data_path = r"D:\1aaa_aa\SMSSpamCollection"
class MyDataset(Dataset):
def __init__(self):
self.lines = open(data_path).readlines()
def __getitem__(self, index):
return self.lines[index].strip()
def __len__(self):
return len(self.lines)
if __name__ == '__main__':
my_dataset = MyDataset()
print(my_dataset[0])
print(len(my_dataset))
然后出现了以下错误:
出现这个现象的原因是:在python中默认的编码方式是 “ gbk ”,而Windows中的文件默认的编码方式是 “ utf-8 ” ,所以导致python编译器无法成功读取或写入文件内容。(这个问题因电脑而异)
然后给出了解决办法:
解决:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x9a in position 14: illegal multibyte sequence_A&&K的博客-CSDN博客
修改后的代码:
import torch
from torch.utils.data import Dataset
data_path = r"D:\1aaa_aa\SMSSpamCollection"
class MyDataset(Dataset):
def __init__(self):
self.lines = open(data_path, encoding='utf-8').readlines()
def __getitem__(self, index):
return self.lines[index].strip()
def __len__(self):
return len(self.lines)
if __name__ == '__main__':
my_dataset = MyDataset()
print(my_dataset[0])
print(len(my_dataset))
再加一些,得到其中的数据 ,实现下边的数据加载器类
二.数据加载器类
1.torch.utils.data.DataLoader
2.DataLoader(dataset=dataset,batch_size=2,shuffle=True)
import torch
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
data_path = r"D:\1aaa_aa\SMSSpamCollection"
class MyDataset(Dataset):
def __init__(self):
self.lines = open(data_path, encoding='utf-8').readlines() #readline会导致换行符,下边的strip可以消除换行符
def __getitem__(self, index):
cur_line = self.lines[index].strip()
label = cur_line[:4].strip()
content = cur_line[4:].strip()
return label, content
def __len__(self):
#返回数据的总数量
return len(self.lines)
my_dataset = MyDataset()
data_loader = DataLoader(dataset=my_dataset, batch_size=2,shuffle=True)
if __name__ == '__main__':
# print(my_dataset[0])
# print(len(my_dataset))
for i in data_loader:
print(i)
break
print(len(my_dataset))
print(len(data_loader))
输出结果为
再run以下,输出结果是有变化的
这是因为数据加载器类中的 shuffle=True 造成的,不会覆盖上一次的i值
Step4 pytorch自带数据集
1.torchvision 图像
a.torchvision.datasets
2.torchtext 文本
a.torchtext.datasets
python自带数据集的使用 torchxision.datasets
import torchvision
from torchvision.datasets import MNIST
mnist = MNIST(root="./data", train=True, download=False)
print(mnist[0][0].show())
输出以下结果(手写数字5):
Step5 手写数字识别
一.思路
准备数据、模型构建、训练、模型保存、模型评估
二.MNist数据的处理api
1.torchvision.transforms.ToTensor
import torchvision
from torchvision.datasets import MNIST
from torchvision import transforms
mnist = MNIST(root="./data", train=True, download=False)
print(mnist[0])
ret = transforms.ToTensor()(mnist[0][0])
print(ret.size())
结果如下:
2.torchvision.transforms.Normalize(mean,std):均值和标准差的形状和通道数相同
3.torchvision.transforms.Compose(transforms):传入列表list,数据经过每一个list并挨个处理
三. 模型的构建
1.激活函数的使用
a. import torch.nn.functional as F
b. x=F.relu(x)
2.每一层数据的形状
3.交叉熵损失
a.loss=-∑sum Y_true*log(P) p是softmax的概率
b.带权损失:loss=-∑sum w_i x_i
4.模型的保存与加载
a.保存: torch.save(model.state_dict(),"./model/model.pkl")
b.加载: model.load_state_dict(torch.load("./model/model.pkl"))
5.模型的评估
a.不是对计算进行追踪:with torch.no_grad():
b.损失:和训练相同
c.准确率:
1.获取预测值:tensor.max(dim=-1)[-1]
2.tensor.eq(tensor2).float().mean()
# pytorch完成手写数据识别
import numpy as np
import os
import torch
from torch.utils.data import DataLoader
import torch.nn as nn
from torch.optim import Adam
import torch.nn.functional as F
from torchvision.datasets import MNIST
from torchvision.transforms import Compose, ToTensor, Normalize
BATCH_SIZE = 128
TEST_BATCH_SIZE = 1000
# 准备数据集
def get_dataloader(train=True, batch_size=BATCH_SIZE):
transform_fn = Compose([
ToTensor(),
Normalize(mean=(0.1307), std=(0.3081)) # mean和std的形状和通道数相同
])
dataset = MNIST(root="./data", train=train, transform=transform_fn)
data_loader = DataLoader(dataset, batch_size=BATCH_SIZE, shuffle=True)
return data_loader
# 构建模型
class MnistModel(nn.Module):
def __init__(self):
super(MnistModel, self).__init__()
self.fc1 = nn.Linear(1 * 28 * 28, 28)
self.fc2 = nn.Linear(28, 10)
def forward(self, input):
x = input.view([input.size(0), 1 * 28 * 28]) # 1形状修改 #input.view([-1, 1 * 28 * 28])
x = self.fc1(x) # 2进行全连接层操作
x = F.relu(x) # 3进行激活函数的处理,形状不变
out = self.fc2(x) # 4输出层
return F.log_softmax(out, dim=-1)
model = MnistModel()
optimizer = Adam(model.parameters(), lr=0.001)
if os.path.exists("./model/model.pkl"):
model.load_state_dict(torch.load("./model/model.pkl"))
optimizer.load_state_dict(torch.load("./model/optimizer.pkl"))
def train(epoch):
data_loader = get_dataloader()
for idx, (input, traget) in enumerate(data_loader):
optimizer.zero_grad()
output = model(input) # 调用模型,得到预测值
loss = F.nll_loss(output, traget) # 得到损失
loss.backward() # 反向传播
optimizer.step() # 梯度更新
if idx % 10 == 0:
print(epoch, idx, loss.item())
if idx % 100 == 0:
torch.save(model.state_dict(), "./model/model.pkl")
torch.save(optimizer.state_dict(), "./model/optimizer.pkl")
def test():
loss_list = []
acc_list = []
test_dataloader = get_dataloader(train=False, batch_size=TEST_BATCH_SIZE)
for idx, (input, target) in enumerate(test_dataloader):
with torch.no_grad():
output = model(input)
cur_loss = F.nll_loss(output, target)
loss_list.append(cur_loss)
# 计算准确率
pred = output.max(dim=-1)[-1]
cur_acc = pred.eq(target).float().mean()
acc_list.append(cur_acc)
print("平均损失率,平均损失:", np.mean(acc_list), np.mean(loss_list))
if __name__ == '__main__':
test()
Step6 RNN(循环神经网络):
一.tokenization:分词(把词分开成单个字)
分词方法:1.转化为单个字
2.切分词语
N-gram:N表示能一起使用的词数量
二.文本的向量化:
1.one-hot编码(使用稀疏的向量表示文本,不常用)
2.word embedding:
a.浮点型的稠密矩阵来表示token
b.向量中的每一个值都是超参数,其初始值是随机生成的,之后会在训练的过程 中学习获得
c.api:torch.nn.Embedding(词典数量,embedding的维度)
d.形状的变化:[batch_size,seq_len]............>[batch_size,seq_len,embedding_dim]
三.文本情感分类(还没看完)(接下周)
1.数据集的准备
2.模型构建
3.模型训练
4.模型评估
其他:现在打算去找一些别的资料
PYTORCH深度学习入门_14662085.pdf这本书看到P51(线性回归),这方面主要是对前段时间的知识点回顾(B站的那个视频对新手不太友好,这个就很基础,它系统地讲述了张量基础、梯度下降、loss函数、线性回归等,挺具体的)
组会总结:
1.老师们的建议:每周只有两到三天去看视频,然后剩下几天去复现人家的代码把代码讲清楚。想了想这样还是不错的,给自己一个规划:
周五下午组会,然后总结组会内容(写到CSDN)
然后晚上做出下一周的大致规划
周六休息,周日和周一看视频学代码
周二、周三、周四的晚上做复现,给个总结(内容不用追求很多,其实复现两三个一周就可以了)