如何使用 PyTorch 进行图像分类

跑代码 戳这里👇:
如何使用 PyTorch 进行图像分类

有小伙伴问了:人工智能和深度学习到底有什么区别?

drawing

深度学习一般是用 Python 写的,人工智能一般是用 PPT写的。

小伙伴:那我还是学深度学习好了,但是那些图片文件怎么就可以送到模型里面去呢?我需要打印出来吗?

drawing 你不需要打印出来!

数字图像由像素组成,像素由一系列代码表示的原色组合而成(例:红绿蓝三通道的彩色图像,单通道的黑白图像),通道是与彩色图像大小相同的灰度图像
在这里插入图片描述
在这里插入图片描述
黑白图像(单通道)和彩色图像(三通道)

在灰度图像中,0 通常表示黑,而最大值通常表示白色。例如,在一个 8 位影像中,最大的无号整数是 255,所以这是白色的值,下图方便小伙伴理解。

于是这个图片就可以以矩阵的形式进行表现:
在这里插入图片描述
人工神经网络(英语:Artificial Neural Network,ANN),简称神经网络(Neural Network,NN)或人工神经网络,在机器学习和认知科学领域,是一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。神经网络由大量的人工神经元联结进行计算。[ Ref ]

简单来说,神经网络的输入就是矩阵形式的数据,输出则是我们想要的结果编码(监督学习),如下图(来源)
在这里插入图片描述

准备数据

图像数据在操作系统中普遍是以图像文件形式存在的,例如:jpg、png、jpeg、avi 等等。甚至视频数据也可以简单的理解为一张张图像数据叠加,当然视频数据会用很多视频协议约束,只是暂时可以这样想方便理解。

下面这段代码就是将我们需要的数据转换成 PyTorch 中神经网络模型“认识”的格式 – Tensor

transform=transforms.Compose([
    transforms.ToTensor(),
    ])

dataset1 = datasets.MNIST(
    '/home/featurize/data',
    train=True,
    download=True,
    transform=transform
)
dataset2 = datasets.MNIST(
    '/home/featurize/data',
    train=False,
    transform=transform
)
train_loader = torch.utils.data.DataLoader(dataset1, batch_size=512)
test_loader = torch.utils.data.DataLoader(dataset2, batch_size=512)

神经网络

下面这部分就是神经网络的代码部分,这只是一个非常简单的小型神经网络总共也就 10 层左右,鉴于我们需要完成的任务是识别手写数字这样简单的任务,这种参数级别的网络也就够了。

当然,经过数十年的发展,各种结构的神经网络也是层出不穷,小伙伴们可以查阅各种典型的神经网络:

class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = torch.nn.Conv2d(1, 32, 3, 1)
        self.conv2 = torch.nn.Conv2d(32, 64, 3, 1)
        self.dropout1 = torch.nn.Dropout(0.25)
        self.dropout2 = torch.nn.Dropout(0.5)
        self.fc1 = torch.nn.Linear(9216, 128)
        self.fc2 = torch.nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)
        x = self.dropout1(x)
        x = torch.flatten(x, 1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.dropout2(x)
        x = self.fc2(x)
        output = F.log_softmax(x, dim=1)
        return output


model = Model().cuda()

损失函数

损失函数,是用来度量神经网络模型预测结果与我们预期的实际结果之间差距的重要指标。

drawing

就比如说我小时候数学考试,我妈问:这题结果是 7 为什么错了啊? 如果我回答:我不小心写成 “1” 了,我妈会说: 下次注意点。但是如果我说:我不小心写成 “5689诶我就是不写正确答案嘿嘿”,你说我脸上会不会多点东西。。。

神经网络也是这样,预测结果和实际结果相差越大,在反向传播的时候对神经网络的“惩罚”也就越大。

损失函数针对不同的任务也是有很多,这里我们使用交叉熵损失函数

criterion = torch.nn.CrossEntropyLoss()

优化器

优化器,是用于最小化误差函数(损失函数)算法或方法。

drawing

这是什么意思呢?比如背化学元素周期表,第一遍:氢氦锂饕旮茕餮旯%#@。。。但是多读几遍就可以背了。

优化器也是这样,在神经网络模型的训练过程中,会逐渐逼近全局最优。

drawing
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
drawing

接下来我们的准备工作完成以后,就开始训练了,下面是 PyTorch 的训练代码,我们训练了 10 个 Epoch,其中把 amp 设置为 True 就会开启半精度训练

amp = True

losses = []
epochs = 10

print('Start training...')

running_loss = 0.0
for epoch in range(epochs):
    for i, data in enumerate(train_loader):
        inputs, labels = data
        inputs, labels = inputs.cuda(), labels.cuda()
        optimizer.zero_grad()

        if amp == False:
            scaler = torch.cuda.amp.GradScaler()
            autocast = torch.cuda.amp.autocast
            with autocast():
                outputs = model(inputs)
                loss = criterion(outputs.squeeze(), labels)
            scaler.scale(loss).backward()
            scaler.step(optimizer)
            scaler.update()
        else:
            outputs = model(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()

    losses.append(loss.item())
    print(f'Epoch: {epoch + 1} Loss: {loss.item()}')

print('Training Finished.')
Start training...
Epoch: 1 Loss: 2.0722591876983643
Epoch: 2 Loss: 0.7566283345222473
Epoch: 3 Loss: 0.6012440323829651
Epoch: 4 Loss: 0.4330746829509735
Epoch: 5 Loss: 0.5116708874702454
Epoch: 6 Loss: 0.44722819328308105
Epoch: 7 Loss: 0.3877495527267456
Epoch: 8 Loss: 0.40162554383277893
Epoch: 9 Loss: 0.42336317896842957
Epoch: 10 Loss: 0.3293791711330414
Training Finished.
f, ax = plt.subplots()
sns.lineplot(x=np.linspace(0, 0+epochs-1, epochs), y=losses).set_title('Training Loss');

在这里插入图片描述
drawing

上图只是训练数据集的损失函数,通常我们会用交叉验证集的损失函数来判断模型效果是否良好。

小伙伴问了:为什么要另外一个数据集来验证呢?这多麻烦啊。

模型老做同样的选择题把答案背下来了怎么办,我得确定他是真的会了才行。

下面对测试集进行结果预测:

f, axs = plt.subplots(2,10, figsize=(16,4))
random_index = [random.randint(0, 128-1) for i in range(20)]
for i in range(2):
    for j in range(10):
        axs[i][j].set_axis_off()
        axs[i][j].set_title(f'Label {label[random_index[i*10+j]]}')
        axs[i][j].imshow(img[random_index[i*10+j]].permute(1,2,0), cmap=cm.gray)

在这里插入图片描述
drawing

结果还是挺不错的,至少随机的这 20 个样本里没有错误。

image

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dave 扫地工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值