我想用猫狗识别程序 框架 在 猫狗两类识别基础上,增加第三类识别,不知道以下程序修改得是否正确,如何改? 模拟应用 模块 不知道怎么改 才能达到 一张图片在 三个分类中识别?麻烦帮忙改下以下程序,谢谢了!
#---------------------------------------构建样本集程序-----------------------------------------------
import cv2 as cv
import numpy as np
import os
if __name__=='__main__':
l_x=128 #输入X的长宽
#样本数量
m=1000#样本总数
m1=100#训练集数量
m2=50#测试集数量
train_set=np.zeros(m1*3*l_x*l_x*3)#创建零矩阵
train_set=np.reshape(train_set,(m1*3,3,l_x,l_x))#重塑成可以存储图像的行政
test_set=np.zeros(m2*3*l_x*l_x*3)#创建零矩阵
test_set=np.reshape(test_set,(m2*3,3,l_x,l_x))#重塑成可以存储图像的形状
sucess_mark=0#成功标记
#构建训练集
for i in range(m1):
#path1=f'./train/cat.{i}.jpg'#训练图片路径
#path2=f'./train/dog.{i}.jpg'
path1=f'./xllz/train/hftl3/{i}.jpg'
path2=f'./xllz/train/hfzt3/{i}.jpg'
path3=f'./xllz/train/hfsl3/{i}.jpg'
if os.path.exists(path1) & os.path.exists(path2) & os.path.exists(path3):
img1=cv.imread(path1)#读取训练图片,转换灰色图片
img2=cv.imread(path2)#读取训练图片
img3=cv.imread(path3)#读取训练图片
img1=cv.resize(img1,(l_x,l_x))#将图片调整规定的尺寸
img2=cv.resize(img2,(l_x,l_x))
img3=cv.resize(img3,(l_x,l_x))
train_set[i,0,:,:]=img1[:,:,0]#赋值给训练集矩阵
train_set[i,1,:,:]=img1[:,:,1]
train_set[i,2,:,:]=img1[:,:,2]
sucess_mark+=1
print("\r"+f'训练集总数:{m1*3},xl当前第{(i+1)*3}个',end="",flush=True)
train_set[m1+i,0,:,:]=img2[:,:,0]
train_set[m1+i,1,:,:]=img2[:,:,1]
train_set[m1+i,2,:,:]=img2[:,:,2]
sucess_mark+=1
train_set[m1+m1+i,0,:,:]=img3[:,:,0]
train_set[m1+m1+i,1,:,:]=img3[:,:,1]
train_set[m1+m1+i,2,:,:]=img3[:,:,2]
sucess_mark+=1
else:
print(f'路径{path1}或{path2}或{path3}不存在0!')
break
pww=input("hello")
#构建测试集
for i in range(100,150):
path1=f'./xllz/train/hftl3/{i}.jpg'
path2=f'./xllz/train/hfzt3/{i}.jpg'
path3=f'./xllz/train/hfsl3/{i}.jpg'
if os.path.exists(path1) & os.path.exists(path2) & os.path.exists(path3):
img1=cv.imread(path1)
img2=cv.imread(path2)
img3=cv.imread(path3)
img1=cv.resize(img1,(l_x,l_x))
img2=cv.resize(img2,(l_x,l_x))
img3=cv.resize(img3,(l_x,l_x))
test_set[i-100,0,:,:]=img1[:,:,0]#赋值给测试集矩阵
test_set[i-100,1,:,:]=img1[:,:,1]
test_set[i-100,2,:,:]=img1[:,:,2]
sucess_mark+=1
print("\r"+f'测试集总数:{m2*3},cs当前第{(i-100+1)*3}个',end="",flush=True)
test_set[m2+i-100,0,:,:]=img2[:,:,0]
test_set[m2+i-100,1,:,:]=img2[:,:,1]
test_set[m2+i-100,2,:,:]=img2[:,:,2]
sucess_mark+=1
test_set[m2+m2+i-100,0,:,:]=img3[:,:,0]
test_set[m2+m2+i-100,1,:,:]=img3[:,:,1]
test_set[m2+m2+i-100,2,:,:]=img3[:,:,2]
sucess_mark+=1
else:
print(f'路径{path1}或{path2}或{path3}不存在1!')
break
print(str(sucess_mark))
if sucess_mark==450:#如果样本总数否则保存两个数据集
np.save('cat_train_set.npy',train_set)
np.save('cat_test_set.npy',test_set)
print('生成成功!')
#-------------------测试样本集-----------------------------
import cv2 as cv
import numpy as np
train_set=np.load('cat_train_set.npy')
test_set=np.load('cat_test_set.npy')
for i in range(1000):
i=400+i
img1=train_set[i,0,:,:]#数字根据生成样本规格数字输入
#img2=test_set[50,0,:,:]
img1=img1.astype(np.uint8)#由float转换uint8格式
#img2=img2.astype(np.uint8)
cv.imshow('q.jpg',img1)#显示图片
#cv.imshow('sl50.jpg',img2)
cv.waitKey(0)
"""
实战2
代码8-3
识别猫狗的卷积神经网络模型
"""
import torch.nn as nn # 引入torch.nn模块
class ICNET(nn.Module): # 定义类存储网络结构
def __init__(self):
super(ICNET, self).__init__()
self.ConvNet = nn.Sequential( # nn模块搭建卷积网络
nn.Conv2d(in_channels=3, out_channels=8, kernel_size=3, stride=1, padding=1,
bias=False), # size:128,128,8
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=8, out_channels=8, kernel_size=3, stride=1, padding=1,
bias=False), # size:128,128,8
nn.ReLU(inplace=True), # ReLU激活函数
nn.MaxPool2d(kernel_size=2, stride=2, padding=0), # size:64,64,18
)
self.LinNet = nn.Sequential( # nn模块搭建网络
nn.Linear(64*64*8, 1000), # 全连接层
nn.ReLU(inplace=True), # ReLU激活函数
nn.Linear(1000, 1000),
nn.ReLU(inplace=True),
nn.Linear(1000, 3),
nn.Softmax(dim=1) # SoftMax分类激活函数
)
def forward(self, x): # 定义前向传播过程
x = self.ConvNet(x) # 将x传入卷积网络
x = x.view(x.size(0), 64*64*8) # 展成一维数组
out = self.LinNet(x) # 接着通过全连接层
return out # 返回预测值
"""
识别猫的卷积神经网络训练程序
(附加可视化)
"""
from net_model import ICNET # 引入网络模型
import torch # 引入torch模块
import torch.nn as nn # 引入torch.nn模块
import numpy as np # 引入np模块
import matplotlib.pyplot as plt # 引入matplotlib模块
net = ICNET().cpu() # 将网络传入GPU
x = np.load(file="cat_train_set.npy") / 255 # 载入训练集并进行简单归一化
x = torch.tensor(x).type(torch.FloatTensor).cpu() # 转换成tensor变量并传入GPU
y1 = torch.zeros(150)
y2 = torch.ones(150)
y = torch.cat((y1, y2)).type(torch.LongTensor)
optimizer = torch.optim.SGD(net.parameters(), lr=0.03) # 设置优化器
loss_func = nn.CrossEntropyLoss() # 设置损失函数
samplenum = 300 # 样本总数(训练集总数)
minibatch = 30 # 小批次样本大小
w_HR = 128 # 样本尺寸
x0 = np.zeros(minibatch * 3 * w_HR * w_HR)
x0 = np.reshape(x0, (minibatch, 3, w_HR, w_HR)) # 创建小批次空白样本
y0 = np.zeros(minibatch) # 创建小批次空白标签
x0 = torch.tensor(x0).type(torch.FloatTensor).cpu()
y0 = torch.tensor(y0).type(torch.LongTensor).cpu() # 将小批次样本和标签传入GPU
plt.ion() # 开启交互模式
x_plt = [0] # x坐标
y_plt = [0] # y坐标
plt.show() # 显示最后一幅图
for epoch in range(80): # epoch循环
print("训练进度:"+str(epoch))
for iterations in range(int(samplenum / minibatch)): # iterations循环
k = 0
for i in range(iterations * minibatch, iterations * minibatch + minibatch): # 部分样本赋值给x0的循环
x0[k, 0, :, :] = x[i, 0, :, :]
x0[k, 1, :, :] = x[i, 1, :, :]
x0[k, 2, :, :] = x[i, 2, :, :]
y0[k] = y[i] # 小批次标签
k = k + 1
out = net(x0) # 实际输出
loss = loss_func(out, y0) # 实际输出和期望输出传入损失函数
optimizer.zero_grad() # 清除梯度
loss.backward() # 误差反向传播
optimizer.step() # 优化器开始优化
if epoch % 10 == 0:# 每50次显示
plt.cla() # 清除上一次绘图
plt.xlim((0, 1000)) # 设置x坐标范围
plt.xlabel('epoch') # x轴的标题
plt.ylim((0, 1)) # 设置y坐标范围
plt.ylabel('loss') # y轴的标题
x_plt.append(epoch) # 增加x坐标
y_plt.append(loss.data) # 增加y坐标
plt.plot(x_plt, y_plt, c='r', marker='x') # 绘制折线图
print(f'epoch:{epoch},loss:{loss}') # 打印中间过程
plt.pause(0.1) # 停留显示
print("循环完成")
plt.ioff() # 关闭交互模式
print("循环完成1")
print("zwc")
torch.save(net, 'net1.pkl') # 保存网络
print("wc")
plt.show() # 显示最后一幅图
#------------------测试网络程序-------------------------------------
import torch
import numpy as np
net=torch.load('net1.pkl')
x=np.load(file="cat_test_set.npy")/255#载入测试集并简单进行归一化
x=torch.tensor(x).type(torch.FloatTensor).cpu()#转换成Tensor变量并传入gpu
y1=torch.zeros(75)
y2=torch.ones(75)
y0=torch.cat((y1,y2))#将两个张量拼接在一起 设置标签用来计算准确率
y=net(x)#输入网络得到结果
a1=torch.max(y,1)[1].cpu().data.numpy()#数据传回CPU 返回数字较大的坐标
a2=y0.data.numpy()#标签转换成numpy数组
print(f'准确率:{sum(a1==a2)/150}')#输出准确率
#--------------模拟识别应用--------------------------------------------------------------
import torch #导入 torch模块
import numpy as np#导入np 模块
import cv2 as cv#导入cv模块
net=torch.load('net1.pkl')#导入PKL网络
img=cv.imread("xllz\\zh\\tl1.jpg")#读取图像
img0=cv.resize(img,(128,128))#更改尺寸
x=np.zeros(128*128*3)#新建空白输入
x=np.reshape(x,(1,3,128,128))#调整到规定维度
x[0,0,:,:]=img0[:,:,0]/255#赋值输入并进行简单归一化
x[0,1,:,:]=img0[:,:,1]/255
x[0,2,:,:]=img0[:,:,2]/255
x=torch.tensor(x).type(torch.FloatTensor).cpu()#转换成tensor变量并传入CPU
y=net(x)#输入网络结果
#听力9
print(y)
max_num=torch.max(y,0)[1]#返回最大值下标
print(max_num)
print(str(max_num))
if max_num==0:
print('听力')
if max_num==1:
print('肢体')
else:
print('视力')
cv.imshow(f'{str}',img)
cv.waitKey(0)
在 构建数据集 网络训练 测试网络 已经增加了第三类识别,不知道程序修改是否正确,正在尝试在 模拟应用 模块增加第三类识别,无法按最接近图片 的一个结果 判断,却出现2个 结果
之前两类识别,分辨率很高,想要增加到 第三类 图片行进识别,达到 图片在 三个分类中进行识别。
3 分类识别,就是 2个二分类 识别的并联
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!