花朵图像分类
1.项目目录介绍
1.flower_photos:通过BML标注的5类花朵数据集。2.train:训练集。3.val:测试集。4.1_create_dataset:划分训练集的代码。5.2_split_dataset:划分测试集的代码。5.AlexNet.pth:花朵识别模型。6.class_indices.json:数据集各类花朵对应的标识集。7.k.jpg和tulip.jpg:指的是用来验证测试项目测试成果。8.model.py:构建网络使用AlexNet 竞赛的冠军网络,分类准确率由传统的70%+提升到80%+。9.predict.py:指的是使用模型识别照片。10.train.py:训练模型并保存模型。
2.项目实现具体操作
1.图像数据标注:数据收集:收集适合标注的花朵图像数据集。从公开数据集采集图像。
标注需求定义:确定需要标注的对象或信息类型,使用图像分类
标注工具选择:根据标注需求选择适合的标注工具,使用BML
标注标准制定:制定清晰的标注标准和规范,确保标注结果的一致性和可靠性。定义物体的类别。
标注对象:使用相应的标注工具,在图像上进行目标标注
添加标签:为标注的对象或区域添加相应的标签信息,如类别名称、类别ID等。
质量控制:对标注结果进行质量检查和验证,确保标注准确性和一致性。可以进行内部评审
数据导出:将标注结果导出为特定的数据格式,格式JSON,以便后续的机器学习训练或数据分析。
2.数据收集:将数据集划分为训练集和测试集,解析json文件并将jpg图片按不同类别划分到不同的文件夹中, 收集代表各个类别的图像数据。确保每个类别都有足够数量的图片,并且图像质量良好。
将图像数据分为训练集和测试集。通常,将大部分数据用于训练,一小部分用于测试模型的性能。
2.1代码是解析json文件获取nng图片的分类类别保存到label,根据label的不同类别创建不同的文件夹,划分jpg图片到不同类别的文件夹。
2.2按8:2的比例划分训练集train和验证集val,这些文件名将用于后续将对应的图片文件从训练集移动到验证集
3.构建网络:使用AlexNet 是2012年 ISLVRC ( ImageNet Large Scale Visual Recognition Challenge)竞赛的冠军网络,分类准确率由传统的70%+提升到80%+。
3.1用nn.Sequential()将网络打包成一个模块,精简代码,卷积层提取图像特征直接修改覆盖原值,节省运算内存全连接层对图像分类,Dropout 随机失活神经元,默认比例为0.5。
3.2前向传播过程, 展平后再传入全连接层, 网络权重初始化,实际上 pytorch 在构建网络时会自动初始化权重。
4.数据预处理:花分类数据集使用datasets.ImageFolder()来导入。ImageFolder()返回的对象是一个包含数据集所有图像及对应标签构成的二维元组容器,支持索引和迭代,可作为torch.utils.data.DataLoader的输入
4.1导入训练集并进行预处理,按batch_size分批次加载训练集
4.2导入验证集并进行预处理方便在 predict 时读取信息,将 索引:标签 存入到一个 json 文件中
5. 训练模型:使用训练集对模型进行训练。在训练过程中,将特征和对应的类别标签作为输入,使模型学习图像特征与类别之间的关联关系。根据模型的训练误差和验证集的性能,进行模型调参和优化。
5.1实例化网络(输出类型为5,初始化权重),分配网络到指定的设备(GPU/CPU)训练,优化器(训练参数,学习率)
5.2保存准确率最高的那次网络参数
6. 模型评估与测试:用测试集对已训练好的模型进行评估。计算模型在测试集上的准确率、精确率、召回率等指标,以衡量其性能和泛化能力。通过分析模型在不同类别上的分类结果和错误情况,了解模型的强项和弱项,并可能调整数据收集或模型设计的策略。
6.1导入测试图片、模型,将输出压缩,即压缩掉 batch 这个维度
3.项目实现具体代码
1.1_create_dataset.py
import os
import json
from PIL import Image
folder_path = r'.flower_dataflower_photos'
file_names = os.listdir(folder_path)
file_paths = [os.path.join(folder_path, file_name) for file_name in file_names if file_name.endswith('.json')]
data_path = r'.flower_datatrain'
for i in range(len(file_paths)):
with open(file_paths[i], 'r') as file:
json_content = json.load(file)
label = json_content.get('labels')[0].get('name')
train_path = os.path.join(data_path, label)
if not os.path.exists(train_path):
os.makedirs(train_path)
img_name = os.path.basename(file_paths[i])[:-5]+".jpg"
img_path = os.path.join(folder_path, img_name)
pickImage = Image.open(img_path)
save_path = os.path.join(train_path, img_name)
pickImage.save(save_path)
2.2_split_dataset.py
import os
import random
import shutil
def move_picture(train_path, val_path):
train_path_list = os.listdir(train_path)
num_pic = len(train_path_list)
rate = 0.5
move_number = int(num_pic * rate)
samples = random.sample(train_path_list, move_number)
for sample in samples:
shutil.move(train_path + r'' + sample, val_path + '' + sample)
if __name__ == '__main__':
output_train_dir = r".flower_datatrain"
output_val_dir = r".flower_dataval"
file_names = os.listdir(output_train_dir)
for i in file_names:
train_path = os.path.join(output_train_dir, i)
val_path = os.path.join(output_val_dir, i)
if not os.path.exists(val_path):
os.makedirs(val_path)
move_picture(train_path, val_path)
3.model.py
import torch.nn as nn
import torch
class AlexNet(nn.Module):
def __init__(self, num_classes=1000, init_weights=False):
super(AlexNet, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 48, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(48, 128, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(128, 192, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(192, 192, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(192, 128, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.classifier = nn.Sequential(
nn.Dropout(p=0.5),
nn.Linear(128 * 6 * 6, 2048),
nn.ReLU(inplace=True),
nn.Dropout(p=0.5),
nn.Linear(2048, 2048),
nn.ReLU(inplace=True),
nn.Linear(2048, num_classes),
)
if init_weights:
self._initialize_weights()
def forward(self, x):
x = self.features(x)
x = torch.flatten(x, start_dim=1)
x = self.classifier(x)
return x
def _initialize_weights(self):
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode='fan_out',
nonlinearity='relu')
if m.bias is not None:
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.Linear):
nn.init.normal_(m.weight, 0, 0.01)
nn.init.constant_(m.bias, 0)
4.predict.py
import os
import json
import torch
from PIL import Image
from torchvision import transforms
import matplotlib.pyplot as plt
from model import AlexNet
def main():
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
data_transform = transforms.Compose(
[transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
img_path = "tulip.jpg"
assert os.path.exists(img_path), "file: '{}' dose not exist.".format(img_path)
img = Image.open(img_path)
plt.imshow(img)
img = data_transform(img)
img = torch.unsqueeze(img, dim=0)
json_path = './class_indices.json'
assert os.path.exists(json_path), "file: '{}' dose not exist.".format(json_path)
with open(json_path, "r") as f:
class_indict = json.load(f)
model = AlexNet(num_classes=5).to(device)
weights_path = "./AlexNet.pth"
assert os.path.exists(weights_path), "file: '{}' dose not exist.".format(weights_path)
model.load_state_dict(torch.load(weights_path))
model.eval()
with torch.no_grad():
output = torch.squeeze(model(img.to(device))).cpu()
predict = torch.softmax(output, dim=0)
predict_cla = torch.argmax(predict).numpy()
print_res = "class: {} prob: {:.3}".format(class_indict[str(predict_cla)],
predict[predict_cla].numpy())
plt.title(print_res)
for i in range(len(predict)):
print("class: {:10} prob: {:.3}".format(class_indict[str(i)],
predict[i].numpy()))
plt.show()
if __name__ == '__main__':
main()
5.train.py
import os
import sys
import json
import torch
import torch.nn as nn
from torchvision import transforms, datasets
import torch.optim as optim
from tqdm import tqdm
from model import AlexNet
def main():
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print("using {} device.".format(device))
data_transform = {
"train": transforms.Compose([transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]),
"val": transforms.Compose([transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])}
image_path="E:桌面总文件夹新建文件夹小学期代码xiaoflower_data"
assert os.path.exists(image_path), "{} path does not exist.".format(image_path)
train_dataset = datasets.ImageFolder(root=os.path.join(image_path, "train"),
transform=data_transform["train"])
train_num = len(train_dataset)
flower_list = train_dataset.class_to_idx
cla_dict = dict((val, key) for key, val in flower_list.items())
json_str = json.dumps(cla_dict, indent=4)
with open('class_indices.json', 'w') as json_file:
json_file.write(json_str)
batch_size = 32
nw = min([os.cpu_count(), batch_size if batch_size > 1 else 0, 8])
print('Using {} dataloader workers every process'.format(nw))
train_loader = torch.utils.data.DataLoader(train_dataset,
batch_size=batch_size, shuffle=True,
num_workers=nw)
validate_dataset = datasets.ImageFolder(root=os.path.join(image_path, "val"),
transform=data_transform["val"])
val_num = len(validate_dataset)
validate_loader = torch.utils.data.DataLoader(validate_dataset,
batch_size=4, shuffle=False,
num_workers=nw)
print("using {} images for training, {} images for validation.".format(train_num,
val_num))
net = AlexNet(num_classes=5, init_weights=True)
net.to(device)
loss_function = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.0002)
epochs = 10
save_path = './AlexNet.pth'
best_acc = 0.0
train_steps = len(train_loader)
for epoch in range(epochs):
net.train()
running_loss = 0.0
train_bar = tqdm(train_loader, file=sys.stdout)
for step, data in enumerate(train_bar):
images, labels = data
optimizer.zero_grad()
outputs = net(images.to(device))
loss = loss_function(outputs, labels.to(device))
loss.backward()
optimizer.step()
running_loss += loss.item()
train_bar.desc = "train epoch[{}/{}] loss:{:.3f}".format(epoch + 1,
epochs,
loss)
net.eval()
acc = 0.0
with torch.no_grad():
val_bar = tqdm(validate_loader, file=sys.stdout)
for val_data in val_bar:
val_images, val_labels = val_data
outputs = net(val_images.to(device))
predict_y = torch.max(outputs, dim=1)[1]
acc += torch.eq(predict_y, val_labels.to(device)).sum().item()
val_accurate = acc / val_num
print('[epoch %d] train_loss: %.3f val_accuracy: %.3f' %
(epoch + 1, running_loss / train_steps, val_accurate))
if val_accurate > best_acc:
best_acc = val_accurate
torch.save(net.state_dict(), save_path)
print('Finished Training')
if __name__ == '__main__':
main()
相关知识
机器学习花朵图像分类
转移学习:使用VGGNet对花朵图像进行分类
图像分类之花卉图像分类(五)测试数据
图像分类之花卉图像分类(一)数据增强
基于图像的植物病害识别与分类
图片分类数据集(17类花朵)
图像分类之花卉识别实验验证
基于深度学习的花卉图像分类算法研究
高光谱图像分类工具包:精准识别的利器
基于卷积神经网络的花卉图像分类研究(32页)
网址: 花朵图像分类 https://www.huajiangbk.com/newsview1326041.html
上一篇: www.aiplants.net |
下一篇: 计算机视觉 【毕业设计】深度学习 |
推荐分享

- 1君子兰什么品种最名贵 十大名 4012
- 2世界上最名贵的10种兰花图片 3364
- 3花圈挽联怎么写? 3286
- 4迷信说家里不能放假花 家里摆 1878
- 5香山红叶什么时候红 1493
- 6花的意思,花的解释,花的拼音 1210
- 7教师节送什么花最合适 1167
- 8勿忘我花图片 1103
- 9橄榄枝的象征意义 1093
- 10洛阳的市花 1039