人工智能(Pytorch)搭建模型1-卷积神经网络实现简单图像分类

人工智能(Pytorch)搭建模型1-卷积神经网络实现简单图像分类

本文参加新星计划人工智能(Pytorch)赛道:

目录

一、Pytorch深度学习框架

二、卷积神经网络

三、代码实战

www.zeeklog.com  - 人工智能(Pytorch)搭建模型1-卷积神经网络实现简单图像分类

内容:

一、Pytorch深度学习框架

PyTorch是一个开源的深度学习框架,它基于Torch进行了重新实现,主要支持GPU加速计算,同时也可以在CPU上运行。PyTorch框架提供了强大的自动求导功能,可以轻松地构建神经网络模型,并通过反向传播算法来优化模型的各种参数。

PyTorch框架特点:

动态图:PyTorch使用动态图来表示计算图,使得在定义模型时更加灵活自由,可以根据需要对模型进行修改和调整。

易于调试:PyTorch具有良好的调试工具,可以帮助开发者快速定位和解决问题。

易于使用:PyTorch的API设计简洁明了,使得使用起来非常方便快捷。

社区支持:PyTorch近几年特别热,它拥有庞大的社区支持,有海量的资料和教程可供参考,可以快速入门和解决问题。

www.zeeklog.com  - 人工智能(Pytorch)搭建模型1-卷积神经网络实现简单图像分类

二、卷积神经网络

卷积神经网络(CNN)是一种深度学习模型,主要应用于图像识别、语音识别等领域。与传统的神经网络相比,CNN引入了卷积层和池化层,可以有效地减少模型参数,提高模型性能。

CNN的核心是卷积层,它通过卷积运算来提取输入特征的空间信息。卷积层包括多个卷积核,每个卷积核可以检测输入数据中的某个特定特征,并生成相应的输出特征图。卷积层的参数共享机制可以大大减少模型参数数量,降低过拟合的风险。

池化层用于进一步降低特征图的维度,同时也可以增强模型的鲁棒性。池化操作通常采用最大池化或平均池化,即对输入特征图中的每个子区域取最大值或平均值,生成新的特征图。

除了卷积层和池化层,CNN还包括全连接层和激活函数等组件,可以构建非常复杂的模型。CNN在图像处理任务中表现出色,它是计算机视觉领域的主流模型之一。

www.zeeklog.com  - 人工智能(Pytorch)搭建模型1-卷积神经网络实现简单图像分类

卷积神经网络的基本层与原理:

卷积操作:卷积操作是卷积神经网络的核心操作之一,其目的是从输入数据中提取特征。卷积操作的本质是一种线性变换,它通过一个卷积核在输入数据上进行滑动,并计算每个位置上卷积核与输入数据的内积,得到一个新的特征图。卷积操作可以有效地减少需要学习的参数数量,并且具有平移不变性,即如果输入图像发生平移,提取出的特征不会发生改变。

池化操作:卷积操作得到的特征图通常比输入数据的尺寸大,为了减少特征图的尺寸,降低计算复杂度,我们通常会使用池化操作对特征图进行下采样。常见的池化操作包括最大池化、平均池化等,它们分别选取特定区域内的最大值或平均值作为该区域的输出,从而将特征图的尺寸降低。

激活函数:卷积神经网络通常在卷积和池化操作之后添加一个非线性激活函数,例如ReLU函数,以增强神经网络的表达能力。

全连接层:全连接层是卷积神经网络中的一种常用结构,它将卷积和池化得到的特征图映射到输出类别上。在全连接层中,每个节点都与前一层中的所有节点相连,因此需要学习的参数非常多,计算复杂度也较高。

Dropout层:Dropout操作是常用的正则化技术,可用于防止过拟合。它在训练时随机删除一部分神经元,使得每个神经元的输出不能依赖于其他神经元的存在,从而增加模型的泛化能力。

三、代码实战

下面我将用PyTorch框架搭载一个卷积神经网络模型,手把手教大家构建CNN网络,包括输入层,卷积层,池化层等。通过PyTorch搭建CNN进行图像分类,图像分类的数据集采用CIFAR10数据集,下面的简单易懂的代码部分:

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms

# 定义超参数
batch_size = 64
epochs = 10
learning_rate = 0.01

# 判断是否有可用的GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 定义数据增强方式
transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

transform_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

# 加载CIFAR10数据集
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)

# 创建数据加载器
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=2)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=2)


# 定义卷积神经网络模型
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.fc1 = nn.Linear(64 * 8 * 8, 512)
        self.fc2 = nn.Linear(512, 10)

    def forward(self, x):
        x = nn.functional.relu(self.conv1(x))
        x = nn.functional.max_pool2d(x, 2)
        x = nn.functional.relu(self.conv2(x))
        x = nn.functional.max_pool2d(x, 2)
        x = x.view(-1, 64 * 8 * 8)
        x = nn.functional.relu(self.fc1(x))
        x = self.fc2(x)
        return x


net = Net().to(device)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=learning_rate, momentum=0.9, weight_decay=5e-4)

if __name__=='__main__':
    # 训练模型
    for epoch in range(epochs):
        running_loss = 0.0
        for i, data in enumerate(train_loader, 0):
            inputs, labels = data[0].to(device), data[1].to(device)

            optimizer.zero_grad()

            outputs = net(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()

            running_loss += loss.item()

            if i % 100 == 99:
                print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100))
                running_loss = 0.0

    print('训练完成')

    # 评估模型性能并进行预测
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            images, labels = data[0].to(device), data[1].to(device)
            outputs = net(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()

    print('Accuracy of the network on the 10000 test images: %d %%' % (
        100 * correct / total))

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

    class_correct = list(0. for i in range(10))
    class_total = list(0. for i in range(10))
    with torch.no_grad():
        for data in test_loader:
            images, labels = data[0].to(device), data[1].to(device)
            outputs = net(images)
            _, predicted = torch.max(outputs, 1)
            c = (predicted == labels).squeeze()
            for i in range(len(labels)):
                label = labels[i]
                class_correct[label] += c[i].item()
                class_total[label] += 1

    for i in range(10):
        print('Accuracy of %5s : %2d %%' % (
            classes[i], 100 * class_correct[i] / class_total[i]))

通过运行,可以得到几图片类别的识别结果。

Read more

深入理解 Proxy 和 Object.defineProperty

在JavaScript中,对象是一种核心的数据结构,而对对象的操作也是开发中经常遇到的任务。在这个过程中,我们经常会使用到两个重要的特性:Proxy和Object.defineProperty。这两者都允许我们在对象上进行拦截和自定义操作,但它们在实现方式、应用场景和灵活性等方面存在一些显著的区别。本文将深入比较Proxy和Object.defineProperty,包括它们的基本概念、使用示例以及适用场景,以帮助读者更好地理解和运用这两个特性。 1. Object.defineProperty 1.1 基本概念 Object.defineProperty 是 ECMAScript 5 引入的一个方法,用于直接在对象上定义新属性或修改已有属性。它的基本语法如下: javascript 代码解读复制代码Object.defineProperty(obj, prop, descriptor); 其中,obj是目标对象,prop是要定义或修改的属性名,descriptor是一个描述符对象,用于定义属性的特性。 1.2 使用示例 javascript 代码解读复制代码//

By Ne0inhk

Proxy 和 Object.defineProperty 的区别

Proxy 和 Object.defineProperty 是 JavaScript 中两个不同的特性,它们的作用也不完全相同。 Object.defineProperty 允许你在一个对象上定义一个新属性或者修改一个已有属性。通过这个方法你可以精确地定义属性的特征,比如它是否可写、可枚举、可配置等。该方法的使用场景通常是需要在一个对象上创建一个属性,然后控制这个属性的行为。 Proxy 也可以用来代理一个对象,但是相比于 Object.defineProperty,它提供了更加强大的功能。使用 Proxy 可以截获并重定义对象的基本操作,比如访问属性、赋值、函数调用等等。在这些操作被执行之前,可以通过拦截器函数对这些操作进行拦截和修改。因此,通过 Proxy,你可以完全重写一个对象的默认行为。该方法的使用场景通常是需要对一个对象的行为进行定制化,或者需要在对象上添加额外的功能。 对比 以下是 Proxy 和 Object.defineProperty 的一些区别对比: 方面ProxyObject.defineProperty语法使用 new Proxy(target,

By Ne0inhk