水稻是世界范围内生产最广泛的粮食产品之一,具有许多遗传品种。这些品种由于其某些特征而彼此分离。这些通常是纹理、形状和颜色等特征。有了这些区分水稻品种的特征,就可以对种子的质量进行分类和评估。在这项研究中,使用了Arborio,Basmati,Ipsala,Jasmine和Karacadag,它们是土耳其经常种植的五种不同品种的水稻。数据集中共包含 75,000 张颗粒图像,其中每个品种有 15,000 张。使用从这些图像中获得的第二个数据集,其中包含106个特征,包括12个形态特征,4个形状特征和90个颜色特征。通过对要素数据集使用人工神经网络 (ANN) 和深度神经网络 (DNN) 算法以及使用卷积神经网络 (CNN) 算法对图像数据集创建模型,并执行分类过程。利用模型的混淆矩阵值计算灵敏度、特异性、预测性、F1评分、准确度、假阳性率和假阴性率的统计结果,并以表格形式给出各模型的结果。
该数据集为识别rice品种:
共分五类,见上图,每个文件夹为一类,下面的为不同类的米饭图片:
数据集下载:下载
第一步读取数据集,处理图像数据:
import torch
from torch.utils.data import Dataset
from torch import randperm
from torchvision import transforms, datasets
import torch.nn.functional as F
class my_dataset(Dataset):
def __init__(self, dir):
super(my_dataset, self).__init__()
transform = transforms.Compose(
transforms.ToTensor(), # 转为tensor类型
)
self.url = dir
self.data = datasets.ImageFolder(self.url, transform=transform)
def __len__(self):
return self.data.__len__()
def __getitem__(self, index):
return self.data[index][0], self.data[index][1]
def data_split(data, rate):
train_l = int(len(data) * rate)
test_l = len(data) - train_l
"""打乱数据集并且划分"""
train_set, test_set = torch.utils.data.random_split(data, [train_l, test_l])
return train_set, test_set
第二步,构建神经网络,训练和测试:
import torch
import numpy as np
from torch.utils.data import DataLoader
from torch import nn
import time
from tqdm import tqdm
from rice_datasets import my_dataset, data_split
class cnn(nn.Module):
def __init__(self):
super(cnn, self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=12, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2)
)
self.layer2 = nn.Sequential(
nn.Conv2d(in_channels=12, out_channels=6, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2)
)
self.layer3 = nn.Sequential(
nn.Flatten(),
nn.Linear(in_features=23064, out_features=1024),
nn.Dropout(0.1), # drop 10% of the neuron
nn.ReLU(),
nn.Linear(in_features=1024, out_features=5)
)
def forward(self, x):
x = self.layer1(x)
# print('layer1:', x.shape)
x = self.layer2(x)
# print('layer2:', x.shape)
x = self.layer3(x)
# x = x.view(x.size(0), -1)
# print('layer3:', x.shape)
return x
# if __name__ == '__main__':
# datasets = my_dataset(r"./Rice_Image_Dataset/")
# model = cnn()
# data = torch.ones(1, 3, 250, 250)
# x = model(data)
# print(x)
#
if __name__ == '__main__':
# 读取数据集
datasets = my_dataset(r"./Rice_Image_Dataset/")
data_train, data_test = data_split(datasets, 0.7)
# 装入训练集,测试集到DataLoader
data_train_loader = DataLoader(data_train, batch_size=100, shuffle=True, num_workers=4)
data_test_loader = DataLoader(data_test, batch_size=100, shuffle=True, num_workers=4)
# 参数设置
Epoch = 100
LR = 0.001
# 构建神经网络
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
model = cnn()
model = model.to(device)
# 优化器
optimizer = torch.optim.Adam(model.parameters(), LR)
# 设定损失函数
loss_func = torch.nn.CrossEntropyLoss()
for epoch in range(10): #
# for epoch in range(Epoch + 1):
time1 = time.time()
model.train()
los = []
bar = tqdm(enumerate(data_train_loader), colour='yellow', total=len(data_train_loader))
bar.set_description(f'Epoch: {epoch}')
for step, data in bar:
inputs, labels = data
inputs = inputs.to(device)
labels = labels.to(device)
outputs = model(inputs)
# 计算损失函数
loss = loss_func(outputs, labels)
# 清空上一轮的梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 参数更新
optimizer.step()
los.append(loss.cpu().detach().numpy())
bar.set_postfix({'loss': loss.cpu().detach().numpy()})
print('epoch:', epoch, 'loss', np.array(los).mean(), 'time:', time.time() - time1, 's')
model.eval()
with torch.no_grad():
j = 0
barl = tqdm(enumerate(data_test_loader), desc='accary', total=len(data_test_loader), colour='blue')
for step, data in barl:
inputs, labels = data
inputs = inputs.to(device)
# labels = labels.to(device)
outputs = model(inputs)
pred_y = torch.max(outputs, 1)[1].cpu().detach().numpy() # torch.max
labels = labels.detach().numpy() # torch.max
for i in range(len(pred_y)):
if pred_y[i] == labels[i]:
j += 1
print('accary:', j / len(data_test))
训练了三次,准确率已经达到0.991了。