【图像分类】实战——使用VGG16实现对植物幼苗的分类(pytroch(1)

导入数据

train_loader = torch.utils.data.DataLoader(dataset_train, batch_size=BATCH_SIZE, shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset_test, batch_size=BATCH_SIZE, shuffle=False)

设置模型

====

使用CrossEntropyLoss作为loss,模型采用alexnet,选用预训练模型。更改全连接层,将最后一层类别设置为12,然后将模型放到DEVICE。优化器选用Adam。

实例化模型并且移动到GPU

criterion = nn.CrossEntropyLoss()

model_ft = vgg16(pretrained=True)

model_ft.classifier = classifier = nn.Sequential(

nn.Linear(512 * 7 * 7, 4096),

nn.ReLU(True),

nn.Dropout(),

nn.Linear(4096, 4096),

nn.ReLU(True),

nn.Dropout(),

nn.Linear(4096, 12),

)

model_ft.to(DEVICE)

选择简单暴力的Adam优化器,学习率调低

optimizer = optim.Adam(model_ft.parameters(), lr=modellr)

def adjust_learning_rate(optimizer, epoch):

“”“Sets the learning rate to the initial LR decayed by 10 every 30 epochs”“”

modellrnew = modellr * (0.1 ** (epoch // 50))

print(“lr:”, modellrnew)

for param_group in optimizer.param_groups:

param_group[‘lr’] = modellrnew

设置训练和验证

=======

定义训练过程

def train(model, device, train_loader, optimizer, epoch):

model.train()

sum_loss = 0

total_num = len(train_loader.dataset)

print(total_num, len(train_loader))

for batch_idx, (data, target) in enumerate(train_loader):

data, target = Variable(data).to(device), Variable(target).to(device)

output = model(data)

loss = criterion(output, target)

optimizer.zero_grad()

loss.backward()

optimizer.step()

print_loss = loss.data.item()

sum_loss += print_loss

if (batch_idx + 1) % 10 == 0:

print(‘Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}’.format(

epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),

    • (batch_idx + 1) / len(train_loader), loss.item()))

ave_loss = sum_loss / len(train_loader)

print(‘epoch:{},loss:{}’.format(epoch, ave_loss))

验证过程

def val(model, device, test_loader):

model.eval()

test_loss = 0

correct = 0

total_num = len(test_loader.dataset)

print(total_num, len(test_loader))

with torch.no_grad():

for data, target in test_loader:

data, target = Variable(data).to(device), Variable(target).to(device)

output = model(data)

loss = criterion(output, target)

_, pred = torch.max(output.data, 1)

correct += torch.sum(pred == target)

print_loss = loss.data.item()

test_loss += print_loss

correct = correct.data.item()

acc = correct / total_num

avgloss = test_loss / len(test_loader)

print(‘\nVal set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n’.format(

avgloss, correct, len(test_loader.dataset), 100 * acc))

训练

for epoch in range(1, EPOCHS + 1):

adjust_learning_rate(optimizer, epoch)

train(model_ft, DEVICE, train_loader, optimizer, epoch)

val(model_ft, DEVICE, test_loader)

torch.save(model_ft, ‘model.pth’)

测试

我介绍两种常用的测试方式,第一种是通用的,通过自己手动加载数据集然后做预测,具体操作如下:

测试集存放的目录如下图:

第一步 定义类别,这个类别的顺序和训练时的类别顺序对应,一定不要改变顺序!!!!

第二步 定义transforms,transforms和验证集的transforms一样即可,别做数据增强。

第三步 加载model,并将模型放在DEVICE里,

第四步 读取图片并预测图片的类别,在这里注意,读取图片用PIL库的Image。不要用cv2,transforms不支持。

import torch.utils.data.distributed

import torchvision.transforms as transforms

from PIL import Image

from torch.autograd import Variable

import os

classes = (‘Black-grass’, ‘Charlock’, ‘Cleavers’, ‘Common Chickweed’,

‘Common wheat’,‘Fat Hen’, ‘Loose Silky-bent’,

‘Maize’,‘Scentless Mayweed’,‘Shepherds Purse’,‘Small-flowered Cranesbill’,‘Sugar beet’)

transform_test = transforms.Compose([

transforms.Resize((224, 224)),

transforms.ToTensor(),

transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])

])

DEVICE = torch.device(“cuda:0” if torch.cuda.is_available() else “cpu”)

model = torch.load(“model.pth”)

model.eval()

model.to(DEVICE)

path=‘data/test/’

testList=os.listdir(path)

for file in testList:

img=Image.open(path+file)

img=transform_test(img)

img.unsqueeze_(0)

img = Variable(img).to(DEVICE)

out=model(img)

Predict

_, pred = torch.max(out.data, 1)

print(‘Image Name:{},predict:{}’.format(file,classes[pred.data.item()]))

第二种 使用自定义的Dataset读取图片

import torch.utils.data.distributed

import torchvision.transforms as transforms

from dataset.dataset import SeedlingData

from torch.autograd import Variable

classes = (‘Black-grass’, ‘Charlock’, ‘Cleavers’, ‘Common Chickweed’,

‘Common wheat’,‘Fat Hen’, ‘Loose Silky-bent’,

‘Maize’,‘Scentless Mayweed’,‘Shepherds Purse’,‘Small-flowered Cranesbill’,‘Sugar beet’)

transform_test = transforms.Compose([

transforms.Resize((224, 224)),

transforms.ToTensor(),

transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])

])

DEVICE = torch.device(“cuda:0” if torch.cuda.is_available() else “cpu”)

model = torch.load(“model.pth”)

model.eval()

model.to(DEVICE)

dataset_test =SeedlingData(‘data/test/’, transform_test,test=True)

print(len(dataset_test))

对应文件夹的label

for index in range(len(dataset_test)):

item = dataset_test[index]

img, label = item

img.unsqueeze_(0)

data = Variable(img).to(DEVICE)

output = model(data)

_, pred = torch.max(output.data, 1)

print(‘Image Name:{},predict:{}’.format(dataset_test.imgs[index], classes[pred.data.item()]))

index += 1

完整代码

====

train.py

import torch.optim as optim

import torch

import torch.nn as nn

import torch.nn.parallel

import torch.utils.data

import torch.utils.data.distributed

import torchvision.transforms as transforms

from dataset.dataset import SeedlingData

from torch.autograd import Variable

from torchvision.models import vgg16

设置全局参数

modellr = 1e-4

BATCH_SIZE = 32

EPOCHS = 10

DEVICE = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)

数据预处理

transform = transforms.Compose([

transforms.Resize((224, 224)),

transforms.ToTensor(),

transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])

])

transform_test = transforms.Compose([

transforms.Resize((224, 224)),

transforms.ToTensor(),

transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])

])

dataset_train = SeedlingData(‘data/train’, transforms=transform, train=True)

dataset_test = SeedlingData(“data/train”, transforms=transform_test, train=False)

读取数据

print(dataset_train.imgs)

导入数据

train_loader = torch.utils.data.DataLoader(dataset_train, batch_size=BATCH_SIZE, shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset_test, batch_size=BATCH_SIZE, shuffle=False)

实例化模型并且移动到GPU

criterion = nn.CrossEntropyLoss()

model_ft = vgg16(pretrained=True)

model_ft.classifier = classifier = nn.Sequential(

nn.Linear(512 * 7 * 7, 4096),

nn.ReLU(True),

nn.Dropout(),

nn.Linear(4096, 4096),

nn.ReLU(True),

nn.Dropout(),

nn.Linear(4096, 12),

)

model_ft.to(DEVICE)

选择简单暴力的Adam优化器,学习率调低

optimizer = optim.Adam(model_ft.parameters(), lr=modellr)

def adjust_learning_rate(optimizer, epoch):

“”“Sets the learning rate to the initial LR decayed by 10 every 30 epochs”“”

modellrnew = modellr * (0.1 ** (epoch // 50))

print(“lr:”, modellrnew)

for param_group in optimizer.param_groups:

param_group[‘lr’] = modellrnew

定义训练过程

def train(model, device, train_loader, optimizer, epoch):

model.train()

sum_loss = 0

total_num = len(train_loader.dataset)

print(total_num, len(train_loader))

for batch_idx, (data, target) in enumerate(train_loader):

data, target = Variable(data).to(device), Variable(target).to(device)

output = model(data)

loss = criterion(output, target)

optimizer.zero_grad()

loss.backward()

optimizer.step()

print_loss = loss.data.item()

sum_loss += print_loss

if (batch_idx + 1) % 10 == 0:

print(‘Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}’.format(

epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),

    • (batch_idx + 1) / len(train_loader), loss.item()))

ave_loss = sum_loss / len(train_loader)

print(‘epoch:{},loss:{}’.format(epoch, ave_loss))

验证过程

def val(model, device, test_loader):

model.eval()

test_loss = 0

correct = 0

total_num = len(test_loader.dataset)

print(total_num, len(test_loader))

with torch.no_grad():

for data, target in test_loader:

data, target = Variable(data).to(device), Variable(target).to(device)

output = model(data)

loss = criterion(output, target)

_, pred = torch.max(output.data, 1)

correct += torch.sum(pred == target)

print_loss = loss.data.item()

test_loss += print_loss

correct = correct.data.item()

acc = correct / total_num

avgloss = test_loss / len(test_loader)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: VGG模型是一种用于图像识别和分类任务的深度学习模型,其特点是具有较深的网络结构和较大的参数规模。要实现植物幼苗分类任务,我们可以利用VGG模型。 首先,我们需要收集大量的植物幼苗图像数据集作为训练集和测试集。这些图像应包含各种不同种类的植物幼苗,确保样本的多样性和代表性。 然后,通过预处理数据来提取植物幼苗图像的特征。这可能包括调整图像大小、剪裁、增强对比度等操作,以优化图像质量和消除冗余信息。 接下来,我们构建一个VGG模型,该模型由多个卷积层、池化层和全连接层组成。我们可以使用已经在其他图像分类任务上预训练好的VGG模型,也可以针对植物幼苗数据集进行自定义训练。 在训练过程中,我们使用经典的反向传播算法,通过计算梯度来优化模型的权重参数。同时,我们可以采用一些正则化技术,如Dropout和L2正则化,以避免模型过拟合。通过不断迭代训练,模型将逐渐学习和提取植物幼苗图像的特征。 最后,我们使用测试集来评估模型的性能。根据模型对植物幼苗图像分类准确率和其他评价指标,我们可以对模型进行调整和改进。 通过这个过程,我们可以使用VGG模型实现植物幼苗分类任务。通过训练模型和优化参数,我们能够较准确地分类和识别各种不同种类的植物幼苗。 ### 回答2: VGG模型是一种深度卷积神经网络模型,其主要特点是使用了多个同样大小(3x3)的卷积层,通过多次堆叠来提高模型的深度。VGG模型在图像分类任务中取得了良好的效果,并成为了很多研究人员的基准模型。 要实现植物幼苗分类,首先需要收集包含不同种类植物幼苗的图片数据集。这些图片可以包含不同种类、不同角度和不同环境下的植物幼苗。将这些图片划分为训练集和测试集,用于模型的训练和评估。 在使用VGG模型之前,需要对图片进行预处理。这包括对图片进行缩放、裁剪、归一化等处理,以确保输入图片的大小和格式与VGG模型的要求相匹配。 接下来,可以使用Python中的深度学习框架,如TensorFlow或PyTorch,加载预训练的VGG模型。预训练的VGG模型可以通过从头开始训练或者从已有的模型中微调得到。 然后,将训练集的图片输入到VGG模型中,通过反向传播算法进行训练。在训练过程中,可以使用交叉熵损失函数来衡量模型的性能,并使用优化算法如梯度下降来更新模型的参数。 训练完成后,可以使用测试集的图片来评估模型的性能。通过计算模型在测试集上的准确率、精确率、召回率等指标,可以了解模型的分类效果。 最后,可以使用已训练好的VGG模型来对新的植物幼苗图片进行分类。将新的图片输入到模型中,通过预测输出的概率大小来判断植物幼苗属于哪个类别。 总之,使用VGG模型可以有效地实现植物幼苗分类。通过合理的数据集处理、模型训练和评估,可以提高模型的分类性能,帮助人们更好地理解和研究植物幼苗。 ### 回答3: vgg模型是一种深度卷积神经网络模型,由于其结构简单、易于理解和实现,在图像分类任务中取得了广泛的应用。如果要使用vgg模型对植物幼苗进行分类,可以按照以下步骤进行实现。 首先,需要准备一个包含不同类别的植物幼苗图像数据集。这些图像应包含不同品种、不同生长阶段以及不同视角的幼苗图片,以便模型具有足够的训练样本进行分类。 接下来,将数据集划分为训练集和测试集。训练集用于训练vgg模型的权重参数,测试集用于评估模型在未见过的数据上的性能。 然后,需要加载预训练的vgg模型。在PyTorch中,可以使用torchvision.models模块中的vgg模型来实现。加载预训练的vgg模型可以借助torchvision.models中的VGG类,并指定使用预训练的参数。 在加载模型后,需要针对植物幼苗分类任务进行微调。由于vgg模型在ImageNet数据集上进行了训练,其输出层的类别数与ImageNet类别数相同。因此,需要根据所需要的植物幼苗类别数进行修改。可以通过修改模型的全连接层中的输出单元数来实现,确保输出类别数与植物幼苗的类别数一致。 接下来,将训练集中的图像输入到vgg模型中进行训练。训练过程涉及前向传播、计算损失函数、反向传播和更新模型参数。可以使用常用的优化器,如随机梯度下降(SGD)或Adam等,来更新vgg模型的权重参数。 最后,使用测试集评估模型的性能。将测试集中的图像输入到微调后的模型中,得到模型的预测结果。可以计算预测结果与真实标签的准确性或其他指标来评估模型的分类性能。 通过以上步骤,我们可以利用vgg模型实现植物幼苗分类任务。此外,还可以根据实际需求对模型进行进一步的优化和调整,以提高分类准确性和泛化能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值