• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
村雨sup
自己选的路,跪着也要走完 XD
博客园    首页    新随笔    联系   管理    订阅  订阅
Pytorch入门笔记
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        #nn.Module子类的函数必须在构造函数中执行父类的构造函数
        #下式等价于nn.Module.__init__(self)
        super(Net,self).__init__()
        # 卷积层‘1’表示输入图片为单通道,‘6’表示输出通道数,‘5’表示卷积核为5*5
        self.conv1 = nn.Conv2d(1,6,5)
        #卷积层
        self.conv2 = nn.Conv2d(6*1*1,16,5)
        #仿射层/全连接层,y = wx + b
        self.fc1 = nn.Linear(16*5*5,120)#输入是16不能改变,5应该是自己定义的卷积核
        self.fc2 = nn.Linear(120,84)
        self.fc3 = nn.Linear(84,10)


    def forward(self, x):
        # 卷积 ->激活 -> 池化
        x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
        x = F.max_pool2d(F.relu(self.conv2(x)),2)
        #reshape, '-1'表示自适应
        x = x.view(x.size()[0],-1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()
print(net)

__

Net(
  (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear(in_features=400, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)

——

 CIFAR-10分类

下载数据集:

import torch as t
import torchvision as tv
import torchvision.transforms as transforms
from torchvision.transforms import ToPILImage
show = ToPILImage() #可以把Tensor 转成Image,方便可视化

#第一次运行torchvision 会自动下载CIFAR-10数据集

#定义对数据的预处理
transform = transforms.Compose([
    transforms.ToTensor, # 转为Tensor
    transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)), #归一化
])

#训练集
trainset = tv.datasets.CIFAR10(
    root='./data',
    train=True,
    download=True,
    transform=transform
)

trainloader = t.utils.data.DataLoader(
    trainset,
    batch_size=4,
    shuffle=True,
    num_workers=2
)

#测试集
testset = tv.datasets.CIFAR10(
    './data',
    train=False,
    download=True,
    transform=transform
)

testloader = t.utils.data.DataLoader(
    testset,
    batch_size=4,
    shuffle=False,
    num_workers=2
)

classes = (
    'plane','car','bird','cat','deer','dog','frog','horse','ship','truck'
)

——

需要FQ,不然下载非常的慢

Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data\cifar-10-python.tar.gz
Files already downloaded and verified

——

全代码:

在CPU上训练,训练了5个epoch,准确率大概在60%,时间在170s左右

windows上不支持多线程

import torch as t
import torchvision as tv
import torchvision.transforms as transforms
from torchvision.transforms import ToPILImage
import numpy as np
import matplotlib.pyplot as plt
show = ToPILImage() #可以把Tensor 转成Image,方便可视化

#第一次运行torchvision 会自动下载CIFAR-10数据集

#定义对数据的预处理
transform = transforms.Compose([
    transforms.ToTensor(), # 转为Tensor
    transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)), #归一化
])

#训练集
trainset = tv.datasets.CIFAR10(
    root='./data',
    train=True,
    download=True,
    transform=transform
)
#注意windows现在还不支持多线程,所以num_workers=0
trainloader = t.utils.data.DataLoader(
    trainset,
    batch_size=4,
    shuffle=True,
    num_workers=0
)

#测试集
testset = tv.datasets.CIFAR10(
    './data',
    train=False,
    download=True,
    transform=transform
)

testloader = t.utils.data.DataLoader(
    testset,
    batch_size=4,
    shuffle=False,
    num_workers=0
)

classes = (
    'plane','car','bird','cat','deer','dog','frog','horse','ship','truck'
)

(data,label) = trainset[100]
print(classes[label])

# (data+1)/2是为了还原被归一化的数据
show((data+1)/2).resize((100,100))

# dataiter=iter(trainloader)
# images,labels=dataiter.next()
# print(''.join('11%s'%classes[labels[j]] for j in range(4)))
# show(tv.utils.make_grid(images+1)/2).resize((400,100))
def imshow(img):
    img = img / 2 + 0.5
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))

dataiter = iter(trainloader)
images, labels = dataiter.next()
print(images.size())
imshow(tv.utils.make_grid(images))
plt.show()#关掉图片才能往后继续算

#卷积网络
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.conv1 = nn.Conv2d(3,6,5)
        self.conv2 = nn.Conv2d(6,16,5)
        self.fc1 = nn.Linear(16*5*5,120)
        self.fc2 = nn.Linear(120,84)
        self.fc3 = nn.Linear(84,10)


    def forward(self, x):
        x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
        x = F.max_pool2d(F.relu(self.conv2(x)),2)

        x = x.view(x.size()[0],-1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()
print(net)

#损失函数和优化器
from torch import optim
criterion = nn.CrossEntropyLoss()#交叉熵损失函数
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9)

#训练网络
from torch.autograd import Variable
import time

tstart = time.time()
for epoch in range(5):
    running_loss = 0.0
    for i, data in enumerate(trainloader,0): #enumerate 用法见注释
        #输入数据
        inputs,labels = data
        inputs,labels = Variable(inputs),Variable(labels)

        #梯度清零
        optimizer.zero_grad()
        #forward+backward
        outputs = net(inputs)
        loss = criterion(outputs,labels)
        loss.backward()
        #更新参数
        optimizer.step()

        #打印log(日志)信息
        running_loss += loss.data[0]
        if i%2000 == 1999: #每2000个batch打印一次训练状态
            print('[%d,%5d] loss:%.3f' %(epoch+1,i+1,running_loss/2000))
            running_loss = 0.0
print('finished')
tend = time.time()
print('Spend time = ',tend - tstart)


correct = 0 #正确数
total = 0 #总数
for data in testloader:
    images,labels = data
    outputs = net(Variable(images))
    _,predicted = t.max(outputs.data,1)
    total += labels.size(0)
    correct += (predicted == labels).sum()


print('%d %%' %(100*correct/total)

——

补充注释:enumerate() 函数

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

Python 2.3. 以上版本可用,2.6 添加 start 参数。

语法

以下是 enumerate() 方法的语法:

enumerate(sequence, [start=0])

参数

  • sequence -- 一个序列、迭代器或其他支持迭代对象。
  • start -- 下标起始位置。

返回值

返回 enumerate(枚举) 对象。


实例

以下展示了使用 enumerate() 方法的实例:

>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter'] >>> list(enumerate(seasons)) [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] >>> list(enumerate(seasons, start=1)) # 小标从 1 开始 [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

 ——

GPU版本,跑的比CPU还慢??

import torch as t
import torchvision as tv
import torchvision.transforms as transforms
from torchvision.transforms import ToPILImage
import numpy as np
import matplotlib.pyplot as plt
show = ToPILImage() #可以把Tensor 转成Image,方便可视化

#第一次运行torchvision 会自动下载CIFAR-10数据集

#定义对数据的预处理
transform = transforms.Compose([
    transforms.ToTensor(), # 转为Tensor
    transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)), #归一化
])

#训练集
trainset = tv.datasets.CIFAR10(
    root='./data',
    train=True,
    download=True,
    transform=transform
)
#注意windows现在还不支持多线程,所以num_workers=0
trainloader = t.utils.data.DataLoader(
    trainset,
    batch_size=4,
    shuffle=True,
    num_workers=0
)

#测试集
testset = tv.datasets.CIFAR10(
    './data',
    train=False,
    download=True,
    transform=transform
)

testloader = t.utils.data.DataLoader(
    testset,
    batch_size=4,
    shuffle=False,
    num_workers=0
)

classes = (
    'plane','car','bird','cat','deer','dog','frog','horse','ship','truck'
)

(data,label) = trainset[100]
print(classes[label])

# (data+1)/2是为了还原被归一化的数据
show((data+1)/2).resize((100,100))

# dataiter=iter(trainloader)
# images,labels=dataiter.next()
# print(''.join('11%s'%classes[labels[j]] for j in range(4)))
# show(tv.utils.make_grid(images+1)/2).resize((400,100))
def imshow(img):
    img = img / 2 + 0.5
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))

dataiter = iter(trainloader)
images, labels = dataiter.next()
print(images.size())
imshow(tv.utils.make_grid(images))
plt.show()#关掉图片才能往后继续算

#卷积网络
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.conv1 = nn.Conv2d(3,6,5)
        self.conv2 = nn.Conv2d(6,16,5)
        self.fc1 = nn.Linear(16*5*5,120)
        self.fc2 = nn.Linear(120,84)
        self.fc3 = nn.Linear(84,10)


    def forward(self, x):
        x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
        x = F.max_pool2d(F.relu(self.conv2(x)),2)

        x = x.view(x.size()[0],-1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()
if t.cuda.is_available():
    net.cuda()
print(net)

#损失函数和优化器
from torch import optim
criterion = nn.CrossEntropyLoss()#交叉熵损失函数
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9)

#训练网络
from torch.autograd import Variable
import time

tstart = time.time()
for epoch in range(5):
    running_loss = 0.0
    for i, data in enumerate(trainloader,0): #enumerate 用法见注释
        #输入数据
        inputs,labels = data
        inputs,labels = Variable(inputs),Variable(labels)
        if t.cuda.is_available():
            inputs = inputs.cuda()
            labels = labels.cuda()
        #梯度清零
        optimizer.zero_grad()
        #forward+backward
        outputs = net(inputs)
        loss = criterion(outputs,labels)
        loss.backward()
        #更新参数
        optimizer.step()

        #打印log(日志)信息
        running_loss += loss.data[0]
        if i%2000 == 1999: #每2000个batch打印一次训练状态
            print('[%d,%5d] loss:%.3f' %(epoch+1,i+1,running_loss/2000))
            running_loss = 0.0
print('finished')
tend = time.time()
print('Spend time = ',tend - tstart)


correct = 0 #正确数
total = 0 #总数
for data in testloader:
    images,labels = data
    images = Variable(images)

    if t.cuda.is_available():
        images = images.cuda()

    outputs = net(images)
    _,predicted = t.max(outputs.data,1)
    total += labels.size(0)
    correct += (predicted == labels.cuda()).sum()


print('%d %%' %(100*correct/total))

____

 CNN + MNIST

import torch
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
import os
import torchvision
import numpy as np
from torch.autograd import Variable

#数据预处理
transform = transforms.Compose([transforms.ToTensor(),
                               transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])])
#下载MNIST
data_train = datasets.MNIST(root = "./data1",
                            transform=transform,
                            train = True,
                            download = True)

data_test = datasets.MNIST(root="./data1",
                           transform = transform,
                           train = False)

data_loader_train = torch.utils.data.DataLoader(dataset=data_train,
                                                batch_size = 64,
                                                shuffle = True,
                                                 num_workers=0)

data_loader_test = torch.utils.data.DataLoader(dataset=data_test,
                                               batch_size = 64,
                                               shuffle = True,
                                                num_workers=0)

#定义卷积网络
# 这里构建的是一个包含了卷积层和全连接层的神经网络,
# 其中卷积层使用torch.nn.Conv2d来构建,
# 激活层使用torch.nn.ReLU来构建,
# 池化层使用torch.nn.MaxPool2d来构建,
# 全连接层使用torch.nn.Linear来构建(dense)
class Model(torch.nn.Module):

    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = torch.nn.Sequential(torch.nn.Conv2d(1, 4, kernel_size=3, stride=1, padding=1),
                                         torch.nn.ReLU(),
                                         torch.nn.Conv2d(4, 16, kernel_size=3, stride=1, padding=1),
                                         torch.nn.ReLU(),
                                         torch.nn.MaxPool2d(stride=2, kernel_size=2))
        #
        self.dense = torch.nn.Sequential(torch.nn.Linear(14 * 14 * 16, 33),  #只有这个14*14不能瞎改不知道为啥
                                         torch.nn.ReLU(),
                                         torch.nn.Dropout(p=0.5),#防止过拟合
                                         torch.nn.Linear(33, 10))

    def forward(self, x):
        x = self.conv1(x)
        # x = self.conv2(x)
        x = x.view(-1, 14 * 14 * 16)
        x = self.dense(x)
        return x

model = Model().cuda()
print(model)


cost = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters())
n_epochs = 5

for epoch in range(n_epochs):
    running_loss = 0.0
    running_correct = 0
    print("Epoch {}/{}".format(epoch, n_epochs))
    print("-" * 10)
    for data in data_loader_train:
        X_train, y_train = data
        X_train, y_train = Variable(X_train).cuda(), Variable(y_train).cuda()
        outputs = model(X_train)
        _, pred = torch.max(outputs.data, 1)
        optimizer.zero_grad()
        loss = cost(outputs, y_train)

        loss.backward()
        optimizer.step()
        running_loss += loss.data[0]
        running_correct += torch.sum(pred == y_train.data)
    testing_correct = 0
    for data in data_loader_test:
        X_test, y_test = data
        X_test, y_test = Variable(X_test).cuda(), Variable(y_test).cuda()
        outputs = model(X_test)
        _, pred = torch.max(outputs.data, 1)
        testing_correct += torch.sum(pred == y_test.data)
    print("Loss is:{:.4f}, Train Accuracy is:{:.4f}%, Test Accuracy is:{:.4f}".format(running_loss / len(data_train),
                                                                                      100 * running_correct / len(
                                                                                          data_train),
                                                                                      100 * testing_correct / len(
                                                                                          data_test)))

___

 

posted on 2018-08-25 12:51  村雨sup  阅读(701)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3