计算机视觉笔记

CNN基础

 

  通过shape修改liner层的输入参数

 

 手写数字 卷积模型训练

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()]
)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 这一步定义使用到的转换方法。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.conv1 = nn.Conv2d(1, 6, 5)
        # 输入的channels,输出的channels(使用的卷积核数),卷积核大小,是否跨像素 1表示不跨,填充的像素数
        self.pool = nn.MaxPool2d((2, 2))
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.liner_1 = nn.Linear(16*4*4, 256)  # 输入为图片像素数
        self.liner_2 = nn.Linear(256, 10)


    def forward(self, input):
        x = F.relu(self.conv1(input))
        x = self.pool(x)
        x = F.relu(self.conv2(x))
        x = self.pool(x)
        # print(x.size())
        # x = x.view(x.size(0), -1)
        # 把图片展平  x.size(0) = 64 就是batch,batch是不变的,只将后面的channel wight hight三个维度展平
        x = x.view(-1, 16*4*4)  # -1表示不改变batch
        # 在forward中使用上面的层,参数为self,对input进行处理
        x = F.relu(self.liner_1(x))  # 第一层调用,直接用F调用relu
        x = self.liner_2(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)
# )
model.to(device)
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:
        x, y = x.to(device), y.to(device)
        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:
            x, y = x.to(device), y.to(device)
            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)


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值