函数知识
next(iter(train_dl))
在pytorch里面图片的表示形式: 【batch, channel, hight, width】
transforms.ToTensor
1, 转化为一个 tensor
2,转换到0-1之间
3,会将channel放在第一维度上
1, 转化为一个 tensor
2,转换到0-1之间
3,会将channel放在第一维度上
enumerate(imgs[: 10])
import torch
import pandas as pd
import matplotlib.pyplot as plt
import pylab
import numpy as np
import torch.utils.data
import torchvision
from torch import nn
import torch.nn.functional as F
from sklearn.model_selection import train_test_split
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
from torchvision import datasets, transforms # transforms 是转换数据集的方法
transformation = transforms.Compose(
[transforms.ToTensor()]
)
# 这一步定义使用到的转换方法。transforms.ToTensor() 转换为tensor,将数据归一化。transforms.Normalize() 做标准化。
train_ds = datasets.MNIST('dataa/', # 存放位置
train=True, # 是否为训练集
transform=transformation, # 采用的转换方法
download=True
)
test_ds = datasets.MNIST('dataa/', # 存放位置
train=False, # 是否为训练集
transform=transformation, # 采用的转换方法
download=True
)
train_dl = torch.utils.data.DataLoader(train_ds, batch_size=64, shuffle=True)
test_dl = torch.utils.data.DataLoader(test_ds, batch_size=256)
imgs, labels = next(iter(train_dl))
# imgs.shape # torch.Size([64, 1, 28, 28])
# 表示有64张[1,28,28]图片数据, 对应 通道, hight,wight,经过ToTensor后,channel是放在长宽前的
# img = imgs[0]
# img = img.numpy() # 转换成ndarray
# img = np.squeeze(img)
# plt.imshow(img)
# pylab.show()
# print(labels[:10])
def imshow(img):
npimg = img.numpy()
npimg = np.squeeze(npimg)
plt.imshow(npimg)
pylab.show()
plt.figure(figsize=(10, 1)) # 创建画布
# for i, img in enumerate(imgs[: 10]):
# plt.subplot(1, 10, i+1)
# imshow(img)
class Model(nn.Module):
# 定义一个类,从nn.Module中继承
def __init__(self): # 初始化
super().__init__() # 继承父类中所有属性
self.liner_1 = nn.Linear(28*28, 120) # 输入为图片像素数
self.liner_2 = nn.Linear(120, 84)
self.liner_3 = nn.Linear(84, 10) # 10分类
def forward(self, input):
x = input.view(-1, 28*28) # 把图片展平
# 在forward中使用上面的层,参数为self,对input进行处理
x = F.relu(self.liner_1(x)) # 第一层调用,直接用F调用relu
x = F.relu(self.liner_2(x))
x = self.liner_3(x) #
return x
model = Model()
# print(model)
# Model(
# (liner_1): Linear(in_features=784, out_features=120, bias=True)
# (liner_2): Linear(in_features=120, out_features=84, bias=True)
# (liner_3): Linear(in_features=84, out_features=10, bias=True)
# )
loss_fn = torch.nn.CrossEntropyLoss()
optim = torch.optim.Adam(model.parameters(), lr=0.0001)
def fit(epoch, model, trainloader, testloater):
correct = 0 # correct预测成功数
total = 0 # total训练总样本数
running_loss = 0
for x, y in trainloader:
y_pred = model(x)
loss = loss_fn(y_pred.to(torch.float32), y.to(torch.int64))
optim.zero_grad()
loss.backward()
optim.step() # 优化
with torch.no_grad():
y_pred = torch.argmax(y_pred, dim=1) # argmax dim=1返回y_pred每一行最大数值对应的列号
correct += (y_pred == y).sum().item() # 累加正确样本个数
total += y.size(0) # 总样本数
running_loss += loss.item() # 表示每一个batch的loss
epoch_acc = correct / total
epoch_loss = running_loss / len(trainloader.dataset) # 平均loss trainloader.dataset 返回对应的ds
test_correct = 0 # correct预测成功数
test_total = 0 # total训练总样本数
test_running_loss = 0
with torch.no_grad():
for x, y in testloater:
y_pred = model(x)
loss = loss_fn(y_pred.to(torch.float32), y.to(torch.int64))
y_pred = torch.argmax(y_pred, dim=1) # argmax dim=1返回y_pred每一行最大数值对应的列号
test_correct += (y_pred == y).sum().item() # 累加正确样本个数
test_total += y.size(0) # 总样本数
test_running_loss += loss.item() # 表示每一个batch的loss
epoch_test_loss = test_running_loss / len(testloater.dataset)
epoch_test_acc = test_correct / test_total
print('epoch', epoch,
'loss: ', round(epoch_loss, 3),
'accuracy:', round(epoch_acc, 3),
'test_loss: ', round(epoch_test_loss, 3),
'test_accuracy:', round(epoch_test_acc, 3)
)
return epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc
train_loss = []
train_acc = []
test_loss = []
test_acc = []
epochs = 20
for epoch in range(epochs):
epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc = fit(epoch, model, train_dl, test_dl)
train_loss.append(epoch_loss)
train_acc.append(epoch_acc)
test_loss.append(epoch_test_loss)
test_acc.append(epoch_test_acc)